From 6978002393ebb467d4772110d70fe566ab2b199c Mon Sep 17 00:00:00 2001 From: zhengxinonly Date: Sun, 23 Jan 2022 00:43:39 +0800 Subject: [PATCH] =?UTF-8?q?refactor(=E9=87=8D=E6=9E=84=E7=A8=8B=E5=BA=8F&?= =?UTF-8?q?=E7=9B=AE=E5=BD=95=E7=BB=93=E6=9E=84)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .flaskenv | 16 +--- app.py | 6 ++ applications/__init__.py | 18 ++-- applications/api/rights/department.py | 21 +++-- applications/api/rights/rights.py | 33 ++++---- applications/api/rights/roles.py | 40 ++++----- applications/api/system/file.py | 17 ++-- applications/api/system/passport.py | 10 +-- applications/api/users/profile.py | 17 ++-- applications/api/users/user.py | 54 ++++++------ applications/configs/__init__.py | 1 - applications/configs/common.py | 24 ------ applications/configs/config.py | 54 ------------ applications/configs/init_data/__init__.py | 11 --- .../extensions/init_databases/__init__.py | 76 ----------------- applications/models/__init__.py | 4 - applications/models/base.py | 8 -- applications/models/file/__init__.py | 1 - applications/models/file/photo.py | 12 --- applications/models/rights/__init__.py | 19 ----- applications/models/rights/power.py | 18 ---- applications/models/rights/role.py | 17 ---- applications/models/users/__init__.py | 2 - applications/models/users/dept.py | 37 --------- applications/view/department.py | 6 +- applications/view/file.py | 2 +- applications/view/logs_view.py | 16 ++-- applications/view/passport.py | 6 +- applications/view/rights.py | 6 +- applications/view/roles.py | 6 +- applications/view/users.py | 14 ++-- {applications/common => common}/__init__.py | 0 .../common => common}/flask_uploads.py | 0 .../common => common}/gen_captcha.py | 0 {applications/common => common}/utils/http.py | 0 .../common => common}/utils/rights.py | 6 +- .../common => common}/utils/upload.py | 12 +-- config.py | 51 ++++++++++++ .../extensions => extensions}/__init__.py | 0 extensions/init_databases.py | 82 +++++++++++++++++++ .../extensions => extensions}/init_dotenv.py | 0 .../init_error_views.py | 0 .../extensions => extensions}/init_login.py | 4 +- .../init_sqlalchemy.py | 0 .../init_template_directives.py | 0 models/__init__.py | 4 + models/file.py | 15 ++++ models/rights.py | 46 +++++++++++ .../models/log.py => models/system.py | 10 ++- .../models/users => models}/users.py | 29 +++++-- .../requirement-dev.txt => requirement.txt | 1 + requirement/requirement.txt | 2 - .../init_data => static/data}/cp_dept.json | 0 .../init_data => static/data}/cp_user.json | 0 .../init_data => static/data}/file_photo.json | 0 .../init_data => static/data}/rt_power.json | 0 .../init_data => static/data}/rt_role.json | 0 .../data}/rt_role_power.json | 0 .../data}/rt_user_role.json | 0 templates/admin/rights/rights.html | 2 +- 60 files changed, 374 insertions(+), 462 deletions(-) create mode 100644 app.py delete mode 100644 applications/configs/__init__.py delete mode 100644 applications/configs/common.py delete mode 100644 applications/configs/config.py delete mode 100644 applications/configs/init_data/__init__.py delete mode 100644 applications/extensions/init_databases/__init__.py delete mode 100644 applications/models/__init__.py delete mode 100644 applications/models/base.py delete mode 100644 applications/models/file/__init__.py delete mode 100644 applications/models/file/photo.py delete mode 100644 applications/models/rights/__init__.py delete mode 100644 applications/models/rights/power.py delete mode 100644 applications/models/rights/role.py delete mode 100644 applications/models/users/__init__.py delete mode 100644 applications/models/users/dept.py rename {applications/common => common}/__init__.py (100%) rename {applications/common => common}/flask_uploads.py (100%) rename {applications/common => common}/gen_captcha.py (100%) rename {applications/common => common}/utils/http.py (100%) rename {applications/common => common}/utils/rights.py (92%) rename {applications/common => common}/utils/upload.py (62%) create mode 100644 config.py rename {applications/extensions => extensions}/__init__.py (100%) create mode 100644 extensions/init_databases.py rename {applications/extensions => extensions}/init_dotenv.py (100%) rename {applications/extensions => extensions}/init_error_views.py (100%) rename {applications/extensions => extensions}/init_login.py (75%) rename {applications/extensions => extensions}/init_sqlalchemy.py (100%) rename {applications/extensions => extensions}/init_template_directives.py (100%) create mode 100644 models/__init__.py create mode 100644 models/file.py create mode 100644 models/rights.py rename applications/models/log.py => models/system.py (56%) rename {applications/models/users => models}/users.py (50%) rename requirement/requirement-dev.txt => requirement.txt (96%) delete mode 100644 requirement/requirement.txt rename {applications/configs/init_data => static/data}/cp_dept.json (100%) rename {applications/configs/init_data => static/data}/cp_user.json (100%) rename {applications/configs/init_data => static/data}/file_photo.json (100%) rename {applications/configs/init_data => static/data}/rt_power.json (100%) rename {applications/configs/init_data => static/data}/rt_role.json (100%) rename {applications/configs/init_data => static/data}/rt_role_power.json (100%) rename {applications/configs/init_data => static/data}/rt_user_role.json (100%) diff --git a/.flaskenv b/.flaskenv index 007748f..99c6c33 100644 --- a/.flaskenv +++ b/.flaskenv @@ -1,17 +1,3 @@ -# MySql配置信息 -MYSQL_HOST=127.0.0.1 -MYSQL_PORT=3306 -MYSQL_DATABASE=PearAdminFlask -MYSQL_USERNAME=root -MYSQL_PASSWORD=123456 - -# Redis 配置 -REDIS_HOST=127.0.0.1 -REDIS_PORT=6379 - -# 密钥配置 -SECRET_KEY='pear-admin-flask2' - FLASK_ENV=development FLASK_RUN_HOST=0.0.0.0 -FLASK_APP='applications:create_app("development")' +FLASK_APP='applications:create_app' diff --git a/app.py b/app.py new file mode 100644 index 0000000..a5622a5 --- /dev/null +++ b/app.py @@ -0,0 +1,6 @@ +from applications import create_app + +app = create_app() + +if __name__ == '__main__': + app.run() diff --git a/applications/__init__.py b/applications/__init__.py index 0a8c586..c2add1e 100644 --- a/applications/__init__.py +++ b/applications/__init__.py @@ -1,26 +1,20 @@ import os from flask import Flask -from applications.common.flask_uploads import configure_uploads +from common.flask_uploads import configure_uploads -from applications.common.utils.upload import photos -from applications.configs import common -from applications.extensions import init_plugs +from common.utils.upload import photos +from extensions import init_plugs from applications.view import init_view from applications.api import init_api -from applications.configs import config +import config -def create_app(config_name=None): +def create_app(): app = Flask('pear-admin-flask') - if not config_name: - # 尝试从本地环境中读取 - config_name = os.getenv('FLASK_CONFIG', 'development') - # 引入数据库配置 - app.config.from_object(common) - app.config.from_object(config[config_name]) + app.config.from_object(config) # 注册各种插件 init_plugs(app) diff --git a/applications/api/rights/department.py b/applications/api/rights/department.py index f2d63f6..9c34255 100644 --- a/applications/api/rights/department.py +++ b/applications/api/rights/department.py @@ -1,20 +1,19 @@ from flask import jsonify from flask_restful import Resource, reqparse -from applications.common.utils.http import success_api, fail_api -from applications.extensions import db -from applications.models import CompanyDepartment, CompanyUser +from common.utils.http import success_api, fail_api +from extensions import db +from models import DepartmentModels, UserModels class DepartmentsResource(Resource): def get(self): - dept_data = CompanyDepartment.query.order_by(CompanyDepartment.sort).all() + dept_data = DepartmentModels.query.order_by(DepartmentModels.sort).all() # TODO dtree 需要返回状态信息 res = { "status": {"code": 200, "message": "默认"}, "data": [ - { 'deptId': item.id, 'parentId': item.parent_id, @@ -45,7 +44,7 @@ class DepartmentsResource(Resource): res = parser.parse_args() - dept = CompanyDepartment( + dept = DepartmentModels( parent_id=res.parent_id, dept_name=res.dept_name, sort=res.sort, @@ -63,7 +62,7 @@ class DepartmentsResource(Resource): class DepartmentResource(Resource): def get(self, dept_id): - dept = CompanyDepartment.query.filter_by(id=dept_id).first() + dept = DepartmentModels.query.filter_by(id=dept_id).first() dept_data = { 'id': dept.id, 'dept_name': dept.dept_name, @@ -96,15 +95,15 @@ class DepartmentResource(Resource): "status": res.status, "address": res.address } - res = CompanyDepartment.query.filter_by(id=dept_id).update(data) + res = DepartmentModels.query.filter_by(id=dept_id).update(data) if not res: return fail_api(message="更新失败") db.session.commit() return success_api(message="更新成功") def delete(self, dept_id): - ret = CompanyDepartment.query.filter_by(id=dept_id).delete() - CompanyUser.query.filter_by(dept_id=dept_id).update({"dept_id": None}) + ret = DepartmentModels.query.filter_by(id=dept_id).delete() + UserModels.query.filter_by(dept_id=dept_id).update({"dept_id": None}) db.session.commit() if ret: return success_api(message="删除成功") @@ -113,7 +112,7 @@ class DepartmentResource(Resource): class DeptEnableResource(Resource): def put(self, dept_id): - d = CompanyDepartment.query.get(dept_id) + d = DepartmentModels.query.get(dept_id) if d: d.status = not d.status db.session.commit() diff --git a/applications/api/rights/rights.py b/applications/api/rights/rights.py index c2f0c82..69e5251 100644 --- a/applications/api/rights/rights.py +++ b/applications/api/rights/rights.py @@ -5,9 +5,9 @@ from flask import request, jsonify, current_app from flask_login import current_user from flask_restful import Resource, reqparse -from applications.common.utils.http import success_api, fail_api -from applications.extensions import db -from applications.models import RightsPower, RightsRole +from common.utils.http import success_api, fail_api +from extensions import db +from models import RightModels, RoleModels def get_render_config(): @@ -105,7 +105,6 @@ def make_menu_tree(): if p.type == 0 or p.type == 1: powers.append(p) - # power_dict = marshal(powers, RightsPower.fields2()) # 生成可序列化对象 power_dict = [ { 'id': item.id, @@ -118,8 +117,6 @@ def make_menu_tree(): 'icon': item.icon, 'sort': item.sort, 'enable': item.enable, - 'update_at': item.update_at.strftime('%Y-%m-%d %H:%M:%S'), - 'create_at': item.create_at.strftime('%Y-%m-%d %H:%M:%S'), } for item in powers ] power_dict.sort(key=lambda x: x['id'], reverse=True) @@ -143,15 +140,15 @@ def make_menu_tree(): # 删除权限(目前没有判断父节点自动删除子节点) def remove_power(power_id): - power = RightsPower.query.filter_by(id=power_id).first() + power = RightModels.query.filter_by(id=power_id).first() role_id_list = [] roles = power.role for role in roles: role_id_list.append(role.id) - roles = RightsRole.query.filter(RightsRole.id.in_(role_id_list)).all() + roles = RoleModels.query.filter(RoleModels.id.in_(role_id_list)).all() for p in roles: power.role.remove(p) - r = RightsPower.query.filter_by(id=power_id).delete() + r = RightModels.query.filter_by(id=power_id).delete() db.session.commit() return r @@ -177,8 +174,8 @@ class RightRightsResource(Resource): def get(self): """获取选择父节点""" - power = RightsPower.query.all() - # power_data = marshal(power, RightsPower.fields()) + power = RightModels.query.all() + # power_data = marshal(power, RightModels.fields()) power_data = [ { 'powerId': item.id, @@ -189,8 +186,6 @@ class RightRightsResource(Resource): 'parentId': item.parent_id, 'icon': item.icon, 'sort': item.sort, - 'create_at': item.create_at.strftime('%Y-%m-%d %H:%M:%S'), - 'update_at': item.update_at.strftime('%Y-%m-%d %H:%M:%S'), 'enable': item.enable, } for item in power ] @@ -211,7 +206,7 @@ class RightPowerResource(Resource): def post(self, power_id): res = parser_power.parse_args() - power = RightsPower( + power = RightModels( icon=res.icon, open_type=res.open_type, parent_id=res.parent_id, @@ -233,15 +228,15 @@ class RightPowerResource(Resource): def delete(self, power_id): # 删除权限(目前没有判断父节点自动删除子节点) - power = RightsPower.query.filter_by(id=power_id).first() + power = RightModels.query.filter_by(id=power_id).first() role_id_list = [] roles = power.role for role in roles: role_id_list.append(role.id) - roles = RightsRole.query.filter(RightsRole.id.in_(role_id_list)).all() + roles = RoleModels.query.filter(RoleModels.id.in_(role_id_list)).all() for p in roles: power.role.remove(p) - r = RightsPower.query.filter_by(id=power_id).delete() + r = RightModels.query.filter_by(id=power_id).delete() db.session.commit() if r: @@ -262,7 +257,7 @@ class RightPowerResource(Resource): "url": res.power_url, "sort": res.sort } - power = RightsPower.query.filter_by(id=power_id).update(data) + power = RightModels.query.filter_by(id=power_id).update(data) db.session.commit() if not power: @@ -273,7 +268,7 @@ class RightPowerResource(Resource): class RightPowerEnableResource(Resource): def put(self, right_id): - power = RightsPower.query.get(right_id) + power = RightModels.query.get(right_id) if power: power.enable = not power.enable db.session.commit() diff --git a/applications/api/rights/roles.py b/applications/api/rights/roles.py index c5b98ab..3ede002 100644 --- a/applications/api/rights/roles.py +++ b/applications/api/rights/roles.py @@ -1,28 +1,28 @@ from flask_restful import Resource, reqparse, marshal -from applications.common.utils.http import table_api, success_api, fail_api -from applications.extensions import db -from applications.models import RightsPower, RightsRole, CompanyUser +from common.utils.http import table_api, success_api, fail_api +from extensions import db +from models import RightModels, RoleModels, UserModels def remove_role(role_id): """ 删除角色 """ - role = RightsRole.query.filter_by(id=role_id).first() + role = RoleModels.query.filter_by(id=role_id).first() # 删除该角色的权限 power_id_list = [] for p in role.power: power_id_list.append(p.id) - powers = RightsPower.query.filter(RightsPower.id.in_(power_id_list)).all() + powers = RightModels.query.filter(RightModels.id.in_(power_id_list)).all() for p in powers: role.power.remove(p) user_id_list = [] for u in role.user: user_id_list.append(u.id) - users = CompanyUser.query.filter(CompanyUser.id.in_(user_id_list)).all() + users = UserModels.query.filter(UserModels.id.in_(user_id_list)).all() for u in users: role.user.remove(u) - r = RightsRole.query.filter_by(id=role_id).delete() + r = RoleModels.query.filter_by(id=role_id).delete() db.session.commit() return r @@ -46,11 +46,11 @@ class RoleRolesResource(Resource): filters = [] if res.role_name: - filters.append(RightsRole.name.like('%' + res.role_name + '%')) + filters.append(RoleModels.name.like('%' + res.role_name + '%')) if res.role_code: - filters.append(RightsRole.code.like('%' + res.role_code + '%')) + filters.append(RoleModels.code.like('%' + res.role_code + '%')) - paginate = RightsRole.query.filter(*filters).paginate(page=res.page, per_page=res.limit, error_out=False) + paginate = RoleModels.query.filter(*filters).paginate(page=res.page, per_page=res.limit, error_out=False) return table_api(result={'items': [{'id': item.id, 'roleName': item.name, @@ -59,7 +59,7 @@ class RoleRolesResource(Resource): 'comment': item.comment, 'details': item.details, 'sort': item.sort, - 'create_at': str(item.create_at), } for item in paginate.items], + } for item in paginate.items], 'total': paginate.total} , code=0) @@ -85,7 +85,7 @@ class RoleRoleResource(Resource): res = parser.parse_args() - role = RightsRole( + role = RoleModels( details=res.details, enable=res.enable, code=res.role_code, @@ -116,7 +116,7 @@ class RoleRoleResource(Resource): "details": res.details } - role = RightsRole.query.filter_by(id=role_id).update(data) + role = RoleModels.query.filter_by(id=role_id).update(data) db.session.commit() if not role: return fail_api(message="更新角色失败") @@ -127,7 +127,7 @@ class RoleEnableResource(Resource): """启用用户""" def put(self, role_id): - ret = RightsRole.query.get(role_id) + ret = RoleModels.query.get(role_id) ret.enable = not ret.enable db.session.commit() @@ -141,11 +141,11 @@ class RolePowerResource(Resource): def get(self, role_id): # 获取角色权限 - role = RightsRole.query.filter_by(id=role_id).first() + role = RoleModels.query.filter_by(id=role_id).first() # 获取权限列表的 id check_powers_list = [rp.id for rp in role.power] - powers = RightsPower.query.all() # 获取所有的权限 - powers = marshal(powers, RightsPower.fields()) + powers = RightModels.query.all() # 获取所有的权限 + powers = marshal(powers, RightModels.fields()) for i in powers: if int(i.get("powerId")) in check_powers_list: i["checkArr"] = "1" @@ -166,14 +166,14 @@ class RolePowerResource(Resource): power_list = res.power_ids.split(',') """ 更新角色权限 """ - role = RightsRole.query.filter_by(id=role_id).first() + role = RoleModels.query.filter_by(id=role_id).first() power_id_list = [] for p in role.power: power_id_list.append(p.id) - powers = RightsPower.query.filter(RightsPower.id.in_(power_id_list)).all() + powers = RightModels.query.filter(RightModels.id.in_(power_id_list)).all() for p in powers: role.power.remove(p) - powers = RightsPower.query.filter(RightsPower.id.in_(power_list)).all() + powers = RightModels.query.filter(RightModels.id.in_(power_list)).all() for p in powers: role.power.append(p) db.session.commit() diff --git a/applications/api/system/file.py b/applications/api/system/file.py index 8120436..e393478 100644 --- a/applications/api/system/file.py +++ b/applications/api/system/file.py @@ -4,10 +4,10 @@ from flask import request, jsonify, current_app from flask_restful import Resource from sqlalchemy import desc -from applications.common.utils.http import fail_api, success_api, table_api -from applications.common.utils.upload import upload_one, delete_photo_by_id -from applications.extensions import db -from applications.models import FilePhoto +from common.utils.http import fail_api, success_api, table_api +from common.utils.upload import upload_one, delete_photo_by_id +from extensions import db +from models import PhotoModels class FilePhotosResource(Resource): @@ -15,11 +15,10 @@ class FilePhotosResource(Resource): def get(self): page = request.args.get('page', type=int) limit = request.args.get('limit', type=int) - photo_paginate = FilePhoto.query.order_by(desc(FilePhoto.create_at) - ).paginate(page=page, + photo_paginate = PhotoModels.query.order_by(desc(PhotoModels.create_at) + ).paginate(page=page, per_page=limit, error_out=False) - # data = marshal(photo_paginate.items, FilePhoto.fields()) data = [ { 'id': item.id, @@ -55,11 +54,11 @@ class FilePhotosResource(Resource): """图片批量删除""" # TODO bugs 图片删除失败 ids = request.form.getlist('ids[]') - photo_name = FilePhoto.query.filter(FilePhoto.id.in_(ids)).all() + photo_name = PhotoModels.query.filter(PhotoModels.id.in_(ids)).all() upload_url = current_app.config.get("UPLOADED_PHOTOS_DEST") for p in photo_name: os.remove(upload_url + '/' + p.name) - photo = FilePhoto.query.filter(FilePhoto.id.in_(ids)).delete(synchronize_session=False) + photo = PhotoModels.query.filter(PhotoModels.id.in_(ids)).delete(synchronize_session=False) db.session.commit() if photo: return success_api(message="删除成功") diff --git a/applications/api/system/passport.py b/applications/api/system/passport.py index b2cf63b..9d1180b 100644 --- a/applications/api/system/passport.py +++ b/applications/api/system/passport.py @@ -3,10 +3,10 @@ from flask import session, redirect, url_for from flask_login import current_user, login_user from flask_restful import Resource, reqparse -from applications.common.gen_captcha import add_auth_session -from applications.common.utils.http import fail_api, success_api -from applications.common.utils.rights import record_logging -from applications.models import CompanyUser +from common.gen_captcha import add_auth_session +from common.utils.http import fail_api, success_api +from common.utils.rights import record_logging +from models import UserModels class LoginResource(Resource): @@ -28,7 +28,7 @@ class LoginResource(Resource): if req.captcha != s_code: return fail_api(message="验证码错误") - user = CompanyUser.query.filter_by(username=req.username).first() + user = UserModels.query.filter_by(username=req.username).first() if user is None: return fail_api(message="不存在的用户") diff --git a/applications/api/users/profile.py b/applications/api/users/profile.py index 275a25b..8025045 100644 --- a/applications/api/users/profile.py +++ b/applications/api/users/profile.py @@ -1,11 +1,10 @@ # 个人中心 from flask import request, jsonify -from flask_login import login_required from flask_restful import Resource, reqparse -from applications.common.utils.http import fail_api, success_api -from applications.extensions import db -from applications.models import CompanyUser +from common.utils.http import fail_api, success_api +from extensions import db +from models import UserModels class UserStatusResource(Resource): @@ -19,11 +18,11 @@ class UserStatusResource(Resource): res = parser.parse_args() if res.operate == 1: - user = CompanyUser.query.get(user_id) + user = UserModels.query.get(user_id) user.enable = res.operate message = success_api(message="启动成功") else: - user = CompanyUser.query.filter_by(id=res.user_id).update({"enable": res.operate}) + user = UserModels.query.filter_by(id=res.user_id).update({"enable": res.operate}) message = success_api(message="禁用成功") if user: db.session.commit() @@ -37,7 +36,7 @@ class UserAvatarResource(Resource): def put(self, user_id): url = request.json.get("avatar").get("src") - ret = CompanyUser.query.get(user_id) + ret = UserModels.query.get(user_id) ret.avatar = url db.session.commit() if not ret: @@ -56,7 +55,7 @@ class UserInfoResource(Resource): res = parser.parse_args() - ret = CompanyUser.query.get(user_id) + ret = UserModels.query.get(user_id) ret.username = res.username ret.realname = res.real_name ret.remark = res.details @@ -81,7 +80,7 @@ class UserPasswordResource(Resource): return fail_api(message='确认密码不一致') """ 修改当前用户密码 """ - user = CompanyUser.query.get(user_id) + user = UserModels.query.get(user_id) is_right = user.validate_password(res.oldPassword) if not is_right: return jsonify(success=False, message="旧密码错误") diff --git a/applications/api/users/user.py b/applications/api/users/user.py index ae05966..4f32106 100644 --- a/applications/api/users/user.py +++ b/applications/api/users/user.py @@ -3,35 +3,35 @@ from flask_login import current_user from flask_restful import Resource, reqparse from sqlalchemy import desc -from applications.common.utils.http import fail_api, success_api, table_api -from applications.extensions import db -from applications.models import CompanyUser, RightsRole, CompanyDepartment -from applications.models import LoggingModel +from common.utils.http import fail_api, success_api, table_api +from extensions import db +from models import UserModels, RoleModels, DepartmentModels +from models import LogModel def get_current_user_logs(): """ 获取当前用户日志 """ - log = LoggingModel.query.filter_by(url='/passport/login').filter_by(uid=current_user.id).order_by( - desc(LoggingModel.create_at)).limit(10) + log = LogModel.query.filter_by(url='/passport/login').filter_by(uid=current_user.id).order_by( + desc(LogModel.create_at)).limit(10) return log def is_user_exists(username): """ 判断用户是否存在 """ - res = CompanyUser.query.filter_by(username=username).count() + res = UserModels.query.filter_by(username=username).count() return bool(res) def delete_by_id(_id): """ 删除用户 """ - user = CompanyUser.query.filter_by(id=_id).first() + user = UserModels.query.filter_by(id=_id).first() roles_id = [] for role in user.role: roles_id.append(role.id) - roles = RightsRole.query.filter(RightsRole.id.in_(roles_id)).all() + roles = RoleModels.query.filter(RoleModels.id.in_(roles_id)).all() for r in roles: user.role.remove(r) - res = CompanyUser.query.filter_by(id=_id).delete() + res = UserModels.query.filter_by(id=_id).delete() db.session.commit() return res @@ -43,14 +43,14 @@ def batch_remove(ids): def update_user_role(_id, roles_list): - user = CompanyUser.query.filter_by(id=_id).first() + user = UserModels.query.filter_by(id=_id).first() roles_id = [] for role in user.role: roles_id.append(role.id) - roles = RightsRole.query.filter(RightsRole.id.in_(roles_id)).all() + roles = RoleModels.query.filter(RoleModels.id.in_(roles_id)).all() for r in roles: user.role.remove(r) - roles = RightsRole.query.filter(RightsRole.id.in_(roles_list)).all() + roles = RoleModels.query.filter(RoleModels.id.in_(roles_list)).all() for r in roles: user.role.append(r) db.session.commit() @@ -72,17 +72,17 @@ class UserUsersResource(Resource): filters = [] if res.real_name: - filters.append(CompanyUser.realname.like('%' + res.real_name + '%')) + filters.append(UserModels.realname.like('%' + res.real_name + '%')) if res.username: - filters.append(CompanyUser.username.like('%' + res.username + '%')) + filters.append(UserModels.username.like('%' + res.username + '%')) if res.dept_id: - filters.append(CompanyUser.dept_id == res.dept_id) + filters.append(UserModels.dept_id == res.dept_id) - paginate = CompanyUser.query.filter(*filters).paginate(page=res.page, - per_page=res.limit, - error_out=False) + paginate = UserModels.query.filter(*filters).paginate(page=res.page, + per_page=res.limit, + error_out=False) - dept_name = lambda dept_id: CompanyDepartment.query.filter_by(id=dept_id).first().dept_name if dept_id else "" + dept_name = lambda dept_id: DepartmentModels.query.filter_by(id=dept_id).first().dept_name if dept_id else "" user_data = [{ 'id': item.id, 'username': item.username, @@ -111,7 +111,7 @@ class UserUsersResource(Resource): if is_user_exists(res.username): return fail_api(message="用户已经存在") - user = CompanyUser() + user = UserModels() user.username = res.username user.realname = res.real_name user.set_password(res.password) @@ -119,8 +119,8 @@ class UserUsersResource(Resource): db.session.commit() """ 增加用户角色 """ - user = CompanyUser.query.filter_by(id=user.id).first() - roles = RightsRole.query.filter(RightsRole.id.in_(role_ids)).all() + user = UserModels.query.filter_by(id=user.id).first() + roles = RoleModels.query.filter(RoleModels.id.in_(role_ids)).all() for r in roles: user.role.append(r) db.session.commit() @@ -152,7 +152,7 @@ class UserUserResource(Resource): if is_user_exists(res.username): return fail_api(message="用户已经存在") - user = CompanyUser() + user = UserModels() user.username = res.username user.realname = res.real_name user.set_password(res.password) @@ -160,8 +160,8 @@ class UserUserResource(Resource): db.session.commit() """ 增加用户角色 """ - user = CompanyUser.query.filter_by(id=user.id).first() - roles = RightsRole.query.filter(RightsRole.id.in_(role_ids)).all() + user = UserModels.query.filter_by(id=user.id).first() + roles = RoleModels.query.filter(RoleModels.id.in_(role_ids)).all() for r in roles: user.role.append(r) db.session.commit() @@ -189,7 +189,7 @@ class UserRoleResource(Resource): role_ids = res.role_ids.split(',') # 更新用户数据 - CompanyUser.query.filter_by(id=user_id).update({'username': res.username, + UserModels.query.filter_by(id=user_id).update({'username': res.username, 'realname': res.real_name, 'dept_id': res.dept_id}) db.session.commit() diff --git a/applications/configs/__init__.py b/applications/configs/__init__.py deleted file mode 100644 index 8dcce20..0000000 --- a/applications/configs/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from .config import config diff --git a/applications/configs/common.py b/applications/configs/common.py deleted file mode 100644 index a58c9ee..0000000 --- a/applications/configs/common.py +++ /dev/null @@ -1,24 +0,0 @@ -SYSTEM_NAME = "Pear Admin" -# 主题面板的链接列表配置 -SYSTEM_PANEL_LINKS = [ - { - "icon": "layui-icon layui-icon-auz", - "title": "官方网站", - "href": "http://www.pearadmin.com" - }, - { - "icon": "layui-icon layui-icon-auz", - "title": "开发文档", - "href": "http://www.pearadmin.com" - }, - { - "icon": "layui-icon layui-icon-auz", - "title": "开源地址", - "href": "https://gitee.com/Jmysy/Pear-Admin-Layui" - } -] - -UPLOADED_PHOTOS_DEST = 'static/upload' -UPLOADED_FILES_ALLOW = ['gif', 'jpg'] -# JSON配置 -JSON_AS_ASCII = False diff --git a/applications/configs/config.py b/applications/configs/config.py deleted file mode 100644 index 53b8b6f..0000000 --- a/applications/configs/config.py +++ /dev/null @@ -1,54 +0,0 @@ -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" - - UPLOADED_PHOTOS_DEST = '/static' - - # 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_DATABASE_URI = r'sqlite:///sql_pear_admin.db' - SQLALCHEMY_TRACK_MODIFICATIONS = True - SQLALCHEMY_ECHO = False - - UPLOADED_PHOTOS_DEST = os.path.join(os.path.dirname(os.path.abspath(__name__)), 'static', 'upload') - - -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 -} diff --git a/applications/configs/init_data/__init__.py b/applications/configs/init_data/__init__.py deleted file mode 100644 index 324523f..0000000 --- a/applications/configs/init_data/__init__.py +++ /dev/null @@ -1,11 +0,0 @@ -import json -import os - -path = os.path.dirname(os.path.abspath(__file__)) -cp_dept_data_list = json.loads(open(os.path.join(path, 'cp_dept.json'), encoding='utf-8').read()) -cp_user_data_list = json.loads(open(os.path.join(path, 'cp_user.json'), encoding='utf-8').read()) -file_photo_data_list = json.loads(open(os.path.join(path, 'file_photo.json'), encoding='utf-8').read()) -rt_power_data_list = json.loads(open(os.path.join(path, 'rt_power.json'), encoding='utf-8').read()) -rt_role_data_list = json.loads(open(os.path.join(path, 'rt_role.json'), encoding='utf-8').read()) -rt_role_power_data_list = json.loads(open(os.path.join(path, 'rt_role_power.json'), encoding='utf-8').read()) -rt_user_role_data_list = json.loads(open(os.path.join(path, 'rt_user_role.json'), encoding='utf-8').read()) diff --git a/applications/extensions/init_databases/__init__.py b/applications/extensions/init_databases/__init__.py deleted file mode 100644 index bb32a87..0000000 --- a/applications/extensions/init_databases/__init__.py +++ /dev/null @@ -1,76 +0,0 @@ -from flask import Flask -import re -from datetime import datetime - -date_str = re.compile('\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d$') - - -def add_data(data_list, obj): - from applications.extensions import db - - for _data in data_list: - dept = obj() - for key, value in _data.items(): - - if isinstance(value, str) and date_str.match(value): - value = datetime.strptime(value, "%Y-%m-%d %H:%M:%S") - - setattr(dept, key, value) - db.session.add(dept) - db.session.commit() - - -def register_script(app: Flask): - @app.cli.command() - def init_db(): - """数据库初始化""" - - # 创建化部门数据 - from applications.models import CompanyDepartment - from applications.configs.init_data import cp_dept_data_list - add_data(cp_dept_data_list, CompanyDepartment) - - # 图片数据 - from applications.models import FilePhoto - from applications.configs.init_data import file_photo_data_list - - add_data(file_photo_data_list, FilePhoto) - - # 初始化权限表数据 - from applications.models import RightsPower - from applications.configs.init_data import rt_power_data_list - - add_data(rt_power_data_list, RightsPower) - # 初始化角色表 - from applications.models import RightsRole - from applications.configs.init_data import rt_role_data_list - - # 角色权限关系表 - from applications.extensions import db - from applications.configs.init_data import rt_role_power_data_list - for data in rt_role_power_data_list: - db.session.execute('insert into rt_role_power VALUES (%s, %s, %s);' % tuple(data)) - db.session.commit() - - add_data(rt_role_data_list, RightsRole) - - # 管理员用户 - from applications.models import CompanyUser - from applications.configs.init_data import cp_user_data_list - - add_data(cp_user_data_list, CompanyUser) - - # 用户角色表 - from applications.extensions import db - from applications.configs.init_data import rt_user_role_data_list - - for data in rt_user_role_data_list: - db.session.execute('insert into rt_user_role VALUES (%s, %s, %s);' % tuple(data)) - db.session.commit() - - @app.cli.command() - def turn(): - """清空数据库""" - from applications.extensions import db - db.drop_all() - db.create_all() diff --git a/applications/models/__init__.py b/applications/models/__init__.py deleted file mode 100644 index 093698a..0000000 --- a/applications/models/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -from applications.models.file import FilePhoto -from applications.models.log import LoggingModel -from applications.models.rights import RightsPower, RightsRole, role_power, user_role -from applications.models.users import CompanyDepartment, CompanyUser diff --git a/applications/models/base.py b/applications/models/base.py deleted file mode 100644 index 7983f3f..0000000 --- a/applications/models/base.py +++ /dev/null @@ -1,8 +0,0 @@ -from datetime import datetime - -from applications.extensions import db - - -class BaseModel(object): - create_at = db.Column(db.DateTime, default=datetime.now, comment='创建时间') - update_at = db.Column(db.DateTime, default=datetime.now, onupdate=datetime.now, comment='更新时间') diff --git a/applications/models/file/__init__.py b/applications/models/file/__init__.py deleted file mode 100644 index 1d4f66b..0000000 --- a/applications/models/file/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from .photo import FilePhoto diff --git a/applications/models/file/photo.py b/applications/models/file/photo.py deleted file mode 100644 index cb685fb..0000000 --- a/applications/models/file/photo.py +++ /dev/null @@ -1,12 +0,0 @@ -from applications.extensions import db - -from ..base import BaseModel - - -class FilePhoto(db.Model, BaseModel): - __tablename__ = 'file_photo' - id = db.Column(db.Integer, primary_key=True) - name = db.Column(db.String(255), nullable=False) - href = db.Column(db.String(255)) - mime = db.Column(db.CHAR(50), nullable=False) - size = db.Column(db.CHAR(30), nullable=False) diff --git a/applications/models/rights/__init__.py b/applications/models/rights/__init__.py deleted file mode 100644 index a6ef60b..0000000 --- a/applications/models/rights/__init__.py +++ /dev/null @@ -1,19 +0,0 @@ -from applications.extensions import db -from .power import RightsPower -from .role import RightsRole - -# 创建中间表 -user_role = db.Table( - "rt_user_role", # 中间表名称 - db.Column("id", db.Integer, primary_key=True, autoincrement=True, comment='标识'), # 主键 - db.Column("user_id", db.Integer, db.ForeignKey("cp_user.id"), comment='用户编号'), # 属性 外键 - db.Column("role_id", db.Integer, db.ForeignKey("rt_role.id"), comment='角色编号'), # 属性 外键 -) - -# 创建中间表 -role_power = db.Table( - "rt_role_power", # 中间表名称 - db.Column("id", db.Integer, primary_key=True, autoincrement=True, comment='标识'), # 主键 - db.Column("power_id", db.Integer, db.ForeignKey("rt_power.id"), comment='用户编号'), # 属性 外键 - db.Column("role_id", db.Integer, db.ForeignKey("rt_role.id"), comment='角色编号'), # 属性 外键 -) diff --git a/applications/models/rights/power.py b/applications/models/rights/power.py deleted file mode 100644 index 7b8f015..0000000 --- a/applications/models/rights/power.py +++ /dev/null @@ -1,18 +0,0 @@ -from applications.extensions import db -from ..base import BaseModel - - -class RightsPower(db.Model, BaseModel): - __tablename__ = 'rt_power' - id = db.Column(db.Integer, primary_key=True, comment='权限编号') - name = db.Column(db.String(255), comment='权限名称') - type = db.Column(db.SMALLINT, comment='权限类型') - code = db.Column(db.String(30), comment='权限标识') - url = db.Column(db.String(255), comment='权限路径') - open_type = db.Column(db.String(10), comment='打开方式') - parent_id = db.Column(db.Integer, db.ForeignKey("rt_power.id"), comment='父类编号') - icon = db.Column(db.String(128), comment='图标') - sort = db.Column(db.Integer, comment='排序') - enable = db.Column(db.Boolean, comment='是否开启') - - parent = db.relationship("RightsPower", remote_side=[id]) # 自关联 diff --git a/applications/models/rights/role.py b/applications/models/rights/role.py deleted file mode 100644 index 0e2224f..0000000 --- a/applications/models/rights/role.py +++ /dev/null @@ -1,17 +0,0 @@ -from flask_restful import fields - -from applications.extensions import db -from ..base import BaseModel - - -class RightsRole(db.Model, BaseModel): - __tablename__ = 'rt_role' - id = db.Column(db.Integer, primary_key=True, comment='角色ID') - name = db.Column(db.String(255), comment='角色名称') - code = db.Column(db.String(255), comment='角色标识') - enable = db.Column(db.Boolean, comment='是否启用') - comment = db.Column(db.String(255), comment='备注') - details = db.Column(db.String(255), comment='详情') - sort = db.Column(db.Integer, comment='排序') - - power = db.relationship('RightsPower', secondary="rt_role_power", backref=db.backref('role')) diff --git a/applications/models/users/__init__.py b/applications/models/users/__init__.py deleted file mode 100644 index 44ac199..0000000 --- a/applications/models/users/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -from .dept import CompanyDepartment -from .users import CompanyUser diff --git a/applications/models/users/dept.py b/applications/models/users/dept.py deleted file mode 100644 index c7b9409..0000000 --- a/applications/models/users/dept.py +++ /dev/null @@ -1,37 +0,0 @@ -from flask_restful import fields -from applications.extensions import db -from ..base import BaseModel - - -class CompanyDepartment(db.Model, BaseModel): - __tablename__ = 'cp_dept' - id = db.Column(db.Integer, primary_key=True, comment="部门ID") - parent_id = db.Column(db.Integer, comment="父级编号") - dept_name = db.Column(db.String(50), comment="部门名称") - leader = db.Column(db.String(50), comment="负责人") - phone = db.Column(db.String(20), comment="联系方式") - email = db.Column(db.String(50), comment="邮箱") - status = db.Column(db.Boolean, comment='状态(1开启,0关闭)') - comment = db.Column(db.Text, comment="备注") - address = db.Column(db.String(255), comment="详细地址") - sort = db.Column(db.Integer, comment="排序") - - @staticmethod - def fields(): - """ - 定义模型的常用输出字段,新手请忽略。可以简化字段序列化操作, - 详细操作请查看 flask-restful marshal 的用法 - """ - return { - 'deptId': fields.Integer(attribute="id"), - 'parentId': fields.Integer(attribute="parent_id"), - 'deptName': fields.String(attribute="dept_name"), - 'sort': fields.Integer, - 'leader': fields.String, - 'phone': fields.String, - 'email': fields.String, - 'status': fields.Boolean, - 'comment': fields.String, - 'address': fields.String, - 'create_at': fields.DateTime - } diff --git a/applications/view/department.py b/applications/view/department.py index d6c4d7d..45d078e 100644 --- a/applications/view/department.py +++ b/applications/view/department.py @@ -1,7 +1,7 @@ from flask import render_template, request -from applications.common.utils.rights import permission_required, view_logging_required -from applications.models import CompanyDepartment +from models import DepartmentModels +from common.utils.rights import permission_required, view_logging_required from applications.view import index_bp @@ -24,5 +24,5 @@ def add(): @permission_required("admin:dept:edit") def edit(): dept_id = request.args.get("deptId", type=int) - dept = CompanyDepartment.query.get(dept_id) + dept = DepartmentModels.query.get(dept_id) return render_template('admin/department/dept_edit.html', dept=dept) diff --git a/applications/view/file.py b/applications/view/file.py index 90b67d3..a84a0eb 100644 --- a/applications/view/file.py +++ b/applications/view/file.py @@ -1,7 +1,7 @@ from flask import render_template from applications.view import index_bp -from applications.common.utils.rights import view_logging_required, permission_required +from common.utils.rights import view_logging_required, permission_required @index_bp.get('/file') diff --git a/applications/view/logs_view.py b/applications/view/logs_view.py index 7e544b4..dabaf01 100644 --- a/applications/view/logs_view.py +++ b/applications/view/logs_view.py @@ -1,9 +1,9 @@ from flask import Blueprint, request, render_template from sqlalchemy import desc -from applications.common.utils.http import table_api -from applications.common.utils.rights import permission_required -from applications.models import LoggingModel +from common.utils.http import table_api +from common.utils.rights import permission_required +from models import LogModel logs_bp = Blueprint('logs', __name__, url_prefix='/logs') @@ -19,9 +19,9 @@ def index(): def login_log(): page = request.args.get('page', type=int) limit = request.args.get('limit', type=int) - log_paginate = LoggingModel.query.filter_by( + log_paginate = LogModel.query.filter_by( url='/api/v1/passport/login').order_by( - desc(LoggingModel.create_at)).paginate( + desc(LogModel.create_at)).paginate( page=page, per_page=limit, error_out=False) data = [ { @@ -47,9 +47,9 @@ def login_log(): def operate_log(): page = request.args.get('page', type=int) limit = request.args.get('limit', type=int) - log_paginate = LoggingModel.query.filter( - LoggingModel.url != '/api/v1/passport/login').order_by( - desc(LoggingModel.create_at)).paginate( + log_paginate = LogModel.query.filter( + LogModel.url != '/api/v1/passport/login').order_by( + desc(LogModel.create_at)).paginate( page=page, per_page=limit, error_out=False) data = [ { diff --git a/applications/view/passport.py b/applications/view/passport.py index 0e4657a..b5c2ccb 100644 --- a/applications/view/passport.py +++ b/applications/view/passport.py @@ -1,8 +1,8 @@ -from flask import Blueprint, session, redirect, render_template, url_for +from flask import session, redirect, render_template, url_for from flask_login import login_required, logout_user, current_user -from applications.common.gen_captcha import get_captcha_image -from applications.common.utils.http import success_api +from common.gen_captcha import get_captcha_image +from common.utils.http import success_api # 获取验证码 from applications.view import index_bp diff --git a/applications/view/rights.py b/applications/view/rights.py index bdbad13..a45de9e 100644 --- a/applications/view/rights.py +++ b/applications/view/rights.py @@ -1,7 +1,7 @@ from flask import render_template -from applications.common.utils.rights import permission_required, view_logging_required -from applications.models import RightsPower +from common.utils.rights import permission_required, view_logging_required +from models import RightModels from applications.view import index_bp @@ -16,7 +16,7 @@ def rights_index(): @view_logging_required @permission_required("admin:power:edit") def rights_edit(power_id): - power = RightsPower.query.filter_by(id=power_id).first() + power = RightModels.query.filter_by(id=power_id).first() icon = str(power.icon).split() if len(icon) == 2: icon = icon[1] diff --git a/applications/view/roles.py b/applications/view/roles.py index 3cc27ab..8122960 100644 --- a/applications/view/roles.py +++ b/applications/view/roles.py @@ -1,8 +1,8 @@ from flask import Blueprint, render_template -from applications.common.utils.rights import permission_required, view_logging_required +from common.utils.rights import permission_required, view_logging_required -from applications.models import RightsRole +from models import RoleModels role_bp = Blueprint('role', __name__, url_prefix='/admin/role') @@ -28,7 +28,7 @@ def power(role_id): @view_logging_required @permission_required("admin:role:edit") def role_editor(role_id): - role = RightsRole.query.filter_by(id=role_id).first() + role = RoleModels.query.filter_by(id=role_id).first() return render_template('admin/roles/roles_edit.html', role=role) diff --git a/applications/view/users.py b/applications/view/users.py index 7db34d2..e348b6b 100644 --- a/applications/view/users.py +++ b/applications/view/users.py @@ -2,8 +2,8 @@ from flask import render_template from flask_login import login_required, current_user from sqlalchemy import desc -from applications.common.utils.rights import permission_required, view_logging_required -from applications.models import LoggingModel, RightsRole, CompanyUser +from common.utils.rights import permission_required, view_logging_required +from models import LogModel, RoleModels, UserModels from . import index_bp @@ -19,7 +19,7 @@ def users_main(): @view_logging_required @permission_required("admin:user:add") def users_add_view(): - roles = RightsRole.query.all() + roles = RoleModels.query.all() return render_template('admin/users/users_add.html', roles=roles) @@ -28,8 +28,8 @@ def users_add_view(): @permission_required("admin:user:edit") def users_user_id_view(user_id): # 获取编辑用户信息 - user = CompanyUser.query.filter_by(id=user_id).first() - roles = RightsRole.query.all() + user = UserModels.query.filter_by(id=user_id).first() + roles = RoleModels.query.all() checked_roles = [] for r in user.role: checked_roles.append(r.id) @@ -39,8 +39,8 @@ def users_user_id_view(user_id): @index_bp.get('/users/center') @login_required def users_center(): - user_logs = LoggingModel.query.filter_by(url='/passport/login').filter_by(uid=current_user.id).order_by( - desc(LoggingModel.create_at)).limit(10) + user_logs = LogModel.query.filter_by(url='/passport/login').filter_by(uid=current_user.id).order_by( + desc(LogModel.create_at)).limit(10) return render_template('admin/users/profile.html', user_info=current_user, user_logs=user_logs) diff --git a/applications/common/__init__.py b/common/__init__.py similarity index 100% rename from applications/common/__init__.py rename to common/__init__.py diff --git a/applications/common/flask_uploads.py b/common/flask_uploads.py similarity index 100% rename from applications/common/flask_uploads.py rename to common/flask_uploads.py diff --git a/applications/common/gen_captcha.py b/common/gen_captcha.py similarity index 100% rename from applications/common/gen_captcha.py rename to common/gen_captcha.py diff --git a/applications/common/utils/http.py b/common/utils/http.py similarity index 100% rename from applications/common/utils/http.py rename to common/utils/http.py diff --git a/applications/common/utils/rights.py b/common/utils/rights.py similarity index 92% rename from applications/common/utils/rights.py rename to common/utils/rights.py index 93df175..0a470fd 100644 --- a/applications/common/utils/rights.py +++ b/common/utils/rights.py @@ -5,8 +5,8 @@ from flask import abort, request, jsonify, session from flask_login import login_required from flask_login import current_user -from applications.extensions import db -from applications.models import LoggingModel +from extensions import db +from models import LogModel def record_logging(success: bool = True) -> None: @@ -22,7 +22,7 @@ def record_logging(success: bool = True) -> None: 'uid': current_user.id, 'success': success } - log = LoggingModel() + log = LogModel() for key, value in info.items(): setattr(log, key, value) diff --git a/applications/common/utils/upload.py b/common/utils/upload.py similarity index 62% rename from applications/common/utils/upload.py rename to common/utils/upload.py index a682c99..4f20c34 100644 --- a/applications/common/utils/upload.py +++ b/common/utils/upload.py @@ -2,9 +2,9 @@ import os from flask import current_app -from applications.common.flask_uploads import UploadSet, IMAGES -from applications.extensions import db -from applications.models import FilePhoto +from common.flask_uploads import UploadSet, IMAGES +from extensions import db +from models import PhotoModels photos = UploadSet('photos', IMAGES) @@ -15,15 +15,15 @@ def upload_one(photo, mime): upload_url = current_app.config.get("UPLOADED_PHOTOS_DEST") size = os.path.getsize(upload_url + '/' + filename) - photo = FilePhoto(name=filename, href=file_url, mime=mime, size=size) + photo = PhotoModels(name=filename, href=file_url, mime=mime, size=size) db.session.add(photo) db.session.commit() return file_url def delete_photo_by_id(_id): - photo_name = FilePhoto.query.filter_by(id=_id).first().name - photo = FilePhoto.query.filter_by(id=_id).delete() + photo_name = PhotoModels.query.filter_by(id=_id).first().name + photo = PhotoModels.query.filter_by(id=_id).delete() db.session.commit() upload_url = current_app.config.get("UPLOADED_PHOTOS_DEST") os.remove(upload_url + '/' + photo_name) diff --git a/config.py b/config.py new file mode 100644 index 0000000..2fd026e --- /dev/null +++ b/config.py @@ -0,0 +1,51 @@ +import logging +import os + +# 主题面板的链接列表配置 +SYSTEM_NAME = "Pear Admin" +SYSTEM_PANEL_LINKS = [ + { + "icon": "layui-icon layui-icon-auz", + "title": "官方网站", + "href": "http://www.pearadmin.com" + }, + { + "icon": "layui-icon layui-icon-auz", + "title": "开发文档", + "href": "http://www.pearadmin.com" + }, + { + "icon": "layui-icon layui-icon-auz", + "title": "开源地址", + "href": "https://gitee.com/Jmysy/Pear-Admin-Layui" + } +] + +SECRET_KEY = os.getenv('SECRET_KEY', 'dev key') + +# mysql 配置 +MYSQL_USERNAME = "root" +MYSQL_PASSWORD = "123456" +MYSQL_HOST = "127.0.0.1" +MYSQL_PORT = 3306 +MYSQL_DATABASE = "PearAdminFlask" + +# redis 配置 +REDIS_HOST = "127.0.0.1" +REDIS_PORT = 6379 + +""" Sqlalchemy 配置 """ +SQLALCHEMY_DATABASE_URI = r'sqlite:///pear_admin.db' +SQLALCHEMY_TRACK_MODIFICATIONS = True +SQLALCHEMY_ECHO = False +SQLALCHEMY_POOL_RECYCLE = 8 +# SQLALCHEMY_DATABASE_URI = f"mysql+pymysql://{MYSQL_USERNAME}:{MYSQL_PASSWORD}@\ +# {MYSQL_HOST}:{MYSQL_PORT}/{MYSQL_DATABASE}" + +LOG_LEVEL = logging.ERROR + +# 图片文件存放位置 +UPLOADED_PHOTOS_DEST = os.path.join(os.path.dirname(os.path.abspath(__name__)), 'static', 'upload') +UPLOADED_FILES_ALLOW = ['gif', 'jpg'] +# JSON配置 +JSON_AS_ASCII = False diff --git a/applications/extensions/__init__.py b/extensions/__init__.py similarity index 100% rename from applications/extensions/__init__.py rename to extensions/__init__.py diff --git a/extensions/init_databases.py b/extensions/init_databases.py new file mode 100644 index 0000000..1f67bec --- /dev/null +++ b/extensions/init_databases.py @@ -0,0 +1,82 @@ +from flask import Flask +import re +from datetime import datetime + +date_str = re.compile('\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d$') + + +def add_data(data_list, obj): + from extensions import db + + for _data in data_list: + dept = obj() + for key, value in _data.items(): + + if isinstance(value, str) and date_str.match(value): + value = datetime.strptime(value, "%Y-%m-%d %H:%M:%S") + + setattr(dept, key, value) + db.session.add(dept) + db.session.commit() + + +def register_script(app: Flask): + @app.cli.command() + def init_db(): + import json + import os + + path = os.path.dirname(os.path.abspath(__name__)) + path = os.path.join(path, 'static', 'data') + cp_dept_data_list = json.loads(open(os.path.join(path, 'cp_dept.json'), encoding='utf-8').read()) + cp_user_data_list = json.loads(open(os.path.join(path, 'cp_user.json'), encoding='utf-8').read()) + file_photo_data_list = json.loads(open(os.path.join(path, 'file_photo.json'), encoding='utf-8').read()) + rt_power_data_list = json.loads(open(os.path.join(path, 'rt_power.json'), encoding='utf-8').read()) + rt_role_data_list = json.loads(open(os.path.join(path, 'rt_role.json'), encoding='utf-8').read()) + rt_role_power_data_list = json.loads(open(os.path.join(path, 'rt_role_power.json'), encoding='utf-8').read()) + rt_user_role_data_list = json.loads(open(os.path.join(path, 'rt_user_role.json'), encoding='utf-8').read()) + + """数据库初始化""" + + # 创建化部门数据 + from models import DepartmentModels + add_data(cp_dept_data_list, DepartmentModels) + + # 图片数据 + from models import PhotoModels + + add_data(file_photo_data_list, PhotoModels) + + # 初始化权限表数据 + from models import RightModels + + add_data(rt_power_data_list, RightModels) + # 初始化角色表 + from models import RoleModels + + # 角色权限关系表 + from extensions import db + for data in rt_role_power_data_list: + db.session.execute('insert into rt_role_power VALUES (%s, %s, %s);' % tuple(data)) + db.session.commit() + + add_data(rt_role_data_list, RoleModels) + + # 管理员用户 + from models import UserModels + + add_data(cp_user_data_list, UserModels) + + # 用户角色表 + from extensions import db + + for data in rt_user_role_data_list: + db.session.execute('insert into rt_user_role VALUES (%s, %s, %s);' % tuple(data)) + db.session.commit() + + @app.cli.command() + def turn(): + """清空数据库""" + from extensions import db + db.drop_all() + db.create_all() diff --git a/applications/extensions/init_dotenv.py b/extensions/init_dotenv.py similarity index 100% rename from applications/extensions/init_dotenv.py rename to extensions/init_dotenv.py diff --git a/applications/extensions/init_error_views.py b/extensions/init_error_views.py similarity index 100% rename from applications/extensions/init_error_views.py rename to extensions/init_error_views.py diff --git a/applications/extensions/init_login.py b/extensions/init_login.py similarity index 75% rename from applications/extensions/init_login.py rename to extensions/init_login.py index a435c93..5128ac6 100644 --- a/applications/extensions/init_login.py +++ b/extensions/init_login.py @@ -10,6 +10,6 @@ def init_login_manager(app): @login_manager.user_loader def load_user(user_id): - from applications.models import CompanyUser - user = CompanyUser.query.get(int(user_id)) + from models import UserModels + user = UserModels.query.get(int(user_id)) return user diff --git a/applications/extensions/init_sqlalchemy.py b/extensions/init_sqlalchemy.py similarity index 100% rename from applications/extensions/init_sqlalchemy.py rename to extensions/init_sqlalchemy.py diff --git a/applications/extensions/init_template_directives.py b/extensions/init_template_directives.py similarity index 100% rename from applications/extensions/init_template_directives.py rename to extensions/init_template_directives.py diff --git a/models/__init__.py b/models/__init__.py new file mode 100644 index 0000000..afc19df --- /dev/null +++ b/models/__init__.py @@ -0,0 +1,4 @@ +from .file import PhotoModels +from .rights import RightModels, RoleModels +from .system import LogModel +from .users import UserModels, DepartmentModels diff --git a/models/file.py b/models/file.py new file mode 100644 index 0000000..623d1ab --- /dev/null +++ b/models/file.py @@ -0,0 +1,15 @@ +from datetime import datetime + +from extensions import db + + +class PhotoModels(db.Model): + __tablename__ = 'file_photo' + id = db.Column(db.Integer, primary_key=True) + name = db.Column(db.String(255), nullable=False) + href = db.Column(db.String(255)) + mime = db.Column(db.CHAR(50), nullable=False) + size = db.Column(db.CHAR(30), nullable=False) + + create_at = db.Column(db.DateTime, default=datetime.now, comment='创建时间') + update_at = db.Column(db.DateTime, default=datetime.now, onupdate=datetime.now, comment='更新时间') diff --git a/models/rights.py b/models/rights.py new file mode 100644 index 0000000..44b8364 --- /dev/null +++ b/models/rights.py @@ -0,0 +1,46 @@ +from extensions import db + +# 创建中间表 +user_role = db.Table( + "rt_user_role", # 中间表名称 + db.Column("id", db.Integer, primary_key=True, autoincrement=True, comment='标识'), # 主键 + db.Column("user_id", db.Integer, db.ForeignKey("cp_user.id"), comment='用户编号'), # 属性 外键 + db.Column("role_id", db.Integer, db.ForeignKey("rt_role.id"), comment='角色编号'), # 属性 外键 +) + +# 创建中间表 +role_power = db.Table( + "rt_role_power", # 中间表名称 + db.Column("id", db.Integer, primary_key=True, autoincrement=True, comment='标识'), # 主键 + db.Column("power_id", db.Integer, db.ForeignKey("rt_power.id"), comment='用户编号'), # 属性 外键 + db.Column("role_id", db.Integer, db.ForeignKey("rt_role.id"), comment='角色编号'), # 属性 外键 +) + + +class RightModels(db.Model): + __tablename__ = 'rt_power' + id = db.Column(db.Integer, primary_key=True, comment='权限编号') + name = db.Column(db.String(255), comment='权限名称') + type = db.Column(db.SMALLINT, comment='权限类型') + code = db.Column(db.String(30), comment='权限标识') + url = db.Column(db.String(255), comment='权限路径') + open_type = db.Column(db.String(10), comment='打开方式') + parent_id = db.Column(db.Integer, db.ForeignKey("rt_power.id"), comment='父类编号') + icon = db.Column(db.String(128), comment='图标') + sort = db.Column(db.Integer, comment='排序') + enable = db.Column(db.Boolean, comment='是否开启') + + parent = db.relationship("RightModels", remote_side=[id]) # 自关联 + + +class RoleModels(db.Model): + __tablename__ = 'rt_role' + id = db.Column(db.Integer, primary_key=True, comment='角色ID') + name = db.Column(db.String(255), comment='角色名称') + code = db.Column(db.String(255), comment='角色标识') + enable = db.Column(db.Boolean, comment='是否启用') + comment = db.Column(db.String(255), comment='备注') + details = db.Column(db.String(255), comment='详情') + sort = db.Column(db.Integer, comment='排序') + + power = db.relationship('RightModels', secondary="rt_role_power", backref=db.backref('role')) diff --git a/applications/models/log.py b/models/system.py similarity index 56% rename from applications/models/log.py rename to models/system.py index fab1952..98e4e64 100644 --- a/applications/models/log.py +++ b/models/system.py @@ -1,10 +1,9 @@ -from flask_restful import fields +from datetime import datetime -from applications.extensions import db -from .base import BaseModel +from extensions import db -class LoggingModel(db.Model, BaseModel): +class LogModel(db.Model): __tablename__ = 'lg_logging' id = db.Column(db.Integer, primary_key=True) method = db.Column(db.String(10)) @@ -14,3 +13,6 @@ class LoggingModel(db.Model, BaseModel): ip = db.Column(db.String(255)) success = db.Column(db.Boolean, default=True) user_agent = db.Column(db.Text) + + create_at = db.Column(db.DateTime, default=datetime.now, comment='创建时间') + update_at = db.Column(db.DateTime, default=datetime.now, onupdate=datetime.now, comment='更新时间') diff --git a/applications/models/users/users.py b/models/users.py similarity index 50% rename from applications/models/users/users.py rename to models/users.py index 74711ab..03ab84c 100644 --- a/applications/models/users/users.py +++ b/models/users.py @@ -1,12 +1,12 @@ +from datetime import datetime + from flask_login import UserMixin from werkzeug.security import generate_password_hash, check_password_hash -from flask_restful import fields -from applications.extensions import db -from ..base import BaseModel +from extensions import db -class CompanyUser(db.Model, UserMixin, BaseModel): +class UserModels(db.Model, UserMixin): __tablename__ = 'cp_user' id = db.Column(db.Integer, primary_key=True, autoincrement=True, comment='用户ID') username = db.Column(db.String(20), comment='用户名') @@ -18,7 +18,7 @@ class CompanyUser(db.Model, UserMixin, BaseModel): enable = db.Column(db.Integer, default=0, comment='启用') dept_id = db.Column(db.Integer, comment='部门id') - role = db.relationship('RightsRole', secondary="rt_user_role", backref=db.backref('user'), lazy='dynamic') + role = db.relationship('RoleModels', secondary="rt_user_role", backref=db.backref('user'), lazy='dynamic') def set_password(self, password): """设置密码,对密码进行加密存储""" @@ -27,3 +27,22 @@ class CompanyUser(db.Model, UserMixin, BaseModel): def validate_password(self, password): """校验密码方法""" return check_password_hash(self.password_hash, password) + + create_at = db.Column(db.DateTime, default=datetime.now, comment='创建时间') + update_at = db.Column(db.DateTime, default=datetime.now, onupdate=datetime.now, comment='更新时间') + + +class DepartmentModels(db.Model): + __tablename__ = 'cp_dept' + id = db.Column(db.Integer, primary_key=True, comment="部门ID") + parent_id = db.Column(db.Integer, comment="父级编号") + dept_name = db.Column(db.String(50), comment="部门名称") + leader = db.Column(db.String(50), comment="负责人") + phone = db.Column(db.String(20), comment="联系方式") + email = db.Column(db.String(50), comment="邮箱") + status = db.Column(db.Boolean, comment='状态(1开启,0关闭)') + comment = db.Column(db.Text, comment="备注") + address = db.Column(db.String(255), comment="详细地址") + sort = db.Column(db.Integer, comment="排序") + + create_at = db.Column(db.DateTime, default=datetime.now, comment='创建时间') diff --git a/requirement/requirement-dev.txt b/requirement.txt similarity index 96% rename from requirement/requirement-dev.txt rename to requirement.txt index 0d3d19f..32f03e5 100644 --- a/requirement/requirement-dev.txt +++ b/requirement.txt @@ -23,3 +23,4 @@ pytz==2021.1 six==1.16.0 SQLAlchemy==1.4.18 Werkzeug==2.0.1 +gunicorn==20.1.0 \ No newline at end of file diff --git a/requirement/requirement.txt b/requirement/requirement.txt deleted file mode 100644 index 0d29f39..0000000 --- a/requirement/requirement.txt +++ /dev/null @@ -1,2 +0,0 @@ -gunicorn==20.1.0 --r requirement-dev.txt diff --git a/applications/configs/init_data/cp_dept.json b/static/data/cp_dept.json similarity index 100% rename from applications/configs/init_data/cp_dept.json rename to static/data/cp_dept.json diff --git a/applications/configs/init_data/cp_user.json b/static/data/cp_user.json similarity index 100% rename from applications/configs/init_data/cp_user.json rename to static/data/cp_user.json diff --git a/applications/configs/init_data/file_photo.json b/static/data/file_photo.json similarity index 100% rename from applications/configs/init_data/file_photo.json rename to static/data/file_photo.json diff --git a/applications/configs/init_data/rt_power.json b/static/data/rt_power.json similarity index 100% rename from applications/configs/init_data/rt_power.json rename to static/data/rt_power.json diff --git a/applications/configs/init_data/rt_role.json b/static/data/rt_role.json similarity index 100% rename from applications/configs/init_data/rt_role.json rename to static/data/rt_role.json diff --git a/applications/configs/init_data/rt_role_power.json b/static/data/rt_role_power.json similarity index 100% rename from applications/configs/init_data/rt_role_power.json rename to static/data/rt_role_power.json diff --git a/applications/configs/init_data/rt_user_role.json b/static/data/rt_user_role.json similarity index 100% rename from applications/configs/init_data/rt_user_role.json rename to static/data/rt_user_role.json diff --git a/templates/admin/rights/rights.html b/templates/admin/rights/rights.html index 34d108a..c052e6b 100644 --- a/templates/admin/rights/rights.html +++ b/templates/admin/rights/rights.html @@ -83,7 +83,7 @@ field: 'enable', title: '是否可用', templet: (d) => { // TODO 修改禁用启动逻辑 return `` + true ? 'checked=checked' : ''}>` }, }, { field: 'sort', title: '排序' },