!4 调整目录结构

Merge pull request !4 from zhengxinonly/v2
This commit is contained in:
mkg
2021-06-12 21:26:24 +08:00
committed by Gitee
590 changed files with 1072 additions and 1160 deletions
-5
View File
@@ -1,5 +0,0 @@
FLASK_APP=main.py
FLASK_ENV=development
FLASK_DEBUG=1
FLASK_RUN_HOST = 127.0.0.1
FLASK_RUN_PORT = 5000
+23 -96
View File
@@ -57,90 +57,23 @@ Pear Admin Flask 分为 Common / Simple 两个版本:
```
Pear Admin Flask
├─applications
│ │
├─config
│ │
│ ├─ common.py #普通配置
│ │
│ └─ database.py #数据库配置
├─models
│ │ └─admin.py #基本模型
│ │
│ ├─service
│ │ │
│ │ ├─admin
│ │ │ │
│ │ │ ├─ file.py #file视图的数据操作
│ │ │ │
│ │ │ ├─ index.py #index视图的数据操作
│ │ │ │
│ │ │ ├─ power.py #power视图的数据操作
│ │ │ │
│ │ │ ├─ role.py #role视图的数据操作
│ │ │ │
│ │ │ └─ user.py #user视图的数据操作
│ │ │
│ │ ├─ admin_log.py #存储日志
│ │ │
│ │ ├─ deBug.py #deBug工具栏初始化
│ │ │
│ │ ├─ login.py #flask_login初始化
│ │ │
│ │ ├─ CaptchaTool.py #验证码
│ │ │
│ │ ├─ OriginalDb.py #原生sql查询封装
│ │ │
│ │ ├─ route_auth.py #权限
│ │ │
│ │ └─ upload.py #上传
│ │
│ └─views
│ │
│ ├─admin #前台视图
│ │ │
│ │ ├─index.py #主视图
│ │ │
│ │ ├─user.py #用户视图
│ │ │
│ │ ├─role.py #角色视图
│ │ │
│ │ ├─power.py #权限视图
│ │ │
│ │ ├─monitor.py #系统监控
│ │ │
│ │ ├─file.py #文件上传
│ │ │
│ │ ├─admin_log.py #系统日志
│ │ │
│ │ ├─context_processor.py #全局模板函数注册
│ │ │
│ │ ├─error.py #错误处理
│ │ │
│ │ └─init.py #蓝图注册
│ │
│ └─index #前台视图
├─dev #数据库初始化
├─migrations
├─readmes
├─static #静态资源
│ │
│ └─upload #文件上传地址
└─templates
├─admin #前台模板
├─errors #错误模板
└─index #前台模板
├─applications # 应用
│ ├─configs # 配置文件
│ │ ├─ common.py # 普通配置
│ └─ config.py # 配置文件对象
├─extensions # 注册插件
│ ├─models # 数据模型
├─static # 静态资源文件
├─templates # 静态模板文件
└─views # 视图部分
├─admin # 后台管理视图模块
└─index # 前台视图模块
├─docs # 文档说明(占坑)
├─migrations # 迁移文件记录
├─requirement # 依赖文件
├─test # 测试文件夹(占坑)
└─.env # 项目的配置文件
```
@@ -152,10 +85,10 @@ Pear Admin Flask
git clone https://gitee.com/pear-admin/pear-admin-flask
# 安 装
pip install -r requirement.txt
pip install -r requirement\requirement-dev.txt
# 配 置
applications\config\database.py
.env
```
@@ -189,14 +122,8 @@ python -m venv venv
#### 运行项目
```bash
# 进 入 目 录
cd dev
# 初 始 化 数 据 库
python initDb.py
# 如 果 报 模 块 路 径 错 误
python dev/initDb.py
python test\init_databases.py
```
@@ -207,6 +134,6 @@ python dev/initDb.py
| | |
|---------------------|---------------------|
| ![](readmes/1.jpg) | ![](readmes/2.jpg) |
| ![](readmes/3.jpg)| ![](readmes/4.jpg) |
| ![](readmes/5.jpg) | ![](readmes/6.jpg) |
| ![](docs/assets/1.jpg) | ![](docs/assets/2.jpg) |
| ![](docs/assets/3.jpg)| ![](docs/assets/4.jpg) |
| ![](docs/assets/5.jpg) | ![](docs/assets/6.jpg) |
+6
View File
@@ -0,0 +1,6 @@
from applications import create_app
app = create_app()
if __name__ == '__main__':
app.run()
+46
View File
@@ -0,0 +1,46 @@
import os
from flask import Flask
from flask_uploads import configure_uploads
from applications.common.utils.upload import photos
from applications.configs import common
from applications.extensions import init_plugs
from applications.view import init_view
from applications.configs import config
def create_app(config_name=None):
app = Flask(__name__)
if not config_name:
# 尝试从本地环境中读取
config_name = os.getenv('FLASK_CONFIG', 'development')
# 引入数据库配置
app.config.from_object(common)
app.config.from_object(config[config_name])
# 注册各种插件
init_plugs(app)
# 注册路由
init_view(app)
# 文件上传
configure_uploads(app, photos)
logo()
return app
def logo():
print('''
_____ _ _ ______ _ _
| __ \ /\ | | (_) | ____| | | |
| |__) |__ __ _ _ __ / \ __| |_ __ ___ _ _ __ | |__ | | __ _ ___| | __
| ___/ _ \/ _` | '__| / /\ \ / _` | '_ ` _ \| | '_ \ | __| | |/ _` / __| |/ /
| | | __/ (_| | | / ____ \ (_| | | | | | | | | | | | | | | (_| \__ \ <
|_| \___|\__,_|_| /_/ \_\__,_|_| |_| |_|_|_| |_| |_| |_|\__,_|___/_|\_\\
''')
@@ -1,8 +1,8 @@
from applications.models import db
from applications.models.admin_dept import Dept, DeptSchema
from applications.models.admin_user import User
from applications.service.common.curd import model_to_dicts
from applications.service.common.validate import xss_escape
from applications.common.utils.validate import xss_escape
from applications.extensions import db
from applications.models import Dept, DeptSchema
from applications.models import User
from applications.common.curd import model_to_dicts
def get_dept_dict():
@@ -12,8 +12,6 @@ def get_dept_dict():
def save_dept(req):
address = xss_escape(req.get("address"))
deptName = xss_escape(req.get("deptName"))
email = xss_escape(req.get("email"))
@@ -1,27 +1,19 @@
# 字典管理
# 查询字典类型
from applications.models import db
from applications.models.admin_dict import DictType, DictData, DictTypeSchema, DictDataSchema
from applications.service.common.curd import model_to_dicts
from applications.service.common.validate import xss_escape
# 通过type_code获取字典dict
# 例:get_dict('user_sex')
# [{'key': '男', 'value': 'boy'}, {'key': '女', 'value': 'girl'}]
from applications.common.utils.validate import xss_escape
from applications.extensions import db
from applications.models import DictType, DictData, DictTypeSchema, DictDataSchema
from applications.common.curd import model_to_dicts
def get_dict(typecode: str):
Dict_list = []
dict_list = []
if DictType.query.filter_by(type_code=typecode, enable=1).first():
Dicts = DictData.query.filter_by(type_code=typecode, enable=1).all()
for d in Dicts:
Dict_Dict = {"key": d.data_label, "value": d.data_value}
Dict_list.append(Dict_Dict)
dicts = DictData.query.filter_by(type_code=typecode, enable=1).all()
for d in dicts:
dict_dict = {"key": d.data_label, "value": d.data_value}
dict_list.append(dict_dict)
else:
return None
return Dict_list
return dict_list
def get_dict_type(page, limit, type_name):
@@ -45,7 +37,7 @@ def get_dict_data(page, limit, type_code):
return dict_dict, count
# 增加dicttype
# 增加 dict type
def save_dict_type(req_json):
description = xss_escape(req_json.get("description"))
enable = xss_escape(req_json.get("enable"))
@@ -1,16 +1,17 @@
import os
from flask import current_app
from sqlalchemy import desc
from applications.models import db
from applications.models.admin_photo import Photo, PhotoSchema
from applications.service.common.curd import model_to_dicts
from applications.service.upload import photos
from applications.common.utils.upload import photos
from applications.extensions import db
from applications.models import Photo, PhotoSchema
from applications.common.curd import model_to_dicts
def get_photo(page, limit):
photo = Photo.query.order_by(desc(Photo.create_time)).paginate(page=page, per_page=limit, error_out=False)
count = Photo.query.count()
data = model_to_dicts(Schema=PhotoSchema,model=photo.items)
data = model_to_dicts(Schema=PhotoSchema, model=photo.items)
return data, count
@@ -26,9 +27,9 @@ def upload_one(photo, mime):
return file_url
def delete_photo_by_id(id):
photo_name = Photo.query.filter_by(id=id).first().name
photo = Photo.query.filter_by(id=id).delete()
def delete_photo_by_id(_id):
photo_name = Photo.query.filter_by(id=_id).first().name
photo = Photo.query.filter_by(id=_id).delete()
db.session.commit()
upload_url = current_app.config.get("UPLOADED_PHOTOS_DEST")
os.remove(upload_url + '/' + photo_name)
@@ -1,8 +1,9 @@
from io import BytesIO
from flask import session, make_response, current_app
from flask_login import current_user
from applications.common.utils.gen_captcha import gen_captcha
from applications.models.admin_power import PowerSchema
from applications.service.captcha import gen_captcha
# 授权路由存入session
@@ -1,8 +1,8 @@
from applications.models import db
from applications.common.utils.validate import xss_escape
from applications.extensions import db
from applications.models.admin_power import Power, PowerSchema2
from applications.models.admin_role import Role
from applications.service.common.curd import model_to_dicts
from applications.service.common.validate import xss_escape
from applications.models import Role
from applications.common.curd import model_to_dicts
def get_power_dict():
@@ -10,6 +10,7 @@ def get_power_dict():
res = model_to_dicts(Schema=PowerSchema2, model=power)
return res
# 选择父节点
def select_parent():
power = Power.query.all()
@@ -1,12 +1,13 @@
from sqlalchemy import and_
from applications.models import db
from applications.models.admin_role import Role, RoleSchema
from applications.common.utils.validate import xss_escape
from applications.extensions import db
from applications.models import Role, RoleSchema
from applications.models.admin_power import Power, PowerSchema2
from applications.models.admin_user import User
from applications.models import User
# 获取角色对象
from applications.service.common.curd import model_to_dicts
from applications.service.common.validate import xss_escape
from applications.common.curd import model_to_dicts
def get_role_data(page, limit, filters):
@@ -1,19 +1,19 @@
from flask import jsonify
from flask_login import current_user
from sqlalchemy import and_, desc
from applications.models import db
from applications.models.admin_user import User, UserSchema
from applications.models.admin_role import Role
from applications.models.admin_log import AdminLog
from applications.extensions import db
from applications.models import User, UserSchema
from applications.models import Role
from applications.models import AdminLog
# 获取用户的 sqlalchemy 对象分页器
from applications.common.curd import model_to_dicts
# 获取用户的sqlalchemy对象分页器
from applications.service.common.curd import model_to_dicts
def get_user_data(page, limit, filters,deptId):
def get_user_data(page, limit, filters, deptId):
if deptId:
user = User.query.filter_by(dept_id=deptId).filter(and_(*[getattr(User, k).like(v) for k, v in filters.items()])).paginate(page=page,
user = User.query.filter_by(dept_id=deptId).filter(
and_(*[getattr(User, k).like(v) for k, v in filters.items()])).paginate(page=page,
per_page=limit,
error_out=False)
else:
@@ -25,9 +25,9 @@ def get_user_data(page, limit, filters,deptId):
# 获取用户的dict数据分页器
def get_user_data_dict(page, limit, filters,deptId):
user, count = get_user_data(page, limit, filters,deptId)
data = model_to_dicts(Schema=UserSchema,model=user.items)
def get_user_data_dict(page, limit, filters, deptId):
user, count = get_user_data(page, limit, filters, deptId)
data = model_to_dicts(Schema=UserSchema, model=user.items)
return data, count
@@ -76,7 +76,7 @@ def update_avatar(url):
# 更新用户信息
def update_user(id, username, realname, deptId):
user = User.query.filter_by(id=id).update({'username': username, 'realname': realname,'dept_id':deptId})
user = User.query.filter_by(id=id).update({'username': username, 'realname': realname, 'dept_id': deptId})
db.session.commit()
return user
@@ -1,10 +1,10 @@
from flask_login import current_user
from applications.models import db
from applications.models.admin_log import AdminLog
from applications.extensions import db
from applications.models import AdminLog
def login_log(request,uid, is_access):
def login_log(request, uid, is_access):
info = {
'method': request.method,
'url': request.path,
@@ -22,7 +22,7 @@ def login_log(request,uid, is_access):
desc=info.get('desc'),
uid=info.get('uid'),
method=info.get('method'),
success = info.get('success')
success=info.get('success')
)
db.session.add(log)
db.session.flush()
@@ -38,7 +38,7 @@ def admin_log(request, is_access):
'user_agent': request.headers.get('User-Agent'),
'desc': str(dict(request.values)),
'uid': current_user.id,
'success':int(is_access)
'success': int(is_access)
}
log = AdminLog(
+17
View File
@@ -0,0 +1,17 @@
#
MYSQL_HOST = '127.0.0.1'
MYSQL_PORT = '3306'
MYSQL_DATABASE = 'PearAdminFlask'
MYSQL_USERNAME = 'root'
MYSQL_PASSWORD = 'root'
MYSQL_DB_URI = "mysql+pymysql://{username}:{password}@{host}:{port}/{db}?charset=utf8".format(username=USERNAME,
password=PASSWORD,
host=HOST,
port=PORT,
db=DATABASE)
SQLALCHEMY_DATABASE_URI = MYSQL_DB_URI
SQLALCHEMY_TRACK_MODIFICATIONS = True
SQLALCHEMY_ECHO = False
SQLALCHEMY_POOL_RECYCLE = 8
+14
View File
@@ -0,0 +1,14 @@
from captcha.image import ImageCaptcha
from PIL import Image
from random import choices
def gen_captcha(content='0123456789'):
""" 生成验证码 """
image = ImageCaptcha()
# 获取字符串
captcha_text = "".join(choices(content, k=4))
# 生成图像
captcha_image = Image.open(image.generate(captcha_text))
return captcha_text, captcha_image
@@ -1,38 +1,20 @@
from flask import jsonify
'''
成功响应
默认值成功
'''
def success_api(msg: str = "成功"):
return jsonify(success=True, msg=msg)
'''
失败响应
默认值失败
'''
""" 成功响应 默认值”成功“ """
return jsonify(success=True, message=msg)
def fail_api(msg: str = "失败"):
return jsonify(success=False, msg=msg)
'''
动态表格渲染响应
'''
""" 失败响应 默认值“失败” """
return jsonify(success=False, message=msg)
def table_api(msg: str = "", count=0, data=None, limit=10):
""" 动态表格渲染响应 """
res = {
'msg': msg,
'message': msg,
'code': 0,
'data': data,
'count': count,
@@ -1,7 +1,7 @@
from functools import wraps
from flask import abort, request, jsonify, session
from flask_login import login_required
from applications.service.admin_log import admin_log
from applications.common.admin_log import admin_log
def authorize(power: str, log: bool = False):
-13
View File
@@ -1,13 +0,0 @@
# 数据库连接
HOST = '127.0.0.1'
PORT = '3306'
DATABASE = 'PearAdminFlask'
USERNAME = 'root'
PASSWORD = 'root'
DB_URI = "mysql+pymysql://{username}:{password}@{host}:{port}/{db}?charset=utf8".format(username=USERNAME,password=PASSWORD, host=HOST,port=PORT, db=DATABASE)
SQLALCHEMY_DATABASE_URI = DB_URI
SQLALCHEMY_TRACK_MODIFICATIONS = True
SQLALCHEMY_ECHO = False
SQLALCHEMY_POOL_RECYCLE=8
+1
View File
@@ -0,0 +1 @@
from .config import config
@@ -17,9 +17,6 @@ SYSTEM_PANEL_LINKS = [
"href": "https://gitee.com/Jmysy/Pear-Admin-Layui"
}
]
# 密钥
# 密钥配置(flask session需要) 记得修改
SECRET_KEY = 'pear-admin-flask'
UPLOADED_PHOTOS_DEST = 'static/upload'
UPLOADED_FILES_ALLOW = ['gif', 'jpg']
+49
View File
@@ -0,0 +1,49 @@
import logging
import os
class BaseConfig:
SECRET_KEY = os.getenv('SECRET_KEY', 'dev key')
# redis配置
REDIS_HOST = os.getenv('REDIS_HOST') or "127.0.0.1"
REDIS_PORT = int(os.getenv('REDIS_PORT') or 6379)
# mysql 配置
MYSQL_USERNAME = os.getenv('MYSQL_USERNAME') or "root"
MYSQL_PASSWORD = os.getenv('MYSQL_PASSWORD') or "123456"
MYSQL_HOST = os.getenv('MYSQL_HOST') or "127.0.0.1"
MYSQL_PORT = int(os.getenv('MYSQL_PORT') or 3306)
MYSQL_DATABASE = os.getenv('MYSQL_DATABASE') or "PearAdminFlask"
# mysql 数据库的配置信息
SQLALCHEMY_DATABASE_URI = f"mysql+pymysql://{MYSQL_USERNAME}:{MYSQL_PASSWORD}@{MYSQL_HOST}:{MYSQL_PORT}/{MYSQL_DATABASE}"
# 默认日志等级
LOG_LEVEL = logging.WARN
class TestingConfig(BaseConfig):
""" 测试配置 """
SQLALCHEMY_DATABASE_URI = 'sqlite:///:memory:' # 内存数据库
class DevelopmentConfig(BaseConfig):
""" 开发配置 """
SQLALCHEMY_TRACK_MODIFICATIONS = True
SQLALCHEMY_ECHO = False
class ProductionConfig(BaseConfig):
"""生成环境配置"""
SQLALCHEMY_TRACK_MODIFICATIONS = False
SQLALCHEMY_ECHO = False
SQLALCHEMY_POOL_RECYCLE = 8
LOG_LEVEL = logging.ERROR
config = {
'development': DevelopmentConfig,
'testing': TestingConfig,
'production': ProductionConfig
}
+15
View File
@@ -0,0 +1,15 @@
from flask import Flask
from .init_sqlalchemy import db, ma, init_databases
from .init_login import init_login_manager
from .init_debug_tool import init_debug_tool
from .init_template_directives import init_template_directives
from .init_error_views import init_error_views
def init_plugs(app: Flask) -> None:
init_debug_tool(app)
init_login_manager(app)
init_databases(app)
init_template_directives(app)
init_error_views(app)
@@ -1,6 +1,7 @@
from flask import Flask
from flask_debugtoolbar import DebugToolbarExtension
def open_debug_tool(app):
def init_debug_tool(app: Flask):
toolbar = DebugToolbarExtension()
toolbar.init_app(app)
+12
View File
@@ -0,0 +1,12 @@
import os
from dotenv import load_dotenv
root_path = os.path.abspath(os.path.dirname(__file__)).split('applications')[0]
dot_env_path = os.path.join(root_path, '.env')
flask_env_path = os.path.join(root_path, '.flaskenv')
if os.path.exists(dot_env_path):
load_dotenv(dot_env_path)
if os.path.exists(flask_env_path):
load_dotenv(flask_env_path)
@@ -1,8 +1,7 @@
from flask import render_template
def init_error(app):
def init_error_views(app):
@app.errorhandler(403)
def page_not_found(e):
return render_template('errors/403.html'), 403
@@ -1,7 +1,7 @@
from flask_login import LoginManager
def init_flask_login(app):
def init_login_manager(app):
login_manager = LoginManager()
login_manager.init_app(app)
@@ -10,6 +10,6 @@ def init_flask_login(app):
@login_manager.user_loader
def load_user(user_id):
from applications.models.admin_user import User
from applications.models import User
user = User.query.get(int(user_id))
return user
@@ -0,0 +1,54 @@
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_marshmallow import Marshmallow
from marshmallow import fields
from marshmallow.validate import (
URL, Email, Range, Length, Equal, Regexp,
Predicate, NoneOf, OneOf, ContainsOnly
)
URL.default_message = '无效的链接'
Email.default_message = '无效的邮箱地址'
Range.message_min = '不能小于{min}'
Range.message_max = '不能小于{max}'
Range.message_all = '不能超过{min}{max}这个范围'
Length.message_min = '长度不得小于{min}'
Length.message_max = '长度不得大于{max}'
Length.message_all = '长度不能超过{min}{max}这个范围'
Length.message_equal = '长度必须等于{equal}'
Equal.default_message = '必须等于{other}'
Regexp.default_message = '非法输入'
Predicate.default_message = '非法输入'
NoneOf.default_message = '非法输入'
OneOf.default_message = '无效的选择'
ContainsOnly.default_message = '一个或多个无效的选择'
fields.Field.default_error_messages = {
"required": "缺少必要数据",
"null": "数据不能为空",
"validator_failed": "非法数据",
}
fields.Str.default_error_messages = {
'invalid': "不是合法文本"
}
fields.Int.default_error_messages = {
"invalid": "不是合法整数"
}
fields.Number.default_error_messages = {
"invalid": "不是合法数字"
}
fields.Boolean.default_error_messages = {
"invalid": "不是合法布尔值"
}
db = SQLAlchemy()
ma = Marshmallow()
def init_databases(app: Flask):
db.init_app(app)
ma.init_app(app)
@@ -1,7 +1,7 @@
from flask import session
def init_template_global(app):
def init_template_directives(app):
@app.template_global()
def authorize(power):
return bool(power in session.get('permissions'))
+9 -47
View File
@@ -1,47 +1,9 @@
from flask_sqlalchemy import SQLAlchemy
from flask_marshmallow import Marshmallow
from marshmallow import fields
from marshmallow.validate import (
URL, Email, Range, Length, Equal, Regexp,
Predicate, NoneOf, OneOf, ContainsOnly
)
URL.default_message = '无效的链接'
Email.default_message = '无效的邮箱地址'
Range.message_min = '不能小于{min}'
Range.message_max = '不能小于{max}'
Range.message_all = '不能超过{min}{max}这个范围'
Length.message_min = '长度不得小于{min}'
Length.message_max = '长度不得大于{max}'
Length.message_all = '长度不能超过{min}{max}这个范围'
Length.message_equal = '长度必须等于{equal}'
Equal.default_message = '必须等于{other}'
Regexp.default_message = '非法输入'
Predicate.default_message = '非法输入'
NoneOf.default_message = '非法输入'
OneOf.default_message = '无效的选择'
ContainsOnly.default_message = '一个或多个无效的选择'
fields.Field.default_error_messages = {
"required": "缺少必要数据",
"null": "数据不能为空",
"validator_failed": "非法数据",
}
fields.Str.default_error_messages = {
'invalid': "不是合法文本"
}
fields.Int.default_error_messages = {
"invalid": "不是合法整数"
}
fields.Number.default_error_messages = {
"invalid": "不是合法数字"
}
fields.Boolean.default_error_messages = {
"invalid": "不是合法布尔值"
}
db = SQLAlchemy()
ma = Marshmallow()
from .admin_dept import Dept, DeptSchema
from .admin_dict import DictType, DictData, DictTypeSchema, DictDataSchema
from .admin_log import AdminLog, LogSchema
from .admin_photo import Photo, PhotoSchema
from .admin_power import Power, PowerSchema, PowerSchema2
from .admin_role import Role, RoleSchema
from .admin_role_power import role_power
from .admin_user import User, UserSchema
from .admin_user_role import user_role
+2 -2
View File
@@ -1,6 +1,6 @@
import datetime
from applications.models import db, ma
from marshmallow import fields,validate
from applications.extensions import db, ma
from marshmallow import fields, validate
class Dept(db.Model):
+1 -1
View File
@@ -1,6 +1,6 @@
import datetime
from applications.models import db, ma
from applications.extensions import db, ma
from marshmallow import fields
+1 -1
View File
@@ -1,5 +1,5 @@
import datetime
from applications.models import db, ma
from applications.extensions import db, ma
from marshmallow import fields
+1 -1
View File
@@ -1,6 +1,6 @@
import datetime
from applications.models import db, ma
from applications.extensions import db, ma
from marshmallow import fields
+1 -2
View File
@@ -1,5 +1,5 @@
import datetime
from applications.models import db, ma
from applications.extensions import db, ma
from marshmallow import fields
@@ -47,4 +47,3 @@ class PowerSchema2(ma.Schema): # 序列化类
create_time = fields.DateTime()
update_time = fields.DateTime()
enable = fields.Integer()
+1 -2
View File
@@ -1,7 +1,6 @@
import datetime
from applications.models import db, ma
from applications.extensions import db, ma
from marshmallow import fields
from applications.models import admin_role_power
class Role(db.Model):
+2 -1
View File
@@ -1,4 +1,5 @@
from applications.models import db
from applications.extensions import db
# 创建中间表
role_power = db.Table(
"admin_role_power", # 中间表名称
+2 -4
View File
@@ -1,10 +1,9 @@
import datetime
from flask_login import UserMixin
from werkzeug.security import generate_password_hash, check_password_hash
from applications.models import db, ma
from applications.extensions import db, ma
from marshmallow import fields
from applications.models import admin_user_role
from applications.models.admin_dept import Dept
from applications.models import Dept
class User(db.Model, UserMixin):
@@ -43,4 +42,3 @@ class UserSchema(ma.Schema):
return Dept.query.filter_by(id=obj.dept_id).first().dept_name
else:
return None
+2 -1
View File
@@ -1,4 +1,5 @@
from applications.models import db
from applications.extensions import db
# 创建中间表
user_role = db.Table(
"admin_user_role", # 中间表名称
-26
View File
@@ -1,26 +0,0 @@
from captcha.image import ImageCaptcha
from PIL import Image
import random
# 定义随机方法
def random_captcha():
# 定义一个容器
captcha_text = []
for i in range(4):
# 定义验证码字符
c = random.choice(['0', '1', '2', '4', '6', '8'])
captcha_text.append(c)
# 返回一个随机生成的字符串
return ''.join(captcha_text)
# 生成验证码方法
def gen_captcha():
# 定义图片对象
image = ImageCaptcha()
# 获取字符串
captcha_text = random_captcha()
# 生成图像
captcha_image = Image.open(image.generate(captcha_text))
return captcha_text, captcha_image
-106
View File
@@ -1,106 +0,0 @@
import datetime
import json
import pymysql
from applications.config.database import HOST, USERNAME, PASSWORD, DATABASE, PORT
DB_CONFIG = {
"host": HOST,
"port": int(PORT),
"user": USERNAME,
"password": PASSWORD,
"db": DATABASE,
"charset": "utf8"
}
class SQLManager(object):
# 初始化实例方法
def __init__(self):
self.conn = None
self.cursor = None
self.connect()
# 连接数据库
def connect(self):
self.conn = pymysql.connect(
host=DB_CONFIG.get('host'),
port=DB_CONFIG.get('port'),
user=DB_CONFIG.get('user'),
passwd=DB_CONFIG.get('password'),
db=DB_CONFIG.get('db'),
)
self.cursor = self.conn.cursor(cursor=pymysql.cursors.DictCursor)
# 查询多条数据
def get_list(self, sql, args=None):
self.cursor.execute(sql, args)
result = self.cursor.fetchall()
return result
# 查询多条数据后关闭
def get_list_close(self, sql, args=None):
self.cursor.execute(sql, args)
result = self.cursor.fetchall()
self.close()
return result
# 查询单条数据
def get_one(self, sql, args=None):
self.cursor.execute(sql, args)
result = self.cursor.fetchone()
return result
# 查询单条数据后关闭
def get_one_close(self, sql, args=None):
self.cursor.execute(sql, args)
result = self.cursor.fetchone()
self.close()
return result
# 执行单条SQL语句
def moddify(self, sql, args=None):
self.cursor.execute(sql, args)
self.conn.commit()
# 执行多条SQL语句
def multi_modify(self, sql, args=None):
self.cursor.executemany(sql, args)
self.conn.commit()
# 创建单条记录的语句
def create(self, sql, args=None):
self.cursor.execute(sql, args)
self.conn.commit()
last_id = self.cursor.lastrowid
return last_id
# 关闭数据库cursor和连接
def close(self):
self.cursor.close()
self.conn.close()
# 进入with语句自动执行
def __enter__(self):
return self
# 退出with语句块自动执行
def __exit__(self, exc_type, exc_val, exc_tb):
self.close()
"""
原生查询dict的datetime解析器
用法
json.dumps(dictxxx, cls=DateEncoder)
"""
class DateEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, datetime.datetime):
return obj.strftime("%Y-%m-%d %H:%M:%S")
else:
return json.JSONEncoder.default(self, obj)

Before

Width:  |  Height:  |  Size: 54 KiB

After

Width:  |  Height:  |  Size: 54 KiB

Before

Width:  |  Height:  |  Size: 87 KiB

After

Width:  |  Height:  |  Size: 87 KiB

Before

Width:  |  Height:  |  Size: 87 KiB

After

Width:  |  Height:  |  Size: 87 KiB

Before

Width:  |  Height:  |  Size: 197 KiB

After

Width:  |  Height:  |  Size: 197 KiB

Before

Width:  |  Height:  |  Size: 74 KiB

After

Width:  |  Height:  |  Size: 74 KiB

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 3.9 KiB

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Before

Width:  |  Height:  |  Size: 55 KiB

After

Width:  |  Height:  |  Size: 55 KiB

Before

Width:  |  Height:  |  Size: 5.8 KiB

After

Width:  |  Height:  |  Size: 5.8 KiB

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Before

Width:  |  Height:  |  Size: 5.7 KiB

After

Width:  |  Height:  |  Size: 5.7 KiB

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

Before

Width:  |  Height:  |  Size: 299 KiB

After

Width:  |  Height:  |  Size: 299 KiB

Some files were not shown because too many files have changed in this diff Show More