重构 admin 初始化:改为 JSON 配置,增加导入导出功能

This commit is contained in:
不胜舟
2026-01-16 18:43:03 +08:00
parent 490f538261
commit 12c31a8e8a
2 changed files with 746 additions and 563 deletions
+215 -561
View File
@@ -1,575 +1,229 @@
import click
import json
import datetime import datetime
import os
from flask.cli import AppGroup from flask.cli import AppGroup
from applications.extensions import db from applications.extensions import db
from applications.models import User, Role, Dept, Power from applications.models import User, Role, Dept, Power
admin_cli = AppGroup("admin") # 1. 定义命令组
admin_cli = AppGroup("admin", help="系统数据管理:包括初始化、导入和导出")
now_time = datetime.datetime.now() # 2. 定义数据存储的文件夹名称
userdata = [ DATA_DIR = "app_data"
User(
id=1,
username='admin',
password_hash='pbkdf2:sha256:150000$raM7mDSr$58fe069c3eac01531fc8af85e6fc200655dd2588090530084d182e6ec9d52c85',
create_at=now_time,
enable=1,
realname='超级管理',
remark='要是不能把握时机,就要终身蹭蹬,一事无成!',
avatar='/static/system/admin/images/avatar.jpg',
dept_id=1,
),
User(
id=2,
username='test',
password_hash='pbkdf2:sha256:150000$cRS8bYNh$adb57e64d929863cf159f924f74d0634f1fecc46dba749f1bfaca03da6d2e3ac',
create_at=now_time,
enable=1,
realname='测试',
remark='要是不能把握时机,就要终身蹭蹬,一事无成!',
avatar='/static/system/admin/images/avatar.jpg',
dept_id=1,
),
User(
id='3',
username='wind',
password_hash='pbkdf2:sha256:150000$skME1obT$6a2c20cd29f89d7d2f21d9e373a7e3445f70ebce3ef1c3a555e42a7d17170b37',
create_at=now_time,
enable=1,
realname='',
remark='要是不能把握时机,就要终身蹭蹬,一事无成!',
avatar='/static/system/admin/images/avatar.jpg',
dept_id=7,
),
]
roledata = [
Role(
id=1,
code='admin',
name='管理员',
enable=1,
details='管理员',
sort=1,
create_time=now_time,
),
Role(
id=2,
code='common',
name='普通用户',
enable=1,
details='只有查看,没有增删改权限',
sort=2,
create_time=now_time,
)
]
deptdata = [
Dept(
id=1,
parent_id=0,
dept_name='总公司',
sort=1,
leader='就眠仪式',
phone='12312345679',
email='123qq.com',
status=1,
remark='这是总公司',
create_at=now_time
),
Dept(
id=4,
parent_id=1,
dept_name='济南分公司',
sort=2,
leader='就眠仪式',
phone='12312345679',
email='123qq.com',
status=1,
remark='这是济南',
create_at=now_time
),
Dept(
id=5,
parent_id=1,
dept_name='唐山分公司',
sort=4,
leader='mkg',
phone='12312345679',
email='123qq.com',
status=1,
remark='这是唐山',
create_at=now_time
),
Dept(
id=7,
parent_id=4,
dept_name='济南分公司开发部',
sort=5,
leader='就眠仪式',
phone='12312345679',
email='123qq.com',
status=1,
remark='测试',
create_at=now_time
),
Dept(
id=8,
parent_id=5,
dept_name='唐山测试部',
sort=5,
leader='mkg',
phone='12312345679',
email='123qq.com',
status=1,
remark='测试部',
create_at=now_time
)
]
powerdata = [
Power(
id=1,
name='系统管理',
type='0',
code='',
url=None,
open_type=None,
parent_id='0',
icon='layui-icon layui-icon-set-fill',
sort=1,
create_time=now_time,
enable=1,
), Power(
id=3,
name='用户管理',
type='1',
code='system:user:main',
url='/system/user/',
open_type='_iframe',
parent_id='1',
icon='layui-icon layui-icon layui-icon layui-icon layui-icon-rate',
sort=1,
create_time=now_time,
enable=1,
), Power(
id=4,
name='权限管理',
type='1',
code='system:power:main',
url='/system/power/',
open_type='_iframe',
parent_id='1',
icon=None,
sort=2,
create_time=now_time,
enable=1,
), Power(
id=9,
name='角色管理',
type='1',
code='system:role:main',
url='/system/role/',
open_type='_iframe',
parent_id='1',
icon='layui-icon layui-icon-username',
sort=2,
create_time=now_time,
enable=1,
), Power(
id=12,
name='系统监控',
type='1',
code='system:monitor:main',
url='/system/monitor/',
open_type='_iframe',
parent_id='1',
icon='layui-icon layui-icon-vercode',
sort=5,
create_time=now_time,
enable=1,
), Power(
id=13,
name='日志管理',
type='1',
code='system:log:main',
url='/system/log/',
open_type='_iframe',
parent_id='1',
icon='layui-icon layui-icon-read',
sort=4,
create_time=now_time,
enable=1,
), Power(
id=17,
name='文件管理',
type='0',
code='',
url='',
open_type='',
parent_id='0',
icon='layui-icon layui-icon-camera',
sort=2,
create_time=now_time,
enable=1,
), Power(
id=18,
name='图片上传',
type='1',
code='system:file:main',
url='/system/file/',
open_type='_iframe',
parent_id='17',
icon='layui-icon layui-icon-camera',
sort=5,
create_time=now_time,
enable=1,
), Power(
id=21,
name='权限增加',
type='2',
code='system:power:add',
url='',
open_type='',
parent_id='4',
icon='layui-icon layui-icon-add-circle',
sort=1,
create_time=now_time,
enable=1,
), Power(
id=22,
name='用户增加',
type='2',
code='system:user:add',
url='',
open_type='',
parent_id='3',
icon='layui-icon layui-icon-add-circle',
sort=1,
create_time=now_time,
enable=1,
), Power(
id=23,
name='用户编辑',
type='2',
code='system:user:edit',
url='',
open_type='',
parent_id='3',
icon='layui-icon layui-icon-rate',
sort=2,
create_time=now_time,
enable=1,
), Power(
id=24,
name='用户删除',
type='2',
code='system:user:remove',
url='',
open_type='',
parent_id='3',
icon='',
sort=3,
create_time=now_time,
enable=1,
), Power(
id=25,
name='权限编辑',
type='2',
code='system:power:edit',
url='',
open_type='',
parent_id='4',
icon='',
sort=2,
create_time=now_time,
enable=1,
), Power(
id=26,
name='权限删除',
type='2',
code='system:power:remove',
url='',
open_type='',
parent_id='4',
icon='',
sort=3,
create_time=now_time,
enable=1,
), Power(
id=27,
name='用户增加',
type='2',
code='system:role:add',
url='',
open_type='',
parent_id='9',
icon='',
sort=1,
create_time=now_time,
enable=1,
), Power(
id=28,
name='角色编辑',
type='2',
code='system:role:edit',
url='',
open_type='',
parent_id='9',
icon='',
sort=2,
create_time=now_time,
enable=1,
), Power(
id=29,
name='角色删除',
type='2',
code='system:role:remove',
url='',
open_type='',
parent_id='9',
icon='',
sort=3,
create_time=now_time,
enable=1,
), Power(
id=30,
name='角色授权',
type='2',
code='system:role:power',
url='',
open_type='',
parent_id='9',
icon='',
sort=4,
create_time=now_time,
enable=1,
), Power(
id=31,
name='图片增加',
type='2',
code='system:file:add',
url='',
open_type='',
parent_id='18',
icon='',
sort=1,
create_time=now_time,
enable=1,
), Power(
id=32,
name='图片删除',
type='2',
code='system:file:delete',
url='',
open_type='',
parent_id='18',
icon='',
sort=2,
create_time=now_time,
enable=1,
), Power(
id=44,
name='数据字典',
type='1',
code='system:dict:main',
url='/system/dict/',
open_type='_iframe',
parent_id='1',
icon='layui-icon layui-icon-console',
sort=6,
create_time=now_time,
enable=1,
), Power(
id=45,
name='字典增加',
type='2',
code='system:dict:add',
url='',
open_type='',
parent_id='44',
icon='',
sort=1,
create_time=now_time,
enable=1,
), Power(
id=46,
name='字典修改',
type='2',
code='system:dict:edit',
url='',
open_type='',
parent_id='44',
icon='',
sort=2,
create_time=now_time,
enable=1,
), Power(
id=47,
name='字典删除',
type='2',
code='system:dict:remove',
url='',
open_type='',
parent_id='44',
icon='',
sort=3,
create_time=now_time,
enable=1,
), Power(
id=48,
name='部门管理',
type='1',
code='system:dept:main',
url='/system/dept/',
open_type='_iframe',
parent_id='1',
icon='layui-icon layui-icon-group',
sort=3,
create_time=now_time,
enable=1,
), Power(
id=49,
name='部门增加',
type='2',
code='system:dept:add',
url='',
open_type='',
parent_id='48',
icon='',
sort=1,
create_time=now_time,
enable=1,
), Power(
id=50,
name='部门编辑',
type='2',
code='system:dept:edit',
url='',
open_type='',
parent_id='48',
icon='',
sort=2,
create_time=now_time,
enable=1,
), Power(
id=51,
name='部门删除',
type='2',
code='system:dept:remove',
url='',
open_type='',
parent_id='48',
icon='',
sort=3,
create_time=now_time,
enable=1,
), Power(
id=57,
name='邮件管理',
type='1',
code='system:mail:main',
url='/system/mail/',
open_type='_iframe',
parent_id='1',
icon='layui-icon ',
sort=7,
create_time=now_time,
enable=1,
), Power(
id=58,
name='邮件发送',
type='2',
code='system:mail:add',
url='',
open_type='',
parent_id='57',
icon='layui-icon layui-icon-ok-circle',
sort=1,
create_time=now_time,
enable=1,
), Power(
id=59,
name='邮件删除',
type='2',
code='system:mail:remove',
url='',
open_type='',
parent_id='57',
icon='',
sort=2,
create_time=now_time,
enable=1,
)
]
def add_user_role(): # --- 辅助工具类 ---
admin_role = Role.query.filter_by(id=1).first() class DateEncoder(json.JSONEncoder):
admin_user = User.query.filter_by(id=1).first() def default(self, obj):
admin_user.role.append(admin_role) if isinstance(obj, datetime.datetime):
test_role = Role.query.filter_by(id=2).first() return obj.strftime('%Y-%m-%d %H:%M:%S')
test_user = User.query.filter_by(id=2).first() return json.JSONEncoder.default(self, obj)
test_user.role.append(test_role)
def parse_time(item):
"""辅助函数:尝试将字典中的时间字符串转换为 datetime 对象"""
for k, v in item.items():
if k in ['create_at', 'create_time', 'update_at'] and isinstance(v, str):
try:
item[k] = datetime.datetime.strptime(v, '%Y-%m-%d %H:%M:%S')
except ValueError:
pass
return item
def model_to_dict(obj):
"""将 SQLAlchemy 模型对象转换为字典"""
data = {}
for c in obj.__table__.columns:
val = getattr(obj, c.name)
data[c.name] = val
return data
def ensure_dir_exists():
"""
确保数据文件夹存在。
修改:路径基于当前脚本文件的位置,而不是执行命令的位置。
"""
# 获取当前脚本(admin_cli.py)所在的目录
current_script_dir = os.path.dirname(os.path.abspath(__file__))
# 拼接得到 app_data 的绝对路径
base_path = os.path.join(current_script_dir, DATA_DIR)
if not os.path.exists(base_path):
os.makedirs(base_path)
return base_path
# --- 核心逻辑:导入数据 ---
def import_logic(file_path, is_force):
"""具体的导入逻辑封装"""
if not os.path.exists(file_path):
click.echo(f"错误: 找不到文件 {file_path}")
return False
click.echo(f"正在读取文件: {file_path}")
with open(file_path, 'r', encoding='utf-8') as f:
raw_data = json.load(f)
if is_force:
click.echo("警告: 正在清空旧数据...")
try:
db.session.query(User).delete()
db.session.query(Role).delete()
db.session.query(Power).delete()
db.session.query(Dept).delete()
db.session.commit()
except Exception as e:
db.session.rollback()
click.echo(f"清空数据失败: {str(e)}")
return False
try:
# 1. 导入部门
count_dept = 0
for item in raw_data.get("depts", []):
item = parse_time(item)
if not Dept.query.get(item['id']):
db.session.add(Dept(**item))
count_dept += 1
db.session.commit() db.session.commit()
# 2. 导入权限
def add_role_power(): count_power = 0
admin_powers = Power.query.filter(Power.id.in_([1, 3, 4, 9, 12, 13, 17, 18, 44, 48])).all() for item in raw_data.get("powers", []):
admin_user = Role.query.filter_by(id=2).first() item = parse_time(item)
for i in admin_powers: if not Power.query.get(item['id']):
admin_user.power.append(i) db.session.add(Power(**item))
count_power += 1
db.session.commit() db.session.commit()
# 3. 导入角色
count_role = 0
for item in raw_data.get("roles", []):
item = parse_time(item)
power_ids = item.pop('power_ids', [])
@admin_cli.command("init") role = Role.query.get(item['id'])
def init_db(): if not role:
db.session.add_all(userdata) role = Role(**item)
print("加载系统必须用户数据") db.session.add(role)
db.session.add_all(roledata) count_role += 1
print("加载系统必须角色数据")
db.session.add_all(deptdata) if power_ids:
print("加载系统必须部门数据") powers = Power.query.filter(Power.id.in_(power_ids)).all()
db.session.add_all(powerdata) role.power = powers
print("加载系统必须权限数据")
db.session.commit() db.session.commit()
print("基础数据存入")
add_user_role() # 4. 导入用户
print("用户角色数据存入") count_user = 0
add_role_power() for item in raw_data.get("users", []):
print("角色权限数据存入") item = parse_time(item)
print("数据初始化完成,请使用run脚本运行") role_ids = item.pop('role_ids', [])
user = User.query.get(item['id'])
if not user:
user = User(**item)
db.session.add(user)
count_user += 1
if role_ids:
roles = Role.query.filter(Role.id.in_(role_ids)).all()
user.role = roles
db.session.commit()
click.echo(f"导入成功! 新增: 部门{count_dept}, 权限{count_power}, 角色{count_role}, 用户{count_user}")
return True
except Exception as e:
db.session.rollback()
click.echo(f"导入失败,已回滚。错误信息: {str(e)}")
return False
# --- 命令:init (系统初始化) ---
@admin_cli.command("init", help="系统初始化:读取 app_data/init.json 并导入数据库")
@click.option('--force', is_flag=True, help='是否强制清空旧数据再导入')
def init_db(force):
"""
系统初始化命令。
默认读取当前脚本同级目录下 app_data/init.json 文件。
"""
base_path = ensure_dir_exists()
target_file = os.path.join(base_path, 'init.json')
if not os.path.exists(target_file):
click.echo(f"错误:在 {base_path} 目录下未找到 init.json 文件。")
click.echo(f"请先将基础数据文件放入该位置,或运行 export 生成。")
return
import_logic(target_file, force)
# --- 命令:export (导出) ---
@admin_cli.command("export", help="导出数据:将数据库数据保存为 JSON 文件")
@click.option('--name', default=None, help='指定导出文件名,不带后缀。如果不填则使用时间戳。')
def export_data(name):
"""
导出数据到当前脚本同级目录下的 app_data 文件夹。
"""
base_path = ensure_dir_exists()
if name:
filename = f"{name}.json"
else:
now_str = datetime.datetime.now().strftime('%Y%m%d_%H%M%S')
filename = f"data_{now_str}.json"
file_path = os.path.join(base_path, filename)
click.echo(f"准备导出数据到: {file_path} ...")
data = {
"depts": [],
"powers": [],
"roles": [],
"users": []
}
# 1. 导出部门
data["depts"] = [model_to_dict(d) for d in Dept.query.order_by(Dept.id).all()]
# 2. 导出权限
data["powers"] = [model_to_dict(p) for p in Power.query.order_by(Power.id).all()]
# 3. 导出角色
roles = Role.query.order_by(Role.id).all()
for r in roles:
r_dict = model_to_dict(r)
r_dict['power_ids'] = [p.id for p in r.power]
data["roles"].append(r_dict)
# 4. 导出用户
users = User.query.order_by(User.id).all()
for u in users:
u_dict = model_to_dict(u)
u_dict['role_ids'] = [r.id for r in u.role]
data["users"].append(u_dict)
try:
with open(file_path, 'w', encoding='utf-8') as f:
json.dump(data, f, cls=DateEncoder, ensure_ascii=False, indent=4)
click.echo(f"导出成功!")
except Exception as e:
click.echo(f"导出失败: {str(e)}")
# --- 命令:import (指定文件导入) ---
@admin_cli.command("import", help="导入数据:从指定的 JSON 文件恢复数据")
@click.option('--file', required=True, help='要导入的文件名 (需包含路径或位于 app_data 下)')
@click.option('--force', is_flag=True, help='是否强制清空旧数据')
def import_data(file, force):
"""
从指定文件导入数据。
"""
# 如果用户只提供了文件名,没有路径,则假设在 app_data 目录下
if not os.path.dirname(file):
file_path = os.path.join(ensure_dir_exists(), file)
else:
file_path = file
import_logic(file_path, force)
@@ -0,0 +1,529 @@
{
"depts": [
{
"id": 1,
"parent_id": 0,
"dept_name": "总公司",
"sort": 1,
"leader": "就眠仪式",
"phone": "12312345679",
"email": "123qq.com",
"status": 1,
"remark": "这是总公司",
"create_at": "2023-01-01 10:00:00"
},
{
"id": 4,
"parent_id": 1,
"dept_name": "济南分公司",
"sort": 2,
"leader": "就眠仪式",
"phone": "12312345679",
"email": "123qq.com",
"status": 1,
"remark": "这是济南",
"create_at": "2023-01-01 10:00:00"
},
{
"id": 5,
"parent_id": 1,
"dept_name": "唐山分公司",
"sort": 4,
"leader": "mkg",
"phone": "12312345679",
"email": "123qq.com",
"status": 1,
"remark": "这是唐山",
"create_at": "2023-01-01 10:00:00"
},
{
"id": 7,
"parent_id": 4,
"dept_name": "济南分公司开发部",
"sort": 5,
"leader": "就眠仪式",
"phone": "12312345679",
"email": "123qq.com",
"status": 1,
"remark": "测试",
"create_at": "2023-01-01 10:00:00"
},
{
"id": 8,
"parent_id": 5,
"dept_name": "唐山测试部",
"sort": 5,
"leader": "mkg",
"phone": "12312345679",
"email": "123qq.com",
"status": 1,
"remark": "测试部",
"create_at": "2023-01-01 10:00:00"
}
],
"powers": [
{
"id": 1,
"name": "系统管理",
"type": "0",
"code": "",
"url": null,
"open_type": null,
"parent_id": "0",
"icon": "layui-icon layui-icon-set-fill",
"sort": 1,
"create_time": "2023-01-01 10:00:00",
"enable": 1
},
{
"id": 3,
"name": "用户管理",
"type": "1",
"code": "system:user:main",
"url": "/system/user/",
"open_type": "_iframe",
"parent_id": "1",
"icon": "layui-icon layui-icon layui-icon layui-icon layui-icon-rate",
"sort": 1,
"create_time": "2023-01-01 10:00:00",
"enable": 1
},
{
"id": 4,
"name": "权限管理",
"type": "1",
"code": "system:power:main",
"url": "/system/power/",
"open_type": "_iframe",
"parent_id": "1",
"icon": null,
"sort": 2,
"create_time": "2023-01-01 10:00:00",
"enable": 1
},
{
"id": 9,
"name": "角色管理",
"type": "1",
"code": "system:role:main",
"url": "/system/role/",
"open_type": "_iframe",
"parent_id": "1",
"icon": "layui-icon layui-icon-username",
"sort": 2,
"create_time": "2023-01-01 10:00:00",
"enable": 1
},
{
"id": 12,
"name": "系统监控",
"type": "1",
"code": "system:monitor:main",
"url": "/system/monitor/",
"open_type": "_iframe",
"parent_id": "1",
"icon": "layui-icon layui-icon-vercode",
"sort": 5,
"create_time": "2023-01-01 10:00:00",
"enable": 1
},
{
"id": 13,
"name": "日志管理",
"type": "1",
"code": "system:log:main",
"url": "/system/log/",
"open_type": "_iframe",
"parent_id": "1",
"icon": "layui-icon layui-icon-read",
"sort": 4,
"create_time": "2023-01-01 10:00:00",
"enable": 1
},
{
"id": 17,
"name": "文件管理",
"type": "0",
"code": "",
"url": "",
"open_type": "",
"parent_id": "0",
"icon": "layui-icon layui-icon-camera",
"sort": 2,
"create_time": "2023-01-01 10:00:00",
"enable": 1
},
{
"id": 18,
"name": "图片上传",
"type": "1",
"code": "system:file:main",
"url": "/system/file/",
"open_type": "_iframe",
"parent_id": "17",
"icon": "layui-icon layui-icon-camera",
"sort": 5,
"create_time": "2023-01-01 10:00:00",
"enable": 1
},
{
"id": 21,
"name": "权限增加",
"type": "2",
"code": "system:power:add",
"url": "",
"open_type": "",
"parent_id": "4",
"icon": "layui-icon layui-icon-add-circle",
"sort": 1,
"create_time": "2023-01-01 10:00:00",
"enable": 1
},
{
"id": 22,
"name": "用户增加",
"type": "2",
"code": "system:user:add",
"url": "",
"open_type": "",
"parent_id": "3",
"icon": "layui-icon layui-icon-add-circle",
"sort": 1,
"create_time": "2023-01-01 10:00:00",
"enable": 1
},
{
"id": 23,
"name": "用户编辑",
"type": "2",
"code": "system:user:edit",
"url": "",
"open_type": "",
"parent_id": "3",
"icon": "layui-icon layui-icon-rate",
"sort": 2,
"create_time": "2023-01-01 10:00:00",
"enable": 1
},
{
"id": 24,
"name": "用户删除",
"type": "2",
"code": "system:user:remove",
"url": "",
"open_type": "",
"parent_id": "3",
"icon": "",
"sort": 3,
"create_time": "2023-01-01 10:00:00",
"enable": 1
},
{
"id": 25,
"name": "权限编辑",
"type": "2",
"code": "system:power:edit",
"url": "",
"open_type": "",
"parent_id": "4",
"icon": "",
"sort": 2,
"create_time": "2023-01-01 10:00:00",
"enable": 1
},
{
"id": 26,
"name": "权限删除",
"type": "2",
"code": "system:power:remove",
"url": "",
"open_type": "",
"parent_id": "4",
"icon": "",
"sort": 3,
"create_time": "2023-01-01 10:00:00",
"enable": 1
},
{
"id": 27,
"name": "用户增加",
"type": "2",
"code": "system:role:add",
"url": "",
"open_type": "",
"parent_id": "9",
"icon": "",
"sort": 1,
"create_time": "2023-01-01 10:00:00",
"enable": 1
},
{
"id": 28,
"name": "角色编辑",
"type": "2",
"code": "system:role:edit",
"url": "",
"open_type": "",
"parent_id": "9",
"icon": "",
"sort": 2,
"create_time": "2023-01-01 10:00:00",
"enable": 1
},
{
"id": 29,
"name": "角色删除",
"type": "2",
"code": "system:role:remove",
"url": "",
"open_type": "",
"parent_id": "9",
"icon": "",
"sort": 3,
"create_time": "2023-01-01 10:00:00",
"enable": 1
},
{
"id": 30,
"name": "角色授权",
"type": "2",
"code": "system:role:power",
"url": "",
"open_type": "",
"parent_id": "9",
"icon": "",
"sort": 4,
"create_time": "2023-01-01 10:00:00",
"enable": 1
},
{
"id": 31,
"name": "图片增加",
"type": "2",
"code": "system:file:add",
"url": "",
"open_type": "",
"parent_id": "18",
"icon": "",
"sort": 1,
"create_time": "2023-01-01 10:00:00",
"enable": 1
},
{
"id": 32,
"name": "图片删除",
"type": "2",
"code": "system:file:delete",
"url": "",
"open_type": "",
"parent_id": "18",
"icon": "",
"sort": 2,
"create_time": "2023-01-01 10:00:00",
"enable": 1
},
{
"id": 44,
"name": "数据字典",
"type": "1",
"code": "system:dict:main",
"url": "/system/dict/",
"open_type": "_iframe",
"parent_id": "1",
"icon": "layui-icon layui-icon-console",
"sort": 6,
"create_time": "2023-01-01 10:00:00",
"enable": 1
},
{
"id": 45,
"name": "字典增加",
"type": "2",
"code": "system:dict:add",
"url": "",
"open_type": "",
"parent_id": "44",
"icon": "",
"sort": 1,
"create_time": "2023-01-01 10:00:00",
"enable": 1
},
{
"id": 46,
"name": "字典修改",
"type": "2",
"code": "system:dict:edit",
"url": "",
"open_type": "",
"parent_id": "44",
"icon": "",
"sort": 2,
"create_time": "2023-01-01 10:00:00",
"enable": 1
},
{
"id": 47,
"name": "字典删除",
"type": "2",
"code": "system:dict:remove",
"url": "",
"open_type": "",
"parent_id": "44",
"icon": "",
"sort": 3,
"create_time": "2023-01-01 10:00:00",
"enable": 1
},
{
"id": 48,
"name": "部门管理",
"type": "1",
"code": "system:dept:main",
"url": "/system/dept/",
"open_type": "_iframe",
"parent_id": "1",
"icon": "layui-icon layui-icon-group",
"sort": 3,
"create_time": "2023-01-01 10:00:00",
"enable": 1
},
{
"id": 49,
"name": "部门增加",
"type": "2",
"code": "system:dept:add",
"url": "",
"open_type": "",
"parent_id": "48",
"icon": "",
"sort": 1,
"create_time": "2023-01-01 10:00:00",
"enable": 1
},
{
"id": 50,
"name": "部门编辑",
"type": "2",
"code": "system:dept:edit",
"url": "",
"open_type": "",
"parent_id": "48",
"icon": "",
"sort": 2,
"create_time": "2023-01-01 10:00:00",
"enable": 1
},
{
"id": 51,
"name": "部门删除",
"type": "2",
"code": "system:dept:remove",
"url": "",
"open_type": "",
"parent_id": "48",
"icon": "",
"sort": 3,
"create_time": "2023-01-01 10:00:00",
"enable": 1
},
{
"id": 57,
"name": "邮件管理",
"type": "1",
"code": "system:mail:main",
"url": "/system/mail/",
"open_type": "_iframe",
"parent_id": "1",
"icon": "layui-icon ",
"sort": 7,
"create_time": "2023-01-01 10:00:00",
"enable": 1
},
{
"id": 58,
"name": "邮件发送",
"type": "2",
"code": "system:mail:add",
"url": "",
"open_type": "",
"parent_id": "57",
"icon": "layui-icon layui-icon-ok-circle",
"sort": 1,
"create_time": "2023-01-01 10:00:00",
"enable": 1
},
{
"id": 59,
"name": "邮件删除",
"type": "2",
"code": "system:mail:remove",
"url": "",
"open_type": "",
"parent_id": "57",
"icon": "",
"sort": 2,
"create_time": "2023-01-01 10:00:00",
"enable": 1
}
],
"roles": [
{
"id": 1,
"code": "admin",
"name": "管理员",
"enable": 1,
"details": "管理员",
"sort": 1,
"create_time": "2023-01-01 10:00:00",
"power_ids": []
},
{
"id": 2,
"code": "common",
"name": "普通用户",
"enable": 1,
"details": "只有查看,没有增删改权限",
"sort": 2,
"create_time": "2023-01-01 10:00:00",
"power_ids": [1, 3, 4, 9, 12, 13, 17, 18, 44, 48]
}
],
"users": [
{
"id": 1,
"username": "admin",
"password_hash": "pbkdf2:sha256:150000$raM7mDSr$58fe069c3eac01531fc8af85e6fc200655dd2588090530084d182e6ec9d52c85",
"create_at": "2023-01-01 10:00:00",
"enable": 1,
"realname": "超级管理",
"remark": "要是不能把握时机,就要终身蹭蹬,一事无成!",
"avatar": "/static/system/admin/images/avatar.jpg",
"dept_id": 1,
"role_ids": [1]
},
{
"id": 2,
"username": "test",
"password_hash": "pbkdf2:sha256:150000$cRS8bYNh$adb57e64d929863cf159f924f74d0634f1fecc46dba749f1bfaca03da6d2e3ac",
"create_at": "2023-01-01 10:00:00",
"enable": 1,
"realname": "测试",
"remark": "要是不能把握时机,就要终身蹭蹬,一事无成!",
"avatar": "/static/system/admin/images/avatar.jpg",
"dept_id": 1,
"role_ids": [2]
},
{
"id": "3",
"username": "wind",
"password_hash": "pbkdf2:sha256:150000$skME1obT$6a2c20cd29f89d7d2f21d9e373a7e3445f70ebce3ef1c3a555e42a7d17170b37",
"create_at": "2023-01-01 10:00:00",
"enable": 1,
"realname": "风",
"remark": "要是不能把握时机,就要终身蹭蹬,一事无成!",
"avatar": "/static/system/admin/images/avatar.jpg",
"dept_id": 7,
"role_ids": []
}
]
}