Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
A
Automat
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
1
Merge Requests
1
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
冯佳佳
Automat
Commits
60911711
Commit
60911711
authored
Jan 17, 2022
by
Aeolus
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
update
parent
c54a7e91
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
283 additions
and
131 deletions
+283
-131
config/commen_config.py
+7
-9
models/models.py
+23
-1
myapps/pc_management/api/__init__.py
+2
-0
myapps/pc_management/api/admin_portal.py
+19
-47
myapps/pc_management/api/business_portal.py
+123
-0
myapps/pc_management/api/hatch_portal.py
+2
-1
myapps/pc_management/api/production_portal.py
+2
-2
service/admin_service.py
+87
-67
utils/error_code.py
+2
-2
utils/jwt_util.py
+2
-2
utils/mytools.py
+14
-0
No files found.
config/commen_config.py
View file @
60911711
...
...
@@ -43,15 +43,13 @@ LOGIN_TYPE = {
AGENT_STATUS
=
{
'1'
:
'超级管理员'
,
'2'
:
'出库员'
,
'3'
:
'渠道经理'
,
'4'
:
'财务'
,
'5'
:
'运维管理员'
,
'6'
:
'推销员'
,
'7'
:
'介绍人'
,
'8'
:
'合伙人'
,
'9'
:
'补货员'
,
'10'
:
'场所'
,
'2'
:
'管理员'
,
'3'
:
'业务员'
,
'4'
:
'代理商'
,
'5'
:
'财务'
,
'6'
:
'运维管理员'
,
'7'
:
'补货员'
,
'8'
:
'客服'
,
}
ACCOUNT_STATUS
=
{
...
...
models/models.py
View file @
60911711
...
...
@@ -49,6 +49,18 @@ class AdminBrand(Base):
updated_at
=
Column
(
DateTime
,
nullable
=
False
,
server_default
=
text
(
"CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP"
))
class
AdminBusiness
(
Base
):
__tablename__
=
'admin_business'
id
=
Column
(
INTEGER
(
11
),
primary_key
=
True
)
user_id
=
Column
(
INTEGER
(
11
),
nullable
=
False
)
user_no
=
Column
(
String
(
25
,
'utf8mb4_unicode_ci'
),
nullable
=
False
)
business_id
=
Column
(
INTEGER
(
11
),
nullable
=
False
)
status
=
Column
(
INTEGER
(
1
),
nullable
=
False
,
server_default
=
text
(
"'1'"
))
created_at
=
Column
(
DateTime
,
nullable
=
False
,
server_default
=
text
(
"CURRENT_TIMESTAMP"
))
updated_at
=
Column
(
DateTime
,
nullable
=
False
,
server_default
=
text
(
"CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP"
))
class
AdminLoginRecord
(
Base
):
__tablename__
=
'admin_login_record'
...
...
@@ -68,7 +80,7 @@ class AdminMachine(Base):
id
=
Column
(
INTEGER
(
11
),
primary_key
=
True
)
user_id
=
Column
(
INTEGER
(
11
),
nullable
=
False
)
user_no
=
Column
(
String
(
25
,
'utf8mb4_unicode_ci'
),
nullable
=
False
)
machine_no
=
Column
(
INTEGER
(
11
),
nullable
=
False
)
machine_no
=
Column
(
String
(
40
,
'utf8mb4_unicode_ci'
),
nullable
=
False
)
status
=
Column
(
INTEGER
(
1
),
default
=
1
,
nullable
=
False
)
created_at
=
Column
(
DateTime
,
nullable
=
False
,
server_default
=
text
(
"CURRENT_TIMESTAMP"
))
updated_at
=
Column
(
DateTime
,
nullable
=
False
,
server_default
=
text
(
"CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP"
))
...
...
@@ -121,6 +133,16 @@ class Brand(Base):
updated_at
=
Column
(
TIMESTAMP
,
server_default
=
text
(
"CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP"
))
class
Business
(
Base
):
__tablename__
=
'business'
id
=
Column
(
INTEGER
(
10
),
primary_key
=
True
)
business_name
=
Column
(
VARCHAR
(
191
),
nullable
=
False
,
index
=
True
,
comment
=
'品牌名'
)
status
=
Column
(
TINYINT
(
1
),
default
=
text
(
"'1'"
),
comment
=
'状态: 1正常-1删除'
)
created_at
=
Column
(
TIMESTAMP
,
server_default
=
text
(
"CURRENT_TIMESTAMP"
))
updated_at
=
Column
(
TIMESTAMP
,
server_default
=
text
(
"CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP"
))
class
Hatch
(
Base
):
__tablename__
=
'hatch'
__table_args__
=
(
...
...
myapps/pc_management/api/__init__.py
View file @
60911711
...
...
@@ -17,6 +17,7 @@ from myapps.pc_management.api.machine_portal import machine_route
from
myapps.pc_management.api.file_protal
import
file_route
from
myapps.pc_management.api.production_portal
import
production_route
from
myapps.pc_management.api.hatch_portal
import
hatch_route
from
myapps.pc_management.api.business_portal
import
business_route
def
register_sukang_blueprint
(
app
:
Flask
):
...
...
@@ -27,3 +28,4 @@ def register_sukang_blueprint(app: Flask):
app
.
register_blueprint
(
file_route
,
url_prefix
=
prefix
+
"/file"
)
app
.
register_blueprint
(
production_route
,
url_prefix
=
prefix
+
"/production"
)
app
.
register_blueprint
(
hatch_route
,
url_prefix
=
prefix
+
"/hatch"
)
app
.
register_blueprint
(
business_route
,
url_prefix
=
prefix
+
"/business"
)
myapps/pc_management/api/admin_portal.py
View file @
60911711
...
...
@@ -13,11 +13,12 @@ from utils.error_code import ACCOUNT_AGENT_SPOT_NULL_ERROR, ACCOUNT_NOT_EXISTS_E
OPERATE_LEVEL_ERROR
,
Param_Invalid_Error
,
COMMON_MONGO_ERROR
from
utils.error_code
import
PHONE_NOT_NULL_ERROR
,
PHONE_NOT_VALID_ERROR
,
TOKEN_NOT_VALID_ERROR
,
\
VERIFICATION_CODE_INVALID_ERROR
,
VERIFICATION_CODE_ERROR
,
PASSWORD_ERROR
from
models.base_model
import
db
from
models.models
import
AdminAccount
,
AdminLoginRecord
,
AdminMachine
,
AdminPlace
,
Place
from
models.base_model
import
db
,
Base
from
models.models
import
AdminAccount
,
AdminLoginRecord
,
AdminMachine
,
AdminPlace
,
Place
,
Business
,
AdminBusiness
from
utils.jwt_util
import
verify_jwt
,
generate_jwt
from
utils.my_response
import
BaseResponse
from
service.sms_service
import
SMSService
from
utils.mytools
import
json2obj
logger
=
logging
.
getLogger
(
__name__
)
...
...
@@ -141,6 +142,10 @@ def add_user():
db
.
session
.
add
(
account
)
db
.
session
.
commit
()
business_ids
=
json_data
.
get
(
"business_ids"
,
[])
if
business_ids
:
AdminService
.
add_or_edit_admin_business
(
account
,
business_ids
)
return
BaseResponse
()
...
...
@@ -151,45 +156,9 @@ def get_account_list():
page_size
=
json_data
.
get
(
"pageSize"
,
None
)
keyword
=
json_data
.
get
(
"keyword"
,
None
)
select_sql
=
"""select admin_account.user_name, admin_account.phone, admin_account.level, admin_account.status,
admin_account.comment,admin_account.parent_id,admin_account.rate, admin_account.created_at,
admin_account.updated_at,admin_account.id, admin_account.user_no
"""
count_sql
=
"select count(admin_account.id) as total_count"
from_sql
=
" from admin_account where admin_account.id in ( select admin_account.id "
from_sql
+=
" from admin_account "
where_sql
=
" where 0=0 and admin_account.level > {} and admin_account.parent_id = {}"
.
format
(
g
.
user
.
level
,
g
.
user
.
id
)
if
keyword
:
where_sql
+=
"""
and CONCAT(admin_account.user_name,admin_account.phone, admin_account.user_no) LIKE '
%
{keyword}
%
'
"""
.
format
(
keyword
=
keyword
)
where_sql
+=
" ) "
order_sql
=
" ORDER BY admin_account.id ASC, admin_account.status ASC"
limit_sql
=
" LIMIT {offset} , {page_size} "
.
format
(
offset
=
(
page
-
1
)
*
page_size
,
page_size
=
page_size
)
count_result
=
db
.
session
.
execute
(
count_sql
+
from_sql
+
where_sql
)
.
fetchone
()
if
not
count_result
:
return
BaseResponse
(
data
=
{
"list"
:
[],
"page"
:
page
,
"pageSize"
:
page_size
,
"total_count"
:
0
})
else
:
total_count
=
count_result
.
total_count
print
(
select_sql
+
from_sql
+
where_sql
+
order_sql
+
limit_sql
)
result
=
db
.
session
.
execute
(
select_sql
+
from_sql
+
where_sql
+
order_sql
+
limit_sql
)
.
fetchall
()
return_data
=
[]
for
info
in
result
:
return_data
.
append
(
{
"user_name"
:
info
.
user_name
,
"phone"
:
info
.
phone
,
"level"
:
info
.
level
,
"status"
:
info
.
status
,
"comment"
:
info
.
comment
,
"user_id"
:
info
.
id
,
"user_no"
:
info
.
user_no
,
"create_time"
:
info
.
created_at
.
strftime
(
"
%
Y-
%
m-
%
d
%
H:
%
M:
%
S"
),
"update_time"
:
info
.
updated_at
.
strftime
(
"
%
Y-
%
m-
%
d
%
H:
%
M:
%
S"
),
})
return_data
=
AdminService
.
get_admin_account_list
(
keyword
=
keyword
,
page
=
page
,
page_size
=
page_size
)
return
BaseResponse
(
{
"list"
:
return_data
,
"page"
:
page
,
"pageSize"
:
page_size
,
"total_count"
:
total_count
}
)
return
BaseResponse
(
return_data
)
@admin_route.route
(
'/account_detail'
,
methods
=
[
"POST"
])
...
...
@@ -199,14 +168,13 @@ def get_account_detail():
if
phone
==
g
.
user
.
phone
:
admin_info
=
g
.
user
else
:
admin_info
=
AdminAccount
.
query
.
filter
(
AdminAccount
.
phone
==
phone
,
AdminAccount
.
level
>
g
.
user
.
level
,
AdminAccount
.
parent_id
==
g
.
user
.
id
)
.
first
()
if
not
admin_info
:
return
BaseResponse
(
**
ACCOUNT_NOT_EXISTS_ERROR
)
result
=
AdminService
.
get_admin_account_list
(
phone
=
phone
)
if
result
[
"total_count"
]
!=
1
:
return
BaseResponse
(
**
ACCOUNT_NOT_EXISTS_ERROR
)
admin_info
=
json2obj
(
result
[
"list"
][
0
])
user_info
=
{
"
user_
id"
:
admin_info
.
id
,
"id"
:
admin_info
.
id
,
"user_no"
:
admin_info
.
user_no
,
"user_name"
:
admin_info
.
user_name
,
"phone"
:
admin_info
.
phone
,
...
...
@@ -223,7 +191,7 @@ def edit_user():
json_data
=
request
.
get_json
()
old_phone
=
json_data
[
'old_phone'
]
if
'old_phone'
in
json_data
else
''
new_phone
=
json_data
[
'new_phone'
]
if
'new_phone'
in
json_data
else
''
user_name
=
json_data
[
'user_name'
]
if
'user_name'
in
json_data
else
'
SSW
'
user_name
=
json_data
[
'user_name'
]
if
'user_name'
in
json_data
else
'
XX
'
password
=
json_data
[
'password'
]
if
'password'
in
json_data
else
''
comment
=
json_data
[
'comment'
]
if
'comment'
in
json_data
else
''
level
=
json_data
[
'level'
]
if
'level'
in
json_data
else
''
...
...
@@ -259,6 +227,10 @@ def edit_user():
db
.
session
.
add
(
admin_info
)
db
.
session
.
commit
()
business_ids
=
json_data
.
get
(
"business_ids"
,
[])
if
business_ids
:
AdminService
.
add_or_edit_admin_business
(
account
,
business_ids
)
return
BaseResponse
()
...
...
myapps/pc_management/api/business_portal.py
0 → 100644
View file @
60911711
#!usr/bin/env python
# -*- coding:utf-8 _*-
"""
@version:
author:Aeolus
@time: 2022/01/12
@file: place_portal.py
@function:
@modify:
"""
import
logging
from
flask
import
Blueprint
,
g
,
request
,
jsonify
from
models.base_model
import
db
from
models.models
import
AdminPlace
,
Place
,
Business
,
AdminBusiness
from
utils.error_code
import
NO_PLACE_ERROR
,
NO_BUSINESS_ERROR
from
utils.my_response
import
BaseResponse
logger
=
logging
.
getLogger
(
__name__
)
business_route
=
Blueprint
(
'business'
,
__name__
)
@business_route.route
(
"business_list"
,
methods
=
[
"POST"
])
def
run_business_list
():
"""
:return:
"""
json_data
=
request
.
get_json
()
page
=
json_data
.
get
(
"page"
,
1
)
page_size
=
json_data
.
get
(
"pageSize"
,
10
)
keyword
=
json_data
.
get
(
"keyword"
,
None
)
admin
=
g
.
user
select_sql
=
"select business.business_name,business.status, business.id "
count_sql
=
"select count(business.id) as total_count"
from_sql
=
""" from business where business.id in (select business_id from admin_business where
admin_business.user_id = {} and admin_business.status = 1) """
.
format
(
admin
.
id
)
where_sql
=
" "
if
keyword
:
where_sql
+=
""" and CONCAT(business.business_name) LIKE '
%
{keyword}
%
' """
.
format
(
keyword
=
keyword
)
order_sql
=
" ORDER BY business.id ASC, business.status ASC"
limit_sql
=
" LIMIT {offset} , {page_size} "
.
format
(
offset
=
(
page
-
1
)
*
page_size
,
page_size
=
page_size
)
count_result
=
db
.
session
.
execute
(
count_sql
+
from_sql
+
where_sql
)
.
fetchone
()
if
not
count_result
:
return
BaseResponse
(
data
=
{
"list"
:
[],
"page"
:
page
,
"pageSize"
:
page_size
,
"total_count"
:
0
})
else
:
total_count
=
count_result
.
total_count
result
=
db
.
session
.
execute
(
select_sql
+
from_sql
+
where_sql
+
order_sql
+
limit_sql
)
.
fetchall
()
return_data
=
[]
for
info
in
result
:
return_data
.
append
({
"business_name"
:
info
.
place_name
,
"business_id"
:
info
.
id
,
"status"
:
info
.
status
})
return
BaseResponse
({
"list"
:
return_data
,
"page"
:
page
,
"pageSize"
:
page_size
,
"total_count"
:
total_count
})
@business_route.route
(
"add_business"
,
methods
=
[
"POST"
])
def
run_add_place
():
"""
:return:
"""
json_data
=
request
.
get_json
()
business_name
=
json_data
[
"business_name"
]
business_model
=
Business
()
business_model
.
business_name
=
business_name
db
.
session
.
add
(
business_model
)
db
.
session
.
commit
()
admin_business
=
AdminBusiness
()
admin_business
.
user_id
=
g
.
user
.
id
admin_business
.
user_no
=
g
.
user
.
user_no
admin_business
.
business_id
=
business_model
.
id
db
.
session
.
add
(
admin_business
)
db
.
session
.
commit
()
return
BaseResponse
()
@business_route.route
(
"edit_business"
,
methods
=
[
"POST"
])
def
run_edit_business
():
"""
:return:
"""
json_data
=
request
.
get_json
()
business_id
=
json_data
[
"business_id"
]
business_name
=
json_data
.
get
(
"business_name"
,
""
)
status
=
json_data
.
get
(
"status"
,
None
)
business_model
=
Business
.
query
.
filter_by
(
id
=
business_id
)
.
first
()
if
business_name
:
business_model
.
business_name
=
business_name
if
status
:
business_model
.
status
=
status
db
.
session
.
add
(
business_model
)
db
.
session
.
commit
()
return
BaseResponse
()
@business_route.route
(
"business_detail"
,
methods
=
[
"POST"
])
def
get_business_detail
():
"""
:return:
"""
json_data
=
request
.
get_json
()
business_id
=
json_data
[
"business_id"
]
business_model
=
Business
.
query
.
filter_by
(
id
=
business_id
)
.
first
()
if
business_model
:
return
BaseResponse
(
data
=
{
"business_name"
:
business_model
.
business_name
,
"status"
:
business_model
.
status
,
})
else
:
return
jsonify
(
NO_BUSINESS_ERROR
)
myapps/pc_management/api/hatch_portal.py
View file @
60911711
...
...
@@ -52,7 +52,8 @@ def run_hatch_list():
where_sql
=
" "
if
keyword
:
where_sql
+=
"""
and CONCAT(hatch.machine_no,ifnull(hatch.brand_name,''), ifnull(hatch.production_type_name,''))
and CONCAT(hatch.machine_no,ifnull(hatch.brand_name,''), ifnull(hatch.production_type_name,''),
ifnull(hatch.production_name,''))
LIKE '
%
{keyword}
%
'
"""
.
format
(
keyword
=
keyword
)
...
...
myapps/pc_management/api/production_portal.py
View file @
60911711
...
...
@@ -77,7 +77,7 @@ def run_production_list():
return_data
=
[]
for
info
in
result
:
return_data
.
append
(
{
"production_name"
:
info
.
production_name
,
"prod
cu
tion_id"
:
info
.
id
,
"production_no"
:
info
.
production_no
,
{
"production_name"
:
info
.
production_name
,
"prod
uc
tion_id"
:
info
.
id
,
"production_no"
:
info
.
production_no
,
"title"
:
info
.
title
,
"brand_id"
:
info
.
brand_id
,
"brand_name"
:
info
.
brand_name
,
"production_type_id"
:
info
.
production_type_id
,
"production_type_name"
:
info
.
production_type_name
,
"price"
:
info
.
price
,
"original_price"
:
info
.
original_price
,
"weight"
:
info
.
weight
,
...
...
@@ -248,7 +248,7 @@ def get_production_detail():
info
=
result
[
0
]
return
BaseResponse
(
data
=
{
"production_name"
:
info
.
production_name
,
"prod
cu
tion_id"
:
info
.
id
,
"production_no"
:
info
.
production_no
,
data
=
{
"production_name"
:
info
.
production_name
,
"prod
uc
tion_id"
:
info
.
id
,
"production_no"
:
info
.
production_no
,
"title"
:
info
.
title
,
"brand_id"
:
info
.
brand_id
,
"brand_name"
:
info
.
brand_name
,
"production_type_id"
:
info
.
production_type_id
,
"production_type_name"
:
info
.
production_type_name
,
"price"
:
info
.
price
,
"original_price"
:
info
.
original_price
,
"weight"
:
info
.
weight
,
...
...
service/admin_service.py
View file @
60911711
...
...
@@ -5,98 +5,118 @@ import hashlib
import
random
import
string
from
flask
import
g
from
config.commen_config
import
ACCOUNT_STATUS
from
models.models
import
AdminAccount
from
models.models
import
AdminAccount
,
Business
,
AdminBusiness
from
models.base_model
import
db
from
models.models
import
Place
# from models.user_models import AgentAccount
# from service.spot_service import SpotService
class
AdminService
():
@staticmethod
def
gene_salt
(
length
=
16
):
key_list
=
[
random
.
choice
((
string
.
ascii_letters
+
string
.
digits
))
for
i
in
range
(
length
)]
return
(
""
.
join
(
key_list
))
class
AdminService
(
object
):
@staticmethod
def
ge
ne_agent_code
(
agent_info
,
salt
):
def
ge
t_business_id_list
(
):
"""
:param agent_info:
:param salt:
:param business_ids:
:return:
"""
m
=
hashlib
.
md5
()
str
=
"
%
s-
%
s-
%
s-
%
s"
%
(
agent_info
.
id
,
agent_info
.
user_name
,
agent_info
.
phone
,
salt
)
m
.
update
(
str
.
encode
(
"utf-8"
))
return
m
.
hexdigest
()
@staticmethod
def
gene_pwd
(
pwd
,
salt
):
"""
if
g
.
user
.
level
==
1
:
business_list
=
Business
.
query
.
filter
()
.
all
()
if
business_list
:
business_id_list
=
[
i
.
id
for
i
in
business_list
]
else
:
business_id_list
=
[]
:param pwd
:
:param salt:
:return
:
"""
m
=
hashlib
.
md5
()
str
=
"
%
s-
%
s"
%
(
base64
.
encodebytes
(
pwd
.
encode
(
"utf-8"
)),
salt
)
m
.
update
(
str
.
encode
(
"utf-8"
))
return
m
.
hexdigest
()
else
:
admin_business_list
=
AdminBusiness
.
query
.
filter_by
(
user_id
=
g
.
user
.
id
,
status
=
1
)
.
all
()
if
admin_business_list
:
business_id_list
=
[
i
.
business_id
for
i
in
admin_business_list
]
else
:
business_id_list
=
[]
return
business_id_list
@staticmethod
def
check_agent_token
(
token
):
def
add_or_edit_admin_business
(
admin_account
,
business_ids
):
"""
:param
token
:
:param
business_ids
:
:return:
"""
token
=
base64
.
b64decode
(
token
)
.
decode
(
"utf-8"
)
try
:
agent_info
=
AgentAccount
.
query
.
filter_by
(
access_token
=
token
)
.
first
()
except
Exception
as
e
:
return
1
if
not
agent_info
:
return
1
s
=
token
.
split
(
"#"
)
if
len
(
s
)
!=
2
:
return
1
if
AgentService
.
gene_agent_code
(
agent_info
,
agent_info
.
salt
)
!=
s
[
0
]:
return
1
my_business_id_list
=
AdminService
.
get_business_id_list
()
right_busines_ids
=
list
(
set
(
business_ids
)
.
intersection
(
set
(
my_business_id_list
)))
if
agent_info
.
expire_time
<
datetime
.
datetime
.
now
():
return
2
return
agent_info
@staticmethod
def
create_agent_no
():
'''
生成用户编号
:return:
'''
ran_int
=
str
(
random
.
randint
(
1
,
999999
))
.
zfill
(
6
)
return
'ssw'
+
ran_int
insert_sql
=
" insert into admin_business (user_id, user_no, business_id) values "
for
i
in
right_busines_ids
:
insert_sql
+=
"('{}','{}','{}'),"
.
format
(
admin_account
.
id
,
admin_account
.
user_no
,
i
)
insert_sql
=
insert_sql
[:
-
1
]
insert_sql
+=
" ON DUPLICATE KEY UPDATE status = 1"
db
.
session
.
execute
(
insert_sql
)
db
.
session
.
commit
()
@staticmethod
def
get_
spot_info
(
agent_info
):
def
get_
admin_account_list
(
phone
=
None
,
keyword
=
None
,
page
=
None
,
page_size
=
None
):
"""
:param agent_info:
:return:
"""
spot_info
=
[]
infos
=
db
.
session
.
query
(
AgentSpot
,
Spot
)
.
join
(
Spot
,
Spot
.
id
==
AgentSpot
.
spot_no
)
.
filter
(
AgentSpot
.
agent_no
==
agent_info
.
id
,
AgentSpot
.
status
==
ACCOUNT_STATUS
[
'on_use'
])
.
all
()
for
info
in
infos
:
cur_info
=
{}
cur_info
[
'id'
]
=
info
.
Spot
.
id
cur_info
[
'spotname'
]
=
info
.
Spot
.
spotname
cur_info
[
'letter'
]
=
SpotService
.
get_pinyin
(
info
.
Spot
.
spotname
)
spot_info
.
append
(
cur_info
)
return
spot_info
select_sql
=
"""select admin_account.user_name, admin_account.phone, admin_account.level, admin_account.status,
admin_account.comment,admin_account.parent_id,admin_account.rate, admin_account.created_at,
admin_account.updated_at,admin_account.id, admin_account.user_no
"""
count_sql
=
"select count(admin_account.id) as total_count"
from_sql
=
" from admin_account "
if
g
.
user
.
level
==
1
:
where_sql
=
" where 0=0 "
else
:
where_sql
=
"""
where
admin_account.id in (
select user_id from admin_business where business_id in (
select business_id from admin_business where user_id = {user_id} and status = 1
)
)
and admin_account.level > {level}
"""
.
format
(
user_id
=
g
.
user
.
id
,
level
=
g
.
user
.
level
)
if
phone
:
where_sql
+=
" and phone = {phone}"
.
format
(
phone
=
phone
)
if
keyword
:
where_sql
+=
"""
and CONCAT( admin_account.user_name,
admin_account.phone,
admin_account.user_no) LIKE '
%
{keyword}
%
'
"""
.
format
(
keyword
=
keyword
)
order_sql
=
" ORDER BY admin_account.id ASC, admin_account.status ASC"
if
page
and
page_size
:
limit_sql
=
" LIMIT {offset} , {page_size} "
.
format
(
offset
=
(
page
-
1
)
*
page_size
,
page_size
=
page_size
)
else
:
limit_sql
=
" "
count_result
=
db
.
session
.
execute
(
count_sql
+
from_sql
+
where_sql
)
.
fetchone
()
if
not
count_result
:
return
{
"list"
:
[],
"page"
:
page
,
"pageSize"
:
page_size
,
"total_count"
:
0
}
else
:
total_count
=
count_result
.
total_count
result
=
db
.
session
.
execute
(
select_sql
+
from_sql
+
where_sql
+
order_sql
+
limit_sql
)
.
fetchall
()
return_data
=
[]
for
info
in
result
:
return_data
.
append
(
{
"user_name"
:
info
.
user_name
,
"phone"
:
info
.
phone
,
"level"
:
info
.
level
,
"status"
:
info
.
status
,
"comment"
:
info
.
comment
,
"id"
:
info
.
id
,
"user_no"
:
info
.
user_no
,
"create_time"
:
info
.
created_at
.
strftime
(
"
%
Y-
%
m-
%
d
%
H:
%
M:
%
S"
),
"update_time"
:
info
.
updated_at
.
strftime
(
"
%
Y-
%
m-
%
d
%
H:
%
M:
%
S"
),
})
return
{
"list"
:
return_data
,
"page"
:
page
,
"pageSize"
:
page_size
,
"total_count"
:
total_count
}
utils/error_code.py
View file @
60911711
#!usr/bin/env python # -*- coding:utf-8 _*- """ @version: author:Aeolus @file: error_code.py """ ### 通用错误相关 Param_Invalid_Error = { "error_code": "500", "error_message": "params is invalid, 参数无效" } TOKEN_NOT_VALID_ERROR = { "error_code": "1001", "error_message": "无效的token" } TOKEN_NOT_PROVIDED_ERROR = { "error_code": "1002", "error_message": "token未提供" } TOKEN_EXPIRE_ERROR = { "error_code": "1003", "error_message": "token超时" } PHONE_NOT_BINDING_ERROR = { "error_code": "1004", "error_message": "未绑定手机号" } PHONE_NOT_NULL_ERROR = { "error_code": "1005", "error_message": "手机号为空" } PHONE_NOT_VALID_ERROR = { "error_code": "1006", "error_message": "无效的手机号" } USER_ALREADY_REGISTER_ERROR = { "error_code": "1007", "error_message": "用户已注册" } VERIFICATION_CODE_NULL_ERROR = { "error_code": "1008", "error_message": "验证码为空" } VERIFICATION_CODE_INVALID_ERROR = { "error_code": "1009", "error_message": "验证码已失效" } VERIFICATION_CODE_ERROR = { "error_code": "1010", "error_message": "验证码错误" } PASSWORD_ERROR = { "error_code": "1011", "error_message": "账号或密码错误" } # 账号相关 12开头 ACCOUNT_ALREADY_EXISTS_ERROR = { "error_code": '1012', "error_message": "该账号已存在" } ACCOUNT_NOT_EXISTS_ERROR = { "error_code": '1013', "error_message": "账号不存在" } ACCOUNT_ALREADY_DELETE_ERROR = { "error_code": '1014', "error_message": "账号已被删除" } ACCOUNT_AGENT_SPOT_NULL_ERROR = { "error_code": '1015', "error_message": "代理商景点列表为空" } AGNET_MODULES_ERROR = { "error_code": '1016', "error_message": "用户未绑定模块" } OPERATE_TYPE_ERROR = { "error_code": '1017', "error_message": "type错误" } OPERATE_LEVEL_ERROR = { "error_code": '1018', "error_message": "权限错误" } OPERATE_ERROR = { "error_code": '1019', "error_message": "操作有误" } MODULES_NOT_EXISTS_ERROR = { "error_code": '1020', "error_message": "modules not exists,模块不存在" } ACCOUNT_AGENT_SPOT_NOT_EXIST = { "error_code": '1021', "error_message": "agent spot not exists,代理景区不存在" } AGENT_MACHINE_NOT_EXIST = { "error_code": '1022', "error_message": "agent machine not exists,代理机柜不存在" } ## 微信登陆相关 WX_LOGIN_DATA_ERROR = { "error_code": "3001", "error_message": "微信登录数据错误" } WX_LOGIN_CODE_ERROR = { "error_code": "3002", "error_message": "微信登录code值错误" } WX_OPENID_NOT_GET_ERROR = { "error_code": "3003", "error_message": "微信OpenId获取失败,请刷新重试" } WX_SESSION_KEY_ERROR = { "error_code": "3004", "error_message": "session key error" } ### 微信支付相关 WE_MINIAPP_PAY_FAIL = { "error_code": "3101", "error_message": "小程序下单失败" } ### 消息推送相关 WXBizMsgCrypt_OK = { "error_code": "0", "error_message": "WXBizMsgCrypt_OK" } WXBizMsgCrypt_ValidateSignature_Error = { "error_code": "4001", "error_message": "验证签名错误" } WXBizMsgCrypt_ParseXml_Error = { "error_code": "4002", "error_message": "解析xml错误" } WXBizMsgCrypt_ComputeSignature_Error = { "error_code": "4003", "error_message": "计算签名错误" } WXBizMsgCrypt_IllegalAesKey = { "error_code": "4004", "error_message": "Aes key非法错误" } WXBizMsgCrypt_ValidateAppid_Error = { "error_code": "4005", "error_message": "appid错误" } WXBizMsgCrypt_EncryptAES_Error = { "error_code": "4006", "error_message": "aes加密错误" } WXBizMsgCrypt_DecryptAES_Error = { "error_code": "4007", "error_message": "aes解密错误" } WXBizMsgCrypt_IllegalBuffer = { "error_code": "4008", "error_message": "illegal buffer" } WXBizMsgCrypt_EncodeBase64_Error = { "error_code": "4009", "error_message": "base64加密错误" } WXBizMsgCrypt_DecodeBase64_Error = { "error_code": "4010", "error_message": "base64解密错误" } WXBizMsgCrypt_GenReturnXml_Error = { "error_code": "4011", "error_message": "gen return xml error" } MACHINE_NOT_EXIST_ERROR = { "error_code": '5001', "error_message": "机柜不存在" } MACHINE_IS_USE_ERROR = { "error_code": '5002', "error_message": "已有他人正在租借中,请稍后" } MACHINE_IS_NOT_ONLINE_ERROR = { "error_code": '5003', "error_message": "机柜不在线" } MACHINE_ADD_ERROR = { "error_code": '5004', "error_message": "机柜添加失败" } MACHINE_NO_DUPLICATE_ERROR = { "error_code": '5005', "error_message": "machine_no duplicate,机柜编号重复" } MACHINE_EDIT_ERROR = { "error_code": '5006', "error_message": "machine edit error, 机柜修改错误" } HATCH_NOT_EXIST_ERROR = { "error_code": "5007", "error_message": "no hatch, 没有仓道商品信息" } HATCH_NOT_ALL_EXIST_ERROR = { "error_code": "5008", "error_message": "no all hatch, 存在已售出商品" } HATCH_COUNT_ERROR = { "error_code": "5009", "error_message": "hatch count error, 商品数量错误,检查数量" } MACHINE_ACTIVATED_ERROR = { "error_code": '5010', "error_message": "machine activated, 机柜已激活" } MACHINE_NO_CREATE_ERROR = { "error_code": '5011', "error_message": "machine_no create error , 机柜编号生成错误" } MACHINE_MAC_DUPLICATE_ERROR = { "error_code": '5012', "error_message": "machine_mac duplicate,机柜mac重复" } HATCH_COUNT_MAX_ERROR = { "error_code": '5013', "error_message": "hatch count max,仓道数量达到上限" } HATCH_NO_DUPLICATE_ERROR = { "error_code": '5014', "error_message": "hatch_no duplicate,仓道序号重复" } HATCH_NO_DUPLICATE_ERROR = { "error_code": '5014', "error_message": "hatch_no duplicate,仓道序号重复" } ### 订单相关 RENT_ORDER_NOT_BACK_ERROR = { "error_code": '6101', "error_message": "有未归还的订单" } RENT_ORDER_NOT_TAKE_ERROR = { "error_code": '6102', "error_message": "有未取货的订单" } RENT_ORDER_NUMBER_MAX = { "error_code": '6103', "error_message": "订单数量达到上限" } TAKE_CODE_NOT_VALID = { "error_code": '6104', "error_message": "取货码错误请确认手机号及取货码是否匹配" } CODE_CANCEL_ERROR = { "error_code": '6105', "error_message": "取货码已取消" } CODE_USED_ERROR = { "error_code": '6108', "error_message": "取货码已使用" } NO_POWER_ERROR = { "error_code": '6106', "error_message": "没有可租借设备" } NO_RENT_RECORD = { "error_code": '6107', "error_message": "订单不存在" } CODE_USED_ERROR = { "error_code": '6108', "error_message": "取货码已使用" } RENT_ORDER_NUMBER_LIMIT = { "error_code": '6109', "error_message": "机柜只允许租借一台" } REFUND_NOT_RENT_INFO = { "error_code": "6301", "error_message": "没有该订单信息" } REFUND_BACK_TIME_ERROR = { "error_code": "6302", "error_message": "归还时间异常" } REFUND_NOT_PRODUCTION_INFO = { "error_code": "6303", "error_message": "没有该讲解器信息" } REFUND_MONEY_IS_ZERO = { "error_code": "6304", "error_message": "退款金额为零" } REFUND_NO_DUPLICATE = { "error_code": "6305", "error_message": "退款单号重复" } TALLYMAN_ACCOUNT_EXIST = { "error_code": "7001", "error_message": "tallyman account exist, 补货员账号已存在" } TALLYMAN_ACCOUNT_NOT_EXIST = { "error_code": "7002", "error_message": "tallyman account not exist, 补货员账号不存在" } NFC_CARD_NOT_EXIST = { "error_code": "8001", "error_message": "nfc card not exist, 卡号错误" } NFC_CARD_ACTIVATED_ERROR = { "error_code": "8002", "error_message": "nfc card activated, 卡片已激活" } NO_NFC_CARD_ERROR = { "error_code": "8003", "error_message": "no nfc card , 不存在卡片" } RE_NFC_CARD_ERROR = { "error_code": "8004", "error_message": "re nfc card , 卡片已存在" } NFC_PAY_LOAD_SECRET_ERROR = { "error_code": "8005", "error_message": "secret error , 身份验证失败" } # 9 场所相关 NO_PLACE_ERROR = { "error_code": "9001", "error_message": "no place error,不存在场景" } # 10 商品相关 NO_PRODUCTION_ERROR = { "error_code": "10001", "error_message": "no production error,商品不存在" } NO_BRAND_ERROR = { "error_code": "10002", "error_message": "no production error,品牌不存在" } # COMMON_MONGO_ERROR = { "error_code": 5001, "error_message": "mongodb operation error, mongodb操作错误" }
\ No newline at end of file
#!usr/bin/env python # -*- coding:utf-8 _*- """ @version: author:Aeolus @file: error_code.py """ ### 通用错误相关 Param_Invalid_Error = { "error_code": "500", "error_message": "params is invalid, 参数无效" } TOKEN_NOT_VALID_ERROR = { "error_code": "1001", "error_message": "无效的token" } TOKEN_NOT_PROVIDED_ERROR = { "error_code": "1002", "error_message": "token未提供" } TOKEN_EXPIRE_ERROR = { "error_code": "1003", "error_message": "token超时" } PHONE_NOT_BINDING_ERROR = { "error_code": "1004", "error_message": "未绑定手机号" } PHONE_NOT_NULL_ERROR = { "error_code": "1005", "error_message": "手机号为空" } PHONE_NOT_VALID_ERROR = { "error_code": "1006", "error_message": "无效的手机号" } USER_ALREADY_REGISTER_ERROR = { "error_code": "1007", "error_message": "用户已注册" } VERIFICATION_CODE_NULL_ERROR = { "error_code": "1008", "error_message": "验证码为空" } VERIFICATION_CODE_INVALID_ERROR = { "error_code": "1009", "error_message": "验证码已失效" } VERIFICATION_CODE_ERROR = { "error_code": "1010", "error_message": "验证码错误" } PASSWORD_ERROR = { "error_code": "1011", "error_message": "账号或密码错误" } # 账号相关 12开头 ACCOUNT_ALREADY_EXISTS_ERROR = { "error_code": '1012', "error_message": "该账号已存在" } ACCOUNT_NOT_EXISTS_ERROR = { "error_code": '1013', "error_message": "账号不存在" } ACCOUNT_ALREADY_DELETE_ERROR = { "error_code": '1014', "error_message": "账号已被删除" } ACCOUNT_AGENT_SPOT_NULL_ERROR = { "error_code": '1015', "error_message": "代理商景点列表为空" } AGNET_MODULES_ERROR = { "error_code": '1016', "error_message": "用户未绑定模块" } OPERATE_TYPE_ERROR = { "error_code": '1017', "error_message": "type错误" } OPERATE_LEVEL_ERROR = { "error_code": '1018', "error_message": "权限错误" } OPERATE_ERROR = { "error_code": '1019', "error_message": "操作有误" } MODULES_NOT_EXISTS_ERROR = { "error_code": '1020', "error_message": "modules not exists,模块不存在" } ACCOUNT_AGENT_SPOT_NOT_EXIST = { "error_code": '1021', "error_message": "agent spot not exists,代理景区不存在" } AGENT_MACHINE_NOT_EXIST = { "error_code": '1022', "error_message": "agent machine not exists,代理机柜不存在" } NO_BUSINESS_ERROR = { "error_code": '1023', "error_message": "no business error,商户不存在" } ## 微信登陆相关 WX_LOGIN_DATA_ERROR = { "error_code": "3001", "error_message": "微信登录数据错误" } WX_LOGIN_CODE_ERROR = { "error_code": "3002", "error_message": "微信登录code值错误" } WX_OPENID_NOT_GET_ERROR = { "error_code": "3003", "error_message": "微信OpenId获取失败,请刷新重试" } WX_SESSION_KEY_ERROR = { "error_code": "3004", "error_message": "session key error" } ### 微信支付相关 WE_MINIAPP_PAY_FAIL = { "error_code": "3101", "error_message": "小程序下单失败" } ### 消息推送相关 WXBizMsgCrypt_OK = { "error_code": "0", "error_message": "WXBizMsgCrypt_OK" } WXBizMsgCrypt_ValidateSignature_Error = { "error_code": "4001", "error_message": "验证签名错误" } WXBizMsgCrypt_ParseXml_Error = { "error_code": "4002", "error_message": "解析xml错误" } WXBizMsgCrypt_ComputeSignature_Error = { "error_code": "4003", "error_message": "计算签名错误" } WXBizMsgCrypt_IllegalAesKey = { "error_code": "4004", "error_message": "Aes key非法错误" } WXBizMsgCrypt_ValidateAppid_Error = { "error_code": "4005", "error_message": "appid错误" } WXBizMsgCrypt_EncryptAES_Error = { "error_code": "4006", "error_message": "aes加密错误" } WXBizMsgCrypt_DecryptAES_Error = { "error_code": "4007", "error_message": "aes解密错误" } WXBizMsgCrypt_IllegalBuffer = { "error_code": "4008", "error_message": "illegal buffer" } WXBizMsgCrypt_EncodeBase64_Error = { "error_code": "4009", "error_message": "base64加密错误" } WXBizMsgCrypt_DecodeBase64_Error = { "error_code": "4010", "error_message": "base64解密错误" } WXBizMsgCrypt_GenReturnXml_Error = { "error_code": "4011", "error_message": "gen return xml error" } MACHINE_NOT_EXIST_ERROR = { "error_code": '5001', "error_message": "机柜不存在" } MACHINE_IS_USE_ERROR = { "error_code": '5002', "error_message": "已有他人正在租借中,请稍后" } MACHINE_IS_NOT_ONLINE_ERROR = { "error_code": '5003', "error_message": "机柜不在线" } MACHINE_ADD_ERROR = { "error_code": '5004', "error_message": "机柜添加失败" } MACHINE_NO_DUPLICATE_ERROR = { "error_code": '5005', "error_message": "machine_no duplicate,机柜编号重复" } MACHINE_EDIT_ERROR = { "error_code": '5006', "error_message": "machine edit error, 机柜修改错误" } HATCH_NOT_EXIST_ERROR = { "error_code": "5007", "error_message": "no hatch, 没有仓道商品信息" } HATCH_NOT_ALL_EXIST_ERROR = { "error_code": "5008", "error_message": "no all hatch, 存在已售出商品" } HATCH_COUNT_ERROR = { "error_code": "5009", "error_message": "hatch count error, 商品数量错误,检查数量" } MACHINE_ACTIVATED_ERROR = { "error_code": '5010', "error_message": "machine activated, 机柜已激活" } MACHINE_NO_CREATE_ERROR = { "error_code": '5011', "error_message": "machine_no create error , 机柜编号生成错误" } MACHINE_MAC_DUPLICATE_ERROR = { "error_code": '5012', "error_message": "machine_mac duplicate,机柜mac重复" } HATCH_COUNT_MAX_ERROR = { "error_code": '5013', "error_message": "hatch count max,仓道数量达到上限" } HATCH_NO_DUPLICATE_ERROR = { "error_code": '5014', "error_message": "hatch_no duplicate,仓道序号重复" } HATCH_NO_DUPLICATE_ERROR = { "error_code": '5014', "error_message": "hatch_no duplicate,仓道序号重复" } ### 订单相关 RENT_ORDER_NOT_BACK_ERROR = { "error_code": '6101', "error_message": "有未归还的订单" } RENT_ORDER_NOT_TAKE_ERROR = { "error_code": '6102', "error_message": "有未取货的订单" } RENT_ORDER_NUMBER_MAX = { "error_code": '6103', "error_message": "订单数量达到上限" } TAKE_CODE_NOT_VALID = { "error_code": '6104', "error_message": "取货码错误请确认手机号及取货码是否匹配" } CODE_CANCEL_ERROR = { "error_code": '6105', "error_message": "取货码已取消" } CODE_USED_ERROR = { "error_code": '6108', "error_message": "取货码已使用" } NO_POWER_ERROR = { "error_code": '6106', "error_message": "没有可租借设备" } NO_RENT_RECORD = { "error_code": '6107', "error_message": "订单不存在" } CODE_USED_ERROR = { "error_code": '6108', "error_message": "取货码已使用" } RENT_ORDER_NUMBER_LIMIT = { "error_code": '6109', "error_message": "机柜只允许租借一台" } REFUND_NOT_RENT_INFO = { "error_code": "6301", "error_message": "没有该订单信息" } REFUND_BACK_TIME_ERROR = { "error_code": "6302", "error_message": "归还时间异常" } REFUND_NOT_PRODUCTION_INFO = { "error_code": "6303", "error_message": "没有该讲解器信息" } REFUND_MONEY_IS_ZERO = { "error_code": "6304", "error_message": "退款金额为零" } REFUND_NO_DUPLICATE = { "error_code": "6305", "error_message": "退款单号重复" } TALLYMAN_ACCOUNT_EXIST = { "error_code": "7001", "error_message": "tallyman account exist, 补货员账号已存在" } TALLYMAN_ACCOUNT_NOT_EXIST = { "error_code": "7002", "error_message": "tallyman account not exist, 补货员账号不存在" } NFC_CARD_NOT_EXIST = { "error_code": "8001", "error_message": "nfc card not exist, 卡号错误" } NFC_CARD_ACTIVATED_ERROR = { "error_code": "8002", "error_message": "nfc card activated, 卡片已激活" } NO_NFC_CARD_ERROR = { "error_code": "8003", "error_message": "no nfc card , 不存在卡片" } RE_NFC_CARD_ERROR = { "error_code": "8004", "error_message": "re nfc card , 卡片已存在" } NFC_PAY_LOAD_SECRET_ERROR = { "error_code": "8005", "error_message": "secret error , 身份验证失败" } # 9 场所相关 NO_PLACE_ERROR = { "error_code": "9001", "error_message": "no place error,不存在场景" } # 10 商品相关 NO_PRODUCTION_ERROR = { "error_code": "10001", "error_message": "no production error,商品不存在" } NO_BRAND_ERROR = { "error_code": "10002", "error_message": "no production error,品牌不存在" } # COMMON_MONGO_ERROR = { "error_code": 5001, "error_message": "mongodb operation error, mongodb操作错误" }
\ No newline at end of file
...
...
utils/jwt_util.py
View file @
60911711
#!usr/bin/.env python # -*- coding:utf-8 _*- """ @version: author:Aeolus @time: 2021/03/30 @file: jwt_util.py @function: @modify: """ import jwt from flask import current_app def generate_jwt(payload, expiry, secret=None): """ 生成jwt :param payload: dict 载荷 :param expiry: datetime 有效期 :param secret: 密钥 :return: jwt """ _payload = {'exp': expiry} _payload.update(payload) if not secret: secret = current_app.config['SECRET_KEY'] token = jwt.encode(_payload, secret, algorithm='HS256') return token def verify_jwt(token, secret=None): """ 检验jwt :param token: jwt :param secret: 密钥 :return: dict: payload """ if not secret: secret = current_app.config['SECRET_KEY'] try: payload = jwt.decode(token, secret, algorithms=['HS256']) except jwt.PyJWTError: payload = None return payload if __name__ == '__main__': import time from config.env_path_config import env_path from dotenv import load_dotenv load_dotenv(dotenv_path=env_path, verbose=True, override=True) import os SECRET_KEY = os.getenv('SECRET_KEY') token = generate_jwt({"user_id": 4}, time.time() + 6000, SECRET_KEY) # token = generate_jwt({"user_no": 'SK000007'}, time.time() + 6000, SECRET_KEY) print(token) # for i in range(10): # result = verify_jwt(token, 'secret') # print(result) # print(time.time()) # time.sleep(1)
\ No newline at end of file
#!usr/bin/.env python # -*- coding:utf-8 _*- """ @version: author:Aeolus @time: 2021/03/30 @file: jwt_util.py @function: @modify: """ import jwt from flask import current_app def generate_jwt(payload, expiry, secret=None): """ 生成jwt :param payload: dict 载荷 :param expiry: datetime 有效期 :param secret: 密钥 :return: jwt """ _payload = {'exp': expiry} _payload.update(payload) if not secret: secret = current_app.config['SECRET_KEY'] token = jwt.encode(_payload, secret, algorithm='HS256') return token def verify_jwt(token, secret=None): """ 检验jwt :param token: jwt :param secret: 密钥 :return: dict: payload """ if not secret: secret = current_app.config['SECRET_KEY'] try: payload = jwt.decode(token, secret, algorithms=['HS256']) except jwt.PyJWTError: payload = None return payload if __name__ == '__main__': import time from config.env_path_config import env_path from dotenv import load_dotenv load_dotenv(dotenv_path=env_path, verbose=True, override=True) import os SECRET_KEY = os.getenv('SECRET_KEY') token = generate_jwt({"user_id": 1}, time.time() + 6000, SECRET_KEY) # token = generate_jwt({"user_no": 'SK000007'}, time.time() + 6000, SECRET_KEY) print(token) # for i in range(10): # result = verify_jwt(token, 'secret') # print(result) # print(time.time()) # time.sleep(1)
\ No newline at end of file
...
...
utils/mytools.py
View file @
60911711
# -*- coding: utf-8 -*-
class
UpdateParams
:
def
__init__
(
self
,
**
kwargs
):
self
.
__dict__
.
update
(
kwargs
)
def
__getattr__
(
self
,
item
):
print
(
f
"没有该属性:{item}"
)
return
None
def
json2obj
(
json_data
):
d
=
UpdateParams
.
__new__
(
UpdateParams
)
d
.
__dict__
.
update
(
json_data
)
return
d
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