Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
T
ts-api-demo
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wmvm
ts-api-demo
Commits
400b5854
Commit
400b5854
authored
Aug 26, 2024
by
ml
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
日志审计、Madex用户管理相关
parent
c136b23b
Show whitespace changes
Inline
Side-by-side
Showing
24 changed files
with
1606 additions
and
59 deletions
+1606
-59
config.development.ts
config/config.development.ts
+11
-1
package-lock.json
package-lock.json
+71
-46
package.json
package.json
+2
-1
emailTemplateType.ts
src/constant/emailTemplateType.ts
+4
-0
errorCode.ts
src/constant/errorCode.ts
+14
-5
mUserInfoConst.ts
src/constant/mUserInfoConst.ts
+10
-0
mUserRedisKey.ts
src/constant/mUserRedisKey.ts
+6
-0
mUserManage.control.ts
src/functional/mvc/control/mUserManage.control.ts
+200
-0
mUserOptLog.control.ts
src/functional/mvc/control/mUserOptLog.control.ts
+24
-0
mUserRealName.control.ts
src/functional/mvc/control/mUserRealName.control.ts
+81
-0
mUserAccountChangeLog.service.ts
src/functional/mvc/service/mUserAccountChangeLog.service.ts
+31
-0
mUserAccountOperateLog.service.ts
src/functional/mvc/service/mUserAccountOperateLog.service.ts
+47
-0
mUserInfoSon.service.ts
src/functional/mvc/service/mUserInfoSon.service.ts
+28
-0
mUserManage.service.ts
src/functional/mvc/service/mUserManage.service.ts
+387
-0
mUserOptLog.service.ts
src/functional/mvc/service/mUserOptLog.service.ts
+80
-0
mUserProfile.service.ts
src/functional/mvc/service/mUserProfile.service.ts
+33
-0
mUserRealName.service.ts
src/functional/mvc/service/mUserRealName.service.ts
+364
-0
userOptLog.service.ts
src/functional/mvc/service/userOptLog.service.ts
+6
-0
index.ts
src/functional/router/v1/index.ts
+23
-4
access-limit.ts
src/setting/access-limit.ts
+13
-2
OSSUtils.ts
src/utils/OSSUtils.ts
+74
-0
aclUserUtils.ts
src/utils/aclUserUtils.ts
+17
-0
mUserCommonUtils.ts
src/utils/mUserCommonUtils.ts
+19
-0
mUserUtils.ts
src/utils/mUserUtils.ts
+61
-0
No files found.
config/config.development.ts
View file @
400b5854
// 配置文件暂时和 js 的导出方式保持一致,涉及到线上环境变量的替换等
// 配置文件暂时和 js 的导出方式保持一致,涉及到线上环境变量的替换等
module
.
exports
=
{
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
package-lock.json
View file @
400b5854
...
@@ -30,6 +30,7 @@
...
@@ -30,6 +30,7 @@
"express-swagger-generator"
:
"^1.1.17"
,
"express-swagger-generator"
:
"^1.1.17"
,
"geoip-lite"
:
"^1.4.7"
,
"geoip-lite"
:
"^1.4.7"
,
"glob"
:
"10.3.10"
,
"glob"
:
"10.3.10"
,
"image-size"
:
"1.0.2"
,
"isemail"
:
"^3.2.0"
,
"isemail"
:
"^3.2.0"
,
"jsonwebtoken"
:
"^7.4.3"
,
"jsonwebtoken"
:
"^7.4.3"
,
"lodash"
:
"^4.17.21"
,
"lodash"
:
"^4.17.21"
,
...
@@ -105,9 +106,9 @@
...
@@ -105,9 +106,9 @@
}
}
},
},
"node_modules/@babel/compat-data"
:
{
"node_modules/@babel/compat-data"
:
{
"version"
:
"7.25.
2
"
,
"version"
:
"7.25.
4
"
,
"resolved"
:
"https://packages.aliyun.com/646341b481b284e28f47a25b/npm/npm-registry/@babel/compat-data/-/compat-data-7.25.
2
.tgz"
,
"resolved"
:
"https://packages.aliyun.com/646341b481b284e28f47a25b/npm/npm-registry/@babel/compat-data/-/compat-data-7.25.
4
.tgz"
,
"integrity"
:
"sha512-
bYcppcpKBvX4znYaPEeFau03bp89ShqNMLs+rmdptMw+heSZh9+z84d2YG+K7cYLbWwzdjtDoW/uqZmPjulCl
Q=="
,
"integrity"
:
"sha512-
+LGRog6RAsCJrrrg/IO6LGmpphNe5DiK30dGjCoxxeGv49B10/3XYGxPsAwrDlMFcFEvdAUavDT8r9k/hSyQq
Q=="
,
"dev"
:
true
,
"dev"
:
true
,
"license"
:
"MIT"
,
"license"
:
"MIT"
,
"engines"
:
{
"engines"
:
{
...
@@ -163,13 +164,13 @@
...
@@ -163,13 +164,13 @@
}
}
},
},
"node_modules/@babel/generator"
:
{
"node_modules/@babel/generator"
:
{
"version"
:
"7.25.
0
"
,
"version"
:
"7.25.
5
"
,
"resolved"
:
"https://packages.aliyun.com/646341b481b284e28f47a25b/npm/npm-registry/@babel/generator/-/generator-7.25.
0
.tgz"
,
"resolved"
:
"https://packages.aliyun.com/646341b481b284e28f47a25b/npm/npm-registry/@babel/generator/-/generator-7.25.
5
.tgz"
,
"integrity"
:
"sha512-
3LEEcj3PVW8pW2R1SR1M89g/qrYk/m/mB/tLqn7dn4sbBUQyTqnlod+II2U4dqiGtUmkcnAmkMDralTFZttRi
w=="
,
"integrity"
:
"sha512-
abd43wyLfbWoxC6ahM8xTkqLpGB2iWBVyuKC9/srhFunCd1SDNrV1s72bBpK4hLj8KLzHBBcOblvLQZBNw9r3
w=="
,
"dev"
:
true
,
"dev"
:
true
,
"license"
:
"MIT"
,
"license"
:
"MIT"
,
"dependencies"
:
{
"dependencies"
:
{
"@babel/types"
:
"^7.25.
0
"
,
"@babel/types"
:
"^7.25.
4
"
,
"@jridgewell/gen-mapping"
:
"^0.3.5"
,
"@jridgewell/gen-mapping"
:
"^0.3.5"
,
"@jridgewell/trace-mapping"
:
"^0.3.25"
,
"@jridgewell/trace-mapping"
:
"^0.3.25"
,
"jsesc"
:
"^2.5.1"
"jsesc"
:
"^2.5.1"
...
@@ -391,13 +392,13 @@
...
@@ -391,13 +392,13 @@
}
}
},
},
"node_modules/@babel/parser"
:
{
"node_modules/@babel/parser"
:
{
"version"
:
"7.25.
3
"
,
"version"
:
"7.25.
4
"
,
"resolved"
:
"https://packages.aliyun.com/646341b481b284e28f47a25b/npm/npm-registry/@babel/parser/-/parser-7.25.
3
.tgz"
,
"resolved"
:
"https://packages.aliyun.com/646341b481b284e28f47a25b/npm/npm-registry/@babel/parser/-/parser-7.25.
4
.tgz"
,
"integrity"
:
"sha512-
iLTJKDbJ4hMvFPgQwwsVoxtHyWpKKPBrxkANrSYewDPaPpT5py5yeVkgPIJ7XYXhndxJpaA3PyALSXQ7u8e/Dw
=="
,
"integrity"
:
"sha512-
nq+eWrOgdtu3jG5Os4TQP3x3cLA8hR8TvJNjD8vnPa20WGycimcparWnLK4jJhElTK6SDyuJo1weMKO/5LpmLA
=="
,
"dev"
:
true
,
"dev"
:
true
,
"license"
:
"MIT"
,
"license"
:
"MIT"
,
"dependencies"
:
{
"dependencies"
:
{
"@babel/types"
:
"^7.25.
2
"
"@babel/types"
:
"^7.25.
4
"
},
},
"bin"
:
{
"bin"
:
{
"parser"
:
"bin/babel-parser.js"
"parser"
:
"bin/babel-parser.js"
...
@@ -422,17 +423,17 @@
...
@@ -422,17 +423,17 @@
}
}
},
},
"node_modules/@babel/traverse"
:
{
"node_modules/@babel/traverse"
:
{
"version"
:
"7.25.
3
"
,
"version"
:
"7.25.
4
"
,
"resolved"
:
"https://packages.aliyun.com/646341b481b284e28f47a25b/npm/npm-registry/@babel/traverse/-/traverse-7.25.
3
.tgz"
,
"resolved"
:
"https://packages.aliyun.com/646341b481b284e28f47a25b/npm/npm-registry/@babel/traverse/-/traverse-7.25.
4
.tgz"
,
"integrity"
:
"sha512-
HefgyP1x754oGCsKmV5reSmtV7IXj/kpaE1XYY+D9G5PvKKoFfSbiS4M77MdjuwlZKDIKFCffq9rPU+H/s3ZdQ
=="
,
"integrity"
:
"sha512-
VJ4XsrD+nOvlXyLzmLzUs/0qjFS4sK30te5yEFlvbbUNEgKaVb2BHZUpAL+ttLPQAHNrsI3zZisbfha5Cvr8vg
=="
,
"dev"
:
true
,
"dev"
:
true
,
"license"
:
"MIT"
,
"license"
:
"MIT"
,
"dependencies"
:
{
"dependencies"
:
{
"@babel/code-frame"
:
"^7.24.7"
,
"@babel/code-frame"
:
"^7.24.7"
,
"@babel/generator"
:
"^7.25.
0
"
,
"@babel/generator"
:
"^7.25.
4
"
,
"@babel/parser"
:
"^7.25.
3
"
,
"@babel/parser"
:
"^7.25.
4
"
,
"@babel/template"
:
"^7.25.0"
,
"@babel/template"
:
"^7.25.0"
,
"@babel/types"
:
"^7.25.
2
"
,
"@babel/types"
:
"^7.25.
4
"
,
"debug"
:
"^4.3.1"
,
"debug"
:
"^4.3.1"
,
"globals"
:
"^11.1.0"
"globals"
:
"^11.1.0"
},
},
...
@@ -451,9 +452,9 @@
...
@@ -451,9 +452,9 @@
}
}
},
},
"node_modules/@babel/types"
:
{
"node_modules/@babel/types"
:
{
"version"
:
"7.25.
2
"
,
"version"
:
"7.25.
4
"
,
"resolved"
:
"https://packages.aliyun.com/646341b481b284e28f47a25b/npm/npm-registry/@babel/types/-/types-7.25.
2
.tgz"
,
"resolved"
:
"https://packages.aliyun.com/646341b481b284e28f47a25b/npm/npm-registry/@babel/types/-/types-7.25.
4
.tgz"
,
"integrity"
:
"sha512-
YTnYtra7W9e6/oAZEHj0bJehPRUlLH9/fbpT5LfB0NhQXyALCRkRs3zH9v07IYhkgpqX6Z78FnuccZr/l4Fs4
Q=="
,
"integrity"
:
"sha512-
zQ1ijeeCXVEh+aNL0RlmkPkG8HUiDcU2pzQQFjtbntgAczRASFzj4H+6+bV+dy1ntKR14I/DypeuRG1uma98i
Q=="
,
"dev"
:
true
,
"dev"
:
true
,
"license"
:
"MIT"
,
"license"
:
"MIT"
,
"dependencies"
:
{
"dependencies"
:
{
...
@@ -874,7 +875,7 @@
...
@@ -874,7 +875,7 @@
},
},
"node_modules/@madex/ex-js-common"
:
{
"node_modules/@madex/ex-js-common"
:
{
"version"
:
"1.0.0"
,
"version"
:
"1.0.0"
,
"resolved"
:
"git+ssh://git@bitbucket.org/biiigle/ex-js-common.git#
8454d948b63c279242837dddf00a1089b6f76223
"
,
"resolved"
:
"git+ssh://git@bitbucket.org/biiigle/ex-js-common.git#
a074015198403c5598adea7e0fd4380936a5aa2b
"
,
"license"
:
"ISC"
,
"license"
:
"ISC"
,
"dependencies"
:
{
"dependencies"
:
{
"@madex/ex-js-dao"
:
"git+ssh://git@bitbucket.org/biiigle/ex-js-dao.git#master"
,
"@madex/ex-js-dao"
:
"git+ssh://git@bitbucket.org/biiigle/ex-js-dao.git#master"
,
...
@@ -940,7 +941,7 @@
...
@@ -940,7 +941,7 @@
},
},
"node_modules/@madex/ex-js-dao"
:
{
"node_modules/@madex/ex-js-dao"
:
{
"version"
:
"1.0.0"
,
"version"
:
"1.0.0"
,
"resolved"
:
"git+ssh://git@bitbucket.org/biiigle/ex-js-dao.git#
1cd641acf21ab34be602e6240ef542bda31195a2
"
,
"resolved"
:
"git+ssh://git@bitbucket.org/biiigle/ex-js-dao.git#
37d36528608cbd7affb29aa88ba022cc073495c5
"
,
"license"
:
"ISC"
,
"license"
:
"ISC"
,
"dependencies"
:
{
"dependencies"
:
{
"@madex/ex-js-public"
:
"git+ssh://git@bitbucket.org/biiigle/ex-js-public.git#master"
,
"@madex/ex-js-public"
:
"git+ssh://git@bitbucket.org/biiigle/ex-js-public.git#master"
,
...
@@ -1068,9 +1069,9 @@
...
@@ -1068,9 +1069,9 @@
}
}
},
},
"node_modules/@madex/ex-ts-dao"
:
{
"node_modules/@madex/ex-ts-dao"
:
{
"version"
:
"0.0.1
5
"
,
"version"
:
"0.0.1
9
"
,
"resolved"
:
"https://packages.aliyun.com/646341b481b284e28f47a25b/npm/npm-registry/@madex/ex-ts-dao/-/@madex/ex-ts-dao-0.0.1
5
.tgz"
,
"resolved"
:
"https://packages.aliyun.com/646341b481b284e28f47a25b/npm/npm-registry/@madex/ex-ts-dao/-/@madex/ex-ts-dao-0.0.1
9
.tgz"
,
"integrity"
:
"sha512-
O2Y/jNMOsTU7dYvgswVLgDzL3hVocD57z2KV293JlI2xJBBnclh+lYC1j1pt6FPbaSP/wo/IcITpfQhiFO6NZ
g=="
,
"integrity"
:
"sha512-
53kKxSQOXwHmf2XLooD6xU+EiD9N1wYym5B4De0CQP5NW+pu63DaDsBzQb9IC7cZ9UzYPXUDtYWlv6u10MTgu
g=="
,
"license"
:
"ISC"
,
"license"
:
"ISC"
,
"dependencies"
:
{
"dependencies"
:
{
"@madex/ex-js-public"
:
"git+ssh://git@bitbucket.org/biiigle/ex-js-public.git#master"
,
"@madex/ex-js-public"
:
"git+ssh://git@bitbucket.org/biiigle/ex-js-public.git#master"
,
...
@@ -1696,9 +1697,9 @@
...
@@ -1696,9 +1697,9 @@
"license"
:
"MIT"
"license"
:
"MIT"
},
},
"node_modules/@types/validator"
:
{
"node_modules/@types/validator"
:
{
"version"
:
"13.12.
0
"
,
"version"
:
"13.12.
1
"
,
"resolved"
:
"https://packages.aliyun.com/646341b481b284e28f47a25b/npm/npm-registry/@types/validator/-/validator-13.12.
0
.tgz"
,
"resolved"
:
"https://packages.aliyun.com/646341b481b284e28f47a25b/npm/npm-registry/@types/validator/-/validator-13.12.
1
.tgz"
,
"integrity"
:
"sha512-
nH45Lk7oPIJ1RVOF6JgFI6Dy0QpHEzq4QecZhvguxYPDwT8c93prCMqAtiIttm39voZ+DDR+qkNnMpJmMBRqag
=="
,
"integrity"
:
"sha512-
w0URwf7BQb0rD/EuiG12KP0bailHKHP5YVviJG9zw3ykAokL0TuxU2TUqMB7EwZ59bDHYdeTIvjI5m0S7qHfOA
=="
,
"dev"
:
true
,
"dev"
:
true
,
"license"
:
"MIT"
"license"
:
"MIT"
},
},
...
@@ -3321,9 +3322,9 @@
...
@@ -3321,9 +3322,9 @@
}
}
},
},
"node_modules/caniuse-lite"
:
{
"node_modules/caniuse-lite"
:
{
"version"
:
"1.0.3000165
1
"
,
"version"
:
"1.0.3000165
3
"
,
"resolved"
:
"https://packages.aliyun.com/646341b481b284e28f47a25b/npm/npm-registry/caniuse-lite/-/caniuse-lite-1.0.3000165
1
.tgz"
,
"resolved"
:
"https://packages.aliyun.com/646341b481b284e28f47a25b/npm/npm-registry/caniuse-lite/-/caniuse-lite-1.0.3000165
3
.tgz"
,
"integrity"
:
"sha512-
9Cf+Xv1jJNe1xPZLGuUXLNkE1BoDkqRqYyFJ9TDYSqhduqA4hu4oR9HluGoWYQC/aj8WHjsGVV+bwkh0+tegRg
=="
,
"integrity"
:
"sha512-
XGWQVB8wFQ2+9NZwZ10GxTYC5hk0Fa+q8cSkr0tgvMhYhMHP/QC+WTgrePMDBWiWc/pV+1ik82Al20XOK25Gcw
=="
,
"dev"
:
true
,
"dev"
:
true
,
"funding"
:
[
"funding"
:
[
{
{
...
@@ -4455,9 +4456,9 @@
...
@@ -4455,9 +4456,9 @@
}
}
},
},
"node_modules/electron-to-chromium"
:
{
"node_modules/electron-to-chromium"
:
{
"version"
:
"1.5.1
2
"
,
"version"
:
"1.5.1
3
"
,
"resolved"
:
"https://packages.aliyun.com/646341b481b284e28f47a25b/npm/npm-registry/electron-to-chromium/-/electron-to-chromium-1.5.1
2
.tgz"
,
"resolved"
:
"https://packages.aliyun.com/646341b481b284e28f47a25b/npm/npm-registry/electron-to-chromium/-/electron-to-chromium-1.5.1
3
.tgz"
,
"integrity"
:
"sha512-
tIhPkdlEoCL1Y+PToq3zRNehUaKp3wBX/sr7aclAWdIWjvqAe/Im/H0SiCM4c1Q8BLPHCdoJTol+ZblflydehA
=="
,
"integrity"
:
"sha512-
lbBcvtIJ4J6sS4tb5TLp1b4LyfCdMkwStzXPyAgVgTRAsep4bvrAGaBOP7ZJtQMNJpSQ9SqG4brWOroNaQtm7Q
=="
,
"dev"
:
true
,
"dev"
:
true
,
"license"
:
"ISC"
"license"
:
"ISC"
},
},
...
@@ -5015,9 +5016,9 @@
...
@@ -5015,9 +5016,9 @@
}
}
},
},
"node_modules/eslint-module-utils"
:
{
"node_modules/eslint-module-utils"
:
{
"version"
:
"2.8.
1
"
,
"version"
:
"2.8.
2
"
,
"resolved"
:
"https://packages.aliyun.com/646341b481b284e28f47a25b/npm/npm-registry/eslint-module-utils/-/eslint-module-utils-2.8.
1
.tgz"
,
"resolved"
:
"https://packages.aliyun.com/646341b481b284e28f47a25b/npm/npm-registry/eslint-module-utils/-/eslint-module-utils-2.8.
2
.tgz"
,
"integrity"
:
"sha512-
rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q
=="
,
"integrity"
:
"sha512-
3XnC5fDyc8M4J2E8pt8pmSVRX2M+5yWMCfI/kDZwauQeFgzQOuhcRBFKjTeJagqgk4sFKxe1mvNVnaWwImx/Tg
=="
,
"dev"
:
true
,
"dev"
:
true
,
"license"
:
"MIT"
,
"license"
:
"MIT"
,
"dependencies"
:
{
"dependencies"
:
{
...
@@ -6975,6 +6976,21 @@
...
@@ -6975,6 +6976,21 @@
"node"
:
">= 4"
"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"
:
{
"node_modules/imageinfo"
:
{
"version"
:
"1.0.4"
,
"version"
:
"1.0.4"
,
"resolved"
:
"https://packages.aliyun.com/646341b481b284e28f47a25b/npm/npm-registry/imageinfo/-/imageinfo-1.0.4.tgz"
,
"resolved"
:
"https://packages.aliyun.com/646341b481b284e28f47a25b/npm/npm-registry/imageinfo/-/imageinfo-1.0.4.tgz"
,
...
@@ -7279,9 +7295,9 @@
...
@@ -7279,9 +7295,9 @@
"license"
:
"MIT"
"license"
:
"MIT"
},
},
"node_modules/is-core-module"
:
{
"node_modules/is-core-module"
:
{
"version"
:
"2.15.
0
"
,
"version"
:
"2.15.
1
"
,
"resolved"
:
"https://packages.aliyun.com/646341b481b284e28f47a25b/npm/npm-registry/is-core-module/-/is-core-module-2.15.
0
.tgz"
,
"resolved"
:
"https://packages.aliyun.com/646341b481b284e28f47a25b/npm/npm-registry/is-core-module/-/is-core-module-2.15.
1
.tgz"
,
"integrity"
:
"sha512-
Dd+Lb2/zvk9SKy1TGCt1wFJFo/MWBPMX5x7KcvLajWTGuomczdQX61PvY5yK6SVACwpoexWo81IfFyoKY2QnTA
=="
,
"integrity"
:
"sha512-
z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ
=="
,
"dev"
:
true
,
"dev"
:
true
,
"license"
:
"MIT"
,
"license"
:
"MIT"
,
"dependencies"
:
{
"dependencies"
:
{
...
@@ -9448,9 +9464,9 @@
...
@@ -9448,9 +9464,9 @@
}
}
},
},
"node_modules/micromatch"
:
{
"node_modules/micromatch"
:
{
"version"
:
"4.0.
7
"
,
"version"
:
"4.0.
8
"
,
"resolved"
:
"https://packages.aliyun.com/646341b481b284e28f47a25b/npm/npm-registry/micromatch/-/micromatch-4.0.
7
.tgz"
,
"resolved"
:
"https://packages.aliyun.com/646341b481b284e28f47a25b/npm/npm-registry/micromatch/-/micromatch-4.0.
8
.tgz"
,
"integrity"
:
"sha512-
LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q
=="
,
"integrity"
:
"sha512-
PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA
=="
,
"dev"
:
true
,
"dev"
:
true
,
"license"
:
"MIT"
,
"license"
:
"MIT"
,
"dependencies"
:
{
"dependencies"
:
{
...
@@ -11469,6 +11485,15 @@
...
@@ -11469,6 +11485,15 @@
"license"
:
"MIT"
,
"license"
:
"MIT"
,
"optional"
:
true
"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"
:
{
"node_modules/queue-microtask"
:
{
"version"
:
"1.2.3"
,
"version"
:
"1.2.3"
,
"resolved"
:
"https://packages.aliyun.com/646341b481b284e28f47a25b/npm/npm-registry/queue-microtask/-/queue-microtask-1.2.3.tgz"
,
"resolved"
:
"https://packages.aliyun.com/646341b481b284e28f47a25b/npm/npm-registry/queue-microtask/-/queue-microtask-1.2.3.tgz"
,
...
@@ -13773,9 +13798,9 @@
...
@@ -13773,9 +13798,9 @@
}
}
},
},
"node_modules/tslib"
:
{
"node_modules/tslib"
:
{
"version"
:
"2.
6.3
"
,
"version"
:
"2.
7.0
"
,
"resolved"
:
"https://packages.aliyun.com/646341b481b284e28f47a25b/npm/npm-registry/tslib/-/tslib-2.
6.3
.tgz"
,
"resolved"
:
"https://packages.aliyun.com/646341b481b284e28f47a25b/npm/npm-registry/tslib/-/tslib-2.
7.0
.tgz"
,
"integrity"
:
"sha512-
xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ
=="
,
"integrity"
:
"sha512-
gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA
=="
,
"license"
:
"0BSD"
"license"
:
"0BSD"
},
},
"node_modules/tsscmp"
:
{
"node_modules/tsscmp"
:
{
...
...
package.json
View file @
400b5854
...
@@ -76,6 +76,7 @@
...
@@ -76,6 +76,7 @@
"
sequelize
"
:
"^4.44.4"
,
"
sequelize
"
:
"^4.44.4"
,
"
should
"
:
"^12.0.0"
,
"
should
"
:
"^12.0.0"
,
"
tunnel
"
:
"^0.0.6"
,
"
tunnel
"
:
"^0.0.6"
,
"
uuid
"
:
"9.0.1"
"
uuid
"
:
"9.0.1"
,
"
image-size
"
:
"1.0.2"
}
}
}
}
src/constant/emailTemplateType.ts
0 → 100644
View file @
400b5854
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
src/constant/errorCode.ts
View file @
400b5854
export
const
ErrorCode
=
{
export
const
ErrorCode
=
{
PARAM_MISS
:
'30000'
,
//请求参数错误
PARAM_MISS
:
'30000'
,
//请求参数错误
DATA_NOT_EXIST
:
'30001'
,
//数据不存在
DATA_NOT_EXIST
:
'30001'
,
//数据不存在
DATA_EXIST
:
'30002'
,
//数据已存在
DATA_EXIST
:
'30002'
,
//数据已存在
NOT_LOGIN
:
'30003'
,
//账号未登录
NOT_LOGIN
:
'30003'
,
//账号未登录
NO_PERMISSION
:
'30004'
,
//账号没有权限
NO_PERMISSION
:
'30004'
,
//账号没有权限
USER_EXIST
:
'30005'
,
//用户已存在
USER_EXIST
:
'30005'
,
//用户已存在
...
@@ -24,6 +24,15 @@ export const ErrorCode = {
...
@@ -24,6 +24,15 @@ export const ErrorCode = {
TOTP_KEY_OVERSTAYED
:
'30022'
,
//密钥已失效,请重新获取
TOTP_KEY_OVERSTAYED
:
'30022'
,
//密钥已失效,请重新获取
USER_TYPE_ILLEGAL
:
'30023'
,
//用户类型不合法
USER_TYPE_ILLEGAL
:
'30023'
,
//用户类型不合法
NEED_INPUT_GOOGLE_CODE
:
'30024'
,
//请输入Google验证码
NEED_INPUT_GOOGLE_CODE
:
'30024'
,
//请输入Google验证码
PUSH_NOT_UPDATE
:
'30025'
,
//已经推送不允许修改
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'
,
//非法操作,数据状态已经变更
}
}
src/constant/mUserInfoConst.ts
0 → 100644
View file @
400b5854
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
src/constant/mUserRedisKey.ts
0 → 100644
View file @
400b5854
export
const
MUserRedisKey
=
{
//登陆限制
USER_LOCK_SUFFIX
:
".login_lock"
}
\ No newline at end of file
src/functional/mvc/control/mUserManage.control.ts
0 → 100644
View file @
400b5854
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
);
}
};
src/functional/mvc/control/mUserOptLog.control.ts
0 → 100644
View file @
400b5854
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
);
}
};
src/functional/mvc/control/mUserRealName.control.ts
0 → 100644
View file @
400b5854
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
);
}
};
src/functional/mvc/service/mUserAccountChangeLog.service.ts
0 → 100644
View file @
400b5854
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
}
src/functional/mvc/service/mUserAccountOperateLog.service.ts
0 → 100644
View file @
400b5854
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
recordOperateLog
=
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
}
});
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
src/functional/mvc/service/mUserInfoSon.service.ts
0 → 100644
View file @
400b5854
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
)
:
[]
}
src/functional/mvc/service/mUserManage.service.ts
0 → 100644
View file @
400b5854
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
{
recordOperateLog
,
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 用户的日志
recordOperateLog
(
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 用户的日志
recordOperateLog
(
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 用户的日志
recordOperateLog
(
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 用户的日志
recordOperateLog
(
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 用户的日志
recordOperateLog
(
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
;
}
}
src/functional/mvc/service/mUserOptLog.service.ts
0 → 100644
View file @
400b5854
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
(),
})
}
src/functional/mvc/service/mUserProfile.service.ts
0 → 100644
View file @
400b5854
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
;
}
src/functional/mvc/service/mUserRealName.service.ts
0 → 100644
View file @
400b5854
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
{
recordOperateLog
,
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
}
}
});
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
}
});
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 用户的日志
recordOperateLog
(
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
;
}
}
src/functional/mvc/service/userOptLog.service.ts
View file @
400b5854
...
@@ -12,6 +12,12 @@ export const LogType = {
...
@@ -12,6 +12,12 @@ export const LogType = {
DEL
:
4
,
//删除
DEL
:
4
,
//删除
TOTP
:
5
,
//谷歌
TOTP
:
5
,
//谷歌
SAVE
:
6
,
//保存(添加或修改)
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
,
//用户实名认证审核
}
}
export
const
addOptLog
=
async
function
(
user_id
:
any
,
msg
:
any
,
type
:
any
,
fail_reason
?:
any
,
session_id
?:
any
)
{
export
const
addOptLog
=
async
function
(
user_id
:
any
,
msg
:
any
,
type
:
any
,
fail_reason
?:
any
,
session_id
?:
any
)
{
...
...
src/functional/router/v1/index.ts
View file @
400b5854
...
@@ -20,16 +20,19 @@ import * as ReqUtils from "../../../utils/req-utils";
...
@@ -20,16 +20,19 @@ import * as ReqUtils from "../../../utils/req-utils";
import
*
as
spotPairCtrl
from
"../../mvc/control/spotPair.control"
;
import
*
as
spotPairCtrl
from
"../../mvc/control/spotPair.control"
;
import
*
as
coinTypeCtrl
from
"../../mvc/control/coinType.control"
;
import
*
as
coinTypeCtrl
from
"../../mvc/control/coinType.control"
;
import
*
as
noticeCtrl
from
"../../mvc/control/notice.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"
;
const
getFunc
=
{
const
getFunc
=
{
'user/info'
:
userController
.
getUserInfo
,
'user/info'
:
userController
.
getUserInfo
,
};
};
const
postFunc
=
{
const
postFunc
=
{
//国际化
'i18n/info/list'
:
i18nCtrl
.
list
,
'i18n/info/list'
:
i18nCtrl
.
list
,
'i18n/info/add'
:
i18nCtrl
.
add
,
'i18n/info/add'
:
i18nCtrl
.
add
,
'i18n/info/update'
:
i18nCtrl
.
update
,
'i18n/info/update'
:
i18nCtrl
.
update
,
'i18n/info/del'
:
i18nCtrl
.
del
,
'i18n/info/del'
:
i18nCtrl
.
del
,
'i18n/info/log/list'
:
i18nLogCtrl
.
list
,
'i18n/info/log/list'
:
i18nLogCtrl
.
list
,
'i18n/info/log/revert'
:
i18nLogCtrl
.
revert
,
'i18n/info/log/revert'
:
i18nLogCtrl
.
revert
,
...
@@ -38,12 +41,12 @@ const postFunc = {
...
@@ -38,12 +41,12 @@ const postFunc = {
'coinType/add'
:
coinTypeCtrl
.
add
,
'coinType/add'
:
coinTypeCtrl
.
add
,
'coinType/list'
:
coinTypeCtrl
.
list
,
'coinType/list'
:
coinTypeCtrl
.
list
,
//权限管理
'acl/user/add'
:
aclUserCtrl
.
add
,
'acl/user/add'
:
aclUserCtrl
.
add
,
'acl/user/list'
:
aclUserCtrl
.
list
,
'acl/user/list'
:
aclUserCtrl
.
list
,
'acl/user/update'
:
aclUserCtrl
.
update
,
'acl/user/update'
:
aclUserCtrl
.
update
,
'acl/user/updateStatus'
:
aclUserCtrl
.
updateStatus
,
'acl/user/updateStatus'
:
aclUserCtrl
.
updateStatus
,
'acl/user/resetPwd'
:
aclUserCtrl
.
resetPwd
,
'acl/user/resetPwd'
:
aclUserCtrl
.
resetPwd
,
'acl/auth/list'
:
aclRoleAuthCtrl
.
authList
,
'acl/auth/list'
:
aclRoleAuthCtrl
.
authList
,
'acl/auth/tree'
:
aclRoleAuthCtrl
.
getAuthTree
,
'acl/auth/tree'
:
aclRoleAuthCtrl
.
getAuthTree
,
'acl/auth/getByUser'
:
aclRoleAuthCtrl
.
getAuthByUser
,
'acl/auth/getByUser'
:
aclRoleAuthCtrl
.
getAuthByUser
,
...
@@ -51,16 +54,17 @@ const postFunc = {
...
@@ -51,16 +54,17 @@ const postFunc = {
'acl/auth/save'
:
aclRoleAuthCtrl
.
saveAuth
,
'acl/auth/save'
:
aclRoleAuthCtrl
.
saveAuth
,
'acl/auth/del'
:
aclRoleAuthCtrl
.
delAuth
,
'acl/auth/del'
:
aclRoleAuthCtrl
.
delAuth
,
//角色管理
'acl/role/list'
:
aclRoleAuthCtrl
.
roleList
,
'acl/role/list'
:
aclRoleAuthCtrl
.
roleList
,
'acl/role/getByUser'
:
aclRoleAuthCtrl
.
getRoleByUser
,
'acl/role/getByUser'
:
aclRoleAuthCtrl
.
getRoleByUser
,
//'acl/role/getUserList':aclUserCtrl.list,
//'acl/role/getUserList':aclUserCtrl.list,
'acl/role/getAll'
:
aclRoleAuthCtrl
.
getAllRole
,
'acl/role/getAll'
:
aclRoleAuthCtrl
.
getAllRole
,
'acl/role/save'
:
aclRoleAuthCtrl
.
saveRole
,
'acl/role/save'
:
aclRoleAuthCtrl
.
saveRole
,
'acl/role/del'
:
aclRoleAuthCtrl
.
delRole
,
'acl/role/del'
:
aclRoleAuthCtrl
.
delRole
,
'acl/changeRoleAuth'
:
aclRoleAuthCtrl
.
changeRoleAuth
,
'acl/changeRoleAuth'
:
aclRoleAuthCtrl
.
changeRoleAuth
,
'acl/changeUserRole'
:
aclRoleAuthCtrl
.
changeUserRole
,
'acl/changeUserRole'
:
aclRoleAuthCtrl
.
changeUserRole
,
//管理后台用户管理
'user/getInfo'
:
userOptCtrl
.
getInfo
,
'user/getInfo'
:
userOptCtrl
.
getInfo
,
'user/login'
:
userOptCtrl
.
login
,
'user/login'
:
userOptCtrl
.
login
,
'user/logout'
:
userOptCtrl
.
logout
,
'user/logout'
:
userOptCtrl
.
logout
,
...
@@ -68,21 +72,36 @@ const postFunc = {
...
@@ -68,21 +72,36 @@ const postFunc = {
'user/updatePwd'
:
userOptCtrl
.
updatePwd
,
'user/updatePwd'
:
userOptCtrl
.
updatePwd
,
'user/bind/totp/ask'
:
userOptCtrl
.
bindTotpAsk
,
'user/bind/totp/ask'
:
userOptCtrl
.
bindTotpAsk
,
'user/bind/totp/confirm'
:
userOptCtrl
.
bindTotpConfirm
,
'user/bind/totp/confirm'
:
userOptCtrl
.
bindTotpConfirm
,
'user/auth/config/list'
:
userAuthConfigCtrl
.
authConfigList
,
'user/auth/config/list'
:
userAuthConfigCtrl
.
authConfigList
,
'user/auth/change/force/status'
:
userAuthConfigCtrl
.
changeForceStatus
,
'user/auth/change/force/status'
:
userAuthConfigCtrl
.
changeForceStatus
,
'user/auth/change/locked/status'
:
userAuthConfigCtrl
.
changeLockedStatus
,
'user/auth/change/locked/status'
:
userAuthConfigCtrl
.
changeLockedStatus
,
'user/auth/reset/totp'
:
userAuthConfigCtrl
.
resetTotp
,
'user/auth/reset/totp'
:
userAuthConfigCtrl
.
resetTotp
,
//热门交易对搜索
'hot/pair/config/list'
:
hotPairConfigCtrl
.
list
,
'hot/pair/config/list'
:
hotPairConfigCtrl
.
list
,
'hot/pair/config/add'
:
hotPairConfigCtrl
.
add
,
'hot/pair/config/add'
:
hotPairConfigCtrl
.
add
,
'hot/pair/config/update'
:
hotPairConfigCtrl
.
update
,
'hot/pair/config/update'
:
hotPairConfigCtrl
.
update
,
'hot/pair/config/del'
:
hotPairConfigCtrl
.
del
,
'hot/pair/config/del'
:
hotPairConfigCtrl
.
del
,
//消息通知
'notice/list'
:
noticeCtrl
.
list
,
'notice/list'
:
noticeCtrl
.
list
,
'notice/add'
:
noticeCtrl
.
add
,
'notice/add'
:
noticeCtrl
.
add
,
'notice/update'
:
noticeCtrl
.
update
,
'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审核
};
};
...
...
src/setting/access-limit.ts
View file @
400b5854
...
@@ -7,8 +7,8 @@ const {
...
@@ -7,8 +7,8 @@ const {
}
=
require
(
"@madex/ex-js-public"
);
}
=
require
(
"@madex/ex-js-public"
);
let
cmdWhiteList
=
{
let
cmdWhiteList
=
{
'i18n/info/list'
:
1
,
'i18n/info/list'
:
1
,
'i18n/info/add'
:
1
,
'i18n/info/add'
:
1
,
'i18n/info/update'
:
1
,
'i18n/info/update'
:
1
,
'i18n/info/del'
:
1
,
'i18n/info/del'
:
1
,
...
@@ -54,6 +54,17 @@ let cmdWhiteList = {'i18n/info/list': 1,
...
@@ -54,6 +54,17 @@ let cmdWhiteList = {'i18n/info/list': 1,
'notice/list'
:
1
,
'notice/list'
:
1
,
'notice/add'
:
1
,
'notice/add'
:
1
,
'notice/update'
:
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
,
};
};
...
...
src/utils/OSSUtils.ts
0 → 100644
View file @
400b5854
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
:
""
;
}
src/utils/aclUserUtils.ts
View file @
400b5854
import
*
as
ReqUtils
from
"./req-utils"
;
import
*
as
ReqUtils
from
"./req-utils"
;
import
{
ErrorCode
}
from
"../constant/errorCode"
;
import
{
ErrorCode
}
from
"../constant/errorCode"
;
import
{
aclUserInfo
}
from
"@madex/ex-ts-dao"
;
import
{
aclUserInfo
}
from
"@madex/ex-ts-dao"
;
let
{
logger
}
=
require
(
"@madex/ex-js-public"
);
let
{
logger
}
=
require
(
"@madex/ex-js-public"
);
import
{
AclUserInfoConst
}
from
"../constant/aclUserConstant"
;
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
* @param sessionId
...
@@ -85,3 +89,16 @@ export const getOneAclUserByAccount = async function (account: string) {
...
@@ -85,3 +89,16 @@ export const getOneAclUserByAccount = async function (account: string) {
}
}
return
dbInfo
;
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
src/utils/mUserCommonUtils.ts
0 → 100644
View file @
400b5854
/**
* 可操作用户最小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
src/utils/mUserUtils.ts
0 → 100644
View file @
400b5854
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
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment