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 @@
-
+
@@ -44,7 +44,7 @@ let table = layui.table let form = layui.form - let MODULE_PATH = '/admin/log/' + let MODULE_PATH = '/logs/' let cols = [ [ @@ -61,8 +61,8 @@ ] table.render({ - elem: '#log-operate-table', - url: MODULE_PATH + 'operateLog', + elem: '#log-access-table', + url: MODULE_PATH + 'access_log', page: true, cols: cols, skin: 'line', @@ -71,7 +71,7 @@ table.render({ elem: '#log-login-table', - url: MODULE_PATH + 'loginLog', + url: MODULE_PATH + 'login_log', page: true, cols: cols, skin: 'line', diff --git a/applications/templates/admin/console/console.html b/applications/templates/admin/console/welcome.html similarity index 100% rename from applications/templates/admin/console/console.html rename to applications/templates/admin/console/welcome.html diff --git a/applications/templates/admin/dept/add.html b/applications/templates/admin/department/add.html similarity index 96% rename from applications/templates/admin/dept/add.html rename to applications/templates/admin/department/add.html index 94ab9473e0f679b675d2e5b0dd89def89ea9860f..27a44848279b79a7e3fa603514ff642228186d54 100644 --- a/applications/templates/admin/dept/add.html +++ b/applications/templates/admin/department/add.html @@ -12,6 +12,7 @@
+ {#渲染树形选择器#}
@@ -86,6 +87,7 @@ let $ = layui.jquery let dtree = layui.dtree + /*渲染下拉选择组件*/ dtree.renderSelect({ elem: '#selectParent', url: '/dept/tree', @@ -97,9 +99,10 @@ selectInitVal: '1' }) + /*表单组件,提交按钮之后触发的事件*/ form.on('submit(dept-save)', function (data) { $.ajax({ - url: '/dept/save', + url: '/dept/add', data: JSON.stringify(data.field), dataType: 'json', contentType: 'application/json', diff --git a/applications/templates/admin/dept/edit.html b/applications/templates/admin/department/edit.html similarity index 97% rename from applications/templates/admin/dept/edit.html rename to applications/templates/admin/department/edit.html index eabbe84b9c67c110006dfffd8cd16d69714068bf..c07042bdba6622d46e401639652de41713b3291f 100644 --- a/applications/templates/admin/dept/edit.html +++ b/applications/templates/admin/department/edit.html @@ -97,9 +97,10 @@ let form = layui.form let $ = layui.jquery + // 当点击更新之后,获取数据 form.on('submit(dept-update)', function (data) { $.ajax({ - url: '/dept/update', + url: '/dept/edit' + data.field.deptId, data: JSON.stringify(data.field), dataType: 'json', contentType: 'application/json', @@ -107,7 +108,7 @@ success: function (result) { if (result.success) { layer.msg(result.msg, { icon: 1, time: 1000 }, function () { - parent.layer.close(parent.layer.getFrameIndex(window.name))//关闭当前页 + parent.layer.close(parent.layer.getFrameIndex(window.name)) //关闭当前页 parent.render() }) } else { diff --git a/applications/templates/admin/dept/main.html b/applications/templates/admin/department/main.html similarity index 73% rename from applications/templates/admin/dept/main.html rename to applications/templates/admin/department/main.html index f0733160e08cdb29a7a80a38e9661bc335e4688a..61b27d3ce288881b6d935a0db81c80728e26522f 100644 --- a/applications/templates/admin/dept/main.html +++ b/applications/templates/admin/department/main.html @@ -4,19 +4,24 @@ 部门新增 {% include 'admin/common/header.html' %} +{#pear 后台边框#} +{#搜索框布局#}
+ {#部门信息搜索字段#}
+ {#查询按钮--需要触发layui事件#} + {#重置按钮#} - -
-
- -{% include 'admin/common/footer.html' %} - - - - \ No newline at end of file diff --git a/applications/templates/admin/dict/data/edit.html b/applications/templates/admin/dict/data/edit.html deleted file mode 100644 index a822fc3f00484824d7367a120179ebca400578b4..0000000000000000000000000000000000000000 --- a/applications/templates/admin/dict/data/edit.html +++ /dev/null @@ -1,103 +0,0 @@ - - - - 字典增加 - {% include 'admin/common/header.html' %} - - -
-
-
-
-
- -
- -
-
-
- -
- -
-
-
- -
- -
-
-
- -
- -
-
-
- -
- - -
-
-
- -
- -
-
-
-
-
-
-
- - -
-
-
-{% include 'admin/common/footer.html' %} - - - - \ No newline at end of file diff --git a/applications/templates/admin/dict/edit.html b/applications/templates/admin/dict/edit.html deleted file mode 100644 index 5e9c9dc9f46a531905f96775becba4052697d477..0000000000000000000000000000000000000000 --- a/applications/templates/admin/dict/edit.html +++ /dev/null @@ -1,97 +0,0 @@ - - - - 字典增加 - {% include 'admin/common/header.html' %} - - -
-
-
-
-
- -
- -
-
-
- -
- -
-
-
- -
- -
-
-
- -
- - -
-
-
- -
- -
-
-
-
-
-
-
- - -
-
-
-{% include 'admin/common/footer.html' %} - - - - \ No newline at end of file diff --git a/applications/templates/admin/dict/main.html b/applications/templates/admin/dict/main.html deleted file mode 100644 index bfe2f327664917a18e9811275212c6564dff14dd..0000000000000000000000000000000000000000 --- a/applications/templates/admin/dict/main.html +++ /dev/null @@ -1,374 +0,0 @@ - - - - 字典管理 - {% include 'admin/common/header.html' %} - - -
-
-
-
-
-
- -
- -
- - -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- - - - - - - - - - - - - - - - -
-
-
-
-
- - - - - - - - - - - - - -{% include 'admin/common/footer.html' %} - - \ No newline at end of file diff --git a/applications/templates/admin/photo/photo.html b/applications/templates/admin/file/photo.html similarity index 98% rename from applications/templates/admin/photo/photo.html rename to applications/templates/admin/file/photo.html index 7ae39ad91c8d85158c89c7fbb68fdee328bbc3ab..c194c562059c88b55ae0082eeda2ff0592b6d9ff 100644 --- a/applications/templates/admin/photo/photo.html +++ b/applications/templates/admin/file/photo.html @@ -162,10 +162,10 @@ layer.close(index) let loading = layer.load() $.ajax({ - url: 'delete', + url: 'upload', data: { id: obj.data['id'] }, dataType: 'json', - type: 'POST', + type: 'delete', success: function (res) { layer.close(loading) if (res.success) { @@ -210,7 +210,7 @@ layer.close(index) let loading = layer.load() $.ajax({ - url: "{{ url_for('adminFile.batch_remove') }}", + url: "{{ url_for('file.batch_remove') }}", data: { ids: ids }, dataType: 'json', type: 'POST', diff --git a/applications/templates/admin/photo/photo_add.html b/applications/templates/admin/file/photo_add.html similarity index 97% rename from applications/templates/admin/photo/photo_add.html rename to applications/templates/admin/file/photo_add.html index 77469ae0dd1d5f4fac2bc4b71c0d459a62be1911..20d343b07cdcf333d377ae0053b537e1bc860604 100644 --- a/applications/templates/admin/photo/photo_add.html +++ b/applications/templates/admin/file/photo_add.html @@ -43,7 +43,7 @@ //选完文件后不自动上传 upload.render({ elem: '#logo-img' - , url: "{{ url_for('adminFile.upload') }}" + , url: "{{ url_for('file.upload') }}" , auto: false , exts: 'jpg|png|gif|bmp|jpeg' , size: 1000 diff --git a/applications/templates/admin/index.html b/applications/templates/admin/index.html index 6fd29d2a7b1709bbe6bf7cbde43016feee99885b..37957e4b7af40a12e9b447536ecb7c6eaae039b1 100644 --- a/applications/templates/admin/index.html +++ b/applications/templates/admin/index.html @@ -17,9 +17,12 @@
@@ -39,7 +42,7 @@
-
基本资料
+
基本资料
注销登录
@@ -58,6 +61,7 @@
+
@@ -65,7 +69,9 @@
-
+
+ +
diff --git a/applications/templates/admin/login.html b/applications/templates/admin/login.html index 3cdaf9b147a0d429522e1a3f8687a78536f52b69..35c51c9074507d7c584eda0b8c07d3a337b34d52 100644 --- a/applications/templates/admin/login.html +++ b/applications/templates/admin/login.html @@ -39,51 +39,56 @@ {% include 'admin/common/footer.html' %} \ No newline at end of file diff --git a/applications/templates/admin/monitor.html b/applications/templates/admin/monitor.html deleted file mode 100644 index 29dd4dcd12c27bdb0150dacdbe46bb2fd4f98326..0000000000000000000000000000000000000000 --- a/applications/templates/admin/monitor.html +++ /dev/null @@ -1,408 +0,0 @@ - - - - 首页 - {% include 'admin/common/header.html' %} - - - -
-
-
-
-
-
- 主机信息 -
-
-
-
-
-
核心数
-
{{ cpu_count }}
-
-
-
-
-
空闲率
-
-
-
-
-
-
等待率
-
-
-
-
-
-
使用率
-
{{ cpus_percent }}%
-
-
-
-
-
-
-
-
-
- 内存监控 -
-
-
-
-
-
空闲内存
-
{{ memory_free }}M
-
-
-
-
-
最大内存
-
{{ memory_total }}M
-
-
-
-
-
已用内存
-
{{ memory_used }}M
-
-
-
-
-
内存使用
-
{{ memory_usage }}%
-
-
-
-
-
-
-
-
-
主机监控
-
-
-
-
-
-
-
-
-
-
-
-
磁盘信息
-
-
    - {% for i in disk_partitions_list %} -
  • -

    {{ i.device }}

    -

    {{ i.fstype }}

    - 磁盘大小 {{ i.total }}M   - 空闲大小 {{ i.free }}M   -
    -
    - 已经使用 {{ i.used }}M   - 使用概率 {{ i.percent }}% -
    - 详情 -
  • - {% endfor %} -
-
-
-
-
主机信息
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
属性
名称{{ hostname }}
系统{{ system_version }}
开机时间{{ boot_time }}
运行时长{{ up_time_format }}
python版本{{ python_version }}
-
-
-
-
-{% include 'admin/common/footer.html' %} - - - \ No newline at end of file diff --git a/applications/templates/admin/power/add.html b/applications/templates/admin/rights/add.html similarity index 98% rename from applications/templates/admin/power/add.html rename to applications/templates/admin/rights/add.html index d1a96423f61bf19bd18fde3c8d1b6648bd4cf274..af895e0d5b891d5a7af5bcda4fe7dbabfde886c5 100644 --- a/applications/templates/admin/power/add.html +++ b/applications/templates/admin/rights/add.html @@ -93,7 +93,7 @@ dtree.renderSelect({ elem: '#selectParent', - url: '/admin/power/selectParent', + url: '{{ url_for('rights.select_parent') }}', method: 'get', selectInputName: { nodeId: 'parentId', context: 'powerName' }, skin: 'layui', @@ -126,7 +126,7 @@ form.on('submit(power-save)', function (data) { data.field.icon = 'layui-icon ' + data.field.icon $.ajax({ - url: '/admin/power/save', + url: '/rights/power', data: JSON.stringify(data.field), dataType: 'json', contentType: 'application/json', diff --git a/applications/templates/admin/power/edit.html b/applications/templates/admin/rights/edit.html similarity index 97% rename from applications/templates/admin/power/edit.html rename to applications/templates/admin/rights/edit.html index 44d528397d281c30e421270f041018152f34f941..aa71e43322b4f7cf8453887317fe1823bb7e981e 100644 --- a/applications/templates/admin/power/edit.html +++ b/applications/templates/admin/rights/edit.html @@ -105,7 +105,7 @@ dtree.renderSelect({ elem: '#selectParent', - url: '/admin/power/selectParent', + url: '{{ url_for('rights.select_parent')}}', method: 'get', selectInputName: { nodeId: 'parentId', context: 'powerName' }, skin: 'layui', @@ -137,8 +137,9 @@ form.on('submit(power-save)', function (data) { data.field.icon = 'layui-icon ' + data.field.icon + console.log(data.field) $.ajax({ - url: '/admin/power/update', + url: '/rights/power/' + data.field.powerId , data: JSON.stringify(data.field), dataType: 'json', contentType: 'application/json', @@ -191,7 +192,7 @@ } } - window.init("{{ power.type}}") + window.init("{{ power.type }}") }) \ No newline at end of file diff --git a/applications/templates/admin/user/center.html b/applications/templates/admin/user/center.html deleted file mode 100644 index aba1bb52871364313574ca66c693497610af6314..0000000000000000000000000000000000000000 --- a/applications/templates/admin/user/center.html +++ /dev/null @@ -1,227 +0,0 @@ - - - - 个人中心 - {% include 'admin/common/header.html' %} - - - -
- {# 左侧栏 #} -
- {# 个人信息卡片 #} -
-
-
- -

{{ user_info.realname }}

-

China , 中国

-
-
-
- {{ user_info.remark }} -
-
- {# 登录信息卡片 #} -
-
- 登录记录 -
-
-
    - {% for log in user_logs %} -
  • - {{ log.url }} - {{ log.create_time }} -
  • - {% endfor %} -
-
-
-
- {# 右侧栏 #} -
- {# 个人信息卡片 #} -
-
个人信息
-
-
-
-
-
-
- -
- -
-
-
- -
- -
-
- -
- -
- -
-
-
-
- - -
-
-
-
-
-
-
-
- {# 个人文章记录 #} -
-
- 我的文章 -
-
-
-
-
-
-
- -
-
-
为什么程序员们愿意在GitHub上开源自己的成果给别人免费使用和学习?
-
- “Git的精髓在于让所有人的贡献无缝合并。而GitHub的天才之处,在于理解了Git的精髓。”来一句我们程序员们接地气的话:分享是一种快乐~ -
-
2020-06-12        评论 5 点赞 12 转发 - 4 -
-
-
-
-
- -
-
-
为什么程序员们愿意在GitHub上开源自己的成果给别人免费使用和学习?
-
- “Git的精髓在于让所有人的贡献无缝合并。而GitHub的天才之处,在于理解了Git的精髓。”来一句我们程序员们接地气的话:分享是一种快乐~ -
-
2020-06-12        评论 5 点赞 12 转发 - 4 -
-
-
-
-
- -
-
-
为什么程序员们愿意在GitHub上开源自己的成果给别人免费使用和学习?
-
- “Git的精髓在于让所有人的贡献无缝合并。而GitHub的天才之处,在于理解了Git的精髓。”来一句我们程序员们接地气的话:分享是一种快乐~ -
-
2020-06-12        评论 5 点赞 12 转发 - 4 -
-
-
-
-
- -
-
-
为什么程序员们愿意在GitHub上开源自己的成果给别人免费使用和学习?
-
- “Git的精髓在于让所有人的贡献无缝合并。而GitHub的天才之处,在于理解了Git的精髓。”来一句我们程序员们接地气的话:分享是一种快乐~ -
-
2020-06-12        评论 5 点赞 12 转发 - 4 -
-
-
-
-
-
-
-
-
-
-{% include 'admin/common/footer.html' %} - - - diff --git a/applications/templates/admin/user/edit_password.html b/applications/templates/admin/user/edit_password.html index f21355d1870b0ae15f4c0e4f6ba6756cd4f0a553..d8fd674e2f5b64a5556132bedcba0fc9d18b473b 100644 --- a/applications/templates/admin/user/edit_password.html +++ b/applications/templates/admin/user/edit_password.html @@ -57,7 +57,7 @@ // 修改密码提交 form.on('submit(edit-password)', function (data) { $.ajax({ - url: '/admin/user/editPassword', + url: '/users/editPassword', data: JSON.stringify(data.field), contentType: 'application/json', dataType: 'json', diff --git a/applications/templates/admin/user/edit.html b/applications/templates/admin/user/edit_users.html similarity index 96% rename from applications/templates/admin/user/edit.html rename to applications/templates/admin/user/edit_users.html index ecf6ba2c06460d1e1e54242c4da20f7535646db2..6dc6fd98d00f4d310d2fe407a0625f2a91739d5e 100644 --- a/applications/templates/admin/user/edit.html +++ b/applications/templates/admin/user/edit_users.html @@ -44,7 +44,7 @@
{% for role in roles %} -
- @@ -94,7 +93,7 @@ roleIds = roleIds.substr(0, roleIds.length - 1) data.field.roleIds = roleIds $.ajax({ - url: '/admin/user/update', + url: '/users/' + data.field.userId, data: JSON.stringify(data.field), dataType: 'json', contentType: 'application/json', diff --git a/applications/templates/admin/user/main.html b/applications/templates/admin/user/main.html index 8ed4d7e211ef489f3407711a06cd26d23e0e5449..d2e350dc62b96eaa272f313d8ecd1957dc469cfb 100644 --- a/applications/templates/admin/user/main.html +++ b/applications/templates/admin/user/main.html @@ -111,7 +111,7 @@ let dtree = layui.dtree let popup = layui.popup let common = layui.common - let MODULE_PATH = '/admin/user/' + let MODULE_PATH = '/users/' // 表格数据 let cols = [ @@ -211,14 +211,14 @@ form.on('switch(user-enable)', function (obj) { let operate if (obj.elem.checked) { - operate = 'enable' + operate = 1 } else { - operate = 'disable' + operate = 0 } let loading = layer.load() $.ajax({ - url: '/admin/user/' + operate, - data: JSON.stringify({ userId: this.value }), + url: MODULE_PATH + 'enable', + data: JSON.stringify({ operate: operate, userId: this.value }), dataType: 'json', contentType: 'application/json', type: 'put', @@ -249,7 +249,7 @@ title: '修改', shade: 0.1, area: ['550px', '500px'], - content: MODULE_PATH + 'edit/' + obj.data['id'] + content: MODULE_PATH + obj.data['id'] }) } @@ -258,7 +258,7 @@ layer.close(index) let loading = layer.load() $.ajax({ - url: MODULE_PATH + 'remove/' + obj.data['id'], + url: MODULE_PATH + obj.data['id'], dataType: 'json', type: 'delete', success: function (result) { diff --git a/applications/templates/admin/user/profile.html b/applications/templates/admin/user/profile.html index e62699578e7224c430fe50233d02a18cfc4dc3f1..6e56cc5496cdddc183c63a0744013bce8823d16f 100644 --- a/applications/templates/admin/user/profile.html +++ b/applications/templates/admin/user/profile.html @@ -1,126 +1,227 @@ - 头像上传 + 个人中心 {% include 'admin/common/header.html' %} + -
-
-
- +
+ {# 左侧栏 #} +
+ {# 个人信息卡片 #} +
+
+
+ +

{{ user_info.realname }}

+

China , 中国

+
+
+
+ {{ user_info.remark }} +
-
-
-
+ {# 登录信息卡片 #} +
+
+ 登录记录 +
+
+
    + {% for log in user_logs %} +
  • + {{ log.url }} + {{ log.create_time }} +
  • + {% endfor %} +
+
-
-
-
-
- - - - - + {# 右侧栏 #} +
+ {# 个人信息卡片 #} +
+
个人信息
+
+
+
+
+
+
+ +
+ +
+
+
+ +
+ +
+
+ +
+ +
+ +
+
+
+
+ + +
+
+
+
+
+
+
+
+ {# 个人文章记录 #} +
+
+ 我的文章 +
+
+
+
+
+
+
+ +
+
+
为什么程序员们愿意在GitHub上开源自己的成果给别人免费使用和学习?
+
+ “Git的精髓在于让所有人的贡献无缝合并。而GitHub的天才之处,在于理解了Git的精髓。”来一句我们程序员们接地气的话:分享是一种快乐~ +
+
2020-06-12        评论 5 点赞 12 转发 + 4 +
+
+
+
+
+ +
+
+
为什么程序员们愿意在GitHub上开源自己的成果给别人免费使用和学习?
+
+ “Git的精髓在于让所有人的贡献无缝合并。而GitHub的天才之处,在于理解了Git的精髓。”来一句我们程序员们接地气的话:分享是一种快乐~ +
+
2020-06-12        评论 5 点赞 12 转发 + 4 +
+
+
+
+
+ +
+
+
为什么程序员们愿意在GitHub上开源自己的成果给别人免费使用和学习?
+
+ “Git的精髓在于让所有人的贡献无缝合并。而GitHub的天才之处,在于理解了Git的精髓。”来一句我们程序员们接地气的话:分享是一种快乐~ +
+
2020-06-12        评论 5 点赞 12 转发 + 4 +
+
+
+
+
+ +
+
+
为什么程序员们愿意在GitHub上开源自己的成果给别人免费使用和学习?
+
+ “Git的精髓在于让所有人的贡献无缝合并。而GitHub的天才之处,在于理解了Git的精髓。”来一句我们程序员们接地气的话:分享是一种快乐~ +
+
2020-06-12        评论 5 点赞 12 转发 + 4 +
+
+
+
+
+
+
-
建议:图片的尺寸宽高比为1:1,大小在5m以内。
- {% include 'admin/common/footer.html' %} \ No newline at end of file + + + diff --git a/applications/view/__init__.py b/applications/view/__init__.py index bec798960b046575ba34748b589a3e50027eb1b0..36c9ee7465b34e7be1bac86453f8f9c14933a9e1 100644 --- a/applications/view/__init__.py +++ b/applications/view/__init__.py @@ -1,4 +1,4 @@ -from applications.view.admin import register_admin_views +from applications.view.system import register_system_views from applications.view.index import register_index_views from applications.view.passport import register_passport_views from applications.view.rights import register_rights_view @@ -6,7 +6,7 @@ from applications.view.department import register_dept_views def init_view(app): - register_admin_views(app) + register_system_views(app) register_index_views(app) register_rights_view(app) register_passport_views(app) diff --git a/applications/view/admin/__init__.py b/applications/view/admin/__init__.py deleted file mode 100644 index ebb9b475f0ff7528f99733f0a7b6bbec60f8124f..0000000000000000000000000000000000000000 --- a/applications/view/admin/__init__.py +++ /dev/null @@ -1,21 +0,0 @@ -from flask import Flask - -from applications.view.admin.admin_log import admin_log -from applications.view.admin.dict import admin_dict -from applications.view.admin.index import admin_bp -from applications.view.admin.file import admin_file -from applications.view.admin.power import admin_power -from applications.view.admin.role import admin_role -from applications.view.admin.user import admin_user -from applications.view.admin.monitor import admin_monitor_bp - - -def register_admin_views(app: Flask): - app.register_blueprint(admin_bp) - app.register_blueprint(admin_user) - app.register_blueprint(admin_file) - app.register_blueprint(admin_monitor_bp) - app.register_blueprint(admin_log) - app.register_blueprint(admin_power) - app.register_blueprint(admin_role) - app.register_blueprint(admin_dict) diff --git a/applications/view/admin/admin_log.py b/applications/view/admin/admin_log.py deleted file mode 100644 index b30271be7d0f1ec59e7f49fea27d49c37800ebe2..0000000000000000000000000000000000000000 --- a/applications/view/admin/admin_log.py +++ /dev/null @@ -1,58 +0,0 @@ -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 authorize -from applications.models import AdminLog, LogSchema -from applications.common.curd import model_to_dicts - -admin_log = Blueprint('adminLog', __name__, url_prefix='/admin/log') - - -# ---------------------------------------------------------- -# ------------------------- 日志管理 -------------------------- -# ---------------------------------------------------------- - - -@admin_log.get('/') -@authorize("admin:log:main") -def index(): - return render_template('admin/admin_log/main.html') - - -# ========================================================== -# 登录日志 -# ========================================================== - - -@admin_log.get('/loginLog') -@authorize("admin:log:main") -def login_log(): - page = request.args.get('page', type=int) - limit = request.args.get('limit', type=int) - log = AdminLog.query.filter_by(url='/admin/login').order_by(desc(AdminLog.create_time)).paginate(page=page, - per_page=limit, - error_out=False) - count = AdminLog.query.filter_by(url='/admin/login').count() - data = model_to_dicts(Schema=LogSchema, model=log.items) - - return table_api(data=data, count=count) - - -# ========================================================== -# 操作日志 -# ========================================================== - - -@admin_log.get('/operateLog') -@authorize("admin:log:main") -def operate_log(): - page = request.args.get('page', type=int) - limit = request.args.get('limit', type=int) - log = AdminLog.query.filter( - AdminLog.url != '/admin/login').order_by( - desc(AdminLog.create_time)).paginate( - page=page, per_page=limit, error_out=False) - count = AdminLog.query.filter(AdminLog.url != '/admin/login').count() - data = model_to_dicts(Schema=LogSchema, model=log.items) - return table_api(data=data, count=count) diff --git a/applications/view/admin/curd.py b/applications/view/admin/curd.py deleted file mode 100644 index d58814cdb12d44e60f31bfc98db3bc13ab0b6cef..0000000000000000000000000000000000000000 --- a/applications/view/admin/curd.py +++ /dev/null @@ -1,8 +0,0 @@ -from flask import Blueprint - -admin_curd = Blueprint('adminCurd', __name__, url_prefix='/admin/curd') - - -@admin_curd.route('/') -def index(): - return "功能开发中" diff --git a/applications/view/admin/dict.py b/applications/view/admin/dict.py deleted file mode 100644 index a9ee9208d726962cb623b1c6384c02e447bf0bc9..0000000000000000000000000000000000000000 --- a/applications/view/admin/dict.py +++ /dev/null @@ -1,179 +0,0 @@ -from flask import Blueprint, render_template, request, jsonify - -from applications.common.utils.http import table_api, success_api, fail_api -from applications.common.utils.rights import authorize -from applications.common.utils.validate import xss_escape -from applications.models import DictType, DictData -from applications.common.admin import dict_curd - -admin_dict = Blueprint('adminDict', __name__, url_prefix='/admin/dict') - - -# 数据字典 -@admin_dict.get('/') -@authorize("admin:dict:main", log=True) -def main(): - return render_template('admin/dict/main.html') - - -@admin_dict.get('/dictType/data') -@authorize("admin:dict:main", log=True) -def dict_type_data(): - page = request.args.get('page', type=int) - limit = request.args.get('limit', type=int) - type_name = xss_escape(request.args.get('typeName', type=str)) - data, count = dict_curd.get_dict_type(page=page, limit=limit, type_name=type_name) - return table_api(data=data,count=count) - - -@admin_dict.get('/dictType/add') -@authorize("admin:dict:add", log=True) -def dict_type_add(): - return render_template('admin/dict/add.html') - - -@admin_dict.post('/dictType/save') -@authorize("admin:dict:add", log=True) -def dict_type_save(): - req_json = request.json - res = dict_curd.save_dict_type(req_json=req_json) - if res is None: - return fail_api(msg="增加失败") - return success_api(msg="增加成功") - - -# 编辑字典类型 -@admin_dict.get('/dictType/edit') -@authorize("admin:dict:edit", log=True) -def dict_type_edit(): - _id = request.args.get('dictTypeId', type=int) - dict_type = DictType.query.filter_by(id=_id).first() - return render_template('admin/dict/edit.html', dict_type=dict_type) - - -# 编辑字典类型 -@admin_dict.put('/dictType/update') -@authorize("admin:dict:edit", log=True) -def dict_type_update(): - req_json = request.json - dict_curd.update_dict_type(req_json) - return success_api(msg="更新成功") - - -# 启用字典 -@admin_dict.put('/dictType/enable') -@authorize("admin:dict:edit", log=True) -def dict_type_enable(): - _id = request.json.get('id') - if id: - res = dict_curd.enable_dict_type_status(_id) - if not res: - return fail_api(msg="出错啦") - return success_api("启动成功") - return fail_api(msg="数据错误") - - -# 禁用字典 -@admin_dict.put('/dictType/disable') -@authorize("admin:dict:edit", log=True) -def dict_type_dis_enable(): - _id = request.json.get('id') - if id: - res = dict_curd.disable_dict_type_status(_id) - if not res: - return fail_api(msg="出错啦") - return success_api("禁用成功") - return fail_api(msg="数据错误") - - -# 删除字典类型 -@admin_dict.delete('/dictType/remove/') -@authorize("admin:dict:remove", log=True) -def dict_type_delete(_id): - res = dict_curd.delete_type_by_id(_id) - if not res: - return fail_api(msg="删除失败") - return success_api(msg="删除成功") - - -@admin_dict.get('/dictData/data') -@authorize("admin:dict:main", log=True) -def dict_code_data(): - page = request.args.get('page', type=int) - limit = request.args.get('limit', type=int) - type_code = xss_escape(request.args.get('typeCode', type=str)) - data, count = dict_curd.get_dict_data(page=page, limit=limit, type_code=type_code) - return table_api(data=data,count=count) - - -# 增加字典数据 -@admin_dict.get('/dictData/add') -@authorize("admin:dict:add", log=True) -def dict_data_add(): - type_code = request.args.get('typeCode', type=str) - return render_template('admin/dict/data/add.html', type_code=type_code) - - -# 增加字典数据 -@admin_dict.get('/dictData/save') -@authorize("admin:dict:add", log=True) -def dict_data_save(): - req_json = request.json - res = dict_curd.save_dict_data(req_json=req_json) - if not res: - return jsonify(success=False, msg="增加失败") - return jsonify(success=True, msg="增加成功") - - -# 编辑字典数据 -@admin_dict.get('/dictData/edit') -@authorize("admin:dict:edit", log=True) -def dict_data_edit(): - _id = request.args.get('dataId', type=str) - dict_data = DictData.query.filter_by(id=_id).first() - return render_template('admin/dict/data/edit.html', dict_data=dict_data) - - -# 编辑字典数据 -@admin_dict.put('/dictData/update') -@authorize("admin:dict:edit", log=True) -def dict_data_update(): - req_json = request.json - dict_curd.update_dict_data(req_json) - return success_api(msg="更新成功") - - -# 启用字典数据 -@admin_dict.put('/dictData/enable') -@authorize("admin:dict:edit", log=True) -def dict_data_enable(): - _id = request.json.get('dataId') - if _id: - res = dict_curd.enable_dict_data_status(_id) - if not res: - return fail_api(msg="出错啦") - return success_api(msg="启动成功") - return fail_api(msg="数据错误") - - -# 禁用字典数据 -@admin_dict.put('/dictData/disable') -@authorize("admin:dict:edit", log=True) -def dict_data_disenable(): - _id = request.json.get('dataId') - if _id: - res = dict_curd.disable_dict_data_status(_id) - if not res: - return fail_api(msg="出错啦") - return success_api(msg="禁用成功") - return fail_api(msg="数据错误") - - -# 删除字典类型 -@admin_dict.delete('dictData/remove/') -@authorize("admin:dict:remove", log=True) -def dict_data_delete(id): - res = dict_curd.delete_data_by_id(id) - if not res: - return fail_api(msg="删除失败") - return success_api(msg="删除成功") diff --git a/applications/view/admin/monitor.py b/applications/view/admin/monitor.py deleted file mode 100644 index b517b84f3df7bb8c253c01571d75cee7e11bb19f..0000000000000000000000000000000000000000 --- a/applications/view/admin/monitor.py +++ /dev/null @@ -1,91 +0,0 @@ -import os -import platform -import re -from datetime import datetime -import time -import psutil -from flask import Blueprint, render_template, jsonify -from flask_marshmallow import Marshmallow - -from applications.common.utils.rights import authorize - -ma = Marshmallow() -admin_monitor_bp = Blueprint('adminMonitor', __name__, url_prefix='/admin/monitor') - - -# 系统监控 -@admin_monitor_bp.get('/') -@authorize("admin:monitor:main", log=True) -def main(): - # 主机名称 - hostname = platform.node() - # 系统版本 - system_version = platform.platform() - # python版本 - python_version = platform.python_version() - # 逻辑cpu数量 - cpu_count = psutil.cpu_count() - # cup使用率 - cpus_percent = psutil.cpu_percent(interval=0.1) - # 内存 - memory_information = psutil.virtual_memory() - # 内存使用率 - memory_usage = memory_information.percent - memory_used = str(round(memory_information.used / 1024 / 1024)) - memory_total = str(round(memory_information.total / 1024 / 1024)) - memory_free = str(round(memory_information.free / 1024 / 1024)) - # 磁盘信息 - - disk_partitions_list = [] - # 判断是否在容器中 - if not os.path.exists('/.dockerenv'): - disk_partitions = psutil.disk_partitions() - for i in disk_partitions: - a = psutil.disk_usage(i.device) - disk_partitions_dict = { - 'device': i.device, - 'fstype': i.fstype, - 'total': str(round(a.total / 1024 / 1024)), - 'used': str(round(a.used / 1024 / 1024)), - 'free': str(round(a.free / 1024 / 1024)), - 'percent': a.percent - } - disk_partitions_list.append(disk_partitions_dict) - - # 开机时间 - boot_time = datetime.fromtimestamp(psutil.boot_time()).replace(microsecond=0) - up_time = datetime.now().replace(microsecond=0) - boot_time - up_time_list = re.split(r':', str(up_time)) - up_time_format = " {} 小时{} 分钟{} 秒".format(up_time_list[0], up_time_list[1], up_time_list[2]) - - # 当前时间 - time_now = time.strftime('%H:%M:%S ', time.localtime(time.time())) - return render_template('admin/monitor.html', - hostname=hostname, - system_version=system_version, - python_version=python_version, - cpus_percent=cpus_percent, - memory_usage=memory_usage, - cpu_count=cpu_count, - memory_used=memory_used, - memory_total=memory_total, - memory_free=memory_free, - boot_time=boot_time, - up_time_format=up_time_format, - disk_partitions_list=disk_partitions_list, - time_now=time_now - - ) - - -# 图表 api -@admin_monitor_bp.get('/polling') -@authorize("admin:monitor:main") -def ajax_polling(): - # 获取cup使用率 - cpus_percent = psutil.cpu_percent(interval=0.1) - # 获取内存使用率 - memory_information = psutil.virtual_memory() - memory_usage = memory_information.percent - time_now = time.strftime('%H:%M:%S ', time.localtime(time.time())) - return jsonify(cups_percent=cpus_percent, memory_used=memory_usage, time_now=time_now) diff --git a/applications/view/admin/power.py b/applications/view/admin/power.py deleted file mode 100644 index 8588e5c369cd7ba88fc304fd1f88c4007399d6c7..0000000000000000000000000000000000000000 --- a/applications/view/admin/power.py +++ /dev/null @@ -1,118 +0,0 @@ -from flask import Blueprint, render_template, request, jsonify -from applications.common.admin import power_curd -from applications.common.utils.http import success_api, fail_api -from applications.common.utils.rights import authorize - -admin_power = Blueprint('adminPower', __name__, url_prefix='/admin/power') - - -@admin_power.get('/') -@authorize("admin:power:main", log=True) -def index(): - return render_template('admin/power/main.html') - - -@admin_power.get('/data') -@authorize("admin:power:main", log=True) -def data(): - power_data = power_curd.get_power_dict() - res = { - "data": power_data - } - return jsonify(res) - - -@admin_power.get('/add') -@authorize("admin:power:add", log=True) -def add(): - return render_template('admin/power/add.html') - - -@admin_power.get('/selectParent') -@authorize("admin:power:main", log=True) -def select_parent(): - power_data = power_curd.select_parent() - res = { - "status": {"code": 200, "message": "默认"}, - "data": power_data - - } - return jsonify(res) - - -# 增加 -@admin_power.post('/save') -@authorize("admin:power:add", log=True) -def save(): - req = request.json - power_curd.save_power(req) - return success_api(msg="成功") - - -# 权限编辑 -@admin_power.get('/edit/') -@authorize("admin:power:edit", log=True) -def edit(_id): - power = power_curd.get_power_by_id(_id) - icon = str(power.icon).split() - if len(icon) == 2: - icon = icon[1] - else: - icon = None - return render_template('admin/power/edit.html', power=power, icon=icon) - - -# 权限更新 -@admin_power.put('/update') -@authorize("admin:power:edit", log=True) -def update(): - res = power_curd.update_power(request.json) - if not res: - return fail_api(msg="更新权限失败") - return success_api(msg="更新权限成功") - - -# 启用权限 -@admin_power.put('/enable') -@authorize("admin:power:edit", log=True) -def enable(): - _id = request.json.get('powerId') - if id: - res = power_curd.enable_status(_id) - if not res: - return fail_api(msg="出错啦") - return success_api(msg="启用成功") - return fail_api(msg="数据错误") - - -# 禁用权限 -@admin_power.put('/disable') -@authorize("admin:power:edit", log=True) -def dis_enable(): - _id = request.json.get('powerId') - if id: - res = power_curd.disable_status(_id) - if not res: - return fail_api(msg="出错啦") - return success_api(msg="禁用成功") - return fail_api(msg="数据错误") - - -# 权限删除 -@admin_power.delete('/remove/') -@authorize("admin:power:remove", log=True) -def remove(_id): - r = power_curd.remove_power(_id) - if r: - return success_api(msg="删除成功") - else: - return fail_api(msg="删除失败") - - -# 批量删除 -@admin_power.delete('/batchRemove') -@authorize("admin:power:remove", log=True) -def batch_remove(): - ids = request.form.getlist('ids[]') - power_curd.batch_remove(ids) - return success_api(msg="批量删除成功") diff --git a/applications/view/admin/role.py b/applications/view/admin/role.py deleted file mode 100644 index eb08507fdee9ad5c1b6e469702cd99ae2e7d54ed..0000000000000000000000000000000000000000 --- a/applications/view/admin/role.py +++ /dev/null @@ -1,145 +0,0 @@ -from flask import Blueprint, render_template, request, jsonify -from flask_login import login_required -from applications.common.admin import role_curd -from applications.common.utils.http import table_api, success_api, fail_api -from applications.common.utils.rights import authorize -from applications.common.utils.validate import xss_escape - -admin_role = Blueprint('adminRole', __name__, url_prefix='/admin/role') - - -# 用户管理 -@admin_role.get('/') -@authorize("admin:role:main", log=True) -def main(): - return render_template('admin/role/main.html') - - -# 表格数据 -@admin_role.get('/data') -@authorize("admin:role:main", log=True) -def table(): - page = request.args.get('page', type=int) - limit = request.args.get('limit', type=int) - role_name = xss_escape(request.args.get('roleName', type=str)) - role_code = xss_escape(request.args.get('roleCode', type=str)) - filters = {} - if role_name: - filters["name"] = ('%' + role_name + '%') - if role_code: - filters["code"] = ('%' + role_code + '%') - data, count = role_curd.get_role_data_dict(page=page, limit=limit, filters=filters) - return table_api(data=data, count=count) - - -# 角色增加 -@admin_role.get('/add') -@authorize("admin:role:add", log=True) -@login_required -def add(): - return render_template('admin/role/add.html') - - -# 角色增加 -@admin_role.post('/save') -@authorize("admin:role:add", log=True) -def save(): - req = request.json - role_curd.add_role(req=req) - return success_api(msg="成功") - - -# 角色授权 -@admin_role.get('/power/') -@authorize("admin:role:power", log=True) -def power(_id): - return render_template('admin/role/power.html', id=_id) - - -# 获取角色权限 -@admin_role.get('/getRolePower/') -@authorize("admin:role:main", log=True) -def get_role_power(id): - powers = role_curd.get_role_power(id) - res = { - "data": powers, - "status": {"code": 200, "message": "默认"} - } - return jsonify(res) - - -# 保存角色权限 -@admin_role.put('/saveRolePower') -@authorize("admin:role:edit", log=True) -def save_role_power(): - req_form = request.form - power_ids = req_form.get("powerIds") - power_list = power_ids.split(',') - role_id = req_form.get("roleId") - role_curd.update_role_power(id=role_id, power_list=power_list) - return success_api(msg="授权成功") - - -# 角色编辑 -@admin_role.get('/edit/') -@authorize("admin:role:edit", log=True) -def edit(_id): - role = role_curd.get_role_by_id(_id) - return render_template('admin/role/edit.html', role=role) - - -# 更新角色 -@admin_role.put('/update') -@authorize("admin:role:edit", log=True) -def update(): - res = role_curd.update_role(request.json) - if not res: - return fail_api(msg="更新角色失败") - return success_api(msg="更新角色成功") - - -# 启用用户 -@admin_role.put('/enable') -@authorize("admin:role:edit", log=True) -def enable(): - id = request.json.get('roleId') - # print(id) - if id: - res = role_curd.enable_status(id) - if not res: - return fail_api(msg="出错啦") - return success_api(msg="启动成功") - return fail_api(msg="数据错误") - - -# 禁用用户 -@admin_role.put('/disable') -@authorize("admin:role:edit", log=True) -def dis_enable(): - _id = request.json.get('roleId') - if _id: - res = role_curd.disable_status(_id) - if not res: - return fail_api(msg="出错啦") - return success_api(msg="禁用成功") - return fail_api(msg="数据错误") - - -# 角色删除 -@admin_role.delete('/remove/') -@authorize("admin:role:remove", log=True) -def remove(_id): - res = role_curd.remove_role(_id) - if not res: - return fail_api(msg="角色删除失败") - return success_api(msg="角色删除成功") - - -# 批量删除 -@admin_role.delete('/batchRemove') -@authorize("admin:role:remove", log=True) -@login_required -def batch_remove(): - ids = request.form.getlist('ids[]') - role_curd.batch_remove(ids) - return success_api(msg="批量删除成功") diff --git a/applications/view/admin/user.py b/applications/view/admin/user.py deleted file mode 100644 index c83778454d9a15791731ab426e0940eeb289323e..0000000000000000000000000000000000000000 --- a/applications/view/admin/user.py +++ /dev/null @@ -1,190 +0,0 @@ -from flask import Blueprint, render_template, request -from flask_login import login_required, current_user - -from applications.common.utils.http import table_api, fail_api, success_api -from applications.common.utils.rights import authorize -from applications.common.utils.validate import xss_escape -from applications.models import User -from applications.models import Role -from applications.common.admin import user_curd - -admin_user = Blueprint('adminUser', __name__, url_prefix='/admin/user') - - -# 用户管理 -@admin_user.get('/') -@authorize("admin:user:main", log=True) -def main(): - return render_template('admin/user/main.html') - - -# 用户分页查询 -@admin_user.get('/data') -@authorize("admin:user:main", log=True) -def data(): - page = request.args.get('page', type=int) - limit = request.args.get('limit', type=int) - real_name = xss_escape(request.args.get('realName', type=str)) - username = xss_escape(request.args.get('username', type=str)) - dept_id = request.args.get('deptId', type=int) - filters = {} - if real_name: - filters["realname"] = ('%' + real_name + '%') - if username: - filters["username"] = ('%' + username + '%') - user_data, count = user_curd.get_user_data_dict(page=page, limit=limit, filters=filters, deptId=dept_id) - return table_api(data=user_data, count=count) - - -# 用户增加 -@admin_user.get('/add') -@authorize("admin:user:add", log=True) -def add(): - roles = Role.query.all() - return render_template('admin/user/add.html', roles=roles) - - -@admin_user.post('/save') -@authorize("admin:user:add", log=True) -def save(): - req_json = request.json - a = req_json.get("roleIds") - username = xss_escape(req_json.get('username')) - real_name = xss_escape(req_json.get('realName')) - password = xss_escape(req_json.get('password')) - role_ids = a.split(',') - - if not username or not real_name or not password: - return fail_api(msg="账号姓名密码不得为空") - - if user_curd.is_user_exists(username): - return fail_api(msg="用户已经存在") - - _id = user_curd.add_user(username, real_name, password) - user_curd.add_user_role(_id, role_ids) - - return success_api(msg="增加成功") - - -# 删除用户 -@admin_user.delete('/remove/') -@authorize("admin:user:remove", log=True) -def delete(_id): - res = user_curd.delete_by_id(_id) - if not res: - return fail_api(msg="删除失败") - return success_api(msg="删除成功") - - -# 编辑用户 -@admin_user.get('/edit/') -@authorize("admin:user:edit", log=True) -def edit(_id): - user = User.query.filter_by(id=_id).first() - roles = Role.query.all() - checked_roles = [] - for r in user.role: - checked_roles.append(r.id) - return render_template('admin/user/edit.html', user=user, roles=roles, checked_roles=checked_roles) - - -# 编辑用户 -@admin_user.put('/update') -@authorize("admin:user:edit", log=True) -def update(): - req_json = request.json - a = xss_escape(req_json.get("roleIds")) - _id = xss_escape(req_json.get("userId")) - username = xss_escape(req_json.get('username')) - real_name = xss_escape(req_json.get('realName')) - dept_id = xss_escape(req_json.get('deptId')) - role_ids = a.split(',') - user_curd.update_user(id, username, real_name, dept_id) - user_curd.update_user_role(_id, role_ids) - return success_api(msg="更新成功") - - -# 个人中心 -@admin_user.get('/center') -@login_required -def center(): - user_info = current_user - user_logs = user_curd.get_current_user_logs() - return render_template('admin/user/center.html', user_info=user_info, user_logs=user_logs) - - -# 修改头像 -@admin_user.get('/profile') -@login_required -def profile(): - return render_template('admin/user/profile.html') - - -# 修改头像 -@admin_user.put('/updateAvatar') -@login_required -def update_avatar(): - url = request.json.get("avatar").get("src") - if not user_curd.update_avatar(url): - return fail_api(msg="出错啦") - return success_api(msg="修改成功") - - -# 修改当前用户信息 -@admin_user.put('/updateInfo') -@login_required -def update_info(): - res_json = request.json - if not user_curd.update_current_user_info(req_json=res_json): - return fail_api(msg="出错啦") - return success_api(msg="更新成功") - - -# 修改当前用户密码 -@admin_user.get('/editPassword') -@login_required -def edit_password(): - return render_template('admin/user/edit_password.html') - - -# 修改当前用户密码 -@admin_user.put('/editPassword') -@login_required -def edit_password_put(): - res_json = request.json - return user_curd.edit_password(res_json=res_json) - - -# 启用用户 -@admin_user.put('/enable') -@authorize("admin:user:edit", log=True) -def enable(): - _id = request.json.get('userId') - if _id: - res = user_curd.enable_status(_id) - if not res: - return fail_api(msg="出错啦") - return success_api(msg="启动成功") - return fail_api(msg="数据错误") - - -# 禁用用户 -@admin_user.put('/disable') -@authorize("admin:user:edit", log=True) -def dis_enable(): - _id = request.json.get('userId') - if _id: - res = user_curd.disable_status(_id) - if not res: - return fail_api(msg="出错啦") - return success_api(msg="禁用成功") - return fail_api(msg="数据错误") - - -# 批量删除 -@admin_user.delete('/batchRemove') -@authorize("admin:user:remove", log=True) -def batch_remove(): - ids = request.form.getlist('ids[]') - user_curd.batch_remove(ids) - return success_api(msg="批量删除成功") diff --git a/applications/view/department/__init__.py b/applications/view/department/__init__.py index 677dc8efbd4188fe4c281ed02a5c81d246a0d5c7..c23354d4e6c724e06de2d4cd6d87054d7478d7f6 100644 --- a/applications/view/department/__init__.py +++ b/applications/view/department/__init__.py @@ -1,13 +1,16 @@ -from flask import Blueprint, render_template, request, jsonify -from marshmallow import INCLUDE +from flask import Blueprint, render_template, jsonify, make_response +from flask_restful import marshal, Api, Resource, reqparse +from applications.common.serialization import dept_fields from applications.common.utils.http import success_api, fail_api from applications.common.utils.rights import authorize -from applications.common.utils.validate import check_data -from applications.models import DeptSchema -from applications.common.admin import dept_curd as dept_curd +from applications.extensions import db +from applications.models import Dept, User + +# from applications.view.company.department import dept_curd dept_bp = Blueprint('dept', __name__, url_prefix='/dept') +dept_api = Api(dept_bp) def register_dept_views(app): @@ -17,96 +20,124 @@ def register_dept_views(app): @dept_bp.get('/') @authorize("admin:dept:main", log=True) def main(): - return render_template('admin/dept/main.html') + return render_template('admin/department/main.html') @dept_bp.get('/data') @authorize("admin:dept:main", log=True) def data(): - power_data = dept_curd.get_dept_dict() + dept_data = Dept.query.order_by(Dept.sort).all() + res = { - "data": power_data + "data": marshal(dept_data, dept_fields) } return jsonify(res) -@dept_bp.get('/add') -@authorize("admin:dept:add", log=True) -def add(): - return render_template('admin/dept/add.html') +@dept_api.resource('/add') +class AddDepartment(Resource): + @authorize("admin:dept:add", log=True) + def get(self): + return make_response(render_template('admin/department/add.html')) + + @authorize("admin:dept:add", log=True) + def post(self): + parser = reqparse.RequestParser() + parser.add_argument('address', type=str) + parser.add_argument('deptName', type=str, dest='dept_name') + parser.add_argument('email', type=str) + parser.add_argument('leader', type=str) + parser.add_argument('parentId', type=int, dest='parent_id') + parser.add_argument('phone', type=str) + parser.add_argument('sort', type=int) + parser.add_argument('status', type=int) + + res = parser.parse_args() + + dept = Dept( + parent_id=res.parent_id, + dept_name=res.dept_name, + sort=res.sort, + leader=res.leader, + phone=res.phone, + email=res.email, + status=res.status, + address=res.address + ) + db.session.add(dept) + db.session.commit() + + return success_api(msg="成功") @dept_bp.get('/tree') @authorize("admin:dept:main", log=True) def tree(): - power_data = dept_curd.get_dept_dict() + dept_data = Dept.query.order_by(Dept.sort).all() res = { "status": {"code": 200, "message": "默认"}, - "data": power_data + "data": marshal(dept_data, dept_fields) } return jsonify(res) -@dept_bp.post('/save') -@authorize("admin:dept:add", log=True) -def save(): - req = request.json - check_data(DeptSchema(unknown=INCLUDE), req) - dept_curd.save_dept(req) - return success_api(msg="成功") - - -@dept_bp.get('/edit') -@authorize("admin:dept:edit", log=True) -def edit(): - _id = request.args.get("deptId") - dept = dept_curd.get_dept_by_id(_id) - return render_template('admin/dept/edit.html', dept=dept) - - # 启用 @dept_bp.put('/enable') @authorize("admin:dept:edit", log=True) def enable(): - _id = request.json.get('deptId') - if id: - res = dept_curd.enable_status(_id) + parser = reqparse.RequestParser() + parser.add_argument('deptId', type=int, dest='dept_id', required=True) + parser.add_argument('operate', type=int, choices=[0, 1], required=True) + + res = parser.parse_args() + d = Dept.query.filter_by(id=res.dept_id).update({"status": res.operate}) + if d: + db.session.commit() + message = '启用成功' if res.operate else '禁用成功' + return success_api(msg=message) + return fail_api(msg="出错啦") + + +@dept_api.resource('/edit/') +class DeptURD(Resource): + @authorize("admin:dept:edit", log=True) + def get(self, dept_id): + dept = Dept.query.filter_by(id=dept_id).first() + return make_response(render_template('admin/department/edit.html', dept=dept)) + + @authorize("admin:dept:edit", log=True) + def put(self, dept_id): + parser = reqparse.RequestParser() + parser.add_argument('address', type=str) + parser.add_argument('deptName', type=str, dest='dept_name') + parser.add_argument('email', type=str) + parser.add_argument('leader', type=str) + parser.add_argument('phone', type=str) + parser.add_argument('sort', type=int) + parser.add_argument('status', type=int) + + res = parser.parse_args() + data = { + "dept_name": res.dept_name, + "sort": res.sort, + "leader": res.leader, + "phone": res.phone, + "email": res.email, + "status": res.status, + "address": res.address + } + res = Dept.query.filter_by(id=dept_id).update(data) if not res: - return fail_api(msg="出错啦") - return success_api(msg="启用成功") - return fail_api(msg="数据错误") - - -# 禁用 -@dept_bp.put('/disable') -@authorize("admin:dept:edit", log=True) -def dis_enable(): - _id = request.json.get('deptId') - if id: - res = dept_curd.disable_status(_id) - if not res: - return fail_api(msg="出错啦") - return success_api(msg="禁用成功") - return fail_api(msg="数据错误") - - -@dept_bp.put('/update') -@authorize("admin:dept:edit", log=True) -def update(): - req = request.json - check_data(DeptSchema(unknown=INCLUDE), req) - res = dept_curd.update_dept(req) - if not res: - return fail_api(msg="更新失败") - return success_api(msg="更新成功") - - -@dept_bp.delete('/remove/') -@authorize("admin:dept:remove", log=True) -def remove(_id): - res = dept_curd.remove_dept(_id) - if res: - return success_api(msg="删除成功") - else: + return fail_api(msg="更新失败") + db.session.commit() + return success_api(msg="更新成功") + + @authorize("admin:dept:remove", log=True) + def delete(self, dept_id): + ret = Dept.query.filter_by(id=dept_id).delete() + User.query.filter_by(dept_id=dept_id).update({"dept_id": None}) + db.session.commit() + if ret: + return success_api(msg="删除成功") return fail_api(msg="删除失败") diff --git a/applications/view/file/__init__.py b/applications/view/file/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/applications/common/admin/file_curd.py b/applications/view/file/_utils.py similarity index 66% rename from applications/common/admin/file_curd.py rename to applications/view/file/_utils.py index dd1fa53d8ccf41a76d08fa9cca9e53d9581a01ab..b62ebe3456ad05d66d85482150b7a7191c7c6198 100644 --- a/applications/common/admin/file_curd.py +++ b/applications/view/file/_utils.py @@ -1,18 +1,8 @@ import os from flask import current_app -from sqlalchemy import desc - from applications.common.utils.upload import photos from applications.extensions import db -from applications.models import Photo, PhotoSchema -from applications.common.curd import model_to_dicts - - -def get_photo(page, limit): - photo = Photo.query.order_by(desc(Photo.create_time)).paginate(page=page, per_page=limit, error_out=False) - count = Photo.query.count() - data = model_to_dicts(Schema=PhotoSchema, model=photo.items) - return data, count +from applications.models import Photo def upload_one(photo, mime): diff --git a/applications/view/admin/file.py b/applications/view/file/file.py similarity index 39% rename from applications/view/admin/file.py rename to applications/view/file/file.py index 8eb6a7f90205b5c88c2db0b6ae3333157cddb490..ef27bbd5f3063cf8709dce04ab97e801218b3743 100644 --- a/applications/view/admin/file.py +++ b/applications/view/file/file.py @@ -1,72 +1,73 @@ import os -from flask import Blueprint, request, render_template, jsonify, current_app +from flask import Blueprint, request, render_template, jsonify, current_app, make_response +from flask_restful import Api, Resource, marshal +from sqlalchemy import desc +from applications.common.serialization import photo_fields from applications.common.utils.http import fail_api, success_api, table_api from applications.common.utils.rights import authorize from applications.extensions import db from applications.models import Photo -from applications.common.admin import file_curd -admin_file = Blueprint('adminFile', __name__, url_prefix='/admin/file') +from applications.view.file._utils import delete_photo_by_id, upload_one + +file_bp = Blueprint('file', __name__, url_prefix='/file') +file_api = Api(file_bp) # 图片管理 -@admin_file.get('/') +@file_bp.get('/') @authorize("admin:file:main", log=True) def index(): - return render_template('admin/photo/photo.html') + return render_template('admin/file/photo.html') # 图片数据 -@admin_file.get('/table') +@file_bp.get('/table') @authorize("admin:file:main", log=True) def table(): page = request.args.get('page', type=int) limit = request.args.get('limit', type=int) - data, count = file_curd.get_photo(page=page, limit=limit) - return table_api(data=data, count=count) - + photo_paginate = Photo.query.order_by(desc(Photo.create_time)).paginate(page=page, per_page=limit, error_out=False) + data = marshal(photo_paginate.items, photo_fields) + return table_api(data=data, count=photo_paginate.total) -# 上传 -@admin_file.get('/upload') -@authorize("admin:file:add", log=True) -def upload(): - return render_template('admin/photo/photo_add.html') +@file_api.resource('/upload') +class Upload(Resource): + @authorize("admin:file:add", log=True) + def get(self): + return make_response(render_template('admin/file/photo_add.html')) -# 上传接口 -@admin_file.post('/upload') -@authorize("admin:file:add", log=True) -def upload_api(): - if 'file' in request.files: - photo = request.files['file'] - mime = request.files['file'].content_type - file_url = file_curd.upload_one(photo=photo, mime=mime) - res = { - "msg": "上传成功", - "code": 0, - "success": True, - "data": - {"src": file_url} - } - return jsonify(res) - return fail_api() + @authorize("admin:file:add", log=True) + def post(self): + if 'file' in request.files: + photo = request.files['file'] + mime = request.files['file'].content_type + file_url = upload_one(photo=photo, mime=mime) + res = { + "msg": "上传成功", + "code": 0, + "success": True, + "data": + {"src": file_url} + } + return jsonify(res) + return fail_api() -# 图片删除 -@admin_file.route('/delete', methods=['GET', 'POST']) -@authorize("admin:file:delete", log=True) -def delete(): - _id = request.form.get('id') - res = file_curd.delete_photo_by_id(_id) - if res: - return success_api(msg="删除成功") - else: - return fail_api(msg="删除失败") + @authorize("admin:file:delete", log=True) + def delete(self): + _id = request.form.get('id') + res = delete_photo_by_id(_id) + if res: + return success_api(msg="删除成功") + else: + return fail_api(msg="删除失败") # 图片批量删除 -@admin_file.route('/batchRemove', methods=['GET', 'POST']) +@file_bp.route('/batchRemove', methods=['GET', 'POST']) @authorize("admin:file:delete", log=True) def batch_remove(): ids = request.form.getlist('ids[]') diff --git a/applications/view/index/__init__.py b/applications/view/index/__init__.py index 382c14f49f316724a51850d6519473a9545a5af8..ad62adf89ba483dc1bd78957e92a807ff12f4249 100644 --- a/applications/view/index/__init__.py +++ b/applications/view/index/__init__.py @@ -1,6 +1,6 @@ from flask import Blueprint -index_bp = Blueprint('Index', __name__, url_prefix='/') +index_bp = Blueprint('index', __name__, url_prefix='/') from . import index diff --git a/applications/view/passport/__init__.py b/applications/view/passport/__init__.py index 7a4cd0f0009368a52afcc87fc60bb454c1d8fdf9..e856c026ef1f8496a08a1a568320cd6eafea5b92 100644 --- a/applications/view/passport/__init__.py +++ b/applications/view/passport/__init__.py @@ -1,12 +1,13 @@ -from flask import Blueprint, session, redirect, url_for, render_template, request +from flask import Blueprint, session, redirect, url_for, render_template, request, make_response from flask_login import current_user, login_user, login_required, logout_user - -from applications.common.admin import index_curd +from flask_restful import Resource, Api, reqparse from applications.common.admin_log import login_log from applications.common.utils.http import fail_api, success_api from applications.models import User +from ._utils import get_captcha_image, add_auth_session passport_bp = Blueprint('passport', __name__, url_prefix='/passport') +passport_api = Api(passport_bp) def register_passport_views(app): @@ -16,54 +17,50 @@ def register_passport_views(app): # 获取验证码 @passport_bp.get('/getCaptcha') def get_captcha(): - resp, code = index_curd.get_captcha() + resp, code = get_captcha_image() session["code"] = code return resp -# 登录 -@passport_bp.get('/login') -def login(): - if current_user.is_authenticated: - return redirect(url_for('admin.index')) - return render_template('admin/login.html') - - -# 登录 -@passport_bp.post('/login') -def login_post(): - req = request.form - username = req.get('username') - password = req.get('password') - code = req.get('captcha') - - if not username or not password or not code: - return fail_api(msg="用户名或密码没有输入") - s_code = session.get("code", None) - - if not all([code, s_code]): - return fail_api(msg="参数错误") - - if code != s_code: - return fail_api(msg="验证码错误") - user = User.query.filter_by(username=username).first() - - if user is None: - return fail_api(msg="不存在的用户") - - if user.enable is 0: - return fail_api(msg="用户被暂停使用") - - if username == user.username and user.validate_password(password): - # 登录 - login_user(user) - # 记录登录日志 - login_log(request, uid=user.id, is_access=True) - # 存入权限 - index_curd.add_auth_session() - return success_api(msg="登录成功") - login_log(request, uid=user.id, is_access=False) - return fail_api(msg="用户名或密码错误") +@passport_api.resource('/login') +class Login(Resource): + login_req = reqparse.RequestParser(bundle_errors=True) + login_req.add_argument('username', type=str, help='请输入用户名', required=True) + login_req.add_argument('password', type=str, help='请输入密码', required=True) + login_req.add_argument('captcha', type=str, help='请输入验证码', required=True) + + def get(self): + if current_user.is_authenticated: + return redirect(url_for('admin.index')) + + return make_response(render_template('admin/login.html')) + + def post(self): + + req = self.login_req.parse_args() + + s_code = session.get("code", None) + + if req.captcha != s_code: + return fail_api(msg="验证码错误") + user = User.query.filter_by(username=req.username).first() + + if user is None: + return fail_api(msg="不存在的用户") + + if user.enable is 0: + return fail_api(msg="用户被暂停使用") + + if user.validate_password(req.password): + # 登录 + login_user(user) + # 记录登录日志 + login_log(request, uid=user.id, is_access=True) + # 存入权限 + add_auth_session() + return success_api(msg="登录成功") + login_log(request, uid=user.id, is_access=False) + return fail_api(msg="用户名或密码错误") # 退出登录 diff --git a/applications/common/utils/gen_captcha.py b/applications/view/passport/_utils.py similarity index 35% rename from applications/common/utils/gen_captcha.py rename to applications/view/passport/_utils.py index 622a6e174caf7d8a9d3b44a784993e3e053553e7..758360134b2d5b8b4b4fe64f543409976146991b 100644 --- a/applications/common/utils/gen_captcha.py +++ b/applications/view/passport/_utils.py @@ -1,8 +1,11 @@ from captcha.image import ImageCaptcha - +from io import BytesIO from PIL import Image from random import choices +from flask import session, make_response +from flask_login import current_user + def gen_captcha(content='0123456789'): """ 生成验证码 """ @@ -12,3 +15,29 @@ def gen_captcha(content='0123456789'): # 生成图像 captcha_image = Image.open(image.generate(captcha_text)) return captcha_text, captcha_image + + +# 生成验证码 +def get_captcha_image(): + code, image = gen_captcha() + out = BytesIO() + session["code"] = code + image.save(out, 'png') + out.seek(0) + resp = make_response(out.read()) + resp.content_type = 'image/png' + return resp, code + + +# 授权路由存入session +def add_auth_session(): + role = current_user.role + user_power = [] + for i in role: + if i.enable == 0: + continue + for p in i.power: + if p.enable == 0: + continue + user_power.append(p.code) + session['permissions'] = user_power diff --git a/applications/view/rights/__init__.py b/applications/view/rights/__init__.py index 0293dbd84f0e5eab0643a53a3283e68cb6a8af7b..a95846d3a34052e736f220ffa8ea3119654bf433 100644 --- a/applications/view/rights/__init__.py +++ b/applications/view/rights/__init__.py @@ -1,8 +1,11 @@ from flask import Blueprint, Flask +from flask_restful import Api rights_bp = Blueprint('rights', __name__, url_prefix='/rights') +rights_api = Api(rights_bp) from . import routes +from . import right def register_rights_view(app: Flask): diff --git a/applications/common/admin/index_curd.py b/applications/view/rights/_utils.py similarity index 56% rename from applications/common/admin/index_curd.py rename to applications/view/rights/_utils.py index f75bbefc6979fc603b281dd77c52b6875adba05b..e94745faee1264f2e20efab55e531aa557f143a9 100644 --- a/applications/common/admin/index_curd.py +++ b/applications/view/rights/_utils.py @@ -1,83 +1,15 @@ -from io import BytesIO -from flask import session, make_response, current_app -from flask_login import current_user - -from applications.common.utils.gen_captcha import gen_captcha -from applications.models.admin_power import PowerSchema - +import copy +from collections import OrderedDict -# 授权路由存入session -def add_auth_session(): - role = current_user.role - user_power = [] - for i in role: - if i.enable == 0: - continue - for p in i.power: - if p.enable == 0: - continue - user_power.append(p.code) - session['permissions'] = user_power +from flask import current_app +from flask_login import current_user +from flask_restful import marshal +from applications.common.serialization import power_fields +from applications.extensions import db +from applications.models import Power, Role, User -# 生成菜单树 -def make_menu_tree(): - # power0 = Power.query.filter( - # Power.type == 0, - # ).all() - # power1 = Power.query.filter( - # Power.type == 1 - # ).all() - # 获取当前用户的角色 - role = current_user.role - power0 = [] - power1 = [] - for i in role: - # 如果角色没有被启用就直接跳过 - if i.enable == 0: - continue - # 变量角色用户的权限 - for p in i.power: - # 如果权限关闭了就直接跳过 - if p.enable == 0: - continue - # 一级菜单 - if int(p.type) == 0: - power0.append(p) - # 二级菜单 - else: - power1.append(p) - - power_schema = PowerSchema(many=True) # 用已继承 ma.ModelSchema 类的自定制类生成序列化类 - power0_dict = power_schema.dump(power0) # 生成可序列化对象 - power1_dict = power_schema.dump(power1) # 生成可序列化对象 - power0_dict = sorted(power0_dict, key=lambda i: i['sort']) - power1_dict = sorted(power1_dict, key=lambda i: i['sort']) - # print(power0) - # print(power1) - - menu = [] - - for p0 in power0_dict: - for p1 in power1_dict: - if p0.get('id') == p1.get('parent_id'): - if p0.get("children") is None: - p0['children'] = [] - p0['children'].append(p1) - menu.append(p0) - return menu - - -# 生成验证码 -def get_captcha(): - code, image = gen_captcha() - out = BytesIO() - session["code"] = code - image.save(out, 'png') - out.seek(0) - resp = make_response(out.read()) - resp.content_type = 'image/png' - return resp, code +from applications.common.serialization import power2_fields def get_render_config(): @@ -150,3 +82,73 @@ def get_render_config(): "autoHead": False }, header=False) return config + + +# 生成菜单树 +def make_menu_tree(): + role = current_user.role + powers = [] + for i in role: + # 如果角色没有被启用就直接跳过 + if i.enable == 0: + continue + # 变量角色用户的权限 + for p in i.power: + # 如果权限关闭了就直接跳过 + if p.enable == 0: + continue + # 一二级菜单 + if p.type == 0 or p.type == 1: + powers.append(p) + + power_dict = marshal(powers, power2_fields) # 生成可序列化对象 + power_dict.sort(key=lambda x: x['id'], reverse=True) + + menu_dict = OrderedDict() + for _dict in power_dict: + if _dict['id'] in menu_dict: + # 当前节点添加子节点 + _dict['children'] = copy.deepcopy(menu_dict[_dict['id']]) + # 删除子节点 + del menu_dict[_dict['id']] + + if _dict['parent_id'] not in menu_dict: + menu_dict[_dict['parent_id']] = [_dict] + else: + menu_dict[_dict['parent_id']].append(_dict) + return menu_dict.get(0) + + +# 选择父节点 +def select_power_dict(): + power = Power.query.all() + res = marshal(power, power_fields) + res.append({"powerId": 0, "powerName": "顶级权限", "parentId": -1}) + return res + + +def get_power_dict(): + power = Power.query.all() + res = marshal(power, power_fields) + return res + + +# 删除权限(目前没有判断父节点自动删除子节点) +def remove_power(power_id): + power = Power.query.filter_by(id=power_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=power_id).delete() + db.session.commit() + return r + + +# 批量删除权限 +def batch_remove_power(ids): + for _id in ids: + remove_power(_id) diff --git a/applications/view/rights/right.py b/applications/view/rights/right.py new file mode 100644 index 0000000000000000000000000000000000000000..4f759421afb29e29b5f558a0384ffc8bb332b57a --- /dev/null +++ b/applications/view/rights/right.py @@ -0,0 +1,161 @@ +from flask import render_template, request, jsonify, make_response +from flask_restful import Resource, reqparse + +from . import rights_bp, rights_api +from ._utils import select_power_dict, get_power_dict, batch_remove_power +from ...common.utils.http import success_api, fail_api +from ...common.utils.rights import authorize +from ...extensions import db +from ...models import Power, Role + +parser_power = reqparse.RequestParser(bundle_errors=True) +parser_power.add_argument('icon', type=str) +parser_power.add_argument('openType', type=str, dest='open_type') +parser_power.add_argument('parentId', type=str, dest='parent_id') +parser_power.add_argument('powerCode', type=str, dest='power_code') +parser_power.add_argument('powerName', type=str, dest='power_name') +parser_power.add_argument('powerType', type=str, dest='power_type') +parser_power.add_argument('powerUrl', type=str, dest='power_url') +parser_power.add_argument('sort', type=int, dest='sort') + + +@rights_bp.get('/') +@authorize("admin:power:main", log=True) +def index(): + return render_template('admin/rights/main.html') + + +@rights_bp.get('/data') +@authorize("admin:power:main", log=True) +def data(): + power_data = get_power_dict() + + res = { + "data": power_data + } + return jsonify(res) + + +@rights_bp.get('/selectParent') +@authorize("admin:power:main", log=True) +def select_parent(): + """获取选择父节点""" + power_data = select_power_dict() + res = { + "status": {"code": 200, "message": "默认"}, + "data": power_data + + } + return jsonify(res) + + +# 启用权限 +@rights_bp.put('/enable') +@authorize("admin:power:edit", log=True) +def enable(): + parser = reqparse.RequestParser(bundle_errors=True) + parser.add_argument('powerId', dest='power_id', type=int, required=True) + parser.add_argument('operate', type=int, required=True, choices=[0, 1]) + + res = parser.parse_args() + + power = Power.query.filter_by(id=res.power_id).update({"enable": res.operate}) + if power: + db.session.commit() + message = "启用成功" if res.operate else '禁用成功' + return success_api(msg=message) + else: + return fail_api(msg="出错啦") + + +# 批量删除 +@rights_bp.delete('/batchRemove') +@authorize("admin:power:remove", log=True) +def batch_remove_view(): + ids = request.form.getlist('ids[]') + batch_remove_power(ids) + return success_api(msg="批量删除成功") + + +@rights_api.resource('/power') +class AddRight(Resource): + @authorize("admin:power:add", log=True) + def get(self): + """获取增加视图""" + return make_response(render_template('admin/rights/add.html')) + + @authorize("admin:power:add", log=True) + def post(self): + res = parser_power.parse_args() + power = Power( + icon=res.icon, + open_type=res.open_type, + parent_id=res.parent_id, + code=res.power_code, + name=res.power_name, + type=res.power_type, + url=res.power_url, + sort=res.sort, + enable=1 + ) + try: + db.session.add(power) + db.session.commit() + except Exception as e: + print(e) + return fail_api(msg='数据提交失败') + + return success_api(msg="成功") + + +@rights_api.resource('/power/') +class RightsURD(Resource): + @authorize("admin:power:edit", log=True) + def get(self, power_id): + power = Power.query.filter_by(id=power_id).first() + icon = str(power.icon).split() + if len(icon) == 2: + icon = icon[1] + else: + icon = None + return make_response(render_template('admin/rights/edit.html', power=power, icon=icon)) + + @authorize("admin:power:remove", log=True) + def delete(self, power_id): + # 删除权限(目前没有判断父节点自动删除子节点) + power = Power.query.filter_by(id=power_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=power_id).delete() + db.session.commit() + + if r: + return success_api(msg="删除成功") + else: + return fail_api(msg="删除失败") + + @authorize("admin:power:edit", log=True) + def put(self, power_id): + + res = parser_power.parse_args() + data = { + "icon": res.icon, + "open_type": res.open_type, + "parent_id": res.parent_id, + "code": res.power_code, + "name": res.power_name, + "type": res.power_type, + "url": res.power_url, + "sort": res.sort + } + power = Power.query.filter_by(id=power_id).update(data) + db.session.commit() + + if not power: + return fail_api(msg="更新权限失败") + return success_api(msg="更新权限成功") diff --git a/applications/view/rights/routes.py b/applications/view/rights/routes.py index be6f42e9afd2c50b5f6f3c70d00db37360eb6b2f..0fa21a4d27b9eced6b8a0e9ef9918d40b7fdad38 100644 --- a/applications/view/rights/routes.py +++ b/applications/view/rights/routes.py @@ -3,18 +3,19 @@ from flask import jsonify from flask_login import login_required from . import rights_bp -from ...common.admin import index_curd + +from ._utils import get_render_config, make_menu_tree @rights_bp.get('/configs') @login_required def configs(): - return index_curd.get_render_config() + return get_render_config() # 菜单 @rights_bp.get('/menu') @login_required def menu(): - menu_tree = index_curd.make_menu_tree() + menu_tree = make_menu_tree() return jsonify(menu_tree) diff --git a/applications/view/roles/__init__.py b/applications/view/roles/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/applications/view/roles/_utils.py b/applications/view/roles/_utils.py new file mode 100644 index 0000000000000000000000000000000000000000..fe1e596e438a03e6a648ec7f657558a16a0c9042 --- /dev/null +++ b/applications/view/roles/_utils.py @@ -0,0 +1,30 @@ +from applications.extensions import db +from applications.models import Power, Role, User + + +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_role(ids): + """ 批量删除 """ + for _id in ids: + remove_role(_id) diff --git a/applications/view/roles/role.py b/applications/view/roles/role.py new file mode 100644 index 0000000000000000000000000000000000000000..d82b84ff6bc9b4cd9f013e7f81b8819c2bffce1d --- /dev/null +++ b/applications/view/roles/role.py @@ -0,0 +1,223 @@ +from flask import Blueprint, render_template, jsonify, make_response +from flask_login import login_required + +from flask_restful import Resource, Api, reqparse + +from applications.extensions import db +from applications.models import Role, Power +from applications.common.utils.http import table_api, success_api, fail_api +from applications.common.utils.rights import authorize +from flask_restful import reqparse, marshal + +from applications.common.serialization import power_fields + +from applications.view.roles._utils import remove_role, batch_remove_role + +role_bp = Blueprint('role', __name__, url_prefix='/admin/role') +role_api = Api(role_bp) + + +# 角色而管理 +@role_bp.get('/') +@authorize("admin:role:main", log=True) +def main(): + return render_template('admin/role/main.html') + + +# 表格数据 +@role_bp.get('/data') +@authorize("admin:role:main", log=True) +def table(): + parser = reqparse.RequestParser(bundle_errors=True) + parser.add_argument('page', type=int, default=1) + parser.add_argument('limit', type=int, default=10) + parser.add_argument('roleName', type=str, dest='role_name', default="") + parser.add_argument('roleCode', type=str, dest='role_code', default="") + + res = parser.parse_args() + + filters = [] + if res.role_name: + filters.append(Role.name.like('%' + res.role_name + '%')) + if res.role_code: + filters.append(Role.code.like('%' + res.role_code + '%')) + + paginate = Role.query.filter(*filters).paginate(page=res.page, per_page=res.limit, error_out=False) + + return table_api(data=[ + { + 'id': item.id, + 'roleName': item.name, + 'roleCode': item.code, + 'enable': item.enable, + 'remark': item.remark, + 'details': item.details, + 'sort': item.sort, + 'create_at': item.create_time, + } for item in paginate.items + ], count=paginate.total) + + +@role_api.resource('/add') +class AddRole(Resource): + @authorize("admin:role:add", log=True) + def get(self): + return make_response(render_template('admin/role/add.html')) + + @authorize("admin:role:add", log=True) + def post(self): + parser = reqparse.RequestParser() + parser.add_argument('details', type=str) + parser.add_argument('enable', type=int) + parser.add_argument('roleCode', type=str, dest='role_code') + parser.add_argument('roleName', type=str, dest='role_name') + parser.add_argument('sort', type=int) + + res = parser.parse_args() + + role = Role( + details=res.details, + enable=res.enable, + code=res.role_code, + name=res.role_name, + sort=res.sort + ) + db.session.add(role) + db.session.commit() + return success_api(msg="成功") + + +# 角色授权操作 +@role_bp.get('/power/') +@authorize("admin:role:power", log=True) +def power(_id): + return render_template('admin/role/power.html', id=_id) + + +@role_api.resource('/role_power/') +class RolePower(Resource): + + @authorize("admin:role:main", log=True) + def get(self, role_id): + # 获取角色权限 + role = Role.query.filter_by(id=role_id).first() + # 获取权限列表的 id + check_powers_list = [rp.id for rp in role.power] + powers = Power.query.all() # 获取所有的权限 + # power_schema = PowerSchema2(many=True) # 用已继承 ma.ModelSchema 类的自定制类生成序列化类 + # 将所有的权限生产可序列化对象 json + # powers = power_schema.dump(powers) # 生成可序列化对象 + powers = marshal(powers, power_fields) + for i in powers: + if int(i.get("powerId")) in check_powers_list: + i["checkArr"] = "1" + else: + i["checkArr"] = "0" + res = { + "data": powers, + "status": {"code": 200, "message": "默认"} + } + return jsonify(res) + + # 保存角色权限 + @authorize("admin:role:edit", log=True) + def put(self, role_id): + parser = reqparse.RequestParser() + parser.add_argument('powerIds', dest='power_ids') + parser.add_argument('roleId', dest='role_id') + + res = parser.parse_args() + power_list = res.power_ids.split(',') + + """ 更新角色权限 """ + role = Role.query.filter_by(id=role_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) + powers = Power.query.filter(Power.id.in_(power_list)).all() + for p in powers: + role.power.append(p) + db.session.commit() + return success_api(msg="授权成功") + + # 角色删除 + @authorize("admin:role:remove", log=True) + def delete(self, role_id): + print(role_id) + res = remove_role(role_id) + print(res) + if not res: + return fail_api(msg="角色删除失败") + return success_api(msg="角色删除成功") + + +@role_api.resource('/edit/') +class EditRole(Resource): + + # 角色编辑 + @authorize("admin:role:edit", log=True) + def get(self, role_id): + role = Role.query.filter_by(id=role_id).first() + return make_response(render_template('admin/role/edit.html', role=role)) + + # 更新角色 + @authorize("admin:role:edit", log=True) + def put(self, role_id): + parser = reqparse.RequestParser() + parser.add_argument('roleId', dest='role_id', type=int) + parser.add_argument('roleCode', dest='role_code', type=str) + parser.add_argument('roleName', dest='role_name', type=str) + parser.add_argument('sort', type=int) + parser.add_argument('enable', type=int) + parser.add_argument('details', type=str) + + res = parser.parse_args() + + data = { + "code": res.role_code, + "name": res.role_name, + "sort": res.sort, + "enable": res.enable, + "details": res.details + } + + role = Role.query.filter_by(id=role_id).update(data) + db.session.commit() + if not role: + return fail_api(msg="更新角色失败") + return success_api(msg="更新角色成功") + + +# 启用用户 +@role_bp.put('/enable') +@authorize("admin:role:edit", log=True) +def enable(): + parser = reqparse.RequestParser() + parser.add_argument('roleId', dest='role_id', required=True, type=int) + parser.add_argument('operate', required=True, type=int) + + res = parser.parse_args() + ret = Role.query.filter_by(id=res.role_id).update({"enable": res.operate}) + db.session.commit() + + message = "启动成功" if res.operate else "禁用成功" + if not ret: + return fail_api(msg="出错啦") + return success_api(msg=message) + + +# 批量删除 +@role_bp.delete('/batchRemove') +@authorize("admin:role:remove", log=True) +@login_required +def batch_remove(): + parser = reqparse.RequestParser() + parser.add_argument('ids[]', action='append', dest='ids') + + res = parser.parse_args() + + batch_remove_role(res.ids) + return success_api(msg="批量删除成功") diff --git a/applications/view/system/__init__.py b/applications/view/system/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..fcd30e55ef2f0a1835eb09e54be581d4f43189f2 --- /dev/null +++ b/applications/view/system/__init__.py @@ -0,0 +1,15 @@ +from flask import Flask + +from applications.view.system.logs import admin_log +from applications.view.system.index import admin_bp +from applications.view.file.file import file_bp +from applications.view.roles.role import role_bp +from applications.view.users import users_bp + + +def register_system_views(app: Flask): + app.register_blueprint(admin_bp) + app.register_blueprint(users_bp) + app.register_blueprint(file_bp) + app.register_blueprint(admin_log) + app.register_blueprint(role_bp) diff --git a/applications/view/admin/index.py b/applications/view/system/index.py similarity index 86% rename from applications/view/admin/index.py rename to applications/view/system/index.py index b4dde3f63c1c6d1c1cb9672130008d1292b3d26f..da838fca55e2d42e830b58ff5ce0ad7555495b14 100644 --- a/applications/view/admin/index.py +++ b/applications/view/system/index.py @@ -16,4 +16,4 @@ def index(): @admin_bp.get('/welcome') @login_required def welcome(): - return render_template('admin/console/console.html') + return render_template('admin/console/welcome.html') diff --git a/applications/view/system/logs.py b/applications/view/system/logs.py new file mode 100644 index 0000000000000000000000000000000000000000..e3f424b8f20db32b616950169ebcddc9b17249d0 --- /dev/null +++ b/applications/view/system/logs.py @@ -0,0 +1,43 @@ +from flask import Blueprint, request, render_template +from sqlalchemy import desc +from flask_restful import marshal +from applications.common.serialization import log_fields + +from applications.common.utils.http import table_api +from applications.common.utils.rights import authorize +from applications.models import AdminLog + +admin_log = Blueprint('logs', __name__, url_prefix='/logs') + + +@admin_log.get('/') +@authorize("admin:log:main") +def index(): + return render_template('admin/admin_log/main.html') + + +@admin_log.get('/login_log') +@authorize("admin:log:main") +def login_log(): + page = request.args.get('page', type=int) + limit = request.args.get('limit', type=int) + log_paginate = AdminLog.query.filter_by( + url='/passport/login').order_by( + desc(AdminLog.create_time)).paginate( + page=page, per_page=limit, error_out=False) + data = marshal(log_paginate.items, log_fields) + + return table_api(data=data, count=log_paginate.total) + + +@admin_log.get('/access_log') +@authorize("admin:log:main") +def operate_log(): + page = request.args.get('page', type=int) + limit = request.args.get('limit', type=int) + log_paginate = AdminLog.query.filter( + AdminLog.url != '/passport/login').order_by( + desc(AdminLog.create_time)).paginate( + page=page, per_page=limit, error_out=False) + data = marshal(log_paginate.items, log_fields) + return table_api(data=data, count=log_paginate.total) diff --git a/applications/view/users/__init__.py b/applications/view/users/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..1c4f048a27e82f5003fa2d3a0524e3db80c98a7e --- /dev/null +++ b/applications/view/users/__init__.py @@ -0,0 +1,60 @@ +from flask import Blueprint, request, render_template +from flask_restful import Api, reqparse + +from applications.common.utils.http import table_api +from applications.common.utils.rights import authorize +from applications.models import Role, User, Dept + +users_bp = Blueprint('users', __name__, url_prefix='/users') +user_api = Api(users_bp) + + +# 用户分页查询 +@users_bp.get('/data') +@authorize("admin:user:main", log=True) +def data(): + parser = reqparse.RequestParser() + parser.add_argument('page', type=int, default=1) + parser.add_argument('limit', type=int, default=10) + parser.add_argument('realName', type=str, dest='real_name') + parser.add_argument('username', type=str) + parser.add_argument('deptId', type=int, dest='dept_id', default=0) + + res = parser.parse_args() + + filters = [] + + if res.real_name: + filters.append(User.realname.like('%' + res.real_name + '%')) + if res.username: + filters.append(User.username.like('%' + res.username + '%')) + if res.dept_id: + filters.append(User.dept_id == res.dept_id) + + paginate = User.query.filter(*filters).paginate(page=res.page, + per_page=res.limit, + error_out=False) + + dept_name = lambda dept_id: Dept.query.filter_by(id=dept_id).first().dept_name + user_data = [{ + 'id': item.id, + 'username': item.username, + 'realname': item.realname, + 'enable': item.enable, + 'create_at': item.create_at, + 'update_at': item.update_at, + 'dept': dept_name(item.dept_id), + } for item in paginate.items] + + return table_api(data=user_data, count=paginate.total) + + +# 用户增加 +@users_bp.get('/') +@authorize("admin:user:main", log=True) +def get(): + return render_template('admin/user/main.html') + + +from . import profile, _utils +from . import user_view diff --git a/applications/view/users/_utils.py b/applications/view/users/_utils.py new file mode 100644 index 0000000000000000000000000000000000000000..e1d6270d0d0d67fd6e284fa2003df03ac43412e6 --- /dev/null +++ b/applications/view/users/_utils.py @@ -0,0 +1,55 @@ +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 +from applications.models import Role +from applications.models import AdminLog + + + +def get_current_user_logs(): + """ 获取当前用户日志 """ + log = AdminLog.query.filter_by(url='/passport/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 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 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/view/users/profile.py b/applications/view/users/profile.py new file mode 100644 index 0000000000000000000000000000000000000000..0a6b016f53075fada132439eb210da333bfa9f3b --- /dev/null +++ b/applications/view/users/profile.py @@ -0,0 +1,86 @@ +# 个人中心 +from flask import render_template, request, make_response, jsonify +from flask_login import login_required, current_user +from flask_restful import Resource, reqparse +from sqlalchemy import desc + +from applications.common.utils.http import fail_api, success_api +from applications.extensions import db +from applications.models import User, AdminLog +from applications.view.users import users_bp, user_api + + +@users_bp.get('/center') +@login_required +def center(): + user_info = current_user + user_logs = AdminLog.query.filter_by(url='/passport/login').filter_by(uid=current_user.id).order_by( + desc(AdminLog.create_time)).limit(10) + return render_template('admin/user/profile.html', user_info=user_info, user_logs=user_logs) + + +@user_api.resource('/avatar') +class Avatar(Resource): + """修改头像""" + + def get(self): + return make_response(render_template('admin/user/avatar.html')) + + def put(self): + url = request.json.get("avatar").get("src") + ret = User.query.filter_by(id=current_user.id).update({"avatar": url}) + db.session.commit() + if not ret: + return fail_api(msg="出错啦") + return success_api(msg="修改成功") + + +# 修改当前用户信息 +@users_bp.put('/updateInfo') +@login_required +def update_info(): + + parser = reqparse.RequestParser() + parser.add_argument('realname', type=str, dest='real_name') + parser.add_argument('remark', type=str) + parser.add_argument('details', type=str) + + res = parser.parse_args() + + ret = User.query.filter_by( + id=current_user.id).update({"realname": res.real_name, + "remark": res.details}) + if not ret: + return fail_api(msg="出错啦") + return success_api(msg="更新成功") + + +@user_api.resource('/editPassword') +class EditPassword(Resource): + """前用户密码""" + + @login_required + def get(self): + return make_response(render_template('admin/user/edit_password.html')) + + @login_required + def put(self): + parser = reqparse.RequestParser() + parser.add_argument('oldPassword', type=str, required=True, help='旧密码不得为空') + parser.add_argument('newPassword', type=str, required=True, help='新密码不得为空') + parser.add_argument('confirmPassword', type=str, required=True, help='确认密码不能为空') + + res = parser.parse_args() + + if res.newPassword != res.confirmPassword: + return fail_api(msg='确认密码不一致') + + """ 修改当前用户密码 """ + is_right = current_user.validate_password(res.oldPassword) + if not is_right: + return jsonify(success=False, msg="旧密码错误") + current_user.set_password(res.newPassword) + db.session.add(current_user) + db.session.commit() + + return jsonify(success=True, msg="更改成功") diff --git a/applications/view/users/user_view.py b/applications/view/users/user_view.py new file mode 100644 index 0000000000000000000000000000000000000000..affc18e102b77754c46b5155da11c2781e081687 --- /dev/null +++ b/applications/view/users/user_view.py @@ -0,0 +1,129 @@ +from flask import render_template, request, make_response +from flask_restful import Resource, reqparse +from applications.extensions import db + +from applications.common.utils.http import fail_api, success_api +from applications.common.utils.rights import authorize +from applications.models import User, Role +from applications.view.users import user_api, users_bp, _utils + + +@user_api.resource('/add') +class Users(Resource): + """用户列表数据操作""" + + @authorize("admin:user:add", log=True) + def get(self): + roles = Role.query.all() + return make_response(render_template('admin/user/add.html', roles=roles)) + + @authorize("admin:user:add", log=True) + def post(self): + """新建单个用户""" + parser = reqparse.RequestParser() + parser.add_argument("roleIds", type=str, dest='role_ids') + parser.add_argument("username", type=str, required=True, help="用户名不能为空") + parser.add_argument("realName", type=str, required=True, help="真实姓名不能为空", dest='real_name') + parser.add_argument("password", type=str, required=True, help="密码不得为空") + + res = parser.parse_args() + + role_ids = res.role_ids.split(',') + + if _utils.is_user_exists(res.username): + return fail_api(msg="用户已经存在") + + user = User() + user.username = res.username + user.realname = res.real_name + user.set_password(res.password) + db.session.add(user) + db.session.commit() + + """ 增加用户角色 """ + user = User.query.filter_by(id=user.id).first() + roles = Role.query.filter(Role.id.in_(role_ids)).all() + for r in roles: + user.role.append(r) + db.session.commit() + + return success_api(msg="增加成功") + + +@user_api.resource('/') +class CURDUser(Resource): + """修改用户数据""" + + @authorize("admin:user:edit", log=True) + def get(self, user_id): + # 获取编辑用户信息 + user = User.query.filter_by(id=user_id).first() + roles = Role.query.all() + checked_roles = [] + for r in user.role: + checked_roles.append(r.id) + return make_response( + render_template('admin/user/edit_users.html', user=user, roles=roles, checked_roles=checked_roles)) + + @authorize("admin:user:remove", log=True) + def delete(self, user_id): + # 删除用户 + res = _utils.delete_by_id(user_id) + if not res: + return fail_api(msg="删除失败") + return success_api(msg="删除成功") + + @authorize("admin:user:edit", log=True) + def put(self, user_id): + + parser = reqparse.RequestParser() + parser.add_argument('roleIds', type=str, dest='role_ids') + parser.add_argument('userId', type=str, dest='user_id') + parser.add_argument('username', type=str) + parser.add_argument('realName', type=str, dest='real_name') + parser.add_argument('deptId', type=str, dest='dept_id') + + res = parser.parse_args() + role_ids = res.role_ids.split(',') + + # 更新用户数据 + User.query.filter_by(id=user_id).update({'username': res.username, + 'realname': res.real_name, + 'dept_id': res.dept_id}) + db.session.commit() + + _utils.update_user_role(user_id, role_ids) + + return success_api(msg="更新成功") + + +# 批量删除 +@users_bp.delete('/batchRemove') +@authorize("admin:user:remove", log=True) +def batch_remove(): + ids = request.form.getlist('ids[]') + _utils.batch_remove(ids) + return success_api(msg="批量删除成功") + + +@users_bp.put('/enable') +def user_enable(): + # 启用或者禁用用户 enable disable + + parser = reqparse.RequestParser() + parser.add_argument('userId', type=int, required=True, dest='user_id') + parser.add_argument('operate', type=int, required=True, dest='operate', choices=[0, 1]) + + res = parser.parse_args() + + if res.operate == 1: + user = User.query.filter_by(id=res.user_id).update({"enable": res.operate}) + message = success_api(msg="启动成功") + else: + user = User.query.filter_by(id=res.user_id).update({"enable": res.operate}) + message = success_api(msg="禁用成功") + if user: + db.session.commit() + else: + return fail_api(msg="出错啦") + return message diff --git a/migrations/README b/migrations/README deleted file mode 100644 index 98e4f9c44effe479ed38c66ba922e7bcc672916f..0000000000000000000000000000000000000000 --- a/migrations/README +++ /dev/null @@ -1 +0,0 @@ -Generic single-database configuration. \ No newline at end of file diff --git a/migrations/alembic.ini b/migrations/alembic.ini deleted file mode 100644 index f8ed4801f78bcb83cc6acb589508c1b24eda297a..0000000000000000000000000000000000000000 --- a/migrations/alembic.ini +++ /dev/null @@ -1,45 +0,0 @@ -# A generic, single database configuration. - -[alembic] -# template used to generate migration files -# file_template = %%(rev)s_%%(slug)s - -# set to 'true' to run the environment during -# the 'revision' command, regardless of autogenerate -# revision_environment = false - - -# Logging configuration -[loggers] -keys = root,sqlalchemy,alembic - -[handlers] -keys = console - -[formatters] -keys = generic - -[logger_root] -level = WARN -handlers = console -qualname = - -[logger_sqlalchemy] -level = WARN -handlers = -qualname = sqlalchemy.engine - -[logger_alembic] -level = INFO -handlers = -qualname = alembic - -[handler_console] -class = StreamHandler -args = (sys.stderr,) -level = NOTSET -formatter = generic - -[formatter_generic] -format = %(levelname)-5.5s [%(name)s] %(message)s -datefmt = %H:%M:%S diff --git a/migrations/env.py b/migrations/env.py deleted file mode 100644 index fb5dbb3acf62e0eb584330df858f83d56a56f10f..0000000000000000000000000000000000000000 --- a/migrations/env.py +++ /dev/null @@ -1,96 +0,0 @@ -from __future__ import with_statement - -import logging -from logging.config import fileConfig - -from sqlalchemy import engine_from_config -from sqlalchemy import pool -from flask import current_app - -from alembic import context - -# this is the Alembic Config object, which provides -# access to the values within the .ini file in use. -config = context.config - -# Interpret the configs file for Python logging. -# This line sets up loggers basically. -fileConfig(config.config_file_name) -logger = logging.getLogger('alembic.env') - -# add your model's MetaData object here -# for 'autogenerate' support -# from myapp import mymodel -# target_metadata = mymodel.Base.metadata -config.set_main_option( - 'sqlalchemy.url', - str(current_app.extensions['migrate'].db.engine.url).replace('%', '%%')) -target_metadata = current_app.extensions['migrate'].db.metadata - -# other values from the configs, defined by the needs of env.py, -# can be acquired: -# my_important_option = configs.get_main_option("my_important_option") -# ... etc. - - -def run_migrations_offline(): - """Run migrations in 'offline' mode. - - This configures the context with just a URL - and not an Engine, though an Engine is acceptable - here as well. By skipping the Engine creation - we don't even need a DBAPI to be available. - - Calls to context.execute() here emit the given string to the - script output. - - """ - url = config.get_main_option("sqlalchemy.url") - context.configure( - url=url, target_metadata=target_metadata, literal_binds=True - ) - - with context.begin_transaction(): - context.run_migrations() - - -def run_migrations_online(): - """Run migrations in 'online' mode. - - In this scenario we need to create an Engine - and associate a connection with the context. - - """ - - # this callback is used to prevent an auto-migration from being generated - # when there are no changes to the schema - # reference: http://alembic.zzzcomputing.com/en/latest/cookbook.html - def process_revision_directives(context, revision, directives): - if getattr(config.cmd_opts, 'autogenerate', False): - script = directives[0] - if script.upgrade_ops.is_empty(): - directives[:] = [] - logger.info('No changes in schema detected.') - - connectable = engine_from_config( - config.get_section(config.config_ini_section), - prefix='sqlalchemy.', - poolclass=pool.NullPool, - ) - - with connectable.connect() as connection: - context.configure( - connection=connection, - target_metadata=target_metadata, - process_revision_directives=process_revision_directives, - **current_app.extensions['migrate'].configure_args - ) - - with context.begin_transaction(): - context.run_migrations() - - -if context.is_offline_mode(): - run_migrations_offline() -else: - run_migrations_online() diff --git a/migrations/script.py.mako b/migrations/script.py.mako deleted file mode 100644 index 2c0156303a8df3ffdc9de87765bf801bf6bea4a5..0000000000000000000000000000000000000000 --- a/migrations/script.py.mako +++ /dev/null @@ -1,24 +0,0 @@ -"""${message} - -Revision ID: ${up_revision} -Revises: ${down_revision | comma,n} -Create Date: ${create_date} - -""" -from alembic import op -import sqlalchemy as sa -${imports if imports else ""} - -# revision identifiers, used by Alembic. -revision = ${repr(up_revision)} -down_revision = ${repr(down_revision)} -branch_labels = ${repr(branch_labels)} -depends_on = ${repr(depends_on)} - - -def upgrade(): - ${upgrades if upgrades else "pass"} - - -def downgrade(): - ${downgrades if downgrades else "pass"} diff --git a/migrations/versions/7634e028e338_.py b/migrations/versions/7634e028e338_.py deleted file mode 100644 index 53491e4a45001b06d3ba2d73a39ad50f3413be29..0000000000000000000000000000000000000000 --- a/migrations/versions/7634e028e338_.py +++ /dev/null @@ -1,28 +0,0 @@ -"""empty message - -Revision ID: 7634e028e338 -Revises: 8b664608a7c7 -Create Date: 2021-06-01 16:43:50.853692 - -""" -from alembic import op -import sqlalchemy as sa - - -# revision identifiers, used by Alembic. -revision = '7634e028e338' -down_revision = '8b664608a7c7' -branch_labels = None -depends_on = None - - -def upgrade(): - # ### commands auto generated by Alembic - please adjust! ### - op.add_column('admin_user', sa.Column('dept_id', sa.Integer(), nullable=True, comment='部门id')) - # ### end Alembic commands ### - - -def downgrade(): - # ### commands auto generated by Alembic - please adjust! ### - op.drop_column('admin_user', 'dept_id') - # ### end Alembic commands ### diff --git a/migrations/versions/8b664608a7c7_.py b/migrations/versions/8b664608a7c7_.py deleted file mode 100644 index 19179562beab192ca5fca3ff7c055101546a8163..0000000000000000000000000000000000000000 --- a/migrations/versions/8b664608a7c7_.py +++ /dev/null @@ -1,42 +0,0 @@ -"""empty message - -Revision ID: 8b664608a7c7 -Revises: ec21e19825ff -Create Date: 2021-06-01 14:37:20.327189 - -""" -from alembic import op -import sqlalchemy as sa - - -# revision identifiers, used by Alembic. -revision = '8b664608a7c7' -down_revision = 'ec21e19825ff' -branch_labels = None -depends_on = None - - -def upgrade(): - # ### commands auto generated by Alembic - please adjust! ### - op.create_table('admin_dept', - sa.Column('id', sa.Integer(), nullable=False, comment='部门ID'), - sa.Column('parent_id', sa.Integer(), nullable=True, comment='父级编号'), - sa.Column('dept_name', sa.String(length=50), nullable=True, comment='部门名称'), - sa.Column('sort', sa.Integer(), nullable=True, comment='排序'), - sa.Column('leader', sa.String(length=50), nullable=True, comment='负责人'), - sa.Column('phone', sa.String(length=20), nullable=True, comment='联系方式'), - sa.Column('email', sa.String(length=50), nullable=True, comment='邮箱'), - sa.Column('status', sa.Integer(), nullable=True, comment='状态(1开启,0关闭)'), - sa.Column('remark', sa.Text(), nullable=True, comment='备注'), - sa.Column('address', sa.String(length=255), nullable=True, comment='详细地址'), - sa.Column('create_at', sa.DateTime(), nullable=True, comment='创建时间'), - sa.Column('update_at', sa.DateTime(), nullable=True, comment='创建时间'), - sa.PrimaryKeyConstraint('id') - ) - # ### end Alembic commands ### - - -def downgrade(): - # ### commands auto generated by Alembic - please adjust! ### - op.drop_table('admin_dept') - # ### end Alembic commands ### diff --git a/migrations/versions/ec21e19825ff_.py b/migrations/versions/ec21e19825ff_.py deleted file mode 100644 index bf88f1de2a28a910f5d806e6209e930b02d238df..0000000000000000000000000000000000000000 --- a/migrations/versions/ec21e19825ff_.py +++ /dev/null @@ -1,133 +0,0 @@ -"""empty message - -Revision ID: ec21e19825ff -Revises: -Create Date: 2021-04-27 11:54:00.453274 - -""" -from alembic import op -import sqlalchemy as sa - - -# revision identifiers, used by Alembic. -revision = 'ec21e19825ff' -down_revision = None -branch_labels = None -depends_on = None - - -def upgrade(): - # ### commands auto generated by Alembic - please adjust! ### - op.create_table('admin_admin_log', - sa.Column('id', sa.Integer(), nullable=False), - sa.Column('method', sa.String(length=10), nullable=True), - sa.Column('uid', sa.Integer(), nullable=True), - sa.Column('url', sa.String(length=255), nullable=True), - sa.Column('desc', sa.Text(), nullable=True), - sa.Column('ip', sa.String(length=255), nullable=True), - sa.Column('success', sa.Integer(), nullable=True), - sa.Column('user_agent', sa.Text(), nullable=True), - sa.Column('create_time', sa.DateTime(), nullable=True), - sa.PrimaryKeyConstraint('id') - ) - op.create_table('admin_dict_data', - sa.Column('id', sa.Integer(), nullable=False), - sa.Column('data_label', sa.String(length=255), nullable=True, comment='字典类型名称'), - sa.Column('data_value', sa.String(length=255), nullable=True, comment='字典类型标识'), - sa.Column('type_code', sa.String(length=255), nullable=True, comment='字典类型描述'), - sa.Column('is_default', sa.Integer(), nullable=True, comment='是否默认'), - sa.Column('enable', sa.Integer(), nullable=True, comment='是否开启'), - sa.Column('remark', sa.String(length=255), nullable=True, comment='备注'), - sa.Column('create_time', sa.DateTime(), nullable=True, comment='创建时间'), - sa.Column('update_time', sa.DateTime(), nullable=True, comment='更新时间'), - sa.PrimaryKeyConstraint('id') - ) - op.create_table('admin_dict_type', - sa.Column('id', sa.Integer(), nullable=False), - sa.Column('type_name', sa.String(length=255), nullable=True, comment='字典类型名称'), - sa.Column('type_code', sa.String(length=255), nullable=True, comment='字典类型标识'), - sa.Column('description', sa.String(length=255), nullable=True, comment='字典类型描述'), - sa.Column('enable', sa.Integer(), nullable=True, comment='是否开启'), - sa.Column('create_time', sa.DateTime(), nullable=True, comment='创建时间'), - sa.Column('update_time', sa.DateTime(), nullable=True, comment='更新时间'), - sa.PrimaryKeyConstraint('id') - ) - op.create_table('admin_photo', - sa.Column('id', sa.Integer(), nullable=False), - sa.Column('name', sa.String(length=255), nullable=False), - sa.Column('href', sa.String(length=255), nullable=True), - sa.Column('mime', sa.CHAR(length=50), nullable=False), - sa.Column('size', sa.CHAR(length=30), nullable=False), - sa.Column('create_time', sa.DateTime(), nullable=True), - sa.PrimaryKeyConstraint('id') - ) - op.create_table('admin_power', - sa.Column('id', sa.Integer(), nullable=False, comment='权限编号'), - sa.Column('name', sa.String(length=255), nullable=True, comment='权限名称'), - sa.Column('type', sa.String(length=1), nullable=True, comment='权限类型'), - sa.Column('code', sa.String(length=30), nullable=True, comment='权限标识'), - sa.Column('url', sa.String(length=255), nullable=True, comment='权限路径'), - sa.Column('open_type', sa.String(length=10), nullable=True, comment='打开方式'), - sa.Column('parent_id', sa.Integer(), nullable=True, comment='父类编号'), - sa.Column('icon', sa.String(length=128), nullable=True, comment='图标'), - sa.Column('sort', sa.Integer(), nullable=True, comment='排序'), - sa.Column('create_time', sa.DateTime(), nullable=True, comment='创建时间'), - sa.Column('update_time', sa.DateTime(), nullable=True, comment='更新时间'), - sa.Column('enable', sa.Integer(), nullable=True, comment='是否开启'), - sa.PrimaryKeyConstraint('id') - ) - op.create_table('admin_role', - sa.Column('id', sa.Integer(), nullable=False, comment='角色ID'), - sa.Column('name', sa.String(length=255), nullable=True, comment='角色名称'), - sa.Column('code', sa.String(length=255), nullable=True, comment='角色标识'), - sa.Column('enable', sa.Integer(), nullable=True, comment='是否启用'), - sa.Column('remark', sa.String(length=255), nullable=True, comment='备注'), - sa.Column('details', sa.String(length=255), nullable=True, comment='详情'), - sa.Column('sort', sa.Integer(), nullable=True, comment='排序'), - sa.Column('create_time', sa.DateTime(), nullable=True, comment='创建时间'), - sa.Column('update_time', sa.DateTime(), nullable=True, comment='更新时间'), - sa.PrimaryKeyConstraint('id') - ) - op.create_table('admin_user', - sa.Column('id', sa.Integer(), autoincrement=True, nullable=False, comment='用户ID'), - sa.Column('username', sa.String(length=20), nullable=True, comment='用户名'), - sa.Column('realname', sa.String(length=20), nullable=True, comment='真实名字'), - sa.Column('avatar', sa.String(length=255), nullable=True, comment='头像'), - sa.Column('remark', sa.String(length=255), nullable=True, comment='备注'), - sa.Column('password_hash', sa.String(length=128), nullable=True, comment='哈希密码'), - sa.Column('enable', sa.Integer(), nullable=True, comment='启用'), - sa.Column('create_at', sa.DateTime(), nullable=True, comment='创建时间'), - sa.Column('update_at', sa.DateTime(), nullable=True, comment='创建时间'), - sa.PrimaryKeyConstraint('id') - ) - op.create_table('admin_role_power', - sa.Column('id', sa.Integer(), autoincrement=True, nullable=False, comment='标识'), - sa.Column('power_id', sa.Integer(), nullable=True, comment='用户编号'), - sa.Column('role_id', sa.Integer(), nullable=True, comment='角色编号'), - sa.ForeignKeyConstraint(['power_id'], ['admin_power.id'], ), - sa.ForeignKeyConstraint(['role_id'], ['admin_role.id'], ), - sa.PrimaryKeyConstraint('id') - ) - op.create_table('admin_user_role', - sa.Column('id', sa.Integer(), autoincrement=True, nullable=False, comment='标识'), - sa.Column('user_id', sa.Integer(), nullable=True, comment='用户编号'), - sa.Column('role_id', sa.Integer(), nullable=True, comment='角色编号'), - sa.ForeignKeyConstraint(['role_id'], ['admin_role.id'], ), - sa.ForeignKeyConstraint(['user_id'], ['admin_user.id'], ), - sa.PrimaryKeyConstraint('id') - ) - # ### end Alembic commands ### - - -def downgrade(): - # ### commands auto generated by Alembic - please adjust! ### - op.drop_table('admin_user_role') - op.drop_table('admin_role_power') - op.drop_table('admin_user') - op.drop_table('admin_role') - op.drop_table('admin_power') - op.drop_table('admin_photo') - op.drop_table('admin_dict_type') - op.drop_table('admin_dict_data') - op.drop_table('admin_admin_log') - # ### end Alembic commands ### diff --git a/requirement/requirement-dev.txt b/requirement/requirement-dev.txt index cd41a4182bcaa384d77155fbfbff983ca8cc9b68..b69d886334653dc9ff8f224d8d0475c6f76e2453 100644 --- a/requirement/requirement-dev.txt +++ b/requirement/requirement-dev.txt @@ -1,24 +1,26 @@ -blinker==1.4 +alembic==1.6.5 +aniso8601==9.0.1 captcha==0.3 click==8.0.1 colorama==0.4.4 Flask==2.0.1 -Flask-DebugToolbar==0.11.0 Flask-Login==0.5.0 -flask-marshmallow==0.14.0 +Flask-Migrate==3.0.1 +Flask-RESTful==0.3.9 Flask-SQLAlchemy==2.5.1 Flask-Uploads==0.2.1 greenlet==1.1.0 itsdangerous==2.0.1 Jinja2==3.0.1 +Mako==1.1.4 MarkupSafe==2.0.1 -marshmallow==3.12.1 -marshmallow-sqlalchemy==0.26.1 Pillow==8.2.0 psutil==5.8.0 PyMySQL==1.0.2 -python-dotenv==0.17.1 +python-dateutil==2.8.1 +python-dotenv==0.18.0 +python-editor==1.0.4 +pytz==2021.1 six==1.16.0 SQLAlchemy==1.4.18 -sqlparse==0.4.1 Werkzeug==2.0.1 diff --git a/static/upload/1623509219000.jpg b/static/upload/1623509219000.jpg deleted file mode 100644 index 68361262598a4a0afbe702dea51a135f3e12d341..0000000000000000000000000000000000000000 Binary files a/static/upload/1623509219000.jpg and /dev/null differ diff --git a/static/upload/1623509456000.jpg b/static/upload/1623509456000.jpg deleted file mode 100644 index b360fbdde02e128991c327a886b9694c308b5791..0000000000000000000000000000000000000000 Binary files a/static/upload/1623509456000.jpg and /dev/null differ diff --git a/test/init_databases.py b/test/init_databases.py deleted file mode 100644 index da05eb4969a8a8278cfb22e0c44443d29790d5d0..0000000000000000000000000000000000000000 --- a/test/init_databases.py +++ /dev/null @@ -1,69 +0,0 @@ -import sys -from dotenv import dotenv_values - -sys.path.append('../') -import sqlparse -import pymysql - -config = dotenv_values('.env') - -# MySql配置信息 -HOST = config.get('MYSQL_PASSWORD') or '127.0.0.1' -PORT = config.get('MYSQL_PORT') or 3306 -DATABASE = config.get('MYSQL_DATABASE') or 'PearAdminFlask' -USERNAME = config.get('MYSQL_USERNAME') or 'root' -PASSWORD = config.get('MYSQL_PASSWORD') or '123456' - - -def is_exist_database(): - db = pymysql.connect(host=HOST, port=int(PORT), user=USERNAME, password=PASSWORD, charset='utf8mb4') - cursor1 = db.cursor() - sql = "select * from information_schema.SCHEMATA WHERE SCHEMA_NAME = '%s' ; " % DATABASE - res = cursor1.execute(sql) - db.close() - return res - - -def init_database(): - db = pymysql.connect(host=HOST, port=int(PORT), user=USERNAME, password=PASSWORD, charset='utf8mb4') - cursor1 = db.cursor() - sql = "CREATE DATABASE IF NOT EXISTS %s" % DATABASE - res = cursor1.execute(sql) - db.close() - return res - - -def execute_fromfile(filename): - db = pymysql.connect(host=HOST, port=int(PORT), user=USERNAME, password=PASSWORD, database=DATABASE, - charset='utf8mb4') - fd = open(filename, 'r', encoding='utf-8') - cursor = db.cursor() - sqlfile = fd.read() - sqlfile = sqlparse.format(sqlfile, strip_comments=True).strip() - - sqlcommamds = sqlfile.split(';') - - for command in sqlcommamds: - try: - cursor.execute(command) - db.commit() - - except Exception as msg: - - db.rollback() - db.close() - - -def init_db(): - if is_exist_database(): - print('数据库已经存在,为防止误初始化,请收动删除 %s 数据库' % str(DATABASE)) - return - if init_database(): - print('数据库%s创建成功' % str(DATABASE)) - execute_fromfile('pear.sql') - print('表创建成功') - print('欢迎使用pear-admin-flask,请使用 flask run 命令启动程序') - - -if __name__ == '__main__': - init_db() diff --git a/test/pear.sql b/test/pear.sql deleted file mode 100644 index 0e666e43af79aba54d4e41a701605c664c198fa6..0000000000000000000000000000000000000000 --- a/test/pear.sql +++ /dev/null @@ -1,326 +0,0 @@ -/* - Navicat Premium Data Transfer - - Source Server : phpmystudy - Source Server Type : MySQL - Source Server Version : 50726 - Source Host : localhost:3306 - Source Schema : pearadminflask - - Target Server Type : MySQL - Target Server Version : 50726 - File Encoding : 65001 - - Date: 03/06/2021 11:23:03 -*/ - -SET NAMES utf8mb4; -SET FOREIGN_KEY_CHECKS = 0; - --- ---------------------------- --- Table structure for admin_admin_log --- ---------------------------- -DROP TABLE IF EXISTS `admin_admin_log`; -CREATE TABLE `admin_admin_log` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `method` varchar(10) CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL DEFAULT NULL, - `uid` int(11) NULL DEFAULT NULL, - `url` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL DEFAULT NULL, - `desc` text CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL, - `ip` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL DEFAULT NULL, - `user_agent` text CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL, - `create_time` datetime(0) NULL DEFAULT NULL, - `success` int(11) NULL DEFAULT NULL, - PRIMARY KEY (`id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 641 CHARACTER SET = utf8 COLLATE = utf8_unicode_ci ROW_FORMAT = DYNAMIC; - --- ---------------------------- --- Records of admin_admin_log --- ---------------------------- - --- ---------------------------- --- Table structure for admin_dept --- ---------------------------- -DROP TABLE IF EXISTS `admin_dept`; -CREATE TABLE `admin_dept` ( - `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '部门ID', - `parent_id` int(11) NULL DEFAULT NULL COMMENT '父级编号', - `dept_name` varchar(50) CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL DEFAULT NULL COMMENT '部门名称', - `sort` int(11) NULL DEFAULT NULL COMMENT '排序', - `leader` varchar(50) CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL DEFAULT NULL COMMENT '负责人', - `phone` varchar(20) CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL DEFAULT NULL COMMENT '联系方式', - `email` varchar(50) CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL DEFAULT NULL COMMENT '邮箱', - `status` int(11) NULL DEFAULT NULL COMMENT '状态(1开启,0关闭)', - `remark` text CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL COMMENT '备注', - `address` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL DEFAULT NULL COMMENT '详细地址', - `create_at` datetime(0) NULL DEFAULT NULL COMMENT '创建时间', - `update_at` datetime(0) NULL DEFAULT NULL COMMENT '创建时间', - PRIMARY KEY (`id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 9 CHARACTER SET = utf8 COLLATE = utf8_unicode_ci ROW_FORMAT = Dynamic; - --- ---------------------------- --- Records of admin_dept --- ---------------------------- -INSERT INTO `admin_dept` VALUES (1, 0, '总公司', 1, '就眠仪式', '12312345679', '123qq.com', 1, NULL, '这是总公司', NULL, '2021-06-01 17:23:20'); -INSERT INTO `admin_dept` VALUES (4, 1, '济南分公司', 2, '就眠仪式', '12312345678', '1234qq.com', 1, NULL, '这是济南', '2021-06-01 17:24:33', '2021-06-01 17:25:19'); -INSERT INTO `admin_dept` VALUES (5, 1, '唐山分公司', 4, 'mkg', '12312345678', '123@qq.com', 1, NULL, '这是唐山', '2021-06-01 17:25:15', '2021-06-01 17:25:20'); -INSERT INTO `admin_dept` VALUES (7, 4, '济南分公司开发部', 5, '就眠仪式', '12312345678', '123@qq.com', 1, NULL, '测试', '2021-06-01 17:27:39', '2021-06-01 17:27:39'); -INSERT INTO `admin_dept` VALUES (8, 5, '唐山测试部', 6, 'mkg', '12312345678', '123@qq.com', 1, NULL, '测试部', '2021-06-01 17:28:27', '2021-06-01 17:28:27'); - --- ---------------------------- --- Table structure for admin_dict_data --- ---------------------------- -DROP TABLE IF EXISTS `admin_dict_data`; -CREATE TABLE `admin_dict_data` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `data_label` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL DEFAULT NULL COMMENT '字典类型名称', - `data_value` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL DEFAULT NULL COMMENT '字典类型标识', - `type_code` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL DEFAULT NULL COMMENT '字典类型描述', - `is_default` int(11) NULL DEFAULT NULL COMMENT '是否默认', - `enable` int(11) NULL DEFAULT NULL COMMENT '是否开启', - `remark` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL DEFAULT NULL COMMENT '备注', - `create_time` datetime(0) NULL DEFAULT NULL COMMENT '创建时间', - `update_time` datetime(0) NULL DEFAULT NULL COMMENT '更新时间', - PRIMARY KEY (`id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 10 CHARACTER SET = utf8 COLLATE = utf8_unicode_ci ROW_FORMAT = DYNAMIC; - --- ---------------------------- --- Records of admin_dict_data --- ---------------------------- -INSERT INTO `admin_dict_data` VALUES (8, '男', 'boy', 'user_sex', NULL, 1, '男 : body', '2021-04-16 13:36:34', '2021-04-16 14:05:06'); -INSERT INTO `admin_dict_data` VALUES (9, '女', 'girl', 'user_sex', NULL, 1, '女 : girl', '2021-04-16 13:36:55', '2021-04-16 13:36:55'); - --- ---------------------------- --- Table structure for admin_dict_type --- ---------------------------- -DROP TABLE IF EXISTS `admin_dict_type`; -CREATE TABLE `admin_dict_type` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `type_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL DEFAULT NULL COMMENT '字典类型名称', - `type_code` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL DEFAULT NULL COMMENT '字典类型标识', - `description` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL DEFAULT NULL COMMENT '字典类型描述', - `enable` int(11) NULL DEFAULT NULL COMMENT '是否开启', - `create_time` datetime(0) NULL DEFAULT NULL COMMENT '创建时间', - `update_time` datetime(0) NULL DEFAULT NULL COMMENT '更新时间', - PRIMARY KEY (`id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8 COLLATE = utf8_unicode_ci ROW_FORMAT = DYNAMIC; - --- ---------------------------- --- Records of admin_dict_type --- ---------------------------- -INSERT INTO `admin_dict_type` VALUES (1, '用户性别', 'user_sex', '用户性别', 1, NULL, '2021-04-16 13:37:11'); - --- ---------------------------- --- Table structure for admin_photo --- ---------------------------- -DROP TABLE IF EXISTS `admin_photo`; -CREATE TABLE `admin_photo` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `name` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL, - `href` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL DEFAULT NULL, - `mime` char(50) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL, - `size` char(30) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL, - `create_time` datetime(0) NULL DEFAULT NULL, - PRIMARY KEY (`id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 18 CHARACTER SET = utf8 COLLATE = utf8_unicode_ci ROW_FORMAT = DYNAMIC; - --- ---------------------------- --- Records of admin_photo --- ---------------------------- -INSERT INTO `admin_photo` VALUES (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'); -INSERT INTO `admin_photo` VALUES (17, '1617291580000.jpg', 'http://127.0.0.1:5000/_uploads/photos/1617291580000.jpg', 'image/png', '94211', '2021-04-01 23:39:41'); - --- ---------------------------- --- Table structure for admin_power --- ---------------------------- -DROP TABLE IF EXISTS `admin_power`; -CREATE TABLE `admin_power` ( - `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '权限编号', - `name` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL DEFAULT NULL COMMENT '权限名称', - `type` varchar(1) CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL DEFAULT NULL COMMENT '权限类型', - `code` varchar(30) CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL DEFAULT NULL COMMENT '权限标识', - `url` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL DEFAULT NULL COMMENT '权限路径', - `open_type` varchar(10) CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL DEFAULT NULL COMMENT '打开方式', - `parent_id` varchar(19) CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL DEFAULT NULL COMMENT '父类编号', - `icon` varchar(128) CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL DEFAULT NULL COMMENT '图标', - `sort` int(11) NULL DEFAULT NULL COMMENT '排序', - `create_time` datetime(0) NULL DEFAULT NULL COMMENT '创建时间', - `update_time` datetime(0) NULL DEFAULT NULL COMMENT '更新时间', - `enable` int(11) NULL DEFAULT NULL COMMENT '是否开启', - PRIMARY KEY (`id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 52 CHARACTER SET = utf8 COLLATE = utf8_unicode_ci ROW_FORMAT = DYNAMIC; - --- ---------------------------- --- Records of admin_power --- ---------------------------- -INSERT INTO `admin_power` VALUES (1, '系统管理', '0', '', NULL, NULL, '0', 'layui-icon layui-icon-set-fill', 1, NULL, NULL, 1); -INSERT INTO `admin_power` VALUES (3, '用户管理', '1', 'admin:user:main', '/admin/user/', '_iframe', '1', 'layui-icon layui-icon layui-icon layui-icon layui-icon-rate', 1, NULL, NULL, 1); -INSERT INTO `admin_power` VALUES (4, '权限管理', '1', 'admin:power:main', '/admin/power/', '_iframe', '1', NULL, 2, NULL, NULL, 1); -INSERT INTO `admin_power` VALUES (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); -INSERT INTO `admin_power` VALUES (12, '系统监控', '1', 'admin:monitor:main', '/admin/monitor', '_iframe', '1', 'layui-icon layui-icon-vercode', 5, '2021-03-18 22:05:19', '2021-03-25 19:15:27', 1); -INSERT INTO `admin_power` VALUES (13, '日志管理', '1', 'admin:log:main', '/admin/log', '_iframe', '1', 'layui-icon layui-icon-read', 4, '2021-03-18 22:37:10', '2021-06-03 11:06:25', 1); -INSERT INTO `admin_power` VALUES (17, '文件管理', '0', '', '', '', '0', 'layui-icon layui-icon-camera', 2, '2021-03-19 18:56:23', '2021-03-25 19:15:08', 1); -INSERT INTO `admin_power` VALUES (18, '图片上传', '1', 'admin:file:main', '/admin/file', '_iframe', '17', 'layui-icon layui-icon-camera', 5, '2021-03-19 18:57:19', '2021-03-25 19:15:13', 1); -INSERT INTO `admin_power` VALUES (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); -INSERT INTO `admin_power` VALUES (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); -INSERT INTO `admin_power` VALUES (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); -INSERT INTO `admin_power` VALUES (24, '用户删除', '2', 'admin:user:remove', '', '', '3', 'layui-icon None', 3, '2021-03-22 19:46:51', '2021-03-25 19:15:18', 1); -INSERT INTO `admin_power` VALUES (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); -INSERT INTO `admin_power` VALUES (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); -INSERT INTO `admin_power` VALUES (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); -INSERT INTO `admin_power` VALUES (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); -INSERT INTO `admin_power` VALUES (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); -INSERT INTO `admin_power` VALUES (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); -INSERT INTO `admin_power` VALUES (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); -INSERT INTO `admin_power` VALUES (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); -INSERT INTO `admin_power` VALUES (44, '数据字典', '1', 'admin:dict:main', '/admin/dict', '_iframe', '1', 'layui-icon layui-icon-console', 6, '2021-04-16 13:59:49', '2021-04-16 13:59:49', 1); -INSERT INTO `admin_power` VALUES (45, '字典增加', '2', 'admin:dict:add', '', '', '44', 'layui-icon ', 1, '2021-04-16 14:00:59', '2021-04-16 14:00:59', 1); -INSERT INTO `admin_power` VALUES (46, '字典修改', '2', 'admin:dict:edit', '', '', '44', 'layui-icon ', 2, '2021-04-16 14:01:33', '2021-04-16 14:01:33', 1); -INSERT INTO `admin_power` VALUES (47, '字典删除', '2', 'admin:dict:remove', '', '', '44', 'layui-icon ', 3, '2021-04-16 14:02:06', '2021-04-16 14:02:06', 1); -INSERT INTO `admin_power` VALUES (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); -INSERT INTO `admin_power` VALUES (49, '部门增加', '2', 'admin:dept:add', '', '', '48', 'layui-icon None', 1, '2021-06-01 17:35:52', '2021-06-01 17:36:15', 1); -INSERT INTO `admin_power` VALUES (50, '部门编辑', '2', 'admin:dept:edit', '', '', '48', 'layui-icon ', 2, '2021-06-01 17:36:41', '2021-06-01 17:36:41', 1); -INSERT INTO `admin_power` VALUES (51, '部门删除', '2', 'admin:dept:remove', '', '', '48', 'layui-icon None', 3, '2021-06-01 17:37:15', '2021-06-01 17:37:26', 1); - --- ---------------------------- --- Table structure for admin_role --- ---------------------------- -DROP TABLE IF EXISTS `admin_role`; -CREATE TABLE `admin_role` ( - `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '角色ID', - `name` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL DEFAULT NULL COMMENT '角色名称', - `code` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL DEFAULT NULL COMMENT '角色标识', - `remark` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL DEFAULT NULL COMMENT '备注', - `details` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL DEFAULT NULL COMMENT '详情', - `sort` int(11) NULL DEFAULT NULL COMMENT '排序', - `create_time` datetime(0) NULL DEFAULT NULL COMMENT '创建时间', - `update_time` datetime(0) NULL DEFAULT NULL COMMENT '更新时间', - `enable` int(11) NULL DEFAULT NULL COMMENT '是否启用', - PRIMARY KEY (`id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8 COLLATE = utf8_unicode_ci ROW_FORMAT = DYNAMIC; - --- ---------------------------- --- Records of admin_role --- ---------------------------- -INSERT INTO `admin_role` VALUES (1, '管理员', 'admin', NULL, '管理员', 1, NULL, NULL, 1); -INSERT INTO `admin_role` VALUES (2, '普通用户', 'common', NULL, '只有查看,没有增删改权限', 2, '2021-03-22 20:02:38', '2021-04-01 22:29:56', 1); - --- ---------------------------- --- Table structure for admin_role_power --- ---------------------------- -DROP TABLE IF EXISTS `admin_role_power`; -CREATE TABLE `admin_role_power` ( - `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '标识', - `power_id` int(11) NULL DEFAULT NULL COMMENT '用户编号', - `role_id` int(11) NULL DEFAULT NULL COMMENT '角色编号', - PRIMARY KEY (`id`) USING BTREE, - INDEX `power_id`(`power_id`) USING BTREE, - INDEX `role_id`(`role_id`) USING BTREE, - CONSTRAINT `admin_role_power_ibfk_1` FOREIGN KEY (`power_id`) REFERENCES `admin_power` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT, - CONSTRAINT `admin_role_power_ibfk_2` FOREIGN KEY (`role_id`) REFERENCES `admin_role` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT -) ENGINE = InnoDB AUTO_INCREMENT = 275 CHARACTER SET = utf8 COLLATE = utf8_unicode_ci ROW_FORMAT = DYNAMIC; - --- ---------------------------- --- Records of admin_role_power --- ---------------------------- -INSERT INTO `admin_role_power` VALUES (237, 1, 1); -INSERT INTO `admin_role_power` VALUES (238, 3, 1); -INSERT INTO `admin_role_power` VALUES (239, 4, 1); -INSERT INTO `admin_role_power` VALUES (240, 9, 1); -INSERT INTO `admin_role_power` VALUES (241, 12, 1); -INSERT INTO `admin_role_power` VALUES (242, 13, 1); -INSERT INTO `admin_role_power` VALUES (243, 17, 1); -INSERT INTO `admin_role_power` VALUES (244, 18, 1); -INSERT INTO `admin_role_power` VALUES (245, 21, 1); -INSERT INTO `admin_role_power` VALUES (246, 22, 1); -INSERT INTO `admin_role_power` VALUES (247, 23, 1); -INSERT INTO `admin_role_power` VALUES (248, 24, 1); -INSERT INTO `admin_role_power` VALUES (249, 25, 1); -INSERT INTO `admin_role_power` VALUES (250, 26, 1); -INSERT INTO `admin_role_power` VALUES (251, 27, 1); -INSERT INTO `admin_role_power` VALUES (252, 28, 1); -INSERT INTO `admin_role_power` VALUES (253, 29, 1); -INSERT INTO `admin_role_power` VALUES (254, 30, 1); -INSERT INTO `admin_role_power` VALUES (255, 31, 1); -INSERT INTO `admin_role_power` VALUES (256, 32, 1); -INSERT INTO `admin_role_power` VALUES (257, 44, 1); -INSERT INTO `admin_role_power` VALUES (258, 45, 1); -INSERT INTO `admin_role_power` VALUES (259, 46, 1); -INSERT INTO `admin_role_power` VALUES (260, 47, 1); -INSERT INTO `admin_role_power` VALUES (261, 48, 1); -INSERT INTO `admin_role_power` VALUES (262, 49, 1); -INSERT INTO `admin_role_power` VALUES (263, 50, 1); -INSERT INTO `admin_role_power` VALUES (264, 51, 1); -INSERT INTO `admin_role_power` VALUES (265, 1, 2); -INSERT INTO `admin_role_power` VALUES (266, 3, 2); -INSERT INTO `admin_role_power` VALUES (267, 4, 2); -INSERT INTO `admin_role_power` VALUES (268, 9, 2); -INSERT INTO `admin_role_power` VALUES (269, 12, 2); -INSERT INTO `admin_role_power` VALUES (270, 13, 2); -INSERT INTO `admin_role_power` VALUES (271, 17, 2); -INSERT INTO `admin_role_power` VALUES (272, 18, 2); -INSERT INTO `admin_role_power` VALUES (273, 44, 2); -INSERT INTO `admin_role_power` VALUES (274, 48, 2); - --- ---------------------------- --- Table structure for admin_user --- ---------------------------- -DROP TABLE IF EXISTS `admin_user`; -CREATE TABLE `admin_user` ( - `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '用户ID', - `username` varchar(20) CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL DEFAULT NULL COMMENT '用户名', - `password_hash` varchar(128) CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL DEFAULT NULL COMMENT '哈希密码', - `create_at` datetime(0) NULL DEFAULT NULL COMMENT '创建时间', - `update_at` datetime(0) NULL DEFAULT NULL COMMENT '创建时间', - `enable` int(11) NULL DEFAULT NULL COMMENT '启用', - `realname` varchar(20) CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL DEFAULT NULL COMMENT '真实名字', - `remark` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL DEFAULT NULL COMMENT '备注', - `avatar` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL DEFAULT NULL COMMENT '头像', - `dept_id` int(11) NULL DEFAULT NULL COMMENT '部门id', - PRIMARY KEY (`id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 9 CHARACTER SET = utf8 COLLATE = utf8_unicode_ci ROW_FORMAT = DYNAMIC; - --- ---------------------------- --- Records of admin_user --- ---------------------------- -INSERT INTO `admin_user` VALUES (1, 'admin', 'pbkdf2:sha256:150000$raM7mDSr$58fe069c3eac01531fc8af85e6fc200655dd2588090530084d182e6ec9d52c85', NULL, '2021-06-01 17:28:55', 1, '超级管理', '要是不能把握时机,就要终身蹭蹬,一事无成!', 'http://127.0.0.1:5000/_uploads/photos/1617291580000.jpg', 1); -INSERT INTO `admin_user` VALUES (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); -INSERT INTO `admin_user` VALUES (8, 'wind', 'pbkdf2:sha256:150000$skME1obT$6a2c20cd29f89d7d2f21d9e373a7e3445f70ebce3ef1c3a555e42a7d17170b37', '2021-06-01 17:30:39', '2021-06-01 17:30:52', 1, '风', NULL, '/static/admin/admin/images/avatar.jpg', 7); - --- ---------------------------- --- Table structure for admin_user_role --- ---------------------------- -DROP TABLE IF EXISTS `admin_user_role`; -CREATE TABLE `admin_user_role` ( - `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '标识', - `user_id` int(11) NULL DEFAULT NULL COMMENT '用户编号', - `role_id` int(11) NULL DEFAULT NULL COMMENT '角色编号', - PRIMARY KEY (`id`) USING BTREE, - INDEX `role_id`(`role_id`) USING BTREE, - INDEX `user_id`(`user_id`) USING BTREE, - CONSTRAINT `admin_user_role_ibfk_1` FOREIGN KEY (`role_id`) REFERENCES `admin_role` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT, - CONSTRAINT `admin_user_role_ibfk_2` FOREIGN KEY (`user_id`) REFERENCES `admin_user` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT -) ENGINE = InnoDB AUTO_INCREMENT = 25 CHARACTER SET = utf8 COLLATE = utf8_unicode_ci ROW_FORMAT = DYNAMIC; - --- ---------------------------- --- Records of admin_user_role --- ---------------------------- -INSERT INTO `admin_user_role` VALUES (21, 1, 1); -INSERT INTO `admin_user_role` VALUES (22, 7, 2); -INSERT INTO `admin_user_role` VALUES (24, 8, 2); - --- ---------------------------- --- Table structure for alembic_version --- ---------------------------- -DROP TABLE IF EXISTS `alembic_version`; -CREATE TABLE `alembic_version` ( - `version_num` varchar(32) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL, - PRIMARY KEY (`version_num`) USING BTREE -) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_unicode_ci ROW_FORMAT = DYNAMIC; - --- ---------------------------- --- Records of alembic_version --- ---------------------------- -INSERT INTO `alembic_version` VALUES ('7634e028e338'); - -SET FOREIGN_KEY_CHECKS = 1;