├── model
├── Live.js
├── Activity.js
├── Advertising.js
├── Area.js
├── Notices.js
├── Log.js
├── ArticleComments.js
├── Tag.js
├── Topic.js
├── Folder.js
├── Carousel.js
├── TagType.js
├── Token.js
├── TechSquare.js
├── TagRelation.js
├── Column.js
├── File.js
├── Question.js
├── DataPerms.js
├── Menu.js
├── Base.js
└── Role.js
├── controller
├── Live.js
├── Activity.js
├── Advertising.js
├── Count.js
├── TagRelation.js
├── Notices.js
├── Log.js
├── Charts.js
├── ArticleComments.js
├── Area.js
├── Base.js
├── Draft.js
├── RoleRelation.js
├── Authority.js
├── Question.js
├── Carousel.js
├── TechSquare.js
├── DataPerms.js
├── Menu.js
└── Tag.js
├── router
├── activity.js
├── live.js
├── advertising.js
├── token.js
├── count.js
├── charts.js
├── notices.js
├── tagRelation.js
├── log.js
├── area.js
├── draft.js
├── articleComments.js
├── roleRelation.js
├── tag.js
├── file.js
├── topic.js
├── folder.js
├── tagType.js
├── role.js
├── index.js
├── column.js
├── article.js
├── question.js
├── carousel.js
├── techSquare.js
├── dataPerms.js
└── menu.js
├── validate
├── Live.js
├── Activity.js
├── Advertising.js
├── Notices.js
├── Base.js
├── TagRelation.js
├── RoleRelation.js
├── Draft.js
├── Log.js
├── Area.js
├── ArticleComments.js
├── Tag.js
├── Topic.js
├── TagType.js
├── File.js
├── Column.js
├── Question.js
├── Article.js
├── Folder.js
├── Carousel.js
├── Role.js
├── TechSquare.js
├── DataPerms.js
└── Menu.js
├── exception
└── BaseException.js
├── public
└── article
│ ├── admin_20190611102707_m1r5.md
│ ├── admin_20190611102759_b32l.md
│ ├── admin_20190611103430_wsfj.md
│ ├── admin_20190611103605_4ape.md
│ ├── admin_20190611103626_towc.md
│ ├── admin_20190611103752_v2wm.md
│ ├── admin_20190611103834_sd5r.md
│ ├── admin_20190611112403_yb8x.md
│ ├── admin_20190611112409_msve.md
│ ├── admin_20190611112747_eh56.md
│ ├── admin_20190611112757_qjgf.md
│ ├── admin_20190611205650_z4lb.md
│ ├── admin_20190611205652_ks06.md
│ ├── admin_20190626151452_53m3.md
│ ├── admin_20190626151453_j70q.md
│ ├── test_20190516144154_uw7l.md
│ ├── test_20190522093346_nd73.md
│ ├── test_20190522093351_plb5.md
│ ├── test_20190523135745_bc9y.md
│ ├── test_20190523140051_ayvo.md
│ ├── test_20190819151530_6b6m.md
│ ├── admin_20190611102821_bgfk.md
│ ├── admin_20190611102847_qnhn.md
│ ├── admin_20190611102920_6ddn.md
│ ├── admin_20190611103247_3duv.md
│ ├── admin_20190611103316_nkfg.md
│ ├── admin_20190611103419_0wqz.md
│ ├── admin_20190611103534_svsi.md
│ ├── admin_20190611103744_808j.md
│ ├── admin_20190611103752_2q21.md
│ ├── admin_20190611112400_ki0d.md
│ ├── admin_20190611205647_r1nl.md
│ ├── test_20190523134346_fvh5.md
│ ├── test_20190523134446_ag52.md
│ ├── test_20190523135838_xb7n.md
│ ├── test_20190523135924_z2vg.md
│ ├── test_20190523140118_glo6.md
│ ├── test_20190819152114_noax.md
│ ├── test_20190523140113_qaok.md
│ └── test_20190516145913_bun1.md
├── index.js
├── config
├── default.js
└── development.js
├── .babelrc
├── .gitignore
├── mqtt
├── client.js
└── server.js
├── redis
└── demo.js
├── .github
└── FUNDING.yml
├── mysql
└── demo.js
├── app.js
├── README.md
├── package.json
└── log
└── index.js
/model/Live.js:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/controller/Live.js:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/model/Activity.js:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/router/activity.js:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/router/live.js:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/validate/Live.js:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/controller/Activity.js:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/model/Advertising.js:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/router/advertising.js:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/validate/Activity.js:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/validate/Advertising.js:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/controller/Advertising.js:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/exception/BaseException.js:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/article/admin_20190611102707_m1r5.md:
--------------------------------------------------------------------------------
1 | 11122
--------------------------------------------------------------------------------
/public/article/admin_20190611102759_b32l.md:
--------------------------------------------------------------------------------
1 | 11111
--------------------------------------------------------------------------------
/public/article/admin_20190611103430_wsfj.md:
--------------------------------------------------------------------------------
1 | 11111
--------------------------------------------------------------------------------
/public/article/admin_20190611103605_4ape.md:
--------------------------------------------------------------------------------
1 | 11111
--------------------------------------------------------------------------------
/public/article/admin_20190611103626_towc.md:
--------------------------------------------------------------------------------
1 | 1111
--------------------------------------------------------------------------------
/public/article/admin_20190611103752_v2wm.md:
--------------------------------------------------------------------------------
1 | 1
--------------------------------------------------------------------------------
/public/article/admin_20190611103834_sd5r.md:
--------------------------------------------------------------------------------
1 | 12
--------------------------------------------------------------------------------
/public/article/admin_20190611112403_yb8x.md:
--------------------------------------------------------------------------------
1 | 11
--------------------------------------------------------------------------------
/public/article/admin_20190611112409_msve.md:
--------------------------------------------------------------------------------
1 | 111
--------------------------------------------------------------------------------
/public/article/admin_20190611112747_eh56.md:
--------------------------------------------------------------------------------
1 | 111
--------------------------------------------------------------------------------
/public/article/admin_20190611112757_qjgf.md:
--------------------------------------------------------------------------------
1 | 111
--------------------------------------------------------------------------------
/public/article/admin_20190611205650_z4lb.md:
--------------------------------------------------------------------------------
1 | 1111
--------------------------------------------------------------------------------
/public/article/admin_20190611205652_ks06.md:
--------------------------------------------------------------------------------
1 | 1111
--------------------------------------------------------------------------------
/public/article/admin_20190626151452_53m3.md:
--------------------------------------------------------------------------------
1 | 111
--------------------------------------------------------------------------------
/public/article/admin_20190626151453_j70q.md:
--------------------------------------------------------------------------------
1 | 111
--------------------------------------------------------------------------------
/public/article/test_20190516144154_uw7l.md:
--------------------------------------------------------------------------------
1 | 1111
--------------------------------------------------------------------------------
/public/article/test_20190522093346_nd73.md:
--------------------------------------------------------------------------------
1 | 1111
--------------------------------------------------------------------------------
/public/article/test_20190522093351_plb5.md:
--------------------------------------------------------------------------------
1 | 1111
--------------------------------------------------------------------------------
/public/article/test_20190523135745_bc9y.md:
--------------------------------------------------------------------------------
1 | 1111
--------------------------------------------------------------------------------
/public/article/test_20190523140051_ayvo.md:
--------------------------------------------------------------------------------
1 | 暂不提供删除
--------------------------------------------------------------------------------
/public/article/test_20190819151530_6b6m.md:
--------------------------------------------------------------------------------
1 | 1111
--------------------------------------------------------------------------------
/public/article/admin_20190611102821_bgfk.md:
--------------------------------------------------------------------------------
1 | 1111111
--------------------------------------------------------------------------------
/public/article/admin_20190611102847_qnhn.md:
--------------------------------------------------------------------------------
1 | 11111111
--------------------------------------------------------------------------------
/public/article/admin_20190611102920_6ddn.md:
--------------------------------------------------------------------------------
1 | 1111111
--------------------------------------------------------------------------------
/public/article/admin_20190611103247_3duv.md:
--------------------------------------------------------------------------------
1 | 11111111
--------------------------------------------------------------------------------
/public/article/admin_20190611103316_nkfg.md:
--------------------------------------------------------------------------------
1 | 1111111
--------------------------------------------------------------------------------
/public/article/admin_20190611103419_0wqz.md:
--------------------------------------------------------------------------------
1 | 111111
--------------------------------------------------------------------------------
/public/article/admin_20190611103534_svsi.md:
--------------------------------------------------------------------------------
1 | 111111
--------------------------------------------------------------------------------
/public/article/admin_20190611103744_808j.md:
--------------------------------------------------------------------------------
1 | undefined
--------------------------------------------------------------------------------
/public/article/admin_20190611103752_2q21.md:
--------------------------------------------------------------------------------
1 | undefined
--------------------------------------------------------------------------------
/public/article/admin_20190611112400_ki0d.md:
--------------------------------------------------------------------------------
1 | undefined
--------------------------------------------------------------------------------
/public/article/admin_20190611205647_r1nl.md:
--------------------------------------------------------------------------------
1 | undefined
--------------------------------------------------------------------------------
/public/article/test_20190523134346_fvh5.md:
--------------------------------------------------------------------------------
1 | undefined
--------------------------------------------------------------------------------
/public/article/test_20190523134446_ag52.md:
--------------------------------------------------------------------------------
1 | undefined
--------------------------------------------------------------------------------
/public/article/test_20190523135838_xb7n.md:
--------------------------------------------------------------------------------
1 | undefined
--------------------------------------------------------------------------------
/public/article/test_20190523135924_z2vg.md:
--------------------------------------------------------------------------------
1 | undefined
--------------------------------------------------------------------------------
/public/article/test_20190523140118_glo6.md:
--------------------------------------------------------------------------------
1 | undefined
--------------------------------------------------------------------------------
/public/article/test_20190819152114_noax.md:
--------------------------------------------------------------------------------
1 | undefined
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | require('babel-core/register'); // 让页面可以使用es6语法
2 | require('./app.js');
--------------------------------------------------------------------------------
/public/article/test_20190523140113_qaok.md:
--------------------------------------------------------------------------------
1 | shh社会化和哈哈哈哈哈哈军绿扩军绿绿军扩绿据了解李经理据了解了解了教练教了解连接了交流交流。1
--------------------------------------------------------------------------------
/config/default.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | module.exports = {
4 | port: process.env.PORT || 1313
5 | }
--------------------------------------------------------------------------------
/config/development.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = {
4 | port: process.env.PORT || 1313
5 | }
--------------------------------------------------------------------------------
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["stage-3"],
3 | "plugins": [
4 | "transform-async-to-generator",
5 | "transform-es2015-modules-commonjs",
6 | "transform-export-extensions"
7 | ]
8 | }
--------------------------------------------------------------------------------
/router/token.js:
--------------------------------------------------------------------------------
1 | import express from 'express'
2 | import Authority from '../controller/Authority'
3 | const router = express.Router()
4 |
5 | router.get('/getToken', Authority.getToken)
6 |
7 | export default router
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules/
3 | /log/file
4 | public/apidoc
5 | public/file
6 | /mysql/index.js
7 | /redis/index.js
8 | npm-debug.log*
9 | yarn-debug.log*
10 | yarn-error.log*
11 |
12 | # Editor directories and files
13 | .idea
14 | .vscode
15 | *.suo
16 | *.ntvs*
17 | *.njsproj
18 | *.sln
19 |
--------------------------------------------------------------------------------
/mqtt/client.js:
--------------------------------------------------------------------------------
1 | import mqtt from 'mqtt'
2 |
3 | const client = mqtt.connect('mqtt://127.0.0.1:1883') // 客户端,用来做转发
4 |
5 | // 连接
6 | client.on('connect', () => {
7 | console.log('连接' + new Date())
8 | })
9 |
10 | client.on('close', () => {
11 | console.log('close重新连接' + new Date())
12 | })
13 |
14 | // 将数据转发到当前mqtt服务
15 | // client.publish('/11123', '111111')
16 |
17 | export default client
18 |
--------------------------------------------------------------------------------
/validate/Notices.js:
--------------------------------------------------------------------------------
1 | import Base from './Base'
2 |
3 | class Notices extends Base{
4 | constructor () {
5 | super()
6 | this.setNotices = this.setNotices.bind(this)
7 | this.getNotices = this.getNotices.bind(this)
8 | }
9 | async setNotices (req, res, next) {
10 | next()
11 | }
12 | async getNotices (req, res, next) {
13 | next()
14 | }
15 | }
16 |
17 | export default new Notices()
18 |
--------------------------------------------------------------------------------
/redis/demo.js:
--------------------------------------------------------------------------------
1 | import redis from 'redis'
2 |
3 | const client = redis.createClient(6379, '127.0.0.1')
4 | client.auth('redis')
5 | client.on('connect', () => {
6 | console.log( 'redis连接成功:' + new Date())
7 | })
8 | client.on('reconnecting', () => {
9 | console.log('redis重新连接:' + new Date())
10 | })
11 | client.on('error', function (err) {
12 | console.log('Error ' + err)
13 | })
14 |
15 | export default client
16 |
--------------------------------------------------------------------------------
/validate/Base.js:
--------------------------------------------------------------------------------
1 | import validate from '../lib/js/validate'
2 |
3 | class Base{
4 | check (arr) {
5 | let success = true, message
6 | for (let item of arr) {
7 | if (!validate(item).success) {
8 | message = validate(item).message
9 | success = false
10 | return {success, message}
11 | }
12 | }
13 | return {success, message}
14 | }
15 | }
16 |
17 | export default Base
18 |
--------------------------------------------------------------------------------
/validate/TagRelation.js:
--------------------------------------------------------------------------------
1 | import Base from './Base'
2 |
3 | class TagRelation extends Base{
4 | constructor () {
5 | super()
6 | this.setBindTag = this.setBindTag.bind(this)
7 | this.getBindTag = this.getBindTag.bind(this)
8 | }
9 | async setBindTag (req, res, next) {
10 | next()
11 | }
12 | async getBindTag (req, res, next) {
13 | next()
14 | }
15 | }
16 |
17 | export default new TagRelation()
18 |
--------------------------------------------------------------------------------
/mqtt/server.js:
--------------------------------------------------------------------------------
1 | import mosca from 'mosca'
2 |
3 | function mqttServer() {
4 | const settings = {
5 | port: 1883,
6 | http: {
7 | port: 1212,
8 | bundle: true,
9 | static: './'
10 | },
11 | backend: {}
12 | };
13 | const server = new mosca.Server(settings)
14 |
15 |
16 | //监听链接
17 | server.on("clientConnected", (client) => {
18 | console.log("client connected",client.id)
19 | })
20 | }
21 |
22 | export default mqttServer
23 |
--------------------------------------------------------------------------------
/router/count.js:
--------------------------------------------------------------------------------
1 | import express from 'express'
2 | import Count from '../controller/Count'
3 |
4 | const router = express.Router()
5 |
6 | /**
7 | * 平台相关数据统计
8 | * @api {POST} /api/Count/platformData 平台相关数据统计
9 | * @apiDescription 平台相关数据统计
10 | * @apiName platformData
11 | * @apiHeader {String} Authorization token
12 | * @apiSampleRequest /api/Count/platformData
13 | * @apiGroup Count
14 | * @apiVersion 0.0.1
15 | */
16 | router.get('/platformDataCount', Count.platformDataCount)
17 |
18 | export default router
19 |
--------------------------------------------------------------------------------
/router/charts.js:
--------------------------------------------------------------------------------
1 | import express from 'express'
2 | import Charts from '../controller/Charts'
3 |
4 | const router = express.Router()
5 |
6 | /**
7 | * 用户登陆分析
8 | * @api {POST} /api/Charts/userLoginAnalyze 用户登陆分析
9 | * @apiDescription 用户登陆分析
10 | * @apiName userLoginAnalyze
11 | * @apiHeader {String} Authorization token
12 | * @apiSampleRequest /api/Charts/userLoginAnalyze
13 | * @apiGroup Charts
14 | * @apiVersion 0.0.1
15 | */
16 | router.get('/userLoginAnalyze', Charts.userLoginAnalyze)
17 |
18 | export default router
19 |
--------------------------------------------------------------------------------
/validate/RoleRelation.js:
--------------------------------------------------------------------------------
1 | import Base from './Base'
2 |
3 | class RoleRelation extends Base{
4 | constructor () {
5 | super()
6 | this.setPermissions = this.setPermissions.bind(this)
7 | this.getPermissions = this.getPermissions.bind(this)
8 | this.setBindUser = this.setBindUser.bind(this)
9 | this.getBindUser = this.getBindUser.bind(this)
10 | }
11 | async setPermissions (req, res, next) {
12 | next()
13 | }
14 | async getPermissions (req, res, next) {
15 | next()
16 | }
17 | async setBindUser (req, res, next) {
18 | next()
19 | }
20 | async getBindUser (req, res, next) {
21 | next()
22 | }
23 | }
24 |
25 | export default new RoleRelation()
26 |
--------------------------------------------------------------------------------
/validate/Draft.js:
--------------------------------------------------------------------------------
1 | import Base from './Base'
2 |
3 | class Draft extends Base{
4 | constructor () {
5 | super()
6 | this.giveUp = this.giveUp.bind(this)
7 | }
8 | async giveUp (req, res, next) {
9 | const params = req.body,
10 | arr = [
11 | {label: 'id', value: params.id, rules: ['notnull', 'number']},
12 | {label: '数据类型', value: params.dataType, rules: ['notnull', 'number']}
13 | ],
14 | result = this.check(arr)
15 | if (!result.success) {
16 | res.json({
17 | code: 20301,
18 | success: false,
19 | message: result.message
20 | })
21 | return
22 | }
23 | next()
24 | }
25 | }
26 |
27 | export default new Draft()
28 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
4 | patreon: # Replace with a single Patreon username
5 | open_collective: # Replace with a single Open Collective username
6 | ko_fi: # Replace with a single Ko-fi username
7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
9 | liberapay: # Replace with a single Liberapay username
10 | issuehunt: # Replace with a single IssueHunt username
11 | otechie: # Replace with a single Otechie username
12 | custom: # Replace with a single custom sponsorship URL
13 |
--------------------------------------------------------------------------------
/router/notices.js:
--------------------------------------------------------------------------------
1 | import express from 'express'
2 | import Notices from '../controller/Notices'
3 | import ValidateNotices from '../validate/Notices'
4 | const router = express.Router()
5 |
6 | /**
7 | * 设置
8 | * @api {POST} /api/Notices/set 设置
9 | * @apiDescription 设置通知
10 | * @apiName set
11 | * @apiHeader {String} Authorization token
12 | * @apiSampleRequest /api/Notices/set
13 | * @apiGroup Notices
14 | * @apiVersion 0.0.1
15 | */
16 | router.post('/set', ValidateNotices.setNotices, Notices.setNotices)
17 | /**
18 | * 获取
19 | * @api {POST} /api/Notices/get 获取
20 | * @apiDescription 获取通知
21 | * @apiName get
22 | * @apiHeader {String} Authorization token
23 | * @apiSampleRequest /api/Notices/get
24 | * @apiGroup Notices
25 | * @apiVersion 0.0.1
26 | */
27 | router.get('/get', ValidateNotices.getNotices, Notices.getNotices)
28 |
29 | export default router
30 |
--------------------------------------------------------------------------------
/router/tagRelation.js:
--------------------------------------------------------------------------------
1 | import express from 'express'
2 | import TagRelation from '../controller/TagRelation'
3 | import ValidateTagRelation from '../validate/TagRelation'
4 | const router = express.Router()
5 |
6 | /**
7 | * 设置绑定标签
8 | * @api {POST} /api/TagRelation/setBindTag 设置绑定标签
9 | * @apiDescription 设置绑定标签
10 | * @apiName setBindTag
11 | * @apiHeader {String} Authorization token
12 | * @apiParam (参数) {Object} Object
13 | * @apiSampleRequest /api/TagRelation/setBindTag
14 | * @apiGroup TagRelation
15 | * @apiVersion 0.0.1
16 | */
17 | router.post('/setBindTag', ValidateTagRelation.setBindTag, TagRelation.setBindTag)
18 | /**
19 | * 获取绑定标签
20 | * @api {put} /api/TagRelation/getBindTag 获取绑定标签
21 | * @apiDescription 获取绑定标签
22 | * @apiName getBindTag
23 | * @apiHeader {String} Authorization token
24 | * @apiSampleRequest /api/TagRelation/getBindTag
25 | * @apiGroup TagRelation
26 | * @apiVersion 0.0.1
27 | */
28 | router.get('/getBindTag', ValidateTagRelation.getBindTag, TagRelation.getBindTag)
29 |
30 | export default router
31 |
--------------------------------------------------------------------------------
/controller/Count.js:
--------------------------------------------------------------------------------
1 | import Base from './Base'
2 | import QuestionModel from '../model/Question'
3 | import ArticleModel from '../model/Article'
4 | import ColumnModel from '../model/Column'
5 | import UserModel from '../model/User'
6 |
7 | class Count extends Base {
8 | constructor () {
9 | super()
10 | }
11 | // 平台相关数据统计
12 | async platformDataCount (req, res, next) {
13 | let params = {flag: 1}, result
14 | try {
15 | result = {
16 | questions: (await QuestionModel.getTotals({get: params}))[0].count,
17 | articles: (await ArticleModel.getTotals({get: {...params, flag: 3}}))[0].count,
18 | columns: (await ColumnModel.getTotals({get: params}))[0].count,
19 | users: (await UserModel.getTotals({get: {...params, create_user: 1}}))[0].count + 1
20 | }
21 | } catch (e) {
22 | this.handleException(req, res, e)
23 | return
24 | }
25 | res.json({
26 | code: 20000,
27 | success: true,
28 | content: result,
29 | message: '操作成功'
30 | })
31 | }
32 | }
33 |
34 | export default new Count()
35 |
--------------------------------------------------------------------------------
/mysql/demo.js:
--------------------------------------------------------------------------------
1 | import mysql from 'mysql'
2 | import NodeLog from '../log/index'
3 | var pool = mysql.createPool({
4 | host : 'host',
5 | user : 'user',
6 | password : 'password',
7 | port: '3306',
8 | database : 'LLLyh_BBS'
9 | });
10 | function query (sql) {
11 | // 写入sql
12 | NodeLog.writeLog(`\n运行sql时间${new Date()}: \n${sql}`, 'sql')
13 | return new Promise((resolve, reject) => {
14 | pool.getConnection((err, conn) => {
15 | if (err) {
16 | // 如果是连接断开,自动重新连接
17 | if (err.code === 'PROTOCOL_CONNECTION_LOST') {
18 | setTimeout(query(), 2000);
19 | reject('断开重连');
20 | } else {
21 | console.error(err.stack || err);
22 | reject(err);
23 | }
24 | } else {
25 | // 得到结果
26 | conn.query(sql, (queryErr, result) => {
27 | if (queryErr) {
28 | reject(queryErr);
29 | } else {
30 | resolve(result);
31 | }
32 | // 释放连接
33 | conn.release();
34 | })
35 | }
36 | })
37 | })
38 | }
39 | export default query
40 |
--------------------------------------------------------------------------------
/model/Area.js:
--------------------------------------------------------------------------------
1 | import query from '../mysql'
2 | import Base from './Base'
3 |
4 | class Area extends Base{
5 | constructor () {
6 | super()
7 | this.update = this.update.bind(this)
8 | this.getList = this.getList.bind(this)
9 | this.getTotals = this.getTotals.bind(this)
10 | this.getAll = this.getAll.bind(this)
11 | }
12 | async update (obj) {
13 | let sql = `UPDATE bbs_area set ${this.joinStr('set', obj.set)} where 1 = 1 ${this.joinStr('get', obj.get)};`
14 | return query(sql)
15 | }
16 | async getList (obj) {
17 | let curPage = obj.get.curPage, pageSize = obj.get.pageSize
18 | let sql = `select * from bbs_area where 1 = 1 ${this.joinStr('get', obj.get)} limit ${(curPage - 1) * pageSize}, ${pageSize};`
19 | return query(sql)
20 | }
21 | async getTotals (obj) {
22 | let sql = `select COUNT(*) as count from bbs_area where 1 = 1 ${this.joinStr('get', obj.get)};`
23 | return query(sql)
24 | }
25 | async getAll (obj) {
26 | let sql = `select * from bbs_area where 1 = 1 ${this.joinStr('get', obj.get)};`
27 | return query(sql)
28 | }
29 | }
30 |
31 | export default new Area()
32 |
--------------------------------------------------------------------------------
/model/Notices.js:
--------------------------------------------------------------------------------
1 | import query from '../mysql'
2 | import Base from './Base'
3 |
4 | class Notices extends Base{
5 | constructor () {
6 | super()
7 | this.setNotices = this.setNotices.bind(this)
8 | this.getNotices = this.getNotices.bind(this)
9 | }
10 | async setNotices (obj) {
11 | const setData = {
12 | status: 0,
13 | update_user: obj.set.create_user,
14 | update_time: new Date()
15 | }
16 | // 将当前所有数据状态置为0
17 | const sql1 = `UPDATE bbs_notices set ${this.joinStr('set', setData)} where 1 = 1 ${this.joinStr('get', obj.get)};`
18 | // 添加新数据
19 | const sql2 = `INSERT INTO bbs_notices set ${this.joinStr('set', obj.set)};`
20 | // 事务开始
21 | await query('begin;')
22 | const result1 = await query(sql1)
23 | const result2 = await query(sql2)
24 | if (result1.affectedRows >= 0 && result2.affectedRows) {
25 | // 事务提交
26 | await query('commit;')
27 | } else {
28 | // 事务回滚
29 | await query('rollback;')
30 | }
31 | return result1.affectedRows >= 0 && result2.affectedRows
32 | }
33 | async getNotices (obj) {
34 | let sql = `select * from bbs_notices where 1 = 1 ${this.joinStr('get', obj.get)};`
35 | return query(sql)
36 | }
37 | }
38 |
39 | export default new Notices()
40 |
--------------------------------------------------------------------------------
/validate/Log.js:
--------------------------------------------------------------------------------
1 | import Base from './Base'
2 |
3 | class Log extends Base{
4 | constructor () {
5 | super()
6 | this.writeLog = this.writeLog.bind(this)
7 | this.getList = this.getList.bind(this)
8 | }
9 | async writeLog (req, res, next) {
10 | const params = req.body,
11 | arr = [
12 | {label: '日志来源', value: params.origin, rules: ['notnull']},
13 | {label: '日志类型', value: params.type, rules: ['notnull']}
14 | ],
15 | result = this.check(arr)
16 | if (!result.success) {
17 | res.json({
18 | code: 20301,
19 | success: false,
20 | message: result.message
21 | })
22 | return
23 | }
24 | next()
25 | }
26 | async getList (req, res, next) {
27 | const data = req.query,
28 | arr = [
29 | {label: 'curPage', value: data.curPage, rules: ['notnull', 'number']},
30 | {label: 'pageSize', value: data.curPage, rules: ['notnull', 'number']}
31 | ],
32 | result = this.check(arr)
33 | if (!result.success) {
34 | res.json({
35 | code: 20301,
36 | success: false,
37 | message: result.message
38 | })
39 | return
40 | }
41 | next()
42 | }
43 | }
44 |
45 | export default new Log()
46 |
--------------------------------------------------------------------------------
/router/log.js:
--------------------------------------------------------------------------------
1 | import express from 'express'
2 | import Log from '../controller/Log'
3 | import ValidateLog from '../validate/Log'
4 | const router = express.Router()
5 |
6 | /**
7 | * 写日志
8 | * @api {POST} /api/log/registered 写日志
9 | * @apiDescription 写日志
10 | * @apiName registered
11 | * @apiHeader {String} Authorization token
12 | * @apiParam (参数) {Number} origin 日志来源:0: 手机 1: 论坛 2: 管理平台
13 | * @apiParam (参数) {Number} type 日志类型: 1.用户登录 2. 用户登出 3. 模块访问 4.功能操作
14 | * @apiParam (参数) {String} title 日志标题
15 | * @apiParam (参数) {String} desc 日志描述
16 | * @apiParam (参数) {String} ip ip
17 | * @apiSampleRequest /api/log/registered
18 | * @apiGroup Log
19 | * @apiVersion 0.0.1
20 | */
21 | router.post('/writeLog', ValidateLog.writeLog, Log.writeLog)
22 | /**
23 | * 获取日志列表
24 | * @api {get} /api/log/getList 获取日志列表
25 | * @apiDescription 获取日志列表
26 | * @apiName getList
27 | * @apiHeader {String} Authorization token
28 | * @apiParam (path参数) {Number} curPage
29 | * @apiParam (path参数) {Number} pageSize
30 | * @apiParam (path参数) {Number} origin 日志来源:0: 手机 1: 论坛 2: 管理平台
31 | * @apiParam (path参数) {Number} type 日志类型: 1.用户登录 2. 用户登出 3. 模块访问 4.功能操作
32 | * @apiSampleRequest /api/log/getList
33 | * @apiGroup Log
34 | * @apiVersion 0.0.1
35 | */
36 | router.get('/getList', ValidateLog.getList, Log.getList)
37 |
38 | export default router
--------------------------------------------------------------------------------
/router/area.js:
--------------------------------------------------------------------------------
1 | import express from 'express'
2 | import Area from '../controller/Area'
3 | import ValidateArea from '../validate/Area'
4 | const router = express.Router()
5 |
6 | /**
7 | * 编辑
8 | * @api {POST} /api/Area/update 编辑
9 | * @apiDescription 编辑
10 | * @apiName update
11 | * @apiHeader {String} Authorization token
12 | * @apiParam (参数) {Number} status
13 | * @apiSampleRequest /api/Area/update
14 | * @apiGroup Area
15 | * @apiVersion 0.0.1
16 | */
17 | router.put('/update', ValidateArea.update, Area.update)
18 | /**
19 | * 获取区域列表
20 | * @api {get} /api/Area/getList 获取日志列表
21 | * @apiDescription 获取日志列表
22 | * @apiName getList
23 | * @apiHeader {String} Authorization token
24 | * @apiParam (path参数) {Number} curPage
25 | * @apiParam (path参数) {Number} pageSize
26 | * @apiParam (path参数) {Number} pid
27 | * @apiSampleRequest /api/Area/getList
28 | * @apiGroup Area
29 | * @apiVersion 0.0.1
30 | */
31 | router.get('/getList', ValidateArea.getList, Area.getList)
32 | /**
33 | * 获取所有区域
34 | * @api {get} /api/Area/getAll/:pid 获取所有区域
35 | * @apiDescription 获取所有区域
36 | * @apiName getAll
37 | * @apiHeader {String} Authorization token
38 | * @apiParam {Number} pid
39 | * @apiSampleRequest /api/Area/getAll
40 | * @apiGroup Area
41 | * @apiVersion 0.0.1
42 | */
43 | router.get('/getAll/:pid', ValidateArea.getAll, Area.getAll)
44 |
45 | export default router
--------------------------------------------------------------------------------
/model/Log.js:
--------------------------------------------------------------------------------
1 | import query from '../mysql'
2 | import Base from './Base'
3 |
4 | class Log extends Base{
5 | constructor () {
6 | super()
7 | this.writeLog = this.writeLog.bind(this)
8 | this.getList = this.getList.bind(this)
9 | this.getTotals = this.getTotals.bind(this)
10 | this.getLoginLog = this.getLoginLog.bind(this)
11 | }
12 | async writeLog (obj) {
13 | let sql = `INSERT INTO bbs_log set ${this.joinStr('set', obj.set)}`
14 | return query(sql)
15 | }
16 | async getList (obj) {
17 | let curPage = obj.get.curPage, pageSize = obj.get.pageSize
18 | let sql = `select a.*, b.name as create_user_name from bbs_log as a
19 | LEFT JOIN bbs_user as b ON a.create_user = b.id
20 | where 1 = 1 ${this.joinStr('get', obj.get)} ${this.joinStr('ORDER BY', {DESC: ['create_time', 'id']})} limit ${(curPage - 1) * pageSize}, ${pageSize};`
21 | // 处理表连接字段
22 | sql = sql.replace(/`type`/, 'a.type')
23 | return query(sql)
24 | }
25 | async getTotals (obj) {
26 | let sql = `select COUNT(*) as count from bbs_log where 1 = 1 ${this.joinStr('get', obj.get)};`
27 | return query(sql)
28 | }
29 | async getLoginLog (obj) {
30 | let sql = `select create_time as time from bbs_log where 1 = 1 ${this.joinStr('get', obj.get)};`
31 | return query(sql)
32 | }
33 | }
34 |
35 | export default new Log()
36 |
--------------------------------------------------------------------------------
/app.js:
--------------------------------------------------------------------------------
1 | import express from 'express'
2 | import path from 'path'
3 | import router from './router'
4 | import bodyParser from 'body-parser'
5 | import config from 'config-lite' // 配置中间件
6 | import history from 'connect-history-api-fallback'
7 | import chalk from 'chalk'
8 | import mqttServer from './mqtt/server' // mqtt服务端
9 | import redis from './redis'
10 |
11 | mqttServer()
12 | const app = express()
13 | app.disable('etag') // 禁止304缓存
14 | app.all('*', (req, res, next) => {
15 | res.header("Access-Control-Allow-Origin", req.headers.origin || req.headers.referer || '*')
16 | res.header("Access-Control-Allow-Headers", "Content-Type, Authorization, X-Requested-With")
17 | res.header("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS")
18 | res.header("Access-Control-Allow-Credentials", true) // 可以带cookies
19 | res.header("Access-Control-Max-Age", -1) // 禁止缓存
20 | res.header("X-Powered-By", 'Express')
21 | if (req.method === 'OPTIONS') {
22 | res.sendStatus(200)
23 | } else {
24 | next()
25 | }
26 | })
27 |
28 | // const server = http.createServer(app)
29 | // const io = require('socket.io')(server)
30 | // new SocketServer(io)
31 |
32 | // 解析body参数
33 | app.use(bodyParser.json())
34 | app.use(bodyParser.urlencoded({extended: false}))
35 | router(app)
36 | app.use(history())
37 | app.use(express.static(path.join(__dirname, 'public')))
38 | app.listen(config.port || '1313', () => {
39 | console.log(
40 | chalk.green(`成功监听端口${config.port || 1313}`)
41 | )
42 | })
43 |
--------------------------------------------------------------------------------
/router/draft.js:
--------------------------------------------------------------------------------
1 | import express from 'express'
2 | import Draft from '../controller/Draft'
3 | import ValidateDraft from '../validate/Draft'
4 | const router = express.Router()
5 |
6 | /**
7 | * 获取草稿数量
8 | * @api {get} /api/Draft/getTotals 获取草稿数量
9 | * @apiDescription 获取草稿数量
10 | * @apiName getTotals
11 | * @apiHeader {String} Authorization token
12 | * @apiSampleRequest /api/Draft/getTotals
13 | * @apiGroup Draft
14 | * @apiVersion 0.0.1
15 | */
16 | router.get('/getTotals', Draft.getTotals)
17 | /**
18 | * 获取草稿
19 | * @api {get} /api/Draft/getAll 获取草稿
20 | * @apiDescription 获取草稿
21 | * @apiName getAll
22 | * @apiHeader {String} Authorization token
23 | * @apiSampleRequest /api/Draft/getAll
24 | * @apiGroup Draft
25 | * @apiVersion 0.0.1
26 | */
27 | router.get('/getAll', Draft.getAll)
28 | /**
29 | * 舍弃草稿
30 | * @api {delete} /api/Draft/giveUp 舍弃草稿
31 | * @apiDescription 舍弃草稿
32 | * @apiName giveUp
33 | * @apiHeader {String} Authorization token
34 | * @apiSampleRequest /api/Draft/giveUp
35 | * @apiGroup Draft
36 | * @apiVersion 0.0.1
37 | */
38 | router.delete('/giveUp', ValidateDraft.giveUp, Draft.giveUp)
39 | /**
40 | * 舍弃全部草稿
41 | * @api {delete} /api/Draft/giveUpAll 舍弃全部草稿
42 | * @apiDescription 舍弃全部草稿
43 | * @apiName giveUpAll
44 | * @apiHeader {String} Authorization token
45 | * @apiSampleRequest /api/Draft/giveUpAll
46 | * @apiGroup Draft
47 | * @apiVersion 0.0.1
48 | */
49 | router.delete('/giveUpAll', Draft.giveUpAll)
50 |
51 | export default router
52 |
--------------------------------------------------------------------------------
/router/articleComments.js:
--------------------------------------------------------------------------------
1 | import express from 'express'
2 | import ArticleComments from '../controller/ArticleComments'
3 | import ValidateArticleComments from '../validate/ArticleComments'
4 | const router = express.Router()
5 |
6 | /**
7 | * 创建
8 | * @api {POST} /api/ArticleComments/create 创建
9 | * @apiDescription 创建评论
10 | * @apiName create
11 | * @apiHeader {String} Authorization token
12 | * @apiParam (参数) {Number} article_id 文章ID
13 | * @apiParam (参数) {Number} pid 父节点,默认为0
14 | * @apiParam (参数) {String} content 内容
15 | * @apiSampleRequest /api/ArticleComments/create
16 | * @apiGroup Article
17 | * @apiVersion 0.0.1
18 | */
19 | router.post('/create', ValidateArticleComments.create, ArticleComments.create)
20 |
21 | /**
22 | * 删除
23 | * @api {delete} /api/ArticleComments/delete/:id 删除
24 | * @apiDescription 删除
25 | * @apiName delete
26 | * @apiHeader {String} Authorization token
27 | * @apiParam {Number} id
28 | * @apiSampleRequest /api/ArticleComments/delete
29 | * @apiGroup Article
30 | * @apiVersion 0.0.1
31 | */
32 | router.delete('/delete/:id', ValidateArticleComments.delete, ArticleComments.delete)
33 |
34 | /**
35 | * 获取所有评论
36 | * @api {get} /api/ArticleComments/getAll 获取所有评论
37 | * @apiDescription 获取所有评论
38 | * @apiName getAll
39 | * @apiParam {Number} type
40 | * @apiHeader {String} Authorization token
41 | * @apiSampleRequest /api/ArticleComments/getAll
42 | * @apiGroup Article
43 | * @apiVersion 0.0.1
44 | */
45 | router.get('/getAll', ValidateArticleComments.getAll, ArticleComments.getAll)
46 |
47 | export default router
48 |
--------------------------------------------------------------------------------
/controller/TagRelation.js:
--------------------------------------------------------------------------------
1 | import Base from './Base'
2 | import TagRelationModel from '../model/TagRelation'
3 |
4 |
5 | class TagRelation extends Base {
6 | constructor () {
7 | super()
8 | this.setBindTag = this.setBindTag.bind(this)
9 | this.getBindTag = this.getBindTag.bind(this)
10 | }
11 | // 设置标签类型绑定的标签
12 | async setBindTag (req, res, next) {
13 | let userInfo = await this.getUserInfo(req), result,
14 | data = req.body
15 | try {
16 | result = await TagRelationModel.setBindTag({
17 | get: {tag_type_id: data.tagTypeId},
18 | data: {
19 | tags: data.tags
20 | }
21 | })
22 | } catch (e) {
23 | this.handleException(req, res, e)
24 | return
25 | }
26 | if (result) {
27 | res.json({
28 | code: 20000,
29 | success: true,
30 | content: {},
31 | message: '操作成功'
32 | })
33 | } else {
34 | res.json({
35 | code: 20001,
36 | success: false,
37 | content: {},
38 | message: '操作失败'
39 | })
40 | }
41 | }
42 | // 获取标签类型绑定的标签
43 | async getBindTag (req, res, next) {
44 | let tag_type_id = req.query.tagTypeId, result
45 | try {
46 | result = await TagRelationModel.getBindTag({get: {tag_type_id}})
47 | } catch (e) {
48 | this.handleException(req, res, e)
49 | return
50 | }
51 | res.json({
52 | code: 20000,
53 | success: true,
54 | content: result,
55 | message: '操作成功'
56 | })
57 | }
58 | }
59 |
60 | export default new TagRelation()
61 |
--------------------------------------------------------------------------------
/model/ArticleComments.js:
--------------------------------------------------------------------------------
1 | import query from '../mysql'
2 | import Base from './Base'
3 |
4 | class ArticleComments extends Base{
5 | constructor () {
6 | super()
7 | this.create = this.create.bind(this)
8 | this.update = this.update.bind(this)
9 | this.delete = this.delete.bind(this)
10 | this.getTotals = this.getTotals.bind(this)
11 | this.getAll = this.getAll.bind(this)
12 | }
13 | async create (obj) {
14 | let sql = `INSERT INTO bbs_article_comments set ${this.joinStr('set', obj.set)};`
15 | return query(sql)
16 | }
17 | async update (obj) {
18 | let sql = `UPDATE bbs_article_comments set ${this.joinStr('set', obj.set)} where 1 = 1 ${this.joinStr('get', obj.get)};`
19 | return query(sql)
20 | }
21 | async delete (obj) {
22 | let sql = `DELETE from bbs_article_comments where 1 = 1 ${this.joinStr('get', obj.get)};`
23 | return query(sql)
24 | }
25 | async getTotals (obj) {
26 | let sql = `select COUNT(*) as count from bbs_article_comments where 1 = 1 ${this.joinStr('get', obj.get)}`
27 | return query(sql)
28 | }
29 | async getAll (obj) {
30 | let sql = `select a.*, b.name as replier_name, b.avatar, c.name as by_replier_name from bbs_article_comments as a
31 | left join bbs_user as b on a.create_user = b.id
32 | left join bbs_user as c on a.p_user_id = c.id
33 | where 1 = 1 ${this.joinStr('get', obj.get)} ORDER BY create_time DESC`
34 | // 处理表连接字段
35 | // sql = sql.replace(/`id`/, 'a.id')
36 | sql = sql.replace(/`flag`/, 'a.flag')
37 | return query(sql)
38 | }
39 | }
40 |
41 | export default new ArticleComments()
42 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## start
2 | 1. 将mysql目录下的demo.js改成index.js, 并设置好相关的数据库连接信息
3 | 2. 在mysql中导入LLLyh_BBS.sql
4 | 33. 将redis目录下的demo.js改成index.js, 并设置好相关的redis连接信息
5 |
6 | ## Build Setup
7 | ``` bash
8 | # 安装依赖
9 | npm install
10 |
11 | # 运行项目
12 | npm run dev
13 |
14 | # 运行node服务
15 | npm run dev
16 |
17 | # 使用热更新打开node服务,方便边开发边调试 (调试时用Debug)
18 | npm run hot
19 |
20 | # 更新接口后使用此命令重新生成api相关文档
21 | npm run apidoc
22 |
23 | # 使用forever 实现在服务器上关闭控制台时node服务正常访问
24 | npm run start # 启用node服务
25 | npm run stop # 关闭node服务
26 |
27 | # 项目基本结构
28 | ├── config // 配置相关
29 | ├── controller // 控制器
30 | ├── model // model
31 | ├── mysql // mysql配置文件
32 | ├── node_modules // 项目依赖
33 | ├── public // 静态资源库
34 | ├── routes // 路由
35 | ├── .babelrc // babel-loader 配置
36 | ├── eslintrc.js // eslint 配置项
37 | ├── .gitignore // git 忽略项
38 | ├── app.js // 入口 加载配置 初始化
39 | ├── index.js // 启动文件
40 | └── package.json // package.json
41 | ```
42 |
43 | # 返回的数据格式
44 | ```
45 | {
46 | success: true, // 响应状态
47 | code: 20000, // 状态码
48 | content: {}, // 数据
49 | message: '操作成功' // 提示
50 | }
51 | ```
52 | # 返回码和相关提示定义
53 | 1 为账号错误
54 | 2 为认证错误
55 | 3 为参数错误
56 | 4 为数据不存在
57 | 5 为系统错误
58 | 0 为成功
59 |
60 | |状态码|定义|
61 | |:----|:---|
62 | |20101|当前被登出|
63 | |20201|身份认证失败|
64 | |20202|无操作权限|
65 | |20203|用户未绑定角色|
66 | |20301|参数错误|
67 | |20401|数据不存在|
68 | |20501|服务器内部错误|
69 | |20000|操作成功|
70 | |20001|操作失败|
71 |
--------------------------------------------------------------------------------
/controller/Notices.js:
--------------------------------------------------------------------------------
1 | import Base from './Base'
2 | import NoticesModel from '../model/Notices'
3 |
4 | class Notices extends Base {
5 | constructor () {
6 | super()
7 | this.setNotices = this.setNotices.bind(this)
8 | this.getNotices = this.getNotices.bind(this)
9 | }
10 | // 设置通知
11 | async setNotices (req, res, next) {
12 | let data = JSON.parse(JSON.stringify(req.body)),
13 | result,
14 | userInfo = await this.getUserInfo(req)
15 | // 参数处理
16 | data.create_user = userInfo.id
17 | data.create_time = new Date()
18 | delete data.id
19 | try {
20 | result = await NoticesModel.setNotices({set: data, get: {status: 1}})
21 | } catch (e) {
22 | this.handleException(req, res, e)
23 | return
24 | }
25 | if (result) {
26 | res.json({
27 | code: 20000,
28 | success: true,
29 | message: '操作成功'
30 | })
31 | } else {
32 | res.json({
33 | code: 20001,
34 | success: false,
35 | message: '操作失败'
36 | })
37 | }
38 | }
39 | // 获取通知
40 | async getNotices (req, res, next) {
41 | const search = await NoticesModel.getNotices({get: {status: 1, flag: 1}})
42 | if (search.length === 0) {
43 | res.json({
44 | code: 20401,
45 | success: false,
46 | content: search,
47 | message: '查询信息不存在'
48 | })
49 | } else {
50 | res.json({
51 | code: 20000,
52 | success: true,
53 | content: search,
54 | message: '操作成功'
55 | })
56 | }
57 | }
58 | }
59 |
60 | export default new Notices()
61 |
--------------------------------------------------------------------------------
/model/Tag.js:
--------------------------------------------------------------------------------
1 | import query from '../mysql'
2 | import Base from './Base'
3 |
4 | class Tag extends Base{
5 | constructor () {
6 | super()
7 | this.create = this.create.bind(this)
8 | this.update = this.update.bind(this)
9 | this.delete = this.delete.bind(this)
10 | this.getRow = this.getRow.bind(this)
11 | this.getList = this.getList.bind(this)
12 | this.getTotals = this.getTotals.bind(this)
13 | this.getAll = this.getAll.bind(this)
14 | }
15 | async create (obj) {
16 | let sql = `INSERT INTO bbs_tag set ${this.joinStr('set', obj.set)};`
17 | return query(sql)
18 | }
19 | async update (obj) {
20 | let sql = `UPDATE bbs_tag set ${this.joinStr('set', obj.set)} where 1 = 1 ${this.joinStr('get', obj.get)};`
21 | return query(sql)
22 | }
23 | async delete (obj) {
24 | let sql = `DELETE from bbs_tag where 1 = 1 ${this.joinStr('get', obj.get)};`
25 | return query(sql)
26 | }
27 | async getRow (obj) {
28 | let sql = `select * from bbs_tag where 1 = 1 ${this.joinStr('get', obj.get)};`
29 | return query(sql)
30 | }
31 | async getList (obj) {
32 | let curPage = obj.get.curPage, pageSize = obj.get.pageSize
33 | let sql = `select * from bbs_tag
34 | where 1 = 1 ${this.joinStr('get', obj.get)} limit ${(curPage - 1) * pageSize}, ${pageSize};`
35 | return query(sql)
36 | }
37 | async getTotals (obj) {
38 | let sql = `select COUNT(*) as count from bbs_tag where 1 = 1 ${this.joinStr('get', obj.get)};`
39 | return query(sql)
40 | }
41 | async getAll (obj) {
42 | let sql = `select * from bbs_tag where 1 = 1 ${this.joinStr('get', obj.get)} ORDER BY sort;`
43 | return query(sql)
44 | }
45 | }
46 |
47 | export default new Tag()
48 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "node_BBS",
3 | "version": "0.0.1",
4 | "description": "BBSapi",
5 | "main": "index.js",
6 | "scripts": {
7 | "dev": "cross-env NODE_ENV=development PORT=1313 node index.js",
8 | "start": "forever start index.js",
9 | "stop": "forever stop index.js",
10 | "hot": "supervisor index.js",
11 | "apidoc": "apidoc -i router/ -o public/apidoc",
12 | "test": "echo \"Error: no test specified\" && exit 1"
13 | },
14 | "author": "ly",
15 | "license": "ISC",
16 | "dependencies": {
17 | "babel": "6.23.0",
18 | "babel-core": "6.24.0",
19 | "babel-preset-es2015": "6.24.0",
20 | "babel-preset-stage-3": "6.22.0",
21 | "babel-register": "6.24.0",
22 | "body-parser": "1.18.3",
23 | "chalk": "2.4.1",
24 | "config-lite": "2.1.0",
25 | "connect-history-api-fallback": "1.5.0",
26 | "cookie-parser": "1.4.3",
27 | "cross-env": "5.2.0",
28 | "crypto": "1.0.1",
29 | "express": "4.16.4",
30 | "express-winston": "3.0.1",
31 | "jsonwebtoken": "8.4.0",
32 | "log4js": "4.3.1",
33 | "mysql": "2.16.0",
34 | "supervisor": "0.12.0",
35 | "apidoc": "0.17.7",
36 | "request": "2.88.0",
37 | "connect-multiparty": "2.2.0",
38 | "mqtt": "2.18.8",
39 | "mosca": "2.8.3",
40 | "node-schedule": "1.3.2",
41 | "redis": "2.8.0"
42 | },
43 | "devDependencies": {
44 | "babel-plugin-transform-async-to-generator": "6.24.1",
45 | "babel-plugin-transform-es2015-classes": "6.24.1",
46 | "babel-plugin-transform-es2015-modules-commonjs": "6.24.1",
47 | "babel-plugin-transform-export-extensions": "6.22.0"
48 | },
49 | "apidoc": {
50 | "title": "BBS接口文档",
51 | "url": "http://localhost:1313"
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/model/Topic.js:
--------------------------------------------------------------------------------
1 | import query from '../mysql'
2 | import Base from './Base'
3 |
4 | class Topic extends Base{
5 | constructor () {
6 | super()
7 | this.create = this.create.bind(this)
8 | this.update = this.update.bind(this)
9 | this.delete = this.delete.bind(this)
10 | this.getRow = this.getRow.bind(this)
11 | this.getList = this.getList.bind(this)
12 | this.getTotals = this.getTotals.bind(this)
13 | this.getAll = this.getAll.bind(this)
14 | }
15 | async create (obj) {
16 | let sql = `INSERT INTO bbs_topic set ${this.joinStr('set', obj.set)};`
17 | return query(sql)
18 | }
19 | async update (obj) {
20 | let sql = `UPDATE bbs_topic set ${this.joinStr('set', obj.set)} where 1 = 1 ${this.joinStr('get', obj.get)};`
21 | return query(sql)
22 | }
23 | async delete (obj) {
24 | let sql = `DELETE from bbs_topic where 1 = 1 ${this.joinStr('get', obj.get)};`
25 | return query(sql)
26 | }
27 | async getRow (obj) {
28 | let sql = `select * from bbs_topic where 1 = 1 ${this.joinStr('get', obj.get)};`
29 | return query(sql)
30 | }
31 | async getList (obj) {
32 | let curPage = obj.get.curPage, pageSize = obj.get.pageSize
33 | let sql = `select * from bbs_topic
34 | where 1 = 1 ${this.joinStr('get', obj.get)} limit ${(curPage - 1) * pageSize}, ${pageSize};`
35 | return query(sql)
36 | }
37 | async getTotals (obj) {
38 | let sql = `select COUNT(*) as count from bbs_topic where 1 = 1 ${this.joinStr('get', obj.get)};`
39 | return query(sql)
40 | }
41 | async getAll (obj) {
42 | let sql = `select * from bbs_topic where 1 = 1 ${this.joinStr('get', obj.get)} ORDER BY sort;`
43 | return query(sql)
44 | }
45 | }
46 |
47 | export default new Topic()
48 |
--------------------------------------------------------------------------------
/model/Folder.js:
--------------------------------------------------------------------------------
1 | import query from '../mysql'
2 | import Base from './Base'
3 |
4 | class Folder extends Base{
5 | constructor () {
6 | super()
7 | this.create = this.create.bind(this)
8 | this.update = this.update.bind(this)
9 | this.delete = this.delete.bind(this)
10 | this.getRow = this.getRow.bind(this)
11 | this.getList = this.getList.bind(this)
12 | this.getTotals = this.getTotals.bind(this)
13 | this.getAll = this.getAll.bind(this)
14 | }
15 | async create (obj) {
16 | let sql = `INSERT INTO bbs_folder set ${this.joinStr('set', obj.set)};`
17 | return query(sql)
18 | }
19 | async update (obj) {
20 | let sql = `UPDATE bbs_folder set ${this.joinStr('set', obj.set)} where 1 = 1 ${this.joinStr('get', obj.get)};`
21 | return query(sql)
22 | }
23 | async delete (obj) {
24 | let sql = `DELETE from bbs_folder where 1 = 1 ${this.joinStr('get', obj.get)};`
25 | return query(sql)
26 | }
27 | async getRow (obj) {
28 | let sql = `select * from bbs_folder where 1 = 1 ${this.joinStr('get', obj.get)};`
29 | return query(sql)
30 | }
31 | async getList (obj) {
32 | let curPage = obj.get.curPage, pageSize = obj.get.pageSize
33 | let sql = `select * from bbs_folder
34 | where 1 = 1 ${this.joinStr('get', obj.get)} limit ${(curPage - 1) * pageSize}, ${pageSize};`
35 | return query(sql)
36 | }
37 | async getTotals (obj) {
38 | let sql = `select COUNT(*) as count from bbs_folder where 1 = 1 ${this.joinStr('get', obj.get)};`
39 | return query(sql)
40 | }
41 | async getAll (obj) {
42 | let sql = `select * from bbs_folder where 1 = 1 ${this.joinStr('get', obj.get)} ORDER BY sort;`
43 | return query(sql)
44 | }
45 | }
46 |
47 | export default new Folder()
48 |
--------------------------------------------------------------------------------
/model/Carousel.js:
--------------------------------------------------------------------------------
1 | import query from '../mysql'
2 | import Base from './Base'
3 |
4 | class Carousel extends Base{
5 | constructor () {
6 | super()
7 | this.create = this.create.bind(this)
8 | this.update = this.update.bind(this)
9 | this.delete = this.delete.bind(this)
10 | this.getRow = this.getRow.bind(this)
11 | this.getList = this.getList.bind(this)
12 | this.getTotals = this.getTotals.bind(this)
13 | this.getAll = this.getAll.bind(this)
14 | }
15 | async create (obj) {
16 | let sql = `INSERT INTO bbs_carousel set ${this.joinStr('set', obj.set)};`
17 | return query(sql)
18 | }
19 | async update (obj) {
20 | let sql = `UPDATE bbs_carousel set ${this.joinStr('set', obj.set)} where 1 = 1 ${this.joinStr('get', obj.get)};`
21 | return query(sql)
22 | }
23 | async delete (obj) {
24 | let sql = `DELETE from bbs_carousel where 1 = 1 ${this.joinStr('get', obj.get)};`
25 | return query(sql)
26 | }
27 | async getRow (obj) {
28 | let sql = `select * from bbs_carousel where 1 = 1 ${this.joinStr('get', obj.get)};`
29 | return query(sql)
30 | }
31 | async getList (obj) {
32 | let curPage = obj.get.curPage, pageSize = obj.get.pageSize
33 | let sql = `select * from bbs_carousel
34 | where 1 = 1 ${this.joinStr('get', obj.get)} limit ${(curPage - 1) * pageSize}, ${pageSize};`
35 | return query(sql)
36 | }
37 | async getTotals (obj) {
38 | let sql = `select COUNT(*) as count from bbs_carousel where 1 = 1 ${this.joinStr('get', obj.get)};`
39 | return query(sql)
40 | }
41 | async getAll (obj) {
42 | let sql = `select * from bbs_carousel where 1 = 1 ${this.joinStr('get', obj.get)} ORDER BY sort;`
43 | return query(sql)
44 | }
45 | }
46 |
47 | export default new Carousel()
48 |
--------------------------------------------------------------------------------
/model/TagType.js:
--------------------------------------------------------------------------------
1 | import query from '../mysql'
2 | import Base from './Base'
3 |
4 | class TagType extends Base{
5 | constructor () {
6 | super()
7 | this.create = this.create.bind(this)
8 | this.update = this.update.bind(this)
9 | this.delete = this.delete.bind(this)
10 | this.getRow = this.getRow.bind(this)
11 | this.getList = this.getList.bind(this)
12 | this.getTotals = this.getTotals.bind(this)
13 | this.getAll = this.getAll.bind(this)
14 | }
15 | async create (obj) {
16 | let sql = `INSERT INTO bbs_tag_type set ${this.joinStr('set', obj.set)};`
17 | return query(sql)
18 | }
19 | async update (obj) {
20 | let sql = `UPDATE bbs_tag_type set ${this.joinStr('set', obj.set)} where 1 = 1 ${this.joinStr('get', obj.get)};`
21 | return query(sql)
22 | }
23 | async delete (obj) {
24 | let sql = `DELETE from bbs_tag_type where 1 = 1 ${this.joinStr('get', obj.get)};`
25 | return query(sql)
26 | }
27 | async getRow (obj) {
28 | let sql = `select * from bbs_tag_type where 1 = 1 ${this.joinStr('get', obj.get)};`
29 | return query(sql)
30 | }
31 | async getList (obj) {
32 | let curPage = obj.get.curPage, pageSize = obj.get.pageSize
33 | let sql = `select * from bbs_tag_type
34 | where 1 = 1 ${this.joinStr('get', obj.get)} limit ${(curPage - 1) * pageSize}, ${pageSize};`
35 | return query(sql)
36 | }
37 | async getTotals (obj) {
38 | let sql = `select COUNT(*) as count from bbs_tag_type where 1 = 1 ${this.joinStr('get', obj.get)};`
39 | return query(sql)
40 | }
41 | async getAll (obj) {
42 | let sql = `select * from bbs_tag_type where 1 = 1 ${this.joinStr('get', obj.get)} ORDER BY sort;`
43 | return query(sql)
44 | }
45 | }
46 |
47 | export default new TagType()
48 |
--------------------------------------------------------------------------------
/validate/Area.js:
--------------------------------------------------------------------------------
1 | import Base from './Base'
2 |
3 | class Area extends Base{
4 | constructor () {
5 | super()
6 | this.update = this.update.bind(this)
7 | this.getList = this.getList.bind(this)
8 | this.getAll = this.getAll.bind(this)
9 | }
10 | async update (req, res, next) {
11 | const params = req.body,
12 | arr = [
13 | {label: '状态', value: params.status, rules: ['notnull', 'number']}
14 | ],
15 | result = this.check(arr)
16 | if (!result.success) {
17 | res.json({
18 | code: 20301,
19 | success: false,
20 | message: result.message
21 | })
22 | return
23 | }
24 | next()
25 | }
26 | async getList (req, res, next) {
27 | const data = req.query,
28 | arr = [
29 | {label: 'curPage', value: data.curPage, rules: ['notnull', 'number']},
30 | {label: 'pageSize', value: data.curPage, rules: ['notnull', 'number']},
31 | {label: '父级ID', value: data.pid, rules: ['notnull', 'number']}
32 | ],
33 | result = this.check(arr)
34 | if (!result.success) {
35 | res.json({
36 | code: 20301,
37 | success: false,
38 | message: result.message
39 | })
40 | return
41 | }
42 | next()
43 | }
44 | async getAll (req, res, next) {
45 | const data = req.params,
46 | arr = [
47 | {label: 'pid', value: data.pid, rules: ['notnull', 'number']}
48 | ],
49 | result = this.check(arr)
50 | if (!result.success) {
51 | res.json({
52 | code: 20301,
53 | success: false,
54 | message: result.message
55 | })
56 | return
57 | }
58 | next()
59 | }
60 | }
61 |
62 | export default new Area()
63 |
--------------------------------------------------------------------------------
/validate/ArticleComments.js:
--------------------------------------------------------------------------------
1 | import Base from './Base'
2 |
3 | class ArticleComments extends Base{
4 | constructor () {
5 | super()
6 | this.create = this.create.bind(this)
7 | this.delete = this.delete.bind(this)
8 | this.getAll = this.getAll.bind(this)
9 | }
10 | async create (req, res, next) {
11 | const params = req.body,
12 | arr = [
13 | {label: '文章ID', value: params.article_id, rules: ['notnull']},
14 | {label: 'pid', value: params.pid, rules: ['notnull']},
15 | {label: 'p_user_id', value: params.p_user_id, rules: ['notnull']},
16 | {label: '内容', value: params.content, rules: ['notnull']}
17 | ],
18 | result = this.check(arr)
19 | if (!result.success) {
20 | res.json({
21 | code: 20301,
22 | success: false,
23 | message: result.message
24 | })
25 | return
26 | }
27 | next()
28 | }
29 | async delete (req, res, next) {
30 | const ID = req.params.id,
31 | arr = [
32 | {label: 'ID', value: ID, rules: ['notnull']}
33 | ],
34 | result = this.check(arr)
35 | if (!result.success) {
36 | res.json({
37 | code: 20301,
38 | success: false,
39 | message: result.message
40 | })
41 | return
42 | }
43 | next()
44 | }
45 | async getAll (req, res, next) {
46 | const query = req.query,
47 | arr = [
48 | {label: '文章ID', value: query.article_id, rules: ['notnull']},
49 | // {label: 'pid', value: query.pid, rules: ['notnull']}
50 | ],
51 | result = this.check(arr)
52 | if (!result.success) {
53 | res.json({
54 | code: 20301,
55 | success: false,
56 | message: result.message
57 | })
58 | return
59 | }
60 | next()
61 | }
62 | }
63 |
64 | export default new ArticleComments()
65 |
--------------------------------------------------------------------------------
/router/roleRelation.js:
--------------------------------------------------------------------------------
1 | import express from 'express'
2 | import RoleRelation from '../controller/RoleRelation'
3 | import ValidateRoleRelation from '../validate/RoleRelation'
4 | const router = express.Router()
5 |
6 | /**
7 | * 设置角色权限
8 | * @api {POST} /api/RoleRelation/setPermissions 设置角色权限
9 | * @apiDescription 设置角色权限
10 | * @apiName setPermissions
11 | * @apiHeader {String} Authorization token
12 | * @apiParam (参数) {Object} Object
13 | * @apiSampleRequest /api/RoleRelation/setPermissions
14 | * @apiGroup RoleRelation
15 | * @apiVersion 0.0.1
16 | */
17 | router.post('/setPermissions', ValidateRoleRelation.setPermissions, RoleRelation.setPermissions)
18 | /**
19 | * 获取角色权限
20 | * @api {put} /api/RoleRelation/getPermissions 获取角色权限
21 | * @apiDescription 获取角色权限
22 | * @apiName getPermissions
23 | * @apiHeader {String} Authorization token
24 | * @apiSampleRequest /api/RoleRelation/getPermissions
25 | * @apiGroup RoleRelation
26 | * @apiVersion 0.0.1
27 | */
28 | router.get('/getPermissions', ValidateRoleRelation.getPermissions, RoleRelation.getPermissions)
29 | /**
30 | * 设置角色绑定用户
31 | * @api {POST} /api/RoleRelation/setBindUser 设置角色绑定用户
32 | * @apiDescription 设置角色绑定用户
33 | * @apiName setBindUser
34 | * @apiHeader {String} Authorization token
35 | * @apiParam (参数) {Object} Object
36 | * @apiSampleRequest /api/RoleRelation/setBindUser
37 | * @apiGroup RoleRelation
38 | * @apiVersion 0.0.1
39 | */
40 | router.post('/setBindUser', ValidateRoleRelation.setBindUser, RoleRelation.setBindUser)
41 | /**
42 | * 获取角色绑定的用户
43 | * @api {delete} /api/RoleRelation/getBindUser 获取角色绑定的用户
44 | * @apiDescription 获取角色绑定的用户
45 | * @apiName getBindUser
46 | * @apiHeader {String} Authorization token
47 | * @apiSampleRequest /api/RoleRelation/getBindUser
48 | * @apiGroup RoleRelation
49 | * @apiVersion 0.0.1
50 | */
51 | router.get('/getBindUser', ValidateRoleRelation.getBindUser, RoleRelation.getBindUser)
52 |
53 | export default router
54 |
--------------------------------------------------------------------------------
/model/Token.js:
--------------------------------------------------------------------------------
1 | import query from '../mysql'
2 | import Base from './Base'
3 | import JWT from 'jsonwebtoken'
4 |
5 | class Token extends Base{
6 | constructor () {
7 | super()
8 | this.getToken = this.getToken.bind(this)
9 | this.setToken = this.setToken.bind(this)
10 | }
11 | async getToken (obj) {
12 | let sql = `select * from bbs_token where 1 = 1 ${this.joinStr('get', obj.get)};`
13 | return query(sql)
14 | }
15 | async setToken (data, obj) {
16 | let search, sql, newUserInfo = JSON.parse(JSON.stringify(data)), oldUserInfo = {}
17 | try {
18 | search = await this.getToken({get: {user_id: data.id}})
19 | } catch (e) {
20 | return e
21 | }
22 | // 用户不存在则创建一条数据,存在则将原来的token替换掉
23 | if (search.length === 0) {
24 | sql = `INSERT INTO bbs_token set ${this.joinStr('set', obj.set)};`
25 | } else {
26 | // 解析token和当前数据做对比
27 | JWT.verify(search[0][data.type + '_token'], 'BBS', (error, decoded) => {
28 | if (error) {
29 | return {}
30 | }
31 | oldUserInfo = decoded
32 | })
33 | // 用户数据发生变化,重新设置数据信息,只修改token
34 | delete newUserInfo[data.type + '_expire_time']
35 | delete oldUserInfo[data.type + '_expire_time']
36 | delete oldUserInfo.iat
37 | if (JSON.stringify(newUserInfo) !== JSON.stringify(oldUserInfo)) {
38 | obj.set = {
39 | [data.type + '_token']: obj.set[data.type + '_token']
40 | }
41 | sql = `UPDATE bbs_token set ${this.joinStr('set', obj.set)} where 1 = 1 ${this.joinStr('get', obj.get)};`
42 | } else if(+new Date(search[0][data.type + '_expire_time']) > +new Date()) {
43 | // 数据未过期,不处理
44 | sql = ``
45 | } else {
46 | sql = `UPDATE bbs_token set ${this.joinStr('set', obj.set)} where 1 = 1 ${this.joinStr('get', obj.get)};`
47 | }
48 | }
49 | return sql ? query(sql) : ''
50 | }
51 | }
52 |
53 | export default new Token()
54 |
--------------------------------------------------------------------------------
/controller/Log.js:
--------------------------------------------------------------------------------
1 | import Base from './Base'
2 | import LogModel from '../model/Log'
3 |
4 | class Log extends Base {
5 | constructor () {
6 | super()
7 | this.writeLog = this.writeLog.bind(this)
8 | this.getList = this.getList.bind(this)
9 | }
10 | // 写入日志
11 | async writeLog (req, res, next) {
12 | let data = req.body,
13 | userInfo = await this.getUserInfo(req)
14 | try {
15 | // 写入登录日志
16 | await logModel.writeLog({
17 | set: {
18 | origin: data.origin,
19 | type: data.type,
20 | title: data.title,
21 | desc: data.desc,
22 | ip: this.getClientIp(req),
23 | create_user: userInfo.id,
24 | create_time: new Date()
25 | }
26 | })
27 | } catch (e) {
28 | this.handleException(req, res, e)
29 | return
30 | }
31 | res.json({
32 | code: 20000,
33 | success: true,
34 | content: {},
35 | message: '写入成功'
36 | })
37 | }
38 | // 查询列表
39 | async getList (req, res, next) {
40 | let query = JSON.parse(JSON.stringify(req.query)),
41 | result,
42 | length,
43 | userInfo = await this.getUserInfo(req)
44 | // 设置非模糊查询字段
45 | for (let key in query) {
46 | if (['id', 'create_user', 'type', 'origin'].indexOf(key) === -1) {
47 | query.like = [...query.like || [], key]
48 | }
49 | }
50 | try {
51 | result = await LogModel.getList({get: query})
52 | length = await LogModel.getTotals({get: query})
53 | } catch (e) {
54 | this.handleException(req, res, e)
55 | return
56 | }
57 | res.json({
58 | code: 20000,
59 | success: true,
60 | content: {
61 | result,
62 | curPage: +query.curPage,
63 | pageSize: +query.pageSize,
64 | totals: length ? length[0].count : 0
65 | },
66 | message: '操作成功'
67 | })
68 | }
69 | }
70 |
71 | export default new Log()
72 |
--------------------------------------------------------------------------------
/model/TechSquare.js:
--------------------------------------------------------------------------------
1 | import query from '../mysql'
2 | import Base from './Base'
3 |
4 | class TechSquare extends Base{
5 | constructor () {
6 | super()
7 | this.create = this.create.bind(this)
8 | this.update = this.update.bind(this)
9 | this.delete = this.delete.bind(this)
10 | this.getRow = this.getRow.bind(this)
11 | this.getList = this.getList.bind(this)
12 | this.getTotals = this.getTotals.bind(this)
13 | this.getAll = this.getAll.bind(this)
14 | }
15 | async create (obj) {
16 | let sql = `INSERT INTO bbs_tech_square set ${this.joinStr('set', obj.set)};`
17 | return query(sql)
18 | }
19 | async update (obj) {
20 | let sql = `UPDATE bbs_tech_square set ${this.joinStr('set', obj.set)} where 1 = 1 ${this.joinStr('get', obj.get)};`
21 | return query(sql)
22 | }
23 | async delete (obj) {
24 | let sql = `DELETE from bbs_tech_square where 1 = 1 ${this.joinStr('get', obj.get)};`
25 | return query(sql)
26 | }
27 | async getRow (obj) {
28 | let sql = `select * from bbs_tech_square where 1 = 1 ${this.joinStr('get', obj.get)};`
29 | return query(sql)
30 | }
31 | async getList (obj) {
32 | let curPage = obj.get.curPage, pageSize = obj.get.pageSize
33 | let sql = `select * from bbs_tech_square
34 | where 1 = 1 ${this.joinStr('get', obj.get)} ORDER BY sort limit ${(curPage - 1) * pageSize}, ${pageSize};`
35 | return query(sql)
36 | }
37 | async getTotals (obj) {
38 | let sql = `select COUNT(*) as count from bbs_tech_square where 1 = 1 ${this.joinStr('get', obj.get)};`
39 | return query(sql)
40 | }
41 | async getAll (obj) {
42 | let sql = `select a.*, b.icon as image, b.name as title from bbs_tech_square as a
43 | left join bbs_tag_type as b on a.tag_type_id = b.id
44 | where 1 = 1 ${this.joinStr('get', obj.get)} ORDER BY sort;`
45 | // 处理表连接字段
46 | sql = sql.replace(/`status`/, 'a.status')
47 | sql = sql.replace(/`flag`/, 'a.flag')
48 | return query(sql)
49 | }
50 | }
51 |
52 | export default new TechSquare()
53 |
--------------------------------------------------------------------------------
/model/TagRelation.js:
--------------------------------------------------------------------------------
1 | import mysql from 'mysql'
2 | import query from '../mysql'
3 | import Base from './Base'
4 |
5 |
6 | class TagRelation extends Base {
7 | constructor () {
8 | super()
9 | this.setBindTag = this.setBindTag.bind(this)
10 | this.getBindTag = this.getBindTag.bind(this)
11 | }
12 | // 设置标签类型绑定的标签
13 | async setBindTag (obj) {
14 | let dbTags, paramsTags = obj.data.tags || [],
15 | createTagList = [], deleteTagList = [], sql1, sql2,
16 | result1, result2
17 | // 先查询到当前标签类型下所有的标签
18 | dbTags = await query(`select a.tag_id from bbs_tag_type_tag as a where 1 = 1 ${this.joinStr('get', obj.get)};`)
19 | // 得到数据库的ID列表
20 | dbTags = dbTags.map(item => item.tag_id)
21 | // 数据库数据和传入数据做对比,数据库有而传入没有的数据删除,传入而数据库没有的数据添加
22 | dbTags.forEach(item => {
23 | // 需要删除菜单的数据
24 | if (!paramsTags.includes(item)) {
25 | deleteTagList.push(item)
26 | }
27 | })
28 | paramsTags.forEach(item => {
29 | // 需要添加菜单的数据
30 | if (!dbTags.includes(item)) {
31 | createTagList.push([obj.get.tag_type_id, item])
32 | }
33 | })
34 | // 事务开始
35 | await query('begin')
36 | // 删除
37 | sql1 = `DELETE from bbs_tag_type_tag where tag_id in (${mysql.escape(deleteTagList)}) and tag_type_id = ${obj.get.tag_type_id};`
38 | // 添加
39 | sql2 = `INSERT INTO bbs_tag_type_tag (tag_type_id, tag_id) VALUES ${mysql.escape(createTagList)};`
40 | // 运行sql
41 | result1 = mysql.escape(deleteTagList) ? await query(sql1) : {affectedRows: true}
42 | result2 = mysql.escape(createTagList) ? await query(sql2) : {affectedRows: true}
43 | if (result1.affectedRows >= 0 && result2.affectedRows) {
44 | // 事务提交
45 | await query('commit')
46 | } else {
47 | // 事务回滚
48 | await query('rollback')
49 | }
50 | return result1.affectedRows >= 0 && result2.affectedRows
51 | }
52 | // 获取标签类型绑定的标签
53 | async getBindTag (obj) {
54 | let sql = `select tag_id from bbs_tag_type_tag where 1 = 1 ${this.joinStr('get', obj.get)};`
55 | return query(sql)
56 | }
57 | }
58 |
59 | export default new TagRelation()
60 |
--------------------------------------------------------------------------------
/model/Column.js:
--------------------------------------------------------------------------------
1 | import query from '../mysql'
2 | import Base from './Base'
3 |
4 | class Column extends Base{
5 | constructor () {
6 | super()
7 | this.create = this.create.bind(this)
8 | this.update = this.update.bind(this)
9 | this.delete = this.delete.bind(this)
10 | this.getRow = this.getRow.bind(this)
11 | this.getList = this.getList.bind(this)
12 | this.getTotals = this.getTotals.bind(this)
13 | this.getAll = this.getAll.bind(this)
14 | }
15 | async create (obj) {
16 | let sql = `INSERT INTO bbs_column set ${this.joinStr('set', obj.set)};`
17 | return query(sql)
18 | }
19 | async update (obj) {
20 | let sql = `UPDATE bbs_column set ${this.joinStr('set', obj.set)} where 1 = 1 ${this.joinStr('get', obj.get)};`
21 | return query(sql)
22 | }
23 | async delete (obj) {
24 | let sql = `DELETE from bbs_column where 1 = 1 ${this.joinStr('get', obj.get)};`
25 | return query(sql)
26 | }
27 | async getRow (obj) {
28 | let sql = `select * from bbs_column where 1 = 1 ${this.joinStr('get', obj.get)};`
29 | return query(sql)
30 | }
31 | async getList (obj) {
32 | let curPage = obj.get.curPage, pageSize = obj.get.pageSize
33 | let sql = `select * from bbs_column
34 | where 1 = 1 ${this.joinStr('get', obj.get)} ${this.joinStr('ORDER BY', {DESC: ['create_time', 'id']})} limit ${(curPage - 1) * pageSize}, ${pageSize};`
35 | return query(sql)
36 | }
37 | async getTotals (obj) {
38 | let sql = `select COUNT(*) as count from bbs_column where 1 = 1 ${this.joinStr('get', obj.get)};`
39 | return query(sql)
40 | }
41 | async getAll (obj) {
42 | let sql = `select a.*, b.name as create_user_name, c.name as update_user_name from bbs_column as a
43 | left join bbs_user as b on a.create_user = b.id
44 | left join bbs_user as c on a.update_user = c.id
45 | where 1 = 1 ${this.joinStr('get', obj.get)} ORDER BY sort;`
46 | // 处理表连接字段
47 | sql = sql.replace(/`flag`/, 'a.flag')
48 | sql = sql.replace(/`name`/, 'a.name')
49 | return query(sql)
50 | }
51 | }
52 |
53 | export default new Column()
54 |
--------------------------------------------------------------------------------
/model/File.js:
--------------------------------------------------------------------------------
1 | import query from '../mysql'
2 | import Base from './Base'
3 |
4 | class File extends Base{
5 | constructor () {
6 | super()
7 | this.create = this.create.bind(this)
8 | this.update = this.update.bind(this)
9 | this.delete = this.delete.bind(this)
10 | this.getRow = this.getRow.bind(this)
11 | this.getList = this.getList.bind(this)
12 | this.getTotals = this.getTotals.bind(this)
13 | this.getAll = this.getAll.bind(this)
14 | }
15 | async create (obj) {
16 | let sql = `INSERT INTO bbs_file set ${this.joinStr('set', obj.set)};`
17 | return query(sql)
18 | }
19 | async update (obj) {
20 | let sql = `UPDATE bbs_file set ${this.joinStr('set', obj.set)} where 1 = 1 ${this.joinStr('get', obj.get)};`
21 | return query(sql)
22 | }
23 | async delete (obj) {
24 | let sql = `DELETE from bbs_file where 1 = 1 ${this.joinStr('get', obj.get)};`
25 | return query(sql)
26 | }
27 | async getRow (obj) {
28 | let sql = `select * from bbs_file where 1 = 1 ${this.joinStr('get', obj.get)};`
29 | return query(sql)
30 | }
31 | async getList (obj) {
32 | let curPage = obj.get.curPage, pageSize = obj.get.pageSize
33 | let sql = `select * from bbs_file
34 | where 1 = 1 ${this.joinStr('get', obj.get)} ${this.joinStr('ORDER BY', {DESC: ['create_time', 'id']})} limit ${(curPage - 1) * pageSize}, ${pageSize};`
35 | return query(sql)
36 | }
37 | async getTotals (obj) {
38 | let sql = `select COUNT(*) as count from bbs_file where 1 = 1 ${this.joinStr('get', obj.get)};`
39 | return query(sql)
40 | }
41 | async getAll (obj) {
42 | let sql = `select a.*, b.name as create_user_name, c.name as update_user_name from bbs_file as a
43 | left join bbs_user as b on a.create_user = b.id
44 | left join bbs_user as c on a.update_user = c.id
45 | where 1 = 1 ${this.joinStr('get', obj.get)} ORDER BY sort;`
46 | // 处理表连接字段
47 | sql = sql.replace(/`type`/, 'a.type')
48 | sql = sql.replace(/`name`/, 'a.name')
49 | sql = sql.replace(/`flag`/, 'a.flag')
50 | return query(sql)
51 | }
52 | }
53 |
54 | export default new File()
55 |
--------------------------------------------------------------------------------
/model/Question.js:
--------------------------------------------------------------------------------
1 | import query from '../mysql'
2 | import Base from './Base'
3 |
4 | class Questions extends Base{
5 | constructor () {
6 | super()
7 | this.create = this.create.bind(this)
8 | this.update = this.update.bind(this)
9 | this.delete = this.delete.bind(this)
10 | this.getRow = this.getRow.bind(this)
11 | this.getList = this.getList.bind(this)
12 | this.getTotals = this.getTotals.bind(this)
13 | this.getAll = this.getAll.bind(this)
14 | }
15 | async create (obj) {
16 | let sql = `INSERT INTO bbs_questions set ${this.joinStr('set', obj.set)};`
17 | return query(sql)
18 | }
19 | async update (obj) {
20 | let sql = `UPDATE bbs_questions set ${this.joinStr('set', obj.set)} where 1 = 1 ${this.joinStr('get', obj.get)};`
21 | return query(sql)
22 | }
23 | async delete (obj) {
24 | let sql = `DELETE from bbs_questions where 1 = 1 ${this.joinStr('get', obj.get)};`
25 | return query(sql)
26 | }
27 | async getRow (obj) {
28 | let sql = `select * from bbs_questions where 1 = 1 ${this.joinStr('get', obj.get)};`
29 | return query(sql)
30 | }
31 | async getList (obj) {
32 | let curPage = obj.get.curPage, pageSize = obj.get.pageSize
33 | let sql = `select * from bbs_questions
34 | where 1 = 1 ${this.joinStr('get', obj.get)} ${this.joinStr('ORDER BY', {DESC: ['create_time', 'id']})} limit ${(curPage - 1) * pageSize}, ${pageSize};`
35 | return query(sql)
36 | }
37 | async getTotals (obj) {
38 | let sql = `select COUNT(*) as count from bbs_questions where 1 = 1 ${this.joinStr('get', obj.get)};`
39 | return query(sql)
40 | }
41 | async getAll (obj) {
42 | let sql = `select a.*, b.name as create_user_name, c.name as update_user_name from bbs_questions as a
43 | left join bbs_user as b on a.create_user = b.id
44 | left join bbs_user as c on a.update_user = c.id
45 | where 1 = 1 ${this.joinStr('get', obj.get)}`
46 | // 处理表连接字段
47 | sql = sql.replace(/`flag`/, 'a.flag')
48 | sql = sql.replace(/`create_user`/, 'a.create_user')
49 | sql = sql.replace(/`name`/, 'a.name')
50 | return query(sql)
51 | }
52 | }
53 |
54 | export default new Questions()
55 |
--------------------------------------------------------------------------------
/controller/Charts.js:
--------------------------------------------------------------------------------
1 | import Base from './Base'
2 | import LogModel from '../model/Log'
3 |
4 | class Charts extends Base {
5 | constructor () {
6 | super()
7 | this.getCharts = this.getCharts.bind(this)
8 | this.userLoginAnalyze = this.userLoginAnalyze.bind(this)
9 | }
10 | async getCharts (req, res, next) {
11 | const data = req.body.config
12 | }
13 | // 用户登陆分析
14 | async userLoginAnalyze (req, res, next) {
15 | let days = req.query.days - 1 || 6,
16 | now = this.utils.switchTime(new Date(), 'YYYY-MM-DD') + ' 00:00:00',
17 | result, lastDays = +new Date(now) - 1000 * 3600 * 24 * days
18 | try {
19 | result = await LogModel.getLoginLog({get: {larger: {create_time: this.utils.switchTime(lastDays, 'YYYY-MM-DD hh:mm:ss')}, type: 1}})
20 | } catch (e) {
21 | this.handleException(req, res, e)
22 | return
23 | }
24 | // 对数据做处理
25 | const arr = [], daysList = [], timeList = [], dataList = []
26 | result.forEach(item => {
27 | arr.push({
28 | day: this.utils.switchTime(item.time, 'MM-DD'),
29 | time: this.utils.switchTime(item.time, 'hh:mm:ss'),
30 | hour: this.utils.switchTime(item.time, 'hh')
31 | })
32 | // 得到天列表
33 | if (!daysList.includes(this.utils.switchTime(item.time, 'MM-DD'))) {
34 | daysList.push(this.utils.switchTime(item.time, 'MM-DD'))
35 | }
36 | })
37 | // 初始化时间列表
38 | for (let i = 0, len = 24; i < len; i++) {
39 | timeList.push(i > 9 ? i + ':00' : '0' + i + ':00')
40 | }
41 | // 初始化数据列表
42 | for (let i = 0; i < days + 1; i++) {
43 | let arr1 = []
44 | for (let i = 0, len = 24; i < len; i++) {
45 | arr1.push(0)
46 | }
47 | // 当天初始为当天的小时个数
48 | i === days ? dataList.push(arr1.slice(0, new Date().getHours() + 1)) : dataList.push(arr1)
49 | }
50 | arr.forEach(item => {
51 | // 得到每天每小时登陆的次数
52 | dataList[daysList.indexOf(item.day)][timeList.indexOf(item.hour + ':00')]++
53 | })
54 | res.json({
55 | code: 20000,
56 | success: true,
57 | content: {timeList, daysList, dataList},
58 | message: '操作成功'
59 | })
60 | }
61 | // 用户注册分析
62 | async userRegisteredAnalyze (req, res, next) {
63 | }
64 | }
65 |
66 | export default new Charts()
67 |
--------------------------------------------------------------------------------
/controller/ArticleComments.js:
--------------------------------------------------------------------------------
1 | import Base from './Base'
2 | import ArticleCommentsModel from '../model/ArticleComments'
3 | import mqttClient from '../mqtt/client'
4 |
5 | class ArticleComments extends Base {
6 | constructor () {
7 | super()
8 | this.create = this.create.bind(this)
9 | this.delete = this.delete.bind(this)
10 | this.getAll = this.getAll.bind(this)
11 | }
12 | // 创建评论
13 | async create (req, res, next) {
14 | let data = JSON.parse(JSON.stringify(req.body)),
15 | userInfo = await this.getUserInfo(req), result
16 | try {
17 | // 参数处理
18 | data.create_user = userInfo.id,
19 | data.create_time = new Date()
20 | result = await ArticleCommentsModel.create({
21 | set: data
22 | })
23 | } catch (e) {
24 | this.handleException(req, res, e)
25 | return
26 | }
27 | // 推送mqtt消息
28 | mqttClient.publish(`/message/user/${data.p_user_id}`, JSON.stringify({
29 | topic: `/message/user/${data.p_user_id}`,
30 | data: data
31 | }))
32 | res.json({
33 | code: 20000,
34 | success: true,
35 | message: '创建成功'
36 | })
37 | }
38 | // 删除评论
39 | async delete (req, res, next) {
40 | const userInfo = await this.getUserInfo(req),
41 | result = await ArticleCommentsModel.update({set: {flag: 0, delete_user: userInfo.id, delete_time: new Date()}, get: {id: req.params.id}})
42 | if (result.affectedRows) {
43 | res.json({
44 | code: 20000,
45 | success: true,
46 | message: '删除成功'
47 | })
48 | } else {
49 | res.json({
50 | code: 20001,
51 | success: true,
52 | message: '删除失败'
53 | })
54 | }
55 | }
56 | // 获取评论
57 | async getAll (req, res, next) {
58 | let result, query = req.query, totals
59 | try {
60 | result = await ArticleCommentsModel.getAll({get: {...query, flag: 1}})
61 | totals = await ArticleCommentsModel.getTotals({get: {...query, flag: 1}})
62 | } catch (e) {
63 | this.handleException(req, res, e)
64 | return
65 | }
66 | res.json({
67 | code: 20000,
68 | success: true,
69 | content: result,
70 | totals: totals[0].count,
71 | message: '操作成功'
72 | })
73 | }
74 | }
75 |
76 | export default new ArticleComments()
77 |
--------------------------------------------------------------------------------
/controller/Area.js:
--------------------------------------------------------------------------------
1 | import Base from './Base'
2 | import AreaModel from '../model/Area'
3 |
4 | class Area extends Base {
5 | constructor () {
6 | super()
7 | this.update = this.update.bind(this)
8 | this.getList = this.getList.bind(this)
9 | this.getAll = this.getAll.bind(this)
10 | }
11 | // 编辑
12 | async update (req, res, next) {
13 | let data = req.body,
14 | result,
15 | userInfo = await this.getUserInfo(req)
16 | try {
17 | result = await AreaModel.update({
18 | set: {
19 | status: data.status
20 | },
21 | get: {
22 | id: data.id
23 | }
24 | })
25 | } catch (e) {
26 | this.handleException(req, res, e)
27 | return
28 | }
29 | if (result.affectedRows) {
30 | res.json({
31 | code: 20000,
32 | success: true,
33 | message: '操作成功'
34 | })
35 | } else {
36 | res.json({
37 | code: 20001,
38 | success: false,
39 | message: '编辑失败'
40 | })
41 | }
42 | }
43 | // 查询列表
44 | async getList (req, res, next) {
45 | let query = JSON.parse(JSON.stringify(req.query)),
46 | result,
47 | length,
48 | userInfo = await this.getUserInfo(req)
49 | // 设置非模糊查询字段
50 | for (let key in query) {
51 | if (['id', 'pid'].indexOf(key) === -1) {
52 | query.like = [...query.like || [], key]
53 | }
54 | }
55 | try {
56 | result = await AreaModel.getList({get: query})
57 | length = await AreaModel.getTotals({get: query})
58 | } catch (e) {
59 | this.handleException(req, res, e)
60 | return
61 | }
62 | res.json({
63 | code: 20000,
64 | success: true,
65 | content: {
66 | result,
67 | curPage: +query.curPage,
68 | pageSize: +query.pageSize,
69 | totals: length ? length[0].count : 0
70 | },
71 | message: '操作成功'
72 | })
73 | }
74 | // 根据PID获取所有下级区域
75 | async getAll (req, res, next) {
76 | let pid = req.params.pid, result
77 | try {
78 | result = await AreaModel.getAll({get: {pid}})
79 | } catch (e) {
80 | this.handleException(req, res, e)
81 | return
82 | }
83 | res.json({
84 | code: 20000,
85 | success: true,
86 | content: result,
87 | message: '操作成功'
88 | })
89 | }
90 | }
91 |
92 | export default new Area()
93 |
--------------------------------------------------------------------------------
/model/DataPerms.js:
--------------------------------------------------------------------------------
1 | import query from '../mysql'
2 | import Base from './Base'
3 |
4 | class DataPerms extends Base{
5 | constructor () {
6 | super()
7 | this.create = this.create.bind(this)
8 | this.update = this.update.bind(this)
9 | this.delete = this.delete.bind(this)
10 | this.getRow = this.getRow.bind(this)
11 | this.getList = this.getList.bind(this)
12 | this.getTotals = this.getTotals.bind(this)
13 | this.getRoleDataPerms = this.getRoleDataPerms.bind(this)
14 | this.getAll = this.getAll.bind(this)
15 | }
16 | async create (obj) {
17 | let sql = `INSERT INTO bbs_data_perms set ${this.joinStr('set', obj.set)};`
18 | return query(sql)
19 | }
20 | async update (obj) {
21 | let sql = `UPDATE bbs_data_perms set ${this.joinStr('set', obj.set)} where 1 = 1 ${this.joinStr('get', obj.get)};`
22 | return query(sql)
23 | }
24 | async delete (obj) {
25 | let sql = `DELETE from bbs_data_perms where 1 = 1 ${this.joinStr('get', obj.get)};`
26 | return query(sql)
27 | }
28 | async getRow (obj) {
29 | let sql = `select * from bbs_data_perms where 1 = 1 ${this.joinStr('get', obj.get)};`
30 | return query(sql)
31 | }
32 | async getList (obj) {
33 | let curPage = obj.get.curPage, pageSize = obj.get.pageSize
34 | let sql = `select * from bbs_data_perms
35 | where 1 = 1 ${this.joinStr('get', obj.get)} limit ${(curPage - 1) * pageSize}, ${pageSize};`
36 | return query(sql)
37 | }
38 | async getTotals (obj) {
39 | let sql = `select COUNT(*) as count from bbs_data_perms where 1 = 1 ${this.joinStr('get', obj.get)};`
40 | return query(sql)
41 | }
42 | async getRoleDataPerms (obj) {
43 | let sql = `select a.* from bbs_data_perms as a
44 | LEFT JOIN bbs_role_data_perms as b
45 | ON a.id = b.data_perms_id where 1 = 1 ${this.joinStr('get', obj.get)};`
46 | return query(sql)
47 | }
48 | // 只获取code,前端页面做数据权限使用
49 | async getCodeByRoleDataPerms (obj) {
50 | let sql = `select a.code from bbs_data_perms as a
51 | LEFT JOIN bbs_role_data_perms as b
52 | ON a.id = b.data_perms_id where 1 = 1 ${this.joinStr('get', obj.get)};`
53 | return query(sql)
54 | }
55 | async getAll (obj) {
56 | let sql = `select * from bbs_data_perms where 1 = 1 ${this.joinStr('get', obj.get)};`
57 | return query(sql)
58 | }
59 | }
60 |
61 | export default new DataPerms()
62 |
--------------------------------------------------------------------------------
/model/Menu.js:
--------------------------------------------------------------------------------
1 | import query from '../mysql'
2 | import Base from './Base'
3 |
4 | class Menu extends Base{
5 | constructor () {
6 | super()
7 | this.create = this.create.bind(this)
8 | this.update = this.update.bind(this)
9 | this.delete = this.delete.bind(this)
10 | this.getRow = this.getRow.bind(this)
11 | this.getRoleMenu = this.getRoleMenu.bind(this)
12 | this.getAll = this.getAll.bind(this)
13 | }
14 | async create (obj) {
15 | let sql = `INSERT INTO bbs_menu set ${this.joinStr('set', obj.set)};`
16 | return query(sql)
17 | }
18 | async update (obj) {
19 | let sql = `UPDATE bbs_menu set ${this.joinStr('set', obj.set)} where 1 = 1 ${this.joinStr('get', obj.get)};`
20 | return query(sql)
21 | }
22 | async delete (obj) {
23 | let sql = `DELETE from bbs_menu where 1 = 1 ${this.joinStr('get', obj.get)};`
24 | return query(sql)
25 | }
26 | async getRow (obj) {
27 | let sql = `select * from bbs_menu where 1 = 1 ${this.joinStr('get', obj.get)};`
28 | return query(sql)
29 | }
30 | async getList (obj) {
31 | let curPage = obj.get.curPage, pageSize = obj.get.pageSize
32 | let sql = `select * from bbs_menu
33 | where 1 = 1 ${this.joinStr('get', obj.get)} limit ${(curPage - 1) * pageSize}, ${pageSize};`
34 | return query(sql)
35 | }
36 | async getTotals (obj) {
37 | let sql = `select COUNT(*) as count from bbs_menu where 1 = 1 ${this.joinStr('get', obj.get)};`
38 | return query(sql)
39 | }
40 | async getRoleMenu (obj) {
41 | let sql = `select a.* from bbs_menu as a
42 | LEFT JOIN bbs_role_menu as b
43 | ON a.id = b.menu_id where 1 = 1 ${this.joinStr('get', obj.get)};`
44 | // admin则获取所有数据
45 | if (+obj.get.role_id === 1) {
46 | delete obj.get.role_id
47 | sql = `select * from bbs_menu where 1 = 1 ${this.joinStr('get', obj.get)};`
48 | }
49 | return query(sql)
50 | }
51 | async getAll (obj) {
52 | let sql = `select a.*, b.name as create_user_name, c.name as update_user_name from bbs_menu as a
53 | left join bbs_user as b on a.create_user = b.id
54 | left join bbs_user as c on a.update_user = c.id
55 | where 1 = 1 ${this.joinStr('get', obj.get)} ORDER BY sort;`
56 | // 处理表连接字段
57 | sql = sql.replace(/`type`/, 'a.type')
58 | sql = sql.replace(/`flag`/, 'a.flag')
59 | return query(sql)
60 | }
61 | }
62 |
63 | export default new Menu()
64 |
--------------------------------------------------------------------------------
/validate/Tag.js:
--------------------------------------------------------------------------------
1 | import Base from './Base'
2 |
3 | class Tag extends Base{
4 | constructor () {
5 | super()
6 | this.create = this.create.bind(this)
7 | this.update = this.update.bind(this)
8 | this.delete = this.delete.bind(this)
9 | this.getRow = this.getRow.bind(this)
10 | this.getList = this.getList.bind(this)
11 | this.getAll = this.getAll.bind(this)
12 | }
13 | async create (req, res, next) {
14 | const params = req.body,
15 | arr = [
16 | ],
17 | result = this.check(arr)
18 | if (!result.success) {
19 | res.json({
20 | code: 20301,
21 | success: false,
22 | message: result.message
23 | })
24 | return
25 | }
26 | next()
27 | }
28 | async update (req, res, next) {
29 | const params = req.body,
30 | arr = [
31 | ],
32 | result = this.check(arr)
33 | if (!result.success) {
34 | res.json({
35 | code: 20301,
36 | success: false,
37 | message: result.message
38 | })
39 | return
40 | }
41 | next()
42 | }
43 | async delete (req, res, next) {
44 | const ID = req.params.id,
45 | arr = [
46 | {label: 'ID', value: ID, rules: ['notnull']}
47 | ],
48 | result = this.check(arr)
49 | if (!result.success) {
50 | res.json({
51 | code: 20301,
52 | success: false,
53 | message: result.message
54 | })
55 | return
56 | }
57 | next()
58 | }
59 | async getRow (req, res, next) {
60 | const ID = req.params.id,
61 | arr = [
62 | {label: 'ID', value: ID, rules: ['notnull']}
63 | ],
64 | result = this.check(arr)
65 | if (!result.success) {
66 | res.json({
67 | code: 20301,
68 | success: false,
69 | message: result.message
70 | })
71 | return
72 | }
73 | next()
74 | }
75 | async getList (req, res, next) {
76 | const data = req.query,
77 | arr = [
78 | {label: 'curPage', value: data.curPage, rules: ['notnull', 'number']},
79 | {label: 'pageSize', value: data.curPage, rules: ['notnull', 'number']}
80 | ],
81 | result = this.check(arr)
82 | if (!result.success) {
83 | res.json({
84 | code: 20301,
85 | success: false,
86 | message: result.message
87 | })
88 | return
89 | }
90 | next()
91 | }
92 | async getAll (req, res, next) {
93 | next()
94 | }
95 | }
96 |
97 | export default new Tag()
98 |
--------------------------------------------------------------------------------
/validate/Topic.js:
--------------------------------------------------------------------------------
1 | import Base from './Base'
2 |
3 | class Topic extends Base{
4 | constructor () {
5 | super()
6 | this.create = this.create.bind(this)
7 | this.update = this.update.bind(this)
8 | this.delete = this.delete.bind(this)
9 | this.getRow = this.getRow.bind(this)
10 | this.getList = this.getList.bind(this)
11 | this.getAll = this.getAll.bind(this)
12 | }
13 | async create (req, res, next) {
14 | const params = req.body,
15 | arr = [
16 | ],
17 | result = this.check(arr)
18 | if (!result.success) {
19 | res.json({
20 | code: 20301,
21 | success: false,
22 | message: result.message
23 | })
24 | return
25 | }
26 | next()
27 | }
28 | async update (req, res, next) {
29 | const params = req.body,
30 | arr = [
31 | ],
32 | result = this.check(arr)
33 | if (!result.success) {
34 | res.json({
35 | code: 20301,
36 | success: false,
37 | message: result.message
38 | })
39 | return
40 | }
41 | next()
42 | }
43 | async delete (req, res, next) {
44 | const ID = req.params.id,
45 | arr = [
46 | {label: 'ID', value: ID, rules: ['notnull']}
47 | ],
48 | result = this.check(arr)
49 | if (!result.success) {
50 | res.json({
51 | code: 20301,
52 | success: false,
53 | message: result.message
54 | })
55 | return
56 | }
57 | next()
58 | }
59 | async getRow (req, res, next) {
60 | const ID = req.params.id,
61 | arr = [
62 | {label: 'ID', value: ID, rules: ['notnull']}
63 | ],
64 | result = this.check(arr)
65 | if (!result.success) {
66 | res.json({
67 | code: 20301,
68 | success: false,
69 | message: result.message
70 | })
71 | return
72 | }
73 | next()
74 | }
75 | async getList (req, res, next) {
76 | const data = req.query,
77 | arr = [
78 | {label: 'curPage', value: data.curPage, rules: ['notnull', 'number']},
79 | {label: 'pageSize', value: data.curPage, rules: ['notnull', 'number']}
80 | ],
81 | result = this.check(arr)
82 | if (!result.success) {
83 | res.json({
84 | code: 20301,
85 | success: false,
86 | message: result.message
87 | })
88 | return
89 | }
90 | next()
91 | }
92 | async getAll (req, res, next) {
93 | next()
94 | }
95 | }
96 |
97 | export default new Topic()
98 |
--------------------------------------------------------------------------------
/validate/TagType.js:
--------------------------------------------------------------------------------
1 | import Base from './Base'
2 |
3 | class TagType extends Base{
4 | constructor () {
5 | super()
6 | this.create = this.create.bind(this)
7 | this.update = this.update.bind(this)
8 | this.delete = this.delete.bind(this)
9 | this.getRow = this.getRow.bind(this)
10 | this.getList = this.getList.bind(this)
11 | this.getAll = this.getAll.bind(this)
12 | }
13 | async create (req, res, next) {
14 | const params = req.body,
15 | arr = [
16 | ],
17 | result = this.check(arr)
18 | if (!result.success) {
19 | res.json({
20 | code: 20301,
21 | success: false,
22 | message: result.message
23 | })
24 | return
25 | }
26 | next()
27 | }
28 | async update (req, res, next) {
29 | const params = req.body,
30 | arr = [
31 | ],
32 | result = this.check(arr)
33 | if (!result.success) {
34 | res.json({
35 | code: 20301,
36 | success: false,
37 | message: result.message
38 | })
39 | return
40 | }
41 | next()
42 | }
43 | async delete (req, res, next) {
44 | const ID = req.params.id,
45 | arr = [
46 | {label: 'ID', value: ID, rules: ['notnull']}
47 | ],
48 | result = this.check(arr)
49 | if (!result.success) {
50 | res.json({
51 | code: 20301,
52 | success: false,
53 | message: result.message
54 | })
55 | return
56 | }
57 | next()
58 | }
59 | async getRow (req, res, next) {
60 | const ID = req.params.id,
61 | arr = [
62 | {label: 'ID', value: ID, rules: ['notnull']}
63 | ],
64 | result = this.check(arr)
65 | if (!result.success) {
66 | res.json({
67 | code: 20301,
68 | success: false,
69 | message: result.message
70 | })
71 | return
72 | }
73 | next()
74 | }
75 | async getList (req, res, next) {
76 | const data = req.query,
77 | arr = [
78 | {label: 'curPage', value: data.curPage, rules: ['notnull', 'number']},
79 | {label: 'pageSize', value: data.curPage, rules: ['notnull', 'number']}
80 | ],
81 | result = this.check(arr)
82 | if (!result.success) {
83 | res.json({
84 | code: 20301,
85 | success: false,
86 | message: result.message
87 | })
88 | return
89 | }
90 | next()
91 | }
92 | async getAll (req, res, next) {
93 | next()
94 | }
95 | }
96 |
97 | export default new TagType()
98 |
--------------------------------------------------------------------------------
/router/tag.js:
--------------------------------------------------------------------------------
1 | import express from 'express'
2 | import Tag from '../controller/Tag'
3 | import ValidateTag from '../validate/Tag'
4 | const router = express.Router()
5 |
6 | /**
7 | * 创建
8 | * @api {POST} /api/Tag/create 创建
9 | * @apiDescription 创建标签类型
10 | * @apiName create
11 | * @apiHeader {String} Authorization token
12 | * @apiParam (参数) {Number} type_id 类型ID
13 | * @apiParam (参数) {String} name 名称
14 | * @apiParam (参数) {String} sort 排序
15 | * @apiParam (参数) {String} desc 描述
16 | * @apiSampleRequest /api/Tag/create
17 | * @apiGroup Tag
18 | * @apiVersion 0.0.1
19 | */
20 | router.post('/create', ValidateTag.create, Tag.create)
21 | /**
22 | * 编辑
23 | * @api {put} /api/Tag/update 编辑
24 | * @apiDescription 编辑
25 | * @apiName update
26 | * @apiHeader {String} Authorization token
27 | * @apiParam (参数) {Number} id
28 | * @apiParam (参数) {Number} type_id 类型ID
29 | * @apiParam (参数) {String} name 名称
30 | * @apiParam (参数) {String} sort 排序
31 | * @apiParam (参数) {String} desc 描述
32 | * @apiSampleRequest /api/Tag/update
33 | * @apiGroup Tag
34 | * @apiVersion 0.0.1
35 | */
36 | router.put('/update', ValidateTag.update, Tag.update)
37 | /**
38 | * 删除
39 | * @api {delete} /api/Tag/delete/:id 删除
40 | * @apiDescription 删除
41 | * @apiName delete
42 | * @apiHeader {String} Authorization token
43 | * @apiParam {Number} id
44 | * @apiSampleRequest /api/Tag/delete
45 | * @apiGroup Tag
46 | * @apiVersion 0.0.1
47 | */
48 | router.delete('/delete/:id', ValidateTag.delete, Tag.delete)
49 |
50 | /**
51 | * 获取标签类型信息
52 | * @api {get} /api/Tag/getRow 获取标签类型信息
53 | * @apiDescription 获取标签类型信息
54 | * @apiName getRow
55 | * @apiHeader {String} Authorization token
56 | * @apiParam {Number} id
57 | * @apiSampleRequest /api/Tag/getRow
58 | * @apiGroup Tag
59 | * @apiVersion 0.0.1
60 | */
61 | router.get('/getRow/:id', ValidateTag.getRow, Tag.getRow)
62 | /**
63 | * 获取标签类型列表
64 | * @api {get} /api/Tag/getList 获取标签类型列表
65 | * @apiDescription 获取标签类型列表
66 | * @apiName getList
67 | * @apiHeader {String} Authorization token
68 | * @apiParam (path参数) {Number} curPage
69 | * @apiParam (path参数) {Number} pageSize
70 | * @apiSampleRequest /api/Tag/getList
71 | * @apiGroup Tag
72 | * @apiVersion 0.0.1
73 | */
74 | router.get('/getList', ValidateTag.getList, Tag.getList)
75 | /**
76 | * 获取所有标签类型
77 | * @api {get} /api/Tag/getAll 获取所有标签类型
78 | * @apiDescription 获取所有标签类型
79 | * @apiName getAll
80 | * @apiParam {Number} type
81 | * @apiHeader {String} Authorization token
82 | * @apiSampleRequest /api/Tag/getAll
83 | * @apiGroup Tag
84 | * @apiVersion 0.0.1
85 | */
86 | router.get('/getAll', ValidateTag.getAll, Tag.getAll)
87 |
88 | export default router
89 |
--------------------------------------------------------------------------------
/router/file.js:
--------------------------------------------------------------------------------
1 | import express from 'express'
2 | import File from '../controller/File'
3 | import ValidateFile from '../validate/File'
4 | import multipart from 'connect-multiparty' // 处理form-data数据中间件
5 |
6 | const router = express.Router()
7 |
8 | /**
9 | * 上传文件
10 | * @api {POST} /api/File/upload 创建
11 | * @apiDescription 上传文件
12 | * @apiName upload
13 | * @apiHeader {String} Authorization token
14 | * @apiParam (参数) {Number} id 目录ID
15 | * @apiSampleRequest /api/File/upload
16 | * @apiGroup File
17 | * @apiVersion 0.0.1
18 | */
19 | router.post('/upload', multipart(), ValidateFile.upload, File.upload)
20 | /**
21 | * 编辑
22 | * @api {put} /api/File/update 编辑
23 | * @apiDescription 编辑
24 | * @apiName update
25 | * @apiHeader {String} Authorization token
26 | * @apiParam (参数) {Number} id
27 | * @apiParam (参数) {Number} f_id 文件目录ID
28 | * @apiParam (参数) {String} name 文件名称
29 | * @apiParam (参数) {String} desc 描述
30 | * @apiSampleRequest /api/File/update
31 | * @apiGroup File
32 | * @apiVersion 0.0.1
33 | */
34 | router.put('/update', ValidateFile.update, File.update)
35 | /**
36 | * 删除
37 | * @api {delete} /api/File/delete/:id 删除
38 | * @apiDescription 删除
39 | * @apiName delete
40 | * @apiHeader {String} Authorization token
41 | * @apiParam {Number} id
42 | * @apiSampleRequest /api/File/delete
43 | * @apiGroup File
44 | * @apiVersion 0.0.1
45 | */
46 | router.delete('/delete/:id', ValidateFile.delete, File.delete)
47 |
48 | /**
49 | * 获取文件信息
50 | * @api {get} /api/File/getRow 获取文件信息
51 | * @apiDescription 获取文件信息
52 | * @apiName getRow
53 | * @apiHeader {String} Authorization token
54 | * @apiParam {Number} id
55 | * @apiSampleRequest /api/File/getRow
56 | * @apiGroup File
57 | * @apiVersion 0.0.1
58 | */
59 | router.get('/getRow/:id', ValidateFile.getRow, File.getRow)
60 | /**
61 | * 获取文件列表
62 | * @api {get} /api/File/getList 获取文件列表
63 | * @apiDescription 获取文件列表
64 | * @apiName getList
65 | * @apiHeader {String} Authorization token
66 | * @apiParam (path参数) {Number} curPage
67 | * @apiParam (path参数) {Number} pageSize
68 | * @apiParam (path参数) {Number} f_id 目录ID
69 | * @apiSampleRequest /api/File/getList
70 | * @apiGroup File
71 | * @apiVersion 0.0.1
72 | */
73 | router.get('/getList', ValidateFile.getList, File.getList)
74 | /**
75 | * 获取所有文件
76 | * @api {get} /api/File/getAll 获取所有文件
77 | * @apiDescription 获取所有文件
78 | * @apiName getAll
79 | * @apiParam {Number} type
80 | * @apiHeader {String} Authorization token
81 | * @apiSampleRequest /api/File/getAll
82 | * @apiParam (path参数) {Number} f_id 目录ID
83 | * @apiGroup File
84 | * @apiVersion 0.0.1
85 | */
86 | router.get('/getAll', ValidateFile.getAll, File.getAll)
87 |
88 | export default router
89 |
--------------------------------------------------------------------------------
/router/topic.js:
--------------------------------------------------------------------------------
1 | import express from 'express'
2 | import Topic from '../controller/Topic'
3 | import ValidateTopic from '../validate/Topic'
4 | const router = express.Router()
5 |
6 | /**
7 | * 创建
8 | * @api {POST} /api/Topic/create 创建
9 | * @apiDescription 创建标签类型
10 | * @apiName create
11 | * @apiHeader {String} Authorization token
12 | * @apiParam (参数) {Number} type_id 类型ID
13 | * @apiParam (参数) {String} name 名称
14 | * @apiParam (参数) {String} sort 排序
15 | * @apiParam (参数) {String} desc 描述
16 | * @apiSampleRequest /api/Topic/create
17 | * @apiGroup Topic
18 | * @apiVersion 0.0.1
19 | */
20 | router.post('/create', ValidateTopic.create, Topic.create)
21 | /**
22 | * 编辑
23 | * @api {put} /api/Topic/update 编辑
24 | * @apiDescription 编辑
25 | * @apiName update
26 | * @apiHeader {String} Authorization token
27 | * @apiParam (参数) {Number} id
28 | * @apiParam (参数) {Number} type_id 类型ID
29 | * @apiParam (参数) {String} name 名称
30 | * @apiParam (参数) {String} sort 排序
31 | * @apiParam (参数) {String} desc 描述
32 | * @apiSampleRequest /api/Topic/update
33 | * @apiGroup Topic
34 | * @apiVersion 0.0.1
35 | */
36 | router.put('/update', ValidateTopic.update, Topic.update)
37 | /**
38 | * 删除
39 | * @api {delete} /api/Topic/delete/:id 删除
40 | * @apiDescription 删除
41 | * @apiName delete
42 | * @apiHeader {String} Authorization token
43 | * @apiParam {Number} id
44 | * @apiSampleRequest /api/Topic/delete
45 | * @apiGroup Topic
46 | * @apiVersion 0.0.1
47 | */
48 | router.delete('/delete/:id', ValidateTopic.delete, Topic.delete)
49 |
50 | /**
51 | * 获取订阅信息
52 | * @api {get} /api/Topic/getRow 获取标签类型信息
53 | * @apiDescription 获取标签类型信息
54 | * @apiName getRow
55 | * @apiHeader {String} Authorization token
56 | * @apiParam {Number} id
57 | * @apiSampleRequest /api/Topic/getRow
58 | * @apiGroup Topic
59 | * @apiVersion 0.0.1
60 | */
61 | router.get('/getRow/:id', ValidateTopic.getRow, Topic.getRow)
62 | /**
63 | * 获取订阅列表
64 | * @api {get} /api/Topic/getList 获取标签类型列表
65 | * @apiDescription 获取标签类型列表
66 | * @apiName getList
67 | * @apiHeader {String} Authorization token
68 | * @apiParam (path参数) {Number} curPage
69 | * @apiParam (path参数) {Number} pageSize
70 | * @apiSampleRequest /api/Topic/getList
71 | * @apiGroup Topic
72 | * @apiVersion 0.0.1
73 | */
74 | router.get('/getList', ValidateTopic.getList, Topic.getList)
75 | /**
76 | * 获取所有标签类型
77 | * @api {get} /api/Topic/getAll 获取所有标签类型
78 | * @apiDescription 获取所有标签类型
79 | * @apiName getAll
80 | * @apiParam {Number} type
81 | * @apiHeader {String} Authorization token
82 | * @apiSampleRequest /api/Topic/getAll
83 | * @apiGroup Topic
84 | * @apiVersion 0.0.1
85 | */
86 | router.get('/getAll', ValidateTopic.getAll, Topic.getAll)
87 |
88 | export default router
89 |
--------------------------------------------------------------------------------
/router/folder.js:
--------------------------------------------------------------------------------
1 | import express from 'express'
2 | import Folder from '../controller/Folder'
3 | import ValidateFolder from '../validate/Folder'
4 | const router = express.Router()
5 |
6 | /**
7 | * 创建
8 | * @api {POST} /api/Folder/create 创建
9 | * @apiDescription 创建目录
10 | * @apiName create
11 | * @apiHeader {String} Authorization token
12 | * @apiParam (参数) {Number} pid 父ID
13 | * @apiParam (参数) {String} name 目录名称
14 | * @apiParam (参数) {String} sort 排序
15 | * @apiParam (参数) {String} desc 描述
16 | * @apiSampleRequest /api/Folder/create
17 | * @apiGroup Folder
18 | * @apiVersion 0.0.1
19 | */
20 | router.post('/create', ValidateFolder.create, Folder.create)
21 | /**
22 | * 编辑
23 | * @api {put} /api/Folder/update 编辑
24 | * @apiDescription 编辑
25 | * @apiName update
26 | * @apiHeader {String} Authorization token
27 | * @apiParam (参数) {Number} id
28 | * @apiParam (参数) {Number} pid 父ID
29 | * @apiParam (参数) {String} name 目录名称
30 | * @apiParam (参数) {String} sort 排序
31 | * @apiParam (参数) {String} desc 描述
32 | * @apiSampleRequest /api/Folder/update
33 | * @apiGroup Folder
34 | * @apiVersion 0.0.1
35 | */
36 | router.put('/update', ValidateFolder.update, Folder.update)
37 | /**
38 | * 删除
39 | * @api {delete} /api/Folder/delete/:id 删除
40 | * @apiDescription 删除
41 | * @apiName delete
42 | * @apiHeader {String} Authorization token
43 | * @apiParam {Number} id
44 | * @apiSampleRequest /api/Folder/delete
45 | * @apiGroup Folder
46 | * @apiVersion 0.0.1
47 | */
48 | router.delete('/delete/:id', ValidateFolder.delete, Folder.delete)
49 |
50 | /**
51 | * 获取目录信息
52 | * @api {get} /api/Folder/getRow 获取目录信息
53 | * @apiDescription 获取目录信息
54 | * @apiName getRow
55 | * @apiHeader {String} Authorization token
56 | * @apiParam {Number} id
57 | * @apiSampleRequest /api/Folder/getRow
58 | * @apiGroup Folder
59 | * @apiVersion 0.0.1
60 | */
61 | router.get('/getRow/:id', ValidateFolder.getRow, Folder.getRow)
62 | /**
63 | * 获取目录列表
64 | * @api {get} /api/Folder/getList 获取目录列表
65 | * @apiDescription 获取目录列表
66 | * @apiName getList
67 | * @apiHeader {String} Authorization token
68 | * @apiParam (path参数) {Number} curPage
69 | * @apiParam (path参数) {Number} pageSize
70 | * @apiSampleRequest /api/Folder/getList
71 | * @apiGroup Folder
72 | * @apiVersion 0.0.1
73 | */
74 | router.get('/getList', ValidateFolder.getList, Folder.getList)
75 | /**
76 | * 获取所有目录
77 | * @api {get} /api/Folder/getAll 获取所有目录
78 | * @apiDescription 获取所有目录
79 | * @apiName getAll
80 | * @apiParam {Number} type
81 | * @apiHeader {String} Authorization token
82 | * @apiSampleRequest /api/Folder/getAll
83 | * @apiGroup Folder
84 | * @apiVersion 0.0.1
85 | */
86 | router.get('/getAll', ValidateFolder.getAll, Folder.getAll)
87 |
88 | export default router
89 |
--------------------------------------------------------------------------------
/model/Base.js:
--------------------------------------------------------------------------------
1 | import mysql from 'mysql'
2 | import utils from '../lib/js/utils'
3 |
4 | class Base{
5 | constructor () {
6 | this.utils = utils
7 | }
8 | joinStr (type, obj) {
9 | let str = ''
10 | switch (type) {
11 | case 'set':
12 | for (let key in obj) {
13 | let separated = str ? ',' : ''
14 | // str += `${separated} ${key} = ${mysql.escape(obj[key])} `
15 | str += separated + '`' + key + '` = ' + mysql.escape(obj[key])
16 | }
17 | return str
18 | case 'get':
19 | // TODO: 暂时只对一般条件查询和模糊查询处理
20 | for (let key in obj) {
21 | // 参数跳过, and相关字符串拼接
22 | if (['curPage', 'pageSize', 'or', 'larger', 'lessThan'].indexOf(key) === -1) {
23 | // 开始拼接SQL
24 | if (obj['like'] && obj['like'].indexOf(key) !== -1) {
25 | // str += `and ${key} like ${mysql.escape('%' + obj[key] + '%')} `
26 | str += ' and `' + key + '` like' + mysql.escape('%' + obj[key] + '%')
27 | } else if (key !== 'like') {
28 | // str += `and ${key} = ${mysql.escape(obj[key])} `
29 | str += ' and `' + key + '` = ' + mysql.escape(obj[key])
30 | }
31 | }
32 | // 或相关字符串拼接
33 | if (key === 'or') {
34 | let or = obj.or, keyWord = 'and', index = 0
35 | for (let key in or) {
36 | if (index > 0) {
37 | keyWord = 'or'
38 | }
39 | index++
40 | str += ' ' + keyWord + ' `' + key + '` = ' + mysql.escape(or[key])
41 | }
42 | }
43 | // 大于
44 | if (key === 'larger') {
45 | let larger = obj.larger, keyWord = 'and'
46 | for (let key in larger) {
47 | str += ' ' + keyWord + ' `' + key + '` > ' + mysql.escape(larger[key])
48 | }
49 | }
50 | // 小于
51 | if (key === 'lessThan') {
52 | let lessThan = obj.lessThan, keyWord = 'and', index = 0
53 | for (let key in lessThan) {
54 | str += ' ' + keyWord + ' `' + key + '` < ' + mysql.escape(lessThan[key])
55 | }
56 | }
57 | }
58 | return str
59 | case 'ORDER BY':
60 | if (obj.DESC.length > 0 || obj.other.length > 0) {
61 | str = 'ORDER BY '
62 | }
63 | obj.DESC = obj.DESC || []
64 | obj.other = obj.other || []
65 | obj.DESC.forEach(val => {
66 | str += `${val} DESC,`
67 | })
68 | obj.other.forEach(val => {
69 | str += `${val},`
70 | })
71 | // 删除最后的逗号
72 | str = str.substr(0, str.length - 1)
73 | return str
74 | }
75 | }
76 | }
77 |
78 | export default Base
79 |
--------------------------------------------------------------------------------
/router/tagType.js:
--------------------------------------------------------------------------------
1 | import express from 'express'
2 | import TagType from '../controller/TagType'
3 | import ValidateTagType from '../validate/TagType'
4 | const router = express.Router()
5 |
6 | /**
7 | * 创建
8 | * @api {POST} /api/TagType/create 创建
9 | * @apiDescription 创建标签
10 | * @apiName create
11 | * @apiHeader {String} Authorization token
12 | * @apiParam (参数) {Number} type_id 类型ID
13 | * @apiParam (参数) {String} name 名称
14 | * @apiParam (参数) {String} wikipedia 标签百科
15 | * @apiParam (参数) {String} sort 排序
16 | * @apiParam (参数) {String} desc 描述
17 | * @apiSampleRequest /api/TagType/create
18 | * @apiGroup TagType
19 | * @apiVersion 0.0.1
20 | */
21 | router.post('/create', ValidateTagType.create, TagType.create)
22 | /**
23 | * 编辑
24 | * @api {put} /api/TagType/update 编辑
25 | * @apiDescription 编辑
26 | * @apiName update
27 | * @apiHeader {String} Authorization token
28 | * @apiParam (参数) {Number} id
29 | * @apiParam (参数) {Number} type_id 类型ID
30 | * @apiParam (参数) {String} name 名称
31 | * @apiParam (参数) {String} wikipedia 标签百科
32 | * @apiParam (参数) {String} sort 排序
33 | * @apiParam (参数) {String} desc 描述
34 | * @apiSampleRequest /api/TagType/update
35 | * @apiGroup TagType
36 | * @apiVersion 0.0.1
37 | */
38 | router.put('/update', ValidateTagType.update, TagType.update)
39 | /**
40 | * 删除
41 | * @api {delete} /api/TagType/delete/:id 删除
42 | * @apiDescription 删除
43 | * @apiName delete
44 | * @apiHeader {String} Authorization token
45 | * @apiParam {Number} id
46 | * @apiSampleRequest /api/TagType/delete
47 | * @apiGroup TagType
48 | * @apiVersion 0.0.1
49 | */
50 | router.delete('/delete/:id', ValidateTagType.delete, TagType.delete)
51 |
52 | /**
53 | * 获取标签信息
54 | * @api {get} /api/TagType/getRow 获取标签信息
55 | * @apiDescription 获取标签信息
56 | * @apiName getRow
57 | * @apiHeader {String} Authorization token
58 | * @apiParam {Number} id
59 | * @apiSampleRequest /api/TagType/getRow
60 | * @apiGroup TagType
61 | * @apiVersion 0.0.1
62 | */
63 | router.get('/getRow/:id', ValidateTagType.getRow, TagType.getRow)
64 | /**
65 | * 获取标签列表
66 | * @api {get} /api/TagType/getList 获取标签列表
67 | * @apiDescription 获取标签列表
68 | * @apiName getList
69 | * @apiHeader {String} Authorization token
70 | * @apiParam (path参数) {Number} curPage
71 | * @apiParam (path参数) {Number} pageSize
72 | * @apiSampleRequest /api/TagType/getList
73 | * @apiGroup TagType
74 | * @apiVersion 0.0.1
75 | */
76 | router.get('/getList', ValidateTagType.getList, TagType.getList)
77 | /**
78 | * 获取所有标签
79 | * @api {get} /api/TagType/getAll 获取所有标签
80 | * @apiDescription 获取所有标签
81 | * @apiName getAll
82 | * @apiParam {Number} type
83 | * @apiHeader {String} Authorization token
84 | * @apiSampleRequest /api/TagType/getAll
85 | * @apiGroup TagType
86 | * @apiVersion 0.0.1
87 | */
88 | router.get('/getAll', ValidateTagType.getAll, TagType.getAll)
89 |
90 | export default router
91 |
--------------------------------------------------------------------------------
/controller/Base.js:
--------------------------------------------------------------------------------
1 | import TokenModel from '../model/Token'
2 | import UserModel from '../model/User'
3 | import JWT from 'jsonwebtoken'
4 | import utils from '../lib/js/utils'
5 | import path from 'path'
6 | import fs from 'fs'
7 | import NodeLog from '../log/index'
8 |
9 | class Base{
10 | constructor () {
11 | this.utils = utils
12 | }
13 | // 获取到用户信息
14 | async getUserInfo (req) {
15 | let userInfo = {}, result
16 | JWT.verify(req.headers.authorization, 'BBS', (error, decoded) => {
17 | if (error) {
18 | return {}
19 | }
20 | userInfo = decoded
21 | })
22 | // 直接从数据库获取,能保证用户最新的数据
23 | result = await UserModel.getRow({get: {id: userInfo.id, flag: 1}})
24 | return result[0]
25 | }
26 | // 获取客户端IP
27 | getClientIp (req) {
28 | var ipAddress, forwardedIpsStr = req.header('x-forwarded-for')
29 | if (forwardedIpsStr) {
30 | var forwardedIps = forwardedIpsStr.split(',')
31 | ipAddress = forwardedIps[0]
32 | }
33 | if (!ipAddress) {
34 | ipAddress = req.connection.remoteAddress
35 | }
36 | return ipAddress
37 | }
38 | // 获取服务端地址
39 | getServiceAddr (req) {
40 | const headers = req.headers
41 | return req.protocol + '://' + headers.host
42 | }
43 | // 查询路径是否存在
44 | async getStat (path) {
45 | return new Promise((resolve, reject) => {
46 | fs.stat(path, (err, stats) => {
47 | if (err) {
48 | resolve(false)
49 | } else {
50 | resolve(stats)
51 | }
52 | })
53 | })
54 | }
55 | // 创建路径
56 | async mkdir(dir){
57 | return new Promise((resolve, reject) => {
58 | fs.mkdir(dir, err => {
59 | if (err) {
60 | resolve(false)
61 | } else {
62 | resolve(true)
63 | }
64 | })
65 | })
66 | }
67 | // 路径是否存在,不存在则创建
68 | async dirExists (dir) {
69 | let isExists = await this.getStat(dir), tempDir, status, mkdirStatus
70 | // 如果该路径存在且不是文件,返回true
71 | if (isExists && isExists.isDirectory()) {
72 | return true
73 | } else if (isExists) { // 如果该路径存在但是文件,返回false
74 | return false
75 | }
76 | // 如果该路径不存在
77 | tempDir = path.parse(dir).dir // 拿到上级路径
78 | // 递归判断,如果上级目录也不存在,则会代码会在此处继续循环执行,直到目录存在
79 | status = await this.dirExists(tempDir)
80 | if (status) {
81 | mkdirStatus = await this.mkdir(dir)
82 | }
83 | return mkdirStatus
84 | }
85 | // TODO: 异常处理, 有时间扩展, 从这里转发到异常处理模块处理
86 | handleException (req, res, e) {
87 | // 写入日志
88 | NodeLog.writeLog(`\n异常发生时间${new Date()}: \n${e}`)
89 |
90 | res.json({
91 | code: e.errno || 20501,
92 | success: false,
93 | content: e,
94 | message: '服务器内部错误'
95 | })
96 | }
97 | }
98 |
99 | export default Base
100 |
--------------------------------------------------------------------------------
/router/role.js:
--------------------------------------------------------------------------------
1 | import express from 'express'
2 | import Role from '../controller/Role'
3 | import ValidateRole from '../validate/Role'
4 | const router = express.Router()
5 |
6 | /**
7 | * 创建
8 | * @api {POST} /api/Role/create 创建
9 | * @apiDescription 创建角色
10 | * @apiName create
11 | * @apiHeader {String} Authorization token
12 | * @apiParam (参数) {Number} pid 父ID
13 | * @apiParam (参数) {String} name 角色名称
14 | * @apiParam (参数) {String} columns 专栏数量
15 | * @apiParam (参数) {Number} users 可创建用户数
16 | * @apiParam (参数) {Number} desc 描述
17 | * @apiParam (参数) {String} status 状态: 0:停用,1:启用(默认为1)
18 | * @apiSampleRequest /api/Role/create
19 | * @apiGroup Role
20 | * @apiVersion 0.0.1
21 | */
22 | router.post('/create', ValidateRole.create, Role.create)
23 | /**
24 | * 编辑
25 | * @api {put} /api/Role/update 编辑
26 | * @apiDescription 编辑
27 | * @apiName update
28 | * @apiHeader {String} Authorization token
29 | * @apiParam (参数) {Number} id
30 | * @apiParam (参数) {Number} pid 父ID
31 | * @apiParam (参数) {String} name 角色名称
32 | * @apiParam (参数) {String} columns 专栏数量
33 | * @apiParam (参数) {Number} users 可创建用户数
34 | * @apiParam (参数) {Number} desc 描述
35 | * @apiParam (参数) {String} status 状态: 0:停用,1:启用(默认为1)
36 | * @apiSampleRequest /api/Role/update
37 | * @apiGroup Role
38 | * @apiVersion 0.0.1
39 | */
40 | router.put('/update', ValidateRole.update, Role.update)
41 | /**
42 | * 删除
43 | * @api {delete} /api/Role/delete/:id 删除
44 | * @apiDescription 删除
45 | * @apiName delete
46 | * @apiHeader {String} Authorization token
47 | * @apiParam {Number} id
48 | * @apiSampleRequest /api/Role/delete
49 | * @apiGroup Role
50 | * @apiVersion 0.0.1
51 | */
52 | router.delete('/delete/:id', ValidateRole.delete, Role.delete)
53 |
54 | /**
55 | * 获取角色信息
56 | * @api {get} /api/Role/getRow 获取角色信息
57 | * @apiDescription 获取角色信息
58 | * @apiName getRow
59 | * @apiHeader {String} Authorization token
60 | * @apiParam {Number} id
61 | * @apiSampleRequest /api/Role/getRow
62 | * @apiGroup Role
63 | * @apiVersion 0.0.1
64 | */
65 | router.get('/getRow/:id', ValidateRole.getRow, Role.getRow)
66 | /**
67 | * 获取角色列表
68 | * @api {get} /api/Role/getList 获取角色列表
69 | * @apiDescription 获取角色列表
70 | * @apiName getList
71 | * @apiHeader {String} Authorization token
72 | * @apiParam (path参数) {Number} curPage
73 | * @apiParam (path参数) {Number} pageSize
74 | * @apiParam (path参数) {String} name 角色名称
75 | * @apiSampleRequest /api/Role/getList
76 | * @apiGroup Role
77 | * @apiVersion 0.0.1
78 | */
79 | router.get('/getList', ValidateRole.getList, Role.getList)
80 | /**
81 | * 获取所有角色
82 | * @api {get} /api/Role/getAll 获取所有角色
83 | * @apiDescription 获取所有角色
84 | * @apiName getAll
85 | * @apiHeader {String} Authorization token
86 | * @apiSampleRequest /api/Role/getAll
87 | * @apiGroup Role
88 | * @apiVersion 0.0.1
89 | */
90 | router.get('/getAll', ValidateRole.getAll, Role.getAll)
91 |
92 | export default router
93 |
--------------------------------------------------------------------------------
/router/index.js:
--------------------------------------------------------------------------------
1 | import Authority from '../controller/Authority'
2 | import user from './user'
3 | import area from './area'
4 | import role from './role'
5 | import menu from './menu'
6 | import dataPerms from './dataPerms'
7 | import roleRelation from './roleRelation'
8 | import log from './log'
9 | import folder from './folder'
10 | import file from './file'
11 | import tag from './tag'
12 | import tagType from './tagType'
13 | import tagRelation from './tagRelation'
14 | import carousel from './carousel'
15 | import techSquare from './techSquare'
16 | import notices from './notices'
17 | import question from './question'
18 | import column from './column'
19 | import article from './article'
20 | import articleComments from './articleComments'
21 | import draft from './draft'
22 | import count from './count'
23 | import charts from './charts'
24 | import topic from './topic'
25 |
26 | /**
27 | * 路由中间件
28 | * 第一层验证Token
29 | * 第二层验证用户是否有操作权限
30 | * 第三层验证参数, 验证成功后再进行事件处理
31 | */
32 | export default app => {
33 | // 图表数据
34 | app.use('/api/charts', Authority.checkToken, Authority.permissions, charts)
35 | // 数据统计
36 | app.use('/api/count', Authority.checkToken, Authority.permissions, count)
37 | // 运维中心
38 | app.use('/api/question', Authority.checkToken, Authority.permissions, question)
39 | app.use('/api/column', Authority.checkToken, Authority.permissions, column)
40 | app.use('/api/article', Authority.checkToken, Authority.permissions, article)
41 | app.use('/api/articleComments', Authority.checkToken, Authority.permissions, articleComments)
42 | app.use('/api/draft', Authority.checkToken, Authority.permissions, draft)
43 | // 论坛配置
44 | app.use('/api/carousel', Authority.checkToken, Authority.permissions, carousel)
45 | app.use('/api/techSquare', Authority.checkToken, Authority.permissions, techSquare)
46 | app.use('/api/notices', Authority.checkToken, Authority.permissions, notices)
47 | app.use('/api/tagRelation', Authority.checkToken, Authority.permissions, tagRelation)
48 | app.use('/api/tagType', Authority.checkToken, Authority.permissions, tagType)
49 | app.use('/api/tag', Authority.checkToken, Authority.permissions, tag)
50 | // 文件库
51 | app.use('/api/folder', Authority.checkToken, Authority.permissions, folder)
52 | app.use('/api/file', Authority.checkToken, Authority.permissions, file)
53 | // 系统设置
54 | app.use('/api/user', Authority.checkToken, Authority.permissions, user)
55 | app.use('/api/area', Authority.checkToken, Authority.permissions, area)
56 | app.use('/api/role', Authority.checkToken, Authority.permissions, role)
57 | app.use('/api/menu', Authority.checkToken, Authority.permissions, menu)
58 | app.use('/api/dataPerms', Authority.checkToken, Authority.permissions, dataPerms)
59 | app.use('/api/roleRelation', Authority.checkToken, Authority.permissions, roleRelation)
60 | app.use('/api/log', Authority.checkToken, Authority.permissions, log)
61 | app.use('/api/topic', Authority.checkToken, Authority.permissions, topic)
62 | }
63 |
--------------------------------------------------------------------------------
/router/column.js:
--------------------------------------------------------------------------------
1 | import express from 'express'
2 | import Column from '../controller/Column'
3 | import ValidateColumn from '../validate/Column'
4 | const router = express.Router()
5 |
6 | /**
7 | * 创建
8 | * @api {POST} /api/Column/create 创建
9 | * @apiDescription 创建专栏
10 | * @apiName create
11 | * @apiHeader {String} Authorization token
12 | * @apiParam (参数) {String} title 标题
13 | * @apiParam (参数) {String} image 图片地址
14 | * @apiParam (参数) {Number} click 点击触发类型
15 | * @apiParam (参数) {String} href 跳转地址
16 | * @apiParam (参数) {Number} sort 排序
17 | * @apiParam (参数) {String} desc 描述
18 | * @apiParam (参数) {Number} status 状态
19 | * @apiSampleRequest /api/Column/create
20 | * @apiGroup Column
21 | * @apiVersion 0.0.1
22 | */
23 | router.post('/create', ValidateColumn.create, Column.create)
24 | /**
25 | * 编辑
26 | * @api {put} /api/Column/update 编辑
27 | * @apiDescription 编辑
28 | * @apiName update
29 | * @apiHeader {String} Authorization token
30 | * @apiParam (参数) {Number} id
31 | * @apiParam (参数) {String} title 标题
32 | * @apiParam (参数) {String} image 图片地址
33 | * @apiParam (参数) {Number} click 点击触发类型
34 | * @apiParam (参数) {String} href 跳转地址
35 | * @apiParam (参数) {Number} sort 排序
36 | * @apiParam (参数) {String} desc 描述
37 | * @apiParam (参数) {Number} status 状态
38 | * @apiSampleRequest /api/Column/update
39 | * @apiGroup Column
40 | * @apiVersion 0.0.1
41 | */
42 | router.put('/update', ValidateColumn.update, Column.update)
43 | /**
44 | * 删除
45 | * @api {delete} /api/Column/delete/:id 删除
46 | * @apiDescription 删除
47 | * @apiName delete
48 | * @apiHeader {String} Authorization token
49 | * @apiParam {Number} id
50 | * @apiSampleRequest /api/Column/delete
51 | * @apiGroup Column
52 | * @apiVersion 0.0.1
53 | */
54 | router.delete('/delete/:id', ValidateColumn.delete, Column.delete)
55 |
56 | /**
57 | * 获取专栏信息
58 | * @api {get} /api/Column/getRow 获取专栏信息
59 | * @apiDescription 获取专栏信息
60 | * @apiName getRow
61 | * @apiHeader {String} Authorization token
62 | * @apiParam {Number} id
63 | * @apiSampleRequest /api/Column/getRow
64 | * @apiGroup Column
65 | * @apiVersion 0.0.1
66 | */
67 | router.get('/getRow/:id', ValidateColumn.getRow, Column.getRow)
68 | /**
69 | * 获取专栏列表
70 | * @api {get} /api/Column/getList 获取专栏列表
71 | * @apiDescription 获取专栏列表
72 | * @apiName getList
73 | * @apiHeader {String} Authorization token
74 | * @apiParam (path参数) {Number} curPage
75 | * @apiParam (path参数) {Number} pageSize
76 | * @apiSampleRequest /api/Column/getList
77 | * @apiGroup Column
78 | * @apiVersion 0.0.1
79 | */
80 | router.get('/getList', ValidateColumn.getList, Column.getList)
81 | /**
82 | * 获取所有专栏
83 | * @api {get} /api/Column/getAll 获取所有专栏
84 | * @apiDescription 获取所有专栏
85 | * @apiName getAll
86 | * @apiParam {Number} type
87 | * @apiHeader {String} Authorization token
88 | * @apiSampleRequest /api/Column/getAll
89 | * @apiGroup Column
90 | * @apiVersion 0.0.1
91 | */
92 | router.get('/getAll', ValidateColumn.getAll, Column.getAll)
93 |
94 | export default router
95 |
--------------------------------------------------------------------------------
/validate/File.js:
--------------------------------------------------------------------------------
1 | import Base from './Base'
2 |
3 | class Menu extends Base{
4 | constructor () {
5 | super()
6 | this.upload = this.upload.bind(this)
7 | this.update = this.update.bind(this)
8 | this.delete = this.delete.bind(this)
9 | this.getRow = this.getRow.bind(this)
10 | this.getList = this.getList.bind(this)
11 | this.getAll = this.getAll.bind(this)
12 | }
13 | async upload (req, res, next) {
14 | const params = req.body,
15 | arr = [
16 | {label: '目录ID', value: params.fid, rules: ['notnull', 'number']},
17 | ],
18 | result = this.check(arr)
19 | if (!result.success) {
20 | res.json({
21 | code: 20301,
22 | success: false,
23 | message: result.message
24 | })
25 | return
26 | }
27 | next()
28 | }
29 | async update (req, res, next) {
30 | const params = req.body,
31 | arr = [
32 | {label: 'ID', value: params.id, rules: ['notnull', 'number']},
33 | {label: '目录ID', value: params.f_id, rules: ['notnull', 'number']}
34 | ],
35 | result = this.check(arr)
36 | if (!result.success) {
37 | res.json({
38 | code: 20301,
39 | success: false,
40 | message: result.message
41 | })
42 | return
43 | }
44 | next()
45 | }
46 | async delete (req, res, next) {
47 | const ID = req.params.id,
48 | arr = [
49 | {label: 'ID', value: ID, rules: ['notnull']}
50 | ],
51 | result = this.check(arr)
52 | if (!result.success) {
53 | res.json({
54 | code: 20301,
55 | success: false,
56 | message: result.message
57 | })
58 | return
59 | }
60 | next()
61 | }
62 | async getRow (req, res, next) {
63 | const ID = req.params.id,
64 | arr = [
65 | {label: 'ID', value: ID, rules: ['notnull']}
66 | ],
67 | result = this.check(arr)
68 | if (!result.success) {
69 | res.json({
70 | code: 20301,
71 | success: false,
72 | message: result.message
73 | })
74 | return
75 | }
76 | next()
77 | }
78 | async getList (req, res, next) {
79 | const data = req.query,
80 | arr = [
81 | {label: 'curPage', value: data.curPage, rules: ['notnull', 'number']},
82 | {label: 'pageSize', value: data.curPage, rules: ['notnull', 'number']}
83 | ],
84 | result = this.check(arr)
85 | if (!result.success) {
86 | res.json({
87 | code: 20301,
88 | success: false,
89 | message: result.message
90 | })
91 | return
92 | }
93 | next()
94 | }
95 | async getRoleMenu (req, res, next) {
96 | next()
97 | }
98 | async getAll (req, res, next) {
99 | next()
100 | }
101 | }
102 |
103 | export default new Menu()
104 |
--------------------------------------------------------------------------------
/router/article.js:
--------------------------------------------------------------------------------
1 | import express from 'express'
2 | import Article from '../controller/Article'
3 | import ValidateArticle from '../validate/Article'
4 | const router = express.Router()
5 |
6 | /**
7 | * 创建
8 | * @api {POST} /api/Article/create 创建
9 | * @apiDescription 创建文章
10 | * @apiName create
11 | * @apiHeader {String} Authorization token
12 | * @apiParam (参数) {String} title 标题
13 | * @apiParam (参数) {String} image 图片地址
14 | * @apiParam (参数) {Number} click 点击触发类型
15 | * @apiParam (参数) {String} href 跳转地址
16 | * @apiParam (参数) {Number} sort 排序
17 | * @apiParam (参数) {String} desc 描述
18 | * @apiParam (参数) {Number} status 状态
19 | * @apiSampleRequest /api/Article/create
20 | * @apiGroup Article
21 | * @apiVersion 0.0.1
22 | */
23 | router.post('/create', ValidateArticle.create, Article.create)
24 | /**
25 | * 编辑
26 | * @api {put} /api/Article/update 编辑
27 | * @apiDescription 编辑
28 | * @apiName update
29 | * @apiHeader {String} Authorization token
30 | * @apiParam (参数) {Number} id
31 | * @apiParam (参数) {String} title 标题
32 | * @apiParam (参数) {String} image 图片地址
33 | * @apiParam (参数) {Number} click 点击触发类型
34 | * @apiParam (参数) {String} href 跳转地址
35 | * @apiParam (参数) {Number} sort 排序
36 | * @apiParam (参数) {String} desc 描述
37 | * @apiParam (参数) {Number} status 状态
38 | * @apiSampleRequest /api/Article/update
39 | * @apiGroup Article
40 | * @apiVersion 0.0.1
41 | */
42 | router.put('/update', ValidateArticle.update, Article.update)
43 | /**
44 | * 删除
45 | * @api {delete} /api/Article/delete/:id 删除
46 | * @apiDescription 删除
47 | * @apiName delete
48 | * @apiHeader {String} Authorization token
49 | * @apiParam {Number} id
50 | * @apiSampleRequest /api/Article/delete
51 | * @apiGroup Article
52 | * @apiVersion 0.0.1
53 | */
54 | router.delete('/delete/:id', ValidateArticle.delete, Article.delete)
55 |
56 | /**
57 | * 获取文章信息
58 | * @api {get} /api/Article/getRow 获取文章信息
59 | * @apiDescription 获取文章信息
60 | * @apiName getRow
61 | * @apiHeader {String} Authorization token
62 | * @apiParam {Number} id
63 | * @apiSampleRequest /api/Article/getRow
64 | * @apiGroup Article
65 | * @apiVersion 0.0.1
66 | */
67 | router.get('/getRow/:id', ValidateArticle.getRow, Article.getRow)
68 | /**
69 | * 获取文章列表
70 | * @api {get} /api/Article/getList 获取文章列表
71 | * @apiDescription 获取文章列表
72 | * @apiName getList
73 | * @apiHeader {String} Authorization token
74 | * @apiParam (path参数) {Number} curPage
75 | * @apiParam (path参数) {Number} pageSize
76 | * @apiSampleRequest /api/Article/getList
77 | * @apiGroup Article
78 | * @apiVersion 0.0.1
79 | */
80 | router.get('/getList', ValidateArticle.getList, Article.getList)
81 | /**
82 | * 获取所有文章
83 | * @api {get} /api/Article/getAll 获取所有文章
84 | * @apiDescription 获取所有文章
85 | * @apiName getAll
86 | * @apiParam {Number} type
87 | * @apiHeader {String} Authorization token
88 | * @apiSampleRequest /api/Article/getAll
89 | * @apiGroup Article
90 | * @apiVersion 0.0.1
91 | */
92 | router.get('/getAll', ValidateArticle.getAll, Article.getAll)
93 |
94 | export default router
95 |
--------------------------------------------------------------------------------
/router/question.js:
--------------------------------------------------------------------------------
1 | import express from 'express'
2 | import Question from '../controller/Question'
3 | import ValidateQuestion from '../validate/Question'
4 | const router = express.Router()
5 |
6 | /**
7 | * 创建
8 | * @api {POST} /api/Question/create 创建
9 | * @apiDescription 创建问题
10 | * @apiName create
11 | * @apiHeader {String} Authorization token
12 | * @apiParam (参数) {Number} pid 父ID
13 | * @apiParam (参数) {String} name 问题名称
14 | * @apiParam (参数) {String} columns 专栏数量
15 | * @apiParam (参数) {Number} users 可创建用户数
16 | * @apiParam (参数) {Number} desc 描述
17 | * @apiParam (参数) {String} status 状态: 0:停用,1:启用(默认为1)
18 | * @apiSampleRequest /api/Question/create
19 | * @apiGroup Question
20 | * @apiVersion 0.0.1
21 | */
22 | router.post('/create', ValidateQuestion.create, Question.create)
23 | /**
24 | * 编辑
25 | * @api {put} /api/Question/update 编辑
26 | * @apiDescription 编辑
27 | * @apiName update
28 | * @apiHeader {String} Authorization token
29 | * @apiParam (参数) {Number} id
30 | * @apiParam (参数) {Number} pid 父ID
31 | * @apiParam (参数) {String} name 问题名称
32 | * @apiParam (参数) {String} columns 专栏数量
33 | * @apiParam (参数) {Number} users 可创建用户数
34 | * @apiParam (参数) {Number} desc 描述
35 | * @apiParam (参数) {String} status 状态: 0:停用,1:启用(默认为1)
36 | * @apiSampleRequest /api/Question/update
37 | * @apiGroup Question
38 | * @apiVersion 0.0.1
39 | */
40 | router.put('/update', ValidateQuestion.update, Question.update)
41 | /**
42 | * 删除
43 | * @api {delete} /api/Question/delete/:id 删除
44 | * @apiDescription 删除
45 | * @apiName delete
46 | * @apiHeader {String} Authorization token
47 | * @apiParam {Number} id
48 | * @apiSampleRequest /api/Question/delete
49 | * @apiGroup Question
50 | * @apiVersion 0.0.1
51 | */
52 | router.delete('/delete/:id', ValidateQuestion.delete, Question.delete)
53 |
54 | /**
55 | * 获取问题信息
56 | * @api {get} /api/Question/getRow 获取问题信息
57 | * @apiDescription 获取问题信息
58 | * @apiName getRow
59 | * @apiHeader {String} Authorization token
60 | * @apiParam {Number} id
61 | * @apiSampleRequest /api/Question/getRow
62 | * @apiGroup Question
63 | * @apiVersion 0.0.1
64 | */
65 | router.get('/getRow/:id', ValidateQuestion.getRow, Question.getRow)
66 | /**
67 | * 获取问题列表
68 | * @api {get} /api/Question/getList 获取问题列表
69 | * @apiDescription 获取问题列表
70 | * @apiName getList
71 | * @apiHeader {String} Authorization token
72 | * @apiParam (path参数) {Number} curPage
73 | * @apiParam (path参数) {Number} pageSize
74 | * @apiParam (path参数) {String} name 问题名称
75 | * @apiSampleRequest /api/Question/getList
76 | * @apiGroup Question
77 | * @apiVersion 0.0.1
78 | */
79 | router.get('/getList', ValidateQuestion.getList, Question.getList)
80 | /**
81 | * 获取所有问题
82 | * @api {get} /api/Question/getAll 获取所有问题
83 | * @apiDescription 获取所有问题
84 | * @apiName getAll
85 | * @apiHeader {String} Authorization token
86 | * @apiSampleRequest /api/Question/getAll
87 | * @apiGroup Question
88 | * @apiVersion 0.0.1
89 | */
90 | router.get('/getAll', ValidateQuestion.getAll, Question.getAll)
91 |
92 | export default router
93 |
--------------------------------------------------------------------------------
/router/carousel.js:
--------------------------------------------------------------------------------
1 | import express from 'express'
2 | import Carousel from '../controller/Carousel'
3 | import ValidateCarousel from '../validate/Carousel'
4 | const router = express.Router()
5 |
6 | /**
7 | * 创建
8 | * @api {POST} /api/Carousel/create 创建
9 | * @apiDescription 创建轮播
10 | * @apiName create
11 | * @apiHeader {String} Authorization token
12 | * @apiParam (参数) {String} title 标题
13 | * @apiParam (参数) {String} image 图片地址
14 | * @apiParam (参数) {Number} click 点击触发类型
15 | * @apiParam (参数) {String} href 跳转地址
16 | * @apiParam (参数) {Number} sort 排序
17 | * @apiParam (参数) {String} desc 描述
18 | * @apiParam (参数) {Number} status 状态
19 | * @apiSampleRequest /api/Carousel/create
20 | * @apiGroup Carousel
21 | * @apiVersion 0.0.1
22 | */
23 | router.post('/create', ValidateCarousel.create, Carousel.create)
24 | /**
25 | * 编辑
26 | * @api {put} /api/Carousel/update 编辑
27 | * @apiDescription 编辑
28 | * @apiName update
29 | * @apiHeader {String} Authorization token
30 | * @apiParam (参数) {Number} id
31 | * @apiParam (参数) {String} title 标题
32 | * @apiParam (参数) {String} image 图片地址
33 | * @apiParam (参数) {Number} click 点击触发类型
34 | * @apiParam (参数) {String} href 跳转地址
35 | * @apiParam (参数) {Number} sort 排序
36 | * @apiParam (参数) {String} desc 描述
37 | * @apiParam (参数) {Number} status 状态
38 | * @apiSampleRequest /api/Carousel/update
39 | * @apiGroup Carousel
40 | * @apiVersion 0.0.1
41 | */
42 | router.put('/update', ValidateCarousel.update, Carousel.update)
43 | /**
44 | * 删除
45 | * @api {delete} /api/Carousel/delete/:id 删除
46 | * @apiDescription 删除
47 | * @apiName delete
48 | * @apiHeader {String} Authorization token
49 | * @apiParam {Number} id
50 | * @apiSampleRequest /api/Carousel/delete
51 | * @apiGroup Carousel
52 | * @apiVersion 0.0.1
53 | */
54 | router.delete('/delete/:id', ValidateCarousel.delete, Carousel.delete)
55 |
56 | /**
57 | * 获取轮播信息
58 | * @api {get} /api/Carousel/getRow 获取轮播信息
59 | * @apiDescription 获取轮播信息
60 | * @apiName getRow
61 | * @apiHeader {String} Authorization token
62 | * @apiParam {Number} id
63 | * @apiSampleRequest /api/Carousel/getRow
64 | * @apiGroup Carousel
65 | * @apiVersion 0.0.1
66 | */
67 | router.get('/getRow/:id', ValidateCarousel.getRow, Carousel.getRow)
68 | /**
69 | * 获取轮播列表
70 | * @api {get} /api/Carousel/getList 获取轮播列表
71 | * @apiDescription 获取轮播列表
72 | * @apiName getList
73 | * @apiHeader {String} Authorization token
74 | * @apiParam (path参数) {Number} curPage
75 | * @apiParam (path参数) {Number} pageSize
76 | * @apiSampleRequest /api/Carousel/getList
77 | * @apiGroup Carousel
78 | * @apiVersion 0.0.1
79 | */
80 | router.get('/getList', ValidateCarousel.getList, Carousel.getList)
81 | /**
82 | * 获取所有轮播
83 | * @api {get} /api/Carousel/getAll 获取所有轮播
84 | * @apiDescription 获取所有轮播
85 | * @apiName getAll
86 | * @apiParam {Number} type
87 | * @apiHeader {String} Authorization token
88 | * @apiSampleRequest /api/Carousel/getAll
89 | * @apiGroup Carousel
90 | * @apiVersion 0.0.1
91 | */
92 | router.get('/getAll', ValidateCarousel.getAll, Carousel.getAll)
93 |
94 | export default router
95 |
--------------------------------------------------------------------------------
/model/Role.js:
--------------------------------------------------------------------------------
1 | import mysql from 'mysql'
2 | import query from '../mysql'
3 | import Base from './Base'
4 | import utils from '../lib/js/utils'
5 |
6 | class Role extends Base{
7 | constructor () {
8 | super()
9 | this.create = this.create.bind(this)
10 | this.update = this.update.bind(this)
11 | this.delete = this.delete.bind(this)
12 | this.getRow = this.getRow.bind(this)
13 | this.getList = this.getList.bind(this)
14 | this.getTotals = this.getTotals.bind(this)
15 | this.getAll = this.getAll.bind(this)
16 | }
17 | async create (obj) {
18 | let sql = `INSERT INTO bbs_role set ${this.joinStr('set', obj.set)};`
19 | return query(sql)
20 | }
21 | async update (obj) {
22 | let sql = `UPDATE bbs_role set ${this.joinStr('set', obj.set)} where 1 = 1 ${this.joinStr('get', obj.get)};`
23 | return query(sql)
24 | }
25 | async delete (obj) {
26 | let sql = `DELETE from bbs_role where 1 = 1 ${this.joinStr('get', obj.get)};`
27 | return query(sql)
28 | }
29 | async getRow (obj) {
30 | let sql = `select * from bbs_role where 1 = 1 ${this.joinStr('get', obj.get)};`
31 | return query(sql)
32 | }
33 | async getList (obj) {
34 | let curPage = obj.get.curPage, pageSize = obj.get.pageSize
35 | let sql = `select a.*, b.name as create_user_name, c.name as update_user_name from bbs_role as a
36 | left join bbs_user as b on a.create_user = b.id
37 | left join bbs_user as c on a.update_user = c.id
38 | where 1 = 1 ${this.joinStr('get', obj.get)} limit ${(curPage - 1) * pageSize}, ${pageSize};`
39 | return query(sql)
40 | }
41 | async getTotals (obj) {
42 | let sql = `select COUNT(*) as count from bbs_role where 1 = 1 ${this.joinStr('get', obj.get)};`
43 | return query(sql)
44 | }
45 | async getAll (obj) {
46 | // 查询到当前角色和当前角色的所有下级角色
47 | let sql, createRoleList = await this.getCreateRole(obj.get.id)
48 | try {
49 | sql = `select a.*, b.name as create_user_name, c.name as update_user_name, d.name as pName from bbs_role as a
50 | left join bbs_user as b on a.create_user = b.id
51 | left join bbs_user as c on a.update_user = c.id
52 | left join bbs_role as d on a.pid = d.id
53 | where 1 = 1 and a.id in (${mysql.escape([obj.get.id, ...createRoleList])}) and a.flag = 1;`
54 | } catch (e) {
55 | return e
56 | }
57 | return query(sql)
58 | }
59 | async getCreateRole (rootPValue) {
60 | let roleList, roleTree, createRoleList = []
61 | // 获取到所有的角色数据
62 | roleList = await query(`select id, pid from bbs_role;`)
63 | // 通过建立树状数据,得到当前用户创建的角色树
64 | roleTree = utils.getTreeArr({key: 'id', pKey: 'pid', data: roleList, rootPValue: +rootPValue})
65 | // 递归得到所有创建的角色
66 | getRole(roleTree)
67 | function getRole (arr) {
68 | for (let val of arr) {
69 | createRoleList.push(val.id)
70 | if (val.children.length) {
71 | getRole(val.children)
72 | }
73 | }
74 | }
75 | return createRoleList
76 | }
77 | }
78 |
79 | export default new Role()
80 |
--------------------------------------------------------------------------------
/router/techSquare.js:
--------------------------------------------------------------------------------
1 | import express from 'express'
2 | import TechSquare from '../controller/TechSquare'
3 | import ValidateTechSquare from '../validate/TechSquare'
4 | const router = express.Router()
5 |
6 | /**
7 | * 创建
8 | * @api {POST} /api/TechSquare/create 创建
9 | * @apiDescription 创建技术频道
10 | * @apiName create
11 | * @apiHeader {String} Authorization token
12 | * @apiParam (参数) {String} title 标题
13 | * @apiParam (参数) {String} image 图片地址
14 | * @apiParam (参数) {Number} click 点击触发类型
15 | * @apiParam (参数) {String} href 跳转地址
16 | * @apiParam (参数) {Number} sort 排序
17 | * @apiParam (参数) {String} desc 描述
18 | * @apiParam (参数) {Number} status 状态
19 | * @apiSampleRequest /api/TechSquare/create
20 | * @apiGroup TechSquare
21 | * @apiVersion 0.0.1
22 | */
23 | router.post('/create', ValidateTechSquare.create, TechSquare.create)
24 | /**
25 | * 编辑
26 | * @api {put} /api/TechSquare/update 编辑
27 | * @apiDescription 编辑
28 | * @apiName update
29 | * @apiHeader {String} Authorization token
30 | * @apiParam (参数) {Number} id
31 | * @apiParam (参数) {String} title 标题
32 | * @apiParam (参数) {String} image 图片地址
33 | * @apiParam (参数) {Number} click 点击触发类型
34 | * @apiParam (参数) {String} href 跳转地址
35 | * @apiParam (参数) {Number} sort 排序
36 | * @apiParam (参数) {String} desc 描述
37 | * @apiParam (参数) {Number} status 状态
38 | * @apiSampleRequest /api/TechSquare/update
39 | * @apiGroup TechSquare
40 | * @apiVersion 0.0.1
41 | */
42 | router.put('/update', ValidateTechSquare.update, TechSquare.update)
43 | /**
44 | * 删除
45 | * @api {delete} /api/TechSquare/delete/:id 删除
46 | * @apiDescription 删除
47 | * @apiName delete
48 | * @apiHeader {String} Authorization token
49 | * @apiParam {Number} id
50 | * @apiSampleRequest /api/TechSquare/delete
51 | * @apiGroup TechSquare
52 | * @apiVersion 0.0.1
53 | */
54 | router.delete('/delete/:id', ValidateTechSquare.delete, TechSquare.delete)
55 |
56 | /**
57 | * 获取技术频道信息
58 | * @api {get} /api/TechSquare/getRow 获取技术频道信息
59 | * @apiDescription 获取技术频道信息
60 | * @apiName getRow
61 | * @apiHeader {String} Authorization token
62 | * @apiParam {Number} id
63 | * @apiSampleRequest /api/TechSquare/getRow
64 | * @apiGroup TechSquare
65 | * @apiVersion 0.0.1
66 | */
67 | router.get('/getRow/:id', ValidateTechSquare.getRow, TechSquare.getRow)
68 | /**
69 | * 获取技术频道列表
70 | * @api {get} /api/TechSquare/getList 获取技术频道列表
71 | * @apiDescription 获取技术频道列表
72 | * @apiName getList
73 | * @apiHeader {String} Authorization token
74 | * @apiParam (path参数) {Number} curPage
75 | * @apiParam (path参数) {Number} pageSize
76 | * @apiSampleRequest /api/TechSquare/getList
77 | * @apiGroup TechSquare
78 | * @apiVersion 0.0.1
79 | */
80 | router.get('/getList', ValidateTechSquare.getList, TechSquare.getList)
81 | /**
82 | * 获取所有技术频道
83 | * @api {get} /api/TechSquare/getAll 获取所有技术频道
84 | * @apiDescription 获取所有技术频道
85 | * @apiName getAll
86 | * @apiParam {Number} type
87 | * @apiHeader {String} Authorization token
88 | * @apiSampleRequest /api/TechSquare/getAll
89 | * @apiGroup TechSquare
90 | * @apiVersion 0.0.1
91 | */
92 | router.get('/getAll', ValidateTechSquare.getAll, TechSquare.getAll)
93 |
94 | export default router
95 |
--------------------------------------------------------------------------------
/validate/Column.js:
--------------------------------------------------------------------------------
1 | import Base from './Base'
2 |
3 | class Column extends Base{
4 | constructor () {
5 | super()
6 | this.create = this.create.bind(this)
7 | this.update = this.update.bind(this)
8 | this.delete = this.delete.bind(this)
9 | this.getRow = this.getRow.bind(this)
10 | this.getList = this.getList.bind(this)
11 | this.getAll = this.getAll.bind(this)
12 | }
13 | async create (req, res, next) {
14 | const params = req.body,
15 | arr = [
16 | {label: '标题', value: params.title, rules: ['notnull']},
17 | {label: '内容', value: params.content, rules: ['notnull']},
18 | {label: '状态', value: params.status, rules: ['notnull', 'number']}
19 | ],
20 | result = this.check(arr)
21 | if (!result.success) {
22 | res.json({
23 | code: 20301,
24 | success: false,
25 | message: result.message
26 | })
27 | return
28 | }
29 | next()
30 | }
31 | async update (req, res, next) {
32 | const params = req.body,
33 | arr = [
34 | {label: 'ID', value: params.id, rules: ['notnull', 'number']},
35 | {label: '标题', value: params.title, rules: ['notnull']},
36 | {label: '内容', value: params.content, rules: ['notnull']},
37 | {label: '状态', value: params.status, rules: ['notnull', 'number']}
38 | ],
39 | result = this.check(arr)
40 | if (!result.success) {
41 | res.json({
42 | code: 20301,
43 | success: false,
44 | message: result.message
45 | })
46 | return
47 | }
48 | next()
49 | }
50 | async delete (req, res, next) {
51 | const ID = req.params.id,
52 | arr = [
53 | {label: 'ID', value: ID, rules: ['notnull']}
54 | ],
55 | result = this.check(arr)
56 | if (!result.success) {
57 | res.json({
58 | code: 20301,
59 | success: false,
60 | message: result.message
61 | })
62 | return
63 | }
64 | next()
65 | }
66 | async getRow (req, res, next) {
67 | const ID = req.params.id,
68 | arr = [
69 | {label: 'ID', value: ID, rules: ['notnull']}
70 | ],
71 | result = this.check(arr)
72 | if (!result.success) {
73 | res.json({
74 | code: 20301,
75 | success: false,
76 | message: result.message
77 | })
78 | return
79 | }
80 | next()
81 | }
82 | async getList (req, res, next) {
83 | const data = req.query,
84 | arr = [
85 | {label: 'curPage', value: data.curPage, rules: ['notnull', 'number']},
86 | {label: 'pageSize', value: data.curPage, rules: ['notnull', 'number']}
87 | ],
88 | result = this.check(arr)
89 | if (!result.success) {
90 | res.json({
91 | code: 20301,
92 | success: false,
93 | message: result.message
94 | })
95 | return
96 | }
97 | next()
98 | }
99 | async getAll (req, res, next) {
100 | next()
101 | }
102 | }
103 |
104 | export default new Column()
105 |
--------------------------------------------------------------------------------
/validate/Question.js:
--------------------------------------------------------------------------------
1 | import Base from './Base'
2 |
3 | class Question extends Base{
4 | constructor () {
5 | super()
6 | this.create = this.create.bind(this)
7 | this.update = this.update.bind(this)
8 | this.delete = this.delete.bind(this)
9 | this.getRow = this.getRow.bind(this)
10 | this.getList = this.getList.bind(this)
11 | this.getAll = this.getAll.bind(this)
12 | }
13 | async create (req, res, next) {
14 | const params = req.body,
15 | arr = [
16 | {label: '标题', value: params.title, rules: ['notnull']},
17 | {label: '内容', value: params.content, rules: ['notnull']},
18 | {label: '状态', value: params.status, rules: ['notnull', 'number']}
19 | ],
20 | result = this.check(arr)
21 | if (!result.success) {
22 | res.json({
23 | code: 20301,
24 | success: false,
25 | message: result.message
26 | })
27 | return
28 | }
29 | next()
30 | }
31 | async update (req, res, next) {
32 | const params = req.body,
33 | arr = [
34 | {label: 'ID', value: params.id, rules: ['notnull', 'number']},
35 | {label: '标题', value: params.title, rules: ['notnull']},
36 | {label: '内容', value: params.content, rules: ['notnull']},
37 | {label: '状态', value: params.status, rules: ['notnull', 'number']}
38 | ],
39 | result = this.check(arr)
40 | if (!result.success) {
41 | res.json({
42 | code: 20301,
43 | success: false,
44 | message: result.message
45 | })
46 | return
47 | }
48 | next()
49 | }
50 | async delete (req, res, next) {
51 | const ID = req.params.id,
52 | arr = [
53 | {label: 'ID', value: ID, rules: ['notnull']}
54 | ],
55 | result = this.check(arr)
56 | if (!result.success) {
57 | res.json({
58 | code: 20301,
59 | success: false,
60 | message: result.message
61 | })
62 | return
63 | }
64 | next()
65 | }
66 | async getRow (req, res, next) {
67 | const ID = req.params.id,
68 | arr = [
69 | {label: 'ID', value: ID, rules: ['notnull']}
70 | ],
71 | result = this.check(arr)
72 | if (!result.success) {
73 | res.json({
74 | code: 20301,
75 | success: false,
76 | message: result.message
77 | })
78 | return
79 | }
80 | next()
81 | }
82 | async getList (req, res, next) {
83 | const data = req.query,
84 | arr = [
85 | {label: 'curPage', value: data.curPage, rules: ['notnull', 'number']},
86 | {label: 'pageSize', value: data.curPage, rules: ['notnull', 'number']}
87 | ],
88 | result = this.check(arr)
89 | if (!result.success) {
90 | res.json({
91 | code: 20301,
92 | success: false,
93 | message: result.message
94 | })
95 | return
96 | }
97 | next()
98 | }
99 | async getAll (req, res, next) {
100 | next()
101 | }
102 | }
103 |
104 | export default new Question()
105 |
--------------------------------------------------------------------------------
/validate/Article.js:
--------------------------------------------------------------------------------
1 | import Base from './Base'
2 |
3 | class Article extends Base{
4 | constructor () {
5 | super()
6 | this.create = this.create.bind(this)
7 | this.update = this.update.bind(this)
8 | this.delete = this.delete.bind(this)
9 | this.getRow = this.getRow.bind(this)
10 | this.getList = this.getList.bind(this)
11 | this.getAll = this.getAll.bind(this)
12 | }
13 | async create (req, res, next) {
14 | const params = req.body,
15 | arr = [
16 | {label: '标题', value: params.title, rules: ['notnull']}
17 | // {label: '内容', value: params.content, rules: ['notnull']},
18 | // {label: '状态', value: params.status, rules: ['notnull', 'number']}
19 | ],
20 | result = this.check(arr)
21 | if (!result.success) {
22 | res.json({
23 | code: 20301,
24 | success: false,
25 | message: result.message
26 | })
27 | return
28 | }
29 | next()
30 | }
31 | async update (req, res, next) {
32 | const params = req.body,
33 | arr = [
34 | {label: 'ID', value: params.id, rules: ['notnull', 'number']},
35 | {label: '标题', value: params.title, rules: ['notnull']}
36 | // {label: '内容', value: params.content, rules: ['notnull']},
37 | // {label: '状态', value: params.status, rules: ['notnull', 'number']}
38 | ],
39 | result = this.check(arr)
40 | if (!result.success) {
41 | res.json({
42 | code: 20301,
43 | success: false,
44 | message: result.message
45 | })
46 | return
47 | }
48 | next()
49 | }
50 | async delete (req, res, next) {
51 | const ID = req.params.id,
52 | arr = [
53 | {label: 'ID', value: ID, rules: ['notnull']}
54 | ],
55 | result = this.check(arr)
56 | if (!result.success) {
57 | res.json({
58 | code: 20301,
59 | success: false,
60 | message: result.message
61 | })
62 | return
63 | }
64 | next()
65 | }
66 | async getRow (req, res, next) {
67 | const ID = req.params.id,
68 | arr = [
69 | {label: 'ID', value: ID, rules: ['notnull']}
70 | ],
71 | result = this.check(arr)
72 | if (!result.success) {
73 | res.json({
74 | code: 20301,
75 | success: false,
76 | message: result.message
77 | })
78 | return
79 | }
80 | next()
81 | }
82 | async getList (req, res, next) {
83 | const data = req.query,
84 | arr = [
85 | {label: 'curPage', value: data.curPage, rules: ['notnull', 'number']},
86 | {label: 'pageSize', value: data.curPage, rules: ['notnull', 'number']}
87 | ],
88 | result = this.check(arr)
89 | if (!result.success) {
90 | res.json({
91 | code: 20301,
92 | success: false,
93 | message: result.message
94 | })
95 | return
96 | }
97 | next()
98 | }
99 | async getAll (req, res, next) {
100 | next()
101 | }
102 | }
103 |
104 | export default new Article()
105 |
--------------------------------------------------------------------------------
/validate/Folder.js:
--------------------------------------------------------------------------------
1 | import Base from './Base'
2 |
3 | class Menu extends Base{
4 | constructor () {
5 | super()
6 | this.create = this.create.bind(this)
7 | this.update = this.update.bind(this)
8 | this.delete = this.delete.bind(this)
9 | this.getRow = this.getRow.bind(this)
10 | this.getList = this.getList.bind(this)
11 | this.getAll = this.getAll.bind(this)
12 | }
13 | async create (req, res, next) {
14 | const params = req.body,
15 | arr = [
16 | {label: 'pid', value: params.pid, rules: ['notnull', 'number']},
17 | {label: '目录名称', value: params.name, rules: ['notnull']},
18 | {label: '排序', value: params.sort, rules: ['notnull', 'number']}
19 | ],
20 | result = this.check(arr)
21 | if (!result.success) {
22 | res.json({
23 | code: 20301,
24 | success: false,
25 | message: result.message
26 | })
27 | return
28 | }
29 | next()
30 | }
31 | async update (req, res, next) {
32 | const params = req.body,
33 | arr = [
34 | {label: 'ID', value: params.id, rules: ['notnull', 'number']},
35 | {label: 'pid', value: params.pid, rules: ['notnull', 'number']},
36 | {label: '目录名称', value: params.name, rules: ['notnull']},
37 | {label: '排序', value: params.sort, rules: ['notnull', 'number']}
38 | ],
39 | result = this.check(arr)
40 | if (!result.success) {
41 | res.json({
42 | code: 20301,
43 | success: false,
44 | message: result.message
45 | })
46 | return
47 | }
48 | next()
49 | }
50 | async delete (req, res, next) {
51 | const ID = req.params.id,
52 | arr = [
53 | {label: 'ID', value: ID, rules: ['notnull']}
54 | ],
55 | result = this.check(arr)
56 | if (!result.success) {
57 | res.json({
58 | code: 20301,
59 | success: false,
60 | message: result.message
61 | })
62 | return
63 | }
64 | next()
65 | }
66 | async getRow (req, res, next) {
67 | const ID = req.params.id,
68 | arr = [
69 | {label: 'ID', value: ID, rules: ['notnull']}
70 | ],
71 | result = this.check(arr)
72 | if (!result.success) {
73 | res.json({
74 | code: 20301,
75 | success: false,
76 | message: result.message
77 | })
78 | return
79 | }
80 | next()
81 | }
82 | async getList (req, res, next) {
83 | const data = req.query,
84 | arr = [
85 | {label: 'curPage', value: data.curPage, rules: ['notnull', 'number']},
86 | {label: 'pageSize', value: data.curPage, rules: ['notnull', 'number']}
87 | ],
88 | result = this.check(arr)
89 | if (!result.success) {
90 | res.json({
91 | code: 20301,
92 | success: false,
93 | message: result.message
94 | })
95 | return
96 | }
97 | next()
98 | }
99 | async getRoleMenu (req, res, next) {
100 | next()
101 | }
102 | async getAll (req, res, next) {
103 | next()
104 | }
105 | }
106 |
107 | export default new Menu()
108 |
--------------------------------------------------------------------------------
/validate/Carousel.js:
--------------------------------------------------------------------------------
1 | import Base from './Base'
2 |
3 | class Carousel extends Base{
4 | constructor () {
5 | super()
6 | this.create = this.create.bind(this)
7 | this.update = this.update.bind(this)
8 | this.delete = this.delete.bind(this)
9 | this.getRow = this.getRow.bind(this)
10 | this.getList = this.getList.bind(this)
11 | this.getAll = this.getAll.bind(this)
12 | }
13 | async create (req, res, next) {
14 | const params = req.body,
15 | arr = [
16 | {label: '标题', value: params.title, rules: ['notnull']},
17 | {label: '轮播图片', value: params.image, rules: ['notnull']},
18 | {label: '点击触发', value: params.click, rules: ['notnull', 'number']},
19 | {label: '状态', value: params.status, rules: ['notnull', 'number']}
20 | ],
21 | result = this.check(arr)
22 | if (!result.success) {
23 | res.json({
24 | code: 20301,
25 | success: false,
26 | message: result.message
27 | })
28 | return
29 | }
30 | next()
31 | }
32 | async update (req, res, next) {
33 | const params = req.body,
34 | arr = [
35 | {label: 'ID', value: params.id, rules: ['notnull', 'number']},
36 | {label: '标题', value: params.title, rules: ['notnull']},
37 | {label: '轮播图片', value: params.image, rules: ['notnull']},
38 | {label: '点击触发', value: params.click, rules: ['notnull', 'number']},
39 | {label: '状态', value: params.status, rules: ['notnull', 'number']}
40 | ],
41 | result = this.check(arr)
42 | if (!result.success) {
43 | res.json({
44 | code: 20301,
45 | success: false,
46 | message: result.message
47 | })
48 | return
49 | }
50 | next()
51 | }
52 | async delete (req, res, next) {
53 | const ID = req.params.id,
54 | arr = [
55 | {label: 'ID', value: ID, rules: ['notnull']}
56 | ],
57 | result = this.check(arr)
58 | if (!result.success) {
59 | res.json({
60 | code: 20301,
61 | success: false,
62 | message: result.message
63 | })
64 | return
65 | }
66 | next()
67 | }
68 | async getRow (req, res, next) {
69 | const ID = req.params.id,
70 | arr = [
71 | {label: 'ID', value: ID, rules: ['notnull']}
72 | ],
73 | result = this.check(arr)
74 | if (!result.success) {
75 | res.json({
76 | code: 20301,
77 | success: false,
78 | message: result.message
79 | })
80 | return
81 | }
82 | next()
83 | }
84 | async getList (req, res, next) {
85 | const data = req.query,
86 | arr = [
87 | {label: 'curPage', value: data.curPage, rules: ['notnull', 'number']},
88 | {label: 'pageSize', value: data.curPage, rules: ['notnull', 'number']}
89 | ],
90 | result = this.check(arr)
91 | if (!result.success) {
92 | res.json({
93 | code: 20301,
94 | success: false,
95 | message: result.message
96 | })
97 | return
98 | }
99 | next()
100 | }
101 | async getAll (req, res, next) {
102 | next()
103 | }
104 | }
105 |
106 | export default new Carousel()
107 |
--------------------------------------------------------------------------------
/validate/Role.js:
--------------------------------------------------------------------------------
1 | import Base from './Base'
2 |
3 | class Role extends Base{
4 | constructor () {
5 | super()
6 | this.create = this.create.bind(this)
7 | this.update = this.update.bind(this)
8 | this.delete = this.delete.bind(this)
9 | this.getRow = this.getRow.bind(this)
10 | this.getList = this.getList.bind(this)
11 | this.getAll = this.getAll.bind(this)
12 | }
13 | async create (req, res, next) {
14 | const params = req.body,
15 | arr = [
16 | {label: 'pid', value: params.pid, rules: ['notnull', 'number']},
17 | {label: '角色名称', value: params.name, rules: ['notnull']},
18 | {label: '状态', value: params.status, rules: ['notnull']}
19 | ],
20 | result = this.check(arr)
21 | if (!result.success) {
22 | res.json({
23 | code: 20301,
24 | success: false,
25 | message: result.message
26 | })
27 | return
28 | }
29 | next()
30 | }
31 | async update (req, res, next) {
32 | const params = req.body,
33 | arr = [
34 | {label: 'ID', value: params.id, rules: ['notnull', 'number']},
35 | {label: 'pid', value: params.pid, rules: ['notnull', 'number']},
36 | {label: '角色名称', value: params.name, rules: ['notnull']},
37 | {label: '状态', value: params.status, rules: ['notnull']}
38 | ],
39 | result = this.check(arr)
40 | if (!result.success) {
41 | res.json({
42 | code: 20301,
43 | success: false,
44 | message: result.message
45 | })
46 | return
47 | }
48 | next()
49 | }
50 | async delete (req, res, next) {
51 | const ID = req.params.id,
52 | arr = [
53 | {label: 'ID', value: ID, rules: ['notnull']}
54 | ],
55 | result = this.check(arr)
56 | // 不能删除管理员
57 | if (ID === 1 || ID === '1') {
58 | res.json({
59 | code: 20202,
60 | success: false,
61 | message: '无法删除管理员'
62 | })
63 | return
64 | }
65 | if (!result.success) {
66 | res.json({
67 | code: 20301,
68 | success: false,
69 | message: result.message
70 | })
71 | return
72 | }
73 | next()
74 | }
75 | async getRow (req, res, next) {
76 | const ID = req.params.id,
77 | arr = [
78 | {label: 'ID', value: ID, rules: ['notnull']}
79 | ],
80 | result = this.check(arr)
81 | if (!result.success) {
82 | res.json({
83 | code: 20301,
84 | success: false,
85 | message: result.message
86 | })
87 | return
88 | }
89 | next()
90 | }
91 | async getList (req, res, next) {
92 | const data = req.query,
93 | arr = [
94 | {label: 'curPage', value: data.curPage, rules: ['notnull', 'number']},
95 | {label: 'pageSize', value: data.curPage, rules: ['notnull', 'number']}
96 | ],
97 | result = this.check(arr)
98 | if (!result.success) {
99 | res.json({
100 | code: 20301,
101 | success: false,
102 | message: result.message
103 | })
104 | return
105 | }
106 | next()
107 | }
108 | async getAll (req, res, next) {
109 | next()
110 | }
111 | }
112 |
113 | export default new Role()
114 |
--------------------------------------------------------------------------------
/validate/TechSquare.js:
--------------------------------------------------------------------------------
1 | import Base from './Base'
2 |
3 | class TechSquare extends Base{
4 | constructor () {
5 | super()
6 | this.create = this.create.bind(this)
7 | this.update = this.update.bind(this)
8 | this.delete = this.delete.bind(this)
9 | this.getRow = this.getRow.bind(this)
10 | this.getList = this.getList.bind(this)
11 | this.getAll = this.getAll.bind(this)
12 | }
13 | async create (req, res, next) {
14 | const params = req.body,
15 | arr = [
16 | // {label: '标题', value: params.title, rules: ['notnull']},
17 | // {label: '轮播图片', value: params.image, rules: ['notnull']},
18 | // {label: '点击触发', value: params.click, rules: ['notnull', 'number']},
19 | // {label: '状态', value: params.status, rules: ['notnull', 'number']}
20 | ],
21 | result = this.check(arr)
22 | if (!result.success) {
23 | res.json({
24 | code: 20301,
25 | success: false,
26 | message: result.message
27 | })
28 | return
29 | }
30 | next()
31 | }
32 | async update (req, res, next) {
33 | const params = req.body,
34 | arr = [
35 | // {label: 'ID', value: params.id, rules: ['notnull', 'number']},
36 | // {label: '标题', value: params.title, rules: ['notnull']},
37 | // {label: '轮播图片', value: params.image, rules: ['notnull']},
38 | // {label: '点击触发', value: params.click, rules: ['notnull', 'number']},
39 | // {label: '状态', value: params.status, rules: ['notnull', 'number']}
40 | ],
41 | result = this.check(arr)
42 | if (!result.success) {
43 | res.json({
44 | code: 20301,
45 | success: false,
46 | message: result.message
47 | })
48 | return
49 | }
50 | next()
51 | }
52 | async delete (req, res, next) {
53 | const ID = req.params.id,
54 | arr = [
55 | {label: 'ID', value: ID, rules: ['notnull']}
56 | ],
57 | result = this.check(arr)
58 | if (!result.success) {
59 | res.json({
60 | code: 20301,
61 | success: false,
62 | message: result.message
63 | })
64 | return
65 | }
66 | next()
67 | }
68 | async getRow (req, res, next) {
69 | const ID = req.params.id,
70 | arr = [
71 | {label: 'ID', value: ID, rules: ['notnull']}
72 | ],
73 | result = this.check(arr)
74 | if (!result.success) {
75 | res.json({
76 | code: 20301,
77 | success: false,
78 | message: result.message
79 | })
80 | return
81 | }
82 | next()
83 | }
84 | async getList (req, res, next) {
85 | const data = req.query,
86 | arr = [
87 | {label: 'curPage', value: data.curPage, rules: ['notnull', 'number']},
88 | {label: 'pageSize', value: data.curPage, rules: ['notnull', 'number']}
89 | ],
90 | result = this.check(arr)
91 | if (!result.success) {
92 | res.json({
93 | code: 20301,
94 | success: false,
95 | message: result.message
96 | })
97 | return
98 | }
99 | next()
100 | }
101 | async getAll (req, res, next) {
102 | next()
103 | }
104 | }
105 |
106 | export default new TechSquare()
107 |
--------------------------------------------------------------------------------
/controller/Draft.js:
--------------------------------------------------------------------------------
1 | import Base from './Base'
2 | import ArticleModel from '../model/Article'
3 | import QuestionModel from '../model/Question'
4 |
5 | class Draft extends Base {
6 | constructor () {
7 | super()
8 | this.getTotals = this.getTotals.bind(this)
9 | this.getAll = this.getAll.bind(this)
10 | this.giveUp = this.giveUp.bind(this)
11 | this.giveUpAll = this.giveUpAll.bind(this)
12 | }
13 | // 查询草稿数量
14 | async getTotals (req, res, next) {
15 | const userInfo = await this.getUserInfo(req)
16 | let question, article
17 | try {
18 | question = await QuestionModel.getTotals({get: {create_user: userInfo.id, flag: 1}})
19 | article = await ArticleModel.getTotals({get: {create_user: userInfo.id, flag: 1}})
20 | } catch (e) {
21 | this.handleException(req, res, e)
22 | return
23 | }
24 | res.json({
25 | code: 20000,
26 | success: true,
27 | content: {
28 | totals: question[0].count + article[0].count
29 | },
30 | message: '操作成功'
31 | })
32 | }
33 | // 查询所有的草稿
34 | async getAll (req, res, next) {
35 | const userInfo = await this.getUserInfo(req)
36 | let question, article, result
37 | try {
38 | question = await QuestionModel.getAll({get: {create_user: userInfo.id, flag: 1}})
39 | article = await ArticleModel.getAll({get: {create_user: userInfo.id, flag: 1}})
40 | } catch (e) {
41 | this.handleException(req, res, e)
42 | return
43 | }
44 | // 排序,处理
45 | result = [...question.map(item => {
46 | item.dataType = 1
47 | return item
48 | }), ...article.map(item => {
49 | item.dataType = 2
50 | return item
51 | })].sort((a, b) => b.id - a.id)
52 | res.json({
53 | code: 20000,
54 | success: true,
55 | content: result,
56 | message: '操作成功'
57 | })
58 | }
59 | // 舍弃草稿
60 | async giveUp (req, res, next) {
61 | let data = JSON.parse(JSON.stringify(req.body)),
62 | userInfo = await this.getUserInfo(req),
63 | result
64 | // dataType 1 问题 2 文章
65 | if (data.dataType === 1) {
66 | result = await QuestionModel.update({get: {id: data.id, create_user: userInfo.id}, set: {flag: 0}})
67 | } else if (data.dataType === 2) {
68 | result = await ArticleModel.update({get: {id: data.id, create_user: userInfo.id}, set: {flag: 0}})
69 | } else {
70 | return
71 | }
72 | if (!result) {
73 | res.json({
74 | code: 20001,
75 | success: false,
76 | content: '操作人和操作数据不匹配',
77 | message: '操作失败'
78 | })
79 | return
80 | }
81 | res.json({
82 | code: 20000,
83 | success: true,
84 | content: result,
85 | message: '操作成功'
86 | })
87 | }
88 | // 舍弃全部草稿
89 | async giveUpAll (req, res, next) {
90 | const userInfo = await this.getUserInfo(req)
91 | try {
92 | await QuestionModel.update({get: {create_user: userInfo.id, flag: 1}, set: {flag: 0}})
93 | await ArticleModel.update({get: {create_user: userInfo.id, flag: 1}, set: {flag: 0}})
94 | } catch (e) {
95 | this.handleException(req, res, e)
96 | return
97 | }
98 | res.json({
99 | code: 20000,
100 | success: true,
101 | message: '操作成功'
102 | })
103 | }
104 | }
105 |
106 | export default new Draft()
107 |
--------------------------------------------------------------------------------
/router/dataPerms.js:
--------------------------------------------------------------------------------
1 | import express from 'express'
2 | import DataPerms from '../controller/DataPerms'
3 | import ValidateDataPerms from '../validate/DataPerms'
4 | const router = express.Router()
5 |
6 | /**
7 | * 创建
8 | * @api {POST} /api/DataPerms/create 创建
9 | * @apiDescription 创建模块权限
10 | * @apiName create
11 | * @apiHeader {String} Authorization token
12 | * @apiParam (参数) {Number} menu_id 模块ID
13 | * @apiParam (参数) {String} name 名称
14 | * @apiParam (参数) {String} code 编码
15 | * @apiParam (参数) {String} type 类型 按钮或者其他
16 | * @apiParam (参数) {String} method 请求方式
17 | * @apiSampleRequest /api/DataPerms/create
18 | * @apiGroup DataPerms
19 | * @apiVersion 0.0.1
20 | */
21 | router.post('/create', ValidateDataPerms.create, DataPerms.create)
22 | /**
23 | * 编辑
24 | * @api {put} /api/DataPerms/update 编辑
25 | * @apiDescription 编辑
26 | * @apiName update
27 | * @apiHeader {String} Authorization token
28 | * @apiParam (参数) {Number} id
29 | * @apiParam (参数) {Number} menu_id 模块ID
30 | * @apiParam (参数) {String} name 名称
31 | * @apiParam (参数) {String} code 编码
32 | * @apiParam (参数) {String} type 类型 按钮或者其他
33 | * @apiParam (参数) {String} method 请求方式
34 | * @apiSampleRequest /api/DataPerms/update
35 | * @apiGroup DataPerms
36 | * @apiVersion 0.0.1
37 | */
38 | router.put('/update', ValidateDataPerms.update, DataPerms.update)
39 | /**
40 | * 删除
41 | * @api {delete} /api/DataPerms/delete/:id 删除
42 | * @apiDescription 删除
43 | * @apiName delete
44 | * @apiHeader {String} Authorization token
45 | * @apiParam {Number} id
46 | * @apiSampleRequest /api/DataPerms/delete
47 | * @apiGroup DataPerms
48 | * @apiVersion 0.0.1
49 | */
50 | router.delete('/delete/:id', ValidateDataPerms.delete, DataPerms.delete)
51 |
52 | /**
53 | * 获取模块信息
54 | * @api {get} /api/DataPerms/getRow 获取模块信息
55 | * @apiDescription 获取模块权限信息
56 | * @apiName getRow
57 | * @apiHeader {String} Authorization token
58 | * @apiParam {Number} id
59 | * @apiSampleRequest /api/DataPerms/getRow
60 | * @apiGroup DataPerms
61 | * @apiVersion 0.0.1
62 | */
63 | router.get('/getRow/:id', ValidateDataPerms.getRow, DataPerms.getRow)
64 | /**
65 | * 获取模块列表
66 | * @api {get} /api/DataPerms/getList 获取模块列表
67 | * @apiDescription 获取模块权限列表
68 | * @apiName getList
69 | * @apiHeader {String} Authorization token
70 | * @apiParam (path参数) {Number} menu_id
71 | * @apiSampleRequest /api/DataPerms/getList
72 | * @apiGroup DataPerms
73 | * @apiVersion 0.0.1
74 | */
75 | router.get('/getList', ValidateDataPerms.getList, DataPerms.getList)
76 | /**
77 | * 获取用户拥有模块权限
78 | * @api {get} /api/DataPerms/getRoleDataPerms 获取用户拥有模块权限
79 | * @apiDescription 获取用户拥有模块权限
80 | * @apiName getRoleDataPerms
81 | * @apiHeader {String} Authorization token
82 | * @apiParam {Number} modId
83 | * @apiSampleRequest /api/DataPerms/getRoleDataPerms
84 | * @apiGroup DataPerms
85 | * @apiVersion 0.0.1
86 | */
87 | router.get('/getRoleDataPerms', ValidateDataPerms.getRoleDataPerms, DataPerms.getRoleDataPerms)
88 | /**
89 | * 获取所有模块权限
90 | * @api {get} /api/DataPerms/getAll 获取所有模块权限
91 | * @apiDescription 获取所有模块权限
92 | * @apiName getAll
93 | * @apiHeader {String} Authorization token
94 | * @apiParam {Number} modId
95 | * @apiSampleRequest /api/DataPerms/getAll
96 | * @apiGroup DataPerms
97 | * @apiVersion 0.0.1
98 | */
99 | router.get('/getAll', ValidateDataPerms.getAll, DataPerms.getAll)
100 |
101 | export default router
102 |
--------------------------------------------------------------------------------
/log/index.js:
--------------------------------------------------------------------------------
1 | import fs from 'fs'
2 | import path from 'path'
3 | import utils from '../lib/js/utils'
4 | import schedule from 'node-schedule'
5 |
6 | class Log {
7 | constructor () {
8 | this.clearLog(7)
9 | }
10 | /**
11 | * 写入日志
12 | * @param {String} type // 日志类型 err 错误日志 sql sql日志
13 | * @param {String} content
14 | */
15 | async writeLog (content, type = 'err') {
16 | // 创建不存在的文件夹
17 | await this.dirExists(`log/file/${type}`)
18 | // 获取到文件files
19 | // fs.readFile(`log/file/${type}/${utils.switchTime(new Date(), 'YYYY-MM-DD')}.log`, (err, data) => {
20 | // if (err) {
21 | // console.log(err)
22 | // }
23 | // // 写入文件
24 | // fs.writeFile(`log/file/${type}/${utils.switchTime(new Date(), 'YYYY-MM-DD')}.log`, `${data || ''}\n${content}`, async (err) => {
25 | // if (err) {
26 | // console.log(err)
27 | // }
28 | // })
29 | // })
30 | // 写入文件
31 | fs.appendFile(`log/file/${type}/${utils.switchTime(new Date(), 'YYYY-MM-DD')}.log`, `\n${content}`, async (err) => {
32 | if (err) {
33 | console.log(err)
34 | }
35 | })
36 | }
37 | // 定时清除日志
38 | async clearLog (day) {
39 | // 创建不存在的文件夹
40 | await this.dirExists(`log/file/sql`)
41 | await this.dirExists(`log/file/err`)
42 | const rule = new schedule.RecurrenceRule()
43 | rule.dayOfWeek = [0, new schedule.Range(1, 6)]
44 | rule.hour = 11;
45 | rule.minute = 54;
46 | schedule.scheduleJob(rule, () => {
47 | const sqlLogList = fs.readdirSync('log/file/sql')
48 | const errLogList = fs.readdirSync('log/file/err')
49 | const NOW = +new Date()
50 | sqlLogList.forEach(item => {
51 | const logDate = +new Date(item.replace('.log', ''))
52 | if (NOW - day * 24 * 3600 * 1000 > logDate) {
53 | fs.unlinkSync('log/file/sql/' + item)
54 | }
55 | })
56 | errLogList.forEach(item => {
57 | const logDate = +new Date(item.replace('.log', ''))
58 | if (NOW - day * 24 * 3600 * 1000 > logDate) {
59 | fs.unlinkSync('log/file/err/' + item)
60 | }
61 | })
62 | console.log('每天定时删除不符合条件的文件')
63 | })
64 | }
65 | // 查询路径是否存在
66 | async getStat (path) {
67 | return new Promise((resolve, reject) => {
68 | fs.stat(path, (err, stats) => {
69 | if (err) {
70 | resolve(false)
71 | } else {
72 | resolve(stats)
73 | }
74 | })
75 | })
76 | }
77 | // 创建路径
78 | async mkdir(dir){
79 | return new Promise((resolve, reject) => {
80 | fs.mkdir(dir, err => {
81 | if (err) {
82 | resolve(false)
83 | } else {
84 | resolve(true)
85 | }
86 | })
87 | })
88 | }
89 | // 路径是否存在,不存在则创建
90 | async dirExists (dir) {
91 | let isExists = await this.getStat(dir), tempDir, status, mkdirStatus
92 | // 如果该路径存在且不是文件,返回true
93 | if (isExists && isExists.isDirectory()) {
94 | return true
95 | } else if (isExists) { // 如果该路径存在但是文件,返回false
96 | return false
97 | }
98 | // 如果该路径不存在
99 | tempDir = path.parse(dir).dir // 拿到上级路径
100 | // 递归判断,如果上级目录也不存在,则会代码会在此处继续循环执行,直到目录存在
101 | status = await this.dirExists(tempDir)
102 | if (status) {
103 | mkdirStatus = await this.mkdir(dir)
104 | }
105 | return mkdirStatus
106 | }
107 | }
108 |
109 | export default new Log()
110 |
--------------------------------------------------------------------------------
/validate/DataPerms.js:
--------------------------------------------------------------------------------
1 | import Base from './Base'
2 |
3 | class DataPerms extends Base{
4 | constructor () {
5 | super()
6 | this.create = this.create.bind(this)
7 | this.update = this.update.bind(this)
8 | this.delete = this.delete.bind(this)
9 | this.getRow = this.getRow.bind(this)
10 | this.getList = this.getList.bind(this)
11 | this.getAll = this.getAll.bind(this)
12 | }
13 | async create (req, res, next) {
14 | const params = req.body,
15 | arr = [
16 | {label: 'menu_id', value: params.menu_id, rules: ['notnull', 'number']},
17 | {label: '类型', value: params.type, rules: ['notnull', 'number']},
18 | {label: '编码', value: params.code, rules: ['notnull', 'noChinese']},
19 | {label: '名称', value: params.name, rules: ['notnull']},
20 | {label: '请求方式', value: params.method, rules: ['notnull', 'string']}
21 | ],
22 | result = this.check(arr)
23 | if (!result.success) {
24 | res.json({
25 | code: 20301,
26 | success: false,
27 | message: result.message
28 | })
29 | return
30 | }
31 | next()
32 | }
33 | async update (req, res, next) {
34 | const params = req.body,
35 | arr = [
36 | {label: 'ID', value: params.id, rules: ['notnull', 'number']},
37 | {label: 'menu_id', value: params.menu_id, rules: ['notnull', 'number']},
38 | {label: '类型', value: params.type, rules: ['notnull', 'number']},
39 | {label: '编码', value: params.code, rules: ['notnull', 'noChinese']},
40 | {label: '名称', value: params.name, rules: ['notnull']},
41 | {label: '请求方式', value: params.method, rules: ['notnull', 'string']}
42 | ],
43 | result = this.check(arr)
44 | if (!result.success) {
45 | res.json({
46 | code: 20301,
47 | success: false,
48 | message: result.message
49 | })
50 | return
51 | }
52 | next()
53 | }
54 | async delete (req, res, next) {
55 | const ID = req.params.id,
56 | arr = [
57 | {label: 'ID', value: ID, rules: ['notnull']}
58 | ],
59 | result = this.check(arr)
60 | if (!result.success) {
61 | res.json({
62 | code: 20301,
63 | success: false,
64 | message: result.message
65 | })
66 | return
67 | }
68 | next()
69 | }
70 | async getRow (req, res, next) {
71 | const ID = req.params.id,
72 | arr = [
73 | {label: 'ID', value: ID, rules: ['notnull']}
74 | ],
75 | result = this.check(arr)
76 | if (!result.success) {
77 | res.json({
78 | code: 20301,
79 | success: false,
80 | message: result.message
81 | })
82 | return
83 | }
84 | next()
85 | }
86 | async getList (req, res, next) {
87 | const data = req.query,
88 | arr = [
89 | {label: 'curPage', value: data.curPage, rules: ['notnull', 'number']},
90 | {label: 'pageSize', value: data.curPage, rules: ['notnull', 'number']}
91 | ],
92 | result = this.check(arr)
93 | if (!result.success) {
94 | res.json({
95 | code: 20301,
96 | success: false,
97 | message: result.message
98 | })
99 | return
100 | }
101 | next()
102 | }
103 | async getRoleDataPerms (req, res, next) {
104 | next()
105 | }
106 | async getAll (req, res, next) {
107 | next()
108 | }
109 | }
110 |
111 | export default new DataPerms()
112 |
--------------------------------------------------------------------------------
/validate/Menu.js:
--------------------------------------------------------------------------------
1 | import Base from './Base'
2 |
3 | class Menu extends Base{
4 | constructor () {
5 | super()
6 | this.create = this.create.bind(this)
7 | this.update = this.update.bind(this)
8 | this.delete = this.delete.bind(this)
9 | this.getRow = this.getRow.bind(this)
10 | this.getList = this.getList.bind(this)
11 | this.getAll = this.getAll.bind(this)
12 | }
13 | async create (req, res, next) {
14 | const params = req.body,
15 | arr = [
16 | {label: 'pid', value: params.pid, rules: ['notnull', 'number']},
17 | {label: '菜单类型', value: params.type, rules: ['notnull', 'number']},
18 | {label: '菜单编码', value: params.code, rules: ['notnull', 'noChinese']},
19 | {label: '菜单名称', value: params.name, rules: ['notnull']},
20 | {label: '排序', value: params.sort, rules: ['notnull', 'number']},
21 | {label: '状态', value: params.status, rules: ['notnull', 'number']}
22 | ],
23 | result = this.check(arr)
24 | if (!result.success) {
25 | res.json({
26 | code: 20301,
27 | success: false,
28 | message: result.message
29 | })
30 | return
31 | }
32 | next()
33 | }
34 | async update (req, res, next) {
35 | const params = req.body,
36 | arr = [
37 | {label: 'ID', value: params.id, rules: ['notnull', 'number']},
38 | {label: 'pid', value: params.pid, rules: ['notnull', 'number']},
39 | {label: '菜单类型', value: params.type, rules: ['notnull', 'number']},
40 | {label: '菜单编码', value: params.code, rules: ['notnull', 'noChinese']},
41 | {label: '菜单名称', value: params.name, rules: ['notnull']},
42 | {label: '排序', value: params.sort, rules: ['notnull', 'number']},
43 | {label: '状态', value: params.status, rules: ['notnull', 'number']}
44 | ],
45 | result = this.check(arr)
46 | if (!result.success) {
47 | res.json({
48 | code: 20301,
49 | success: false,
50 | message: result.message
51 | })
52 | return
53 | }
54 | next()
55 | }
56 | async delete (req, res, next) {
57 | const ID = req.params.id,
58 | arr = [
59 | {label: 'ID', value: ID, rules: ['notnull']}
60 | ],
61 | result = this.check(arr)
62 | if (!result.success) {
63 | res.json({
64 | code: 20301,
65 | success: false,
66 | message: result.message
67 | })
68 | return
69 | }
70 | next()
71 | }
72 | async getRow (req, res, next) {
73 | const ID = req.params.id,
74 | arr = [
75 | {label: 'ID', value: ID, rules: ['notnull']}
76 | ],
77 | result = this.check(arr)
78 | if (!result.success) {
79 | res.json({
80 | code: 20301,
81 | success: false,
82 | message: result.message
83 | })
84 | return
85 | }
86 | next()
87 | }
88 | async getList (req, res, next) {
89 | const data = req.query,
90 | arr = [
91 | {label: 'curPage', value: data.curPage, rules: ['notnull', 'number']},
92 | {label: 'pageSize', value: data.curPage, rules: ['notnull', 'number']}
93 | ],
94 | result = this.check(arr)
95 | if (!result.success) {
96 | res.json({
97 | code: 20301,
98 | success: false,
99 | message: result.message
100 | })
101 | return
102 | }
103 | next()
104 | }
105 | async getRoleMenu (req, res, next) {
106 | next()
107 | }
108 | async getAll (req, res, next) {
109 | next()
110 | }
111 | }
112 |
113 | export default new Menu()
114 |
--------------------------------------------------------------------------------
/router/menu.js:
--------------------------------------------------------------------------------
1 | import express from 'express'
2 | import Menu from '../controller/Menu'
3 | import ValidateMenu from '../validate/Menu'
4 | const router = express.Router()
5 |
6 | /**
7 | * 创建
8 | * @api {POST} /api/Menu/create 创建
9 | * @apiDescription 创建菜单
10 | * @apiName create
11 | * @apiHeader {String} Authorization token
12 | * @apiParam (参数) {Number} pid 父ID
13 | * @apiParam (参数) {Number} type 菜单类型: 1. 管理平台菜单 2. BBS菜单 3. 移动端菜单
14 | * @apiParam (参数) {String} code 菜单编码
15 | * @apiParam (参数) {String} name 菜单名称
16 | * @apiParam (参数) {String} icon 菜单图标
17 | * @apiParam (参数) {String} redirect 重定向路径: 配置菜单编码或URL
18 | * @apiParam (参数) {String} sort 排序
19 | * @apiParam (参数) {String} desc 描述
20 | * @apiParam (参数) {String} status 状态: 0:停用,1:启用(默认为1)
21 | * @apiSampleRequest /api/Menu/create
22 | * @apiGroup Menu
23 | * @apiVersion 0.0.1
24 | */
25 | router.post('/create', ValidateMenu.create, Menu.create)
26 | /**
27 | * 编辑
28 | * @api {put} /api/Menu/update 编辑
29 | * @apiDescription 编辑
30 | * @apiName update
31 | * @apiHeader {String} Authorization token
32 | * @apiParam (参数) {Number} id
33 | * @apiParam (参数) {Number} pid 父ID
34 | * @apiParam (参数) {Number} type 菜单类型: 1. 管理平台菜单 2. BBS菜单 3. 移动端菜单
35 | * @apiParam (参数) {String} code 菜单编码
36 | * @apiParam (参数) {String} name 菜单名称
37 | * @apiParam (参数) {String} icon 菜单图标
38 | * @apiParam (参数) {String} redirect 重定向路径: 配置菜单编码或URL
39 | * @apiParam (参数) {String} sort 排序
40 | * @apiParam (参数) {String} desc 描述
41 | * @apiParam (参数) {String} status 状态: 0:停用,1:启用(默认为1)
42 | * @apiSampleRequest /api/Menu/update
43 | * @apiGroup Menu
44 | * @apiVersion 0.0.1
45 | */
46 | router.put('/update', ValidateMenu.update, Menu.update)
47 | /**
48 | * 删除
49 | * @api {delete} /api/Menu/delete/:id 删除
50 | * @apiDescription 删除
51 | * @apiName delete
52 | * @apiHeader {String} Authorization token
53 | * @apiParam {Number} id
54 | * @apiSampleRequest /api/Menu/delete
55 | * @apiGroup Menu
56 | * @apiVersion 0.0.1
57 | */
58 | router.delete('/delete/:id', ValidateMenu.delete, Menu.delete)
59 |
60 | /**
61 | * 获取菜单信息
62 | * @api {get} /api/Menu/getRow 获取菜单信息
63 | * @apiDescription 获取菜单信息
64 | * @apiName getRow
65 | * @apiHeader {String} Authorization token
66 | * @apiParam {Number} id
67 | * @apiSampleRequest /api/Menu/getRow
68 | * @apiGroup Menu
69 | * @apiVersion 0.0.1
70 | */
71 | router.get('/getRow/:id', ValidateMenu.getRow, Menu.getRow)
72 | /**
73 | * 获取菜单列表
74 | * @api {get} /api/Menu/getList 获取菜单列表
75 | * @apiDescription 获取菜单列表
76 | * @apiName getList
77 | * @apiHeader {String} Authorization token
78 | * @apiParam (path参数) {Number} curPage
79 | * @apiParam (path参数) {Number} pageSize
80 | * @apiParam (path参数) {String} account 账号
81 | * @apiParam (path参数) {String} name 昵称
82 | * @apiParam (path参数) {Number} create_Menu
83 | * @apiSampleRequest /api/Menu/getList
84 | * @apiGroup Menu
85 | * @apiVersion 0.0.1
86 | */
87 | router.get('/getList', ValidateMenu.getList, Menu.getList)
88 | /**
89 | * 获取用户拥有的所有菜单
90 | * @api {get} /api/Menu/getRoleMenu 获取所有菜单
91 | * @apiDescription 获取所有菜单
92 | * @apiName getRoleMenu
93 | * @apiParam {Number} type
94 | * @apiHeader {String} Authorization token
95 | * @apiSampleRequest /api/Menu/getRoleMenu
96 | * @apiGroup Menu
97 | * @apiVersion 0.0.1
98 | */
99 | router.get('/getRoleMenu', ValidateMenu.getRoleMenu, Menu.getRoleMenu)
100 | /**
101 | * 获取所有菜单
102 | * @api {get} /api/Menu/getAll 获取所有菜单
103 | * @apiDescription 获取所有菜单
104 | * @apiName getAll
105 | * @apiParam {Number} type
106 | * @apiHeader {String} Authorization token
107 | * @apiSampleRequest /api/Menu/getAll
108 | * @apiGroup Menu
109 | * @apiVersion 0.0.1
110 | */
111 | router.get('/getAll', ValidateMenu.getAll, Menu.getAll)
112 |
113 | export default router
114 |
--------------------------------------------------------------------------------
/controller/RoleRelation.js:
--------------------------------------------------------------------------------
1 | import Base from './Base'
2 | import RoleRelationModel from '../model/RoleRelation'
3 |
4 | class RoleRelation extends Base {
5 | constructor () {
6 | super()
7 | this.setPermissions = this.setPermissions.bind(this)
8 | this.getPermissions = this.getPermissions.bind(this)
9 | this.setBindUser = this.setBindUser.bind(this)
10 | this.getBindUser = this.getBindUser.bind(this)
11 | }
12 | // 设置权限
13 | async setPermissions (req, res, next) {
14 | let userInfo = await this.getUserInfo(req), result,
15 | data = req.body
16 | try {
17 | result = await RoleRelationModel.setPermissions({
18 | get: {role_id: data.roleId},
19 | data: {
20 | menu: data.menu,
21 | permissions: data.permissions
22 | }
23 | })
24 | } catch (e) {
25 | this.handleException(req, res, e)
26 | return
27 | }
28 | if (result) {
29 | res.json({
30 | code: 20000,
31 | success: true,
32 | content: {},
33 | message: '操作成功'
34 | })
35 | } else {
36 | res.json({
37 | code: 20001,
38 | success: false,
39 | content: {},
40 | message: '操作失败'
41 | })
42 | }
43 | }
44 | // 获取权限
45 | async getPermissions (req, res, next) {
46 | let userInfo = await this.getUserInfo(req), menu, permissions,
47 | role_id = req.query.roleId
48 | // TODO: 不是改用户创建的角色,用户不能查看到这个角色的权限
49 | try {
50 | menu = await RoleRelationModel.getMenu({get: {role_id}})
51 | permissions = await RoleRelationModel.getDataPerms({get: {role_id}})
52 | } catch (e) {
53 | this.handleException(req, res, e)
54 | return
55 | }
56 | res.json({
57 | code: 20000,
58 | success: true,
59 | content: {
60 | menu: menu.map(item => item.id),
61 | permissions: permissions.map(item => item.id)
62 | },
63 | message: '操作成功'
64 | })
65 | }
66 | // 设置绑定用户
67 | async setBindUser (req, res, next) {
68 | let userInfo = await this.getUserInfo(req), checkBind, result,
69 | data = req.body
70 | try {
71 | // 当传入的用户已经有绑定的角色, 并且当前要绑定的不是之前的角色,则不往下执行
72 | checkBind = await RoleRelationModel.checkBindUser(data.user)
73 | checkBind = checkBind.filter(item => {
74 | return item.role_id !== data.roleId
75 | })
76 | if (checkBind.length > 0) {
77 | res.json({
78 | code: 20000,
79 | success: false,
80 | content: {},
81 | message: `用户<${checkBind[0].name}>已绑定角色<${checkBind[0].role_name}>, 请先解绑`
82 | })
83 | return
84 | }
85 | result = await RoleRelationModel.setBindUser({
86 | get: {role_id: data.roleId},
87 | data: {
88 | user: data.user
89 | }
90 | })
91 | } catch (e) {
92 | this.handleException(req, res, e)
93 | return
94 | }
95 | if (result) {
96 | res.json({
97 | code: 20000,
98 | success: true,
99 | content: {},
100 | message: '操作成功'
101 | })
102 | } else {
103 | res.json({
104 | code: 20001,
105 | success: false,
106 | content: {},
107 | message: '操作失败'
108 | })
109 | }
110 | }
111 | // 获取绑定用户
112 | async getBindUser (req, res, next) {
113 | let result, userInfo = await this.getUserInfo(req), role_id = req.query.roleId
114 | try {
115 | result = await RoleRelationModel.getBindUser({get: {role_id, userId: userInfo.id}})
116 | } catch (e) {
117 | this.handleException(req, res, e)
118 | return
119 | }
120 | res.json({
121 | code: 20000,
122 | success: true,
123 | content: result,
124 | message: '操作成功'
125 | })
126 | }
127 | }
128 |
129 | export default new RoleRelation()
130 |
--------------------------------------------------------------------------------
/controller/Authority.js:
--------------------------------------------------------------------------------
1 | import Base from './Base'
2 | import TokenModel from '../model/Token'
3 | import UserModel from '../model/User'
4 | import DataPermsModel from '../model/DataPerms'
5 | import JWT from 'jsonwebtoken'
6 |
7 | class Authority extends Base{
8 | constructor () {
9 | super()
10 | this.checkToken = this.checkToken.bind(this)
11 | this.setToken = this.setToken.bind(this)
12 | this.getToken = this.getToken.bind(this)
13 | this.permissions = this.permissions.bind(this)
14 | }
15 | // 验证Token令牌
16 | async checkToken (req, res, next) {
17 | const whiteList = ['/login', '/registered']
18 | // 登录和注册页面不作限制
19 | // TODO: 暂时不对获取数据的接口验证
20 | if (req.method.toLocaleLowerCase() === 'get' || whiteList.includes(req.path)) {
21 | next()
22 | return
23 | }
24 | let token = req.headers.authorization,
25 | message = '',
26 | success = false,
27 | content = {},
28 | search
29 | // token不存在
30 | if (!token) {
31 | res.json({
32 | code: 20201,
33 | success: false,
34 | content: {},
35 | message: '无访问权限'
36 | })
37 | return
38 | }
39 | // 验证 Token
40 | JWT.verify(token, 'BBS', (error, decoded) => {
41 | if (error) {
42 | success = false
43 | message = 'token验证失败'
44 | return
45 | }
46 | success = true
47 | content = decoded
48 | message = '验证tonken成功'
49 | })
50 | // 验证token格式失败
51 | if (!success) {
52 | res.json({
53 | code: 20201,
54 | success: false,
55 | content: {},
56 | message: '无效的token'
57 | })
58 | return
59 | }
60 | // 查询数据库中该token的相关信息
61 | try {
62 | search = await this.getToken({get: {[content.type + '_token']: token}})
63 | } catch (e) {
64 | res.json({
65 | code: 20200,
66 | success: false,
67 | content: {},
68 | message: '服务器内部错误'
69 | })
70 | return
71 | }
72 | // 验证Token不存在或者Token过期
73 | if (search.length === 0) {
74 | res.json({
75 | code: 20201,
76 | success: false,
77 | content: {},
78 | message: '无访问权限'
79 | })
80 | return
81 | } else if ((search[content.type + '_expire_time']) < +new Date()) {
82 | res.json({
83 | code: 20201,
84 | success: false,
85 | content: {},
86 | message: 'token过期'
87 | })
88 | return
89 | }
90 | next()
91 | }
92 | // 设置Token令牌
93 | async setToken (data, obj) {
94 | let result
95 | try {
96 | result = await TokenModel.setToken(data, obj)
97 | } catch (e) {
98 | throw e
99 | }
100 | }
101 | // 获取Token令牌
102 | async getToken (obj) {
103 | return TokenModel.getToken(obj)
104 | }
105 | // 验证用户是否有操作权限
106 | async permissions (req, res, next) {
107 | const baseUrl = req.baseUrl.split('/')
108 | const method = req.method
109 | const userInfo = await this.getUserInfo(req)
110 | const whiteList = ['/api/user/login', '/api/user/registered', '/api/user/loginOut',
111 | '/api/article/create', '/api/article/update',
112 | '/api/articleComments/create', '/api/articleComments/delete',
113 | '/api/draft/giveUp', '/api/draft/giveUpAll']
114 | let api = req.baseUrl + req.path
115 | // 如果是删除接口,将delete后面去掉再校验
116 | if (/delete/.test(api)) {
117 | api = api.replace(/\/[^/*]*$/, '')
118 | }
119 | // 当请求方式为get时或者登陆注册时,不需要验证数据权限
120 | if (method.toLocaleLowerCase() === 'get' || whiteList.includes(api) || whiteList.includes(req.originalUrl)) {
121 | next()
122 | return
123 | }
124 | // 查询当前接口是否配置权限
125 | const search = userInfo.id === 1 ?
126 | await DataPermsModel.getAll({get: {api}}) :
127 | await DataPermsModel.getRoleDataPerms({get: {role_id: userInfo.role_id, api: api.replace('/api/', '')}})
128 | if (search.length > 0) {
129 | next()
130 | } else {
131 | res.json({
132 | code: 20001,
133 | success: false,
134 | content: {},
135 | message: '无操作权限'
136 | })
137 | }
138 | }
139 | }
140 |
141 | export default new Authority()
142 |
--------------------------------------------------------------------------------
/controller/Question.js:
--------------------------------------------------------------------------------
1 | import Base from './Base'
2 | import QuestionModel from '../model/Question'
3 |
4 | class Question extends Base {
5 | constructor () {
6 | super()
7 | this.create = this.create.bind(this)
8 | this.update = this.update.bind(this)
9 | this.delete = this.delete.bind(this)
10 | this.getRow = this.getRow.bind(this)
11 | this.getList = this.getList.bind(this)
12 | this.getAll = this.getAll.bind(this)
13 | }
14 | // 创建
15 | async create (req, res, next) {
16 | let data = JSON.parse(JSON.stringify(req.body)),
17 | userInfo = await this.getUserInfo(req), result
18 | try {
19 | // 参数处理
20 | data.create_user = userInfo.id,
21 | data.create_time = new Date()
22 | result = await QuestionModel.create({
23 | set: data
24 | })
25 | } catch (e) {
26 | this.handleException(req, res, e)
27 | return
28 | }
29 | res.json({
30 | code: 20000,
31 | success: true,
32 | message: '创建成功'
33 | })
34 | }
35 | // 编辑
36 | async update (req, res, next) {
37 | let id = req.body.id,
38 | data = JSON.parse(JSON.stringify(req.body)),
39 | result,
40 | userInfo = await this.getUserInfo(req)
41 | // 参数处理
42 | data.update_user = userInfo.id
43 | data.update_time = new Date()
44 | delete data.id
45 | try {
46 | result = await QuestionModel.update({set: data, get: {id}})
47 | } catch (e) {
48 | this.handleException(req, res, e)
49 | return
50 | }
51 | if (result.affectedRows) {
52 | res.json({
53 | code: 20000,
54 | success: true,
55 | message: '操作成功'
56 | })
57 | } else {
58 | res.json({
59 | code: 20001,
60 | success: false,
61 | message: '编辑失败'
62 | })
63 | }
64 | }
65 | // 删除
66 | async delete (req, res, next) {
67 | const userInfo = await this.getUserInfo(req),
68 | result = await QuestionModel.update({set: {flag: 0, delete_user: userInfo.id, delete_time: new Date()}, get: {id: req.params.id}})
69 | if (result.affectedRows) {
70 | res.json({
71 | code: 20000,
72 | success: true,
73 | message: '删除成功'
74 | })
75 | } else {
76 | res.json({
77 | code: 20001,
78 | success: true,
79 | message: '删除失败'
80 | })
81 | }
82 | }
83 | // 获取单条数据
84 | async getRow (req, res, next) {
85 | const search = await QuestionModel.getRow({get: {id: req.params.id, flag: 1}})
86 | if (search.length === 0) {
87 | res.json({
88 | code: 20401,
89 | success: false,
90 | content: search,
91 | message: '查询信息不存在'
92 | })
93 | } else {
94 | res.json({
95 | code: 20000,
96 | success: true,
97 | content: search,
98 | message: '操作成功'
99 | })
100 | }
101 | }
102 | // 查询列表
103 | async getList (req, res, next) {
104 | let query = JSON.parse(JSON.stringify(req.query)),
105 | result,
106 | length,
107 | userInfo = await this.getUserInfo(req)
108 | // 设置非模糊查询字段
109 | for (let key in query) {
110 | if (['id', 'create_user'].indexOf(key) === -1) {
111 | query.like = [...query.like || [], key]
112 | }
113 | }
114 | try {
115 | result = await QuestionModel.getList({get: {...query, flag: 1}})
116 | length = await QuestionModel.getTotals({get: {...query, flag: 1}})
117 | } catch (e) {
118 | this.handleException(req, res, e)
119 | return
120 | }
121 | res.json({
122 | code: 20000,
123 | success: true,
124 | content: {
125 | result,
126 | curPage: +query.curPage,
127 | pageSize: +query.pageSize,
128 | totals: length ? length[0].count : 0
129 | },
130 | message: '操作成功'
131 | })
132 | }
133 | // 获取所有
134 | async getAll (req, res, next) {
135 | let result, query = req.query
136 | try {
137 | result = await QuestionModel.getAll({get: {...query, flag: 1}})
138 | } catch (e) {
139 | this.handleException(req, res, e)
140 | return
141 | }
142 | res.json({
143 | code: 20000,
144 | success: true,
145 | content: result,
146 | message: '操作成功'
147 | })
148 | }
149 | }
150 |
151 | export default new Question()
152 |
--------------------------------------------------------------------------------
/controller/Carousel.js:
--------------------------------------------------------------------------------
1 | import Base from './Base'
2 | import CarouselModel from '../model/Carousel'
3 |
4 | class Carousel extends Base {
5 | constructor () {
6 | super()
7 | this.create = this.create.bind(this)
8 | this.update = this.update.bind(this)
9 | this.delete = this.delete.bind(this)
10 | this.getRow = this.getRow.bind(this)
11 | this.getList = this.getList.bind(this)
12 | this.getAll = this.getAll.bind(this)
13 | }
14 | // 创建
15 | async create (req, res, next) {
16 | let data = JSON.parse(JSON.stringify(req.body)),
17 | userInfo = await this.getUserInfo(req), result
18 | try {
19 | // 参数处理
20 | data.create_user = userInfo.id,
21 | data.create_time = new Date()
22 | result = await CarouselModel.create({
23 | set: data
24 | })
25 | } catch (e) {
26 | this.handleException(req, res, e)
27 | return
28 | }
29 | res.json({
30 | code: 20000,
31 | success: true,
32 | message: '创建成功'
33 | })
34 | }
35 | // 编辑
36 | async update (req, res, next) {
37 | let id = req.body.id,
38 | data = JSON.parse(JSON.stringify(req.body)),
39 | result,
40 | search,
41 | userInfo = await this.getUserInfo(req)
42 | // 参数处理
43 | data.update_user = userInfo.id
44 | data.update_time = new Date()
45 | delete data.id
46 | // 设置同时启用的轮播数量为5个
47 | search = await CarouselModel.getRow({get: {status: 1, flag: 1}})
48 | if (search.length > 5) {
49 | res.json({
50 | code: 20001,
51 | success: false,
52 | message: '轮播最多同时启用五个!'
53 | })
54 | return
55 | }
56 | try {
57 | result = await CarouselModel.update({set: data, get: {id}})
58 | } catch (e) {
59 | this.handleException(req, res, e)
60 | return
61 | }
62 | if (result.affectedRows) {
63 | res.json({
64 | code: 20000,
65 | success: true,
66 | message: '操作成功'
67 | })
68 | } else {
69 | res.json({
70 | code: 20001,
71 | success: false,
72 | message: '编辑失败'
73 | })
74 | }
75 | }
76 | // 删除
77 | async delete (req, res, next) {
78 | const userInfo = await this.getUserInfo(req),
79 | result = await CarouselModel.update({set: {flag: 0, delete_user: userInfo.id, delete_time: new Date()}, get: {id: req.params.id}})
80 | if (result.affectedRows) {
81 | res.json({
82 | code: 20000,
83 | success: true,
84 | message: '删除成功'
85 | })
86 | } else {
87 | res.json({
88 | code: 20001,
89 | success: true,
90 | message: '删除失败'
91 | })
92 | }
93 | }
94 | // 获取单条数据
95 | async getRow (req, res, next) {
96 | const search = await CarouselModel.getRow({get: {id: req.params.id, flag: 1}})
97 | if (search.length === 0) {
98 | res.json({
99 | code: 20401,
100 | success: false,
101 | content: search,
102 | message: '查询信息不存在'
103 | })
104 | } else {
105 | res.json({
106 | code: 20000,
107 | success: true,
108 | content: search,
109 | message: '操作成功'
110 | })
111 | }
112 | }
113 | // 查询列表
114 | async getList (req, res, next) {
115 | let query = JSON.parse(JSON.stringify(req.query)),
116 | result,
117 | length,
118 | userInfo = await this.getUserInfo(req)
119 | // 设置非模糊查询字段
120 | for (let key in query) {
121 | if (['id', 'create_user'].indexOf(key) === -1) {
122 | query.like = [...query.like || [], key]
123 | }
124 | }
125 | try {
126 | result = await CarouselModel.getList({get: {...query, flag: 1}})
127 | length = await CarouselModel.getTotals({get: {...query, flag: 1}})
128 | } catch (e) {
129 | this.handleException(req, res, e)
130 | return
131 | }
132 | res.json({
133 | code: 20000,
134 | success: true,
135 | content: {
136 | result,
137 | curPage: +query.curPage,
138 | pageSize: +query.pageSize,
139 | totals: length ? length[0].count : 0
140 | },
141 | message: '操作成功'
142 | })
143 | }
144 | // 获取所有
145 | async getAll (req, res, next) {
146 | let result, query = req.query
147 | try {
148 | result = await CarouselModel.getAll({get: {...query, flag: 1}})
149 | } catch (e) {
150 | this.handleException(req, res, e)
151 | return
152 | }
153 | res.json({
154 | code: 20000,
155 | success: true,
156 | content: result,
157 | message: '操作成功'
158 | })
159 | }
160 | }
161 |
162 | export default new Carousel()
163 |
--------------------------------------------------------------------------------
/controller/TechSquare.js:
--------------------------------------------------------------------------------
1 | import Base from './Base'
2 | import TechSquareModel from '../model/TechSquare'
3 |
4 | class TechSquare extends Base {
5 | constructor () {
6 | super()
7 | this.create = this.create.bind(this)
8 | this.update = this.update.bind(this)
9 | this.delete = this.delete.bind(this)
10 | this.getRow = this.getRow.bind(this)
11 | this.getList = this.getList.bind(this)
12 | this.getAll = this.getAll.bind(this)
13 | }
14 | // 创建
15 | async create (req, res, next) {
16 | let data = JSON.parse(JSON.stringify(req.body)),
17 | userInfo = await this.getUserInfo(req), result
18 | try {
19 | // 参数处理
20 | data.create_user = userInfo.id,
21 | data.create_time = new Date()
22 | result = await TechSquareModel.create({
23 | set: data
24 | })
25 | } catch (e) {
26 | this.handleException(req, res, e)
27 | return
28 | }
29 | res.json({
30 | code: 20000,
31 | success: true,
32 | message: '创建成功'
33 | })
34 | }
35 | // 编辑
36 | async update (req, res, next) {
37 | let id = req.body.id,
38 | data = JSON.parse(JSON.stringify(req.body)),
39 | result,
40 | search,
41 | userInfo = await this.getUserInfo(req)
42 | // 参数处理
43 | data.update_user = userInfo.id
44 | data.update_time = new Date()
45 | delete data.id
46 | // 设置同时启用的轮播数量为5个
47 | search = await TechSquareModel.getRow({get: {status: 1, flag: 1}})
48 | if (search.length > 15) {
49 | res.json({
50 | code: 20001,
51 | success: false,
52 | message: '技术频道最多同时启用15个!'
53 | })
54 | return
55 | }
56 | try {
57 | result = await TechSquareModel.update({set: data, get: {id}})
58 | } catch (e) {
59 | this.handleException(req, res, e)
60 | return
61 | }
62 | if (result.affectedRows) {
63 | res.json({
64 | code: 20000,
65 | success: true,
66 | message: '操作成功'
67 | })
68 | } else {
69 | res.json({
70 | code: 20001,
71 | success: false,
72 | message: '编辑失败'
73 | })
74 | }
75 | }
76 | // 删除
77 | async delete (req, res, next) {
78 | const userInfo = await this.getUserInfo(req),
79 | result = await TechSquareModel.update({set: {flag: 0, delete_user: userInfo.id, delete_time: new Date()}, get: {id: req.params.id}})
80 | if (result.affectedRows) {
81 | res.json({
82 | code: 20000,
83 | success: true,
84 | message: '删除成功'
85 | })
86 | } else {
87 | res.json({
88 | code: 20001,
89 | success: true,
90 | message: '删除失败'
91 | })
92 | }
93 | }
94 | // 获取单条数据
95 | async getRow (req, res, next) {
96 | const search = await TechSquareModel.getRow({get: {id: req.params.id, flag: 1}})
97 | if (search.length === 0) {
98 | res.json({
99 | code: 20401,
100 | success: false,
101 | content: search,
102 | message: '查询信息不存在'
103 | })
104 | } else {
105 | res.json({
106 | code: 20000,
107 | success: true,
108 | content: search,
109 | message: '操作成功'
110 | })
111 | }
112 | }
113 | // 查询列表
114 | async getList (req, res, next) {
115 | let query = JSON.parse(JSON.stringify(req.query)),
116 | result,
117 | length,
118 | userInfo = await this.getUserInfo(req)
119 | // 设置非模糊查询字段
120 | for (let key in query) {
121 | if (['id', 'create_user'].indexOf(key) === -1) {
122 | query.like = [...query.like || [], key]
123 | }
124 | }
125 | try {
126 | result = await TechSquareModel.getList({get: {...query, flag: 1}})
127 | length = await TechSquareModel.getTotals({get: {...query, flag: 1}})
128 | } catch (e) {
129 | this.handleException(req, res, e)
130 | return
131 | }
132 | res.json({
133 | code: 20000,
134 | success: true,
135 | content: {
136 | result,
137 | curPage: +query.curPage,
138 | pageSize: +query.pageSize,
139 | totals: length ? length[0].count : 0
140 | },
141 | message: '操作成功'
142 | })
143 | }
144 | // 获取所有
145 | async getAll (req, res, next) {
146 | let result, status = req.query.status
147 | try {
148 | result = await TechSquareModel.getAll(status ? {get: {status, flag: 1}} : {get: {flag: 1}})
149 | } catch (e) {
150 | this.handleException(req, res, e)
151 | return
152 | }
153 | res.json({
154 | code: 20000,
155 | success: true,
156 | content: result,
157 | message: '操作成功'
158 | })
159 | }
160 | }
161 |
162 | export default new TechSquare()
163 |
--------------------------------------------------------------------------------
/public/article/test_20190516145913_bun1.md:
--------------------------------------------------------------------------------
1 | > 最近在自己写页面,模仿思否论坛,然后写登录注册UI的时候需要一个验证码组件. 去搜一下没找到什么合适的,而且大多都是基于后端的,于是自己手写一个。
2 |
3 | ## 演示 ##
4 | ![图片描述][1]
5 |
6 |
7 | ## 分析验证码组件 ##
8 |
9 | **分析验证码功能**
10 |
11 | 1. 随机出现的数字大小写字母 (基础功能)
12 | 2. 不同的数字或者字母有不同的颜色 (功能优化)
13 | 3. 不同的数字或者字母有不同的字体大写 (功能优化)
14 | 4. 不同的数字或者字母有不同的边距 (功能优化)
15 | 5. 不同的数字或者字母有不同的倾斜角度 (功能优化)
16 | 6. 更多功能优化...
17 |
18 |
19 | ----------
20 | **分析组件功能**
21 | 1. 可以设置生成验证码的长度 (基本功能)
22 | 2. 可以设置验证码组件的宽高 (基本功能)
23 |
24 |
25 | ----------
26 | ## 编写验证码组件 ##
27 |
28 | **template**
29 |
30 | 最外层div绑定点击事件,点击后刷新验证码。
31 | span是单个验证码的载体,样式动态绑定
32 | ```
33 |
34 |
35 | {{item.code}}
36 |
37 |
38 | ```
39 | **methods**
40 |
41 | refreshCode 刷新验证码的方法
42 | createdCode 生成验证码的方法
43 | getStyle 为每个元素生成动态的样式
44 | ```
45 | methods: {
46 | refreshCode () {
47 | this.createdCode()
48 | },
49 | createdCode () {
50 | let len = this.length,
51 | codeList = [],
52 | chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz0123456789',
53 | charsLen = chars.length
54 | // 生成
55 | for (let i = 0; i < len; i++) {
56 | let rgb = [Math.round(Math.random() * 220), Math.round(Math.random() * 240), Math.round(Math.random() * 200)]
57 | codeList.push({
58 | code: chars.charAt(Math.floor(Math.random() * charsLen)), // 随机码
59 | color: `rgb(${rgb})`, // 随机颜色
60 | fontSize: `1${[Math.floor(Math.random() * 10)]}px`, // 随机字号
61 | padding: `${[Math.floor(Math.random() * 10)]}px`, // 随机内边距
62 | transform: `rotate(${Math.floor(Math.random() * 90) - Math.floor(Math.random() * 90)}deg)` // 随机旋转角度
63 | })
64 | }
65 | // 指向
66 | this.codeList = codeList
67 | // 将当前数据派发出去
68 | this.$emit('update:value', codeList.map(item => item.code).join(''))
69 | },
70 | // 动态绑定样式
71 | getStyle (data) {
72 | return `color: ${data.color}; font-size: ${data.fontSize}; padding: ${data.padding}; transform: ${data.transform}`
73 | }
74 | }
75 | ```
76 |
77 | **完整代码**
78 | --------
79 |
80 | **使用**
81 |
82 | ```
83 |
84 | ```
85 |
86 | **组件**
87 | ```
88 |
89 |
90 | {{item.code}}
91 |
92 |
93 |
94 |
150 |
151 |
162 |
163 | ```
164 |
165 | [源码地址][2]
166 |
167 | [演示地址][3] 模仿思否写的网站,点注册可看到验证码
168 |
169 | [1]: https://image-static.segmentfault.com/601/311/6013117-5c4576fbd5d3c_articlex
170 | [2]: https://github.com/2017coding/BBS/tree/master/src/components/ValidCode
171 | [3]: https://lyh.red/#/
--------------------------------------------------------------------------------
/controller/DataPerms.js:
--------------------------------------------------------------------------------
1 | import Base from './Base'
2 | import DataPermsModel from '../model/DataPerms'
3 |
4 | class DataPerms extends Base {
5 | constructor () {
6 | super()
7 | this.create = this.create.bind(this)
8 | this.update = this.update.bind(this)
9 | this.delete = this.delete.bind(this)
10 | this.getRow = this.getRow.bind(this)
11 | this.getList = this.getList.bind(this)
12 | this.getRoleDataPerms = this.getRoleDataPerms.bind(this)
13 | this.getAll = this.getAll.bind(this)
14 | }
15 | // 创建
16 | async create (req, res, next) {
17 | try {
18 | let data = JSON.parse(JSON.stringify(req.body)),
19 | userInfo = await this.getUserInfo(req),
20 | result
21 | // 参数处理
22 | data.create_user = userInfo.id,
23 | data.create_time = new Date()
24 | result = await DataPermsModel.create({
25 | set: data
26 | })
27 | } catch (e) {
28 | this.handleException(req, res, e)
29 | return
30 | }
31 | res.json({
32 | code: 20000,
33 | success: true,
34 | message: '创建成功'
35 | })
36 | }
37 | // 编辑
38 | async update (req, res, next) {
39 | let id = req.body.id,
40 | data = JSON.parse(JSON.stringify(req.body)),
41 | result,
42 | userInfo = await this.getUserInfo(req)
43 | // 参数处理
44 | data.update_user = userInfo.id
45 | data.update_time = new Date()
46 | delete data.id
47 | try {
48 | result = await DataPermsModel.update({set: data, get: {id}})
49 | } catch (e) {
50 | this.handleException(req, res, e)
51 | return
52 | }
53 | if (result.affectedRows) {
54 | res.json({
55 | code: 20000,
56 | success: true,
57 | message: '操作成功'
58 | })
59 | } else {
60 | res.json({
61 | code: 20001,
62 | success: false,
63 | message: '编辑失败'
64 | })
65 | }
66 | }
67 | // 删除
68 | async delete (req, res, next) {
69 | const userInfo = await this.getUserInfo(req),
70 | result = await DataPermsModel.update({set: {flag: 0, delete_user: userInfo.id, delete_time: new Date()}, get: {id: req.params.id}})
71 | if (result.affectedRows) {
72 | res.json({
73 | code: 20000,
74 | success: true,
75 | message: '删除成功'
76 | })
77 | } else {
78 | res.json({
79 | code: 20001,
80 | success: true,
81 | message: '删除失败'
82 | })
83 | }
84 | }
85 | // 获取单条数据
86 | async getRow (req, res, next) {
87 | const search = await DataPermsModel.getRow({get: {id: req.params.id}})
88 | if (search.length === 0) {
89 | res.json({
90 | code: 20401,
91 | success: false,
92 | content: search,
93 | message: '查询信息不存在'
94 | })
95 | } else {
96 | res.json({
97 | code: 20000,
98 | success: true,
99 | content: search,
100 | message: '操作成功'
101 | })
102 | }
103 | }
104 | // 查询列表
105 | async getList (req, res, next) {
106 | let query = JSON.parse(JSON.stringify(req.query)),
107 | result,
108 | length,
109 | userInfo = await this.getUserInfo(req)
110 | // 设置非模糊查询字段
111 | for (let key in query) {
112 | if (['id', 'create_user'].indexOf(key) === -1) {
113 | query.like = [...query.like || [], key]
114 | }
115 | }
116 | try {
117 | result = await DataPermsModel.getList({get: query})
118 | length = await DataPermsModel.getTotals({get: query})
119 | } catch (e) {
120 | this.handleException(req, res, e)
121 | return
122 | }
123 | res.json({
124 | code: 20000,
125 | success: true,
126 | content: {
127 | result,
128 | curPage: +query.curPage,
129 | pageSize: +query.pageSize,
130 | totals: length ? length[0].count : 0
131 | },
132 | message: '操作成功'
133 | })
134 | }
135 | // 获取当前用户拥有
136 | async getRoleDataPerms (req, res, next) {
137 | let menuId = req.query.menuId, result, userInfo = await this.getUserInfo(req)
138 | try {
139 | result = userInfo.id === 1 ?
140 | await DataPermsModel.getAll({get: {menu_id: menuId}}) :
141 | await DataPermsModel.getRoleDataPerms({get: {menu_id: menuId, role_id: userInfo.role_id}})
142 | } catch (e) {
143 | this.handleException(req, res, e)
144 | return
145 | }
146 | res.json({
147 | code: 20000,
148 | success: true,
149 | content: result,
150 | message: '操作成功'
151 | })
152 | }
153 | // 获取所有
154 | async getAll (req, res, next) {
155 | let menuId = req.query.menuId, result
156 | try {
157 | result = await DataPermsModel.getAll(menuId ? {get: {menu_id: menuId}} : '')
158 | } catch (e) {
159 | this.handleException(req, res, e)
160 | return
161 | }
162 | res.json({
163 | code: 20000,
164 | success: true,
165 | content: result,
166 | message: '操作成功'
167 | })
168 | }
169 | }
170 |
171 | export default new DataPerms()
172 |
--------------------------------------------------------------------------------
/controller/Menu.js:
--------------------------------------------------------------------------------
1 | import Base from './Base'
2 | import MenuModel from '../model/Menu'
3 |
4 | class Menu extends Base {
5 | constructor () {
6 | super()
7 | this.create = this.create.bind(this)
8 | this.update = this.update.bind(this)
9 | this.delete = this.delete.bind(this)
10 | this.getRow = this.getRow.bind(this)
11 | this.getList = this.getList.bind(this)
12 | this.getRoleMenu = this.getRoleMenu.bind(this)
13 | this.getAll = this.getAll.bind(this)
14 | }
15 | // 创建
16 | async create (req, res, next) {
17 | try {
18 | let data = JSON.parse(JSON.stringify(req.body)),
19 | userInfo = await this.getUserInfo(req), result
20 | // 参数处理
21 | data.create_user = userInfo.id,
22 | data.create_time = new Date()
23 | result = await MenuModel.create({
24 | set: data
25 | })
26 | } catch (e) {
27 | this.handleException(req, res, e)
28 | return
29 | }
30 | res.json({
31 | code: 20000,
32 | success: true,
33 | message: '创建成功'
34 | })
35 | }
36 | // 编辑
37 | async update (req, res, next) {
38 | let id = req.body.id,
39 | data = JSON.parse(JSON.stringify(req.body)),
40 | result,
41 | userInfo = await this.getUserInfo(req)
42 | // 参数处理
43 | data.update_user = userInfo.id
44 | data.update_time = new Date()
45 | delete data.id
46 | try {
47 | result = await MenuModel.update({set: data, get: {id}})
48 | } catch (e) {
49 | this.handleException(req, res, e)
50 | return
51 | }
52 | if (result.affectedRows) {
53 | res.json({
54 | code: 20000,
55 | success: true,
56 | message: '操作成功'
57 | })
58 | } else {
59 | res.json({
60 | code: 20001,
61 | success: false,
62 | message: '编辑失败'
63 | })
64 | }
65 | }
66 | // 删除
67 | async delete (req, res, next) {
68 | // 如果当前模块下面有节点,则不能删除
69 | const child = await MenuModel.getAll({get: {pid: req.params.id}})
70 | if (child.length > 0) {
71 | res.json({
72 | code: 20001,
73 | success: false,
74 | message: '请先删除子目录'
75 | })
76 | return
77 | }
78 | const userInfo = await this.getUserInfo(req),
79 | result = await MenuModel.update({set: {flag: 0, delete_user: userInfo.id, delete_time: new Date()}, get: {id: req.params.id}})
80 | if (result.affectedRows) {
81 | res.json({
82 | code: 20000,
83 | success: true,
84 | message: '删除成功'
85 | })
86 | } else {
87 | res.json({
88 | code: 20001,
89 | success: true,
90 | message: '删除失败'
91 | })
92 | }
93 | }
94 | // 获取单条数据
95 | async getRow (req, res, next) {
96 | const search = await MenuModel.getRow({get: {id: req.params.id, flag: 1}})
97 | if (search.length === 0) {
98 | res.json({
99 | code: 20401,
100 | success: false,
101 | content: search,
102 | message: '查询信息不存在'
103 | })
104 | } else {
105 | res.json({
106 | code: 20000,
107 | success: true,
108 | content: search,
109 | message: '操作成功'
110 | })
111 | }
112 | }
113 | // 查询列表
114 | async getList (req, res, next) {
115 | let query = JSON.parse(JSON.stringify(req.query)),
116 | result,
117 | length,
118 | userInfo = await this.getUserInfo(req)
119 | // 设置非模糊查询字段
120 | for (let key in query) {
121 | if (['id', 'create_user'].indexOf(key) === -1) {
122 | query.like = [...query.like || [], key]
123 | }
124 | }
125 | try {
126 | result = await MenuModel.getList({get: {...query, flag: 1}})
127 | length = await MenuModel.getTotals({get: {...query, flag: 1}})
128 | } catch (e) {
129 | this.handleException(req, res, e)
130 | return
131 | }
132 | res.json({
133 | code: 20000,
134 | success: true,
135 | content: {
136 | result,
137 | curPage: +query.curPage,
138 | pageSize: +query.pageSize,
139 | totals: length ? length[0].count : 0
140 | },
141 | message: '操作成功'
142 | })
143 | }
144 | // 获取角色拥有的模块
145 | async getRoleMenu (req, res, next) {
146 | let result, query = req.query
147 | try {
148 | result = await MenuModel.getRoleMenu({get: {type: query.type, role_id: query.roleId, flag: 1}})
149 | } catch (e) {
150 | this.handleException(req, res, e)
151 | return
152 | }
153 | res.json({
154 | code: 20000,
155 | success: true,
156 | content: result,
157 | message: '操作成功'
158 | })
159 | }
160 | // 获取所有
161 | async getAll (req, res, next) {
162 | let result, query = req.query
163 | try {
164 | result = await MenuModel.getAll({get: {...query, flag: 1}})
165 | } catch (e) {
166 | this.handleException(req, res, e)
167 | return
168 | }
169 | res.json({
170 | code: 20000,
171 | success: true,
172 | content: result,
173 | message: '操作成功'
174 | })
175 | }
176 | }
177 |
178 | export default new Menu()
179 |
--------------------------------------------------------------------------------
/controller/Tag.js:
--------------------------------------------------------------------------------
1 | import Base from './Base'
2 | import TagModel from '../model/Tag'
3 |
4 | class Tag extends Base {
5 | constructor () {
6 | super()
7 | this.create = this.create.bind(this)
8 | this.update = this.update.bind(this)
9 | this.delete = this.delete.bind(this)
10 | this.getRow = this.getRow.bind(this)
11 | this.getList = this.getList.bind(this)
12 | this.getAll = this.getAll.bind(this)
13 | }
14 | // 创建
15 | async create (req, res, next) {
16 | let data = JSON.parse(JSON.stringify(req.body)),
17 | userInfo = await this.getUserInfo(req), result, search, path
18 | // 查询标签是否存在
19 | try {
20 | search = await TagModel.getRow({get: {name: data.name, flag: 1}})
21 | } catch (e) {
22 | this.handleException(req, res, e)
23 | return
24 | }
25 | // 如果存在,提示
26 | if (search.length === 0) {
27 | try {
28 | // 参数处理
29 | data.create_user = userInfo.id,
30 | data.create_time = new Date()
31 | result = await TagModel.create({
32 | set: data
33 | })
34 | } catch (e) {
35 | this.handleException(req, res, e)
36 | return
37 | }
38 | res.json({
39 | code: 20000,
40 | success: true,
41 | message: '创建成功'
42 | })
43 | } else {
44 | res.json({
45 | code: 20001,
46 | success: false,
47 | message: '标签已存在'
48 | })
49 | }
50 | }
51 | // 编辑
52 | async update (req, res, next) {
53 | let id = req.body.id,
54 | data = JSON.parse(JSON.stringify(req.body)),
55 | result,
56 | search,
57 | userInfo = await this.getUserInfo(req)
58 | // 参数处理
59 | data.update_user = userInfo.id
60 | data.update_time = new Date()
61 | delete data.id
62 | // 查询标签是否存在
63 | try {
64 | search = await TagModel.getRow({get: {name: data.name, flag: 1}})
65 | } catch (e) {
66 | this.handleException(req, res, e)
67 | return
68 | }
69 | // 修改的名字重复
70 | if (search.length > 0 && search[0].id !== id) {
71 | res.json({
72 | code: 20001,
73 | success: false,
74 | message: '标签名字重复'
75 | })
76 | return
77 | }
78 | try {
79 | result = await TagModel.update({set: data, get: {id}})
80 | } catch (e) {
81 | this.handleException(req, res, e)
82 | return
83 | }
84 | if (result.affectedRows) {
85 | res.json({
86 | code: 20000,
87 | success: true,
88 | message: '操作成功'
89 | })
90 | } else {
91 | res.json({
92 | code: 20001,
93 | success: false,
94 | message: '编辑失败'
95 | })
96 | }
97 | }
98 | // 删除
99 | async delete (req, res, next) {
100 | const userInfo = await this.getUserInfo(req),
101 | result = await TagModel.update({set: {flag: 0, delete_user: userInfo.id, delete_time: new Date()}, get: {id: req.params.id}})
102 | if (result.affectedRows) {
103 | res.json({
104 | code: 20000,
105 | success: true,
106 | message: '删除成功'
107 | })
108 | } else {
109 | res.json({
110 | code: 20001,
111 | success: true,
112 | message: '删除失败'
113 | })
114 | }
115 | }
116 | // 获取单条数据
117 | async getRow (req, res, next) {
118 | const search = await TagModel.getRow({get: {id: req.params.id, flag: 1}})
119 | if (search.length === 0) {
120 | res.json({
121 | code: 20401,
122 | success: false,
123 | content: search,
124 | message: '查询信息不存在'
125 | })
126 | } else {
127 | res.json({
128 | code: 20000,
129 | success: true,
130 | content: search,
131 | message: '操作成功'
132 | })
133 | }
134 | }
135 | // 查询列表
136 | async getList (req, res, next) {
137 | let query = JSON.parse(JSON.stringify(req.query)),
138 | result,
139 | length,
140 | userInfo = await this.getUserInfo(req)
141 | // 设置非模糊查询字段
142 | for (let key in query) {
143 | if (['id', 'create_user', 'type_id'].indexOf(key) === -1) {
144 | query.like = [...query.like || [], key]
145 | }
146 | }
147 | try {
148 | result = await TagModel.getList({get: {...query, flag: 1}})
149 | length = await TagModel.getTotals({get: {...query, flag: 1}})
150 | } catch (e) {
151 | this.handleException(req, res, e)
152 | return
153 | }
154 | res.json({
155 | code: 20000,
156 | success: true,
157 | content: {
158 | result,
159 | curPage: +query.curPage,
160 | pageSize: +query.pageSize,
161 | totals: length ? length[0].count : 0
162 | },
163 | message: '操作成功'
164 | })
165 | }
166 | // 获取所有
167 | async getAll (req, res, next) {
168 | let result, query = req.query
169 | try {
170 | result = await TagModel.getAll({get: {...query, flag: 1}})
171 | } catch (e) {
172 | this.handleException(req, res, e)
173 | return
174 | }
175 | res.json({
176 | code: 20000,
177 | success: true,
178 | content: result,
179 | message: '操作成功'
180 | })
181 | }
182 | }
183 |
184 | export default new Tag()
185 |
--------------------------------------------------------------------------------