Commit 157852e2 authored by 1486327116's avatar 1486327116

Merge remote-tracking branch 'origin/master'

parents 72f92e71 fef64a78
// 配置文件暂时和 js 的导出方式保持一致,涉及到线上环境变量的替换等
module.exports = {
BASE_URL: "/backend/v1/"
BASE_URL: "/backend/v1/",
OSS_CONFIG: {
region: "oss-cn-hongkong",
accessKeyId: "LTAIKTww9T29bp9t",
accessKeySecret: "6cbKA6dlkg2BIHovQV217izCrwJg8B",
endPoint: "https://oss-cn-hongkong.aliyuncs.com",
avatar_bucket: "biiigle-oss-bucket-oss",
linkcoin_host: "https://res.linkcoin.pro",
kyc_bucket: "bibox-oss",
bibox_host: "https://res.bibox.com"
}
};
\ No newline at end of file
......@@ -13,7 +13,7 @@ export default _.merge(
require(config_file),
common_config,
{
port: 8080, //服务端口
port: 8081, //服务端口
contractData: {}
},
{
......
......@@ -30,6 +30,7 @@
"express-swagger-generator": "^1.1.17",
"geoip-lite": "^1.4.7",
"glob": "10.3.10",
"image-size": "1.0.2",
"isemail": "^3.2.0",
"jsonwebtoken": "^7.4.3",
"lodash": "^4.17.21",
......@@ -105,9 +106,9 @@
}
},
"node_modules/@babel/compat-data": {
"version": "7.25.2",
"resolved": "https://packages.aliyun.com/646341b481b284e28f47a25b/npm/npm-registry/@babel/compat-data/-/compat-data-7.25.2.tgz",
"integrity": "sha512-bYcppcpKBvX4znYaPEeFau03bp89ShqNMLs+rmdptMw+heSZh9+z84d2YG+K7cYLbWwzdjtDoW/uqZmPjulClQ==",
"version": "7.25.4",
"resolved": "https://packages.aliyun.com/646341b481b284e28f47a25b/npm/npm-registry/@babel/compat-data/-/compat-data-7.25.4.tgz",
"integrity": "sha512-+LGRog6RAsCJrrrg/IO6LGmpphNe5DiK30dGjCoxxeGv49B10/3XYGxPsAwrDlMFcFEvdAUavDT8r9k/hSyQqQ==",
"dev": true,
"license": "MIT",
"engines": {
......@@ -163,13 +164,13 @@
}
},
"node_modules/@babel/generator": {
"version": "7.25.0",
"resolved": "https://packages.aliyun.com/646341b481b284e28f47a25b/npm/npm-registry/@babel/generator/-/generator-7.25.0.tgz",
"integrity": "sha512-3LEEcj3PVW8pW2R1SR1M89g/qrYk/m/mB/tLqn7dn4sbBUQyTqnlod+II2U4dqiGtUmkcnAmkMDralTFZttRiw==",
"version": "7.25.5",
"resolved": "https://packages.aliyun.com/646341b481b284e28f47a25b/npm/npm-registry/@babel/generator/-/generator-7.25.5.tgz",
"integrity": "sha512-abd43wyLfbWoxC6ahM8xTkqLpGB2iWBVyuKC9/srhFunCd1SDNrV1s72bBpK4hLj8KLzHBBcOblvLQZBNw9r3w==",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/types": "^7.25.0",
"@babel/types": "^7.25.4",
"@jridgewell/gen-mapping": "^0.3.5",
"@jridgewell/trace-mapping": "^0.3.25",
"jsesc": "^2.5.1"
......@@ -391,13 +392,13 @@
}
},
"node_modules/@babel/parser": {
"version": "7.25.3",
"resolved": "https://packages.aliyun.com/646341b481b284e28f47a25b/npm/npm-registry/@babel/parser/-/parser-7.25.3.tgz",
"integrity": "sha512-iLTJKDbJ4hMvFPgQwwsVoxtHyWpKKPBrxkANrSYewDPaPpT5py5yeVkgPIJ7XYXhndxJpaA3PyALSXQ7u8e/Dw==",
"version": "7.25.4",
"resolved": "https://packages.aliyun.com/646341b481b284e28f47a25b/npm/npm-registry/@babel/parser/-/parser-7.25.4.tgz",
"integrity": "sha512-nq+eWrOgdtu3jG5Os4TQP3x3cLA8hR8TvJNjD8vnPa20WGycimcparWnLK4jJhElTK6SDyuJo1weMKO/5LpmLA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/types": "^7.25.2"
"@babel/types": "^7.25.4"
},
"bin": {
"parser": "bin/babel-parser.js"
......@@ -422,17 +423,17 @@
}
},
"node_modules/@babel/traverse": {
"version": "7.25.3",
"resolved": "https://packages.aliyun.com/646341b481b284e28f47a25b/npm/npm-registry/@babel/traverse/-/traverse-7.25.3.tgz",
"integrity": "sha512-HefgyP1x754oGCsKmV5reSmtV7IXj/kpaE1XYY+D9G5PvKKoFfSbiS4M77MdjuwlZKDIKFCffq9rPU+H/s3ZdQ==",
"version": "7.25.4",
"resolved": "https://packages.aliyun.com/646341b481b284e28f47a25b/npm/npm-registry/@babel/traverse/-/traverse-7.25.4.tgz",
"integrity": "sha512-VJ4XsrD+nOvlXyLzmLzUs/0qjFS4sK30te5yEFlvbbUNEgKaVb2BHZUpAL+ttLPQAHNrsI3zZisbfha5Cvr8vg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/code-frame": "^7.24.7",
"@babel/generator": "^7.25.0",
"@babel/parser": "^7.25.3",
"@babel/generator": "^7.25.4",
"@babel/parser": "^7.25.4",
"@babel/template": "^7.25.0",
"@babel/types": "^7.25.2",
"@babel/types": "^7.25.4",
"debug": "^4.3.1",
"globals": "^11.1.0"
},
......@@ -451,9 +452,9 @@
}
},
"node_modules/@babel/types": {
"version": "7.25.2",
"resolved": "https://packages.aliyun.com/646341b481b284e28f47a25b/npm/npm-registry/@babel/types/-/types-7.25.2.tgz",
"integrity": "sha512-YTnYtra7W9e6/oAZEHj0bJehPRUlLH9/fbpT5LfB0NhQXyALCRkRs3zH9v07IYhkgpqX6Z78FnuccZr/l4Fs4Q==",
"version": "7.25.4",
"resolved": "https://packages.aliyun.com/646341b481b284e28f47a25b/npm/npm-registry/@babel/types/-/types-7.25.4.tgz",
"integrity": "sha512-zQ1ijeeCXVEh+aNL0RlmkPkG8HUiDcU2pzQQFjtbntgAczRASFzj4H+6+bV+dy1ntKR14I/DypeuRG1uma98iQ==",
"dev": true,
"license": "MIT",
"dependencies": {
......@@ -874,7 +875,7 @@
},
"node_modules/@madex/ex-js-common": {
"version": "1.0.0",
"resolved": "git+ssh://git@bitbucket.org/biiigle/ex-js-common.git#6aa1d7d9264b2a13e13fe6c79d33223205b9cc40",
"resolved": "git+ssh://git@bitbucket.org/biiigle/ex-js-common.git#8731a80a995567cd1c6e9ecdb256ea9df1e0ff31",
"license": "ISC",
"dependencies": {
"@madex/ex-js-dao": "git+ssh://git@bitbucket.org/biiigle/ex-js-dao.git#master",
......@@ -1068,9 +1069,9 @@
}
},
"node_modules/@madex/ex-ts-dao": {
"version": "0.0.17",
"resolved": "https://packages.aliyun.com/646341b481b284e28f47a25b/npm/npm-registry/@madex/ex-ts-dao/-/@madex/ex-ts-dao-0.0.17.tgz",
"integrity": "sha512-TDR4FNGVSAv4FLqJQJZ+D8ZeJmBacQIF7AYVECutsL4PWE5LBRP3xylvuL1EB6DRdbDRt/L42k7bdChWn1TN0A==",
"version": "0.0.21",
"resolved": "https://packages.aliyun.com/646341b481b284e28f47a25b/npm/npm-registry/@madex/ex-ts-dao/-/@madex/ex-ts-dao-0.0.21.tgz",
"integrity": "sha512-uXdHq1OyOLxilsj9/k5lavzDvt0HqKOH/oTf3HHSHup2aF/UepUIwm62RyZoDE/MdrdRFS0DZsnddAbAcARRqw==",
"license": "ISC",
"dependencies": {
"@madex/ex-js-public": "git+ssh://git@bitbucket.org/biiigle/ex-js-public.git#master",
......@@ -1616,9 +1617,9 @@
}
},
"node_modules/@types/node": {
"version": "20.16.1",
"resolved": "https://packages.aliyun.com/646341b481b284e28f47a25b/npm/npm-registry/@types/node/-/node-20.16.1.tgz",
"integrity": "sha512-zJDo7wEadFtSyNz5QITDfRcrhqDvQI1xQNQ0VoizPjM/dVAODqqIUWbJPkvsxmTI0MYRGRikcdjMPhOssnPejQ==",
"version": "20.16.2",
"resolved": "https://packages.aliyun.com/646341b481b284e28f47a25b/npm/npm-registry/@types/node/-/node-20.16.2.tgz",
"integrity": "sha512-91s/n4qUPV/wg8eE9KHYW1kouTfDk2FPGjXbBMfRWP/2vg1rCXNQL1OCabwGs0XSdukuK+MwCDXE30QpSeMUhQ==",
"license": "MIT",
"dependencies": {
"undici-types": "~6.19.2"
......@@ -1696,9 +1697,9 @@
"license": "MIT"
},
"node_modules/@types/validator": {
"version": "13.12.0",
"resolved": "https://packages.aliyun.com/646341b481b284e28f47a25b/npm/npm-registry/@types/validator/-/validator-13.12.0.tgz",
"integrity": "sha512-nH45Lk7oPIJ1RVOF6JgFI6Dy0QpHEzq4QecZhvguxYPDwT8c93prCMqAtiIttm39voZ+DDR+qkNnMpJmMBRqag==",
"version": "13.12.1",
"resolved": "https://packages.aliyun.com/646341b481b284e28f47a25b/npm/npm-registry/@types/validator/-/validator-13.12.1.tgz",
"integrity": "sha512-w0URwf7BQb0rD/EuiG12KP0bailHKHP5YVviJG9zw3ykAokL0TuxU2TUqMB7EwZ59bDHYdeTIvjI5m0S7qHfOA==",
"dev": true,
"license": "MIT"
},
......@@ -2724,9 +2725,9 @@
}
},
"node_modules/aws4": {
"version": "1.13.1",
"resolved": "https://packages.aliyun.com/646341b481b284e28f47a25b/npm/npm-registry/aws4/-/aws4-1.13.1.tgz",
"integrity": "sha512-u5w79Rd7SU4JaIlA/zFqG+gOiuq25q5VLyZ8E+ijJeILuTxVzZgp2CaGw/UTw6pXYN9XMO9yiqj/nEHmhTG5CA==",
"version": "1.13.2",
"resolved": "https://packages.aliyun.com/646341b481b284e28f47a25b/npm/npm-registry/aws4/-/aws4-1.13.2.tgz",
"integrity": "sha512-lHe62zvbTB5eEABUVi/AwVh0ZKY9rMMDhmm+eeyuuUQbQ3+J+fONVQOZyj+DdrvD4BY33uYniyRJ4UJIaSKAfw==",
"license": "MIT"
},
"node_modules/axios": {
......@@ -3321,9 +3322,9 @@
}
},
"node_modules/caniuse-lite": {
"version": "1.0.30001651",
"resolved": "https://packages.aliyun.com/646341b481b284e28f47a25b/npm/npm-registry/caniuse-lite/-/caniuse-lite-1.0.30001651.tgz",
"integrity": "sha512-9Cf+Xv1jJNe1xPZLGuUXLNkE1BoDkqRqYyFJ9TDYSqhduqA4hu4oR9HluGoWYQC/aj8WHjsGVV+bwkh0+tegRg==",
"version": "1.0.30001653",
"resolved": "https://packages.aliyun.com/646341b481b284e28f47a25b/npm/npm-registry/caniuse-lite/-/caniuse-lite-1.0.30001653.tgz",
"integrity": "sha512-XGWQVB8wFQ2+9NZwZ10GxTYC5hk0Fa+q8cSkr0tgvMhYhMHP/QC+WTgrePMDBWiWc/pV+1ik82Al20XOK25Gcw==",
"dev": true,
"funding": [
{
......@@ -5015,9 +5016,9 @@
}
},
"node_modules/eslint-module-utils": {
"version": "2.8.1",
"resolved": "https://packages.aliyun.com/646341b481b284e28f47a25b/npm/npm-registry/eslint-module-utils/-/eslint-module-utils-2.8.1.tgz",
"integrity": "sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q==",
"version": "2.8.2",
"resolved": "https://packages.aliyun.com/646341b481b284e28f47a25b/npm/npm-registry/eslint-module-utils/-/eslint-module-utils-2.8.2.tgz",
"integrity": "sha512-3XnC5fDyc8M4J2E8pt8pmSVRX2M+5yWMCfI/kDZwauQeFgzQOuhcRBFKjTeJagqgk4sFKxe1mvNVnaWwImx/Tg==",
"dev": true,
"license": "MIT",
"dependencies": {
......@@ -6975,6 +6976,21 @@
"node": ">= 4"
}
},
"node_modules/image-size": {
"version": "1.0.2",
"resolved": "https://packages.aliyun.com/646341b481b284e28f47a25b/npm/npm-registry/image-size/-/image-size-1.0.2.tgz",
"integrity": "sha512-xfOoWjceHntRb3qFCrh5ZFORYH8XCdYpASltMhZ/Q0KZiOwjdE/Yl2QCiWdwD+lygV5bMCvauzgu5PxBX/Yerg==",
"license": "MIT",
"dependencies": {
"queue": "6.0.2"
},
"bin": {
"image-size": "bin/image-size.js"
},
"engines": {
"node": ">=14.0.0"
}
},
"node_modules/imageinfo": {
"version": "1.0.4",
"resolved": "https://packages.aliyun.com/646341b481b284e28f47a25b/npm/npm-registry/imageinfo/-/imageinfo-1.0.4.tgz",
......@@ -9448,9 +9464,9 @@
}
},
"node_modules/micromatch": {
"version": "4.0.7",
"resolved": "https://packages.aliyun.com/646341b481b284e28f47a25b/npm/npm-registry/micromatch/-/micromatch-4.0.7.tgz",
"integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==",
"version": "4.0.8",
"resolved": "https://packages.aliyun.com/646341b481b284e28f47a25b/npm/npm-registry/micromatch/-/micromatch-4.0.8.tgz",
"integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
"dev": true,
"license": "MIT",
"dependencies": {
......@@ -11469,6 +11485,15 @@
"license": "MIT",
"optional": true
},
"node_modules/queue": {
"version": "6.0.2",
"resolved": "https://packages.aliyun.com/646341b481b284e28f47a25b/npm/npm-registry/queue/-/queue-6.0.2.tgz",
"integrity": "sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA==",
"license": "MIT",
"dependencies": {
"inherits": "~2.0.3"
}
},
"node_modules/queue-microtask": {
"version": "1.2.3",
"resolved": "https://packages.aliyun.com/646341b481b284e28f47a25b/npm/npm-registry/queue-microtask/-/queue-microtask-1.2.3.tgz",
......@@ -13773,9 +13798,9 @@
}
},
"node_modules/tslib": {
"version": "2.6.3",
"resolved": "https://packages.aliyun.com/646341b481b284e28f47a25b/npm/npm-registry/tslib/-/tslib-2.6.3.tgz",
"integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==",
"version": "2.7.0",
"resolved": "https://packages.aliyun.com/646341b481b284e28f47a25b/npm/npm-registry/tslib/-/tslib-2.7.0.tgz",
"integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==",
"license": "0BSD"
},
"node_modules/tsscmp": {
......
......@@ -76,6 +76,7 @@
"sequelize": "^4.44.4",
"should": "^12.0.0",
"tunnel": "^0.0.6",
"uuid": "9.0.1"
"uuid": "9.0.1",
"image-size": "1.0.2"
}
}
export const EMAIL_FORBID_TEMPLATE = "MODIFYING_MAILBOX_FORBID_FUNCTION"; // 限制用户3个功能
export const AFTER_MODIFIED_MAILBOX_TIP = "AFTER_MODIFIED_MAILBOX_TIP"; // 7天每日提醒
export const REAL_NAME_PASS = "REAL_NAME_PASS"; // 实名认证通过
export const REAL_NAME_DENY = "REAL_NAME_DENY"; // 实名认证未通过
\ No newline at end of file
export const ErrorCode = {
PARAM_MISS:'30000',//请求参数错误
DATA_NOT_EXIST:'30001',//数据不存在
DATA_EXIST:'30002',//数据已存在
PARAM_MISS: '30000',//请求参数错误
DATA_NOT_EXIST: '30001',//数据不存在
DATA_EXIST: '30002',//数据已存在
NOT_LOGIN: '30003',//账号未登录
NO_PERMISSION: '30004',//账号没有权限
USER_EXIST: '30005',//用户已存在
......@@ -24,6 +24,31 @@ export const ErrorCode = {
TOTP_KEY_OVERSTAYED: '30022',//密钥已失效,请重新获取
USER_TYPE_ILLEGAL: '30023',//用户类型不合法
NEED_INPUT_GOOGLE_CODE: '30024',//请输入Google验证码
PUSH_NOT_UPDATE: '30025',//已经推送不允许修改
UID_LIMIT: '30026',//UID受限,不允许操作
UPDATE_EMAIL_EXIST: '30027',//要修改的邮箱已存在
EMAIL_USED_NTO_CHANGE: '30028',//该邮箱已经使用,请切换邮箱
EMAIL_CHANGE_OFTEN: '30029',//请勿频繁切换邮箱
DAD_ACCOUNT_NOT_EXIST: '30030',//该子账户的父账户不存在
DEL_USER_NO_UNLOCK: '30031',//删除的用户不予许解锁
USER_NOT_LOCK: '30032',//该用户未锁定
REASON_TOO_LONG: '30033',//驳回原因过长
DATA_STATUS_CHANGED: '30034',//非法操作,数据状态已经变更
UID_ILLEGALITY: '30035',//UID不合法
UID_TOO_MUCH: '30036',//UID过多
SPOT_NO_ASSETS:'30037',//用户现货账户未有资产记录
U_NO_ASSETS:'30038',//用户U本位合约账户未有资产记录
COIN_NO_ASSETS:'30039',//用户币本位合约账户未有资产记录
SPOT_FEE_NEED_SET:'30040',//币币费率需要设置
CONTRACT_FEE_NEED_SET:'30041',//合约费率需要设置
SON_NOT_ADD_FEE:'30042',//子账户不能添加为市商
LEVEL_NOT_EXIST:'30043',//指定等级不存在
ONLY_ONE_FEE:'30044',//只能有一条未提交的费率设置
ONLY_UN_SUBMIT_UPDATE:'30045',//只有未提交的记录可以修改
UID_TYPE_NOT_UPDATE:'30046',//用户ID和类型不能修改
DEL_UN_SUBMIT_ACTIVE:'30047',//只能删除未提交或未生效的记录
FEE_USED_NOT_DEL:'30048',//费率已生效,不能删除
ONLY_UN_SUBMIT_CAN_SUBMIT:'30049',//只有未提交的记录才能提交
}
export const FEE_RATE_LOG_STATUS = {
/**
* 状态: 未生效。
*/
CHECK_STATUS_UNCHECK: 0,
/**
* 状态: 生效中。
*/
CHECK_STATUS_ACTIVE: 1,
/**
* 状态: 已删除(未生效时用户主动删除)。
*/
CHECK_STATUS_DELETED: 2,
/**
* 状态: 已经生效过,已失效(生效后被新的费率覆盖而失效)。
*/
CHECK_STATUS_ACTIVE_OVER: 3,
}
/**
* 币币、合约手续费feeModel字段默认值。
*/
export const FEE_MODEL_SPOT_DEFAULT = "fixedingain"
\ No newline at end of file
export const KYC_STATUS = {
STATUS_NOT_COMMIT: 0,//未提交
STATUS_AUDITING: 1,//审核中
STATUS_AUDIT_DENY: 2,//审核不通过
STATUS_AUDIT_PASS: 3//审核通过
}
export const SETTING_FLAG = {
FLAG_REAL_NAME_AUTH: 1 << 4
}
\ No newline at end of file
export const MUserRedisKey = {
//登陆限制
USER_LOCK_SUFFIX :".login_lock"
}
\ No newline at end of file
export const FEE_TYPE = {
/**
* 费率类型: 全部。
*/
FEE_TYPE_ALL: 0,
/**
* 费率类型: 币币。
*/
FEE_TYPE_SPOT: 1,
/**
* 费率类型: U本位合约。
*/
FEE_TYPE_CONTRACT: 2,
/**
* 费率类型: 币本位合约。
*/
FEE_TYPE_BASE_COIN_CONTRACT: 3,
/**
* 费率类型: 合约(U本位+币本位)
*/
FEE_TYPE_CONTRACT_ALL: 5,
}
export const FEE_TYPE_LIST = [FEE_TYPE.FEE_TYPE_ALL, FEE_TYPE.FEE_TYPE_SPOT, FEE_TYPE.FEE_TYPE_CONTRACT, FEE_TYPE.FEE_TYPE_BASE_COIN_CONTRACT, FEE_TYPE.FEE_TYPE_CONTRACT_ALL,]
export const FEE_STATUS = {
/**
* 费率设置纪录状态: 未提交。
*/
STATUS_FEE_SETTING_NEW: 0,
/**
* 费率设置纪录状态: 已提交。
*/
STATUS_FEE_SETTING_SUBMIT: 1,
/**
* 费率设置纪录状态: 已生效。
*/
STATUS_FEE_SETTING_EFFECTED: 2,
/**
* 费率设置纪录状态: 已过期。
*/
STATUS_FEE_SETTING_EXPIRE: 3,
/**
* 费率设置纪录状态: 已删除。
*/
STATUS_FEE_SETTING_DELETED: 4,
}
/**
* 普通用户手续费提交备注。
*/
export const COMMENT_USER_FEE_SUBMIT = "提交普通用户手续费";
\ No newline at end of file
export const TYPE_MAIL = {
/**
* 邮件日志类型: 。
*/
TYPE_MAIL_LOG_MONEY_AND_KYC : 1,
/**
* 邮件日志类型: 。
*/
TYPE_MAIL_LOG_MONEY_AND_NO_KYC : 2,
/**
* 邮件日志类型: 。
*/
TYPE_MAIL_LOG_NO_MONEY_AND_KYC : 3,
/**
* 邮件日志类型: 。
*/
TYPE_MAIL_LOG_NO_MONEY_AND_NO_KYC : 4,
/**
* 邮件日志类型: 。
*/
TYPE_MAIL_LOG_ALL : 5,
/**
* 邮件日志类型: 。
*/
TYPE_MAIL_LOG_SINGLE : 6,
}
\ No newline at end of file
export const SYMBOL_ALL = "all";
\ No newline at end of file
/**
* useful_link表常量。
*/
export const IS_ACTIVE = {
/**
* 是否启用: 未启用。
*/
IS_ACTIVE_NO: 0,
/**
* 是否启用: 已启用。
*/
IS_ACTIVE_YES: 1
}
export const IS_ACTIVE_ARR = [IS_ACTIVE.IS_ACTIVE_NO, IS_ACTIVE.IS_ACTIVE_YES]
export const LINK_TYPE = {
/**
* 友情链接。
*/
TYPE_NORMAL: 1,
/**
* 合作伙伴。
*/
TYPE_FRIEND: 2,
/**
* 公告。
*/
TYPE_NOTICE: 3,
/**
* 轮播图。
*/
TYPE_SLIDESHOW: 4,
/**
* app 轮播图。
*/
TYPE_SLIDESHOW_APP: 5,
/**
* 鼓励金比例管理。
*/
TYPE_BIX_LOCK_BACK_RATE: 6,
/**
* app 弹窗。
*/
TYPE_APP_POP: 8,
/**
* web 弹框。
*/
TYPE_WEB_POP: 9,
/**
* banner, 首页活动 banner。
*/
TYPE_BANNER: 10,
/**
* 活动中心。
*/
TYPE_ACTIVE_CENTER: 11,
/**
* 广告位: 红包页面。
*/
TYPE_ADVERTISE_RED_PACKET: 12,
/**
* 广告位: web交易页,币对位置。
*/
TYPE_ADVERTISE_WEB_PAIR: 13,
/**
* 广告位: 登录页面。
*/
TYPE_ADVERTISE_LOGIN: 14,
/**
* 广告位: 系统邮件。
*/
TYPE_ADVERTISE_SYS_MAIL: 15,
/**
* 标题广告: 币币交易详情页。
*/
TYPE_DETAIL_TRADE_SPOT: 16,
/**
* 标题广告: 杠杆交易详情页。
*/
TYPE_DETAIL_TRADE_CREDIT: 17,
/**
* 标题广告: 合约交易详情页。
*/
TYPE_DETAIL_TRADE_CONTRACT: 18,
/**
* 合约轮播图。
*/
TYPE_SLIDESHOW_CONTRACT: 19,
/**
* 合约公告
*/
TYPE_NOTICE_CONTRACT: 20,
}
export const LINK_TYPE_ARR = [
LINK_TYPE.TYPE_NORMAL,
LINK_TYPE.TYPE_FRIEND,
LINK_TYPE.TYPE_NOTICE,
LINK_TYPE.TYPE_SLIDESHOW,
LINK_TYPE.TYPE_SLIDESHOW_APP,
LINK_TYPE.TYPE_BIX_LOCK_BACK_RATE,
LINK_TYPE.TYPE_APP_POP,
LINK_TYPE.TYPE_WEB_POP,
LINK_TYPE.TYPE_BANNER,
LINK_TYPE.TYPE_ACTIVE_CENTER,
LINK_TYPE.TYPE_ADVERTISE_RED_PACKET,
LINK_TYPE.TYPE_ADVERTISE_WEB_PAIR,
LINK_TYPE.TYPE_ADVERTISE_LOGIN,
LINK_TYPE.TYPE_ADVERTISE_SYS_MAIL,
LINK_TYPE.TYPE_DETAIL_TRADE_SPOT,
LINK_TYPE.TYPE_DETAIL_TRADE_CREDIT,
LINK_TYPE.TYPE_DETAIL_TRADE_CONTRACT,
LINK_TYPE.TYPE_SLIDESHOW_CONTRACT,
LINK_TYPE.TYPE_NOTICE_CONTRACT,
]
import * as commonUserFeeSettingService from "../service/commonUserFeeSetting.service";
import { CommonUserFeeVO, CommonUserFeePageVO } from "../service/commonUserFeeSetting.service";
import { vipLevelFeeSetting } from "@madex/ex-ts-dao";
let { logger, Res3Utils, optionalUtils: Optional, apiAssertUtils: ApiAssert, datetimeUtils } = require('@madex/ex-js-public');
import { ErrorCode } from "../../../constant/errorCode";
import { IS_ACTIVE, IS_ACTIVE_ARR, LINK_TYPE_ARR } from "../../../constant/usefulLinkConst";
import { getCurrentUserId } from "../../../utils/aclUserUtils";
import { FEE_TYPE, FEE_TYPE_LIST } from "../../../constant/marketMakerConst";
import { baseCoinCheck, baseUCheck, spotCheck } from "../../../utils/feeRateCheckValidUtils";
import { getMUserInfoByUid } from "../../../utils/mUserUtils";
import { getFatherUserId } from "../service/mUserInfoSon.service";
let isIp = require('is-ip');
/**
* 手续费列表
* @param req
* @param infoVO
*/
export const list = async (req: any, pageVO: CommonUserFeePageVO) => {
let func_name = "commonUserFeeSetting.control.list";
try {
pageVO.page = Optional.opt(pageVO, 'page', 1);
pageVO.size = Optional.opt(pageVO, 'size', 20);
let res = await commonUserFeeSettingService.list(pageVO);
return Res3Utils.result(res);
}
catch (e) {
logger.error(`${func_name} error:${e}`);
return Res3Utils.getErrorResult(e);
}
};
/**
* 添加用户费率
* @param req
* @param authConfigVO
*/
export const add = async (req: any, commonUserFeeVO: CommonUserFeeVO) => {
let func_name = "commonUserFeeSetting.control.add";
try {
let ip = isIp(req.ip) ? req.ip : '*.*.*.*';
let currentUserId = await getCurrentUserId(req.cookies.session_id);
await addParamValid(commonUserFeeVO);
let res = await commonUserFeeSettingService.add(commonUserFeeVO, currentUserId, ip);
return Res3Utils.result(res);
}
catch (e) {
logger.error(`${func_name} error:${e}`);
return Res3Utils.getErrorResult(e);
}
};
/**
* 修改用户费率
* @param req
* @param authConfigVO
*/
export const update = async (req: any, commonUserFeeVO: CommonUserFeeVO) => {
let func_name = "commonUserFeeSetting.control.update";
try {
let ip = isIp(req.ip) ? req.ip : '*.*.*.*';
let currentUserId = await getCurrentUserId(req.cookies.session_id);
await updateParamValid(commonUserFeeVO);
let res = await commonUserFeeSettingService.update(commonUserFeeVO, currentUserId, ip);
return Res3Utils.result(res);
}
catch (e) {
logger.error(`${func_name} error:${e}`);
return Res3Utils.getErrorResult(e);
}
};
/**
* 删除用户费率
* @param req
* @param authConfigVO
*/
export const del = async (req: any, commonUserFeeVO: CommonUserFeeVO) => {
let func_name = "commonUserFeeSetting.control.del";
try {
let ip = isIp(req.ip) ? req.ip : '*.*.*.*';
let currentUserId = await getCurrentUserId(req.cookies.session_id);
if (!commonUserFeeVO.id) {
throw ErrorCode.PARAM_MISS
}
let res = await commonUserFeeSettingService.del(commonUserFeeVO.id, currentUserId, ip);
return Res3Utils.result(res);
}
catch (e) {
logger.error(`${func_name} error:${e}`);
return Res3Utils.getErrorResult(e);
}
};
/**
* 提交用户费率
* @param req
* @param authConfigVO
*/
export const submit = async (req: any, commonUserFeeVO: CommonUserFeeVO) => {
let func_name = "commonUserFeeSetting.control.submit";
try {
let ip = isIp(req.ip) ? req.ip : '*.*.*.*';
let currentUserId = await getCurrentUserId(req.cookies.session_id);
if (!commonUserFeeVO.id) {
throw ErrorCode.PARAM_MISS
}
let res = await commonUserFeeSettingService.submit(commonUserFeeVO.id, currentUserId, ip);
return Res3Utils.result(res);
}
catch (e) {
logger.error(`${func_name} error:${e}`);
return Res3Utils.getErrorResult(e);
}
};
async function addParamValid(commonUserFeeVO: CommonUserFeeVO) {
let userId = commonUserFeeVO.user_id;
let beginTime = commonUserFeeVO.begin_time;
let expireTime = commonUserFeeVO.expire_time;
let type = commonUserFeeVO.type;
let levelId = commonUserFeeVO.level_id;
if (!userId || !beginTime || !expireTime) {
throw ErrorCode.PARAM_MISS;
}
await paramCheck(beginTime, expireTime, Number(type), userId);
if (levelId) {
let vipLevelSetting = await vipLevelFeeSetting.prototype.findOne({
where: {
id: levelId
},
raw: true
});
if (!vipLevelSetting) {
throw ErrorCode.LEVEL_NOT_EXIST;
}
commonUserFeeVO.spot_maker_fee = vipLevelSetting.spot_maker;
commonUserFeeVO.spot_taker_fee = vipLevelSetting.spot_taker;
commonUserFeeVO.contract_maker_fee = vipLevelSetting.contract_maker;
commonUserFeeVO.contract_taker_fee = vipLevelSetting.contract_taker;
return;
}
if ((type == FEE_TYPE.FEE_TYPE_ALL || type == FEE_TYPE.FEE_TYPE_SPOT)
&& (!commonUserFeeVO.spot_maker_fee || !commonUserFeeVO.spot_taker_fee)) {
throw ErrorCode.SPOT_FEE_NEED_SET;
}
if ((type == FEE_TYPE.FEE_TYPE_ALL || type == FEE_TYPE.FEE_TYPE_CONTRACT_ALL
|| type == FEE_TYPE.FEE_TYPE_CONTRACT || type == FEE_TYPE.FEE_TYPE_BASE_COIN_CONTRACT)
&& (!commonUserFeeVO.contract_maker_fee || !commonUserFeeVO.contract_taker_fee)) {
throw ErrorCode.CONTRACT_FEE_NEED_SET;
}
let user = await getMUserInfoByUid(userId);
if (!user || user.deleted_flag == 1) {
throw ErrorCode.USER_NOT_EXIST;
}
let fuid = await getFatherUserId(userId);
if (fuid) {
throw ErrorCode.SON_NOT_ADD_FEE;
}
}
async function updateParamValid(commonUserFeeVO: CommonUserFeeVO) {
let id = commonUserFeeVO.id;
let userId = commonUserFeeVO.user_id;
let beginTime = commonUserFeeVO.begin_time;
let expireTime = commonUserFeeVO.expire_time;
let type = commonUserFeeVO.type;
let makerFee = commonUserFeeVO.maker_fee;
let takerFee = commonUserFeeVO.taker_fee;
if (!id || !userId || !beginTime || !expireTime || !makerFee || !takerFee) {
throw ErrorCode.PARAM_MISS;
}
await paramCheck(beginTime, expireTime, Number(type), userId);
}
/**
* 添加和更新校验入参
* @param beginTime
* @param expireTime
* @param type
* @param userId
*/
async function paramCheck(beginTime: any, expireTime: any, type: number, userId: number) {
//结束时间最少需要是一小时后;开始时间和结束时间最少需要间隔一小时
if (!datetimeUtils.between(expireTime, new Date()) > datetimeUtils.HOUR
|| !datetimeUtils.between(expireTime, beginTime) > datetimeUtils.HOUR) {
throw ErrorCode.PARAM_MISS;
}
if (isNaN(Number(type)) || !FEE_TYPE_LIST.includes(Number(type))) {
throw ErrorCode.PARAM_MISS;
}
if (type == FEE_TYPE.FEE_TYPE_SPOT) {
if (!await spotCheck(userId)) {
throw ErrorCode.SPOT_NO_ASSETS;
}
}
else if (type == FEE_TYPE.FEE_TYPE_CONTRACT) {
if (!await baseUCheck(userId)) {
throw ErrorCode.U_NO_ASSETS;
}
}
else if (type == FEE_TYPE.FEE_TYPE_BASE_COIN_CONTRACT) {
if (!await baseCoinCheck(userId)) {
throw ErrorCode.COIN_NO_ASSETS;
}
}
else if (type == FEE_TYPE.FEE_TYPE_CONTRACT_ALL) {
if (!await baseUCheck(userId)) {
throw ErrorCode.U_NO_ASSETS;
}
if (!await baseCoinCheck(userId)) {
throw ErrorCode.COIN_NO_ASSETS;
}
}
else if (type == FEE_TYPE.FEE_TYPE_ALL) {
if (!await spotCheck(userId)) {
throw ErrorCode.SPOT_NO_ASSETS;
}
if (!await baseUCheck(userId)) {
throw ErrorCode.U_NO_ASSETS;
}
if (!await baseCoinCheck(userId)) {
throw ErrorCode.COIN_NO_ASSETS;
}
}
}
import * as mUserManageService from "../service/mUserManage.service";
import { QueryVO } from "../service/mUserManage.service";
let { logger, Res3Utils, optionalUtils: Optional, apiAssertUtils: ApiAssert } = require('@madex/ex-js-public');
import { ErrorCode } from "../../../constant/errorCode";
import { getCurrentUserId, isAdminUserBySessionId } from "../../../utils/aclUserUtils";
import * as IsEmail from "isemail";
import { isLimitUserId } from "../../../utils/mUserCommonUtils";
let isIp = require('is-ip');
/**
* Madex 用户列表
* @param req
* @param infoVO
*/
export const userList = async (req: any, queryVO: QueryVO) => {
let func_name = "mUserManageCtrl.userList";
try {
queryVO.page = Optional.opt(queryVO, 'page', 1);
queryVO.size = Optional.opt(queryVO, 'size', 20);
let res = await mUserManageService.userList(queryVO);
return Res3Utils.result(res);
}
catch (e) {
logger.error(`${func_name} error:${e}`);
return Res3Utils.getErrorResult(e);
}
};
/**
* Madex 单个用户详情
* @param req
* @param queryVO
*/
export const oneUserDetail = async (req: any, queryVO: QueryVO) => {
let func_name = "mUserManageCtrl.oneUserDetail";
try {
if (!queryVO.user_id) {
throw ErrorCode.PARAM_MISS
}
let res = await mUserManageService.oneUserDetail(queryVO.user_id);
return Res3Utils.result(res);
}
catch (e) {
logger.error(`${func_name} error:${e}`);
return Res3Utils.getErrorResult(e);
}
};
/**
* Madex 修改用户邮箱
* @param req
* @param queryVO
*/
export const updateUserEmail = async (req: any, queryVO: QueryVO) => {
let func_name = "mUserManageCtrl.updateUserEmail";
try {
if (!queryVO.user_id || !queryVO.email || !queryVO.totp_code) {
throw ErrorCode.PARAM_MISS
}
//超管才有权限修改
await isAdminUserBySessionId(req.cookies.session_id);
//uid 是否在受限范围内
if (isLimitUserId(queryVO.user_id)) {
throw ErrorCode.UID_LIMIT
}
if (!IsEmail.validate(queryVO.email, { minDomainAtoms: 2 })) {
//邮箱格式错误
throw '2000';
}
let ip = isIp(req.ip) ? req.ip : '*.*.*.*';
let currentUserId = await getCurrentUserId(req.cookies.session_id);
let res = await mUserManageService.updateUserEmail(currentUserId, queryVO.user_id, queryVO.email, queryVO.totp_code, ip);
return Res3Utils.result(res);
}
catch (e) {
logger.error(`${func_name} error:${e}`);
return Res3Utils.getErrorResult(e);
}
};
/**
* Madex 锁定账户
* @param req
* @param queryVO
*/
//TODO: 前端需要弹窗选择锁定当前账户 还是 当前账户及其所有子账户
export const lockAccount = async (req: any, queryVO: QueryVO) => {
let func_name = "mUserManageCtrl.lockAccount";
try {
if (!queryVO.user_id || !queryVO.lock_type || !queryVO.totp_code) {
throw ErrorCode.PARAM_MISS
}
//超管才有权限
await isAdminUserBySessionId(req.cookies.session_id);
//uid 是否在受限范围内
if (isLimitUserId(queryVO.user_id)) {
throw ErrorCode.UID_LIMIT
}
let ip = isIp(req.ip) ? req.ip : '*.*.*.*';
let currentUserId = await getCurrentUserId(req.cookies.session_id);
let res = await mUserManageService.lockAccount(currentUserId, queryVO.user_id, ip, queryVO.lock_type, queryVO.totp_code);
return Res3Utils.result(res);
}
catch (e) {
logger.error(`${func_name} error:${e}`);
return Res3Utils.getErrorResult(e);
}
};
/**
* 解锁账户
* @param req
* @param queryVO
*/
//TODO: 前端需要弹窗选择锁定当前账户 还是 当前账户及其所有子账户
export const unlockAccount = async (req: any, queryVO: QueryVO) => {
let func_name = "mUserManageCtrl.unlockAccount";
try {
if (!queryVO.user_id || !queryVO.lock_type || !queryVO.totp_code) {
throw ErrorCode.PARAM_MISS
}
//超管才有权限
await isAdminUserBySessionId(req.cookies.session_id);
//uid 是否在受限范围内
if (isLimitUserId(queryVO.user_id)) {
throw ErrorCode.UID_LIMIT
}
let ip = isIp(req.ip) ? req.ip : '*.*.*.*';
let currentUserId = await getCurrentUserId(req.cookies.session_id);
let res = await mUserManageService.unlockAccount(currentUserId, queryVO.user_id, ip, queryVO.lock_type, queryVO.totp_code);
return Res3Utils.result(res);
}
catch (e) {
logger.error(`${func_name} error:${e}`);
return Res3Utils.getErrorResult(e);
}
};
/**
* Madex 清除登陆限制
* @param req
* @param queryVO
*/
export const clearLoginLimit = async (req: any, queryVO: QueryVO) => {
let func_name = "mUserManageCtrl.clearLoginLimit";
try {
if (!queryVO.user_id || !queryVO.totp_code) {
throw ErrorCode.PARAM_MISS
}
//超管才有权限
await isAdminUserBySessionId(req.cookies.session_id);
//uid 是否在受限范围内
if (isLimitUserId(queryVO.user_id)) {
throw ErrorCode.UID_LIMIT
}
let ip = isIp(req.ip) ? req.ip : '*.*.*.*';
let currentUserId = await getCurrentUserId(req.cookies.session_id);
let res = await mUserManageService.clearLoginLimit(currentUserId, queryVO.user_id, ip, queryVO.totp_code);
return Res3Utils.result(res);
}
catch (e) {
logger.error(`${func_name} error:${e}`);
return Res3Utils.getErrorResult(e);
}
};
/**
* Madex 清除24小时提现限制
* @param req
* @param queryVO
*/
export const clear24WithdrawLimit = async (req: any, queryVO: QueryVO) => {
let func_name = "mUserManageCtrl.clear24WithdrawLimit";
try {
if (!queryVO.user_id || !queryVO.totp_code) {
throw ErrorCode.PARAM_MISS
}
//超管才有权限
await isAdminUserBySessionId(req.cookies.session_id);
//uid 是否在受限范围内
if (isLimitUserId(queryVO.user_id)) {
throw ErrorCode.UID_LIMIT
}
let ip = isIp(req.ip) ? req.ip : '*.*.*.*';
let currentUserId = await getCurrentUserId(req.cookies.session_id);
let res = await mUserManageService.clear24WithdrawLimit(currentUserId, queryVO.user_id, ip, queryVO.totp_code);
return Res3Utils.result(res);
}
catch (e) {
logger.error(`${func_name} error:${e}`);
return Res3Utils.getErrorResult(e);
}
};
import * as mUserOptLogService from "../service/mUserOptLog.service";
import { QueryVO } from "../service/mUserOptLog.service";
let { logger, Res3Utils, optionalUtils: Optional, apiAssertUtils: ApiAssert } = require('@madex/ex-js-public');
import { ErrorCode } from "../../../constant/errorCode";
/**
* Madex 用户操作日志列表
* @param req
* @param infoVO
*/
export const list = async (req: any, queryVO: QueryVO) => {
let func_name = "mUserOptLogCtrl.list";
try {
queryVO.page = Optional.opt(queryVO, 'page', 1);
queryVO.size = Optional.opt(queryVO, 'size', 20);
let res = await mUserOptLogService.list(queryVO);
return Res3Utils.result(res);
}
catch (e) {
logger.error(`${func_name} error:${e}`);
return Res3Utils.getErrorResult(e);
}
};
import * as mUserRealNameService from "../service/mUserRealName.service";
import { QueryVO } from "../service/mUserRealName.service";
let { logger, Res3Utils, optionalUtils: Optional, apiAssertUtils: ApiAssert } = require('@madex/ex-js-public');
import { ErrorCode } from "../../../constant/errorCode";
import { getCurrentUserId, getOneAclUserByUid, isAdminUserBySessionId } from "../../../utils/aclUserUtils";
import { isLimitUserId } from "../../../utils/mUserCommonUtils";
import { AclUserInfoConst } from "../../../constant/aclUserConstant";
let isIp = require('is-ip');
/**
* Madex 用户实名列表
* @param req
* @param infoVO
*/
export const kycList = async (req: any, queryVO: QueryVO) => {
let func_name = "mUserRealNameCtrl.kycList";
try {
queryVO.page = Optional.opt(queryVO, 'page', 1);
queryVO.size = Optional.opt(queryVO, 'size', 20);
let currentUserId = await getCurrentUserId(req.cookies.session_id);
let dbInfo = await getOneAclUserByUid(currentUserId);
let isAdmin = dbInfo.user_type == AclUserInfoConst.USER_TYPE.ADMIN
let res = await mUserRealNameService.kycList(queryVO, isAdmin);
return Res3Utils.result(res);
}
catch (e) {
logger.error(`${func_name} error:${e}`);
return Res3Utils.getErrorResult(e);
}
};
/**
* Madex 单个实名用户详情
* @param req
* @param queryVO
*/
export const oneDetail = async (req: any, queryVO: QueryVO) => {
let func_name = "mUserRealNameCtrl.oneDetail";
try {
if (!queryVO.id) {
throw ErrorCode.PARAM_MISS
}
//超管才有权限修改
await isAdminUserBySessionId(req.cookies.session_id);
let res = await mUserRealNameService.oneDetail(queryVO.id);
return Res3Utils.result(res);
}
catch (e) {
logger.error(`${func_name} error:${e}`);
return Res3Utils.getErrorResult(e);
}
};
/**
* Madex 实名审核
* @param req
* @param queryVO
*/
export const audit = async (req: any, queryVO: QueryVO) => {
let func_name = "mUserRealNameCtrl.audit";
try {
if (!queryVO.id) {
throw ErrorCode.PARAM_MISS
}
//超管才有权限修改
await isAdminUserBySessionId(req.cookies.session_id);
let currentUserId = await getCurrentUserId(req.cookies.session_id);
let ip = isIp(req.ip) ? req.ip : '*.*.*.*';
let res = await mUserRealNameService.audit(queryVO, currentUserId, ip);
return Res3Utils.result(res);
}
catch (e) {
logger.error(`${func_name} error:${e}`);
return Res3Utils.getErrorResult(e);
}
};
import * as mUserSubscribeService from "../service/mUserSubscribe.service";
import { QueryVO } from "../service/mUserSubscribe.service";
import * as mUserMailLogService from "../service/mUserMailLog.service";
import { UserMailLogVO } from "../service/mUserMailLog.service";
let { logger, Res3Utils, optionalUtils: Optional, apiAssertUtils: ApiAssert } = require('@madex/ex-js-public');
import { ErrorCode } from "../../../constant/errorCode";
import { IS_ACTIVE, IS_ACTIVE_ARR, LINK_TYPE_ARR } from "../../../constant/usefulLinkConst";
import { getCurrentUserId } from "../../../utils/aclUserUtils";
let isIp = require('is-ip');
/**
* 订阅列表
* @param req
* @param infoVO
*/
export const list = async (req: any, queryVO: QueryVO) => {
let func_name = "mUserSubscribe.control.list";
try {
queryVO.page = Optional.opt(queryVO, 'page', 1);
queryVO.size = Optional.opt(queryVO, 'size', 20);
let res = await mUserSubscribeService.list(queryVO);
return Res3Utils.result(res);
}
catch (e) {
logger.error(`${func_name} error:${e}`);
return Res3Utils.getErrorResult(e);
}
};
/**
* 删除订阅
* TODO: 关于status 字段 从老管理后台来看 0 代表无效 1 代表有效 但是数据库备注 0 有效 1 无效 以哪个为准?
* @param req
* @param authConfigVO
*/
export const del = async (req: any, queryVO: QueryVO) => {
let func_name = "mUserSubscribe.control.delete";
try {
let ip = isIp(req.ip) ? req.ip : '*.*.*.*';
let currentUserId = await getCurrentUserId(req.cookies.session_id);
ApiAssert.notNull(ErrorCode.PARAM_MISS, queryVO.id);
let res = await mUserSubscribeService.del(Number(queryVO.id), currentUserId, ip);
return Res3Utils.result(res);
}
catch (e) {
logger.error(`${func_name} error:${e}`);
return Res3Utils.getErrorResult(e);
}
};
/**
* 订阅统计
* TODO: 关于status 字段 从老管理后台来看 0 代表无效 1 代表有效 但是数据库备注 0 有效 1 无效 以哪个为准?
* @param req
* @param authConfigVO
*/
export const count = async (req: any, queryVO: QueryVO) => {
let func_name = "mUserSubscribe.control.count";
try {
let res = await mUserSubscribeService.count();
return Res3Utils.result(res);
}
catch (e) {
logger.error(`${func_name} error:${e}`);
return Res3Utils.getErrorResult(e);
}
};
/**
* 邮件发送历史
* @param req
* @param infoVO
*/
export const history = async (req: any, userMailLogVO: UserMailLogVO) => {
let func_name = "mUserSubscribe.control.history";
try {
userMailLogVO.page = Optional.opt(userMailLogVO, 'page', 1);
userMailLogVO.size = Optional.opt(userMailLogVO, 'size', 20);
let res = await mUserMailLogService.history(userMailLogVO.page, userMailLogVO.size);
return Res3Utils.result(res);
}
catch (e) {
logger.error(`${func_name} error:${e}`);
return Res3Utils.getErrorResult(e);
}
};
/**
* 邮件详情
* @param req
* @param infoVO
*/
export const mailDetail = async (req: any, userMailLogVO: UserMailLogVO) => {
let func_name = "mUserSubscribe.control.mailDetail";
try {
if (!userMailLogVO.id) {
throw ErrorCode.PARAM_MISS
}
let res = await mUserMailLogService.mailDetail(userMailLogVO.id);
return Res3Utils.result(res);
}
catch (e) {
logger.error(`${func_name} error:${e}`);
return Res3Utils.getErrorResult(e);
}
};
/**
* 邮件发送
* TODO: 关于status 字段 从老管理后台来看 0 代表无效 1 代表有效 但是数据库备注 0 有效 1 无效 service里面又查询 status = 0 的 ???
* @param req
* @param userMailLogVO
*/
export const mailSend = async (req: any, userMailLogVO: UserMailLogVO) => {
let func_name = "mUserSubscribe.control.mailSend";
try {
if (!userMailLogVO.subject || !userMailLogVO.content) {
throw ErrorCode.PARAM_MISS
}
let ip = isIp(req.ip) ? req.ip : '*.*.*.*';
let currentUserId = await getCurrentUserId(req.cookies.session_id);
let subjectBuf = Buffer.from(String(userMailLogVO.subject), 'base64');
let contentBuf = Buffer.from(String(userMailLogVO.content), 'base64');
userMailLogVO.subject = subjectBuf.toString('utf8');
userMailLogVO.content = contentBuf.toString('utf8');
let res = await mUserMailLogService.mailSend(userMailLogVO, currentUserId, ip);
return Res3Utils.result(res);
}
catch (e) {
logger.error(`${func_name} error:${e}`);
return Res3Utils.getErrorResult(e);
}
};
/**
* 群发邮件
* @param req
* @param userMailLogVO
*/
export const maiSendGroup = async (req: any, userMailLogVO: UserMailLogVO) => {
let func_name = "mUserSubscribe.control.maiSendGroup";
try {
if (!userMailLogVO.subject || !userMailLogVO.content || !userMailLogVO.uidStr) {
throw ErrorCode.PARAM_MISS
}
let ip = isIp(req.ip) ? req.ip : '*.*.*.*';
let currentUserId = await getCurrentUserId(req.cookies.session_id);
let subjectBuf = Buffer.from(String(userMailLogVO.subject), 'base64');
let contentBuf = Buffer.from(String(userMailLogVO.content), 'base64');
userMailLogVO.subject = subjectBuf.toString('utf8');
userMailLogVO.content = contentBuf.toString('utf8');
let uids = userMailLogVO.uidStr.split(",");
if (uids.length > 1000) {
throw ErrorCode.UID_TOO_MUCH;
}
for (let uid of uids) {
if (!uid) {
throw ErrorCode.UID_ILLEGALITY;
}
}
let res = await mUserMailLogService.maiSendGroup(userMailLogVO.subject, userMailLogVO.content, currentUserId, ip, uids);
return Res3Utils.result(res);
}
catch (e) {
logger.error(`${func_name} error:${e}`);
return Res3Utils.getErrorResult(e);
}
};
\ No newline at end of file
import * as usefulLinkService from "../service/usefulLink.service";
import { UsefulLinkVO, UsefulLinkPageVO } from "../service/usefulLink.service";
let { logger, Res3Utils, optionalUtils: Optional, apiAssertUtils: ApiAssert } = require('@madex/ex-js-public');
import { ErrorCode } from "../../../constant/errorCode";
import { IS_ACTIVE, IS_ACTIVE_ARR, LINK_TYPE_ARR } from "../../../constant/usefulLinkConst";
import { getCurrentUserId } from "../../../utils/aclUserUtils";
let isIp = require('is-ip');
/**
* 分页查询链接列表
* @param req
* @param infoVO
*/
export const list = async (req: any, usefulLinkPageVO: UsefulLinkPageVO) => {
let func_name = "usefulLinkCtrl.list";
try {
usefulLinkPageVO.page = Optional.opt(usefulLinkPageVO, 'page', 1);
usefulLinkPageVO.size = Optional.opt(usefulLinkPageVO, 'size', 20);
let res = await usefulLinkService.list(usefulLinkPageVO);
return Res3Utils.result(res);
}
catch (e) {
logger.error(`${func_name} error:${e}`);
return Res3Utils.getErrorResult(e);
}
};
/**
* 添加链接
* @param req
* @param infoVO
*/
export const add = async (req: any, usefulLinkVO: UsefulLinkVO) => {
let func_name = "usefulLinkCtrl.add";
try {
let ip = isIp(req.ip) ? req.ip : '*.*.*.*';
let currentUserId = await getCurrentUserId(req.cookies.session_id);
await paramValid(usefulLinkVO);
let res = await usefulLinkService.add(usefulLinkVO, currentUserId, ip);
return Res3Utils.result(res);
}
catch (e) {
logger.error(`${func_name} error:${e}`);
return Res3Utils.getErrorResult(e);
}
};
/**
* 修改链接
* @param req
* @param infoVO
*/
export const update = async (req: any, usefulLinkVO: UsefulLinkVO) => {
let func_name = "usefulLinkCtrl.update";
try {
let ip = isIp(req.ip) ? req.ip : '*.*.*.*';
let currentUserId = await getCurrentUserId(req.cookies.session_id);
await paramValid(usefulLinkVO);
let res = await usefulLinkService.update(usefulLinkVO, currentUserId, ip);
return Res3Utils.result(res);
}
catch (e) {
logger.error(`${func_name} error:${e}`);
return Res3Utils.getErrorResult(e);
}
};
/**
* 删除链接
* @param req
* @param authConfigVO
*/
export const del = async (req: any, usefulLinkVO: UsefulLinkVO) => {
let func_name = "usefulLinkCtrl.del";
try {
let ip = isIp(req.ip) ? req.ip : '*.*.*.*';
let currentUserId = await getCurrentUserId(req.cookies.session_id);
ApiAssert.notNull(ErrorCode.PARAM_MISS, usefulLinkVO.id);
let res = await usefulLinkService.del(Number(usefulLinkVO.id), currentUserId, ip);
return Res3Utils.result(res);
}
catch (e) {
logger.error(`${func_name} error:${e}`);
return Res3Utils.getErrorResult(e);
}
};
/**
* 链接详情
* @param req
* @param authConfigVO
*/
export const detail = async (req: any, usefulLinkVO: UsefulLinkVO) => {
let func_name = "usefulLinkCtrl.detail";
try {
ApiAssert.notNull(ErrorCode.PARAM_MISS, usefulLinkVO.id);
let res = await usefulLinkService.detail(Number(usefulLinkVO.id));
return Res3Utils.result(res);
}
catch (e) {
logger.error(`${func_name} error:${e}`);
return Res3Utils.getErrorResult(e);
}
};
async function paramValid(usefulLinkVO: UsefulLinkVO) {
let type = Number(usefulLinkVO.type);
let active = Number(usefulLinkVO.is_active);
if (!usefulLinkVO.name || !usefulLinkVO.url || !type || isNaN(Number(active))
|| !usefulLinkVO.weight || !usefulLinkVO.comment) {
throw ErrorCode.PARAM_MISS;
}
if (!IS_ACTIVE_ARR.includes(active) || !LINK_TYPE_ARR.includes(type)) {
throw ErrorCode.PARAM_MISS;
}
}
\ No newline at end of file
import { ormDB, usefulLink, commonUserFeeSetting, feeRateContractLog, feeRateBaseCoinContractLog, feeRateSpotLog } from "@madex/ex-ts-dao";
import { ErrorCode } from "../../../constant/errorCode";
import { addOptLog, LogType } from "./userOptLog.service";
import { COMMENT_USER_FEE_SUBMIT, FEE_STATUS, FEE_TYPE } from "../../../constant/marketMakerConst";
import { SYMBOL_ALL } from "../../../constant/symbolConst";
import * as feeRateSpotLogService from "./feeRateSpotLog.service";
import * as feeRateContractLogService from "./feeRateContractLog.service";
import * as feeRateBaseCoinContractLogService from "./feeRateBaseCoinContractLog.service";
import { FEE_MODEL_SPOT_DEFAULT, FEE_RATE_LOG_STATUS } from "../../../constant/feeRateLogConst";
let _ = require('lodash');
let { logger } = require('@madex/ex-js-public');
export interface CommonUserFeeVO {
id?: number;
user_id?: number | any;
vip_level?: number;
type?: number;
pair?: string;
maker_fee?: number,
taker_fee?: number,
begin_time?: Date | any,
expire_time?: Date | any,
maker_fee_later?: number,
taker_fee_later?: number,
status?: number,
remark?: string;
fee_log_ids?: string;
create_time?: Date | any,
update_time?: Date | any,
level_id?: number;
spot_maker_fee?: number;
spot_taker_fee?: number;
contract_maker_fee?: number;
contract_taker_fee?: number;
}
export interface CommonUserFeePageVO extends CommonUserFeeVO {
page?: number,
size?: number,
export?: number,//是不全部数据 1 全部倒出 0 否
}
export async function list(pageVO: CommonUserFeePageVO) {
if (pageVO.export) {
let resList = await commonUserFeeSetting.prototype.findAll({
order: [['id', 'desc']],
raw: true
});
return resList;
}
let where = Object.create(null);
if (pageVO.user_id) {
where.user_id = pageVO.user_id;
}
if (pageVO.type) {
where.type = pageVO.type;
}
let resList = await commonUserFeeSetting.prototype.findAndCount({
where: where,
limit: pageVO.size,
offset: (Number(pageVO.page) - 1) * Number(pageVO.size),
order: [["id", "desc"]],
raw: true
});
return resList;
}
export async function add(commonUserFeeVO: CommonUserFeeVO, currentUserId: any, ip: string | undefined) {
let insertList: any = [];
let { spotFeeSetting, contractFeeSetting, baseCoinFeeSetting } = dealData(commonUserFeeVO);
if (spotFeeSetting) {
let [spot, all] = await Promise.all([getFeeSetting(commonUserFeeVO.user_id, FEE_TYPE.FEE_TYPE_SPOT),
getFeeSetting(commonUserFeeVO.user_id, FEE_TYPE.FEE_TYPE_ALL)]);
if (spot || all) {
throw ErrorCode.ONLY_ONE_FEE
}
insertList.push(spotFeeSetting);
}
if (contractFeeSetting) {
let [contract, contractAll, all] = await Promise.all([getFeeSetting(commonUserFeeVO.user_id, FEE_TYPE.FEE_TYPE_CONTRACT),
getFeeSetting(commonUserFeeVO.user_id, FEE_TYPE.FEE_TYPE_CONTRACT_ALL),
getFeeSetting(commonUserFeeVO.user_id, FEE_TYPE.FEE_TYPE_ALL)]);
if (contract || contractAll || all) {
throw ErrorCode.ONLY_ONE_FEE
}
insertList.push(contractFeeSetting);
}
if (baseCoinFeeSetting) {
let [contract, contractAll, all] = await Promise.all([getFeeSetting(commonUserFeeVO.user_id, FEE_TYPE.FEE_TYPE_BASE_COIN_CONTRACT),
getFeeSetting(commonUserFeeVO.user_id, FEE_TYPE.FEE_TYPE_CONTRACT_ALL),
getFeeSetting(commonUserFeeVO.user_id, FEE_TYPE.FEE_TYPE_ALL)]);
if (contract || contractAll || all) {
throw ErrorCode.ONLY_ONE_FEE
}
insertList.push(baseCoinFeeSetting);
}
await commonUserFeeSetting.prototype.bulkCreate(insertList);
//管理后台操作日志
addOptLog(currentUserId, `ip:${ip},新增用户手续费:${JSON.stringify(commonUserFeeVO)}`, LogType.ADD);
}
export async function update(commonUserFeeVO: CommonUserFeeVO, currentUserId: any, ip: string | undefined) {
let dbInfo = await commonUserFeeSetting.prototype.findOne({
where: {
id: commonUserFeeVO.id
},
raw: true
});
if (!dbInfo) {
throw ErrorCode.DATA_NOT_EXIST
}
if (dbInfo.status != FEE_STATUS.STATUS_FEE_SETTING_NEW) {
throw ErrorCode.ONLY_UN_SUBMIT_UPDATE
}
if (dbInfo.user_id != commonUserFeeVO.user_id || dbInfo.type != commonUserFeeVO.type) {
throw ErrorCode.UID_TYPE_NOT_UPDATE
}
await commonUserFeeSetting.prototype.update({
pair: commonUserFeeVO.pair,
maker_fee: Number(commonUserFeeVO.maker_fee),
taker_fee: Number(commonUserFeeVO.taker_fee),
begin_time: commonUserFeeVO.begin_time,
expire_time: commonUserFeeVO.expire_time,
remark: commonUserFeeVO.remark,
fee_log_ids: "",
update_time: new Date(),
}, {
where: {
id: Number(commonUserFeeVO.id)
}
})
//管理后台操作日志
addOptLog(currentUserId, `ip:${ip},修改用户手续费:${JSON.stringify(commonUserFeeVO)}`, LogType.UPDATE);
}
export async function del(id: number, currentUserId: any, ip: string | undefined) {
let dbInfo = await commonUserFeeSetting.prototype.findOne({
where: {
id: id
},
raw: true
});
if (!dbInfo) {
throw ErrorCode.DATA_NOT_EXIST
}
let status = dbInfo.status;
let type = dbInfo.type;
if (status != FEE_STATUS.STATUS_FEE_SETTING_NEW && status != FEE_STATUS.STATUS_FEE_SETTING_SUBMIT) {
throw ErrorCode.DEL_UN_SUBMIT_ACTIVE
}
if (status == FEE_STATUS.STATUS_FEE_SETTING_NEW) {
await commonUserFeeSetting.prototype.destroy({
where: {
id: id
}
});
//管理后台操作日志
addOptLog(currentUserId, `ip:${ip},删除用户手续费:${JSON.stringify(id)}`, LogType.DEL);
return 'success'
}
let feeLogIdsStr = dbInfo.fee_log_ids;
let feeLogIds = feeLogIdsStr.split(",");
let isActive = false;
// 根据费率设置纪录的状态,确定是否有记录被激活。
if (type == FEE_TYPE.FEE_TYPE_SPOT) {
let dbList = await feeRateSpotLogService.getByIdList(feeLogIds);
let filterList = _.filter(dbList, i => i.is_check != FEE_RATE_LOG_STATUS.CHECK_STATUS_UNCHECK);
if (filterList && filterList.length) {
isActive = true
}
}
else if (type == FEE_TYPE.FEE_TYPE_BASE_COIN_CONTRACT) {
let dbList = await feeRateBaseCoinContractLogService.getByIdList(feeLogIds);
let filterList = _.filter(dbList, i => i.is_check != FEE_RATE_LOG_STATUS.CHECK_STATUS_UNCHECK);
if (filterList && filterList.length) {
isActive = true
}
}
else {
let dbList = await feeRateContractLogService.getByIdList(feeLogIds);
let filterList = _.filter(dbList, i => i.is_check != FEE_RATE_LOG_STATUS.CHECK_STATUS_UNCHECK);
if (filterList && filterList.length) {
isActive = true
}
}
if (isActive) {
await commonUserFeeSetting.prototype.update({
status: FEE_STATUS.STATUS_FEE_SETTING_EFFECTED,
update_time: new Date()
}, {
where: {
id: id,
status: status
}
});
throw ErrorCode.FEE_USED_NOT_DEL
}
let tx;
try {
tx = await ormDB.transaction();
if (type == FEE_TYPE.FEE_TYPE_SPOT) {
await feeRateSpotLogService.uncheck2Deleted(feeLogIds, tx);
}
else if (type == FEE_TYPE.FEE_TYPE_BASE_COIN_CONTRACT) {
await feeRateBaseCoinContractLogService.uncheck2Deleted(feeLogIds, tx);
}
else {
await feeRateContractLogService.uncheck2Deleted(feeLogIds, tx);
}
await commonUserFeeSetting.prototype.update({
status: FEE_STATUS.STATUS_FEE_SETTING_DELETED,
update_time: new Date()
}, {
where: {
id: id,
status: status
},
transaction: tx
});
await tx.commit();
}
catch (e) {
if (tx) {
await tx.rollback();
}
logger.error('commonUserFeeSetting.service.del.error:' + e);
throw e;
}
//管理后台操作日志
addOptLog(currentUserId, `ip:${ip},删除用户手续费:${JSON.stringify(id)}`, LogType.DEL);
return 'success';
}
export async function submit(id: number, currentUserId: any, ip: string | undefined) {
let dbInfo = await commonUserFeeSetting.prototype.findOne({
where: {
id: id
},
raw: true
});
if (!dbInfo) {
throw ErrorCode.DATA_NOT_EXIST
}
let status = dbInfo.status;
let type = dbInfo.type;
if (status != FEE_STATUS.STATUS_FEE_SETTING_NEW) {
throw ErrorCode.ONLY_UN_SUBMIT_CAN_SUBMIT
}
let pair = String(dbInfo.pair);
let userId = dbInfo.user_id;
let feeLogId = "";
let now = new Date();
let tx;
try {
tx = await ormDB.transaction();
if (type == FEE_TYPE.FEE_TYPE_SPOT) {
let insertInfo = buildSubmitItem(pair, dbInfo, now);
let item = await feeRateSpotLog.prototype.create(insertInfo, {
transaction: tx
});
feeLogId = item.id.toString();
}
else if (type == FEE_TYPE.FEE_TYPE_BASE_COIN_CONTRACT) {//币本位
if (pair.toLowerCase() == "all") {
//TODO:币本位币对查询 enable = 1 的
let pairList = [];
let insertList: any = [];
let ids: any = [];
for (let onePair of pairList) {
let oneInsert = buildSubmitItem(onePair, dbInfo, now);
insertList.push(oneInsert);
}
let bulkList = await feeRateBaseCoinContractLog.prototype.bulkCreate(insertList, {
transaction: tx
});
for (let one of bulkList) {
ids.push(one.id);
}
feeLogId = ids.toString();
}
else {
let one = buildSubmitItem(pair, dbInfo, now);
let insertOne = await feeRateBaseCoinContractLog.prototype.create(one, {
transaction: tx
});
feeLogId = insertOne.id.toString()
}
}
else {//U本位
if (pair.toLowerCase() == "all") {
//TODO:U本位币对查询 enable = 1 的
let pairList = [];
let insertList: any = [];
let ids: any = [];
for (let onePair of pairList) {
let oneInsert = buildSubmitItem(onePair, dbInfo, now);
insertList.push(oneInsert);
}
let bulkList = await feeRateContractLog.prototype.bulkCreate(insertList, {
transaction: tx
});
for (let one of bulkList) {
ids.push(one.id);
}
feeLogId = ids.toString();
}
else {
let one = buildSubmitItem(pair, dbInfo, now);
let insertOne = await feeRateContractLog.prototype.create(one, {
transaction: tx
});
feeLogId = insertOne.id.toString()
}
}
await commonUserFeeSetting.prototype.update({
status: FEE_STATUS.STATUS_FEE_SETTING_SUBMIT,
fee_log_ids: feeLogId,
update_time: new Date()
}, {
where: {
id: id,
status: FEE_STATUS.STATUS_FEE_SETTING_NEW
},
transaction: tx
});
await tx.commit();
}
catch (e) {
if (tx) {
await tx.rollback();
}
logger.error('commonUserFeeSetting.service.submit.error:' + e);
throw e;
}
//管理后台操作日志
addOptLog(currentUserId, `ip:${ip},提交用户手续费:${JSON.stringify(id)}`, LogType.ADD);
return 'success'
}
function dealData(commonUserFeeVO: CommonUserFeeVO) {
let spotFeeSetting, contractFeeSetting, baseCoinFeeSetting;
let type = commonUserFeeVO.type;
if (type == FEE_TYPE.FEE_TYPE_SPOT) {
spotFeeSetting = buildOne(commonUserFeeVO, commonUserFeeVO.spot_maker_fee, commonUserFeeVO.spot_taker_fee, FEE_TYPE.FEE_TYPE_SPOT)
}
else if (type == FEE_TYPE.FEE_TYPE_CONTRACT) {
contractFeeSetting = buildOne(commonUserFeeVO, commonUserFeeVO.contract_maker_fee, commonUserFeeVO.contract_taker_fee, FEE_TYPE.FEE_TYPE_CONTRACT)
}
else if (type == FEE_TYPE.FEE_TYPE_BASE_COIN_CONTRACT) {
baseCoinFeeSetting = buildOne(commonUserFeeVO, commonUserFeeVO.contract_maker_fee, commonUserFeeVO.contract_taker_fee, FEE_TYPE.FEE_TYPE_BASE_COIN_CONTRACT)
}
else if (type == FEE_TYPE.FEE_TYPE_CONTRACT_ALL) {
contractFeeSetting = buildOne(commonUserFeeVO, commonUserFeeVO.contract_maker_fee, commonUserFeeVO.contract_taker_fee, FEE_TYPE.FEE_TYPE_CONTRACT)
baseCoinFeeSetting = buildOne(commonUserFeeVO, commonUserFeeVO.contract_maker_fee, commonUserFeeVO.contract_taker_fee, FEE_TYPE.FEE_TYPE_BASE_COIN_CONTRACT)
}
else {
spotFeeSetting = buildOne(commonUserFeeVO, commonUserFeeVO.spot_maker_fee, commonUserFeeVO.spot_taker_fee, FEE_TYPE.FEE_TYPE_SPOT)
contractFeeSetting = buildOne(commonUserFeeVO, commonUserFeeVO.contract_maker_fee, commonUserFeeVO.contract_taker_fee, FEE_TYPE.FEE_TYPE_CONTRACT)
baseCoinFeeSetting = buildOne(commonUserFeeVO, commonUserFeeVO.contract_maker_fee, commonUserFeeVO.contract_taker_fee, FEE_TYPE.FEE_TYPE_BASE_COIN_CONTRACT)
}
return {
spotFeeSetting,
contractFeeSetting,
baseCoinFeeSetting
}
}
function buildOne(commonUserFeeVO: CommonUserFeeVO, maker_fee: number | any, taker_fee: number | any, type: number | any) {
let one = {
user_id: commonUserFeeVO.user_id,
type: Number(type),
pair: SYMBOL_ALL,
maker_fee: Number(maker_fee),
taker_fee: Number(taker_fee),
begin_time: commonUserFeeVO.begin_time,
expire_time: commonUserFeeVO.expire_time,
remark: commonUserFeeVO.remark,
status: FEE_STATUS.STATUS_FEE_SETTING_NEW,
fee_log_ids: "",
create_time: new Date(),
update_time: new Date(),
}
return one;
}
async function getFeeSetting(user_id: number | any, type: number | any) {
let dbInfo = await commonUserFeeSetting.prototype.findOne({
where: {
user_id: Number(user_id),
type: Number(type),
status: FEE_STATUS.STATUS_FEE_SETTING_NEW
},
raw: true
});
return dbInfo;
}
function buildSubmitItem(pair: string, dbInfo: any, now: Date) {
let item = {
user_id: dbInfo.user_id,
pair: pair,
fee_model: FEE_MODEL_SPOT_DEFAULT,
maker_fee: dbInfo.maker_fee,
taker_fee: dbInfo.taker_fee,
beginAt: dbInfo.begin_time,
expireAt: dbInfo.expire_time,
is_check: FEE_RATE_LOG_STATUS.CHECK_STATUS_UNCHECK,
comment: COMMENT_USER_FEE_SUBMIT,
createdAt: now,
updatedAt: now
}
return item;
}
import { ormDB, feeRateBaseCoinContractLog } from "@madex/ex-ts-dao";
import { FEE_RATE_LOG_STATUS } from "../../../constant/feeRateLogConst";
export const getByIdList = async function (ids: any) {
let list = await feeRateBaseCoinContractLog.prototype.findAll({
where: {
id: { [ormDB.Op.in]: ids }
},
raw: true
});
return list;
}
export const uncheck2Deleted = async function (ids: any, tx: any) {
await feeRateBaseCoinContractLog.prototype.update({
is_check: FEE_RATE_LOG_STATUS.CHECK_STATUS_DELETED
}, {
where: {
id: { [ormDB.Op.in]: ids },
is_check: FEE_RATE_LOG_STATUS.CHECK_STATUS_UNCHECK
},
transaction: tx
});
}
\ No newline at end of file
import { ormDB, feeRateContractLog } from "@madex/ex-ts-dao";
import { FEE_RATE_LOG_STATUS } from "../../../constant/feeRateLogConst";
export const getByIdList = async function (ids: any) {
let list = await feeRateContractLog.prototype.findAll({
where: {
id: { [ormDB.Op.in]: ids }
},
raw: true
});
return list;
}
/**
* 需要注意在上层处理事务
* @param ids
* @param tx
*/
export const uncheck2Deleted = async function (ids: any, tx: any) {
await feeRateContractLog.prototype.update({
is_check: FEE_RATE_LOG_STATUS.CHECK_STATUS_DELETED
}, {
where: {
id: { [ormDB.Op.in]: ids },
is_check: FEE_RATE_LOG_STATUS.CHECK_STATUS_UNCHECK
},
transaction: tx
});
}
\ No newline at end of file
import { ormDB, feeRateSpotLog } from "@madex/ex-ts-dao";
import { FEE_RATE_LOG_STATUS } from "../../../constant/feeRateLogConst";
export const getByIdList = async function (ids: any) {
let list = await feeRateSpotLog.prototype.findAll({
where: {
id: { [ormDB.Op.in]: ids }
},
raw: true
});
return list;
}
export const uncheck2Deleted = async function (ids: any, tx: any) {
await feeRateSpotLog.prototype.update({
is_check: FEE_RATE_LOG_STATUS.CHECK_STATUS_DELETED
}, {
where: {
id: { [ormDB.Op.in]: ids },
is_check: FEE_RATE_LOG_STATUS.CHECK_STATUS_UNCHECK
},
transaction: tx
});
}
\ No newline at end of file
import { ormDB, userInfo, userAccountChangeLog } from "@madex/ex-ts-dao";
export const existEmail = async function (email: string) {
let where = {
type: 1,//邮箱
[ormDB.Op.or]: {
account_old: email,
account_new: email
}
}
let dbInfo = await userAccountChangeLog.prototype.findOne({
where: where,
raw: true
});
return dbInfo
}
export const getProcessingEmailListByMUserId = async function (m_user_id: number) {
let where = {
type: 1,//邮箱,
user_id: m_user_id,
state: 3//状态 3 修改完成--可在7日内恢复成5
}
let dbInfoList = await userAccountChangeLog.prototype.findAll({
where: where,
raw: true
});
return dbInfoList
}
import { ormDB, userInfo, userAccountOperateLog, aclUserInfo } from "@madex/ex-ts-dao";
export const TYPE = {
//google密钥
GOOGLE_KEY: 0,
//2小时限制
TWO_HOUR_LIMIT: 1,
//24小时限制
TWENTY_FOUR_HOUR_LIMIT: 2,
//邮箱
MAIL: 3,
//最大提现额度
MAXIMUM_WITHDRAWAL_AMOUNT: 4,
//账户状态
ACCOUNT_STATUS: 5,
//能否提现修改
CAN_WITHDRAW_AND_MODIFY: 6,
//账户激活状态
ACCOUNT_ACTIVATION_STATUS: 7,
//备注
REMARK: 8,
//实名
KYC: 9
}
export const recordMUserOperateLog = async function (m_user_id: number, operate_user_id: number, operate_type: number,
comment: string, before_v: string, after_v: string) {
let aclUser = await aclUserInfo.prototype.findOne({
where: {
user_id: operate_user_id
},
raw: true
});
let operate_user_name = aclUser.account ? aclUser.account : operate_user_id;
await userAccountOperateLog.prototype.create({
user_id: m_user_id,
operate_user_id: operate_user_id,
operate_user_name: operate_user_name,
operate_type: operate_type,
operational_situation: comment,
before_value: before_v,
after_value: after_v,
createdAt: new Date(),
updatedAt: new Date()
});
}
\ No newline at end of file
import { ormDB, userInfoSon } from "@madex/ex-ts-dao";
let _ = require('lodash');
export async function getFatherUserId(user_id: number | any) {
let dbInfo = await userInfoSon.prototype.findOne({
where: {
user_id: user_id
},
raw: true
});
return dbInfo ? dbInfo.father_id : null
}
export async function getUidsByFatherUid(father_user_id: number) {
let dbInfoList = await userInfoSon.prototype.findAll({
where: {
father_id: father_user_id
},
raw: true
});
return dbInfoList.length ? dbInfoList.map(item => item.user_id) : []
}
import { ormDB, usefulLink, userMailLog, userSub } from "@madex/ex-ts-dao";
import { ErrorCode } from "../../../constant/errorCode";
import { addOptLog, LogType } from "./userOptLog.service";
import { sendEmail } from "../../../utils/mUserUtils";
import { TYPE_MAIL } from "../../../constant/statusConst";
let _ = require('lodash');
let { logger } = require('@madex/ex-js-public');
export interface UserMailLogVO {
id?: number;
user_id?: number;
is_kyc?: number;
lang?: string;
have_money?: number;
subject?: string,
content?: string,
page?: number,
size?: number
uidStr?: string
}
export async function history(page: number | undefined, size: number | undefined) {
let resList = await userMailLog.prototype.findAndCount({
limit: size,
offset: (Number(page) - 1) * Number(size),
order: [["id", "desc"]],
raw: true
});
return resList;
}
export async function mailDetail(id: number | undefined) {
let dbInfo = await userMailLog.prototype.findOne({
where: {
id: id
},
raw: true
});
if (!dbInfo) {
throw ErrorCode.DATA_NOT_EXIST;
}
return dbInfo;
}
export async function mailSend(userMailLogVO: UserMailLogVO, currentUserId: any, ip: string | undefined) {
let where = {
//TODO:0 ? 1 ???
status: 0
};
if (userMailLogVO.user_id) {
where["user_id"] = userMailLogVO.user_id
}
else {
let kyc = userMailLogVO.is_kyc;
if (kyc && (kyc == 1 || kyc == 2)) {
where["is_kyc"] = kyc
}
let haveMoney = userMailLogVO.have_money;
if (haveMoney && (haveMoney == 1 || haveMoney == 2)) {
where["have_money"] = haveMoney
}
if (userMailLogVO.lang) {
where["lang"] = userMailLogVO.lang
}
}
let toAddrRes = await userSub.prototype.findAll({
where: where,
raw: true
});
if (!toAddrRes.length) {
throw ErrorCode.DATA_NOT_EXIST
}
let params = {
subject: userMailLogVO.subject,
content: userMailLogVO.content
}
for (let sub of toAddrRes) {
//TODO:老管理后台就没有模版 ???
sendEmail(sub.sub, sub.user_id, "", params, userMailLogVO.lang);
}
let type = userMailLogVO.user_id ? TYPE_MAIL.TYPE_MAIL_LOG_SINGLE : getType(Number(userMailLogVO.is_kyc), Number(userMailLogVO.have_money));
let insertInfo = await userMailLog.prototype.create({
subject: userMailLogVO.subject,
content: userMailLogVO.content,
user_id: userMailLogVO.user_id,
type: type,
number: toAddrRes.length,
createdAt: new Date(),
updatedAt: new Date(),
});
//管理后台操作日志
addOptLog(currentUserId, `ip:${ip},发送订阅邮件:${JSON.stringify(insertInfo)}`, LogType.SUB_MAIL_SEND);
return insertInfo;
}
export async function maiSendGroup(subject: string, content: string, currentUserId: any, ip: string | undefined, uids: string[]) {
let mailLogList: any = [];
for (let uid of uids) {
let oneUid = Number(uid);
if (!oneUid) {
throw ErrorCode.UID_ILLEGALITY
}
let insertOne = {
subject: subject,
content: content,
user_id: oneUid,
type: TYPE_MAIL.TYPE_MAIL_LOG_SINGLE,
number: 1,
status: -1,
createdAt: new Date(),
updatedAt: new Date(),
}
mailLogList.push(insertOne);
}
let partList = _.chunk(mailLogList, 100);
let tx;
try {
tx = await ormDB.transaction();
for (let onePartList of partList) {
await userMailLog.prototype.bulkCreate(onePartList, {
transaction: tx
});
}
await tx.commit();
}
catch (e) {
if (tx) {
await tx.rollback();
}
logger.error(`maiSendGroup.bulkCreate.error:` + e);
}
//管理后台操作日志
addOptLog(currentUserId, `ip:${ip},群发邮件:主题:${JSON.stringify(subject)},用户:${uids}`, LogType.SUB_MAIL_SEND_GROUP);
return "success"
}
function getType(isKyc: number, haveMoney: number) {
if (haveMoney == 1 && isKyc == 1) {
return 1;
}
if (haveMoney == 1 && isKyc == 2) {
return 2;
}
if (haveMoney == 2 && isKyc == 1) {
return 3;
}
if (haveMoney == 2 && isKyc == 2) {
return 4;
}
return 5;
}
import { ormDB, userAccountChangeLog, userInfo, userProfile } from "@madex/ex-ts-dao";
import { ErrorCode } from "../../../constant/errorCode";
import { getProfileByUserIds } from "./mUserProfile.service";
import { getRealNameByUserIds, getRealNameByUserId } from "./mUserRealName.service";
import { MUserRedisKey } from "../../../constant/mUserRedisKey";
import { getMUserInfoByEmail, getMUserInfoByUid, sendEmail, updateMUserInfo } from "../../../utils/mUserUtils";
import { existEmail, getProcessingEmailListByMUserId } from "./mUserAccountChangeLog.service";
import { AFTER_MODIFIED_MAILBOX_TIP, EMAIL_FORBID_TEMPLATE } from "../../../constant/emailTemplateType";
import { addLog, MUserLogType } from "./mUserOptLog.service";
import { addOptLog, LogType } from "./userOptLog.service";
import { checkTotp } from "../../../utils/aclUserUtils";
import { getFatherUserId, getUidsByFatherUid } from "./mUserInfoSon.service";
import { recordMUserOperateLog, TYPE } from "./mUserAccountOperateLog.service";
let _ = require('lodash');
let { logger, datetimeUtils } = require('@madex/ex-js-public');
let { redisUtilsCommon, authCommon } = require('@madex/ex-js-common');
export interface QueryVO {
page?: number,
size?: number
user_id?: number | any;
kyc_status?: number | any;
lock_status?: number | any;
totp_status?: number | any;
start_date?: Date | any;
end_date?: Date | any;
email?: string | any
totp_code?: string | any
lock_type?: number | any//锁定类型 1 锁定当前账户 2 锁定当前账户及其所有子账户
}
export async function userList(queryVO: QueryVO) {
let where = Object.create(null);
if (queryVO.user_id) {
where.user_id = queryVO.user_id;
}
if (!isNaN(queryVO.kyc_status)) {
where.real_name = queryVO.kyc_status ? { [ormDB.Op.not]: null } : "";
}
if (!isNaN(queryVO.lock_status)) {
where.is_lock = queryVO.lock_status;
}
if (!isNaN(queryVO.totp_status)) {
where.totp_encrypt = queryVO.totp_status ? { [ormDB.Op.not]: null } : { [ormDB.Op.is]: null };
}
if (queryVO.start_date && queryVO.end_date) {
let from = datetimeUtils.trim(queryVO.start_date, 's');
let to = datetimeUtils.trim(queryVO.end_date, 's');
where.createdAt = { [ormDB.Op.between]: [from, to] };
}
let resList = await userInfo.prototype.findAndCount({
attributes: ['user_id', 'email', 'real_name', 'createdAt', 'totp_encrypt', 'is_lock'],
where: where,
limit: queryVO.size,
offset: (Number(queryVO.page) - 1) * Number(queryVO.size),
order: [["user_id", "asc"]],
raw: true
});
if (resList.rows.length > 0) {
let uids = resList.rows.map(item => item.user_id);
//个人资料
let profileMap = await getProfileByUserIds(uids);
//实名信息
let realNameMap = await getRealNameByUserIds(uids);
//替换rows的集合
let infoList: any = [];
for (let item of resList.rows) {
let oneProfile = profileMap[item.user_id];
let oneRealName = realNameMap[item.user_id];
let one = {
user_id: item.user_id,
nick_name: oneProfile ? (oneProfile.nick_name ? oneProfile.nick_name : "") : "",
real_name: item.real_name,
email: item.email,
register_date: item.createdAt,
spot_trade_total: 0,//TODO:现货交易总量
contract_trade_total: 0,//TODO:永续合约交易总量
spot_balance: 0,//TODO:现货余额
contract_balance: 0,//TODO:永续合约余额
assets_total: 0,//TODO: 总资产
spot_order: 0,//TODO: 现货订单数量
contract_order: 0,//TODO: 永续合约订单数量
wallet_account_balance: 0,//TODO: 钱包账户余额
trade_account_balance: 0,//TODO: 交易账户余额
kyc_status: oneRealName ? oneRealName.status : 0,//0未提交,1审核中,2审核不通过,3审核通过
kyc_type: oneRealName ? oneRealName.type : 0,//1身份证,2护照,3驾驶证
kyc_identity: oneRealName ? oneRealName.identity : 0,//证件号
is_bind_totp: item.totp_encrypt ? 1 : 0,
lock_status: item.is_lock, //0 否 1 是
}
infoList.push(one);
}
resList.rows = infoList;
}
return resList;
}
export async function oneUserDetail(m_user_id: number) {
let oneUser = await userInfo.prototype.findOne({
attributes: ['user_id', 'email', 'real_name', 'createdAt', 'totp_encrypt', 'is_lock', 'secure_modifiedAt'],
where: {
user_id: m_user_id
},
raw: true
});
if (!oneUser) {
throw ErrorCode.DATA_NOT_EXIST;
}
let oneRealName = await getRealNameByUserId(m_user_id);
let isLoginLock = await redisUtilsCommon.getSync(m_user_id + MUserRedisKey.USER_LOCK_SUFFIX);
//24小时提现限制
let dead_line = datetimeUtils.add(oneUser.secure_modifiedAt, datetimeUtils.DAY);
let is_withdraw = datetimeUtils.between(new Date(), dead_line);
let res = {
user_id: oneUser.user_id,
real_name: oneUser.real_name,
email: oneUser.email,
register_date: oneUser.createdAt,
kyc_status: oneRealName ? oneRealName.status : 0,//0未提交,1审核中,2审核不通过,3审核通过
kyc_type: oneRealName ? oneRealName.type : 0,//1身份证,2护照,3驾驶证
kyc_identity: oneRealName ? oneRealName.identity : 0,//证件号
is_bind_totp: oneUser.totp_encrypt ? 1 : 0,
lock_status: oneUser.is_lock, //0 否 1 是
login_lock: isLoginLock ? 1 : 0,//登陆锁定 0 否 1 是
withdraw_limit_24: is_withdraw > 0 ? 0 : 1,//24小时提现限制
}
return res;
}
export async function updateUserEmail(currentUserId: number, m_user_id: any, email: any, totp_code: any, ip: any) {
//校验谷歌
await checkTotp(currentUserId, totp_code);
let mUserDbInfo = await getMUserInfoByEmail(email);
if (mUserDbInfo) {
throw ErrorCode.UPDATE_EMAIL_EXIST;
}
let dnUidUserInfo = await getMUserInfoByUid(m_user_id);
if (!dnUidUserInfo) {
throw ErrorCode.USER_NOT_EXIST;
}
//检查邮箱是否存在于 userAccountChangeLog中,是则不可用
let isExist = await existEmail(email);
if (isExist) {
throw ErrorCode.EMAIL_USED_NTO_CHANGE;
}
//检查是否已经有一条待修改记录 记录新/旧邮箱
let isExistList = await getProcessingEmailListByMUserId(m_user_id);
if (isExistList.length > 0) {
throw ErrorCode.EMAIL_CHANGE_OFTEN;
}
let dbEmail = dnUidUserInfo.email;
await modifyUserEmail(m_user_id, email, dbEmail);
//踢出登陆
authCommon.delSessionIdList(m_user_id);
//新邮箱发邮件
sendEmail(email, m_user_id, EMAIL_FORBID_TEMPLATE);
//旧邮箱发送邮件
sendEmail(dbEmail, m_user_id, AFTER_MODIFIED_MAILBOX_TIP);
//记录Madex的用户自己的日志
addLog(m_user_id, MUserLogType.UP_EMAIL, ip, currentUserId, `运营修改用户邮箱为:${email}`);
//管理后台操作日志
addOptLog(currentUserId, `ip:${ip},修改用户:${m_user_id} 邮箱,原邮箱: ${dbEmail},新邮箱:${email}`, LogType.UPDATE_MUSER_EMAIL);
//管理后台操作Madex 用户的日志
recordMUserOperateLog(m_user_id, currentUserId, TYPE.MAIL, `ip:${ip},修改邮箱`, dbEmail, email);
return 'success';
}
export async function lockAccount(currentUserId: number, m_user_id: any, ip: any, lock_type: any, totp_code: any) {
//校验谷歌
await checkTotp(currentUserId, totp_code);
let dnUidUserInfo = await getMUserInfoByUid(m_user_id);
if (!dnUidUserInfo) {
throw ErrorCode.USER_NOT_EXIST;
}
let comment = "";
let fatherUserId = dnUidUserInfo.user_id;
//锁定当前用户
if (lock_type == 1) {
await updateMUserInfo(m_user_id, { is_lock: 1 });
//踢出登陆
authCommon.delSessionIdList(m_user_id);
comment = `ip:${ip},锁定用户:${fatherUserId}`;
}
else {
if (dnUidUserInfo.user_type == userInfo.USER_TYPE.SON) {
let temp = await getFatherUserId(m_user_id);
if (!temp) {
throw ErrorCode.DAD_ACCOUNT_NOT_EXIST;
}
fatherUserId = temp;
let uids = await getUidsByFatherUid(fatherUserId);
uids.push(fatherUserId);
//更新主账户及其子账户
await userInfo.prototype.update({
is_lock: 1,
updatedAt: new Date()
}, {
where: {
user_id: { [ormDB.Op.in]: uids }
}
});
//踢出登陆
for (let uid of uids) {
authCommon.delSessionIdList(uid);
}
comment = `ip:${ip},锁定用户:${uids}`;
}
}
//管理后台操作日志
addOptLog(currentUserId, comment, LogType.LOCK_MUSER);
//管理后台操作Madex 用户的日志
recordMUserOperateLog(fatherUserId, currentUserId, TYPE.ACCOUNT_STATUS, comment, "0", "1");
return 'success';
}
export async function unlockAccount(currentUserId: number, m_user_id: any, ip: any, lock_type: any, totp_code: any) {
//校验谷歌
await checkTotp(currentUserId, totp_code);
let dnUidUserInfo = await getMUserInfoByUid(m_user_id);
if (!dnUidUserInfo) {
throw ErrorCode.USER_NOT_EXIST;
}
if (Number(dnUidUserInfo.deleted_flag) > 0) {
throw ErrorCode.DEL_USER_NO_UNLOCK;
}
if (!dnUidUserInfo.is_lock) {
throw ErrorCode.USER_NOT_LOCK;
}
let comment = "";
let fatherUserId = dnUidUserInfo.user_id;
//解锁当前用户
if (lock_type == 1) {
await updateMUserInfo(m_user_id, {
is_lock: 0,
login_error_times: 0
});
comment = `ip:${ip},解锁用户:${fatherUserId}`;
}
else {
if (dnUidUserInfo.user_type == userInfo.USER_TYPE.SON) {
let temp = await getFatherUserId(m_user_id);
if (!temp) {
throw ErrorCode.DAD_ACCOUNT_NOT_EXIST;
}
fatherUserId = temp;
let uids = await getUidsByFatherUid(fatherUserId);
uids.push(fatherUserId);
//更新主账户及其子账户
await userInfo.prototype.update({
is_lock: 0,
login_error_times: 0,
updatedAt: new Date()
}, {
where: {
user_id: { [ormDB.Op.in]: uids }
}
});
comment = `ip:${ip},解锁用户:${uids}`;
}
}
//管理后台操作日志
addOptLog(currentUserId, comment, LogType.UNLOCK_MUSER);
//管理后台操作Madex 用户的日志
recordMUserOperateLog(fatherUserId, currentUserId, TYPE.ACCOUNT_STATUS, comment, "1", "0");
return 'success';
}
export async function clearLoginLimit(currentUserId: number, m_user_id: any, ip: any, totp_code: any) {
//校验谷歌
await checkTotp(currentUserId, totp_code);
await redisUtilsCommon.delSync(m_user_id + MUserRedisKey.USER_LOCK_SUFFIX);
//管理后台操作日志
addOptLog(currentUserId, `ip:${ip},清除用户登陆限制:${m_user_id}`, LogType.CLEAR_LOGIN_LIMIT);
//管理后台操作Madex 用户的日志
recordMUserOperateLog(m_user_id, currentUserId, TYPE.TWO_HOUR_LIMIT, `ip:${ip},清除用户登陆限制:${m_user_id}`, "", "");
return 'success';
}
export async function clear24WithdrawLimit(currentUserId: number, m_user_id: any, ip: any, totp_code: any) {
//校验谷歌
await checkTotp(currentUserId, totp_code);
let dnUidUserInfo = await getMUserInfoByUid(m_user_id);
if (!dnUidUserInfo) {
throw ErrorCode.USER_NOT_EXIST;
}
let date = datetimeUtils.add(new Date(), datetimeUtils.DAY * -1)
await updateMUserInfo(m_user_id, {
secure_modifiedAt: date,
});
//管理后台操作日志
addOptLog(currentUserId, `ip:${ip},清除用户24小时提现限制:${m_user_id}`, LogType.WITHDRAW_24_LIMIT);
//管理后台操作Madex 用户的日志
recordMUserOperateLog(m_user_id, currentUserId, TYPE.TWENTY_FOUR_HOUR_LIMIT, `ip:${ip},清除用户24小时提现限制:${m_user_id}`, "", "");
return 'success';
}
async function modifyUserEmail(m_user_id: number, email_new: string, email_old: string) {
let tx;
try {
tx = await ormDB.transaction();
await userAccountChangeLog.prototype.create({
user_id: m_user_id,
state: 3,
account_old: email_old,
account_new: email_new,
type: 1,
createdAt: new Date(),
updatedAt: new Date(),
finish_time: new Date(),
},
{
transaction: tx,
});
await userInfo.prototype.update({
email: email_new,
updatedAt: new Date(),
}, {
where: {
user_id: m_user_id
},
transaction: tx
});
await tx.commit();
}
catch (e) {
if (tx) {
await tx.rollback();
}
logger.error('modifyUserEmail.error:' + e)
throw e;
}
}
import { ormDB, userLog, userProfile } from "@madex/ex-ts-dao";
import { ErrorCode } from "../../../constant/errorCode";
import { getProfileByUserIds } from "./mUserProfile.service";
let _ = require('lodash');
let { logger, datetimeUtils } = require('@madex/ex-js-public');
export const MUserLogType = {
UP_EMAIL: 25,//运营修改用户邮箱
}
export interface QueryVO {
page?: number,
size?: number
user_id?: number | any;
place?: string | any;
type?: number;
start_date?: Date | any;
end_date?: Date | any;
}
export async function list(queryVO: QueryVO) {
let where = Object.create(null);
if (queryVO.user_id) {
where.user_id = queryVO.user_id;
}
if (queryVO.type) {
where.type = queryVO.type;
}
if (queryVO.start_date && queryVO.end_date) {
let from = datetimeUtils.trim(queryVO.start_date, 's');
let to = datetimeUtils.trim(queryVO.end_date, 's');
where.createdAt = { [ormDB.Op.between]: [from, to] };
}
let resList = await userLog.prototype.findAndCount({
where: where,
limit: queryVO.size,
offset: (Number(queryVO.page) - 1) * Number(queryVO.size),
order: [["id", "desc"]],
raw: true
});
if (resList.rows.length > 0) {
let uids = resList.rows.map(item => item.user_id);
let profileMap = await getProfileByUserIds(_.uniq(uids));
for (let item of resList.rows) {
let oneProfileInfo = profileMap[item.user_id];
item.nick_name = oneProfileInfo ? (oneProfileInfo.nick_name ? oneProfileInfo.nick_name : "") : "";
}
}
return resList;
}
export const addLog = async function (m_user_id: number, type: number, ip: string, operator: number, comment: string) {
userLog.prototype.create({
user_id: m_user_id,
type: type,
user_ip: ip,
device_id: operator,
comment: comment,
createdAt: new Date(),
updatedAt: new Date(),
})
}
import { ormDB, userProfile } from "@madex/ex-ts-dao";
let _ = require('lodash');
export async function getProfileByUserId(user_id: number | any) {
let dbInfo = await userProfile.prototype.findOne({
where: {
user_id: user_id
},
raw: true
});
return dbInfo ? dbInfo : null
}
export async function getProfileByUserIds(userIds: number[]) {
let dbInfoList = await userProfile.prototype.findAll({
where: {
user_id: { [ormDB.Op.in]: userIds }
},
raw: true
});
let resMap = {};
for (let item of dbInfoList) {
resMap[item.user_id] = item
}
return resMap;
}
import { ormDB, userInfo, userRealName } from "@madex/ex-ts-dao";
import { isLimitUserId, UID_MIN, UID_LIMIT } from "../../../utils/mUserCommonUtils";
import { ErrorCode } from "../../../constant/errorCode";
import * as ossUtils from "../../../utils/OSSUtils";
import { getMUserInfoByUid, sendEmail } from "../../../utils/mUserUtils";
import { EMAIL_FORBID_TEMPLATE, REAL_NAME_DENY, REAL_NAME_PASS } from "../../../constant/emailTemplateType";
import { KYC_STATUS, SETTING_FLAG } from "../../../constant/mUserInfoConst";
import { addOptLog, LogType } from "./userOptLog.service";
import { recordMUserOperateLog, TYPE } from "./mUserAccountOperateLog.service";
let { logger, } = require('@madex/ex-js-public');
let _ = require('lodash');
export interface QueryVO {
page?: number,
size?: number
id?: number | any;
user_id?: number | any;
totp_code?: string | any
status?: number | any
audit_deny?: string,
comment?: string
}
export async function getRealNameByUserId(user_id: number | any) {
let dbInfo = await userRealName.prototype.findOne({
where: {
user_id: user_id
},
raw: true
});
return dbInfo ? dbInfo : null
}
export async function getRealNameByUserIds(userIds: number[]) {
let dbInfoList = await userRealName.prototype.findAll({
where: {
user_id: { [ormDB.Op.in]: userIds }
},
raw: true
});
let resMap = {};
for (let item of dbInfoList) {
resMap[item.user_id] = item
}
return resMap;
}
export async function kycList(queryVO: QueryVO, isAdmin: boolean) {
let where = {}
if (isAdmin) {
if (queryVO.user_id) {
where["user_id"] = queryVO.user_id
}
}
else {
if (queryVO.user_id) {
//uid 是否在受限范围内
if (isLimitUserId(queryVO.user_id)) {
throw ErrorCode.UID_LIMIT
}
where["user_id"] = queryVO.user_id
}
else {
where[ormDB.Op.and] = [{
user_id: { [ormDB.Op.gte]: UID_MIN }
},
{
user_id: { [ormDB.Op.notIn]: UID_LIMIT },
}]
}
}
if (queryVO.status) {
where["status"] = queryVO.status
}
let resList = await userRealName.prototype.findAndCount({
attributes: ['id', 'user_id', 'status', 'createdAt'],
where: where,
limit: queryVO.size,
offset: (Number(queryVO.page) - 1) * Number(queryVO.size),
order: [["id", "desc"]],
raw: true
});
if (resList.rows.length) {
let uids = resList.rows.map(item => item.user_id);
let userMap = {};
let dbUserInfos = await userInfo.prototype.findAll({
attributes: ['user_id', 'email'],
where: {
user_id: { [ormDB.Op.in]: uids }
},
raw: true
});
for (let dbUserInfo of dbUserInfos) {
userMap[dbUserInfo.user_id] = dbUserInfo.email;
}
for (let item of resList.rows) {
item.email = userMap[item.user_id] ? userMap[item.user_id] : ""
}
}
return resList;
}
export async function oneDetail(id: number) {
let dbOne = await userRealName.prototype.findOne({
where: {
id: id
},
raw: true
});
if (!dbOne) {
throw ErrorCode.DATA_NOT_EXIST
}
//uid 是否在受限范围内
if (isLimitUserId(dbOne.user_id)) {
throw ErrorCode.UID_LIMIT
}
let dbUserInfo = await userInfo.prototype.findOne({
attributes: ['user_id', 'email'],
where: {
user_id: dbOne.user_id
},
raw: true
});
dbOne.email = dbUserInfo ? dbUserInfo.email : "";
await updateImageUrl(dbOne);
return dbOne;
}
export async function audit(queryVO: QueryVO, currentUserId: any, ip: string | undefined) {
let dbOne = await userRealName.prototype.findOne({
where: {
id: queryVO.id
},
raw: true
});
if (!dbOne) {
throw ErrorCode.DATA_NOT_EXIST
}
//uid 是否在受限范围内
if (isLimitUserId(dbOne.user_id)) {
throw ErrorCode.UID_LIMIT
}
if (queryVO.audit_deny && queryVO.audit_deny.length > 250) {
throw ErrorCode.REASON_TOO_LONG
}
let dbUserInfo = await getMUserInfoByUid(dbOne.user_id);
if (!dbUserInfo) {
throw ErrorCode.USER_NOT_EXIST
}
let settingFlag = dbUserInfo.setting_flag;
let dbEmail = dbUserInfo.email;
let remark = "用户实名认证审核不通过";
let template = "";
if (!queryVO.audit_deny) {
remark = "用户实名认证审核通过";
template = REAL_NAME_PASS;
if (dbOne.status == KYC_STATUS.STATUS_AUDIT_PASS) {
throw ErrorCode.DATA_STATUS_CHANGED
}
let firstName = dbOne.first_name;
let realName = dbOne.real_name;
// firstName和realName字段不为空,且是国内数据认证;并且realName中不包含firstName,则将firstName拼接到realName中。
if (firstName && realName && "cn" == dbOne.country.toLowerCase()
&& "test" != firstName && !realName.startsWith(firstName)) {
realName = firstName + realName;
}
await auditPass(dbOne.id, dbUserInfo.user_id, settingFlag, realName, currentUserId);
}
else {
template = REAL_NAME_DENY
if (dbOne.status == KYC_STATUS.STATUS_AUDIT_DENY) {
throw ErrorCode.DATA_STATUS_CHANGED
}
await auditDeny(dbOne.id, dbUserInfo.user_id, settingFlag, queryVO.audit_deny, currentUserId, queryVO.comment ? queryVO.audit_deny : "")
}
//发邮件
sendEmail(dbEmail, dbUserInfo.user_id, template);
//日志记录
//管理后台操作日志
addOptLog(currentUserId, `ip:${ip},实名认证审核:${dbUserInfo.user_id}${remark}`, LogType.KYC_AUDIT);
//管理后台操作Madex 用户的日志
recordMUserOperateLog(dbUserInfo.user_id, currentUserId, TYPE.KYC, `ip:${ip},实名认证审核:${dbUserInfo.user_id}${remark}`, "", "");
return 'success';
}
/**
* 根据图片的情况设置缩略图
* @param dbRealNameInfo
*/
async function updateImageUrl(dbRealNameInfo: any) {
let identityFrondSide = dbRealNameInfo.identity_frond_side;
if (identityFrondSide) {
if (!identityFrondSide.includes("http")) {
dbRealNameInfo.identity_frond_side_small = ossUtils.resizeWithWaterMark(identityFrondSide, "Madex", 300);
dbRealNameInfo.identity_frond_side = ossUtils.withWaterMark(identityFrondSide, "Madex");
}
else {
dbRealNameInfo.identity_frond_side_small = identityFrondSide
}
}
else {
dbRealNameInfo.identity_frond_side_small = ""
}
let identityOtherSide = dbRealNameInfo.identity_other_side;
if (identityOtherSide) {
if (!identityOtherSide.includes("http")) {
dbRealNameInfo.identity_other_side_small = ossUtils.resizeWithWaterMark(identityOtherSide, "Madex", 300);
dbRealNameInfo.identity_other_side = ossUtils.withWaterMark(identityOtherSide, "Madex");
}
else {
dbRealNameInfo.identity_other_side_small = identityOtherSide
}
}
else {
dbRealNameInfo.identity_other_side_small = ""
}
let identityInHand = dbRealNameInfo.identity_in_hand;
if (identityInHand) {
if (!identityInHand.includes("http")) {
dbRealNameInfo.identity_in_hand_small = ossUtils.resizeWithWaterMark(identityInHand, "Madex", 300);
dbRealNameInfo.identity_in_hand = ossUtils.withWaterMark(identityInHand, "Madex");
}
else {
dbRealNameInfo.identity_in_hand_small = identityInHand
}
}
else {
dbRealNameInfo.identity_in_hand_small = ""
}
let latestPhoto = dbRealNameInfo.latest_photo;
if (latestPhoto) {
if (!latestPhoto.includes("http")) {
dbRealNameInfo.latest_photo_small = ossUtils.resizeWithWaterMark(latestPhoto, "Madex", 300);
dbRealNameInfo.latest_photo = ossUtils.withWaterMark(latestPhoto, "Madex");
}
else {
dbRealNameInfo.latest_photo_small = latestPhoto
}
}
else {
dbRealNameInfo.latest_photo_small = ""
}
}
async function auditPass(id: number, m_user_id: number, setting_flag: any, real_name: string, operator: number) {
let tx;
try {
tx = await ormDB.transaction();
await userInfo.prototype.update({
real_name: real_name,
setting_flag: setting_flag | SETTING_FLAG.FLAG_REAL_NAME_AUTH,
updatedAt: new Date()
}, {
where: {
user_id: m_user_id,
setting_flag: setting_flag
},
transaction: tx,
});
await userRealName.prototype.update({
status: KYC_STATUS.STATUS_AUDIT_PASS,
auditor: operator,
updatedAt: new Date()
}, {
where: {
id: id
},
transaction: tx,
})
await tx.commit()
}
catch (e) {
logger.error("mUserRealNameService.auditPass.err:" + e);
if (tx) {
await tx.rollback();
}
throw e;
}
}
async function auditDeny(id: number, m_user_id: number, setting_flag: any, audit_deny: string, operator: number, comment: string) {
let tx;
try {
tx = await ormDB.transaction();
await userInfo.prototype.update({
real_name: "",
setting_flag: setting_flag & (~SETTING_FLAG.FLAG_REAL_NAME_AUTH),
updatedAt: new Date()
}, {
where: {
user_id: m_user_id,
setting_flag: setting_flag
},
transaction: tx,
});
await userRealName.prototype.update({
status: KYC_STATUS.STATUS_AUDIT_DENY,
auditor: operator,
auth_deny: audit_deny,
comment: comment,
updatedAt: new Date()
}, {
where: {
id: id
},
transaction: tx,
})
await tx.commit()
}
catch (e) {
logger.error("mUserRealNameService.auditDeny.err:" + e);
if (tx) {
await tx.rollback();
}
throw e;
}
}
import { ormDB, usefulLink, userSub } from "@madex/ex-ts-dao";
import { ErrorCode } from "../../../constant/errorCode";
import { addOptLog, LogType } from "./userOptLog.service";
let _ = require('lodash');
let { logger } = require('@madex/ex-js-public');
export interface QueryVO {
id?: number;
user_id?: number | any;
is_kyc?: number;
have_money?: number;
page?: number,
size?: number
}
export async function list(queryVO: QueryVO) {
let where = Object.create(null);
if (queryVO.user_id) {
where.user_id = queryVO.user_id;
}
if (queryVO.is_kyc) {
where.is_kyc = queryVO.is_kyc;
}
if (queryVO.have_money) {
where.have_money = queryVO.have_money;
}
let resList = await userSub.prototype.findAndCount({
where: where,
limit: queryVO.size,
offset: (Number(queryVO.page) - 1) * Number(queryVO.size),
order: [["createdAt", "desc"]],
raw: true
});
return resList;
}
export async function del(id: number, currentUserId: any, ip: string | undefined) {
let dbInfo = await userSub.prototype.findOne({
where: {
id: id
},
raw: true
});
if (!dbInfo) {
throw ErrorCode.DATA_NOT_EXIST;
}
await userSub.prototype.update({
status: 0,
}, {
where: {
id: Number(id)
}
});
//管理后台操作日志
addOptLog(currentUserId, `ip:${ip},删除用户订阅:${JSON.stringify(dbInfo)}`, LogType.DEL);
return 'success'
}
export async function count() {
let res = {
money_and_kyc: 0,
money_and_no_kyc: 0,
no_money_and_kyc: 0,
no_money_and_no_kyc: 0,
}
let dbInfoList = await userSub.prototype.findAll({
where: {
status: 1
},
raw: true
});
if (dbInfoList.length) {
let kycMap = _.groupBy(dbInfoList, 'is_kyc');
let throughList = kycMap["1"] ? kycMap["1"] : [];
let noThroughList = kycMap["2"] ? kycMap["2"] : [];
if (throughList.length) {
let moneyMap = _.groupBy(throughList, 'have_money');
res.money_and_kyc = moneyMap["1"] && moneyMap["1"].length ? moneyMap["1"].length : 0
res.no_money_and_kyc = moneyMap["2"] && moneyMap["2"].length ? moneyMap["2"].length : 0
}
if (noThroughList.length) {
let moneyMap = _.groupBy(noThroughList, 'have_money');
res.money_and_no_kyc = moneyMap["1"] && moneyMap["1"].length ? moneyMap["1"].length : 0
res.no_money_and_no_kyc = moneyMap["2"] && moneyMap["2"].length ? moneyMap["2"].length : 0
}
}
return res;
}
import { ormDB, usefulLink } from "@madex/ex-ts-dao";
import { ErrorCode } from "../../../constant/errorCode";
import { addOptLog, LogType } from "./userOptLog.service";
let _ = require('lodash');
let { logger } = require('@madex/ex-js-public');
export interface UsefulLinkVO {
id?: number;
name?: string | any;
url?: string | any;
type?: number | any;
weight?: number;
is_active?: number;
status?: number;
time_per_day?: number;
comment?: string | any;
createdAt?: Date | any;
updatedAt?: Date | any;
}
export interface UsefulLinkPageVO extends UsefulLinkVO {
page?: number,
size?: number
}
export async function list(usefulLinkPageVO: UsefulLinkPageVO) {
let where = Object.create(null);
if (usefulLinkPageVO.name) {
where.name = { [ormDB.Op.like]: `${usefulLinkPageVO.name}%` };
}
if (usefulLinkPageVO.url) {
where.url = { [ormDB.Op.like]: `${usefulLinkPageVO.url}%` };
}
if (usefulLinkPageVO.type) {
if (!isNaN(Number(usefulLinkPageVO.type))){
where.type = usefulLinkPageVO.type;
}else {
let typeList = usefulLinkPageVO.type.split(",");
where.type = { [ormDB.Op.in]: typeList };
}
}
if (!isNaN(Number(usefulLinkPageVO.is_active))) {
where.is_active = usefulLinkPageVO.is_active;
}
let resList = await usefulLink.prototype.findAndCount({
where: where,
limit: usefulLinkPageVO.size,
offset: (Number(usefulLinkPageVO.page) - 1) * Number(usefulLinkPageVO.size),
order: [["weight", "desc"]],
raw: true
});
return resList;
}
export async function add(usefulLinkVO: UsefulLinkVO, currentUserId: any, ip: string | undefined) {
usefulLinkVO.createdAt = new Date();
usefulLinkVO.updatedAt = new Date();
let dbInfo = await usefulLink.prototype.create(usefulLinkVO);
//日志
//管理后台操作日志
addOptLog(currentUserId, `ip:${ip},添加链接记录:${JSON.stringify(dbInfo.id)}`, LogType.ADD);
return 'success'
}
export async function update(usefulLinkVO: UsefulLinkVO, currentUserId: any, ip: string | undefined) {
let dbInfo = await usefulLink.prototype.findOne({
where: {
id: usefulLinkVO.id
},
raw: true
});
if (!dbInfo) {
throw ErrorCode.DATA_NOT_EXIST;
}
let updateInfo = {
updatedAt: new Date()
};
if (usefulLinkVO.name) {
updateInfo["name"] = usefulLinkVO.name
}
if (usefulLinkVO.url) {
updateInfo["url"] = usefulLinkVO.url;
}
if (usefulLinkVO.type) {
updateInfo["type"] = usefulLinkVO.type;
}
if (usefulLinkVO.weight) {
updateInfo["weight"] = usefulLinkVO.weight;
}
if (!isNaN(Number(usefulLinkVO.status))) {
updateInfo["status"] = usefulLinkVO.status;
}
if (!isNaN(Number(usefulLinkVO.time_per_day))) {
updateInfo["time_per_day"] = usefulLinkVO.time_per_day;
}
if (!isNaN(Number(usefulLinkVO.is_active))) {
updateInfo["is_active"] = usefulLinkVO.is_active;
}
if (usefulLinkVO.comment) {
updateInfo["comment"] = usefulLinkVO.comment;
}
await usefulLink.prototype.update(updateInfo, {
where: {
id: Number(dbInfo.id)
}
});
//管理后台操作日志
addOptLog(currentUserId, `ip:${ip},修改链接记录:原记录:${JSON.stringify(dbInfo.id)}`, LogType.UPDATE);
return 'success'
}
export async function del(id: number, currentUserId: any, ip: string | undefined) {
let dbInfo = await usefulLink.prototype.findOne({
where: {
id: id
},
raw: true
});
if (!dbInfo) {
throw ErrorCode.DATA_NOT_EXIST;
}
await usefulLink.prototype.destroy({
where: {
id: Number(id)
}
});
//管理后台操作日志
addOptLog(currentUserId, `ip:${ip},删除链接记录:${JSON.stringify(dbInfo.id)}`, LogType.DEL);
return 'success'
}
export async function detail(id: number) {
let dbInfo = await usefulLink.prototype.findOne({
where: {
id: id
},
raw: true
});
if (!dbInfo) {
throw ErrorCode.DATA_NOT_EXIST;
}
return dbInfo;
}
......@@ -11,6 +11,7 @@ import { getOneAclUserByAccount, getOneAclUserByUid } from "../../../utils/aclUs
import { RedisVal } from "../../../constant/redis-val";
import Config from "../../../../config";
import * as userOptLogService from "./userOptLog.service";
import { findByUserId } from "../service/userAuthConfig.service";
const Otplib = require('otplib');
......@@ -30,7 +31,8 @@ export const getInfo = async (currentUserId: number | any, sessionId: string) =>
ApiAssert.isFalse(ErrorCode.ACCOUNT_STOP, dbUserInfo.user_status === AclUserInfoConst.USER_STATUS.DEL);
let { roleSet, authSet } = await aclRoleAuthService.getUserAcl(dbUserInfo.user_id);
//安全项配置
let authConfigDbInfo = await findByUserId(currentUserId);
let data = {
remark: dbUserInfo.remark,
......@@ -40,6 +42,11 @@ export const getInfo = async (currentUserId: number | any, sessionId: string) =>
sessionId: sessionId,
roleSet: roleSet,
authSet: authSet,
force: authConfigDbInfo ? authConfigDbInfo.force : 0,
deadline: authConfigDbInfo ? authConfigDbInfo.deadline : null,
hasTotp: authConfigDbInfo && authConfigDbInfo.totp_encrypt ? 1 : 0,
isLocked: authConfigDbInfo ? authConfigDbInfo.is_locked : 0,
lockedTime: authConfigDbInfo ? authConfigDbInfo.locked_time : null,
}
return data
......
......@@ -12,6 +12,14 @@ export const LogType = {
DEL: 4,//删除
TOTP: 5,//谷歌
SAVE: 6,//保存(添加或修改)
UPDATE_MUSER_EMAIL: 7,//修改 Madex 用户邮箱
LOCK_MUSER: 8,//锁定用户
UNLOCK_MUSER: 9,//解锁用户
CLEAR_LOGIN_LIMIT: 10,//清除用户登陆限制
WITHDRAW_24_LIMIT: 11,//清除用户24小时限制
KYC_AUDIT: 12,//用户实名认证审核
SUB_MAIL_SEND: 13,//邮件订阅发送
SUB_MAIL_SEND_GROUP: 14,//邮件订阅群发
}
export const addOptLog = async function (user_id: any, msg: any, type: any, fail_reason?: any, session_id?: any) {
......
......@@ -20,16 +20,22 @@ import * as ReqUtils from "../../../utils/req-utils";
import * as spotPairCtrl from "../../mvc/control/spotPair.control";
import * as coinTypeCtrl from "../../mvc/control/coinType.control";
import * as noticeCtrl from "../../mvc/control/notice.control";
import * as mUserOptLogCtrl from "../../mvc/control/mUserOptLog.control";
import * as mUserManageCtrl from "../../mvc/control/mUserManage.control";
import * as mUserRealNameCtrl from "../../mvc/control/mUserRealName.control";
import * as usefulLinkCtrl from "../../mvc/control/usefulLink.control";
import * as mUserSubscribeCtrl from "../../mvc/control/mUserSubscribe.control";
import * as commonUserFeeSettingCtrl from "../../mvc/control/commonUserFeeSetting.control";
const getFunc = {
'user/info': userController.getUserInfo,
};
const postFunc = {
//国际化
'i18n/info/list': i18nCtrl.list,
'i18n/info/add': i18nCtrl.add,
'i18n/info/update': i18nCtrl.update,
'i18n/info/del': i18nCtrl.del,
'i18n/info/log/list': i18nLogCtrl.list,
'i18n/info/log/revert': i18nLogCtrl.revert,
......@@ -41,12 +47,12 @@ const postFunc = {
'coinType/list': coinTypeCtrl.list,
'coinType/spotPairCtl': coinTypeCtrl.pushToCoreSystem,
//权限管理
'acl/user/add': aclUserCtrl.add,
'acl/user/list': aclUserCtrl.list,
'acl/user/update': aclUserCtrl.update,
'acl/user/updateStatus': aclUserCtrl.updateStatus,
'acl/user/resetPwd': aclUserCtrl.resetPwd,
'acl/auth/list': aclRoleAuthCtrl.authList,
'acl/auth/tree': aclRoleAuthCtrl.getAuthTree,
'acl/auth/getByUser': aclRoleAuthCtrl.getAuthByUser,
......@@ -54,16 +60,17 @@ const postFunc = {
'acl/auth/save': aclRoleAuthCtrl.saveAuth,
'acl/auth/del': aclRoleAuthCtrl.delAuth,
//角色管理
'acl/role/list': aclRoleAuthCtrl.roleList,
'acl/role/getByUser': aclRoleAuthCtrl.getRoleByUser,
//'acl/role/getUserList':aclUserCtrl.list,
'acl/role/getAll': aclRoleAuthCtrl.getAllRole,
'acl/role/save': aclRoleAuthCtrl.saveRole,
'acl/role/del': aclRoleAuthCtrl.delRole,
'acl/changeRoleAuth': aclRoleAuthCtrl.changeRoleAuth,
'acl/changeUserRole': aclRoleAuthCtrl.changeUserRole,
//管理后台用户管理
'user/getInfo': userOptCtrl.getInfo,
'user/login': userOptCtrl.login,
'user/logout': userOptCtrl.logout,
......@@ -71,21 +78,58 @@ const postFunc = {
'user/updatePwd': userOptCtrl.updatePwd,
'user/bind/totp/ask': userOptCtrl.bindTotpAsk,
'user/bind/totp/confirm': userOptCtrl.bindTotpConfirm,
'user/auth/config/list': userAuthConfigCtrl.authConfigList,
'user/auth/change/force/status': userAuthConfigCtrl.changeForceStatus,
'user/auth/change/locked/status': userAuthConfigCtrl.changeLockedStatus,
'user/auth/reset/totp': userAuthConfigCtrl.resetTotp,
//热门交易对搜索
'hot/pair/config/list': hotPairConfigCtrl.list,
'hot/pair/config/add': hotPairConfigCtrl.add,
'hot/pair/config/update': hotPairConfigCtrl.update,
'hot/pair/config/del': hotPairConfigCtrl.del,
//消息通知
'notice/list': noticeCtrl.list,
'notice/add': noticeCtrl.add,
'notice/update': noticeCtrl.update,
//日志和审计
'mUser/opt/log/list':mUserOptLogCtrl.list,//Madex 用户操作日志列表
//Madex 用户管理
'mUser/manage/userList': mUserManageCtrl.userList,//Madex 用户管理 ->用户列表
'mUser/manage/oneUserDetail': mUserManageCtrl.oneUserDetail,//Madex 用户管理 ->单个用户详情
'mUser/manage/updateUserEmail': mUserManageCtrl.updateUserEmail,//Madex 用户管理 ->修改用户邮箱
'mUser/manage/lockAccount': mUserManageCtrl.lockAccount,//Madex 用户管理 ->锁定账户
'mUser/manage/unlockAccount': mUserManageCtrl.unlockAccount,//Madex 用户管理 ->解锁账户
'mUser/manage/clearLoginLimit': mUserManageCtrl.clearLoginLimit,//Madex 用户管理 ->清除登陆限制
'mUser/manage/clear24WithdrawLimit': mUserManageCtrl.clear24WithdrawLimit,//Madex 用户管理 ->清除24小时提现限制
'mUser/manage/kyc/list': mUserRealNameCtrl.kycList,//Madex 用户管理 ->实名认证列表
'mUser/manage/kyc/oneDetail': mUserRealNameCtrl.oneDetail,//Madex 用户管理 ->kyc详情
'mUser/manage/kyc/audit': mUserRealNameCtrl.audit,//Madex 用户管理 ->kyc审核
//资源位管理
'link/useful/list': usefulLinkCtrl.list,//链接记录列表
'link/useful/add': usefulLinkCtrl.add,//添加链接记录
'link/useful/delete': usefulLinkCtrl.del,//删除链接记录
'link/useful/update': usefulLinkCtrl.update,//修改链接记录
'link/useful/detail': usefulLinkCtrl.detail,//链接记录详情
//邮件订阅
'mUser/subscribe/list': mUserSubscribeCtrl.list,//订阅列表
'mUser/subscribe/delete': mUserSubscribeCtrl.del,//删除订阅
'mUser/subscribe/count': mUserSubscribeCtrl.count,//订阅统计
'mUser/subscribe/mail/history': mUserSubscribeCtrl.history,//发送历史
'mUser/subscribe/mail/send': mUserSubscribeCtrl.mailSend,//邮件发送
'mUser/subscribe/mail/detail': mUserSubscribeCtrl.mailDetail,//发送详情
'mUser/subscribe/mail/send/group': mUserSubscribeCtrl.maiSendGroup,//群发邮件
//普通用户手续费
'mUser/fee/setting/list': commonUserFeeSettingCtrl.list,//普通用户手续费列表
'mUser/fee/setting/add': commonUserFeeSettingCtrl.add,//新增普通用户手续费
'mUser/fee/setting/update': commonUserFeeSettingCtrl.update,//修改普通用户手续费
'mUser/fee/setting/delete': commonUserFeeSettingCtrl.del,//删除普通用户手续费
'mUser/fee/setting/submit': commonUserFeeSettingCtrl.submit,//提交普通用户手续费
};
......
......@@ -7,8 +7,8 @@ const {
} = require("@madex/ex-js-public");
let cmdWhiteList = {'i18n/info/list': 1,
let cmdWhiteList = {
'i18n/info/list': 1,
'i18n/info/add': 1,
'i18n/info/update': 1,
'i18n/info/del': 1,
......@@ -54,6 +54,35 @@ let cmdWhiteList = {'i18n/info/list': 1,
'notice/list': 1,
'notice/add': 1,
'notice/update': 1,
'mUser/opt/log/list': 1,
'mUser/manage/userList': 1,
'mUser/manage/oneUserDetail': 1,
'mUser/manage/updateUserEmail': 1,
'mUser/manage/lockAccount': 1,
'mUser/manage/unlockAccount': 1,
'mUser/manage/clearLoginLimit': 1,
'mUser/manage/clear24WithdrawLimit': 1,
'mUser/manage/kyc/list': 1,
'mUser/manage/kyc/oneDetail': 1,
'mUser/manage/kyc/audit': 1,
'link/useful/list': 1,
'link/useful/add': 1,
'link/useful/delete': 1,
'link/useful/update': 1,
'link/useful/detail': 1,
'mUser/subscribe/list': 1,
'mUser/subscribe/delete': 1,
'mUser/subscribe/count': 1,
'mUser/subscribe/mail/history': 1,
'mUser/subscribe/mail/send': 1,
'mUser/subscribe/mail/detail': 1,
'mUser/subscribe/mail/send/group': 1,
'mUser/fee/setting/list': 1,
'mUser/fee/setting/add': 1,
'mUser/fee/setting/update': 1,
'mUser/fee/setting/delete': 1,
'mUser/fee/setting/submit': 1,
};
......
let { ossUtils } = require('@madex/ex-js-common');
let { logger } = require('@madex/ex-js-public');
const sizeOf = require('image-size');
const axios = require("axios");
/**
* 获取访问链接
* @param url
*/
export const getKycImageUrl = async function (url: string) {
return await getSignatureUrl(url)
}
/**
* 获取签名后的图片链接
* @param url
* @param style
*/
async function getSignatureUrl(url: string, style?: string | any) {
let res: string | any;
let newUrl = url.replace(/^\/+/, '');
if (style) {
res = await ossUtils.getUrlResize(newUrl, style);
}
else {
res = await ossUtils.getUrl(newUrl);
}
return res;
}
export const resizeWithWaterMark = async function (url: string, text: string, font_size?: number) {
let style = await watermarkStyle(text, font_size ? font_size : 60)
return await getSignatureUrl(url, style);
}
export const getImageWidth = async function (urlStr: string) {
try {
let response = await axios({
url: urlStr,
method: 'GET',
responseType: 'arraybuffer'
});
let dimensions = sizeOf(response.data);
let width = dimensions ? dimensions.width : 0;
return width;
}
catch (e) {
logger.error("OSSUtils.getImageWidth.error:" + e);
return 0;
}
}
export const withWaterMark = async function (url: string, text: string) {
let imgUrl = await getKycImageUrl(url);
let imageWidth = await getImageWidth(imgUrl);
if (imageWidth <= 0) {
imageWidth = 1000;
}
let fontSize = (imageWidth / 5);
if (fontSize > 999) {
fontSize = 999;
}
let style = await watermarkStyle(text, fontSize);
return await getSignatureUrl(url, style);
}
export const watermarkStyle = async function (text: string, font_size?: number) {
let base64 = Buffer.from(text).toString('base64');
let textWatermark = base64.replace("+", "-").replace('/', '_').replace("=", "");
return "/watermark,text_" + textWatermark + ",g_center,x_10,y_10,t_10,fill_1,color_FFFFFF,size_" + font_size ? font_size : "";
}
import * as ReqUtils from "./req-utils";
import { ErrorCode } from "../constant/errorCode";
import { aclUserInfo } from "@madex/ex-ts-dao";
let { logger } = require("@madex/ex-js-public");
import { AclUserInfoConst } from "../constant/aclUserConstant";
import * as userAuthConfigService from "../../src/functional/mvc/service/userAuthConfig.service";
let { apiAssertUtils: ApiAssert, BigNumberUtils } = require('@madex/ex-js-public');
let { authCommon: AuthCommon, redisUtilsCommon: RedisClient, } = require('@madex/ex-js-common');
/**
* 获取当前登陆用户信息
* @param sessionId
......@@ -85,3 +89,16 @@ export const getOneAclUserByAccount = async function (account: string) {
}
return dbInfo;
}
export const checkTotp = async function (user_id: number, totp_code: string) {
//获取谷歌密钥并验证
let authInfo = await userAuthConfigService.findByUserId(user_id)
ApiAssert.isTrue(ErrorCode.UNBOUND_TOTP, authInfo && authInfo.totp_encrypt !== '');
await AuthCommon.totpCheckSync(totp_code, authInfo.totp_encrypt)
//判断是否已经使用过
let latestVerifiedKey = "bastard.totp.used.user." + user_id
let latestUsed = RedisClient.getSync(latestVerifiedKey)
ApiAssert.isFalse(ErrorCode.TOTP_CODE_USED, totp_code === latestUsed)
await RedisClient.writeSync(latestVerifiedKey, totp_code, 60 * 60)
}
\ No newline at end of file
let blockCoin = "BIX0";
export const spotCheck = async function (user_id: number) {
//TODO:后面补齐查询现货资产逻辑
let exist = {};
return exist;
}
export const baseCoinCheck = async function (user_id: number) {
//TODO:后面补齐查询币本位资产逻辑
let exist = {};
return exist;
}
export const baseUCheck = async function (user_id: number) {
//TODO:后面补齐查询U本位资产逻辑
let exist = {};
return exist;
}
\ No newline at end of file
/**
* 可操作用户最小UID
*/
export let UID_MIN = 1000;
/**
* 受限用户
*/
export let UID_LIMIT: number[] = []
/**
* uid 是否受到限制
* @param user_id
*/
export const isLimitUserId = function (user_id: number) {
return user_id <= UID_MIN || UID_LIMIT.includes(user_id);
}
\ No newline at end of file
import { userInfo } from "@madex/ex-ts-dao";
import { requestUtils, logger } from "@madex/ex-js-public";
import { config } from "@madex/ex-js-common";
import { ErrorCode } from "../constant/errorCode";
let emailServiceUrl = config.email_service_url;
export const getMUserInfoByUid = async function (m_user_id: number) {
let dbInfo = await userInfo.prototype.findOne({
where: {
user_id: m_user_id
},
raw: true
});
return dbInfo ? dbInfo : null
}
export const getMUserInfoByEmail = async function (email: string) {
let dbInfo = await userInfo.prototype.findOne({
where: {
email: email
},
raw: true
});
return dbInfo ? dbInfo : null
}
export const sendEmail = async function (email: string, m_user_id: number, template: string, params?: any, lang?: string) {
try {
let form = {
to: email,
user_id: m_user_id,
templateType: template,
params: params ? params : "{}"
};
if (lang) {
form["lang"] = lang;
}
requestUtils.doRequest(emailServiceUrl, form, () => {
});
}
catch (e) {
logger.error("mUserUtils.sendEmail.error:" + e);
}
}
export const updateMUserInfo = async function (user_id: number, updateInfo: any) {
if (!user_id || !updateInfo) {
throw ErrorCode.PARAM_MISS;
}
updateInfo.updatedAt = new Date();
await userInfo.prototype.update(updateInfo, {
where: {
user_id: user_id
}
});
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment