Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dc1e9afe0c | ||
|
|
6220f979bf | ||
|
|
6ec05fd3f9 | ||
|
|
8c3e43b85b | ||
|
|
248145b821 | ||
|
|
261a983678 | ||
|
|
1a7e457054 | ||
|
|
7ae59415e8 | ||
|
|
c50d5e7921 | ||
|
|
af873bf45e | ||
|
|
4384a3000c | ||
|
|
72a951a2b6 | ||
|
|
38a5136e69 | ||
|
|
96dbeb0cbd | ||
|
|
936c37c65c |
@@ -14,11 +14,11 @@ MYSQL_HOST=127.0.0.1
|
||||
MYSQL_PORT=3306
|
||||
MYSQL_DATABASE=PearAdminFlask
|
||||
MYSQL_USERNAME=root
|
||||
MYSQL_PASSWORD=root
|
||||
MYSQL_PASSWORD=123456
|
||||
|
||||
# Redis 配置
|
||||
REDIS_HOST=127.0.0.1
|
||||
REDIS_PORT=6379
|
||||
# REDIS_HOST=127.0.0.1
|
||||
# REDIS_PORT=6379
|
||||
|
||||
# 密钥配置(记得改)
|
||||
SECRET_KEY='pear-admin-flask'
|
||||
|
||||
+1
-3
@@ -1,9 +1,7 @@
|
||||
FROM python:3.7-alpine
|
||||
|
||||
|
||||
RUN echo http://mirrors.aliyun.com/alpine/v3.12/main > /etc/apk/repositories \
|
||||
&& echo http://mirrors.aliyun.com/alpine/v3.12/community >> /etc/apk/repositories \
|
||||
&& apk update \
|
||||
RUN apk update \
|
||||
&& apk --update add --no-cache gcc \
|
||||
&& apk --update add --no-cache g++ \
|
||||
&& apk --update add --no-cache tzdata \
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
开 箱 即 用 的 Flask 快 速 开 发 平 台
|
||||
</h4>
|
||||
|
||||
[预 览](http://flask.pearadmin.com) | [官 网](http://www.pearadmin.com/) | [群聊](https://jq.qq.com/?_wv=1027&k=5OdSmve) | [社区](http://forum.pearadmin.com/)
|
||||
[预 览](http://flask.pearadmin.com) | [官 网](http://www.pearadmin.com/) | [群聊](https://jq.qq.com/?_wv=1027&k=TkLAKUxC) | [社区](http://forum.pearadmin.com/)
|
||||
|
||||
|
||||
<p align="center">
|
||||
@@ -90,8 +90,6 @@ Pear Admin Flask
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
#### 项目安装
|
||||
|
||||
```bash
|
||||
|
||||
@@ -36,12 +36,12 @@ def make_menu_tree():
|
||||
if p.enable == 0:
|
||||
continue
|
||||
# 一二级菜单
|
||||
if int(p.type) == 0 or int(p.type) == 1:
|
||||
if int(p.type) in [0,1] and p not in powers:
|
||||
powers.append(p)
|
||||
|
||||
power_schema = PowerOutSchema(many=True) # 用已继承 ma.ModelSchema 类的自定制类生成序列化类
|
||||
power_dict = power_schema.dump(powers) # 生成可序列化对象
|
||||
power_dict.sort(key=lambda x: x['id'], reverse=True)
|
||||
power_dict.sort(key=lambda x: (x['parent_id'], x['id']), reverse=True)
|
||||
|
||||
menu_dict = OrderedDict()
|
||||
for _dict in power_dict:
|
||||
|
||||
@@ -22,7 +22,7 @@ def is_exist_database():
|
||||
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
|
||||
sql = "CREATE DATABASE IF NOT EXISTS %s CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;" % DATABASE
|
||||
res = cursor1.execute(sql)
|
||||
db.close()
|
||||
return res
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import logging
|
||||
import os
|
||||
from urllib.parse import quote_plus as urlquote
|
||||
|
||||
|
||||
class BaseConfig:
|
||||
@@ -44,7 +45,8 @@ class BaseConfig:
|
||||
MYSQL_DATABASE = os.getenv('MYSQL_DATABASE') or "PearAdminFlask"
|
||||
|
||||
# mysql 数据库的配置信息
|
||||
SQLALCHEMY_DATABASE_URI = f"mysql+pymysql://{MYSQL_USERNAME}:{MYSQL_PASSWORD}@{MYSQL_HOST}:{MYSQL_PORT}/{MYSQL_DATABASE}"
|
||||
SQLALCHEMY_DATABASE_URI = f"mysql+pymysql://{MYSQL_USERNAME}:{urlquote(MYSQL_PASSWORD)}@{MYSQL_HOST}:{MYSQL_PORT}/{MYSQL_DATABASE}?charset=utf8mb4"
|
||||
|
||||
# 默认日志等级
|
||||
LOG_LEVEL = logging.WARN
|
||||
#
|
||||
|
||||
@@ -55,16 +55,34 @@ class Query(BaseQuery):
|
||||
def logic_all(self):
|
||||
return self.filter_by(delete_at=None).all()
|
||||
|
||||
def all_json(self, schema: Marshmallow().Schema):
|
||||
return schema(many=True).dump(self.all())
|
||||
|
||||
def layui_paginate(self):
|
||||
"""
|
||||
layui表格分页
|
||||
page
|
||||
limit
|
||||
"""
|
||||
return self.paginate(page=request.args.get('page', type=int),
|
||||
per_page=request.args.get('limit', type=int),
|
||||
error_out=False)
|
||||
|
||||
def layui_paginate_json(self, schema: Marshmallow().Schema):
|
||||
"""
|
||||
返回dict
|
||||
"""
|
||||
_res = self.paginate(
|
||||
page=request.args.get('page', type=int),
|
||||
per_page=request.args.get('limit', type=int),
|
||||
error_out=False
|
||||
)
|
||||
return schema(many=True).dump(_res.items), _res.total, _res.page, _res.per_page
|
||||
|
||||
def layui_paginate_db_json(self):
|
||||
"""
|
||||
db.query(A.name).layui_paginate_db_json()
|
||||
"""
|
||||
_res = self.paginate(page=request.args.get('page', type=int),
|
||||
per_page=request.args.get('limit', type=int),
|
||||
error_out=False)
|
||||
return [dict(i) for i in _res.items], _res.total
|
||||
|
||||
|
||||
db = SQLAlchemy(query_class=Query)
|
||||
ma = Marshmallow()
|
||||
|
||||
@@ -1,15 +1,13 @@
|
||||
from flask import Blueprint, render_template, request, jsonify
|
||||
from marshmallow import INCLUDE
|
||||
from webargs.flaskparser import use_args
|
||||
|
||||
from applications.common import curd
|
||||
from applications.common.utils import validate
|
||||
from applications.common.utils.http import success_api, fail_api
|
||||
from applications.common.utils.rights import authorize
|
||||
from applications.common.utils import validate
|
||||
from applications.common.utils.validate import xss_escape
|
||||
from applications.extensions import db
|
||||
from applications.models import Dept, User
|
||||
from applications.schemas import DeptOutSchema
|
||||
from applications.schemas.admin_dept import DeptInSchema
|
||||
|
||||
dept_bp = Blueprint('dept', __name__, url_prefix='/dept')
|
||||
|
||||
@@ -56,17 +54,17 @@ def tree():
|
||||
|
||||
@dept_bp.post('/save')
|
||||
@authorize("admin:dept:add", log=True)
|
||||
@use_args(DeptInSchema(), location="json", unknown=True)
|
||||
def save(args):
|
||||
def save():
|
||||
req_json = request.json
|
||||
dept = Dept(
|
||||
parent_id=args['parentId'],
|
||||
dept_name=args['deptName'],
|
||||
sort=args['sort'],
|
||||
leader=args['leader'],
|
||||
phone=args['phone'],
|
||||
email=args['email'],
|
||||
status=args['status'],
|
||||
address=args['address']
|
||||
parent_id=req_json.get('parentId'),
|
||||
dept_name=xss_escape(req_json.get('deptName')),
|
||||
sort=xss_escape(req_json.get('sort')),
|
||||
leader=xss_escape(req_json.get('leader')),
|
||||
phone=xss_escape(req_json.get('phone')),
|
||||
email=xss_escape(req_json.get('email')),
|
||||
status=xss_escape(req_json.get('status')),
|
||||
address=xss_escape(req_json.get('address'))
|
||||
)
|
||||
r = db.session.add(dept)
|
||||
db.session.commit()
|
||||
@@ -77,7 +75,7 @@ def save(args):
|
||||
@authorize("admin:dept:edit", log=True)
|
||||
def edit():
|
||||
_id = request.args.get("deptId")
|
||||
dept = curd.get_one_by_id(model=Dept,id=_id)
|
||||
dept = curd.get_one_by_id(model=Dept, id=_id)
|
||||
return render_template('admin/dept/edit.html', dept=dept)
|
||||
|
||||
|
||||
@@ -115,7 +113,6 @@ def dis_enable():
|
||||
@authorize("admin:dept:edit", log=True)
|
||||
def update():
|
||||
json = request.json
|
||||
validate.check_data(DeptSchema(unknown=INCLUDE), json)
|
||||
id = json.get("deptId"),
|
||||
data = {
|
||||
"dept_name": validate.xss_escape(json.get("deptName")),
|
||||
|
||||
@@ -49,10 +49,10 @@ def login_post():
|
||||
return fail_api(msg="验证码错误")
|
||||
user = User.query.filter_by(username=username).first()
|
||||
|
||||
if user is None:
|
||||
if not user:
|
||||
return fail_api(msg="不存在的用户")
|
||||
|
||||
if user.enable is 0:
|
||||
if user.enable == 0:
|
||||
return fail_api(msg="用户被暂停使用")
|
||||
|
||||
if username == user.username and user.validate_password(password):
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
Flask==2.0.2
|
||||
Flask==2.1.1
|
||||
Flask-APScheduler==1.12.2
|
||||
Flask-DebugToolbar==0.11.0
|
||||
Flask-Migrate==3.1.0
|
||||
Flask-Login==0.5.0
|
||||
Flask-Login==0.6.0
|
||||
Flask_Reuploaded==0.5.0
|
||||
Flask-SQLAlchemy==2.5.1
|
||||
flask-marshmallow==0.14.0
|
||||
|
||||
Reference in New Issue
Block a user