109 Commits
Author SHA1 Message Date
zhengxinonlyandGitee dc1e9afe0c !39 修复账号多角色时菜单重复,子菜单ID小于父菜单ID时无法显示的问题
Merge pull request !39 from waizking/N/A
2022-06-16 08:44:53 +00:00
就眠儀式andGitee 6220f979bf !42 update Dockerfile.
Merge pull request !42 from kyqv/N/A
2022-06-16 04:09:10 +00:00
kyqvandGitee 6ec05fd3f9 update Dockerfile.
阿里镜像源问题更新 导致docker 无法安装
2022-06-16 03:45:10 +00:00
不胜舟andGitee 8c3e43b85b !41 修复mysql连接中密码包含@特殊字符时的错误
Merge pull request !41 from stevenhu/N/A
2022-06-02 07:11:05 +00:00
stevenhuandGitee 248145b821 修复mysql连接中密码包含@特殊字符时的错误 2022-06-02 05:08:36 +00:00
就眠儀式andGitee 261a983678 update README.md. 2022-05-13 06:52:00 +00:00
sunshine 1a7e457054 解决bug 2022-05-08 21:29:44 +08:00
不胜舟andGitee 7ae59415e8 update applications/view/passport/__init__.py. 2022-04-12 11:16:54 +00:00
sunshine c50d5e7921 重写sqlalchemy的query,增加序列化方法 2022-04-12 16:55:27 +08:00
sunshine af873bf45e 升级依赖 2022-04-12 16:50:48 +08:00
waizkingandGitee 4384a3000c 修复账号多角色时菜单重复,子菜单ID小于父菜单ID时无法显示的问题 2022-03-21 03:15:25 +00:00
不胜舟andGitee 72a951a2b6 !34 修改数据库的字符集
Merge pull request !34 from zebra/N/A
2022-02-08 10:20:02 +00:00
zebraandGitee 38a5136e69 修改数据库的字符集 2022-02-08 10:18:47 +00:00
不胜舟andGitee 96dbeb0cbd !33 【轻量级 PR】:update applications/configs/config.py.
Merge pull request !33 from VincentFu/N/A
2022-01-25 07:14:04 +00:00
VincentFuandGitee 936c37c65c update applications/configs/config.py.
数据库编码设置为utf8mb4
2022-01-25 07:12:58 +00:00
resonate e51c86c83f reset 2022-01-14 12:46:40 +08:00
resonate 71a25f4774 session存入redis 2022-01-14 12:39:42 +08:00
杭州-伍个一andGitee 56563657e8 update applications/common/helper.py.
修正between查询的类型
2021-12-15 03:18:23 +00:00
mkg 6bfb10e4a4 增加自动序列化(根据orm模型)方法,增加软(逻辑)删除 2021-12-07 15:39:56 +08:00
mkg 70cb8eb35b 更新依赖 2021-11-22 14:13:08 +08:00
mkg cdea48c7d4 加入webargs验证扩展,分区用于验证的inschema和用户序列化的outschema 2021-11-17 18:07:36 +08:00
mkg fba22bbcbf 构造多级菜单树(来源mini分支) 2021-11-17 16:02:51 +08:00
不胜舟andGitee 14f96abdb3 !28 回退 'Pull Request !25 : 【轻量级 PR】:update applications/common/admin.py.'
Merge pull request !28 from 不胜舟/revert-merge-25-master
2021-11-17 02:42:15 +00:00
不胜舟andGitee 28ff95bf0d 回退 'Pull Request !25 : 【轻量级 PR】:update applications/common/admin.py.' 2021-11-17 02:41:27 +00:00
mkg 6cee5a6104 合并配置文件,解决logo打印多次问题 2021-11-16 23:18:20 +08:00
不胜舟andGitee 3add95e910 update requirement/requirement-dev.txt. 2021-11-16 09:41:18 +00:00
mkg 1db1064c11 图片上传数据库存储改为相对路径 2021-11-14 22:40:44 +08:00
mkg f75928119e 修改目录 2021-11-14 20:15:26 +08:00
mkg 9051e8138c 修改环境配置文件 2021-11-14 18:36:08 +08:00
mkg 8396f49105 简化requirement 2021-11-10 23:02:28 +08:00
不胜舟andGitee c664c70bbc !26 update applications/view/department/__init__.py.
Merge pull request !26 from sys/N/A
2021-11-09 13:30:33 +00:00
不胜舟andGitee 7a503cd94a !27 update applications/templates/admin/dept/edit.html.
Merge pull request !27 from sys/N/A
2021-11-09 13:30:20 +00:00
sysandGitee 7a9aeec8db update applications/templates/admin/dept/edit.html. 2021-11-09 06:33:20 +00:00
sysandGitee 2c57bc36ea update applications/view/department/__init__.py. 2021-11-09 06:17:05 +00:00
mkg c0fc70425b 删除.env 2021-11-08 21:39:39 +08:00
mkg f95944a781 Merge branch 'master' of https://gitee.com/pear-admin/pear-admin-flask into master 2021-11-08 18:52:46 +08:00
mkg 589e0c8ce7 提交docker-compose.yml 2021-11-08 18:52:36 +08:00
不胜舟andGitee 6e0ff64893 !25 update applications/common/admin.py.
Merge pull request !25 from sys/N/A
2021-11-06 17:26:18 +00:00
sysandGitee 044e432eb7 update applications/common/admin.py. 2021-11-06 17:22:05 +00:00
不胜舟andGitee 5887079ade !24 update applications/view/admin/user.py.
Merge pull request !24 from sys/N/A
2021-11-06 12:34:50 +00:00
sysandGitee 724e0817a5 update applications/view/admin/user.py. 2021-11-06 12:31:52 +00:00
不胜舟andGitee 9caa7a22e5 update applications/configs/config.py. 2021-11-06 09:17:49 +00:00
mkgandGitee c2042d5f80 update start.sh. 2021-10-28 07:56:41 +00:00
mkg 51f17c9539 提交Dockerfile 2021-10-28 13:12:18 +08:00
mkg 27ed99ee27 增加gunicorn启动脚本 2021-10-28 10:00:21 +08:00
mkg 7eb41e9754 修补日志的xss漏洞 2021-10-13 19:38:28 +08:00
mkg c7f266a482 Merge branch 'master' of https://gitee.com/pear-admin/pear-admin-flask into master 2021-10-08 22:58:28 +08:00
mkg f2d444b877 修补iconPicker -> icon 导致的bug 2021-10-08 22:58:14 +08:00
mkgandGitee 9e59035300 !23 update applications/view/admin/dict.py.
Merge pull request !23 from VincentFu/N/A
2021-10-06 08:23:54 +00:00
VincentFuandGitee b0ed2100a2 update applications/view/admin/dict.py.
修复字典类型更新
2021-10-05 05:53:05 +00:00
mkgandGitee 6f0c86fba6 !18 update applications/view/department/__init__.py.
Merge pull request !18 from VincentFu/N/A
2021-10-04 00:42:32 +00:00
VincentFuandGitee c71562a12f update applications/view/department/__init__.py.
这个地方也需要相应的修改,和power.py一样。
2021-10-03 17:31:39 +00:00
mkg a7fa415545 修改权限管理为post 2021-10-02 23:06:20 +08:00
mkg 24d2523385 更新依赖pearadminlayui 2021-10-02 16:11:07 +08:00
Rabbitandmkg d30a3d79de !17 修改角色状态值
* 角色状态值修复
2021-09-23 02:35:20 +00:00
mkgandGitee 860d5778cc !16 简化分页取count
Merge pull request !16 from Rabbit/master
2021-09-23 02:09:34 +00:00
xz 23dbe9ee9c 简化分页取count 2021-09-23 09:57:13 +08:00
就眠儀式andGitee 9114964ef2 update README.md. 2021-09-21 18:36:34 +00:00
mkgandGitee 56615528b9 !15 新增字典数据405
Merge pull request !15 from yanyuan/master
2021-09-09 09:54:12 +00:00
yanyuanandGitee 1b5c54daf9 update applications/view/admin/dict.py.
新增字典数据有误
2021-09-09 09:50:05 +00:00
Rabbitandmkg c0a3f5243b !14 【轻量级 PR】:update applications/view/admin/user.py.
Merge pull request !14 from Rabbit/N/A
2021-09-09 02:29:22 +00:00
Rabbitandmkg d22eb22f74 !13 【轻量级 PR】:update applications/view/admin/role.py.
Merge pull request !13 from Rabbit/N/A
2021-09-09 02:29:04 +00:00
就眠儀式andGitee 7eeb4c2489 !12 update applications/templates/admin/user/main.html.
Merge pull request !12 from Rabbit/N/A
2021-09-08 14:29:40 +00:00
RabbitandGitee d691c444ae update applications/templates/admin/user/main.html.
312行:table.reload('role-table') -> table.reload('user-table')
2021-09-08 14:27:39 +00:00
mkgandGitee 83c23ea276 !10 update applications/view/admin/power.py.
Merge pull request !10 from Rabbit/N/A
2021-09-06 11:23:43 +00:00
mkgandGitee cff67d152f !11 update applications/view/admin/user.py.
Merge pull request !11 from Rabbit/N/A
2021-09-06 11:23:25 +00:00
mkgandGitee ad67c289d3 !9 update applications/view/admin/role.py.
Merge pull request !9 from Rabbit/N/A
2021-09-06 11:23:05 +00:00
RabbitandGitee 4a4d8f763d update applications/view/admin/user.py.
多对多删除简化
2021-09-06 10:24:05 +00:00
RabbitandGitee dfc734c13a update applications/view/admin/power.py.
多对多关系删除简化
2021-09-06 10:21:51 +00:00
RabbitandGitee 654f441d05 update applications/view/admin/role.py. 2021-09-06 10:19:02 +00:00
mkg 48eebc1c95 定时任务(部分) 2021-08-26 15:31:36 +08:00
mkg 3c1764e58d 图形验证码 2021-08-26 12:12:39 +08:00
mkg 233241c962 优化验证码字符 2021-08-26 12:06:27 +08:00
mkg 30f9774ab1 Merge branch 'master' of https://gitee.com/pear-admin/pear-admin-flask into master 2021-08-25 21:17:33 +08:00
mkg a255c746d4 解决验证码可绕过安全问题 2021-08-25 21:17:16 +08:00
mkgandGitee eac2a1c941 update requirement/requirement-dev.txt. 2021-07-19 13:51:58 +00:00
mkg 110a5faaff 回退依赖版本解决不能上传问题 2021-07-19 21:40:03 +08:00
mkg f3cfdcf580 _id和id混乱导致的role编辑bug 2021-07-19 15:55:32 +08:00
mkg 34a1066cd0 user中_id改为id 2021-07-18 20:16:49 +08:00
mkg 67d05c39f3 修复过滤后count数量 2021-07-18 14:45:07 +08:00
mkg fa49130c4f 更新readme 2021-07-16 17:48:08 +08:00
mkg 5b76973d9c 删除因去除curd层复制错误导致的多余代码 2021-07-16 17:45:09 +08:00
mkg 0d57a2a8f2 更新md 2021-07-16 13:10:01 +08:00
mkg 78b7dae880 增加命令行新建空白视图功能 2021-07-16 13:04:49 +08:00
mkg 04a89144ba 扩充过滤器 2021-07-12 14:38:11 +08:00
mkg 3b3eecc1d1 删除curd层 2021-07-12 13:04:16 +08:00
mkg ca92d949dd 增加layui表格分页器layui_paginate() 2021-07-12 12:13:29 +08:00
mkg 663c7925e3 Merge branch 'master' of https://gitee.com/pear-admin/pear-admin-flask into master 2021-07-12 11:28:34 +08:00
mkg 76b2ad6f58 增加多条件查询构造器,删除部分curd层 2021-07-12 11:28:21 +08:00
mkgandGitee fd8dcfee40 update README.md. 2021-07-07 23:55:21 +00:00
mkg 0a60c1960d 更新layui,修复数据库初始化路径问题 2021-07-07 13:54:37 +08:00
mkg 28021df2ab 更新文档 2021-07-04 17:17:14 +08:00
mkg 6d42b6d56c 更新文档 2021-07-04 17:15:51 +08:00
mkgandGitee 3b467f42fe update requirement/requirement-dev.txt. 2021-07-04 09:01:37 +00:00
mkg e37749c669 Merge branch 'v2' of https://gitee.com/pear-admin/pear-admin-flask into v2 2021-06-24 13:17:45 +08:00
mkg 2cbbf25060 增加定时任务前端(部分) 2021-06-24 13:17:34 +08:00
mkgandGitee 986ae4e4bc update requirement/requirement-dev.txt. 2021-06-17 22:00:40 +08:00
mkg 103aaf4911 增加定时任务 2021-06-17 21:59:28 +08:00
mkgandGitee 7038ce64a6 update requirement/requirement-dev.txt. 2021-06-17 16:54:53 +08:00
mkgandGitee 9b8525ca1e update requirement/requirement-dev.txt. 2021-06-17 13:06:55 +08:00
mkgandGitee 254ce53387 update requirement/requirement-dev.txt. 2021-06-16 15:53:10 +08:00
mkgandGitee 0ff0c456b0 update .env. 2021-06-16 15:44:50 +08:00
mkg 57a54090bb Merge branch 'v2' of https://gitee.com/pear-admin/pear-admin-flask into v2 2021-06-16 15:40:48 +08:00
mkg e3d3424ee1 增加邮箱功能 2021-06-16 15:34:39 +08:00
mkgandGitee 99b2f611ec add .env. 2021-06-13 16:39:01 +08:00
mkgandGitee a675d78b82 !6 解决冲突
Merge pull request !6 from mkg/pr_5
2021-06-13 16:16:43 +08:00
mkg 62bd10cc60 Merge branch 'v2' into pr_5
# Conflicts:
#	applications/view/__init__.py
2021-06-13 16:14:23 +08:00
mkg 14a32e6d3c 增加数据库迁移命令和数据库初始化命令,分离schemas 2021-06-12 23:05:30 +08:00
mkgandGitee 5e08f3e49b !4 调整目录结构
Merge pull request !4 from zhengxinonly/v2
2021-06-12 21:26:24 +08:00
1085 changed files with 117764 additions and 94378 deletions
+29
View File
@@ -0,0 +1,29 @@
# flask配置
FLASK_APP=app.py
FLASK_ENV=development
FLASK_DEBUG=1
FLASK_RUN_HOST = 127.0.0.1
FLASK_RUN_PORT = 5000
# pear admin flask配置
SYSTEM_NAME = Pear Admin
# MySql配置信息
MYSQL_HOST=127.0.0.1
# MYSQL_HOST=dbserver
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-flask'
# 邮箱配置
MAIL_SERVER='smtp.qq.com'
MAIL_USERNAME='123@qq.com'
MAIL_PASSWORD='XXXXX' # 生成的授权码
+25
View File
@@ -0,0 +1,25 @@
FROM python:3.7-alpine
RUN apk update \
&& apk --update add --no-cache gcc \
&& apk --update add --no-cache g++ \
&& apk --update add --no-cache tzdata \
&& apk --update add --no-cache libffi-dev \
&& apk --update add --no-cache libxslt-dev \
&& apk --update add --no-cache jpeg-dev
ENV TIME_ZONE Asia/Shanghai
ENV PIPURL "https://pypi.tuna.tsinghua.edu.cn/simple"
RUN echo "${TIME_ZONE}" > /etc/timezone \
&& ln -sf /usr/share/zoneinfo/${TIME_ZONE} /etc/localtime
COPY . /app
WORKDIR /app
RUN pip --no-cache-dir install -i ${PIPURL} --upgrade pip \
&& pip --no-cache-dir install -i ${PIPURL} -r requirement/requirement-dev.txt \
&& pip --no-cache-dir install -i ${PIPURL} gunicorn \
&& chmod +x start.sh
CMD ./start.sh
+47 -22
View File
@@ -1,7 +1,6 @@
<div align="center">
<br/>
<br/>
<img src="https://gitee.com/pear-admin/Pear-Admin-Layui/raw/master/admin/images/logo.png" width="90px" style="margin-top:30px;"/>
<h1 align="center">
Pear Admin Flask
</h1>
@@ -9,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">
@@ -34,13 +33,27 @@
>
>项目旨在为python开发者提供一个后台管理系统的模板,成为您构建信息管理系统,物联网后台....等等应用时灵活,简单的工具
>
>各位Python爱好者多多指教
>众人拾柴火焰高,欢迎pythoner参与项目~
Pear Admin Flask 分为 Common / Simple 两个版本:
Pear Admin Flask 有以下几个版本:
[** Common 通用版本 **](https://gitee.com/pear-admin/pear-admin-flask/tree/master/)
[master分支版本 ](https://gitee.com/pear-admin/pear-admin-flask/tree/master/)
[** Simple 简洁版本 **](https://gitee.com/pear-admin/pear-admin-flask/tree/simple/)
> flask 2.0.1 + flask-sqlalchemy + mysql + 权限验证 + Flask-APScheduler 定时任务 + marshmallow 序列化与数据验证
[Mini 分支版本 ](https://gitee.com/pear-admin/pear-admin-flask/tree/mini/)
>flask 2.0.1 + flask-sqlalchemy + sqllite + 权限验证 + Flask-RESTful 序列化与数据验证
[v1 分支版本(不再更新,仅供参考) ](https://gitee.com/pear-admin/pear-admin-flask/tree/v1/)
>flask 1.12 + flask-sqlalchemy + mysql + 权限验证 + marshmallow 序列化与数据验证
[simple 分支版本(不再更新,仅供参考) ](https://gitee.com/pear-admin/pear-admin-flask/tree/simple/)
>flask 1.12 + flask-sqlalchemy + mysql + 极简权限 + marshmallow 序列化与数据验证
>
>项目最简版本
#### 内置功能
@@ -51,6 +64,7 @@ Pear Admin Flask 分为 Common / Simple 两个版本:
- [x] 登录日志:系统登录日志记录查询包含登录异常。
- [x] 服务监控:监视当前系统CPU、内存、磁盘、python版本,运行时长等相关信息。
- [x] 文件上传: 图片上传示例
- [x] 定时任务: 简单的定时任务
- [ ] 代码生成: 构想中....
#### 项目结构
@@ -76,8 +90,6 @@ Pear Admin Flask
```
#### 项目安装
```bash
@@ -95,40 +107,53 @@ pip install -r requirement\requirement-dev.txt
#### 修改配置
```python
# 主 机
HOST = '127.0.0.1'
.env
# MySql配置信息
MYSQL_HOST=127.0.0.1
MYSQL_PORT=3306
MYSQL_DATABASE=PearAdminFlask
MYSQL_USERNAME=root
MYSQL_PASSWORD=root
# 端 口
PORT = '3306'
# Redis 配置
REDIS_HOST=127.0.0.1
REDIS_PORT=6379
# 数 据 库
DATABASE = 'PearAdminFlask'
# 账 户
USERNAME = 'root'
# 密 码
PASSWORD = 'root'
# 密钥配置
SECRET_KEY='pear-admin-flask'
# 邮箱配置
MAIL_SERVER='smtp.qq.com'
MAIL_USERNAME='123@qq.com'
MAIL_PASSWORD='XXXXX' # 生成的授权码
```
#### Venv 安装
```bash
python -m venv venv
```
#### 运行项目
```bash
# 初 始 化 数 据 库
python test\init_databases.py
flask init
```
执行 flask run 命令启动项目
#### 命令行创建视图
```bash
# 示例
flask new --type view --name test/a
# 自动注册蓝图
# 访问http://127.0.0.1:5000/test/a/
```
#### 预览项目
+4
View File
@@ -1,6 +1,10 @@
from applications import create_app
from flask_migrate import Migrate
from applications.extensions import db
app = create_app()
migrate = Migrate(app, db)
if __name__ == '__main__':
app.run()
+6 -8
View File
@@ -1,34 +1,32 @@
import os
from flask import Flask
from flask_uploads import configure_uploads
from applications.common.utils.upload import photos
from applications.configs import common
from applications.common.script import init_script
from applications.extensions import init_plugs
from applications.view import init_view
from applications.configs import config
def create_app(config_name=None):
app = Flask(__name__)
app = Flask(os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))
if not config_name:
# 尝试从本地环境中读取
config_name = os.getenv('FLASK_CONFIG', 'development')
# 引入数据库配置
app.config.from_object(common)
app.config.from_object(config[config_name])
# 注册各种插件
init_plugs(app)
# 注册路由
init_view(app)
# 文件上传
configure_uploads(app, photos)
# 注册命令
init_script(app)
if os.environ.get('WERKZEUG_RUN_MAIN') == 'true':
logo()
return app
@@ -1,9 +1,11 @@
import copy
from collections import OrderedDict
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
from applications.schemas import PowerOutSchema
# 授权路由存入session
@@ -22,16 +24,8 @@ def add_auth_session():
# 生成菜单树
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 = []
powers = []
for i in role:
# 如果角色没有被启用就直接跳过
if i.enable == 0:
@@ -41,31 +35,28 @@ def make_menu_tree():
# 如果权限关闭了就直接跳过
if p.enable == 0:
continue
# 一级菜单
if int(p.type) == 0:
power0.append(p)
# 二级菜单
# 一级菜单
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['parent_id'], 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']])
_dict['children'].sort(key=lambda item: item['sort'])
# 删除子节点
del menu_dict[_dict['id']]
if _dict['parent_id'] not in menu_dict:
menu_dict[_dict['parent_id']] = [_dict]
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
menu_dict[_dict['parent_id']].append(_dict)
return sorted(menu_dict.get(0), key=lambda item: item['sort'])
# 生成验证码
@@ -91,25 +82,27 @@ def get_render_config():
}, menu={
# 菜单数据来源
"data": "/rights/menu",
"collaspe": True,
"collaspe": False,
# 是否同时只打开一个菜单目录
"accordion": True,
"method": "GET",
# 是否开启多系统菜单模式
"control": False,
# 顶部菜单宽度 PX
"controlWidth": 500,
# 默认选中的菜单项
"select": "0",
# 是否开启异步菜单,false 时 data 属性设置为菜单数据,false 时为 json 文件或后端接口
"async": True
}, tab={
# 是否开启多选项卡
"muiltTab": True,
"enable": True,
# 切换选项卡时,是否刷新页面状态
"keepState": True,
# 是否开启 Tab 记忆
"session": True,
# 最大可打开的选项卡数量
"tabMax": 30,
"max": 30,
"index": {
# 标识 ID , 建议与菜单项中的 ID 一致
"id": "10",
-87
View File
@@ -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
-145
View File
@@ -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
-36
View File
@@ -1,36 +0,0 @@
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
def upload_one(photo, mime):
filename = photos.save(photo)
file_url = photos.url(filename)
upload_url = current_app.config.get("UPLOADED_PHOTOS_DEST")
size = os.path.getsize(upload_url + '/' + filename)
photo = Photo(name=filename, href=file_url, mime=mime, size=size)
db.session.add(photo)
db.session.commit()
return file_url
def delete_photo_by_id(_id):
photo_name = Photo.query.filter_by(id=_id).first().name
photo = Photo.query.filter_by(id=_id).delete()
db.session.commit()
upload_url = current_app.config.get("UPLOADED_PHOTOS_DEST")
os.remove(upload_url + '/' + photo_name)
return photo
-112
View File
@@ -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)
-149
View File
@@ -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)
-159
View File
@@ -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()
+5 -4
View File
@@ -1,5 +1,6 @@
from flask_login import current_user
from applications.common.utils.validate import xss_escape
from applications.extensions import db
from applications.models import AdminLog
@@ -9,8 +10,8 @@ def login_log(request, uid, is_access):
'method': request.method,
'url': request.path,
'ip': request.remote_addr,
'user_agent': request.headers.get('User-Agent'),
'desc': request.form.get('username'),
'user_agent': xss_escape(request.headers.get('User-Agent')),
'desc': xss_escape(request.form.get('username')),
'uid': uid,
'success': int(is_access)
@@ -35,8 +36,8 @@ def admin_log(request, is_access):
'method': request.method,
'url': request.path,
'ip': request.remote_addr,
'user_agent': request.headers.get('User-Agent'),
'desc': str(dict(request.values)),
'user_agent': xss_escape(request.headers.get('User-Agent')),
'desc': xss_escape(str(dict(request.values))),
'uid': current_user.id,
'success': int(is_access)
+93 -4
View File
@@ -1,5 +1,94 @@
def model_to_dicts(Schema, model):
# 如果是分页器返回,需要传入model.items
common_schema = Schema(many=True) # 用已继承ma.ModelSchema类的自定制类生成序列化类
output = common_schema.dump(model) # 生成可序列化对象
import datetime
from marshmallow import Schema
from marshmallow_sqlalchemy import SQLAlchemyAutoSchema
from applications.extensions import db, ma
class LogicalDeleteMixin(object):
"""
class Test(db.Model,LogicalDeleteMixin):
__tablename__ = 'admin_test'
id = db.Column(db.Integer, primary_key=True, comment='角色ID')
Test.query.filter_by(id=1).soft_delete()
Test.query.logic_all()
"""
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='创建时间')
delete_at = db.Column(db.DateTime, comment='删除时间')
def auto_model_jsonify(data, model: db.Model):
"""
不需要建立schemas,直接使用orm的定义模型进行序列化
基本功能,待完善
示例
power_data = curd.auto_model_jsonify(model=Dept, data=dept)
"""
def get_model():
return model
class AutoSchema(SQLAlchemyAutoSchema):
class Meta(Schema):
model = get_model()
include_fk = True
include_relationships = True
load_instance = True
common_schema = AutoSchema(many=True) # 用已继承ma.ModelSchema类的自定制类生成序列化类
output = common_schema.dump(data)
return output
def model_to_dicts(schema: ma.Schema, data):
"""
:param schema: schema类
:param model: sqlalchemy查询结果
:return: 返回单个查询结果
"""
# 如果是分页器返回,需要传入model.items
common_schema = schema(many=True) # 用已继承ma.ModelSchema类的自定制类生成序列化类
output = common_schema.dump(data) # 生成可序列化对象
return output
def get_one_by_id(model: db.Model, id):
"""
:param model: 模型类
:param id: id
:return: 返回单个查询结果
"""
return model.query.filter_by(id=id).first()
def delete_one_by_id(model: db.Model, id):
"""
:param model: 模型类
:param id: id
:return: 返回单个查询结果
"""
r = model.query.filter_by(id=id).delete()
db.session.commit()
return r
# 启动状态
def enable_status(model: db.Model, id):
enable = 1
role = model.query.filter_by(id=id).update({"enable": enable})
if role:
db.session.commit()
return True
return False
# 停用状态
def disable_status(model: db.Model, id):
enable = 0
role = model.query.filter_by(id=id).update({"enable": enable})
if role:
db.session.commit()
return True
return False
+126
View File
@@ -0,0 +1,126 @@
from sqlalchemy import and_
from applications.extensions import db
class ModelFilter:
"""
orm多参数构造器
"""
filter_field = {}
filter_list = []
type_exact = "exact"
type_neq = "neq"
type_greater = "greater"
type_less = "less"
type_vague = "vague"
type_contains = "contains"
type_between = "between"
def __init__(self):
self.filter_field = {}
self.filter_list = []
def exact(self, field_name, value):
"""
准确查询字段
:param field_name: 模型字段名称
:param value: 值
"""
if value and value != '':
self.filter_field[field_name] = {"data": value, "type": self.type_exact}
def neq(self, field_name, value):
"""
不等于查询字段
:param field_name: 模型字段名称
:param value: 值
"""
if value and value != '':
self.filter_field[field_name] = {"data": value, "type": self.type_neq}
def greater(self, field_name, value):
"""
大于查询字段
:param field_name: 模型字段名称
:param value: 值
"""
if value and value != '':
self.filter_field[field_name] = {"data": value, "type": self.type_greater}
def less(self, field_name, value):
"""
大于查询字段
:param field_name: 模型字段名称
:param value: 值
"""
if value and value != '':
self.filter_field[field_name] = {"data": value, "type": self.type_less}
def vague(self, field_name, value: str):
"""
模糊查询字段
:param field_name: 模型字段名称
:param value: 值
"""
if value and value != '':
self.filter_field[field_name] = {"data": ('%' + value + '%'), "type": self.type_vague}
def left_vague(self, field_name, value: str):
"""
左模糊查询字段
:param field_name: 模型字段名称
:param value: 值
"""
if value and value != '':
self.filter_field[field_name] = {"data": ('%' + value), "type": self.type_vague}
def right_vague(self, field_name, value: str):
"""
左模糊查询字段
:param field_name: 模型字段名称
:param value: 值
"""
if value and value != '':
self.filter_field[field_name] = {"data": (value + '%'), "type": self.type_vague}
def contains(self, field_name, value: str):
"""
包含查询字段
:param field_name: 模型字段名称
:param value: 值
"""
if value and value != '':
self.filter_field[field_name] = {"data": value, "type": self.type_contains}
def between(self, field_name, value1, value2):
"""
范围查询字段
:param field_name: 模型字段名称
:param value: 值
"""
if value1 and value2 and value1 != '' and value2 != '':
self.filter_field[field_name] = {"data": [value1, value2], "type": self.type_between}
def get_filter(self, model: db.Model):
"""
获取过滤条件
:param model: 模型字段名称
"""
for k, v in self.filter_field.items():
if v.get("type") == self.type_vague:
self.filter_list.append(getattr(model, k).like(v.get("data")))
if v.get("type") == self.type_contains:
self.filter_list.append(getattr(model, k).contains(v.get("data")))
if v.get("type") == self.type_exact:
self.filter_list.append(getattr(model, k) == v.get("data"))
if v.get("type") == self.type_neq:
self.filter_list.append(getattr(model, k) != v.get("data"))
if v.get("type") == self.type_greater:
self.filter_list.append(getattr(model, k) > v.get("data"))
if v.get("type") == self.type_less:
self.filter_list.append(getattr(model, k) < v.get("data"))
if v.get("type") == self.type_between:
self.filter_list.append(getattr(model, k).between(v.get("data")[0], v.get("data")[1]))
return and_(*self.filter_list)
+26
View File
@@ -0,0 +1,26 @@
import os
import click
from applications.common.script.initdb import init_db
from applications.common.script.newmodular.new import NewViewModular
def init_script(app):
@app.cli.command()
def init():
init_db()
@app.cli.command()
@click.option('--type', prompt="请输入类型", help='新增的类型')
@click.option('--name', prompt="请输入新增的名称", help='新增的名称')
def new(type,name):
if type == 'view':
if name.count('/') > 1:
print("目前只支持二级目录,多级目录需要蓝图嵌套,本命令暂不支持,请手动创建")
quit()
if type == "view" and os.path.exists(f"applications/view/{name}.py"):
print(f'已经存在视图模块{name}.py')
quit()
NewViewModular(name=name).new_view()
@@ -1,14 +1,9 @@
import sys
from dotenv import dotenv_values
sys.path.append('../')
import sqlparse
import pymysql
config = dotenv_values('.env')
config = dotenv_values('.flaskenv')
# MySql配置信息
HOST = config.get('MYSQL_PASSWORD') or '127.0.0.1'
HOST = config.get('MYSQL_HOST') 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'
@@ -27,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
@@ -56,14 +51,10 @@ def execute_fromfile(filename):
def init_db():
if is_exist_database():
print('数据库已经存在,为防止误初始化,请动删除 %s 数据库' % str(DATABASE))
print('数据库已经存在,为防止误初始化,请动删除 %s 数据库' % str(DATABASE))
return
if init_database():
print('数据库%s创建成功' % str(DATABASE))
execute_fromfile('pear.sql')
execute_fromfile('test/pear.sql')
print('表创建成功')
print('欢迎使用pear-admin-flask,请使用 flask run 命令启动程序')
if __name__ == '__main__':
init_db()
@@ -0,0 +1,92 @@
import os
import jinja2
class NewViewModular():
def __init__(self, name):
self.name = name
def path_is_exists(self):
return os.path.exists(f"applications/view/{self.name.split('/')[0]}")
def new_dirs(self):
if not self.path_is_exists():
# 如果不存在则创建目录
# 创建目录操作函数
os.makedirs(f"applications/view/{self.name.split('/')[0]}")
print(self.name + ' 创建成功')
return True
else:
return False
def add_view(self):
# jinja渲染
templateLoader = jinja2.FileSystemLoader(searchpath='applications/common/script/newmodular/template/')
templateEnv = jinja2.Environment(loader=templateLoader)
TEMPLATE_FILE = "view"
template = templateEnv.get_template(TEMPLATE_FILE, )
templateVars = {"name": self.name}
outputText = template.render(templateVars)
with open(f"applications/view/{self.name}.py", "a", encoding='utf-8') as f:
f.write(outputText)
f.close()
def add_init(self):
# 判断__init__.py
if os.path.exists(f"applications/view/{self.name.split('/')[0]}/__init__.py"):
with open(f"applications/view/{self.name.split('/')[0]}/__init__.py", "r") as file:
lines = file.readlines()
print(lines)
file.close()
import_line_num = 0
for line in lines:
if 'def' in line:
import_line_num = lines.index(line) - 2
with open(f"applications/view/{self.name.split('/')[0]}/__init__.py", "w") as file:
lines.insert(import_line_num,
f"from applications.view.{self.name.replace('/', '.')} import {self.name.replace('/', '_')}\n")
print(lines)
lines.insert(len(lines) - 1, f" app.register_blueprint({self.name.replace('/', '_')})\n")
print(lines)
file.writelines(lines)
file.close()
return True
else:
templateLoader = jinja2.FileSystemLoader(searchpath='applications/common/script/newmodular/template/')
templateEnv = jinja2.Environment(loader=templateLoader)
TEMPLATE_FILE = "__init__"
template = templateEnv.get_template(TEMPLATE_FILE, )
templateVars = {"name": self.name}
output = template.render(templateVars)
with open(f"applications/view/{self.name.split('/')[0]}/__init__.py", "a", encoding='utf-8') as f:
f.write(output)
f.close()
self.add_root_init()
return True
def add_root_init(self):
with open(f"applications/view/__init__.py", "r") as file:
lines = file.readlines()
file.close()
import_line_num = 0
for line in lines:
if 'def' in line:
import_line_num = lines.index(line) - 2
with open(f"applications/view/__init__.py", "w") as file:
lines.insert(
import_line_num,
f"from applications.view.{self.name.split('/')[0]} import register_{self.name.split('/')[0]}_views\n")
print(lines)
lines.insert(len(lines) - 1, f" register_{self.name.split('/')[0]}_views(app)\n")
print(lines)
file.writelines(lines)
file.close()
def new_view(self):
self.new_dirs()
self.add_view()
self.add_init()
@@ -0,0 +1,6 @@
from flask import Flask
from applications.view.{{name.replace('/','.')}} import {{name.replace('/','_')}}
def register_{{name.split('/')[0]}}_views(app: Flask):
app.register_blueprint({{name.replace('/','_')}})
@@ -0,0 +1,8 @@
from flask import Blueprint
{{name.replace('/','_')}} = Blueprint('{{name.replace('/','_')}}', __name__, url_prefix='/{{name}}')
@{{name.replace('/','_')}}.route('/')
def index():
return "这是{{name}}路由"
-17
View File
@@ -1,17 +0,0 @@
#
MYSQL_HOST = '127.0.0.1'
MYSQL_PORT = '3306'
MYSQL_DATABASE = 'PearAdminFlask'
MYSQL_USERNAME = 'root'
MYSQL_PASSWORD = 'root'
MYSQL_DB_URI = "mysql+pymysql://{username}:{password}@{host}:{port}/{db}?charset=utf8".format(username=USERNAME,
password=PASSWORD,
host=HOST,
port=PORT,
db=DATABASE)
SQLALCHEMY_DATABASE_URI = MYSQL_DB_URI
SQLALCHEMY_TRACK_MODIFICATIONS = True
SQLALCHEMY_ECHO = False
SQLALCHEMY_POOL_RECYCLE = 8
+54
View File
@@ -0,0 +1,54 @@
from apscheduler.events import (
EVENT_JOB_ADDED,
EVENT_JOB_ERROR,
EVENT_JOB_EXECUTED,
EVENT_JOB_MISSED,
EVENT_JOB_REMOVED,
EVENT_JOB_SUBMITTED,
)
from applications.extensions.init_apscheduler import scheduler
def job_missed(event):
"""Job missed event."""
with scheduler.app.app_context():
print(event) # noqa: T001
def job_error(event):
"""Job error event."""
with scheduler.app.app_context():
print(event) # noqa: T001
def job_executed(event):
"""Job executed event."""
with scheduler.app.app_context():
print(event) # noqa: T001
def job_added(event):
"""Job added event."""
with scheduler.app.app_context():
print(event) # noqa: T001
def job_removed(event):
"""Job removed event."""
with scheduler.app.app_context():
print(event) # noqa: T001
def job_submitted(event):
"""Job scheduled to run event."""
with scheduler.app.app_context():
print(event) # noqa: T001
scheduler.add_listener(job_missed, EVENT_JOB_MISSED)
scheduler.add_listener(job_error, EVENT_JOB_ERROR)
scheduler.add_listener(job_executed, EVENT_JOB_EXECUTED)
scheduler.add_listener(job_added, EVENT_JOB_ADDED)
scheduler.add_listener(job_removed, EVENT_JOB_REMOVED)
scheduler.add_listener(job_submitted, EVENT_JOB_SUBMITTED)
+15
View File
@@ -0,0 +1,15 @@
import datetime
task_list = ['task2', 'task3', 'task4']
def task2(a, b):
print(f'定时任务_1_{a},{b},{datetime.datetime.now()}')
def task3(a, b):
print(f'定时任务_2_{a}{b}{datetime.datetime.now()}')
def task4(a, b):
print(f'定时任务_4_{a}{b}{datetime.datetime.now()}')
+2 -2
View File
@@ -4,11 +4,11 @@ from PIL import Image
from random import choices
def gen_captcha(content='0123456789'):
def gen_captcha(content='2345689abcdefghijklmnpqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ'):
""" 生成验证码 """
image = ImageCaptcha()
# 获取字符串
captcha_text = "".join(choices(content, k=4))
captcha_text = "".join(choices(content, k=4)).lower()
# 生成图像
captcha_image = Image.open(image.generate(captcha_text))
return captcha_text, captcha_image
+13
View File
@@ -0,0 +1,13 @@
from flask_mail import Message
from applications.extensions.init_mail import mail
# send_mail(subject='title', recipients=['123@qq.com'], content='body')
def send_mail(subject, recipients, content):
try:
message = Message(subject=subject, recipients=recipients, body=content)
mail.send(message)
except Exception as e:
print('邮箱发送出错了')
raise
+34 -2
View File
@@ -1,4 +1,36 @@
from flask_uploads import UploadSet, IMAGES
import os
from flask import current_app
from sqlalchemy import desc
from applications.extensions import db
from applications.extensions.init_upload import photos
from applications.models import Photo
from applications.schemas import PhotoOutSchema
from applications.common.curd import model_to_dicts
photos = UploadSet('photos', IMAGES)
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=PhotoOutSchema, data=photo.items)
return data, count
def upload_one(photo, mime):
filename = photos.save(photo)
file_url = '/_uploads/photos/'+filename
# file_url = photos.url(filename)
upload_url = current_app.config.get("UPLOADED_PHOTOS_DEST")
size = os.path.getsize(upload_url + '/' + filename)
photo = Photo(name=filename, href=file_url, mime=mime, size=size)
db.session.add(photo)
db.session.commit()
return file_url
def delete_photo_by_id(_id):
photo_name = Photo.query.filter_by(id=_id).first().name
photo = Photo.query.filter_by(id=_id).delete()
db.session.commit()
upload_url = current_app.config.get("UPLOADED_PHOTOS_DEST")
os.remove(upload_url + '/' + photo_name)
return photo
-24
View File
@@ -1,24 +0,0 @@
SYSTEM_NAME = "Pear Admin"
# 主题面板的链接列表配置
SYSTEM_PANEL_LINKS = [
{
"icon": "layui-icon layui-icon-auz",
"title": "官方网站",
"href": "http://www.pearadmin.com"
},
{
"icon": "layui-icon layui-icon-auz",
"title": "开发文档",
"href": "http://www.pearadmin.com"
},
{
"icon": "layui-icon layui-icon-auz",
"title": "开源地址",
"href": "https://gitee.com/Jmysy/Pear-Admin-Layui"
}
]
UPLOADED_PHOTOS_DEST = 'static/upload'
UPLOADED_FILES_ALLOW = ['gif', 'jpg']
# JSON配置
JSON_AS_ASCII = False
+39 -3
View File
@@ -1,8 +1,36 @@
import logging
import os
from urllib.parse import quote_plus as urlquote
class BaseConfig:
SYSTEM_NAME = os.getenv('SYSTEM_NAME', 'Pear Admin')
# 主题面板的链接列表配置
SYSTEM_PANEL_LINKS = [
{
"icon": "layui-icon layui-icon-auz",
"title": "官方网站",
"href": "http://www.pearadmin.com"
},
{
"icon": "layui-icon layui-icon-auz",
"title": "开发文档",
"href": "http://www.pearadmin.com"
},
{
"icon": "layui-icon layui-icon-auz",
"title": "开源地址",
"href": "https://gitee.com/Jmysy/Pear-Admin-Layui"
}
]
UPLOADED_PHOTOS_DEST = 'static/upload'
UPLOADED_FILES_ALLOW = ['gif', 'jpg']
# JSON配置
JSON_AS_ASCII = False
SECRET_KEY = os.getenv('SECRET_KEY', 'dev key')
# redis配置
@@ -16,12 +44,20 @@ class BaseConfig:
MYSQL_PORT = int(os.getenv('MYSQL_PORT') or 3306)
MYSQL_DATABASE = os.getenv('MYSQL_DATABASE') or "PearAdminFlask"
UPLOADED_PHOTOS_DEST = '/static'
# mysql 数据库的配置信息
SQLALCHEMY_DATABASE_URI = f"mysql+pymysql://{MYSQL_USERNAME}:{MYSQL_PASSWORD}@{MYSQL_HOST}:{MYSQL_PORT}/{MYSQL_DATABASE}"
SQLALCHEMY_DATABASE_URI = f"mysql+pymysql://{MYSQL_USERNAME}:{urlquote(MYSQL_PASSWORD)}@{MYSQL_HOST}:{MYSQL_PORT}/{MYSQL_DATABASE}?charset=utf8mb4"
# 默认日志等级
LOG_LEVEL = logging.WARN
#
MAIL_SERVER = os.getenv('MAIL_SERVER') or 'smtp.qq.com'
MAIL_USE_TLS = False
MAIL_USE_SSL = True
MAIL_PORT = 465
MAIL_USERNAME = os.getenv('MAIL_USERNAME') or '123@qq.com'
MAIL_PASSWORD = os.getenv('MAIL_PASSWORD') or 'XXXXX' # 生成的授权码
# 默认发件人的邮箱,这里填写和MAIL_USERNAME一致即可
MAIL_DEFAULT_SENDER = ('pear admin', os.getenv('MAIL_USERNAME') or '123@qq.com')
class TestingConfig(BaseConfig):
+8
View File
@@ -5,6 +5,10 @@ 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
from .init_mail import init_mail
from .init_apscheduler import init_scheduler
from .init_upload import init_upload
from .init_dotenv import init_dotenv
def init_plugs(app: Flask) -> None:
@@ -13,3 +17,7 @@ def init_plugs(app: Flask) -> None:
init_databases(app)
init_template_directives(app)
init_error_views(app)
init_mail(app)
init_scheduler(app)
init_upload(app)
init_dotenv()
@@ -0,0 +1,12 @@
from flask import Flask
from flask_apscheduler import APScheduler
scheduler = APScheduler()
def init_scheduler(app: Flask):
scheduler.init_app(app)
with app.app_context():
from applications.common.tasks import tasks
scheduler.start()
from applications.common.tasks import events
+6 -4
View File
@@ -2,11 +2,13 @@ import os
from dotenv import load_dotenv
root_path = os.path.abspath(os.path.dirname(__file__)).split('applications')[0]
dot_env_path = os.path.join(root_path, '.env')
# dot_env_path = os.path.join(root_path, '.env')
flask_env_path = os.path.join(root_path, '.flaskenv')
if os.path.exists(dot_env_path):
load_dotenv(dot_env_path)
if os.path.exists(flask_env_path):
# if os.path.exists(dot_env_path):
# load_dotenv(dot_env_path)
def init_dotenv():
if os.path.exists(flask_env_path):
load_dotenv(flask_env_path)
+20 -1
View File
@@ -1,4 +1,4 @@
from flask import render_template
from flask import render_template, jsonify
def init_error_views(app):
@@ -13,3 +13,22 @@ def init_error_views(app):
@app.errorhandler(500)
def internal_server_error(e):
return render_template('errors/500.html'), 500
# Return validation errors as JSON
@app.errorhandler(422)
@app.errorhandler(400)
def handle_error(err):
headers = err.data.get("headers", None)
messages = err.data.get("messages", ["Invalid request."]).get('json')
print(err.data.get("messages"))
print(messages.items())
msg = ''
for i in messages.items():
msg = str(i[0]) + str(i[1][0])
break
if headers:
return jsonify({"success": False, "msg": msg})
else:
return jsonify({"success": False, "msg": msg})
+8
View File
@@ -0,0 +1,8 @@
from flask import Flask
from flask_mail import Mail
mail = Mail()
def init_mail(app: Flask):
mail.init_app(app)
+42 -3
View File
@@ -1,5 +1,7 @@
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
import datetime
from flask import Flask, request
from flask_sqlalchemy import SQLAlchemy, BaseQuery
from flask_marshmallow import Marshmallow
from marshmallow import fields
from marshmallow.validate import (
@@ -45,7 +47,44 @@ fields.Boolean.default_error_messages = {
"invalid": "不是合法布尔值"
}
db = SQLAlchemy()
class Query(BaseQuery):
def soft_delete(self):
return self.update({"delete_at": datetime.datetime.now()})
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):
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()
+9
View File
@@ -0,0 +1,9 @@
from flask import Flask
from flask_uploads import configure_uploads
from flask_uploads import UploadSet, IMAGES
photos = UploadSet('photos', IMAGES)
def init_upload(app: Flask):
configure_uploads(app, photos)
+9
View File
@@ -0,0 +1,9 @@
from marshmallow import EXCLUDE
from webargs.flaskparser import FlaskParser
class Parser(FlaskParser):
DEFAULT_UNKNOWN_BY_LOCATION = {"query": EXCLUDE}
parser = Parser()
+7 -7
View File
@@ -1,9 +1,9 @@
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_dept import Dept
from .admin_dict import DictType, DictData
from .admin_log import AdminLog
from .admin_photo import Photo
from .admin_power import Power
from .admin_role import Role
from .admin_role_power import role_power
from .admin_user import User, UserSchema
from .admin_user import User
from .admin_user_role import user_role
+1 -14
View File
@@ -1,6 +1,5 @@
import datetime
from applications.extensions import db, ma
from marshmallow import fields, validate
from applications.extensions import db
class Dept(db.Model):
@@ -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()
+1 -22
View File
@@ -1,7 +1,5 @@
import datetime
from applications.extensions import db, ma
from marshmallow import fields
from applications.extensions import db
class DictType(db.Model):
@@ -26,22 +24,3 @@ class DictData(db.Model):
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()
+1 -15
View File
@@ -1,7 +1,5 @@
import datetime
from applications.extensions import db, ma
from marshmallow import fields
from applications.extensions import db
class AdminLog(db.Model):
__tablename__ = 'admin_admin_log'
@@ -14,15 +12,3 @@ class AdminLog(db.Model):
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()
+1 -13
View File
@@ -1,7 +1,5 @@
import datetime
from applications.extensions import db, ma
from marshmallow import fields
from applications.extensions import db
class Photo(db.Model):
@@ -12,13 +10,3 @@ class Photo(db.Model):
mime = db.Column(db.CHAR(50), nullable=False)
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()
+1 -32
View File
@@ -1,6 +1,5 @@
import datetime
from applications.extensions import db, ma
from marshmallow import fields
from applications.extensions import db
class Power(db.Model):
@@ -17,33 +16,3 @@ class Power(db.Model):
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()
+1 -14
View File
@@ -1,6 +1,5 @@
import datetime
from applications.extensions import db, ma
from marshmallow import fields
from applications.extensions import db
class Role(db.Model):
@@ -15,15 +14,3 @@ class Role(db.Model):
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()
+1 -20
View File
@@ -1,9 +1,7 @@
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):
@@ -25,20 +23,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
+7
View File
@@ -0,0 +1,7 @@
from .admin_user import UserOutSchema
from .admin_role import RoleOutSchema
from .admin_power import PowerOutSchema, PowerOutSchema2
from .admin_dict import DictDataOutSchema, DictTypeOutSchema
from .admin_dept import DeptOutSchema
from .admin_log import LogOutSchema
from .admin_photo import PhotoOutSchema
+25
View File
@@ -0,0 +1,25 @@
from applications.extensions import ma
from marshmallow import fields, validate
class DeptInSchema(ma.Schema):
parentId = fields.Integer(required=True)
deptName = fields.Str(required=True)
leader = fields.Str(required=True)
phone = fields.Str(required=True)
email = fields.Str(validate=validate.Email())
address = fields.Str()
status = fields.Str(validate=validate.OneOf(["0", "1"]))
sort = fields.Integer()
class DeptOutSchema(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()
+21
View File
@@ -0,0 +1,21 @@
from applications.extensions import ma
from marshmallow import fields
class DictTypeOutSchema(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 DictDataOutSchema(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()
+14
View File
@@ -0,0 +1,14 @@
from applications.extensions import ma
from marshmallow import fields
class LogOutSchema(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()
+12
View File
@@ -0,0 +1,12 @@
from applications.extensions import ma
from marshmallow import fields
class PhotoOutSchema(ma.Schema):
id = fields.Integer()
name = fields.Str()
href = fields.Str()
mime = fields.Str()
size = fields.Str()
ext = fields.Str()
create_time = fields.DateTime()
+32
View File
@@ -0,0 +1,32 @@
from applications.extensions import ma
from marshmallow import fields
# 权限models序列化类
class PowerOutSchema(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 PowerOutSchema2(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()
+14
View File
@@ -0,0 +1,14 @@
from applications.extensions import ma
from marshmallow import fields
class RoleOutSchema(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()
+20
View File
@@ -0,0 +1,20 @@
from applications.extensions import ma
from marshmallow import fields
from applications.models import Dept
# 用户models的序列化类
class UserOutSchema(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
@@ -1,18 +0,0 @@
.pear-container {background-color: whitesmoke;margin: 10px;}
.pear-card {width: 100%;height: 66px;background-color: #F8F8F8;display: inline-block;border-radius: 5px;text-align: center;margin-bottom: 3px;}
.pear-card:hover,.pear-card2:hover{box-shadow: 2px 0 8px 0 lightgray!important;}.pear-card2 {width: 100%;height: 90px;background-color: #F8F8F8;display: inline-block;border-radius: 5px;text-align: center;margin-bottom: 3px;}
.pear-card2 i {font-size: 30px;height: 90px;line-height: 90px;}
.pear-card i {font-size: 30px;height: 66px;line-height: 66px;}
.layui-col-md3 {text-align: center;}
.pear-card-title {margin-top: 3px;}
.person img {width: 90px;height: 90px;border-radius: 4px;margin-top: 8px;margin-left: 8px;}
.pear-card2 .count {color: #51A351;font-size: 30px;margin-top: 12px;}
.pear-card2 .title {color: gray;font-size: 14px;margin-top: 14px;}
.pear-card-status {padding: 0 10px 10px;}
.pear-card-status li {position: relative;padding: 10px 0;border-bottom: 1px solid #EEE;}
.pear-card-status li h3 {padding-bottom: 5px;font-weight: 700;}
.pear-card-status li p {padding-bottom: 10px;padding-top: 3px ;}
.pear-card-status li>span {color: #999;}
.pear-reply {position: absolute;right: 20px;}
.person .title{font-size: 17px;font-weight: 600;margin-left: 18px;margin-top: 16px;position: absolute;display: inline-block;}
.person .desc{font-size: 16px;font-weight: 600;margin-left: 115px;margin-top: -30px;position: absolute;display: inline-block;}
@@ -1,56 +0,0 @@
{
"code": 0,
"msg": "...",
"count": 3,
"data": [{
"id": "1",
"image": "https://gw.alipayobjects.com/zos/rmsportal/gLaIAoVWTtLbBWZNYEMg.png",
"title": "Alipay",
"remark": "那是一种内在的东西, 他们到达不了,也无法触及的",
"time": "几秒前"
},{
"id": "2",
"image": "https://gw.alipayobjects.com/zos/rmsportal/iXjVmWVHbCJAyqvDxdtx.png",
"title": "Layui",
"remark": "生命就像一盒巧克力,结果往往出人意料",
"time": "几秒前"
},{
"id": "1",
"image": "https://gw.alipayobjects.com/zos/rmsportal/iZBVOIhGJiAnhplqjvZW.png",
"title": "Angular",
"remark": "希望是一个好东西,也许是最好的,好东西是不会消亡的",
"time": "几秒前"
},
{
"id": "1",
"image": "https://gw.alipayobjects.com/zos/rmsportal/uMfMFlvUuceEyPpotzlq.png",
"title": "React",
"remark": "那是一种内在的东西, 他们到达不了,也无法触及的",
"time": "几秒前"
},{
"id": "1",
"image": "https://gw.alipayobjects.com/zos/rmsportal/gLaIAoVWTtLbBWZNYEMg.png",
"title": "Alipay",
"remark": "那是一种内在的东西, 他们到达不了,也无法触及的",
"time": "几秒前"
},{
"id": "2",
"image": "https://gw.alipayobjects.com/zos/rmsportal/iXjVmWVHbCJAyqvDxdtx.png",
"title": "Layui",
"remark": "生命就像一盒巧克力,结果往往出人意料",
"time": "几秒前"
},{
"id": "1",
"image": "https://gw.alipayobjects.com/zos/rmsportal/iZBVOIhGJiAnhplqjvZW.png",
"title": "Angular",
"remark": "希望是一个好东西,也许是最好的,好东西是不会消亡的",
"time": "几秒前"
},
{
"id": "1",
"image": "https://gw.alipayobjects.com/zos/rmsportal/uMfMFlvUuceEyPpotzlq.png",
"title": "React",
"remark": "那是一种内在的东西, 他们到达不了,也无法触及的",
"time": "几秒前"
}]
}
@@ -1,88 +0,0 @@
[{
"id": 1,
"title": "私信",
"children": [{
"id": 11,
"avatar":"admin/images/avatar.jpg",
"title": "收到一条私人消息",
"context": "这是消息内容。",
"form": "就眠仪式",
"time": "2019-02-15"
}, {
"id": 12,
"avatar":"admin/images/avatar.jpg",
"title": "收到一条私人消息",
"context": "这是消息内容。",
"form": "就眠仪式",
"time": "2019-02-15"
}]
},
{
"id": 2,
"title": "消息",
"children": [{
"id": 11,
"avatar":"admin/images/avatar.jpg",
"title": "收到一条紧急任务",
"context": "这是消息内容。",
"form": "就眠仪式",
"time": "2019-02-15"
}, {
"id": 12,
"avatar":"admin/images/avatar.jpg",
"title": "收到一条紧急任务",
"context": "这是消息内容。",
"form": "就眠仪式",
"time": "2019-02-15"
},
{
"id": 11,
"avatar":"admin/images/avatar.jpg",
"title": "收到一条紧急任务",
"context": "这是消息内容。",
"form": "就眠仪式",
"time": "2019-02-15"
}, {
"id": 12,
"avatar":"admin/images/avatar.jpg",
"title": "收到一条紧急任务",
"context": "这是消息内容。",
"form": "就眠仪式",
"time": "2019-02-15"
},
{
"id": 11,
"avatar":"admin/images/avatar.jpg",
"title": "收到一条紧急任务",
"context": "这是消息内容。",
"form": "就眠仪式",
"time": "2019-02-15"
}, {
"id": 12,
"avatar":"admin/images/avatar.jpg",
"title": "收到一条紧急任务",
"context": "这是消息内容。",
"form": "就眠仪式",
"time": "2019-02-15"
}]
},
{
"id": 3,
"title": "通知",
"children": [{
"id": 11,
"avatar":"admin/images/avatar.jpg",
"title": "收到一条警告通知",
"context": "这是消息内容。",
"form": "就眠仪式",
"time": "2019-02-15"
}, {
"id": 12,
"avatar":"admin/images/avatar.jpg",
"title": "收到一条警告通知",
"context": "这是消息内容。",
"form": "就眠仪式",
"time": "2019-02-15"
}]
}
]
@@ -1 +0,0 @@
{"createTime":null,"createBy":null,"updateTime":null,"updateBy":null,"remark":null,"code":0,"msg":"...","count":3,"data":[{"createTime":null,"createBy":null,"updateTime":null,"updateBy":null,"remark":null,"roleId":"1","roleName":"超级管理员","roleCode":"admin","enable":"1","details":"超级管理员","checked":false},{"createTime":null,"createBy":null,"updateTime":null,"updateBy":null,"remark":null,"roleId":"2","roleName":"普通管理员","roleCode":"manager","enable":"0","details":"普通管理员","checked":false},{"createTime":null,"createBy":null,"updateTime":null,"updateBy":null,"remark":null,"roleId":"3","roleName":"普通用户","roleCode":"pearson","enable":"0","details":"普通用户","checked":false}]}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 299 KiB

File diff suppressed because one or more lines are too long
@@ -1,3 +0,0 @@
.layui-iconpicker .layui-anim{
width: 300px!important;
}
@@ -1,42 +0,0 @@
.pear-notice .layui-this {
color: #5FB878 !important;
font-weight: 500;
}
.pear-notice li {
border-right: 1px solid whitesmoke;
}
.pear-notice * {
color: dimgray !important;
}
.pear-notice{
width: 285px!important;
}
.pear-notice span{
margin-left: 20px;
font-size: 13px;
}
.pear-notice img{
margin-left: 8px;
width: 33px!important;
height: 33px!important;
border-radius: 50px;
}
.pear-notice-item{
height: 45px!important;
line-height: 45px!important;
}
/** 滚动条样式 */
.pear-notice *::-webkit-scrollbar{width:0px;height:0px;}
.pear-notice *::-webkit-scrollbar-track{background: white;border-radius:2px;}
.pear-notice *::-webkit-scrollbar-thumb{background: #E6E6E6;border-radius:2px;}
.pear-notice *::-webkit-scrollbar-thumb:hover{background: #E6E6E6;}
.pear-notice *::-webkit-scrollbar-corner{background: #f6f6f6;}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,356 +0,0 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
<!--
2013-9-30: Created.
-->
<svg>
<metadata>
Created by iconfont
</metadata>
<defs>
<font id="pear-icon" horiz-adv-x="1024" >
<font-face
font-family="pear-icon"
font-weight="500"
font-stretch="normal"
units-per-em="1024"
ascent="896"
descent="-128"
/>
<missing-glyph />
<glyph glyph-name="jiazai" unicode="&#59072;" d="M512-96c-64.78 0-127.65 12.7-186.85 37.74-57.16 24.18-108.49 58.78-152.56 102.85-44.07 44.07-78.68 95.4-102.85 152.56C44.7 256.35 32 319.22 32 384s12.7 127.65 37.74 186.85c24.18 57.16 58.78 108.49 102.85 152.56s95.4 78.68 152.56 102.85C384.35 851.3 447.22 864 512 864c19.89 0 36.01-16.12 36.01-36.01s-16.12-36.01-36.01-36.01c-55.09 0-108.52-10.78-158.79-32.05-48.58-20.55-92.21-49.97-129.69-87.45s-66.9-81.11-87.45-129.69c-21.26-50.27-32.05-103.7-32.05-158.79s10.78-108.52 32.05-158.79c20.55-48.58 49.97-92.21 87.45-129.69s81.11-66.9 129.69-87.45c50.27-21.26 103.7-32.05 158.79-32.05s108.52 10.78 158.79 32.05c48.58 20.55 92.21 49.97 129.69 87.45s66.9 81.11 87.45 129.69c21.26 50.27 32.05 103.7 32.05 158.79 0 44.18-7.01 87.61-20.83 129.09-6.29 18.87 3.91 39.26 22.78 45.55 18.87 6.29 39.26-3.91 45.55-22.78C983.75 487.02 992 435.93 992 384c0-64.78-12.7-127.65-37.74-186.85-24.18-57.16-58.78-108.49-102.85-152.56-44.07-44.07-95.4-78.68-152.56-102.85C639.65-83.3 576.78-96 512-96z" horiz-adv-x="1024" />
<glyph glyph-name="3column" unicode="&#59004;" d="M874.666667 778.666667H149.333333C108.8 778.666667 74.666667 744.533333 74.666667 704v-640c0-40.533333 34.133333-74.666667 74.666666-74.666667h725.333334c40.533333 0 74.666667 34.133333 74.666666 74.666667V704c0 40.533333-34.133333 74.666667-74.666666 74.666667z m-245.333334-64v-661.333334h-234.666666v661.333334h234.666666zM138.666667 64V704c0 6.4 4.266667 10.666667 10.666666 10.666667h181.333334v-661.333334H149.333333c-6.4 0-10.666667 4.266667-10.666666 10.666667z m746.666666 0c0-6.4-4.266667-10.666667-10.666666-10.666667h-181.333334v661.333334H874.666667c6.4 0 10.666667-4.266667 10.666666-10.666667v-640z" horiz-adv-x="1024" />
<glyph glyph-name="column-4" unicode="&#59005;" d="M874.666667 778.666667H149.333333C108.8 778.666667 74.666667 744.533333 74.666667 704v-640c0-40.533333 34.133333-74.666667 74.666666-74.666667h725.333334c40.533333 0 74.666667 34.133333 74.666666 74.666667V704c0 40.533333-34.133333 74.666667-74.666666 74.666667z m-330.666667-64h128v-661.333334h-128v661.333334z m-64-661.333334h-128v661.333334h128v-661.333334z m-341.333333 10.666667V704c0 6.4 4.266667 10.666667 10.666666 10.666667h138.666667v-661.333334H149.333333c-6.4 0-10.666667 4.266667-10.666666 10.666667z m746.666666 0c0-6.4-4.266667-10.666667-10.666666-10.666667h-138.666667v661.333334H874.666667c6.4 0 10.666667-4.266667 10.666666-10.666667v-640z" horiz-adv-x="1024" />
<glyph glyph-name="add" unicode="&#59006;" d="M853.333333 416H544V725.333333c0 17.066667-14.933333 32-32 32s-32-14.933333-32-32v-309.333333H170.666667c-17.066667 0-32-14.933333-32-32s14.933333-32 32-32h309.333333V42.666667c0-17.066667 14.933333-32 32-32s32 14.933333 32 32V352H853.333333c17.066667 0 32 14.933333 32 32s-14.933333 32-32 32z" horiz-adv-x="1024" />
<glyph glyph-name="adjust" unicode="&#59007;" d="M522.666667 437.333333c-17.066667 0-32-14.933333-32-32v-362.666666c0-17.066667 14.933333-32 32-32S554.666667 25.6 554.666667 42.666667V405.333333c0 17.066667-14.933333 32-32 32zM341.333333 341.333333H106.666667c-17.066667 0-32-14.933333-32-32S89.6 277.333333 106.666667 277.333333h74.666666v-234.666666c0-17.066667 14.933333-32 32-32s32 14.933333 32 32V277.333333H341.333333c17.066667 0 32 14.933333 32 32S358.4 341.333333 341.333333 341.333333zM693.333333 522.666667c0 17.066667-14.933333 32-32 32h-106.666666V725.333333c0 17.066667-14.933333 32-32 32S490.666667 742.4 490.666667 725.333333v-170.666666h-106.666667c-17.066667 0-32-14.933333-32-32S366.933333 490.666667 384 490.666667h277.333333c17.066667 0 32 14.933333 32 32zM917.333333 277.333333H682.666667c-17.066667 0-32-14.933333-32-32S665.6 213.333333 682.666667 213.333333h96v-170.666666c0-17.066667 14.933333-32 32-32s32 14.933333 32 32v170.666666H917.333333c17.066667 0 32 14.933333 32 32S934.4 277.333333 917.333333 277.333333zM213.333333 437.333333c17.066667 0 32 14.933333 32 32V725.333333c0 17.066667-14.933333 32-32 32S181.333333 742.4 181.333333 725.333333v-256c0-17.066667 14.933333-32 32-32zM810.666667 373.333333c17.066667 0 32 14.933333 32 32V725.333333c0 17.066667-14.933333 32-32 32s-32-14.933333-32-32v-320c0-17.066667 14.933333-32 32-32z" horiz-adv-x="1024" />
<glyph glyph-name="ashbin" unicode="&#59008;" d="M874.666667 654.933333h-202.666667V725.333333c0 40.533333-34.133333 74.666667-74.666667 74.666667h-170.666666c-40.533333 0-74.666667-34.133333-74.666667-74.666667v-70.4H149.333333c-17.066667 0-32-14.933333-32-32s14.933333-32 32-32h53.333334V42.666667c0-40.533333 34.133333-74.666667 74.666666-74.666667h469.333334c40.533333 0 74.666667 34.133333 74.666666 74.666667V590.933333H874.666667c17.066667 0 32 14.933333 32 32s-14.933333 32-32 32zM416 725.333333c0 6.4 4.266667 10.666667 10.666667 10.666667h170.666666c6.4 0 10.666667-4.266667 10.666667-10.666667v-70.4h-192V725.333333z m341.333333-682.666666c0-6.4-4.266667-10.666667-10.666666-10.666667H277.333333c-6.4 0-10.666667 4.266667-10.666666 10.666667V586.666667h490.666666V42.666667zM426.666667 160c17.066667 0 32 14.933333 32 32V405.333333c0 17.066667-14.933333 32-32 32s-32-14.933333-32-32v-213.333333c0-17.066667 14.933333-32 32-32zM597.333333 160c17.066667 0 32 14.933333 32 32V405.333333c0 17.066667-14.933333 32-32 32s-32-14.933333-32-32v-213.333333c0-17.066667 14.933333-32 32-32z" horiz-adv-x="1024" />
<glyph glyph-name="browse" unicode="&#59009;" d="M512 59.733333C230.4 59.733333 74.666667 362.666667 68.266667 375.466667c-4.266667 8.533333-4.266667 19.2 0 29.866666 6.4 12.8 164.266667 315.733333 443.733333 315.733334 281.6 0 437.333333-305.066667 443.733333-317.866667 4.266667-8.533333 4.266667-19.2 0-29.866667-6.4-10.666667-162.133333-313.6-443.733333-313.6zM132.266667 390.4c34.133333-57.6 170.666667-266.666667 379.733333-266.666667s345.6 209.066667 379.733333 266.666667c-34.133333 57.6-170.666667 266.666667-379.733333 266.666667S166.4 448 132.266667 390.4zM512 245.333333c-76.8 0-138.666667 61.866667-138.666667 138.666667s61.866667 138.666667 138.666667 138.666667 138.666667-61.866667 138.666667-138.666667-61.866667-138.666667-138.666667-138.666667z m0 213.333334c-40.533333 0-74.666667-34.133333-74.666667-74.666667s34.133333-74.666667 74.666667-74.666667 74.666667 34.133333 74.666667 74.666667-34.133333 74.666667-74.666667 74.666667z" horiz-adv-x="1024" />
<glyph glyph-name="bottom" unicode="&#59010;" d="M896 32H128c-17.066667 0-32-14.933333-32-32s14.933333-32 32-32h768c17.066667 0 32 14.933333 32 32s-14.933333 32-32 32zM488.533333 168.533333c6.4-6.4 14.933333-8.533333 23.466667-8.533333s17.066667 2.133333 23.466667 8.533333l213.333333 213.333334c12.8 12.8 12.8 32 0 44.8-12.8 12.8-32 12.8-44.8 0l-157.866667-157.866667V725.333333c0 17.066667-14.933333 32-32 32s-34.133333-14.933333-34.133333-32v-456.533333L322.133333 426.666667c-12.8 12.8-32 12.8-44.8 0-12.8-12.8-12.8-32 0-44.8l211.2-213.333334z" horiz-adv-x="1024" />
<glyph glyph-name="back" unicode="&#59011;" d="M853.333333 650.666667H245.333333l93.866667 93.866666c12.8 12.8 12.8 34.133333 0 46.933334-12.8 12.8-34.133333 12.8-46.933333 0l-145.066667-145.066667c-12.8-12.8-12.8-34.133333 0-46.933333l145.066667-145.066667c6.4-6.4 14.933333-10.666667 23.466666-10.666667s17.066667 4.266667 23.466667 10.666667c12.8 12.8 12.8 34.133333 0 46.933333L256 584.533333h597.333333c6.4 0 10.666667-4.266667 10.666667-10.666666v-426.666667c0-6.4-4.266667-10.666667-10.666667-10.666667H170.666667c-17.066667 0-32-14.933333-32-32s14.933333-32 32-32h682.666666c40.533333 0 74.666667 34.133333 74.666667 74.666667V576c0 40.533333-34.133333 74.666667-74.666667 74.666667z" horiz-adv-x="1024" />
<glyph glyph-name="bad" unicode="&#59012;" d="M904.533333 373.333333L853.333333 710.4c-8.533333 51.2-55.466667 89.6-106.666666 89.6H204.8c-59.733333 0-108.8-46.933333-108.8-106.666667v-258.133333c0-57.6 49.066667-106.666667 108.8-106.666667h91.733333l125.866667-281.6c2.133333-2.133333 2.133333-4.266667 4.266667-6.4 14.933333-23.466667 38.4-36.266667 64-36.266666 12.8 0 25.6 4.266667 38.4 10.666666 57.6 34.133333 87.466667 72.533333 87.466666 117.333334v117.333333h183.466667c32 0 59.733333 12.8 81.066667 36.266667 19.2 25.6 29.866667 55.466667 23.466666 87.466666z m-616.533333 21.333334H204.8c-25.6 0-44.8 19.2-44.8 42.666666v256c0 23.466667 19.2 42.666667 44.8 42.666667h83.2v-341.333333zM832 328.533333c-8.533333-8.533333-21.333333-14.933333-34.133333-14.933333h-213.333334c-17.066667 0-32-14.933333-32-32v-149.333333c0-25.6-29.866667-49.066667-55.466666-64-4.266667-2.133333-10.666667-2.133333-14.933334 4.266666L352 362.666667V736H746.666667c21.333333 0 40.533333-14.933333 42.666666-36.266667L842.666667 362.666667c2.133333-10.666667-2.133333-23.466667-10.666667-34.133334z" horiz-adv-x="1024" />
<glyph glyph-name="arrow-double-left" unicode="&#59013;" d="M842.666667 32c-8.533333 0-14.933333 2.133333-21.333334 8.533333l-341.333333 309.333334c-6.4 6.4-10.666667 14.933333-10.666667 23.466666 0 8.533333 4.266667 17.066667 10.666667 23.466667l341.333333 309.333333c12.8 12.8 34.133333 10.666667 44.8-2.133333 12.8-12.8 10.666667-34.133333-2.133333-44.8L548.266667 373.333333l315.733333-285.866666c12.8-10.666667 14.933333-32 2.133333-44.8-6.4-6.4-14.933333-10.666667-23.466666-10.666667zM512 32c-8.533333 0-14.933333 2.133333-21.333333 8.533333L149.333333 349.866667c-6.4 6.4-10.666667 14.933333-10.666666 23.466666 0 8.533333 4.266667 17.066667 10.666666 23.466667L490.666667 706.133333c12.8 12.8 34.133333 10.666667 44.8-2.133333 12.8-12.8 10.666667-34.133333-2.133334-44.8L217.6 373.333333 533.333333 87.466667c12.8-12.8 14.933333-32 2.133334-44.8-6.4-6.4-14.933333-10.666667-23.466667-10.666667z" horiz-adv-x="1024" />
<glyph glyph-name="arrow-double-right" unicode="&#59014;" d="M544 373.333333c0 8.533333-4.266667 17.066667-10.666667 23.466667L192 706.133333c-12.8 12.8-34.133333 10.666667-44.8-2.133333-12.8-12.8-10.666667-34.133333 2.133333-44.8l315.733334-285.866667L149.333333 87.466667c-12.8-12.8-14.933333-32-2.133333-44.8 6.4-6.4 14.933333-10.666667 23.466667-10.666667 8.533333 0 14.933333 2.133333 21.333333 8.533333l341.333333 309.333334c6.4 6.4 10.666667 14.933333 10.666667 23.466666zM864 396.8l-341.333333 309.333333c-12.8 12.8-34.133333 10.666667-44.8-2.133333-12.8-12.8-10.666667-34.133333 2.133333-44.8l315.733333-285.866667-315.733333-285.866666c-12.8-12.8-14.933333-32-2.133333-44.8 6.4-6.4 14.933333-10.666667 23.466666-10.666667 8.533333 0 14.933333 2.133333 21.333334 8.533333l341.333333 309.333334c6.4 6.4 10.666667 14.933333 10.666667 23.466666 0 8.533333-4.266667 17.066667-10.666667 23.466667z" horiz-adv-x="1024" />
<glyph glyph-name="camera" unicode="&#59015;" d="M846.933333 657.066667h-140.8L646.4 746.666667c-6.4 10.666667-17.066667 17.066667-29.866667 17.066666h-209.066666c-12.8 0-23.466667-6.4-29.866667-17.066666l-59.733333-89.6H177.066667c-57.6 0-106.666667-46.933333-106.666667-106.666667v-426.666667c0-57.6 46.933333-106.666667 106.666667-106.666666h672c57.6 0 106.666667 46.933333 106.666666 106.666666v426.666667c-2.133333 59.733333-49.066667 106.666667-108.8 106.666667z m34.133334-533.333334c0-19.2-14.933333-34.133333-34.133334-34.133333H177.066667c-19.2 0-34.133333 14.933333-34.133334 34.133333v426.666667c0 19.2 14.933333 34.133333 34.133334 34.133333h160c12.8 0 23.466667 6.4 29.866666 17.066667L426.666667 689.066667h170.666666l59.733334-89.6c6.4-10.666667 17.066667-17.066667 29.866666-17.066667h160c19.2 0 34.133333-14.933333 34.133334-34.133333v-424.533334zM512 531.2c-96 0-174.933333-78.933333-174.933333-174.933333 0-96 78.933333-174.933333 174.933333-174.933334 96 0 174.933333 78.933333 174.933333 174.933334 0 96-78.933333 174.933333-174.933333 174.933333z m0-279.466667c-57.6 0-104.533333 46.933333-104.533333 104.533334s46.933333 104.533333 104.533333 104.533333 104.533333-46.933333 104.533333-104.533333-46.933333-104.533333-104.533333-104.533334z" horiz-adv-x="1024" />
<glyph glyph-name="chart-bar" unicode="&#59016;" d="M149.333333 96h128c29.866667 0 53.333333 23.466667 53.333334 53.333333V362.666667c0 29.866667-23.466667 53.333333-53.333334 53.333333H149.333333c-29.866667 0-53.333333-23.466667-53.333333-53.333333v-213.333334c0-29.866667 23.466667-53.333333 53.333333-53.333333z m10.666667 256h106.666667v-192h-106.666667v192zM448 96h128c29.866667 0 53.333333 23.466667 53.333333 53.333333V746.666667c0 29.866667-23.466667 53.333333-53.333333 53.333333h-128c-29.866667 0-53.333333-23.466667-53.333333-53.333333v-597.333334c0-29.866667 23.466667-53.333333 53.333333-53.333333z m10.666667 640h106.666666v-576h-106.666666v576zM874.666667 586.666667h-128c-29.866667 0-53.333333-23.466667-53.333334-53.333334v-384c0-29.866667 23.466667-53.333333 53.333334-53.333333h128c29.866667 0 53.333333 23.466667 53.333333 53.333333V533.333333c0 29.866667-23.466667 53.333333-53.333333 53.333334z m-10.666667-426.666667h-106.666667v362.666667h106.666667v-362.666667zM896 42.666667H128c-17.066667 0-32-14.933333-32-32S110.933333-21.333333 128-21.333333h768c17.066667 0 32 14.933333 32 32S913.066667 42.666667 896 42.666667z" horiz-adv-x="1024" />
<glyph glyph-name="attachment" unicode="&#59017;" d="M874.666667 428.8c-10.666667 10.666667-29.866667 12.8-42.666667 0l-343.466667-341.333333c-74.666667-74.666667-198.4-74.666667-275.2 0-36.266667 36.266667-57.6 85.333333-57.6 136.533333s19.2 100.266667 57.6 136.533333L556.8 704c46.933333 46.933333 121.6 46.933333 168.533333 0 23.466667-23.466667 34.133333-53.333333 34.133334-83.2 0-32-12.8-61.866667-34.133334-83.2L384 192c-17.066667-17.066667-44.8-17.066667-64 0-8.533333 8.533333-12.8 19.2-12.8 32s4.266667 23.466667 12.8 32l317.866667 315.733333c10.666667 10.666667 12.8 29.866667 0 42.666667-10.666667 12.8-29.866667 12.8-42.666667 0L277.333333 298.666667c-19.2-19.2-29.866667-46.933333-29.866666-74.666667S258.133333 170.666667 277.333333 149.333333c40.533333-40.533333 106.666667-40.533333 147.2 0L768 492.8c34.133333 34.133333 53.333333 78.933333 53.333333 125.866667s-19.2 93.866667-53.333333 125.866666a178.986667 178.986667 0 0 1-253.866667 0l-341.333333-341.333333c-46.933333-46.933333-74.666667-110.933333-74.666667-179.2s25.6-132.266667 74.666667-179.2c49.066667-49.066667 115.2-74.666667 179.2-74.666667s130.133333 25.6 179.2 74.666667l343.466667 341.333333c10.666667 12.8 10.666667 32 0 42.666667z" horiz-adv-x="1024" />
<glyph glyph-name="code" unicode="&#59018;" d="M322.133333 599.466667c-12.8 12.8-32 12.8-44.8 0l-192-192c-12.8-12.8-12.8-32 0-44.8l192-192c6.4-6.4 14.933333-8.533333 23.466667-8.533334s17.066667 2.133333 23.466667 8.533334c12.8 12.8 12.8 32 0 44.8L151.466667 384l168.533333 168.533333c12.8 12.8 12.8 34.133333 2.133333 46.933334zM940.8 407.466667l-192 192c-12.8 12.8-32 12.8-44.8 0-12.8-12.8-12.8-32 0-44.8l168.533333-168.533334-168.533333-168.533333c-12.8-12.8-12.8-32 0-44.8 6.4-6.4 14.933333-8.533333 23.466667-8.533333s17.066667 2.133333 23.466666 8.533333l192 192c8.533333 8.533333 8.533333 29.866667-2.133333 42.666667zM622.933333 819.2c-17.066667 4.266667-34.133333-6.4-38.4-23.466667L366.933333-6.4c-4.266667-17.066667 6.4-34.133333 23.466667-38.4 2.133333 0 6.4-2.133333 8.533333-2.133333 14.933333 0 27.733333 8.533333 29.866667 23.466666L644.266667 780.8c4.266667 17.066667-4.266667 34.133333-21.333334 38.4z" horiz-adv-x="1024" />
<glyph glyph-name="close" unicode="&#59019;" d="M556.8 384L832 659.2c12.8 12.8 12.8 32 0 44.8-12.8 12.8-32 12.8-44.8 0L512 428.8l-275.2 277.333333c-12.8 12.8-32 12.8-44.8 0-12.8-12.8-12.8-32 0-44.8l275.2-277.333333-277.333333-275.2c-12.8-12.8-12.8-32 0-44.8 6.4-6.4 14.933333-8.533333 23.466666-8.533333s17.066667 2.133333 23.466667 8.533333L512 339.2 787.2 64c6.4-6.4 14.933333-8.533333 23.466667-8.533333s17.066667 2.133333 23.466666 8.533333c12.8 12.8 12.8 32 0 44.8L556.8 384z" horiz-adv-x="1024" />
<glyph glyph-name="check-item" unicode="&#59020;" d="M853.333333 800H170.666667C130.133333 800 96 765.866667 96 725.333333v-682.666666c0-40.533333 34.133333-74.666667 74.666667-74.666667h682.666666c40.533333 0 74.666667 34.133333 74.666667 74.666667V725.333333c0 40.533333-34.133333 74.666667-74.666667 74.666667z m10.666667-757.333333c0-6.4-4.266667-10.666667-10.666667-10.666667H170.666667c-6.4 0-10.666667 4.266667-10.666667 10.666667V725.333333c0 6.4 4.266667 10.666667 10.666667 10.666667h682.666666c6.4 0 10.666667-4.266667 10.666667-10.666667v-682.666666zM704 514.133333l-243.2-234.666666-117.333333 125.866666c-12.8 12.8-32 12.8-44.8 2.133334-12.8-12.8-12.8-32-2.133334-44.8l140.8-149.333334c6.4-6.4 14.933333-10.666667 23.466667-10.666666 8.533333 0 17.066667 4.266667 21.333333 8.533333l264.533334 256c12.8 12.8 12.8 32 0 44.8-10.666667 12.8-29.866667 14.933333-42.666667 2.133333z" horiz-adv-x="1024" />
<glyph glyph-name="calendar" unicode="&#59021;" d="M853.333333 746.666667h-138.666666V789.333333c0 17.066667-14.933333 32-32 32s-32-14.933333-32-32v-42.666666h-277.333334V789.333333c0 17.066667-14.933333 32-32 32s-32-14.933333-32-32v-42.666666H170.666667c-40.533333 0-74.666667-34.133333-74.666667-74.666667v-618.666667C96 12.8 130.133333-21.333333 170.666667-21.333333h682.666666c40.533333 0 74.666667 34.133333 74.666667 74.666666v618.666667C928 712.533333 893.866667 746.666667 853.333333 746.666667zM170.666667 682.666667h138.666666v-64c0-17.066667 14.933333-32 32-32s32 14.933333 32 32v64h277.333334v-64c0-17.066667 14.933333-32 32-32s32 14.933333 32 32v64H853.333333c6.4 0 10.666667-4.266667 10.666667-10.666667v-194.133333c-4.266667 2.133333-6.4 2.133333-10.666667 2.133333H170.666667c-4.266667 0-6.4 0-10.666667-2.133333v194.133333c0 6.4 4.266667 10.666667 10.666667 10.666667z m682.666666-640H170.666667c-6.4 0-10.666667 4.266667-10.666667 10.666666V418.133333c4.266667-2.133333 6.4-2.133333 10.666667-2.133333h682.666666c4.266667 0 6.4 0 10.666667 2.133333v-364.8c0-6.4-4.266667-10.666667-10.666667-10.666666zM384 288h-85.333333c-17.066667 0-32-14.933333-32-32s14.933333-32 32-32h85.333333c17.066667 0 32 14.933333 32 32s-14.933333 32-32 32zM725.333333 288h-192c-17.066667 0-32-14.933333-32-32s14.933333-32 32-32h192c17.066667 0 32 14.933333 32 32s-14.933333 32-32 32z" horiz-adv-x="1024" />
<glyph glyph-name="comment" unicode="&#59022;" d="M853.333333 757.333333H170.666667c-40.533333 0-74.666667-34.133333-74.666667-74.666666v-512c0-40.533333 34.133333-74.666667 74.666667-74.666667h151.466666V-21.333333c0-12.8 8.533333-25.6 19.2-29.866667 4.266667-2.133333 8.533333-2.133333 12.8-2.133333 8.533333 0 17.066667 4.266667 23.466667 10.666666l136.533333 138.666667H853.333333c40.533333 0 74.666667 34.133333 74.666667 74.666667V682.666667c0 40.533333-34.133333 74.666667-74.666667 74.666666z m10.666667-586.666666c0-6.4-4.266667-10.666667-10.666667-10.666667H501.333333c-8.533333 0-17.066667-4.266667-23.466666-10.666667l-89.6-93.866666V128c0 17.066667-14.933333 32-32 32H170.666667c-6.4 0-10.666667 4.266667-10.666667 10.666667V682.666667c0 6.4 4.266667 10.666667 10.666667 10.666666h682.666666c6.4 0 10.666667-4.266667 10.666667-10.666666v-512zM512 405.333333H298.666667c-17.066667 0-32-14.933333-32-32S281.6 341.333333 298.666667 341.333333h213.333333c17.066667 0 32 14.933333 32 32S529.066667 405.333333 512 405.333333zM672 554.666667H298.666667c-17.066667 0-32-14.933333-32-32S281.6 490.666667 298.666667 490.666667h373.333333c17.066667 0 32 14.933333 32 32s-14.933333 32-32 32z" horiz-adv-x="1024" />
<glyph glyph-name="column-vertical" unicode="&#59023;" d="M874.666667 778.666667H149.333333C108.8 778.666667 74.666667 744.533333 74.666667 704v-640c0-40.533333 34.133333-74.666667 74.666666-74.666667h725.333334c40.533333 0 74.666667 34.133333 74.666666 74.666667V704c0 40.533333-34.133333 74.666667-74.666666 74.666667z m-725.333334-64h725.333334c6.4 0 10.666667-4.266667 10.666666-10.666667v-288h-746.666666V704c0 6.4 4.266667 10.666667 10.666666 10.666667z m725.333334-661.333334H149.333333c-6.4 0-10.666667 4.266667-10.666666 10.666667V352h746.666666V64c0-6.4-4.266667-10.666667-10.666666-10.666667z" horiz-adv-x="1024" />
<glyph glyph-name="column-horizontal" unicode="&#59024;" d="M874.666667 778.666667H149.333333C108.8 778.666667 74.666667 744.533333 74.666667 704v-640c0-40.533333 34.133333-74.666667 74.666666-74.666667h725.333334c40.533333 0 74.666667 34.133333 74.666666 74.666667V704c0 40.533333-34.133333 74.666667-74.666666 74.666667zM138.666667 64V704c0 6.4 4.266667 10.666667 10.666666 10.666667h330.666667v-661.333334H149.333333c-6.4 0-10.666667 4.266667-10.666666 10.666667z m746.666666 0c0-6.4-4.266667-10.666667-10.666666-10.666667H544v661.333334H874.666667c6.4 0 10.666667-4.266667 10.666666-10.666667v-640z" horiz-adv-x="1024" />
<glyph glyph-name="complete" unicode="&#59025;" d="M874.666667 394.666667c-17.066667 0-32-14.933333-32-32v-298.666667c0-6.4-4.266667-10.666667-10.666667-10.666667H192c-6.4 0-10.666667 4.266667-10.666667 10.666667V704c0 6.4 4.266667 10.666667 10.666667 10.666667h469.333333c17.066667 0 32 14.933333 32 32s-14.933333 32-32 32H192C151.466667 778.666667 117.333333 744.533333 117.333333 704v-640c0-40.533333 34.133333-74.666667 74.666667-74.666667h640c40.533333 0 74.666667 34.133333 74.666667 74.666667V362.666667c0 17.066667-14.933333 32-32 32zM940.8 727.466667c-12.8 12.8-32 12.8-44.8 0l-390.4-384-106.666667 106.666666c-12.8 12.8-32 12.8-44.8 0-12.8-12.8-12.8-32 0-44.8l130.133334-128c6.4-6.4 14.933333-8.533333 23.466666-8.533333s17.066667 2.133333 23.466667 8.533333l411.733333 405.333334c8.533333 10.666667 10.666667 32-2.133333 44.8z" horiz-adv-x="1024" />
<glyph glyph-name="chart-pie" unicode="&#59026;" d="M887.466667 253.866667c-17.066667 6.4-34.133333 0-42.666667-17.066667-64-151.466667-221.866667-243.2-386.133333-221.866667-164.266667 21.333333-294.4 149.333333-315.733334 313.6C119.466667 490.666667 209.066667 650.666667 358.4 716.8c17.066667 6.4 23.466667 25.6 17.066667 42.666667-6.4 17.066667-25.6 23.466667-42.666667 17.066666C155.733333 697.6 51.2 509.866667 78.933333 317.866667c27.733333-192 179.2-343.466667 371.2-369.066667 19.2-2.133333 36.266667-4.266667 55.466667-4.266667 170.666667 0 330.666667 102.4 398.933333 264.533334 6.4 17.066667-2.133333 36.266667-17.066666 44.8zM814.933333 686.933333C727.466667 774.4 612.266667 821.333333 490.666667 821.333333c-17.066667 0-32-14.933333-32-32v-426.666666c0-17.066667 14.933333-32 32-32h426.666666c17.066667 0 32 14.933333 32 32 0 121.6-46.933333 236.8-134.4 324.266666zM522.666667 394.666667V755.2c93.866667-6.4 179.2-46.933333 247.466666-115.2 66.133333-66.133333 106.666667-153.6 115.2-247.466667h-362.666666z" horiz-adv-x="1024" />
<glyph glyph-name="cry" unicode="&#59027;" d="M512 821.333333C270.933333 821.333333 74.666667 625.066667 74.666667 384S270.933333-53.333333 512-53.333333 949.333333 142.933333 949.333333 384 753.066667 821.333333 512 821.333333z m0-810.666666c-204.8 0-373.333333 168.533333-373.333333 373.333333S307.2 757.333333 512 757.333333 885.333333 588.8 885.333333 384 716.8 10.666667 512 10.666667zM512 298.666667c-81.066667 0-151.466667-36.266667-211.2-106.666667-10.666667-12.8-8.533333-34.133333 4.266667-44.8 12.8-10.666667 34.133333-8.533333 44.8 4.266667 46.933333 57.6 100.266667 85.333333 162.133333 85.333333s115.2-27.733333 162.133333-85.333333c6.4-8.533333 14.933333-10.666667 25.6-10.666667 6.4 0 14.933333 2.133333 21.333334 6.4 12.8 10.666667 14.933333 32 4.266666 44.8-61.866667 70.4-132.266667 106.666667-213.333333 106.666667zM362.666667 384c23.466667 0 42.666667 19.2 42.666666 42.666667v64c0 23.466667-19.2 42.666667-42.666666 42.666666s-42.666667-19.2-42.666667-42.666666v-64c0-23.466667 19.2-42.666667 42.666667-42.666667zM661.333333 384c23.466667 0 42.666667 19.2 42.666667 42.666667v64c0 23.466667-19.2 42.666667-42.666667 42.666666s-42.666667-19.2-42.666666-42.666666v-64c0-23.466667 19.2-42.666667 42.666666-42.666667z" horiz-adv-x="1024" />
<glyph glyph-name="customer-service" unicode="&#59028;" d="M864 456.533333V469.333333c0 194.133333-157.866667 352-352 352S160 663.466667 160 469.333333v-12.8c-36.266667-4.266667-64-36.266667-64-72.533333v-170.666667c0-40.533333 34.133333-74.666667 74.666667-74.666666h85.333333c40.533333 0 74.666667 34.133333 74.666667 74.666666v170.666667c0 40.533333-34.133333 74.666667-74.666667 74.666667h-32V469.333333c0 157.866667 130.133333 288 288 288S800 627.2 800 469.333333v-10.666666H768c-40.533333 0-74.666667-34.133333-74.666667-74.666667v-170.666667c0-40.533333 34.133333-74.666667 74.666667-74.666666h21.333333c-17.066667-49.066667-59.733333-98.133333-179.2-106.666667-12.8 19.2-32 32-55.466666 32-36.266667 0-64-27.733333-64-64s27.733333-64 64-64c23.466667 0 44.8 12.8 55.466666 34.133333 166.4 10.666667 226.133333 91.733333 245.333334 170.666667 40.533333 2.133333 72.533333 34.133333 72.533333 74.666667v170.666666c0 36.266667-27.733333 66.133333-64 70.4z m-597.333333-72.533333v-170.666667c0-6.4-4.266667-10.666667-10.666667-10.666666H170.666667c-6.4 0-10.666667 4.266667-10.666667 10.666666v170.666667c0 6.4 4.266667 10.666667 10.666667 10.666667h85.333333c6.4 0 10.666667-4.266667 10.666667-10.666667z m597.333333-170.666667c0-6.4-4.266667-10.666667-10.666667-10.666666h-85.333333c-6.4 0-10.666667 4.266667-10.666667 10.666666v170.666667c0 6.4 4.266667 10.666667 10.666667 10.666667h85.333333c6.4 0 10.666667-4.266667 10.666667-10.666667v-170.666667z" horiz-adv-x="1024" />
<glyph glyph-name="direction-down" unicode="&#59029;" d="M898.133333 384c-12.8 12.8-32 12.8-44.8 2.133333L544 96V746.666667c0 17.066667-14.933333 32-32 32s-32-14.933333-32-32v-650.666667L170.666667 386.133333c-12.8 12.8-34.133333 10.666667-44.8-2.133333-12.8-12.8-10.666667-34.133333 2.133333-44.8l362.666667-341.333333c2.133333-2.133333 6.4-4.266667 8.533333-6.4 4.266667-2.133333 6.4-2.133333 10.666667-2.133334s8.533333 0 10.666666 2.133334c4.266667 2.133333 6.4 4.266667 8.533334 6.4l362.666666 341.333333c17.066667 12.8 19.2 32 6.4 44.8z" horiz-adv-x="1024" />
<glyph glyph-name="copy" unicode="&#59030;" d="M853.333333 672h-53.333333V725.333333c0 40.533333-34.133333 74.666667-74.666667 74.666667H170.666667C130.133333 800 96 765.866667 96 725.333333v-554.666666c0-40.533333 34.133333-74.666667 74.666667-74.666667h53.333333V42.666667c0-40.533333 34.133333-74.666667 74.666667-74.666667h554.666666c40.533333 0 74.666667 34.133333 74.666667 74.666667V597.333333c0 40.533333-34.133333 74.666667-74.666667 74.666667zM160 170.666667V725.333333c0 6.4 4.266667 10.666667 10.666667 10.666667h554.666666c6.4 0 10.666667-4.266667 10.666667-10.666667v-554.666666c0-6.4-4.266667-10.666667-10.666667-10.666667H170.666667c-6.4 0-10.666667 4.266667-10.666667 10.666667z m704-128c0-6.4-4.266667-10.666667-10.666667-10.666667H298.666667c-6.4 0-10.666667 4.266667-10.666667 10.666667v53.333333H725.333333c40.533333 0 74.666667 34.133333 74.666667 74.666667V608H853.333333c6.4 0 10.666667-4.266667 10.666667-10.666667v-554.666666zM576 480h-96V576c0 17.066667-14.933333 32-32 32s-32-14.933333-32-32v-96H320c-17.066667 0-32-14.933333-32-32s14.933333-32 32-32h96V320c0-17.066667 14.933333-32 32-32s32 14.933333 32 32v96H576c17.066667 0 32 14.933333 32 32s-14.933333 32-32 32z" horiz-adv-x="1024" />
<glyph glyph-name="cut" unicode="&#59031;" d="M917.333333 693.333333h-96V789.333333c0 17.066667-14.933333 32-32 32s-32-14.933333-32-32v-96H277.333333c-40.533333 0-74.666667-34.133333-74.666666-74.666666v-480H106.666667c-17.066667 0-32-14.933333-32-32s14.933333-32 32-32h96V-21.333333c0-17.066667 14.933333-32 32-32s32 14.933333 32 32v96H746.666667c40.533333 0 74.666667 34.133333 74.666666 74.666666V629.333333H917.333333c17.066667 0 32 14.933333 32 32s-14.933333 32-32 32zM757.333333 149.333333c0-6.4-4.266667-10.666667-10.666666-10.666666H266.666667V618.666667c0 6.4 4.266667 10.666667 10.666666 10.666666h480V149.333333z" horiz-adv-x="1024" />
<glyph glyph-name="data-view" unicode="&#59032;" d="M874.666667 32H170.666667c-6.4 0-10.666667 4.266667-10.666667 10.666667V746.666667c0 17.066667-14.933333 32-32 32S96 763.733333 96 746.666667v-704c0-40.533333 34.133333-74.666667 74.666667-74.666667h704c17.066667 0 32 14.933333 32 32s-14.933333 32-32 32zM437.333333 426.666667v-320c0-17.066667 14.933333-32 32-32s32 14.933333 32 32V426.666667c0 17.066667-14.933333 32-32 32s-32-14.933333-32-32zM298.666667 74.666667c17.066667 0 32 14.933333 32 32V362.666667c0 17.066667-14.933333 32-32 32s-32-14.933333-32-32v-256c0-17.066667 14.933333-32 32-32zM640 330.666667c-17.066667 0-32-14.933333-32-32v-192c0-17.066667 14.933333-32 32-32s32 14.933333 32 32v192c0 17.066667-14.933333 32-32 32zM810.666667 544c-17.066667 0-32-14.933333-32-32v-405.333333c0-17.066667 14.933333-32 32-32s32 14.933333 32 32V512c0 17.066667-14.933333 32-32 32zM322.133333 488.533333l147.2 147.2 147.2-147.2c6.4-6.4 14.933333-8.533333 23.466667-8.533333h2.133333c8.533333 0 17.066667 6.4 23.466667 12.8l170.666667 234.666667c10.666667 14.933333 6.4 34.133333-6.4 44.8-14.933333 10.666667-34.133333 6.4-44.8-6.4l-149.333334-204.8L490.666667 706.133333c-12.8 12.8-32 12.8-44.8 0l-170.666667-170.666666c-12.8-12.8-12.8-32 0-44.8 12.8-12.8 34.133333-12.8 46.933333-2.133334z" horiz-adv-x="1024" />
<glyph glyph-name="direction-right" unicode="&#59033;" d="M904.533333 373.333333c2.133333 4.266667 2.133333 6.4 2.133334 10.666667s0 8.533333-2.133334 10.666667c-2.133333 4.266667-4.266667 6.4-6.4 8.533333l-341.333333 362.666667c-12.8 12.8-32 12.8-44.8 2.133333-12.8-12.8-12.8-32-2.133333-44.8l290.133333-309.333333H149.333333c-17.066667 0-32-14.933333-32-32s14.933333-32 32-32h650.666667L509.866667 42.666667c-12.8-12.8-10.666667-34.133333 2.133333-44.8 6.4-6.4 14.933333-8.533333 21.333333-8.533334 8.533333 0 17.066667 4.266667 23.466667 10.666667l341.333333 362.666667c2.133333 2.133333 4.266667 6.4 6.4 10.666666z" horiz-adv-x="1024" />
<glyph glyph-name="direction-up" unicode="&#59034;" d="M896 428.8l-362.666667 341.333333c-2.133333 2.133333-6.4 4.266667-8.533333 6.4-4.266667 2.133333-6.4 2.133333-10.666667 2.133334s-8.533333 0-10.666666-2.133334c-4.266667-2.133333-6.4-4.266667-8.533334-6.4l-362.666666-341.333333c-12.8-12.8-12.8-32-2.133334-44.8 12.8-12.8 32-12.8 44.8-2.133333l309.333334 290.133333V21.333333c0-17.066667 14.933333-32 32-32s32 14.933333 32 32V672L853.333333 381.866667c6.4-6.4 14.933333-8.533333 21.333334-8.533334 8.533333 0 17.066667 4.266667 23.466666 10.666667 12.8 12.8 10.666667 32-2.133333 44.8z" horiz-adv-x="1024" />
<glyph glyph-name="discount" unicode="&#59035;" d="M874.666667 800H593.066667c-19.2 0-38.4-8.533333-53.333334-21.333333l-405.333333-405.333334c-29.866667-29.866667-29.866667-76.8 0-104.533333l260.266667-260.266667c14.933333-14.933333 32-21.333333 53.333333-21.333333s38.4 8.533333 53.333333 21.333333l405.333334 405.333334c14.933333 14.933333 21.333333 32 21.333333 53.333333V746.666667c0 29.866667-23.466667 53.333333-53.333333 53.333333z m-10.666667-334.933333c0-2.133333-2.133333-6.4-2.133333-8.533334l-405.333334-405.333333c-2.133333-2.133333-6.4-2.133333-8.533333-2.133333s-4.266667 0-8.533333 2.133333L181.333333 311.466667c-4.266667 4.266667-4.266667 10.666667 0 14.933333l405.333334 405.333333c2.133333 2.133333 4.266667 2.133333 8.533333 2.133334h270.933333v-268.8zM704 480c53.333333 0 96 42.666667 96 96s-42.666667 96-96 96-96-42.666667-96-96 42.666667-96 96-96z m0 128c17.066667 0 32-14.933333 32-32s-14.933333-32-32-32-32 14.933333-32 32 14.933333 32 32 32z" horiz-adv-x="1024" />
<glyph glyph-name="direction-left" unicode="&#59036;" d="M874.666667 416H224L514.133333 725.333333c12.8 12.8 10.666667 34.133333-2.133333 44.8s-32 10.666667-44.8-2.133333l-341.333333-362.666667c-2.133333-2.133333-4.266667-6.4-6.4-8.533333-2.133333-4.266667-2.133333-6.4-2.133334-10.666667s0-8.533333 2.133334-10.666666c2.133333-4.266667 4.266667-6.4 6.4-8.533334l341.333333-362.666666c6.4-6.4 14.933333-10.666667 23.466667-10.666667 8.533333 0 14.933333 2.133333 21.333333 8.533333 12.8 12.8 12.8 32 2.133333 44.8L224 352H874.666667c17.066667 0 32 14.933333 32 32s-14.933333 32-32 32z" horiz-adv-x="1024" />
<glyph glyph-name="download" unicode="&#59037;" d="M896 224c-17.066667 0-32-14.933333-32-32v-128c0-6.4-4.266667-10.666667-10.666667-10.666667H170.666667c-6.4 0-10.666667 4.266667-10.666667 10.666667v128c0 17.066667-14.933333 32-32 32s-32-14.933333-32-32v-128c0-40.533333 34.133333-74.666667 74.666667-74.666667h682.666666c40.533333 0 74.666667 34.133333 74.666667 74.666667v128c0 17.066667-14.933333 32-32 32zM488.533333 168.533333c6.4-6.4 14.933333-8.533333 23.466667-8.533333s17.066667 2.133333 23.466667 8.533333l213.333333 213.333334c12.8 12.8 12.8 32 0 44.8-12.8 12.8-32 12.8-44.8 0l-157.866667-157.866667V725.333333c0 17.066667-14.933333 32-32 32s-34.133333-14.933333-34.133333-32v-456.533333L322.133333 426.666667c-12.8 12.8-32 12.8-44.8 0-12.8-12.8-12.8-32 0-44.8l211.2-213.333334z" horiz-adv-x="1024" />
<glyph glyph-name="electronics" unicode="&#59038;" d="M840.533333 778.666667H183.466667c-59.733333 0-108.8-49.066667-108.8-108.8v-379.733334c0-59.733333 49.066667-108.8 108.8-108.8h232.533333v-115.2H341.333333c-17.066667 0-32-14.933333-32-32s14.933333-32 32-32h341.333334c17.066667 0 32 14.933333 32 32s-14.933333 32-32 32h-74.666667v115.2h232.533333c59.733333 0 108.8 49.066667 108.8 108.8V669.866667c0 59.733333-49.066667 108.8-108.8 108.8zM544 66.133333h-64v115.2h64v-115.2z m341.333333 224c0-25.6-19.2-44.8-44.8-44.8H183.466667c-25.6 0-44.8 19.2-44.8 44.8V669.866667c0 25.6 19.2 44.8 44.8 44.8h657.066666c25.6 0 44.8-19.2 44.8-44.8v-379.733334z" horiz-adv-x="1024" />
<glyph glyph-name="drag" unicode="&#59039;" d="M362.666667 704m-64 0a64 64 0 1 1 128 0 64 64 0 1 1-128 0ZM661.333333 704m-64 0a64 64 0 1 1 128 0 64 64 0 1 1-128 0ZM362.666667 384m-64 0a64 64 0 1 1 128 0 64 64 0 1 1-128 0ZM661.333333 384m-64 0a64 64 0 1 1 128 0 64 64 0 1 1-128 0ZM362.666667 64m-64 0a64 64 0 1 1 128 0 64 64 0 1 1-128 0ZM661.333333 64m-64 0a64 64 0 1 1 128 0 64 64 0 1 1-128 0Z" horiz-adv-x="1024" />
<glyph glyph-name="elipsis" unicode="&#59040;" d="M192 384m-64 0a64 64 0 1 1 128 0 64 64 0 1 1-128 0ZM512 384m-64 0a64 64 0 1 1 128 0 64 64 0 1 1-128 0ZM832 384m-64 0a64 64 0 1 1 128 0 64 64 0 1 1-128 0Z" horiz-adv-x="1024" />
<glyph glyph-name="export" unicode="&#59041;" d="M582.4 32H170.666667c-6.4 0-10.666667 4.266667-10.666667 10.666667V725.333333c0 6.4 4.266667 10.666667 10.666667 10.666667h309.333333V576c0-40.533333 34.133333-74.666667 74.666667-74.666667h160v-38.4c0-17.066667 14.933333-32 32-32s32 14.933333 32 32V597.333333c0 8.533333-4.266667 17.066667-8.533334 23.466667l-170.666666 170.666667c-6.4 6.4-14.933333 8.533333-23.466667 8.533333H170.666667C130.133333 800 96 765.866667 96 725.333333v-682.666666c0-40.533333 34.133333-74.666667 74.666667-74.666667h411.733333c17.066667 0 32 14.933333 32 32s-14.933333 32-32 32z m132.266667 550.4v-17.066667H554.666667c-6.4 0-10.666667 4.266667-10.666667 10.666667V736h19.2l151.466667-153.6zM866.133333 226.133333l-106.666666 106.666667c-12.8 12.8-32 12.8-44.8 0s-12.8-32 0-44.8l51.2-51.2H512c-17.066667 0-32-14.933333-32-32S494.933333 170.666667 512 170.666667h253.866667l-51.2-51.2c-12.8-12.8-12.8-32 0-44.8 6.4-6.4 14.933333-8.533333 23.466666-8.533334s17.066667 2.133333 23.466667 8.533334l106.666667 106.666666c8.533333 10.666667 8.533333 32-2.133334 44.8z" horiz-adv-x="1024" />
<glyph glyph-name="explain" unicode="&#59042;" d="M789.333333 821.333333H234.666667C194.133333 821.333333 160 787.2 160 746.666667v-725.333334c0-40.533333 34.133333-74.666667 74.666667-74.666666h554.666666c40.533333 0 74.666667 34.133333 74.666667 74.666666V746.666667c0 40.533333-34.133333 74.666667-74.666667 74.666666z m-138.666666-64v-296.533333L576 531.2c-6.4 6.4-14.933333 8.533333-21.333333 8.533333-8.533333 0-17.066667-2.133333-21.333334-8.533333l-74.666666-72.533333v298.666666h192z m149.333333-736c0-6.4-4.266667-10.666667-10.666667-10.666666H234.666667c-6.4 0-10.666667 4.266667-10.666667 10.666666V746.666667c0 6.4 4.266667 10.666667 10.666667 10.666666h160v-322.133333c0-14.933333 6.4-27.733333 14.933333-36.266667 21.333333-21.333333 53.333333-21.333333 74.666667 0l70.4 68.266667 70.4-68.266667c10.666667-10.666667 23.466667-14.933333 36.266666-14.933333 29.866667 0 53.333333 23.466667 53.333334 53.333333v320H789.333333c6.4 0 10.666667-4.266667 10.666667-10.666666v-725.333334z" horiz-adv-x="1024" />
<glyph glyph-name="edit" unicode="&#59043;" d="M853.333333 394.666667c-17.066667 0-32-14.933333-32-32v-320c0-6.4-4.266667-10.666667-10.666666-10.666667H170.666667c-6.4 0-10.666667 4.266667-10.666667 10.666667V682.666667c0 6.4 4.266667 10.666667 10.666667 10.666666h320c17.066667 0 32 14.933333 32 32s-14.933333 32-32 32H170.666667c-40.533333 0-74.666667-34.133333-74.666667-74.666666v-640c0-40.533333 34.133333-74.666667 74.666667-74.666667h640c40.533333 0 74.666667 34.133333 74.666666 74.666667V362.666667c0 17.066667-14.933333 32-32 32zM405.333333 411.733333l-32-125.866666c-2.133333-10.666667 0-23.466667 8.533334-29.866667 6.4-6.4 14.933333-8.533333 23.466666-8.533333h8.533334l125.866666 32c6.4 2.133333 10.666667 4.266667 14.933334 8.533333l300.8 300.8c38.4 38.4 38.4 102.4 0 140.8-38.4 38.4-102.4 38.4-140.8 0L413.866667 426.666667c-4.266667-4.266667-6.4-8.533333-8.533334-14.933334z m59.733334-23.466666L761.6 682.666667c12.8 12.8 36.266667 12.8 49.066667 0 12.8-12.8 12.8-36.266667 0-49.066667L516.266667 337.066667l-66.133334-17.066667 14.933334 68.266667z" horiz-adv-x="1024" />
<glyph glyph-name="eye-close" unicode="&#59044;" d="M955.733333 403.2c-6.4 12.8-162.133333 317.866667-443.733333 317.866667-23.466667 0-46.933333-2.133333-70.4-6.4-17.066667-4.266667-29.866667-19.2-25.6-36.266667 4.266667-17.066667 19.2-29.866667 36.266667-25.6 19.2 4.266667 38.4 4.266667 57.6 4.266667 209.066667 0 345.6-209.066667 379.733333-266.666667-10.666667-19.2-32-53.333333-64-91.733333-10.666667-12.8-8.533333-34.133333 4.266667-44.8 6.4-4.266667 12.8-6.4 21.333333-6.4s19.2 4.266667 25.6 10.666666c51.2 61.866667 78.933333 115.2 78.933333 117.333334 6.4 8.533333 6.4 19.2 0 27.733333zM215.466667 770.133333c-12.8 12.8-32 12.8-44.8 0-12.8-12.8-12.8-32 0-44.8l91.733333-91.733333C138.666667 541.866667 72.533333 411.733333 68.266667 405.333333c-4.266667-8.533333-4.266667-19.2 0-29.866666 6.4-12.8 162.133333-315.733333 443.733333-315.733334 83.2 0 164.266667 27.733333 241.066667 81.066667l96-96c6.4-6.4 14.933333-8.533333 23.466666-8.533333s17.066667 2.133333 23.466667 8.533333c12.8 12.8 12.8 32 0 44.8L215.466667 770.133333z m243.2-334.933333l104.533333-104.533333c-12.8-12.8-32-21.333333-51.2-21.333334-40.533333 0-74.666667 34.133333-74.666667 74.666667 0 19.2 8.533333 38.4 21.333334 51.2zM512 123.733333c-209.066667 0-345.6 209.066667-379.733333 266.666667 21.333333 36.266667 81.066667 130.133333 174.933333 196.266667l104.533333-104.533334c-25.6-25.6-38.4-59.733333-38.4-96 0-76.8 61.866667-138.666667 138.666667-138.666666 36.266667 0 70.4 14.933333 96 38.4l98.133333-98.133334c-61.866667-42.666667-128-64-194.133333-64z" horiz-adv-x="1024" />
<glyph glyph-name="email" unicode="&#59045;" d="M874.666667 714.666667H149.333333c-40.533333 0-74.666667-34.133333-74.666666-74.666667v-512c0-40.533333 34.133333-74.666667 74.666666-74.666667h725.333334c40.533333 0 74.666667 34.133333 74.666666 74.666667V640c0 40.533333-34.133333 74.666667-74.666666 74.666667z m-725.333334-64h725.333334c6.4 0 10.666667-4.266667 10.666666-10.666667v-25.6L512 379.733333l-373.333333 234.666667V640c0 6.4 4.266667 10.666667 10.666666 10.666667z m725.333334-533.333334H149.333333c-6.4 0-10.666667 4.266667-10.666666 10.666667V539.733333l356.266666-224c4.266667-4.266667 10.666667-4.266667 17.066667-4.266666s12.8 2.133333 17.066667 4.266666l356.266666 224V128c0-6.4-4.266667-10.666667-10.666666-10.666667z" horiz-adv-x="1024" />
<glyph glyph-name="favorite" unicode="&#59046;" d="M934.4 539.733333c-8.533333 10.666667-21.333333 19.2-34.133333 21.333334l-234.666667 34.133333-104.533333 213.333333c-6.4 8.533333-14.933333 17.066667-25.6 23.466667-12.8 6.4-27.733333 6.4-40.533334 2.133333-12.8-4.266667-23.466667-14.933333-29.866666-27.733333l-104.533334-213.333333-234.666666-34.133334c-10.666667-2.133333-21.333333-6.4-29.866667-14.933333-21.333333-21.333333-19.2-55.466667 0-74.666667l170.666667-166.4-40.533334-234.666666c-2.133333-10.666667 0-23.466667 6.4-34.133334 12.8-25.6 46.933333-36.266667 72.533334-21.333333l211.2 110.933333 211.2-110.933333c8.533333-4.266667 17.066667-6.4 25.6-6.4h8.533333c14.933333 2.133333 25.6 10.666667 34.133333 21.333333 8.533333 10.666667 10.666667 25.6 8.533334 40.533334l-40.533334 234.666666 170.666667 166.4c8.533333 8.533333 14.933333 19.2 14.933333 29.866667-2.133333 14.933333-6.4 27.733333-14.933333 40.533333z m-224-194.133333c-12.8-12.8-19.2-29.866667-14.933333-46.933333l38.4-217.6L512 196.266667l-221.866667-115.2L328.533333 298.666667c2.133333 17.066667-2.133333 34.133333-14.933333 46.933333l-157.866667 153.6 219.733334 32c17.066667 2.133333 32 12.8 40.533333 29.866667L512 759.466667l98.133333-198.4c8.533333-14.933333 23.466667-27.733333 40.533334-29.866667l219.733333-32-160-153.6z" horiz-adv-x="1024" />
<glyph glyph-name="file-common" unicode="&#59047;" d="M832 821.333333H192c-17.066667 0-32-14.933333-32-32v-765.866666c0-12.8 4.266667-23.466667 12.8-34.133334 8.533333-10.666667 21.333333-17.066667 36.266667-19.2h6.4c12.8 0 23.466667 4.266667 34.133333 12.8l264.533333 213.333334 264.533334-213.333334c8.533333-8.533333 21.333333-12.8 34.133333-12.8 29.866667 0 53.333333 23.466667 53.333333 53.333334V789.333333c-2.133333 17.066667-17.066667 32-34.133333 32z m-32-776.533333L531.2 262.4c-10.666667 8.533333-27.733333 8.533333-40.533333 0L224 44.8V757.333333h576v-712.533333zM341.333333 554.666667h320c17.066667 0 32 14.933333 32 32S678.4 618.666667 661.333333 618.666667H341.333333c-17.066667 0-32-14.933333-32-32S324.266667 554.666667 341.333333 554.666667zM341.333333 384h213.333334c17.066667 0 32 14.933333 32 32S571.733333 448 554.666667 448H341.333333c-17.066667 0-32-14.933333-32-32S324.266667 384 341.333333 384z" horiz-adv-x="1024" />
<glyph glyph-name="file-delete" unicode="&#59048;" d="M842.666667 610.133333l-187.733334 187.733334c-14.933333 14.933333-32 21.333333-53.333333 21.333333H234.666667C194.133333 821.333333 160 787.2 160 746.666667v-725.333334c0-40.533333 34.133333-74.666667 74.666667-74.666666h554.666666c40.533333 0 74.666667 34.133333 74.666667 74.666666V558.933333c0 19.2-8.533333 38.4-21.333333 51.2z m-44.8-44.8c-2.133333-2.133333-4.266667 0-8.533334 0h-170.666666c-6.4 0-10.666667 4.266667-10.666667 10.666667V746.666667c0 2.133333 0 6.4-2.133333 8.533333 0 0 2.133333 0 2.133333-2.133333l189.866667-187.733334z m-8.533334-554.666666H234.666667c-6.4 0-10.666667 4.266667-10.666667 10.666666V746.666667c0 6.4 4.266667 10.666667 10.666667 10.666666h311.466666c-2.133333-4.266667-2.133333-6.4-2.133333-10.666666v-170.666667c0-40.533333 34.133333-74.666667 74.666667-74.666667h170.666666c4.266667 0 6.4 0 10.666667 2.133334V21.333333c0-6.4-4.266667-10.666667-10.666667-10.666666zM640 309.333333H384c-17.066667 0-32-14.933333-32-32s14.933333-32 32-32h256c17.066667 0 32 14.933333 32 32s-14.933333 32-32 32z" horiz-adv-x="1024" />
<glyph glyph-name="file-add" unicode="&#59049;" d="M842.666667 610.133333l-187.733334 187.733334c-14.933333 14.933333-32 21.333333-53.333333 21.333333H234.666667C194.133333 821.333333 160 787.2 160 746.666667v-725.333334c0-40.533333 34.133333-74.666667 74.666667-74.666666h554.666666c40.533333 0 74.666667 34.133333 74.666667 74.666666V558.933333c0 19.2-8.533333 38.4-21.333333 51.2z m-44.8-44.8H618.666667c-6.4 0-10.666667 4.266667-10.666667 10.666667V755.2l189.866667-189.866667z m-8.533334-554.666666H234.666667c-6.4 0-10.666667 4.266667-10.666667 10.666666V746.666667c0 6.4 4.266667 10.666667 10.666667 10.666666h309.333333V576c0-40.533333 34.133333-74.666667 74.666667-74.666667h181.333333V21.333333c0-6.4-4.266667-10.666667-10.666667-10.666666zM618.666667 309.333333h-74.666667V384c0 17.066667-14.933333 32-32 32s-32-14.933333-32-32v-74.666667H405.333333c-17.066667 0-32-14.933333-32-32s14.933333-32 32-32h74.666667V170.666667c0-17.066667 14.933333-32 32-32s32 14.933333 32 32v74.666666H618.666667c17.066667 0 32 14.933333 32 32s-14.933333 32-32 32z" horiz-adv-x="1024" />
<glyph glyph-name="fabulous" unicode="&#59050;" d="M859.733333 642.133333c-44.8 44.8-102.4 70.4-166.4 70.4-61.866667 0-121.6-25.6-166.4-70.4l-14.933333-17.066666-17.066667 17.066666c-44.8 44.8-102.4 70.4-166.4 70.4-61.866667 0-121.6-25.6-166.4-70.4-91.733333-91.733333-91.733333-243.2 0-337.066666l324.266667-330.666667c6.4-6.4 14.933333-8.533333 23.466667-8.533333s17.066667 4.266667 23.466666 8.533333l324.266667 330.666667c44.8 44.8 68.266667 104.533333 68.266667 168.533333s-21.333333 123.733333-66.133334 168.533333z m-44.8-290.133333L512 42.666667 209.066667 352c-66.133333 68.266667-66.133333 179.2 0 247.466667 32 32 74.666667 51.2 119.466666 51.2 44.8 0 87.466667-17.066667 119.466667-51.2l38.4-40.533334c12.8-12.8 34.133333-12.8 44.8 0l38.4 40.533334c32 32 74.666667 51.2 119.466667 51.2 44.8 0 87.466667-17.066667 119.466666-51.2 32-32 49.066667-76.8 49.066667-123.733334s-12.8-91.733333-42.666667-123.733333z" horiz-adv-x="1024" />
<glyph glyph-name="file" unicode="&#59051;" d="M842.666667 610.133333l-187.733334 187.733334c-14.933333 14.933333-32 21.333333-53.333333 21.333333H234.666667C194.133333 821.333333 160 787.2 160 746.666667v-725.333334c0-40.533333 34.133333-74.666667 74.666667-74.666666h554.666666c40.533333 0 74.666667 34.133333 74.666667 74.666666V558.933333c0 19.2-8.533333 38.4-21.333333 51.2z m-44.8-44.8c-2.133333-2.133333-4.266667 0-8.533334 0h-170.666666c-6.4 0-10.666667 4.266667-10.666667 10.666667V746.666667c0 2.133333 0 6.4-2.133333 8.533333 0 0 2.133333 0 2.133333-2.133333l189.866667-187.733334z m-8.533334-554.666666H234.666667c-6.4 0-10.666667 4.266667-10.666667 10.666666V746.666667c0 6.4 4.266667 10.666667 10.666667 10.666666h311.466666c-2.133333-4.266667-2.133333-6.4-2.133333-10.666666v-170.666667c0-40.533333 34.133333-74.666667 74.666667-74.666667h170.666666c4.266667 0 6.4 0 10.666667 2.133334V21.333333c0-6.4-4.266667-10.666667-10.666667-10.666666zM640 202.666667H341.333333c-17.066667 0-32-14.933333-32-32s14.933333-32 32-32h298.666667c17.066667 0 32 14.933333 32 32s-14.933333 32-32 32zM640 373.333333H341.333333c-17.066667 0-32-14.933333-32-32s14.933333-32 32-32h298.666667c17.066667 0 32 14.933333 32 32s-14.933333 32-32 32zM341.333333 480h85.333334c17.066667 0 32 14.933333 32 32s-14.933333 32-32 32h-85.333334c-17.066667 0-32-14.933333-32-32s14.933333-32 32-32z" horiz-adv-x="1024" />
<glyph glyph-name="folder-close" unicode="&#59052;" d="M853.333333 629.333333H514.133333c-4.266667 0-6.4 2.133333-8.533333 4.266667l-38.4 66.133333c-12.8 21.333333-38.4 36.266667-64 36.266667H170.666667c-40.533333 0-74.666667-34.133333-74.666667-74.666667v-554.666666c0-40.533333 34.133333-74.666667 74.666667-74.666667h682.666666c40.533333 0 74.666667 34.133333 74.666667 74.666667V554.666667c0 40.533333-34.133333 74.666667-74.666667 74.666666z m-682.666666 42.666667h232.533333c4.266667 0 6.4-2.133333 8.533333-4.266667l38.4-66.133333c12.8-21.333333 38.4-36.266667 64-36.266667H853.333333c6.4 0 10.666667-4.266667 10.666667-10.666666v-74.666667h-704V661.333333c0 6.4 4.266667 10.666667 10.666667 10.666667z m682.666666-576H170.666667c-6.4 0-10.666667 4.266667-10.666667 10.666667V416h704V106.666667c0-6.4-4.266667-10.666667-10.666667-10.666667z" horiz-adv-x="1024" />
<glyph glyph-name="good" unicode="&#59053;" d="M881.066667 501.333333c-21.333333 23.466667-51.2 36.266667-81.066667 36.266667H618.666667v117.333333c0 44.8-29.866667 85.333333-87.466667 117.333334-17.066667 10.666667-38.4 12.8-57.6 8.533333-19.2-4.266667-36.266667-17.066667-46.933333-34.133333-2.133333-2.133333-2.133333-4.266667-4.266667-6.4l-125.866667-281.6H204.8c-59.733333 0-108.8-46.933333-108.8-106.666667v-258.133333c0-57.6 49.066667-106.666667 108.8-106.666667h544c53.333333 0 98.133333 38.4 106.666667 89.6l51.2 337.066667c4.266667 34.133333-6.4 64-25.6 87.466666z m-593.066667-448H204.8c-25.6 0-44.8 19.2-44.8 42.666667v256c0 23.466667 19.2 42.666667 44.8 42.666667h83.2v-341.333334z m554.666667 373.333334L789.333333 89.6c-4.266667-21.333333-21.333333-36.266667-42.666666-36.266667H352V424.533333l130.133333 290.133334c2.133333 4.266667 4.266667 4.266667 6.4 4.266666 2.133333 0 4.266667 0 8.533334-2.133333 25.6-14.933333 55.466667-38.4 55.466666-64v-149.333333c0-17.066667 14.933333-32 32-32h213.333334c12.8 0 25.6-4.266667 34.133333-14.933334 8.533333-6.4 12.8-19.2 10.666667-29.866666z" horiz-adv-x="1024" />
<glyph glyph-name="hide" unicode="&#59054;" d="M917.333333 322.133333l-87.466666 87.466667c34.133333 32 66.133333 68.266667 91.733333 108.8 8.533333 14.933333 4.266667 34.133333-10.666667 44.8-14.933333 8.533333-34.133333 4.266667-44.8-10.666667-76.8-125.866667-209.066667-200.533333-356.266666-200.533333-145.066667 0-279.466667 74.666667-354.133334 198.4-8.533333 14.933333-29.866667 19.2-44.8 10.666667-14.933333-8.533333-19.2-29.866667-10.666666-44.8 25.6-40.533333 55.466667-76.8 91.733333-108.8l-85.333333-85.333334c-12.8-12.8-12.8-32 0-44.8 6.4-6.4 14.933333-8.533333 23.466666-8.533333s17.066667 2.133333 23.466667 8.533333l91.733333 91.733334c38.4-25.6 81.066667-46.933333 125.866667-59.733334l-34.133333-130.133333c-4.266667-17.066667 6.4-34.133333 23.466666-38.4 2.133333 0 6.4-2.133333 8.533334-2.133333 14.933333 0 27.733333 8.533333 29.866666 23.466666l36.266667 132.266667c25.6-4.266667 51.2-6.4 78.933333-6.4 27.733333 0 55.466667 2.133333 83.2 6.4l36.266667-132.266667c4.266667-14.933333 17.066667-23.466667 29.866667-23.466666 2.133333 0 6.4 0 8.533333 2.133333 17.066667 4.266667 27.733333 21.333333 23.466667 38.4L661.333333 311.466667c44.8 12.8 85.333333 34.133333 123.733334 59.733333l91.733333-91.733333c6.4-6.4 14.933333-8.533333 23.466667-8.533334s17.066667 2.133333 23.466666 8.533334c6.4 10.666667 6.4 29.866667-6.4 42.666666z" horiz-adv-x="1024" />
<glyph glyph-name="file-open" unicode="&#59055;" d="M921.6 445.866667c-6.4 8.533333-14.933333 12.8-25.6 12.8h-10.666667V554.666667c0 40.533333-34.133333 74.666667-74.666666 74.666666H514.133333c-4.266667 0-6.4 2.133333-8.533333 4.266667l-38.4 66.133333c-12.8 21.333333-38.4 36.266667-64 36.266667H170.666667c-40.533333 0-74.666667-34.133333-74.666667-74.666667v-597.333333c0-6.4 2.133333-12.8 6.4-19.2 6.4-8.533333 14.933333-12.8 25.6-12.8h640c12.8 0 25.6 8.533333 29.866667 21.333333l128 362.666667c4.266667 10.666667 2.133333 21.333333-4.266667 29.866667zM170.666667 672h232.533333c4.266667 0 6.4-2.133333 8.533333-4.266667l38.4-66.133333c12.8-21.333333 38.4-36.266667 64-36.266667H810.666667c6.4 0 10.666667-4.266667 10.666666-10.666666v-96H256c-12.8 0-25.6-8.533333-29.866667-21.333334l-66.133333-185.6V661.333333c0 6.4 4.266667 10.666667 10.666667 10.666667z m573.866666-576H172.8l104.533333 298.666667h571.733334l-104.533334-298.666667z" horiz-adv-x="1024" />
<glyph glyph-name="forward" unicode="&#59056;" d="M853.333333 138.666667H170.666667c-6.4 0-10.666667 4.266667-10.666667 10.666666V576c0 6.4 4.266667 10.666667 10.666667 10.666667h599.466666l-83.2-83.2c-12.8-12.8-12.8-34.133333 0-46.933334 6.4-6.4 14.933333-10.666667 23.466667-10.666666s17.066667 4.266667 23.466667 10.666666l145.066666 145.066667c12.8 12.8 12.8 34.133333 0 46.933333l-145.066666 145.066667c-12.8 12.8-34.133333 12.8-46.933334 0-12.8-12.8-12.8-34.133333 0-46.933333l93.866667-93.866667H170.666667c-40.533333 0-74.666667-34.133333-74.666667-74.666667v-426.666666c0-40.533333 34.133333-74.666667 74.666667-74.666667h682.666666c17.066667 0 32 14.933333 32 32s-14.933333 29.866667-32 29.866667z" horiz-adv-x="1024" />
<glyph glyph-name="import" unicode="&#59057;" d="M667.733333 32H170.666667c-6.4 0-10.666667 4.266667-10.666667 10.666667V725.333333c0 6.4 4.266667 10.666667 10.666667 10.666667h309.333333V576c0-40.533333 34.133333-74.666667 74.666667-74.666667h160v-38.4c0-17.066667 14.933333-32 32-32s32 14.933333 32 32V597.333333c0 8.533333-4.266667 17.066667-8.533334 23.466667l-170.666666 170.666667c-6.4 6.4-14.933333 8.533333-23.466667 8.533333H170.666667C130.133333 800 96 765.866667 96 725.333333v-682.666666c0-40.533333 34.133333-74.666667 74.666667-74.666667h497.066666c17.066667 0 32 14.933333 32 32s-14.933333 32-32 32z m46.933334 550.4v-17.066667H554.666667c-6.4 0-10.666667 4.266667-10.666667 10.666667V736h19.2l151.466667-153.6zM853.333333 298.666667H599.466667l51.2 51.2c12.8 12.8 12.8 32 0 44.8-12.8 12.8-32 12.8-44.8 0l-106.666667-106.666667c-12.8-12.8-12.8-32 0-44.8l106.666667-106.666667c6.4-6.4 14.933333-8.533333 23.466666-8.533333s17.066667 2.133333 23.466667 8.533333c12.8 12.8 12.8 32 0 44.8L599.466667 234.666667H853.333333c17.066667 0 32 14.933333 32 32S870.4 298.666667 853.333333 298.666667z" horiz-adv-x="1024" />
<glyph glyph-name="link" unicode="&#59058;" d="M861.866667 731.733333c-87.466667 87.466667-230.4 89.6-320 2.133334l-68.266667-68.266667c-12.8-12.8-12.8-32 0-44.8s32-12.8 44.8 0l68.266667 68.266667c64 61.866667 166.4 61.866667 230.4-2.133334 64-64 64-168.533333 2.133333-232.533333l-117.333333-119.466667c-34.133333-34.133333-81.066667-51.2-128-49.066666-46.933333 4.266667-91.733333 27.733333-119.466667 66.133333-10.666667 14.933333-29.866667 17.066667-44.8 6.4-14.933333-10.666667-17.066667-29.866667-6.4-44.8 40.533333-53.333333 100.266667-87.466667 166.4-91.733333h17.066667c59.733333 0 119.466667 23.466667 162.133333 68.266666l117.333333 119.466667c83.2 89.6 83.2 234.666667-4.266666 322.133333zM505.6 145.066667l-66.133333-68.266667c-64-61.866667-166.4-61.866667-230.4 2.133333-64 64-64 168.533333-2.133334 232.533334l117.333334 119.466666c34.133333 34.133333 81.066667 51.2 128 49.066667 46.933333-4.266667 91.733333-27.733333 119.466666-66.133333 10.666667-14.933333 29.866667-17.066667 44.8-6.4 14.933333 10.666667 17.066667 29.866667 6.4 44.8-40.533333 53.333333-100.266667 87.466667-166.4 91.733333-66.133333 4.266667-130.133333-19.2-177.066666-66.133333l-117.333334-119.466667c-85.333333-89.6-85.333333-234.666667 2.133334-322.133333 44.8-44.8 102.4-66.133333 162.133333-66.133334 57.6 0 115.2 21.333333 160 64l66.133333 68.266667c12.8 12.8 12.8 32 0 44.8-14.933333 10.666667-34.133333 10.666667-46.933333-2.133333z" horiz-adv-x="1024" />
<glyph glyph-name="layout" unicode="&#59059;" d="M853.333333 800H170.666667C130.133333 800 96 765.866667 96 725.333333v-682.666666c0-40.533333 34.133333-74.666667 74.666667-74.666667h682.666666c40.533333 0 74.666667 34.133333 74.666667 74.666667V725.333333c0 40.533333-34.133333 74.666667-74.666667 74.666667z m-682.666666-64h682.666666c6.4 0 10.666667-4.266667 10.666667-10.666667v-213.333333h-704V725.333333c0 6.4 4.266667 10.666667 10.666667 10.666667zM160 42.666667V448H341.333333v-416H170.666667c-6.4 0-10.666667 4.266667-10.666667 10.666667z m693.333333-10.666667H405.333333V448h458.666667v-405.333333c0-6.4-4.266667-10.666667-10.666667-10.666667z" horiz-adv-x="1024" />
<glyph glyph-name="fullscreen-shrink" unicode="&#59060;" d="M313.6 537.6H177.066667c-17.066667 0-32-14.933333-32-32s14.933333-32 32-32h213.333333c4.266667 0 8.533333 0 10.666667 2.133333 8.533333 4.266667 14.933333 8.533333 17.066666 17.066667 2.133333 4.266667 2.133333 8.533333 2.133334 10.666667v213.333333c0 17.066667-14.933333 32-32 32s-32-14.933333-32-32v-136.533333L172.8 770.133333c-12.8 12.8-32 12.8-44.8 0-12.8-12.8-12.8-32 0-44.8l185.6-187.733333zM695.466667 245.333333H832c17.066667 0 32 14.933333 32 32s-14.933333 32-32 32H618.666667c-4.266667 0-8.533333 0-10.666667-2.133333-8.533333-4.266667-14.933333-8.533333-17.066667-17.066667-2.133333-4.266667-2.133333-8.533333-2.133333-10.666666v-213.333334c0-17.066667 14.933333-32 32-32s32 14.933333 32 32v136.533334l200.533333-200.533334c6.4-6.4 14.933333-8.533333 23.466667-8.533333s17.066667 2.133333 23.466667 8.533333c12.8 12.8 12.8 32 0 44.8l-204.8 198.4zM435.2 290.133333c-4.266667 8.533333-8.533333 14.933333-17.066667 17.066667-4.266667 2.133333-8.533333 2.133333-10.666666 2.133333H192c-17.066667 0-32-14.933333-32-32s14.933333-32 32-32h136.533333L128 44.8c-12.8-12.8-12.8-32 0-44.8 6.4-6.4 14.933333-8.533333 23.466667-8.533333s17.066667 2.133333 23.466666 8.533333l200.533334 200.533333V64c0-17.066667 14.933333-32 32-32s32 14.933333 32 32V277.333333c-2.133333 4.266667-2.133333 8.533333-4.266667 12.8zM603.733333 492.8c4.266667-8.533333 8.533333-14.933333 17.066667-17.066667 4.266667-2.133333 8.533333-2.133333 10.666667-2.133333h213.333333c17.066667 0 32 14.933333 32 32s-14.933333 32-32 32h-136.533333L896 725.333333c12.8 12.8 12.8 32 0 44.8-12.8 12.8-32 12.8-44.8 0l-187.733333-187.733333V718.933333c0 17.066667-14.933333 32-32 32s-32-14.933333-32-32v-213.333333c2.133333-4.266667 2.133333-8.533333 4.266666-12.8z" horiz-adv-x="1024" />
<glyph glyph-name="layers" unicode="&#59061;" d="M110.933333 544l384-192c4.266667-2.133333 10.666667-4.266667 17.066667-4.266667s10.666667 2.133333 17.066667 4.266667l384 192c12.8 6.4 19.2 19.2 19.2 32s-8.533333 25.6-19.2 32l-384 192c-10.666667 4.266667-21.333333 4.266667-32 0l-384-192c-12.8-6.4-19.2-19.2-19.2-32s6.4-25.6 17.066666-32zM512 727.466667L814.933333 576 512 424.533333 209.066667 576 512 727.466667zM878.933333 224L512 40.533333 145.066667 224c-17.066667 8.533333-38.4 2.133333-49.066667-17.066667-8.533333-17.066667-2.133333-38.4 17.066667-49.066666l384-192c4.266667-2.133333 10.666667-4.266667 17.066666-4.266667s10.666667 2.133333 17.066667 4.266667l384 192c17.066667 8.533333 25.6 29.866667 17.066667 49.066666-12.8 19.2-34.133333 25.6-53.333334 17.066667zM878.933333 416L512 232.533333 145.066667 416c-17.066667 8.533333-38.4 2.133333-49.066667-17.066667-8.533333-17.066667-2.133333-38.4 17.066667-49.066666l384-192c4.266667-2.133333 10.666667-4.266667 17.066666-4.266667s10.666667 2.133333 17.066667 4.266667l384 192c17.066667 8.533333 25.6 29.866667 17.066667 49.066666-12.8 19.2-34.133333 25.6-53.333334 17.066667z" horiz-adv-x="1024" />
<glyph glyph-name="lock" unicode="&#59062;" d="M785.066667 480h-61.866667v121.6c0 108.8-91.733333 198.4-202.666667 198.4s-202.666667-89.6-202.666666-198.4v-121.6h-78.933334c-55.466667 0-100.266667-44.8-100.266666-100.266667v-311.466666c0-55.466667 44.8-100.266667 100.266666-100.266667h546.133334c55.466667 0 100.266667 44.8 100.266666 100.266667V379.733333c0 55.466667-44.8 100.266667-100.266666 100.266667z m-403.2 121.6c0 74.666667 61.866667 134.4 138.666666 134.4s138.666667-59.733333 138.666667-134.4v-121.6h-277.333333v121.6z m439.466666-533.333333c0-19.2-17.066667-36.266667-36.266666-36.266667H238.933333c-19.2 0-36.266667 17.066667-36.266666 36.266667V379.733333c0 19.2 17.066667 36.266667 36.266666 36.266667h546.133334c19.2 0 36.266667-17.066667 36.266666-36.266667v-311.466666zM512 352c-17.066667 0-32-14.933333-32-32v-106.666667c0-17.066667 14.933333-32 32-32s32 14.933333 32 32v106.666667c0 17.066667-14.933333 32-32 32z" horiz-adv-x="1024" />
<glyph glyph-name="fullscreen-expand" unicode="&#59063;" d="M149.333333 501.333333c17.066667 0 32 14.933333 32 32v136.533334l187.733334-187.733334c6.4-6.4 14.933333-8.533333 23.466666-8.533333s17.066667 2.133333 23.466667 8.533333c12.8 12.8 12.8 32 0 44.8l-187.733333 187.733334H362.666667c17.066667 0 32 14.933333 32 32s-14.933333 32-32 32H149.333333c-4.266667 0-8.533333 0-10.666666-2.133334-8.533333-4.266667-14.933333-10.666667-19.2-17.066666-2.133333-4.266667-2.133333-8.533333-2.133334-12.8v-213.333334c0-17.066667 14.933333-32 32-32zM874.666667 266.666667c-17.066667 0-32-14.933333-32-32v-136.533334L642.133333 298.666667c-12.8 12.8-32 12.8-44.8 0s-12.8-32 0-44.8l200.533334-200.533334H661.333333c-17.066667 0-32-14.933333-32-32s14.933333-32 32-32h213.333334c4.266667 0 8.533333 0 10.666666 2.133334 8.533333 4.266667 14.933333 8.533333 17.066667 17.066666 2.133333 4.266667 2.133333 8.533333 2.133333 10.666667V234.666667c2.133333 17.066667-12.8 32-29.866666 32zM381.866667 300.8l-200.533334-200.533333V234.666667c0 17.066667-14.933333 32-32 32s-32-14.933333-32-32v-213.333334c0-4.266667 0-8.533333 2.133334-10.666666 4.266667-8.533333 8.533333-14.933333 17.066666-17.066667 4.266667-2.133333 8.533333-2.133333 10.666667-2.133333h213.333333c17.066667 0 32 14.933333 32 32s-14.933333 32-32 32h-136.533333l200.533333 200.533333c12.8 12.8 12.8 32 0 44.8s-29.866667 10.666667-42.666666 0zM904.533333 757.333333c0 2.133333 0 2.133333 0 0-4.266667 8.533333-10.666667 14.933333-17.066666 17.066667-4.266667 2.133333-8.533333 2.133333-10.666667 2.133333H661.333333c-17.066667 0-32-14.933333-32-32s14.933333-32 32-32h136.533334l-187.733334-187.733333c-12.8-12.8-12.8-32 0-44.8 6.4-6.4 14.933333-8.533333 23.466667-8.533333s17.066667 2.133333 23.466667 8.533333l187.733333 187.733333V533.333333c0-17.066667 14.933333-32 32-32s32 14.933333 32 32V746.666667c-2.133333 4.266667-2.133333 8.533333-4.266667 10.666666z" horiz-adv-x="1024" />
<glyph glyph-name="map" unicode="&#59064;" d="M512 821.333333C317.866667 821.333333 160 661.333333 160 467.2c0-264.533333 320-484.266667 334.933333-492.8 6.4-4.266667 10.666667-6.4 17.066667-6.4s12.8 2.133333 17.066667 6.4c12.8 8.533333 334.933333 228.266667 334.933333 492.8C864 661.333333 706.133333 821.333333 512 821.333333z m0-782.933333c-66.133333 49.066667-288 228.266667-288 426.666667 0 160 130.133333 290.133333 288 290.133333s288-130.133333 288-290.133333c0-196.266667-221.866667-377.6-288-426.666667zM512 586.666667c-76.8 0-138.666667-61.866667-138.666667-138.666667s61.866667-138.666667 138.666667-138.666667 138.666667 61.866667 138.666667 138.666667-61.866667 138.666667-138.666667 138.666667z m0-213.333334c-40.533333 0-74.666667 34.133333-74.666667 74.666667s34.133333 74.666667 74.666667 74.666667 74.666667-34.133333 74.666667-74.666667-34.133333-74.666667-74.666667-74.666667z" horiz-adv-x="1024" />
<glyph glyph-name="meh" unicode="&#59065;" d="M512-53.333333C270.933333-53.333333 74.666667 142.933333 74.666667 384S270.933333 821.333333 512 821.333333 949.333333 625.066667 949.333333 384 753.066667-53.333333 512-53.333333z m0 810.666666C307.2 757.333333 138.666667 588.8 138.666667 384S307.2 10.666667 512 10.666667 885.333333 179.2 885.333333 384 716.8 757.333333 512 757.333333zM362.666667 384c-23.466667 0-42.666667 19.2-42.666667 42.666667v64c0 23.466667 19.2 42.666667 42.666667 42.666666s42.666667-19.2 42.666666-42.666666v-64c0-23.466667-19.2-42.666667-42.666666-42.666667zM661.333333 384c-23.466667 0-42.666667 19.2-42.666666 42.666667v64c0 23.466667 19.2 42.666667 42.666666 42.666666s42.666667-19.2 42.666667-42.666666v-64c0-23.466667-19.2-42.666667-42.666667-42.666667zM699.733333 181.333333H324.266667c-17.066667 0-32 14.933333-32 32s14.933333 32 32 32h373.333333c17.066667 0 32-14.933333 32-32s-12.8-32-29.866667-32z" horiz-adv-x="1024" />
<glyph glyph-name="menu" unicode="&#59066;" d="M170.666667 682.666667m-64 0a64 64 0 1 1 128 0 64 64 0 1 1-128 0ZM170.666667 384m-64 0a64 64 0 1 1 128 0 64 64 0 1 1-128 0ZM170.666667 85.333333m-64 0a64 64 0 1 1 128 0 64 64 0 1 1-128 0ZM896 117.333333H362.666667c-17.066667 0-32-14.933333-32-32s14.933333-32 32-32h533.333333c17.066667 0 32 14.933333 32 32s-14.933333 32-32 32zM362.666667 650.666667h533.333333c17.066667 0 32 14.933333 32 32s-14.933333 32-32 32H362.666667c-17.066667 0-32-14.933333-32-32s14.933333-32 32-32zM896 416H362.666667c-17.066667 0-32-14.933333-32-32s14.933333-32 32-32h533.333333c17.066667 0 32 14.933333 32 32s-14.933333 32-32 32z" horiz-adv-x="1024" />
<glyph glyph-name="loading" unicode="&#59067;" d="M512 821.333333c-17.066667 0-32-14.933333-32-32v-149.333333c0-17.066667 14.933333-32 32-32s32 14.933333 32 32V789.333333c0 17.066667-14.933333 32-32 32zM693.333333 533.333333c8.533333 0 17.066667 2.133333 23.466667 8.533334l104.533333 104.533333c12.8 12.8 12.8 32 0 44.8-12.8 12.8-32 12.8-44.8 0l-104.533333-104.533333c-12.8-12.8-12.8-32 0-44.8 4.266667-6.4 12.8-8.533333 21.333333-8.533334zM917.333333 416h-149.333333c-17.066667 0-32-14.933333-32-32s14.933333-32 32-32h149.333333c17.066667 0 32 14.933333 32 32s-14.933333 32-32 32zM714.666667 226.133333c-12.8 12.8-32 12.8-44.8 0s-12.8-32 0-44.8l104.533333-104.533333c6.4-6.4 14.933333-8.533333 23.466667-8.533333s17.066667 2.133333 23.466666 8.533333c12.8 12.8 12.8 32 0 44.8l-106.666666 104.533333zM512 160c-17.066667 0-32-14.933333-32-32v-149.333333c0-17.066667 14.933333-32 32-32s32 14.933333 32 32v149.333333c0 17.066667-14.933333 32-32 32zM309.333333 226.133333l-104.533333-104.533333c-12.8-12.8-12.8-32 0-44.8 6.4-6.4 14.933333-8.533333 23.466667-8.533333s17.066667 2.133333 23.466666 8.533333l104.533334 104.533333c12.8 12.8 12.8 32 0 44.8s-36.266667 12.8-46.933334 0zM288 384c0 17.066667-14.933333 32-32 32H106.666667c-17.066667 0-32-14.933333-32-32s14.933333-32 32-32h149.333333c17.066667 0 32 14.933333 32 32zM247.466667 693.333333c-12.8 12.8-32 12.8-44.8 0-12.8-12.8-12.8-32 0-44.8l104.533333-104.533333c6.4-6.4 14.933333-8.533333 23.466667-8.533333s17.066667 2.133333 23.466666 8.533333c12.8 12.8 12.8 32 0 44.8l-106.666666 104.533333z" horiz-adv-x="1024" />
<glyph glyph-name="help" unicode="&#59068;" d="M512 821.333333C270.933333 821.333333 74.666667 625.066667 74.666667 384S270.933333-53.333333 512-53.333333 949.333333 142.933333 949.333333 384 753.066667 821.333333 512 821.333333z m0-810.666666c-204.8 0-373.333333 168.533333-373.333333 373.333333S307.2 757.333333 512 757.333333 885.333333 588.8 885.333333 384 716.8 10.666667 512 10.666667zM512 149.333333m-42.666667 0a42.666667 42.666667 0 1 1 85.333334 0 42.666667 42.666667 0 1 1-85.333334 0ZM512 650.666667c-76.8 0-138.666667-61.866667-138.666667-138.666667 0-17.066667 14.933333-32 32-32s32 14.933333 32 32c0 40.533333 34.133333 74.666667 74.666667 74.666667s74.666667-34.133333 74.666667-74.666667c0-27.733333-53.333333-76.8-91.733334-100.266667-8.533333-6.4-14.933333-17.066667-14.933333-27.733333v-106.666667c0-17.066667 14.933333-32 32-32s32 14.933333 32 32v89.6c34.133333 25.6 106.666667 83.2 106.666667 145.066667 0 76.8-61.866667 138.666667-138.666667 138.666667z" horiz-adv-x="1024" />
<glyph glyph-name="modular" unicode="&#59069;" d="M405.333333 437.333333H149.333333c-29.866667 0-53.333333 23.466667-53.333333 53.333334V746.666667c0 29.866667 23.466667 53.333333 53.333333 53.333333h256c29.866667 0 53.333333-23.466667 53.333334-53.333333v-256c0-29.866667-23.466667-53.333333-53.333334-53.333334z m-245.333333 64h234.666667v234.666667h-234.666667v-234.666667zM874.666667 437.333333H618.666667c-29.866667 0-53.333333 23.466667-53.333334 53.333334V746.666667c0 29.866667 23.466667 53.333333 53.333334 53.333333h256c29.866667 0 53.333333-23.466667 53.333333-53.333333v-256c0-29.866667-23.466667-53.333333-53.333333-53.333334z m-245.333334 64h234.666667v234.666667h-234.666667v-234.666667zM874.666667-32H618.666667c-29.866667 0-53.333333 23.466667-53.333334 53.333333V277.333333c0 29.866667 23.466667 53.333333 53.333334 53.333334h256c29.866667 0 53.333333-23.466667 53.333333-53.333334v-256c0-29.866667-23.466667-53.333333-53.333333-53.333333z m-245.333334 64h234.666667v234.666667h-234.666667v-234.666667zM405.333333-32H149.333333c-29.866667 0-53.333333 23.466667-53.333333 53.333333V277.333333c0 29.866667 23.466667 53.333333 53.333333 53.333334h256c29.866667 0 53.333333-23.466667 53.333334-53.333334v-256c0-29.866667-23.466667-53.333333-53.333334-53.333333z m-245.333333 64h234.666667v234.666667h-234.666667v-234.666667z" horiz-adv-x="1024" />
<glyph glyph-name="notification" unicode="&#59070;" d="M800 270.933333V448c0 117.333333-70.4 217.6-170.666667 262.4-4.266667 61.866667-55.466667 110.933333-117.333333 110.933333s-113.066667-49.066667-117.333333-110.933333c-100.266667-44.8-170.666667-145.066667-170.666667-262.4v-177.066667c-57.6-46.933333-85.333333-110.933333-85.333333-185.6 0-17.066667 14.933333-32 32-32h206.933333c14.933333-61.866667 70.4-106.666667 134.4-106.666666s119.466667 44.8 134.4 106.666666H853.333333c17.066667 0 32 14.933333 32 32 0 76.8-27.733333 138.666667-85.333333 185.6zM512 757.333333c19.2 0 36.266667-10.666667 44.8-25.6-14.933333 2.133333-29.866667 4.266667-44.8 4.266667-14.933333 0-29.866667-2.133333-44.8-4.266667 8.533333 14.933333 25.6 25.6 44.8 25.6z m0-746.666666c-29.866667 0-55.466667 17.066667-66.133333 42.666666h134.4c-12.8-25.6-38.4-42.666667-68.266667-42.666666z m-307.2 106.666666c6.4 46.933333 29.866667 83.2 70.4 113.066667 8.533333 6.4 12.8 14.933333 12.8 25.6v192c0 123.733333 100.266667 224 224 224S736 571.733333 736 448v-192c0-10.666667 4.266667-19.2 12.8-25.6 40.533333-29.866667 64-66.133333 70.4-113.066667H204.8z" horiz-adv-x="1024" />
<glyph glyph-name="mic" unicode="&#59071;" d="M516.266667 238.933333c78.933333 0 142.933333 64 142.933333 142.933334V678.4a142.933333 142.933333 0 0 1-285.866667 0v-296.533333c0-78.933333 64-142.933333 142.933334-142.933334z m-78.933334 439.466667c0 42.666667 36.266667 78.933333 78.933334 78.933333s78.933333-36.266667 78.933333-78.933333v-296.533333c0-42.666667-36.266667-78.933333-78.933333-78.933334s-78.933333 36.266667-78.933334 78.933334V678.4zM774.4 486.4c-17.066667 0-32-14.933333-32-32v-74.666667c0-125.866667-102.4-228.266667-228.266667-228.266666S288 256 288 381.866667v74.666666c0 17.066667-14.933333 32-32 32s-32-14.933333-32-32v-74.666666c0-149.333333 113.066667-273.066667 260.266667-290.133334v-85.333333h-117.333334c-17.066667 0-32-14.933333-32-32s14.933333-32 32-32h296.533334c17.066667 0 32 14.933333 32 32s-14.933333 32-32 32h-117.333334v85.333333c145.066667 14.933333 260.266667 140.8 260.266667 290.133334v74.666666c0 17.066667-12.8 29.866667-32 29.866667z" horiz-adv-x="1024" />
<glyph glyph-name="operation" unicode="&#59073;" d="M823.466667 384H578.133333v187.733333c0 66.133333-53.333333 119.466667-117.333333 119.466667s-117.333333-53.333333-117.333333-119.466667v-296.533333l-21.333334 21.333333c-46.933333 46.933333-121.6 46.933333-168.533333 2.133334s-44.8-121.6 2.133333-168.533334l174.933334-174.933333c6.4-6.4 14.933333-8.533333 23.466666-8.533333 8.533333 0 17.066667 2.133333 23.466667 8.533333 12.8 12.8 12.8 32 0 44.8l-174.933333 174.933333c-21.333333 21.333333-23.466667 57.6-2.133334 76.8 21.333333 21.333333 55.466667 19.2 76.8-2.133333l74.666667-74.666667c12.8-12.8 32-12.8 44.8 0 6.4 6.4 8.533333 14.933333 8.533333 23.466667V569.6c0 29.866667 23.466667 55.466667 53.333334 55.466667s53.333333-25.6 53.333333-55.466667v-219.733333c0-17.066667 14.933333-32 32-32h277.333333c6.4 0 10.666667-6.4 10.666667-12.8V-21.333333c0-17.066667 14.933333-32 32-32S896-38.4 896-21.333333V309.333333c2.133333 40.533333-32 74.666667-72.533333 74.666667zM266.666667 565.333333c17.066667 0 32 14.933333 32 32 0 87.466667 72.533333 160 160 160S618.666667 684.8 618.666667 597.333333c0-17.066667 14.933333-32 32-32S682.666667 580.266667 682.666667 597.333333c0 123.733333-100.266667 224-224 224S234.666667 721.066667 234.666667 597.333333c0-17.066667 14.933333-32 32-32z" horiz-adv-x="1024" />
<glyph glyph-name="print" unicode="&#59074;" d="M819.2 531.2h-44.8V768c0 17.066667-14.933333 32-32 32H281.6c-17.066667 0-32-14.933333-32-32v-236.8H204.8c-59.733333 0-108.8-49.066667-108.8-108.8v-192c0-59.733333 49.066667-108.8 108.8-108.8h44.8V0c0-17.066667 14.933333-32 32-32h460.8c17.066667 0 32 14.933333 32 32v121.6h44.8c59.733333 0 108.8 49.066667 108.8 108.8v192c0 59.733333-49.066667 108.8-108.8 108.8zM313.6 736h396.8v-204.8H313.6V736z m396.8-704H313.6V275.2h396.8v-243.2z m153.6 198.4c0-25.6-19.2-44.8-44.8-44.8h-44.8v121.6c0 17.066667-14.933333 32-32 32H281.6c-17.066667 0-32-14.933333-32-32v-121.6H204.8c-25.6 0-44.8 19.2-44.8 44.8v192c0 25.6 19.2 44.8 44.8 44.8h614.4c25.6 0 44.8-19.2 44.8-44.8v-192z" horiz-adv-x="1024" />
<glyph glyph-name="mobile-phone" unicode="&#59075;" d="M746.666667-53.333333H277.333333c-40.533333 0-74.666667 34.133333-74.666666 74.666666V746.666667c0 40.533333 34.133333 74.666667 74.666666 74.666666h469.333334c40.533333 0 74.666667-34.133333 74.666666-74.666666v-725.333334c0-40.533333-34.133333-74.666667-74.666666-74.666666z m-469.333334 810.666666c-6.4 0-10.666667-4.266667-10.666666-10.666666v-725.333334c0-6.4 4.266667-10.666667 10.666666-10.666666h469.333334c6.4 0 10.666667 4.266667 10.666666 10.666666V746.666667c0 6.4-4.266667 10.666667-10.666666 10.666666H277.333333zM512 128m-42.666667 0a42.666667 42.666667 0 1 1 85.333334 0 42.666667 42.666667 0 1 1-85.333334 0ZM597.333333 650.666667h-170.666666c-17.066667 0-32 14.933333-32 32s14.933333 32 32 32h170.666666c17.066667 0 32-14.933333 32-32s-14.933333-32-32-32z" horiz-adv-x="1024" />
<glyph glyph-name="navigation" unicode="&#59076;" d="M834.133333 682.666667c-6.4 12.8-17.066667 23.466667-29.866666 27.733333-12.8 4.266667-27.733333 4.266667-40.533334-2.133333L106.666667 394.666667c-14.933333-6.4-25.6-21.333333-29.866667-36.266667-6.4-27.733333 12.8-57.6 40.533333-64l249.6-53.333333 53.333334-249.6c4.266667-17.066667 14.933333-29.866667 29.866666-36.266667 6.4-4.266667 14.933333-4.266667 23.466667-4.266667 19.2 0 38.4 10.666667 49.066667 29.866667l313.6 657.066667c6.4 12.8 6.4 29.866667-2.133334 44.8zM477.866667 34.133333L426.666667 273.066667c-2.133333 12.8-12.8 21.333333-23.466667 23.466666L162.133333 349.866667l601.6 288-285.866666-603.733334z" horiz-adv-x="1024" />
<glyph glyph-name="move" unicode="&#59077;" d="M921.6 403.2l-121.6 121.6c-12.8 12.8-32 12.8-44.8 0s-12.8-32 0-44.8l66.133333-66.133333h-277.333333v277.333333l66.133333-66.133333c6.4-6.4 14.933333-8.533333 23.466667-8.533334s17.066667 2.133333 23.466667 8.533334c12.8 12.8 12.8 32 0 44.8l-121.6 121.6c-12.8 12.8-32 12.8-44.8 0l-121.6-121.6c-12.8-12.8-12.8-32 0-44.8 12.8-12.8 32-12.8 44.8 0l66.133333 66.133333v-277.333333h-277.333333l66.133333 66.133333c12.8 12.8 12.8 32 0 44.8-12.8 12.8-32 12.8-44.8 0l-121.6-121.6c-12.8-12.8-12.8-32 0-44.8l121.6-121.6c6.4-6.4 14.933333-8.533333 23.466667-8.533333s17.066667 2.133333 23.466666 8.533333c12.8 12.8 12.8 32 0 44.8l-66.133333 66.133333h277.333333v-277.333333l-66.133333 66.133333c-12.8 12.8-32 12.8-44.8 0s-12.8-32 0-44.8l121.6-121.6c6.4-6.4 14.933333-8.533333 23.466667-8.533333s17.066667 2.133333 23.466666 8.533333l121.6 121.6c12.8 12.8 12.8 32 0 44.8s-32 12.8-44.8 0l-66.133333-66.133333v277.333333h277.333333l-66.133333-66.133333c-12.8-12.8-12.8-32 0-44.8 6.4-6.4 14.933333-8.533333 23.466667-8.533333s17.066667 2.133333 23.466666 8.533333l121.6 121.6c6.4 6.4 8.533333 14.933333 8.533334 23.466667s-10.666667 14.933333-17.066667 21.333333z" horiz-adv-x="1024" />
<glyph glyph-name="refresh" unicode="&#59078;" d="M934.4 689.066667c-17.066667 4.266667-34.133333-6.4-38.4-23.466667l-23.466667-87.466667C797.866667 712.533333 654.933333 800 497.066667 800 264.533333 800 74.666667 614.4 74.666667 384s189.866667-416 422.4-416c179.2 0 339.2 110.933333 398.933333 275.2 6.4 17.066667-2.133333 34.133333-19.2 40.533333-17.066667 6.4-34.133333-2.133333-40.533333-19.2-51.2-138.666667-187.733333-232.533333-339.2-232.533333C298.666667 32 138.666667 189.866667 138.666667 384S300.8 736 497.066667 736c145.066667 0 277.333333-87.466667 330.666666-217.6l-128 36.266667c-17.066667 4.266667-34.133333-6.4-38.4-23.466667-4.266667-17.066667 6.4-34.133333 23.466667-38.4l185.6-49.066667c2.133333 0 6.4-2.133333 8.533333-2.133333 6.4 0 10.666667 2.133333 17.066667 4.266667 6.4 4.266667 12.8 10.666667 14.933333 19.2l49.066667 185.6c0 17.066667-8.533333 34.133333-25.6 38.4z" horiz-adv-x="1024" />
<glyph glyph-name="run-up" unicode="&#59079;" d="M409.6 601.338776l71.053061 71.053061v-248.685715c0-16.718367 14.628571-31.346939 31.346939-31.346938s31.346939 14.628571 31.346939 31.346938v250.775511l71.053061-71.053062c6.269388-6.269388 14.628571-8.359184 22.987755-8.359183s16.718367 2.089796 22.987755 8.359183c12.538776 12.538776 12.538776 31.346939 0 43.885715l-125.387755 125.387755c-12.538776 12.538776-31.346939 12.538776-43.885714 0l-125.387755-125.387755c-12.538776-12.538776-12.538776-31.346939 0-43.885715 10.44898-12.538776 31.346939-12.538776 43.885714-2.089795zM936.228571 444.604082l-242.416326 81.50204c-16.718367 6.269388-33.436735-4.179592-39.706123-18.808163-6.269388-16.718367 4.179592-33.436735 18.808164-39.706122l156.734694-52.244898L512 302.497959 194.35102 415.346939l156.734694 52.244898c16.718367 6.269388 25.077551 22.987755 18.808164 39.706122-6.269388 16.718367-22.987755 25.077551-39.706123 18.808163L87.771429 444.604082c-12.538776-4.179592-20.897959-16.718367-20.89796-29.257143 0-12.538776 8.359184-25.077551 20.89796-29.257143l413.779591-146.285714c4.179592-2.089796 6.269388-2.089796 10.44898-2.089796s6.269388 0 10.44898 2.089796l413.779591 146.285714c12.538776 4.179592 20.897959 16.718367 20.89796 29.257143 0 14.628571-8.359184 25.077551-20.89796 29.257143zM512 181.289796c-16.718367 0-31.346939-14.628571-31.346939-31.346939v-156.734694c0-16.718367 14.628571-31.346939 31.346939-31.346939s31.346939 14.628571 31.346939 31.346939v156.734694c0 16.718367-14.628571 31.346939-31.346939 31.346939z" horiz-adv-x="1024" />
<glyph glyph-name="picture" unicode="&#59080;" d="M819.2 800H204.8c-59.733333 0-108.8-49.066667-108.8-108.8v-616.533333c0-59.733333 49.066667-108.8 108.8-108.8h616.533333c59.733333 0 108.8 49.066667 108.8 108.8V691.2c-2.133333 59.733333-51.2 108.8-110.933333 108.8zM160 76.8V691.2c0 23.466667 19.2 44.8 44.8 44.8h616.533333c23.466667 0 44.8-19.2 44.8-44.8v-388.266667l-125.866666 125.866667c-27.733333 27.733333-76.8 27.733333-104.533334 0l-390.4-384c-4.266667-4.266667-6.4-8.533333-6.4-12.8H204.8c-25.6 0-44.8 19.2-44.8 44.8z m659.2-44.8H324.266667l354.133333 354.133333c2.133333 2.133333 6.4 2.133333 8.533333 2.133334s4.266667 0 8.533334-2.133334l160-160c4.266667-4.266667 8.533333-6.4 12.8-6.4v-142.933333c-4.266667-25.6-23.466667-44.8-49.066667-44.8zM375.466667 413.866667c59.733333 0 106.666667 46.933333 106.666666 106.666666s-46.933333 106.666667-106.666666 106.666667-106.666667-46.933333-106.666667-106.666667 49.066667-106.666667 106.666667-106.666666z m0 149.333333c23.466667 0 42.666667-19.2 42.666666-42.666667s-19.2-42.666667-42.666666-42.666666-42.666667 19.2-42.666667 42.666666 19.2 42.666667 42.666667 42.666667z" horiz-adv-x="1024" />
<glyph glyph-name="run-in" unicode="&#59081;" d="M612.352 130.048l-69.632-69.632V179.2c0 16.384-14.336 30.72-30.72 30.72s-30.72-14.336-30.72-30.72v-120.832l-69.632 69.632c-12.288 12.288-30.72 12.288-43.008 0s-12.288-30.72 0-43.008l122.88-122.88c6.144-6.144 14.336-8.192 22.528-8.192s16.384 2.048 22.528 8.192l122.88 122.88c12.288 12.288 12.288 30.72 0 43.008s-34.816 12.288-47.104 2.048zM927.744 474.112l-237.568 79.872c-16.384 6.144-32.768-4.096-38.912-18.432-6.144-16.384 4.096-32.768 18.432-38.912l153.6-51.2L512 334.848 200.704 445.44l153.6 51.2c16.384 6.144 24.576 22.528 18.432 38.912-6.144 16.384-22.528 24.576-38.912 18.432L96.256 474.112c-12.288-4.096-20.48-16.384-20.48-28.672 0-12.288 8.192-24.576 20.48-28.672l405.504-143.36c4.096-2.048 6.144-2.048 10.24-2.048s6.144 0 10.24 2.048l405.504 143.36c12.288 4.096 20.48 16.384 20.48 28.672 0 14.336-8.192 24.576-20.48 28.672zM512 394.24c16.384 0 30.72 14.336 30.72 30.72V742.4c0 16.384-14.336 30.72-30.72 30.72s-30.72-14.336-30.72-30.72V424.96c0-16.384 14.336-30.72 30.72-30.72z" horiz-adv-x="1024" />
<glyph glyph-name="pin" unicode="&#59082;" d="M911.15102 572.081633L689.632653 793.6c-18.808163 18.808163-50.155102 20.897959-71.053061 2.089796l-267.493878-229.877551-96.130612-14.628572c-6.269388 0-12.538776-4.179592-16.718367-8.359183l-58.514286-58.514286c-20.897959-20.897959-20.897959-54.334694 0-73.142857l152.555102-152.555102L125.387755 51.722449c-12.538776-12.538776-12.538776-31.346939 0-43.885714 6.269388-6.269388 14.628571-10.44898 20.897959-10.44898s16.718367 2.089796 22.987755 8.359184l204.8 204.8 152.555102-152.555102c10.44898-10.44898 22.987755-14.628571 37.616327-14.628572s27.167347 6.269388 37.616326 14.628572l58.514286 58.514285c4.179592 4.179592 8.359184 10.44898 8.359184 16.718368l14.628571 96.130612 227.787755 267.493878c18.808163 25.077551 18.808163 56.42449 0 75.232653zM631.118367 266.971429c-4.179592-4.179592-6.269388-10.44898-6.269387-14.628572l-14.628572-94.040816-45.97551-45.97551-334.367347 334.367347 43.885714 43.885714 94.040817 14.628571c6.269388 0 10.44898 4.179592 14.628571 6.269388l269.583674 229.877551 206.889795-206.889796-227.787755-267.493877z" horiz-adv-x="1024" />
<glyph glyph-name="save" unicode="&#59083;" d="M906.666667 597.333333L725.333333 778.666667c-14.933333 14.933333-32 21.333333-53.333333 21.333333H170.666667C130.133333 800 96 765.866667 96 725.333333v-682.666666c0-40.533333 34.133333-74.666667 74.666667-74.666667h682.666666c40.533333 0 74.666667 34.133333 74.666667 74.666667V546.133333c0 19.2-8.533333 38.4-21.333333 51.2zM652.8 32H371.2V247.466667h281.6v-215.466667z m211.2 10.666667c0-6.4-4.266667-10.666667-10.666667-10.666667h-140.8V277.333333c0 17.066667-12.8 29.866667-29.866666 29.866667H341.333333c-17.066667 0-29.866667-12.8-29.866666-29.866667v-245.333333H170.666667c-6.4 0-10.666667 4.266667-10.666667 10.666667V725.333333c0 6.4 4.266667 10.666667 10.666667 10.666667h140.8V576c0-17.066667 12.8-29.866667 29.866666-29.866667h277.333334c17.066667 0 29.866667 12.8 29.866666 29.866667s-12.8 29.866667-29.866666 29.866667H371.2V736h302.933333c2.133333 0 6.4-2.133333 8.533334-2.133333l179.2-179.2c2.133333-2.133333 2.133333-4.266667 2.133333-8.533334V42.666667z" horiz-adv-x="1024" />
<glyph glyph-name="search" unicode="&#59084;" d="M945.066667-2.133333l-189.866667 189.866666c55.466667 64 87.466667 149.333333 87.466667 241.066667 0 204.8-168.533333 373.333333-373.333334 373.333333S96 631.466667 96 426.666667 264.533333 53.333333 469.333333 53.333333c91.733333 0 174.933333 34.133333 241.066667 87.466667l189.866667-189.866667c6.4-6.4 14.933333-8.533333 23.466666-8.533333s17.066667 2.133333 23.466667 8.533333c8.533333 12.8 8.533333 34.133333-2.133333 46.933334zM469.333333 117.333333C298.666667 117.333333 160 256 160 426.666667S298.666667 736 469.333333 736 778.666667 597.333333 778.666667 426.666667 640 117.333333 469.333333 117.333333z" horiz-adv-x="1024" />
<glyph glyph-name="share" unicode="&#59085;" d="M874.666667 352c-17.066667 0-32-14.933333-32-32v-256c0-6.4-4.266667-10.666667-10.666667-10.666667H192c-6.4 0-10.666667 4.266667-10.666667 10.666667V704c0 6.4 4.266667 10.666667 10.666667 10.666667h256c17.066667 0 32 14.933333 32 32s-14.933333 32-32 32H192C151.466667 778.666667 117.333333 744.533333 117.333333 704v-640c0-40.533333 34.133333-74.666667 74.666667-74.666667h640c40.533333 0 74.666667 34.133333 74.666667 74.666667V320c0 17.066667-14.933333 32-32 32zM874.666667 778.666667H640c-17.066667 0-32-14.933333-32-32s14.933333-32 32-32h157.866667L509.866667 428.8c-12.8-12.8-12.8-32 0-44.8 6.4-6.4 14.933333-8.533333 23.466666-8.533333s17.066667 2.133333 23.466667 8.533333l285.866667 285.866667V512c0-17.066667 14.933333-32 32-32s32 14.933333 32 32V746.666667c0 17.066667-14.933333 32-32 32z" horiz-adv-x="1024" />
<glyph glyph-name="scanning" unicode="&#59086;" d="M341.333333 32H170.666667c-6.4 0-10.666667 4.266667-10.666667 10.666667v170.666666c0 17.066667-14.933333 32-32 32s-32-14.933333-32-32v-170.666666c0-40.533333 34.133333-74.666667 74.666667-74.666667h170.666666c17.066667 0 32 14.933333 32 32s-14.933333 32-32 32zM896 245.333333c-17.066667 0-32-14.933333-32-32v-170.666666c0-6.4-4.266667-10.666667-10.666667-10.666667h-170.666666c-17.066667 0-32-14.933333-32-32s14.933333-32 32-32h170.666666c40.533333 0 74.666667 34.133333 74.666667 74.666667v170.666666c0 17.066667-14.933333 32-32 32zM128 522.666667c17.066667 0 32 14.933333 32 32V725.333333c0 6.4 4.266667 10.666667 10.666667 10.666667h170.666666c17.066667 0 32 14.933333 32 32s-14.933333 32-32 32H170.666667C130.133333 800 96 765.866667 96 725.333333v-170.666666c0-17.066667 14.933333-32 32-32zM853.333333 800h-170.666666c-17.066667 0-32-14.933333-32-32s14.933333-32 32-32h170.666666c6.4 0 10.666667-4.266667 10.666667-10.666667v-170.666666c0-17.066667 14.933333-32 32-32s32 14.933333 32 32V725.333333c0 40.533333-34.133333 74.666667-74.666667 74.666667zM896 426.666667H128c-17.066667 0-32-14.933333-32-32S110.933333 362.666667 128 362.666667h768c17.066667 0 32 14.933333 32 32S913.066667 426.666667 896 426.666667z" horiz-adv-x="1024" />
<glyph glyph-name="security" unicode="&#59087;" d="M814.933333 716.8L529.066667 817.066667c-10.666667 4.266667-23.466667 4.266667-34.133334 0L209.066667 716.8c-29.866667-10.666667-49.066667-38.4-49.066667-70.4V298.666667c0-194.133333 157.866667-352 352-352S864 104.533333 864 298.666667V646.4c0 32-19.2 61.866667-49.066667 70.4zM800 298.666667c0-157.866667-130.133333-288-288-288S224 140.8 224 298.666667V646.4c0 4.266667 2.133333 8.533333 6.4 10.666667L512 755.2l281.6-98.133333c4.266667-2.133333 6.4-6.4 6.4-10.666667V298.666667zM659.2 492.8l-192-194.133333-85.333333 68.266666c-12.8 10.666667-34.133333 8.533333-44.8-4.266666-10.666667-12.8-8.533333-34.133333 4.266666-44.8l106.666667-85.333334c6.4-4.266667 12.8-6.4 19.2-6.4 8.533333 0 17.066667 2.133333 23.466667 8.533334l213.333333 213.333333c12.8 12.8 12.8 32 0 44.8-10.666667 10.666667-32 10.666667-44.8 0z" horiz-adv-x="1024" />
<glyph glyph-name="select" unicode="&#59088;" d="M409.6 138.666667c-8.533333 0-17.066667 2.133333-23.466667 8.533333l-238.933333 234.666667c-12.8 12.8-12.8 32 0 44.8 12.8 12.8 32 12.8 44.8 0l215.466667-213.333334 422.4 428.8c12.8 12.8 32 12.8 44.8 0 12.8-12.8 12.8-32 0-44.8L430.933333 149.333333c-4.266667-8.533333-12.8-10.666667-21.333333-10.666666z" horiz-adv-x="1024" />
<glyph glyph-name="stop" unicode="&#59089;" d="M512 821.333333C270.933333 821.333333 74.666667 625.066667 74.666667 384S270.933333-53.333333 512-53.333333 949.333333 142.933333 949.333333 384 753.066667 821.333333 512 821.333333zM885.333333 384c0-85.333333-29.866667-164.266667-78.933333-228.266667l-533.333333 514.133334c64 55.466667 149.333333 87.466667 238.933333 87.466666 204.8 0 373.333333-168.533333 373.333333-373.333333z m-746.666666 0c0 91.733333 34.133333 174.933333 87.466666 241.066667l535.466667-516.266667c-66.133333-59.733333-153.6-98.133333-251.733333-98.133333-202.666667 0-371.2 168.533333-371.2 373.333333z" horiz-adv-x="1024" />
<glyph glyph-name="smile" unicode="&#59090;" d="M512 821.333333C270.933333 821.333333 74.666667 625.066667 74.666667 384S270.933333-53.333333 512-53.333333 949.333333 142.933333 949.333333 384 753.066667 821.333333 512 821.333333z m0-810.666666c-204.8 0-373.333333 168.533333-373.333333 373.333333S307.2 757.333333 512 757.333333 885.333333 588.8 885.333333 384 716.8 10.666667 512 10.666667zM674.133333 288c-46.933333-57.6-100.266667-85.333333-162.133333-85.333333s-115.2 27.733333-162.133333 85.333333c-10.666667 12.8-32 14.933333-44.8 4.266667-12.8-10.666667-14.933333-32-4.266667-44.8 59.733333-70.4 130.133333-106.666667 211.2-106.666667s151.466667 36.266667 211.2 106.666667c10.666667 12.8 8.533333 34.133333-4.266667 44.8-12.8 10.666667-34.133333 8.533333-44.8-4.266667zM362.666667 384c23.466667 0 42.666667 19.2 42.666666 42.666667v64c0 23.466667-19.2 42.666667-42.666666 42.666666s-42.666667-19.2-42.666667-42.666666v-64c0-23.466667 19.2-42.666667 42.666667-42.666667zM661.333333 384c23.466667 0 42.666667 19.2 42.666667 42.666667v64c0 23.466667-19.2 42.666667-42.666667 42.666666s-42.666667-19.2-42.666666-42.666666v-64c0-23.466667 19.2-42.666667 42.666666-42.666667z" horiz-adv-x="1024" />
<glyph glyph-name="switch" unicode="&#59091;" d="M128 373.333333c17.066667 0 32 14.933333 32 32v170.666667c0 6.4 4.266667 10.666667 10.666667 10.666667h652.8l-83.2-83.2c-12.8-12.8-12.8-34.133333 0-46.933334 6.4-6.4 14.933333-10.666667 23.466666-10.666666s17.066667 4.266667 23.466667 10.666666l145.066667 145.066667c12.8 12.8 12.8 34.133333 0 46.933333l-145.066667 145.066667c-12.8 12.8-34.133333 12.8-46.933333 0-12.8-12.8-12.8-34.133333 0-46.933333l93.866666-93.866667H170.666667c-40.533333 0-74.666667-34.133333-74.666667-74.666667v-170.666666c0-19.2 14.933333-34.133333 32-34.133334zM906.666667 394.666667c-17.066667 0-32-14.933333-32-32v-170.666667c0-6.4-4.266667-10.666667-10.666667-10.666667H211.2l83.2 83.2c12.8 12.8 12.8 34.133333 0 46.933334-12.8 12.8-34.133333 12.8-46.933333 0l-145.066667-145.066667c-12.8-12.8-12.8-34.133333 0-46.933333l145.066667-145.066667c6.4-6.4 14.933333-10.666667 23.466666-10.666667s17.066667 4.266667 23.466667 10.666667c12.8 12.8 12.8 34.133333 0 46.933333l-93.866667 93.866667h663.466667c40.533333 0 74.666667 34.133333 74.666667 74.666667v170.666666c0 19.2-12.8 34.133333-32 34.133334z" horiz-adv-x="1024" />
<glyph glyph-name="setting" unicode="&#59092;" d="M904.533333 473.6l-85.333333 14.933333-17.066667 38.4 49.066667 70.4c14.933333 21.333333 12.8 49.066667-6.4 68.266667l-53.333333 53.333333c-19.2 19.2-46.933333 21.333333-68.266667 6.4l-70.4-49.066666-38.4 17.066666-14.933333 85.333334c-2.133333 23.466667-23.466667 42.666667-49.066667 42.666666h-74.666667c-25.6 0-46.933333-19.2-53.333333-44.8l-14.933333-85.333333-38.4-17.066667L296.533333 725.333333c-21.333333 14.933333-49.066667 12.8-68.266666-6.4l-53.333334-53.333333c-19.2-19.2-21.333333-46.933333-6.4-68.266667l49.066667-70.4-17.066667-38.4-85.333333-14.933333c-21.333333-4.266667-40.533333-25.6-40.533333-51.2v-74.666667c0-25.6 19.2-46.933333 44.8-53.333333l85.333333-14.933333 17.066667-38.4L170.666667 168.533333c-14.933333-21.333333-12.8-49.066667 6.4-68.266666l53.333333-53.333334c19.2-19.2 46.933333-21.333333 68.266667-6.4l70.4 49.066667 38.4-17.066667 14.933333-85.333333c4.266667-25.6 25.6-44.8 53.333333-44.8h74.666667c25.6 0 46.933333 19.2 53.333333 44.8l14.933334 85.333333 38.4 17.066667 70.4-49.066667c21.333333-14.933333 49.066667-12.8 68.266666 6.4l53.333334 53.333334c19.2 19.2 21.333333 46.933333 6.4 68.266666l-49.066667 70.4 17.066667 38.4 85.333333 14.933334c25.6 4.266667 44.8 25.6 44.8 53.333333v74.666667c-4.266667 27.733333-23.466667 49.066667-49.066667 53.333333z m-19.2-117.333333l-93.866666-17.066667c-10.666667-2.133333-19.2-8.533333-23.466667-19.2l-29.866667-70.4c-4.266667-10.666667-2.133333-21.333333 4.266667-29.866667l53.333333-76.8-40.533333-40.533333-76.8 53.333333c-8.533333 6.4-21.333333 8.533333-29.866667 4.266667L576 128c-10.666667-4.266667-17.066667-12.8-19.2-23.466667l-17.066667-93.866666h-57.6l-17.066666 93.866666c-2.133333 10.666667-8.533333 19.2-19.2 23.466667l-70.4 29.866667c-10.666667 4.266667-21.333333 2.133333-29.866667-4.266667l-76.8-53.333333-40.533333 40.533333 53.333333 76.8c6.4 8.533333 8.533333 21.333333 4.266667 29.866667L256 320c-4.266667 10.666667-12.8 17.066667-23.466667 19.2l-93.866666 17.066667v57.6l93.866666 17.066666c10.666667 2.133333 19.2 8.533333 23.466667 19.2l29.866667 70.4c4.266667 10.666667 2.133333 21.333333-4.266667 29.866667l-53.333333 76.8 40.533333 40.533333 76.8-53.333333c8.533333-6.4 21.333333-8.533333 29.866667-4.266667L448 640c10.666667 4.266667 17.066667 12.8 19.2 23.466667l17.066667 93.866666h57.6l17.066666-93.866666c2.133333-10.666667 8.533333-19.2 19.2-23.466667l70.4-29.866667c10.666667-4.266667 21.333333-2.133333 29.866667 4.266667l76.8 53.333333 40.533333-40.533333-53.333333-76.8c-6.4-8.533333-8.533333-21.333333-4.266667-29.866667L768 448c4.266667-10.666667 12.8-17.066667 23.466667-19.2l93.866666-17.066667v-55.466666zM512 501.333333c-64 0-117.333333-53.333333-117.333333-117.333333s53.333333-117.333333 117.333333-117.333333 117.333333 53.333333 117.333333 117.333333-53.333333 117.333333-117.333333 117.333333z m0-170.666666c-29.866667 0-53.333333 23.466667-53.333333 53.333333s23.466667 53.333333 53.333333 53.333333 53.333333-23.466667 53.333333-53.333333-23.466667-53.333333-53.333333-53.333333z" horiz-adv-x="1024" />
<glyph glyph-name="survey" unicode="&#59093;" d="M810.666667 757.333333h-85.333334V768c0 29.866667-23.466667 53.333333-53.333333 53.333333h-320C322.133333 821.333333 298.666667 797.866667 298.666667 768v-10.666667h-85.333334c-40.533333 0-74.666667-34.133333-74.666666-74.666666v-661.333334c0-40.533333 34.133333-74.666667 74.666666-74.666666h597.333334c40.533333 0 74.666667 34.133333 74.666666 74.666666V682.666667c0 40.533333-34.133333 74.666667-74.666666 74.666666z m-149.333334 0v-64H362.666667v64h298.666666zM821.333333 21.333333c0-6.4-4.266667-10.666667-10.666666-10.666666H213.333333c-6.4 0-10.666667 4.266667-10.666666 10.666666V682.666667c0 6.4 4.266667 10.666667 10.666666 10.666666h85.333334v-10.666666c0-29.866667 23.466667-53.333333 53.333333-53.333334h320c29.866667 0 53.333333 23.466667 53.333333 53.333334v10.666666h85.333334c6.4 0 10.666667-4.266667 10.666666-10.666666v-661.333334zM659.2 450.133333l-211.2-213.333333-83.2 83.2c-12.8 12.8-32 12.8-44.8 0s-12.8-32 0-44.8l106.666667-106.666667c6.4-6.4 14.933333-8.533333 23.466666-8.533333s17.066667 2.133333 23.466667 8.533333l234.666667 234.666667c12.8 12.8 12.8 32 0 44.8-14.933333 12.8-36.266667 12.8-49.066667 2.133333z" horiz-adv-x="1024" />
<glyph glyph-name="task" unicode="&#59094;" d="M846.933333 780.8c-8.533333 6.4-21.333333 6.4-29.866666 2.133333 0 0-74.666667-34.133333-174.933334-34.133333-49.066667 0-96 17.066667-145.066666 34.133333-53.333333 19.2-106.666667 38.4-166.4 38.4-119.466667 0-162.133333-40.533333-168.533334-44.8-4.266667-6.4-8.533333-14.933333-8.533333-23.466666V-21.333333c0-17.066667 14.933333-32 32-32s32 14.933333 32 32V300.8c14.933333 8.533333 51.2 21.333333 113.066667 21.333333 49.066667 0 96-17.066667 145.066666-34.133333 53.333333-19.2 106.666667-38.4 166.4-38.4 115.2 0 198.4 38.4 200.533334 38.4 10.666667 4.266667 19.2 17.066667 19.2 29.866667V753.066667c0 10.666667-6.4 21.333333-14.933334 27.733333z m-49.066666-441.6c-27.733333-10.666667-85.333333-25.6-155.733334-25.6-49.066667 0-96 17.066667-145.066666 34.133333-53.333333 19.2-106.666667 38.4-166.4 38.4-49.066667 0-87.466667-6.4-113.066667-17.066666V736c14.933333 8.533333 51.2 21.333333 113.066667 21.333333 49.066667 0 96-17.066667 145.066666-34.133333 53.333333-19.2 106.666667-38.4 166.4-38.4 64 0 119.466667 12.8 155.733334 23.466667v-369.066667z" horiz-adv-x="1024" />
<glyph glyph-name="skip" unicode="&#59095;" d="M921.6 539.733333c-14.933333 8.533333-34.133333 4.266667-42.666667-12.8L829.866667 448c-51.2 157.866667-200.533333 266.666667-369.066667 266.666667-172.8 0-324.266667-115.2-373.333333-277.333334-4.266667-17.066667 4.266667-34.133333 21.333333-40.533333 17.066667-4.266667 34.133333 4.266667 40.533333 21.333333 40.533333 136.533333 166.4 232.533333 311.466667 232.533334 140.8 0 264.533333-89.6 307.2-219.733334l-81.066667 46.933334c-14.933333 8.533333-34.133333 4.266667-42.666666-10.666667-8.533333-14.933333-4.266667-34.133333 10.666666-42.666667l147.2-85.333333c4.266667-2.133333 10.666667-4.266667 17.066667-4.266667 2.133333 0 6.4 0 8.533333 2.133334 8.533333 2.133333 14.933333 8.533333 19.2 14.933333l85.333334 147.2c8.533333 12.8 4.266667 32-10.666667 40.533333zM896 138.666667H128c-17.066667 0-32-14.933333-32-32s14.933333-32 32-32h768c17.066667 0 32 14.933333 32 32s-14.933333 32-32 32z" horiz-adv-x="1024" />
<glyph glyph-name="text" unicode="&#59096;" d="M853.333333 757.333333H170.666667c-17.066667 0-32-14.933333-32-32v-128c0-17.066667 14.933333-32 32-32s32 14.933333 32 32V693.333333h277.333333v-618.666666H384c-17.066667 0-32-14.933333-32-32s14.933333-32 32-32h256c17.066667 0 32 14.933333 32 32s-14.933333 32-32 32h-96v618.666666h277.333333V597.333333c0-17.066667 14.933333-32 32-32s32 14.933333 32 32V725.333333c0 17.066667-14.933333 32-32 32z" horiz-adv-x="1024" />
<glyph glyph-name="time" unicode="&#59097;" d="M512 821.333333C270.933333 821.333333 74.666667 625.066667 74.666667 384S270.933333-53.333333 512-53.333333 949.333333 142.933333 949.333333 384 753.066667 821.333333 512 821.333333z m0-810.666666c-204.8 0-373.333333 168.533333-373.333333 373.333333S307.2 757.333333 512 757.333333 885.333333 588.8 885.333333 384 716.8 10.666667 512 10.666667zM695.466667 328.533333l-151.466667 70.4V618.666667c0 17.066667-14.933333 32-32 32s-32-14.933333-32-32v-238.933334c0-12.8 6.4-23.466667 19.2-29.866666l170.666667-81.066667c4.266667-2.133333 8.533333-2.133333 12.8-2.133333 12.8 0 23.466667 6.4 29.866666 19.2 6.4 14.933333 0 34.133333-17.066666 42.666666z" horiz-adv-x="1024" />
<glyph glyph-name="toggle-left" unicode="&#59098;" d="M874.666667 96H149.333333c-17.066667 0-32-14.933333-32-32s14.933333-32 32-32h725.333334c17.066667 0 32 14.933333 32 32s-14.933333 32-32 32zM149.333333 672h725.333334c17.066667 0 32 14.933333 32 32s-14.933333 32-32 32H149.333333c-17.066667 0-32-14.933333-32-32s14.933333-32 32-32zM341.333333 416c-17.066667 0-32-14.933333-32-32s14.933333-32 32-32h512c17.066667 0 32 14.933333 32 32s-14.933333 32-32 32H341.333333zM275.2 211.2c6.4-6.4 14.933333-8.533333 23.466667-8.533333s17.066667 2.133333 23.466666 8.533333c12.8 12.8 12.8 32 0 44.8l-128 128 125.866667 125.866667c12.8 12.8 12.8 32 0 44.8-12.8 12.8-32 12.8-44.8 0l-149.333333-149.333334c-12.8-12.8-12.8-32 0-44.8l149.333333-149.333333z" horiz-adv-x="1024" />
<glyph glyph-name="toggle-right" unicode="&#59099;" d="M874.666667 96H149.333333c-17.066667 0-32-14.933333-32-32s14.933333-32 32-32h725.333334c17.066667 0 32 14.933333 32 32s-14.933333 32-32 32zM149.333333 672h725.333334c17.066667 0 32 14.933333 32 32s-14.933333 32-32 32H149.333333c-17.066667 0-32-14.933333-32-32s14.933333-32 32-32zM149.333333 352h512c17.066667 0 32 14.933333 32 32s-14.933333 32-32 32H149.333333c-17.066667 0-32-14.933333-32-32s14.933333-32 32-32zM748.8 556.8c-12.8 12.8-32 12.8-44.8 0-12.8-12.8-12.8-32 0-44.8l125.866667-125.866667-125.866667-125.866666c-12.8-12.8-12.8-32 0-44.8 6.4-6.4 14.933333-8.533333 23.466667-8.533334s17.066667 2.133333 23.466666 8.533334l149.333334 149.333333c12.8 12.8 12.8 32 0 44.8l-151.466667 147.2z" horiz-adv-x="1024" />
<glyph glyph-name="top" unicode="&#59100;" d="M896 800H128c-17.066667 0-32-14.933333-32-32S110.933333 736 128 736h768c17.066667 0 32 14.933333 32 32s-14.933333 32-32 32zM535.466667 599.466667c-12.8 12.8-32 12.8-44.8 0l-213.333334-213.333334c-12.8-12.8-12.8-32 0-44.8s32-12.8 44.8 0l157.866667 157.866667V42.666667c0-17.066667 14.933333-32 32-32s32 14.933333 32 32V499.2l157.866667-157.866667c6.4-6.4 14.933333-8.533333 23.466666-8.533333s17.066667 2.133333 23.466667 8.533333c12.8 12.8 12.8 32 0 44.8l-213.333333 213.333334z" horiz-adv-x="1024" />
<glyph glyph-name="unlock" unicode="&#59101;" d="M785.066667 480H381.866667v121.6c0 74.666667 61.866667 134.4 138.666666 134.4 59.733333 0 113.066667-36.266667 132.266667-91.733333 6.4-17.066667 23.466667-25.6 40.533333-19.2 17.066667 6.4 25.6 23.466667 19.2 40.533333-27.733333 81.066667-104.533333 134.4-192 134.4-110.933333 0-202.666667-89.6-202.666666-198.4v-121.6h-78.933334c-55.466667 0-100.266667-44.8-100.266666-100.266667v-311.466666c0-55.466667 44.8-100.266667 100.266666-100.266667h546.133334c55.466667 0 100.266667 44.8 100.266666 100.266667V379.733333c0 55.466667-44.8 100.266667-100.266666 100.266667z m36.266666-411.733333c0-19.2-17.066667-36.266667-36.266666-36.266667H238.933333c-19.2 0-36.266667 17.066667-36.266666 36.266667V379.733333c0 19.2 17.066667 36.266667 36.266666 36.266667h546.133334c19.2 0 36.266667-17.066667 36.266666-36.266667v-311.466666zM512 352c-17.066667 0-32-14.933333-32-32v-106.666667c0-17.066667 14.933333-32 32-32s32 14.933333 32 32v106.666667c0 17.066667-14.933333 32-32 32z" horiz-adv-x="1024" />
<glyph glyph-name="user" unicode="&#59102;" d="M512 821.333333C270.933333 821.333333 74.666667 625.066667 74.666667 384S270.933333-53.333333 512-53.333333 949.333333 142.933333 949.333333 384 753.066667 821.333333 512 821.333333zM288 85.333333c0 123.733333 100.266667 224 224 224S736 209.066667 736 85.333333c-61.866667-46.933333-140.8-74.666667-224-74.666666s-162.133333 27.733333-224 74.666666z m128 384c0 53.333333 42.666667 96 96 96s96-42.666667 96-96-42.666667-96-96-96-96 42.666667-96 96z m377.6-328.533333c-19.2 96-85.333333 174.933333-174.933333 211.2 32 29.866667 51.2 70.4 51.2 117.333333 0 87.466667-72.533333 160-160 160s-160-72.533333-160-160c0-46.933333 19.2-87.466667 51.2-117.333333-89.6-36.266667-155.733333-115.2-174.933334-211.2-55.466667 66.133333-91.733333 149.333333-91.733333 243.2 0 204.8 168.533333 373.333333 373.333333 373.333333S885.333333 588.8 885.333333 384c0-93.866667-34.133333-177.066667-91.733333-243.2z" horiz-adv-x="1024" />
<glyph glyph-name="upload" unicode="&#59103;" d="M896 266.666667c-17.066667 0-32-14.933333-32-32v-170.666667c0-6.4-4.266667-10.666667-10.666667-10.666667H170.666667c-6.4 0-10.666667 4.266667-10.666667 10.666667v170.666667c0 17.066667-14.933333 32-32 32s-32-14.933333-32-32v-170.666667c0-40.533333 34.133333-74.666667 74.666667-74.666667h682.666666c40.533333 0 74.666667 34.133333 74.666667 74.666667v170.666667c0 17.066667-14.933333 32-32 32zM322.133333 488.533333l157.866667 157.866667V192c0-17.066667 14.933333-32 32-32s32 14.933333 32 32V648.533333l157.866667-157.866666c6.4-6.4 14.933333-8.533333 23.466666-8.533334s17.066667 2.133333 23.466667 8.533334c12.8 12.8 12.8 32 0 44.8l-213.333333 213.333333c-12.8 12.8-32 12.8-44.8 0l-213.333334-213.333333c-12.8-12.8-12.8-32 0-44.8 10.666667-12.8 32-12.8 44.8-2.133334z" horiz-adv-x="1024" />
<glyph glyph-name="work" unicode="&#59104;" d="M885.333333 640H725.333333V697.6C723.2 738.133333 689.066667 768 648.533333 768h-298.666666c-40.533333-2.133333-72.533333-34.133333-72.533334-74.666667V640H138.666667C98.133333 640 64 605.866667 64 565.333333v-490.666666C64 34.133333 98.133333 0 138.666667 0h746.666666c40.533333 0 74.666667 34.133333 74.666667 74.666667v490.666666c0 40.533333-34.133333 74.666667-74.666667 74.666667zM341.333333 693.333333c2.133333 6.4 6.4 10.666667 12.8 10.666667h296.533334c6.4 0 10.666667-6.4 10.666666-10.666667V640H341.333333V693.333333zM138.666667 576h746.666666c6.4 0 10.666667-4.266667 10.666667-10.666667v-128H128v128c0 6.4 4.266667 10.666667 10.666667 10.666667z m277.333333-202.666667h192V320c0-6.4-4.266667-10.666667-10.666667-10.666667h-170.666666c-6.4 0-10.666667 4.266667-10.666667 10.666667v53.333333z m469.333333-309.333333h-746.666666c-6.4 0-10.666667 4.266667-10.666667 10.666667v298.666666h224V320c0-40.533333 34.133333-74.666667 74.666667-74.666667h170.666666c40.533333 0 74.666667 34.133333 74.666667 74.666667v53.333333H896v-298.666666c0-6.4-4.266667-10.666667-10.666667-10.666667z" horiz-adv-x="1024" />
<glyph glyph-name="warning" unicode="&#59105;" d="M934.4 125.866667L605.866667 714.666667C586.666667 748.8 550.4 768 512 768c-38.4 0-74.666667-21.333333-93.866667-53.333333L89.6 125.866667c-19.2-34.133333-19.2-76.8 0-110.933334S145.066667-42.666667 183.466667-42.666667h657.066666c38.4 0 74.666667 21.333333 93.866667 57.6 19.2 34.133333 19.2 76.8 0 110.933334z m-55.466667-81.066667c-8.533333-14.933333-23.466667-23.466667-38.4-23.466667H183.466667c-14.933333 0-29.866667 8.533333-38.4 23.466667-8.533333 14.933333-8.533333 34.133333 0 49.066667L473.6 682.666667c8.533333 12.8 23.466667 21.333333 38.4 21.333333s29.866667-8.533333 38.4-21.333333l328.533333-588.8c8.533333-14.933333 8.533333-32 0-49.066667zM512 149.333333m-42.666667 0a42.666667 42.666667 0 1 1 85.333334 0 42.666667 42.666667 0 1 1-85.333334 0ZM512 266.666667c17.066667 0 32 14.933333 32 32v192c0 17.066667-14.933333 32-32 32s-32-14.933333-32-32v-192c0-17.066667 14.933333-32 32-32z" horiz-adv-x="1024" />
<glyph glyph-name="add-bold" unicode="&#59106;" d="M874.666667 426.666667H554.666667V746.666667c0 23.466667-19.2 42.666667-42.666667 42.666666s-42.666667-19.2-42.666667-42.666666v-320H149.333333c-23.466667 0-42.666667-19.2-42.666666-42.666667s19.2-42.666667 42.666666-42.666667h320v-320c0-23.466667 19.2-42.666667 42.666667-42.666666s42.666667 19.2 42.666667 42.666666V341.333333h320c23.466667 0 42.666667 19.2 42.666666 42.666667s-19.2 42.666667-42.666666 42.666667z" horiz-adv-x="1024" />
<glyph glyph-name="arrow-left-bold" unicode="&#59107;" d="M384 384L731.733333 693.333333c17.066667 14.933333 19.2 42.666667 4.266667 59.733334-14.933333 17.066667-42.666667 19.2-59.733333 4.266666l-384-341.333333c-10.666667-8.533333-14.933333-19.2-14.933334-32s4.266667-23.466667 14.933334-32l384-341.333333c8.533333-6.4 19.2-10.666667 27.733333-10.666667 12.8 0 23.466667 4.266667 32 14.933333 14.933333 17.066667 14.933333 44.8-4.266667 59.733334L384 384z" horiz-adv-x="1024" />
<glyph glyph-name="arrow-up-bold" unicode="&#59108;" d="M904.533333 221.866667l-362.666666 362.666666c-17.066667 17.066667-42.666667 17.066667-59.733334 0l-362.666666-362.666666c-17.066667-17.066667-17.066667-42.666667 0-59.733334 17.066667-17.066667 42.666667-17.066667 59.733333 0L512 494.933333l332.8-332.8c8.533333-8.533333 19.2-12.8 29.866667-12.8s21.333333 4.266667 29.866666 12.8c17.066667 17.066667 17.066667 42.666667 0 59.733334z" horiz-adv-x="1024" />
<glyph glyph-name="close-bold" unicode="&#59109;" d="M571.733333 384l268.8 268.8c17.066667 17.066667 17.066667 42.666667 0 59.733333-17.066667 17.066667-42.666667 17.066667-59.733333 0L512 443.733333 243.2 712.533333c-17.066667 17.066667-42.666667 17.066667-59.733333 0-17.066667-17.066667-17.066667-42.666667 0-59.733333L452.266667 384 183.466667 115.2c-17.066667-17.066667-17.066667-42.666667 0-59.733333 8.533333-8.533333 19.2-12.8 29.866666-12.8s21.333333 4.266667 29.866667 12.8L512 324.266667l268.8-268.8c8.533333-8.533333 19.2-12.8 29.866667-12.8s21.333333 4.266667 29.866666 12.8c17.066667 17.066667 17.066667 42.666667 0 59.733333L571.733333 384z" horiz-adv-x="1024" />
<glyph glyph-name="arrow-down-bold" unicode="&#59110;" d="M904.533333 584.5333330000001c-17.066667 17.066667-42.666667 17.066667-59.733333 0L512 251.73333300000002 179.2 584.5333330000001c-17.066667 17.066667-42.666667 17.066667-59.733333 0-17.066667-17.066667-17.066667-42.666667 0-59.733333l362.666666-362.666667c8.533333-8.533333 19.2-12.8 29.866667-12.8s21.333333 4.266667 29.866667 12.8l362.666666 362.666667c17.066667 17.066667 17.066667 42.666667 0 59.733333z" horiz-adv-x="1024" />
<glyph glyph-name="minus-bold" unicode="&#59111;" d="M853.333333 341.333333H170.666667c-23.466667 0-42.666667 19.2-42.666667 42.666667s19.2 42.666667 42.666667 42.666667h682.666666c23.466667 0 42.666667-19.2 42.666667-42.666667s-19.2-42.666667-42.666667-42.666667z" horiz-adv-x="1024" />
<glyph glyph-name="arrow-right-bold" unicode="&#59112;" d="M731.733333 416l-384 341.333333c-17.066667 14.933333-44.8 14.933333-59.733333-4.266666-14.933333-17.066667-14.933333-44.8 4.266667-59.733334L640 384 292.266667 74.666667c-17.066667-14.933333-19.2-42.666667-4.266667-59.733334 8.533333-8.533333 19.2-14.933333 32-14.933333 10.666667 0 19.2 4.266667 27.733333 10.666667l384 341.333333c8.533333 8.533333 14.933333 19.2 14.933334 32s-4.266667 23.466667-14.933334 32z" horiz-adv-x="1024" />
<glyph glyph-name="select-bold" unicode="&#59113;" d="M883.2 648.533333c-17.066667 17.066667-44.8 17.066667-59.733333 0L409.6 230.4l-209.066667 204.8c-17.066667 17.066667-44.8 17.066667-59.733333 0-17.066667-17.066667-17.066667-44.8 0-59.733333l238.933333-234.666667c8.533333-8.533333 19.2-12.8 29.866667-12.8 10.666667 0 21.333333 4.266667 29.866667 12.8l443.733333 448c17.066667 17.066667 17.066667 42.666667 0 59.733333z" horiz-adv-x="1024" />
</font>
</defs></svg>

Before

Width:  |  Height:  |  Size: 106 KiB

@@ -1,102 +0,0 @@
layui.define(['table', 'laypage','jquery', 'element'], function(exports) {
"use strict";
var MOD_NAME = 'card',
$ = layui.jquery,
element = layui.element,
laypage = layui.laypage;
var pearCard = function(opt) {
this.option = opt;
};
pearCard.prototype.render = function(opt) {
var option = {
// 构建的模型
elem: opt.elem,
// 数据 url 连接
url: opt.url,
// lineSize 每行的个数
lineSize: opt.lineSize ? opt.lineSize : 4,
// 共多少个
pageSize: opt.pageSize ? opt.pageSize : 12,
// 当前页
currentPage: opt.currentSize ? opt.currentSize : 0,
// 完 成 函 数
done: opt.done ? opt.done : function() {
alert("跳转页面");
}
}
// 根 据 请 求 方 式 获 取 数 据
if (option.url != null) {
// 复制数据
option.data = getData(option.url).data;
}
// 根据结果进行相应结构的创建
var html = createComponent(option.data);
$(option.elem).html(html);
// 初始化分页组件
laypage.render({
elem: 'cardpage'
,count: 100
,layout: ['count', 'prev', 'page', 'next', 'limit', 'refresh', 'skip']
,jump: function(obj){
console.log(obj)
}
});
return new pearCard(option);
}
function createComponent(data) {
var html = "<div class='pear-card-component'>"
var content = createCards(data);
var page = "<div id='cardpage'></div>"
content = content + page;
html += content + "</div>"
return html;
}
/** 创建指定数量的卡片 */
function createCards(data) {
var content = "<div class='layui-row layui-col-space30'>";
$.each(data, function(i, item) {
content += createCard(item);
})
content += "</div>"
return content;
}
/** 创建一个卡片 */
function createCard(item) {
var card =
'<div class="layui-col-md3 ew-datagrid-item" data-index="0" data-number="1"> <div class="project-list-item"> <img class="project-list-item-cover" src="'+item.image+'"> <div class="project-list-item-body"> <h2>'+item.title+'</h2> <div class="project-list-item-text layui-text">'+item.remark+'</div> <div class="project-list-item-desc"> <span class="time">'+item.time+'</span> <div class="ew-head-list"> <img class="ew-head-list-item" lay-tips="曲丽丽" lay-offset="0,-5px" src="https://gw.alipayobjects.com/zos/rmsportal/ZiESqWwCXBRQoaPONSJe.png"> <img class="ew-head-list-item" lay-tips="王昭君" lay-offset="0,-5px" src="https://gw.alipayobjects.com/zos/rmsportal/tBOxZPlITHqwlGjsJWaF.png"> <img class="ew-head-list-item" lay-tips="董娜娜" lay-offset="0,-5px" src="https://gw.alipayobjects.com/zos/rmsportal/sBxjgqiuHMGRkIjqlQCd.png"> </div> </div> </div> </div> </div>'
return card;
}
/** 同 步 请 求 获 取 数 据 */
function getData(url) {
$.ajaxSettings.async = false;
var data = null;
$.get(url, function(result) {
data = result;
});
$.ajaxSettings.async = true;
return data;
}
exports(MOD_NAME, new pearCard());
})
File diff suppressed because it is too large Load Diff
@@ -1,388 +0,0 @@
layui.define(['laypage', 'form'], function (exports) {
"use strict";
var IconPicker =function () {
this.v = '1.1';
}, _MOD = 'iconPicker',
_this = this,
$ = layui.jquery,
laypage = layui.laypage,
form = layui.form,
BODY = 'body',
TIPS = '请选择图标';
IconPicker.prototype.render = function(options){
var opts = options,
// DOM选择器
elem = opts.elem,
// 数据类型:fontClass/unicode
type = opts.type == null ? 'fontClass' : opts.type,
// 是否分页:true/false
page = opts.page == null ? true : opts.page,
// 每页显示数量
limit = opts.limit == null ? 12 : opts.limit,
// 是否开启搜索:true/false
search = opts.search == null ? true : opts.search,
// 每个图标格子的宽度:'43px'或'20%'
cellWidth = opts.cellWidth,
// 点击回调
click = opts.click,
// 渲染成功后的回调
success = opts.success,
// json数据
data = {},
// 唯一标识
tmp = new Date().getTime(),
// 是否使用的class数据
isFontClass = opts.type === 'fontClass',
// 初始化时input的值
ORIGINAL_ELEM_VALUE = $(elem).val(),
TITLE = 'layui-select-title',
TITLE_ID = 'layui-select-title-' + tmp,
ICON_BODY = 'layui-iconpicker-' + tmp,
PICKER_BODY = 'layui-iconpicker-body-' + tmp,
PAGE_ID = 'layui-iconpicker-page-' + tmp,
LIST_BOX = 'layui-iconpicker-list-box',
selected = 'layui-form-selected',
unselect = 'layui-unselect';
var a = {
init: function () {
data = common.getData[type]();
a.hideElem().createSelect().createBody().toggleSelect();
a.preventEvent().inputListen();
common.loadCss();
if (success) {
success(this.successHandle());
}
return a;
},
successHandle: function(){
var d = {
options: opts,
data: data,
id: tmp,
elem: $('#' + ICON_BODY)
};
return d;
},
/**
* 隐藏elem
*/
hideElem: function () {
$(elem).hide();
return a;
},
/**
* 绘制select下拉选择框
*/
createSelect: function () {
var oriIcon = '<i class="layui-icon">';
// 默认图标
if(ORIGINAL_ELEM_VALUE === '') {
if(isFontClass) {
ORIGINAL_ELEM_VALUE = 'layui-icon-circle-dot';
} else {
ORIGINAL_ELEM_VALUE = '&#xe617;';
}
}
if (isFontClass) {
oriIcon = '<i class="layui-icon '+ ORIGINAL_ELEM_VALUE +'">';
} else {
oriIcon += ORIGINAL_ELEM_VALUE;
}
oriIcon += '</i>';
var selectHtml = '<div class="layui-iconpicker layui-unselect layui-form-select" id="'+ ICON_BODY +'">' +
'<div class="'+ TITLE +'" id="'+ TITLE_ID +'">' +
'<div class="layui-iconpicker-item">'+
'<span class="layui-iconpicker-icon layui-unselect">' +
oriIcon +
'</span>'+
'<i class="layui-edge"></i>' +
'</div>'+
'</div>' +
'<div class="layui-anim layui-anim-upbit" style="">' +
'123' +
'</div>';
$(elem).after(selectHtml);
return a;
},
/**
* 展开/折叠下拉框
*/
toggleSelect: function () {
var item = '#' + TITLE_ID + ' .layui-iconpicker-item,#' + TITLE_ID + ' .layui-iconpicker-item .layui-edge';
a.event('click', item, function (e) {
var $icon = $('#' + ICON_BODY);
if ($icon.hasClass(selected)) {
$icon.removeClass(selected).addClass(unselect);
} else {
// 隐藏其他picker
$('.layui-form-select').removeClass(selected);
// 显示当前picker
$icon.addClass(selected).removeClass(unselect);
}
e.stopPropagation();
});
return a;
},
/**
* 绘制主体部分
*/
createBody: function () {
// 获取数据
var searchHtml = '';
if (search) {
searchHtml = '<div class="layui-iconpicker-search">' +
'<input class="layui-input">' +
'<i class="layui-icon">&#xe615;</i>' +
'</div>';
}
// 组合dom
var bodyHtml = '<div class="layui-iconpicker-body" id="'+ PICKER_BODY +'">' +
searchHtml +
'<div class="'+ LIST_BOX +'"></div> '+
'</div>';
$('#' + ICON_BODY).find('.layui-anim').eq(0).html(bodyHtml);
a.search().createList().check().page();
return a;
},
/**
* 绘制图标列表
* @param text 模糊查询关键字
* @returns {string}
*/
createList: function (text) {
var d = data,
l = d.length,
pageHtml = '',
listHtml = $('<div class="layui-iconpicker-list">')//'<div class="layui-iconpicker-list">';
// 计算分页数据
var _limit = limit, // 每页显示数量
_pages = l % _limit === 0 ? l / _limit : parseInt(l / _limit + 1), // 总计多少页
_id = PAGE_ID;
// 图标列表
var icons = [];
for (var i = 0; i < l; i++) {
var obj = d[i];
// 判断是否模糊查询
if (text && obj.indexOf(text) === -1) {
continue;
}
// 是否自定义格子宽度
var style = '';
if (cellWidth !== null) {
style += ' style="width:' + cellWidth + '"';
}
// 每个图标dom
var icon = '<div class="layui-iconpicker-icon-item" title="'+ obj +'" '+ style +'>';
if (isFontClass){
icon += '<i class="layui-icon '+ obj +'"></i>';
} else {
icon += '<i class="layui-icon">'+ obj.replace('amp;', '') +'</i>';
}
icon += '</div>';
icons.push(icon);
}
// 查询出图标后再分页
l = icons.length;
_pages = l % _limit === 0 ? l / _limit : parseInt(l / _limit + 1);
for (var i = 0; i < _pages; i++) {
// 按limit分块
var lm = $('<div class="layui-iconpicker-icon-limit" id="layui-iconpicker-icon-limit-' + tmp + (i+1) +'">');
for (var j = i * _limit; j < (i+1) * _limit && j < l; j++) {
lm.append(icons[j]);
}
listHtml.append(lm);
}
// 无数据
if (l === 0) {
listHtml.append('<p class="layui-iconpicker-tips">无数据</p>');
}
// 判断是否分页
if (page){
$('#' + PICKER_BODY).addClass('layui-iconpicker-body-page');
pageHtml = '<div class="layui-iconpicker-page" id="'+ PAGE_ID +'">' +
'<div class="layui-iconpicker-page-count">' +
'<span id="'+ PAGE_ID +'-current">1</span>/' +
'<span id="'+ PAGE_ID +'-pages">'+ _pages +'</span>' +
' (<span id="'+ PAGE_ID +'-length">'+ l +'</span>)' +
'</div>' +
'<div class="layui-iconpicker-page-operate">' +
'<i class="layui-icon" id="'+ PAGE_ID +'-prev" data-index="0" prev>&#xe603;</i> ' +
'<i class="layui-icon" id="'+ PAGE_ID +'-next" data-index="2" next>&#xe602;</i> ' +
'</div>' +
'</div>';
}
$('#' + ICON_BODY).find('.layui-anim').find('.' + LIST_BOX).html('').append(listHtml).append(pageHtml);
return a;
},
preventEvent: function() {
var item = '#' + ICON_BODY + ' .layui-anim';
a.event('click', item, function (e) {
e.stopPropagation();
});
return a;
},
page: function () {
var icon = '#' + PAGE_ID + ' .layui-iconpicker-page-operate .layui-icon';
$(icon).unbind('click');
a.event('click', icon, function (e) {
var elem = e.currentTarget,
total = parseInt($('#' +PAGE_ID + '-pages').html()),
isPrev = $(elem).attr('prev') !== undefined,
// 按钮上标的页码
index = parseInt($(elem).attr('data-index')),
$cur = $('#' +PAGE_ID + '-current'),
// 点击时正在显示的页码
current = parseInt($cur.html());
// 分页数据
if (isPrev && current > 1) {
current=current-1;
$(icon + '[prev]').attr('data-index', current);
} else if (!isPrev && current < total){
current=current+1;
$(icon + '[next]').attr('data-index', current);
}
$cur.html(current);
// 图标数据
$('#'+ ICON_BODY + ' .layui-iconpicker-icon-limit').hide();
$('#layui-iconpicker-icon-limit-' + tmp + current).show();
e.stopPropagation();
});
return a;
},
/**
* 搜索
*/
search: function () {
var item = '#' + PICKER_BODY + ' .layui-iconpicker-search .layui-input';
a.event('input propertychange', item, function (e) {
var elem = e.target,
t = $(elem).val();
a.createList(t);
});
return a;
},
/**
* 点击选中图标
*/
check: function () {
var item = '#' + PICKER_BODY + ' .layui-iconpicker-icon-item';
a.event('click', item, function (e) {
var el = $(e.currentTarget).find('.layui-icon'),
icon = '';
if (isFontClass) {
var clsArr = el.attr('class').split(/[\s\n]/),
cls = clsArr[1],
icon = cls;
$('#' + TITLE_ID).find('.layui-iconpicker-item .layui-icon').html('').attr('class', clsArr.join(' '));
} else {
var cls = el.html(),
icon = cls;
$('#' + TITLE_ID).find('.layui-iconpicker-item .layui-icon').html(icon);
}
$('#' + ICON_BODY).removeClass(selected).addClass(unselect);
$(elem).val(icon).attr('value', icon);
// 回调
if (click) {
click({
icon: icon
});
}
});
return a;
},
// 监听原始input数值改变
inputListen: function(){
var el = $(elem);
a.event('change', elem, function(){
var value = el.val();
})
// el.change(function(){
// });
return a;
},
event: function (evt, el, fn) {
$(BODY).on(evt, el, fn);
}
};
var common = {
/**
* 加载样式表
*/
loadCss: function () {
var css = '.layui-iconpicker {max-width: 280px;}.layui-iconpicker .layui-anim{display:none;width:280px;position:absolute;left:0;top:42px;padding:5px 0;z-index:899;min-width:100%;border:1px solid #d2d2d2;max-height:300px;overflow-y:auto;background-color:#fff;border-radius:2px;box-shadow:0 2px 4px rgba(0,0,0,.12);box-sizing:border-box;}.layui-iconpicker-item{border:1px solid #e6e6e6;width:90px;height:38px;border-radius:4px;cursor:pointer;position:relative;}.layui-iconpicker-icon{border-right:1px solid #e6e6e6;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;display:block;width:60px;height:100%;float:left;text-align:center;background:#fff;transition:all .3s;}.layui-iconpicker-icon i{line-height:38px;font-size:18px;}.layui-iconpicker-item > .layui-edge{left:70px;}.layui-iconpicker-item:hover{border-color:#D2D2D2!important;}.layui-iconpicker-item:hover .layui-iconpicker-icon{border-color:#D2D2D2!important;}.layui-iconpicker.layui-form-selected .layui-anim{display:block;}.layui-iconpicker-body{padding:6px;}.layui-iconpicker .layui-iconpicker-list{background-color:#fff;border:1px solid #ccc;border-radius:4px;}.layui-iconpicker .layui-iconpicker-icon-item{display:inline-block;width:21.1%;line-height:36px;text-align:center;cursor:pointer;vertical-align:top;height:36px;margin:4px;border:1px solid #ddd;border-radius:2px;transition:300ms;}.layui-iconpicker .layui-iconpicker-icon-item i.layui-icon{font-size:17px;}.layui-iconpicker .layui-iconpicker-icon-item:hover{background-color:#eee;border-color:#ccc;-webkit-box-shadow:0 0 2px #aaa,0 0 2px #fff inset;-moz-box-shadow:0 0 2px #aaa,0 0 2px #fff inset;box-shadow:0 0 2px #aaa,0 0 2px #fff inset;text-shadow:0 0 1px #fff;}.layui-iconpicker-search{position:relative;margin:0 0 6px 0;border:1px solid #e6e6e6;border-radius:2px;transition:300ms;}.layui-iconpicker-search:hover{border-color:#D2D2D2!important;}.layui-iconpicker-search .layui-input{cursor:text;display:inline-block;width:86%;border:none;padding-right:0;margin-top:1px;}.layui-iconpicker-search .layui-icon{position:absolute;top:11px;right:4%;}.layui-iconpicker-tips{text-align:center;padding:8px 0;cursor:not-allowed;}.layui-iconpicker-page{margin-top:6px;margin-bottom:-6px;font-size:12px;padding:0 2px;}.layui-iconpicker-page-count{display:inline-block;}.layui-iconpicker-page-operate{display:inline-block;float:right;cursor:default;}.layui-iconpicker-page-operate .layui-icon{font-size:12px;cursor:pointer;}.layui-iconpicker-body-page .layui-iconpicker-icon-limit{display:none;}.layui-iconpicker-body-page .layui-iconpicker-icon-limit:first-child{display:block;}';
var $style = $('head').find('style[iconpicker]');
if ($style.length === 0) {
$('head').append('<style rel="stylesheet" iconpicker>'+css+'</style>');
}
},
/**
* 获取数据
*/
getData: {
fontClass: function () {
var arr = ["layui-icon-rate-half","layui-icon-rate","layui-icon-rate-solid","layui-icon-cellphone","layui-icon-vercode","layui-icon-login-wechat","layui-icon-login-qq","layui-icon-login-weibo","layui-icon-password","layui-icon-username","layui-icon-refresh-3","layui-icon-auz","layui-icon-spread-left","layui-icon-shrink-right","layui-icon-snowflake","layui-icon-tips","layui-icon-note","layui-icon-home","layui-icon-senior","layui-icon-refresh","layui-icon-refresh-1","layui-icon-flag","layui-icon-theme","layui-icon-notice","layui-icon-website","layui-icon-console","layui-icon-face-surprised","layui-icon-set","layui-icon-template-1","layui-icon-app","layui-icon-template","layui-icon-praise","layui-icon-tread","layui-icon-male","layui-icon-female","layui-icon-camera","layui-icon-camera-fill","layui-icon-more","layui-icon-more-vertical","layui-icon-rmb","layui-icon-dollar","layui-icon-diamond","layui-icon-fire","layui-icon-return","layui-icon-location","layui-icon-read","layui-icon-survey","layui-icon-face-smile","layui-icon-face-cry","layui-icon-cart-simple","layui-icon-cart","layui-icon-next","layui-icon-prev","layui-icon-upload-drag","layui-icon-upload","layui-icon-download-circle","layui-icon-component","layui-icon-file-b","layui-icon-user","layui-icon-find-fill","layui-icon-loading","layui-icon-loading-1","layui-icon-add-1","layui-icon-play","layui-icon-pause","layui-icon-headset","layui-icon-video","layui-icon-voice","layui-icon-speaker","layui-icon-fonts-del","layui-icon-fonts-code","layui-icon-fonts-html","layui-icon-fonts-strong","layui-icon-unlink","layui-icon-picture","layui-icon-link","layui-icon-face-smile-b","layui-icon-align-left","layui-icon-align-right","layui-icon-align-center","layui-icon-fonts-u","layui-icon-fonts-i","layui-icon-tabs","layui-icon-radio","layui-icon-circle","layui-icon-edit","layui-icon-share","layui-icon-delete","layui-icon-form","layui-icon-cellphone-fine","layui-icon-dialogue","layui-icon-fonts-clear","layui-icon-layer","layui-icon-date","layui-icon-water","layui-icon-code-circle","layui-icon-carousel","layui-icon-prev-circle","layui-icon-layouts","layui-icon-util","layui-icon-templeate-1","layui-icon-upload-circle","layui-icon-tree","layui-icon-table","layui-icon-chart","layui-icon-chart-screen","layui-icon-engine","layui-icon-triangle-d","layui-icon-triangle-r","layui-icon-file","layui-icon-set-sm","layui-icon-add-circle","layui-icon-404","layui-icon-about","layui-icon-up","layui-icon-down","layui-icon-left","layui-icon-right","layui-icon-circle-dot","layui-icon-search","layui-icon-set-fill","layui-icon-group","layui-icon-friends","layui-icon-reply-fill","layui-icon-menu-fill","layui-icon-log","layui-icon-picture-fine","layui-icon-face-smile-fine","layui-icon-list","layui-icon-release","layui-icon-ok","layui-icon-help","layui-icon-chat","layui-icon-top","layui-icon-star","layui-icon-star-fill","layui-icon-close-fill","layui-icon-close","layui-icon-ok-circle","layui-icon-add-circle-fine"];
return arr;
},
unicode: function () {
return ["&amp;#xe6c9;","&amp;#xe67b;","&amp;#xe67a;","&amp;#xe678;","&amp;#xe679;","&amp;#xe677;","&amp;#xe676;","&amp;#xe675;","&amp;#xe673;","&amp;#xe66f;","&amp;#xe9aa;","&amp;#xe672;","&amp;#xe66b;","&amp;#xe668;","&amp;#xe6b1;","&amp;#xe702;","&amp;#xe66e;","&amp;#xe68e;","&amp;#xe674;","&amp;#xe669;","&amp;#xe666;","&amp;#xe66c;","&amp;#xe66a;","&amp;#xe667;","&amp;#xe7ae;","&amp;#xe665;","&amp;#xe664;","&amp;#xe716;","&amp;#xe656;","&amp;#xe653;","&amp;#xe663;","&amp;#xe6c6;","&amp;#xe6c5;","&amp;#xe662;","&amp;#xe661;","&amp;#xe660;","&amp;#xe65d;","&amp;#xe65f;","&amp;#xe671;","&amp;#xe65e;","&amp;#xe659;","&amp;#xe735;","&amp;#xe756;","&amp;#xe65c;","&amp;#xe715;","&amp;#xe705;","&amp;#xe6b2;","&amp;#xe6af;","&amp;#xe69c;","&amp;#xe698;","&amp;#xe657;","&amp;#xe65b;","&amp;#xe65a;","&amp;#xe681;","&amp;#xe67c;","&amp;#xe601;","&amp;#xe857;","&amp;#xe655;","&amp;#xe770;","&amp;#xe670;","&amp;#xe63d;","&amp;#xe63e;","&amp;#xe654;","&amp;#xe652;","&amp;#xe651;","&amp;#xe6fc;","&amp;#xe6ed;","&amp;#xe688;","&amp;#xe645;","&amp;#xe64f;","&amp;#xe64e;","&amp;#xe64b;","&amp;#xe62b;","&amp;#xe64d;","&amp;#xe64a;","&amp;#xe64c;","&amp;#xe650;","&amp;#xe649;","&amp;#xe648;","&amp;#xe647;","&amp;#xe646;","&amp;#xe644;","&amp;#xe62a;","&amp;#xe643;","&amp;#xe63f;","&amp;#xe642;","&amp;#xe641;","&amp;#xe640;","&amp;#xe63c;","&amp;#xe63b;","&amp;#xe63a;","&amp;#xe639;","&amp;#xe638;","&amp;#xe637;","&amp;#xe636;","&amp;#xe635;","&amp;#xe634;","&amp;#xe633;","&amp;#xe632;","&amp;#xe631;","&amp;#xe630;","&amp;#xe62f;","&amp;#xe62e;","&amp;#xe62d;","&amp;#xe62c;","&amp;#xe629;","&amp;#xe628;","&amp;#xe625;","&amp;#xe623;","&amp;#xe621;","&amp;#xe620;","&amp;#xe61f;","&amp;#xe61c;","&amp;#xe60b;","&amp;#xe619;","&amp;#xe61a;","&amp;#xe603;","&amp;#xe602;","&amp;#xe617;","&amp;#xe615;","&amp;#xe614;","&amp;#xe613;","&amp;#xe612;","&amp;#xe611;","&amp;#xe60f;","&amp;#xe60e;","&amp;#xe60d;","&amp;#xe60c;","&amp;#xe60a;","&amp;#xe609;","&amp;#xe605;","&amp;#xe607;","&amp;#xe606;","&amp;#xe604;","&amp;#xe600;","&amp;#xe658;","&amp;#x1007;","&amp;#x1006;","&amp;#x1005;","&amp;#xe608;"];
}
}
};
a.init();
return new IconPicker();
};
/**
* 选中图标
* @param filter lay-filter
* @param iconName 图标名称,自动识别fontClass/unicode
*/
IconPicker.prototype.checkIcon = function (filter, iconName){
var el = $('*[lay-filter='+ filter +']'),
p = el.next().find('.layui-iconpicker-item .layui-icon'),
c = iconName;
if (c.indexOf('#xe') > 0){
p.html(c);
} else {
p.html('').attr('class', 'layui-icon ' + c);
}
el.attr('value', c).val(c);
};
var iconPicker = new IconPicker();
exports(_MOD, iconPicker);
});
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+2
View File
@@ -8,6 +8,7 @@ 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
from applications.view.admin.task import admin_task
def register_admin_views(app: Flask):
@@ -19,3 +20,4 @@ def register_admin_views(app: Flask):
app.register_blueprint(admin_power)
app.register_blueprint(admin_role)
app.register_blueprint(admin_dict)
app.register_blueprint(admin_task)
+14 -32
View File
@@ -1,58 +1,40 @@
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.models import AdminLog
from applications.schemas import LogOutSchema
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)
# orm查询
# 使用分页获取data需要.items
log = AdminLog.query.filter_by(url='/passport/login').order_by(desc(AdminLog.create_time)).layui_paginate()
count = log.total
return table_api(data= model_to_dicts(schema=LogOutSchema, data=log.items), 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)
# orm查询
# 使用分页获取data需要.items
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)
AdminLog.url != '/passport/login').order_by(
desc(AdminLog.create_time)).layui_paginate()
count = log.total
return table_api(data=model_to_dicts(schema=LogOutSchema, data=log.items), count=count)
-8
View File
@@ -1,8 +0,0 @@
from flask import Blueprint
admin_curd = Blueprint('adminCurd', __name__, url_prefix='/admin/curd')
@admin_curd.route('/')
def index():
return "功能开发中"
+65 -23
View File
@@ -1,10 +1,13 @@
from flask import Blueprint, render_template, request, jsonify
from applications.common import curd
from applications.common.helper import ModelFilter
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.extensions import db
from applications.models import DictType, DictData
from applications.common.admin import dict_curd
from applications.schemas import DictTypeOutSchema, DictDataOutSchema
admin_dict = Blueprint('adminDict', __name__, url_prefix='/admin/dict')
@@ -19,11 +22,18 @@ def main():
@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)
# 查询参数构造
mf = ModelFilter()
if type_name:
mf.vague(field_name="type_name", value=type_name)
# orm查询
# 使用分页获取data需要.items
dict_all = DictType.query.filter(mf.get_filter(DictType)).layui_paginate()
count = dict_all.total
data = curd.model_to_dicts(schema=DictTypeOutSchema, data=dict_all.items)
return table_api(data=data, count=count)
@admin_dict.get('/dictType/add')
@@ -36,8 +46,14 @@ def dict_type_add():
@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:
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()
if d.id is None:
return fail_api(msg="增加失败")
return success_api(msg="增加成功")
@@ -56,7 +72,18 @@ def dict_type_edit():
@authorize("admin:dict:edit", log=True)
def dict_type_update():
req_json = request.json
dict_curd.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 success_api(msg="更新成功")
@@ -66,7 +93,7 @@ def dict_type_update():
def dict_type_enable():
_id = request.json.get('id')
if id:
res = dict_curd.enable_dict_type_status(_id)
res = curd.enable_status(DictType,_id)
if not res:
return fail_api(msg="出错啦")
return success_api("启动成功")
@@ -79,7 +106,7 @@ def dict_type_enable():
def dict_type_dis_enable():
_id = request.json.get('id')
if id:
res = dict_curd.disable_dict_type_status(_id)
res = curd.disable_status(DictType,_id)
if not res:
return fail_api(msg="出错啦")
return success_api("禁用成功")
@@ -90,7 +117,7 @@ def dict_type_dis_enable():
@admin_dict.delete('/dictType/remove/<int:_id>')
@authorize("admin:dict:remove", log=True)
def dict_type_delete(_id):
res = dict_curd.delete_type_by_id(_id)
res = curd.delete_one_by_id(DictType,_id)
if not res:
return fail_api(msg="删除失败")
return success_api(msg="删除成功")
@@ -99,11 +126,11 @@ def dict_type_delete(_id):
@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)
dict_data = DictData.query.filter_by(type_code=type_code).layui_paginate()
count = dict_data.total
data = curd.model_to_dicts(schema=DictDataOutSchema, data=dict_data.items)
return table_api(data=data, count=count)
# 增加字典数据
@@ -115,12 +142,19 @@ def dict_data_add():
# 增加字典数据
@admin_dict.get('/dictData/save')
@admin_dict.post('/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:
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()
if not d.id:
return jsonify(success=False, msg="增加失败")
return jsonify(success=True, msg="增加成功")
@@ -130,7 +164,7 @@ def dict_data_save():
@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()
dict_data = curd.get_one_by_id(DictData, _id)
return render_template('admin/dict/data/edit.html', dict_data=dict_data)
@@ -139,7 +173,15 @@ def dict_data_edit():
@authorize("admin:dict:edit", log=True)
def dict_data_update():
req_json = request.json
dict_curd.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 success_api(msg="更新成功")
@@ -149,7 +191,7 @@ def dict_data_update():
def dict_data_enable():
_id = request.json.get('dataId')
if _id:
res = dict_curd.enable_dict_data_status(_id)
res = curd.enable_status(model=DictData, id=_id)
if not res:
return fail_api(msg="出错啦")
return success_api(msg="启动成功")
@@ -162,7 +204,7 @@ def dict_data_enable():
def dict_data_disenable():
_id = request.json.get('dataId')
if _id:
res = dict_curd.disable_dict_data_status(_id)
res = curd.disable_status(model=DictData, id=_id)
if not res:
return fail_api(msg="出错啦")
return success_api(msg="禁用成功")
@@ -173,7 +215,7 @@ def dict_data_disenable():
@admin_dict.delete('dictData/remove/<int:id>')
@authorize("admin:dict:remove", log=True)
def dict_data_delete(id):
res = dict_curd.delete_data_by_id(id)
res = curd.delete_one_by_id(model=DictData, id=id)
if not res:
return fail_api(msg="删除失败")
return success_api(msg="删除成功")
+5 -4
View File
@@ -5,7 +5,7 @@ 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
from applications.common.utils import upload as upload_curd
admin_file = Blueprint('adminFile', __name__, url_prefix='/admin/file')
@@ -23,7 +23,7 @@ def index():
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)
data, count = upload_curd.get_photo(page=page, limit=limit)
return table_api(data=data, count=count)
@@ -41,7 +41,8 @@ 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)
file_url = upload_curd.upload_one(photo=photo, mime=mime)
res = {
"msg": "上传成功",
"code": 0,
@@ -58,7 +59,7 @@ def upload_api():
@authorize("admin:file:delete", log=True)
def delete():
_id = request.form.get('id')
res = file_curd.delete_photo_by_id(_id)
res = upload_curd.delete_photo_by_id(_id)
if res:
return success_api(msg="删除成功")
else:
-3
View File
@@ -5,11 +5,8 @@ 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')
+64 -15
View File
@@ -1,7 +1,12 @@
from flask import Blueprint, render_template, request, jsonify
from applications.common.admin import power_curd
from applications.common import curd
from applications.common.utils.http import success_api, fail_api
from applications.common.utils.rights import authorize
from applications.common.utils.validate import xss_escape
from applications.extensions import db
from applications.models import Power
from applications.schemas import PowerOutSchema2
admin_power = Blueprint('adminPower', __name__, url_prefix='/admin/power')
@@ -12,12 +17,12 @@ def index():
return render_template('admin/power/main.html')
@admin_power.get('/data')
@admin_power.post('/data')
@authorize("admin:power:main", log=True)
def data():
power_data = power_curd.get_power_dict()
power = Power.query.all()
res = {
"data": power_data
"data": curd.model_to_dicts(schema=PowerOutSchema2, data=power)
}
return jsonify(res)
@@ -31,10 +36,12 @@ def add():
@admin_power.get('/selectParent')
@authorize("admin:power:main", log=True)
def select_parent():
power_data = power_curd.select_parent()
power = Power.query.all()
res = curd.model_to_dicts(schema=PowerOutSchema2, data=power)
res.append({"powerId": 0, "powerName": "顶级权限", "parentId": -1})
res = {
"status": {"code": 200, "message": "默认"},
"data": power_data
"data": res
}
return jsonify(res)
@@ -45,7 +52,27 @@ def select_parent():
@authorize("admin:power:add", log=True)
def save():
req = request.json
power_curd.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 success_api(msg="成功")
@@ -53,7 +80,7 @@ def save():
@admin_power.get('/edit/<int:_id>')
@authorize("admin:power:edit", log=True)
def edit(_id):
power = power_curd.get_power_by_id(_id)
power = curd.get_one_by_id(Power, _id)
icon = str(power.icon).split()
if len(icon) == 2:
icon = icon[1]
@@ -66,7 +93,20 @@ def edit(_id):
@admin_power.put('/update')
@authorize("admin:power:edit", log=True)
def update():
res = power_curd.update_power(request.json)
req_json = request.json
id = request.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"))
}
res = Power.query.filter_by(id=id).update(data)
db.session.commit()
if not res:
return fail_api(msg="更新权限失败")
return success_api(msg="更新权限成功")
@@ -78,7 +118,7 @@ def update():
def enable():
_id = request.json.get('powerId')
if id:
res = power_curd.enable_status(_id)
res = curd.enable_status(Power, _id)
if not res:
return fail_api(msg="出错啦")
return success_api(msg="启用成功")
@@ -91,7 +131,7 @@ def enable():
def dis_enable():
_id = request.json.get('powerId')
if id:
res = power_curd.disable_status(_id)
res = curd.disable_status(Power, _id)
if not res:
return fail_api(msg="出错啦")
return success_api(msg="禁用成功")
@@ -99,10 +139,14 @@ def dis_enable():
# 权限删除
@admin_power.delete('/remove/<int:_id>')
@admin_power.delete('/remove/<int:id>')
@authorize("admin:power:remove", log=True)
def remove(_id):
r = power_curd.remove_power(_id)
def remove(id):
power = Power.query.filter_by(id=id).first()
power.role = []
r = Power.query.filter_by(id=id).delete()
db.session.commit()
if r:
return success_api(msg="删除成功")
else:
@@ -114,5 +158,10 @@ def remove(_id):
@authorize("admin:power:remove", log=True)
def batch_remove():
ids = request.form.getlist('ids[]')
power_curd.batch_remove(ids)
for id in ids:
power = Power.query.filter_by(id=id).first()
power.role = []
r = Power.query.filter_by(id=id).delete()
db.session.commit()
return success_api(msg="批量删除成功")
+86 -27
View File
@@ -1,9 +1,13 @@
from flask import Blueprint, render_template, request, jsonify
from flask_login import login_required
from applications.common.admin import role_curd
from applications.common.curd import model_to_dicts, enable_status, disable_status, get_one_by_id
from applications.common.helper import ModelFilter
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.extensions import db
from applications.models import Role, Power, User
from applications.schemas import RoleOutSchema, PowerOutSchema2
admin_role = Blueprint('adminRole', __name__, url_prefix='/admin/role')
@@ -19,23 +23,26 @@ def main():
@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 = {}
# 查询参数构造
mf = ModelFilter()
if role_name:
filters["name"] = ('%' + role_name + '%')
mf.vague(field_name="name", value=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)
mf.vague(field_name="code", value=role_code)
# orm查询
# 使用分页获取data需要.items
role = Role.query.filter(mf.get_filter(Role)).layui_paginate()
count = role.total
# 返回api
return table_api(data=model_to_dicts(schema=RoleOutSchema, data=role.items), count=count)
# 角色增加
@admin_role.get('/add')
@authorize("admin:role:add", log=True)
@login_required
def add():
return render_template('admin/role/add.html')
@@ -45,7 +52,20 @@ def add():
@authorize("admin:role:add", log=True)
def save():
req = request.json
role_curd.add_role(req=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()
return success_api(msg="成功")
@@ -60,9 +80,21 @@ def power(_id):
@admin_role.get('/getRolePower/<int:id>')
@authorize("admin:role:main", log=True)
def get_role_power(id):
powers = role_curd.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 = PowerOutSchema2(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"
res = {
"data": powers,
"data": output,
"status": {"code": 200, "message": "默认"}
}
return jsonify(res)
@@ -76,24 +108,39 @@ def save_role_power():
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)
role = Role.query.filter_by(id=role_id).first()
powers = Power.query.filter(Power.id.in_(power_list)).all()
role.power = powers
db.session.commit()
return success_api(msg="授权成功")
# 角色编辑
@admin_role.get('/edit/<int:_id>')
@admin_role.get('/edit/<int:id>')
@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)
def edit(id):
r = get_one_by_id(model=Role, id=id)
return render_template('admin/role/edit.html', role=r)
# 更新角色
@admin_role.put('/update')
@authorize("admin:role:edit", log=True)
def update():
res = role_curd.update_role(request.json)
if not res:
req_json = request.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()
if not role:
return fail_api(msg="更新角色失败")
return success_api(msg="更新角色成功")
@@ -103,9 +150,8 @@ def update():
@authorize("admin:role:edit", log=True)
def enable():
id = request.json.get('roleId')
# print(id)
if id:
res = role_curd.enable_status(id)
res = enable_status(Role, id)
if not res:
return fail_api(msg="出错啦")
return success_api(msg="启动成功")
@@ -118,7 +164,7 @@ def enable():
def dis_enable():
_id = request.json.get('roleId')
if _id:
res = role_curd.disable_status(_id)
res = disable_status(Role, _id)
if not res:
return fail_api(msg="出错啦")
return success_api(msg="禁用成功")
@@ -126,11 +172,17 @@ def dis_enable():
# 角色删除
@admin_role.delete('/remove/<int:_id>')
@admin_role.delete('/remove/<int:id>')
@authorize("admin:role:remove", log=True)
def remove(_id):
res = role_curd.remove_role(_id)
if not res:
def remove(id):
role = Role.query.filter_by(id=id).first()
# 删除该角色的权限和用户
role.power = []
role.user = []
r = Role.query.filter_by(id=id).delete()
db.session.commit()
if not r:
return fail_api(msg="角色删除失败")
return success_api(msg="角色删除成功")
@@ -141,5 +193,12 @@ def remove(_id):
@login_required
def batch_remove():
ids = request.form.getlist('ids[]')
role_curd.batch_remove(ids)
for id in ids:
role = Role.query.filter_by(id=id).first()
# 删除该角色的权限和用户
role.power = []
role.user = []
r = Role.query.filter_by(id=id).delete()
db.session.commit()
return success_api(msg="批量删除成功")
+112
View File
@@ -0,0 +1,112 @@
from flask import Blueprint, request, render_template
from flask_apscheduler.utils import job_to_dict
from applications.common.tasks import tasks
from applications.common.tasks.tasks import task_list
from applications.common.utils.http import table_api, fail_api, success_api
from applications.extensions.init_apscheduler import scheduler
admin_task = Blueprint('adminTask', __name__, url_prefix='/admin/task')
@admin_task.route('/add_job', methods=['GET'])
def add_task():
scheduler.add_job(func=tasks.get(), id='4', args=(1, 1), trigger='interval', seconds=3,
replace_existing=True)
return '6'
@admin_task.get('/')
def main():
return render_template('admin/task/main.html')
@admin_task.route('/data', methods=['GET'])
def get_task(): # 获取
jobs = scheduler.get_jobs()
jobs_list = []
for job in jobs:
jobs_list.append(job_to_dict(job))
return table_api(data=jobs_list, count=len(jobs_list))
# 增加
@admin_task.get('/add')
def add():
return render_template('admin/task/add.html', task_list=task_list)
@admin_task.post('/save')
def save():
_id = request.json.get("id")
name = request.json.get("id")
type = request.json.get("type")
functions = request.json.get("functions")
datetime = request.json.get("datetime")
time = request.json.get("time")
if not hasattr(tasks, functions):
return fail_api()
if type == 'date':
scheduler.add_job(
func=getattr(tasks, functions),
id=_id,
name=name,
args=(1, 1),
trigger=type,
run_date=datetime,
replace_existing=True)
elif type == 'interval':
scheduler.add_job(
func=getattr(tasks, functions),
id=_id,
name=name,
args=(1, 1),
trigger=type,
replace_existing=True)
elif type == 'cron':
scheduler.add_job(
func=getattr(tasks, functions),
id=_id,
name=name,
args=(1, 1),
trigger=type,
replace_existing=True)
return success_api()
# 恢复
@admin_task.put('/enable')
def enable():
_id = request.json.get('id')
# print(id)
if _id:
scheduler.resume_job(str(_id))
return success_api(msg="启动成功")
return fail_api(msg="数据错误")
# 暂停
@admin_task.put('/disable')
def dis_enable():
_id = request.json.get('id')
if _id:
scheduler.pause_job(str(_id))
return success_api(msg="暂停成功")
return fail_api(msg="数据错误")
@admin_task.delete('/remove/<int:_id>')
def remove_job(_id): # 移除
scheduler.remove_job(str(_id))
return success_api(msg="删除成功")
# scheduler.add_job(func=task1, id='2', args=(1, 1), trigger='cron', day_of_week='0-6', hour=18, minute=24,
# second=10, replace_existing=True)
# scheduler.add_job(func=task4, id='4', args=(2, 2), trigger='interval', seconds=3,
# replace_existing=True, misfire_grace_time=3)
# # trigger='interval' 表示是一个循环任务,每隔多久执行一次
# scheduler.add_job(func=task2, id='3', args=(2, 2), trigger='interval', seconds=3,
# replace_existing=True)
+76 -31
View File
@@ -1,12 +1,17 @@
from flask import Blueprint, render_template, request
from flask_login import login_required, current_user
from sqlalchemy import desc
from applications.common import curd
from applications.common.curd import model_to_dicts, enable_status, disable_status
from applications.common.helper import ModelFilter
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.extensions import db
from applications.models import Role
from applications.common.admin import user_curd
from applications.models import User, AdminLog
from applications.schemas import UserOutSchema
admin_user = Blueprint('adminUser', __name__, url_prefix='/admin/user')
@@ -22,18 +27,24 @@ def main():
@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 = {}
# 查询参数构造
mf = ModelFilter()
if real_name:
filters["realname"] = ('%' + real_name + '%')
mf.contains(field_name="realname", value=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)
mf.contains(field_name="username", value=username)
if dept_id:
mf.exact(field_name="dept_id", value=dept_id)
# orm查询
# 使用分页获取data需要.items
user = User.query.filter(mf.get_filter(model=User)).layui_paginate()
count = user.total
# 返回api
return table_api(data=model_to_dicts(schema=UserOutSchema, data=user.items), count=count)
# 用户增加
@@ -57,30 +68,37 @@ def save():
if not username or not real_name or not password:
return fail_api(msg="账号姓名密码不得为空")
if user_curd.is_user_exists(username):
if bool(User.query.filter_by(username=username).count()):
return fail_api(msg="用户已经存在")
_id = user_curd.add_user(username, real_name, password)
user_curd.add_user_role(_id, role_ids)
user = User(username=username, realname=real_name)
user.set_password(password)
db.session.add(user)
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="增加成功")
# 删除用户
@admin_user.delete('/remove/<int:_id>')
@admin_user.delete('/remove/<int:id>')
@authorize("admin:user:remove", log=True)
def delete(_id):
res = user_curd.delete_by_id(_id)
def delete(id):
user = User.query.filter_by(id=id).first()
user.role = []
res = User.query.filter_by(id=id).delete()
db.session.commit()
if not res:
return fail_api(msg="删除失败")
return success_api(msg="删除成功")
# 编辑用户
@admin_user.get('/edit/<int:_id>')
@admin_user.get('/edit/<int:id>')
@authorize("admin:user:edit", log=True)
def edit(_id):
user = User.query.filter_by(id=_id).first()
def edit(id):
user = curd.get_one_by_id(User,id)
roles = Role.query.all()
checked_roles = []
for r in user.role:
@@ -94,13 +112,18 @@ def edit(_id):
def update():
req_json = request.json
a = xss_escape(req_json.get("roleIds"))
_id = xss_escape(req_json.get("userId"))
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)
User.query.filter_by(id=id).update({'username': username, 'realname': real_name, 'dept_id': dept_id})
u = User.query.filter_by(id=id).first()
roles = Role.query.filter(Role.id.in_(role_ids)).all()
u.role = roles
db.session.commit()
return success_api(msg="更新成功")
@@ -109,7 +132,8 @@ def update():
@login_required
def center():
user_info = current_user
user_logs = user_curd.get_current_user_logs()
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/center.html', user_info=user_info, user_logs=user_logs)
@@ -125,7 +149,9 @@ def profile():
@login_required
def update_avatar():
url = request.json.get("avatar").get("src")
if not user_curd.update_avatar(url):
r = User.query.filter_by(id=current_user.id).update({"avatar": url})
db.session.commit()
if not r:
return fail_api(msg="出错啦")
return success_api(msg="修改成功")
@@ -134,8 +160,11 @@ def update_avatar():
@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):
req_json = request.json
r = User.query.filter_by(id=current_user.id).update(
{"realname": req_json.get("realName"), "remark": req_json.get("details")})
db.session.commit()
if not r:
return fail_api(msg="出错啦")
return success_api(msg="更新成功")
@@ -152,7 +181,18 @@ def edit_password():
@login_required
def edit_password_put():
res_json = request.json
return user_curd.edit_password(res_json=res_json)
if res_json.get("newPassword") == '':
return fail_api("新密码不得为空")
if res_json.get("newPassword") != res_json.get("confirmPassword"):
return fail_api("俩次密码不一样")
user = current_user
is_right = user.validate_password(res_json.get("oldPassword"))
if not is_right:
return fail_api("旧密码错误")
user.set_password(res_json.get("newPassword"))
db.session.add(user)
db.session.commit()
return success_api("更改成功")
# 启用用户
@@ -161,7 +201,7 @@ def edit_password_put():
def enable():
_id = request.json.get('userId')
if _id:
res = user_curd.enable_status(_id)
res = enable_status(model=User, id=_id)
if not res:
return fail_api(msg="出错啦")
return success_api(msg="启动成功")
@@ -174,7 +214,7 @@ def enable():
def dis_enable():
_id = request.json.get('userId')
if _id:
res = user_curd.disable_status(_id)
res = disable_status(model=User,id=_id)
if not res:
return fail_api(msg="出错啦")
return success_api(msg="禁用成功")
@@ -186,5 +226,10 @@ def dis_enable():
@authorize("admin:user:remove", log=True)
def batch_remove():
ids = request.form.getlist('ids[]')
user_curd.batch_remove(ids)
for id in ids:
user = User.query.filter_by(id=id).first()
user.role = []
res = User.query.filter_by(id=id).delete()
db.session.commit()
return success_api(msg="批量删除成功")
+56 -24
View File
@@ -1,11 +1,13 @@
from flask import Blueprint, render_template, request, jsonify
from marshmallow import INCLUDE
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.validate import check_data
from applications.models import DeptSchema
from applications.common.admin import dept_curd as dept_curd
from applications.common.utils.validate import xss_escape
from applications.extensions import db
from applications.models import Dept, User
from applications.schemas import DeptOutSchema
dept_bp = Blueprint('dept', __name__, url_prefix='/dept')
@@ -20,10 +22,11 @@ def main():
return render_template('admin/dept/main.html')
@dept_bp.get('/data')
@dept_bp.post('/data')
@authorize("admin:dept:main", log=True)
def data():
power_data = dept_curd.get_dept_dict()
dept = Dept.query.order_by(Dept.sort).all()
power_data = curd.model_to_dicts(schema=DeptOutSchema, data=dept)
res = {
"data": power_data
}
@@ -39,7 +42,8 @@ def add():
@dept_bp.get('/tree')
@authorize("admin:dept:main", log=True)
def tree():
power_data = dept_curd.get_dept_dict()
dept = Dept.query.order_by(Dept.sort).all()
power_data = curd.model_to_dicts(schema=DeptOutSchema, data=dept)
res = {
"status": {"code": 200, "message": "默认"},
"data": power_data
@@ -51,9 +55,19 @@ def tree():
@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)
req_json = request.json
dept = Dept(
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()
return success_api(msg="成功")
@@ -61,7 +75,7 @@ def save():
@authorize("admin:dept:edit", log=True)
def edit():
_id = request.args.get("deptId")
dept = dept_curd.get_dept_by_id(_id)
dept = curd.get_one_by_id(model=Dept, id=_id)
return render_template('admin/dept/edit.html', dept=dept)
@@ -69,12 +83,14 @@ def edit():
@dept_bp.put('/enable')
@authorize("admin:dept:edit", log=True)
def enable():
_id = request.json.get('deptId')
id = request.json.get('deptId')
if id:
res = dept_curd.enable_status(_id)
if not res:
return fail_api(msg="出错啦")
enable = 1
d = Dept.query.filter_by(id=id).update({"status": enable})
if d:
db.session.commit()
return success_api(msg="启用成功")
return fail_api(msg="出错啦")
return fail_api(msg="数据错误")
@@ -82,30 +98,46 @@ def enable():
@dept_bp.put('/disable')
@authorize("admin:dept:edit", log=True)
def dis_enable():
_id = request.json.get('deptId')
id = request.json.get('deptId')
if id:
res = dept_curd.disable_status(_id)
if not res:
return fail_api(msg="出错啦")
enable = 0
d = Dept.query.filter_by(id=id).update({"status": enable})
if d:
db.session.commit()
return success_api(msg="禁用成功")
return fail_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:
json = request.json
id = json.get("deptId"),
data = {
"dept_name": validate.xss_escape(json.get("deptName")),
"sort": validate.xss_escape(json.get("sort")),
"leader": validate.xss_escape(json.get("leader")),
"phone": validate.xss_escape(json.get("phone")),
"email": validate.xss_escape(json.get("email")),
"status": validate.xss_escape(json.get("status")),
"address": validate.xss_escape(json.get("address"))
}
d = Dept.query.filter_by(id=id).update(data)
if not d:
return fail_api(msg="更新失败")
db.session.commit()
return success_api(msg="更新成功")
@dept_bp.delete('/remove/<int:_id>')
@authorize("admin:dept:remove", log=True)
def remove(_id):
res = dept_curd.remove_dept(_id)
d = Dept.query.filter_by(id=_id).delete()
if not d:
return fail_api(msg="删除失败")
res = User.query.filter_by(dept_id=_id).update({"dept_id": None})
db.session.commit()
if res:
return success_api(msg="删除成功")
else:
+1 -3
View File
@@ -1,6 +1,4 @@
from flask import Blueprint
index_bp = Blueprint('Index', __name__, url_prefix='/')
from applications.view.index.index import index_bp
from . import index
+2 -2
View File
@@ -1,6 +1,6 @@
from flask import render_template
from flask import render_template, Blueprint
from . import index_bp
index_bp = Blueprint('Index', __name__, url_prefix='/')
@index_bp.route('/')
+5 -4
View File
@@ -1,7 +1,7 @@
from flask import Blueprint, session, redirect, url_for, render_template, request
from flask_login import current_user, login_user, login_required, logout_user
from applications.common.admin import index_curd
from applications.common import admin as index_curd
from applications.common.admin_log import login_log
from applications.common.utils.http import fail_api, success_api
from applications.models import User
@@ -35,11 +35,12 @@ def login_post():
req = request.form
username = req.get('username')
password = req.get('password')
code = req.get('captcha')
code = req.get('captcha').__str__().lower()
if not username or not password or not code:
return fail_api(msg="用户名或密码没有输入")
s_code = session.get("code", None)
session["code"] = None
if not all([code, s_code]):
return fail_api(msg="参数错误")
@@ -48,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):
+3 -3
View File
@@ -3,18 +3,18 @@ from flask import jsonify
from flask_login import login_required
from . import rights_bp
from ...common.admin import index_curd
from ...common import admin
@rights_bp.get('/configs')
@login_required
def configs():
return index_curd.get_render_config()
return admin.get_render_config()
# 菜单
@rights_bp.get('/menu')
@login_required
def menu():
menu_tree = index_curd.make_menu_tree()
menu_tree = admin.make_menu_tree()
return jsonify(menu_tree)
+14
View File
@@ -0,0 +1,14 @@
version: '3'
services:
flask:
build: .
ports:
- "8000:8000"
restart: always
links:
- mysql:dbserver
mysql:
image: "mysql:5.7"
environment:
- MYSQL_ROOT_PASSWORD=root
restart: always
+19
View File
@@ -0,0 +1,19 @@
import os
import multiprocessing
bind = '0.0.0.0:8000'
backlog = 512
chdir = os.path.dirname(os.path.abspath(__file__))
timeout = 30
worker_class = 'sync'
workers = multiprocessing.cpu_count() * 2 + 1
threads = 2
loglevel = 'info'
access_log_format = '%(t)s %(p)s %(h)s "%(r)s" %(s)s %(L)s %(b)s %(f)s" "%(a)s"'
if not os.path.exists('logs'):
os.mkdir('logs')
accesslog = os.path.join(chdir, "logs/gunicorn_access.log")
errorlog = os.path.join(chdir, "logs/gunicorn_error.log")
+13 -20
View File
@@ -1,24 +1,17 @@
blinker==1.4
captcha==0.3
click==8.0.1
colorama==0.4.4
Flask==2.0.1
Flask==2.1.1
Flask-APScheduler==1.12.2
Flask-DebugToolbar==0.11.0
Flask-Login==0.5.0
flask-marshmallow==0.14.0
Flask-Migrate==3.1.0
Flask-Login==0.6.0
Flask_Reuploaded==0.5.0
Flask-SQLAlchemy==2.5.1
Flask-Uploads==0.2.1
greenlet==1.1.0
itsdangerous==2.0.1
Jinja2==3.0.1
MarkupSafe==2.0.1
marshmallow==3.12.1
flask-marshmallow==0.14.0
marshmallow-sqlalchemy==0.26.1
Pillow==8.2.0
psutil==5.8.0
PyMySQL==1.0.2
python-dotenv==0.17.1
six==1.16.0
SQLAlchemy==1.4.18
sqlparse==0.4.1
Werkzeug==2.0.1
psutil==5.8.0
Flask-Mail==0.9.1
sqlparse==0.4.2
captcha==0.3
Pillow==8.2.0
python-dotenv==0.19.1
webargs==8.0.1
+1
View File
@@ -0,0 +1 @@
exec gunicorn -c gunicorn.conf.py "applications:create_app('development')"
@@ -12,13 +12,64 @@ body,
transition: all .3s;
}
.pear-admin.banner-layout .layui-side {
top: 60px!important;
}
.pear-admin.banner-layout .layui-side .layui-logo {
display: none;
}
.pear-admin.banner-layout .layui-header .layui-logo {
display: inline-block;
}
.pear-admin.banner-layout .layui-side .layui-side-scroll {
height: 100%!important;
}
.pear-admin.banner-layout .layui-side .layui-side-scroll {
height: 100%!important;
}
.pear-admin .layui-header.dark-theme .layui-layout-control .layui-this *{
background-color: rgba(0,0,0,.1)!important;
}
.pear-admin.banner-layout .layui-header {
z-index: 99999;
width: 100%;
left: 0px;
}
.pear-admin.banner-layout .layui-header .layui-layout-left {
left: 230px;
}
.pear-admin.banner-layout .layui-header .layui-logo .title {
top: 2px;
}
.pear-admin.banner-layout .layui-header .layui-layout-control {
display: inline-block;
left: 370px;
}
.pear-admin.banner-layout .layui-header.dark-theme {
box-shadow: 2px 0 6px rgb(0 21 41 / 35%);
}
.pear-admin .layui-header .layui-logo {
display: none;
}
.pear-admin .layui-logo .title {
font-size: 20px;
}
.pear-admin .layui-layout-right .layui-nav-child {
border: 1px solid whitesmoke;
border-radius: 6px;
border-radius: 4px;
width: 150px;
}
@@ -29,23 +80,22 @@ body,
border-bottom: 1px solid whitesmoke;
}
.pear-admin .layui-header .layui-nav-img {
width: 30px;
height: 30px;
.pear-admin .layui-layout-control {
left: 140px;
position: absolute;
}
.pear-admin .layui-layout-control {
left: 120px;
position: absolute;
.pear-admin .layui-layout-control .layui-nav {
padding: 0px;
}
.pear-admin .layui-logo {
width: 230px;
height: 60px;
line-height: 60px;
height: 59px;
line-height: 59px;
position: relative;
background-color: #28333E;
border-bottom: 1px solid rgba(0, 0, 0, .12);
}
.pear-admin .layui-logo img {
@@ -100,12 +150,12 @@ body,
left: 0px;
}
/** 隐 藏 布 局 样 式 */
.pear-mini .layui-logo .title {
/** 收缩布局 */
.pear-mini .layui-side .layui-logo .title {
display: none;
}
.pear-mini .layui-logo .logo {
.pear-mini .layui-side .layui-logo .logo {
display: inline-block;
}
@@ -122,7 +172,7 @@ body,
left: 60px;
}
.pear-mini .layui-logo {
.pear-mini .layui-side .layui-logo {
width: 60px;
}
@@ -210,7 +260,6 @@ body,
height: calc(100% - 62px);
}
/** 隐 藏 布 局 样 式 */
.pear-mini .layui-side {
width: 0px;
}
@@ -289,22 +338,50 @@ body,
}
/** 亮色侧边风格 */
.light-theme .layui-logo {
background-color: white !important;
color: black !important;
}
.light-theme .layui-side-scroll {
background-color: white !important;
color: black !important;
}
.light-theme .layui-side {
/** 侧边主题 (亮) */
.light-theme.layui-side {
box-shadow: 2px 0 8px 0 rgba(29, 35, 41, .05) !important;
}
/** 主 题 选 择 界 面 样 式 */
.light-theme.layui-side .layui-logo {
background-color: white !important;
color: black !important;
border-bottom: 1px whitesmoke solid;
}
.light-theme.layui-side .layui-side-scroll {
background-color: white !important;
color: black !important;
}
.dark-theme.layui-header {
border-bottom: none;
background-color: #28333E;
color: whitesmoke;
}
.dark-theme.layui-header li>a{
color: whitesmoke!important;
}
.dark-theme.layui-header .layui-logo {
box-shadow: none;
border: none;
}
/** 顶部主题 (白) */
.light-theme.layui-header .layui-logo {
background-color: white;
border: none;
box-shadow: none;
}
/** 主题面板 */
.pearone-color .set-text {
height: 42px;
line-height: 42px;
}
.pearone-color .color-title {
padding: 15px 0 0px 20px;
margin-bottom: 4px;
@@ -386,58 +463,3 @@ body,
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, .15);
line-height: 30px;
}
/** 友情链接 */
.more-setting {
margin-top: 45px;
}
.more-setting form {
margin-top: 30px;
}
.more-setting-title {
padding: 15px 0 0px 20px;
margin-bottom: 4px;
}
.more-setting .layui-form-label {
width: 60px;
}
.more-menu-list {
width: 100%;
margin-top: 80px;
}
.more-menu-item:first-child {
border-top: 1px solid #e8e8e8;
}
.more-menu-item .layui-icon {
font-size: 18px;
padding-right: 10px;
}
.more-menu-item {
color: #595959;
height: 50px;
line-height: 50px;
font-size: 16px;
padding: 0 25px;
border-bottom: 1px solid #e8e8e8;
font-style: normal;
display: block;
}
.more-menu-item:hover {
background-color: whitesmoke;
}
.more-menu-item:after {
color: #8c8c8c;
right: 16px;
content: "\e602";
position: absolute;
font-family: layui-icon !important;
}

Some files were not shown because too many files have changed in this diff Show More