From 36250fad438238661c4ab869a063c97c7c438e42 Mon Sep 17 00:00:00 2001 From: zhengxinonly Date: Wed, 11 May 2022 23:31:58 +0800 Subject: [PATCH] =?UTF-8?q?wip:(=E9=87=8D=E6=9E=84=E6=8E=A5=E5=8F=A3?= =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E6=96=B9=E5=BC=8F4)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- applications/rights/__init__.py | 8 ++-- applications/rights/department.py | 63 +++++++++++++++---------------- applications/rights/rights.py | 35 +++++++++-------- applications/rights/roles.py | 2 +- applications/system/file.py | 4 +- applications/system/passport.py | 24 ++++++------ templates/index/login.html | 3 +- 7 files changed, 71 insertions(+), 68 deletions(-) diff --git a/applications/rights/__init__.py b/applications/rights/__init__.py index b908540..386b6d3 100644 --- a/applications/rights/__init__.py +++ b/applications/rights/__init__.py @@ -8,15 +8,15 @@ from .roles import RoleRoleApi, RolePowerApi, role_deletes, role_enable_resource def register_rights_api(api_bp): - register_api(DepartmentsApi, 'rights_dept_api', '/dept/department/', pk='dept_id', app=api_bp) - api_bp.add_url_rule('/dept/department//status', + register_api(DepartmentsApi, 'rights_dept_api', '/dept/department/', pk='_id', app=api_bp) + api_bp.add_url_rule('/dept/department//status', view_func=DeptEnableAPI.as_view('dept_status_api'), methods=['PUT', ]) api_bp.add_url_rule('/rights/rights', view_func=RightsApi.as_view('dept_rights_api'), methods=['GET', 'DELETE']) - register_api(PowerApi, 'rights_power_api', '/power/', pk='_id', app=api_bp) + register_api(PowerApi, 'rights_power_api', '/rights/power/', pk='_id', app=api_bp) api_bp.add_url_rule('/rights/configs', endpoint='rights_config_api', view_func=admin_configs_resource, @@ -25,7 +25,7 @@ def register_rights_api(api_bp): endpoint='rights_menu_api', view_func=admin_menu_resource, methods=['GET']) - api_bp.add_url_rule('/power//', + api_bp.add_url_rule('/rights/power//', endpoint='rights_power_action_api', view_func=right_power_enable_resource, methods=['PUT']) diff --git a/applications/rights/department.py b/applications/rights/department.py index 1da9262..b60e910 100644 --- a/applications/rights/department.py +++ b/applications/rights/department.py @@ -1,17 +1,31 @@ +import typing as t + from flask import jsonify from flask.views import MethodView -from flask_restful import reqparse +from flask_pydantic import validate +from pydantic import BaseModel, Field from common.utils.http import success_api, fail_api from extensions import db from models import DepartmentModel, UserModel +class DeptModel(BaseModel): + address: t.Optional[str] + dept_name: t.Optional[str] = Field(alias='deptName') + email: t.Optional[str] + leader: t.Optional[str] + parent_id: t.Optional[str] = Field(alias='parentId') + phone: t.Optional[str] + sort: t.Optional[int] + status: t.Optional[int] + + class DepartmentsApi(MethodView): - def get(self, dept_id): - if dept_id: - dept = DepartmentModel.query.filter_by(id=dept_id).first() + def get(self, _id): + if _id: + dept = DepartmentModel.query.filter_by(id=_id).first() dept_data = { 'id': dept.id, 'dept_name': dept.dept_name, @@ -46,18 +60,9 @@ class DepartmentsApi(MethodView): } return jsonify(res) - 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() + @validate() + def post(self, body: DeptModel): + res = body dept = DepartmentModel( parent_id=res.parent_id, @@ -74,17 +79,9 @@ class DepartmentsApi(MethodView): return success_api(message="成功") - 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() + @validate() + def put(self, _id, body: DeptModel): + res = body data = { "dept_name": res.dept_name, "sort": res.sort, @@ -94,15 +91,15 @@ class DepartmentsApi(MethodView): "status": res.status, "address": res.address } - res = DepartmentModel.query.filter_by(id=dept_id).update(data) + res = DepartmentModel.query.filter_by(id=_id).update(data) if not res: return fail_api(message="更新失败") db.session.commit() return success_api(message="更新成功") - def delete(self, dept_id): - ret = DepartmentModel.query.filter_by(id=dept_id).delete() - UserModel.query.filter_by(dept_id=dept_id).update({"dept_id": None}) + def delete(self, _id): + ret = DepartmentModel.query.filter_by(id=_id).delete() + UserModel.query.filter_by(dept_id=_id).update({"dept_id": None}) db.session.commit() if ret: return success_api(message="删除成功") @@ -110,8 +107,8 @@ class DepartmentsApi(MethodView): class DeptEnableAPI(MethodView): - def put(self, dept_id): - d = DepartmentModel.query.get(dept_id) + def put(self, _id): + d = DepartmentModel.query.get(_id) if d: d.status = not d.status db.session.commit() diff --git a/applications/rights/rights.py b/applications/rights/rights.py index d78acd5..741c20d 100644 --- a/applications/rights/rights.py +++ b/applications/rights/rights.py @@ -1,10 +1,13 @@ import copy +from typing import Optional from collections import OrderedDict from flask import request, jsonify, current_app from flask.views import MethodView from flask_login import current_user -from flask_restful import reqparse +from flask_pydantic import validate + +from pydantic import BaseModel, Field from common.utils.http import success_api, fail_api from extensions import db @@ -160,15 +163,15 @@ def batch_remove_power(ids): remove_power(_id) -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') +class PowerModel(BaseModel): + icon: str + open_type: Optional[str] = Field(alias='openType') + parent_id: Optional[str] = Field(alias='parentId') + power_code: Optional[str] = Field(alias='powerCode') + power_name: Optional[str] = Field(alias='powerName') + power_type: Optional[str] = Field(alias='powerType') + power_url: Optional[str] = Field(alias='powerUrl') + sort: Optional[int] = Field(alias='sort') class RightsApi(MethodView): @@ -204,9 +207,9 @@ class RightsApi(MethodView): class PowerApi(MethodView): - - def post(self): - res = parser_power.parse_args() + @validate() + def post(self, body: PowerModel): + res = body power = RightModel( icon=res.icon, open_type=res.open_type, @@ -245,9 +248,9 @@ class PowerApi(MethodView): else: return fail_api(message="删除失败") - def put(self, _id): - - res = parser_power.parse_args() + @validate() + def put(self, _id, body: PowerModel): + res = body data = { "icon": res.icon, "open_type": res.open_type, diff --git a/applications/rights/roles.py b/applications/rights/roles.py index 80a7c0d..93c864f 100644 --- a/applications/rights/roles.py +++ b/applications/rights/roles.py @@ -1,6 +1,6 @@ from flask.views import MethodView -from flask_restful import Resource, reqparse +from flask_restful import reqparse from common.utils.http import table_api, success_api, fail_api from extensions import db diff --git a/applications/system/file.py b/applications/system/file.py index 7f69036..f958e8d 100644 --- a/applications/system/file.py +++ b/applications/system/file.py @@ -11,8 +11,8 @@ class FilePhotoAPI(MethodView): def get(self, photo_id): if photo_id is None: - page = request.args.get('page', type=int) - limit = request.args.get('limit', type=int) + page = request.args.get('page', type=int, default=1) + limit = request.args.get('limit', type=int, default=10) photo_paginate = PhotoModel.query.order_by(desc(PhotoModel.create_at) ).paginate(page=page, per_page=limit, diff --git a/applications/system/passport.py b/applications/system/passport.py index abdcc9f..ebedcb8 100644 --- a/applications/system/passport.py +++ b/applications/system/passport.py @@ -2,7 +2,8 @@ from flask import render_template, make_response from flask import session, redirect, url_for from flask.views import MethodView from flask_login import current_user, login_user -from flask_restful import reqparse +from flask_pydantic import validate +from pydantic import BaseModel from common.gen_captcha import add_auth_session from common.utils.http import fail_api, success_api @@ -10,6 +11,12 @@ from common.utils.rights import record_logging from models import UserModel +class LoginModel(BaseModel): + username: str + password: str + captcha: str + + class LoginAPI(MethodView): def get(self): @@ -17,19 +24,14 @@ class LoginAPI(MethodView): return redirect(url_for('admin.index')) return make_response(render_template('index/login.html')) - def post(self): - 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) - req = login_req.parse_args() - + @validate() + def post(self, body: LoginModel): s_code = session.get("code", None) session["code"] = None - if req.captcha != s_code: + if body.captcha != s_code: return fail_api(message="验证码错误") - user = UserModel.query.filter_by(username=req.username).first() + user = UserModel.query.filter_by(username=body.username).first() if user is None: return fail_api(message="不存在的用户") @@ -37,7 +39,7 @@ class LoginAPI(MethodView): if user.enable == 0: return fail_api(message="用户被暂停使用") - if user.validate_password(req.password): + if user.validate_password(body.password): # 登录 login_user(user) # 记录登录日志 diff --git a/templates/index/login.html b/templates/index/login.html index 999ccba..9ee8348 100644 --- a/templates/index/login.html +++ b/templates/index/login.html @@ -53,7 +53,8 @@ let btn = button.load({ elem: '.login' }) $.ajax({ url: '/api/v1/passport/login', - data: data.field, + data: JSON.stringify(data.field), + contentType: 'application/json', type: 'post', dataType: 'json', // 请求成功之后返回的数据