diff --git a/.flaskenv b/.flaskenv index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..007748f1e9703f86140834cf44d749a887cc7fb7 100644 --- a/.flaskenv +++ b/.flaskenv @@ -0,0 +1,17 @@ +# 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")' diff --git a/.gitignore b/.gitignore index 935a2f887fda48ac4d5918b06eb131eea0faa62f..3dae7c480606c2b394a4158743ca3e8a61ae527e 100644 --- a/.gitignore +++ b/.gitignore @@ -115,4 +115,10 @@ dmypy.json .pyre/ #ide -.idea/ \ No newline at end of file +.idea/ + +# 数据库文件 +*.db +#上传到本地的图片文件 +*upload* +migrations/ \ No newline at end of file diff --git a/README.md b/README.md index 5225fa33b26ae6d30f6df4007db5cb8d4d34be1e..9edafdc6fe0f7a8c87a34117ca6b805f2b13bc73 100644 --- a/README.md +++ b/README.md @@ -30,17 +30,23 @@ #### 项目简介 ->Pear Admin Flask 基于 Flask 的后台管理系统,拥抱应用广泛的python语言,通过使用本系统,即可快速构建你的功能业务 -> ->项目旨在为python开发者提供一个后台管理系统的模板,成为您构建信息管理系统,物联网后台....等等应用时灵活,简单的工具 -> ->各位Python爱好者多多指教 +Pear Admin Flask 基于 Flask 生态的后台管理系统,该项目旨在为 python 开发者提供一个快速开发前后端半分离的后台管理系统的模板 -Pear Admin Flask 分为 Common / Simple 两个版本: +在使用本项目之前最好掌握以下知识点 -[** Common 通用版本 **](https://gitee.com/pear-admin/pear-admin-flask/tree/master/) ++ html、css、JavaScript ++ jQuery ++ layui ++ flask ++ flask-login ++ flask-sqlalchemy ++ flask-restful -[** Simple 简洁版本 **](https://gitee.com/pear-admin/pear-admin-flask/tree/simple/) + +Pear Admin Flask 分为 Common / Simple 两个版本: + +[Common 通用版本](https://gitee.com/pear-admin/pear-admin-flask/tree/master/) +[Simple 简洁版本](https://gitee.com/pear-admin/pear-admin-flask/tree/simple/) #### 内置功能 @@ -49,9 +55,7 @@ Pear Admin Flask 分为 Common / Simple 两个版本: - [x] 角色管理:角色菜单权限分配。 - [x] 操作日志:系统正常操作日志记录和查询;系统异常信息日志记录和查询。 - [x] 登录日志:系统登录日志记录查询包含登录异常。 -- [x] 服务监控:监视当前系统CPU、内存、磁盘、python版本,运行时长等相关信息。 -- [x] 文件上传: 图片上传示例 -- [ ] 代码生成: 构想中.... +- [x] 文件上传: 图片上传示例 #### 项目结构 @@ -73,62 +77,46 @@ Pear Admin Flask ├─requirement # 依赖文件 ├─test # 测试文件夹(占坑) └─.env # 项目的配置文件 - ``` +#### 项目启动 - -#### 项目安装 - +##### 1. 下载源码 ```bash -# 下 载 git clone https://gitee.com/pear-admin/pear-admin-flask -# 安 装 -pip install -r requirement\requirement-dev.txt - -# 配 置 -.env - +# 切换分支 +git checkout mini ``` -#### 修改配置 - -```python -# 主 机 -HOST = '127.0.0.1' - -# 端 口 -PORT = '3306' - -# 数 据 库 -DATABASE = 'PearAdminFlask' - -# 账 户 -USERNAME = 'root' +##### 2. 安装依赖 +```bash +# 创建虚拟环境 +python -m venv venv -# 密 码 -PASSWORD = 'root' +# 然后使虚拟环境生效(windows,Linux自行解决) +venv\Scripts\activate +# 安装依赖 +pip install -r requirement\requirement-dev.txt ``` -#### Venv 安装 - +##### 3. 数据迁移 +默认的使用 `sqlite3` 作为开发环境的数据库进行演示,如果需要二次开发,建议改成 `mysql` 。 ```bash -python -m venv venv +flask db init +flask db migrate -m '数据初始化' +flask db upgrade +flask init-db ``` -#### 运行项目 -```bash -# 初 始 化 数 据 库 -python test\init_databases.py - -``` +##### 4. 其他事项 -执行 flask run 命令启动项目 +如果需要在开发环境使用 mysql 作为数据库,请查看 `applications/configs/config.py` 文件里面的相关配置文件 +如果需要修改数据的配置信息,请在 `.flaskenv` 里面调整即可 #### 预览项目 diff --git a/app.py b/app.py deleted file mode 100644 index a5622a5f989ca794dafc5932f0163f9cf4de5952..0000000000000000000000000000000000000000 --- a/app.py +++ /dev/null @@ -1,6 +0,0 @@ -from applications import create_app - -app = create_app() - -if __name__ == '__main__': - app.run() diff --git a/applications/__init__.py b/applications/__init__.py index 2592ddfb72167acbd53fff2b0bd1842699a59ed7..8c4b209c6f85c8e1ec43335af857bbdbf86ee6ba 100644 --- a/applications/__init__.py +++ b/applications/__init__.py @@ -30,10 +30,29 @@ def create_app(config_name=None): configure_uploads(app, photos) logo() - + register_shell(app) return app +def register_shell(app: Flask): + @app.cli.command() + def create(): + """测试关系""" + from .extensions import db + from .models import Power, User + from .models import PowerSchema + power_schema = PowerSchema(many=True) # 用已继承 ma.ModelSchema 类的自定制类生成序列化类 + user = User.query.get(1) + power_list = [] + for role in user.role: + if role.enable: + for power in role.power: + # 权限被启用 + if power.enable and power: + power_list.append(power) + power_dict = sorted(power_list, key=lambda i: i['sort']) + + def logo(): print(''' _____ _ _ ______ _ _ diff --git a/applications/common/admin/dept_curd.py b/applications/common/admin/dept_curd.py deleted file mode 100644 index ba5b05ff632f93cb8567972fef2b5cc465e2f725..0000000000000000000000000000000000000000 --- a/applications/common/admin/dept_curd.py +++ /dev/null @@ -1,87 +0,0 @@ -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(): - dept = Dept.query.order_by(Dept.sort).all() - res = model_to_dicts(Schema=DeptSchema, model=dept) - return res - - -def save_dept(req): - address = xss_escape(req.get("address")) - deptName = xss_escape(req.get("deptName")) - email = xss_escape(req.get("email")) - leader = xss_escape(req.get("leader")) - parentId = xss_escape(req.get("parentId")) - phone = xss_escape(req.get("phone")) - sort = xss_escape(req.get("sort")) - status = xss_escape(req.get("status")) - dept = Dept( - parent_id=parentId, - dept_name=deptName, - sort=sort, - leader=leader, - phone=phone, - email=email, - status=status, - address=address - ) - r = db.session.add(dept) - db.session.commit() - return r - - -def get_dept_by_id(id): - d = Dept.query.filter_by(id=id).first() - return d - - -# 启动权限 -def enable_status(id): - enable = 1 - d = Dept.query.filter_by(id=id).update({"status": enable}) - if d: - db.session.commit() - return True - return False - - -# 停用权限 -def disable_status(id): - enable = 0 - d = Dept.query.filter_by(id=id).update({"status": enable}) - if d: - db.session.commit() - return True - return False - - -def update_dept(json): - id = json.get("deptId"), - data = { - "dept_name": xss_escape(json.get("deptName")), - "sort": xss_escape(json.get("sort")), - "leader": xss_escape(json.get("leader")), - "phone": xss_escape(json.get("phone")), - "email": xss_escape(json.get("email")), - "status": xss_escape(json.get("status")), - "address": xss_escape(json.get("address")) - } - d = Dept.query.filter_by(id=id).update(data) - if not d: - return False - db.session.commit() - return True - - -def remove_dept(id): - d = Dept.query.filter_by(id=id).delete() - if not d: - return False - User.query.filter_by(dept_id=id).update({"dept_id": None}) - db.session.commit() - return True diff --git a/applications/common/admin/dict_curd.py b/applications/common/admin/dict_curd.py deleted file mode 100644 index 8f674c69fed882bf79d41428afb44eca019ae9fa..0000000000000000000000000000000000000000 --- a/applications/common/admin/dict_curd.py +++ /dev/null @@ -1,145 +0,0 @@ -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 = [] - 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) - else: - return None - return dict_list - - -def get_dict_type(page, limit, type_name): - dict_all = DictType.query - if type_name: - dict_all = dict_all.filter(DictType.type_name.like('%' + type_name + '%')) - dict_all = dict_all.paginate(page=page, - per_page=limit, - error_out=False) - count = DictType.query.count() - data = model_to_dicts(Schema=DictTypeSchema, model=dict_all.items) - return data, count - - -def get_dict_data(page, limit, type_code): - dict_all = DictData.query.filter_by(type_code=type_code).paginate(page=page, - per_page=limit, - error_out=False) - count = DictType.query.count() - dict_dict = model_to_dicts(Schema=DictDataSchema, model=dict_all.items) - return dict_dict, count - - -# 增加 dict type -def save_dict_type(req_json): - description = xss_escape(req_json.get("description")) - enable = xss_escape(req_json.get("enable")) - type_code = xss_escape(req_json.get("typeCode")) - type_name = xss_escape(req_json.get("typeName")) - d = DictType(type_name=type_name, type_code=type_code, enable=enable, description=description) - db.session.add(d) - db.session.commit() - return d.id - - -# 编辑字典类型 -def update_dict_type(req_json): - id = xss_escape(req_json.get("id")) - description = xss_escape(req_json.get("description")) - enable = xss_escape(req_json.get("enable")) - type_code = xss_escape(req_json.get("typeCode")) - type_name = xss_escape(req_json.get("typeName")) - DictType.query.filter_by(id=id).update({ - "description": description, - "enable": enable, - "type_code": type_code, - "type_name": type_name - }) - db.session.commit() - return - - -def enable_dict_type_status(id): - enable = 1 - res = DictType.query.filter_by(id=id).update({"enable": enable}) - if res: - db.session.commit() - return True - return False - - -def disable_dict_type_status(id): - enable = 0 - res = DictType.query.filter_by(id=id).update({"enable": enable}) - if res: - db.session.commit() - return True - return False - - -# 删除字典类型 -def delete_type_by_id(id): - type_code = DictType.query.filter_by(id=id).first().type_code - DictData.query.filter_by(type_code=type_code).delete() - res = DictType.query.filter_by(id=id).delete() - db.session.commit() - return res - - -# 增加dictdata -def save_dict_data(req_json): - data_label = xss_escape(req_json.get("dataLabel")) - data_value = xss_escape(req_json.get("dataValue")) - enable = xss_escape(req_json.get("enable")) - remark = xss_escape(req_json.get("remark")) - type_code = xss_escape(req_json.get("typeCode")) - d = DictData(data_label=data_label, data_value=data_value, enable=enable, remark=remark, type_code=type_code) - db.session.add(d) - db.session.commit() - return d.id - - -# 编辑字典数据 -def update_dict_data(req_json): - id = req_json.get("dataId") - DictData.query.filter_by(id=id).update({ - "data_label": xss_escape(req_json.get("dataLabel")), - "data_value": xss_escape(req_json.get("dataValue")), - "enable": xss_escape(req_json.get("enable")), - "remark": xss_escape(req_json.get("remark")), - "type_code": xss_escape(req_json.get("typeCode")) - }) - db.session.commit() - return - - -def enable_dict_data_status(id): - enable = 1 - res = DictData.query.filter_by(id=id).update({"enable": enable}) - if res: - db.session.commit() - return True - return False - - -def disable_dict_data_status(id): - enable = 0 - res = DictData.query.filter_by(id=id).update({"enable": enable}) - if res: - db.session.commit() - return True - return False - - -# 删除dictdata -def delete_data_by_id(id): - res = DictData.query.filter_by(id=id).delete() - db.session.commit() - return res diff --git a/applications/common/admin/power_curd.py b/applications/common/admin/power_curd.py deleted file mode 100644 index da7c9d0f6f51107c55920d4720ebaec730da8ec4..0000000000000000000000000000000000000000 --- a/applications/common/admin/power_curd.py +++ /dev/null @@ -1,112 +0,0 @@ -from applications.common.utils.validate import xss_escape -from applications.extensions import db -from applications.models.admin_power import Power, PowerSchema2 -from applications.models import Role -from applications.common.curd import model_to_dicts - - -def get_power_dict(): - power = Power.query.all() - res = model_to_dicts(Schema=PowerSchema2, model=power) - return res - - -# 选择父节点 -def select_parent(): - power = Power.query.all() - res = model_to_dicts(Schema=PowerSchema2, model=power) - res.append({"powerId": 0, "powerName": "顶级权限", "parentId": -1}) - return res - - -# 增加权限 -def save_power(req): - icon = xss_escape(req.get("icon")) - openType = xss_escape(req.get("openType")) - parentId = xss_escape(req.get("parentId")) - powerCode = xss_escape(req.get("powerCode")) - powerName = xss_escape(req.get("powerName")) - powerType = xss_escape(req.get("powerType")) - powerUrl = xss_escape(req.get("powerUrl")) - sort = xss_escape(req.get("sort")) - power = Power( - icon=icon, - open_type=openType, - parent_id=parentId, - code=powerCode, - name=powerName, - type=powerType, - url=powerUrl, - sort=sort, - enable=1 - ) - r = db.session.add(power) - db.session.commit() - return r - - -# 根据id查询权限 -def get_power_by_id(id): - p = Power.query.filter_by(id=id).first() - return p - - -# 更新权限 -def update_power(req_json): - id = req_json.get("powerId") - data = { - "icon": xss_escape(req_json.get("icon")), - "open_type": xss_escape(req_json.get("openType")), - "parent_id": xss_escape(req_json.get("parentId")), - "code": xss_escape(req_json.get("powerCode")), - "name": xss_escape(req_json.get("powerName")), - "type": xss_escape(req_json.get("powerType")), - "url": xss_escape(req_json.get("powerUrl")), - "sort": xss_escape(req_json.get("sort")) - } - # print(data) - power = Power.query.filter_by(id=id).update(data) - db.session.commit() - # print(power) - return power - - -# 启动权限 -def enable_status(id): - enable = 1 - user = Power.query.filter_by(id=id).update({"enable": enable}) - if user: - db.session.commit() - return True - return False - - -# 停用权限 -def disable_status(id): - enable = 0 - user = Power.query.filter_by(id=id).update({"enable": enable}) - if user: - db.session.commit() - return True - return False - - -# 删除权限(目前没有判断父节点自动删除子节点) -def remove_power(id): - power = Power.query.filter_by(id=id).first() - role_id_list = [] - roles = power.role - for role in roles: - role_id_list.append(role.id) - roles = Role.query.filter(Role.id.in_(role_id_list)).all() - for p in roles: - power.role.remove(p) - r = Power.query.filter_by(id=id).delete() - db.session.commit() - return r - - -# 批量删除权限 -def batch_remove(ids): - for id in ids: - remove_power(id) diff --git a/applications/common/admin/role_curd.py b/applications/common/admin/role_curd.py deleted file mode 100644 index 22c06ef674635f67e419d76624c18aab5140b11e..0000000000000000000000000000000000000000 --- a/applications/common/admin/role_curd.py +++ /dev/null @@ -1,149 +0,0 @@ -from sqlalchemy import and_ - -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 import User - -# 获取角色对象 -from applications.common.curd import model_to_dicts - - -def get_role_data(page, limit, filters): - role = Role.query.filter(and_(*[getattr(Role, k).like(v) for k, v in filters.items()])).paginate(page=page, - per_page=limit, - error_out=False) - count = Role.query.count() - return role, count - - -# 获取角色dict -def get_role_data_dict(page, limit, filters): - role, count = get_role_data(page, limit, filters) - data = model_to_dicts(Schema=RoleSchema, model=role.items) - return data, count - - -# 增加角色 -def add_role(req): - details = xss_escape(req.get("details")) - enable = xss_escape(req.get("enable")) - roleCode = xss_escape(req.get("roleCode")) - roleName = xss_escape(req.get("roleName")) - sort = xss_escape(req.get("sort")) - role = Role( - details=details, - enable=enable, - code=roleCode, - name=roleName, - sort=sort - ) - db.session.add(role) - db.session.commit() - - -# 通过id获取角色 -def get_role_by_id(id): - r = Role.query.filter_by(id=id).first() - return r - - -# 更新角色 -def update_role(req_json): - id = req_json.get("roleId") - data = { - "code": xss_escape(req_json.get("roleCode")), - "name": xss_escape(req_json.get("roleName")), - "sort": xss_escape(req_json.get("sort")), - "enable": xss_escape(req_json.get("enable")), - "details": xss_escape(req_json.get("details")) - } - role = Role.query.filter_by(id=id).update(data) - db.session.commit() - return role - - -# 获取角色的权限 -def get_role_power(id): - role = Role.query.filter_by(id=id).first() - check_powers = role.power - check_powers_list = [] - for cp in check_powers: - check_powers_list.append(cp.id) - powers = Power.query.all() - power_schema = PowerSchema2(many=True) # 用已继承ma.ModelSchema类的自定制类生成序列化类 - output = power_schema.dump(powers) # 生成可序列化对象 - for i in output: - if int(i.get("powerId")) in check_powers_list: - i["checkArr"] = "1" - else: - i["checkArr"] = "0" - return output - - -# 更新角色权限 -def update_role_power(id, power_list): - role = Role.query.filter_by(id=id).first() - power_id_list = [] - for p in role.power: - power_id_list.append(p.id) - # print(p.id) - # print(power_id_list) - powers = Power.query.filter(Power.id.in_(power_id_list)).all() - for p in powers: - role.power.remove(p) - powers = Power.query.filter(Power.id.in_(power_list)).all() - for p in powers: - role.power.append(p) - db.session.commit() - - -# 启动角色 -def enable_status(id): - enable = 1 - role = Role.query.filter_by(id=id).update({"enable": enable}) - if role: - db.session.commit() - return True - return False - - -# 停用角色 -def disable_status(id): - enable = 0 - role = Role.query.filter_by(id=id).update({"enable": enable}) - if role: - db.session.commit() - return True - return False - - -# 删除角色 -def remove_role(id): - role = Role.query.filter_by(id=id).first() - # 删除该角色的权限 - power_id_list = [] - for p in role.power: - power_id_list.append(p.id) - - powers = Power.query.filter(Power.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 = User.query.filter(User.id.in_(user_id_list)).all() - for u in users: - role.user.remove(u) - r = Role.query.filter_by(id=id).delete() - db.session.commit() - return r - - -# 批量删除 -def batch_remove(ids): - # role = Role.query.filter(Role.id.in_(ids)).delete(synchronize_session=False) - # db.session.commit() - for id in ids: - remove_role(id) diff --git a/applications/common/admin/user_curd.py b/applications/common/admin/user_curd.py deleted file mode 100644 index 2fb4ab94acbb2a16d5e3bc5797927e81a81f9314..0000000000000000000000000000000000000000 --- a/applications/common/admin/user_curd.py +++ /dev/null @@ -1,159 +0,0 @@ -from flask import jsonify -from flask_login import current_user -from sqlalchemy import and_, desc -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 - - -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, - per_page=limit, - error_out=False) - else: - user = User.query.filter(and_(*[getattr(User, k).like(v) for k, v in filters.items()])).paginate(page=page, - per_page=limit, - error_out=False) - count = User.query.count() - return user, count - - -# 获取用户的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) - return data, count - - -# 通过名称获取用户 -def get_user_by_name(username): - return User.query.filter_by(username=username).first() - - -# 获取当前用户日志 -def get_current_user_logs(): - log = AdminLog.query.filter_by(url='/admin/login').filter_by(uid=current_user.id).order_by( - desc(AdminLog.create_time)).limit(10) - return log - - -# 判断用户是否存在 -def is_user_exists(username): - res = User.query.filter_by(username=username).count() - return bool(res) - - -# 增加用户 -def add_user(username, realName, password): - user = User(username=username, realname=realName) - user.set_password(password) - db.session.add(user) - db.session.commit() - return user.id - - -# 增加用户角色 -def add_user_role(id, roles_list): - user = User.query.filter_by(id=id).first() - roles = Role.query.filter(Role.id.in_(roles_list)).all() - for r in roles: - user.role.append(r) - db.session.commit() - - -# 更新用户头像 -def update_avatar(url): - r = User.query.filter_by(id=current_user.id).update({"avatar": url}) - db.session.commit() - return r - - -# 更新用户信息 -def update_user(id, username, realname, deptId): - user = User.query.filter_by(id=id).update({'username': username, 'realname': realname, 'dept_id': deptId}) - db.session.commit() - return user - - -# 更新当前用户信息 -def update_current_user_info(req_json): - r = User.query.filter_by(id=current_user.id).update( - {"realname": req_json.get("realName"), "remark": req_json.get("details")}) - db.session.commit() - return r - - -# 修改当前用户密码 -def edit_password(res_json): - if res_json.get("newPassword") == '': - return jsonify(success=False, msg="新密码不得为空") - if res_json.get("newPassword") != res_json.get("confirmPassword"): - return jsonify(success=False, msg="俩次密码不一样") - user = current_user - is_right = user.validate_password(res_json.get("oldPassword")) - if not is_right: - return jsonify(success=False, msg="旧密码错误") - user.set_password(res_json.get("newPassword")) - db.session.add(user) - db.session.commit() - return jsonify(success=True, msg="更改成功") - - -# 删除用户 -def delete_by_id(id): - user = User.query.filter_by(id=id).first() - roles_id = [] - for role in user.role: - roles_id.append(role.id) - roles = Role.query.filter(Role.id.in_(roles_id)).all() - for r in roles: - user.role.remove(r) - res = User.query.filter_by(id=id).delete() - db.session.commit() - return res - - -# 启用用户 -def enable_status(id): - enable = 1 - user = User.query.filter_by(id=id).update({"enable": enable}) - if user: - db.session.commit() - return True - return False - - -# 停用用户 -def disable_status(id): - enable = 0 - user = User.query.filter_by(id=id).update({"enable": enable}) - if user: - db.session.commit() - return True - return False - - -# 批量删除 -def batch_remove(ids): - for id in ids: - delete_by_id(id) - - -def update_user_role(id, roles_list): - user = User.query.filter_by(id=id).first() - roles_id = [] - for role in user.role: - roles_id.append(role.id) - roles = Role.query.filter(Role.id.in_(roles_id)).all() - for r in roles: - user.role.remove(r) - roles = Role.query.filter(Role.id.in_(roles_list)).all() - for r in roles: - user.role.append(r) - db.session.commit() diff --git a/applications/common/serialization/__init__.py b/applications/common/serialization/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..0a8b3c33113e5ba08a7d5faa59866255b88220bc --- /dev/null +++ b/applications/common/serialization/__init__.py @@ -0,0 +1,76 @@ +from flask_restful import fields + +power_fields = { + 'powerId': fields.String(attribute="id"), + 'powerName': fields.String(attribute="name"), + 'powerType': fields.String(attribute="type"), + 'powerUrl': fields.String(attribute="url"), + 'openType': fields.String(attribute="open_type"), + 'parentId': fields.String(attribute="parent_id"), + 'icon': fields.String, + 'sort': fields.Integer, + 'create_time': fields.DateTime, + 'update_time': fields.DateTime, + 'enable': fields.Integer, +} + +power2_fields = { + 'id': fields.Integer, + 'title': fields.String(attribute="name"), + 'type': fields.String, + 'code': fields.String, + 'href': fields.String(attribute="url"), + 'openType': fields.String(attribute="open_type"), + 'parent_id': fields.Integer, + 'icon': fields.String, + 'sort': fields.Integer, + 'create_time': fields.DateTime, + 'update_time': fields.DateTime, + 'enable': fields.Integer, +} + +role_fields = { + 'id': fields.Integer, + 'roleName': fields.String(attribute="name"), + 'roleCode': fields.String(attribute="code"), + 'enable': fields.String, + 'remark': fields.String, + 'details': fields.String, + 'sort': fields.Integer, + 'create_at': fields.DateTime, + 'update_at': fields.DateTime, +} + +log_fields = { + 'id': fields.Integer, + 'method': fields.String, + 'uid': fields.String, + 'url': fields.String, + 'desc': fields.String, + 'ip': fields.String, + 'user_agent': fields.String, + 'success': fields.Boolean, + 'create_time': fields.DateTime, +} + +dept_fields = { + 'deptId': fields.Integer(attribute="id"), + 'parentId': fields.Integer(attribute="parent_id"), + 'deptName': fields.String(attribute="dept_name"), + 'leader': fields.String, + 'phone': fields.String, + 'email': fields.String, + 'address': fields.String, + 'status': fields.Integer, + 'sort': fields.Integer, +} + +photo_fields = { + 'id': fields.Integer, + 'name': fields.String, + 'href': fields.String, + 'mime': fields.String, + 'size': fields.String, + 'ext': fields.String, + 'create_time': fields.DateTime, +} diff --git a/applications/common/utils/rights.py b/applications/common/utils/rights.py index 024387235df1ec5c46abdff666279293d14da1b9..f110059f712b208f2e89e06beb15b51063ae0b20 100644 --- a/applications/common/utils/rights.py +++ b/applications/common/utils/rights.py @@ -9,7 +9,7 @@ def authorize(power: str, log: bool = False): @login_required @wraps(func) def wrapper(*args, **kwargs): - if not power in session.get('permissions'): + if power not in session.get('permissions'): if log: admin_log(request=request, is_access=False) if request.method == 'GET': diff --git a/applications/common/utils/validate.py b/applications/common/utils/validate.py index 2921f8c3385e655fc15fa842997019f5a1d29d5a..cf00959d53e83482a8abd51f9d3bfe8c81ebd887 100644 --- a/applications/common/utils/validate.py +++ b/applications/common/utils/validate.py @@ -2,14 +2,6 @@ from flask import abort, make_response, jsonify -def xss_escape(s: str): - if s is None: - return None - else: - return s.replace("&", "&").replace(">", ">").replace("<", "<").replace("'", "'").replace('"', - """) - - def check_data(schema, data): errors = schema.validate(data) for k, v in errors.items(): diff --git a/applications/configs/config.py b/applications/configs/config.py index b40fb1015b42d1831017c06a5f29928bf5b82aa8..7470005f41c934dfafe8ba79a7839db13bb761bb 100644 --- a/applications/configs/config.py +++ b/applications/configs/config.py @@ -31,9 +31,12 @@ class TestingConfig(BaseConfig): 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__)), 'applications', 'static', 'upload') + class ProductionConfig(BaseConfig): """生成环境配置""" diff --git a/applications/extensions/__init__.py b/applications/extensions/__init__.py index 67f315c8cc75382b4eb56119b28c60a626506eb3..d24820989e9d1167fb9f0bce32d73a13b2a3a924 100644 --- a/applications/extensions/__init__.py +++ b/applications/extensions/__init__.py @@ -1,15 +1,15 @@ from flask import Flask -from .init_sqlalchemy import db, ma, init_databases +from .init_databases import register_script +from .init_sqlalchemy import db, 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) + register_script(app) diff --git a/applications/extensions/init_databases/__init__.py b/applications/extensions/init_databases/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..17268d99929a4dc6d2b8de7f72011bd39267d584 --- /dev/null +++ b/applications/extensions/init_databases/__init__.py @@ -0,0 +1,276 @@ +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(fields, data_list, obj): + from applications.extensions import db + + for _data in data_list: + dept = obj() + for key, value in dict(zip(fields, _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 create_dept_data(): + """创建化部门数据""" + from applications.models import Dept + _data_list = [ + (1, 0, '总公司', 1, '就眠仪式', '12312345679', '123qq.com', 1, None, '这是总公司', None, '2021-06-01 17:23:20'), + (4, 1, '济南分公司', 2, '就眠仪式', '12312345678', '1234qq.com', 1, None, '这是济南', '2021-06-01 17:24:33', + '2021-06-01 17:25:19'), + (5, 1, '唐山分公司', 4, 'mkg', '12312345678', '123@qq.com', 1, None, '这是唐山', '2021-06-01 17:25:15', + '2021-06-01 17:25:20'), + (7, 4, '济南分公司开发部', 5, '就眠仪式', '12312345678', '123@qq.com', 1, None, '测试', '2021-06-01 17:27:39', + '2021-06-01 17:27:39'), + (8, 5, '唐山测试部', 6, 'mkg', '12312345678', '123@qq.com', 1, None, '测试部', '2021-06-01 17:28:27', + '2021-06-01 17:28:27'), + ] + _fields = ['id', 'parent_id', 'dept_name', 'sort', 'leader', 'phone', 'email', 'status', 'remark', 'address', + 'create_at', 'update_at'] + + _data_list = [item for item in _data_list] + + add_data(_fields, _data_list, Dept) + + +def create_admin_photo(): + from applications.models import Photo + + _fields = [ + 'id', + 'name', + 'href', + 'mime', + 'size', + 'create_time', + ] + _data_list = [ + (3, '6958819_pear-admin_1607443454_1.png', + 'http://127.0.0.1:5000/_uploads/photos/6958819_pear-admin_1607443454_1.png', 'image/png', '2204', + '2021-03-19 18:53:02'), + (17, '1617291580000.jpg', 'http://127.0.0.1:5000/_uploads/photos/1617291580000.jpg', 'image/png', '94211', + '2021-04-01 23:39:41'), + ] + add_data(_fields, _data_list, Photo) + + +def create_admin_power(): + from applications.models import Power + + _data_list = \ + [ + (1, '系统管理', '0', '', None, None, '0', 'layui-icon layui-icon-set-fill', 1, None, None, 1), + (3, '用户管理', '1', 'admin:user:main', '/users/', '_iframe', '1', + 'layui-icon layui-icon layui-icon layui-icon layui-icon-rate', 1, None, None, 1), + (4, '权限管理', '1', 'admin:power:main', '/rights/', '_iframe', '1', None, 2, None, None, 1), + (9, '角色管理', '1', 'admin:role:main', '/admin/role', '_iframe', '1', 'layui-icon layui-icon-username', 2, + '2021-03-16 22:24:58', '2021-03-25 19:15:24', 1), + (13, '日志管理', '1', 'admin:log:main', '/logs', '_iframe', '1', 'layui-icon layui-icon-read', 4, + '2021-03-18 22:37:10', '2021-06-03 11:06:25', 1), + (17, '文件管理', '0', '', '', '', '0', 'layui-icon layui-icon-camera', 2, '2021-03-19 18:56:23', + '2021-03-25 19:15:08', 1), + (18, '图片上传', '1', 'admin:file:main', '/file', '_iframe', '17', 'layui-icon layui-icon-camera', 5, + '2021-03-19 18:57:19', '2021-03-25 19:15:13', 1), + (21, '权限增加', '2', 'admin:power:add', '', '', '4', 'layui-icon layui-icon-add-circle', 1, + '2021-03-22 19:43:52', + '2021-03-25 19:15:22', 1), + (22, '用户增加', '2', 'admin:user:add', '', '', '3', 'layui-icon layui-icon-add-circle', 1, + '2021-03-22 19:45:40', + '2021-03-25 19:15:17', 1), + (23, '用户编辑', '2', 'admin:user:edit', '', '', '3', 'layui-icon layui-icon-rate', 2, '2021-03-22 19:46:15', + '2021-03-25 19:15:18', 1), + (24, '用户删除', '2', 'admin:user:remove', '', '', '3', 'layui-icon None', 3, '2021-03-22 19:46:51', + '2021-03-25 19:15:18', 1), + (25, '权限编辑', '2', 'admin:power:edit', '', '', '4', 'layui-icon layui-icon-edit', 2, '2021-03-22 19:47:36', + '2021-03-25 19:15:22', 1), + (26, '用户删除', '2', 'admin:power:remove', '', '', '4', 'layui-icon layui-icon-delete', 3, + '2021-03-22 19:48:17', + '2021-03-25 19:15:23', 1), + (27, '用户增加', '2', 'admin:role:add', '', '', '9', 'layui-icon layui-icon-add-circle', 1, + '2021-03-22 19:49:09', + '2021-03-25 19:15:24', 1), + (28, '角色编辑', '2', 'admin:role:edit', '', '', '9', 'layui-icon layui-icon-edit', 2, '2021-03-22 19:49:41', + '2021-03-25 19:15:25', 1), + ( + 29, '角色删除', '2', 'admin:role:remove', '', '', '9', 'layui-icon layui-icon-delete', 3, + '2021-03-22 19:50:15', + '2021-03-25 19:15:26', 1), + (30, '角色授权', '2', 'admin:role:power', '', '', '9', 'layui-icon layui-icon-component', 4, + '2021-03-22 19:50:54', + '2021-03-25 19:15:26', 1), + (31, '图片增加', '2', 'admin:file:add', '', '', '18', 'layui-icon layui-icon-add-circle', 1, + '2021-03-22 19:58:05', + '2021-03-25 19:15:28', 1), + (32, '图片删除', '2', 'admin:file:delete', '', '', '18', 'layui-icon layui-icon-delete', 2, + '2021-03-22 19:58:45', + '2021-03-25 19:15:29', 1), + (48, '部门管理', '1', 'admin:dept:main', '/dept', '_iframe', '1', 'layui-icon layui-icon-group', 3, + '2021-06-01 16:22:11', '2021-06-01 16:22:11', 1), + (49, '部门增加', '2', 'admin:dept:add', '', '', '48', 'layui-icon None', 1, '2021-06-01 17:35:52', + '2021-06-01 17:36:15', 1), + (50, '部门编辑', '2', 'admin:dept:edit', '', '', '48', 'layui-icon ', 2, '2021-06-01 17:36:41', + '2021-06-01 17:36:41', 1), + (51, '部门删除', '2', 'admin:dept:remove', '', '', '48', 'layui-icon None', 3, '2021-06-01 17:37:15', + '2021-06-01 17:37:26', 1), + ] + _fields = [ + 'id', + 'name', + 'type', + 'code', + 'url', + 'open_type', + 'parent_id', + 'icon', + 'sort', + 'create_time', + 'update_time', + 'enable', + ] + + add_data(_fields, _data_list, Power) + + +def create_admin_role(): + from applications.models import Role + + _fields = [ + 'id', + 'name', + 'code', + 'remark', + 'details', + 'sort', + 'create_time', + 'update_time', + 'enable', + ] + _data_list = [ + (1, '管理员', 'admin', None, '管理员', 1, None, None, 1), + (2, '普通用户', 'common', None, '只有查看,没有增删改权限', 2, '2021-03-22 20:02:38', '2021-04-01 22:29:56', 1), + ] + + add_data(_fields, _data_list, Role) + + +def create_admin_role_power(): + from applications.extensions import db + + _data_list = [ + (237, 1, 1), + (238, 3, 1), + (239, 4, 1), + (240, 9, 1), + (241, 12, 1), + (242, 13, 1), + (243, 17, 1), + (244, 18, 1), + (245, 21, 1), + (246, 22, 1), + (247, 23, 1), + (248, 24, 1), + (249, 25, 1), + (250, 26, 1), + (251, 27, 1), + (252, 28, 1), + (253, 29, 1), + (254, 30, 1), + (255, 31, 1), + (256, 32, 1), + (257, 44, 1), + (258, 45, 1), + (259, 46, 1), + (260, 47, 1), + (261, 48, 1), + (262, 49, 1), + (263, 50, 1), + (264, 51, 1), + (265, 1, 2), + (266, 3, 2), + (267, 4, 2), + (268, 9, 2), + (269, 12, 2), + (270, 13, 2), + (271, 17, 2), + (272, 18, 2), + (273, 44, 2), + (274, 48, 2), + ] + + # add_data(_fields, _data_list, UserRole) + for data in _data_list: + db.session.execute('insert into rt_role_power VALUES (%s, %s, %s);' % data) + db.session.commit() + + +def create_admin_user(): + from applications.models import User + + _fields = [ + 'id', + 'username', + 'password_hash', + 'create_at', + 'update_at', + 'enable', + 'realname', + 'remark', + 'avatar', + 'dept_id', + ] + _data_list = [ + (1, 'admin', 'pbkdf2:sha256:150000$raM7mDSr$58fe069c3eac01531fc8af85e6fc200655dd2588090530084d182e6ec9d52c85', + None, '2021-06-01 17:28:55', 1, '超级管理', '要是不能把握时机,就要终身蹭蹬,一事无成!', + 'http://127.0.0.1:5000/_uploads/photos/1617291580000.jpg', 1), + (7, 'test', 'pbkdf2:sha256:150000$cRS8bYNh$adb57e64d929863cf159f924f74d0634f1fecc46dba749f1bfaca03da6d2e3ac', + '2021-03-22 20:03:42', '2021-06-01 17:29:47', 1, '超级管理', '要是不能把握时机,就要终身蹭蹬,一事无成', + '/static/admin/admin/images/avatar.jpg', 1), + (8, 'wind', 'pbkdf2:sha256:150000$skME1obT$6a2c20cd29f89d7d2f21d9e373a7e3445f70ebce3ef1c3a555e42a7d17170b37', + '2021-06-01 17:30:39', '2021-06-01 17:30:52', 1, '风', None, '/static/admin/admin/images/avatar.jpg', 7), + ] + + add_data(_fields, _data_list, User) + + +def create_admin_user_role() -> object: + from applications.extensions import db + + _data_list = [ + (21, 1, 1), + (22, 7, 2), + (24, 8, 2), + ] + + # add_data(_fields, _data_list, UserRole) + for data in _data_list: + db.session.execute('insert into rt_user_role VALUES (%s, %s, %s);' % data) + db.session.commit() + + +def register_script(app: Flask): + @app.cli.command() + def init_db(): + """数据库初始化""" + create_dept_data() + create_admin_photo() + create_admin_power() + create_admin_role() + create_admin_role_power() + create_admin_user() + create_admin_user_role() + + @app.cli.command() + def turn(): + """清空数据库""" + from applications.extensions import db + db.drop_all() + db.create_all() diff --git a/applications/extensions/init_debug_tool.py b/applications/extensions/init_debug_tool.py deleted file mode 100644 index 8182457bbad5d5f9bbd60ff4e022c858b662720f..0000000000000000000000000000000000000000 --- a/applications/extensions/init_debug_tool.py +++ /dev/null @@ -1,7 +0,0 @@ -from flask import Flask -from flask_debugtoolbar import DebugToolbarExtension - - -def init_debug_tool(app: Flask): - toolbar = DebugToolbarExtension() - toolbar.init_app(app) diff --git a/applications/extensions/init_sqlalchemy.py b/applications/extensions/init_sqlalchemy.py index 40900415c448d7a8aa036b42e91f34408c1530f7..4989dff65dd5c405a39d5afd6bad8273b4e2d5e7 100644 --- a/applications/extensions/init_sqlalchemy.py +++ b/applications/extensions/init_sqlalchemy.py @@ -1,54 +1,11 @@ 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": "不是合法布尔值" -} +from flask_migrate import Migrate db = SQLAlchemy() -ma = Marshmallow() +migrate = Migrate() def init_databases(app: Flask): db.init_app(app) - ma.init_app(app) + migrate.init_app(app, db) diff --git a/applications/models/__init__.py b/applications/models/__init__.py index fb5040376430831bc7effd9d93cccc03c46ab2be..1324d8f15ef2c8c036c4ef8cb5830c4a4234cdbe 100644 --- a/applications/models/__init__.py +++ b/applications/models/__init__.py @@ -1,9 +1,7 @@ -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 +from applications.models.company import Dept, User +from applications.models.log import AdminLog +from applications.models.file.photo import Photo +from applications.models.rights.power import Power +from applications.models.rights.role import Role +from applications.models.rights.role_power import role_power +from applications.models.rights.user_role import user_role diff --git a/applications/models/admin_dict.py b/applications/models/admin_dict.py deleted file mode 100644 index 29da3c0e599ffca5099c55c07497f345f5a8bdb4..0000000000000000000000000000000000000000 --- a/applications/models/admin_dict.py +++ /dev/null @@ -1,47 +0,0 @@ -import datetime - -from applications.extensions import db, ma -from marshmallow import fields - - -class DictType(db.Model): - __tablename__ = 'admin_dict_type' - id = db.Column(db.Integer, primary_key=True) - type_name = db.Column(db.String(255), comment='字典类型名称') - type_code = db.Column(db.String(255), comment='字典类型标识') - description = db.Column(db.String(255), comment='字典类型描述') - enable = db.Column(db.Integer, comment='是否开启') - create_time = db.Column(db.DateTime, default=datetime.datetime.now, comment='创建时间') - update_time = db.Column(db.DateTime, default=datetime.datetime.now, onupdate=datetime.datetime.now, comment='更新时间') - - -class DictData(db.Model): - __tablename__ = 'admin_dict_data' - id = db.Column(db.Integer, primary_key=True) - data_label = db.Column(db.String(255), comment='字典类型名称') - data_value = db.Column(db.String(255), comment='字典类型标识') - type_code = db.Column(db.String(255), comment='字典类型描述') - is_default = db.Column(db.Integer, comment='是否默认') - enable = db.Column(db.Integer, comment='是否开启') - remark = db.Column(db.String(255), comment='备注') - create_time = db.Column(db.DateTime, default=datetime.datetime.now, comment='创建时间') - update_time = db.Column(db.DateTime, default=datetime.datetime.now, onupdate=datetime.datetime.now, comment='更新时间') - - -class DictTypeSchema(ma.Schema): # 序列化类 - id = fields.Str(attribute="id") - typeName = fields.Str(attribute="type_name") - typeCode = fields.Str(attribute="type_code") - description = fields.Str(attribute="description") - createTime = fields.Str(attribute="create_time") - updateName = fields.Str(attribute="update_time") - remark = fields.Str() - enable = fields.Str() - - -class DictDataSchema(ma.Schema): # 序列化类 - dataId = fields.Str(attribute="id") - dataLabel = fields.Str(attribute="data_label") - dataValue = fields.Str(attribute="data_value") - remark = fields.Str() - enable = fields.Str() diff --git a/applications/models/company/__init__.py b/applications/models/company/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..2efb72d16d22f649049370ce2aeb6feee7078aea --- /dev/null +++ b/applications/models/company/__init__.py @@ -0,0 +1,2 @@ +from .dept import Dept +from .users import User diff --git a/applications/models/admin_dept.py b/applications/models/company/dept.py similarity index 62% rename from applications/models/admin_dept.py rename to applications/models/company/dept.py index b4826e6841eb40577b5847d3e5486e966e080963..5b472005554e90f1812ce5fe13e33cf8303b764c 100644 --- a/applications/models/admin_dept.py +++ b/applications/models/company/dept.py @@ -1,10 +1,9 @@ import datetime -from applications.extensions import db, ma -from marshmallow import fields, validate +from applications.extensions import db class Dept(db.Model): - __tablename__ = 'admin_dept' + __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="部门名称") @@ -17,15 +16,3 @@ class Dept(db.Model): address = db.Column(db.String(255), comment="详细地址") create_at = db.Column(db.DateTime, default=datetime.datetime.now, comment='创建时间') update_at = db.Column(db.DateTime, default=datetime.datetime.now, onupdate=datetime.datetime.now, comment='创建时间') - - -class DeptSchema(ma.Schema): # 序列化类 - deptId = fields.Integer(attribute="id") - parentId = fields.Integer(attribute="parent_id") - deptName = fields.Str(attribute="dept_name") - leader = fields.Str() - phone = fields.Str() - email = fields.Str(validate=validate.Email()) - address = fields.Str() - status = fields.Str(validate=validate.OneOf(["0", "1"])) - sort = fields.Integer() diff --git a/applications/models/admin_user.py b/applications/models/company/users.py similarity index 62% rename from applications/models/admin_user.py rename to applications/models/company/users.py index 0883e77cb72a80788be1c2624560b5f252cf4865..2481c163696ba42463c14c7231898c1c4024ee14 100644 --- a/applications/models/admin_user.py +++ b/applications/models/company/users.py @@ -1,16 +1,15 @@ import datetime from flask_login import UserMixin from werkzeug.security import generate_password_hash, check_password_hash -from applications.extensions import db, ma -from marshmallow import fields -from applications.models import Dept +from applications.extensions import db class User(db.Model, UserMixin): - __tablename__ = 'admin_user' + __tablename__ = 'cp_user' id = db.Column(db.Integer, primary_key=True, autoincrement=True, comment='用户ID') username = db.Column(db.String(20), comment='用户名') realname = db.Column(db.String(20), comment='真实名字') + mobile = db.Column(db.String(11), comment='电话号码') avatar = db.Column(db.String(255), comment='头像', default="/static/admin/admin/images/avatar.jpg") remark = db.Column(db.String(255), comment='备注') password_hash = db.Column(db.String(128), comment='哈希密码') @@ -18,7 +17,8 @@ class User(db.Model, UserMixin): dept_id = db.Column(db.Integer, comment='部门id') create_at = db.Column(db.DateTime, default=datetime.datetime.now, comment='创建时间') update_at = db.Column(db.DateTime, default=datetime.datetime.now, onupdate=datetime.datetime.now, comment='创建时间') - role = db.relationship('Role', secondary="admin_user_role", backref=db.backref('user'), lazy='dynamic') + + role = db.relationship('Role', secondary="rt_user_role", backref=db.backref('user'), lazy='dynamic') def set_password(self, password): self.password_hash = generate_password_hash(password) @@ -26,19 +26,3 @@ class User(db.Model, UserMixin): def validate_password(self, password): return check_password_hash(self.password_hash, password) - -# 用户models的序列化类 -class UserSchema(ma.Schema): - id = fields.Integer() - username = fields.Str() - realname = fields.Str() - enable = fields.Integer() - create_at = fields.DateTime() - update_at = fields.DateTime() - dept = fields.Method("get_dept") - - def get_dept(self, obj): - if obj.dept_id != None: - return Dept.query.filter_by(id=obj.dept_id).first().dept_name - else: - return None diff --git a/applications/common/admin/__init__.py b/applications/models/file/__init__.py similarity index 100% rename from applications/common/admin/__init__.py rename to applications/models/file/__init__.py diff --git a/applications/models/admin_photo.py b/applications/models/file/photo.py similarity index 52% rename from applications/models/admin_photo.py rename to applications/models/file/photo.py index 299e932e87333c30b6fd57333638f723125f444a..2d3bb728755c5db04f90a8d3686b5edad088d857 100644 --- a/applications/models/admin_photo.py +++ b/applications/models/file/photo.py @@ -1,11 +1,10 @@ import datetime -from applications.extensions import db, ma -from marshmallow import fields +from applications.extensions import db class Photo(db.Model): - __tablename__ = 'admin_photo' + __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)) @@ -13,12 +12,3 @@ class Photo(db.Model): size = db.Column(db.CHAR(30), nullable=False) create_time = db.Column(db.DateTime, default=datetime.datetime.now) - -class PhotoSchema(ma.Schema): - id = fields.Integer() - name = fields.Str() - href = fields.Str() - mime = fields.Str() - size = fields.Str() - ext = fields.Str() - create_time = fields.DateTime() diff --git a/applications/models/admin_log.py b/applications/models/log.py similarity index 44% rename from applications/models/admin_log.py rename to applications/models/log.py index d2339bbf5aca73a612dd3bbfef3b9c5ab873ff14..3cba020cedfbc883b014a4b82905b23e65d77897 100644 --- a/applications/models/admin_log.py +++ b/applications/models/log.py @@ -1,6 +1,5 @@ -import datetime -from applications.extensions import db, ma -from marshmallow import fields +from datetime import datetime +from applications.extensions import db class AdminLog(db.Model): @@ -13,16 +12,4 @@ class AdminLog(db.Model): ip = db.Column(db.String(255)) success = db.Column(db.Integer) user_agent = db.Column(db.Text) - create_time = db.Column(db.DateTime, default=datetime.datetime.now) - - -class LogSchema(ma.Schema): # 序列化类 - id = fields.Integer() - method = fields.Str() - uid = fields.Str() - url = fields.Str() - desc = fields.Str() - ip = fields.Str() - user_agent = fields.Str() - success = fields.Bool() - create_time = fields.DateTime() + create_time = db.Column(db.DateTime, default=datetime.now) diff --git a/applications/models/rights/__init__.py b/applications/models/rights/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/applications/models/admin_power.py b/applications/models/rights/power.py similarity index 39% rename from applications/models/admin_power.py rename to applications/models/rights/power.py index d0835b7233970ef4ffc486b740bd4eb1072e853c..68c2f05b7c8913a677946dd934c2eb454e8c2d67 100644 --- a/applications/models/admin_power.py +++ b/applications/models/rights/power.py @@ -1,49 +1,20 @@ import datetime -from applications.extensions import db, ma -from marshmallow import fields +from applications.extensions import db class Power(db.Model): - __tablename__ = 'admin_power' + __tablename__ = 'rt_power' id = db.Column(db.Integer, primary_key=True, comment='权限编号') name = db.Column(db.String(255), comment='权限名称') - type = db.Column(db.String(1), 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, 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='排序') create_time = db.Column(db.DateTime, default=datetime.datetime.now, comment='创建时间') update_time = db.Column(db.DateTime, default=datetime.datetime.now, onupdate=datetime.datetime.now, comment='更新时间') enable = db.Column(db.Integer, comment='是否开启') - -# 权限models序列化类 -class PowerSchema(ma.Schema): - id = fields.Integer() - title = fields.Str(attribute="name") - type = fields.Str() - code = fields.Str() - href = fields.Str(attribute="url") - openType = fields.Str(attribute="open_type") - parent_id = fields.Integer() - icon = fields.Str() - sort = fields.Integer() - create_time = fields.DateTime() - update_time = fields.DateTime() - enable = fields.Integer() - - -class PowerSchema2(ma.Schema): # 序列化类 - powerId = fields.Str(attribute="id") - powerName = fields.Str(attribute="name") - powerType = fields.Str(attribute="type") - powerUrl = fields.Str(attribute="url") - openType = fields.Str(attribute="open_type") - parentId = fields.Str(attribute="parent_id") - icon = fields.Str() - sort = fields.Integer() - create_time = fields.DateTime() - update_time = fields.DateTime() - enable = fields.Integer() + parent = db.relationship("Power", remote_side=[id]) # 自关联 diff --git a/applications/models/admin_role.py b/applications/models/rights/role.py similarity index 56% rename from applications/models/admin_role.py rename to applications/models/rights/role.py index 802d4ffe26e9fc38c33696ec16433433d0165882..42df2dd9b3952374e91b10e17d2aec8b96c66d81 100644 --- a/applications/models/admin_role.py +++ b/applications/models/rights/role.py @@ -1,10 +1,9 @@ import datetime -from applications.extensions import db, ma -from marshmallow import fields +from applications.extensions import db class Role(db.Model): - __tablename__ = 'admin_role' + __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='角色标识') @@ -14,16 +13,4 @@ class Role(db.Model): sort = db.Column(db.Integer, comment='排序') create_time = db.Column(db.DateTime, default=datetime.datetime.now, comment='创建时间') update_time = db.Column(db.DateTime, default=datetime.datetime.now, onupdate=datetime.datetime.now, comment='更新时间') - power = db.relationship('Power', secondary="admin_role_power", backref=db.backref('role')) - - -class RoleSchema(ma.Schema): - id = fields.Integer() - roleName = fields.Str(attribute="name") - roleCode = fields.Str(attribute="code") - enable = fields.Str() - remark = fields.Str() - details = fields.Str() - sort = fields.Integer() - create_at = fields.DateTime() - update_at = fields.DateTime() + power = db.relationship('Power', secondary="rt_role_power", backref=db.backref('role')) diff --git a/applications/models/admin_role_power.py b/applications/models/rights/role_power.py similarity index 40% rename from applications/models/admin_role_power.py rename to applications/models/rights/role_power.py index 975895323e3d3294545c6f4829a96c0c737d21e9..929f581a56cc8043c07a33c035aa080899308ab9 100644 --- a/applications/models/admin_role_power.py +++ b/applications/models/rights/role_power.py @@ -2,8 +2,8 @@ from applications.extensions import db # 创建中间表 role_power = db.Table( - "admin_role_power", # 中间表名称 + "rt_role_power", # 中间表名称 db.Column("id", db.Integer, primary_key=True, autoincrement=True, comment='标识'), # 主键 - db.Column("power_id", db.Integer, db.ForeignKey("admin_power.id"), comment='用户编号'), # 属性 外键 - db.Column("role_id", db.Integer, db.ForeignKey("admin_role.id"), 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/admin_user_role.py b/applications/models/rights/user_role.py similarity index 40% rename from applications/models/admin_user_role.py rename to applications/models/rights/user_role.py index b293329ae2244fce173e83447a0380306243ecc6..78aa1eb830cadd24ff01823b60c3d3f14ad2492d 100644 --- a/applications/models/admin_user_role.py +++ b/applications/models/rights/user_role.py @@ -2,8 +2,8 @@ from applications.extensions import db # 创建中间表 user_role = db.Table( - "admin_user_role", # 中间表名称 + "rt_user_role", # 中间表名称 db.Column("id", db.Integer, primary_key=True, autoincrement=True, comment='标识'), # 主键 - db.Column("user_id", db.Integer, db.ForeignKey("admin_user.id"), comment='用户编号'), # 属性 外键 - db.Column("role_id", db.Integer, db.ForeignKey("admin_role.id"), 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='角色编号'), # 属性 外键 ) diff --git a/applications/templates/admin/admin_log/main.html b/applications/templates/admin/admin_log/main.html index cf5a1a87ece98f17c14f1fb592ab9cd920a29379..ea6eca92cdc76062a6ff44da37ee85179613ff3d 100644 --- a/applications/templates/admin/admin_log/main.html +++ b/applications/templates/admin/admin_log/main.html @@ -12,14 +12,14 @@