├── public
├── images
│ ├── b2.jpeg
│ ├── bg1.jpeg
│ ├── 404.png
│ ├── arrow.png
│ ├── logo.png
│ ├── step1.png
│ ├── step2.png
│ ├── step3.png
│ ├── step4.png
│ ├── wxpay.png
│ ├── favicon.ico
│ ├── success1.png
│ ├── success2.png
│ ├── zhifubao.png
│ ├── renrenpay.ico
│ ├── partner_wxpay.jpg
│ └── partner_alipay.jpg
├── dist
│ ├── static
│ │ ├── css
│ │ │ ├── chunk-f779.79af9e6e.css
│ │ │ ├── chunk-5743.8cad7bcd.css
│ │ │ ├── chunk-b69e.de0b32b4.css
│ │ │ ├── chunk-27db.6a1661a5.css
│ │ │ ├── chunk-0224.f01dfcab.css
│ │ │ ├── chunk-26f3.a8b3c6c5.css
│ │ │ ├── chunk-fc3b.b79580c9.css
│ │ │ ├── chunk-3200.6e36a35c.css
│ │ │ ├── chunk-7e70.92d696e8.css
│ │ │ ├── chunk-280b.7469e992.css
│ │ │ ├── chunk-libs.e73a8678.css
│ │ │ ├── chunk-6929.486b8768.css
│ │ │ └── app.cab2c720.css
│ │ ├── img
│ │ │ ├── 404.a57b6f3.png
│ │ │ └── bg.cf0887a.jpg
│ │ ├── fonts
│ │ │ └── element-icons.6f0a763.ttf
│ │ └── js
│ │ │ ├── eej3.42f74184.js
│ │ │ ├── EwA2.cf227d21.js
│ │ │ ├── chunk-27db.8a51fb19.js
│ │ │ ├── chunk-f779.74ec5683.js
│ │ │ ├── chunk-54db.2bca911d.js
│ │ │ ├── chunk-0224.e4d32421.js
│ │ │ ├── chunk-5743.e739dad9.js
│ │ │ ├── chunk-3200.30d05b08.js
│ │ │ ├── chunk-7e70.17b6490e.js
│ │ │ ├── chunk-280b.82d6890b.js
│ │ │ ├── chunk-6929.2461bbf3.js
│ │ │ └── chunk-fc3b.827b4c52.js
│ ├── favicon.ico
│ └── index.html
├── stylesheets
│ └── style.css
├── css
│ └── normalize.css
└── font
│ └── iconfont.js
├── dump.rdb
├── playground.js
├── utils
├── md5.js
├── fileIO.js
├── logger.js
├── jwt.js
├── sendSms.js
├── sendEmail.js
├── callback.js
├── verifyParams.js
├── errorCode.js
├── verifyToken.js
├── websocket.js
├── redisClient.js
├── errorHandler.js
├── timeformatter.js
├── returnJson.js
└── statistic.js
├── keys
├── master-public.pem
└── master-privatekey.pem
├── test.js
├── .gitignore
├── README.md
├── db
├── index.js
├── models
│ ├── withdraws.js
│ ├── logs.js
│ ├── statistic.js
│ ├── payCode.js
│ ├── trades.js
│ ├── deposits.js
│ ├── paychecks.js
│ ├── orders.js
│ ├── apps.js
│ └── users.js
├── schema
│ ├── logs.js
│ ├── paycode.js
│ ├── withdraws.js
│ ├── trades.js
│ ├── deposits.js
│ ├── paychecks.js
│ ├── apps.js
│ ├── orders.js
│ ├── statistic.js
│ └── users.js
└── sqlTable.js
├── conf
└── default.js
├── views
└── 404.ejs
├── package.json
├── app.js
├── bin
└── www
├── init
└── index.js
└── controllers
├── withdrawsController.js
├── ordersController.js
├── index.js
├── paychecksController.js
└── tradeController.js
/public/images/b2.jpeg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/images/bg1.jpeg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/dist/static/css/chunk-f779.79af9e6e.css:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/dump.rdb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/verylove/renrenpay-server/HEAD/dump.rdb
--------------------------------------------------------------------------------
/public/dist/static/css/chunk-5743.8cad7bcd.css:
--------------------------------------------------------------------------------
1 | .orders-index-page[data-v-07355ba6]{padding:32px}
--------------------------------------------------------------------------------
/public/images/404.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/verylove/renrenpay-server/HEAD/public/images/404.png
--------------------------------------------------------------------------------
/public/dist/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/verylove/renrenpay-server/HEAD/public/dist/favicon.ico
--------------------------------------------------------------------------------
/public/images/arrow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/verylove/renrenpay-server/HEAD/public/images/arrow.png
--------------------------------------------------------------------------------
/public/images/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/verylove/renrenpay-server/HEAD/public/images/logo.png
--------------------------------------------------------------------------------
/public/images/step1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/verylove/renrenpay-server/HEAD/public/images/step1.png
--------------------------------------------------------------------------------
/public/images/step2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/verylove/renrenpay-server/HEAD/public/images/step2.png
--------------------------------------------------------------------------------
/public/images/step3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/verylove/renrenpay-server/HEAD/public/images/step3.png
--------------------------------------------------------------------------------
/public/images/step4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/verylove/renrenpay-server/HEAD/public/images/step4.png
--------------------------------------------------------------------------------
/public/images/wxpay.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/verylove/renrenpay-server/HEAD/public/images/wxpay.png
--------------------------------------------------------------------------------
/playground.js:
--------------------------------------------------------------------------------
1 |
2 | let a = "pay" + 100 + "wechat" + 2 + Math.random().toString().slice(-8);
3 | console.log(a)
--------------------------------------------------------------------------------
/public/images/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/verylove/renrenpay-server/HEAD/public/images/favicon.ico
--------------------------------------------------------------------------------
/public/images/success1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/verylove/renrenpay-server/HEAD/public/images/success1.png
--------------------------------------------------------------------------------
/public/images/success2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/verylove/renrenpay-server/HEAD/public/images/success2.png
--------------------------------------------------------------------------------
/public/images/zhifubao.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/verylove/renrenpay-server/HEAD/public/images/zhifubao.png
--------------------------------------------------------------------------------
/public/images/renrenpay.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/verylove/renrenpay-server/HEAD/public/images/renrenpay.ico
--------------------------------------------------------------------------------
/public/images/partner_wxpay.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/verylove/renrenpay-server/HEAD/public/images/partner_wxpay.jpg
--------------------------------------------------------------------------------
/public/images/partner_alipay.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/verylove/renrenpay-server/HEAD/public/images/partner_alipay.jpg
--------------------------------------------------------------------------------
/public/dist/static/img/404.a57b6f3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/verylove/renrenpay-server/HEAD/public/dist/static/img/404.a57b6f3.png
--------------------------------------------------------------------------------
/public/dist/static/img/bg.cf0887a.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/verylove/renrenpay-server/HEAD/public/dist/static/img/bg.cf0887a.jpg
--------------------------------------------------------------------------------
/public/dist/static/fonts/element-icons.6f0a763.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/verylove/renrenpay-server/HEAD/public/dist/static/fonts/element-icons.6f0a763.ttf
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/utils/md5.js:
--------------------------------------------------------------------------------
1 | const crypto = require('crypto')
2 |
3 | const MD5 = data => {
4 | const md5 = crypto.createHash('md5')
5 | md5.update(data)
6 | return md5.digest('hex')
7 | }
8 |
9 | module.exports = MD5
10 |
--------------------------------------------------------------------------------
/keys/master-public.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN PUBLIC KEY-----
2 | MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDKx57/DKGMVaPrCm9dewigq/uV
3 | 3/LvmD8gA9OkcG3Tfd/V4yrLqqBH3eH0Qkfi3SbYo2mo6sFYhvZI1Cg0jlPUwT1m
4 | NedGDNJsEugXujeNMDAEc2xpjwCvuAO7XGWUmyEynGbS+t4APX1vR0eqZ1XtVDFc
5 | WD+Si5EoLcJ+9zcSbQIDAQAB
6 | -----END PUBLIC KEY-----
7 |
--------------------------------------------------------------------------------
/test.js:
--------------------------------------------------------------------------------
1 | let crypto = require('crypto');
2 | const md5 = info => {
3 | const md5 = crypto.createHash('md5')
4 | md5.update(info)
5 | return md5.digest('hex')
6 | }
7 |
8 | // console.log(md5("qwerty"))
9 | let dbInfo = {
10 | };
11 | const pwd = md5(md5(dbInfo.password) + dbInfo.salt);
12 | console.log(pwd)
--------------------------------------------------------------------------------
/public/dist/static/js/eej3.42f74184.js:
--------------------------------------------------------------------------------
1 | (window.webpackJsonp=window.webpackJsonp||[]).push([["eej3"],{eej3:function(e,n,t){"use strict";t.r(n);var i=t("KHd+"),s=Object(i.a)({},function(){var e=this.$createElement;return(this._self._c||e)("div",{staticClass:"api-index-page"},[this._v("\n API 文档\n")])},[],!1,null,null,null);s.options.__file="Index.vue";n.default=s.exports}}]);
--------------------------------------------------------------------------------
/public/dist/static/js/EwA2.cf227d21.js:
--------------------------------------------------------------------------------
1 | (window.webpackJsonp=window.webpackJsonp||[]).push([["EwA2"],{EwA2:function(n,e,t){"use strict";t.r(e);var s=t("KHd+"),i=Object(s.a)({},function(){var n=this.$createElement;return(this._self._c||n)("div",{staticClass:"download-index-page"},[this._v("\n 软件下载页面\n")])},[],!1,null,null,null);i.options.__file="Index.vue";e.default=i.exports}}]);
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.db
2 | dapps/
3 | .DS_Store
4 | .ed25519-node
5 | .idea/
6 | *.log
7 | __MACOSX/
8 | nodejs/
9 | node_modules
10 | logs
11 | .project
12 | release
13 | sqlite/
14 | ssl/
15 | stacktrace*
16 | tmp
17 | *.pid
18 | package-lock.json
19 | .vs/
20 | .vscode
21 | public/bower_components
22 | public/npm-debug.log
23 | public/.sass-cache
24 | public/.tmp
25 | public/.gulp
26 | public/*.css
27 | public/node_modules
28 | *.save
29 | accountKey.json
30 |
31 |
--------------------------------------------------------------------------------
/utils/fileIO.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs')
2 | const path = require('path')
3 | const {
4 | loggerHttp
5 | } = require('./logger.js')
6 |
7 | const fileIO = {
8 | // write into a file
9 | async writeFile(filename, data) {
10 | try {
11 | fs.writeFileSync(path.join(__dirname, filename), data)
12 | return true
13 | } catch (err) {
14 | loggerHttp.error(`writeFile -- ${err}`)
15 | }
16 | }
17 | }
18 |
19 | module.exports = fileIO
20 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 利用xposed框架监听支付宝微信的收付款服务端
2 | 安卓端地址:https://github.com/cxyxxx0924/renrenpay-android.git
3 | ## 说明
4 | 服务端和客户端需要配合使用,不然客户端都无法打开
5 |
6 | ## 安装步骤
7 | ```
8 | 下载node环境 http://nodejs.cn/ (版本最好新一点,我使用的是10.14.2)
9 |
10 | git clone https://github.com/cxyxxx0924/renrenpay-server.git
11 | cd renrenpay-server
12 | npm i
13 | 下载redis
14 | 下载mysql
15 | 修改./conf/default.js下的user和password为mysql的用户名和密码
16 | 添加 数据库:db_renrenpay
17 | 运行 bin/www 既可以运行项目
18 | 打开浏览器 127.0.0.1:3000 既可以看到项目运行
19 | 确保运行后在打开安卓客户端
20 | ```
21 |
--------------------------------------------------------------------------------
/public/dist/static/js/chunk-27db.8a51fb19.js:
--------------------------------------------------------------------------------
1 | (window.webpackJsonp=window.webpackJsonp||[]).push([["chunk-27db"],{mS28:function(e,n,t){"use strict";var i=t("z+hT");t.n(i).a},r2dA:function(e,n,t){"use strict";t.r(n);var i={components:{Membership:t("I8ep").a}},s=(t("mS28"),t("KHd+")),c=Object(s.a)(i,function(){var e=this.$createElement,n=this._self._c||e;return n("div",{staticClass:"admin-member-index"},[n("Membership",{attrs:{mode:"edit"}})],1)},[],!1,null,"51c447f2",null);c.options.__file="Index.vue";n.default=c.exports},"z+hT":function(e,n,t){}}]);
--------------------------------------------------------------------------------
/public/dist/static/css/chunk-b69e.de0b32b4.css:
--------------------------------------------------------------------------------
1 | .pay-comp[data-v-549a193a]{text-align:center}.pay-comp.wepay .deposit-title[data-v-549a193a]{color:#09bb07}.pay-comp.alipay .deposit-title[data-v-549a193a]{color:#00aae8}.pay-comp .deposit-title[data-v-549a193a]{font-size:24px}.pay-comp .deposit-num[data-v-549a193a]{font-size:40px;font-weight:700;margin-top:30px;color:#606266}.app-index-page[data-v-00346527]{padding:32px}.app-index-page .input-hint[data-v-00346527]{font-size:12px;line-height:1.7;color:#909399;margin-top:5px}.app-index-page .input-hint a[data-v-00346527]{text-decoration:underline}
--------------------------------------------------------------------------------
/db/index.js:
--------------------------------------------------------------------------------
1 | const Sequelize = require('sequelize')
2 | const SqlTable = require('./sqlTable.js')
3 | const config = require('../conf/default.js')
4 |
5 | let sequelize, sqlTable
6 |
7 | async function init() {
8 | sequelize = new Sequelize(config.db.db, config.db.user, config.db.password, {
9 | host: config.db.host,
10 | port: config.db.port,
11 | dialect: config.db.dialect,
12 | pool: {
13 | max: 100,
14 | min: 0,
15 | acquire: 30000,
16 | idle: 10000,
17 | },
18 | timezone: '+08:00'
19 | })
20 | // init
21 | sqlTable = new SqlTable(Sequelize, sequelize)
22 | }
23 |
24 | init()
25 | module.exports = {Sequelize, sequelize, sqlTable}
26 |
--------------------------------------------------------------------------------
/db/models/withdraws.js:
--------------------------------------------------------------------------------
1 | const Sequelize = require('sequelize')
2 | const {
3 | sqlTable,
4 | } = require('../index.js')
5 |
6 | const withdraws = {
7 | async addWithdraw(data) {
8 | return sqlTable.withdraws.create({
9 | userid: data.userid,
10 | uuid: data.uuid,
11 | type: data.type || '',
12 | amount: data.amount || 0,
13 | memo: data.memo || '',
14 | status: 1
15 | })
16 | },
17 |
18 | async updateWithdrawInfo(data) {
19 | return sqlTable.withdraws.update({
20 | status: data.status || 0
21 | }, {
22 | where: {
23 | id: data.userid || 0
24 | }
25 | })
26 | },
27 | }
28 |
29 | module.exports = withdraws
30 |
--------------------------------------------------------------------------------
/utils/logger.js:
--------------------------------------------------------------------------------
1 | const log4js = require('log4js')
2 |
3 | log4js.configure({
4 | appenders: {
5 | out: { type: 'stdout' },
6 | httpError: { type: 'dateFile', filename: `${__dirname}/../logs/http/httpError.log`, alwaysIncludePattern: true },
7 | httpInfo: { type: 'dateFile', filename: `${__dirname}/../logs/httpInfo/httpInfo.log`, alwaysIncludePattern: true }
8 | },
9 | categories: {
10 | default: { appenders: ['out'], level: 'error' },
11 | httpError: { appenders: ['httpError'], level: 'error' },
12 | httpInfo: { appenders: ['httpInfo'], level: 'info' }
13 | }
14 | })
15 |
16 | const loggerHttp = log4js.getLogger('httpError')
17 | const loggerHttpInfo = log4js.getLogger('httpInfo')
18 |
19 | module.exports = { loggerHttp, loggerHttpInfo }
20 |
--------------------------------------------------------------------------------
/db/models/logs.js:
--------------------------------------------------------------------------------
1 | const Sequelize = require('sequelize')
2 | const {
3 | sqlTable,
4 | } = require('../index.js')
5 |
6 | const logs = {
7 | async setLog(data){
8 | return await sqlTable.logs.create({
9 | userid:data.userid,
10 | content:data.content,
11 | timestamps:data.timestamps
12 | })
13 | },
14 | async setLogs(data){
15 | return await sqlTable.logs.bulkCreate(data.list)
16 | },
17 | async queryLog(data){
18 | let limit = data.page_size*1;
19 | let offset = data.page_size * (data.page - 1);
20 | return sqlTable.deposits.findAndCountAll({
21 | limit,
22 | offset,
23 | where: {
24 | userid:data.userid
25 | }
26 | })
27 | }
28 | }
29 |
30 | module.exports=logs
--------------------------------------------------------------------------------
/public/dist/static/css/chunk-27db.6a1661a5.css:
--------------------------------------------------------------------------------
1 | .admin-member-index .combo-list[data-v-51c447f2]{font-size:0;margin-left:-20px}.admin-member-index .combo-list .combo-item[data-v-51c447f2]{display:inline-block;width:150px;height:150px;padding:0 10px;border:1px solid #e4e7ed;border-radius:4px;text-align:center;overflow:hidden;margin-left:20px;cursor:pointer}.admin-member-index .combo-list .combo-item.active[data-v-51c447f2]{border:1px solid #f56c6c}.admin-member-index .combo-list .item-title[data-v-51c447f2]{height:50px;line-height:50px;border-bottom:1px dashed #dcdfe6;font-size:18px;color:#333}.admin-member-index .combo-list .item-num[data-v-51c447f2]{font-size:18px;margin-top:15px}.admin-member-index .combo-list .primary[data-v-51c447f2]{font-size:30px;color:#f56c6c;font-weight:700;margin-right:5px}.admin-member-index .combo-list .item-desc[data-v-51c447f2]{font-size:14px;margin-top:15px}
--------------------------------------------------------------------------------
/db/schema/logs.js:
--------------------------------------------------------------------------------
1 | class sqlTable {
2 | // columns
3 | static logs(Sequelize) {
4 | return {
5 | id: {
6 | type: Sequelize.BIGINT,
7 | primaryKey: true,
8 | autoIncrement: true,
9 | allowNull: false
10 | },
11 | userid: {
12 | type: Sequelize.STRING,
13 | allowNull: false,
14 | },
15 | content: {
16 | type: Sequelize.STRING
17 | },
18 | timestamps: {
19 | type: Sequelize.BIGINT,
20 | },
21 | }
22 | }
23 |
24 | static publicSet() {
25 | return {
26 | freezeTableName: true,
27 | paranoid: true,
28 | timestamps: true,
29 | }
30 | }
31 | }
32 |
33 | module.exports = sqlTable
34 |
--------------------------------------------------------------------------------
/keys/master-privatekey.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN RSA PRIVATE KEY-----
2 | MIICXAIBAAKBgQDKx57/DKGMVaPrCm9dewigq/uV3/LvmD8gA9OkcG3Tfd/V4yrL
3 | qqBH3eH0Qkfi3SbYo2mo6sFYhvZI1Cg0jlPUwT1mNedGDNJsEugXujeNMDAEc2xp
4 | jwCvuAO7XGWUmyEynGbS+t4APX1vR0eqZ1XtVDFcWD+Si5EoLcJ+9zcSbQIDAQAB
5 | AoGAecgfLe+pCb3ZHux6a3rbeJsxEhaYMNqPdqu1rHk1DCH5jtvKNNy5O8/+xpIT
6 | 2CSXEt45M5AhJAiR2rVHnCCqKPdjCK0vNef4dI3Q1ngkn7f9pFd/n7QklIUj5HXC
7 | 1I+ucylCVGEHkb6MAV4lya2KWORAgBIm5PYeDVr2bxV+Z4UCQQDlw8EvJZZikI37
8 | 3b8HCMUuHJRSUM4VNCITW67OKUin1GfUy6qdQq5Zqrh/PEM6lUfjrRbraGuMPQba
9 | uSoVfZXrAkEA4e8SVBy0r2ZYqr4QIeJWhK9eRjigvT1TaaJmQ6L6FAx3XxEgk+eE
10 | tpZ6lxy5lM6Z/PkVxwWV1fzXH77Wm+yrBwJAKm2ZkOE6Af17mpT6H4xpDPjOEt1F
11 | EPlNiZGWmA9bkVJR0iPB38ReecRiyWwRZhIG8m4WG2Zu5binOWCT+t/z/QJAWdfk
12 | 1PfZTgqH5dXQuniz6O2HsqrgGICjg9Ulj23mvkQ6z94Ss14UYzsxope0oJ0LlRJD
13 | +7GX5NE3hpMv6i9RzwJBAIZdi6bw53IsMH63KfmIBhfoXSrdma1TrLet6nwDD5b1
14 | 1nC39Y30zzIY9BXKy7Vpc/tPyQRQXfUtPfQAdSVwYWU=
15 | -----END RSA PRIVATE KEY-----
16 |
--------------------------------------------------------------------------------
/db/models/statistic.js:
--------------------------------------------------------------------------------
1 | const Sequelize = require('sequelize')
2 | const Op = Sequelize.Op
3 | const {
4 | sqlTable,sequelize
5 | } = require('../index.js')
6 |
7 | const statistic={
8 | async set_statistic(data){
9 | return sqlTable.statistic.bulkCreate(data.list)
10 | },
11 |
12 | async getToday(data) {
13 | return sequelize.query(`select w_count,p_count,w_total1,p_total1,w_total2,p_total2 from statistic where userid=? and date=?`,{
14 | type: Sequelize.QueryTypes.SELECT,
15 | replacements:[data.userid,data.day]
16 | })
17 | },
18 |
19 | async getWeek(data) {
20 | return sequelize.query(`select w_count,p_count,w_total1,p_total1,w_total2,p_total2,date from statistic where userid=? and date>=? and date<=? order by date`,{
21 | type: Sequelize.QueryTypes.SELECT,
22 | replacements:[data.userid,data.startDate,data.endDate]
23 | })
24 | },
25 |
26 | }
27 |
28 | module.exports = statistic
--------------------------------------------------------------------------------
/utils/jwt.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs')
2 | const path = require('path')
3 | const jwt = require('jsonwebtoken')
4 |
5 | class Jwt {
6 | constructor(data) {
7 | this.data = data
8 | }
9 |
10 | generateToken() {
11 | let data = this.data
12 | let now = Math.floor(Date.now() / 1000)
13 | let cert = fs.readFileSync(path.join(__dirname, '../keys/master-privatekey.pem'))
14 | let token = jwt.sign({
15 | data,
16 | exp: now + 60 * 60 / 2,
17 | }, cert, { algorithm: 'RS256' })
18 |
19 | return token
20 | }
21 |
22 | verifyToken() {
23 | let token = this.data
24 | let cert = fs.readFileSync(path.join(__dirname, '../keys/master-public.pem'))
25 | let res
26 | try {
27 | let result = jwt.verify(token, cert, { algorithm: ['RS256'] }) || {}
28 | let {exp = 0} = result, current = Math.floor(Date.now() / 1000)
29 | if (current <= exp) {
30 | res = result.data || {}
31 | }
32 | } catch (err) {
33 | res = 'err'
34 | }
35 | return res
36 | }
37 | }
38 |
39 | module.exports = Jwt
40 |
--------------------------------------------------------------------------------
/utils/sendSms.js:
--------------------------------------------------------------------------------
1 | const SMS = require('@alicloud/sms-sdk')
2 |
3 | /**
4 | * 短信相关
5 | * */
6 | const accessKeyId = 'accessKeyId'
7 | const secretAccessKey = 'secretAccessKey'
8 | const sign_name = 'sign_name'
9 |
10 | const tp1 = 'tp1' // 注册模板
11 |
12 | const sendSms = async (mobile_phone, code, type) => {
13 | let cli = new SMS({accessKeyId, secretAccessKey})
14 |
15 | try {
16 | cli.sendSMS({
17 | PhoneNumbers: mobile_phone, //必填:待发送手机号。支持以逗号分隔的形式进行批量调用,批量上限为1000个手机号码,批量调用相对于单条调用及时性稍有延迟,验证码类型的短信推荐使用单条调用的方式;发送国际/港澳台消息时,接收号码格式为00+国际区号+号码,如“0085200000000”
18 | SignName: sign_name, //必填:短信签名-可在短信控制台中找到
19 | TemplateCode: tp1, //必填:短信模板-可在短信控制台中找到,发送国际/港澳台消息时,请使用国际/港澳台短信模版
20 | TemplateParam: `{"code": "${code}"}` //可选:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}"时。
21 | }).then(res => {
22 | let {Code} = res
23 | if (Code === 'OK') {
24 | return true
25 | } else {
26 | return false
27 | }
28 | })
29 | return true
30 | } catch (err) {
31 | console.info(err,'error');
32 | }
33 | }
34 |
35 | module.exports = sendSms
36 |
37 |
--------------------------------------------------------------------------------
/utils/sendEmail.js:
--------------------------------------------------------------------------------
1 | const Mailer = require('nodemailer')
2 |
3 | // 邮箱服务
4 | const host = '';
5 | const port = 80;
6 | const user = '';
7 | const pass = '';
8 |
9 | const sendEmail = async (email, code, type) => {
10 | const transport = Mailer.createTransport({
11 | host:host, // 服务
12 | port:port, // smtp端口
13 | secureConnection: true, // 使用ssl
14 | auth: {
15 | user,
16 | pass
17 | }
18 | })
19 |
20 | try {
21 | let html1 = `
欢迎使用人人收付平台,您本次注册的验证码为
您的验证码是:${code}
请将以上验证码输入注册页面中的验证码输入框内以完成注册;
如非本人操作,请忽略
`;//注册
22 |
23 | transport.sendMail({
24 | from: user, // 发件邮箱
25 | to: email, // 收件列表
26 | subject: '来自人人收付平台的邮件', // 标题
27 | // text:'ass',
28 | html: html1 // html 内容
29 | }, function (err, data) {
30 | if (err) {
31 | console.info(err,'error');
32 | }
33 | transport.close(); // 如果没用,关闭连接池
34 | })
35 |
36 | return true
37 | } catch (err) {
38 | console.info(err,'error');
39 | }
40 | }
41 |
42 | module.exports = sendEmail
43 |
44 |
--------------------------------------------------------------------------------
/utils/callback.js:
--------------------------------------------------------------------------------
1 | let request = require('request')
2 |
3 | let callback = (callurl,data)=>{
4 | return new Promise((resolve,reject)=>{
5 | request.get({url: callurl+`?orderid=${data.orderid}&appid=${data.appid}&amount=${data.amount}&sign=${data.sign}`},(err, _, body)=>{
6 | if(err){
7 | reject();
8 | }else{
9 | resolve()
10 | }
11 | })
12 | })
13 | }
14 | let callPost = (callurl,data)=>{
15 | var options = {
16 | method: 'POST',
17 | url: callurl,
18 | form: {
19 | sign: data.sign,
20 | appid:data.appid,
21 | orderid:data.orderid,
22 | payway:data.payway,
23 | amount:data.amount
24 | },
25 | headers: {
26 | 'Content-Type': 'text/plain; charset=utf-8'
27 | },
28 | timeout: 50000
29 | };
30 | return new Promise((resolve,reject)=>{
31 | request.post(options,(err, response, body)=>{
32 | if(err){
33 | reject();
34 | }else{
35 | resolve()
36 | }
37 | })
38 | })
39 | }
40 |
41 | module.exports={
42 | callPost,
43 | callback
44 | }
--------------------------------------------------------------------------------
/db/models/payCode.js:
--------------------------------------------------------------------------------
1 | const Sequelize = require('sequelize')
2 | const Op = Sequelize.Op
3 | const {
4 | sqlTable,
5 | } = require('../index.js')
6 |
7 | const paycodes = {
8 | async addPayCode(data) {
9 | return sqlTable.paycodes.create({
10 | userid: data.userid,
11 | qrcode: data.qrcode,
12 | pay_code: data.pay_code,
13 | amount: data.amount,
14 | use_num: 0
15 | })
16 | },
17 | async getPayCode(data) {
18 | return sqlTable.paycodes.findOne({
19 | where: {
20 | userid: data.userid,
21 | amount: data.amount,
22 | pay_code:{$notIn:data.qrcode}
23 | },
24 | order: ["use_num"],
25 | }, Op.notIn[{qrcode: data.qrcode}])
26 | },
27 | async addPayCodeNum(data) {
28 | return sqlTable.paycodes.update({
29 | num: data.num + 1
30 | }, {
31 | where: {
32 | id: data.id
33 | }
34 | })
35 | },
36 | async deletePayCode(data){
37 | return sqlTable.paycodes.destroy( {
38 | where: {
39 | userid: data.userid
40 | }
41 | })
42 | }
43 | };
44 |
45 | module.exports = paycodes
46 |
--------------------------------------------------------------------------------
/db/schema/paycode.js:
--------------------------------------------------------------------------------
1 | class sqlTable {
2 | static paycodes(Sequelize) {
3 | return {
4 | id: {
5 | type: Sequelize.BIGINT,
6 | primaryKey: true,
7 | autoIncrement: true,
8 | allowNull: false
9 | },
10 | // 用户id
11 | userid: {
12 | type: Sequelize.INTEGER,
13 | allowNull: false
14 | },
15 | // 付款码
16 | qrcode: {
17 | type: Sequelize.STRING,
18 | allowNull: false
19 | },
20 | // 付款信息备注
21 | pay_code: {
22 | type: Sequelize.STRING,
23 | allowNull: false
24 | },
25 | // 金额
26 | amount: {
27 | type: Sequelize.INTEGER,
28 | allowNull: false
29 | },
30 | // 使用次数
31 | use_num: {
32 | type: Sequelize.INTEGER,
33 | defaultValue: 0
34 | }
35 | }
36 | }
37 |
38 | static publicSet() {
39 | return {
40 | freezeTableName: true,
41 | paranoid: true,
42 | timestamps: true,
43 | }
44 | }
45 | }
46 |
47 |
48 | module.exports = sqlTable
--------------------------------------------------------------------------------
/db/schema/withdraws.js:
--------------------------------------------------------------------------------
1 | class sqlTable {
2 | // columns
3 | static withdraws(Sequelize) {
4 | return {
5 | id: {
6 | type: Sequelize.BIGINT,
7 | primaryKey: true,
8 | autoIncrement: true,
9 | allowNull: false
10 | },
11 | userid: {
12 | type: Sequelize.STRING,
13 | allowNull: false,
14 | },
15 | uuid: {
16 | type: Sequelize.STRING,
17 | allowNull: false,
18 | unique: true
19 | },
20 | type: {
21 | type: Sequelize.STRING,
22 | allowNull: false,
23 | unique: true
24 | },
25 | amount: {
26 | type: Sequelize.FLOAT
27 | },
28 | memo: {
29 | type: Sequelize.STRING
30 | },
31 | status: {
32 | type: Sequelize.TINYINT(1),
33 | defaultValue: 1
34 | }
35 | }
36 | }
37 |
38 | static publicSet() {
39 | return {
40 | freezeTableName: true,
41 | paranoid: true,
42 | timestamps: true,
43 | }
44 | }
45 | }
46 |
47 | module.exports = sqlTable
48 |
--------------------------------------------------------------------------------
/db/schema/trades.js:
--------------------------------------------------------------------------------
1 | class sqlTable {
2 | // 系统商品表
3 | static trades(Sequelize) {
4 | return {
5 | id: {
6 | type: Sequelize.BIGINT,
7 | primaryKey: true,
8 | autoIncrement: true,
9 | allowNull: false
10 | },
11 | name: { // 产品名称
12 | type: Sequelize.STRING,
13 | allowNull: false,
14 | },
15 | amount: { // 产品金额
16 | type: Sequelize.INTEGER,
17 | allowNull: false
18 | },
19 | create_account_id: {
20 | type: Sequelize.INTEGER,
21 | allowNull: false
22 | },
23 | desc: { // 商品描述
24 | type: Sequelize.STRING,
25 | allowNull: false
26 | },
27 | day: { //充值天数
28 | type: Sequelize.INTEGER,
29 | defaultValue: 0
30 | },
31 | lv: { //充值等级
32 | type: Sequelize.INTEGER,
33 | defaultValue: 0
34 | }
35 | }
36 | };
37 |
38 | static publicSet() {
39 | return {
40 | freezeTableName: true,
41 | paranoid: true,
42 | timestamps: true,
43 | };
44 | }
45 | }
46 |
47 | module.exports = sqlTable;
--------------------------------------------------------------------------------
/conf/default.js:
--------------------------------------------------------------------------------
1 | const _ = require('lodash')
2 |
3 | let config = {
4 | port: 3000,
5 | db: {
6 | host: process.env.host || '127.0.0.1',
7 | port: process.env.port || 3306,
8 | db: process.env.db ||'db_renrenpay',
9 | dialect: 'mysql',
10 | user: process.env.username || 'root',
11 | password: process.env.password || '123456'
12 | },
13 | redis: {
14 | host: '127.0.0.1',
15 | port: 6379
16 | },
17 | websocket: {
18 | port: 7234
19 | },
20 | appid: process.env.appid || '15c821df1e52',
21 | adminPwd: process.env.adminpwd || '123456',
22 | userid: '1',
23 | pay_userid: process.env.pay_userid ||'2088112172418889'
24 | }
25 |
26 | const init = () => {
27 | if (process.env.NODE_ENV === 'development') {
28 | const localConfig = {
29 | db: _.extend(config.db, {
30 | user: config.user,
31 | password: db.password
32 | })
33 | }
34 | config = _.extend(config, localConfig)
35 | }
36 |
37 | if (process.env.NODE_ENV === 'production') {
38 | const localConfig = {
39 | db: _.extend(config.db, {
40 | user: '',
41 | password: ''
42 | })
43 | }
44 | config = _.extend(config, localConfig)
45 | }
46 |
47 | return config
48 | }
49 |
50 | module.exports = init()
51 |
--------------------------------------------------------------------------------
/views/404.ejs:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 404
6 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |

56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
--------------------------------------------------------------------------------
/db/models/trades.js:
--------------------------------------------------------------------------------
1 | const Sequelize = require('sequelize')
2 | const Op = Sequelize.Op
3 | const {
4 | sqlTable,
5 | } = require('../index.js')
6 | const trades = {
7 | //添加充值订单
8 | async addTrades(data) {
9 | return sqlTable.trades.create({
10 | name: data.name,
11 | amount: data.amount,
12 | create_account_id: data.userid,
13 | desc: data.desc,
14 | day: data.day,
15 | lv: data.lv
16 | });
17 | },
18 | // 修改商品
19 | async modifyTrades(data) {
20 | return sqlTable.trades.update(data, {
21 | where: {
22 | id: data.tradeid
23 | }
24 | })
25 | },
26 | /**
27 | * deleteTrades
28 | * 删除商品
29 | * */
30 | async deleteTrades(data) {
31 | return sqlTable.trades.destroy({
32 | where: {
33 | id: data.tradeid
34 | }
35 | })
36 | },
37 | /**
38 | * 查询订单列表
39 | * start 开始条数
40 | * size 查询页面大小
41 | */
42 | async getTrades(data) {
43 | return sqlTable.trades.findAndCountAll({
44 | attributes:[['id', 'tradeid'], 'name', 'desc', 'amount', 'day', 'lv'],
45 | limit: data.page_size * 1,
46 | offset: data.start
47 | })
48 | },
49 | /**
50 | * 查找指定的商品
51 | * */
52 | async findTradeById(trade_id) {
53 | return sqlTable.trades.findById(trade_id);
54 | }
55 | };
56 |
57 | module.exports = trades;
--------------------------------------------------------------------------------
/db/schema/deposits.js:
--------------------------------------------------------------------------------
1 | class sqlTable {
2 | // columns
3 | static deposits(Sequelize) {
4 | return {
5 | id: {
6 | type: Sequelize.BIGINT,
7 | primaryKey: true,
8 | autoIncrement: true,
9 | allowNull: false
10 | },
11 | userid: {
12 | type: Sequelize.STRING,
13 | allowNull: false,
14 | },
15 | orderid: {
16 | type: Sequelize.STRING,
17 | allowNull: false,
18 | unique: true
19 | },
20 | tradeid: {
21 | type: Sequelize.INTEGER,
22 | allowNull: false,
23 | defaultValue: 0
24 | },
25 | //1支付宝充值,2微信充值,3购买会员,4平台消费
26 | type: {
27 | type: Sequelize.TINYINT(6),
28 | allowNull: false,
29 | },
30 | amount: {//
31 | type: Sequelize.INTEGER
32 | },
33 | memo: {
34 | type: Sequelize.STRING
35 | },
36 | status: {//0生成订单 1订单成功
37 | type: Sequelize.TINYINT(1),
38 | defaultValue: 1
39 | }
40 | }
41 | }
42 |
43 | static publicSet() {
44 | return {
45 | freezeTableName: true,
46 | paranoid: true,
47 | timestamps: true,
48 | }
49 | }
50 | }
51 |
52 | module.exports = sqlTable
53 |
--------------------------------------------------------------------------------
/db/schema/paychecks.js:
--------------------------------------------------------------------------------
1 | class sqlTable {
2 | static paychecks(Sequelize){
3 | return {
4 | id: {
5 | type: Sequelize.BIGINT,
6 | primaryKey: true,
7 | autoIncrement: true,
8 | allowNull: false
9 | },
10 | userid: {//用户id
11 | type: Sequelize.STRING,
12 | allowNull: false,
13 | },
14 | appid: {//
15 | type: Sequelize.STRING,
16 | },
17 | orderid: {//订单的id
18 | type:Sequelize.STRING,
19 | unique: true
20 | },
21 | transid:{//支付宝,微信平台获取的交易id
22 | type: Sequelize.STRING,
23 | unique: true
24 | },
25 | amount: {//金额
26 | type: Sequelize.FLOAT,
27 | defaultValue: 0.0
28 | },
29 | payway:{//收款方式
30 | type: Sequelize.TINYINT(1),
31 | defaultValue: 1
32 | },
33 | memo:{//备注
34 | type:Sequelize.STRING
35 | },
36 | status: {//订单状态
37 | type: Sequelize.TINYINT(1),
38 | defaultValue: 1,
39 | }
40 | }
41 | }
42 | static publicSet() {
43 | return {
44 | freezeTableName: true,
45 | paranoid: true,
46 | timestamps: true,
47 | }
48 | }
49 | }
50 |
51 | module.exports = sqlTable
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "renrenpay",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "start": "node bin/www",
7 | "dev": "./node_modules/.bin/nodemon bin/www",
8 | "prd": "pm2 start bin/www",
9 | "test": "echo \"Error: no test specified\" && exit 1"
10 | },
11 | "dependencies": {
12 | "@alicloud/sms-sdk": "^1.1.6",
13 | "async": "^2.6.2",
14 | "debug": "^2.6.3",
15 | "decimal.js": "^10.1.1",
16 | "ejs": "~2.3.3",
17 | "ioredis": "^4.9.0",
18 | "jsonwebtoken": "^8.5.0",
19 | "koa": "^2.2.0",
20 | "koa-bodyparser": "^3.2.0",
21 | "koa-convert": "^1.2.0",
22 | "koa-cors": "0.0.16",
23 | "koa-json": "^2.0.2",
24 | "koa-logger": "^2.0.1",
25 | "koa-onerror": "^1.2.1",
26 | "koa-router": "^7.1.1",
27 | "koa-session": "^5.10.1",
28 | "koa-simple-router": "^0.2.0",
29 | "koa-static": "^3.0.0",
30 | "koa-views": "^5.2.1",
31 | "lodash": "^4.17.11",
32 | "log4js": "^4.0.2",
33 | "mysql2": "^1.6.5",
34 | "nanoid": "^2.0.1",
35 | "node-fetch": "^2.3.0",
36 | "node-schedule": "^1.3.2",
37 | "nodemailer": "^5.1.1",
38 | "redis": "^2.8.0",
39 | "request": "^2.88.0",
40 | "sequelize": "^4.43.0",
41 | "shelljs": "^0.8.3",
42 | "uuid": "^3.3.2",
43 | "websocket": "^1.0.28"
44 | },
45 | "devDependencies": {
46 | "babel-core": "^6.26.3",
47 | "babel-preset-es2015": "^6.24.1",
48 | "cross-env": "^5.2.0",
49 | "gulp": "^4.0.0",
50 | "gulp-babel": "^8.0.0",
51 | "nodemon": "^1.8.1"
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/db/schema/apps.js:
--------------------------------------------------------------------------------
1 | class sqlTable {
2 | // columns
3 | static apps(Sequelize) {
4 | return {
5 | id: {
6 | type: Sequelize.BIGINT,
7 | primaryKey: true,
8 | autoIncrement: true,
9 | allowNull: false
10 | },
11 | userid: {
12 | type: Sequelize.STRING,
13 | allowNull: false,
14 | },
15 | name: {
16 | type: Sequelize.STRING,
17 | allowNull: false
18 | // unique: true
19 | },
20 | callback_url: {
21 | type: Sequelize.STRING
22 | },
23 | whitelist: {
24 | type: Sequelize.STRING
25 | },
26 | appid: {
27 | type: Sequelize.STRING,
28 | allowNull: false,
29 | unique: true
30 | },
31 | appsecret: {
32 | type: Sequelize.STRING,
33 | allowNull: false,
34 | },
35 | pay_userid:{
36 | type: Sequelize.STRING,
37 | // allowNull: false
38 | },
39 | status: {
40 | type: Sequelize.TINYINT(1),
41 | defaultValue: 1
42 | }
43 | }
44 | }
45 |
46 | static publicSet() {
47 | return {
48 | freezeTableName: true,
49 | paranoid: true,
50 | timestamps: true,
51 | }
52 | }
53 | }
54 |
55 | module.exports = sqlTable
56 |
--------------------------------------------------------------------------------
/db/schema/orders.js:
--------------------------------------------------------------------------------
1 | class sqlTable {
2 | static orders(Sequelize){
3 | return {
4 | id: {
5 | type: Sequelize.BIGINT,
6 | primaryKey: true,
7 | autoIncrement: true,
8 | allowNull: false
9 | },
10 | userid: {
11 | type: Sequelize.STRING,
12 | },
13 | appid: {//用户应用的id
14 | type: Sequelize.STRING,
15 | },
16 | orderid: {//订单的id
17 | type:Sequelize.STRING,
18 | unique: true
19 | },
20 | amount: {//金额
21 | type: Sequelize.BIGINT,
22 | defaultValue: 0.0
23 | },
24 | payway:{//1支付宝,2微信
25 | type: Sequelize.INTEGER,
26 | defaultValue: 1
27 | },
28 | qrcode:{
29 | type:Sequelize.STRING,
30 | },
31 | memo:{//备注
32 | type:Sequelize.STRING
33 | },
34 | state:{//0生成订单,订单成功
35 | type: Sequelize.TINYINT(1),
36 | defaultValue: 0
37 | },
38 | //付款码备注
39 | pay_code: {
40 | type:Sequelize.STRING,
41 | allowNull: false
42 | }
43 | }
44 | }
45 | static publicSet() {
46 | return {
47 | freezeTableName: true,
48 | paranoid: true,
49 | timestamps: true,
50 | }
51 | }
52 | }
53 |
54 | module.exports = sqlTable
--------------------------------------------------------------------------------
/public/dist/static/css/chunk-0224.f01dfcab.css:
--------------------------------------------------------------------------------
1 | .login-container .el-input{display:inline-block;height:47px;width:85%}.login-container .el-input input{background:transparent;border:0;-webkit-appearance:none;border-radius:0;padding:12px 5px 12px 15px;color:#eee;height:47px}.login-container .el-input input:-webkit-autofill{-webkit-box-shadow:0 0 0 1000px #2d3a4b inset!important;-webkit-text-fill-color:#fff!important}.login-container .el-form-item{border:1px solid hsla(0,0%,100%,.1);background:rgba(0,0,0,.1);border-radius:5px;color:#454545}.login-container[data-v-b6901faa]{position:fixed;height:100%;width:100%;background-color:#2d3a4b;background:url(/static/img/bg.cf0887a.jpg) no-repeat;background-size:100% 100%}.login-container .login-form[data-v-b6901faa]{position:absolute;top:20%;left:50%;right:0;width:520px;max-width:100%;-webkit-transform:translate(-50%);transform:translate(-50%);padding:35px 35px 15px;background:rgba(0,0,0,.3);border-radius:8px}.login-container .tips[data-v-b6901faa]{font-size:14px;color:#fff;margin-bottom:10px}.login-container .tips a[data-v-b6901faa]{color:#409eff}.login-container .tips-line[data-v-b6901faa]{color:hsla(0,0%,100%,.8);margin:0 10px}.login-container .svg-container[data-v-b6901faa]{padding:6px 5px 6px 15px;color:#889aa4;vertical-align:middle;width:30px;display:inline-block}.login-container .title[data-v-b6901faa]{font-size:26px;font-weight:400;color:#eee;margin:0 auto 40px;text-align:center;font-weight:700}.login-container .show-pwd[data-v-b6901faa]{position:absolute;right:10px;top:7px;font-size:16px;color:#889aa4;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}
--------------------------------------------------------------------------------
/app.js:
--------------------------------------------------------------------------------
1 | const Koa = require('koa')
2 | const app = new Koa()
3 | const router = require('koa-simple-router')
4 | const views = require('koa-views')
5 | const json = require('koa-json')
6 | const onerror = require('koa-onerror')
7 | const bodyparser = require('koa-bodyparser')
8 | const logger = require('koa-logger')
9 | const cors = require('koa-cors')
10 | const errorHandler = require('./utils/errorHandler.js')
11 | const controllers = require('./controllers/index.js');
12 | let websocket = require('./utils/websocket.js');
13 | const events = require('events');
14 | let event = new events.EventEmitter();
15 | require('./utils/statistic.js').scheduleCronstyle()
16 | let socket = new websocket();
17 |
18 | require('./db/index.js')
19 | require('./init');
20 | // error handler
21 | onerror(app)
22 |
23 | // middlewares
24 | app.use(cors())
25 | app.use(bodyparser({
26 | enableTypes:['json', 'form', 'text']
27 | }))
28 | app.use(json())
29 | app.use(logger())
30 | app.use(require('koa-static')(__dirname + '/public/dist'))
31 |
32 | app.use(views(__dirname + '/views', {
33 | extension: 'ejs'
34 | }))
35 |
36 | // logger
37 | app.use(async (ctx, next) => {
38 | const start = new Date()
39 | await next()
40 | const ms = new Date() - start
41 |
42 | if ((/\/api\/*/).test(ctx.url)){
43 | console.log(`${ctx.method} ${ctx.url} - ${ms}ms`)
44 | // await next()
45 | // return
46 | }
47 |
48 | })
49 |
50 |
51 | // error handler
52 | errorHandler.error(app)
53 | // routers
54 | controllers.getAllRouters(app, router,socket,event)
55 |
56 | // error-handling
57 | app.on('error', (err, ctx) => {
58 | console.error('server error', err, ctx)
59 | });
60 |
61 | module.exports = app
62 |
--------------------------------------------------------------------------------
/utils/verifyParams.js:
--------------------------------------------------------------------------------
1 | const nonEmpty = data => {
2 | if (typeof data == 'number') {
3 | return true
4 | }
5 |
6 | if (typeof data == 'boolean') {
7 | return true
8 | }
9 |
10 | if (data && data.length > 0) {
11 | return true
12 | }
13 |
14 | return false
15 | }
16 |
17 | const verifyParams = async (data, ...params) => {
18 | let result = true
19 |
20 | params.forEach(item => {
21 | if (item === 'mobile_phone_or_email') {
22 | result = nonEmpty(data['mobile_phone']) || nonEmpty(data['email'])
23 | } else if (item === 'lv') {
24 | if (nonEmpty(data['lv'])) {
25 | if (parseInt(data['lv']) === 1 ||
26 | parseInt(data['lv']) === 2) {
27 | result = true
28 | } else {
29 | result = false
30 | }
31 | } else {
32 | result = false
33 | }
34 | } else if (item === 'membership_expired') {
35 | if (nonEmpty(data['membership_expired'])) {
36 | if (parseInt(data['membership_expired']) === 30 ||
37 | parseInt(data['membership_expired']) === 90 ||
38 | parseInt(data['membership_expired']) === 180 ||
39 | parseInt(data['membership_expired']) === 365) {
40 | result = true
41 | } else {
42 | result = false
43 | }
44 | } else {
45 | result = false
46 | }
47 | } else if (!nonEmpty(data[item])) {
48 | result = false
49 | }
50 | })
51 |
52 | return result
53 | }
54 |
55 | module.exports = verifyParams
56 |
--------------------------------------------------------------------------------
/public/dist/static/css/chunk-26f3.a8b3c6c5.css:
--------------------------------------------------------------------------------
1 | .membership-comp.edit .combo-item:hover .item-del[data-v-1fb68bb0]{-webkit-transform:translate(0);transform:translate(0)}.membership-comp .dead-line[data-v-1fb68bb0]{margin:15px 0}.membership-comp .dead-line .dead-line_member[data-v-1fb68bb0]{color:#e6a23c;margin-left:10px}.membership-comp .dead-line .dead-line_primary[data-v-1fb68bb0]{color:#333;margin-left:10px}.membership-comp .dead-line .dead-line_desc[data-v-1fb68bb0]{margin-left:10px;color:#909399;font-size:12px}.membership-comp .combo-list[data-v-1fb68bb0]{font-size:0;margin-left:-20px}.membership-comp .combo-item[data-v-1fb68bb0]{display:inline-block;width:150px;height:150px;padding:0 10px;border:1px solid #e4e7ed;border-radius:4px;text-align:center;overflow:hidden;margin-left:20px;cursor:pointer;position:relative}.membership-comp .combo-item.active[data-v-1fb68bb0]{border:1px solid #f56c6c}.membership-comp .combo-plus[data-v-1fb68bb0]{font-size:40px;line-height:150px;color:#e4e7ed}.membership-comp .item-title[data-v-1fb68bb0]{height:50px;line-height:50px;border-bottom:1px dashed #dcdfe6;font-size:18px;color:#333}.membership-comp .item-num[data-v-1fb68bb0]{font-size:18px;margin-top:15px}.membership-comp .primary[data-v-1fb68bb0]{font-size:30px;color:#f56c6c;font-weight:700;margin-right:5px}.membership-comp .item-desc[data-v-1fb68bb0]{font-size:14px;margin-top:15px}.membership-comp .item-del[data-v-1fb68bb0]{position:absolute;top:0;left:0;right:0;bottom:0;z-index:9;background:rgba(0,0,0,.8);text-align:center;font-size:30px;color:hsla(0,0%,100%,.7);padding:0 15px;-webkit-transform:translateY(100%);transform:translateY(100%);-webkit-transition:all .3s;transition:all .3s}.membership-comp .item-del div[data-v-1fb68bb0]{height:75px;line-height:75px;cursor:pointer}.membership-comp .item-del div[data-v-1fb68bb0]:first-child{border-bottom:1px dashed hsla(0,0%,100%,.3)}
--------------------------------------------------------------------------------
/db/sqlTable.js:
--------------------------------------------------------------------------------
1 | const appsTable = require('./schema/apps.js')
2 | const depositsTable = require('./schema/deposits.js')
3 | const usersTable = require('./schema/users.js')
4 | const withdrawsTable = require('./schema/withdraws.js')
5 | const ordersTable = require('./schema/orders.js')
6 | const paychecksTable = require('./schema/paychecks.js')
7 | const paycodeTable = require('./schema/paycode.js')
8 | const tradesTable = require('./schema/trades.js')
9 | const logsTable = require('./schema/logs.js')
10 | const statisticTable = require('./schema/statistic.js')
11 |
12 | class sqlTable {
13 | constructor(Sequelize, sequelize) {
14 | this.apps = sequelize.define('apps', appsTable.apps(Sequelize), appsTable.publicSet())
15 | this.deposits = sequelize.define('deposits', depositsTable.deposits(Sequelize), depositsTable.publicSet())
16 | this.users = sequelize.define('users', usersTable.users(Sequelize), usersTable.publicSet())
17 | this.withdraws = sequelize.define('withdraws', withdrawsTable.withdraws(Sequelize), withdrawsTable.publicSet())
18 | this.orders = sequelize.define('orders', ordersTable.orders(Sequelize), ordersTable.publicSet())
19 | this.paychecks = sequelize.define('paychecks', paychecksTable.paychecks(Sequelize), paychecksTable.publicSet())
20 | this.paycodes = sequelize.define('paycodes', paycodeTable.paycodes(Sequelize), paycodeTable.publicSet())
21 | this.trades = sequelize.define('trades', tradesTable.trades(Sequelize), tradesTable.publicSet())
22 | this.logs = sequelize.define('logs', logsTable.logs(Sequelize), logsTable.publicSet())
23 | this.statistic = sequelize.define('statistic', statisticTable.statistic(Sequelize),statisticTable.publicSet())
24 | sequelize.sync({
25 | logging: false
26 | })
27 | }
28 | }
29 |
30 | module.exports = sqlTable
31 |
--------------------------------------------------------------------------------
/db/models/deposits.js:
--------------------------------------------------------------------------------
1 | const Sequelize = require('sequelize')
2 | const {
3 | sqlTable,
4 | } = require('../index.js')
5 |
6 | const deposits = {
7 | async addDeposit(data) {
8 | return sqlTable.deposits.create({
9 | userid: data.userid,
10 | orderid: data.orderid,
11 | type: data.type || 0,
12 | amount: data.amount || 0,
13 | memo: data.memo || data.pay_code || data.orderid || '',
14 | status:data.status || 0
15 | })
16 | },
17 |
18 | async updateDepositInfo(data) {
19 | return sqlTable.deposits.update({
20 | status: data.status || 0
21 | }, {
22 | where: {
23 | orderid: data.orderid || '0',
24 | }
25 | })
26 | },
27 |
28 | async getDepositList(data) {
29 | let limit = data.page_size*1;
30 | let offset = data.page_size * (data.page - 1);
31 | let w = {};
32 | if(data.state == 1){//充值的记录
33 | w = {
34 | userid: data.userid,
35 | status:1,
36 | $or:[{type:1},{type:2}]
37 | }
38 | }else if(data.state == 2){ //购买会员的记录
39 | w = {
40 | userid: data.userid,
41 | status:1,
42 | type:3
43 | }
44 | }else if(data.state == 3){//手续费记录
45 | w = {
46 | userid: data.userid,
47 | status:1,
48 | type:4
49 | }
50 | }else{
51 | w = {
52 | userid: data.userid,
53 | status:1
54 | }
55 | }
56 | return sqlTable.deposits.findAndCountAll({
57 | limit,
58 | offset,
59 | where: w
60 | })
61 | },
62 |
63 | }
64 |
65 | module.exports = deposits
66 |
--------------------------------------------------------------------------------
/public/dist/static/css/chunk-fc3b.b79580c9.css:
--------------------------------------------------------------------------------
1 | .login-container .el-input{height:47px;width:85%}.login-container .el-input input{background:transparent;border:0;-webkit-appearance:none;border-radius:0;padding:12px 5px 12px 15px;color:#eee;height:47px}.login-container .el-input input:-webkit-autofill{-webkit-box-shadow:0 0 0 1000px #2d3a4b inset!important;-webkit-text-fill-color:#fff!important}.login-container .el-form-item{border:1px solid hsla(0,0%,100%,.1);background:rgba(0,0,0,.1);border-radius:5px;color:#454545}.login-container .el-input-group__append{background:transparent;color:#eee;border:none}.login-container[data-v-b89682e8]{position:fixed;height:100%;width:100%;background-color:#2d3a4b;background:url(/static/img/bg.cf0887a.jpg) no-repeat;background-size:100% 100%}.login-container .login-form[data-v-b89682e8]{position:absolute;top:20%;left:50%;right:0;-webkit-transform:translate(-50%);transform:translate(-50%);width:520px;max-width:100%;padding:35px 35px 15px;background:rgba(0,0,0,.3);border-radius:8px}.login-container .verify-btn[data-v-b89682e8]{position:absolute;z-index:9;right:20px;top:50%;color:#fff;-webkit-transform:translateY(-50%);transform:translateY(-50%);cursor:pointer;text-align:right}.login-container .tips[data-v-b89682e8]{font-size:14px;color:#fff;margin-bottom:10px}.login-container .tips a[data-v-b89682e8]{color:#409eff}.login-container .tips-line[data-v-b89682e8]{color:hsla(0,0%,100%,.5);margin:0 10px}.login-container .svg-container[data-v-b89682e8]{padding:6px 5px 6px 15px;color:#889aa4;vertical-align:middle;width:30px;display:inline-block}.login-container .title[data-v-b89682e8]{font-size:26px;font-weight:400;color:#eee;margin:0 auto 40px;text-align:center;font-weight:700}.login-container .show-pwd[data-v-b89682e8]{position:absolute;right:10px;top:7px;font-size:16px;color:#889aa4;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}
--------------------------------------------------------------------------------
/db/models/paychecks.js:
--------------------------------------------------------------------------------
1 | const Sequelize = require('sequelize')
2 | const {
3 | sqlTable,sequelize
4 | } = require('../index.js')
5 |
6 | const paychecks = {
7 | async addPaychecks(data){
8 | return sqlTable.paychecks.create({
9 | userid:data.userid || '',
10 | appid:data.appid || '',
11 | orderid:data.orderid || null,
12 | amount:data.amount || 0,
13 | payway:data.payway || 1,
14 | memeo:data.memeo || '',
15 | transid:data.transid || null
16 | })
17 | },
18 |
19 | async getList(data){
20 | let limit = data.page_size*1;
21 | let offset = data.page_size * (data.page - 1);
22 | let w = {}
23 | if(data.state*1 === 1){//订单支付成功来源
24 | w = {
25 | userid: data.userid,
26 | orderid:{$ne:null},
27 | }
28 | }else if(data.state*1 === 0){ //其他来源
29 | w = {
30 | userid: data.userid,
31 | orderid:{$eq:null}
32 | }
33 | }else{
34 | w = {
35 | userid: data.userid
36 | }
37 | }
38 | return sqlTable.paychecks.findAndCountAll({
39 | limit,
40 | offset,
41 | order: [['createdAt', 'DESC']] ,
42 | where: w
43 | })
44 | },
45 |
46 | async totalAmount(data){
47 | // return sequelize.query(`select amount,payway,appid from paychecks where userid=? and dayofyear(createdAt)=?`,{
48 | return sequelize.query(`SELECT amount,payway,appid FROM paychecks WHERE userid=? and DATE_FORMAT( createdAt,'%Y-%m-%d') = DATE_FORMAT(CURDATE(),'%Y-%m-%d') ORDER BY createdAt DESC;`,{
49 | type:Sequelize.QueryTypes.SELECT,
50 | replacements:[data.userid],
51 | })
52 | },
53 | }
54 | module.exports = paychecks
--------------------------------------------------------------------------------
/public/dist/static/css/chunk-3200.6e36a35c.css:
--------------------------------------------------------------------------------
1 | .forget-container .el-input{height:47px;width:85%}.forget-container .el-input input{background:transparent;border:0;-webkit-appearance:none;border-radius:0;padding:12px 5px 12px 15px;color:#eee;height:47px}.forget-container .el-input input:-webkit-autofill{-webkit-box-shadow:0 0 0 1000px #2d3a4b inset!important;-webkit-text-fill-color:#fff!important}.forget-container .el-form-item{border:1px solid hsla(0,0%,100%,.1);background:rgba(0,0,0,.1);border-radius:5px;color:#454545}.forget-container .el-input-group__append{background:transparent;color:#eee;border:none}.forget-container[data-v-6227c914]{position:fixed;height:100%;width:100%;background-color:#2d3a4b;background:url(/static/img/bg.cf0887a.jpg) no-repeat;background-size:100% 100%}.forget-container .login-form[data-v-6227c914]{position:absolute;top:20%;left:50%;right:0;-webkit-transform:translate(-50%);transform:translate(-50%);width:520px;max-width:100%;padding:35px 35px 15px;background:rgba(0,0,0,.3);border-radius:8px}.forget-container .verify-btn[data-v-6227c914]{position:absolute;z-index:9;right:20px;top:50%;color:#fff;-webkit-transform:translateY(-50%);transform:translateY(-50%);cursor:pointer;text-align:right}.forget-container .tips[data-v-6227c914]{font-size:14px;color:#fff;margin-bottom:10px}.forget-container .tips a[data-v-6227c914]{color:#409eff}.forget-container .tips-line[data-v-6227c914]{color:hsla(0,0%,100%,.5);margin:0 10px}.forget-container .svg-container[data-v-6227c914]{padding:6px 5px 6px 15px;color:#889aa4;vertical-align:middle;width:30px;display:inline-block}.forget-container .title[data-v-6227c914]{font-size:26px;font-weight:400;color:#eee;margin:0 auto 40px;text-align:center;font-weight:700}.forget-container .show-pwd[data-v-6227c914]{position:absolute;right:10px;top:7px;font-size:16px;color:#889aa4;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}
--------------------------------------------------------------------------------
/db/schema/statistic.js:
--------------------------------------------------------------------------------
1 | class sqlTable {
2 | static statistic(Sequelize) {
3 | return {
4 | id: {
5 | type: Sequelize.BIGINT,
6 | primaryKey: true,
7 | autoIncrement: true,
8 | allowNull: false
9 | },
10 | userid: {
11 | type: Sequelize.STRING,
12 | allowNull: false,
13 | },
14 | appid:{
15 | type: Sequelize.STRING,
16 | // allowNull: false,
17 | },
18 | w_count:{//微信订单数量
19 | type: Sequelize.BIGINT,
20 | defaultValue: 0,
21 | },
22 | p_count:{//支付宝订单数量
23 | type: Sequelize.BIGINT,
24 | defaultValue: 0,
25 | },
26 | w_total1:{//微信已知来源总额
27 | type: Sequelize.BIGINT,
28 | defaultValue: 0,
29 | },
30 | p_total1:{//支付宝已知来源总额
31 | type: Sequelize.BIGINT,
32 | defaultValue: 0,
33 | },
34 | w_total2:{//微信未知来源总额
35 | type: Sequelize.BIGINT,
36 | defaultValue: 0,
37 | },
38 | p_total2:{//支付宝未知来源总额
39 | type: Sequelize.BIGINT,
40 | defaultValue: 0,
41 | },
42 | // payway:{
43 | // type: Sequelize.TINYINT(1),
44 | // // defaultValue: 1
45 | // },
46 | // status:{
47 | // type: Sequelize.TINYINT(1),
48 | // defaultValue: 1
49 | // },
50 | date:{
51 | type: Sequelize.STRING,
52 | }
53 | }
54 | }
55 | static publicSet() {
56 | return {
57 | freezeTableName: true,
58 | paranoid: true,
59 | timestamps: true,
60 | }
61 | }
62 | }
63 |
64 | module.exports = sqlTable
--------------------------------------------------------------------------------
/bin/www:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | /**
4 | * Module dependencies.
5 | */
6 |
7 | var app = require('../app');
8 | var debug = require('debug')('demo:server');
9 | var http = require('http');
10 | var config = require('../conf/default.js')
11 |
12 | /**
13 | * Get port from environment and store in Express.
14 | */
15 |
16 | var port = normalizePort(process.env.PORT || config.port);
17 | // app.set('port', port);
18 |
19 | /**
20 | * Create HTTP server.
21 | */
22 |
23 | var server = http.createServer(app.callback());
24 |
25 | /**
26 | * Listen on provided port, on all network interfaces.
27 | */
28 |
29 | server.listen(port);
30 | server.on('error', onError);
31 | server.on('listening', onListening);
32 |
33 | /**
34 | * Normalize a port into a number, string, or false.
35 | */
36 |
37 | function normalizePort(val) {
38 | var port = parseInt(val, 10);
39 |
40 | if (isNaN(port)) {
41 | // named pipe
42 | return val;
43 | }
44 |
45 | if (port >= 0) {
46 | // port number
47 | return port;
48 | }
49 |
50 | return false;
51 | }
52 |
53 | /**
54 | * Event listener for HTTP server "error" event.
55 | */
56 |
57 | function onError(error) {
58 | if (error.syscall !== 'listen') {
59 | throw error;
60 | }
61 |
62 | var bind = typeof port === 'string'
63 | ? 'Pipe ' + port
64 | : 'Port ' + port;
65 |
66 | // handle specific listen errors with friendly messages
67 | switch (error.code) {
68 | case 'EACCES':
69 | console.error(bind + ' requires elevated privileges');
70 | process.exit(1);
71 | break;
72 | case 'EADDRINUSE':
73 | console.error(bind + ' is already in use');
74 | process.exit(1);
75 | break;
76 | default:
77 | throw error;
78 | }
79 | }
80 |
81 | /**
82 | * Event listener for HTTP server "listening" event.
83 | */
84 |
85 | function onListening() {
86 | var addr = server.address();
87 | var bind = typeof addr === 'string'
88 | ? 'pipe ' + addr
89 | : 'port ' + addr.port;
90 | console.log('Listening on ' + bind);
91 | }
92 |
--------------------------------------------------------------------------------
/db/models/orders.js:
--------------------------------------------------------------------------------
1 | const Sequelize = require('sequelize')
2 | const {
3 | sqlTable,
4 | } = require('../index.js')
5 |
6 | const orders = {
7 | async addOrder(data) {
8 | return sqlTable.orders.create({
9 | userid: data.userid,
10 | appid: data.appid,
11 | orderid: data.orderid || '',
12 | amount: data.amount || '',
13 | payway: data.payway || '',
14 | memo:data.memo || '',
15 | qrcode:data.qrcode || '',
16 | pay_code: data.pay_code || ''
17 | })
18 | },
19 |
20 | async findOne(data){
21 | return sqlTable.orders.findOne({
22 | where:{orderid:data.orderid}
23 | })
24 | },
25 |
26 | async findOne2(data){
27 | return sqlTable.orders.findOne({
28 | where:{memo:data.memo,userid:data.userid}
29 | })
30 | },
31 |
32 | async update(data){
33 | return sqlTable.orders.update({
34 | qrcode:data.qrcode
35 | },{
36 | where:{
37 | orderid:data.orderid
38 | }
39 | })
40 | },
41 |
42 | async update2(data){
43 | return sqlTable.orders.update({
44 | state:1
45 | },{
46 | where:{
47 | orderid:data.orderid
48 | }
49 | })
50 | },
51 |
52 | async getList(data){
53 | let limit = data.page_size*1;
54 | let offset = data.page_size * (data.page - 1);
55 | let w = {}
56 | if(data.state === 0){
57 | w = {
58 | userid: data.userid,
59 | status:0
60 | }
61 | }else if(data.state === 1){
62 | w = {
63 | userid: data.userid,
64 | status:1
65 | }
66 | }else{
67 | w = {
68 | userid: data.userid
69 | }
70 | }
71 | return sqlTable.deposits.findAndCountAll({
72 | limit,
73 | offset,
74 | where: w
75 | })
76 | }
77 | }
78 |
79 | module.exports=orders
--------------------------------------------------------------------------------
/db/schema/users.js:
--------------------------------------------------------------------------------
1 | class sqlTable {
2 | // columns
3 | static users(Sequelize) {
4 | return {
5 | id: {
6 | type: Sequelize.BIGINT,
7 | primaryKey: true,
8 | autoIncrement: true,
9 | allowNull: false
10 | },
11 | mobile_phone: {
12 | type: Sequelize.STRING,
13 | unique: true
14 | },
15 | email: {
16 | type: Sequelize.STRING,
17 | unique: true
18 | },
19 | password: {
20 | type: Sequelize.STRING,
21 | allowNull: false,
22 | },
23 | salt: {
24 | type: Sequelize.STRING,
25 | defaultValue: ''
26 | },
27 | balance: {
28 | type: Sequelize.BIGINT,
29 | defaultValue: 100
30 | },
31 | lv: {
32 | type: Sequelize.INTEGER,
33 | allowNull: false,
34 | defaultValue: 0
35 | },
36 | membership_expired: {
37 | type: Sequelize.BIGINT(13),
38 | defaultValue: 0
39 | },
40 | status: {
41 | type: Sequelize.TINYINT(1),
42 | defaultValue: 1
43 | },
44 | nickname: {
45 | type: Sequelize.STRING,
46 | defaultValue: ''
47 | },
48 | weixin: {
49 | type: Sequelize.STRING,
50 | defaultValue: ''
51 | },
52 | qq: {
53 | type: Sequelize.STRING,
54 | defaultValue: ''
55 | },
56 | address: {
57 | type: Sequelize.STRING,
58 | defaultValue: ''
59 | }
60 | }
61 | }
62 |
63 | static publicSet() {
64 | return {
65 | freezeTableName: true,
66 | paranoid: true,
67 | timestamps: true,
68 | }
69 | }
70 | }
71 |
72 | module.exports = sqlTable
73 |
--------------------------------------------------------------------------------
/utils/errorCode.js:
--------------------------------------------------------------------------------
1 | const ErrorCode = {
2 |
3 | // 系统相关
4 | ERRORCODE_SERVER_INSIDE_ERROR: 1001, // 服务器错误
5 | ERRORCODE_DATABASE: 1002, // 数据库操作异常
6 | ERRORCODE_MISSING_PARAMS: 1003, // 缺少参数
7 | ERRORCODE_INVALID_PARAMS: 1004, // 参数验证失败
8 | ERRORCODE_DATA_STORAGE: 1005, // 数据保存失败
9 | ERRORCODE_SEND_SMS_FAIED: 1006, // 发送短信失败
10 | ERRORCODE_VERIFY_SMS_FAIED: 1007, // 验证短信失败
11 | ERRORCODE_SEND_EMAILCODE_FAIED: 1008, // 发送邮箱验证码失败
12 | ERRORCODE_VERIFY_EMAILCODE_FAIED: 1009, // 验证邮箱验证码失败
13 |
14 | // 应用相关
15 | ERRORCODE_APP_NOT_EXIST: 2001, // 应用不存在
16 | ERRORCODE_APP_ALREADY_EXIST: 2002, // 应用已存在
17 | ERRORCODE_APP_CREATE_FAIED: 2003, // 应用创建失败
18 | ERRORCODE_APP_OVER_LIMIT: 2004, // 应用超过上限
19 | ERRORCODE_APP_NO_CALLBACK: 2005, // 应用没有回调函数
20 | ERRORCODE_APP_GET_APPINFO_FAIED: 2006, // 应用列表获取失败
21 | ERRORCODE_APP_UPDATE_APPINFO_FAIED: 2007, // 应用信息更新失败
22 | ERRORCODE_APP_NOT_ME:2008,//应用不是本人
23 |
24 | // 用户相关
25 | ERRORCODE_USER_NOT_EXIST: 3001, // 用户不存在
26 | ERRORCODE_USER_ALREADY_EXIST: 3002, // 用户已存在
27 | ERRORCODE_USER_REGISTER_FAIED: 3003, // 用户注册失败
28 | ERRORCODE_USER_GET_SALT_FAIED: 3004, // 用户取盐失败
29 | ERRORCODE_USER_LOGIN_FAIED: 3005, // 用户登录失败
30 | ERRORCODE_USER_LOGOUT_FAIED: 3006, // 用户退出失败
31 | ERRORCODE_USER_NOT_ENOUGH_BALANCE: 3007, // 用户余额不足
32 | ERRORCODE_USER_INVALID_USERNAME_OR_PASSWORD: 3008, // 用户名/邮箱/手机号码或密码不正确
33 | ERRORCODE_USER_INVALID_TOKEN: 3009, // 用户Token错误
34 | ERRORCODE_USER_PERMISSION_DENIED: 3010, // 用户权限不足
35 | ERRORCODE_USER_INVALID_SIGNATURE: 3011, // 用户签名错误
36 | ERRORCODE_USER_GET_USERINFO_FAIED: 3012, // 用户信息获取失败
37 | ERRORCODE_USER_DEPOSIT_FAILED: 3013, // 用户充值不足
38 | ERRORCODE_USER_WITHDRAW_FAILED: 3014, // 用户提现不足
39 | ERRORCODE_USER_UPDATE_USERINFO_FAIED: 3015, // 用户信息更新失败
40 | ERRORCODE_USER_RECHARGE_MEMBERSHIP_FAILED: 3016, // 用户购买会员失败
41 | ERRORCODE_USER_BALANCE_NOT_ENOUGH: 3017, // 用户余额不足
42 | ERRORCODE_USER_PASSWORD_ERR: 3018, // 密码正确
43 |
44 | ERRORCODE_SIGN_ERROR:4001,//签名错误
45 | ERRORCODE_APPID_NOT_EXIST:4002,//appid 不存在
46 | NOT_FIND_PHONE:4003,//设备不存在
47 |
48 | ERRORCODE_PERMISSIONS_DENIED: 5001, //权限不足
49 | ERRORCODE_OVER_LOAD_LIMIT: 5002, //会员等级异常
50 |
51 |
52 | }
53 |
54 | module.exports = ErrorCode
55 |
--------------------------------------------------------------------------------
/public/dist/static/css/chunk-7e70.92d696e8.css:
--------------------------------------------------------------------------------
1 | .dashboard-container[data-v-604c748c]{padding:32px}.dashboard-container .panel-group[data-v-604c748c]{margin-top:18px}.dashboard-container .panel-group .card-panel-col[data-v-604c748c]{margin-bottom:32px}.dashboard-container .panel-group .card-panel[data-v-604c748c]{display:block;height:108px;cursor:pointer;font-size:12px;position:relative;overflow:hidden;color:#666;background:#fff;-webkit-box-shadow:4px 4px 40px rgba(0,0,0,.05);box-shadow:4px 4px 40px rgba(0,0,0,.05);border-color:rgba(0,0,0,.05)}.dashboard-container .panel-group .card-panel:hover .card-panel-icon-wrapper[data-v-604c748c]{color:#fff}.dashboard-container .panel-group .card-panel:hover .icon-people[data-v-604c748c]{background:#40c9c6}.dashboard-container .panel-group .card-panel:hover .icon-message[data-v-604c748c]{background:#36a3f7}.dashboard-container .panel-group .card-panel:hover .icon-money[data-v-604c748c]{background:#f4516c}.dashboard-container .panel-group .card-panel:hover .icon-shopping[data-v-604c748c]{background:#34bfa3}.dashboard-container .panel-group .card-panel .icon-people[data-v-604c748c]{color:#40c9c6}.dashboard-container .panel-group .card-panel .icon-message[data-v-604c748c]{color:#36a3f7}.dashboard-container .panel-group .card-panel .icon-money[data-v-604c748c]{color:#f4516c}.dashboard-container .panel-group .card-panel .icon-shopping[data-v-604c748c]{color:#34bfa3}.dashboard-container .panel-group .card-panel .card-panel-icon-wrapper[data-v-604c748c]{float:left;margin:14px 0 0 14px;padding:16px;-webkit-transition:all .38s ease-out;transition:all .38s ease-out;border-radius:6px}.dashboard-container .panel-group .card-panel .card-panel-icon[data-v-604c748c]{float:left;font-size:48px}.dashboard-container .panel-group .card-panel .card-panel-description[data-v-604c748c]{float:right;font-weight:700;padding:0 30px;margin:26px 0;text-align:right}.dashboard-container .panel-group .card-panel .card-panel-description.primary[data-v-604c748c]{border-right:1px solid #ccc}.dashboard-container .panel-group .card-panel .card-panel-description .card-panel-text[data-v-604c748c]{line-height:18px;color:rgba(0,0,0,.45);font-size:14px;margin-bottom:12px;font-weight:400}.dashboard-container .panel-group .card-panel .card-panel-description .card-panel-num[data-v-604c748c]{font-size:20px}.dashboard-container .chart-title[data-v-604c748c]{text-align:center;font-size:20px;color:#36a3f7;margin:30px 0 20px}
--------------------------------------------------------------------------------
/init/index.js:
--------------------------------------------------------------------------------
1 | const users = require("../db/models/users");
2 | const apps = require("../db/models/apps");
3 | const crypto = require('crypto');
4 | const MD5 = require('../utils/md5.js');
5 | const config = require('../conf/default')
6 | const initController = {
7 | // 初始化用户信息
8 | async initAdmin() {
9 | try {
10 | let sum = 1;
11 | const pwd = MD5(config.adminPwd);
12 | let data = {
13 | mobile_phone: 'admin',
14 | password: pwd,
15 | lv: 99,
16 | // nick_name: 'Rick Chen',
17 | amount: 1000000000,
18 | pay_userid:'2088112172418889',
19 | membership_expired:'9999999999999'
20 | // e_mail: '573099498@qq.com',
21 | // wechart: 'cxyxxx0924',
22 | };
23 | // 添加用户
24 | const admin = await users.getUserById({userid: 1});
25 | if(!admin)
26 | await users.addUser(data);
27 | } catch (err) {
28 | console.log(err)
29 | console.error(`initAdmin--${err}`);
30 | }
31 | },
32 | async initApps() {
33 | const uuidv1 = require('uuid/v1')
34 | // const appid = uuidv1().substring(24, 36)
35 | const appid = config.appid;
36 | console.info(appid);
37 | const appsecret = MD5(appid + Date.now()).toUpperCase()
38 | console.info(appsecret, '--');
39 | try {
40 | let data = {
41 | userid: config.userid,
42 | name: 'renrenpay',
43 | callback_url: 'http://127.0.0.1:3000/api/deposits/verbCall',
44 | whitelist: '',
45 | appid: appid,
46 | appsecret: appsecret,
47 | pay_userid: config.pay_userid
48 | };
49 | await apps.chkAppExist(data).then(result => {
50 | if (result.count > 0) {
51 | throw {
52 | code: 3000
53 | }
54 | }
55 | })
56 | await apps.addApplication(data);
57 | } catch (err) {
58 | console.log(err);
59 | console.error(`initApps--${err}`);
60 | }
61 | }
62 | }
63 | setTimeout(item => {
64 | initController.initAdmin();
65 | initController.initApps();
66 | }, 3000)
67 |
--------------------------------------------------------------------------------
/utils/verifyToken.js:
--------------------------------------------------------------------------------
1 | const errorCode = require('./errorCode.js')
2 | const redisClient = require('./redisClient.js')
3 | const returnCodesAndMessages = require('./returnJson.js')
4 | const Jwt = require('./jwt.js')
5 | const {
6 | loggerHttp
7 | } = require('./logger.js')
8 |
9 | const verifyToken = async (ctx, rank = 0) => {
10 | try {
11 | const token = ctx.request.header.token
12 |
13 | if (token) {
14 | // 验证Token
15 | let jwt = new Jwt(token)
16 | let result = jwt.verifyToken()
17 | if (!result || result === 'err') {
18 | throw {
19 | code: errorCode.ERRORCODE_USER_INVALID_TOKEN
20 | }
21 | }
22 | ctx.state.user = result
23 | // 判断用户等级
24 | if (rank <= result.lv) {
25 | return result
26 | } else {
27 | throw {
28 | code: errorCode.ERRORCODE_USER_PERMISSION_DENIED
29 | }
30 | }
31 | } else {
32 | throw {
33 | code: errorCode.ERRORCODE_USER_INVALID_TOKEN
34 | }
35 | }
36 | } catch (err) {
37 | if (err.code) {
38 | returnCodesAndMessages.err(ctx, err.code, err.message)
39 | } else {
40 | returnCodesAndMessages.err(ctx, errorCode.ERRORCODE_SERVER_INSIDE_ERROR, '')
41 | loggerHttp.error(`verifyToken -- ${err}`)
42 | }
43 | }
44 | }
45 |
46 | const verifyToken2 = async (ctx, rank = 0)=>{
47 | try {
48 | const token = ctx.request.header.token
49 |
50 | if (token) {
51 | let result = await redisClient.get('3', token);
52 | if(result){
53 | ctx.state.user = JSON.parse(result);
54 | return JSON.parse(result);
55 | }else {
56 | throw {
57 | code: errorCode.ERRORCODE_USER_PERMISSION_DENIED
58 | }
59 | }
60 | } else {
61 | throw {
62 | code: errorCode.ERRORCODE_USER_INVALID_TOKEN
63 | }
64 | }
65 | } catch (err) {
66 | if (err.code) {
67 | returnCodesAndMessages.err(ctx, err.code, err.message)
68 | } else {
69 | returnCodesAndMessages.err(ctx, errorCode.ERRORCODE_SERVER_INSIDE_ERROR, '')
70 | loggerHttp.error(`verifyToken -- ${err}`)
71 | }
72 | }
73 | }
74 |
75 | module.exports = {
76 | verifyToken,
77 | verifyToken2
78 | }
79 |
--------------------------------------------------------------------------------
/public/dist/static/js/chunk-f779.74ec5683.js:
--------------------------------------------------------------------------------
1 | (window.webpackJsonp=window.webpackJsonp||[]).push([["chunk-f779"],{DmCF:function(e,r,s){"use strict";var t=s("gEW1");s.n(t).a},gEW1:function(e,r,s){},nIie:function(e,r,s){"use strict";s.r(r);var t=s("14Xm"),a=s.n(t),o=s("D3Ub"),n=s.n(o),i=s("wk8/"),l=s("gjeX"),p=s.n(l),d=s("QqA1"),u=s.n(d),c={data:function(){var e=this;return{active:"first",loading:!1,form:{old_password:"",new_password:"",new_password_confirm:""},rules:{old_password:[{required:!0,message:"请输入旧密码",trigger:"blur"}],new_password:[{required:!0,message:"请输入新密码",trigger:"blur"},{min:6,message:"密码长度不低于6位",trigger:"blur"}],new_password_confirm:[{required:!0,message:"请再次输入密码",trigger:"blur"},{validator:function(r,s,t){s!==e.form.new_password?t(new Error("两次输入密码不一致!")):t()},trigger:"blur"}]}}},methods:{submit:function(){var e=this;this.$refs.form.validate(function(){var r=n()(a.a.mark(function r(s){var t;return a.a.wrap(function(r){for(;;)switch(r.prev=r.next){case 0:if(!s){r.next=12;break}return e.loading=!0,(t=u()({},e.form)).old_password=p()(t.old_password),t.new_password=p()(t.new_password),r.next=7,Object(i.i)(t);case 7:if(null!==r.sent){r.next=10;break}return r.abrupt("return");case 10:e.loading=!1,e.$message({type:"success",message:"修改密码成功"});case 12:case"end":return r.stop()}},r,e)}));return function(e){return r.apply(this,arguments)}}())}}},m=(s("DmCF"),s("KHd+")),w=Object(m.a)(c,function(){var e=this,r=e.$createElement,s=e._self._c||r;return s("div",{staticClass:"settings-index-page"},[s("el-tabs",{model:{value:e.active,callback:function(r){e.active=r},expression:"active"}},[s("el-tab-pane",{attrs:{label:"修改密码",name:"first"}},[s("el-form",{ref:"form",staticStyle:{"max-width":"600px"},attrs:{model:e.form,rules:e.rules,"label-width":"100px"}},[s("el-form-item",{attrs:{label:"旧密码",prop:"old_password"}},[s("el-input",{attrs:{type:"password"},model:{value:e.form.old_password,callback:function(r){e.$set(e.form,"old_password",r)},expression:"form.old_password"}})],1),e._v(" "),s("el-form-item",{attrs:{label:"新密码",prop:"new_password"}},[s("el-input",{attrs:{type:"password"},model:{value:e.form.new_password,callback:function(r){e.$set(e.form,"new_password",r)},expression:"form.new_password"}})],1),e._v(" "),s("el-form-item",{attrs:{label:"新密码确认",prop:"new_password_confirm"}},[s("el-input",{attrs:{type:"password"},model:{value:e.form.new_password_confirm,callback:function(r){e.$set(e.form,"new_password_confirm",r)},expression:"form.new_password_confirm"}})],1),e._v(" "),s("el-form-item",[s("el-button",{attrs:{loading:e.loading,type:"primary"},on:{click:e.submit}},[e._v("提交")])],1)],1)],1)],1)],1)},[],!1,null,"3815b536",null);w.options.__file="Index.vue";r.default=w.exports}}]);
--------------------------------------------------------------------------------
/controllers/withdrawsController.js:
--------------------------------------------------------------------------------
1 | const nanoid = require('nanoid')
2 | const _ = require('lodash')
3 | const {
4 | loggerHttp
5 | } = require('../utils/logger.js')
6 | const ErrorCode = require('../utils/errorCode.js')
7 | const returnJson = require('../utils/returnJson.js')
8 | const redisCli = require('../utils/redisClient.js')
9 | const MD5 = require('../utils/md5.js')
10 | const Jwt = require('../utils/jwt.js')
11 | const verifyParams = require('../utils/verifyParams.js')
12 | const verifyToken = require('../utils/verifyToken.js')
13 | const sendSms = require('../utils/sendSms.js')
14 | const sendEmail = require('../utils/sendEmail.js')
15 | const withdraws = require('../db/models/withdraws.js')
16 | const users = require('../db/models/users.js')
17 | const uuidv1 = require('uuid/v1')
18 |
19 | const withdrawsController = {
20 | withdraw() {
21 | return async (ctx, next) => {
22 | try {
23 | const data = ctx.request.body
24 | data.userid = ctx.state.user.id
25 | data.action = 'withdraw'
26 | data.uuid = uuidv1()
27 | data.memo = ''
28 |
29 | // 判断参数是否缺少
30 | await verifyParams(data, 'type', 'amount', 'memo').then(result => {
31 | if (!result) {
32 | throw {
33 | code: ErrorCode.ERRORCODE_MISSING_PARAMS,
34 | message: '或者参数错误'
35 | }
36 | }
37 | })
38 |
39 | // 添加提现记录
40 | await withdraws.addWithdraw(data).then(result => {
41 | if (!result) {
42 | throw {
43 | code: ErrorCode.ERRORCODE_USER_WITHDRAW_FAILED,
44 | message: '添加提现记录错误'
45 | }
46 | }
47 | })
48 |
49 | // 更新balance
50 | await users.updateBalance(data).then(result => {
51 | if (result[0]) {
52 | returnJson.success(ctx)
53 | } else {
54 | throw {
55 | code: ErrorCode.ERRORCODE_USER_NOT_EXIST
56 | }
57 | }
58 | })
59 | } catch (err) {
60 | console.info(`${ctx.url} -- `,err)
61 | if (err.code) {
62 | returnJson.err(ctx, err.code, err.message)
63 | } else {
64 | returnJson.err(ctx, ErrorCode.ERRORCODE_USER_WITHDRAW_FAILED)
65 | }
66 | }
67 | }
68 | },
69 | }
70 |
71 | module.exports = withdrawsController
72 |
--------------------------------------------------------------------------------
/public/dist/static/js/chunk-54db.2bca911d.js:
--------------------------------------------------------------------------------
1 | (window.webpackJsonp=window.webpackJsonp||[]).push([["chunk-54db"],{"4XeK":function(t,e,a){"use strict";a.d(e,"a",function(){return o}),a.d(e,"b",function(){return r});var n=a("t3Un"),o=function(t){var e=t.payway,a=t.amount;return Object(n.a)({url:"/api/deposits/qrcode",method:"post",data:{payway:e,amount:a}})},r=function(t){var e=t.page,a=void 0===e?1:e,o=t.page_size,r=void 0===o?10:o,i=t.state,s=void 0===i?"":i;return Object(n.a)({url:"/api/deposits/list",method:"get",data:{page:a,page_size:r,state:s}})}},E8qc:function(t,e,a){"use strict";a.r(e);var n=a("14Xm"),o=a.n(n),r=a("D3Ub"),i=a.n(r),s=a("4XeK"),c={data:function(){return{form:{page:1,page_size:10},total:0,loading:!1,list:[]}},created:function(){this.fetch()},methods:{fetch:function(){var t=this;return i()(o.a.mark(function e(){var a;return o.a.wrap(function(e){for(;;)switch(e.prev=e.next){case 0:return t.loading=!0,e.next=3,Object(s.b)(t.form);case 3:if(a=e.sent,t.loading=!1,null!==a){e.next=7;break}return e.abrupt("return");case 7:a.rows.forEach(function(t){t._createdAt=new Date(t.createdAt).toLocaleString()}),t.list=a.rows,t.total=a.count;case 10:case"end":return e.stop()}},e,t)}))()}}},l=a("KHd+"),u=Object(l.a)(c,function(){var t=this,e=t.$createElement,a=t._self._c||e;return a("div",{staticClass:"bill-index-page"},[a("el-table",{staticStyle:{width:"100%","margin-top":"20px"},attrs:{data:t.list,loading:t.loading,stripe:""}},[a("el-table-column",{attrs:{prop:"orderid",label:"id","min-width":"180"}}),t._v(" "),a("el-table-column",{attrs:{prop:"_createdAt",label:"时间","min-width":"180"}}),t._v(" "),a("el-table-column",{attrs:{prop:"amount",label:"类型","min-width":"180"},scopedSlots:t._u([{key:"default",fn:function(e){return[a("div",[1==e.row.type?a("div",{staticStyle:{color:"#00aae8"}},[a("svg-icon",{attrs:{"icon-class":"zhifubao"}}),t._v(" 支付宝充值")],1):t._e(),t._v(" "),2==e.row.type?a("div",{staticStyle:{color:"#09bb07"}},[a("svg-icon",{attrs:{"icon-class":"wepay"}}),t._v(" 微信充值")],1):t._e(),t._v(" "),3==e.row.type?a("el-tag",{attrs:{type:"success"}},[t._v("购买会员")]):t._e(),t._v(" "),4==e.row.type?a("el-tag",{attrs:{type:"success"}},[t._v("手续费扣除")]):t._e()],1)]}}])}),t._v(" "),a("el-table-column",{attrs:{prop:"amount",label:"金额(元)","min-width":"180"},scopedSlots:t._u([{key:"default",fn:function(e){return[1==e.row.type||2==e.row.type?a("div",[a("b",{staticStyle:{color:"#409EFF","font-size":"16px","font-weight":"400"}},[t._v("+ "+t._s(e.row.amount/100)+" ")])]):a("div",[a("span",{staticStyle:{color:"#909399"}},[t._v("- "+t._s(e.row.amount/100))])])]}}])})],1),t._v(" "),a("el-pagination",{staticStyle:{"text-align":"right","margin-top":"20px"},attrs:{background:"",layout:"prev, pager, next",total:t.total,"current-page":t.form.page},on:{"update:currentPage":function(e){t.$set(t.form,"page",e)},"current-change":t.fetch}})],1)},[],!1,null,null,null);u.options.__file="index.vue";e.default=u.exports}}]);
--------------------------------------------------------------------------------
/utils/websocket.js:
--------------------------------------------------------------------------------
1 | const WebsocketServer = require('websocket').server
2 | const http = require('http')
3 | const wsMap = new Map()
4 | const ErrorCode = require('../utils/errorCode.js')
5 | const config = require('../conf/default.js')
6 |
7 |
8 | const httpServer = http.createServer(function (req, res) {
9 | console.log((new Date()) + ' Received request for ' + req.url)
10 | res.writeHead(404)
11 | res.end()
12 | })
13 |
14 | function websocket() {
15 | httpServer.listen(config.websocket.port, function () {
16 | console.log((new Date()) + ' Server is listening on port ' + config.websocket.port)
17 | })
18 |
19 | let wsServer = new WebsocketServer({
20 | httpServer: httpServer,
21 | autoAcceptConnections: false
22 | })
23 |
24 | wsServer.on('request', async function (req) {
25 | // let connection = req.accept('echo-protocol', req.origin);
26 | console.info(req.resourceURL.query.user)
27 | console.log((new Date()) + ' Origin: ' + req.origin)
28 | if (!originIsAllowed(req.origin)) {
29 | req.reject()
30 | console.log((new Date()) + ' Connection from origin ' + req.origin + ' rejected.')
31 | return
32 | }
33 | let conn;
34 | try {
35 | conn = req.accept('echo-protocol', req.origin);
36 | } catch (error) {
37 | wsMap.delete(req.origin)
38 | return error
39 | }
40 | let key = req.resourceURL.query.user;
41 | if(key) {
42 | console.info('--->',key);
43 | wsMap.set(key.toString(), conn)
44 | } else {
45 | return
46 | }
47 |
48 | console.log((new Date()) + ' Connection from origin ' + req.origin + ' accepted.')
49 |
50 | conn.on('message', async function (msg) {
51 | console.log(req.origin + ' >>>',req.resourceURL.query.user)
52 | console.log('Received message: ' + msg.utf8Data)
53 | })
54 |
55 | conn.on('close', function (reasonCode, desc) {
56 | console.log(req.origin + ' >>>')
57 | console.log('Received close: ' + reasonCode + ' desc: ' + desc)
58 |
59 | wsMap.delete(req.origin)
60 | console.log((new Date()) + ' Peer ' + conn.remoteAddrress + ' disconnected.')
61 | })
62 | })
63 | }
64 |
65 | function originIsAllowed(origin) {
66 | return true
67 | }
68 |
69 | websocket.prototype.sendMsg = function(useId, msg) {
70 | try {
71 | console.info(useId,msg);
72 | const connection = wsMap.get(useId + "");
73 | if(!connection)
74 | throw {code: ErrorCode.NOT_FIND_PHONE, message: "没有找到设备"}
75 | connection.sendUTF(msg);
76 | } catch (error) {
77 | console.log(error)
78 | throw {code: ErrorCode.ERRORCODE_SERVER_INSIDE_ERROR, message: "sendMsg error"}
79 | }
80 |
81 | };
82 |
83 | module.exports = websocket
84 |
--------------------------------------------------------------------------------
/public/dist/static/js/chunk-0224.e4d32421.js:
--------------------------------------------------------------------------------
1 | (window.webpackJsonp=window.webpackJsonp||[]).push([["chunk-0224"],{B30W:function(t,n,e){},"Yq+K":function(t,n,e){"use strict";var s=e("B30W");e.n(s).a},c11S:function(t,n,e){"use strict";var s=e("gTgX");e.n(s).a},gTgX:function(t,n,e){},ntYl:function(t,n,e){"use strict";e.r(n);var s=e("14Xm"),o=e.n(s),a=e("D3Ub"),i=e.n(a),r=(e("gjeX"),{name:"Login",data:function(){return{account:"",loginForm:{password:"",mobile_phone:"",email:""},loading:!1,pwdType:"password",redirect:void 0}},watch:{$route:{handler:function(t){this.redirect=t.query&&t.query.redirect},immediate:!0}},methods:{showPwd:function(){"password"===this.pwdType?this.pwdType="":this.pwdType="password"},handleLogin:function(){var t=this;return i()(o.a.mark(function n(){var e;return o.a.wrap(function(n){for(;;)switch(n.prev=n.next){case 0:return t.account||t.$message({type:"warning",message:"请输入邮箱或者手机号"}),/\d{11}/.test(t.account)||"admin"==t.account?t.loginForm.mobile_phone=t.account:t.loginForm.email=t.account,t.loading=!0,n.next=5,t.$store.dispatch("Login",t.loginForm);case 5:e=n.sent,t.loading=!1,null!==e&&(t.$message({type:"success",message:"登录成功"}),t.$router.push({path:"/"}));case 8:case"end":return n.stop()}},n,t)}))()}}}),c=(e("c11S"),e("Yq+K"),e("KHd+")),l=Object(c.a)(r,function(){var t=this,n=t.$createElement,e=t._self._c||n;return e("div",{staticClass:"login-container"},[e("el-form",{ref:"loginForm",staticClass:"login-form",attrs:{model:t.loginForm,"auto-complete":"on","label-position":"left"}},[e("h3",{staticClass:"title"},[t._v("人人收付")]),t._v(" "),e("el-form-item",[e("span",{staticClass:"svg-container"},[e("svg-icon",{attrs:{"icon-class":"phone"}})],1),t._v(" "),e("el-input",{attrs:{name:"phone",type:"text","auto-complete":"on",placeholder:"邮箱/手机号"},model:{value:t.account,callback:function(n){t.account=n},expression:"account"}})],1),t._v(" "),e("el-form-item",{attrs:{prop:"password"}},[e("span",{staticClass:"svg-container"},[e("svg-icon",{attrs:{"icon-class":"password"}})],1),t._v(" "),e("el-input",{attrs:{type:t.pwdType,name:"password","auto-complete":"on",placeholder:"请输入密码"},nativeOn:{keyup:function(n){return"button"in n||!t._k(n.keyCode,"enter",13,n.key,"Enter")?t.handleLogin(n):null}},model:{value:t.loginForm.password,callback:function(n){t.$set(t.loginForm,"password",n)},expression:"loginForm.password"}}),t._v(" "),e("span",{staticClass:"show-pwd",on:{click:t.showPwd}},[e("svg-icon",{attrs:{"icon-class":"password"===t.pwdType?"eye":"eye-open"}})],1)],1),t._v(" "),e("el-form-item",[e("el-button",{staticStyle:{width:"100%"},attrs:{loading:t.loading,type:"primary"},on:{click:t.handleLogin}},[t._v("\n 登录\n ")])],1),t._v(" "),e("div",{staticClass:"tips"},[e("router-link",{staticClass:"tips-link",attrs:{to:{path:"forget"}}},[t._v("忘记密码?")]),t._v(" "),e("span",{staticClass:"tips-line"},[t._v("|")]),t._v(" "),e("router-link",{staticClass:"tips-link",attrs:{to:{path:"register"}}},[t._v(" 注册")])],1)],1)],1)},[],!1,null,"b6901faa",null);l.options.__file="index.vue";n.default=l.exports}}]);
--------------------------------------------------------------------------------
/db/models/apps.js:
--------------------------------------------------------------------------------
1 | const Sequelize = require('sequelize')
2 | const {
3 | sqlTable,
4 | } = require('../index.js')
5 |
6 | const apps = {
7 | async addApplication(data) {
8 | return sqlTable.apps.create({
9 | userid: data.userid,
10 | name: data.name,
11 | callback_url: data.callback_url || '',
12 | whitelist: data.whitelist || '',
13 | appid: data.appid,
14 | appsecret: data.appsecret,
15 | pay_userid:data.pay_userid,
16 | status: 1
17 | })
18 | },
19 |
20 | async chkAppExist(data) {
21 | return sqlTable.apps.findAndCountAll({
22 | where: {
23 | userid: data.userid,
24 | name: data.name
25 | }
26 | })
27 | },
28 | async chkAppExist2(data) {
29 | return sqlTable.apps.findAndCountAll({
30 | where: {
31 | userid: data.userid,
32 | name: data.name,
33 | id:{$ne:data.id}
34 | }
35 | })
36 | },
37 | async getAppCount(data) {
38 | return sqlTable.apps.findAndCountAll({
39 | where: {
40 | userid: data.userid,
41 | }
42 | })
43 | },
44 |
45 | async getApps(data) {
46 | let limit = data.page_size*1;
47 | let offset = data.page_size * (data.page - 1);
48 | return sqlTable.apps.findAndCount({
49 | limit,
50 | offset,
51 | where: {
52 | userid: data.userid,
53 | }
54 | })
55 | },
56 |
57 | async queryApps(data) {
58 | return sqlTable.apps.findAll({
59 | where: {
60 | appid: data.appid,
61 | }
62 | })
63 | },
64 |
65 | async updateAppInfo(data) {
66 | return sqlTable.apps.update({
67 | callback_url: data.callback_url || '',
68 | whitelist: data.whitelist || '',
69 | name: data.name,
70 | pay_userid:data.pay_userid
71 | }, {
72 | where: {
73 | id: data.id || 0,
74 | userid: data.userid
75 | }
76 | })
77 | },
78 |
79 | async deleteApp(data) {
80 | return sqlTable.apps.destroy({
81 | where: {
82 | id: data.id,
83 | userid: data.userid
84 | }
85 | })
86 | },
87 |
88 | async allApps(data) {
89 | return sqlTable.apps.findAll({
90 | where: {
91 | userid: data.userid,
92 | }
93 | })
94 | },
95 |
96 | async isMeApp(data) {
97 | return sqlTable.apps.findAll({
98 | where: {
99 | userid: data.userid,
100 | appid: data.appid
101 | }
102 | })
103 | }
104 | }
105 |
106 | module.exports = apps
107 |
--------------------------------------------------------------------------------
/public/dist/static/css/chunk-280b.7469e992.css:
--------------------------------------------------------------------------------
1 | .pay-comp[data-v-549a193a]{text-align:center}.pay-comp.wepay .deposit-title[data-v-549a193a]{color:#09bb07}.pay-comp.alipay .deposit-title[data-v-549a193a]{color:#00aae8}.pay-comp .deposit-title[data-v-549a193a]{font-size:24px}.pay-comp .deposit-num[data-v-549a193a]{font-size:40px;font-weight:700;margin-top:30px;color:#606266}.deposit-comp[data-v-3258e044]{padding:0 20px 20px;-webkit-box-shadow:0 2px 4px 0 rgba(0,0,0,.12),0 0 6px 0 rgba(0,0,0,.04);box-shadow:0 2px 4px 0 rgba(0,0,0,.12),0 0 6px 0 rgba(0,0,0,.04);border:1px solid #dcdfe6;color:#606266;font-size:14px}.deposit-comp .balance-cell[data-v-3258e044]{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;height:60px;border-bottom:1px solid #dcdfe6}.deposit-comp .balance-cell .cell-bd[data-v-3258e044]{margin-left:10px}.deposit-comp .balance-cell .primary[data-v-3258e044]{color:#f56c6c}.deposit-comp .balance-cell .cell-ft[data-v-3258e044]{margin-left:30px}.deposit-comp .amount-list[data-v-3258e044]{margin-left:-15px}.deposit-comp .amount-item[data-v-3258e044]{display:inline-block;width:100px;height:100px;line-height:100px;vertical-align:middle;border:1px solid #e4e7ed;border-radius:4px;text-align:center;cursor:pointer;margin-left:15px;margin-bottom:20px;font-size:20px;color:#606266;font-weight:400}.deposit-comp .amount-item[data-v-3258e044]:hover{-webkit-box-shadow:0 2px 12px 0 rgba(0,0,0,.1);box-shadow:0 2px 12px 0 rgba(0,0,0,.1)}.deposit-comp .amount-item.hover[data-v-3258e044]{border:1px solid #409eff;color:#409eff}.deposit-comp .amount-item .desc[data-v-3258e044]{font-size:16px}.deposit-comp .num-widget[data-v-3258e044]{font-size:24px;vertical-align:super}.deposit-comp .combo-list[data-v-3258e044]{font-size:0;margin-left:-20px}.deposit-comp .combo-list .combo-item[data-v-3258e044]{display:inline-block;width:150px;height:150px;padding:0 10px;border:1px solid #e4e7ed;border-radius:4px;text-align:center;overflow:hidden;margin-left:20px;cursor:pointer}.deposit-comp .combo-list .combo-item.active[data-v-3258e044]{border:1px solid #f56c6c}.deposit-comp .combo-list .item-title[data-v-3258e044]{height:50px;line-height:50px;border-bottom:1px dashed #dcdfe6;font-size:18px;color:#333}.deposit-comp .combo-list .item-num[data-v-3258e044]{font-size:18px;margin-top:15px}.deposit-comp .combo-list .primary[data-v-3258e044]{font-size:30px;color:#f56c6c;font-weight:700;margin-right:5px}.deposit-comp .combo-list .item-desc[data-v-3258e044]{font-size:14px;margin-top:15px}.intro-index-page .sec[data-v-63a081ac]{padding:0 20px 20px;-webkit-box-shadow:0 2px 4px 0 rgba(0,0,0,.12),0 0 6px 0 rgba(0,0,0,.04);box-shadow:0 2px 4px 0 rgba(0,0,0,.12),0 0 6px 0 rgba(0,0,0,.04);border:1px solid #dcdfe6;color:#606266;font-size:14px;margin-top:20px}.intro-index-page .sec-title[data-v-63a081ac]{height:60px;line-height:60px;font-size:16px;border-bottom:1px solid #dcdfe6;color:#303133}.intro-index-page .title[data-v-63a081ac]{font-size:15px;margin:20px 0}.intro-index-page .text[data-v-63a081ac]{font-size:14px;margin:10px 0;line-height:1.8}
--------------------------------------------------------------------------------
/controllers/ordersController.js:
--------------------------------------------------------------------------------
1 | const nanoid = require('nanoid')
2 | const _ = require('lodash')
3 | const {
4 | loggerHttp
5 | } = require('../utils/logger.js')
6 | const ErrorCode = require('../utils/errorCode.js')
7 | const returnJson = require('../utils/returnJson.js')
8 | const redisCli = require('../utils/redisClient.js')
9 | const MD5 = require('../utils/md5.js')
10 | const Jwt = require('../utils/jwt.js')
11 | const verifyParams = require('../utils/verifyParams.js')
12 | const verifyToken = require('../utils/verifyToken.js')
13 | const sendSms = require('../utils/sendSms.js')
14 | const sendEmail = require('../utils/sendEmail.js')
15 | const deposits = require('../db/models/deposits.js')
16 | const users = require('../db/models/users.js')
17 | const uuidv1 = require('uuid/v1')
18 | const orders = require('../db/models/orders.js')
19 |
20 | const ordersController={
21 | getList(){//查询订单列表
22 | return async (ctx, next)=>{
23 | try {
24 | const data = ctx.query
25 | data.userid = ctx.state.user.id
26 | data.page = data.page || 1
27 | data.page_size = data.page_size || 10
28 |
29 | await verifyParams(data, 'userid').then(result => {//
30 | if (!result) {
31 | throw {
32 | code: ErrorCode.ERRORCODE_MISSING_PARAMS,
33 | message: '或者参数错误'
34 | }
35 | }
36 | })
37 | await orders.getList(data).then(result=>{
38 | returnJson.success(ctx, result);
39 | })
40 | } catch (err) {
41 | console.info(`${ctx.url} -- `, err)
42 | if(err.code) {
43 | returnJson.err(ctx, err.code, err.message);
44 | } else {
45 | returnJson.err(ctx, ErrorCode.ERRORCODE_SERVER_INSIDE_ERROR)
46 | }
47 | }
48 |
49 |
50 | }
51 | },
52 |
53 | getDetail(){//查询订单详情
54 | return async(ctx,next)=>{
55 | try {
56 | const data = ctx.query
57 | data.userid = ctx.state.user.id
58 | await verifyParams(data, 'orderid').then(result => {
59 | if (!result) {
60 | throw {
61 | code: ErrorCode.ERRORCODE_MISSING_PARAMS,
62 | message: '或者参数错误'
63 | }
64 | }
65 | })
66 |
67 | await orders.findOne(data).then(result=>{
68 | returnJson.success(ctx, result);
69 | })
70 | } catch (err) {
71 | console.info(`${ctx.url} -- `, err)
72 | if(err.code) {
73 | returnJson.err(ctx, err.code, err.message);
74 | } else {
75 | returnJson.err(ctx, ErrorCode.ERRORCODE_SERVER_INSIDE_ERROR)
76 | }
77 | }
78 | }
79 | }
80 | }
81 |
82 | module.exports = ordersController;
--------------------------------------------------------------------------------
/utils/redisClient.js:
--------------------------------------------------------------------------------
1 | // const redis = require('redis')
2 | // const bluebird = require('bluebird')
3 | // const config = require('../conf/default.js')
4 | // const {
5 | // loggerHttp
6 | // } = require('./logger.js')
7 |
8 | // const redis_client = redis.createClient(config.redis.port, config.redis.host)
9 |
10 | // bluebird.promisifyAll(redis.RedisClient.prototype)
11 | // bluebird.promisifyAll(redis.Multi.prototype)
12 |
13 | // redis_client.on('error', err => {
14 | // loggerHttp.error(`redis -- ${err}`)
15 | // })
16 |
17 | // const redis_cli = {
18 |
19 | // async set (db, key, value, expired) {
20 |
21 | // await redis_client.selectAsync(db)
22 |
23 | // await redis_client.setAsync(key, value)
24 |
25 | // return redis_client.expireAsync(key, expired)
26 | // },
27 |
28 | // async get (db, key) {
29 | // await redis_client.selectAsync(db)
30 |
31 | // return await redis_client.getAsync(key)
32 | // },
33 |
34 | // async del(db, key) {
35 | // await redis_client.selectAsync(db)
36 |
37 | // return await redis_client.delAsync(key)
38 | // },
39 | // async push(key, value, expired) {
40 | // await redis_client.selectAsync(7)
41 | // await redis_client.lpush(key, value);
42 | // return await redis_client.expireAsync(key, expired);
43 | // },
44 | // async getList(key) {
45 | // await redis_client.selectAsync(7)
46 | // return await redis_client.lrange(key, 0, 100);
47 | // }
48 | // }
49 |
50 |
51 |
52 | const Redis = require('ioredis')
53 | const bluebird = require('bluebird')
54 | const config = require('../conf/default.js')
55 |
56 | const redis_client = new Redis({
57 | port: config.redis.port,
58 | host: config.redis.host,
59 | family: 4,
60 | // password:settings.ioredis.password,
61 | db: 0
62 | });
63 | redis_client.on('connect', function () {
64 | // console.info('Reids connect success')
65 | });
66 | redis_client.on('end', function () {
67 | console.error('Redis connect error')
68 | });
69 |
70 | const redis_cli = {
71 |
72 | async set (db, key, value, expired) {
73 | await redis_client.select(db)
74 | // await redis_client.set(key, value,'EX',expired)
75 | await redis_client.set(key, value)
76 | return redis_client.expire(key, expired)
77 | },
78 |
79 | async get (db, key) {
80 | await redis_client.select(db)
81 | return await redis_client.get(key)
82 | },
83 |
84 | async del(db, key) {
85 | await redis_client.select(db)
86 | return await redis_client.del(key)
87 | },
88 |
89 | async push(key, value, expired) {
90 | await redis_client.select(4)
91 | await redis_client.lpush(key, value);
92 | return await redis_client.expire(key, expired);
93 | },
94 | async getList(key) {
95 | await redis_client.select(4)
96 | return await redis_client.lrange(key, 0, 100);
97 | },
98 | async remove(key,value){
99 | await redis_client.select(4)
100 | await redis_client.lrem(key,0,value)
101 | }
102 |
103 | }
104 |
105 | module.exports = redis_cli
--------------------------------------------------------------------------------
/utils/errorHandler.js:
--------------------------------------------------------------------------------
1 | const {
2 | loggerHttp,
3 | loggerHttpInfo
4 | } = require('./logger.js')
5 | const verify = require('./verifyToken.js')
6 | const ErrorCode = require('../utils/errorCode.js')
7 | const returnJson = require('../utils/returnJson.js')
8 | const errorHandler = {
9 | error(app) {
10 | // 判断Token
11 | app.use(async (ctx, next) => {
12 | try {
13 | if (ctx.url === '/') {
14 | await next()
15 | return
16 | }
17 | if ((/\/api\/users\/sms\?mobile_phone=.*/ ).test(ctx.url)) {
18 | await next()
19 | return
20 | }
21 | if ((/\/api\/users\/email\?email=.*/ ).test(ctx.url)) {
22 | await next()
23 | return
24 | }
25 | if ((/\/api3\/*/).test(ctx.url)){
26 | await next()
27 | return
28 | }
29 | if (ctx.url === '/api/users/register') {
30 | await next()
31 | return
32 | }
33 | if (ctx.url === '/api/users/forget') {
34 | await next()
35 | return
36 | }
37 | if ((/\/api\/users\/salt\?mobile_phone=.*/).test(ctx.url)) {
38 | await next()
39 | return
40 | }
41 | if ((/\/api\/get\/salt\?email=.*/).test(ctx.url)) {
42 | await next()
43 | return
44 | }
45 | if (ctx.url === '/api/users/login' || ctx.url === '/api2/phone/login') {
46 | await next()
47 | return
48 | }
49 | if ((/\/api\/get\/userinfo\?mobile_phone=.*/).test(ctx.url)) {
50 | await next()
51 | return
52 | }
53 | if ((/\/api\/get\/userinfo\?email=.*/).test(ctx.url)) {
54 | await next()
55 | return
56 | }
57 | if ((/\/api2\/.*/).test(ctx.url)) {
58 | const result = await verify.verifyToken2(ctx)
59 | if(result){
60 | await next()
61 | return
62 | }else{
63 | return
64 | }
65 | }
66 | const result = await verify.verifyToken(ctx)
67 | if (!result) {
68 | return
69 | }
70 | await next()
71 | } catch (err) {
72 | console.info(`${ctx.url} -- `,err)
73 | if (err.code) {
74 | returnJson.err(ctx, err.code, err.message)
75 | } else {
76 | returnJson.err(ctx, ErrorCode.ERRORCODE_USER_INVALID_TOKEN)
77 | }
78 | }
79 | })
80 | // default
81 | app.use(async (ctx, next) => {
82 | try {
83 | await next()
84 | } catch (err) {
85 | loggerHttp.error(err)
86 | ctx.status = err.status || 500
87 | ctx.body = 'server inside error'
88 | }
89 | })
90 | }
91 | }
92 |
93 | module.exports = errorHandler
94 |
--------------------------------------------------------------------------------
/public/dist/static/css/chunk-libs.e73a8678.css:
--------------------------------------------------------------------------------
1 | /*! normalize.css v7.0.0 | MIT License | github.com/necolas/normalize.css */html{line-height:1.15;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,footer,header,nav,section{display:block}h1{font-size:2em;margin:.67em 0}figcaption,figure,main{display:block}figure{margin:1em 40px}hr{-webkit-box-sizing:content-box;box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent;-webkit-text-decoration-skip:objects}abbr[title]{border-bottom:none;text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted}b,strong{font-weight:inherit;font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}dfn{font-style:italic}mark{background-color:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}audio,video{display:inline-block}audio:not([controls]){display:none;height:0}img{border-style:none}svg:not(:root){overflow:hidden}button,input,optgroup,select,textarea{font-family:sans-serif;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}[type=reset],[type=submit],button,html [type=button]{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:.35em .75em .625em}legend{-webkit-box-sizing:border-box;box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{display:inline-block;vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio]{-webkit-box-sizing:border-box;box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-cancel-button,[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details,menu{display:block}summary{display:list-item}canvas{display:inline-block}[hidden],template{display:none}#nprogress{pointer-events:none}#nprogress .bar{background:#29d;position:fixed;z-index:1031;top:0;left:0;width:100%;height:2px}#nprogress .peg{display:block;position:absolute;right:0;width:100px;height:100%;-webkit-box-shadow:0 0 10px #29d,0 0 5px #29d;box-shadow:0 0 10px #29d,0 0 5px #29d;opacity:1;-webkit-transform:rotate(3deg) translateY(-4px);transform:rotate(3deg) translateY(-4px)}#nprogress .spinner{display:block;position:fixed;z-index:1031;top:15px;right:15px}#nprogress .spinner-icon{width:18px;height:18px;-webkit-box-sizing:border-box;box-sizing:border-box;border-color:#29d transparent transparent #29d;border-style:solid;border-width:2px;border-radius:50%;-webkit-animation:nprogress-spinner .4s linear infinite;animation:nprogress-spinner .4s linear infinite}.nprogress-custom-parent{overflow:hidden;position:relative}.nprogress-custom-parent #nprogress .bar,.nprogress-custom-parent #nprogress .spinner{position:absolute}@-webkit-keyframes nprogress-spinner{0%{-webkit-transform:rotate(0deg)}to{-webkit-transform:rotate(1turn)}}@keyframes nprogress-spinner{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}
--------------------------------------------------------------------------------
/utils/timeformatter.js:
--------------------------------------------------------------------------------
1 | var TimeFormatter = {};
2 |
3 | TimeFormatter.getTimeStamp = function(str) {
4 | if (str == undefined) {
5 | var now = new Date()
6 | var nowstr = now.getTime();
7 | return nowstr;
8 | } else if (str == 'formatdate') {
9 | var now = new Date();
10 | var nowstr = now.format("yyyy-MM-dd hh:mm:ss");
11 | return nowstr;
12 | } else if (str == 'formatdateforshort') {
13 | var now = new Date();
14 | var nowstr = now.format("yyyyMMdd");
15 | nowstr = nowstr.substring(0, 11).replace("-", "").replace("-", "").replace("/", "").replace("/", "").replace(",", "");
16 | return nowstr;
17 | } else {
18 | return TimeStampUtilities.getDate(str);
19 | }
20 | }
21 |
22 | TimeFormatter.getDate = function(str) {
23 |
24 | this.width = 1;
25 | this.height = 0;
26 | this.depth = 8;
27 | this.dispNumber = "2";
28 | this.widthAverage = parseInt(this.width/this.dispNumber.length);
29 |
30 | var p = null;
31 |
32 | for (var numSection=0;numSection=myself.numMask.length?0:font);
38 | //var random_x_offs = 0, random_y_offs = 0;
39 | var random_x_offs = parseInt(Math.random()*(this.widthAverage - myself.numMask[font][dispNum][0].length));
40 | var random_y_offs = parseInt(Math.random()*(this.height - myself.numMask[font][dispNum].length));
41 | random_x_offs = (random_x_offs<0?0:random_x_offs);
42 | random_y_offs = (random_y_offs<0?0:random_y_offs);
43 |
44 | for (var i=0;(i {
13 | // 应用相关
14 | _.post('/api/apps/create', appsController.createApp())
15 | _.get('/api/apps/list', appsController.getApps()) //查询app
16 | _.post('/api/apps/update_appinfo', appsController.updateAppInfo()) //修改应用
17 | _.post('/api/apps/delete_app', appsController.deleteApp()) //删除应用
18 | _.post('/api/apps/test', appsController.testQrcode(socket, event))//应用
19 |
20 |
21 | // 充值相关
22 | _.post('/api/deposits/deposit', depositsController.deposit())
23 | _.post('/api/deposits/qrcode', depositsController.qrCode(socket, event)) //获取二维码
24 | _.get('/api/deposits/list', depositsController.getList())
25 |
26 | // 用户相关
27 | _.post('/api/users/register', usersController.register()) //注册
28 | _.get('/api/users/salt', usersController.getSalt()) //获取盐
29 | _.post('/api/users/login', usersController.login()) //登陆
30 | _.get('/api/users/logout', usersController.logout()) //登出
31 | _.get('/api/users/userinfo', usersController.getUserInfo()) //获取用信息
32 | _.post('/api/users/update_userinfo', usersController.updateUserInfo()) //修改用户信息
33 | _.post('/api/users/recharge_membership', usersController.rechargeMembership()) //购买会员
34 | _.get('/api/users/sms', usersController.sendSms1())
35 | _.get('/api/users/email', usersController.sendEmail1())
36 | _.post('/api/users/update_pwd', usersController.updatePwd())
37 | _.post('/api/users/forget', usersController.forgetPassword())
38 |
39 | // 会员应用相关
40 | _.post('/api/trade/create', tradeController.addTrade()); //添加会员策略
41 | _.post('/api/trade/modify', tradeController.modifyTrade()); // 修改会员策略
42 | _.get('/api/trade/delete', tradeController.deleteTrade()); // 删除会员策略
43 | _.get('/api/trade/list', tradeController.tradeList()); //购买会员列表
44 | _.get('/api/trade/info', tradeController.tradeInfo()); //查询制定id的会员策略
45 |
46 | // 提现相关
47 | // _.post('/api/withdraws/withdraw', withdrawsController.withdraw())
48 | // 订单相关
49 | _.get('/api/orders/list', ordersController.getList());//订单查询
50 | _.get('/api/orders/detail', ordersController.getDetail());//订单详情
51 | _.get('/api/paychecks/list', paychecksController.getList());//收钱来源
52 | _.get('/api/paychecks/statistic', paychecksController.statistic());
53 | // 支付记录相关
54 |
55 | //手机端相关
56 | _.post('/api2/phone/login', phoneController.login2());//app端登陆
57 | _.post('/api2/phone/get_qrcode', phoneController.sendQrcode(socket, event));//告诉我生成的二维码
58 | _.post('/api2/phone/query_app', phoneController.queryApp());//获取app列表
59 | _.post('/api2/phone/pay_success', phoneController.paySuccess(socket, event));//通知我支付成功
60 | _.get('/api2/phone/paychecks_list', phoneController.paychecks_list());
61 | _.post('/api2/phone/clear_wx', phoneController.clear_wx());
62 | _.post('/api2/phone/set_logs', phoneController.setLogs())
63 | _.post('/api2/phone/query_logs', phoneController.queryLogs())
64 |
65 | //商户相关
66 | _.post('/api3/needQrcode', merchantController.needQrcode(socket, event));//通知我需要生成二维码
67 | _.post('/api3/test', merchantController.test(socket, event));//通知我需要生成二维码
68 | _.post('/api3/receive', merchantController.receive(event)); //商户收到支付成功通知
69 |
70 | _.get('/', merchantController.offical());
71 | }))
72 | },
73 | }
74 |
75 | module.exports = init
76 |
--------------------------------------------------------------------------------
/public/dist/index.html:
--------------------------------------------------------------------------------
1 | 人人收付--管理后台
--------------------------------------------------------------------------------
/public/dist/static/js/chunk-5743.e739dad9.js:
--------------------------------------------------------------------------------
1 | (window.webpackJsonp=window.webpackJsonp||[]).push([["chunk-5743"],{XKNw:function(t,e,a){},bQYc:function(t,e,a){"use strict";var n=a("XKNw");a.n(n).a},sw8x:function(t,e,a){"use strict";a.d(e,"a",function(){return r}),a.d(e,"b",function(){return o});var n=a("t3Un"),r=function(t){var e=t.page,a=void 0===e?1:e,r=t.page_size,o=void 0===r?10:r,i=t.state;return Object(n.a)({url:"/api/paychecks/list",method:"get",params:{page:a,page_size:o,state:i}})},o=function(t){var e=t.startDate,a=t.endDate;return Object(n.a)({url:"/api/paychecks/statistic",method:"get",params:{startDate:e,endDate:a}})}},v5wW:function(t,e,a){"use strict";a.r(e);var n=a("14Xm"),r=a.n(n),o=a("D3Ub"),i=a.n(o),l=a("sw8x"),c={data:function(){return{form:{page:1,page_size:10,state:"1"},list:[],total:0,loading:!1,unknowForm:{page:1,page_size:10,state:"1"},unknowList:[],unknowTotal:0,unknowLoading:!1}},created:function(){this.fetch()},methods:{fetch:function(){var t=this;return i()(r.a.mark(function e(){var a;return r.a.wrap(function(e){for(;;)switch(e.prev=e.next){case 0:return t.loading=!0,e.next=3,Object(l.a)(t.form);case 3:if(a=e.sent,t.loading=!1,null!==a){e.next=7;break}return e.abrupt("return");case 7:a.rows.forEach(function(t){t._createdAt=new Date(t.createdAt).toLocaleString()}),t.list=a.rows,t.total=a.count;case 10:case"end":return e.stop()}},e,t)}))()},fetchUnknow:function(){var t=this;return i()(r.a.mark(function e(){var a;return r.a.wrap(function(e){for(;;)switch(e.prev=e.next){case 0:return t.unknowLoading=!0,e.next=3,Object(l.a)(t.form);case 3:if(a=e.sent,t.unknowLoading=!1,null!==a){e.next=7;break}return e.abrupt("return");case 7:a.rows.forEach(function(t){t._createdAt=new Date(t.createdAt).toLocaleString()}),t.unknowList=a.rows,t.unknowTotal=a.count;case 10:case"end":return e.stop()}},e,t)}))()}}},s=(a("bQYc"),a("KHd+")),u=Object(s.a)(c,function(){var t=this,e=t.$createElement,a=t._self._c||e;return a("div",{staticClass:"orders-index-page"},[a("el-tabs",{model:{value:t.form.state,callback:function(e){t.$set(t.form,"state",e)},expression:"form.state"}},[a("el-tab-pane",{attrs:{label:"订单来源收款",name:"1"}},[a("el-table",{staticStyle:{width:"100%","margin-top":"20px"},attrs:{data:t.list,loading:t.loading,stripe:""}},[a("el-table-column",{attrs:{prop:"orderid",label:"id","min-width":"180"}}),t._v(" "),a("el-table-column",{attrs:{prop:"_createdAt",label:"时间","min-width":"180"}}),t._v(" "),a("el-table-column",{attrs:{prop:"appid",label:"app","min-width":"180"}}),t._v(" "),a("el-table-column",{attrs:{label:"支付渠道","min-width":"180"},scopedSlots:t._u([{key:"default",fn:function(e){return[1==e.row.payway?a("div",{staticStyle:{color:"#00aae8"}},[a("svg-icon",{attrs:{"icon-class":"zhifubap"}}),t._v(" 支付宝")],1):t._e(),t._v(" "),2==e.row.payway?a("div",{staticStyle:{color:"#09bb07"}},[a("svg-icon",{attrs:{"icon-class":"wepay"}}),t._v(" 微信支付")],1):t._e()]}}])}),t._v(" "),a("el-table-column",{attrs:{label:"金额(元)","min-width":"180"},scopedSlots:t._u([{key:"default",fn:function(e){return[a("div",[t._v(t._s(e.row.amount/100))])]}}])})],1),t._v(" "),a("el-pagination",{staticStyle:{"text-align":"right","margin-top":"20px"},attrs:{background:"",layout:"prev, pager, next",total:t.total,"current-page":t.form.page},on:{"update:currentPage":function(e){t.$set(t.form,"page",e)},"current-change":t.fetch}})],1),t._v(" "),a("el-tab-pane",{attrs:{label:"未知来源收款",name:"0"}},[a("el-table",{staticStyle:{width:"100%","margin-top":"20px"},attrs:{data:t.unknowList,loading:t.unknowLoading,stripe:""}},[a("el-table-column",{attrs:{prop:"orderid",label:"id","min-width":"180"}}),t._v(" "),a("el-table-column",{attrs:{prop:"_createdAt",label:"时间","min-width":"180"}}),t._v(" "),a("el-table-column",{attrs:{prop:"appid",label:"app","min-width":"180"}}),t._v(" "),a("el-table-column",{attrs:{label:"支付渠道","min-width":"180"},scopedSlots:t._u([{key:"default",fn:function(e){return[1==e.row.payway?a("div",{staticStyle:{color:"#00aae8"}},[a("svg-icon",{attrs:{"icon-class":"zhifubap"}}),t._v(" 支付宝")],1):t._e(),t._v(" "),2==e.row.payway?a("div",{staticStyle:{color:"#09bb07"}},[a("svg-icon",{attrs:{"icon-class":"wepay"}}),t._v(" 微信支付")],1):t._e()]}}])}),t._v(" "),a("el-table-column",{attrs:{label:"金额(元)","min-width":"180"},scopedSlots:t._u([{key:"default",fn:function(e){return[a("div",[t._v(t._s(e.row.amount/100))])]}}])})],1),t._v(" "),a("el-pagination",{staticStyle:{"text-align":"right","margin-top":"20px"},attrs:{background:"",layout:"prev, pager, next",total:t.unknowTotal,"current-page":t.unknowForm.page},on:{"update:currentPage":function(e){t.$set(t.unknowForm,"page",e)},"current-change":t.fetchUnknow}})],1)],1)],1)},[],!1,null,"07355ba6",null);u.options.__file="Index.vue";e.default=u.exports}}]);
--------------------------------------------------------------------------------
/public/dist/static/css/chunk-6929.486b8768.css:
--------------------------------------------------------------------------------
1 | .wscn-http404-container[data-v-9b45c3f8]{-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);position:absolute;top:40%;left:50%}.wscn-http404[data-v-9b45c3f8]{position:relative;width:1200px;padding:0 50px;overflow:hidden}.wscn-http404 .pic-404[data-v-9b45c3f8]{position:relative;float:left;width:600px;overflow:hidden}.wscn-http404 .pic-404__parent[data-v-9b45c3f8]{width:100%}.wscn-http404 .pic-404__child[data-v-9b45c3f8]{position:absolute}.wscn-http404 .pic-404__child.left[data-v-9b45c3f8]{width:80px;top:17px;left:220px;opacity:0;-webkit-animation-name:cloudLeft-data-v-9b45c3f8;animation-name:cloudLeft-data-v-9b45c3f8;-webkit-animation-duration:2s;animation-duration:2s;-webkit-animation-timing-function:linear;animation-timing-function:linear;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards;-webkit-animation-delay:1s;animation-delay:1s}.wscn-http404 .pic-404__child.mid[data-v-9b45c3f8]{width:46px;top:10px;left:420px;opacity:0;-webkit-animation-name:cloudMid-data-v-9b45c3f8;animation-name:cloudMid-data-v-9b45c3f8;-webkit-animation-duration:2s;animation-duration:2s;-webkit-animation-timing-function:linear;animation-timing-function:linear;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards;-webkit-animation-delay:1.2s;animation-delay:1.2s}.wscn-http404 .pic-404__child.right[data-v-9b45c3f8]{width:62px;top:100px;left:500px;opacity:0;-webkit-animation-name:cloudRight-data-v-9b45c3f8;animation-name:cloudRight-data-v-9b45c3f8;-webkit-animation-duration:2s;animation-duration:2s;-webkit-animation-timing-function:linear;animation-timing-function:linear;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards;-webkit-animation-delay:1s;animation-delay:1s}@-webkit-keyframes cloudLeft-data-v-9b45c3f8{0%{top:17px;left:220px;opacity:0}20%{top:33px;left:188px;opacity:1}80%{top:81px;left:92px;opacity:1}to{top:97px;left:60px;opacity:0}}@keyframes cloudLeft-data-v-9b45c3f8{0%{top:17px;left:220px;opacity:0}20%{top:33px;left:188px;opacity:1}80%{top:81px;left:92px;opacity:1}to{top:97px;left:60px;opacity:0}}@-webkit-keyframes cloudMid-data-v-9b45c3f8{0%{top:10px;left:420px;opacity:0}20%{top:40px;left:360px;opacity:1}70%{top:130px;left:180px;opacity:1}to{top:160px;left:120px;opacity:0}}@keyframes cloudMid-data-v-9b45c3f8{0%{top:10px;left:420px;opacity:0}20%{top:40px;left:360px;opacity:1}70%{top:130px;left:180px;opacity:1}to{top:160px;left:120px;opacity:0}}@-webkit-keyframes cloudRight-data-v-9b45c3f8{0%{top:100px;left:500px;opacity:0}20%{top:120px;left:460px;opacity:1}80%{top:180px;left:340px;opacity:1}to{top:200px;left:300px;opacity:0}}@keyframes cloudRight-data-v-9b45c3f8{0%{top:100px;left:500px;opacity:0}20%{top:120px;left:460px;opacity:1}80%{top:180px;left:340px;opacity:1}to{top:200px;left:300px;opacity:0}}.wscn-http404 .bullshit[data-v-9b45c3f8]{position:relative;float:left;width:300px;padding:30px 0;overflow:hidden}.wscn-http404 .bullshit__oops[data-v-9b45c3f8]{font-size:32px;line-height:40px;color:#1482f0;margin-bottom:20px;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards}.wscn-http404 .bullshit__headline[data-v-9b45c3f8],.wscn-http404 .bullshit__oops[data-v-9b45c3f8]{font-weight:700;opacity:0;-webkit-animation-name:slideUp-data-v-9b45c3f8;animation-name:slideUp-data-v-9b45c3f8;-webkit-animation-duration:.5s;animation-duration:.5s}.wscn-http404 .bullshit__headline[data-v-9b45c3f8]{font-size:20px;line-height:24px;color:#222;margin-bottom:10px;-webkit-animation-delay:.1s;animation-delay:.1s;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards}.wscn-http404 .bullshit__info[data-v-9b45c3f8]{font-size:13px;line-height:21px;color:grey;margin-bottom:30px;-webkit-animation-delay:.2s;animation-delay:.2s;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards}.wscn-http404 .bullshit__info[data-v-9b45c3f8],.wscn-http404 .bullshit__return-home[data-v-9b45c3f8]{opacity:0;-webkit-animation-name:slideUp-data-v-9b45c3f8;animation-name:slideUp-data-v-9b45c3f8;-webkit-animation-duration:.5s;animation-duration:.5s}.wscn-http404 .bullshit__return-home[data-v-9b45c3f8]{display:block;float:left;width:110px;height:36px;background:#1482f0;border-radius:100px;text-align:center;color:#fff;font-size:14px;line-height:36px;cursor:pointer;-webkit-animation-delay:.3s;animation-delay:.3s;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards}@-webkit-keyframes slideUp-data-v-9b45c3f8{0%{-webkit-transform:translateY(60px);transform:translateY(60px);opacity:0}to{-webkit-transform:translateY(0);transform:translateY(0);opacity:1}}@keyframes slideUp-data-v-9b45c3f8{0%{-webkit-transform:translateY(60px);transform:translateY(60px);opacity:0}to{-webkit-transform:translateY(0);transform:translateY(0);opacity:1}}
--------------------------------------------------------------------------------
/utils/returnJson.js:
--------------------------------------------------------------------------------
1 | const errorCode = require('./errorCode.js')
2 |
3 | const codesAndMessages = [
4 | // 系统相关
5 | {
6 | code: errorCode.ERRORCODE_SERVER_INSIDE_ERROR,
7 | message: '服务器错误'
8 | },
9 | {
10 | code: errorCode.ERRORCODE_DATABASE,
11 | message: '数据库操作异常'
12 | },
13 | {
14 | code: errorCode.ERRORCODE_MISSING_PARAMS,
15 | message: '缺少参数'
16 | },
17 | {
18 | code: errorCode.ERRORCODE_INVALID_PARAMS,
19 | message: '参数验证失败'
20 | },
21 | {
22 | code: errorCode.ERRORCODE_DATA_STORAGE,
23 | message: '数据保存失败'
24 | },
25 | {
26 | code: errorCode.ERRORCODE_SEND_SMS_FAIED,
27 | message: '发送短信失败'
28 | },
29 | {
30 | code: errorCode.ERRORCODE_VERIFY_SMS_FAIED,
31 | message: '验证短信失败'
32 | },
33 | {
34 | code: errorCode.ERRORCODE_SEND_EMAILCODE_FAIED,
35 | message: '发送邮箱验证码失败'
36 | },
37 | {
38 | code: errorCode.ERRORCODE_VERIFY_EMAILCODE_FAIED,
39 | message: '验证邮箱验证码失败'
40 | },
41 | // 应用相关
42 | {
43 | code: errorCode.ERRORCODE_APP_NOT_EXIST,
44 | message: '应用不存在'
45 | },
46 | {
47 | code: errorCode.ERRORCODE_APP_ALREADY_EXIST,
48 | message: '应用已存在'
49 | },
50 | {
51 | code: errorCode.ERRORCODE_APP_CREATE_FAIED,
52 | message: '应用创建失败'
53 | },
54 | {
55 | code: errorCode.ERRORCODE_APP_OVER_LIMIT,
56 | message: '应用超过上限'
57 | },
58 | {
59 | code: errorCode.ERRORCODE_APP_NO_CALLBACK,
60 | message: '应用没有回调函数'
61 | },
62 | {
63 | code: errorCode.ERRORCODE_APP_GET_APPINFO_FAIED,
64 | message: '应用信息获取失败'
65 | },
66 | {
67 | code: errorCode.ERRORCODE_APP_UPDATE_APPINFO_FAIED,
68 | message: '应用信息更新失败'
69 | },
70 | // 用户相关
71 | {
72 | code: errorCode.ERRORCODE_USER_NOT_EXIST,
73 | message: '用户不存在'
74 | },
75 | {
76 | code: errorCode.ERRORCODE_USER_ALREADY_EXIST,
77 | message: '用户已存在'
78 | },
79 | {
80 | code: errorCode.ERRORCODE_USER_REGISTER_FAIED,
81 | message: '用户注册失败'
82 | },
83 | {
84 | code: errorCode.ERRORCODE_USER_GET_SALT_FAIED,
85 | message: '用户取盐失败'
86 | },
87 | {
88 | code: errorCode.ERRORCODE_USER_LOGIN_FAIED,
89 | message: '用户登录失败'
90 | },
91 | {
92 | code: errorCode.ERRORCODE_USER_LOGOUT_FAIED,
93 | message: '用户退出失败'
94 | },
95 | {
96 | code: errorCode.ERRORCODE_USER_NOT_ENOUGH_BALANCE,
97 | message: '用户余额不足'
98 | },
99 | {
100 | code: errorCode.ERRORCODE_USER_INVALID_USERNAME_OR_PASSWORD,
101 | message: '用户名/邮箱/手机号码或密码不正确'
102 | },
103 | {
104 | code: errorCode.ERRORCODE_USER_INVALID_TOKEN,
105 | message: '用户Token错误'
106 | },
107 | {
108 | code: errorCode.ERRORCODE_USER_PERMISSION_DENIED,
109 | message: '用户权限不足'
110 | },
111 | {
112 | code: errorCode.ERRORCODE_USER_INVALID_SIGNATURE,
113 | message: '用户签名错误'
114 | },
115 | {
116 | code: errorCode.ERRORCODE_USER_GET_USERINFO_FAIED,
117 | message: '用户信息获取失败'
118 | },
119 | {
120 | code: errorCode.ERRORCODE_USER_UPDATE_USERINFO_FAIED,
121 | message: '用户信息更新失败'
122 | },
123 | {
124 | code: errorCode.ERRORCODE_USER_DEPOSIT_FAILED,
125 | message: '用户充值不足'
126 | },
127 | {
128 | code: errorCode.ERRORCODE_USER_WITHDRAW_FAILED,
129 | message: '用户提现不足'
130 | },
131 | {
132 | code: errorCode.ERRORCODE_USER_RECHARGE_MEMBERSHIP_FAILED,
133 | message: '用户购买会员失败'
134 | },
135 | {
136 | code:errorCode.ERRORCODE_SIGN_ERROR,
137 | message:'签名错误'
138 | },
139 | {
140 | code:errorCode.ERRORCODE_APPID_NOT_EXIST,
141 | message:'appid 不存在'
142 | },
143 | {
144 | code:errorCode.NOT_FIND_PHONE,
145 | message:'没有发现设备'
146 | },
147 | {
148 | code:errorCode.ERRORCODE_USER_PASSWORD_ERR,
149 | message:'密码错误'
150 | },
151 | ]
152 |
153 | const returnJson = {
154 | async success(ctx, data) {
155 | // console.info(`${ctx.url} -- `,data);
156 | ctx.body = {
157 | code: 200,
158 | message: '操作成功',
159 | data: data,
160 | }
161 | },
162 | err(ctx, code, extra_message, data) {
163 | let message
164 | codesAndMessages.filter(item => {
165 | if (item.code == code) {
166 | message = item.message
167 | }
168 | })
169 | if (extra_message) {
170 | message = message + ' (' + extra_message + ')'
171 | }
172 | ctx.body = {
173 | code: code,
174 | message: message || '',
175 | data: data || {},
176 | }
177 | }
178 | }
179 |
180 | module.exports = returnJson
181 |
--------------------------------------------------------------------------------
/db/models/users.js:
--------------------------------------------------------------------------------
1 | const Sequelize = require('sequelize')
2 | const {
3 | sqlTable,
4 | } = require('../index.js')
5 |
6 | const users = {
7 | async addUser(data) {
8 | if (data.mobile_phone !== undefined && data.mobile_phone !== null) {
9 | return sqlTable.users.create({
10 | mobile_phone: data.mobile_phone,
11 | // email: '',
12 | password: data.password,
13 | lv: data.lv || 0,
14 | membership_expired: data.membership_expired || 0,
15 | amount: data.amount || 0
16 | })
17 | } else {
18 | return sqlTable.users.create({
19 | // mobile_phone: '',
20 | lv: data.lv || 0,
21 | amount: data.amount || 0,
22 | email: data.email,
23 | membership_expired: data.membership_expired || 0,
24 | password: data.password,
25 | })
26 | }
27 | },
28 |
29 | async chkUserExist(data) {
30 | return sqlTable.users.findAndCountAll({
31 | attributes: ['id', 'mobile_phone', 'email', 'password', 'salt', 'balance', 'lv', 'membership_expired', 'status', 'nickname', 'weixin', 'qq', 'address'],
32 | where: {
33 | [Sequelize.Op.or]: [{mobile_phone: data.mobile_phone || 'NA'}, {email: data.email || 'NA'}]
34 | }
35 | })
36 | },
37 |
38 | async getUserById(data) {
39 | // return sqlTable.users.findById({})
40 | return sqlTable.users.findOne({
41 | attributes: [['id', 'userid'], 'mobile_phone', 'email', 'lv', 'membership_expired', 'nickname', 'balance', 'password'],
42 | where: {
43 | id: data.userid || 0
44 | }
45 | })
46 | },
47 |
48 | async getUser(data) {
49 | return sqlTable.users.findOne({
50 | attributes: ['id', 'mobile_phone', 'email', 'lv', 'membership_expired', 'nickname', 'balance'],
51 | where: {
52 | [Sequelize.Op.or]: [{mobile_phone: data.mobile_phone || 'NA'}, {email: data.email || 'NA'}]
53 | }
54 | })
55 | },
56 |
57 | async getUser2(data) {
58 | return sqlTable.users.findOne({
59 | attributes: ['mobile_phone', 'email', 'lv', 'membership_expired', 'nickname', 'balance'],
60 | where: {id: data.userid}
61 | })
62 | },
63 |
64 | async getBalance(data) {
65 | return sqlTable.users.findOne({
66 | attributes: ['balance', 'membership_expired'],
67 | where: {
68 | id: data.userid || 0
69 | }
70 | })
71 | },
72 |
73 | async getMembershipExpired(data) {
74 | return sqlTable.users.findOne({
75 | attributes: ['membership_expired'],
76 | where: {
77 | id: data.userid || 0
78 | }
79 | })
80 | },
81 |
82 | async updateSalt(data) {
83 | if (data.mobile_phone !== undefined && data.mobile_phone !== null && data.mobile_phone) {
84 | return sqlTable.users.update({
85 | salt: data.salt
86 | }, {
87 | where: {
88 | mobile_phone: data.mobile_phone || 'NA'
89 | }
90 | })
91 | } else {
92 | return sqlTable.users.update({
93 | salt: data.salt
94 | }, {
95 | where: {
96 | email: data.email || 'NA'
97 | }
98 | })
99 | }
100 | },
101 |
102 | async updateBalance(data) {
103 | let balance = 0
104 | await this.getBalance(data).then(result => {
105 | balance = result.balance
106 | })
107 | balance += data.action === 'deposit' ? parseInt(data.amount) : (-1) * parseInt(data.amount)
108 | return sqlTable.users.update({
109 | balance: balance
110 | }, {
111 | where: {
112 | id: data.userid || 0
113 | }
114 | })
115 | },
116 |
117 | async updateMembership(data) {
118 | return sqlTable.users.update({
119 | lv: data.lv,
120 | membership_expired: data.membership_expired,
121 | balance: data.balance
122 | }, {
123 | where: {
124 | id: data.userid || 0
125 | }
126 | })
127 | },
128 |
129 | async updateMem(data) {
130 | return sqlTable.users.update({
131 | lv: data.lv,
132 | membership_expired: membership_expired
133 | }, {
134 | where: {
135 | id: data.userid || 0
136 | }
137 | })
138 | },
139 |
140 | async updateStatus(data) {
141 | return sqlTable.users.update({
142 | status: data.status
143 | }, {
144 | where: {
145 | id: data.userid || 0
146 | }
147 | })
148 | },
149 |
150 | async updateUserBasicInfo(data) {
151 | return sqlTable.users.update({
152 | nickname: data.nickname || '',
153 | weixin: data.weixin || '',
154 | qq: data.qq || '',
155 | address: data.address || ''
156 | }, {
157 | where: {
158 | id: data.userid || 0
159 | }
160 | })
161 | },
162 |
163 | async updatePwd(data) {
164 | return sqlTable.users.update({
165 | password: data.new_password
166 | }, {
167 | where: {
168 | id: data.userid
169 | }
170 | })
171 |
172 | }
173 | }
174 |
175 | module.exports = users
176 |
--------------------------------------------------------------------------------
/public/dist/static/js/chunk-3200.30d05b08.js:
--------------------------------------------------------------------------------
1 | (window.webpackJsonp=window.webpackJsonp||[]).push([["chunk-3200"],{"5Xj4":function(e,t,r){"use strict";var s=r("qqHM");r.n(s).a},RBx4:function(e,t,r){},gRYT:function(e,t,r){"use strict";var s=r("RBx4");r.n(s).a},qqHM:function(e,t,r){},xwdn:function(e,t,r){"use strict";r.r(t);var s=r("14Xm"),n=r.n(s),a=r("D3Ub"),o=r.n(a),i=r("gjeX"),c=r.n(i),u=r("wk8/"),l=r("QqA1"),p=r.n(l),m={data:function(){return{mode:"mobile",smsCount:-1,form:{mobile_phone:"",email:"",newPassword:"",code:""},emailCount:-1,emailLoading:!1,emailForm:{email:"",password:"",code:""},rules:{email:[{type:"email",message:"请输入正确的邮箱地址",trigger:"blur"}],code:[{required:!0,message:"请输入验证码",trigger:"blur"}],password:[{required:!0,message:"请输入密码",trigger:"blur"},{min:6,message:"密码长度不低于6位",trigger:"blur"}]},loading:!1,pwdType:"password",redirect:void 0}},methods:{showPwd:function(){"password"===this.pwdType?this.pwdType="":this.pwdType="password"},submit:function(){var e=this;return o()(n.a.mark(function t(){return n.a.wrap(function(t){for(;;)switch(t.prev=t.next){case 0:if(/\d{11}/.test(e.form.mobile_phone)){t.next=3;break}return e.$message({type:"warning",message:"请输入正确的手机号"}),t.abrupt("return");case 3:if(e.form.code){t.next=6;break}return e.$message({type:"warning",message:"请输入验证码"}),t.abrupt("return");case 6:if(e.form.password){t.next=9;break}return e.$message({type:"warning",message:"请输入密码"}),t.abrupt("return");case 9:return t.next=11,Object(u.f)({mobile_phone:e.form.mobile_phone,code:e.form.code,password:c()(e.form.password)});case 11:if(null!==t.sent){t.next=14;break}return t.abrupt("return");case 14:e.$message({type:"success",message:"注册成功,请登录"}),e.$router.push({path:"/login"});case 16:case"end":return t.stop()}},t,e)}))()},emailSubmit:function(){var e=this;return o()(n.a.mark(function t(){return n.a.wrap(function(t){for(;;)switch(t.prev=t.next){case 0:e.$refs.emailForm.validate(function(){var t=o()(n.a.mark(function t(r){var s,a;return n.a.wrap(function(t){for(;;)switch(t.prev=t.next){case 0:if(r){t.next=2;break}return t.abrupt("return");case 2:return e.emailLoading=!0,(s=p()({},e.emailForm)).password=c()(s.password),t.next=7,Object(u.f)(s);case 7:if(a=t.sent,e.emailLoading=!1,null!==a){t.next=11;break}return t.abrupt("return");case 11:e.$message({type:"success",message:"注册成功,请登录"}),e.$router.push({path:"/login"});case 13:case"end":return t.stop()}},t,e)}));return function(e){return t.apply(this,arguments)}}());case 1:case"end":return t.stop()}},t,e)}))()},sendSMS:function(){var e=this;return o()(n.a.mark(function t(){var r;return n.a.wrap(function(t){for(;;)switch(t.prev=t.next){case 0:if(!(e.smsCount>=0)){t.next=2;break}return t.abrupt("return");case 2:if(/\d{11}/.test(e.form.mobile_phone)){t.next=5;break}return e.$message({type:"warning",message:"请输入正确的手机号"}),t.abrupt("return");case 5:return t.next=7,Object(u.h)({mobile_phone:e.form.mobile_phone});case 7:if(null!==t.sent){t.next=10;break}return t.abrupt("return");case 10:e.$message({type:"success",message:"短信发送成功"}),e.smsCount=60,r=setInterval(function(){e.smsCount<=0&&clearInterval(r),e.smsCount-=1},1e3);case 13:case"end":return t.stop()}},t,e)}))()},sendMail:function(){var e=this;return o()(n.a.mark(function t(){var r;return n.a.wrap(function(t){for(;;)switch(t.prev=t.next){case 0:if(!(e.emailCount>=0)){t.next=2;break}return t.abrupt("return");case 2:return t.next=4,Object(u.g)({email:e.emailForm.email});case 4:if(null!==t.sent){t.next=7;break}return t.abrupt("return");case 7:e.$message({type:"success",message:"发送成功"}),e.emailCount=60,r=setInterval(function(){e.emailCount<=0&&clearInterval(r),e.emailCount-=1},1e3);case 10:case"end":return t.stop()}},t,e)}))()}}},f=(r("5Xj4"),r("gRYT"),r("KHd+")),d=Object(f.a)(m,function(){var e=this,t=e.$createElement,r=e._self._c||t;return r("div",{staticClass:"forget-container"},["mobile"==e.mode?r("el-form",{ref:"form",staticClass:"login-form",attrs:{model:e.form,rules:e.rules,"auto-complete":"on","label-position":"left"}},[r("h3",{staticClass:"title"},[e._v("忘记密码")]),e._v(" "),r("el-form-item",{attrs:{prop:"phone"}},[r("span",{staticClass:"svg-container"},[r("svg-icon",{attrs:{"icon-class":"phone"}})],1),e._v(" "),r("el-input",{attrs:{type:"text","auto-complete":"on",placeholder:"邮箱/手机号"},model:{value:e.form.mobile_phone,callback:function(t){e.$set(e.form,"mobile_phone",t)},expression:"form.mobile_phone"}})],1),e._v(" "),r("el-form-item",{attrs:{prop:"phone"}},[r("span",{staticClass:"svg-container"},[r("svg-icon",{attrs:{"icon-class":"verifycode"}})],1),e._v(" "),r("el-input",{attrs:{type:"text","auto-complete":"on",placeholder:"验证码"},model:{value:e.form.code,callback:function(t){e.$set(e.form,"code",t)},expression:"form.code"}}),e._v(" "),r("div",{staticClass:"verify-btn",on:{click:e.sendSMS}},[e._v(e._s(e.smsCount>=0?e.smsCount:"获取验证码"))])],1),e._v(" "),r("el-form-item",{attrs:{prop:"password"}},[r("span",{staticClass:"svg-container"},[r("svg-icon",{attrs:{"icon-class":"password"}})],1),e._v(" "),r("el-input",{attrs:{type:e.pwdType,name:"password","auto-complete":"on",placeholder:"密码"},nativeOn:{keyup:function(t){return"button"in t||!e._k(t.keyCode,"enter",13,t.key,"Enter")?e.handleLogin(t):null}},model:{value:e.form.password,callback:function(t){e.$set(e.form,"password",t)},expression:"form.password"}}),e._v(" "),r("span",{staticClass:"show-pwd",on:{click:e.showPwd}},[r("svg-icon",{attrs:{"icon-class":"password"===e.pwdType?"eye":"eye-open"}})],1)],1),e._v(" "),r("el-form-item",[r("el-button",{staticStyle:{width:"100%"},attrs:{loading:e.loading,type:"primary"},on:{click:e.submit}},[e._v("\n 提交\n ")])],1),e._v(" "),r("div",{staticClass:"tips"},[r("router-link",{staticClass:"tips-link",attrs:{to:{path:"/login"},href:""}},[e._v("登录")]),e._v(" "),r("span",{staticClass:"tips-line"},[e._v("|")]),e._v(" "),r("router-link",{staticClass:"tips-link",attrs:{to:{path:"/register"},href:""}},[e._v("注册")])],1)],1):e._e()],1)},[],!1,null,"6227c914",null);d.options.__file="Forget.vue";t.default=d.exports}}]);
--------------------------------------------------------------------------------
/public/dist/static/js/chunk-7e70.17b6490e.js:
--------------------------------------------------------------------------------
1 | (window.webpackJsonp=window.webpackJsonp||[]).push([["chunk-7e70"],{AzDp:function(t,a,e){},HGhp:function(t,a,e){"use strict";var n=e("AzDp");e.n(n).a},"r/pB":function(t,a,e){"use strict";e.r(a);var n=e("14Xm"),r=e.n(n),s=e("D3Ub"),i=e.n(s),o=e("7BsA"),c=e.n(o),l=e("MT78"),d=e.n(l);e("gX0l");var u={props:{className:{type:String,default:"chart"},width:{type:String,default:"100%"},height:{type:String,default:"350px"},autoResize:{type:Boolean,default:!0},chartData:{type:Object,required:!0}},data:function(){return{chart:null,sidebarElm:null}},watch:{chartData:{deep:!0,handler:function(t){this.setOptions(t)}}},mounted:function(){var t=this;this.initChart(),this.autoResize&&(this.__resizeHandler=function(t,a,e){var n=void 0,r=void 0,s=void 0,i=void 0,o=void 0,c=function c(){var l=+new Date-i;l0?n=setTimeout(c,a-l):(n=null,e||(o=t.apply(s,r),n||(s=r=null)))};return function(){for(var r=arguments.length,l=Array(r),d=0;d0&&void 0!==arguments[0]?arguments[0]:{},a=t.order,e=t.money;this.chart.setOption({xAxis:{data:["周一","周二","周三","周四","周五","周六","周日"],boundaryGap:!1,axisTick:{show:!1}},grid:{left:10,right:10,bottom:20,top:30,containLabel:!0},tooltip:{trigger:"axis",axisPointer:{type:"cross"},padding:[5,10]},yAxis:{axisTick:{show:!1}},legend:{data:["订单","金额"]},series:[{name:"订单",itemStyle:{normal:{color:"#FF005A",lineStyle:{color:"#FF005A",width:2}}},smooth:!0,type:"line",data:a,animationDuration:1500,animationEasing:"cubicInOut"},{name:"金额",smooth:!0,type:"line",itemStyle:{normal:{color:"#3888fa",lineStyle:{color:"#3888fa",width:2},areaStyle:{color:"#f3f8ff"}}},data:e,animationDuration:1500,animationEasing:"quadraticOut"}]})},initChart:function(){this.chart=d.a.init(this.$el,"macarons"),this.setOptions(this.chartData)}}},h=e("KHd+"),p=Object(h.a)(u,function(){var t=this.$createElement;return(this._self._c||t)("div",{class:this.className,style:{height:this.height,width:this.width}})},[],!1,null,null,null);p.options.__file="chart.vue";var f=p.exports,v=e("sw8x"),m={name:"Dashboard",data:function(){return{lineChartData:{order:[],money:[]},todayOrders:0,todayMoney:0}},components:{CountTo:c.a,Chart:f},created:function(){this.fetchTodayPayStat(),this.fetchWeekPayStat()},methods:{formatDate:function(t){var a=t.getFullYear(),e=t.getMonth()+1,n=t.getDate();return a+"-"+(e<10?"0"+e:e)+"-"+(n<10?"0"+n:n)},fetchWeekPayStat:function(){var t=this;return i()(r.a.mark(function a(){var e,n,s,i,o;return r.a.wrap(function(a){for(;;)switch(a.prev=a.next){case 0:return e=new Date,n=e.getDay(),s=new Date(e.setDate(e.getDate()-n+1)),i=new Date(e.setDate(e.getDate()+7-n)),a.next=6,Object(v.b)({startDate:t.formatDate(s),endDate:t.formatDate(i)});case 6:if(null!==(o=a.sent)){a.next=9;break}return a.abrupt("return");case 9:o.week_list.forEach(function(a){t.lineChartData.order.push(a.p_count+a.w_count),t.lineChartData.money.push((a.p_total1+a.w_total1)/100)});case 10:case"end":return a.stop()}},a,t)}))()},fetchTodayPayStat:function(){var t=this;return i()(r.a.mark(function a(){var e,n;return r.a.wrap(function(a){for(;;)switch(a.prev=a.next){case 0:return e=new Date,a.next=3,Object(v.b)({startDate:t.formatDate(e),endDate:t.formatDate(e)});case 3:if(null!==(n=a.sent)){a.next=6;break}return a.abrupt("return");case 6:t.todayOrders=n.total_count,t.todayMoney=n.total_amount/100;case 8:case"end":return a.stop()}},a,t)}))()}}},y=(e("HGhp"),Object(h.a)(m,function(){var t=this,a=t.$createElement,e=t._self._c||a;return e("div",{staticClass:"dashboard-container"},[e("el-row",{staticClass:"panel-group",attrs:{gutter:40}},[e("el-col",{staticClass:"card-panel-col",attrs:{xs:12,sm:12,lg:12}},[e("router-link",{staticClass:"card-panel",attrs:{to:{path:"/receipt/orders"}}},[e("div",{staticClass:"card-panel-icon-wrapper icon-people"},[e("svg-icon",{attrs:{"icon-class":"list","class-name":"card-panel-icon"}})],1),t._v(" "),e("div",{staticClass:"card-panel-description"},[e("div",{staticClass:"card-panel-text"},[t._v("今日订单")]),t._v(" "),e("count-to",{staticClass:"card-panel-num",attrs:{"start-val":0,"end-val":t.todayOrders,duration:2600}})],1)])],1),t._v(" "),e("el-col",{staticClass:"card-panel-col",attrs:{xs:12,sm:12,lg:12}},[e("router-link",{staticClass:"card-panel",attrs:{to:{path:"/receipt/orders"}}},[e("div",{staticClass:"card-panel-icon-wrapper icon-message"},[e("svg-icon",{attrs:{"icon-class":"money","class-name":"card-panel-icon"}})],1),t._v(" "),e("div",{staticClass:"card-panel-description"},[e("div",{staticClass:"card-panel-text"},[t._v("今日金额(元)")]),t._v(" "),e("count-to",{staticClass:"card-panel-num",attrs:{"start-val":0,"end-val":t.todayMoney,decimals:2,duration:3e3}})],1)])],1)],1),t._v(" "),e("div",{staticClass:"chart-title"},[t._v("本周收款")]),t._v(" "),e("Chart",{attrs:{"chart-data":t.lineChartData}})],1)},[],!1,null,"604c748c",null));y.options.__file="Index.vue";a.default=y.exports},sw8x:function(t,a,e){"use strict";e.d(a,"a",function(){return r}),e.d(a,"b",function(){return s});var n=e("t3Un"),r=function(t){var a=t.page,e=void 0===a?1:a,r=t.page_size,s=void 0===r?10:r,i=t.state;return Object(n.a)({url:"/api/paychecks/list",method:"get",params:{page:e,page_size:s,state:i}})},s=function(t){var a=t.startDate,e=t.endDate;return Object(n.a)({url:"/api/paychecks/statistic",method:"get",params:{startDate:a,endDate:e}})}}}]);
--------------------------------------------------------------------------------
/controllers/paychecksController.js:
--------------------------------------------------------------------------------
1 | const nanoid = require('nanoid')
2 | const _ = require('lodash')
3 | const {
4 | loggerHttp
5 | } = require('../utils/logger.js')
6 | const ErrorCode = require('../utils/errorCode.js')
7 | const returnJson = require('../utils/returnJson.js')
8 | const redisCli = require('../utils/redisClient.js')
9 | const MD5 = require('../utils/md5.js')
10 | const Jwt = require('../utils/jwt.js')
11 | const verifyParams = require('../utils/verifyParams.js')
12 | const verifyToken = require('../utils/verifyToken.js')
13 | const sendSms = require('../utils/sendSms.js')
14 | const sendEmail = require('../utils/sendEmail.js')
15 | const deposits = require('../db/models/deposits.js')
16 | const users = require('../db/models/users.js')
17 | const uuidv1 = require('uuid/v1')
18 | const paychecks = require('../db/models/paychecks.js')
19 | const statistic = require('../db/models/statistic.js')
20 |
21 |
22 | const paychecksController = {
23 | getList() {//查询收钱列表
24 | return async (ctx, next) => {
25 | try {
26 | const data = ctx.query
27 | data.userid = ctx.state.user.id
28 | data.page = data.page || 1
29 | data.page_size = data.page_size || 10
30 |
31 | await verifyParams(data, 'userid').then(result => {//
32 | if (!result) {
33 | throw {
34 | code: ErrorCode.ERRORCODE_MISSING_PARAMS,
35 | message: '或者参数错误'
36 | }
37 | }
38 | })
39 |
40 | await paychecks.getList(data).then(result => {
41 | returnJson.success(ctx, result);
42 | })
43 | } catch (err) {
44 | console.info(`${ctx.url} -- `, err)
45 | if (err.code) {
46 | returnJson.err(ctx, err.code, err.message);
47 | } else {
48 | returnJson.err(ctx, ErrorCode.ERRORCODE_SERVER_INSIDE_ERROR)
49 | }
50 | }
51 | }
52 | },
53 |
54 | statistic() {
55 | return async (ctx, next) => {
56 | try {
57 | const data = ctx.query
58 | data.userid = ctx.state.user.id
59 | await verifyParams(data, 'userid', 'startDate', 'endDate').then(result => {
60 | if (!result) {
61 | throw {
62 | code: ErrorCode.ERRORCODE_MISSING_PARAMS,
63 | message: '或者参数错误'
64 | }
65 | }
66 | })
67 |
68 | let now = new Date();
69 | data.day = parseInt((now - new Date(now.getFullYear().toString())) / (24 * 60 * 60 * 1000)) + 1;
70 | data.now = now.format("yyyy-MM-dd");
71 | let row = {
72 | total_count: 0,
73 | total_amount: 0,
74 | week_list: []
75 | }
76 | if (data.endDate >= data.now) {
77 | let results = await paychecks.totalAmount(data);
78 | let result = {
79 | date: data.now,
80 | w_count: 0,//微信订单数量
81 | p_count: 0,//支付宝订单数量
82 | w_total1: 0,//微信已知来源金额总量
83 | p_total1: 0,//支付宝已知来源金额总量
84 | w_total2: 0,//微信未知来源金额总量
85 | p_total2: 0//支付宝未知来源金额总量
86 | }
87 | results.forEach(item => {
88 | if (item.appid && item.payway == '2') {
89 | result.w_count++;
90 | result.w_total1 += item.amount;
91 | }
92 | if (item.appid && item.payway == '1') {
93 | result.p_count++;
94 | result.p_total1 += item.amount;
95 | }
96 | if (!item.appid && item.payway == '2') {
97 | result.w_total2 += item.amount;
98 | }
99 | if (!item.appid && item.payway == '1') {
100 | result.p_total2 += item.amount;
101 | }
102 | });
103 | row.total_count = result.w_count + result.p_count;
104 | row.total_amount = result.w_total1 + result.p_total1 + result.w_total2 + result.p_total2;
105 | if (data.endDate == data.startDate) {
106 | row.week_list.push(result);
107 | returnJson.success(ctx, row)
108 | } else {
109 | let week_list = await statistic.getWeek(data);
110 | week_list.forEach(item => {//w_total1,p_total1,w_total2,p_total2
111 | row.total_count = row.total_count + item.w_count + item.p_count
112 | row.total_amount = row.total_amount + item.w_total1 + item.p_total1 + item.w_total2 + item.p_total2
113 | row.week_list.push(item)
114 | })
115 | row.week_list.push(result);
116 | returnJson.success(ctx, row)
117 | }
118 | } else {
119 | let week_list = await statistic.getWeek(data);
120 | week_list.forEach(item => {//w_total1,p_total1,w_total2,p_total2
121 | row.total_count = row.total_count + item.w_count + item.p_count
122 | row.total_amount = row.total_amount + item.w_total1 + item.p_total1 + item.w_total2 + item.p_total2
123 | row.week_list.push(item)
124 | })
125 | returnJson.success(ctx, row)
126 | }
127 | } catch (err) {
128 | console.info(`${ctx.url} -- `, err)
129 | if (err.code) {
130 | returnJson.err(ctx, err.code, err.message);
131 | } else {
132 | returnJson.err(ctx, ErrorCode.ERRORCODE_SERVER_INSIDE_ERROR)
133 | }
134 | }
135 | }
136 | }
137 | }
138 |
139 | module.exports = paychecksController;
--------------------------------------------------------------------------------
/controllers/tradeController.js:
--------------------------------------------------------------------------------
1 | const ErrorCode = require('../utils/errorCode.js')
2 | const returnJson = require('../utils/returnJson.js')
3 | const trades = require('../db/models/trades');
4 | const verifyParams = require('../utils/verifyParams.js')
5 |
6 | const tradeController = {
7 | // 添加系统商品(会员相关)
8 | addTrade() {
9 | return async (ctx, next) => {
10 | try {
11 | const data = ctx.query;
12 | const user = ctx.state.user;
13 | data.userid = user.id;
14 | if (user.lv < 10) {
15 | throw {code: ErrorCode.ERRORCODE_PERMISSIONS_DENIED, message: "权限不足"}
16 | }
17 | await verifyParams(data, 'amount', 'day', 'lv', 'userid').then(result => {
18 | if (!result) {
19 | throw {
20 | code: ErrorCode.ERRORCODE_MISSING_PARAMS,
21 | message: '或者参数错误'
22 | }
23 | }
24 | });
25 | if (data.lv > 3) {
26 | throw {code: ErrorCode.ERRORCODE_OVER_LOAD_LIMIT, message: "级别错误"}
27 | }
28 | await trades.addTrades(data).then(result => {
29 | returnJson.success(ctx, {
30 | name: result.name,
31 | amount: result.amount,
32 | desc: result.desc,
33 | day: result.day,
34 | tradeid: result.id,
35 | lv: result.lv
36 | });
37 | })
38 | } catch (err) {
39 | if (err.code) {
40 | console.log(err);
41 | returnJson.err(ctx, err.code, err);
42 | } else {
43 | returnJson.err(ctx, ErrorCode.ERRORCODE_SERVER_INSIDE_ERROR);
44 | }
45 | }
46 | }
47 | },
48 | // 修改系统商品(会员相关)
49 | modifyTrade() {
50 | return async (ctx, next) => {
51 | try {
52 | const data = ctx.query;
53 | const user = ctx.state.user;
54 | if (user.lv < 10) {
55 | throw {code: ErrorCode.ERRORCODE_PERMISSIONS_DENIED, message: "权限不足"}
56 | }
57 | await verifyParams(data, 'amount', 'day', 'lv', 'tradeid').then(result => {
58 | if (!result) {
59 | throw {
60 | code: ErrorCode.ERRORCODE_MISSING_PARAMS,
61 | message: '或者参数错误'
62 | }
63 | }
64 | });
65 | if (data.lv > 3) {
66 | throw {code: ErrorCode.ERRORCODE_OVER_LOAD_LIMIT, message: "级别错误"}
67 | }
68 | await trades.modifyTrades(data).then(result => {
69 | returnJson.success(ctx, result);
70 | })
71 | } catch (err) {
72 | if (err.code) {
73 | console.log(err);
74 | returnJson.err(ctx, err.code, err);
75 | } else {
76 | returnJson.err(ctx, ErrorCode.ERRORCODE_SERVER_INSIDE_ERROR);
77 | }
78 | }
79 | }
80 | },
81 | // 删除会员商品
82 | deleteTrade() {
83 | return async (ctx, next) => {
84 | try {
85 | const data = ctx.query;
86 | const user = ctx.state.user;
87 | if (user.lv < 10) {
88 | throw {code: ErrorCode.ERRORCODE_PERMISSIONS_DENIED, message: "权限不足"}
89 | }
90 | await verifyParams(data, 'tradeid').then(result => {
91 | if (!result) {
92 | throw {
93 | code: ErrorCode.ERRORCODE_MISSING_PARAMS,
94 | message: '或者参数错误'
95 | }
96 | }
97 | });
98 | await trades.deleteTrades(data).then(result => {
99 | returnJson.success(ctx, result);
100 | })
101 | } catch (err) {
102 | if (err.code) {
103 | console.log(err);
104 | returnJson.err(ctx, err.code, err);
105 | } else {
106 | returnJson.err(ctx, ErrorCode.ERRORCODE_SERVER_INSIDE_ERROR);
107 | }
108 | }
109 | }
110 | },
111 | // 查询会员商品列表
112 | tradeList() {
113 | return async (ctx, next) => {
114 | try {
115 | const data = ctx.query;
116 | data.page = data.page ? data.page : 1;
117 | data.page_size = data.page_size ? data.page_size : 10;
118 | data.start = (data.page - 1) * data.page_size;
119 | await trades.getTrades(data).then(result => {
120 | return returnJson.success(ctx, result);
121 | })
122 | } catch (err) {
123 | console.log(err)
124 | returnJson.err(ctx, ErrorCode.ERRORCODE_SERVER_INSIDE_ERROR);
125 | }
126 | }
127 | },
128 | // 制定的会员策略
129 | tradeInfo() {
130 | return async (ctx, next) => {
131 | try {
132 | const data = ctx.query;
133 | await verifyParams(data, 'tradeid').then(result => {
134 | if (!result) {
135 | throw {
136 | code: ErrorCode.ERRORCODE_MISSING_PARAMS,
137 | message: '或者参数错误'
138 | }
139 | }
140 | });
141 | await trades.getTrades(data).then(result => {
142 | returnJson.success(ctx, result);
143 | })
144 | } catch (err) {
145 | if (err.code) {
146 | returnJson.err(ctx, err.code, err.message);
147 | } else {
148 | returnJson.err(ctx, err.ERRORCODE_SERVER_INSIDE_ERROR)
149 | }
150 | }
151 | }
152 | }
153 | };
154 |
155 | const md5 = info => {
156 | const md5 = crypto.createHash('md5')
157 | md5.update(info)
158 | return md5.digest('hex')
159 | }
160 |
161 | module.exports = tradeController;
162 |
--------------------------------------------------------------------------------
/public/dist/static/js/chunk-280b.82d6890b.js:
--------------------------------------------------------------------------------
1 | (window.webpackJsonp=window.webpackJsonp||[]).push([["chunk-280b"],{"1jgq":function(t,s,a){},"3NST":function(t,s,a){"use strict";var e=a("HKbb");a.n(e).a},"4XeK":function(t,s,a){"use strict";a.d(s,"a",function(){return n}),a.d(s,"b",function(){return i});var e=a("t3Un"),n=function(t){var s=t.payway,a=t.amount;return Object(e.a)({url:"/api/deposits/qrcode",method:"post",data:{payway:s,amount:a}})},i=function(t){var s=t.page,a=void 0===s?1:s,n=t.page_size,i=void 0===n?10:n,o=t.state,c=void 0===o?"":o;return Object(e.a)({url:"/api/deposits/list",method:"get",data:{page:a,page_size:i,state:c}})}},"4trN":function(t,s,a){"use strict";var e=a("vF8W");a.n(e).a},C5dt:function(t,s,a){"use strict";var e=a("QbLZ"),n=a.n(e),i=a("0FX9"),o=a.n(i),c=a("L2JU"),r={props:{qrcode:String,payway:String,amount:Number},ws:null,computed:n()({},Object(c.c)(["user"])),mounted:function(){var t=this;this.ws=new WebSocket("wss://ws2.renrenpay.info?user=_"+this.user.info.id,"echo-protocol"),this.ws.onopen=function(s){o.a.toCanvas(t.$el.querySelector(".qrcode-canvas"),t.qrcode,{width:300})},this.ws.onmessage=function(s){try{var a=JSON.parse(s.data);1==a.paySuccess?t.$emit("success",a):t.$emit("fail")}catch(t){alert(t)}}},methods:{close:function(){this.ws.close()}}},l=(a("3NST"),a("KHd+")),u=Object(l.a)(r,function(){var t=this,s=t.$createElement,a=t._self._c||s;return a("div",{staticClass:"pay-comp",class:{wepay:2==t.payway,alipay:1==t.payway}},[1==t.payway?a("div",{staticClass:"deposit-title"},[a("svg-icon",{attrs:{"icon-class":"zhifubao"}}),t._v(" 支付宝\n ")],1):t._e(),t._v(" "),2==t.payway?a("div",{staticClass:"deposit-title"},[a("svg-icon",{attrs:{"icon-class":"wepay"}}),t._v(" 微信支付\n ")],1):t._e(),t._v(" "),a("div",{staticClass:"deposit-num"},[a("span",{staticClass:"num-widget"},[t._v("¥")]),t._v("\n "+t._s(t.amount/100)+"\n ")]),t._v(" "),a("canvas",{staticClass:"qrcode-canvas"})])},[],!1,null,"549a193a",null);u.options.__file="Pay.vue";s.a=u.exports},GgHD:function(t,s,a){"use strict";a.r(s);var e=a("14Xm"),n=a.n(e),i=a("D3Ub"),o=a.n(i),c=a("QbLZ"),r=a.n(c),l=a("4XeK"),u=(a("wk8/"),a("L2JU")),p=(a("0FX9"),a("I8ep")),v=a("C5dt"),d={data:function(){return{dialogVisible:!1,amountList:[1,1e3,2e3,3e3,5e3,1e4,3e4,1e5],btnLoading:!1,form:{payway:"2",amount:""},depositStep:1,qrcode:""}},watch:{"form.payway":function(){this.form.amount=""},dialogVisible:function(t){t&&(this.depositStep=1)}},computed:r()({},Object(u.c)({user:function(t){return t.user}})),components:{Membership:p.a,Pay:v.a},created:function(){var t=this;return o()(n.a.mark(function s(){return n.a.wrap(function(s){for(;;)switch(s.prev=s.next){case 0:t.$store.dispatch("FetchUser");case 1:case"end":return s.stop()}},s,t)}))()},methods:{changeMember:function(t){this.member=t},paySuccess:function(){this.$message({type:"success",message:"充值成功"}),this.dialogVisible=!1,this.$store.dispatch("FetchUser")},fetchQrcodeSubmit:function(){var t=this;return o()(n.a.mark(function s(){var a;return n.a.wrap(function(s){for(;;)switch(s.prev=s.next){case 0:if(t.form.amount){s.next=3;break}return t.$message({type:"warning",message:"请选择充值金额"}),s.abrupt("return");case 3:return t.btnLoading=!0,s.next=6,Object(l.a)(t.form);case 6:if(a=s.sent,t.btnLoading=!1,null!==a){s.next=10;break}return s.abrupt("return");case 10:t.qrcode=a.qrcode,t.depositStep=2;case 12:case"end":return s.stop()}},s,t)}))()}}},m=(a("rOdO"),a("KHd+")),f=Object(m.a)(d,function(){var t=this,s=t.$createElement,a=t._self._c||s;return a("div",{staticClass:"deposit-comp"},[a("div",{staticClass:"balance-cell"},[a("div",{staticClass:"cell-hd"},[t._v("账户余额 : ")]),t._v(" "),a("div",{staticClass:"cell-bd"},[a("b",{staticClass:"primary"},[t._v(t._s(t.user.info.balance/100||0))]),t._v("\n 元\n ")]),t._v(" "),a("div",{staticClass:"cell-ft"},[a("el-button",{attrs:{size:"small",type:"primary"},on:{click:function(s){t.dialogVisible=!0}}},[t._v("充值")])],1)]),t._v(" "),a("Membership",{on:{change:t.changeMember}}),t._v(" "),a("el-dialog",{attrs:{title:"充值",visible:t.dialogVisible,width:"40%"},on:{"update:visible":function(s){t.dialogVisible=s}}},[1==t.depositStep?[a("el-tabs",{model:{value:t.form.payway,callback:function(s){t.$set(t.form,"payway",s)},expression:"form.payway"}},[a("el-tab-pane",{attrs:{name:"2"}},[a("span",{attrs:{slot:"label"},slot:"label"},[a("svg-icon",{attrs:{"icon-class":"wepay"}}),t._v(" 微信支付\n ")],1),t._v(" "),a("div",{staticClass:"amount-list"},t._l(t.amountList,function(s,e){return a("div",{key:e,staticClass:"amount-item",class:{hover:t.form.amount==s},on:{click:function(a){t.form.amount=s}}},[t._v("\n "+t._s(s/100)+" \n "),a("span",{staticClass:"desc"},[t._v("元")])])}))]),t._v(" "),a("el-tab-pane",{attrs:{name:"1"}},[a("span",{attrs:{slot:"label"},slot:"label"},[a("svg-icon",{attrs:{"icon-class":"zhifubao"}}),t._v(" 支付宝\n ")],1),t._v(" "),a("div",{staticClass:"amount-list"},t._l(t.amountList,function(s,e){return a("div",{key:e,staticClass:"amount-item",class:{hover:t.form.amount==s},on:{click:function(a){t.form.amount=s}}},[t._v("\n "+t._s(s/100)+" \n "),a("span",{staticClass:"desc"},[t._v("元")])])}))])],1),t._v(" "),a("span",{staticClass:"dialog-footer",attrs:{slot:"footer"},slot:"footer"},[a("el-button",{on:{click:function(s){t.dialogVisible=!1}}},[t._v("取 消")]),t._v(" "),a("el-button",{attrs:{type:"primary",loading:t.btnLoading},on:{click:t.fetchQrcodeSubmit}},[t._v("确 定")])],1)]:t._e(),t._v(" "),2==t.depositStep?a("pay",{attrs:{amount:t.form.amount,payway:t.form.payway,qrcode:t.qrcode},on:{success:t.paySuccess}}):t._e()],2)],1)},[],!1,null,"3258e044",null);f.options.__file="Deposit.vue";var _={components:{Deposit:f.exports}},b=(a("4trN"),Object(m.a)(_,function(){var t=this.$createElement,s=this._self._c||t;return s("div",{staticClass:"intro-index-page"},[s("deposit"),this._v(" "),this._m(0)],1)},[function(){var t=this,s=t.$createElement,a=t._self._c||s;return a("div",{staticClass:"sec"},[a("div",{staticClass:"sec-title"},[a("b",[t._v("使用教程")])]),t._v(" "),a("div",{staticClass:"title"},[a("b",[t._v("第一步: 创建应用")])]),t._v(" "),a("div",{staticClass:"text"},[t._v("\n 点击左侧菜单栏 ”应用管理“,进入界面,然后点击里面的”创建应用“按钮,开始创建您的第一个应用。 "),a("br"),t._v("创建成功后,就会为你生成AppID和AppSecret,这两个字段后面用于手机上的app配置\n ")]),t._v(" "),a("div",{staticClass:"title"},[a("b",[t._v("第二步: 下载App")])]),t._v(" "),a("div",{staticClass:"text"},[t._v("\n 点击左侧菜单栏 ”软件下载“,进入界面,按照要求依次下载里面的软件。如果手机内预先安装了其他版本的微信、支付宝,请卸载后再安装\n ")]),t._v(" "),a("div",{staticClass:"title"},[a("b",[t._v("第三步: 配置App")])]),t._v(" "),a("div",{staticClass:"text"},[t._v("\n 点击左侧菜单栏 ”软件下载“,进入界面,按照要求依次下载里面的软件。如果手机内预先安装了其他版本的微信、支付宝,请卸载后再安装\n ")]),t._v(" "),a("div",{staticClass:"title"},[a("b",[t._v("第四步: 测试支付")])]),t._v(" "),a("div",{staticClass:"text"},[t._v("\n 点击左侧菜单栏 ”软件下载“,进入界面,按照要求依次下载里面的软件。如果手机内预先安装了其他版本的微信、支付宝,请卸载后再安装\n ")])])}],!1,null,"63a081ac",null));b.options.__file="Index.vue";s.default=b.exports},HKbb:function(t,s,a){},rOdO:function(t,s,a){"use strict";var e=a("1jgq");a.n(e).a},vF8W:function(t,s,a){}}]);
--------------------------------------------------------------------------------
/public/dist/static/css/app.cab2c720.css:
--------------------------------------------------------------------------------
1 | .fade-enter-active,.fade-leave-active{-webkit-transition:opacity .28s;transition:opacity .28s}.fade-enter,.fade-leave-active{opacity:0}.fade-transform-enter-active,.fade-transform-leave-active{-webkit-transition:all .5s;transition:all .5s}.fade-transform-enter{opacity:0;-webkit-transform:translateX(-30px);transform:translateX(-30px)}.fade-transform-leave-to{opacity:0;-webkit-transform:translateX(30px);transform:translateX(30px)}.breadcrumb-enter-active,.breadcrumb-leave-active{-webkit-transition:all .5s;transition:all .5s}.breadcrumb-enter,.breadcrumb-leave-active{opacity:0;-webkit-transform:translateX(20px);transform:translateX(20px)}.breadcrumb-move{-webkit-transition:all .5s;transition:all .5s}.breadcrumb-leave-active{position:absolute}.el-upload input[type=file]{display:none!important}.el-upload__input{display:none}.el-dialog{-webkit-transform:none;transform:none;left:0;position:relative;margin:0 auto}.upload-container .el-upload{width:100%}.upload-container .el-upload .el-upload-dragger{width:100%;height:200px}#app .main-container{min-height:100%;-webkit-transition:margin-left .28s;transition:margin-left .28s;margin-left:180px;position:relative}#app .sidebar-container{-webkit-transition:width .28s;transition:width .28s;width:180px!important;height:100%;position:fixed;font-size:0;top:0;bottom:0;left:0;z-index:1001;overflow:hidden}#app .sidebar-container .horizontal-collapse-transition{-webkit-transition:width 0s ease-in-out,padding-left 0s ease-in-out,padding-right 0s ease-in-out;transition:width 0s ease-in-out,padding-left 0s ease-in-out,padding-right 0s ease-in-out}#app .sidebar-container .scrollbar-wrapper{overflow-x:hidden!important}#app .sidebar-container .scrollbar-wrapper .el-scrollbar__view{height:100%}#app .sidebar-container .el-scrollbar__bar.is-vertical{right:0}#app .sidebar-container .is-horizontal{display:none}#app .sidebar-container a{display:inline-block;width:100%;overflow:hidden}#app .sidebar-container .svg-icon{margin-right:16px}#app .sidebar-container .el-menu{border:none;height:100%;width:100%!important}#app .sidebar-container .el-submenu__title:hover,#app .sidebar-container .submenu-title-noDropdown:hover{background-color:#263445!important}#app .sidebar-container .is-active>.el-submenu__title{color:#f4f4f5!important}#app .sidebar-container .el-submenu .el-menu-item,#app .sidebar-container .nest-menu .el-submenu>.el-submenu__title{min-width:180px!important;background-color:#1f2d3d!important}#app .sidebar-container .el-submenu .el-menu-item:hover,#app .sidebar-container .nest-menu .el-submenu>.el-submenu__title:hover{background-color:#001528!important}#app .hideSidebar .sidebar-container{width:36px!important}#app .hideSidebar .main-container{margin-left:36px}#app .hideSidebar .submenu-title-noDropdown{padding-left:10px!important;position:relative}#app .hideSidebar .submenu-title-noDropdown .el-tooltip{padding:0 10px!important}#app .hideSidebar .el-submenu{overflow:hidden}#app .hideSidebar .el-submenu>.el-submenu__title{padding-left:10px!important}#app .hideSidebar .el-submenu>.el-submenu__title .el-submenu__icon-arrow{display:none}#app .hideSidebar .el-menu--collapse .el-submenu>.el-submenu__title>span{height:0;width:0;overflow:hidden;visibility:hidden;display:inline-block}#app .el-menu--collapse .el-menu .el-submenu{min-width:180px!important}#app .mobile .main-container{margin-left:0}#app .mobile .sidebar-container{-webkit-transition:-webkit-transform .28s;transition:-webkit-transform .28s;transition:transform .28s;transition:transform .28s,-webkit-transform .28s;width:180px!important}#app .mobile.hideSidebar .sidebar-container{pointer-events:none;-webkit-transition-duration:.3s;transition-duration:.3s;-webkit-transform:translate3d(-180px,0,0);transform:translate3d(-180px,0,0)}#app .withoutAnimation .main-container,#app .withoutAnimation .sidebar-container{-webkit-transition:none;transition:none}.el-menu--vertical>.el-menu .svg-icon{margin-right:16px}.el-menu--vertical .el-menu-item:hover,.el-menu--vertical .nest-menu .el-submenu>.el-submenu__title:hover{background-color:#263445!important}.el-menu--vertical>.el-menu--popup{max-height:100vh;overflow-y:auto}.el-menu--vertical>.el-menu--popup::-webkit-scrollbar-track-piece{background:#d3dce6}.el-menu--vertical>.el-menu--popup::-webkit-scrollbar{width:6px}.el-menu--vertical>.el-menu--popup::-webkit-scrollbar-thumb{background:#99a9bf;border-radius:20px}body{height:100%;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;font-family:Helvetica Neue,Helvetica,PingFang SC,Hiragino Sans GB,Microsoft YaHei,Arial,sans-serif}label{font-weight:700}html{-webkit-box-sizing:border-box;box-sizing:border-box}#app,html{height:100%}*,:after,:before{-webkit-box-sizing:inherit;box-sizing:inherit}a,a:active,a:focus,a:hover,div:focus{outline:none}a,a:focus,a:hover{cursor:pointer;color:inherit;text-decoration:none}.clearfix:after{visibility:hidden;display:block;font-size:0;content:" ";clear:both;height:0}.app-main{min-height:100%}.app-container{padding:20px}.cell{display:-webkit-box;display:-ms-flexbox;display:flex}.cell .primary{-webkit-box-flex:1;-ms-flex:1;flex:1}.app-breadcrumb.el-breadcrumb[data-v-6eeb655c]{display:inline-block;font-size:14px;line-height:50px;margin-left:10px}.app-breadcrumb.el-breadcrumb .no-redirect[data-v-6eeb655c]{color:#97a8be;cursor:text}.hamburger[data-v-68efea28]{display:inline-block;cursor:pointer;width:20px;height:20px}.hamburger.is-active[data-v-68efea28]{-webkit-transform:rotate(180deg);transform:rotate(180deg)}.navbar[data-v-9bbe2cc8]{height:50px;line-height:50px;-webkit-box-shadow:0 1px 3px 0 rgba(0,0,0,.12),0 0 3px 0 rgba(0,0,0,.04);box-shadow:0 1px 3px 0 rgba(0,0,0,.12),0 0 3px 0 rgba(0,0,0,.04)}.navbar .hamburger-container[data-v-9bbe2cc8]{line-height:58px;height:50px;float:left;padding:0 10px}.navbar .screenfull[data-v-9bbe2cc8]{position:absolute;right:90px;top:16px;color:red}.navbar .avatar-container[data-v-9bbe2cc8]{height:50px;display:inline-block;position:absolute;right:35px}.navbar .avatar-container .avatar-wrapper[data-v-9bbe2cc8]{cursor:pointer;margin-top:5px;position:relative;line-height:normal;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;height:40px}.navbar .avatar-container .avatar-wrapper .user-avatar[data-v-9bbe2cc8]{width:40px;height:40px;border-radius:50%}.navbar .avatar-container .avatar-wrapper .user-nickname[data-v-9bbe2cc8]{margin:0 10px}.navbar .avatar-container .avatar-wrapper .el-icon-caret-bottom[data-v-9bbe2cc8]{font-size:12px}.contact-us[data-v-5e16de72]{background:#263445;cursor:pointer;font-size:14px;color:#bfcbd9;position:absolute;left:0;right:0;height:70px;line-height:70px;text-align:center;bottom:0}.app-main[data-v-dfcc6c68]{min-height:calc(100vh - 50px);position:relative;overflow:hidden;padding:32px}.app-wrapper[data-v-6ec8cb25]{position:relative;height:100%;width:100%}.app-wrapper[data-v-6ec8cb25]:after{content:"";display:table;clear:both}.app-wrapper.mobile.openSidebar[data-v-6ec8cb25]{position:fixed;top:0}.drawer-bg[data-v-6ec8cb25]{background:#000;opacity:.3;width:100%;top:0;height:100%;position:absolute;z-index:999}.svg-icon[data-v-77a1c50c]{width:1em;height:1em;vertical-align:-.15em;fill:currentColor;overflow:hidden}
--------------------------------------------------------------------------------
/utils/statistic.js:
--------------------------------------------------------------------------------
1 | /*
2 | * @Author: hechao
3 | * @Date: 2019-04-01 16:46:36
4 | * @describe: 定时任务,跑统计结果
5 | */
6 |
7 | const {
8 | sqlTable,sequelize
9 | } = require('../db/index.js')
10 | const Sequelize = require('sequelize')
11 | const schedule = require('node-schedule');
12 |
13 | Date.prototype.format = function (fmt) {
14 | var o = {
15 | "M+": this.getMonth() + 1, //月份
16 | "d+": this.getDate(), //日
17 | "h+": this.getHours(), //小时
18 | "m+": this.getMinutes(), //分
19 | "s+": this.getSeconds(), //秒
20 | "q+": Math.floor((this.getMonth() + 3) / 3), //季度
21 | "S": this.getMilliseconds() //毫秒
22 | };
23 | if (/(y+)/.test(fmt)) {
24 | fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
25 | }
26 | for (var k in o) {
27 | if (new RegExp("(" + k + ")").test(fmt)) {
28 | fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
29 | }
30 | }
31 | return fmt;
32 | };
33 | //今日统计更新
34 | async function day_statistic(){
35 | // setInterval(()=>{
36 | try {
37 | let now = new Date();
38 | let date = now.format("yyyy-MM-dd");
39 | let day =parseInt(( now - new Date(now.getFullYear().toString()))/(24*60*60*1000))+1;
40 | let result = await sequelize.query(`select * from paychecks where dayofyear(createdAt)=?`,{
41 | type: Sequelize.QueryTypes.SELECT,
42 | replacements:[day]
43 | })
44 | let obj={}
45 | result.forEach(item => {
46 | if(obj[item['userid']] || (obj[item['userid']] = [])) {
47 | obj[item['userid']].push(item)
48 | }
49 | });
50 | console.info(obj)
51 | for(var p in obj){
52 | let w_count=0,p_count=0,w_total1=0,p_total1=0,w_total2=0,p_total2=0;//微信订单数量,支付宝订单数量,微信已知来源收款总额..
53 | obj[p].forEach(item=>{
54 | if(item.appid && item.payway == 1){
55 | p_count++;
56 | p_total1+=item.amount;
57 | }
58 | if(item.appid && item.payway == 2){
59 | w_count++;
60 | w_total1+=item.amount;
61 | }
62 | if(!item.appid && item.payway == 1){
63 | p_total2+=item.amount;
64 | }
65 | if(!item.appid && item.payway == 2){
66 | w_total2+=item.amount;
67 | }
68 | })
69 | let statistics = await sequelize.query(`select id from statistic where userid=? and date=?`,{
70 | type: Sequelize.QueryTypes.SELECT,
71 | replacements:[p,date]
72 | })
73 | if(statistics.length>0){
74 | await sequelize.query(`update statistic set w_count=?,p_count=?,w_total1=?,p_total1=?,
75 | w_total2=?,p_total2=? where userid=? and date=?`,{
76 | type: Sequelize.QueryTypes.UPDATE,
77 | replacements:[w_count,p_count,w_total1,p_total1,w_total2,p_total2,p,date]
78 | })
79 | }else{
80 | await sqlTable.statistic.create({
81 | userid:p,
82 | w_count,
83 | p_count,
84 | w_total1,
85 | p_total1,
86 | w_total2,
87 | p_total2,
88 | date
89 | })
90 | }
91 | }
92 | } catch (error) {
93 | console.info('error----->',error)
94 | }
95 |
96 | // },10000)
97 |
98 |
99 | }
100 |
101 | //昨天统计
102 | async function yesterday_statistic(){
103 | try {
104 | let now = new Date();
105 | // let date = now.format("yyyy-MM-dd");
106 | let yesterday = new Date(now.getTime()-24*60*60*1000);
107 | let day =parseInt(( yesterday - new Date(yesterday.getFullYear().toString()))/(24*60*60*1000))+1;
108 | let date= yesterday.format("yyyy-MM-dd")
109 | let result = await sequelize.query(`select * from paychecks where dayofyear(createdAt)=?`,{
110 | type: Sequelize.QueryTypes.SELECT,
111 | replacements:[day]
112 | })
113 | let users = await sequelize.query(`select id from users`,{
114 | type: Sequelize.QueryTypes.SELECT,
115 | })
116 | let obj={}
117 | users.forEach(item=>{
118 | obj[item['id']]=[]
119 | })
120 | result.forEach(item => {
121 | if(obj[item['userid']] || (obj[item['userid']] = [])) {
122 | obj[item['userid']].push(item)
123 | }
124 | });
125 | console.info(obj)
126 | for(var p in obj){
127 | let w_count=0,p_count=0,w_total1=0,p_total1=0,w_total2=0,p_total2=0;//微信订单数量,支付宝订单数量,微信已知来源收款总额..
128 | obj[p].forEach(item=>{
129 | if(item.appid && item.payway == 1){
130 | p_count++;
131 | p_total1+=item.amount;
132 | }
133 | if(item.appid && item.payway == 2){
134 | w_count++;
135 | w_total1+=item.amount;
136 | }
137 | if(!item.appid && item.payway == 1){
138 | p_total2+=item.amount;
139 | }
140 | if(!item.appid && item.payway == 2){
141 | w_total2+=item.amount;
142 | }
143 | })
144 | let statistics = await sequelize.query(`select id from statistic where userid=? and date=?`,{
145 | type: Sequelize.QueryTypes.SELECT,
146 | replacements:[p,date]
147 | })
148 | if(statistics.length>0){
149 | await sequelize.query(`update statistic set w_count=?,p_count=?,w_total1=?,p_total1=?,
150 | w_total2=?,p_total2=? where userid=? and date=?`,{
151 | type: Sequelize.QueryTypes.UPDATE,
152 | replacements:[w_count,p_count,w_total1,p_total1,w_total2,p_total2,p,date]
153 | })
154 | }else{
155 | await sqlTable.statistic.create({
156 | userid:p,
157 | w_count,
158 | p_count,
159 | w_total1,
160 | p_total1,
161 | w_total2,
162 | p_total2,
163 | date
164 | })
165 | }
166 | }
167 | } catch (error) {
168 | console.info('err---->=',error)
169 | }
170 | }
171 |
172 |
173 | function scheduleCronstyle(){
174 | // yesterday_statistic();
175 | // day_statistic()
176 | schedule.scheduleJob('0 0 10 * * *', yesterday_statistic);
177 | // schedule.scheduleJob('0 5 * * * *', day_statistic);
178 | }
179 | module.exports={
180 | scheduleCronstyle
181 | }
--------------------------------------------------------------------------------
/public/dist/static/js/chunk-6929.2461bbf3.js:
--------------------------------------------------------------------------------
1 | (window.webpackJsonp=window.webpackJsonp||[]).push([["chunk-6929"],{Jvyq:function(s,t){s.exports="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAJgAAACKCAYAAABW3IOxAAAAAXNSR0IArs4c6QAAElhJREFUeAHtnXuQHMV9x7tndvdOQkgCWZKxkITEQ5YB87AVCT9iEqgyTsXlyA42QVRcScXYzvOPkKeJLSrOy8RVxMSVBNuVqrhIxS7KJk5BKlWpQKiKX4hgwOII6CzLAk6H0Pt0e/uY6Xx+p7vT3Gl2b2e3Z2d2t7vqdzuP7l//+tvf6+75dU+PVi5kioAxZl01UDtMEG43Wu/AmOuUUYeVVqNKmVGjvX2+HAdqX6mkfqS1Pp2pwQkz1wnju+gdIACZlpTr6npU7FChETIh5uJkKvWYPkO+fUp7oyZUowWt9hWLahTyHU2mK/3YjmApYjxlzGWmSuukQ4iktwP2NZCsmFqWWh9D96hWZp+nvb2lgvompNubWn4tKHYEawGkVqJAnBWVutpmZlono2mdjFnVSlqbcTytnynSpHlaXYPeV5F3QLIDNvNIossRLAlaM3Ehk1etqitDIZGidTKMnbTayvVM8IRAZQj1dNHXF9N9blhQpBc4f2dW3WcmgCwAIPenEGdNJVDbGYhDpOmB+DaunZ+14VrpV31fjxb96dZqeRN7vs29m4WITeKkcssRbAGsEKdUq6lrQ7o6M9M6GWU2LYiW6Snd4HO+p8sFX70dQ7wWjfkW8T4IyYIW41uJNvAEKxuzUQbiSocMwqdbp+sh2ZAVdC0qgRhVur8nS75+A79b2lT9AHo+3mbatpINHMEgz/JKqH7ZmPBtJtA3J3cTtIVz+4m0PsyYfS8D9ytRsrp9RXMpd0Oye+bOUj4YOIJNVsJvQKqdgitAh8aocQbIr/P0d4pLNbmMDOPsXKk9tSYMzUrOux6wbaTg6SN0g9vI3HaLeif6v9SNQg0UwSZr5ndVGP51EmCpiJPEH4OAxwFLBskyhilyvozBzyp+L5JxWxKdjeKSl+j+Xqmgl0D66xrFs3Bd8tlJfv9mQVdTFQNDMMj1Tm3M45Ch0BSRhDeppBqtnXjXZXrnlApV1TAKxwe2hHsreEBYw/015NsYazzwdIM/KBT0ZURa6GZIaFHL0eWf5SZs/E7LKdqI2LjQbSjLaxIqd3W5ap6ma1yXiY2MowB6nLyPQbZJ7dE1Kzz6Ri2hG6zMdINZuD2OYNO7IJn4ylIJfU8wyOVN1cx/8MuAPj+BSq0PFabnFddnbNUB8r8Be8bSsKNVH0oaeXdF51Q13J03cknB8WM9TUeaNbnElI3Iv4NRM0etxGsr9HULRsv1XoAT8HJVToZozw8V9VvaqrH0Ej2G6ltoyao2s+jbFmzSmPX4IB7MG7mowIlSUa+xWYmWdP0Mev7JNl59STBAKqqa+XoWqxkWq+yCr1+iOX3DYvEyuv8R8r3bZt59SbByDV+XmV7QZxOrjnUx7tpT8FL1b3VsIwq22lAyq6PvCDZZMbfy+P/bswXMz68ew4FqtfLyU7bGlvQVwVhBeoXW5iuNi5vNHcZdhkH9cXI/LxsLssu1bwjGuGuJqZmH+M3CYdm0Bnlp49tM/Qxc6yWgWJ02aYpyyjenauHfMXF9dcrZJFZP6/UiKyG2J07YJwn6ogVjGujXINdH81YnkGuKrlFWQvTNP3JSjHueYNWquZY5xvuTFrwb8Zln3INLQjzlAxt6n2BBeBdPjaxm0CZPtYg9e5jEfleebMrClp5vuk9Vwl1CLqZf9nuePljy1YTvqxKku4iB9eUM+m0v1lu8nrR+fbioB7rlmgWp5wkmBYFEOjBmcxCqzbX6bNFkaao+4fvmh3RVRwu+Z3iau5CLl5LggrOx7B/h7xpF68AO7KOI9gXBogWKHrPmakU9UG+rB/SetWD6Fq1dQEv3Eu8QjtHCVYueWso4aT1xraxsQPcTEPmno3YM8nFfEyyuYmnt/CAwlweBujx6n0WARwqe9+OCF55kOodDbzXE20z8lpdD02LuZ42X7D3hwgwCA0ewRjVvQrOqFgar5K2PMyGQl0JqdK//xxzi6wzYA1qmFazhugTSrZiNNfsrcSHXBOebZq+53wH2z7RS+RCpWAvMFnrXLdPvG80kohscLxW8l30dln3PG+ZR/E2QcATy3dSK3kGK41qwNmqbV9nWTlWDtWeSnhnbrT6/kNclOG2U0F6SnveD2YOiY03unzUGQkewGFDcJXsIOILZw9JpikHAESwGFHfJHgKOYPawdJpiEHAEiwHFXbKHgCOYPSydphgEHMFiQHGX7CHgCGYPS6cpBgFHsBhQ3CV7CDiC2cPSaYpBwE1vxIAy4Jd+gUn+V1rA4Ani3CHr65rFdQRrhs5g3ltCsUUWC7cRQbYX/XiziK6LbIaOu7cYAnfS2t3TLJIjWDN03L1WEPg0JPtko4iOYI2QcdeTIPC3kOxDcQkcweJQcdeSIiA8ks3+blyY0BFsISLuvF0E5P3ThyGZfEZwLjiCzUHhDiwgIC/DyJ64cy++OIJZQNWpmIfARZzJtvHT31VyBJuHjTuxhIC8c/ooJJPP7bjgEEgFAfmW5UOOYKlg65TOIHCTI5jjQqoIOIKlCq9T7gjmOJAqAo5gqcLrlDuCOQ6kikBPEww/yw2+7z3FvlynU0XJKW8bgZ5bcAipZDHcLyG/gVy/+owrr16tq2fLNXO0UgtWhopPtmSxN2vb1dC/CdnErzcCxLoUSz+B/Cpy4SJWlys1M1KuhyeqdcP3svWbSe8vkqaj22zfFPqe6ukeoSMA4hPXc00wSCEVdgsirdX7kLbsZYfWE3yc9AW+fltmQ7mLjNJXoLstXdgQGxzBYmHJJ8GofGmhfgX5dWRzrOkdXOSrIIf5OsiLtHB1NgneQH6bOlA3ndQRLBbBfBGMipYNdKW1kjFWKy8exJYq6cXQqJch3GilFupqIIQ2FyfV4QgWi1j2BINUsovzrchvIjtizezyRfbb38cDw0E+sFXgeAs2LvoJZEew2ErKjmBU2gZMkleePoZMrx2KNTH7i2EtVCO0cIdo4ZaGodrKnvorF5rlCLYQkenz7hMMYt1M1tINvh9J9cluuoj2/9T4msjeybo5DOFWmFBdCeHOcwSLBbo7BINUy8n+o4gQa0usKb17cbJSV4+VCurneCy1+mTau5DMWZ4uwSDWVWQlpLoDWTaXbf8cvERR5FPJ2/qnSFZLUrfuyYdUonMnIsR6j1Vz86PsJ5jyMnID4lqtJvViDRyIJYv975yRNzXJs5dvjWO8tFrytGv9n7OXgWlg+2sdEwxivRvl0lp9ECk2yKjXL0s3+CwiXWHX/HM9DNppbL8PubdtgkGsN/INn78s+upnUbS+h8FoZroAtQe5DpEHFReaI1Dl9j8gn2Vbp9ckatsEK1eDrzHl8mEUhSj5AR+D4qOf6gp0in+r14MA9T1kK+K+QbR4bcoeYV9FdsOHA9HobRFsqm7eFwbho1FFcoxymUF+Zubzd/Ju3MaFcXJ+HmLfd5FLkH4dR1I0q+EbaLubuh+J05qYYHSNS6eqZi/OxUviFM5emyHbs0I2vqF9KRk1jT+bLsPf75P3amRThjb0Utb/ibF/RD3LEKJhSEywqUpwL//mdzXUGHNDyMaSmef4uOdhutG8ke1pTF6K9JsDOKYmrFySoYMQ67FWtCUiWLVqrgmU2UMr1tEjOsb9kJZtHLJtwgDry3FaKThx9iIydnhri/EHPZrgJV3hw0mAaJlgkMpjhcF3WIr8U0kyWCwuBu+dIdslXSLbPmwSt4O82u7C4gjsJ8pnkAepKxmjJgotE4xx12+FJvxCIu0JI1OAEcg2Rsu2EcNkibTNcBBlryDbkZbLbdOAHtN1CHs/izxAvZz9lHnCQrQENK3XOpYcj/B7fkL9bUenUPIx9lch24YOySb+GPG+C7E66trbLkxvJZTW/XPI31AHk52a3hLBJishj6JG5hczCRT0Rcj2CmRbj8GXtWiEAPUcsg0ZbjHNIEcTMkkP9VfgLdhZCYsSrFI3HwiC8GEruVlQQuH3QbaDBQ+y6ViyCVBPIdciXWtxLRQtKxXS/T2AiPddukWroSnB6BKXMfZ6Hp9XLqeCeOF2lFfFDhZ8vQ6ybQQZ8WWJ932VVZT6U5kM2B9EPgOxZCCfSmhKsMlqcJ8y6ndSydmiUgAKhor6dQqz1qLaflb1rxTuU+AmrodUQ0OC4fN6Oz6v79KK5X5Zs+/rl0u+TvwmUKrI5lP5f2HWH0MscZZ2JcQSTEiFz+tJfF6yiiDXAbAmhou6H1fL2sT9SZQJsWR6p6sh9rG9XKdb7AFyCVJFv30fTVeRziYzmYAW77tMSGcSzmnByvI6WY2BvTHnZWJRgkw1c5vDBb06QZJBiXqAgu5Gvgq5ZDoss3BOC2aq5ov4vHJPLkGMcZds/O/CWQTEqfxnyN9DLFnTlnmYRzB8Xr+Iz+vnM7eqBQM8Tx/ytHpjC1EHIcoJCnkvch/EOp2nAs91kXSJK3h7mT57+uWNPNl4ji2AWMMtUZwz/pwYA3OhTEnvR8T7fjSPpZ5rwdiH4S8wUN4Myn3Ai38Kcl2Ye0PTM1C8719B/hRivZpeNp1rnm4E8HntwOf1P7RiXucq09UAoCdxSyxPN5fcajdY9i/In4DDaG6tjBhWgFQFVko80AvkErtxSwxF7B+kw/+msHdBrKZLlPMGiDdVV3dBrqvzZlicPbgljjD3OGgEE1/WByDWjb1GLqlDjy3+buR1oCNxFZqna4Brhnw9SJPYsrLhE8jVlP1beaqLJLboseM1tizV1VLB+9+SH0762mM1Qv6eJFkxcYzu8YIkhevRuOJm+DzyOYiVK5dDO3ieIVgkJYUKqcxn8JAfw890GWTbELmdySE2VRjY93vXKB73f0RkAG99XVYmFUem5xBsoSG4BEaGCvpQ0ffWsy4MwnU/FAteGTuWdD/nruX4CDn9PsR6vms5dimjRQkWtcMvePuHff0TXqRdw5uOsrAv9eBpfQqnar+uTH0KAOXJ8PHUgcwog0QEi9rIVM3YkqLH8mVzASR4S1pujqGiZ+iq+81p/2OwvBv5Z8glvq2+DW0TLIqI53tHadle4KWMpZDhKvGtRe+3e8za+xOlQl9NaB8Diz9H7odYlXZx6aV0VggWLTBPoRNF34yUitBOs0Fum98MogJCxn40jlHtPXssKxu+iMjUjpBsYIJ1gkWRgx7VkqefZ1lNnXHbVsjW8jIgnmQncUssjerrwWPp/r6OyF4O+3vQ/o5NTpVgUeukRYIwI7gbJmnZ5FtBDddyEXeKeMPR9D14LFM7v0dZnuxB262Z3DWCLbQYx+5LeOaPez6bnxgzz0PPvYApody/bLKwTDPnMrXzhxCrZ73vDcrV1uXMCBa1tljQB0u+GmfItR7CLWPs1XJXGtWT8bE4R+9BvgS5Ml2mnDEO87LPBcGiFp0/7KvzhnpqZD87tXMvxJqIlsUd53AzEGYLqJeeIFhfTu3Y/qew4q+ybVQP6OvbqR3b2DuCJUNUpnbkyfCxZMkGN3bul0jnpGoOYMcdyDZHrmQ14lqw5njJPlkytfMFiDUQUzvN4Uh+1xEsHrPZqR3ZMyuXr4PFm52/q45g8+tk4Kd25sPR+Zkj2FkMn+BQ1mYN9NTOWTjsHDmCKfUCUP4BxHJTO3Y4NU/LID9FjoPEJ5GrHLnmccLqySC2YG5qxyqFmisrsBp5gumZQdghcHZq59O0WGPNYXF3bSHgrV3hrwXwXcgjSNtfdLBlUEp6HkXvNZTvY4gjV0ogx6mdN6t88qRZVQ7DDxsd7mLC+R0sCpx3P06B7WvLhj3W61gbGrqpHdsVlFBfQwIdK5uNlUp4u1Lh7TiHrkqot+3olggmUzufQvr+rZ22ge5SwoYEi+Y/PmHequr1XaHSt6X9pneHBHNTO9GKy8FxSwSbtVO6zMMT6t2hCW7nC6O3stTZ+iZwbRLMTe3MVlLOfhMRLGo7ZCuOnwpuYX3gLsj2flo2K28AJSTY7NSO7AH/o6h97jgfCLRNsKj5r/FNI3My2MnHb3ah8GbI1/YLGwkIJlM7sjbr+1Fb3HG+ELBCsGiRDp0ya1QYfmT64cCoHdF7rRy3QDA3tdMKkDmJY51g0XKNHzebcXnwFIrbw6g3R+81Om5CMJna2Y18mVar3ii9u54vBFIlWLSoh0+b6+u1+u3MHNzGzMG66L3ocQzB5PuPn0dkQzb31k4UrB447hrBZrFgfOYdmqi/RwcaZ676EGRbOXtPfiMEc1M7UWDccXIEINvQ+Mn6zrHj9YfGTtTLsp3nqamAy+YR5MrkGl0Kh0ADBI4Ys/zUVPj4sdPBPQ2iuMsOAYeAQ2A+Av8Pby5Qwk3kUm8AAAAASUVORK5CYII="},jNvO:function(s,t,i){"use strict";i.r(t);var n=[function(){var s=this.$createElement,t=this._self._c||s;return t("div",{staticClass:"pic-404"},[t("img",{staticClass:"pic-404__parent",attrs:{src:i("o2sD"),alt:"404"}}),this._v(" "),t("img",{staticClass:"pic-404__child left",attrs:{src:i("Jvyq"),alt:"404"}}),this._v(" "),t("img",{staticClass:"pic-404__child mid",attrs:{src:i("Jvyq"),alt:"404"}}),this._v(" "),t("img",{staticClass:"pic-404__child right",attrs:{src:i("Jvyq"),alt:"404"}})])},function(){var s=this.$createElement,t=this._self._c||s;return t("div",{staticClass:"bullshit__info"},[this._v("版权所有\n "),t("a",{staticClass:"link-type",attrs:{href:"https://wallstreetcn.com",target:"_blank"}},[this._v("华尔街见闻")])])}],r={name:"Page404",computed:{message:function(){return"网管说这个页面你不能进......"}}},l=(i("yGHO"),i("KHd+")),e=Object(l.a)(r,function(){var s=this,t=s.$createElement,i=s._self._c||t;return i("div",{staticClass:"wscn-http404-container"},[i("div",{staticClass:"wscn-http404"},[s._m(0),s._v(" "),i("div",{staticClass:"bullshit"},[i("div",{staticClass:"bullshit__oops"},[s._v("OOPS!")]),s._v(" "),s._m(1),s._v(" "),i("div",{staticClass:"bullshit__headline"},[s._v(s._s(s.message))]),s._v(" "),i("div",{staticClass:"bullshit__info"},[s._v("请检查您输入的网址是否正确,请点击以下按钮返回主页或者发送错误报告")]),s._v(" "),i("a",{staticClass:"bullshit__return-home",attrs:{href:""}},[s._v("返回首页")])])])])},n,!1,null,"9b45c3f8",null);e.options.__file="404.vue";t.default=e.exports},o2sD:function(s,t,i){s.exports=i.p+"static/img/404.a57b6f3.png"},oBSS:function(s,t,i){},yGHO:function(s,t,i){"use strict";var n=i("oBSS");i.n(n).a}}]);
--------------------------------------------------------------------------------
/public/dist/static/js/chunk-fc3b.827b4c52.js:
--------------------------------------------------------------------------------
1 | (window.webpackJsonp=window.webpackJsonp||[]).push([["chunk-fc3b"],{"2uYv":function(e,t,s){"use strict";var a=s("UDD5");s.n(a).a},Timz:function(e,t,s){"use strict";var a=s("qvc3");s.n(a).a},UDD5:function(e,t,s){},qeMi:function(e,t,s){"use strict";s.r(t);var a=s("14Xm"),r=s.n(a),n=s("D3Ub"),o=s.n(n),i=s("gjeX"),l=s.n(i),c=s("wk8/"),m=s("QqA1"),p=s.n(m),u={data:function(){return{mode:"mobile",smsCount:-1,mobileForm:{mobile_phone:"",password:"",code:""},emailCount:-1,emailLoading:!1,emailForm:{email:"",password:"",code:""},emailRules:{email:[{required:!0,message:"请输入邮箱",trigger:"blur"},{type:"email",message:"请输入正确的邮箱地址",trigger:"blur"}],code:[{required:!0,message:"请输入验证码",trigger:"blur"}],password:[{required:!0,message:"请输入密码",trigger:"blur"},{min:6,message:"密码长度不低于6位",trigger:"blur"}]},loading:!1,pwdType:"password",redirect:void 0}},methods:{showPwd:function(){"password"===this.pwdType?this.pwdType="":this.pwdType="password"},mobileSubmit:function(){var e=this;return o()(r.a.mark(function t(){return r.a.wrap(function(t){for(;;)switch(t.prev=t.next){case 0:if(/\d{11}/.test(e.mobileForm.mobile_phone)){t.next=3;break}return e.$message({type:"warning",message:"请输入正确的手机号"}),t.abrupt("return");case 3:if(e.mobileForm.code){t.next=6;break}return e.$message({type:"warning",message:"请输入验证码"}),t.abrupt("return");case 6:if(e.mobileForm.password){t.next=9;break}return e.$message({type:"warning",message:"请输入密码"}),t.abrupt("return");case 9:return t.next=11,Object(c.f)({mobile_phone:e.mobileForm.mobile_phone,code:e.mobileForm.code,password:l()(e.mobileForm.password)});case 11:if(null!==t.sent){t.next=14;break}return t.abrupt("return");case 14:e.$message({type:"success",message:"注册成功,请登录"}),e.$router.push({path:"/login"});case 16:case"end":return t.stop()}},t,e)}))()},emailSubmit:function(){var e=this;return o()(r.a.mark(function t(){return r.a.wrap(function(t){for(;;)switch(t.prev=t.next){case 0:e.$refs.emailForm.validate(function(){var t=o()(r.a.mark(function t(s){var a,n;return r.a.wrap(function(t){for(;;)switch(t.prev=t.next){case 0:if(s){t.next=2;break}return t.abrupt("return");case 2:return e.emailLoading=!0,(a=p()({},e.emailForm)).password=l()(a.password),t.next=7,Object(c.f)(a);case 7:if(n=t.sent,e.emailLoading=!1,null!==n){t.next=11;break}return t.abrupt("return");case 11:e.$message({type:"success",message:"注册成功,请登录"}),e.$router.push({path:"/login"});case 13:case"end":return t.stop()}},t,e)}));return function(e){return t.apply(this,arguments)}}());case 1:case"end":return t.stop()}},t,e)}))()},sendSMS:function(){var e=this;return o()(r.a.mark(function t(){var s;return r.a.wrap(function(t){for(;;)switch(t.prev=t.next){case 0:if(!(e.smsCount>=0)){t.next=2;break}return t.abrupt("return");case 2:if(/\d{11}/.test(e.mobileForm.mobile_phone)){t.next=5;break}return e.$message({type:"warning",message:"请输入正确的手机号"}),t.abrupt("return");case 5:return t.next=7,Object(c.h)({mobile_phone:e.mobileForm.mobile_phone});case 7:if(null!==t.sent){t.next=10;break}return t.abrupt("return");case 10:e.$message({type:"success",message:"短信发送成功"}),e.smsCount=60,s=setInterval(function(){e.smsCount<=0&&clearInterval(s),e.smsCount-=1},1e3);case 13:case"end":return t.stop()}},t,e)}))()},sendMail:function(){var e=this;return o()(r.a.mark(function t(){var s;return r.a.wrap(function(t){for(;;)switch(t.prev=t.next){case 0:if(!(e.emailCount>=0)){t.next=2;break}return t.abrupt("return");case 2:return t.next=4,Object(c.g)({email:e.emailForm.email});case 4:if(null!==t.sent){t.next=7;break}return t.abrupt("return");case 7:e.$message({type:"success",message:"发送成功"}),e.emailCount=60,s=setInterval(function(){e.emailCount<=0&&clearInterval(s),e.emailCount-=1},1e3);case 10:case"end":return t.stop()}},t,e)}))()}}},d=(s("Timz"),s("2uYv"),s("KHd+")),v=Object(d.a)(u,function(){var e=this,t=e.$createElement,s=e._self._c||t;return s("div",{staticClass:"login-container"},["mobile"==e.mode?s("el-form",{ref:"mobileForm",staticClass:"login-form",attrs:{model:e.mobileForm,"auto-complete":"on","label-position":"left"}},[s("h3",{staticClass:"title"},[e._v("手机注册")]),e._v(" "),s("el-form-item",{attrs:{prop:"phone"}},[s("span",{staticClass:"svg-container"},[s("svg-icon",{attrs:{"icon-class":"phone"}})],1),e._v(" "),s("el-input",{attrs:{type:"text","auto-complete":"on",placeholder:"请输入手机号"},model:{value:e.mobileForm.mobile_phone,callback:function(t){e.$set(e.mobileForm,"mobile_phone",t)},expression:"mobileForm.mobile_phone"}})],1),e._v(" "),s("el-form-item",{attrs:{prop:"phone"}},[s("span",{staticClass:"svg-container"},[s("svg-icon",{attrs:{"icon-class":"verifycode"}})],1),e._v(" "),s("el-input",{attrs:{type:"text","auto-complete":"on",placeholder:"验证码"},model:{value:e.mobileForm.code,callback:function(t){e.$set(e.mobileForm,"code",t)},expression:"mobileForm.code"}}),e._v(" "),s("div",{staticClass:"verify-btn",on:{click:e.sendSMS}},[e._v(e._s(e.smsCount>=0?e.smsCount:"获取验证码"))])],1),e._v(" "),s("el-form-item",{attrs:{prop:"password"}},[s("span",{staticClass:"svg-container"},[s("svg-icon",{attrs:{"icon-class":"password"}})],1),e._v(" "),s("el-input",{attrs:{type:e.pwdType,name:"password","auto-complete":"on",placeholder:"密码"},nativeOn:{keyup:function(t){return"button"in t||!e._k(t.keyCode,"enter",13,t.key,"Enter")?e.handleLogin(t):null}},model:{value:e.mobileForm.password,callback:function(t){e.$set(e.mobileForm,"password",t)},expression:"mobileForm.password"}}),e._v(" "),s("span",{staticClass:"show-pwd",on:{click:e.showPwd}},[s("svg-icon",{attrs:{"icon-class":"password"===e.pwdType?"eye":"eye-open"}})],1)],1),e._v(" "),s("el-form-item",[s("el-button",{staticStyle:{width:"100%"},attrs:{loading:e.loading,type:"primary"},on:{click:e.mobileSubmit}},[e._v("\n 注册\n ")])],1),e._v(" "),s("div",{staticClass:"tips"},[s("a",{on:{click:function(t){e.mode="email"}}},[e._v("邮箱注册")]),e._v(" "),s("span",{staticClass:"tips-line"},[e._v("|")]),e._v(" "),s("router-link",{staticClass:"tips-link",attrs:{to:{path:"/login"},href:""}},[e._v("登录")])],1)],1):s("el-form",{ref:"emailForm",staticClass:"login-form",attrs:{model:e.emailForm,rules:e.emailRules,"auto-complete":"on","label-position":"left"}},[s("h3",{staticClass:"title"},[e._v("邮箱注册")]),e._v(" "),s("el-form-item",{attrs:{prop:"email"}},[s("span",{staticClass:"svg-container"},[s("svg-icon",{attrs:{"icon-class":"email"}})],1),e._v(" "),s("el-input",{attrs:{type:"text","auto-complete":"on",placeholder:"请输入邮箱"},model:{value:e.emailForm.email,callback:function(t){e.$set(e.emailForm,"email",t)},expression:"emailForm.email"}})],1),e._v(" "),s("el-form-item",{attrs:{prop:"code"}},[s("span",{staticClass:"svg-container"},[s("svg-icon",{attrs:{"icon-class":"verifycode"}})],1),e._v(" "),s("el-input",{attrs:{type:"text","auto-complete":"on",placeholder:"验证码"},model:{value:e.emailForm.code,callback:function(t){e.$set(e.emailForm,"code",t)},expression:"emailForm.code"}}),e._v(" "),s("div",{staticClass:"verify-btn",on:{click:e.sendMail}},[e._v(e._s(e.emailCount>=0?e.emailCount:"获取验证码"))])],1),e._v(" "),s("el-form-item",{attrs:{prop:"password"}},[s("span",{staticClass:"svg-container"},[s("svg-icon",{attrs:{"icon-class":"password"}})],1),e._v(" "),s("el-input",{attrs:{type:e.pwdType,name:"password","auto-complete":"on",placeholder:"密码"},nativeOn:{keyup:function(t){return"button"in t||!e._k(t.keyCode,"enter",13,t.key,"Enter")?e.emailSubmit(t):null}},model:{value:e.emailForm.password,callback:function(t){e.$set(e.emailForm,"password",t)},expression:"emailForm.password"}}),e._v(" "),s("span",{staticClass:"show-pwd",on:{click:e.showPwd}},[s("svg-icon",{attrs:{"icon-class":"password"===e.pwdType?"eye":"eye-open"}})],1)],1),e._v(" "),s("el-form-item",[s("el-button",{staticStyle:{width:"100%"},attrs:{loading:e.emailLoading,type:"primary"},on:{click:e.emailSubmit}},[e._v("\n 注册\n ")])],1),e._v(" "),s("div",{staticClass:"tips"},[s("a",{on:{click:function(t){e.mode="mobile"}}},[e._v("手机注册")]),e._v(" "),s("span",{staticClass:"tips-line"},[e._v("|")]),e._v(" "),s("router-link",{staticClass:"tips-link",attrs:{to:{path:"/login"},href:""}},[e._v("登录")])],1)],1)],1)},[],!1,null,"b89682e8",null);v.options.__file="Register.vue";t.default=v.exports},qvc3:function(e,t,s){}}]);
--------------------------------------------------------------------------------
/public/css/normalize.css:
--------------------------------------------------------------------------------
1 | /*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */
2 |
3 | /* Document
4 | ========================================================================== */
5 |
6 | /**
7 | * 1. Correct the line height in all browsers.
8 | * 2. Prevent adjustments of font size after orientation changes in iOS.
9 | */
10 |
11 | html {
12 | line-height: 1.15; /* 1 */
13 | -webkit-text-size-adjust: 100%; /* 2 */
14 | }
15 |
16 | /* Sections
17 | ========================================================================== */
18 |
19 | /**
20 | * Remove the margin in all browsers.
21 | */
22 |
23 | body {
24 | margin: 0;
25 | }
26 |
27 | /**
28 | * Render the `main` element consistently in IE.
29 | */
30 |
31 | main {
32 | display: block;
33 | }
34 |
35 | /**
36 | * Correct the font size and margin on `h1` elements within `section` and
37 | * `article` contexts in Chrome, Firefox, and Safari.
38 | */
39 |
40 | h1 {
41 | font-size: 2em;
42 | margin: 0.67em 0;
43 | }
44 |
45 | /* Grouping content
46 | ========================================================================== */
47 |
48 | /**
49 | * 1. Add the correct box sizing in Firefox.
50 | * 2. Show the overflow in Edge and IE.
51 | */
52 |
53 | hr {
54 | box-sizing: content-box; /* 1 */
55 | height: 0; /* 1 */
56 | overflow: visible; /* 2 */
57 | }
58 |
59 | /**
60 | * 1. Correct the inheritance and scaling of font size in all browsers.
61 | * 2. Correct the odd `em` font sizing in all browsers.
62 | */
63 |
64 | pre {
65 | font-family: monospace, monospace; /* 1 */
66 | font-size: 1em; /* 2 */
67 | }
68 |
69 | /* Text-level semantics
70 | ========================================================================== */
71 |
72 | /**
73 | * Remove the gray background on active links in IE 10.
74 | */
75 |
76 | a {
77 | background-color: transparent;
78 | }
79 |
80 | /**
81 | * 1. Remove the bottom border in Chrome 57-
82 | * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.
83 | */
84 |
85 | abbr[title] {
86 | border-bottom: none; /* 1 */
87 | text-decoration: underline; /* 2 */
88 | text-decoration: underline dotted; /* 2 */
89 | }
90 |
91 | /**
92 | * Add the correct font weight in Chrome, Edge, and Safari.
93 | */
94 |
95 | b,
96 | strong {
97 | font-weight: bolder;
98 | }
99 |
100 | /**
101 | * 1. Correct the inheritance and scaling of font size in all browsers.
102 | * 2. Correct the odd `em` font sizing in all browsers.
103 | */
104 |
105 | code,
106 | kbd,
107 | samp {
108 | font-family: monospace, monospace; /* 1 */
109 | font-size: 1em; /* 2 */
110 | }
111 |
112 | /**
113 | * Add the correct font size in all browsers.
114 | */
115 |
116 | small {
117 | font-size: 80%;
118 | }
119 |
120 | /**
121 | * Prevent `sub` and `sup` elements from affecting the line height in
122 | * all browsers.
123 | */
124 |
125 | sub,
126 | sup {
127 | font-size: 75%;
128 | line-height: 0;
129 | position: relative;
130 | vertical-align: baseline;
131 | }
132 |
133 | sub {
134 | bottom: -0.25em;
135 | }
136 |
137 | sup {
138 | top: -0.5em;
139 | }
140 |
141 | /* Embedded content
142 | ========================================================================== */
143 |
144 | /**
145 | * Remove the border on images inside links in IE 10.
146 | */
147 |
148 | img {
149 | border-style: none;
150 | }
151 |
152 | /* Forms
153 | ========================================================================== */
154 |
155 | /**
156 | * 1. Change the font styles in all browsers.
157 | * 2. Remove the margin in Firefox and Safari.
158 | */
159 |
160 | button,
161 | input,
162 | optgroup,
163 | select,
164 | textarea {
165 | font-family: inherit; /* 1 */
166 | font-size: 100%; /* 1 */
167 | line-height: 1.15; /* 1 */
168 | margin: 0; /* 2 */
169 | }
170 |
171 | /**
172 | * Show the overflow in IE.
173 | * 1. Show the overflow in Edge.
174 | */
175 |
176 | button,
177 | input { /* 1 */
178 | overflow: visible;
179 | }
180 |
181 | /**
182 | * Remove the inheritance of text transform in Edge, Firefox, and IE.
183 | * 1. Remove the inheritance of text transform in Firefox.
184 | */
185 |
186 | button,
187 | select { /* 1 */
188 | text-transform: none;
189 | }
190 |
191 | /**
192 | * Correct the inability to style clickable types in iOS and Safari.
193 | */
194 |
195 | button,
196 | [type="button"],
197 | [type="reset"],
198 | [type="submit"] {
199 | -webkit-appearance: button;
200 | }
201 |
202 | /**
203 | * Remove the inner border and padding in Firefox.
204 | */
205 |
206 | button::-moz-focus-inner,
207 | [type="button"]::-moz-focus-inner,
208 | [type="reset"]::-moz-focus-inner,
209 | [type="submit"]::-moz-focus-inner {
210 | border-style: none;
211 | padding: 0;
212 | }
213 |
214 | /**
215 | * Restore the focus styles unset by the previous rule.
216 | */
217 |
218 | button:-moz-focusring,
219 | [type="button"]:-moz-focusring,
220 | [type="reset"]:-moz-focusring,
221 | [type="submit"]:-moz-focusring {
222 | outline: 1px dotted ButtonText;
223 | }
224 |
225 | /**
226 | * Correct the padding in Firefox.
227 | */
228 |
229 | fieldset {
230 | padding: 0.35em 0.75em 0.625em;
231 | }
232 |
233 | /**
234 | * 1. Correct the text wrapping in Edge and IE.
235 | * 2. Correct the color inheritance from `fieldset` elements in IE.
236 | * 3. Remove the padding so developers are not caught out when they zero out
237 | * `fieldset` elements in all browsers.
238 | */
239 |
240 | legend {
241 | box-sizing: border-box; /* 1 */
242 | color: inherit; /* 2 */
243 | display: table; /* 1 */
244 | max-width: 100%; /* 1 */
245 | padding: 0; /* 3 */
246 | white-space: normal; /* 1 */
247 | }
248 |
249 | /**
250 | * Add the correct vertical alignment in Chrome, Firefox, and Opera.
251 | */
252 |
253 | progress {
254 | vertical-align: baseline;
255 | }
256 |
257 | /**
258 | * Remove the default vertical scrollbar in IE 10+.
259 | */
260 |
261 | textarea {
262 | overflow: auto;
263 | }
264 |
265 | /**
266 | * 1. Add the correct box sizing in IE 10.
267 | * 2. Remove the padding in IE 10.
268 | */
269 |
270 | [type="checkbox"],
271 | [type="radio"] {
272 | box-sizing: border-box; /* 1 */
273 | padding: 0; /* 2 */
274 | }
275 |
276 | /**
277 | * Correct the cursor style of increment and decrement buttons in Chrome.
278 | */
279 |
280 | [type="number"]::-webkit-inner-spin-button,
281 | [type="number"]::-webkit-outer-spin-button {
282 | height: auto;
283 | }
284 |
285 | /**
286 | * 1. Correct the odd appearance in Chrome and Safari.
287 | * 2. Correct the outline style in Safari.
288 | */
289 |
290 | [type="search"] {
291 | -webkit-appearance: textfield; /* 1 */
292 | outline-offset: -2px; /* 2 */
293 | }
294 |
295 | /**
296 | * Remove the inner padding in Chrome and Safari on macOS.
297 | */
298 |
299 | [type="search"]::-webkit-search-decoration {
300 | -webkit-appearance: none;
301 | }
302 |
303 | /**
304 | * 1. Correct the inability to style clickable types in iOS and Safari.
305 | * 2. Change font properties to `inherit` in Safari.
306 | */
307 |
308 | ::-webkit-file-upload-button {
309 | -webkit-appearance: button; /* 1 */
310 | font: inherit; /* 2 */
311 | }
312 |
313 | /* Interactive
314 | ========================================================================== */
315 |
316 | /*
317 | * Add the correct display in Edge, IE 10+, and Firefox.
318 | */
319 |
320 | details {
321 | display: block;
322 | }
323 |
324 | /*
325 | * Add the correct display in all browsers.
326 | */
327 |
328 | summary {
329 | display: list-item;
330 | }
331 |
332 | /* Misc
333 | ========================================================================== */
334 |
335 | /**
336 | * Add the correct display in IE 10+.
337 | */
338 |
339 | template {
340 | display: none;
341 | }
342 |
343 | /**
344 | * Add the correct display in IE 10.
345 | */
346 |
347 | [hidden] {
348 | display: none;
349 | }
--------------------------------------------------------------------------------
/public/font/iconfont.js:
--------------------------------------------------------------------------------
1 | !function(l){var t,o='',e=(t=document.getElementsByTagName("script"))[t.length-1].getAttribute("data-injectcss");if(e&&!l.__iconfont__svg__cssinject__){l.__iconfont__svg__cssinject__=!0;try{document.write("")}catch(t){console&&console.log(t)}}!function(t){if(document.addEventListener)if(~["complete","loaded","interactive"].indexOf(document.readyState))setTimeout(t,0);else{var e=function(){document.removeEventListener("DOMContentLoaded",e,!1),t()};document.addEventListener("DOMContentLoaded",e,!1)}else document.attachEvent&&(o=t,n=l.document,i=!1,c=function(){i||(i=!0,o())},(s=function(){try{n.documentElement.doScroll("left")}catch(t){return void setTimeout(s,50)}c()})(),n.onreadystatechange=function(){"complete"==n.readyState&&(n.onreadystatechange=null,c())});var o,n,i,c,s}(function(){var t,e;(t=document.createElement("div")).innerHTML=o,o=null,(e=t.getElementsByTagName("svg")[0])&&(e.setAttribute("aria-hidden","true"),e.style.position="absolute",e.style.width=0,e.style.height=0,e.style.overflow="hidden",function(t,e){e.firstChild?function(t,e){e.parentNode.insertBefore(t,e)}(t,e.firstChild):e.appendChild(t)}(e,document.body))})}(window);
--------------------------------------------------------------------------------