├── key
├── alipay-public-key.pem
├── apiclient_key.pem
├── apiclient_cert.pem
├── apiclient_cert.p12
├── alipayCertPublicKey_RSA2.crt
├── alipay-private-key.pem
├── appCertPublicKey_2021001193638066.crt
└── alipayRootCert.crt
├── views
├── error.ejs
└── index.ejs
├── public
├── export
│ └── 用户列表-20201220133328.xlsx
└── stylesheets
│ └── style.css
├── config
├── index.js
├── prod.js
└── dev.js
├── routes
├── upload.js
├── index.js
├── log.js
├── sms.js
├── times.js
├── register.js
├── update.js
├── system.js
├── score.js
├── favorite.js
├── entries.js
├── banners.js
├── administrator.js
├── address.js
├── money.js
├── sign.js
├── statistics.js
├── certifications.js
├── refresh.js
├── help.js
├── user.js
├── messages.js
├── withdraw.js
├── goods.js
├── login.js
├── order.js
└── tasks.js
├── schedule
└── index.js
├── service
├── message.js
└── user.js
├── middlewares
├── times.js
├── upload.js
├── export.js
├── register.js
├── update.js
├── sms.js
├── log.js
├── score.js
├── banners.js
├── address.js
├── favorite.js
├── administrator.js
├── entries.js
├── sign.js
├── money.js
├── certifications.js
├── help.js
├── refresh.js
├── statistics.js
├── messages.js
└── system.js
├── package.json
├── README.md
├── bin
└── www
├── utils
├── pool.js
├── function.js
├── download.js
├── avatar.js
├── wepay.js
└── md5.js
└── app.js
/key/alipay-public-key.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN PUBLIC KEY-----
2 | -----END PUBLIC KEY-----
--------------------------------------------------------------------------------
/key/apiclient_key.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN PRIVATE KEY-----
2 |
3 | -----END PRIVATE KEY-----
4 |
--------------------------------------------------------------------------------
/key/apiclient_cert.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN CERTIFICATE-----
2 |
3 | -----END CERTIFICATE-----
4 |
--------------------------------------------------------------------------------
/key/apiclient_cert.p12:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xigupro/SharkTask_Server/HEAD/key/apiclient_cert.p12
--------------------------------------------------------------------------------
/views/error.ejs:
--------------------------------------------------------------------------------
1 |
<%= message %>
2 | <%= error.status %>
3 | <%= error.stack %>
4 |
--------------------------------------------------------------------------------
/public/export/用户列表-20201220133328.xlsx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xigupro/SharkTask_Server/HEAD/public/export/用户列表-20201220133328.xlsx
--------------------------------------------------------------------------------
/config/index.js:
--------------------------------------------------------------------------------
1 | const dev = require('./dev');
2 | const prod = require('./prod');
3 | module.exports = process.env.NODE_ENV === 'development' ? dev : prod;
4 |
--------------------------------------------------------------------------------
/public/stylesheets/style.css:
--------------------------------------------------------------------------------
1 | body {
2 | padding: 50px;
3 | font: 14px "Lucida Grande", Helvetica, Arial, sans-serif;
4 | }
5 |
6 | a {
7 | color: #00B7FF;
8 | }
9 |
--------------------------------------------------------------------------------
/routes/upload.js:
--------------------------------------------------------------------------------
1 | const express = require('express');
2 | const router = express.Router();
3 | const { upload } = require('../middlewares/upload.js');
4 |
5 | // 获取七牛上传token
6 | router.post('/token', upload.img);
7 |
8 | module.exports = router;
--------------------------------------------------------------------------------
/routes/index.js:
--------------------------------------------------------------------------------
1 | var express = require('express');
2 | var router = express.Router();
3 |
4 | /* GET home page. */
5 | router.get('/', function(req, res, next) {
6 | res.render('index', { title: '鲨鱼任务' });
7 | });
8 |
9 | module.exports = router;
10 |
--------------------------------------------------------------------------------
/routes/log.js:
--------------------------------------------------------------------------------
1 | const express = require('express');
2 | const router = express.Router();
3 | const { log } = require('../middlewares/log.js');
4 |
5 | router.post('/list', log.list, function(req, res, next) {
6 | res.json(req.body);
7 | });
8 | module.exports = router;
9 |
--------------------------------------------------------------------------------
/routes/sms.js:
--------------------------------------------------------------------------------
1 | const express = require('express');
2 | const router = express.Router();
3 | const { sms } = require('../middlewares/sms.js');
4 |
5 | router.post('/send', sms.send, function(req, res, next) {
6 | res.json(req.body);
7 | });
8 |
9 | module.exports = router;
10 |
--------------------------------------------------------------------------------
/routes/times.js:
--------------------------------------------------------------------------------
1 | const express = require('express');
2 | const router = express.Router();
3 | const { times } = require('../middlewares/times.js');
4 |
5 | router.post('/list', times.list, function(req, res, next) {
6 | res.json(req.body);
7 | });
8 |
9 |
10 | module.exports = router;
11 |
--------------------------------------------------------------------------------
/views/index.ejs:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | <%= title %>
5 |
6 |
7 |
8 | <%= title %>
9 | 欢迎来到 <%= title %>
10 |
11 |
12 |
--------------------------------------------------------------------------------
/routes/register.js:
--------------------------------------------------------------------------------
1 | const express = require('express');
2 | const router = express.Router();
3 | const { register } = require('../middlewares/register.js');
4 |
5 | router.post('/', register.add, function(req, res, next) {
6 | res.json(req.body);
7 | });
8 |
9 |
10 | module.exports = router;
11 |
--------------------------------------------------------------------------------
/routes/update.js:
--------------------------------------------------------------------------------
1 | const express = require('express');
2 | const router = express.Router();
3 | const { update } = require('../middlewares/update.js');
4 |
5 | router.post('/userTasks', update.userTasks, function(req, res, next) {
6 | res.json(req.body);
7 | });
8 |
9 |
10 | module.exports = router;
11 |
--------------------------------------------------------------------------------
/schedule/index.js:
--------------------------------------------------------------------------------
1 | const schedule = require('node-schedule')
2 | const { UserService } = require('../service/user')
3 |
4 | const scheduleCronstyle = () => {
5 | console.info('定时任务启动')
6 |
7 | schedule.scheduleJob('0 0 4 1 * *', async () => {
8 | console.info('每月1号凌晨4点执行定时任务:', new Date().toLocaleString())
9 | // 每月1号凌晨4点发放用户等级奖金
10 | await UserService.sendAward()
11 | })
12 | }
13 |
14 | scheduleCronstyle()
15 |
--------------------------------------------------------------------------------
/routes/system.js:
--------------------------------------------------------------------------------
1 | const express = require('express');
2 | const router = express.Router();
3 | const { login } = require('../middlewares/login.js');
4 | const { log } = require('../middlewares/log.js');
5 | const { system } = require('../middlewares/system.js');
6 |
7 | // 获取系统配置
8 | router.post('/get', system.get, function(req, res, next) {
9 | res.json(req.body);
10 | });
11 |
12 | // 更新系统配置
13 | router.post('/update', login.check, system.update, log.add, function(req, res, next) {
14 | res.json(req.body);
15 | });
16 |
17 |
18 | module.exports = router;
19 |
--------------------------------------------------------------------------------
/service/message.js:
--------------------------------------------------------------------------------
1 | /*
2 | * @Author: 唐文雍
3 | * @Date: 2019-01-16 10:17:32
4 | * @Last Modified by: 唐文雍
5 | * @Last Modified time: 2019-01-16 10:17:32
6 | */
7 | const query = require('../utils/pool');
8 | const MessageService = {};
9 | exports.MessageService = MessageService;
10 |
11 | // 添加客户端首页动态
12 | MessageService.addDynamic = async function(title) {
13 | const created_at = Date.now();
14 | const sql = `insert into messages(type,user_id,title,content,business_id,created_at)
15 | values(8,0,'${title}','','','${created_at}')`;
16 | const result = await query(sql, null, null, '新增动态')
17 | console.info('新增动态返回', result)
18 | }
--------------------------------------------------------------------------------
/routes/score.js:
--------------------------------------------------------------------------------
1 | const express = require('express');
2 | const router = express.Router();
3 | const { login } = require('../middlewares/login.js');
4 | const { log } = require('../middlewares/log.js');
5 | const { score } = require('../middlewares/score.js');
6 |
7 | router.post('/stream', score.stream, function(req, res, next) {
8 | res.json(req.body);
9 | });
10 |
11 | router.post('/add', login.check, score.add, log.add, function(req, res, next) {
12 | res.json(req.body);
13 | });
14 |
15 | router.post('/getLuckyDrawList', login.check, score.getLuckyDrawList, function(req, res, next) {
16 | res.json(req.body);
17 | });
18 |
19 |
20 | module.exports = router;
21 |
--------------------------------------------------------------------------------
/routes/favorite.js:
--------------------------------------------------------------------------------
1 | const express = require('express');
2 | const router = express.Router();
3 | const { login } = require('../middlewares/login.js');
4 | const { favorite } = require('../middlewares/favorite.js');
5 |
6 | router.post('/list', login.check, favorite.list, function(req, res, next) {
7 | res.json(req.body);
8 | });
9 |
10 | router.post('/add', login.check, favorite.add, function(req, res, next) {
11 | res.json(req.body);
12 | });
13 |
14 | router.post('/remove', login.check, favorite.remove, function(req, res, next) {
15 | res.json(req.body);
16 | });
17 |
18 | router.post('/isFavorite', login.check, favorite.isFavorite, function(req, res, next) {
19 | res.json(req.body);
20 | });
21 |
22 |
23 | module.exports = router;
24 |
--------------------------------------------------------------------------------
/middlewares/times.js:
--------------------------------------------------------------------------------
1 | /*
2 | * @Author: 唐文雍
3 | * @Date: 2019-01-16 10:17:32
4 | * @Last Modified by: 唐文雍
5 | * @Last Modified time: 2019-01-16 10:17:32
6 | */
7 | const query = require('../utils/pool');
8 | const times = {};
9 | exports.times = times;
10 |
11 | times.list = function(req, res, next) {
12 | const sql = `SELECT * FROM time_step order by sort desc`;
13 | console.info("查询时间步骤", sql);
14 | query(sql, (err, vals) => {
15 | if (!err && vals instanceof Array) {
16 | req.body.data = vals;
17 | req.body.code = '10000';
18 | req.body.message = '操作成功';
19 | req.body.success = true;
20 | return next();
21 | } else {
22 | return res.json({ code: '10001', message: err.code, success: false, data: null });
23 | }
24 | })
25 | }
--------------------------------------------------------------------------------
/routes/entries.js:
--------------------------------------------------------------------------------
1 | const express = require('express');
2 | const router = express.Router();
3 | const { login } = require('../middlewares/login.js');
4 | const { log } = require('../middlewares/log.js');
5 | const { entries } = require('../middlewares/entries.js');
6 |
7 | router.post('/list', entries.get, function(req, res, next) {
8 | res.json(req.body);
9 | });
10 | router.post('/add', login.check, entries.add, log.add, function(req, res, next) {
11 | res.json(req.body);
12 | });
13 | router.post('/update', login.check, entries.update, log.add, function(req, res, next) {
14 | res.json(req.body);
15 | });
16 | router.post('/remove', login.check, entries.remove, log.add, function(req, res, next) {
17 | res.json(req.body);
18 | });
19 |
20 |
21 | module.exports = router;
22 |
--------------------------------------------------------------------------------
/routes/banners.js:
--------------------------------------------------------------------------------
1 | const express = require('express');
2 | const router = express.Router();
3 | const { login } = require('../middlewares/login.js');
4 | const { log } = require('../middlewares/log.js');
5 | const { banners } = require('../middlewares/banners.js');
6 |
7 | // 获取轮播图
8 | router.post('/', banners.get, function(req, res, next) {
9 | res.json(req.body);
10 | });
11 | router.post('/add', login.check, banners.add, log.add, function(req, res, next) {
12 | res.json(req.body);
13 | });
14 | router.post('/update', login.check, banners.update, log.add, function(req, res, next) {
15 | res.json(req.body);
16 | });
17 | router.post('/remove', login.check, banners.remove, log.add, function(req, res, next) {
18 | res.json(req.body);
19 | });
20 |
21 |
22 | module.exports = router;
23 |
--------------------------------------------------------------------------------
/routes/administrator.js:
--------------------------------------------------------------------------------
1 | const express = require('express');
2 | const router = express.Router();
3 | const { login } = require('../middlewares/login.js');
4 | const { log } = require('../middlewares/log.js');
5 | const { administrator } = require('../middlewares/administrator.js');
6 |
7 | router.post('/list', administrator.list, function(req, res, next) {
8 | res.json(req.body);
9 | });
10 | router.post('/add', login.check, administrator.add, log.add, function(req, res, next) {
11 | res.json(req.body);
12 | });
13 | router.post('/update', login.check, administrator.update, log.add, function(req, res, next) {
14 | res.json(req.body);
15 | });
16 | router.post('/remove', login.check, administrator.remove, log.add, function(req, res, next) {
17 | res.json(req.body);
18 | });
19 | module.exports = router;
20 |
--------------------------------------------------------------------------------
/routes/address.js:
--------------------------------------------------------------------------------
1 | const express = require('express');
2 | const router = express.Router();
3 | const { login } = require('../middlewares/login.js');
4 | const { address } = require('../middlewares/address.js');
5 |
6 | router.post('/list', login.check, address.list, function(req, res, next) {
7 | res.json(req.body);
8 | });
9 |
10 | router.post('/detail', login.check, address.detail, function(req, res, next) {
11 | res.json(req.body);
12 | });
13 |
14 | router.post('/add', login.check, address.add, function(req, res, next) {
15 | res.json(req.body);
16 | });
17 |
18 | router.post('/update', login.check, address.update, function(req, res, next) {
19 | res.json(req.body);
20 | });
21 |
22 | router.post('/remove', login.check, address.remove, function(req, res, next) {
23 | res.json(req.body);
24 | });
25 |
26 | module.exports = router;
27 |
--------------------------------------------------------------------------------
/routes/money.js:
--------------------------------------------------------------------------------
1 | const express = require('express');
2 | const router = express.Router();
3 | const { exportFile } = require('../middlewares/export');
4 | const { login } = require('../middlewares/login.js');
5 | const { log } = require('../middlewares/log.js');
6 | const { money } = require('../middlewares/money.js');
7 |
8 | router.post('/add', login.check, money.add, log.add, function(req, res, next) {
9 | res.json(req.body);
10 | });
11 |
12 | router.post('/reduce', login.check, money.reduce, log.add, function(req, res, next) {
13 | res.json(req.body);
14 | });
15 |
16 | router.post('/stream', login.check, money.stream, function(req, res, next) {
17 | res.json(req.body);
18 | });
19 |
20 | router.post('/exportAll', login.check, money.exportAll, exportFile.excel, function(req, res, next) {
21 | res.json(req.body);
22 | });
23 |
24 |
25 |
26 | module.exports = router;
27 |
--------------------------------------------------------------------------------
/routes/sign.js:
--------------------------------------------------------------------------------
1 | const express = require('express');
2 | const router = express.Router();
3 | const { login } = require('../middlewares/login.js');
4 | const { log } = require('../middlewares/log.js');
5 | const { sign } = require('../middlewares/sign.js');
6 |
7 | router.post('/list', sign.list, function(req, res, next) {
8 | res.json(req.body);
9 | });
10 |
11 | router.post('/do', login.check, sign.do, function(req, res, next) {
12 | res.json(req.body);
13 | });
14 |
15 | router.post('/add', login.check, sign.add, log.add, function(req, res, next) {
16 | res.json(req.body);
17 | });
18 |
19 | router.post('/update', login.check, sign.update, log.add, function(req, res, next) {
20 | res.json(req.body);
21 | });
22 |
23 | router.post('/remove', login.check, sign.remove, log.add, function(req, res, next) {
24 | res.json(req.body);
25 | });
26 |
27 |
28 | module.exports = router;
29 |
--------------------------------------------------------------------------------
/middlewares/upload.js:
--------------------------------------------------------------------------------
1 | /*
2 | * @Author: 唐文雍
3 | * @Date: 2019-01-16 10:17:32
4 | * @Last Modified by: 唐文雍
5 | * @Last Modified time: 2019-01-16 10:17:32
6 | */
7 | const qiniu = require('qiniu');
8 | const config = require('../config/index');
9 | const upload = {};
10 | exports.upload = upload;
11 |
12 | //图片上传
13 | upload.img = function(req, res, next) {
14 | const mac = new qiniu.auth.digest.Mac(
15 | config.qiniu.accessKey,
16 | config.qiniu.secretKey,
17 | );
18 | const options = {
19 | scope: config.qiniu.bucket,
20 | };
21 | const putPolicy = new qiniu.rs.PutPolicy(options);
22 | const uploadToken = putPolicy.uploadToken(mac);
23 | if (uploadToken) {
24 | return res.json({
25 | code: '10000',
26 | message: '操作成功',
27 | success: true,
28 | data: {
29 | uptoken: uploadToken
30 | },
31 | });
32 | } else {
33 | return res.json({
34 | code: '10001',
35 | message: '服务器异常',
36 | success: false,
37 | data: null,
38 | });
39 | }
40 | };
41 |
--------------------------------------------------------------------------------
/middlewares/export.js:
--------------------------------------------------------------------------------
1 | /*
2 | * @Author: 唐文雍
3 | * @Date: 2019-01-16 10:17:32
4 | * @Last Modified by: 唐文雍
5 | * @Last Modified time: 2019-01-16 10:17:32
6 | */
7 | const moment = require('moment');
8 | const fs = require('fs');
9 | const nodeExcel = require('excel-export');
10 | const exportFile = {};
11 | exports.exportFile = exportFile;
12 |
13 | // 导出Excel文件
14 | exportFile.excel = async function (req, res, next) {
15 | const { exportConfig, prefix } = req.body.excelData;
16 | const result = nodeExcel.execute(exportConfig);
17 | const timestamp = moment().format('YYYYMMDDHHmmss');
18 | const uploadDir = `/export/${prefix}-${timestamp}.xlsx`;
19 | const filePath = `./public${uploadDir}`;
20 | fs.writeFile(filePath, result, 'binary', function (err) {
21 | if (err) {
22 | return res.json({ code: '10001', message: err, success: false, data: null });
23 | }
24 | delete req.body.excelData;
25 | req.body.data = uploadDir;
26 | req.body.code = '10000';
27 | req.body.message = '操作成功';
28 | req.body.success = true;
29 | return next();
30 | });
31 | };
32 |
--------------------------------------------------------------------------------
/routes/statistics.js:
--------------------------------------------------------------------------------
1 | const express = require('express');
2 | const router = express.Router();
3 | const { login } = require('../middlewares/login.js');
4 | const { statistics } = require('../middlewares/statistics.js');
5 |
6 | // 统计当前用户各个状态的任务数量
7 | router.post('/getTaskCount', statistics.getTaskCount, function(req, res, next) {
8 | res.json(req.body);
9 | });
10 |
11 | // 统计当前用户指定状态下任务的总金额
12 | router.post('/getMoneyByTaskStatus', statistics.getMoneyByTaskStatus, function(req, res, next) {
13 | res.json(req.body);
14 | });
15 |
16 | // 统计当前用户金额数据
17 | router.post('/getUserMoneyStatistics', statistics.getUserMoneyStatistics, function(req, res, next) {
18 | res.json(req.body);
19 | });
20 |
21 | // 用户任务完成排行榜
22 | router.post('/getUserRankList', statistics.getUserRankList, function(req, res, next) {
23 | res.json(req.body);
24 | });
25 |
26 | // 用户邀请排行榜
27 | router.post('/getInviteRankList', statistics.getInviteRankList, function(req, res, next) {
28 | res.json(req.body);
29 | });
30 |
31 | // 获取后台仪表盘统计
32 | router.post('/getDashboardData', login.check, statistics.getDashboardData, function(req, res, next) {
33 | res.json(req.body);
34 | });
35 |
36 | module.exports = router;
37 |
--------------------------------------------------------------------------------
/routes/certifications.js:
--------------------------------------------------------------------------------
1 | const express = require('express');
2 | const router = express.Router();
3 | const { login } = require('../middlewares/login.js');
4 | const { log } = require('../middlewares/log.js');
5 | const { certifications } = require('../middlewares/certifications.js');
6 | const { messages } = require('../middlewares/messages.js');
7 |
8 | // 获取认证列表
9 | router.post('/get', login.check, certifications.get, function(req, res, next) {
10 | res.json(req.body);
11 | });
12 | // 获取认证详情
13 | router.post('/detail', login.check, certifications.detail, function(req, res, next) {
14 | res.json(req.body);
15 | });
16 | // 用户提交认证资料
17 | router.post('/add', login.check, certifications.add, messages.add, function(req, res, next) {
18 | res.json(req.body);
19 | });
20 | // 管理员审核认证资料
21 | router.post('/review', login.check, certifications.review, log.add, function(req, res, next) {
22 | res.json(req.body);
23 | });
24 | // 用户更新认证资料
25 | router.post('/update', login.check, certifications.update, function(req, res, next) {
26 | res.json(req.body);
27 | });
28 | // 删除用户认证资料
29 | router.post('/remove', login.check, certifications.remove, log.add, function(req, res, next) {
30 | res.json(req.body);
31 | });
32 |
33 | module.exports = router;
34 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "task-paradise",
3 | "version": "0.0.0",
4 | "private": true,
5 | "scripts": {
6 | "start": "npm run dev",
7 | "watch": "nodemon --watch",
8 | "dev": "node ./bin/www"
9 | },
10 | "nodemonConfig": {
11 | "ignore": [
12 | "node_modules/**/node_modules"
13 | ],
14 | "env": {
15 | "NODE_ENV": "development"
16 | }
17 | },
18 | "dependencies": {
19 | "@alicloud/pop-core": "^1.7.9",
20 | "alipay-sdk": "^3.1.2",
21 | "body-parser": "^1.18.3",
22 | "body-parser-xml": "^1.1.0",
23 | "connect-redis": "^3.4.0",
24 | "cookie-parser": "~1.4.3",
25 | "crypto": "^1.0.1",
26 | "debug": "~2.6.9",
27 | "ejs": "~2.5.7",
28 | "excel-export": "^0.5.1",
29 | "express": "~4.16.0",
30 | "express-session": "^1.15.6",
31 | "express-xml-bodyparser": "^0.3.0",
32 | "http-errors": "~1.6.2",
33 | "moment": "^2.27.0",
34 | "morgan": "~1.9.0",
35 | "mysql": "^2.16.0",
36 | "node-schedule": "^2.0.0",
37 | "qiniu": "^7.2.1",
38 | "qs": "^6.9.4",
39 | "redis": "^2.8.0",
40 | "request": "^2.88.0",
41 | "xml2js": "^0.4.22",
42 | "xmlreader": "^0.2.3"
43 | },
44 | "devDependencies": {
45 | "nodemon": "^1.18.9"
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/routes/refresh.js:
--------------------------------------------------------------------------------
1 | const express = require('express');
2 | const router = express.Router();
3 | const { login } = require('../middlewares/login.js');
4 | const { log } = require('../middlewares/log.js');
5 | const { refresh } = require('../middlewares/refresh.js');
6 |
7 | router.post('/list', refresh.list, function(req, res, next) {
8 | res.json(req.body);
9 | });
10 |
11 | router.post('/add', login.check, refresh.add, log.add, function(req, res, next) {
12 | res.json(req.body);
13 | });
14 |
15 | router.post('/update', login.check, refresh.update, log.add, function(req, res, next) {
16 | res.json(req.body);
17 | });
18 |
19 | router.post('/remove', login.check, refresh.remove, log.add, function(req, res, next) {
20 | res.json(req.body);
21 | });
22 |
23 | router.post('/buy', login.check, refresh.buy, function(req, res, next) {
24 | res.json(req.body);
25 | });
26 |
27 | router.post('/do', login.check, refresh.do, function(req, res, next) {
28 | res.json(req.body);
29 | });
30 |
31 | router.post('/recommend', login.check, refresh.recommend, function(req, res, next) {
32 | res.json(req.body);
33 | });
34 |
35 | router.post('/top', login.check, refresh.top, function(req, res, next) {
36 | res.json(req.body);
37 | });
38 |
39 | module.exports = router;
40 |
--------------------------------------------------------------------------------
/config/prod.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | wechat: {
3 | appId: '',
4 | appSecret: '',
5 | mchId: '',
6 | mchAppId: '',
7 | mchKey: '',
8 | officialAccount: {
9 | appId: '',
10 | appSecret: '',
11 | },
12 | open: {
13 | appId: '',
14 | appSecret: '',
15 | }
16 | },
17 | image: 'https://img.xigu.pro',
18 | domain: 'https://shark-api.xigu.pro',
19 | mysql: {
20 | host: '',
21 | port: 3306,
22 | user: '',
23 | database: '',
24 | },
25 | redis: {
26 | host: '127.0.0.1',
27 | port: 6379,
28 | password: 'xigu.pro',
29 | prefix: 'xigu:',
30 | },
31 | qiniu: {
32 | accessKey: '',
33 | secretKey: '',
34 | bucket: '',
35 | },
36 | aliyun: {
37 | accessKey: '',
38 | secretKey: '',
39 | sms: {
40 | signName: "鲨鱼任务",
41 | templateCode: "SMS_189763152",
42 | },
43 | },
44 | alipay: {
45 | appId: '2021001146644054',
46 | },
47 | xianwan: {
48 | '5395': 'lf6ycxkk9p4vajxe', // 安卓
49 | '5526': 'tuhuwh4340rkirsn', // iOS
50 | },
51 | yuwan: {
52 | appId: '1540',
53 | appSecret: '25jdovqsq0khowsmo5nir0mx9m30gk41',
54 | },
55 | duoyou: {
56 | 'dy_59634076': '9ef2f1dd1c913d9057eb5b544b4512ef', // 安卓
57 | 'dy_59634077': '4745bef81ca46a035ac0998505f7f6f0', // iOS
58 | }
59 | };
60 |
--------------------------------------------------------------------------------
/config/dev.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | wechat: {
3 | appId: '',
4 | appSecret: '',
5 | mchId: '',
6 | mchAppId: '',
7 | mchKey: '',
8 | officialAccount: {
9 | appId: '',
10 | appSecret: '',
11 | },
12 | open: {
13 | appId: '',
14 | appSecret: '',
15 | }
16 | },
17 | image: 'https://img.xigu.pro',
18 | domain: 'https://shark-api.xigu.pro',
19 | mysql: {
20 | host: 'localhost',
21 | port: 3306,
22 | user: 'root',
23 | password: 'TAMMENY',
24 | database: 'task_paradise',
25 | },
26 | redis: {
27 | host: '127.0.0.1',
28 | port: 6379,
29 | password: '123456',
30 | prefix: 'xigu:',
31 | },
32 | qiniu: {
33 | accessKey: '',
34 | secretKey: '',
35 | bucket: '',
36 | },
37 | aliyun: {
38 | accessKey: '',
39 | secretKey: '',
40 | sms: {
41 | signName: "鲨鱼任务",
42 | templateCode: "SMS_189763152",
43 | },
44 | },
45 | alipay: {
46 | appId: '2021001146644054',
47 | },
48 | xianwan: {
49 | '5395': 'lf6ycxkk9p4vajxe', // 安卓
50 | '5526': 'tuhuwh4340rkirsn', // iOS
51 | },
52 | yuwan: {
53 | appId: '1540',
54 | appSecret: '25jdovqsq0khowsmo5nir0mx9m30gk41',
55 | },
56 | duoyou: {
57 | 'dy_59634076': '9ef2f1dd1c913d9057eb5b544b4512ef', // 安卓
58 | 'dy_59634077': '4745bef81ca46a035ac0998505f7f6f0', // iOS
59 | }
60 | };
61 |
--------------------------------------------------------------------------------
/key/alipayCertPublicKey_RSA2.crt:
--------------------------------------------------------------------------------
1 | -----BEGIN CERTIFICATE-----
2 | MIIDuDCCAqCgAwIBAgIQICAJB6OY+OfBsjVjijqJ/zANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UE
3 | BhMCQ04xFjAUBgNVBAoMDUFudCBGaW5hbmNpYWwxIDAeBgNVBAsMF0NlcnRpZmljYXRpb24gQXV0
4 | aG9yaXR5MTkwNwYDVQQDDDBBbnQgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5IENs
5 | YXNzIDIgUjEwHhcNMjAwOTA3MDkzNDMyWhcNMjIwOTA3MDkzNDMyWjCBmDELMAkGA1UEBhMCQ04x
6 | MzAxBgNVBAoMKuatpuaxieS6kuWKqOe+juS8oOaWh+WMluS8oOWqkuaciemZkOWFrOWPuDEPMA0G
7 | A1UECwwGQWxpcGF5MUMwQQYDVQQDDDrmlK/ku5jlrp0o5Lit5Zu9Kee9kee7nOaKgOacr+aciemZ
8 | kOWFrOWPuC0yMDg4ODIxMTMyOTYzOTI0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
9 | kxYnV+y/jTKKyN+vPEz1aLINqmeRUeIlfLEsWYP/bGuL3Q9LgFcwmSaR5E5ewr69SCrMvH8smHoT
10 | QN2wl0g1s/KGkQjb9GJarpu/xZ3i10Tn2597PLlBs/MwV9tmR5RRCjxv4SzJaHvKrjuX5nsYETcJ
11 | H5SFcAKhkHjlJWTqtNFmwaMmgg7781UuATA669oOOJEqiNTsTYV40hfabpMpITL6n28Yjq9jpbz5
12 | vTrSo8y/KvrQZn8KBLaP6zwbIYohtoSiFAE5uagJp2pWbyImQUbFrGl7FQXs1o3cYYQ2sHhPovrg
13 | u2cLTSo3kDzgkMYGn+27mMq/45B3cs2/ousHgQIDAQABoxIwEDAOBgNVHQ8BAf8EBAMCA/gwDQYJ
14 | KoZIhvcNAQELBQADggEBAASvy08zokviQjsXiBt7qpHQtO5UDPQpqZ+Q798CmZoxPoBIU3Mok448
15 | km+90uXzZQmnowqIraZ9v9tDRg1CDnX2I54Fvv7F+rZAwDgpCckHMmXD6ETMV1lU51mdyAa45oU6
16 | u5OBQhMwO9UxoYb9d9+r3/dP4LbAaDSp/l2+Cqig71/tbR0a5O4dE1qlzE4pvLT2qz9J+WjbnsLR
17 | 5NRcmWje0uN3CmuItSuQxvaKi3hTH3u24m5Hxxr+yD+Yn3L5dbYleMIB6PvH7Znw07zfOYflHuv0
18 | zZLB0vqXKeym8wkj3Pmvds+iWbAc72RUQwn8eInerLDGt75ZRz7OE2b6IKw=
19 | -----END CERTIFICATE-----
20 |
--------------------------------------------------------------------------------
/routes/help.js:
--------------------------------------------------------------------------------
1 | const express = require('express');
2 | const router = express.Router();
3 | const { login } = require('../middlewares/login.js');
4 | const { log } = require('../middlewares/log.js');
5 | const { help } = require('../middlewares/help.js');
6 |
7 | router.post('/list', help.list, function(req, res, next) {
8 | res.json(req.body);
9 | });
10 |
11 | router.post('/typeList', help.typeList, function(req, res, next) {
12 | res.json(req.body);
13 | });
14 |
15 | router.post('/detail', login.check, help.detail, log.add, function(req, res, next) {
16 | res.json(req.body);
17 | });
18 |
19 | router.post('/add', login.check, help.add, log.add, function(req, res, next) {
20 | res.json(req.body);
21 | });
22 |
23 | router.post('/update', login.check, help.update, log.add, function(req, res, next) {
24 | res.json(req.body);
25 | });
26 |
27 | router.post('/remove', login.check, help.remove, log.add, function(req, res, next) {
28 | res.json(req.body);
29 | });
30 |
31 | // 删除分类
32 | router.post('/removeType', login.check, help.removeType, log.add, function(req, res, next) {
33 | res.json(req.body);
34 | });
35 |
36 | // 添加分类
37 | router.post('/addType', login.check, help.addType, log.add, function(req, res, next) {
38 | res.json(req.body);
39 | });
40 |
41 | // 更新分类
42 | router.post('/updateType', login.check, help.updateType, log.add, function(req, res, next) {
43 | res.json(req.body);
44 | });
45 |
46 |
47 | module.exports = router;
48 |
--------------------------------------------------------------------------------
/routes/user.js:
--------------------------------------------------------------------------------
1 | const express = require('express');
2 | const router = express.Router();
3 | const { login } = require('../middlewares/login.js');
4 | const { log } = require('../middlewares/log.js');
5 | const { exportFile } = require('../middlewares/export.js');
6 | const { user } = require('../middlewares/user.js');
7 | const { messages } = require('../middlewares/messages.js');
8 |
9 | // 获取用户信息
10 | router.post('/info', login.check, user.info, function(req, res, next) {
11 | res.json(req.body);
12 | });
13 | // 根据用户ID获取用户信息
14 | router.post('/getInfoByID', login.check, user.getInfoByID, function(req, res, next) {
15 | res.json(req.body);
16 | });
17 | // 获取用户列表
18 | router.post('/all', login.check, user.all, function(req, res, next) {
19 | res.json(req.body);
20 | });
21 | // 用户列表导出Excel
22 | router.post('/exportAll', login.check, user.exportAll, exportFile.excel, function(req, res, next) {
23 | res.json(req.body);
24 | });
25 |
26 | // 更新用户
27 | router.post('/update', login.check, user.update, log.add, function(req, res, next) {
28 | res.json(req.body);
29 | });
30 | // 获取用户等级列表
31 | router.post('/getLevelList', user.getLevelList, function(req, res, next) {
32 | res.json(req.body);
33 | });
34 | // 更新用户等级
35 | router.post('/updateLevel', login.check, user.updateLevel, log.add, function(req, res, next) {
36 | res.json(req.body);
37 | });
38 |
39 | // 根据手机号重置密码
40 | router.post('/updateUserPassword', user.updateUserPassword, function(req, res, next) {
41 | res.json(req.body);
42 | });
43 |
44 | module.exports = router;
45 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 鲨鱼任务悬赏平台
2 |
3 | 注: 此仓库为后端服务,需配合[H5端](https://github.com/xigupro/SharkTask_H5)、[管理端](https://github.com/xigupro/SharkTask_Admin)使用
4 |
5 | [查看演示](https://shark-m.xigu.pro)
6 | [公司官网](https://www.xigu.pro/products/task.html)
7 |
8 | ### 为什么开源
9 | 到目前已有300+的付费客户选择了我们,考虑到有一部分小公司或个人可能前期没有太多的预算投入到平台的开发建设方面来,加上近两年口罩原因大家都非常困难,为了能帮助到这部分客户,所以将此项目开源,希望各位创业者能够飞黄腾达,早日成功。
10 |
11 | ### 介绍
12 | 鲨鱼任务是广州西谷科技自主研发的一款悬赏平台。适合一切想赚钱的人群,如上班族,家庭主妇,自由职业者,创业者等,平台搭建后即可作为你的副业去发展,也可以成为主业去拼搏。 凡是“给钱办事”的业务,如任务悬赏,应用试玩,拉新注册,抖音点赞,购物返利,威客众包,兼职,跑腿,拉票,中介等都适合。
13 |
14 | ### 技术栈
15 | * nodejs v14.16.1
16 | * expressjs 4.16.0
17 | * mysql v5.7
18 | * redis v6.2.6
19 |
20 | ### 配置
21 |
22 | 开发环境配置文件路径`/config/dev.js`
23 | 生产环境配置文件路径`/config/prod.js`
24 | 语义化命名一看就懂,不需要过多解释。
25 |
26 | ### 安装
27 | 1. 安装依赖 `npm i`
28 | 2. 将根目录的sql脚本导入到数据库
29 | 3. 修改配置文件
30 | 4. 启动服务 `npm run watch`
31 |
32 | ### 功能
33 | | 功能 | 开源版 | 商业版(3888元) |
34 | | ---- | ---- | ---- |
35 | | 任务 | ✅ | ✅ |
36 | | 积分城 | ✅ | ✅ |
37 | | 合伙人 | ✅ | ✅ |
38 | | 财务 | ✅ | ✅ |
39 | | 消息 | ✅ | ✅ |
40 | | 超级会员 | ❌ | ✅ |
41 | | 三级分销 | ❌ | ✅ |
42 | | 活动 | ❌ | ✅ |
43 | | 福利 | ❌ | ✅ |
44 |
45 | ### 提供服务
46 | 如果你搞不定,可以找我们提供一条龙服务
47 | * 部署上线,一条龙部署程序到服务器, 直到可以正常使用
48 | * 运维服务,免费BUG修复, 一对一解决问题
49 | * 定制开发,根据你的需求进行二次开发
50 |
51 | ### 联系 or 申请入群
52 |
53 |
54 | ### 打赏
55 | 如果项目对你有用,请不要吝啬请我喝杯咖啡呗哈哈哈。
56 |
57 |
58 |
59 |
60 | ### 版权
61 | 本平台已申请著作权,请勿侵权。
--------------------------------------------------------------------------------
/key/alipay-private-key.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN RSA PRIVATE KEY-----
2 | MIIEpQIBAAKCAQEAiuyiac9W9tsYU0JlK9WSstskcgGTrpy3UG8A6p5MPneMczcfuL3/v9gjP/yn17mw4eApH3UqDkyZTrcUrN+UHan7YVlLBU+DyfPnmzVSRPs23RtRq8xtqEiANXoKUQa1c1nu7TRAC6dEfqagrdYS5s7ceFGqhuY+lZjkM945/jhB9gYdcxQyF1QoyXQKlT83wwyaJ6wr51rBS4P7/s6kxvvWVX72ynokVh+fe38R8jNAtXFcAIIPCJgNCC/VncYoEg/7qCXOpOZJcMX9ml0ob3PD+EOtMEmQR9YAQpoHSgp3AxCpGx+w2/a128QICA1zcHKkWnEb3mfFBS0VAUqsHQIDAQABAoIBAFDdlVyJ+FERD4PHbiSp2Q6LSRejm1dUmdAUDTCEnFTwOa0HNUvQLQJ6yWoBo6GK0U9psAZDqQtRwxtyrnJCYnEx9MWhuG2K72eqtfI+g3jr0e+6azvZbys5qId4VnD7urs+ajlg5Lbj0pb2XylRJwd6+hJ/VwfXFi72JD+c55z2OYM0bDmNMX4yRubZUD3JCvFf7Cp0/7qeSXBBZ8tiDmlFz43FARcxeEITuWZvr1lmj7N/Eft5uc6Qxgc1WTtmrNs/JuCIza3McXVmq6cVVt3YoG+8iW6+j56eRpHQ+Tpl+3V+WAqzJL76pZ4PiZmg4Ga9rRK92WRbf8MUxCxepnECgYEA6pHuxKHCUg9hXl9O6QHfWxymve9zVkfuy4Fg7qk4SVwAXkSctFq6ldW4cl08BjmiZALyL/VzkFqmVUlIrST0euQwLMBipNT2+zwTQYLDC/UBmT3CzvbiIXu0RXn+3tpXKtfa4brIJAYLzpoSV1vie0z1I9fZLMJ+0fPigS0sXXcCgYEAl53DcKrs0XyAYRNqGLJeiq7A7XatbM3YpXV0oIj6ml5rGk6JvVJWk/sFaw6UEoFBv7hUdIdQYqdS1MNPMqrNDsssUqbpiKFm5S8xzTTGA1UA7bZc8cwnXrXrhqd8MBBcJzyQtkU8eC3itlggf+QsFUQCgmnFZ6U0fACXbvc8mAsCgYEA4pEkI+7uJ57NeH7sVClH2NRaxdhz+eGu6AfGXZ87S7g+bs8s4RNFZ5Yv+t7NLGIc1Sb3UJVvEv5L7NLFDOBF+DFRytfkL7u390C2hK9Nv83dxmseMBPMpXS70eOc5xnT2gD2XNOxnwHsA5lTn+eTYW8a1I0XKqGOJzK/E/BTCs8CgYEAhXvFTNV/aDQHxu/T0eiAKfMPMkHxD8DvQ0T0qD3Q/MWx39hTllX+mYxASe/s15nrLAL6gBl94U1VNLK7cG1F2gdwf1gqdTs8nvx9CSC0UMyu45pRnCRUaSMbOFMOmDZfG8BL2917Doe/eTB/dHmLgjF9UBoVTVn6qk3PBUgwld8CgYEAid7km6akWQDymfRqCcRHFUpXrCsg3Ghnh8eo00U2i2iIlzjj6+EUm5PkrjaBsEhznpQT1b7PzhCqLaQPh8PuEgqZvAqF7YFtuRxpLosPztrETr5Q7+xquyUjc8pbQXLTEyndykRxsO28s1zN9Vthd5T4kbh/m3YUHeGS3vdH7bQ=
3 | -----END RSA PRIVATE KEY-----
--------------------------------------------------------------------------------
/routes/messages.js:
--------------------------------------------------------------------------------
1 | const express = require('express');
2 | const router = express.Router();
3 | const { login } = require('../middlewares/login.js');
4 | const { log } = require('../middlewares/log');
5 | const { messages } = require('../middlewares/messages.js');
6 |
7 | router.post('/getNoticeList', messages.getNoticeList, function(req, res, next) {
8 | res.json(req.body);
9 | });
10 | router.post('/list', messages.list, function(req, res, next) {
11 | res.json(req.body);
12 | });
13 | router.post('/getDynamicList', messages.getDynamicList, function(req, res, next) {
14 | res.json(req.body);
15 | });
16 | router.post('/unreadCount', login.check, messages.unreadCount, function(req, res, next) {
17 | res.json(req.body);
18 | });
19 | router.post('/add', login.check, messages.add, function(req, res, next) {
20 | res.json(req.body);
21 | });
22 | router.post('/addNotice', login.check, messages.addNotice, log.add, function(req, res, next) {
23 | res.json(req.body);
24 | });
25 | router.post('/updateNotice', login.check, messages.updateNotice, log.add, function(req, res, next) {
26 | res.json(req.body);
27 | });
28 | router.post('/getNoticeDetail', login.check, messages.getNoticeDetail, function(req, res, next) {
29 | res.json(req.body);
30 | });
31 | router.post('/detail', login.check, messages.detail, function(req, res, next) {
32 | res.json(req.body);
33 | });
34 | router.post('/read', login.check, messages.read, function(req, res, next) {
35 | res.json(req.body);
36 | });
37 | router.post('/remove', login.check, messages.remove, log.add, function(req, res, next) {
38 | res.json(req.body);
39 | });
40 |
41 |
42 | module.exports = router;
43 |
--------------------------------------------------------------------------------
/routes/withdraw.js:
--------------------------------------------------------------------------------
1 | const express = require('express');
2 | const router = express.Router();
3 | const { login } = require('../middlewares/login.js');
4 | const { log } = require('../middlewares/log.js');
5 | const { exportFile } = require('../middlewares/export.js');
6 | const { withdraw } = require('../middlewares/withdraw.js');
7 | const { user } = require('../middlewares/user.js');
8 | const { messages } = require('../middlewares/messages.js');
9 | const { order } = require('../middlewares/order.js');
10 | const wepay = require('../utils/wepay');
11 |
12 | // 用户提现
13 | router.post('/submit', login.check, user.info, withdraw.submit, function(req, res, next) {
14 | res.json({
15 | data: req.body.data,
16 | message: '操作成功',
17 | code: '10000',
18 | success: true
19 | });
20 | });
21 | // 用户提现列表
22 | router.post('/list', withdraw.list, function(req, res, next) {
23 | res.json(req.body);
24 | });
25 | // 导出提现列表
26 | router.post('/exportAll', withdraw.exportAll, exportFile.excel, function(req, res, next) {
27 | res.json(req.body);
28 | });
29 | // 用户提现详情
30 | router.post('/detail', withdraw.detail, function(req, res, next) {
31 | res.json(req.body);
32 | });
33 | // 用户提现驳回
34 | router.post('/reject', login.check, withdraw.reject, messages.add, log.add, function(req, res, next) {
35 | res.json(req.body);
36 | });
37 | // 用户提现通过,付款到微信方式
38 | router.post('/resolve', login.check, wepay.wxcompay, withdraw.resolve, messages.add, log.add, function(req, res, next) {
39 | res.json(req.body);
40 | });
41 | // 用户提现通过,付款到支付宝方式
42 | router.post('/resolveByAlipay', login.check, order.alipayPayToAccount, withdraw.resolve, messages.add, log.add, function(req, res, next) {
43 | res.json(req.body);
44 | });
45 | module.exports = router;
--------------------------------------------------------------------------------
/key/appCertPublicKey_2021001193638066.crt:
--------------------------------------------------------------------------------
1 | -----BEGIN CERTIFICATE-----
2 | MIIEtzCCA5+gAwIBAgIQICAJE/eXc3TlCMayl/tgKTANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UE
3 | BhMCQ04xFjAUBgNVBAoMDUFudCBGaW5hbmNpYWwxIDAeBgNVBAsMF0NlcnRpZmljYXRpb24gQXV0
4 | aG9yaXR5MTkwNwYDVQQDDDBBbnQgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5IENs
5 | YXNzIDEgUjEwHhcNMjAwOTEzMDk0MzIzWhcNMjIwOTEzMDk0MzIzWjB/MQswCQYDVQQGEwJDTjEz
6 | MDEGA1UECgwq5q2m5rGJ5LqS5Yqo576O5Lyg5paH5YyW5Lyg5aqS5pyJ6ZmQ5YWs5Y+4MQ8wDQYD
7 | VQQLDAZBbGlwYXkxKjAoBgNVBAMMITIwODg4MjExMzI5NjM5MjQtMjAyMTAwMTE5MzYzODA2NjCC
8 | ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAIrsomnPVvbbGFNCZSvVkrLbJHIBk66ct1Bv
9 | AOqeTD53jHM3H7i9/7/YIz/8p9e5sOHgKR91Kg5MmU63FKzflB2p+2FZSwVPg8nz55s1UkT7Nt0b
10 | UavMbahIgDV6ClEGtXNZ7u00QAunRH6moK3WEubO3HhRqobmPpWY5DPeOf44QfYGHXMUMhdUKMl0
11 | CpU/N8MMmiesK+dawUuD+/7OpMb71lV+9sp6JFYfn3t/EfIzQLVxXACCDwiYDQgv1Z3GKBIP+6gl
12 | zqTmSXDF/ZpdKG9zw/hDrTBJkEfWAEKaB0oKdwMQqRsfsNv2tdvECAgNc3BypFpxG95nxQUtFQFK
13 | rB0CAwEAAaOCASkwggElMB8GA1UdIwQYMBaAFHEH4gRhFuTl8mXrMQ/J4PQ8mtWRMB0GA1UdDgQW
14 | BBRSRHKYrd6lMtISAevnizWicHjPVTBABgNVHSAEOTA3MDUGB2CBHAFuAQEwKjAoBggrBgEFBQcC
15 | ARYcaHR0cDovL2NhLmFsaXBheS5jb20vY3BzLnBkZjAOBgNVHQ8BAf8EBAMCBsAwLwYDVR0fBCgw
16 | JjAkoCKgIIYeaHR0cDovL2NhLmFsaXBheS5jb20vY3JsNDUuY3JsMGAGCCsGAQUFBwEBBFQwUjAo
17 | BggrBgEFBQcwAoYcaHR0cDovL2NhLmFsaXBheS5jb20vY2E2LmNlcjAmBggrBgEFBQcwAYYaaHR0
18 | cDovL2NhLmFsaXBheS5jb206ODM0MC8wDQYJKoZIhvcNAQELBQADggEBAFSYoCUn+PqP+Rjy35kw
19 | 3teck98Ay6O3o4J4XMp9LTN2H1QOU9+DSQwjFkJo3k0+0e67ttSssNoRbgC3XgITFuL5epArr5xm
20 | BxgV8pyLz6Ml8R7L0WSbSREUi5A1lwqkI/TVCyctzEoMltYlJXg9ehqQQVH1caMpddJp8GErDPf5
21 | BpnC08uFVvNaxGl52d7s2nEWAskLd2I3o9BM84gZSGDGAqCIalUW/MeGNQY21gcQAITaStbyNCZH
22 | 4xLUXtr94lQzZ+83vwgcpWPEe9v9IZ+51swWONS81EUWIMoQU0WyhsYzERgursbZTXn6G3iDf5Rz
23 | TvLhODUcKy0OQDqmYQ0=
24 | -----END CERTIFICATE-----
--------------------------------------------------------------------------------
/bin/www:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | /**
4 | * Module dependencies.
5 | */
6 |
7 | var app = require('../app');
8 | var debug = require('debug')('task-paradise:server');
9 | var http = require('http');
10 |
11 | /**
12 | * Get port from environment and store in Express.
13 | */
14 |
15 | var port = normalizePort(process.env.PORT || '3000');
16 | app.set('port', port);
17 |
18 | /**
19 | * Create HTTP server.
20 | */
21 |
22 | var server = http.createServer(app);
23 |
24 | /**
25 | * Listen on provided port, on all network interfaces.
26 | */
27 |
28 | server.listen(port);
29 | server.on('error', onError);
30 | server.on('listening', onListening);
31 |
32 | /**
33 | * Normalize a port into a number, string, or false.
34 | */
35 |
36 | function normalizePort(val) {
37 | var port = parseInt(val, 10);
38 |
39 | if (isNaN(port)) {
40 | // named pipe
41 | return val;
42 | }
43 |
44 | if (port >= 0) {
45 | // port number
46 | return port;
47 | }
48 |
49 | return false;
50 | }
51 |
52 | /**
53 | * Event listener for HTTP server "error" event.
54 | */
55 |
56 | function onError(error) {
57 | if (error.syscall !== 'listen') {
58 | throw error;
59 | }
60 |
61 | var bind = typeof port === 'string'
62 | ? 'Pipe ' + port
63 | : 'Port ' + port;
64 |
65 | // handle specific listen errors with friendly messages
66 | switch (error.code) {
67 | case 'EACCES':
68 | console.error(bind + ' requires elevated privileges');
69 | process.exit(1);
70 | break;
71 | case 'EADDRINUSE':
72 | console.error(bind + ' is already in use');
73 | process.exit(1);
74 | break;
75 | default:
76 | throw error;
77 | }
78 | }
79 |
80 | /**
81 | * Event listener for HTTP server "listening" event.
82 | */
83 |
84 | function onListening() {
85 | var addr = server.address();
86 | var bind = typeof addr === 'string'
87 | ? 'pipe ' + addr
88 | : 'port ' + addr.port;
89 | debug('Listening on ' + bind);
90 | }
91 |
--------------------------------------------------------------------------------
/middlewares/register.js:
--------------------------------------------------------------------------------
1 | /*
2 | * @Author: 唐文雍
3 | * @Date: 2019-01-16 10:17:32
4 | * @Last Modified by: 唐文雍
5 | * @Last Modified time: 2019-01-16 10:17:32
6 | */
7 | const query = require('../utils/pool');
8 | const register = {};
9 | exports.register = register;
10 |
11 | register.add = async function(req, res, next) {
12 | const username = req.body.username;
13 | const password = req.body.password;
14 | const inviter = req.body.inviter || null;
15 | const createdAt = new Date().getTime();
16 | // 初始用户赠送的账户金额
17 | const baseAmountSql = 'select base_amount from system';
18 | const baseAmountResult = await query(baseAmountSql);
19 | let baseAmount = 0;
20 | if (!baseAmountResult.fail && baseAmountResult instanceof Array) {
21 | baseAmount = baseAmountResult[0].base_amount || 0;
22 | }
23 | const sql = `insert into users(username, password, created_at, inviter, task_limit, account_amount, refresh_count)
24 | values(?,?,?,?, (select task_limit from growth_levels where level=1), ${baseAmount}, (select refresh_count from system))`;
25 | const sqlValue = [username, password, createdAt, inviter];
26 | const result = await query(sql, null, sqlValue, '新增用户');
27 | if (!result.fail && result instanceof Object && result.insertId) {
28 | if (baseAmount) {
29 | query(`insert into money_stream(type,money,balance,user_id,is_income,created_at,remark)
30 | values(3,${baseAmount},${baseAmount},${result.insertId},1,"${createdAt}","新用户红包");`, null, null, '发放新用户红包');
31 | }
32 | req.body.data = result.insertId;
33 | req.body.userId = inviter;
34 | req.body.taskType = 5;
35 | req.body.code = '10000';
36 | req.body.message = '操作成功';
37 | req.body.success = true;
38 | return next();
39 | } else {
40 | if (result.sqlState === '23000') {
41 | return res.json({ code: '10007', message: '已存在此用户名,请更换', success: false, data: null });
42 | }
43 | return res.json({ code: '10001', message: result.sqlMessage, success: false, data: null });
44 | }
45 | }
--------------------------------------------------------------------------------
/routes/goods.js:
--------------------------------------------------------------------------------
1 | const express = require('express');
2 | const router = express.Router();
3 | const { log } = require('../middlewares/log.js');
4 | const { login } = require('../middlewares/login.js');
5 | const { goods } = require('../middlewares/goods.js');
6 |
7 | router.post('/list', goods.list, function(req, res, next) {
8 | res.json(req.body);
9 | });
10 |
11 | router.post('/orders', login.check, goods.orders, function(req, res, next) {
12 | res.json(req.body);
13 | });
14 |
15 | router.post('/exchange', login.check, goods.exchange, function(req, res, next) {
16 | res.json(req.body);
17 | });
18 |
19 | router.post('/orderDetail', login.check, goods.orderDetail, function(req, res, next) {
20 | res.json(req.body);
21 | });
22 |
23 | router.post('/cancelOrder', login.check, goods.cancelOrder, log.add, function(req, res, next) {
24 | res.json(req.body);
25 | });
26 |
27 | router.post('/deliver', login.check, goods.deliver, log.add, function(req, res, next) {
28 | res.json(req.body);
29 | });
30 |
31 | router.post('/detail', goods.detail, function(req, res, next) {
32 | res.json(req.body);
33 | });
34 |
35 | router.post('/updateStatus', goods.updateStatus, log.add, function(req, res, next) {
36 | res.json(req.body);
37 | });
38 |
39 | router.post('/add', login.check, goods.add, log.add, function(req, res, next) {
40 | res.json(req.body);
41 | });
42 |
43 | router.post('/update', login.check, goods.update, log.add, function(req, res, next) {
44 | res.json(req.body);
45 | });
46 |
47 | router.post('/remove', goods.remove, log.add, function(req, res, next) {
48 | res.json(req.body);
49 | });
50 |
51 | router.post('/types', goods.types, function(req, res, next) {
52 | res.json(req.body);
53 | });
54 |
55 | // 删除分类
56 | router.post('/removeType', login.check, goods.removeType, log.add, function(req, res, next) {
57 | res.json(req.body);
58 | });
59 |
60 | // 添加分类
61 | router.post('/addType', login.check, goods.addType, log.add, function(req, res, next) {
62 | res.json(req.body);
63 | });
64 |
65 | // 更新分类
66 | router.post('/updateType', login.check, goods.updateType, log.add, function(req, res, next) {
67 | res.json(req.body);
68 | });
69 |
70 | module.exports = router;
71 |
--------------------------------------------------------------------------------
/utils/pool.js:
--------------------------------------------------------------------------------
1 | const mysql = require('mysql');
2 | const config = require('../config/index');
3 |
4 | // 创建连接池
5 | const pool = mysql.createPool({
6 | host : config.mysql.host,
7 | user : config.mysql.user,
8 | password : config.mysql.password,
9 | database : config.mysql.database,
10 | charset : 'utf8mb4',
11 | connectionLimit: 10,
12 | multipleStatements: true
13 | });
14 |
15 | const query = (sql, callback, data, tips) => {
16 | if (callback) {
17 | pool.getConnection((err, conn) => {
18 | if (err) {
19 | callback && callback(err, null, null)
20 | } else {
21 | conn.query(sql, data, (qerr, vals, fields) => {
22 | // 释放连接
23 | conn.release()
24 | // 回调函数
25 | callback && callback(qerr, vals, fields)
26 | });
27 | }
28 | })
29 | } else {
30 | // 使用async await
31 | return new Promise((resolve, reject) => {
32 | pool.getConnection((err, conn) => {
33 | if (err) {
34 | reject(err);
35 | } else {
36 | const query = conn.query(sql, data, (qerr, vals, fields) => {
37 | // 释放连接
38 | conn.release();
39 | if (qerr) {
40 | qerr.fail = true;
41 | console.warn(tips, '出错', query.sql, qerr);
42 | resolve(qerr);
43 | } else {
44 | console.info(tips, '成功', query.sql);
45 | resolve(vals);
46 | }
47 | })
48 | }
49 | })
50 | });
51 | }
52 | }
53 |
54 | module.exports = query
55 |
56 | // 1、使用连接池示例
57 |
58 | // const query = require(./pool);
59 | // query("SELECT * FROM `user_info`", (err, vals, fields) => { })
60 |
61 | // ------------------------------------------------------------------------------------
62 |
63 | // 2、创建多条查询语句
64 |
65 | // 启用多条语句查询
66 | // var connection = mysql.creatConnection({ multipleStatements: true});
67 | // 新建多条语句实例
68 | // connection.query('sql statementq; sql statement2; sql statement3;', (err, data) => {
69 | // if (err) {
70 | // throw new Error(err);
71 | // } else {
72 | // console.dir(data[0], data[1], data[2]);
73 | // }
74 | // })
75 |
76 | // ------------------------------------------------------------------------------------
--------------------------------------------------------------------------------
/middlewares/update.js:
--------------------------------------------------------------------------------
1 | /*
2 | * @Author: 唐文雍
3 | * @Date: 2019-01-16 10:17:32
4 | * @Last Modified by: 唐文雍
5 | * @Last Modified time: 2019-01-16 10:17:32
6 | */
7 | const query = require('../utils/pool');
8 | const update = {};
9 | exports.update = update;
10 |
11 | // 更新user_tasks表中的textStep,reviewStep,reviewField字段,从对应的表拼装数据塞进去
12 | update.userTasks = function(req, res, next) {
13 | const taskSql = `SELECT * FROM user_tasks`;
14 | query(taskSql, (taskErr, taskVals) => {
15 | if (!taskErr && taskVals instanceof Array) {
16 | taskVals.forEach((item) => {
17 | const textStepSql = `select * from task_text_step where task_id=${item.task_id}`;
18 | query(textStepSql, (textStepErr, textStepVals) => {
19 | if (!textStepErr && textStepVals instanceof Array) {
20 | textStepVals.forEach((stepItem) => {
21 | const updateTextStepSql = `update user_tasks set textStep='${JSON.stringify(stepItem)}' where id=${item.id}`
22 | query(updateTextStepSql);
23 | })
24 | }
25 | })
26 |
27 | const reviewStepSql = `select * from task_review_step where task_id=${item.task_id}`;
28 | query(reviewStepSql, (reviewStepErr, reviewStepVals) => {
29 | if (!reviewStepErr && reviewStepVals instanceof Array) {
30 | reviewStepVals.forEach((stepItem) => {
31 | const updateReviewStepSql = `update user_tasks set reviewStep='${JSON.stringify(stepItem)}' where id=${item.id}`
32 | query(updateReviewStepSql);
33 | })
34 | }
35 | })
36 |
37 | const reviewFieldSql = `select * from task_review_field where task_id=${item.task_id}`;
38 | query(reviewFieldSql, (reviewFieldErr, reviewFieldVals) => {
39 | if (!reviewFieldErr && reviewFieldVals instanceof Array) {
40 | reviewFieldVals.forEach((fieldItem) => {
41 | const updateReviewFieldSql = `update user_tasks set reviewField='${JSON.stringify(fieldItem)}' where id=${item.id}`
42 | query(updateReviewFieldSql);
43 | })
44 | }
45 | })
46 | })
47 | return next();
48 | } else {
49 | return res.json({ code: '10001', message: taskErr.message, success: false, data: taskErr });
50 | }
51 | })
52 | }
53 |
--------------------------------------------------------------------------------
/utils/function.js:
--------------------------------------------------------------------------------
1 | const crypto = require('crypto');
2 | const qs = require('qs');
3 | const config = require('../config/index');
4 |
5 | module.exports = {
6 | /**
7 | * randomWord 产生任意长度随机字母数字组合
8 | * @param randomFlag 是否任意长度 min-任意长度最小位[固定位数] max-任意长度最大位
9 | * @param min
10 | * @param max
11 | * @returns {string}
12 | */
13 | randomWord: function(randomFlag, min, max) {
14 | var str = "",
15 | range = min,
16 | arr = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'];
17 | // 随机产生
18 | if(randomFlag){
19 | range = Math.round(Math.random() * (max-min)) + min;
20 | }
21 | for(var i=0; i {
51 | console.log('发送验证码返回', JSON.stringify(res));
52 | if (res.Code === 'OK') {
53 | req.body.data = true;
54 | req.body.code = '10000';
55 | req.body.message = '操作成功';
56 | req.body.success = true;
57 | return next();
58 | } else {
59 | return res.json({ code: '10012', message: res.Message, success: false, data: null });
60 | }
61 | }, (ex) => {
62 | console.info('验证码发送失败', ex);
63 | return res.json({ code: '10012', message: '发送失败', success: false, data: ex });
64 | })
65 | }
66 | }
67 |
68 | sms.check = function(req, res, next) {
69 | const phone = req.body.phone || req.body.phone;
70 | const code = req.body.code || req.body.code;
71 | global.redisClient.get(phone, function(err, reply) {
72 | if (reply && reply.toString() && reply.toString() === code) {
73 | // 验证码正确
74 | return next();
75 | } else {
76 | return res.json({
77 | code: '10013',
78 | message: '验证码不正确',
79 | success: false,
80 | data: false,
81 | });
82 | }
83 | });
84 | }
--------------------------------------------------------------------------------
/routes/order.js:
--------------------------------------------------------------------------------
1 | const express = require('express');
2 | var xmlparser = require('express-xml-bodyparser');
3 | const router = express.Router();
4 | const { login } = require('../middlewares/login.js');
5 | const { system } = require('../middlewares/system.js');
6 | const { order } = require('../middlewares/order.js');
7 | const { user } = require('../middlewares/user.js');
8 |
9 | router.post('/getDetail', order.getDetail, function(req, res, next) {
10 | res.json(req.body);
11 | });
12 |
13 | // 充值
14 | router.post('/rechargeMoney',
15 | login.check,
16 | system.get,
17 | order.rechargeMoney,
18 | order.session,
19 | order.add,
20 | function(req, res, next) {
21 | res.json(req.body);
22 | });
23 |
24 | // 充值支付回调
25 | router.post('/rechargeMoneyNotify',
26 | xmlparser({ trim: false, explicitArray: false }),
27 | order.rechargeMoneyNotify,
28 | function(req, res, next) {
29 | res.json(req.body);
30 | });
31 |
32 | // APP下单接口
33 | router.post('/appAdd',
34 | login.check,
35 | order.appAdd,
36 | function(req, res, next) {
37 | res.json(req.body);
38 | });
39 |
40 | // 公众号获取openid
41 | router.post('/publicSession',
42 | login.check,
43 | order.officialSession,
44 | function(req, res, next) {
45 | res.json(req.body);
46 | });
47 |
48 | // 公众号下单接口
49 | router.post('/publicAdd',
50 | login.check,
51 | order.publicAdd,
52 | function(req, res, next) {
53 | res.json(req.body);
54 | });
55 |
56 | // 支付宝下单接口
57 | router.post('/alipayAdd',
58 | login.check,
59 | order.alipayAdd,
60 | function(req, res, next) {
61 | res.json(req.body);
62 | });
63 |
64 | // 支付宝充值支付回调
65 | router.post('/alipayRechargeNotify',
66 | order.alipayRechargeNotify,
67 | function(req, res, next) {
68 | res.json(req.body);
69 | });
70 |
71 | // 接收闲玩订单
72 | router.get('/xianwan',
73 | order.xianwan,
74 | function(req, res, next) {
75 | res.json(req.body);
76 | });
77 |
78 | // 接收鱼玩订单
79 | router.post('/yuwan',
80 | order.yuwan,
81 | function(req, res, next) {
82 | res.json(req.body);
83 | });
84 |
85 | // 接收多游订单
86 | router.get('/duoyou',
87 | order.duoyou,
88 | function(req, res, next) {
89 | res.json(req.body);
90 | });
91 |
92 | // 发红包订单
93 | router.post('/redAdd',
94 | login.check,
95 | user.info,
96 | order.red,
97 | function(req, res, next) {
98 | res.json(req.body);
99 | });
100 |
101 | // 获取红包订单详情
102 | router.post('/redDetail',
103 | login.check,
104 | order.redDetail,
105 | function(req, res, next) {
106 | res.json(req.body);
107 | });
108 |
109 | // 领取红包
110 | router.post('/redReceive',
111 | login.check,
112 | order.redReceive,
113 | function(req, res, next) {
114 | res.json(req.body);
115 | });
116 |
117 | module.exports = router;
118 |
--------------------------------------------------------------------------------
/middlewares/log.js:
--------------------------------------------------------------------------------
1 | /*
2 | * @Author: 唐文雍
3 | * @Date: 2019-01-16 10:17:32
4 | * @Last Modified by: 唐文雍
5 | * @Last Modified time: 2019-01-16 10:17:32
6 | */
7 | const query = require('../utils/pool');
8 | const log = {};
9 | exports.log = log;
10 |
11 | //后台管理》分页获取操作日志列表
12 | log.list = async function(req, res, next) {
13 | var param = req.body;
14 | //分页实现
15 | var currentPage = 1; //默认为1
16 | var size = 10; //每页条数
17 | if (param.page) {
18 | currentPage = parseInt(param.page);
19 | }
20 | if (param.size) {
21 | size = parseInt(param.size);
22 | }
23 | //设置最后一页页码
24 | var lastPage = currentPage - 1;
25 | //假如目前仅有一页,则最后一页则为1
26 | if (currentPage <= 1) {
27 | lastPage = 1;
28 | }
29 | //如果需要下一页,则开启
30 | //var nextPage = currentPage + 1;
31 | var offset = (currentPage - 1) * size;
32 | const { content, user, createDateRange } = param;
33 | const filters = [];
34 | content && filters.push(`content like "%${content}%"`);
35 | user && filters.push(`user='${user}'`);
36 | createDateRange && createDateRange.length === 2 && filters.push(`created_at >= ${createDateRange[0]} and created_at <= ${createDateRange[1]}`);
37 | const filterString = filters.length ? `where ${filters.join(' and ')}` : '';
38 | var sql = `SELECT count(*) FROM logs ${filterString};
39 | select * FROM logs ${filterString} order by created_at desc limit ${size} offset ${offset}`;
40 | console.info('查询操作日志', sql);;
41 | query(sql, (err, vals) => {
42 | if (!err && vals instanceof Array) {
43 | const totalCount = vals[0][0]['count(*)'];
44 | const totalPage = Math.ceil(parseInt(totalCount) / size);
45 | req.body.data = {
46 | list: vals[1],
47 | size: size,
48 | page: currentPage,
49 | totalPage: totalPage,
50 | totalCount: totalCount,
51 | };
52 | req.body.code = '10000';
53 | req.body.message = '操作成功';
54 | req.body.success = true;
55 | return next();
56 | } else {
57 | return res.json({
58 | code: '10001',
59 | message: err,
60 | success: false,
61 | data: null,
62 | });
63 | }
64 | });
65 | };
66 |
67 | // 添加操作日志
68 | log.add = async function(req, res, next) {
69 | if (!req.body.log) {
70 | return next();
71 | }
72 | const ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress || req.socket.remoteAddress || req.connection.socket.remoteAddress;
73 | const { user, client, content } = req.body.log;
74 | if (!user || !client || !content) {
75 | return next();
76 | }
77 | const created_at = new Date().getTime();
78 | const sql = `insert into logs(user,client,ip,content,created_at) values(?,?,?,?,?)`;
79 | await query(sql, null, [user, client, ip, content, created_at], '添加操作日志');
80 | // 清空日志
81 | delete req.body.log;
82 | return next();
83 | }
--------------------------------------------------------------------------------
/utils/download.js:
--------------------------------------------------------------------------------
1 | /**
2 | * 下载演员图片
3 | */
4 |
5 | var fs = require('fs');
6 | var request = require('request');
7 |
8 | // 1. 获取图片src
9 | var data = require('../public/data/film_origin_all.json');
10 | // var url = './public/data/films_all.json';
11 |
12 | console.log(data.count);
13 |
14 | downloadImage(data)
15 | // 2. 下载图片
16 | function downloadImage(data) {
17 | console.log('收到 ' + data.subjects.length+ ' 条数据');
18 | var subjects = data.subjects;
19 |
20 | // casts
21 | for (let i = 0; i < subjects.length; i ++) {
22 | for (let x = 0; x < subjects[i].casts.length; x ++) {
23 | var id = subjects[i].casts[x].id;
24 | if (id == null) {
25 | break;
26 | }
27 | var src = subjects[i].casts[x].avatars.small;
28 | console.log('casts');
29 | console.log(i, x);
30 | console.log(src);
31 | // return;
32 | let tail = null;
33 | if ( src.indexOf('.webp') > -1 ) {
34 | tail = '.webp'
35 | } else if ( src.indexOf('.jpg') > -1 ) {
36 | tail = '.jpg'
37 | } else if ( src.indexOf('.jpeg') > -1 ) {
38 | tail = '.jpeg'
39 | } else {
40 | tail = '.png'
41 | }
42 | var writeStream = fs.createWriteStream('./public/images/test/'+ subjects[i].casts[x].id + tail);
43 | var readStream = request(src);
44 | readStream.pipe(writeStream);
45 |
46 | readStream.on('end', function() {
47 | console.log(i + ' 文件下载成功');
48 | });
49 | readStream.on('error', function() {
50 | console.log("错误信息:" + err)
51 | })
52 | writeStream.on("finish", function() {
53 | console.log(i + " 文件写入成功");
54 | // writeStream.end();
55 | })
56 | }
57 | }
58 |
59 | // directors
60 | for (let i = 0; i < subjects.length; i ++) {
61 | for (let x = 0; x < subjects[i].directors.length; x ++) {
62 | var id = subjects[i].directors[x].id;
63 | if (id == null) {
64 | break;
65 | }
66 | var src = subjects[i].directors[x].avatars.small;
67 | console.log('directors');
68 | console.log(i, x);
69 | console.log(src);
70 | // return;
71 | let tail = null;
72 | if ( src.indexOf('.webp') > -1 ) {
73 | tail = '.webp'
74 | } else if ( src.indexOf('.jpg') > -1 ) {
75 | tail = '.jpg'
76 | } else if ( src.indexOf('.jpeg') > -1 ) {
77 | tail = '.jpeg'
78 | } else {
79 | tail = '.png'
80 | }
81 | var writeStream = fs.createWriteStream('./public/images/test/'+ subjects[i].directors[x].id + tail);
82 | var readStream = request(src);
83 | readStream.pipe(writeStream);
84 |
85 | readStream.on('end', function() {
86 | console.log(i + ' 文件下载成功');
87 | });
88 | readStream.on('error', function() {
89 | console.log("错误信息:" + err)
90 | })
91 | writeStream.on("finish", function() {
92 | console.log(i + " 文件写入成功");
93 | // writeStream.end();
94 | })
95 | }
96 | }
97 | }
--------------------------------------------------------------------------------
/middlewares/score.js:
--------------------------------------------------------------------------------
1 | /*
2 | * @Author: 唐文雍
3 | * @Date: 2019-01-16 10:17:32
4 | * @Last Modified by: 唐文雍
5 | * @Last Modified time: 2019-01-16 10:17:32
6 | */
7 | const query = require('../utils/pool');
8 | const score = {};
9 | exports.score = score;
10 |
11 | // 给用户加减积分
12 | score.add = function(req, res, next) {
13 | const user_id = req.body.user_id;
14 | const score = req.body.score || 0;
15 | // 积分获得来源。1签到;2发任务;3完成任务;4实名认证;5加入会员;6充值;7平台赠送/扣除;8转盘
16 | const type = req.body.type;
17 | const remark = req.body.remark || '';
18 | const created_at = new Date().getTime();
19 | const is_income = score > 0;
20 | const sql = `begin;
21 | update users set score=score+${score} where id=${user_id};
22 | insert into score_stream(type,score,balance,user_id,is_income,created_at,remark)
23 | values(${type},${Math.abs(score)},(select score from users where id=${user_id}),${user_id},${is_income},'${created_at}','${remark}');
24 | commit;`
25 | console.info("加积分", sql);
26 | query(sql, (err, vals) => {
27 | console.info('加积分返回', vals)
28 | if (!err && vals instanceof Array) {
29 | req.body.data = true;
30 | req.body.code = '10000';
31 | req.body.message = '操作成功';
32 | req.body.success = true;
33 | // 记录操作日志
34 | req.body.log = Object.assign(req.body.log || {}, {
35 | client: 1,
36 | content: `给ID为${user_id}的用户${is_income ? '发放' : '扣除'}了${score}积分`,
37 | });
38 | return next();
39 | } else {
40 | return res.json({ code: '10001', message: err.message, success: false, data: err });
41 | }
42 | })
43 | }
44 |
45 | // 获取用户积分流水
46 | score.stream = function(req, res, next) {
47 | var param = req.body;
48 | //分页实现
49 | var currentPage = 1; //默认为1
50 | var size = 10; //每页条数
51 | if (param.page) {
52 | currentPage = parseInt(param.page);
53 | }
54 | if (param.size) {
55 | size = parseInt(param.size);
56 | }
57 | //设置最后一页页码
58 | var lastPage = currentPage - 1;
59 | //假如目前仅有一页,则最后一页则为1
60 | if (currentPage <= 1) {
61 | lastPage = 1;
62 | }
63 | //如果需要下一页,则开启
64 | //var nextPage = currentPage + 1;
65 | var offset = (currentPage - 1) * size;
66 |
67 | const type = param.type;
68 | const userId = param.userId;
69 | const isSearch = type || userId;
70 | let filters = [];
71 | type && filters.push(`type=${type}`);
72 | userId && filters.push(`user_id=${userId}`);
73 | filters = isSearch ? filters.join(' and ') : '';
74 |
75 | var sql = `SELECT COUNT(*) FROM score_stream where ${filters};
76 | select * FROM score_stream where ${filters}
77 | order by created_at desc limit ${size} offset ${offset}`;
78 |
79 | console.info('查询用户积分流水', sql);;
80 | query(sql, (err, vals) => {
81 | if (!err && vals instanceof Array) {
82 | const totalCount = vals[0][0]['COUNT(*)'];
83 | const totalPage = Math.ceil(parseInt(totalCount) / size);
84 | req.body.data = {
85 | list: vals[1],
86 | size: size,
87 | page: currentPage,
88 | totalPage: totalPage,
89 | totalCount: totalCount,
90 | };
91 | req.body.code = '10000';
92 | req.body.message = '操作成功';
93 | req.body.success = true;
94 | return next();
95 | } else {
96 | return res.json({
97 | code: '10001',
98 | message: err.message,
99 | success: false,
100 | data: err,
101 | });
102 | }
103 | });
104 | }
105 |
106 | // 获取转盘列表
107 | score.getLuckyDrawList = async function(req, res, next) {
108 | const sql = `SELECT * FROM lucky_draw order by sort desc`;
109 | const result = await query(sql, null, null, '查询转盘列表');
110 | if (!result.fail && result instanceof Array) {
111 | req.body.data = result;
112 | req.body.code = '10000';
113 | req.body.message = '操作成功';
114 | req.body.success = true;
115 | return next();
116 | } else {
117 | return res.json({ code: '10001', message: '', success: false, data: 'err' });
118 | }
119 | }
--------------------------------------------------------------------------------
/utils/avatar.js:
--------------------------------------------------------------------------------
1 | /**
2 | * 下载演员图片
3 | */
4 |
5 | var fs = require('fs');
6 | var request = require('request');
7 |
8 | // 1. 获取图片src
9 | var data = require('../public/data/200_films_top250.json');
10 | var url = './public/data/200_films_top250.json';
11 |
12 | console.log(data.count);
13 |
14 | fs.readFile(url, 'utf-8', function (err, data) {
15 | if (err) {
16 | console.error(err);
17 | }
18 |
19 | data = JSON.parse(data);
20 | console.log(typeof data);
21 |
22 | for (let i = 0; i < data.subjects.length; i ++) {
23 |
24 | delete data.subjects[i].rating;
25 | delete data.subjects[i].genres;
26 | delete data.subjects[i].title;
27 | delete data.subjects[i].collect_count;
28 | delete data.subjects[i].original_title;
29 | delete data.subjects[i].subtype;
30 | delete data.subjects[i].year;
31 | delete data.subjects[i].id;
32 | delete data.subjects[i].cover;
33 |
34 | // casts
35 | for (let m = 0; m < data.subjects[i].casts.length; m ++) {
36 | let id = data.subjects[i].casts[m].id;
37 |
38 | if (id === null) {
39 | data.subjects[i].casts[m].id = '';
40 | data.subjects[i].casts[m].avatar = "";
41 | }
42 | }
43 |
44 | // directors
45 | for (let n = 0; n < data.subjects[i].directors.length; n ++) {
46 | let id = data.subjects[i].directors[n].id;
47 |
48 | if (id === null) {
49 | data.subjects[i].directors[n].id = '';
50 | data.subjects[i].directors[n].avatar = "";
51 | } else {
52 | let src = data.subjects[i].directors[n].small;
53 |
54 | if (src == null) {
55 | data.subjects[i].directors[n].avatar = ''
56 | } else {
57 | data.subjects[i].directors[n].avatar = src;
58 | }
59 | }
60 | }
61 | }
62 |
63 | // 2. 下载图片
64 | downloadImage(data);
65 |
66 | data = JSON.stringify(data);
67 | fs.writeFile('./public/data/avatar/200_249.json', data, 'utf-8', err => {
68 | if (err) {
69 | console.error(err);
70 | }
71 |
72 | console.log('write success');
73 | })
74 | })
75 |
76 | // 2. 下载图片
77 | function downloadImage(data, start) {
78 | console.log('收到 ' + data.subjects.length+ ' 条数据');
79 | start = 1*start;
80 | var subjects = data.subjects;
81 |
82 | // casts
83 | for (let i = 0; i < subjects.length; i ++) {
84 | for (let x = 0; x < subjects[i].casts.length; x ++) {
85 | var src = subjects[i].casts[x].avatar;
86 | if (src == '') {
87 | break;
88 | }
89 | console.log(i, x);
90 | console.log(src);
91 | // return;
92 | var writeStream = fs.createWriteStream('./public/images/avatars/'+ subjects[i].casts[x].id + '.jpg');
93 | var readStream = request(src);
94 | readStream.pipe(writeStream);
95 |
96 | readStream.on('end', function() {
97 | console.log(i + ' 文件下载成功');
98 | });
99 | readStream.on('error', function() {
100 | console.log("错误信息:" + err)
101 | })
102 | writeStream.on("finish", function() {
103 | console.log(i + " 文件写入成功");
104 | // writeStream.end();
105 | })
106 | }
107 | }
108 |
109 | // directors
110 | for (let i = 0; i < subjects.length; i ++) {
111 | for (let x = 0; x < subjects[i].directors.length; x ++) {
112 | var src = subjects[i].directors[x].avatar;
113 | if (src == '') {
114 | break;
115 | }
116 | console.log(i, x);
117 | console.log(src);
118 | // return;
119 | var writeStream = fs.createWriteStream('./public/images/avatars/'+ subjects[i].directors[x].id + '.jpg');
120 | var readStream = request(src);
121 | readStream.pipe(writeStream);
122 |
123 | readStream.on('end', function() {
124 | console.log(i + ' 文件下载成功');
125 | });
126 | readStream.on('error', function() {
127 | console.log("错误信息:" + err)
128 | })
129 | writeStream.on("finish", function() {
130 | console.log(i + " 文件写入成功");
131 | // writeStream.end();
132 | })
133 | }
134 | }
135 | }
--------------------------------------------------------------------------------
/middlewares/banners.js:
--------------------------------------------------------------------------------
1 | /*
2 | * @Author: 唐文雍
3 | * @Date: 2019-01-16 10:17:32
4 | * @Last Modified by: 唐文雍
5 | * @Last Modified time: 2019-01-16 10:17:32
6 | */
7 | const query = require('../utils/pool');
8 | const banners = {};
9 | exports.banners = banners;
10 |
11 | //获取轮播图
12 | banners.get = async function(req, res, next) {
13 | const client = req.body.client || '';
14 | const type = req.body.type || '';
15 | const values = [];
16 | const filters = ['deleted=0'];
17 | client && filters.push(`client like "%?%"`) && values.push(+client);
18 | type && filters.push(`type=?`) && values.push(type);
19 | const filterString = filters.length ? `where ${filters.join(' and ')}` : '';
20 | const sql = `SELECT * FROM banners ${filterString} order by sort desc`;
21 | const result = await query(sql, null, values, '查询图片轮播');
22 | if (!result.fail && result instanceof Array) {
23 | req.body.data = result;
24 | req.body.code = '10000';
25 | req.body.message = '操作成功';
26 | req.body.success = true;
27 | return next();
28 | } else {
29 | return res.json({ code: '10001', message: '', success: false, data: 'err' });
30 | }
31 | }
32 | banners.add = function(req, res, next) {
33 | const image = req.body.image;
34 | const title = req.body.title;
35 | const type = req.body.type || 1;
36 | const url = req.body.url;
37 | const mpUrl = req.body.mpUrl;
38 | let client = req.body.client;
39 | client = client instanceof Array ? client.join(',') : client;
40 | const createdAt = new Date().getTime();
41 | const createdBy = req.body.createdBy;
42 | const sql = `insert into banners(type,client,image,title,url,mp_url,created_at,created_by)
43 | values(${type},'${client}',"${image}","${title}","${url}","${mpUrl}","${createdAt}","${createdBy}")`;
44 | console.info("新增轮播图", sql);
45 | query(sql, (err, vals) => {
46 | if (!err && vals instanceof Object) {
47 | req.body.data = vals.insertId;
48 | req.body.code = '10000';
49 | req.body.message = '操作成功';
50 | req.body.success = true;
51 | // 记录操作日志
52 | req.body.log = Object.assign(req.body.log || {}, {
53 | client: 1,
54 | content: `添加了ID为${vals.insertId}的图片轮播`,
55 | });
56 | return next();
57 | } else {
58 | return res.json({ code: '10001', message: err, success: false, data: null });
59 | }
60 | })
61 | }
62 | banners.update = function(req, res, next) {
63 | const id = req.body.id;
64 | const image = req.body.image;
65 | const title = req.body.title;
66 | const type = req.body.type || 1;
67 | const url = req.body.url;
68 | const mpUrl = req.body.mpUrl;
69 | let client = req.body.client;
70 | client = client instanceof Array ? client.join(',') : client;
71 | const updated_at = new Date().getTime();
72 | const sql = `update banners set
73 | client='${client}',
74 | type=${type},
75 | image="${image}",
76 | title="${title}",
77 | url="${url}",
78 | mp_url="${mpUrl}",
79 | updated_at="${updated_at}"
80 | where id=${id};`;
81 | console.info("更新轮播", sql);
82 | query(sql, (err, vals) => {
83 | if (!err && vals instanceof Object) {
84 | req.body.data = true;
85 | req.body.code = '10000';
86 | req.body.message = '操作成功';
87 | req.body.success = true;
88 | // 记录操作日志
89 | req.body.log = Object.assign(req.body.log || {}, {
90 | client: 1,
91 | content: `更新了ID为${id}的图片轮播`,
92 | });
93 | return next();
94 | } else {
95 | return res.json({ code: '10001', message: err.message, success: false, data: err });
96 | }
97 | })
98 | }
99 | banners.remove = function(req, res, next) {
100 | const id = req.body.id || req.body.id;
101 | const updatedAt = new Date().getTime();
102 | const sql = `update banners set deleted=1,updated_at=${updatedAt} where id=${id}`;
103 | console.info("删除轮播图", sql);
104 | query(sql, (err, vals) => {
105 | if (!err && vals instanceof Object) {
106 | req.body.data = true;
107 | req.body.code = '10000';
108 | req.body.message = '操作成功';
109 | req.body.success = true;
110 | // 记录操作日志
111 | req.body.log = Object.assign(req.body.log || {}, {
112 | client: 1,
113 | content: `删除了ID为${id}的图片轮播`,
114 | });
115 | return next();
116 | } else {
117 | return res.json({ code: '10001', message: err.code, success: false, data: null });
118 | }
119 | })
120 | }
--------------------------------------------------------------------------------
/service/user.js:
--------------------------------------------------------------------------------
1 | /*
2 | * @Author: 唐文雍
3 | * @Date: 2019-01-16 10:17:32
4 | * @Last Modified by: 唐文雍
5 | * @Last Modified time: 2019-01-16 10:17:32
6 | */
7 | const query = require('../utils/pool');
8 | const { MessageService } = require('./message');
9 | const UserService = {};
10 | exports.UserService = UserService;
11 |
12 | /**
13 | * 查询用户信息
14 | * @param {Number} userId 用户ID
15 | * @returns Object
16 | */
17 | UserService.getUserInfo = async function(userId) {
18 | const userSql = `select * from users where id=${userId}`;
19 | const userResult = await query(userSql, null, null, '查询用户信息');
20 | console.info('用户信息', userResult)
21 | if (!userResult.fail && userResult instanceof Array) {
22 | return userResult[0] || {}
23 | }
24 | return {}
25 | }
26 |
27 | /**
28 | * 查询等级信息
29 | * @param {Number} level 用户等级
30 | * @returns
31 | */
32 | UserService.getLevelInfo = async function(level) {
33 | const levelSql = `select * from growth_levels where level=${level}`;
34 | const levelResult = await query(levelSql, null, null, '查询等级信息');
35 | console.info('等级信息', levelResult)
36 | if (!levelResult.fail && levelResult instanceof Array) {
37 | return levelResult[0] || {}
38 | }
39 | return {}
40 | }
41 |
42 | /**
43 | * 给指定用户升级
44 | * @param {Number} userId 用户ID
45 | * @returns
46 | */
47 | UserService.growthLevel = async function(userId) {
48 | // 查询用户信息
49 | const userInfo = await UserService.getUserInfo(userId)
50 | // 下一等级信息
51 | const nextLevelInfo = await UserService.getLevelInfo(userInfo.level + 1)
52 |
53 | const taskSql = `SELECT count(*) as task_count FROM user_tasks where user_id=${userId} and status=3`;
54 | const taskResult = await query(taskSql, null, null, '查询用户已完成任务数');
55 | console.info('用户已完成任务数', taskResult)
56 | let taskCount = 0
57 | if (!taskResult.fail && taskResult instanceof Array && taskResult[0]) {
58 | taskCount = taskResult[0].task_count
59 | }
60 |
61 | const inviteSql = `SELECT count(*) as invite_count FROM users where inviter=${userId}`;
62 | const inviteResult = await query(inviteSql, null, null, '查询用户直属下级数');
63 | console.info('用户已完成任务数', inviteResult)
64 | let inviteCount = 0
65 | if (!inviteResult.fail && inviteResult instanceof Array && inviteResult[0]) {
66 | inviteCount = inviteResult[0].invite_count
67 | }
68 |
69 | // 当直属下级数量和已完成任务数满足升级
70 | if (nextLevelInfo
71 | && nextLevelInfo.task_count
72 | && taskCount >= nextLevelInfo.task_count
73 | && nextLevelInfo.invite_count
74 | && inviteCount >= nextLevelInfo.invite_count ) {
75 | const growthSql = `update users set level=level+1 where id=${userId}`
76 | const growthResult = await query(growthSql, null, null, '用户升级')
77 | console.info('用户升级返回', growthResult)
78 | if (!growthResult.fail && growthResult instanceof Object && growthResult.affectedRows) {
79 | // 添加动态
80 |
81 | const { phone, nick_name, username } = userInfo
82 | await MessageService.addDynamic(`恭喜用户${phone || nick_name || username}成功晋级到${nextLevelInfo.name}`)
83 | }
84 | }
85 | }
86 |
87 | /**
88 | * 给用户按等级发放奖金
89 | */
90 | UserService.sendAward = async function() {
91 | const sql = `select u.id,u.account_amount,u.level,g.money_monthly from users u left join growth_levels g on u.level=g.level where u.deleted=0 and u.status=1 and g.money_monthly > 0`
92 | const userResult = await query(sql, null, null, '查询用户等级每月奖励')
93 | if (!userResult.fail && userResult instanceof Array) {
94 | userResult.forEach(async (item) => {
95 | await UserService.addMoney(item.id, item.money_monthly, 3, '发放用户等级奖金')
96 | })
97 | }
98 | }
99 |
100 | /**
101 | * 给用户加钱
102 | * @param {Number} userId 用户ID
103 | * @param {Number} money 加的金额
104 | * @param {Number} type 类型,1充值;2提现;3收入;4支出
105 | * @param {String} remark 备注
106 | * @returns Boolean
107 | */
108 | UserService.addMoney = async function(userId, money, type, remark) {
109 | money = +money
110 | if (money < 0 || !userId) {
111 | return false
112 | }
113 | const sql = `begin;
114 | update users set account_amount=account_amount+${money} where id=${userId};
115 | insert into money_stream(type,money,balance,user_id,is_income,created_at,remark)
116 | values(${type},${money},(select account_amount from users where id=${userId}),${userId},1,'${Date.now()}','${remark}');
117 | commit;`
118 | console.info("加钱", sql);
119 | const addResult = await query(sql, null, null, `给用户${userId}加${money}元,备注:${remark}`)
120 | return !addResult.fail
121 | }
--------------------------------------------------------------------------------
/middlewares/address.js:
--------------------------------------------------------------------------------
1 | /*
2 | * @Author: 唐文雍
3 | * @Date: 2019-01-16 10:17:32
4 | * @Last Modified by: 唐文雍
5 | * @Last Modified time: 2019-01-16 10:17:32
6 | */
7 | const query = require('../utils/pool');
8 | const address = {};
9 | exports.address = address;
10 |
11 | //获取收货地址列表
12 | address.list = async function(req, res, next) {
13 | const values = [req.body.userId];
14 | const filters = ['deleted=0', `user_id=?`];
15 | const filterString = filters.length ? `where ${filters.join(' and ')}` : '';
16 | const sql = `SELECT * FROM address ${filterString} order by is_default desc`;
17 | const result = await query(sql, null, values, '查询收货地址');
18 | if (!result.fail && result instanceof Array) {
19 | req.body.data = result;
20 | req.body.code = '10000';
21 | req.body.message = '操作成功';
22 | req.body.success = true;
23 | return next();
24 | } else {
25 | return res.json({ code: '10001', message: '', success: false, data: 'err' });
26 | }
27 | }
28 |
29 | address.detail = async function(req, res, next) {
30 | const id = req.body.id;
31 | const sql = `select * from address where deleted=0 and id=${id}`;
32 | const result = await query(sql, null, null, '获取收货地址详情');
33 | if (!result.fail && result instanceof Array) {
34 | req.body.data = result[0];
35 | req.body.code = '10000';
36 | req.body.message = '操作成功';
37 | req.body.success = true;
38 | return next();
39 | } else {
40 | return res.json({ code: '10001', message: result.message, success: false, data: result });
41 | }
42 | }
43 |
44 | address.add = async function(req, res, next) {
45 | const userId = req.body.userId;
46 | const province = req.body.province;
47 | const city = req.body.city;
48 | const area = req.body.county;
49 | const area_code = req.body.area_code;
50 | const postal_code = req.body.postal_code;
51 | const address = req.body.addressDetail;
52 | const name = req.body.name;
53 | const tel = req.body.tel;
54 | const is_default = req.body.is_default === 'true' ? 1 : 0;
55 | const createdAt = new Date().getTime();
56 | const values = [userId, name, tel, province, city, area, area_code, postal_code, address, is_default, createdAt];
57 | const sql = `insert into address(user_id,name,tel,province,city,area,area_code,postal_code,address,is_default,created_at) values(?,?,?,?,?,?,?,?,?,?,?)`;
58 | const result = await query(sql, null, values, '新增收货地址');
59 | if (!result.fail && result instanceof Object) {
60 | req.body.data = result.insertId;
61 | req.body.code = '10000';
62 | req.body.message = '操作成功';
63 | req.body.success = true;
64 | return next();
65 | } else {
66 | return res.json({ code: '10001', message: result.message, success: false, data: null });
67 | }
68 | }
69 |
70 | address.update = async function(req, res, next) {
71 | const id = req.body.id;
72 | const province = req.body.province;
73 | const city = req.body.city;
74 | const area = req.body.county;
75 | const area_code = req.body.area_code;
76 | const postal_code = req.body.postal_code;
77 | const address = req.body.addressDetail;
78 | const name = req.body.name;
79 | const tel = req.body.tel;
80 | const is_default = req.body.is_default === 'true' ? 1 : 0;
81 | const updated_at = new Date().getTime();
82 | const values = [name, tel, province, city, area, area_code, postal_code, address, is_default, updated_at, id];
83 | const sql = `update address set name=?,tel=?,province=?,city=?,area=?,area_code=?,postal_code=?,address=?,is_default=?,updated_at=? where id=?;`;
84 | const result = await query(sql, null, values, '更新收货地址');
85 | if (!result.fail && result instanceof Object) {
86 | req.body.data = true;
87 | req.body.code = '10000';
88 | req.body.message = '操作成功';
89 | req.body.success = true;
90 | return next();
91 | } else {
92 | return res.json({ code: '10001', message: result.message, success: false, data: result });
93 | }
94 | }
95 |
96 | address.remove = async function(req, res, next) {
97 | const id = req.body.id;
98 | const updatedAt = new Date().getTime();
99 | const values = [updatedAt, id]
100 | const sql = `update address set deleted=1,updated_at=? where id=?`;
101 | const result = await query(sql, null, values, '删除收货地址');
102 | if (!result.fail && result instanceof Object) {
103 | req.body.data = true;
104 | req.body.code = '10000';
105 | req.body.message = '操作成功';
106 | req.body.success = true;
107 | return next();
108 | } else {
109 | return res.json({ code: '10001', message: result.message, success: false, data: result });
110 | }
111 | }
--------------------------------------------------------------------------------
/middlewares/favorite.js:
--------------------------------------------------------------------------------
1 | /*
2 | * @Author: 唐文雍
3 | * @Date: 2019-01-16 10:17:32
4 | * @Last Modified by: 唐文雍
5 | * @Last Modified time: 2019-01-16 10:17:32
6 | */
7 | const query = require('../utils/pool');
8 | const favorite = {};
9 | exports.favorite = favorite;
10 |
11 | // 收藏列表
12 | favorite.list = function(req, res, next) {
13 | var param = req.body;
14 | //分页实现
15 | var currentPage = 1; //默认为1
16 | var size = 10; //每页条数
17 | if (param.page) {
18 | currentPage = parseInt(param.page);
19 | }
20 | if (param.size) {
21 | size = parseInt(param.size);
22 | }
23 | //设置最后一页页码
24 | var lastPage = currentPage - 1;
25 | //假如目前仅有一页,则最后一页则为1
26 | if (currentPage <= 1) {
27 | lastPage = 1;
28 | }
29 | //如果需要下一页,则开启
30 | //var nextPage = currentPage + 1;
31 | var offset = (currentPage - 1) * size;
32 | // 类型
33 | var type = req.body.type || 1;
34 | // 类型
35 | var user_id = req.body.user_id;
36 |
37 | var sql = `SELECT COUNT(*) FROM favorite where type=${type} and user_id=${user_id};
38 | select tasks.id,tasks.money,tasks.title,tasks.thumbnail,favorite.created_at
39 | FROM favorite left join tasks on favorite.task_id=tasks.id
40 | where favorite.type=${type} and favorite.user_id=${user_id}
41 | order by favorite.created_at desc limit ${size} offset ${offset}`;
42 |
43 | console.info('查询收藏', sql);
44 | query(sql, (err, vals) => {
45 | if (!err && vals instanceof Array) {
46 | const totalCount = vals[0][0]['COUNT(*)'];
47 | const totalPage = Math.ceil(parseInt(totalCount) / size);
48 | req.body.data = {
49 | list: vals[1],
50 | size: size,
51 | page: currentPage,
52 | totalPage: totalPage,
53 | totalCount: totalCount,
54 | };
55 | req.body.code = '10000';
56 | req.body.message = '操作成功';
57 | req.body.success = true;
58 | return next();
59 | } else {
60 | return res.json({
61 | code: '10001',
62 | message: err,
63 | success: false,
64 | data: null,
65 | });
66 | }
67 | });
68 | };
69 |
70 | // 添加收藏
71 | favorite.add = function(req, res, next) {
72 | const type = req.body.type;
73 | const user_id = req.body.user_id;
74 | const task_id = req.body.task_id;
75 | const created_at = new Date().getTime();
76 | const sql = `insert into favorite(user_id,task_id,type,created_at)
77 | values(${user_id},
78 | ${task_id},
79 | ${type},
80 | '${created_at}')`;
81 | console.info('添加收藏', sql);
82 | query(sql, (err, vals) => {
83 | if (!err && vals instanceof Object) {
84 | req.body.data = vals.insertId;
85 | req.body.code = '10000';
86 | req.body.message = '操作成功';
87 | req.body.success = true;
88 | return next();
89 | } else {
90 | return res.json({
91 | code: '10001',
92 | message: err,
93 | success: false,
94 | data: null,
95 | });
96 | }
97 | });
98 | };
99 |
100 |
101 | // 添加收藏
102 | favorite.isFavorite = function(req, res, next) {
103 | const type = req.body.type;
104 | const user_id = req.body.user_id;
105 | const task_id = req.body.task_id;
106 | const sql = `select * from favorite where type=${type} and user_id=${user_id} and task_id=${task_id}`;
107 | console.info('是否已收藏', sql);
108 | query(sql, (err, vals) => {
109 | if (!err && vals instanceof Object) {
110 | req.body.data = !!vals.length;
111 | req.body.code = '10000';
112 | req.body.message = '操作成功';
113 | req.body.success = true;
114 | return next();
115 | } else {
116 | return res.json({
117 | code: '10001',
118 | message: err,
119 | success: false,
120 | data: null,
121 | });
122 | }
123 | });
124 | };
125 |
126 | // 删除收藏
127 | favorite.remove = function(req, res, next) {
128 | const type = req.body.type;
129 | const user_id = req.body.user_id;
130 | const task_id = req.body.task_id;
131 | const sql = `delete from favorite where type=${type} and user_id=${user_id} and task_id=${task_id}`;
132 | console.info('删除收藏', sql);
133 | query(sql, (err, vals) => {
134 | if (!err && vals instanceof Object) {
135 | req.body.data = true;
136 | req.body.code = '10000';
137 | req.body.message = '操作成功';
138 | req.body.success = true;
139 | return next();
140 | } else {
141 | return res.json({
142 | code: '10001',
143 | message: err,
144 | success: false,
145 | data: null,
146 | });
147 | }
148 | });
149 | };
--------------------------------------------------------------------------------
/middlewares/administrator.js:
--------------------------------------------------------------------------------
1 | /*
2 | * @Author: 唐文雍
3 | * @Date: 2019-01-16 10:17:32
4 | * @Last Modified by: 唐文雍
5 | * @Last Modified time: 2019-01-16 10:17:32
6 | */
7 | const query = require('../utils/pool');
8 | const administrator = {};
9 | exports.administrator = administrator;
10 |
11 | //后台管理》分页获取管理员列表
12 | administrator.list = function(req, res, next) {
13 | var param = req.body;
14 | //分页实现
15 | var currentPage = 1; //默认为1
16 | var size = 10; //每页条数
17 | if (param.page) {
18 | currentPage = parseInt(param.page);
19 | }
20 | if (param.size) {
21 | size = parseInt(param.size);
22 | }
23 | //设置最后一页页码
24 | var lastPage = currentPage - 1;
25 | //假如目前仅有一页,则最后一页则为1
26 | if (currentPage <= 1) {
27 | lastPage = 1;
28 | }
29 | //如果需要下一页,则开启
30 | //var nextPage = currentPage + 1;
31 | var offset = (currentPage - 1) * size;
32 | var sql = `SELECT COUNT(*) FROM administrators;
33 | select * FROM administrators where deleted=0
34 | order by created_at desc limit ${size} offset ${offset}`;
35 |
36 | console.info('查询管理员', sql);;
37 | query(sql, (err, vals) => {
38 | if (!err && vals instanceof Array) {
39 | const totalCount = vals[0][0]['COUNT(*)'];
40 | const totalPage = Math.ceil(parseInt(totalCount) / size);
41 | req.body.data = {
42 | list: vals[1],
43 | size: size,
44 | page: currentPage,
45 | totalPage: totalPage,
46 | totalCount: totalCount,
47 | };
48 | req.body.code = '10000';
49 | req.body.message = '操作成功';
50 | req.body.success = true;
51 | return next();
52 | } else {
53 | return res.json({
54 | code: '10001',
55 | message: err,
56 | success: false,
57 | data: null,
58 | });
59 | }
60 | });
61 | };
62 |
63 | // 添加管理员
64 | administrator.add = function(req, res, next) {
65 | const username = req.body.username;
66 | const password = req.body.password;
67 | const powers = req.body.powers instanceof Object ? JSON.stringify(req.body.powers) : '';
68 | const created_at = new Date().getTime();
69 | const updated_at = created_at;
70 | const sql = `insert into administrators(username,password,role,powers,created_at,updated_at) values("${username}","${password}",2,'${powers}',"${created_at}","${updated_at}")`;
71 | console.info("添加管理员", sql);
72 | query(sql, (err, vals) => {
73 | if (!err && vals instanceof Object) {
74 | req.body.data = vals.insertId;
75 | req.body.code = '10000';
76 | req.body.message = '操作成功';
77 | req.body.success = true;
78 | // 记录操作日志
79 | req.body.log = Object.assign(req.body.log || {}, {
80 | client: 1,
81 | content: `添加了ID为${vals.insertId}的管理员`,
82 | });
83 | return next();
84 | } else {
85 | return res.json({ code: '10001', message: err, success: false, data: null });
86 | }
87 | })
88 | }
89 |
90 | // 修改管理员
91 | administrator.update = function(req, res, next) {
92 | const username = req.body.username;
93 | const password = req.body.password;
94 | const powers = req.body.powers instanceof Object ? JSON.stringify(req.body.powers) : '';
95 | const id = req.body.id;
96 | const updated_at = new Date().getTime();
97 | const sql = `update administrators set powers='${powers}',username="${username}",password="${password}",updated_at="${updated_at}" where id=${id}`;
98 | console.info("修改管理员", sql);
99 | query(sql, (err, vals) => {
100 | if (!err && vals.affectedRows) {
101 | req.body.data = true;
102 | req.body.code = '10000';
103 | req.body.message = '操作成功';
104 | req.body.success = true;
105 | // 记录操作日志
106 | req.body.log = Object.assign(req.body.log || {}, {
107 | client: 1,
108 | content: `修改了ID为${id}的管理员`,
109 | });
110 | return next();
111 | } else {
112 | return res.json({ code: '10001', message: err, success: false, data: null });
113 | }
114 | })
115 | }
116 |
117 | // 删除管理员
118 | administrator.remove = function(req, res, next) {
119 | const id = req.body.id;
120 | const updated_at = new Date().getTime();
121 | const sql = `update administrators set deleted=1,updated_at="${updated_at}" where id=${id}`;
122 | console.info("更新用户信息", sql);
123 | query(sql, (err, vals) => {
124 | if (!err && vals instanceof Object) {
125 | req.body.data = true;
126 | req.body.code = '10000';
127 | req.body.message = '操作成功';
128 | req.body.success = true;
129 | // 记录操作日志
130 | req.body.log = Object.assign(req.body.log || {}, {
131 | client: 1,
132 | content: `删除了ID为${id}的管理员`,
133 | });
134 | return next();
135 | } else {
136 | return res.json({ code: '10001', message: err, success: false, data: null });
137 | }
138 | })
139 | }
--------------------------------------------------------------------------------
/middlewares/entries.js:
--------------------------------------------------------------------------------
1 | /*
2 | * @Author: 唐文雍
3 | * @Date: 2019-01-16 10:17:32
4 | * @Last Modified by: 唐文雍
5 | * @Last Modified time: 2019-01-16 10:17:32
6 | */
7 | const query = require('../utils/pool');
8 | const entries = {};
9 | exports.entries = entries;
10 |
11 | //获取菜单
12 | entries.get = function(req, res, next) {
13 | const client = req.body.client || '';
14 | const type = req.body.type || '';
15 | let condition = client ? `and client like '%${client}%'` : '';
16 | condition += type ? ` and type like '%${type}%'` : '';
17 | const sql = `SELECT * FROM entries where deleted=0 ${condition} order by sort desc`;
18 | console.info("查询菜单", sql);
19 | query(sql, (err, vals) => {
20 | if (!err && vals instanceof Array) {
21 | req.body.data = vals;
22 | req.body.code = '10000';
23 | req.body.message = '操作成功';
24 | req.body.success = true;
25 | return next();
26 | } else {
27 | return res.json({ code: '10001', message: err.code, success: false, data: null });
28 | }
29 | })
30 | }
31 | entries.add = function(req, res, next) {
32 | const sort = req.body.sort;
33 | const is_show = req.body.is_show;
34 | const name = req.body.name;
35 | const sub_name = req.body.sub_name;
36 | const url = req.body.url;
37 | const mpUrl = req.body.mpUrl;
38 | let client = req.body.client;
39 | client = client instanceof Array ? client.join(',') : client;
40 | let type = req.body.type;
41 | type = type instanceof Array ? type.join(',') : type;
42 | const icon = req.body.icon;
43 | const font_color = req.body.font_color;
44 | const createdAt = new Date().getTime();
45 | const sql = `insert into entries(type,is_show,client,icon,name,sub_name,url,mp_url,created_at,sort,font_color)
46 | values('${type}',${is_show},'${client}','${icon}','${name}','${sub_name}','${url}','${mpUrl}','${createdAt}',${sort},'${font_color}')`;
47 | console.info("新增菜单", sql);
48 | query(sql, (err, vals) => {
49 | if (!err && vals instanceof Object) {
50 | req.body.data = vals.insertId;
51 | req.body.code = '10000';
52 | req.body.message = '操作成功';
53 | req.body.success = true;
54 | // 记录操作日志
55 | req.body.log = Object.assign(req.body.log || {}, {
56 | client: 1,
57 | content: `添加了ID为${vals.insertId}的菜单`,
58 | });
59 | return next();
60 | } else {
61 | return res.json({ code: '10001', message: err.message, success: false, data: err });
62 | }
63 | })
64 | }
65 | entries.update = async function(req, res, next) {
66 | const id = req.body.id;
67 | const sort = req.body.sort;
68 | const is_show = req.body.is_show;
69 | const name = req.body.name;
70 | const sub_name = req.body.sub_name;
71 | const url = req.body.url;
72 | const mpUrl = req.body.mpUrl;
73 | let client = req.body.client;
74 | client = client instanceof Array ? client.join(',') : client;
75 | let type = req.body.type;
76 | type = type instanceof Array ? type.join(',') : type;
77 | const icon = req.body.icon;
78 | const font_color = req.body.font_color;
79 | const updated_at = new Date().getTime();
80 | const sql = `update entries set
81 | client=?,
82 | icon=?,
83 | name=?,
84 | sub_name=?,
85 | url=?,
86 | mp_url=?,
87 | updated_at=?,
88 | sort=?,
89 | is_show=?,
90 | type=?,
91 | font_color=?
92 | where id=?;`;
93 | const sqlValue = [client, icon, name, sub_name, url, mpUrl, updated_at, sort, is_show, type, font_color, id];
94 | const result = await query(sql, null, sqlValue, '更新菜单');
95 | if (!result.fail && result instanceof Object) {
96 | req.body.data = true;
97 | req.body.code = '10000';
98 | req.body.message = '操作成功';
99 | req.body.success = true;
100 | // 记录操作日志
101 | req.body.log = Object.assign(req.body.log || {}, {
102 | client: 1,
103 | content: `更新了ID为${id}的菜单`,
104 | });
105 | console.info(req.body);
106 | return next();
107 | } else {
108 | return res.json({ code: '10001', message: result.message, success: false, data: result });
109 | }
110 | }
111 | entries.remove = function(req, res, next) {
112 | const id = req.body.id || req.body.id;
113 | const updatedAt = new Date().getTime();
114 | const sql = `update entries set deleted=1,updated_at=${updatedAt} where id=${id}`;
115 | console.info("删除菜单", sql);
116 | query(sql, (err, vals) => {
117 | if (!err && vals instanceof Object) {
118 | req.body.data = true;
119 | req.body.code = '10000';
120 | req.body.message = '操作成功';
121 | req.body.success = true;
122 | // 记录操作日志
123 | req.body.log = Object.assign(req.body.log || {}, {
124 | client: 1,
125 | content: `删除了ID为${id}的菜单`,
126 | });
127 | return next();
128 | } else {
129 | return res.json({ code: '10001', message: err.code, success: false, data: null });
130 | }
131 | })
132 | }
--------------------------------------------------------------------------------
/app.js:
--------------------------------------------------------------------------------
1 | const createError = require('http-errors');
2 | const express = require('express');
3 | const path = require('path');
4 | const cookieParser = require('cookie-parser');
5 | const bodyParser = require('body-parser');
6 | const logger = require('morgan');
7 | const { validateData, isEmptyObject } = require('./utils/function');
8 | global.redis = require('redis');
9 | const config = require('./config/index');
10 | global.redisClient = redis.createClient({
11 | password: config.redis.password,
12 | host: config.redis.host,
13 | port: config.redis.port,
14 | prefix: config.redis.prefix,
15 | });
16 |
17 | // 定时任务
18 | require('./schedule/index');
19 |
20 | const indexRouter = require('./routes/index');
21 | const userRouter = require('./routes/user');
22 | const loginRouter = require('./routes/login');
23 | const registerRouter = require('./routes/register');
24 | const bannersRouter = require('./routes/banners');
25 | const tasksRouter = require('./routes/tasks');
26 | const uploadRouter = require('./routes/upload');
27 | const statisticsRouter = require('./routes/statistics');
28 | const withdrawRouter = require('./routes/withdraw');
29 | const administratorRouter = require('./routes/administrator');
30 | const systemRouter = require('./routes/system');
31 | const certificationsRouter = require('./routes/certifications');
32 | const orderRouter = require('./routes/order');
33 | const moneyRouter = require('./routes/money');
34 | const entriesRouter = require('./routes/entries');
35 | const updateRouter = require('./routes/update');
36 | const refreshRouter = require('./routes/refresh');
37 | const timesRouter = require('./routes/times');
38 | const smsRouter = require('./routes/sms');
39 | const favoriteRouter = require('./routes/favorite');
40 | const messagesRouter = require('./routes/messages');
41 | const signRouter = require('./routes/sign');
42 | const scoreRouter = require('./routes/score');
43 | const logRouter = require('./routes/log');
44 | const helpRouter = require('./routes/help');
45 | const goodsRouter = require('./routes/goods');
46 | const addressRouter = require('./routes/address');
47 |
48 | const app = express();
49 |
50 | // view engine setup
51 | app.set('views', path.join(__dirname, 'views'));
52 | app.set('view engine', 'ejs');
53 |
54 | app.use(logger('dev'));
55 | app.use(bodyParser.urlencoded({ limit: 1024 * 1024 * 1024, extended: true }));
56 | app.use(bodyParser.json());
57 | app.use(cookieParser());
58 | app.use(express.static(path.join(__dirname, 'public')));
59 |
60 | //设置跨域访问
61 | app.all('*', function(req, res, next) {
62 | res.header('Access-Control-Allow-Origin', '*');
63 | res.header('Access-Control-Allow-Headers', 'skey');
64 | res.header('Access-Control-Allow-Methods', 'PUT,POST,GET,DELETE,OPTIONS');
65 | res.header('X-Powered-By', ' 3.2.1');
66 | if (req.method.toLocaleLowerCase() === 'options'){
67 | res.status(204);
68 | return res.json({})
69 | }else {
70 | next();
71 | }
72 | });
73 |
74 | app.use(function(req, res, next) {
75 | if (req.method.toUpperCase() === 'POST') {
76 | const whiteList = [
77 | '/order/rechargeMoneyNotify',
78 | '/order/alipayRechargeNotify',
79 | '/order/yuwan',
80 | '/order/duoyou',
81 | '/order/xianwan'
82 | ];
83 | if (!whiteList.includes(req.url) && !isEmptyObject(req.body)) {
84 | if (!req.body.encryptedResult || !validateData(req.body)) {
85 | return res.json({ code: '10001', message: '非法请求', success: false, data: '' });
86 | }
87 | }
88 | }
89 | next();
90 | })
91 |
92 | app.use('/', indexRouter);
93 | app.use('/user', userRouter);
94 | app.use('/login', loginRouter);
95 | app.use('/register', registerRouter);
96 | app.use('/banners', bannersRouter);
97 | app.use('/tasks', tasksRouter);
98 | app.use('/upload', uploadRouter);
99 | app.use('/statistics', statisticsRouter);
100 | app.use('/withdraw', withdrawRouter);
101 | app.use('/administrator', administratorRouter);
102 | app.use('/system', systemRouter);
103 | app.use('/certifications', certificationsRouter);
104 | app.use('/order', orderRouter);
105 | app.use('/money', moneyRouter);
106 | app.use('/entries', entriesRouter);
107 | app.use('/update', updateRouter);
108 | app.use('/refresh', refreshRouter);
109 | app.use('/times', timesRouter);
110 | app.use('/sms', smsRouter);
111 | app.use('/favorite', favoriteRouter);
112 | app.use('/messages', messagesRouter);
113 | app.use('/sign', signRouter);
114 | app.use('/score', scoreRouter);
115 | app.use('/log', logRouter);
116 | app.use('/help', helpRouter);
117 | app.use('/goods', goodsRouter);
118 | app.use('/address', addressRouter);
119 |
120 | // catch 404 and forward to error handler
121 | app.use(function(req, res, next) {
122 | next(createError(404));
123 | });
124 |
125 | // error handler
126 | app.use(function(err, req, res, next) {
127 | // set locals, only providing error in development
128 | res.locals.message = err.message;
129 | res.locals.error = req.app.get('env') === 'development' ? err : {};
130 |
131 | // render the error page
132 | res.status(err.status || 500);
133 | res.render('error');
134 | });
135 |
136 | module.exports = app;
137 |
--------------------------------------------------------------------------------
/key/alipayRootCert.crt:
--------------------------------------------------------------------------------
1 | -----BEGIN CERTIFICATE-----
2 | MIIBszCCAVegAwIBAgIIaeL+wBcKxnswDAYIKoEcz1UBg3UFADAuMQswCQYDVQQG
3 | EwJDTjEOMAwGA1UECgwFTlJDQUMxDzANBgNVBAMMBlJPT1RDQTAeFw0xMjA3MTQw
4 | MzExNTlaFw00MjA3MDcwMzExNTlaMC4xCzAJBgNVBAYTAkNOMQ4wDAYDVQQKDAVO
5 | UkNBQzEPMA0GA1UEAwwGUk9PVENBMFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAE
6 | MPCca6pmgcchsTf2UnBeL9rtp4nw+itk1Kzrmbnqo05lUwkwlWK+4OIrtFdAqnRT
7 | V7Q9v1htkv42TsIutzd126NdMFswHwYDVR0jBBgwFoAUTDKxl9kzG8SmBcHG5Yti
8 | W/CXdlgwDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAQYwHQYDVR0OBBYEFEwysZfZ
9 | MxvEpgXBxuWLYlvwl3ZYMAwGCCqBHM9VAYN1BQADSAAwRQIgG1bSLeOXp3oB8H7b
10 | 53W+CKOPl2PknmWEq/lMhtn25HkCIQDaHDgWxWFtnCrBjH16/W3Ezn7/U/Vjo5xI
11 | pDoiVhsLwg==
12 | -----END CERTIFICATE-----
13 |
14 | -----BEGIN CERTIFICATE-----
15 | MIIF0zCCA7ugAwIBAgIIH8+hjWpIDREwDQYJKoZIhvcNAQELBQAwejELMAkGA1UE
16 | BhMCQ04xFjAUBgNVBAoMDUFudCBGaW5hbmNpYWwxIDAeBgNVBAsMF0NlcnRpZmlj
17 | YXRpb24gQXV0aG9yaXR5MTEwLwYDVQQDDChBbnQgRmluYW5jaWFsIENlcnRpZmlj
18 | YXRpb24gQXV0aG9yaXR5IFIxMB4XDTE4MDMyMTEzNDg0MFoXDTM4MDIyODEzNDg0
19 | MFowejELMAkGA1UEBhMCQ04xFjAUBgNVBAoMDUFudCBGaW5hbmNpYWwxIDAeBgNV
20 | BAsMF0NlcnRpZmljYXRpb24gQXV0aG9yaXR5MTEwLwYDVQQDDChBbnQgRmluYW5j
21 | aWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5IFIxMIICIjANBgkqhkiG9w0BAQEF
22 | AAOCAg8AMIICCgKCAgEAtytTRcBNuur5h8xuxnlKJetT65cHGemGi8oD+beHFPTk
23 | rUTlFt9Xn7fAVGo6QSsPb9uGLpUFGEdGmbsQ2q9cV4P89qkH04VzIPwT7AywJdt2
24 | xAvMs+MgHFJzOYfL1QkdOOVO7NwKxH8IvlQgFabWomWk2Ei9WfUyxFjVO1LVh0Bp
25 | dRBeWLMkdudx0tl3+21t1apnReFNQ5nfX29xeSxIhesaMHDZFViO/DXDNW2BcTs6
26 | vSWKyJ4YIIIzStumD8K1xMsoaZBMDxg4itjWFaKRgNuPiIn4kjDY3kC66Sl/6yTl
27 | YUz8AybbEsICZzssdZh7jcNb1VRfk79lgAprm/Ktl+mgrU1gaMGP1OE25JCbqli1
28 | Pbw/BpPynyP9+XulE+2mxFwTYhKAwpDIDKuYsFUXuo8t261pCovI1CXFzAQM2w7H
29 | DtA2nOXSW6q0jGDJ5+WauH+K8ZSvA6x4sFo4u0KNCx0ROTBpLif6GTngqo3sj+98
30 | SZiMNLFMQoQkjkdN5Q5g9N6CFZPVZ6QpO0JcIc7S1le/g9z5iBKnifrKxy0TQjtG
31 | PsDwc8ubPnRm/F82RReCoyNyx63indpgFfhN7+KxUIQ9cOwwTvemmor0A+ZQamRe
32 | 9LMuiEfEaWUDK+6O0Gl8lO571uI5onYdN1VIgOmwFbe+D8TcuzVjIZ/zvHrAGUcC
33 | AwEAAaNdMFswCwYDVR0PBAQDAgEGMAwGA1UdEwQFMAMBAf8wHQYDVR0OBBYEFF90
34 | tATATwda6uWx2yKjh0GynOEBMB8GA1UdIwQYMBaAFF90tATATwda6uWx2yKjh0Gy
35 | nOEBMA0GCSqGSIb3DQEBCwUAA4ICAQCVYaOtqOLIpsrEikE5lb+UARNSFJg6tpkf
36 | tJ2U8QF/DejemEHx5IClQu6ajxjtu0Aie4/3UnIXop8nH/Q57l+Wyt9T7N2WPiNq
37 | JSlYKYbJpPF8LXbuKYG3BTFTdOVFIeRe2NUyYh/xs6bXGr4WKTXb3qBmzR02FSy3
38 | IODQw5Q6zpXj8prYqFHYsOvGCEc1CwJaSaYwRhTkFedJUxiyhyB5GQwoFfExCVHW
39 | 05ZFCAVYFldCJvUzfzrWubN6wX0DD2dwultgmldOn/W/n8at52mpPNvIdbZb2F41
40 | T0YZeoWnCJrYXjq/32oc1cmifIHqySnyMnavi75DxPCdZsCOpSAT4j4lAQRGsfgI
41 | kkLPGQieMfNNkMCKh7qjwdXAVtdqhf0RVtFILH3OyEodlk1HYXqX5iE5wlaKzDop
42 | PKwf2Q3BErq1xChYGGVS+dEvyXc/2nIBlt7uLWKp4XFjqekKbaGaLJdjYP5b2s7N
43 | 1dM0MXQ/f8XoXKBkJNzEiM3hfsU6DOREgMc1DIsFKxfuMwX3EkVQM1If8ghb6x5Y
44 | jXayv+NLbidOSzk4vl5QwngO/JYFMkoc6i9LNwEaEtR9PhnrdubxmrtM+RjfBm02
45 | 77q3dSWFESFQ4QxYWew4pHE0DpWbWy/iMIKQ6UZ5RLvB8GEcgt8ON7BBJeMc+Dyi
46 | kT9qhqn+lw==
47 | -----END CERTIFICATE-----
48 |
49 | -----BEGIN CERTIFICATE-----
50 | MIICiDCCAgygAwIBAgIIQX76UsB/30owDAYIKoZIzj0EAwMFADB6MQswCQYDVQQG
51 | EwJDTjEWMBQGA1UECgwNQW50IEZpbmFuY2lhbDEgMB4GA1UECwwXQ2VydGlmaWNh
52 | dGlvbiBBdXRob3JpdHkxMTAvBgNVBAMMKEFudCBGaW5hbmNpYWwgQ2VydGlmaWNh
53 | dGlvbiBBdXRob3JpdHkgRTEwHhcNMTkwNDI4MTYyMDQ0WhcNNDkwNDIwMTYyMDQ0
54 | WjB6MQswCQYDVQQGEwJDTjEWMBQGA1UECgwNQW50IEZpbmFuY2lhbDEgMB4GA1UE
55 | CwwXQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxMTAvBgNVBAMMKEFudCBGaW5hbmNp
56 | YWwgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgRTEwdjAQBgcqhkjOPQIBBgUrgQQA
57 | IgNiAASCCRa94QI0vR5Up9Yr9HEupz6hSoyjySYqo7v837KnmjveUIUNiuC9pWAU
58 | WP3jwLX3HkzeiNdeg22a0IZPoSUCpasufiLAnfXh6NInLiWBrjLJXDSGaY7vaokt
59 | rpZvAdmjXTBbMAsGA1UdDwQEAwIBBjAMBgNVHRMEBTADAQH/MB0GA1UdDgQWBBRZ
60 | 4ZTgDpksHL2qcpkFkxD2zVd16TAfBgNVHSMEGDAWgBRZ4ZTgDpksHL2qcpkFkxD2
61 | zVd16TAMBggqhkjOPQQDAwUAA2gAMGUCMQD4IoqT2hTUn0jt7oXLdMJ8q4vLp6sg
62 | wHfPiOr9gxreb+e6Oidwd2LDnC4OUqCWiF8CMAzwKs4SnDJYcMLf2vpkbuVE4dTH
63 | Rglz+HGcTLWsFs4KxLsq7MuU+vJTBUeDJeDjdA==
64 | -----END CERTIFICATE-----
65 |
66 | -----BEGIN CERTIFICATE-----
67 | MIIDxTCCAq2gAwIBAgIUEMdk6dVgOEIS2cCP0Q43P90Ps5YwDQYJKoZIhvcNAQEF
68 | BQAwajELMAkGA1UEBhMCQ04xEzARBgNVBAoMCmlUcnVzQ2hpbmExHDAaBgNVBAsM
69 | E0NoaW5hIFRydXN0IE5ldHdvcmsxKDAmBgNVBAMMH2lUcnVzQ2hpbmEgQ2xhc3Mg
70 | MiBSb290IENBIC0gRzMwHhcNMTMwNDE4MDkzNjU2WhcNMzMwNDE4MDkzNjU2WjBq
71 | MQswCQYDVQQGEwJDTjETMBEGA1UECgwKaVRydXNDaGluYTEcMBoGA1UECwwTQ2hp
72 | bmEgVHJ1c3QgTmV0d29yazEoMCYGA1UEAwwfaVRydXNDaGluYSBDbGFzcyAyIFJv
73 | b3QgQ0EgLSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOPPShpV
74 | nJbMqqCw6Bz1kehnoPst9pkr0V9idOwU2oyS47/HjJXk9Rd5a9xfwkPO88trUpz5
75 | 4GmmwspDXjVFu9L0eFaRuH3KMha1Ak01citbF7cQLJlS7XI+tpkTGHEY5pt3EsQg
76 | wykfZl/A1jrnSkspMS997r2Gim54cwz+mTMgDRhZsKK/lbOeBPpWtcFizjXYCqhw
77 | WktvQfZBYi6o4sHCshnOswi4yV1p+LuFcQ2ciYdWvULh1eZhLxHbGXyznYHi0dGN
78 | z+I9H8aXxqAQfHVhbdHNzi77hCxFjOy+hHrGsyzjrd2swVQ2iUWP8BfEQqGLqM1g
79 | KgWKYfcTGdbPB1MCAwEAAaNjMGEwHQYDVR0OBBYEFG/oAMxTVe7y0+408CTAK8hA
80 | uTyRMB8GA1UdIwQYMBaAFG/oAMxTVe7y0+408CTAK8hAuTyRMA8GA1UdEwEB/wQF
81 | MAMBAf8wDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQBLnUTfW7hp
82 | emMbuUGCk7RBswzOT83bDM6824EkUnf+X0iKS95SUNGeeSWK2o/3ALJo5hi7GZr3
83 | U8eLaWAcYizfO99UXMRBPw5PRR+gXGEronGUugLpxsjuynoLQu8GQAeysSXKbN1I
84 | UugDo9u8igJORYA+5ms0s5sCUySqbQ2R5z/GoceyI9LdxIVa1RjVX8pYOj8JFwtn
85 | DJN3ftSFvNMYwRuILKuqUYSHc2GPYiHVflDh5nDymCMOQFcFG3WsEuB+EYQPFgIU
86 | 1DHmdZcz7Llx8UOZXX2JupWCYzK1XhJb+r4hK5ncf/w8qGtYlmyJpxk3hr1TfUJX
87 | Yf4Zr0fJsGuv
88 | -----END CERTIFICATE-----
--------------------------------------------------------------------------------
/middlewares/sign.js:
--------------------------------------------------------------------------------
1 | /*
2 | * @Author: 唐文雍
3 | * @Date: 2019-01-16 10:17:32
4 | * @Last Modified by: 唐文雍
5 | * @Last Modified time: 2019-01-16 10:17:32
6 | */
7 | const moment = require('moment');
8 | const query = require('../utils/pool');
9 | const sign = {};
10 | exports.sign = sign;
11 |
12 | // 获取签到规则列表
13 | sign.list = function(req, res, next) {
14 | const sql = `SELECT * FROM sign order by sort`;
15 | console.info("查询签到列表", sql);
16 | query(sql, (err, vals) => {
17 | if (!err && vals instanceof Array) {
18 | req.body.data = vals;
19 | req.body.code = '10000';
20 | req.body.message = '操作成功';
21 | req.body.success = true;
22 | return next();
23 | } else {
24 | return res.json({ code: '10001', message: err.message, success: false, data: err });
25 | }
26 | })
27 | }
28 |
29 | // 用户签到
30 | sign.do = async function(req, res, next) {
31 | const user_id = req.body.user_id;
32 | // 本次签到积分
33 | const sign_score = req.body.sign_score;
34 | // 签到id
35 | const sign_id = req.body.sign_id;
36 | // 上次签到次数
37 | let sign_count = req.body.sign_count;
38 | // 上次签到时间
39 | const now = new Date().getTime();
40 | const sign_at = req.body.sign_at; // 如果为null,则说明没签过到days < 1为false
41 |
42 | // 判断此用户今天是否已签到过
43 | const checkResult = await query(`select sign_at from users where id=${user_id}`);
44 | if (!checkResult.fail && checkResult instanceof Array) {
45 | if(!isNaN(checkResult[0].sign_at) && moment(new Date(+checkResult[0].sign_at)).isSame(moment(), 'day')) {
46 | return res.json({ code: '10001', message: '今天已签到,明天再来吧', success: false, data: '' });
47 | }
48 | }
49 |
50 | // 现在和上次签到时间相差的天数
51 | const start = moment(moment(new Date(+sign_at), 'YYYY-MM-DD')).set({
52 | hour: 0,
53 | minute: 0,
54 | second: 0,
55 | millisecond: 0,
56 | });
57 | const end = moment(moment(new Date(), 'YYYY-MM-DD'));
58 | const days = end.diff(start, 'days');
59 | console.info('距离上次签到天数', days);
60 | if (days < 1) {
61 | return res.json({ code: '10001', message: '今天已签到,明天再来吧', success: false, data: '' });
62 | }
63 | const sql = `begin;
64 | update users set
65 | ${days > 1 ? `sign_count=1` : `sign_count=sign_count+1`},
66 | sign_at='${now}',
67 | score=score+${sign_score} where id=${user_id};
68 | insert into score_stream(business_id,type,score,balance,user_id,is_income,created_at,remark)
69 | values(${sign_id},1,${sign_score},(select score from users where id=${user_id}),${user_id},1,'${now}','签到');
70 | commit;`;
71 | console.info("用户签到", sql);
72 | query(sql, (err, vals) => {
73 | if (!err && vals instanceof Array) {
74 | req.body = {
75 | data: {
76 | sign_at: now,
77 | sign_count: days > 1 ? 1 : (+sign_count + 1),
78 | },
79 | code: '10000',
80 | message: '操作成功',
81 | success: true,
82 | }
83 | return next();
84 | } else {
85 | return res.json({ code: '10001', message: err.message, success: false, data: err });
86 | }
87 | })
88 | }
89 |
90 | // 添加签到规则
91 | sign.add = function(req, res, next) {
92 | const sort = req.body.sort;
93 | const name = req.body.name;
94 | const score = req.body.score;
95 | const sql = `insert into sign(sort,name,score)
96 | values(${sort},'${name}',${score})`;
97 | console.info("新增签到规则", sql);
98 | query(sql, (err, vals) => {
99 | if (!err && vals instanceof Object) {
100 | req.body.data = vals.insertId;
101 | req.body.code = '10000';
102 | req.body.message = '操作成功';
103 | req.body.success = true;
104 | // 记录操作日志
105 | req.body.log = Object.assign(req.body.log || {}, {
106 | client: 1,
107 | content: `添加了ID为${vals.insertId}的签到规则`,
108 | });
109 | return next();
110 | } else {
111 | return res.json({ code: '10001', message: err.message, success: false, data: err });
112 | }
113 | })
114 | }
115 |
116 | // 更新签到规则
117 | sign.update = function(req, res, next) {
118 | const id = req.body.id;
119 | const sort = req.body.sort;
120 | const name = req.body.name;
121 | const score = req.body.score;
122 | const sql = `update sign set sort=${sort},name='${name}',score=${score} where id=${id}`;
123 | console.info("更新签到规则", sql);
124 | query(sql, (err, vals) => {
125 | if (!err && vals instanceof Object) {
126 | req.body.data = true;
127 | req.body.code = '10000';
128 | req.body.message = '操作成功';
129 | req.body.success = true;
130 | // 记录操作日志
131 | req.body.log = Object.assign(req.body.log || {}, {
132 | client: 1,
133 | content: `修改了ID为${id}的签到规则`,
134 | });
135 | return next();
136 | } else {
137 | return res.json({ code: '10001', message: err.message, success: false, data: message });
138 | }
139 | })
140 | }
141 |
142 | // 删除签到规则
143 | sign.remove = function(req, res, next) {
144 | const id = req.body.id;
145 | const sql = `delete from sign where id=${id}`;
146 | console.info("删除签到规则", sql);
147 | query(sql, (err, vals) => {
148 | if (!err && vals instanceof Object) {
149 | req.body.data = true;
150 | req.body.code = '10000';
151 | req.body.message = '操作成功';
152 | req.body.success = true;
153 | // 记录操作日志
154 | req.body.log = Object.assign(req.body.log || {}, {
155 | client: 1,
156 | content: `删除了ID为${id}的签到规则`,
157 | });
158 | return next();
159 | } else {
160 | return res.json({ code: '10001', message: err.message, success: false, data: message });
161 | }
162 | })
163 | }
--------------------------------------------------------------------------------
/routes/tasks.js:
--------------------------------------------------------------------------------
1 | const express = require('express');
2 | const router = express.Router();
3 | const { login } = require('../middlewares/login.js');
4 | const { log } = require('../middlewares/log.js');
5 | const { tasks } = require('../middlewares/tasks.js');
6 | const { money } = require('../middlewares/money.js');
7 | const { messages } = require('../middlewares/messages.js');
8 |
9 | // 获取任务,不返回下架的
10 | router.post('/', tasks.updateAutoend, tasks.getAll, function(req, res, next) {
11 | res.json(req.body);
12 | });
13 |
14 | // 获取任务,下架的也返回
15 | router.post('/admin', tasks.getAllUnlimited, function(req, res, next) {
16 | res.json(req.body);
17 | });
18 |
19 | // 抢任务
20 | router.post('/grab', login.check, tasks.isVip, tasks.detail, tasks.grab, function(req, res, next) {
21 | res.json(req.body);
22 | });
23 |
24 | // 查询单个任务,带判断是否已抢
25 | router.post('/detailForUser', tasks.updateTimeoutTask, tasks.getDetail, function(req, res, next) {
26 | res.json(req.body);
27 | });
28 |
29 | // 用户领取的任务详情(任务快照)
30 | router.post('/userTaskDetail', tasks.updateTimeoutTask, tasks.userTaskDetail, function(req, res, next) {
31 | res.json(req.body);
32 | });
33 |
34 | // 获取任务提交审核的步骤
35 | router.post('/getReviewStep', tasks.getReviewStep, function(req, res, next) {
36 | res.json(req.body);
37 | });
38 |
39 | // 获取任务提交审核的字段
40 | router.post('/getReviewField', tasks.getReviewField, function(req, res, next) {
41 | res.json(req.body);
42 | });
43 |
44 | // 获取任务审核列表
45 | router.post('/getReviewList', tasks.getReviewList, function(req, res, next) {
46 | res.json(req.body);
47 | });
48 |
49 | // 获取申诉列表
50 | router.post('/getAppealList', tasks.getAppealList, function(req, res, next) {
51 | res.json(req.body);
52 | });
53 |
54 | // 驳回审核请求
55 | router.post('/reviewReject', login.check, tasks.reviewReject, messages.add, log.add, function(req, res, next) {
56 | res.json(req.body);
57 | });
58 |
59 | // 删除提交的审核
60 | router.post('/reviewRemove', login.check, tasks.reviewRemove, log.add, function(req, res, next) {
61 | res.json(req.body);
62 | });
63 |
64 | // 通过审核请求
65 | router.post(
66 | '/reviewResolve',
67 | login.check,
68 | tasks.money,
69 | tasks.reviewResolve,
70 | messages.add,
71 | money.add,
72 | log.add,
73 | function(req, res, next) {
74 | res.json({
75 | data: true,
76 | code: '10000',
77 | message: '操作成功',
78 | success: true
79 | });
80 | }
81 | );
82 |
83 | // 获取当前任务审核列表
84 | router.post('/getTaskGrabList', tasks.getTaskGrabList, function(req, res, next) {
85 | res.json(req.body);
86 | });
87 |
88 | // 获取当前用户参与的任务
89 | router.post('/getUserTasks', login.check, tasks.getUserTasks, function(req, res, next) {
90 | res.json(req.body);
91 | });
92 |
93 | // 回收任务数量
94 | router.post('/updateTimeoutTask', login.check, tasks.updateTimeoutTask, function(req, res, next) {
95 | res.json(req.body);
96 | });
97 |
98 | // 处理审核超时的任务
99 | router.post('/updateReviewTimeoutTask',
100 | login.check,
101 | tasks.money,
102 | tasks.updateReviewTimeoutTask,
103 | money.add,
104 | function(req, res, next) {
105 | res.json({
106 | data: true,
107 | code: '10000',
108 | message: '操作成功',
109 | success: true
110 | });
111 | },
112 | );
113 |
114 |
115 | // 获取当前用户发布的任务
116 | router.post('/getUserPublishedTasks', login.check, tasks.getUserPublishedTasks, function(req, res, next) {
117 | res.json(req.body);
118 | });
119 |
120 | // 获取任务类型
121 | router.post('/getTypes', tasks.getTypes, function(req, res, next) {
122 | res.json(req.body);
123 | });
124 |
125 | // 用户提交任务审核
126 | router.post('/submitReview', login.check, tasks.submitReview, messages.add, function(req, res, next) {
127 | res.json({
128 | data: req.body.data,
129 | message: '操作成功',
130 | code: '10000',
131 | success: true
132 | });
133 | });
134 |
135 | // 用户提交申诉
136 | router.post('/addAppeal', login.check, tasks.addAppeal, function(req, res, next) {
137 | res.json(req.body);
138 | });
139 |
140 | // 申诉详情
141 | router.post('/getAppeal', login.check, tasks.getAppeal, function(req, res, next) {
142 | res.json(req.body);
143 | });
144 |
145 | // 更新申诉
146 | router.post('/updateAppeal', login.check, tasks.updateAppeal, log.add, function(req, res, next) {
147 | res.json(req.body);
148 | });
149 |
150 | // 用户修改任务审核
151 | router.post('/updateReview', login.check, tasks.updateReview, function(req, res, next) {
152 | res.json(req.body);
153 | });
154 |
155 | // 删除任务
156 | router.post('/remove', login.check, tasks.remove, log.add, function(req, res, next) {
157 | res.json(req.body);
158 | });
159 |
160 | // 管理员发布任务
161 | router.post('/adminAdd', login.check, tasks.add, log.add, function(req, res, next) {
162 | res.json(req.body);
163 | });
164 |
165 | // 用户发布任务
166 | router.post('/add', login.check, tasks.add, function(req, res, next) {
167 | res.json(req.body);
168 | });
169 |
170 | // 更新任务
171 | router.post('/update', login.check, tasks.update, log.add, function(req, res, next) {
172 | res.json(req.body);
173 | });
174 |
175 | // 根据ID获取审核的任务
176 | router.post('/getReviewDetail', tasks.getReviewDetail, function(req, res, next) {
177 | res.json(req.body);
178 | });
179 |
180 | // 根据ID获取审核详情,用户端审核
181 | router.post('/getReviewDetailForUser', tasks.getReviewDetailForUser, function(req, res, next) {
182 | res.json(req.body);
183 | });
184 |
185 | // 根据任务ID获取任务详情
186 | router.post('/getDetail', tasks.detail, function(req, res, next) {
187 | res.json(req.body);
188 | });
189 |
190 | // 修改任务状态
191 | router.post('/updateStatus', login.check, tasks.updateStatus, messages.add, log.add, function(req, res, next) {
192 | res.json(req.body);
193 | });
194 |
195 | // 删除分类
196 | router.post('/removeType', login.check, tasks.removeType, log.add, function(req, res, next) {
197 | res.json(req.body);
198 | });
199 |
200 | // 添加分类
201 | router.post('/addType', login.check, tasks.addType, log.add, function(req, res, next) {
202 | res.json(req.body);
203 | });
204 |
205 | // 更新分类
206 | router.post('/updateType', login.check, tasks.updateType, log.add, function(req, res, next) {
207 | res.json(req.body);
208 | });
209 |
210 | module.exports = router;
211 |
--------------------------------------------------------------------------------
/middlewares/money.js:
--------------------------------------------------------------------------------
1 | /*
2 | * @Author: 唐文雍
3 | * @Date: 2019-01-16 10:17:32
4 | * @Last Modified by: 唐文雍
5 | * @Last Modified time: 2019-01-16 10:17:32
6 | */
7 | const moment = require('moment');
8 | const query = require('../utils/pool');
9 | const money = {};
10 | exports.money = money;
11 |
12 | // 给用户加钱
13 | money.add = function(req, res, next) {
14 | const userId = req.body.userId || req.body.userId;
15 | let money = req.body.money || req.body.money || 0;
16 | money = +money;
17 |
18 | // 加钱类型,1充值;2提现;3收入;4支出
19 | const type = req.body.type;
20 | const remark = req.body.remark || '';
21 | const created_at = new Date().getTime();
22 | if (money < 0) {
23 | return res.json({ code: '10010', message: '金额不合法', success: false, data: money });
24 | }
25 | const sql = `begin;
26 | update users set account_amount=account_amount+${money} where id=${userId};
27 | insert into money_stream(type,money,balance,user_id,is_income,created_at,remark)
28 | values(${type},${money},(select account_amount from users where id=${userId}),${userId},1,'${created_at}','${remark}');
29 | commit;`
30 | console.info("加钱", sql);
31 | query(sql, (err, vals) => {
32 | console.info('加钱返回', vals)
33 | if (!err && vals instanceof Array) {
34 | req.body.data = true;
35 | req.body.code = '10000';
36 | req.body.message = '操作成功';
37 | req.body.success = true;
38 | return next();
39 | } else {
40 | return res.json({ code: '10001', message: err, success: false, data: err });
41 | }
42 | })
43 | }
44 | // 给用户减钱
45 | money.reduce = function(req, res, next) {
46 | const userId = req.body.userId || req.body.userId;
47 | let money = req.body.money || req.body.money || 0;
48 | money = +money;
49 | if (money < 0) {
50 | return res.json({ code: '10010', message: '金额不合法', success: false, data: money });
51 | }
52 | const remark = req.body.remark;
53 | const created_at = new Date().getTime();
54 | const sql = `begin;
55 | update users set account_amount=account_amount-${money},
56 | finished_amount=finished_amount+${money} where id=${userId};
57 | insert into money_stream(type,money,balance,user_id,is_income,created_at,remark)
58 | values(4,${money},(select account_amount from users where id=${userId}),${userId},0,"${created_at}","${remark || ''}");
59 | commit;`
60 | console.info("减钱", sql);
61 | query(sql, (err, vals) => {
62 | if (!err && vals instanceof Object) {
63 | req.body.data = true;
64 | req.body.code = '10000';
65 | req.body.message = '操作成功';
66 | req.body.success = true;
67 | // 记录操作日志
68 | req.body.log = Object.assign(req.body.log || {}, {
69 | client: 1,
70 | content: `给用户${userId}账户余额减去了${money}元`,
71 | });
72 | return next();
73 | } else {
74 | return res.json({ code: '10001', message: err.message, success: false, data: err });
75 | }
76 | })
77 | }
78 |
79 | // 获取用户金额流水
80 | money.stream = function(req, res, next) {
81 | var param = req.body;
82 | //分页实现
83 | var currentPage = 1; //默认为1
84 | var size = 10; //每页条数
85 | if (param.page) {
86 | currentPage = parseInt(param.page);
87 | }
88 | if (param.size) {
89 | size = parseInt(param.size);
90 | }
91 | //设置最后一页页码
92 | var lastPage = currentPage - 1;
93 | //假如目前仅有一页,则最后一页则为1
94 | if (currentPage <= 1) {
95 | lastPage = 1;
96 | }
97 | //如果需要下一页,则开启
98 | //var nextPage = currentPage + 1;
99 | var offset = (currentPage - 1) * size;
100 |
101 | const { type, userId, createDateRange } = param;
102 | let filters = [];
103 | type && filters.push(`type=${type}`);
104 | userId && filters.push(`user_id=${userId}`);
105 | createDateRange && createDateRange.length === 2 && filters.push(`created_at >= ${createDateRange[0]} and created_at <= ${createDateRange[1]}`);
106 | const filterString = filters.length ? `where ${filters.join(' and ')}` : '';
107 |
108 | var sql = `SELECT count(*) FROM money_stream ${filterString};
109 | select * FROM money_stream ${filterString}
110 | order by created_at desc limit ${size} offset ${offset}`;
111 |
112 | console.info('查询用户流水', sql);;
113 | query(sql, (err, vals) => {
114 | if (!err && vals instanceof Array) {
115 | const totalCount = vals[0][0]['count(*)'];
116 | const totalPage = Math.ceil(parseInt(totalCount) / size);
117 | req.body.data = {
118 | list: vals[1],
119 | size: size,
120 | page: currentPage,
121 | totalPage: totalPage,
122 | totalCount: totalCount,
123 | };
124 | req.body.code = '10000';
125 | req.body.message = '操作成功';
126 | req.body.success = true;
127 | return next();
128 | } else {
129 | return res.json({
130 | code: '10001',
131 | message: err.message,
132 | success: false,
133 | data: err,
134 | });
135 | }
136 | });
137 | }
138 |
139 | // 导出用户金额流水
140 | money.exportAll = async function(req, res, next) {
141 | const { type, userId, createDateRange } = req.body;
142 | const filters = [];
143 | type && filters.push(`type=${type}`);
144 | userId && filters.push(`user_id=${userId}`);
145 | createDateRange && createDateRange.length === 2 && filters.push(`created_at >= ${createDateRange[0]} and created_at <= ${createDateRange[1]}`);
146 | const filterString = filters.length ? `where ${filters.join(' and ')}` : '';
147 | const sql = `select * FROM money_stream ${filterString} order by created_at desc`;
148 | const result = await query(sql);
149 | if (!result.fail && result instanceof Array) {
150 | const exportConfig = {};
151 | exportConfig.cols = [
152 | {
153 | caption: 'id',
154 | type: 'number',
155 | }, {
156 | caption: '用户ID',
157 | type: 'number',
158 | }, {
159 | caption: '类型(1.充值;2.提现;3.收入;4.支出;)',
160 | type: 'number',
161 | }, {
162 | caption: '金额',
163 | type: 'number',
164 | }, {
165 | caption: '账户余额',
166 | type: 'number',
167 | }, {
168 | caption: '备注',
169 | type: 'string',
170 | }, {
171 | caption: '创建时间',
172 | type: 'string',
173 | },
174 | ];
175 | const temp = [];
176 | result.forEach((item) => {
177 | temp.push([
178 | item.id,
179 | item.user_id,
180 | item.type,
181 | item.money,
182 | item.balance,
183 | item.remark,
184 | item.created_at ? moment(+item.created_at).format('YYYY-MM-DD HH:mm:ss') : '',
185 | ]);
186 | });
187 | exportConfig.rows = temp;
188 | req.body.excelData = { exportConfig, prefix: '金额流水' };
189 | return next();
190 | } else {
191 | return res.json({ code: '10001', message: result.message, success: false, data: null });
192 | }
193 | };
--------------------------------------------------------------------------------
/middlewares/certifications.js:
--------------------------------------------------------------------------------
1 | /*
2 | * @Author: 唐文雍
3 | * @Date: 2019-01-16 10:17:32
4 | * @Last Modified by: 唐文雍
5 | * @Last Modified time: 2019-01-16 10:17:32
6 | */
7 | const query = require('../utils/pool');
8 | const certifications = {};
9 | exports.certifications = certifications;
10 |
11 | //获取认证列表
12 | certifications.get = async function(req, res, next) {
13 | var param = req.body;
14 | //分页实现
15 | var currentPage = 1; //默认为1
16 | var size = 10; //每页条数
17 | if (param.page) {
18 | currentPage = parseInt(param.page);
19 | }
20 | if (param.size) {
21 | size = parseInt(param.size);
22 | }
23 | //设置最后一页页码
24 | var lastPage = currentPage - 1;
25 | //假如目前仅有一页,则最后一页则为1
26 | if (currentPage <= 1) {
27 | lastPage = 1;
28 | }
29 | //如果需要下一页,则开启
30 | //var nextPage = currentPage + 1;
31 | var offset = (currentPage - 1) * size;
32 | const { createdAt, userId, truename, phone, status } = param;
33 | const filters = [];
34 | truename && filters.push(`truename like "%${truename}%"`);
35 | phone && filters.push(`phone like "%${phone}%"`);
36 | userId && filters.push(`user_id=${userId}`);
37 | [0,1,2,'0','1','2'].includes(status) && filters.push(`status=${status}`);
38 | createdAt && filters.push(`TO_DAYS(FROM_UNIXTIME(created_at/1000))=TO_DAYS(FROM_UNIXTIME(${new Date(createdAt).getTime()/1000}))`);
39 | const filterString = filters.length ? `where ${filters.join(' and ')}` : '';
40 | var sql = `SELECT count(*) FROM certifications ${filterString};
41 | SELECT * FROM certifications ${filterString}
42 | order by created_at desc limit ? offset ?`;
43 | const queryResult = await query(sql, null, [size, offset], '查询认证列表');
44 | if (!queryResult.fail && queryResult instanceof Array) {
45 | const totalCount = queryResult[0][0]['count(*)'];
46 | const totalPage = Math.ceil(parseInt(totalCount) / size);
47 | req.body.data = {
48 | list: queryResult[1],
49 | size: size,
50 | page: currentPage,
51 | totalPage: totalPage,
52 | totalCount: totalCount,
53 | };
54 | req.body.code = '10000';
55 | req.body.message = '操作成功';
56 | req.body.success = true;
57 | return next();
58 | } else {
59 | return res.json({ code: '10001', message: queryResult.message, success: false, data: null});
60 | }
61 | }
62 |
63 | // 获取认证详情
64 | certifications.detail = function(req, res, next) {
65 | const userId = req.body.userId;
66 | const sql = `SELECT * FROM certifications where user_id=${userId}`;
67 | console.info("获取认证详情", sql);
68 | query(sql, (err, vals) => {
69 | if (!err && vals instanceof Array) {
70 | req.body.data = vals[0];
71 | req.body.code = '10000';
72 | req.body.message = '操作成功';
73 | req.body.success = true;
74 | return next();
75 | } else {
76 | return res.json({ code: '10001', message: err.code, success: false, data: null });
77 | }
78 | })
79 | }
80 |
81 | // 用户提交认证资料
82 | certifications.add = async function(req, res, next) {
83 | const certificate = req.body.certificate;
84 | const wxpay_code = req.body.wxpay_code;
85 | const alipay_code = req.body.alipay_code;
86 | const userId = req.body.userId;
87 | const truename = req.body.truename;
88 | const phone = req.body.phone;
89 | const remark = req.body.remark;
90 | const idCard = req.body.idCard;
91 | const createdAt = new Date().getTime();
92 | const checkResult = await query(`select id from certifications where user_id=?`, null, [userId], '查询认证详情');
93 | if (!checkResult.fail && checkResult instanceof Array) {
94 | if (checkResult[0] && checkResult[0].id) {
95 | return res.json({ code: '10001', message: '请勿重复提交', success: false, data: null });
96 | }
97 | }
98 | const sql = `insert into certifications(certificate,wxpay_code,alipay_code,user_id,truename,phone,remark,status,created_at,id_card)
99 | values("${certificate}","${wxpay_code}","${alipay_code}",${userId},"${truename}","${phone}","${remark}",0,"${createdAt}","${idCard}")`;
100 | console.info("用户提交认证资料", sql);
101 | query(sql, (err, vals) => {
102 | if (!err && vals instanceof Object) {
103 | req.body.data = vals.insertId;
104 | req.body.code = '10000';
105 | req.body.message = '操作成功';
106 | req.body.success = true;
107 | // 设置消息内容
108 | req.body.message_add = {
109 | type: 1,
110 | user_id: 1,
111 | business_id: {certification_id: vals.insertId},
112 | title: '用户申请认证',
113 | content: `ID为${userId}的用户提交了认证资料给你审核,认证ID为${vals.insertId}`,
114 | }
115 | return next();
116 | } else {
117 | return res.json({ code: '10001', message: err, success: false, data: null });
118 | }
119 | })
120 | }
121 |
122 | // 管理员审核认证资料
123 | certifications.review = function(req, res, next) {
124 | const certificate = req.body.certificate;
125 | const wxpay_code = req.body.wxpay_code;
126 | const alipay_code = req.body.alipay_code;
127 | const userId = req.body.userId;
128 | const truename = req.body.truename;
129 | const phone = req.body.phone;
130 | const remark = req.body.remark;
131 | const result = req.body.result;
132 | const status = req.body.status;
133 | const idCard = req.body.idCard;
134 | const updatedAt = new Date().getTime();
135 | const reviewedAt = req.body.reviewedAt;
136 | const sql = `update certifications set
137 | certificate="${certificate}",
138 | wxpay_code="${wxpay_code}",
139 | alipay_code="${alipay_code}",
140 | truename="${truename}",
141 | phone="${phone}",
142 | remark="${remark}",
143 | status=${status},
144 | updated_at="${updatedAt}",
145 | reviewed_at="${reviewedAt}",
146 | result="${result || ''}",
147 | id_card="${idCard}"
148 | where user_id=${userId};
149 | update users set is_certified=${status == 1 ? 1 : 0} where id=${userId};`;
150 | console.info("用户更新认证资料", sql);
151 | query(sql, (err, vals) => {
152 | if (!err) {
153 | req.body.data = true;
154 | req.body.code = '10000';
155 | req.body.message = '操作成功';
156 | req.body.success = true;
157 | // 记录操作日志
158 | req.body.log = Object.assign(req.body.log || {}, {
159 | client: 1,
160 | content: `${status == 1 ? '通过' : '驳回'}了用户ID为${userId}的认证申请`,
161 | });
162 | return next();
163 | } else {
164 | return res.json({ code: '10001', message: err, success: false, data: null });
165 | }
166 | })
167 | }
168 |
169 | // 用户更新认证资料
170 | certifications.update = function(req, res, next) {
171 | const certificate = req.body.certificate;
172 | const wxpay_code = req.body.wxpay_code;
173 | const alipay_code = req.body.alipay_code;
174 | const userId = req.body.userId;
175 | const truename = req.body.truename;
176 | const phone = req.body.phone;
177 | const remark = req.body.remark;
178 | const idCard = req.body.idCard;
179 | const updatedAt = new Date().getTime();
180 | const sql = `update certifications set
181 | certificate="${certificate}",
182 | wxpay_code="${wxpay_code}",
183 | alipay_code="${alipay_code}",
184 | truename="${truename}",
185 | phone="${phone}",
186 | remark="${remark}",
187 | updated_at="${updatedAt}",
188 | reviewed_at="",
189 | id_card="${idCard}",
190 | status=0
191 | where user_id=${userId}`;
192 | console.info("用户更新认证资料", sql);
193 | query(sql, (err, vals) => {
194 | if (!err) {
195 | req.body.data = true;
196 | req.body.code = '10000';
197 | req.body.message = '操作成功';
198 | req.body.success = true;
199 | return next();
200 | } else {
201 | return res.json({ code: '10001', message: err, success: false, data: null });
202 | }
203 | })
204 | }
205 |
206 | // 删除用户认证资料
207 | certifications.remove = function(req, res, next) {
208 | const id = req.body.id;
209 | const userId = req.body.userId;
210 | const sql = `delete from certifications where id=${id};
211 | update users set is_certified=0 where id=${userId}`;
212 | console.info("删除用户认证资料", sql);
213 | query(sql, (err, vals) => {
214 | if (!err && vals instanceof Object) {
215 | req.body.data = true;
216 | req.body.code = '10000';
217 | req.body.message = '操作成功';
218 | req.body.success = true;
219 | // 记录操作日志
220 | req.body.log = Object.assign(req.body.log || {}, {
221 | client: 1,
222 | content: `删除了用户ID为${userId}的认证资料`,
223 | });
224 | return next();
225 | } else {
226 | return res.json({ code: '10001', message: err.code, success: false, data: null });
227 | }
228 | })
229 | }
--------------------------------------------------------------------------------
/middlewares/help.js:
--------------------------------------------------------------------------------
1 | /*
2 | * @Author: 唐文雍
3 | * @Date: 2019-01-16 10:17:32
4 | * @Last Modified by: 唐文雍
5 | * @Last Modified time: 2019-01-16 10:17:32
6 | */
7 | const query = require('../utils/pool');
8 | const help = {};
9 | exports.help = help;
10 |
11 | // 帮助文章列表
12 | help.list = async function(req, res, next) {
13 | var param = req.body;
14 | //分页实现
15 | var currentPage = 1; //默认为1
16 | var size = 10; //每页条数
17 | if (param.page) {
18 | currentPage = parseInt(param.page);
19 | }
20 | if (param.size) {
21 | size = parseInt(param.size);
22 | }
23 | //设置最后一页页码
24 | var lastPage = currentPage - 1;
25 | //假如目前仅有一页,则最后一页则为1
26 | if (currentPage <= 1) {
27 | lastPage = 1;
28 | }
29 | //如果需要下一页,则开启
30 | //var nextPage = currentPage + 1;
31 | var offset = (currentPage - 1) * size;
32 | const { type, title } = param;
33 | const filters = ['a.deleted=0'];
34 | title && filters.push(`a.title like "%${title}%"`);
35 | type && filters.push(`a.type=${type}`);
36 | const filterString = filters.length ? `where ${filters.join(' and ')}` : '';
37 | var sql = `SELECT count(*) FROM help_articles a ${filterString};
38 | SELECT a.id,a.title,a.type,t.name as type_name,a.created_at,a.updated_at FROM help_articles a
39 | left join help_type t on t.id=a.type ${filterString}
40 | order by a.created_at desc limit ? offset ?`;
41 | const queryResult = await query(sql, null, [size, offset], '查询帮助文章列表');
42 | if (!queryResult.fail && queryResult instanceof Array) {
43 | const totalCount = queryResult[0][0]['count(*)'];
44 | const totalPage = Math.ceil(parseInt(totalCount) / size);
45 | req.body.data = {
46 | list: queryResult[1],
47 | size: size,
48 | page: currentPage,
49 | totalPage: totalPage,
50 | totalCount: totalCount,
51 | };
52 | req.body.code = '10000';
53 | req.body.message = '操作成功';
54 | req.body.success = true;
55 | return next();
56 | } else {
57 | return res.json({ code: '10001', message: queryResult.message, success: false, data: null});
58 | }
59 | }
60 |
61 | // 帮助文章详情
62 | help.detail = async function(req, res, next) {
63 | const id = req.body.id;
64 | const sql = `select * from help_articles where id=${id}`;
65 | console.info('活动详情', sql);
66 | query(sql, (err, vals) => {
67 | if (!err && vals instanceof Object) {
68 | req.body.data = vals[0];
69 | req.body.code = '10000';
70 | req.body.message = '操作成功';
71 | req.body.success = true;
72 | return next();
73 | } else {
74 | return res.json({
75 | code: '10001',
76 | message: err,
77 | success: false,
78 | data: null,
79 | });
80 | }
81 | });
82 | };
83 |
84 | // 添加帮助文章
85 | help.add = async function(req, res, next) {
86 | const title = req.body.title;
87 | const content = req.body.content;
88 | const type = req.body.type;
89 | const createdAt = new Date().getTime();
90 | const sql = `insert into help_articles(type,title,content,created_at)
91 | values(?,?,?,?)`;
92 | const result = await query(sql, null, [type, title, content, createdAt], '新增帮助文章');
93 | if (!result.fail && result instanceof Object) {
94 | req.body.data = result.insertId;
95 | req.body.code = '10000';
96 | req.body.message = '操作成功';
97 | req.body.success = true;
98 | // 记录操作日志
99 | req.body.log = Object.assign(req.body.log || {}, {
100 | client: 1,
101 | content: `添加了ID为${result.insertId}的帮助文章`,
102 | });
103 | return next();
104 | } else {
105 | return res.json({ code: '10001', message: result.message, success: false, data: null });
106 | }
107 | }
108 |
109 | // 更新帮助文章
110 | help.update = async function(req, res, next) {
111 | const id = req.body.id;
112 | const title = req.body.title;
113 | const content = req.body.content;
114 | const type = req.body.type;
115 | const updated_at = new Date().getTime();
116 | const sql = `update help_articles set type=?,title=?,content=?,updated_at=? where id=?;`;
117 | const result = await query(sql, null, [type, title, content, updated_at, id], '更新帮助文章');
118 | if (!result.fail && result.affectedRows) {
119 | req.body.data = true;
120 | req.body.code = '10000';
121 | req.body.message = '操作成功';
122 | req.body.success = true;
123 | // 记录操作日志
124 | req.body.log = Object.assign(req.body.log || {}, {
125 | client: 1,
126 | content: `更新了ID为${id}的帮助文章`,
127 | });
128 | return next();
129 | } else {
130 | return res.json({ code: '10001', message: result.message, success: false, data: null });
131 | }
132 | }
133 |
134 | // 删除帮助文章
135 | help.remove = async function(req, res, next) {
136 | const id = req.body.id;
137 | const updated_at = new Date().getTime();
138 | const sql = `update help_articles set deleted=1,updated_at=? where id=?`;
139 | const result = await query(sql, null, [updated_at, id], '删除帮助文章');
140 | if (!result.fail && result.affectedRows) {
141 | req.body.data = true;
142 | req.body.code = '10000';
143 | req.body.message = '操作成功';
144 | req.body.success = true;
145 | // 记录操作日志
146 | req.body.log = Object.assign(req.body.log || {}, {
147 | client: 1,
148 | content: `删除了ID为${id}的帮助文章`,
149 | });
150 | return next();
151 | } else {
152 | return res.json({ code: '10001', message: result.message, success: false, data: null });
153 | }
154 | }
155 |
156 | // 分类列表
157 | help.typeList = async function(req, res, next) {
158 | const sql = `SELECT * FROM help_type order by created_at desc`;
159 | const result = await query(sql, null, null, '查询帮助文章分类');
160 | if (!result.fail && result instanceof Array) {
161 | req.body.data = result;
162 | req.body.code = '10000';
163 | req.body.message = '操作成功';
164 | req.body.success = true;
165 | return next();
166 | } else {
167 | return res.json({ code: '10001', message: '', success: false, data: 'err' });
168 | }
169 | }
170 |
171 | // 删除分类
172 | help.removeType = function(req, res, next) {
173 | const id = req.body.id;
174 | // 先查找是否有帮助文章在使用此分类
175 | const checkSql = `select count(*) from help_articles where type=${id} and deleted=0`;
176 | const sql = `delete from help_type where id=${id}`;
177 | console.info('删除帮助文章分类', sql);
178 | query(checkSql, (helpErr, helpVals) => {
179 | console.info('查询分类下的帮助文章数返回', helpVals);
180 | if (!helpErr && helpVals instanceof Array) {
181 | if (helpVals[0]['count(*)'] > 0) {
182 | return res.json({ code: '10001', message: '删除失败,有帮助文章在使用此分类', success: false, data: null });
183 | } else {
184 | query(sql, (err, vals) => {
185 | console.info('删除帮助文章分类返回', vals);
186 | if (!err && vals instanceof Object) {
187 | req.body.data = vals;
188 | req.body.code = '10000';
189 | req.body.message = '操作成功';
190 | req.body.success = true;
191 | // 记录操作日志
192 | req.body.log = Object.assign(req.body.log || {}, {
193 | client: 1,
194 | content: `删除了ID为${id}的帮助文章分类`,
195 | });
196 | return next();
197 | } else {
198 | return res.json({ code: '10001', message: err.code, success: false, data: null });
199 | }
200 | });
201 | }
202 | }
203 | });
204 |
205 | }
206 |
207 | // 添加分类
208 | help.addType = function(req, res, next) {
209 | const name = req.body.name;
210 | const created_at = new Date().getTime();
211 | const sql = `insert into help_type(name, created_at) values("${name}","${created_at}")`;
212 | console.info('添加分类', sql);
213 | query(sql, (err, vals) => {
214 | console.info('添加分类返回', vals, err);
215 | if (!err && vals instanceof Object) {
216 | req.body.data = vals.insertId;
217 | req.body.code = '10000';
218 | req.body.message = '操作成功';
219 | req.body.success = true;
220 | // 记录操作日志
221 | req.body.log = Object.assign(req.body.log || {}, {
222 | client: 1,
223 | content: `添加了ID为${vals.insertId}的帮助文章分类`,
224 | });
225 | return next();
226 | } else {
227 | return res.json({ code: '10001', message: err.code, success: false, data: null });
228 | }
229 | });
230 | }
231 |
232 | // 更新分类
233 | help.updateType = function(req, res, next) {
234 | const id = req.body.id;
235 | const name = req.body.name;
236 | const updated_at = new Date().getTime();
237 | const sql = `update help_type set name="${name}",updated_at="${updated_at}" where id=${id}`;
238 | console.info('更新帮助文章分类', sql);
239 | query(sql, (err, vals) => {
240 | console.info('更新帮助文章分类返回', vals, err);
241 | if (!err && vals instanceof Object) {
242 | req.body.data = vals;
243 | req.body.code = '10000';
244 | req.body.message = '操作成功';
245 | req.body.success = true;
246 | // 记录操作日志
247 | req.body.log = Object.assign(req.body.log || {}, {
248 | client: 1,
249 | content: `更新了ID为${id}的帮助文章分类`,
250 | });
251 | return next();
252 | } else {
253 | return res.json({ code: '10001', message: err.code, success: false, data: null });
254 | }
255 | });
256 | }
--------------------------------------------------------------------------------
/middlewares/refresh.js:
--------------------------------------------------------------------------------
1 | /*
2 | * @Author: 唐文雍
3 | * @Date: 2019-01-16 10:17:32
4 | * @Last Modified by: 唐文雍
5 | * @Last Modified time: 2019-01-16 10:17:32
6 | */
7 | const query = require('../utils/pool');
8 | const refresh = {};
9 | exports.refresh = refresh;
10 |
11 | // 获取价格表
12 | refresh.list = function(req, res, next) {
13 | var param = req.body;
14 | //分页实现
15 | var currentPage = 1; //默认为1
16 | var size = 10; //每页条数
17 | if (param.page) {
18 | currentPage = parseInt(param.page);
19 | }
20 | if (param.size) {
21 | size = parseInt(param.size);
22 | }
23 | //设置最后一页页码
24 | var lastPage = currentPage - 1;
25 | //假如目前仅有一页,则最后一页则为1
26 | if (currentPage <= 1) {
27 | lastPage = 1;
28 | }
29 | //如果需要下一页,则开启
30 | //var nextPage = currentPage + 1;
31 | var offset = (currentPage - 1) * size;
32 | var sql = `SELECT COUNT(*) FROM refresh_price where deleted=0;
33 | select * FROM refresh_price where deleted=0
34 | order by count desc limit ${size} offset ${offset}`;
35 |
36 | console.info('查询管理员', sql);;
37 | query(sql, (err, vals) => {
38 | if (!err && vals instanceof Array) {
39 | const totalCount = vals[0][0]['COUNT(*)'];
40 | const totalPage = Math.ceil(parseInt(totalCount) / size);
41 | req.body.data = {
42 | list: vals[1],
43 | size: size,
44 | page: currentPage,
45 | totalPage: totalPage,
46 | totalCount: totalCount,
47 | };
48 | req.body.code = '10000';
49 | req.body.message = '操作成功';
50 | req.body.success = true;
51 | return next();
52 | } else {
53 | return res.json({
54 | code: '10001',
55 | message: err,
56 | success: false,
57 | data: null,
58 | });
59 | }
60 | });
61 | };
62 |
63 | // 添加刷新价格
64 | refresh.add = function(req, res, next) {
65 | const original_price = req.body.original_price;
66 | const price = req.body.price;
67 | const count = req.body.count;
68 | const is_show = req.body.is_show;
69 | const created_at = new Date().getTime();
70 | const sql = `insert into refresh_price(original_price,price,count,is_show,created_at) values(${original_price},${price},${count},${is_show},"${created_at}")`;
71 | console.info("添加刷新价格", sql);
72 | query(sql, (err, vals) => {
73 | if (!err && vals instanceof Object) {
74 | req.body.data = vals.insertId;
75 | req.body.code = '10000';
76 | req.body.message = '操作成功';
77 | req.body.success = true;
78 | // 记录操作日志
79 | req.body.log = Object.assign(req.body.log || {}, {
80 | client: 1,
81 | content: `添加了ID为${vals.insertId}的刷新套餐`,
82 | });
83 | return next();
84 | } else {
85 | return res.json({ code: '10001', message: err, success: false, data: null });
86 | }
87 | })
88 | }
89 |
90 | // 修改刷新价格
91 | refresh.update = function(req, res, next) {
92 | const id = req.body.id;
93 | const original_price = req.body.original_price;
94 | const price = req.body.price;
95 | const count = req.body.count;
96 | const is_show = req.body.is_show;
97 | const updated_at = new Date().getTime();
98 | const sql = `update refresh_price set original_price=${original_price},price=${price},count=${count},is_show=${is_show},updated_at="${updated_at}" where id=${id}`;
99 | console.info("修改刷新价格", sql);
100 | query(sql, (err, vals) => {
101 | if (!err && vals.affectedRows) {
102 | req.body.data = true;
103 | req.body.code = '10000';
104 | req.body.message = '操作成功';
105 | req.body.success = true;
106 | // 记录操作日志
107 | req.body.log = Object.assign(req.body.log || {}, {
108 | client: 1,
109 | content: `修改了ID为${id}的刷新套餐`,
110 | });
111 | return next();
112 | } else {
113 | return res.json({ code: '10001', message: err, success: false, data: null });
114 | }
115 | })
116 | }
117 |
118 | // 删除刷新价格
119 | refresh.remove = function(req, res, next) {
120 | const id = req.body.id;
121 | const updated_at = new Date().getTime();
122 | const sql = `update refresh_price set deleted=1,updated_at="${updated_at}" where id=${id}`;
123 | console.info("删除刷新价格", sql);
124 | query(sql, (err, vals) => {
125 | if (!err && vals instanceof Object) {
126 | req.body.data = true;
127 | req.body.code = '10000';
128 | req.body.message = '操作成功';
129 | req.body.success = true;
130 | // 记录操作日志
131 | req.body.log = Object.assign(req.body.log || {}, {
132 | client: 1,
133 | content: `删除了ID为${id}的刷新套餐`,
134 | });
135 | return next();
136 | } else {
137 | return res.json({ code: '10001', message: err, success: false, data: null });
138 | }
139 | })
140 | }
141 |
142 | // 用户付费购买刷新次数
143 | refresh.buy = function(req, res, next) {
144 | const id = req.body.id;
145 | const user_id = req.body.user_id;
146 | const created_at = new Date().getTime();
147 | const sql = `begin;
148 | update users set refresh_count=refresh_count+(select count from refresh_price where id=${id}),
149 | account_amount=account_amount-(select price from refresh_price where id=${id}) where id=${user_id};
150 | insert into money_stream(type,money,balance,user_id,is_income,created_at,remark)
151 | values(4,(select price from refresh_price where id=${id}),(select account_amount from users where id=${user_id}),${user_id},0,"${created_at}","购买任务刷新次数");
152 | commit`;
153 | console.info("用户付费购买刷新次数", sql);
154 | query(sql, (err, vals) => {
155 | if (!err && vals instanceof Object) {
156 | req.body.data = true;
157 | req.body.code = '10000';
158 | req.body.message = '操作成功';
159 | req.body.success = true;
160 | return next();
161 | } else {
162 | return res.json({ code: '10001', message: err, success: false, data: null });
163 | }
164 | })
165 | }
166 |
167 | // 付费刷新
168 | refresh.do = function(req, res, next) {
169 | const id = req.body.id;
170 | const user_id = req.body.user_id;
171 | const sql = `begin;
172 | update tasks set sort=(
173 | select ub.newsort from (
174 | select (MAX(ua.sort)+1) newsort from tasks ua where ua.id=${id} and ua.created_by=${user_id}
175 | ) ub
176 | ) where id=${id} and created_by=${user_id} and (select refresh_count from users where id=${user_id}) > 0;
177 | update users set refresh_count=refresh_count-1 where id=${user_id} and refresh_count>0;
178 | commit`;
179 | console.info('付费刷新', sql);
180 | query(sql, (err, vals) => {
181 | console.info('付费刷新返回', vals, err);
182 | if (!err && vals instanceof Object) {
183 | req.body.data = true;
184 | req.body.code = '10000';
185 | req.body.message = '操作成功';
186 | req.body.success = true;
187 | return next();
188 | } else {
189 | return res.json({ code: '10001', message: err.code, success: false, data: null });
190 | }
191 | });
192 | }
193 |
194 | // 推荐上首页
195 | refresh.recommend = function(req, res, next) {
196 | const id = req.body.id;
197 | const user_id = req.body.user_id;
198 | const time = req.body.time;
199 | const money = req.body.money;
200 | if (money <= 0) {
201 | return res.json({ code: '10010', message: '金额不合法', success: false, data: money });
202 | }
203 | const now = new Date().getTime();
204 | const sql = `begin;
205 | update tasks set recommend=1,recommend_timeout="${time}"
206 | where id=${id}
207 | and (select account_amount from users where id=${user_id}) >= ${money};
208 | update users set account_amount=account_amount-${money} where id=${user_id} and account_amount>=${money};
209 | insert into money_stream(type,money,balance,user_id,is_income,created_at,remark)
210 | values(4,${money},(select account_amount from users where id=${user_id}),${user_id},0,"${now}","推荐任务上首页");
211 | commit`;
212 | console.info('推荐上首页', sql);
213 | query(sql, (err, vals) => {
214 | console.info('推荐上首页返回', vals, err);
215 | if (!err && vals instanceof Object) {
216 | req.body.data = true;
217 | req.body.code = '10000';
218 | req.body.message = '操作成功';
219 | req.body.success = true;
220 | return next();
221 | } else {
222 | return res.json({ code: '10001', message: err.code, success: false, data: null });
223 | }
224 | });
225 | }
226 |
227 | // 任务置顶
228 | refresh.top = function(req, res, next) {
229 | const id = req.body.id;
230 | const user_id = req.body.user_id;
231 | const time = req.body.time;
232 | const money = req.body.money;
233 | if (money <= 0) {
234 | return res.json({ code: '10010', message: '金额不合法', success: false, data: money });
235 | }
236 | const now = new Date().getTime();
237 | const sql = `begin;
238 | update tasks set top_timeout="${time}"
239 | where id=${id}
240 | and (select account_amount from users where id=${user_id}) >= ${money};
241 | update users set account_amount=account_amount-${money} where id=${user_id} and account_amount>=${money};
242 | insert into money_stream(type,money,balance,user_id,is_income,created_at,remark)
243 | values(4,${money},(select account_amount from users where id=${user_id}),${user_id},0,"${now}","任务置顶");
244 | commit`;
245 | console.info('任务置顶', sql);
246 | query(sql, (err, vals) => {
247 | console.info('任务置顶返回', vals, err);
248 | if (!err && vals instanceof Object) {
249 | req.body.data = true;
250 | req.body.code = '10000';
251 | req.body.message = '操作成功';
252 | req.body.success = true;
253 | return next();
254 | } else {
255 | return res.json({ code: '10001', message: err.code, success: false, data: null });
256 | }
257 | });
258 | }
--------------------------------------------------------------------------------
/utils/wepay.js:
--------------------------------------------------------------------------------
1 | var xmlreader = require('xmlreader');
2 | let xml2js = require('xml2js');
3 | let fs = require('fs');
4 | const request = require('request');
5 | const query = require('../utils/pool');
6 | const config = require('../config/index');
7 | const { userInfo } = require('os');
8 |
9 | var wepay = {
10 | // 把json转为xml
11 | json2Xml: function (json) {
12 | let _xml = '';
13 | Object.keys(json).map((key) => {
14 | _xml += `<${key}>${json[key]}${key}>`;
15 | });
16 | return `${_xml}`;
17 | },
18 | //把金额转为分
19 | getmoney: function (money) {
20 | return Math.floor(parseFloat(money) * 100);
21 | },
22 |
23 | // 随机字符串产生函数
24 | createNonceStr: function () {
25 | return Math.random().toString(36).substr(2, 15);
26 | },
27 |
28 | // 时间戳产生函数
29 | createTimeStamp: function () {
30 | return parseInt(new Date().getTime() / 1000) + '';
31 | },
32 |
33 | //签名加密算法
34 | paysignjsapi: function (
35 | appid,
36 | body,
37 | mch_id,
38 | nonce_str,
39 | notify_url,
40 | openid,
41 | out_trade_no,
42 | spbill_create_ip,
43 | total_fee,
44 | trade_type,
45 | mchkey,
46 | ) {
47 | var ret = {
48 | appid: appid,
49 | mch_id: mch_id,
50 | nonce_str: nonce_str,
51 | body: body,
52 | notify_url: notify_url,
53 | out_trade_no: out_trade_no,
54 | spbill_create_ip: spbill_create_ip,
55 | total_fee: total_fee,
56 | trade_type: trade_type,
57 | };
58 | if (openid) {
59 | ret.openid = openid;
60 | }
61 | console.log('ret==', ret);
62 | var string = raw(ret);
63 | var key = mchkey;
64 | string = string + '&key=' + key;
65 | console.log('string=', string);
66 | var crypto = require('crypto');
67 | return crypto
68 | .createHash('md5')
69 | .update(string, 'utf8')
70 | .digest('hex')
71 | .toUpperCase();
72 | },
73 | // 小程序签名
74 | paysignjsapimini: function (
75 | appId,
76 | nonceStr,
77 | package,
78 | signType,
79 | timestamp,
80 | mchkey,
81 | ) {
82 | var ret = {
83 | appId: appId,
84 | nonceStr: nonceStr,
85 | package: package,
86 | signType: signType,
87 | timeStamp: timestamp,
88 | };
89 | console.log('Miniret==', ret);
90 | var string = raw(ret);
91 | var key = mchkey;
92 | string = string + '&key=' + key;
93 | console.log('Ministring>>>>>>', string);
94 | var crypto = require('crypto');
95 | return crypto
96 | .createHash('md5')
97 | .update(string, 'utf8')
98 | .digest('hex')
99 | .toUpperCase();
100 | },
101 | // app签名
102 | paysignjsapiapp: function (
103 | appid,
104 | partnerid,
105 | prepayid,
106 | noncestr,
107 | timestamp,
108 | package,
109 | mchkey,
110 | ) {
111 | var ret = {
112 | appid: appid,
113 | partnerid: partnerid,
114 | prepayid: prepayid,
115 | noncestr: noncestr,
116 | timestamp: timestamp,
117 | package: package,
118 | };
119 | console.log('Miniret==', ret);
120 | var string = raw(ret);
121 | var key = mchkey;
122 | string = string + '&key=' + key;
123 | console.log('Ministring>>>>>>', string);
124 | var crypto = require('crypto');
125 | return crypto
126 | .createHash('md5')
127 | .update(string, 'utf8')
128 | .digest('hex')
129 | .toUpperCase();
130 | },
131 | getXMLNodeValue: function (xml) {
132 | xmlreader.read(xml, function (errors, response) {
133 | if (null !== errors) {
134 | console.log(errors);
135 | return;
136 | }
137 | console.log('长度===', response.xml.prepay_id.text().length);
138 | var prepay_id = response.xml.prepay_id.text();
139 | console.log('解析后的prepay_id==', prepay_id);
140 | return prepay_id;
141 | });
142 | },
143 | // 以下是企业付款到微信余额相关方法
144 | /*生成url串用于微信md5校验*/
145 | fnCreateUrlParam: function (json) {
146 | let _arr = [];
147 | for (let key in json) {
148 | _arr.push(key + '=' + json[key]);
149 | }
150 | return _arr.join('&');
151 | },
152 | /*生成付款xml参数数据*/
153 | fnGetWeixinBonus: function (option) {
154 | console.log('option===', option);
155 | let amount = option.amount || 100; //红包总金额
156 | let openid = option.openid; // '可以修改成你自己的openid,这样如果出错就会发送到你的账户上面了';//红包发送的目标用户
157 | let openid_type = option.openid_type;
158 | let now = new Date();
159 | let clientIp = option.clientIp; //ip地址
160 | let desc = option.wishing; //企业付款备注
161 | let mch_id = config.wechat.mchId; //商户号
162 | let mch_appid = ''; //appid
163 | switch (Number(openid_type)) {
164 | case 1:
165 | // 小程序
166 | mch_appid = config.wechat.appId;
167 | break;
168 | case 2:
169 | // 公众号
170 | mch_appid = config.wechat.officialAccount.appId;
171 | break;
172 | case 3:
173 | // APP
174 | mch_appid = config.wechat.open.appId;
175 | break;
176 | default:
177 | // 此配置是旧版本遗留
178 | mch_appid = config.wechat.mchAppId;
179 | break;
180 | }
181 | let wxkey = config.wechat.mchKey; //key为在微信商户平台(pay.weixin.qq.com)-->账户设置-->API安全-->密钥设置
182 | let date_time =
183 | now.getFullYear() + '' + (now.getMonth() + 1) + '' + now.getDate();
184 | let date_no = (now.getTime() + '').substr(-8); //生成8为日期数据,精确到毫秒
185 | let random_no = Math.floor(Math.random() * 99);
186 | if (random_no < 10) {
187 | //生成位数为2的随机码
188 | random_no = '0' + random_no;
189 | }
190 |
191 | let nonce_str = Math.random().toString(36).substr(2, 15); //生成随机字符串
192 | let partner_trade_no = mch_id + date_time + date_no + random_no; //生成商户订单号
193 |
194 | let contentJson = {};
195 | contentJson.amount = amount; // '100';
196 | contentJson.check_name = 'NO_CHECK'; // '强制验证名字';FORCE_CHECK
197 | contentJson.desc = desc; //'恭喜发财';
198 | contentJson.mch_appid = mch_appid; //商户appid
199 | contentJson.mchid = mch_id;
200 | contentJson.nonce_str = nonce_str;
201 | contentJson.openid = openid; // 'oovyt4u9yTamaCAxlZ-U2HjH-Z'; //墨色梧桐的openid // 'oovyt4u9yTamaCAxlZ-U2HjH-Z';
202 | contentJson.partner_trade_no = partner_trade_no; //订单号为 mch_id + yyyymmdd+10位一天内不能重复的数字; //+201502041234567893';
203 | contentJson.spbill_create_ip = clientIp; //IP地址
204 | contentJson.key = wxkey; //微信安全密钥
205 |
206 | /*生成url串用于微信md5校验*/
207 | let contentStr = wepay.fnCreateUrlParam(contentJson);
208 | console.log('content=' + contentStr);
209 | //生成签名
210 | let crypto = require('crypto');
211 | contentJson.sign = crypto
212 | .createHash('md5')
213 | .update(contentStr, 'utf8')
214 | .digest('hex')
215 | .toUpperCase();
216 |
217 | //删除 contentJson对象中的key (key不参与签名)
218 | delete contentJson.key;
219 | //生成xml函数
220 | let xmlData = wepay.json2Xml(contentJson);
221 | return xmlData;
222 | },
223 | //微信企业支付到零钱中间件
224 | wxcompay: async (req, res, next) => {
225 | let id = req.body.id; // 提现列表的ID
226 | let amount = req.body.money; //金额
227 | let openid = req.body.openid;
228 | let openid_type = req.body.openid_type;
229 | let user_id = req.body.userId;
230 | let wishing = req.body.wishing || `${id}:用户${user_id}提现到余额`; // 备注
231 | let clientIp =
232 | req.body.clientIp || req.ip.match(/\d+\.\d+\.\d+\.\d+/) || '127.0.0.1';
233 | const result = await query('select pay_to_wechat from system');
234 | if (result instanceof Object) {
235 | if (result[0].pay_to_wechat && openid) {
236 | if (!(user_id && amount)) {
237 | return res.json({ code: '10001', message: '参数不正确', success: false, data: null});
238 | }
239 | } else {
240 | return next();
241 | }
242 | }
243 | // 提现金额精确到角
244 | amount = Number(amount).toFixed(1);
245 | // 按微信要求转化成分
246 | amount = amount * 100;
247 | // 解决js浮点运算问题
248 | amount = amount.toFixed();
249 | let sendData = wepay.fnGetWeixinBonus({
250 | amount: Number(amount),
251 | openid,
252 | openid_type,
253 | wishing,
254 | clientIp,
255 | });
256 | let now = new Date().getTime();
257 | console.log('付款到余额sendData=====', sendData);
258 | //读取微信生成的证书用作加密
259 | let opt = {
260 | url:
261 | 'https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers',
262 | body: sendData,
263 | key: fs.readFileSync(`${process.cwd()}/key/apiclient_key.pem`), //将微信生成的证书放入 cert目录下
264 | cert: fs.readFileSync(`${process.cwd()}/key/apiclient_cert.pem`),
265 | };
266 | request.post(opt, function (err, response, body) {
267 | console.log('付款到余额err==', err);
268 | console.log('付款到余额body==', body);
269 | let parser = new xml2js.Parser({
270 | trim: true,
271 | explicitArray: false,
272 | explicitRoot: false,
273 | }); //解析签名结果xml转json
274 | parser.parseString(body, async (error, result) => {
275 | console.log('付款到余额res==', result);
276 | if (result && result.result_code == 'SUCCESS') {
277 | await query(`insert into orders(order_id,user_id,paid,money,created_at,direction)
278 | values('${result.partner_trade_no}',${user_id},1,${amount},'${now}',2)`);
279 | return next();
280 | } else {
281 | return res.json({
282 | code: '10016',
283 | message: result.err_code_des,
284 | success: false,
285 | data: result,
286 | });
287 | }
288 | });
289 | });
290 | },
291 | };
292 | function raw(args) {
293 | var keys = Object.keys(args);
294 | keys = keys.sort();
295 | var newArgs = {};
296 | keys.forEach(function(key) {
297 | newArgs[key] = args[key];
298 | });
299 | var string = '';
300 | for (var k in newArgs) {
301 | string += '&' + k + '=' + newArgs[k];
302 | }
303 | string = string.substr(1);
304 | return string;
305 | }
306 |
307 | module.exports = wepay;
308 |
--------------------------------------------------------------------------------
/middlewares/statistics.js:
--------------------------------------------------------------------------------
1 | /*
2 | * @Author: 唐文雍
3 | * @Date: 2019-01-16 10:17:32
4 | * @Last Modified by: 唐文雍
5 | * @Last Modified time: 2019-01-16 10:17:32
6 | */
7 | const query = require('../utils/pool');
8 | const statistics = {};
9 | exports.statistics = statistics;
10 |
11 | // 统计当前用户各个状态的任务数量
12 | statistics.getTaskCount = function(req, res, next) {
13 | console.info("统计当前用户各个状态的任务数量");
14 | // 用户ID查询条件
15 | const userId = req.body.userId;
16 | // 发布人ID查询条件
17 | const creatorId = req.body.creatorId;
18 | // 任务状态查询条件
19 | const taskStatus = req.body.taskStatus;
20 | const sql = `SELECT COUNT(*) FROM user_tasks where deleted=0 and ${creatorId?`created_by=${creatorId}`:`user_id=${userId}`}${taskStatus ? ` and status = ${taskStatus}` : ''};`
21 | query(sql, (err, vals) => {
22 | if (!err && vals instanceof Array) {
23 | console.info('统计当前用户各个状态的任务数量', vals)
24 | if (req.body.data instanceof Object) {
25 | req.body.data.taskCount = vals[0]['COUNT(*)']
26 | } else {
27 | req.body.data = {
28 | taskCount: vals[0]['COUNT(*)']
29 | }
30 | }
31 | req.body.code = '10000';
32 | req.body.message = '操作成功';
33 | req.body.success = true;
34 | return next();
35 | } else {
36 | return res.json({ code: '10001', message: err.code, success: false, data: null });
37 | }
38 | })
39 | }
40 | // 统计当前用户指定状态下任务的总金额
41 | statistics.getMoneyByTaskStatus = function(req, res, next) {
42 | console.info("统计当前用户指定状态下任务的总金额");
43 | // 用户ID查询条件
44 | const userId = req.body.userId;
45 | // 发布人ID查询条件
46 | const creatorId = req.body.creatorId;
47 | // 任务状态查询条件
48 | let taskStatus = req.body.taskStatus;
49 | taskStatus = taskStatus.split(',');
50 | let taskStatusSql = '';
51 | if (taskStatus.length > 1){
52 | // 如果是数组,即查询多个状态下的数据
53 | taskStatusSql = ' and (';
54 | taskStatus.map((item, index)=>{
55 | const isLastOne = index === taskStatus.length-1;
56 | taskStatusSql += `status = ${item} ${isLastOne ? '' : 'or '}`
57 | });
58 | taskStatusSql += ')';
59 | } else {
60 | // 只有一个元素的数组
61 | taskStatusSql = ` and status = ${taskStatus[0]}`;
62 | }
63 |
64 | const sql = `select sum(money)
65 | from user_tasks where
66 | ${creatorId?`created_by=${creatorId}`:`user_id=${userId}`} and deleted=0
67 | ${taskStatusSql}`
68 | console.info(sql);
69 | query(sql, (err, vals) => {
70 | if (!err && vals instanceof Array) {
71 | console.info('统计当前用户未完成任务的总金额', vals)
72 | if (req.body.data instanceof Object) {
73 | req.body.data.money = vals[0]['sum(money)']
74 | } else {
75 | req.body.data = {
76 | money: vals[0]['sum(money)']
77 | }
78 | }
79 | req.body.code = '10000';
80 | req.body.message = '操作成功';
81 | req.body.success = true;
82 | return next();
83 | } else {
84 | return res.json({ code: '10001', message: err.code, success: false, data: null });
85 | }
86 | })
87 | }
88 | // 统计当前用户金额数据
89 | statistics.getUserMoneyStatistics = function(req, res, next) {
90 | const userId = req.body.userId;
91 | const sql = `select sum(money) from money_stream where user_id=${userId} and type=1;
92 | select sum(money) from money_stream where user_id=${userId} and type=4;
93 | select sum(money) from money_stream where user_id=${userId} and type=3;
94 | select sum(money) from withdraw_money where status=2 and user_id=${userId};
95 | select sum(account_amount) from users where id=${userId};
96 | select sum(money) from money_stream where user_id=${userId} and type=3 and DATE_FORMAT(FROM_UNIXTIME(created_at/1000),'%Y-%m-%d') = DATE_FORMAT(NOW(),'%Y-%m-%d');
97 | select sum(money) from money_stream where user_id=${userId} and type=3 and DATEDIFF(now(), FROM_UNIXTIME(created_at/1000)) = 1;
98 | select sum(money) as totalTaskIncome from user_tasks where user_id=${userId} and status=3;
99 | select sum(money) as totalTaskExpend from user_tasks where created_by=${userId} and status=3;`
100 | query(sql, (err, vals, fields) => {
101 | if (!err && vals instanceof Array) {
102 | console.info('获取用户金额数据返回', vals);
103 | req.body.data = {
104 | taskTotalRechargeSum: +vals[0][0]['sum(money)'], // 总充值金额
105 | taskTotalPaySum: +vals[1][0]['sum(money)'], // 总发放佣金
106 | totalIncomeSum: +vals[2][0]['sum(money)'], // 总收入佣金
107 | withdrawTotalMoney: +vals[3][0]['sum(money)'], // 总提现金额
108 | userTotalMoney: +vals[4][0]['sum(account_amount)'], // 未提现总金额
109 | todayIncomeSum: +vals[5][0]['sum(money)'], // 今天收益
110 | yesterdayIncomeSum: +vals[6][0]['sum(money)'], // 昨天收益
111 | totalTaskIncome: +vals[7][0]['totalTaskIncome'], // 总获得的任务佣金
112 | totalTaskExpend: +vals[8][0]['totalTaskExpend'], // 总发放的任务佣金,不含服务费
113 | };
114 | req.body.code = '10000';
115 | req.body.message = '操作成功';
116 | req.body.success = true;
117 | return next();
118 | } else {
119 | console.info('获取用户金额数据出错', err);
120 | return res.json({ code: '10001', message: err.code, success: false, data: err });
121 | }
122 | })
123 | }
124 | // 获取任务完成最多的十个用户
125 | statistics.getUserRankList = function(req, res, next) {
126 | query( `select u.id,u.nick_name,u.avatar,u.username,count(t.task_id) as task_count
127 | from users u left join user_tasks t on t.user_id = u.id
128 | where t.status = 3 and t.deleted=0 group by u.id order by task_count desc limit 10`,
129 | (err, vals, fields) => {
130 | if (!err && vals instanceof Array) {
131 | req.body.data = vals;
132 | req.body.code = '10000';
133 | req.body.message = '操作成功';
134 | req.body.success = true;
135 | return next();
136 | } else {
137 | return res.json({ code: '10001', message: err.code, success: false, data: null });
138 | }
139 | })
140 | };
141 | // 获取邀请最多的十个用户
142 | statistics.getInviteRankList = function(req, res, next) {
143 | query( `select count(u.id) as count,u.inviter,s.avatar,s.username,s.nick_name from users u left join users s on s.id=u.inviter where u.inviter is not null GROUP BY u.inviter order by count desc limit 10`,
144 | (err, vals, fields) => {
145 | if (!err && vals instanceof Array) {
146 | req.body.data = vals;
147 | req.body.code = '10000';
148 | req.body.message = '操作成功';
149 | req.body.success = true;
150 | return next();
151 | } else {
152 | return res.json({ code: '10001', message: err.code, success: false, data: null });
153 | }
154 | })
155 | };
156 |
157 | // 获取后台仪表盘统计
158 | statistics.getDashboardData = function(req, res, next) {
159 | const sql = `select count(*) from user_reviews where status=1 and deleted=0 and task_creator in (select id from administrators);
160 | select count(*) from withdraw_money where status=1;
161 | select count(*) from users where DATE_FORMAT(FROM_UNIXTIME(created_at/1000),'%Y-%m-%d') = DATE_FORMAT(NOW(),'%Y-%m-%d');
162 | select count(*) from user_reviews where status=2 and deleted=0 and DATE_FORMAT(FROM_UNIXTIME(updated_at/1000),'%Y-%m-%d') = DATE_FORMAT(NOW(),'%Y-%m-%d');
163 | select sum(t.money) from user_reviews u left join user_tasks t on t.task_id = u.task_id where u.status=2 and u.deleted=0 and u.task_creator in (select id from administrators) and DATE_FORMAT(FROM_UNIXTIME(u.updated_at/1000),'%Y-%m-%d') = DATE_FORMAT(NOW(),'%Y-%m-%d');
164 | select count(*) from users where deleted=0;
165 | select count(*) from tasks where deleted=0;
166 | select sum(t.money) from user_reviews u left join user_tasks t on t.task_id = u.task_id where u.status=2 and u.deleted=0 and u.task_creator in (select id from administrators);
167 | select sum(money) from withdraw_money where status=2;
168 | select sum(account_amount) from users;
169 | select count(*) from user_tasks where status=3 and deleted=0;
170 | select count(*) from user_tasks where status=1 and deleted=0;
171 | select count(*) from user_tasks where status=2 and deleted=0;
172 | select count(*) from user_tasks where status=4 and deleted=0;
173 | select count(*) from user_tasks where status=5 and deleted=0;
174 | select count(*) from user_tasks where deleted=0;
175 | select count(*) from certifications where status=0;
176 | select count(*) from users where deleted=0 and is_vip=1;
177 | select sum(money) from money_stream where is_income=1;
178 | select count(*) from tasks where status=3 and deleted=0;
179 | select sum(service_price) from tasks where DATE_FORMAT(FROM_UNIXTIME(created_at/1000),'%Y-%m-%d') = DATE_FORMAT(NOW(),'%Y-%m-%d');
180 | select sum(account_amount+finished_amount+withdraw_amount) from users;
181 | select sum(money) from money_stream where is_income=0;
182 | select count(*) from users where is_certified=1;
183 | select sum(score) from users;`;
184 | query(sql, (err, vals, fields) => {
185 | if (!err && vals instanceof Array) {
186 | console.info('获取数据统计返回', vals);
187 | req.body.data = {
188 | taskTobeReviewCount: +vals[0][0]['count(*)'], // 任务待审核数
189 | withdrawTobeReviewCount: +vals[1][0]['count(*)'], // 提现待审核数
190 | todayNewUserCount: +vals[2][0]['count(*)'], // 今日新增用户数
191 | todayTaskFinishCount: +vals[3][0]['count(*)'], // 今日完成任务数
192 | todayTaskPaySum: +vals[4][0]['sum(t.money)'], // 官方今日发放佣金
193 | userTotalCount: +vals[5][0]['count(*)'], // 用户总数
194 | taskTotalCount: +vals[6][0]['count(*)'], // 任务总数
195 | taskTotalPaySum: +vals[7][0]['sum(t.money)'], // 官方总发放佣金
196 | withdrawTotalMoney: +vals[8][0]['sum(money)'], // 总提现金额
197 | userTotalMoney: +vals[9][0]['sum(account_amount)'], // 未提现总金额
198 | finishTaskTotalCount: +vals[10][0]['count(*)'], // 完成任务总数
199 | onGoingTaskCount: +vals[11][0]['count(*)'], // 进行中的任务总数
200 | onReviewingTaskCount: +vals[12][0]['count(*)'], // 审核中的任务总数
201 | expiredTaskCount: +vals[13][0]['count(*)'], // 过期的任务总数
202 | rejectTaskCount: +vals[14][0]['count(*)'], // 审核失败的任务总数
203 | grabTaskCount: +vals[15][0]['count(*)'], // 领取的任务总数
204 | certificationTobeReviewCount: +vals[16][0]['count(*)'], // 认证待审核数量
205 | vipUserTotalCount: +vals[17][0]['count(*)'], // 会员总数
206 | totalIncome: +vals[18][0]['sum(money)'], // 平台总收入
207 | onSellReviewCount: +vals[19][0]['count(*)'], // 待审核上架
208 | todayServicePrice: +vals[20][0]['sum(service_price)'], // 今日任务佣金
209 | totalMoney: +vals[21][0]['sum(account_amount+finished_amount+withdraw_amount)'], // 平台总金额(包括已提现,提现中,用户账户中)
210 | totalOutcome: +vals[22][0]['sum(money)'], // 平台总支出
211 | totalCertifiedUser: +vals[23][0]['count(*)'], // 总实名认证人数
212 | totalUserScore: +vals[24][0]['sum(score)'], // 平台总积分
213 | };
214 | req.body.code = '10000';
215 | req.body.message = '操作成功';
216 | req.body.success = true;
217 | return next();
218 | } else {
219 | console.info('获取数据统计出错', err);
220 | return res.json({ code: '10001', message: err.code, success: false, data: err });
221 | }
222 | })
223 | }
--------------------------------------------------------------------------------
/middlewares/messages.js:
--------------------------------------------------------------------------------
1 | /*
2 | * @Author: 唐文雍
3 | * @Date: 2019-01-16 10:17:32
4 | * @Last Modified by: 唐文雍
5 | * @Last Modified time: 2019-01-16 10:17:32
6 | */
7 | const query = require('../utils/pool');
8 | const messages = {};
9 | exports.messages = messages;
10 |
11 | // 获取公告
12 | messages.getNoticeList = function(req, res, next) {
13 | var param = req.body;
14 | //分页实现
15 | var currentPage = 1; //默认为1
16 | var size = 10; //每页条数
17 | if (param.page) {
18 | currentPage = parseInt(param.page);
19 | }
20 | if (param.size) {
21 | size = parseInt(param.size);
22 | }
23 | //设置最后一页页码
24 | var lastPage = currentPage - 1;
25 | //假如目前仅有一页,则最后一页则为1
26 | if (currentPage <= 1) {
27 | lastPage = 1;
28 | }
29 | //如果需要下一页,则开启
30 | //var nextPage = currentPage + 1;
31 | // 分类
32 | var offset = (currentPage - 1) * size;
33 | var sql = `SELECT count(*) FROM messages where deleted=0 and type=7;
34 | select * FROM messages where deleted=0 and type=7 order by created_at desc limit ${size} offset ${offset}`;
35 | console.info('获取公告列表', sql);
36 | query(sql, (err, vals) => {
37 | if (!err && vals instanceof Array) {
38 | const totalCount = vals[0][0]['count(*)'];
39 | const totalPage = Math.ceil(parseInt(totalCount) / size);
40 | req.body.data = {
41 | list: vals[1],
42 | size: size,
43 | page: currentPage,
44 | totalPage: totalPage,
45 | totalCount: totalCount,
46 | };
47 | req.body.code = '10000';
48 | req.body.message = '操作成功';
49 | req.body.success = true;
50 | return next();
51 | } else {
52 | return res.json({
53 | code: '10001',
54 | message: err.message,
55 | success: false,
56 | data: err,
57 | });
58 | }
59 | });
60 | }
61 |
62 | // 获取动态
63 | messages.getDynamicList = function(req, res, next) {
64 | var param = req.body;
65 | //分页实现
66 | var currentPage = 1; //默认为1
67 | var size = 10; //每页条数
68 | if (param.page) {
69 | currentPage = parseInt(param.page);
70 | }
71 | if (param.size) {
72 | size = parseInt(param.size);
73 | }
74 | //设置最后一页页码
75 | var lastPage = currentPage - 1;
76 | //假如目前仅有一页,则最后一页则为1
77 | if (currentPage <= 1) {
78 | lastPage = 1;
79 | }
80 | //如果需要下一页,则开启
81 | //var nextPage = currentPage + 1;
82 | // 分类
83 | var offset = (currentPage - 1) * size;
84 | var sql = `SELECT count(*) FROM messages where deleted=0 and type=8;
85 | select * FROM messages where deleted=0 and type=8 order by created_at desc limit ${size} offset ${offset}`;
86 | console.info('获取动态列表', sql);
87 | query(sql, (err, vals) => {
88 | if (!err && vals instanceof Array) {
89 | const totalCount = vals[0][0]['count(*)'];
90 | const totalPage = Math.ceil(parseInt(totalCount) / size);
91 | req.body.data = {
92 | list: vals[1],
93 | size: size,
94 | page: currentPage,
95 | totalPage: totalPage,
96 | totalCount: totalCount,
97 | };
98 | req.body.code = '10000';
99 | req.body.message = '操作成功';
100 | req.body.success = true;
101 | return next();
102 | } else {
103 | return res.json({
104 | code: '10001',
105 | message: err.message,
106 | success: false,
107 | data: err,
108 | });
109 | }
110 | });
111 | }
112 |
113 | // 获取消息
114 | messages.list = function(req, res, next) {
115 | var param = req.body;
116 | //分页实现
117 | var currentPage = 1; //默认为1
118 | var size = 10; //每页条数
119 | if (param.page) {
120 | currentPage = parseInt(param.page);
121 | }
122 | if (param.size) {
123 | size = parseInt(param.size);
124 | }
125 | //设置最后一页页码
126 | var lastPage = currentPage - 1;
127 | //假如目前仅有一页,则最后一页则为1
128 | if (currentPage <= 1) {
129 | lastPage = 1;
130 | }
131 | //如果需要下一页,则开启
132 | //var nextPage = currentPage + 1;
133 | // 分类
134 | const userId = param.userId;
135 | var offset = (currentPage - 1) * size;
136 | var sql = `SELECT COUNT(*) FROM messages where deleted=0 and user_id in (0, ${userId}) and type!=8;
137 | select m.id,m.type,m.business_id,m.title,m.content,m.created_at,s.is_read FROM messages as m
138 | left join (select message_id,is_read from messages_state group by message_id,is_read) as s
139 | on m.id=s.message_id
140 | where m.deleted=0 and m.user_id in (0, ${userId}) and type!=8
141 | order by m.created_at desc
142 | limit ${size} offset ${offset}`;
143 | console.info('获取消息列表', sql);
144 | query(sql, (err, vals) => {
145 | if (!err && vals instanceof Array) {
146 | const totalCount = vals[0][0]['COUNT(*)'];
147 | const totalPage = Math.ceil(parseInt(totalCount) / size);
148 | req.body.data = {
149 | list: vals[1],
150 | size: size,
151 | page: currentPage,
152 | totalPage: totalPage,
153 | totalCount: totalCount,
154 | };
155 | req.body.code = '10000';
156 | req.body.message = '操作成功';
157 | req.body.success = true;
158 | return next();
159 | } else {
160 | return res.json({
161 | code: '10001',
162 | message: err.message,
163 | success: false,
164 | data: err,
165 | });
166 | }
167 | });
168 | }
169 | // 获取未读消息数
170 | messages.unreadCount = async function(req, res, next) {
171 | const user_id = req.body.userId;
172 | const sql = `SELECT COUNT(*) as message_count FROM messages where deleted=0 and user_id in (0, ?) and type!=8;
173 | SELECT COUNT(*) as read_count FROM messages_state where user_id in (0, ?);`;
174 | const result = await query(sql, null, [+user_id, +user_id], '获取未读消息数');
175 | if (!result.fail && result instanceof Array) {
176 | req.body.data = result[0][0]['message_count']-result[1][0]['read_count'];
177 | req.body.code = '10000';
178 | req.body.message = '操作成功';
179 | req.body.success = true;
180 | return next();
181 | } else {
182 | return res.json({ code: '10001', message: '', success: false, data: 'err' });
183 | }
184 | }
185 | // 添加公告
186 | messages.addNotice = async function(req, res, next) {
187 | const title = req.body.title;
188 | const content = req.body.content;
189 | const created_at = new Date().getTime();
190 | const sql = `insert into messages(type,title,content,created_at)
191 | values(?,?,?,?)`;
192 | const result = await query(sql, null, [7, title, content, created_at], '添加公告');
193 | if (!result.fail && result instanceof Object) {
194 | req.body.data = true;
195 | req.body.code = '10000';
196 | req.body.message = '操作成功';
197 | req.body.success = true;
198 | // 记录操作日志
199 | req.body.log = Object.assign(req.body.log || {}, {
200 | client: 1,
201 | content: `添加了ID为${result.insertId}的公告`,
202 | });
203 | return next();
204 | } else {
205 | return res.json({
206 | code: '10001',
207 | message: '添加公告失败',
208 | success: false,
209 | data: result.message,
210 | });
211 | }
212 | }
213 | // 添加消息
214 | messages.add = function(req, res, next) {
215 | if (!(req.body.message_add instanceof Object)) {
216 | return next();
217 | }
218 | const type = req.body.message_add.type;
219 | const user_id = req.body.message_add.user_id;
220 | // 业务id,是个json,主要用于页面跳转,如:
221 | // {
222 | // task_id: '',
223 | // user_id: '',
224 | // review_id: '',
225 | // user_task: '',
226 | // withdraw_id: '',
227 | // }
228 | const business_id = req.body.message_add.business_id instanceof Object ? JSON.stringify(req.body.message_add.business_id) : req.body.message_add.business_id;
229 | const title = req.body.message_add.title;
230 | const content = req.body.message_add.content;
231 | const created_at = new Date().getTime();
232 | const sql = `insert into messages(type,user_id,title,content,business_id,created_at)
233 | values(${type},${user_id},'${title}','${content}','${business_id}','${created_at}')`;
234 | console.info("新增消息", sql);
235 | query(sql, () => {
236 | delete req.body.message_add;
237 | return next();
238 | })
239 | }
240 | // 修改公告
241 | messages.updateNotice = async function(req, res, next) {
242 | const id = req.body.id;
243 | const title = req.body.title;
244 | const content = req.body.content;
245 | const updated_at = new Date().getTime();
246 | const sql = `update messages set title=?,content=?,updated_at=? where id=?`;
247 | const result = await query(sql, null, [title, content, updated_at, id], '修改公告');
248 | if (!result.fail && result instanceof Object) {
249 | req.body.data = true;
250 | req.body.code = '10000';
251 | req.body.message = '操作成功';
252 | req.body.success = true;
253 | // 记录操作日志
254 | req.body.log = Object.assign(req.body.log || {}, {
255 | client: 1,
256 | content: `修改了ID为${id}的公告`,
257 | });
258 | return next();
259 | } else {
260 | return res.json({
261 | code: '10001',
262 | message: '修改公告失败',
263 | success: false,
264 | data: result.message,
265 | });
266 | }
267 | }
268 | // 公告详情
269 | messages.getNoticeDetail = async function(req, res, next) {
270 | const id = req.body.id;
271 | const sql = `select * from messages where id=${id} and deleted=0`;
272 | console.info("获取公告详情", sql);
273 | query(sql, (err, vals) => {
274 | if (!err && vals instanceof Object) {
275 | req.body.data = vals[0];
276 | req.body.code = '10000';
277 | req.body.message = '操作成功';
278 | req.body.success = true;
279 | return next();
280 | } else {
281 | return res.json({ code: '10001', message: err.message, success: false, data: err });
282 | }
283 | })
284 | }
285 | // 获取消息详情
286 | messages.detail = function(req, res, next) {
287 | const id = req.body.id;
288 | const user_id = req.body.user_id;
289 | const sql = `select * from messages where id=${id} and deleted=0 and user_id in (0, ${user_id});`;
290 | console.info("获取消息详情", sql);
291 | query(sql, (err, vals) => {
292 | if (!err && vals instanceof Object) {
293 | req.body.data = vals[0];
294 | req.body.code = '10000';
295 | req.body.message = '操作成功';
296 | req.body.success = true;
297 | return next();
298 | } else {
299 | return res.json({ code: '10001', message: err.message, success: false, data: err });
300 | }
301 | })
302 | }
303 | // 设为已读
304 | messages.read = function(req, res, next) {
305 | const id = req.body.id;
306 | const user_id = req.body.user_id;
307 | const created_at = new Date().getTime();
308 | const sql = `insert into messages_state(message_id,is_read,user_id,created_at) values(${id},1,${user_id},${created_at})`;
309 | console.info("设为已读", sql);
310 | query(sql, (err, vals) => {
311 | if (!err && vals instanceof Object) {
312 | req.body.data = true;
313 | req.body.code = '10000';
314 | req.body.message = '操作成功';
315 | req.body.success = true;
316 | return next();
317 | } else {
318 | return res.json({ code: '10001', message: err.message, success: false, data: err });
319 | }
320 | })
321 | }
322 | // 删除消息
323 | messages.remove = function(req, res, next) {
324 | const id = req.body.id;
325 | const updated_at = new Date().getTime();
326 | const sql = `update messages set deleted=1,updated_at='${updated_at}' where id=${id};`;
327 | console.info("删除消息", sql);
328 | query(sql, (err, vals) => {
329 | if (!err && vals instanceof Object) {
330 | req.body.data = true;
331 | req.body.code = '10000';
332 | req.body.message = '操作成功';
333 | req.body.success = true;
334 | return next();
335 | } else {
336 | return res.json({ code: '10001', message: err.message, success: false, data: err });
337 | }
338 | })
339 | }
--------------------------------------------------------------------------------
/middlewares/system.js:
--------------------------------------------------------------------------------
1 | /*
2 | * @Author: 唐文雍
3 | * @Date: 2019-01-16 10:17:32
4 | * @Last Modified by: 唐文雍
5 | * @Last Modified time: 2019-01-16 10:17:32
6 | */
7 | const query = require('../utils/pool');
8 | const system = {};
9 | exports.system = system;
10 |
11 | // 获取系统配置
12 | system.get = function(req, res, next) {
13 | const sql = "SELECT * FROM `system`";
14 | console.info("查询系统配置", sql);
15 | query(sql, (err, vals) => {
16 | if (!err && vals instanceof Array) {
17 | req.body.data = Object.assign(vals[0], req.body.data);
18 | req.body.code = '10000';
19 | req.body.message = '操作成功';
20 | req.body.success = true;
21 | return next();
22 | } else {
23 | return res.json({ code: '10001', message: err.code, success: false, data: null });
24 | }
25 | })
26 | }
27 | // 更新系统配置
28 | system.update = function(req, res, next) {
29 | const program_name = req.body.program_name;
30 | const show_certification = req.body.show_certification;
31 | const show_vip = req.body.show_vip;
32 | const show_publish = req.body.show_publish;
33 | const show_wallet = req.body.show_wallet;
34 | const withdraw_min = req.body.withdraw_min;
35 | const first_withdraw_min = req.body.first_withdraw_min;
36 | const withdraw_max = req.body.withdraw_max;
37 | const withdraw_notice = req.body.withdraw_notice;
38 | const is_review = req.body.is_review;
39 | const contact = req.body.contact;
40 | const h5 = req.body.h5;
41 | const share_title = req.body.share_title;
42 | const share_image = req.body.share_image;
43 | const commission_ratio = req.body.commission_ratio;
44 | const first_commission_ratio = req.body.first_commission_ratio;
45 | const commission_ratio_vip = req.body.commission_ratio_vip;
46 | const agreement_title = req.body.agreement_title;
47 | const agreement_content = req.body.agreement_content;
48 | const need_certification = req.body.need_certification;
49 | const publish_need_certification = req.body.publish_need_certification;
50 | const need_vip = req.body.need_vip;
51 | const vip_unlimited = req.body.vip_unlimited;
52 | const alipay_code = req.body.alipay_code;
53 | const wepay_code = req.body.wepay_code;
54 | const vip_description = req.body.vip_description;
55 | const online_pay = req.body.online_pay || 0;
56 | const use_apppay = req.body.use_apppay || 0;
57 | const use_publicpay = req.body.use_publicpay || 0;
58 | const use_app_alipay = req.body.use_app_alipay || 0;
59 | const mch_id = req.body.mch_id || '';
60 | const mch_key = req.body.mch_key || '';
61 | const task_price = req.body.task_price;
62 | const task_price_vip = req.body.task_price_vip;
63 | const invite_rule = req.body.invite_rule;
64 | const show_withdraw = req.body.show_withdraw;
65 | const show_recharge = req.body.show_recharge;
66 | const show_invite = req.body.show_invite;
67 | const show_contact = req.body.show_contact;
68 | const show_connect = req.body.show_connect;
69 | const is_ratio = req.body.is_ratio;
70 | const need_review = req.body.need_review;
71 | const show_about = req.body.show_about;
72 | const about_us = req.body.about_us;
73 | const show_recommend = req.body.show_recommend;
74 | const show_high = req.body.show_high;
75 | const show_simple = req.body.show_simple;
76 | const show_member = req.body.show_member;
77 | const base_amount = req.body.base_amount;
78 | const max_review_time = req.body.max_review_time;
79 | const open_appeal = req.body.open_appeal;
80 | const min_task_price = req.body.min_task_price;
81 | const max_task_price = req.body.max_task_price;
82 | const min_limit_time = req.body.min_limit_time;
83 | const max_limit_time = req.body.max_limit_time;
84 | const android_download_url = req.body.android_download_url;
85 | const ios_download_url = req.body.ios_download_url;
86 | const android_download_code = req.body.android_download_code;
87 | const ios_download_code = req.body.ios_download_code;
88 | const refresh_count = req.body.refresh_count;
89 | const show_refresh = req.body.show_refresh;
90 | const recommend_price = req.body.recommend_price;
91 | const vip_recommend_price = req.body.vip_recommend_price;
92 | const top_price = req.body.top_price;
93 | const vip_top_price = req.body.vip_top_price;
94 | const withdraw_need_certificate = req.body.withdraw_need_certificate;
95 | const show_certification_IDcard = req.body.show_certification_IDcard;
96 | const show_certification_card_number = req.body.show_certification_card_number;
97 | const show_register_entry = req.body.show_register_entry;
98 | const show_phone_login = req.body.show_phone_login;
99 | const vip_award_ratio = req.body.vip_award_ratio;
100 | const vip_award_ratio_two = req.body.vip_award_ratio_two;
101 | const need_bind_phone = req.body.need_bind_phone;
102 | const score_rate = req.body.score_rate;
103 | const score_for_task = req.body.score_for_task;
104 | const app_version = req.body.app_version;
105 | const app_version_name = req.body.app_version_name;
106 | const app_update_description = req.body.app_update_description;
107 | const app_update_rule = req.body.app_update_rule;
108 | const invite_text = req.body.invite_text;
109 | const invite_poster = req.body.invite_poster;
110 | const poster_code_width = req.body.poster_code_width;
111 | const poster_code_height = req.body.poster_code_height;
112 | const poster_code_left = req.body.poster_code_left;
113 | const poster_code_top = req.body.poster_code_top;
114 | const download_page = req.body.download_page;
115 | const pay_to_wechat = req.body.pay_to_wechat || 0;
116 | const pay_to_alipay = req.body.pay_to_alipay || 0;
117 | const withdraw_need_bind_wechat = req.body.withdraw_need_bind_wechat || 0;
118 | const policy_title = req.body.policy_title || '';
119 | const policy_content = req.body.policy_content || '';
120 | const use_phone_register = req.body.use_phone_register;
121 | const show_app_wechat_login = req.body.show_app_wechat_login;
122 | const show_find_password = req.body.show_find_password;
123 | const show_bind_phone = req.body.show_bind_phone || 0;
124 | const show_wallet_recharge = req.body.show_wallet_recharge || 0;
125 | const show_app_apple_login = req.body.show_app_apple_login || 0;
126 | const grab_btn_ad = req.body.grab_btn_ad || '';
127 | const withdraw_btn_ad = req.body.withdraw_btn_ad || '';
128 | const show_alipay_withdraw = req.body.show_alipay_withdraw || 0;
129 | const show_wechat_withdraw = req.body.show_wechat_withdraw || 0;
130 | const show_bank_withdraw = req.body.show_bank_withdraw || 0;
131 | const recharge_rate = req.body.recharge_rate || 100;
132 | const enable_location = req.body.enable_location || 0;
133 |
134 | const sql = `update system set
135 | grab_btn_ad="${grab_btn_ad}",
136 | withdraw_btn_ad="${withdraw_btn_ad}",
137 | program_name="${program_name}",
138 | android_download_url="${android_download_url}",
139 | ios_download_url="${ios_download_url}",
140 | android_download_code="${android_download_code}",
141 | ios_download_code="${ios_download_code}",
142 | min_task_price=${min_task_price},
143 | max_task_price=${max_task_price},
144 | min_limit_time="${min_limit_time}",
145 | max_limit_time="${max_limit_time}",
146 | show_certification=${show_certification},
147 | show_vip=${show_vip},
148 | show_publish=${show_publish},
149 | show_wallet=${show_wallet},
150 | withdraw_min=${withdraw_min},
151 | first_withdraw_min=${first_withdraw_min},
152 | withdraw_max=${withdraw_max},
153 | withdraw_notice="${withdraw_notice}",
154 | contact="${contact}",
155 | h5="${h5}",
156 | share_title="${share_title}",
157 | share_image="${share_image}",
158 | commission_ratio=${commission_ratio},
159 | first_commission_ratio=${first_commission_ratio},
160 | commission_ratio_vip=${commission_ratio_vip},
161 | agreement_title="${agreement_title}",
162 | agreement_content="${agreement_content}",
163 | need_certification=${need_certification},
164 | publish_need_certification=${publish_need_certification},
165 | enable_location=${enable_location},
166 | need_vip=${need_vip},
167 | vip_unlimited=${vip_unlimited},
168 | alipay_code="${alipay_code}",
169 | wepay_code="${wepay_code}",
170 | vip_description="${vip_description}",
171 | online_pay=${online_pay},
172 | use_apppay=${use_apppay},
173 | mch_id="${mch_id}",
174 | mch_key="${mch_key}",
175 | task_price=${task_price},
176 | task_price_vip=${task_price_vip},
177 | invite_rule="${invite_rule}",
178 | show_withdraw=${show_withdraw},
179 | show_recharge=${show_recharge},
180 | show_invite=${show_invite},
181 | show_contact=${show_contact},
182 | show_connect=${show_connect},
183 | is_ratio=${is_ratio},
184 | need_review=${need_review},
185 | show_about=${show_about},
186 | about_us="${about_us}",
187 | show_recommend=${show_recommend},
188 | show_high=${show_high},
189 | show_simple=${show_simple},
190 | show_member=${show_member},
191 | base_amount=${base_amount},
192 | max_review_time=${max_review_time},
193 | open_appeal=${open_appeal},
194 | refresh_count=${refresh_count},
195 | show_refresh=${show_refresh},
196 | recommend_price=${recommend_price},
197 | vip_recommend_price=${vip_recommend_price},
198 | top_price=${top_price},
199 | vip_top_price=${vip_top_price},
200 | withdraw_need_certificate=${withdraw_need_certificate},
201 | show_certification_IDcard=${show_certification_IDcard},
202 | show_certification_card_number=${show_certification_card_number},
203 | show_register_entry=${show_register_entry},
204 | show_phone_login=${show_phone_login},
205 | use_publicpay=${use_publicpay},
206 | use_app_alipay=${use_app_alipay},
207 | vip_award_ratio=${vip_award_ratio},
208 | vip_award_ratio_two=${vip_award_ratio_two},
209 | need_bind_phone=${need_bind_phone},
210 | score_rate=${score_rate},
211 | score_for_task=${score_for_task},
212 | app_version=${app_version},
213 | app_version_name='${app_version_name}',
214 | app_update_description='${app_update_description}',
215 | app_update_rule=${app_update_rule},
216 | invite_text='${invite_text}',
217 | invite_poster='${invite_poster}',
218 | poster_code_width=${poster_code_width},
219 | poster_code_height=${poster_code_height},
220 | poster_code_left=${poster_code_left},
221 | poster_code_top=${poster_code_top},
222 | download_page='${download_page}',
223 | pay_to_wechat=${pay_to_wechat},
224 | pay_to_alipay=${pay_to_alipay},
225 | withdraw_need_bind_wechat=${withdraw_need_bind_wechat},
226 | policy_title='${policy_title}',
227 | policy_content='${policy_content}',
228 | use_phone_register=${use_phone_register},
229 | show_app_wechat_login=${show_app_wechat_login},
230 | show_find_password=${show_find_password},
231 | show_bind_phone=${show_bind_phone},
232 | show_wallet_recharge=${show_wallet_recharge},
233 | show_app_apple_login=${show_app_apple_login},
234 | show_alipay_withdraw=${show_alipay_withdraw},
235 | show_wechat_withdraw=${show_wechat_withdraw},
236 | show_bank_withdraw=${show_bank_withdraw},
237 | recharge_rate=${recharge_rate},
238 | is_review=${is_review}`;
239 | query(sql, (err, vals) => {
240 | if (!err && vals instanceof Object) {
241 | console.info('更新系统配置返回', vals);
242 | req.body.data = true;
243 | req.body.code = '10000';
244 | req.body.message = '操作成功';
245 | req.body.success = true;
246 | // 记录操作日志
247 | req.body.log = Object.assign(req.body.log || {}, {
248 | client: 1,
249 | content: `修改了系统设置`,
250 | });
251 | return next();
252 | } else {
253 | return res.json({ code: '10001', message: err.code, success: false, data: err });
254 | }
255 | })
256 | }
--------------------------------------------------------------------------------
/utils/md5.js:
--------------------------------------------------------------------------------
1 | /*
2 | * JavaScript MD5
3 | * https://github.com/blueimp/JavaScript-MD5
4 | *
5 | * Copyright 2011, Sebastian Tschan
6 | * https://blueimp.net
7 | *
8 | * Licensed under the MIT license:
9 | * https://opensource.org/licenses/MIT
10 | *
11 | * Based on
12 | * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
13 | * Digest Algorithm, as defined in RFC 1321.
14 | * Version 2.2 Copyright (C) Paul Johnston 1999 - 2009
15 | * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
16 | * Distributed under the BSD License
17 | * See http://pajhome.org.uk/crypt/md5 for more info.
18 | */
19 |
20 | /* global define */
21 |
22 | /* eslint-disable strict */
23 |
24 | ;(function($) {
25 | 'use strict'
26 |
27 | /**
28 | * Add integers, wrapping at 2^32.
29 | * This uses 16-bit operations internally to work around bugs in interpreters.
30 | *
31 | * @param {number} x First integer
32 | * @param {number} y Second integer
33 | * @returns {number} Sum
34 | */
35 | function safeAdd(x, y) {
36 | var lsw = (x & 0xffff) + (y & 0xffff)
37 | var msw = (x >> 16) + (y >> 16) + (lsw >> 16)
38 | return (msw << 16) | (lsw & 0xffff)
39 | }
40 |
41 | /**
42 | * Bitwise rotate a 32-bit number to the left.
43 | *
44 | * @param {number} num 32-bit number
45 | * @param {number} cnt Rotation count
46 | * @returns {number} Rotated number
47 | */
48 | function bitRotateLeft(num, cnt) {
49 | return (num << cnt) | (num >>> (32 - cnt))
50 | }
51 |
52 | /**
53 | * Basic operation the algorithm uses.
54 | *
55 | * @param {number} q q
56 | * @param {number} a a
57 | * @param {number} b b
58 | * @param {number} x x
59 | * @param {number} s s
60 | * @param {number} t t
61 | * @returns {number} Result
62 | */
63 | function md5cmn(q, a, b, x, s, t) {
64 | return safeAdd(bitRotateLeft(safeAdd(safeAdd(a, q), safeAdd(x, t)), s), b)
65 | }
66 | /**
67 | * Basic operation the algorithm uses.
68 | *
69 | * @param {number} a a
70 | * @param {number} b b
71 | * @param {number} c c
72 | * @param {number} d d
73 | * @param {number} x x
74 | * @param {number} s s
75 | * @param {number} t t
76 | * @returns {number} Result
77 | */
78 | function md5ff(a, b, c, d, x, s, t) {
79 | return md5cmn((b & c) | (~b & d), a, b, x, s, t)
80 | }
81 | /**
82 | * Basic operation the algorithm uses.
83 | *
84 | * @param {number} a a
85 | * @param {number} b b
86 | * @param {number} c c
87 | * @param {number} d d
88 | * @param {number} x x
89 | * @param {number} s s
90 | * @param {number} t t
91 | * @returns {number} Result
92 | */
93 | function md5gg(a, b, c, d, x, s, t) {
94 | return md5cmn((b & d) | (c & ~d), a, b, x, s, t)
95 | }
96 | /**
97 | * Basic operation the algorithm uses.
98 | *
99 | * @param {number} a a
100 | * @param {number} b b
101 | * @param {number} c c
102 | * @param {number} d d
103 | * @param {number} x x
104 | * @param {number} s s
105 | * @param {number} t t
106 | * @returns {number} Result
107 | */
108 | function md5hh(a, b, c, d, x, s, t) {
109 | return md5cmn(b ^ c ^ d, a, b, x, s, t)
110 | }
111 | /**
112 | * Basic operation the algorithm uses.
113 | *
114 | * @param {number} a a
115 | * @param {number} b b
116 | * @param {number} c c
117 | * @param {number} d d
118 | * @param {number} x x
119 | * @param {number} s s
120 | * @param {number} t t
121 | * @returns {number} Result
122 | */
123 | function md5ii(a, b, c, d, x, s, t) {
124 | return md5cmn(c ^ (b | ~d), a, b, x, s, t)
125 | }
126 |
127 | /**
128 | * Calculate the MD5 of an array of little-endian words, and a bit length.
129 | *
130 | * @param {Array} x Array of little-endian words
131 | * @param {number} len Bit length
132 | * @returns {Array} MD5 Array
133 | */
134 | function binlMD5(x, len) {
135 | /* append padding */
136 | x[len >> 5] |= 0x80 << len % 32
137 | x[(((len + 64) >>> 9) << 4) + 14] = len
138 |
139 | var i
140 | var olda
141 | var oldb
142 | var oldc
143 | var oldd
144 | var a = 1732584193
145 | var b = -271733879
146 | var c = -1732584194
147 | var d = 271733878
148 |
149 | for (i = 0; i < x.length; i += 16) {
150 | olda = a
151 | oldb = b
152 | oldc = c
153 | oldd = d
154 |
155 | a = md5ff(a, b, c, d, x[i], 7, -680876936)
156 | d = md5ff(d, a, b, c, x[i + 1], 12, -389564586)
157 | c = md5ff(c, d, a, b, x[i + 2], 17, 606105819)
158 | b = md5ff(b, c, d, a, x[i + 3], 22, -1044525330)
159 | a = md5ff(a, b, c, d, x[i + 4], 7, -176418897)
160 | d = md5ff(d, a, b, c, x[i + 5], 12, 1200080426)
161 | c = md5ff(c, d, a, b, x[i + 6], 17, -1473231341)
162 | b = md5ff(b, c, d, a, x[i + 7], 22, -45705983)
163 | a = md5ff(a, b, c, d, x[i + 8], 7, 1770035416)
164 | d = md5ff(d, a, b, c, x[i + 9], 12, -1958414417)
165 | c = md5ff(c, d, a, b, x[i + 10], 17, -42063)
166 | b = md5ff(b, c, d, a, x[i + 11], 22, -1990404162)
167 | a = md5ff(a, b, c, d, x[i + 12], 7, 1804603682)
168 | d = md5ff(d, a, b, c, x[i + 13], 12, -40341101)
169 | c = md5ff(c, d, a, b, x[i + 14], 17, -1502002290)
170 | b = md5ff(b, c, d, a, x[i + 15], 22, 1236535329)
171 |
172 | a = md5gg(a, b, c, d, x[i + 1], 5, -165796510)
173 | d = md5gg(d, a, b, c, x[i + 6], 9, -1069501632)
174 | c = md5gg(c, d, a, b, x[i + 11], 14, 643717713)
175 | b = md5gg(b, c, d, a, x[i], 20, -373897302)
176 | a = md5gg(a, b, c, d, x[i + 5], 5, -701558691)
177 | d = md5gg(d, a, b, c, x[i + 10], 9, 38016083)
178 | c = md5gg(c, d, a, b, x[i + 15], 14, -660478335)
179 | b = md5gg(b, c, d, a, x[i + 4], 20, -405537848)
180 | a = md5gg(a, b, c, d, x[i + 9], 5, 568446438)
181 | d = md5gg(d, a, b, c, x[i + 14], 9, -1019803690)
182 | c = md5gg(c, d, a, b, x[i + 3], 14, -187363961)
183 | b = md5gg(b, c, d, a, x[i + 8], 20, 1163531501)
184 | a = md5gg(a, b, c, d, x[i + 13], 5, -1444681467)
185 | d = md5gg(d, a, b, c, x[i + 2], 9, -51403784)
186 | c = md5gg(c, d, a, b, x[i + 7], 14, 1735328473)
187 | b = md5gg(b, c, d, a, x[i + 12], 20, -1926607734)
188 |
189 | a = md5hh(a, b, c, d, x[i + 5], 4, -378558)
190 | d = md5hh(d, a, b, c, x[i + 8], 11, -2022574463)
191 | c = md5hh(c, d, a, b, x[i + 11], 16, 1839030562)
192 | b = md5hh(b, c, d, a, x[i + 14], 23, -35309556)
193 | a = md5hh(a, b, c, d, x[i + 1], 4, -1530992060)
194 | d = md5hh(d, a, b, c, x[i + 4], 11, 1272893353)
195 | c = md5hh(c, d, a, b, x[i + 7], 16, -155497632)
196 | b = md5hh(b, c, d, a, x[i + 10], 23, -1094730640)
197 | a = md5hh(a, b, c, d, x[i + 13], 4, 681279174)
198 | d = md5hh(d, a, b, c, x[i], 11, -358537222)
199 | c = md5hh(c, d, a, b, x[i + 3], 16, -722521979)
200 | b = md5hh(b, c, d, a, x[i + 6], 23, 76029189)
201 | a = md5hh(a, b, c, d, x[i + 9], 4, -640364487)
202 | d = md5hh(d, a, b, c, x[i + 12], 11, -421815835)
203 | c = md5hh(c, d, a, b, x[i + 15], 16, 530742520)
204 | b = md5hh(b, c, d, a, x[i + 2], 23, -995338651)
205 |
206 | a = md5ii(a, b, c, d, x[i], 6, -198630844)
207 | d = md5ii(d, a, b, c, x[i + 7], 10, 1126891415)
208 | c = md5ii(c, d, a, b, x[i + 14], 15, -1416354905)
209 | b = md5ii(b, c, d, a, x[i + 5], 21, -57434055)
210 | a = md5ii(a, b, c, d, x[i + 12], 6, 1700485571)
211 | d = md5ii(d, a, b, c, x[i + 3], 10, -1894986606)
212 | c = md5ii(c, d, a, b, x[i + 10], 15, -1051523)
213 | b = md5ii(b, c, d, a, x[i + 1], 21, -2054922799)
214 | a = md5ii(a, b, c, d, x[i + 8], 6, 1873313359)
215 | d = md5ii(d, a, b, c, x[i + 15], 10, -30611744)
216 | c = md5ii(c, d, a, b, x[i + 6], 15, -1560198380)
217 | b = md5ii(b, c, d, a, x[i + 13], 21, 1309151649)
218 | a = md5ii(a, b, c, d, x[i + 4], 6, -145523070)
219 | d = md5ii(d, a, b, c, x[i + 11], 10, -1120210379)
220 | c = md5ii(c, d, a, b, x[i + 2], 15, 718787259)
221 | b = md5ii(b, c, d, a, x[i + 9], 21, -343485551)
222 |
223 | a = safeAdd(a, olda)
224 | b = safeAdd(b, oldb)
225 | c = safeAdd(c, oldc)
226 | d = safeAdd(d, oldd)
227 | }
228 | return [a, b, c, d]
229 | }
230 |
231 | /**
232 | * Convert an array of little-endian words to a string
233 | *
234 | * @param {Array} input MD5 Array
235 | * @returns {string} MD5 string
236 | */
237 | function binl2rstr(input) {
238 | var i
239 | var output = ''
240 | var length32 = input.length * 32
241 | for (i = 0; i < length32; i += 8) {
242 | output += String.fromCharCode((input[i >> 5] >>> i % 32) & 0xff)
243 | }
244 | return output
245 | }
246 |
247 | /**
248 | * Convert a raw string to an array of little-endian words
249 | * Characters >255 have their high-byte silently ignored.
250 | *
251 | * @param {string} input Raw input string
252 | * @returns {Array} Array of little-endian words
253 | */
254 | function rstr2binl(input) {
255 | var i
256 | var output = []
257 | output[(input.length >> 2) - 1] = undefined
258 | for (i = 0; i < output.length; i += 1) {
259 | output[i] = 0
260 | }
261 | var length8 = input.length * 8
262 | for (i = 0; i < length8; i += 8) {
263 | output[i >> 5] |= (input.charCodeAt(i / 8) & 0xff) << i % 32
264 | }
265 | return output
266 | }
267 |
268 | /**
269 | * Calculate the MD5 of a raw string
270 | *
271 | * @param {string} s Input string
272 | * @returns {string} Raw MD5 string
273 | */
274 | function rstrMD5(s) {
275 | return binl2rstr(binlMD5(rstr2binl(s), s.length * 8))
276 | }
277 |
278 | /**
279 | * Calculates the HMAC-MD5 of a key and some data (raw strings)
280 | *
281 | * @param {string} key HMAC key
282 | * @param {string} data Raw input string
283 | * @returns {string} Raw MD5 string
284 | */
285 | function rstrHMACMD5(key, data) {
286 | var i
287 | var bkey = rstr2binl(key)
288 | var ipad = []
289 | var opad = []
290 | var hash
291 | ipad[15] = opad[15] = undefined
292 | if (bkey.length > 16) {
293 | bkey = binlMD5(bkey, key.length * 8)
294 | }
295 | for (i = 0; i < 16; i += 1) {
296 | ipad[i] = bkey[i] ^ 0x36363636
297 | opad[i] = bkey[i] ^ 0x5c5c5c5c
298 | }
299 | hash = binlMD5(ipad.concat(rstr2binl(data)), 512 + data.length * 8)
300 | return binl2rstr(binlMD5(opad.concat(hash), 512 + 128))
301 | }
302 |
303 | /**
304 | * Convert a raw string to a hex string
305 | *
306 | * @param {string} input Raw input string
307 | * @returns {string} Hex encoded string
308 | */
309 | function rstr2hex(input) {
310 | var hexTab = '0123456789abcdef'
311 | var output = ''
312 | var x
313 | var i
314 | for (i = 0; i < input.length; i += 1) {
315 | x = input.charCodeAt(i)
316 | output += hexTab.charAt((x >>> 4) & 0x0f) + hexTab.charAt(x & 0x0f)
317 | }
318 | return output
319 | }
320 |
321 | /**
322 | * Encode a string as UTF-8
323 | *
324 | * @param {string} input Input string
325 | * @returns {string} UTF8 string
326 | */
327 | function str2rstrUTF8(input) {
328 | return unescape(encodeURIComponent(input))
329 | }
330 |
331 | /**
332 | * Encodes input string as raw MD5 string
333 | *
334 | * @param {string} s Input string
335 | * @returns {string} Raw MD5 string
336 | */
337 | function rawMD5(s) {
338 | return rstrMD5(str2rstrUTF8(s))
339 | }
340 | /**
341 | * Encodes input string as Hex encoded string
342 | *
343 | * @param {string} s Input string
344 | * @returns {string} Hex encoded string
345 | */
346 | function hexMD5(s) {
347 | return rstr2hex(rawMD5(s))
348 | }
349 | /**
350 | * Calculates the raw HMAC-MD5 for the given key and data
351 | *
352 | * @param {string} k HMAC key
353 | * @param {string} d Input string
354 | * @returns {string} Raw MD5 string
355 | */
356 | function rawHMACMD5(k, d) {
357 | return rstrHMACMD5(str2rstrUTF8(k), str2rstrUTF8(d))
358 | }
359 | /**
360 | * Calculates the Hex encoded HMAC-MD5 for the given key and data
361 | *
362 | * @param {string} k HMAC key
363 | * @param {string} d Input string
364 | * @returns {string} Raw MD5 string
365 | */
366 | function hexHMACMD5(k, d) {
367 | return rstr2hex(rawHMACMD5(k, d))
368 | }
369 |
370 | /**
371 | * Calculates MD5 value for a given string.
372 | * If a key is provided, calculates the HMAC-MD5 value.
373 | * Returns a Hex encoded string unless the raw argument is given.
374 | *
375 | * @param {string} string Input string
376 | * @param {string} [key] HMAC key
377 | * @param {boolean} [raw] Raw output switch
378 | * @returns {string} MD5 output
379 | */
380 | function md5(string, key, raw) {
381 | if (!key) {
382 | if (!raw) {
383 | return hexMD5(string)
384 | }
385 | return rawMD5(string)
386 | }
387 | if (!raw) {
388 | return hexHMACMD5(key, string)
389 | }
390 | return rawHMACMD5(key, string)
391 | }
392 |
393 | if (typeof define === 'function' && define.amd) {
394 | define(function() {
395 | return md5
396 | })
397 | } else if (typeof module === 'object' && module.exports) {
398 | module.exports = md5
399 | } else {
400 | $.md5 = md5
401 | }
402 | })(this)
403 |
--------------------------------------------------------------------------------