提交 f1f7116b2acda9b224204094c738ec39c5e01bef

作者 nheweijun
2 个父辈 6c8be461 c5800678

merge

DMapManager @ 8e446e18
1 -Subproject commit 8e446e18a7a81ea282d05f6026f4d41d5dae1378  
1 -import decimal  
2 -  
3 -from flask import Flask as _Flask  
4 -from flask.json import JSONEncoder as _JSONEncoder  
5 -from flask_cors import CORS  
6 -import time  
7 -import configure  
8 -from app.util import BlueprintApi  
9 -from app.util import find_class  
10 -from app.models import db, Table, InsertingLayerName, Database, DES, Task  
11 -from app.modules.auth.oauth2 import config_oauth  
12 -from flasgger import Swagger  
13 -# from rtree import index  
14 -import logging  
15 -from sqlalchemy.orm import Session  
16 -import multiprocessing  
17 -from app.util.component.EntryData import EntryData  
18 -from app.util.component.EntryDataVacuate import EntryDataVacuate  
19 -import json  
20 -import threading  
21 -import traceback  
22 -from sqlalchemy import distinct  
23 -import uuid  
24 -from osgeo.ogr import DataSource  
25 -import datetime  
26 -from sqlalchemy import or_  
27 -from app.util.component.StructuredPrint import StructurePrint  
28 -from app.util.component.PGUtil import PGUtil  
29 -import os  
30 -  
31 -class JSONEncoder(_JSONEncoder):  
32 - """  
33 - 因为decimal不能序列化,增加Flask对decimal类的解析  
34 - """  
35 - def default(self, o):  
36 - if isinstance(o, decimal.Decimal):  
37 - return float(o)  
38 - super(JSONEncoder, self).default(o)  
39 -  
40 -  
41 -class Flask(_Flask):  
42 - json_encoder = JSONEncoder  
43 -  
44 -  
45 -GLOBAL_DIC={}  
46 -def create_app():  
47 - """  
48 - flask应用创建函数  
49 - :return:app,flask实例  
50 - """  
51 -  
52 - # app基本设置  
53 - app = Flask(__name__)  
54 - app.config['SQLALCHEMY_DATABASE_URI'] = configure.SQLALCHEMY_DATABASE_URI  
55 - app.config['echo'] = True  
56 - app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True  
57 - app.config['JSON_AS_ASCII'] = False  
58 - app.config['SECRET_KEY'] = configure.SECRET_KEY  
59 - app.config['OAUTH2_JWT_ENABLED'] = True  
60 -  
61 - app.config['OAUTH2_JWT_ISS'] = 'http://localhost:5000'  
62 - app.config['OAUTH2_JWT_KEY'] = 'secret-key'  
63 - app.config['OAUTH2_JWT_ALG'] = 'HS256'  
64 - # app.config['SQLALCHEMY_ECHO'] = True  
65 -  
66 - # 跨域设置  
67 - CORS(app)  
68 -  
69 - # swagger设置  
70 - swagger_config = Swagger.DEFAULT_CONFIG  
71 - swagger_config.update(configure.swagger_configure)  
72 - Swagger(app, config=swagger_config)  
73 -  
74 - # 创建数据库  
75 - db.init_app(app)  
76 - db.create_all(app=app)  
77 -  
78 - # 日志  
79 - logging.basicConfig(level=logging.INFO)  
80 - log_file = os.path.join(os.path.dirname(os.path.dirname(  
81 - os.path.realpath(__file__))), "logs", "log.txt")  
82 - handler = logging.FileHandler(  
83 - log_file, encoding='UTF-8') # 设置日志字符集和存储路径名字  
84 - logging_format = logging.Formatter(  
85 - '[%(levelname)s] %(asctime)s %(message)s')  
86 - handler.setFormatter(logging_format)  
87 - app.logger.addHandler(handler)  
88 -  
89 - # 配置使用鉴权组件,不写无法认证授权  
90 - config_oauth(app)  
91 -  
92 - # 注册blueprint,查找BlueprintApi的子类  
93 - for scan in configure.scan_module:  
94 - for api in find_class(scan, BlueprintApi):  
95 - app.register_blueprint(api.bp)  
96 -  
97 - # 入库监测线程  
98 -  
99 - @app.before_first_request  
100 - def data_entry_process():  
101 - StructurePrint.print("start listen")  
102 - process = threading.Thread(target=data_entry_center)  
103 - process.start()  
104 -  
105 - # 不检测https  
106 - os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = '1'  
107 -  
108 - # 上下文全局变量字典  
109 - global GLOBAL_DIC  
110 -  
111 - return app  
112 -  
113 -  
114 -def data_entry_center():  
115 - running_dict = {}  
116 - sys_session: Session = PGUtil.get_db_session(  
117 - configure.SQLALCHEMY_DATABASE_URI)  
118 -  
119 - while True:  
120 -  
121 - try:  
122 - time.sleep(3)  
123 -  
124 - # 已经结束的进程 从监测中删除  
125 - remove_process = []  
126 -  
127 - # structured_print(running_dict.__len__().__str__())  
128 -  
129 - for process, layer_names in running_dict.items():  
130 - if not process.is_alive():  
131 - for l in layer_names:  
132 - inserted = sys_session.query(  
133 - InsertingLayerName).filter_by(name=l).one_or_none()  
134 - if inserted:  
135 - sys_session.delete(inserted)  
136 - sys_session.commit()  
137 - remove_process.append(process)  
138 - for process in remove_process:  
139 - running_dict.pop(process)  
140 -  
141 - # StructurePrint.print("listening...")  
142 -  
143 - # 入库进程少于阈值,开启入库进程  
144 -  
145 - inter_size = sys_session.query(  
146 - distinct(InsertingLayerName.task_guid)).count()  
147 -  
148 - if inter_size < configure.entry_data_thread:  
149 - # 锁表啊  
150 - ready_task:Task = sys_session.query(Task).filter_by(state=0,task_type=1).order_by(Task.create_time).with_lockmode("update").limit(1).one_or_none()  
151 - if ready_task:  
152 -  
153 - try:  
154 - parameter = json.loads(ready_task.parameter)  
155 - StructurePrint.print("检测到入库任务")  
156 - ready_task.state = 2  
157 - ready_task.process = "入库中"  
158 - sys_session.commit()  
159 -  
160 - metas: list = json.loads(  
161 - parameter.get("meta").__str__())  
162 - parameter["meta"] = metas  
163 -  
164 - database = sys_session.query(Database).filter_by(  
165 - guid=ready_task.database_guid).one_or_none()  
166 - pg_ds: DataSource = PGUtil.open_pg_data_source(  
167 - 1, DES.decode(database.sqlalchemy_uri))  
168 -  
169 - this_task_layer = []  
170 - for meta in metas:  
171 - overwrite = parameter.get("overwrite", "no")  
172 -  
173 - for layer_name_origin, layer_name in meta.get("layer").items():  
174 - origin_name = layer_name  
175 - no = 1  
176 -  
177 - while (overwrite.__eq__("no") and pg_ds.GetLayerByName(layer_name)) or sys_session.query(InsertingLayerName).filter_by(name=layer_name).one_or_none():  
178 - layer_name = origin_name + "_{}".format(no)  
179 - no += 1  
180 -  
181 - # 添加到正在入库的列表中  
182 - iln = InsertingLayerName(guid=uuid.uuid1().__str__(),  
183 - task_guid=ready_task.guid,  
184 - name=layer_name)  
185 -  
186 - sys_session.add(iln)  
187 - sys_session.commit()  
188 - this_task_layer.append(layer_name)  
189 - # 修改表名  
190 - meta["layer"][layer_name_origin] = layer_name  
191 -  
192 - pg_ds.Destroy()  
193 - entry_data_process = multiprocessing.Process(  
194 - target=EntryDataVacuate().entry, args=(parameter,))  
195 - entry_data_process.start()  
196 - running_dict[entry_data_process] = this_task_layer  
197 - except Exception as e:  
198 - sys_session.query(Task).filter_by(guid=ready_task.guid).update(  
199 - {"state": -1, "process": "入库失败"})  
200 - sys_session.commit()  
201 - StructurePrint.print(e.__str__(), "error")  
202 - else:  
203 - # 解表啊  
204 - sys_session.commit()  
205 - except Exception as e:  
206 - sys_session.commit()  
207 - StructurePrint.print(e.__str__(), "error") 1 +import decimal
  2 +
  3 +from flask import Flask as _Flask
  4 +from flask.json import JSONEncoder as _JSONEncoder
  5 +from flask_cors import CORS
  6 +import time
  7 +
  8 +from sqlalchemy.sql.expression import true
  9 +import configure
  10 +from app.util import BlueprintApi
  11 +from app.util import find_class
  12 +from app.models import db, Table, InsertingLayerName, Database, DES, Task
  13 +from app.modules.auth.oauth2 import config_oauth, myCodeIDToken
  14 +from flasgger import Swagger
  15 +# from rtree import index
  16 +import logging
  17 +from sqlalchemy.orm import Session
  18 +import multiprocessing
  19 +from app.util.component.EntryData import EntryData
  20 +from app.util.component.EntryDataVacuate import EntryDataVacuate
  21 +import json
  22 +import threading
  23 +import traceback
  24 +from sqlalchemy import distinct
  25 +import uuid
  26 +from osgeo.ogr import DataSource
  27 +import datetime
  28 +from sqlalchemy import or_
  29 +from app.util.component.StructuredPrint import StructurePrint
  30 +from app.util.component.PGUtil import PGUtil
  31 +import os
  32 +
  33 +
  34 +class JSONEncoder(_JSONEncoder):
  35 + """
  36 + 因为decimal不能序列化,增加Flask对decimal类的解析
  37 + """
  38 +
  39 + def default(self, o):
  40 + if isinstance(o, decimal.Decimal):
  41 + return float(o)
  42 + super(JSONEncoder, self).default(o)
  43 +
  44 +
  45 +class Flask(_Flask):
  46 + json_encoder = JSONEncoder
  47 +
  48 +
  49 +GLOBAL_DIC = {}
  50 +
  51 +
  52 +def create_app():
  53 + """
  54 + flask应用创建函数
  55 + :return:app,flask实例
  56 + """
  57 +
  58 + # app基本设置
  59 + app = Flask(__name__)
  60 + app.config['SQLALCHEMY_DATABASE_URI'] = configure.SQLALCHEMY_DATABASE_URI
  61 + app.config['echo'] = True
  62 + app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
  63 + app.config['JSON_AS_ASCII'] = False
  64 + app.config['SECRET_KEY'] = configure.SECRET_KEY
  65 + app.config['OAUTH2_JWT_ENABLED'] = True
  66 +
  67 + app.config['OAUTH2_JWT_ISS'] = 'http://localhost:5000'
  68 + app.config['OAUTH2_JWT_KEY'] = 'secret-key'
  69 + app.config['OAUTH2_JWT_ALG'] = 'HS256'
  70 + # app.config['SQLALCHEMY_ECHO'] = True
  71 +
  72 + # allows cookies and credentials to be submitted across domains
  73 + app.config['CORS_SUPPORTS_CREDENTIALS'] = true
  74 + app.config['CORS_ORIGINS ']="*"
  75 +
  76 + # 跨域设置
  77 + CORS(app)
  78 +
  79 + # swagger设置
  80 + swagger_config = Swagger.DEFAULT_CONFIG
  81 + swagger_config.update(configure.swagger_configure)
  82 + Swagger(app, config=swagger_config)
  83 +
  84 + # 创建数据库
  85 + db.init_app(app)
  86 + db.create_all(app=app)
  87 +
  88 + # 日志
  89 + logging.basicConfig(level=logging.INFO)
  90 + log_file = os.path.join(os.path.dirname(os.path.dirname(
  91 + os.path.realpath(__file__))), "logs", "log.txt")
  92 + handler = logging.FileHandler(
  93 + log_file, encoding='UTF-8') # 设置日志字符集和存储路径名字
  94 + logging_format = logging.Formatter(
  95 + '[%(levelname)s] %(asctime)s %(message)s')
  96 + handler.setFormatter(logging_format)
  97 + app.logger.addHandler(handler)
  98 +
  99 + # 配置使用鉴权组件,不写无法认证授权
  100 + config_oauth(app)
  101 +
  102 + # 注册blueprint,查找BlueprintApi的子类
  103 + for scan in configure.scan_module:
  104 + for api in find_class(scan, BlueprintApi):
  105 + app.register_blueprint(api.bp)
  106 +
  107 + # 入库监测线程
  108 +
  109 + @app.before_first_request
  110 + def data_entry_process():
  111 + StructurePrint.print("start listen")
  112 + process = threading.Thread(target=data_entry_center)
  113 + process.start()
  114 +
  115 + # 不检测https
  116 + os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = '1'
  117 +
  118 + # 上下文全局变量字典
  119 + global GLOBAL_DIC
  120 +
  121 + return app
  122 +
  123 +
  124 +def data_entry_center():
  125 + running_dict = {}
  126 + sys_session: Session = PGUtil.get_db_session(
  127 + configure.SQLALCHEMY_DATABASE_URI)
  128 +
  129 + while True:
  130 +
  131 + try:
  132 + time.sleep(3)
  133 +
  134 + # 已经结束的进程 从监测中删除
  135 + remove_process = []
  136 +
  137 + # structured_print(running_dict.__len__().__str__())
  138 +
  139 + for process, layer_names in running_dict.items():
  140 + if not process.is_alive():
  141 + for l in layer_names:
  142 + inserted = sys_session.query(
  143 + InsertingLayerName).filter_by(name=l).one_or_none()
  144 + if inserted:
  145 + sys_session.delete(inserted)
  146 + sys_session.commit()
  147 + remove_process.append(process)
  148 + for process in remove_process:
  149 + running_dict.pop(process)
  150 +
  151 + # StructurePrint.print("listening...")
  152 +
  153 + # 入库进程少于阈值,开启入库进程
  154 +
  155 + inter_size = sys_session.query(
  156 + distinct(InsertingLayerName.task_guid)).count()
  157 +
  158 + if inter_size < configure.entry_data_thread:
  159 + # 锁表啊
  160 + ready_task: Task = sys_session.query(Task).filter_by(state=0, task_type=1).order_by(
  161 + Task.create_time).with_lockmode("update").limit(1).one_or_none()
  162 + if ready_task:
  163 +
  164 + try:
  165 + parameter = json.loads(ready_task.parameter)
  166 + StructurePrint.print("检测到入库任务")
  167 + ready_task.state = 2
  168 + ready_task.process = "入库中"
  169 + sys_session.commit()
  170 +
  171 + metas: list = json.loads(
  172 + parameter.get("meta").__str__())
  173 + parameter["meta"] = metas
  174 +
  175 + database = sys_session.query(Database).filter_by(
  176 + guid=ready_task.database_guid).one_or_none()
  177 + pg_ds: DataSource = PGUtil.open_pg_data_source(
  178 + 1, DES.decode(database.sqlalchemy_uri))
  179 +
  180 + this_task_layer = []
  181 + for meta in metas:
  182 + overwrite = parameter.get("overwrite", "no")
  183 +
  184 + for layer_name_origin, layer_name in meta.get("layer").items():
  185 + origin_name = layer_name
  186 + no = 1
  187 +
  188 + while (overwrite.__eq__("no") and pg_ds.GetLayerByName(layer_name)) or sys_session.query(InsertingLayerName).filter_by(name=layer_name).one_or_none():
  189 + layer_name = origin_name + "_{}".format(no)
  190 + no += 1
  191 +
  192 + # 添加到正在入库的列表中
  193 + iln = InsertingLayerName(guid=uuid.uuid1().__str__(),
  194 + task_guid=ready_task.guid,
  195 + name=layer_name)
  196 +
  197 + sys_session.add(iln)
  198 + sys_session.commit()
  199 + this_task_layer.append(layer_name)
  200 + # 修改表名
  201 + meta["layer"][layer_name_origin] = layer_name
  202 +
  203 + pg_ds.Destroy()
  204 + entry_data_process = multiprocessing.Process(
  205 + target=EntryDataVacuate().entry, args=(parameter,))
  206 + entry_data_process.start()
  207 + running_dict[entry_data_process] = this_task_layer
  208 + except Exception as e:
  209 + sys_session.query(Task).filter_by(guid=ready_task.guid).update(
  210 + {"state": -1, "process": "入库失败"})
  211 + sys_session.commit()
  212 + StructurePrint.print(e.__str__(), "error")
  213 + else:
  214 + # 解表啊
  215 + sys_session.commit()
  216 + except Exception as e:
  217 + sys_session.commit()
  218 + StructurePrint.print(e.__str__(), "error")
1 -from app.util import BlueprintApi  
2 -from app.util import BlueprintApi  
3 -from flask import Blueprint, render_template, redirect, url_for, request, session, jsonify  
4 -from flask_sqlalchemy import sqlalchemy  
5 -from sqlalchemy import and_  
6 -from .models import *  
7 -from werkzeug.security import gen_salt  
8 -import time  
9 -from .oauth2 import authorization, require_oauth, generate_user_info  
10 -from authlib.oauth2 import OAuth2Error  
11 -from authlib.integrations.flask_oauth2 import current_token  
12 -  
13 -  
14 -def current_user():  
15 - if 'id' in session:  
16 - uid = session['id']  
17 - return User.query.get(uid)  
18 - return None  
19 -  
20 -  
21 -def split_by_crlf(s):  
22 - return [v for v in s.splitlines() if v]  
23 -  
24 -  
25 -class DataManager(BlueprintApi):  
26 - bp = Blueprint("Auth", __name__, url_prefix="/auth")  
27 -  
28 - # @staticmethod  
29 - # @bp.route('/test', methods=('GET', 'POST'))  
30 - # def Test():  
31 - # res = {}  
32 - # try:  
33 - # res['user'] = User.query.all()  
34 - # except Exception as e:  
35 - # raise e  
36 - # return res  
37 -  
38 - # @staticmethod  
39 - # @bp.route('/login', methods=('GET', 'POST'))  
40 - # def Login():  
41 - # if request.method == 'POST':  
42 - # username = request.form['username']  
43 - # password = request.form['password']  
44 - # user = User.query.filter_by(username=username).first()  
45 - # if not user:  
46 - # user = User(username=username,  
47 - # password=password, role='admin')  
48 - # db.session.add(user)  
49 - # db.session.commit()  
50 - # session['id'] = user.id  
51 - # return redirect('/auth/authorize')  
52 - # user = current_user()  
53 - # if user:  
54 - # clients = OAuth2Client.query.filter_by(user_id=user.id).all()  
55 - # else:  
56 - # clients = []  
57 - # return render_template('auth/authorize.html', user=user, clients=clients)  
58 -  
59 - # @staticmethod  
60 - # @bp.route('/create_client', methods=('GET', 'POST'))  
61 - # def create_client():  
62 - # user = current_user()  
63 - # if not user:  
64 - # return redirect('/auth/login')  
65 - # if request.method == 'GET':  
66 - # return render_template('auth/create_client.html')  
67 - # form = request.form  
68 - # client_id = gen_salt(24)  
69 - # client = OAuth2Client(client_id=client_id, user_id=user.id)  
70 - # # Mixin doesn't set the issue_at date  
71 - # client.client_id_issued_at = int(time.time())  
72 - # if client.token_endpoint_auth_method == 'none':  
73 - # client.client_secret = ''  
74 - # else:  
75 - # client.client_secret = gen_salt(48)  
76 - # client_metadata = {  
77 - # "client_name": form["client_name"],  
78 - # "client_uri": form["client_uri"],  
79 - # "grant_types": split_by_crlf(form["grant_type"]),  
80 - # "redirect_uris": split_by_crlf(form["redirect_uri"]),  
81 - # "response_types": split_by_crlf(form["response_type"]),  
82 - # "scope": form["scope"],  
83 - # "token_endpoint_auth_method": form["token_endpoint_auth_method"]  
84 - # }  
85 - # client.set_client_metadata(client_metadata)  
86 - # db.session.add(client)  
87 - # db.session.commit()  
88 - # return redirect('/auth/login')  
89 -  
90 - @staticmethod  
91 - @bp.route('/authorize', methods=('GET', 'POST'))  
92 - def authorize():  
93 - user = current_user()  
94 - if request.method == 'GET':  
95 - try:  
96 - grant = authorization.validate_consent_request(end_user=user)  
97 - except OAuth2Error as error:  
98 - return jsonify(dict(error.get_body()))  
99 - return render_template('auth/authorize.html', user=user, grant=grant)  
100 - # return render_template('auth/login1.html', user=user, grant=grant)  
101 - if not user and 'username' in request.form:  
102 - username = request.form.get('username')  
103 - password = request.form.get('password')  
104 - user = User.query.filter_by(  
105 - username=username, password=password).first()  
106 - grant_user = user  
107 - # if request.form['confirm']:  
108 - # grant_user = user  
109 - # else:  
110 - # grant_user = None  
111 - return authorization.create_authorization_response(grant_user=grant_user)  
112 -  
113 - @staticmethod  
114 - @bp.route('/token', methods=['POST'])  
115 - def issue_token():  
116 - return authorization.create_token_response()  
117 -  
118 - @staticmethod  
119 - @bp.route('/userinfo')  
120 - @require_oauth('profile')  
121 - def api_me():  
122 - return jsonify(generate_user_info(current_token.user, current_token.scope)) 1 +from enum import auto
  2 +from logging import error
  3 +from flasgger import swag_from
  4 +from app.util import BlueprintApi
  5 +from app.util import BlueprintApi
  6 +from flask import Blueprint, render_template, redirect, request, session, jsonify
  7 +from sqlalchemy import and_
  8 +from .models import *
  9 +from .oauth2 import authorization, require_oauth, generate_user_info
  10 +from authlib.oauth2 import OAuth2Error
  11 +from authlib.integrations.flask_oauth2 import current_token
  12 +from . import user_create, client_create, client_query, user_query, user_update, user_delete
  13 +
  14 +
  15 +def current_user():
  16 + if "id" in session:
  17 + uid = session["id"]
  18 + return User.query.get(uid)
  19 + return None
  20 +
  21 +
  22 +def remove_user():
  23 + user = current_user()
  24 + if user:
  25 + session.pop("id")
  26 +
  27 +
  28 +def split_by_crlf(s):
  29 + return [v for v in s.splitlines() if v]
  30 +
  31 +
  32 +class DataManager(BlueprintApi):
  33 + bp = Blueprint("Auth", __name__, url_prefix="/auth")
  34 +
  35 + # @staticmethod
  36 + # @bp.route("/test", methods=("GET", "POST"))
  37 + # def Test():
  38 + # res = {}
  39 + # try:
  40 + # res["user"] = User.query.all()
  41 + # except Exception as e:
  42 + # raise e
  43 + # return res
  44 +
  45 + # @staticmethod
  46 + # @bp.route("/login", methods=("GET", "POST"))
  47 + # def Login():
  48 + # if request.method == "POST":
  49 + # username = request.form["username"]
  50 + # password = request.form["password"]
  51 + # user = User.query.filter_by(username=username).first()
  52 + # if not user:
  53 + # user = User(username=username,
  54 + # password=password, role="admin")
  55 + # db.session.add(user)
  56 + # db.session.commit()
  57 + # session["id"] = user.id
  58 + # return redirect("/auth/authorize")
  59 + # user = current_user()
  60 + # if user:
  61 + # clients = OAuth2Client.query.filter_by(user_id=user.id).all()
  62 + # else:
  63 + # clients = []
  64 + # return render_template("auth/authorize.html", user=user, clients=clients)
  65 +
  66 + # @staticmethod
  67 + # @bp.route("/create_client", methods=("GET", "POST"))
  68 + # def create_client():
  69 + # user = current_user()
  70 + # if not user:
  71 + # return redirect("/auth/login")
  72 + # if request.method == "GET":
  73 + # return render_template("auth/create_client.html")
  74 + # form = request.form
  75 + # client_id = gen_salt(24)
  76 + # client = OAuth2Client(client_id=client_id, user_id=user.id)
  77 + # # Mixin doesn"t set the issue_at date
  78 + # client.client_id_issued_at = int(time.time())
  79 + # if client.token_endpoint_auth_method == "none":
  80 + # client.client_secret = ""
  81 + # else:
  82 + # client.client_secret = gen_salt(48)
  83 + # client_metadata = {
  84 + # "client_name": form["client_name"],
  85 + # "client_uri": form["client_uri"],
  86 + # "grant_types": split_by_crlf(form["grant_type"]),
  87 + # "redirect_uris": split_by_crlf(form["redirect_uri"]),
  88 + # "response_types": split_by_crlf(form["response_type"]),
  89 + # "scope": form["scope"],
  90 + # "token_endpoint_auth_method": form["token_endpoint_auth_method"]
  91 + # }
  92 + # client.set_client_metadata(client_metadata)
  93 + # db.session.add(client)
  94 + # db.session.commit()
  95 + # return redirect("/auth/login")
  96 +
  97 + @staticmethod
  98 + @bp.route("/authorize", methods=("GET", "POST"))
  99 + def authorize():
  100 + user = current_user()
  101 + if request.method == "GET":
  102 + # 没有登录,跳转到登录界面
  103 + try:
  104 + grant = authorization.validate_consent_request(end_user=user)
  105 + except OAuth2Error as error:
  106 + return jsonify(dict(error.get_body()))
  107 + if not user:
  108 + return render_template("auth/authorize.html", user=user, grant=grant)
  109 + # return render_template("auth/login1.html", user=user, grant=grant)
  110 + error = ""
  111 + if not user:
  112 + if not "username" in request.form or not request.form.get("username"):
  113 + error = "用户名不可为空"
  114 + elif not "password" in request.form or not request.form.get("password"):
  115 + error = "密码不可为空"
  116 + else:
  117 + username = request.form.get("username")
  118 + password = request.form.get("password")
  119 + user = User.query.filter_by(
  120 + username=username, password=password).first()
  121 + if not user:
  122 + error = "账号或密码不正确"
  123 +
  124 + if user:
  125 + session["id"] = user.id
  126 + grant_user = user
  127 + return authorization.create_authorization_response(grant_user=grant_user)
  128 +
  129 + try:
  130 + grant = authorization.validate_consent_request(end_user=user)
  131 + except OAuth2Error as error:
  132 + return jsonify(dict(error.get_body()))
  133 + return render_template("auth/authorize.html", user=user, grant=grant, error=error)
  134 +
  135 + # if request.form["confirm"]:
  136 + # grant_user = user
  137 + # else:
  138 + # grant_user = None
  139 +
  140 + @staticmethod
  141 + @bp.route("/token", methods=["POST"])
  142 + def issue_token():
  143 + return authorization.create_token_response()
  144 +
  145 + @staticmethod
  146 + @bp.route("/userinfo")
  147 + @require_oauth("profile")
  148 + def api_me():
  149 + try:
  150 + return jsonify(generate_user_info(current_token.user, current_token.scope))
  151 + except error as e:
  152 + return jsonify(dict(e.get_body()))
  153 +
  154 + @staticmethod
  155 + @bp.route("/logout", methods=["GET"])
  156 + # @require_oauth("profile")
  157 + def logout():
  158 + url = ''
  159 + try:
  160 + user = current_user()
  161 + grant = authorization.validate_consent_request(end_user=user)
  162 + access_token = request.args.get("accesstoken")
  163 + accesstoken = OAuth2Token.query.filter_by(
  164 + access_token=access_token).first()
  165 + accesstoken.revoked = True
  166 + db.session.commit()
  167 + remove_user()
  168 + if accesstoken:
  169 + url = grant.client.client_uri
  170 + except OAuth2Error as error:
  171 + return jsonify(dict(error.get_body()))
  172 + return redirect(url)
  173 + # if current_token:
  174 + # remove_user()
  175 + # # accesstoken = OAuth2Token.query.filter_by(
  176 + # # access_token=current_token.access_token).first()
  177 + # try:
  178 + # # accesstoken.revoked = True
  179 + # # db.session.commit()
  180 + # except error as e:
  181 + # return jsonify(dict(e.get_body()))
  182 + # else:
  183 + # return jsonify({"result": False, "message": "access_token is null"})
  184 +
  185 + # return jsonify({"result": True, "message": "logout success"})
  186 +
  187 + """接口"""
  188 + @staticmethod
  189 + @bp.route("/users", methods=["GET"])
  190 + @swag_from(user_query.Api.api_doc)
  191 + def user_query():
  192 + """
  193 + 获取用户列表
  194 + """
  195 + return user_query.Api().result
  196 +
  197 + @staticmethod
  198 + @bp.route("/users", methods=["POST"])
  199 + @swag_from(user_create.Api.api_doc)
  200 + def user_create():
  201 + """
  202 + 创建用户
  203 + """
  204 + return user_create.Api().result
  205 +
  206 + @staticmethod
  207 + @bp.route("/userEdit", methods=["POST"])
  208 + @swag_from(user_update.Api.api_doc)
  209 + def user_update():
  210 + """
  211 + 更新用户信息
  212 + """
  213 + return user_update.Api().result
  214 +
  215 + @staticmethod
  216 + @bp.route("/userDelete", methods=["POST"])
  217 + @swag_from(user_delete.Api.api_doc)
  218 + def user_delete():
  219 + """
  220 + 删除用户
  221 + """
  222 + return user_delete.Api().result
  223 +
  224 + @staticmethod
  225 + @bp.route("/client", methods=["POST"])
  226 + @swag_from(client_create.Api.api_doc)
  227 + def client_create():
  228 + """
  229 + 创建client
  230 + """
  231 + return client_create.Api().result
  232 +
  233 + @staticmethod
  234 + @bp.route("/client", methods=["GET"])
  235 + @swag_from(client_query.Api.api_doc)
  236 + def client_query():
  237 + """
  238 + 获取client列表
  239 + """
  240 + return client_query.Api().result
  1 +# coding=utf-8
  2 +#author: qianyingz
  3 +#createtime: 2021/8/13
  4 +#email: qianyingz@chinadci.com
  5 +
  6 +from re import split
  7 +from .models import *
  8 +from app.util.component.ApiTemplate import ApiTemplate
  9 +from werkzeug.security import gen_salt
  10 +import time
  11 +import string
  12 +
  13 +
  14 +class Api(ApiTemplate):
  15 + api_name = "注册客户端"
  16 +
  17 + def para_check(self):
  18 + if not self.para.get("name"):
  19 + raise Exception("name is null")
  20 + if not self.para.get("uri"):
  21 + raise Exception("uri is null")
  22 + if not self.para.get("redirect_uris"):
  23 + raise Exception("redirect_uris is null")
  24 + # if not self.para.get('username'):
  25 + # raise Exception("username is null")
  26 + # if not self.para.get("scope"):
  27 + # raise Exception("scope is null")
  28 + # if not self.para.get("grant_type"):
  29 + # raise Exception("grant_type is null")
  30 + # if not self.para.get("response_type"):
  31 + # raise Exception("response_type is null")
  32 +
  33 + def process(self):
  34 +
  35 + # 返回结果
  36 + res = {}
  37 + res["result"] = False
  38 + try:
  39 + # 默认值
  40 + scope = "openid profile"
  41 + grant_type = ["authorization_code"]
  42 + response_type = ["code"]
  43 + auth_method = "client_secret_basic"
  44 + # 业务逻辑
  45 + username = self.para.get("username")
  46 + client_id = gen_salt(24)
  47 + name = self.para.get("name")
  48 + uri = self.para.get("uri")
  49 + redirect_uris = self.para.get("redirect_uris").split(",")
  50 +
  51 + if not username:
  52 + username = 'admin'
  53 + user = User.query.filter_by(username=username).first()
  54 + if not User:
  55 + res["msg"] = "username 指定用户不存在"
  56 + res["data"] = {}
  57 + res["result"] = False
  58 + else:
  59 + client = OAuth2Client(client_id=client_id, user_id=user.id)
  60 + # Mixin doesn"t set the issue_at date
  61 + client.client_id_issued_at = int(time.time())
  62 + if client.token_endpoint_auth_method == "none":
  63 + client.client_secret = ""
  64 + else:
  65 + client.client_secret = gen_salt(48)
  66 + client_metadata = {
  67 + "client_name": name,
  68 + "client_uri": uri,
  69 + "grant_types": grant_type,
  70 + "redirect_uris": redirect_uris,
  71 + "response_types": response_type,
  72 + "scope": scope,
  73 + "token_endpoint_auth_method": auth_method
  74 + }
  75 + client.set_client_metadata(client_metadata)
  76 + db.session.add(client)
  77 + db.session.commit()
  78 + res["msg"] = "创建client成功"
  79 + res["data"] = {"client_secret": client.client_secret,
  80 + "client_id": client.client_id}
  81 + res["result"] = True
  82 + except Exception as e:
  83 + db.session.rollback()
  84 + raise e
  85 + return res
  86 +
  87 + api_doc = {
  88 +
  89 + "tags": ["认证接口"],
  90 + "parameters": [
  91 + {"name": "name",
  92 + "in": "formData",
  93 + "type": "string",
  94 + "description": "客户端名称",
  95 + "required": "true"},
  96 + {"name": "uri",
  97 + "in": "formData",
  98 + "type": "string",
  99 + "description": "客户端地址,多个地址用,连接",
  100 + "required": "true"},
  101 + {"name": "redirect_uris",
  102 + "in": "formData",
  103 + "type": "string",
  104 + "description": "重定向地址",
  105 + "required": "true"},
  106 + {"name": "username",
  107 + "in": "formData",
  108 + "type": "string",
  109 + "description": "注册client账号,默认使用admin"
  110 + },
  111 + # {"name": "scope",
  112 + # "in": "formData",
  113 + # "type": "string",
  114 + # "description": "范围"},
  115 + # {"name": "grant_type",
  116 + # "in": "formData",
  117 + # "type": "string",
  118 + # "description": "授权类型: authorization_code"},
  119 + # {"name": "response_type",
  120 + # "in": "formData",
  121 + # "type": "string",
  122 + # "description": "授权类型: code"}
  123 + ],
  124 + "responses": {
  125 + 200: {
  126 + "schema": {
  127 + "properties": {
  128 + }
  129 + }
  130 + }
  131 + }
  132 + }
  1 +# coding=utf-8
  2 +#author: qianyingz
  3 +#createtime: 2021/8/13
  4 +#email: qianyingz@chinadci.com
  5 +
  6 +from .models import *
  7 +from app.util.component.ApiTemplate import ApiTemplate
  8 +from werkzeug.security import gen_salt
  9 +
  10 +class Api(ApiTemplate):
  11 + api_name = "获取client列表"
  12 +
  13 + def para_check(self):
  14 + pass
  15 +
  16 + def process(self):
  17 + # 返回结果
  18 + res = {}
  19 + res["result"] = False
  20 + res["data"] = []
  21 + try:
  22 + # 默认值
  23 + name = self.para.get("name")
  24 + if name:
  25 + clients = OAuth2Client.query.filter_by(client_name=name).all()
  26 + else:
  27 + clients = OAuth2Client.query.all()
  28 + for client in clients:
  29 + res["data"].append(
  30 + {'client_id': client.client_id,
  31 + 'client_secret': client.client_secret,
  32 + 'client_id_issued_at': client.client_id_issued_at,
  33 + 'client_secret_expires_at': client.client_secret_expires_at,
  34 + 'client_metadata': client.client_metadata,
  35 + 'id': client.id,
  36 + 'user_id': client.user_id
  37 + })
  38 + res["msg"] = "获取clients集合成功"
  39 + res["result"] = True
  40 + except Exception as e:
  41 + db.session.rollback()
  42 + raise e
  43 + return res
  44 +
  45 + api_doc = {
  46 +
  47 + "tags": ["认证接口"],
  48 + "parameters": [
  49 + {"name": "name",
  50 + "in": "formData",
  51 + "type": "string",
  52 + "description": "客户端名称"}
  53 + ],
  54 + "responses": {
  55 + 200: {
  56 + "schema": {
  57 + "properties": {
  58 + }
  59 + }
  60 + }
  61 + }
  62 + }
1 -from flask_sqlalchemy import sqlalchemy  
2 -from sqlalchemy import Column, Integer, Text, Time, ForeignKey  
3 -from app.models import db  
4 -from authlib.integrations.sqla_oauth2 import (  
5 - OAuth2ClientMixin,  
6 - OAuth2TokenMixin,  
7 - OAuth2AuthorizationCodeMixin  
8 -)  
9 -from sqlalchemy.orm import relationship  
10 -  
11 -  
12 -class User (db.Model):  
13 - '''  
14 - 用户信息表  
15 - '''  
16 - __tablename__ = "dmdms_user"  
17 - id = Column(Integer, primary_key=True)  
18 - username = Column(Text)  
19 - password = Column(Text)  
20 - company = Column(Text)  
21 - position = Column(Text)  
22 - phone = Column(Text)  
23 - email = Column(Text)  
24 - create_time = Column(Time)  
25 - update_time = Column(Time)  
26 - role = Column(Text)  
27 -  
28 - def __str__(self):  
29 - return self.username  
30 -  
31 - def get_user_id(self):  
32 - return self.id  
33 -  
34 -  
35 -class OAuth2Client(db.Model, OAuth2ClientMixin):  
36 - __tablename__ = 'oauth2_client'  
37 -  
38 - id = Column(Integer, primary_key=True)  
39 - user_id = Column(  
40 - Integer, ForeignKey('dmdms_user.id', ondelete='CASCADE'))  
41 - user = relationship('User')  
42 -  
43 -  
44 -class OAuth2AuthorizationCode(db.Model, OAuth2AuthorizationCodeMixin):  
45 - __tablename__ = 'oauth2_code'  
46 -  
47 - id = Column(Integer, primary_key=True)  
48 - user_id = Column(  
49 - Integer, ForeignKey('dmdms_user.id', ondelete='CASCADE'))  
50 - user = relationship('User')  
51 -  
52 -  
53 -class OAuth2Token(db.Model, OAuth2TokenMixin):  
54 - __tablename__ = 'oauth2_token'  
55 -  
56 - id = Column(Integer, primary_key=True)  
57 - user_id = Column(  
58 - Integer, ForeignKey('dmdms_user.id', ondelete='CASCADE'))  
59 - user = relationship('User') 1 +from flask_sqlalchemy import sqlalchemy
  2 +from sqlalchemy import Column, Integer, Text, Time, ForeignKey
  3 +from app.models import db
  4 +from authlib.integrations.sqla_oauth2 import (
  5 + OAuth2ClientMixin,
  6 + OAuth2TokenMixin,
  7 + OAuth2AuthorizationCodeMixin
  8 +)
  9 +from sqlalchemy.orm import relationship
  10 +
  11 +
  12 +class User (db.Model):
  13 + '''
  14 + 用户信息表
  15 + '''
  16 + __tablename__ = "dmdms_user"
  17 + id = Column(Integer, primary_key=True)
  18 + username = Column(Text)
  19 + password = Column(Text)
  20 + company = Column(Text)
  21 + position = Column(Text)
  22 + phone = Column(Text)
  23 + email = Column(Text)
  24 + create_time = Column(Time)
  25 + update_time = Column(Time)
  26 + role = Column(Text)
  27 +
  28 + def __str__(self):
  29 + return self.username
  30 +
  31 + def get_user_id(self):
  32 + return self.id
  33 +
  34 +
  35 +class OAuth2Client(db.Model, OAuth2ClientMixin):
  36 + __tablename__ = 'dmdms_oauth2_client'
  37 +
  38 + id = Column(Integer, primary_key=True)
  39 + user_id = Column(
  40 + Integer, ForeignKey('dmdms_user.id', ondelete='CASCADE'))
  41 + user = relationship('User')
  42 +
  43 +
  44 +class OAuth2AuthorizationCode(db.Model, OAuth2AuthorizationCodeMixin):
  45 + __tablename__ = 'dmdms_oauth2_code'
  46 +
  47 + id = Column(Integer, primary_key=True)
  48 + user_id = Column(
  49 + Integer, ForeignKey('dmdms_user.id', ondelete='CASCADE'))
  50 + user = relationship('User')
  51 +
  52 +
  53 +class OAuth2Token(db.Model, OAuth2TokenMixin):
  54 + __tablename__ = 'dmdms_oauth2_token'
  55 +
  56 + id = Column(Integer, primary_key=True)
  57 + user_id = Column(
  58 + Integer, ForeignKey('dmdms_user.id', ondelete='CASCADE'))
  59 + # name = Column(Text)
  60 + user = relationship('User')
  1 +from os import access, remove
  2 +from time import time
1 from authlib.integrations.flask_oauth2 import ( 3 from authlib.integrations.flask_oauth2 import (
2 AuthorizationServer, ResourceProtector) 4 AuthorizationServer, ResourceProtector)
3 from authlib.integrations.sqla_oauth2 import ( 5 from authlib.integrations.sqla_oauth2 import (
@@ -13,11 +15,12 @@ from authlib.oidc.core.grants import ( @@ -13,11 +15,12 @@ from authlib.oidc.core.grants import (
13 OpenIDImplicitGrant as _OpenIDImplicitGrant, 15 OpenIDImplicitGrant as _OpenIDImplicitGrant,
14 OpenIDHybridGrant as _OpenIDHybridGrant, 16 OpenIDHybridGrant as _OpenIDHybridGrant,
15 ) 17 )
16 -from authlib.oidc.core import UserInfo 18 +from authlib.oidc.core import UserInfo, CodeIDToken, IDToken
  19 +from sqlalchemy.sql.sqltypes import DateTime
17 from werkzeug.security import gen_salt 20 from werkzeug.security import gen_salt
18 from .models import db, User 21 from .models import db, User
19 from .models import OAuth2Client, OAuth2AuthorizationCode, OAuth2Token 22 from .models import OAuth2Client, OAuth2AuthorizationCode, OAuth2Token
20 - 23 +from flask import g
21 24
22 DUMMY_JWT_CONFIG = { 25 DUMMY_JWT_CONFIG = {
23 'key': 'secret-key', 26 'key': 'secret-key',
@@ -26,6 +29,17 @@ DUMMY_JWT_CONFIG = { @@ -26,6 +29,17 @@ DUMMY_JWT_CONFIG = {
26 'exp': 7200, 29 'exp': 7200,
27 } 30 }
28 31
  32 +class myCodeIDToken(CodeIDToken):
  33 + def validate(self, now, leeway):
  34 + return super().validate(now=now, leeway=leeway)
  35 +
  36 + def validate_exp(self, now, leeway):
  37 + return super().validate_exp(now, leeway)
  38 +
  39 +
  40 +def validate_token(accesstoken):
  41 + return IDToken.validate(self=accesstoken)
  42 +
29 43
30 def exists_nonce(nonce, req): 44 def exists_nonce(nonce, req):
31 exists = OAuth2AuthorizationCode.query.filter_by( 45 exists = OAuth2AuthorizationCode.query.filter_by(
@@ -119,11 +133,12 @@ def config_oauth(app): @@ -119,11 +133,12 @@ def config_oauth(app):
119 app, 133 app,
120 query_client=query_client, 134 query_client=query_client,
121 save_token=save_token 135 save_token=save_token
  136 + # fetch_token=fetch_token
122 ) 137 )
123 138
124 # support all openid grants 139 # support all openid grants
125 authorization.register_grant(AuthorizationCodeGrant, [ 140 authorization.register_grant(AuthorizationCodeGrant, [
126 - OpenIDCode(require_nonce=True), 141 + OpenIDCode(require_nonce=True)
127 ]) 142 ])
128 authorization.register_grant(ImplicitGrant) 143 authorization.register_grant(ImplicitGrant)
129 authorization.register_grant(HybridGrant) 144 authorization.register_grant(HybridGrant)
  1 +# coding=utf-8
  2 +#author: qianyingz
  3 +#createtime: 2021/8/13
  4 +#email: qianyingz@chinadci.com
  5 +
  6 +from .models import *
  7 +from app.util.component.ApiTemplate import ApiTemplate
  8 +import time
  9 +
  10 +
  11 +class Api(ApiTemplate):
  12 + api_name = "创建用户"
  13 +
  14 + def para_check(self):
  15 + if not self.para.get("username"):
  16 + raise Exception("username is null")
  17 + if not self.para.get("pwd"):
  18 + raise Exception("pwd is null")
  19 + if not self.para.get("role"):
  20 + raise Exception("role is null")
  21 +
  22 + def process(self):
  23 +
  24 + # 返回结果
  25 + res = {}
  26 + res["result"] = False
  27 + try:
  28 + # 业务逻辑
  29 + username = self.para.get("username")
  30 + password = self.para.get("pwd")
  31 + role = self.para.get("role")
  32 + company = self.para.get("company", None)
  33 + position = self.para.get("position", None)
  34 + email = self.para.get("email", None)
  35 + phone = self.para.get("phone", None)
  36 + # 是否重名
  37 + if(User.query.filter_by(username=username).one_or_none()):
  38 + res["msg"] = "username 已存在"
  39 + else:
  40 + user = User(username=username, password=password, role=role,
  41 + phone=phone, company=company, position=position, email=email,
  42 + create_time=time.strftime(
  43 + "%Y-%m-%d %H:%M:%S", time.localtime()),
  44 + update_time=time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
  45 + db.session.add(user)
  46 + db.session.commit()
  47 + res["msg"] = "用户创建成功"
  48 + res["data"] = {"id": user.id,
  49 + "username": user.username, "role": user.role}
  50 + res["result"] = True
  51 + except Exception as e:
  52 + db.session.rollback()
  53 + raise e
  54 + return res
  55 +
  56 + api_doc = {
  57 +
  58 + "tags": ["认证接口"],
  59 + "parameters": [
  60 + {"name": "username",
  61 + "in": "formData",
  62 + "type": "string",
  63 + "description": "用户名",
  64 + "required": "true"},
  65 + {"name": "pwd",
  66 + "in": "formData",
  67 + "type": "string",
  68 + "description": "密码",
  69 + "required": "true"},
  70 + {"name": "role",
  71 + "in": "formData",
  72 + "type": "string",
  73 + "description": "角色",
  74 + "required": "true"},
  75 + {"name": "company",
  76 + "in": "formData",
  77 + "type": "string",
  78 + "description": "单位",
  79 + "required": ""},
  80 + {"name": "email",
  81 + "in": "formData",
  82 + "type": "string",
  83 + "description": "邮件",
  84 + "required": ""},
  85 + {"name": "phone",
  86 + "in": "formData",
  87 + "type": "string",
  88 + "description": "电话",
  89 + "required": ""},
  90 + {"name": "position",
  91 + "in": "formData",
  92 + "type": "string",
  93 + "description": "职位",
  94 + "required": ""},
  95 + ],
  96 + "responses": {
  97 + 200: {
  98 + "schema": {
  99 + "properties": {
  100 + }
  101 + }
  102 + }
  103 + }
  104 + }
  1 +from app.util.component.ApiTemplate import ApiTemplate
  2 +import time
  3 +from .models import *
  4 +
  5 +
  6 +class Api(ApiTemplate):
  7 + api_name = "更新用户信息"
  8 +
  9 + def para_check(self):
  10 + if not self.para.get("guid"):
  11 + raise Exception("guid is null")
  12 + return super().para_check()
  13 +
  14 + def process(self):
  15 + res = {}
  16 + res["result"] = False
  17 + try:
  18 + user_guid = int(self.para.get("guid"))
  19 + userinfo = User.query.filter_by(id=user_guid).one_or_none()
  20 + if not userinfo:
  21 + res["msg"] = "用户不存在"
  22 + else:
  23 + db.session.delete(userinfo)
  24 + db.session.commit()
  25 + res["result"] = True
  26 + res["msg"] = "删除用户成功"
  27 + except Exception as e:
  28 + db.session.rollback()
  29 + raise e
  30 + return res
  31 +
  32 + api_doc = {
  33 + "tags": ["认证接口"],
  34 + "parameters": [
  35 + {"name": "guid",
  36 + "in": "formData",
  37 + "type": "string",
  38 + "description": "用户id",
  39 + "required": "true"}
  40 + ],
  41 + "responses": {
  42 + 200: {
  43 + "schema": {
  44 + "properties": {
  45 + }
  46 + }
  47 + }
  48 + }
  49 + }
  1 +# coding=utf-8
  2 +#author: qianyingz
  3 +#createtime: 2021/8/14
  4 +#email: qianyingz@chinadci.com
  5 +
  6 +from authlib.oidc.core.claims import UserInfo
  7 +from .models import *
  8 +from app.util.component.ApiTemplate import ApiTemplate
  9 +
  10 +
  11 +class Api(ApiTemplate):
  12 + api_name = "获取用户列表"
  13 +
  14 + def para_check(self):
  15 + pass
  16 +
  17 + def process(self):
  18 + # 返回结果
  19 + res = {}
  20 + res["result"] = False
  21 + try:
  22 + # 业务逻辑
  23 + pass
  24 + page_index = int(self.para.get("page_index", "0"))
  25 + page_size = int(self.para.get("page_size", "1000"))
  26 + name = self.para.get("name")
  27 + id = self.para.get('guid')
  28 +
  29 + if id:
  30 + tmp_user = User.query.filter_by(id=id).first()
  31 + res["data"] = {"guid": tmp_user.id, "username": tmp_user.username,
  32 + "role": tmp_user.role, "company": tmp_user.company,
  33 + "position": tmp_user.position, "email": tmp_user.email,
  34 + "phone": tmp_user.phone}
  35 + else:
  36 + # 获取集合
  37 + userLinq = User.query.order_by(User.id.desc())
  38 + if name:
  39 + userLinq = userLinq.filter(
  40 + User.username.like("%" + name + "%"))
  41 + tmp_count = userLinq.count()
  42 + tmp_list = userLinq.limit(page_size).offset(
  43 + page_index * page_size).all()
  44 + res["data"] = {
  45 + "count": tmp_count,
  46 + "list": list(map(lambda t:
  47 + {"guid": t.id, "username": t.username,
  48 + "role": t.role},
  49 + tmp_list))}
  50 + res["result"] = True
  51 +
  52 + except Exception as e:
  53 + raise e
  54 + return res
  55 +
  56 + api_doc = {
  57 +
  58 + "tags": ["认证接口"],
  59 + "parameters": [
  60 + {"name": "page_index",
  61 + "in": "query",
  62 + "type": "int",
  63 + "description": "当前页",
  64 + "default": 0},
  65 + {"name": "page_size",
  66 + "in": "query",
  67 + "type": "int",
  68 + "description": "条数",
  69 + "default": 1000},
  70 + {"name": "name",
  71 + "in": "query",
  72 + "type": "string",
  73 + "description": "名称关键字"},
  74 + {"name": "guid",
  75 + "in": "query",
  76 + "type": "string",
  77 + "description": "用户id,用于获取用户信息"}
  78 + ],
  79 + "responses": {
  80 + 200: {
  81 + "schema": {
  82 + "properties": {
  83 + }
  84 + }
  85 + }
  86 + }
  87 + }
  1 +from app.util.component.ApiTemplate import ApiTemplate
  2 +import time
  3 +from .models import *
  4 +
  5 +
  6 +class Api(ApiTemplate):
  7 + api_name = "更新用户信息"
  8 +
  9 + def para_check(self):
  10 + if not self.para.get("guid"):
  11 + raise Exception("guid is null")
  12 + return super().para_check()
  13 +
  14 + def process(self):
  15 + res = {}
  16 + res["result"] = False
  17 + try:
  18 + user_guid = int(self.para.get("guid"))
  19 + obj_value = {"company": "company", "email": "email",
  20 + "position": "position", "phone": "phone"}
  21 +
  22 + userinfo = User.query.filter_by(id=user_guid)
  23 + if not userinfo.one_or_none():
  24 + res["msg"] = "数据不存在"
  25 + else:
  26 + # 更新密码要求同时输入pwd/newPwd/reNewPwd
  27 + if self.para.__contains__("pwd") or self.para.__contains__("newPwd") or self.para.__contains__("reNewPwd"):
  28 + password = self.para.get("pwd")
  29 + new_password = self.para.get("newPwd")
  30 + re_new_password = self.para.get("reNewPwd")
  31 +
  32 + # validate pwd
  33 + if not password:
  34 + res["result"] = False
  35 + res["msg"] = "无原密码"
  36 + return res
  37 + if new_password != re_new_password:
  38 + res["result"] = False
  39 + res["msg"] = "两次输入密码不一致"
  40 + return res
  41 + if userinfo.first().password != password:
  42 + res["result"] = False
  43 + res["msg"] = "原密码输入错误"
  44 + return res
  45 +
  46 + # 更新密码
  47 + userinfo.update({"password": new_password})
  48 +
  49 + #更新用户基本信息
  50 + for key in obj_value:
  51 + if self.para.__contains__(obj_value[key]):
  52 + value = self.para.get(obj_value[key])
  53 + value = "" if value == "None" or value == "none" else value
  54 + userinfo.update({key: value})
  55 +
  56 + db.session.commit()
  57 + res["result"] = True
  58 + res["msg"] = "更新用户信息成功"
  59 + except Exception as e:
  60 + db.session.rollback()
  61 + raise e
  62 + return res
  63 +
  64 + api_doc = {
  65 + "tags": ["认证接口"],
  66 + "parameters": [
  67 + {"name": "guid",
  68 + "in": "formData",
  69 + "type": "string",
  70 + "description": "用户id",
  71 + "required": "true"},
  72 + {"name": "pwd",
  73 + "in": "formData",
  74 + "type": "string",
  75 + "description": "密码",
  76 + "required": ""},
  77 + {"name": "newPwd",
  78 + "in": "formData",
  79 + "type": "string",
  80 + "description": "密码",
  81 + "required": ""},
  82 + {"name": "reNewPwd",
  83 + "in": "formData",
  84 + "type": "string",
  85 + "description": "密码",
  86 + "required": ""},
  87 + {"name": "company",
  88 + "in": "formData",
  89 + "type": "string",
  90 + "description": "单位",
  91 + "required": ""},
  92 + {"name": "email",
  93 + "in": "formData",
  94 + "type": "string",
  95 + "description": "邮件",
  96 + "required": ""},
  97 + {"name": "phone",
  98 + "in": "formData",
  99 + "type": "string",
  100 + "description": "电话",
  101 + "required": ""},
  102 + {"name": "position",
  103 + "in": "formData",
  104 + "type": "string",
  105 + "description": "职位",
  106 + "required": ""},
  107 + ],
  108 + "responses": {
  109 + 200: {
  110 + "schema": {
  111 + "properties": {
  112 + }
  113 + }
  114 + }
  115 + }
  116 + }
1 -html,  
2 -body {  
3 - font-family: Microsoft YaHei Regular, Microsoft YaHei Regular-Regular;  
4 -}  
5 -  
6 -html,  
7 -body,  
8 -p,  
9 -input {  
10 - margin: 0;  
11 - padding: 0;  
12 -}  
13 -  
14 -.login {  
15 - background: url(../images/login_background.png) no-repeat;  
16 - background-size: 100% 100%;  
17 - width: 100%;  
18 - height: 100%;  
19 - position: relative;  
20 -}  
21 -  
22 -.login-container {  
23 - position: absolute;  
24 - top: -50px;  
25 - bottom: 0;  
26 - left: 0;  
27 - right: 0;  
28 - margin: auto;  
29 - width: 900px;  
30 - height: 454px;  
31 - background: #ffffff;  
32 - border-radius: 4px;  
33 - box-shadow: 2px 0 21px 0 rgba(38, 106, 184, 0.53);  
34 -}  
35 -  
36 -.login-container-logo {  
37 - margin: 0;  
38 - background: url(../images/login_logo.png) no-repeat;  
39 - width: 401px;  
40 - height: 455px;  
41 - overflow: hidden;  
42 - float: left;  
43 -}  
44 -  
45 -.login-container-header {  
46 - font-size: 22px;  
47 - font-weight: 700;  
48 - text-align: left;  
49 - color: #545454;  
50 - letter-spacing: 1px;  
51 - text-align: center;  
52 - margin-bottom: 54px;  
53 -}  
54 -  
55 -.login-container-form {  
56 - margin-left: 401px;  
57 - height: 100%;  
58 - padding: 80px;  
59 -}  
60 -  
61 -.login-container-form .form-group {  
62 - width: 296px;  
63 - margin: 0 auto;  
64 - margin-top: 22px;  
65 -}  
66 -  
67 -.login-container-form .has-feedback.feedback-left .form-control-feedback {  
68 - left: 0;  
69 - right: auto;  
70 - width: 38px;  
71 - height: 45px;  
72 - line-height: 45px;  
73 - z-index: 4;  
74 - color: #dcdcdc;  
75 - font-size: 16px;  
76 -}  
77 -  
78 -.login-container-form .has-feedback.feedback-left .micons-pwd {  
79 - font-size: 18px;  
80 - line-height: 48px;  
81 -}  
82 -  
83 -.login-container-form .has-feedback.feedback-left .form-control {  
84 - padding-left: 38px;  
85 - padding-right: 12px;  
86 - border: 1px solid #ebebeb;  
87 - border-radius: 4px;  
88 - height: 45px;  
89 - color: #999;  
90 - font-size: 16px;  
91 - letter-spacing: 1px;  
92 -}  
93 -  
94 -.login-container-form .has-feedback.feedback-left .form-control:hover,  
95 -.login-container-form .has-feedback.feedback-left .form-control:hover,  
96 -.login-container-form .has-feedback.feedback-left .form-control:focus {  
97 - border: 1px solid #3081c3;  
98 - outline: unset;  
99 - box-shadow: unset;  
100 -}  
101 -  
102 -.login-container-form .overhidden {  
103 - padding-left: 24px;  
104 - font-size: 14px;  
105 - color: #999999;  
106 - vertical-align: bottom;  
107 - line-height: 18px;  
108 -}  
109 -  
110 -.login-container-form .overhidden:hover {  
111 - color: #3081c3;  
112 -}  
113 -  
114 -.login-container-form .ftdms-checkbox span::before {  
115 - height: 15px;  
116 - width: 15px;  
117 - border-width: 1px;  
118 - top: 2px;  
119 -}  
120 -  
121 -#btn-login {  
122 - background: #3081c3;  
123 - height: 45px;  
124 - font-size: 16px;  
125 - font-weight: 400;  
126 - color: #ffffff;  
127 - letter-spacing: 1px;  
128 -}  
129 -  
130 -#btn-login:hover {  
131 - background: #2ba3f6;  
132 -}  
133 -  
134 -.form-control:focus,  
135 -.form-control:hover {  
136 - box-shadow: unset;  
137 - border: 1px solid #3081c3 !important;  
138 -}  
139 -  
140 -.form-control {  
141 - width: 100%;  
142 -}  
143 -  
144 -.btn-info.btn-info:active {  
145 - border: 1px solid;  
146 -}  
147 -  
148 -.btn {  
149 - padding: 8px 12px;  
150 - border-radius: 2px;  
151 - outline: none !important;  
152 - -webkit-transition: 0.15s linear;  
153 - transition: 0.15s linear;  
154 -}  
155 -  
156 -button {  
157 - display: block;  
158 - width: 100%;  
159 - margin-bottom: 0;  
160 - line-height: 1.42857143;  
161 - text-align: center;  
162 - white-space: nowrap;  
163 - touch-action: manipulation;  
164 - cursor: pointer;  
165 - user-select: none;  
166 - font-family: inherit;  
167 - overflow: visible;  
168 - margin: 0;  
169 - font: inherit;  
170 - outline: none !important;  
171 -}  
172 -  
173 -.ftdms-checkbox span::before,  
174 -.ftdms-radio span::before {  
175 - content: '';  
176 - position: absolute;  
177 - display: inline-block;  
178 - height: 18px;  
179 - width: 18px;  
180 - left: 0.5px;  
181 - top: 0px;  
182 - border: 2px solid #ebebeb;  
183 - -webkit-transition: all 0.1s;  
184 - -o-transition: all 0.1s;  
185 - transition: all 0.1s;  
186 -}  
187 -  
188 -:after,  
189 -:before {  
190 - -webkit-box-sizing: border-box;  
191 - -moz-box-sizing: border-box;  
192 - box-sizing: border-box; 1 +html,
  2 +body {
  3 + font-family: Microsoft YaHei Regular, Microsoft YaHei Regular-Regular;
  4 +}
  5 +
  6 +html,
  7 +body,
  8 +p,
  9 +input {
  10 + margin: 0;
  11 + padding: 0;
  12 +}
  13 +
  14 +.login {
  15 + background: url(../images/login_background.png) no-repeat;
  16 + background-size: 100% 100%;
  17 + width: 100%;
  18 + height: 100%;
  19 + position: relative;
  20 +}
  21 +
  22 +.login-container {
  23 + position: absolute;
  24 + top: -50px;
  25 + bottom: 0;
  26 + left: 0;
  27 + right: 0;
  28 + margin: auto;
  29 + width: 900px;
  30 + height: 454px;
  31 + background: #ffffff;
  32 + border-radius: 4px;
  33 + box-shadow: 2px 0 21px 0 rgba(38, 106, 184, 0.53);
  34 +}
  35 +
  36 +.login-container-logo {
  37 + margin: 0;
  38 + background: url(../images/login_logo.png) no-repeat;
  39 + width: 401px;
  40 + height: 455px;
  41 + overflow: hidden;
  42 + float: left;
  43 +}
  44 +
  45 +.login-container-header {
  46 + font-size: 22px;
  47 + font-weight: 700;
  48 + text-align: left;
  49 + color: #545454;
  50 + letter-spacing: 1px;
  51 + text-align: center;
  52 + margin-bottom: 54px;
  53 +}
  54 +
  55 +.login-container-header-small.login-container-header {
  56 + font-size: 22px;
  57 + font-weight: 700;
  58 + text-align: left;
  59 + color: #545454;
  60 + letter-spacing: 1px;
  61 + text-align: center;
  62 + margin-bottom: 22px;
  63 +}
  64 +
  65 +.login-container-form {
  66 + margin-left: 401px;
  67 + height: 100%;
  68 + padding: 80px;
  69 +}
  70 +
  71 +.login-container-form .form-tip {
  72 + margin-left: 21.5px;
  73 + color: red;
  74 + margin-bottom: 10px;
  75 + padding: 5px 6px;
  76 + width: 296px;
  77 + background: #ffebeb;
  78 + border: 1px solid #faccc6;
  79 + font-size: 11px;
  80 + border-radius: 4px;
  81 +}
  82 +
  83 +.login-container-form .form-tip {
  84 + height: 32px;
  85 +}
  86 +
  87 +.login-container-form .form-tip p {
  88 + margin: 0 0 0 5px;
  89 + line-height: 23px;
  90 +}
  91 +
  92 +.login-container-form .form-tip p,
  93 +.login-container-form .form-tip span {
  94 + display: block;
  95 + float: left;
  96 + height: 20px;
  97 +}
  98 +
  99 +.stop {
  100 + background: url(../images/stop.png) no-repeat;
  101 + width: 20px;
  102 + height: 20px;
  103 +}
  104 +
  105 +.login-container-form .form-group {
  106 + width: 296px;
  107 + margin: 0 auto;
  108 + margin-top: 22px;
  109 +}
  110 +
  111 +.login-container-form :first-child {
  112 + margin-top: 0px;
  113 +}
  114 +
  115 +.login-container-form .has-feedback.feedback-left .form-control-feedback {
  116 + left: 0;
  117 + right: auto;
  118 + width: 38px;
  119 + height: 45px;
  120 + line-height: 45px;
  121 + z-index: 4;
  122 + color: #dcdcdc;
  123 + font-size: 16px;
  124 +}
  125 +
  126 +.login-container-form .has-feedback.feedback-left .micons-pwd {
  127 + font-size: 18px;
  128 + line-height: 48px;
  129 +}
  130 +
  131 +.login-container-form .has-feedback.feedback-left .form-control {
  132 + padding-left: 38px;
  133 + padding-right: 12px;
  134 + border: 1px solid #ebebeb;
  135 + border-radius: 4px;
  136 + height: 45px;
  137 + color: #999;
  138 + font-size: 16px;
  139 + letter-spacing: 1px;
  140 +}
  141 +
  142 +.login-container-form .has-feedback.feedback-left .form-control:hover,
  143 +.login-container-form .has-feedback.feedback-left .form-control:hover,
  144 +.login-container-form .has-feedback.feedback-left .form-control:focus {
  145 + border: 1px solid #3081c3;
  146 + outline: unset;
  147 + box-shadow: unset;
  148 +}
  149 +
  150 +.login-container-form .overhidden {
  151 + padding-left: 24px;
  152 + font-size: 14px;
  153 + color: #999999;
  154 + vertical-align: bottom;
  155 + line-height: 18px;
  156 +}
  157 +
  158 +.login-container-form .overhidden:hover {
  159 + color: #3081c3;
  160 +}
  161 +
  162 +.login-container-form .ftdms-checkbox span::before {
  163 + height: 15px;
  164 + width: 15px;
  165 + border-width: 1px;
  166 + top: 2px;
  167 +}
  168 +
  169 +#btn-login {
  170 + background: #3081c3;
  171 + height: 45px;
  172 + font-size: 16px;
  173 + font-weight: 400;
  174 + color: #ffffff;
  175 + letter-spacing: 1px;
  176 +}
  177 +
  178 +#btn-login:hover {
  179 + background: #2ba3f6;
  180 +}
  181 +
  182 +.form-control:focus,
  183 +.form-control:hover {
  184 + box-shadow: unset;
  185 + border: 1px solid #3081c3 !important;
  186 +}
  187 +
  188 +.form-control {
  189 + width: 100%;
  190 +}
  191 +
  192 +.btn-info.btn-info:active {
  193 + border: 1px solid;
  194 +}
  195 +
  196 +.btn {
  197 + padding: 8px 12px;
  198 + border-radius: 2px;
  199 + outline: none !important;
  200 + -webkit-transition: 0.15s linear;
  201 + transition: 0.15s linear;
  202 +}
  203 +
  204 +button {
  205 + display: block;
  206 + width: 100%;
  207 + margin-bottom: 0;
  208 + line-height: 1.42857143;
  209 + text-align: center;
  210 + white-space: nowrap;
  211 + touch-action: manipulation;
  212 + cursor: pointer;
  213 + user-select: none;
  214 + font-family: inherit;
  215 + overflow: visible;
  216 + margin: 0;
  217 + font: inherit;
  218 + outline: none !important;
  219 +}
  220 +
  221 +.ftdms-checkbox span::before,
  222 +.ftdms-radio span::before {
  223 + content: '';
  224 + position: absolute;
  225 + display: inline-block;
  226 + height: 18px;
  227 + width: 18px;
  228 + left: 0.5px;
  229 + top: 0px;
  230 + border: 2px solid #ebebeb;
  231 + -webkit-transition: all 0.1s;
  232 + -o-transition: all 0.1s;
  233 + transition: all 0.1s;
  234 +}
  235 +
  236 +:after,
  237 +:before {
  238 + -webkit-box-sizing: border-box;
  239 + -moz-box-sizing: border-box;
  240 + box-sizing: border-box;
193 } 241 }

224.1 KB | 宽: | 高:

234.1 KB | 宽: | 高:

  • 两方对比
  • 交换覆盖
  • 透明覆盖
1 -if (typeof(dmap) == "undefined") var dmap = {};  
2 -dmap.login = {  
3 - init: function() {  
4 - $('#btn-login').bind('click', function(e) {  
5 - let username = $("#username").val();  
6 - let password = $("#password").val();  
7 -  
8 - if (username.length <= 0 || password.length <= 0) {  
9 - tips.notify("用户名或密码不能为空", "danger", 1e3);  
10 - return false;  
11 - }  
12 -  
13 - $.post("authorize", { username: username, password: password })  
14 - });  
15 - } 1 +if (typeof(dmap) == "undefined") var dmap = {};
  2 +dmap.login = {
  3 + init: function() {
  4 + $('#btn-login').bind('click', function(e) {
  5 + let username = $("#username").val();
  6 + let password = $("#password").val();
  7 +
  8 + if (username.length <= 0 || password.length <= 0) {
  9 + tips.notify("用户名或密码不能为空", "danger", 1e3);
  10 + return false;
  11 + }
  12 +
  13 + $.post("authorize", { username: username, password: password }, function(data) {
  14 + if (!data.result) {
  15 + tips.notify("账号或密码错误", "danger", 1e3);
  16 + }
  17 + })
  18 + });
  19 + }
16 }; 20 };
1 -<html>  
2 - <head>  
3 - <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />  
4 - <title>DMap Server</title>  
5 - <link  
6 - rel="stylesheet"  
7 - type="text/css"  
8 - href="{{ url_for('static', filename = 'content/css/login.css') }}"  
9 - />  
10 - <link  
11 - rel="stylesheet"  
12 - type="text/css"  
13 - href="{{ url_for('static', filename = 'content/css/font.css') }}"  
14 - />  
15 - <link  
16 - rel="stylesheet"  
17 - type="text/css"  
18 - href="{{ url_for('static', filename = 'content/css/bootstrap.min.css') }}"  
19 - />  
20 - <script src="{{ url_for('static',filename='content/js/jquery.min.js') }}"></script>  
21 - <script src="{{ url_for('static',filename='content/js/bootstrap-notify.min.js') }}"></script>  
22 - <script src="{{ url_for('static',filename='content/js/tips.js') }}"></script>  
23 - <script src="{{ url_for('static',filename='content/js/login.js') }}"></script>  
24 - </head>  
25 -</html>  
26 -  
27 -<div class="login">  
28 - <div class="login-container">  
29 - <p class="login-container-logo"></p>  
30 - <div class="login-container-form">  
31 - <p class="login-container-header">广州城市信息研究所有限公司</p>  
32 - <form action="" method="post">  
33 - <div class="form-group has-feedback feedback-left">  
34 - <input  
35 - type="text"  
36 - placeholder="用户名"  
37 - maxlength="20"  
38 - autocomplete="off"  
39 - class="form-control border-info"  
40 - name="username"  
41 - id="username"  
42 - />  
43 - <span class="micons-user form-control-feedback"></span>  
44 - </div>  
45 -  
46 - <div class="form-group has-feedback feedback-left">  
47 - <input  
48 - type="password"  
49 - placeholder="密码"  
50 - maxlength="20"  
51 - autocomplete="off"  
52 - class="form-control border-info"  
53 - id="password"  
54 - name="password"  
55 - />  
56 - <span class="micons-pwd form-control-feedback"></span>  
57 - </div>  
58 -  
59 - <div class="form-group">  
60 - <button class="btn btn-block btn-info" type="submit" id="btn-login">  
61 - 立即登录  
62 - </button>  
63 - </div>  
64 - </form>  
65 - </div>  
66 - <div class="clear"></div>  
67 - </div>  
68 -</div>  
69 -<script>  
70 - $(function () {})  
71 -</script> 1 +<html>
  2 + <head>
  3 + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
  4 + <title>DMap Server</title>
  5 + <link
  6 + rel="stylesheet"
  7 + type="text/css"
  8 + href="{{ url_for('static', filename = 'content/css/login.css') }}"
  9 + />
  10 + <link
  11 + rel="stylesheet"
  12 + type="text/css"
  13 + href="{{ url_for('static', filename = 'content/css/font.css') }}"
  14 + />
  15 + <link
  16 + rel="stylesheet"
  17 + type="text/css"
  18 + href="{{ url_for('static', filename = 'content/css/bootstrap.min.css') }}"
  19 + />
  20 + <script src="{{ url_for('static',filename='content/js/jquery.min.js') }}"></script>
  21 + <script src="{{ url_for('static',filename='content/js/bootstrap-notify.min.js') }}"></script>
  22 + <script src="{{ url_for('static',filename='content/js/tips.js') }}"></script>
  23 + <script src="{{ url_for('static',filename='content/js/login.js') }}"></script>
  24 + </head>
  25 +</html>
  26 +
  27 +<div class="login">
  28 + <div class="login-container">
  29 + <p class="login-container-logo"></p>
  30 + <div class="login-container-form">
  31 +
  32 + {%if error%}
  33 + <p class="login-container-header-small login-container-header">广州城市信息研究所有限公司</p>
  34 + <div class="form-tip">
  35 + <span class="stop"></span>
  36 + <p>{{error}}</p>
  37 + </div>
  38 + {% else %}
  39 + <p class="login-container-header">广州城市信息研究所有限公司</p>
  40 + {% endif %}
  41 +
  42 + <form action="" method="post">
  43 + <div class="form-group has-feedback feedback-left">
  44 + <input
  45 + type="text"
  46 + placeholder="用户名"
  47 + maxlength="20"
  48 + autocomplete="off"
  49 + class="form-control border-info"
  50 + name="username"
  51 + id="username"
  52 + />
  53 + <span class="micons-user form-control-feedback"></span>
  54 + </div>
  55 +
  56 + <div class="form-group has-feedback feedback-left">
  57 + <input
  58 + type="password"
  59 + placeholder="密码"
  60 + maxlength="20"
  61 + autocomplete="off"
  62 + class="form-control border-info"
  63 + id="password"
  64 + name="password"
  65 + />
  66 + <span class="micons-pwd form-control-feedback"></span>
  67 + </div>
  68 +
  69 + <div class="form-group">
  70 + <button class="btn btn-block btn-info" type="submit" id="btn-login">
  71 + 立即登录
  72 + </button>
  73 + </div>
  74 + </form>
  75 + </div>
  76 + <div class="clear"></div>
  77 + </div>
  78 +</div>
  79 +<script>
  80 + $(function () {})
  81 +</script>
@@ -20,3 +20,4 @@ swagger_configure = {"title": "DMapManager"} @@ -20,3 +20,4 @@ swagger_configure = {"title": "DMapManager"}
20 entry_data_thread = 3 20 entry_data_thread = 3
21 scan_module = ["app.modules"] # API所在的模块 21 scan_module = ["app.modules"] # API所在的模块
22 SECRET_KEY = b'_5#y2L"F4Q8z\n\xec]/' 22 SECRET_KEY = b'_5#y2L"F4Q8z\n\xec]/'
  23 +
1 -# coding=utf-8  
2 -from flask import Flask  
3 -from app import create_app  
4 -app:Flask = create_app()  
5 -if __name__ == '__main__':  
6 - app.run(host="0.0.0.0", port="8840", threaded=True, debug=True)  
7 - # app.run(host="0.0.0.0", port="8840", threaded=True)  
  1 +# coding=utf-8
  2 +from flask import Flask
  3 +from app import create_app
  4 +import os
  5 +os.environ['AUTHLIB_INSECURE_TRANSPORT'] = '1'
  6 +app: Flask = create_app()
  7 +if __name__ == '__main__':
  8 + app.run(host="0.0.0.0", port="8840", threaded=True, debug=True)
  9 + # app.run(host="0.0.0.0", port="8840", threaded=True)
注册登录 后发表评论