670 Commits
v1.0 ... v1

Author SHA1 Message Date
JaguarJack
160e506bfe add:优雅的返回Json数据 2020-08-27 16:19:06 +08:00
JaguarJack
a859e98207 fixed:修复类型异常未捕获 2020-08-27 16:18:09 +08:00
JaguarJack
b1f5c22c9d update:用户禁用 2020-08-20 21:02:16 +08:00
JaguarJack
a7609d9c77 update:修改部门权限标志 2020-08-18 19:32:33 +08:00
JaguarJack
cb9deeb7ce update:更新readme 2020-08-13 08:55:10 +08:00
JaguarJack
b62cf987d1 fixed:修改方法返回 2020-08-12 19:29:41 +08:00
JaguarJack
c6e235ca6c 更新readme 2020-08-11 21:24:18 +08:00
JaguarJack
03bb91cd9e update:优化数据表搜索 2020-08-10 11:37:34 +08:00
JaguarJack
e15838386f update:更新zip类 2020-08-10 11:17:32 +08:00
JaguarJack
bcf37924d3 update:更新解析parseClass 2020-08-10 11:16:42 +08:00
JaguarJack
1a965ff4f5 add:新增安装模块的类 2020-08-10 11:16:12 +08:00
JaguarJack
bbfb206210 update:更新打包工具 2020-08-10 11:15:48 +08:00
JaguarJack
2f76d0da38 update:更新上传模块 2020-08-10 11:15:12 +08:00
JaguarJack
ea6e45450c update:更新安装模块 2020-08-10 11:14:53 +08:00
JaguarJack
4bfa907191 update: 优化创建模块 2020-08-10 10:33:13 +08:00
JaguarJack
6c9f1cface Merge branch 'master' of https://github.com/yanwenwu/catch-admin 2020-08-10 08:11:42 +08:00
JaguarJack
8776849d98 update:修改人物提示信息
:^O
2020-08-08 20:49:34 +08:00
JaguarJack
b5a589d4da update:新增进程最大内存限制 2020-08-08 20:43:58 +08:00
JaguarJack
c529d36f03 !2 1.修改描述,嘿嘿
Merge pull request !2 from sunhuan/master
2020-08-07 11:05:51 +08:00
sunhuan
de97a1319e 1.修改描述 2020-08-07 10:51:41 +08:00
JaguarJack
d410434979 fixed:菜单更新 2020-07-29 10:29:10 +08:00
JaguarJack
29732738dc add:新增菜单字段 2020-07-29 07:30:05 +08:00
JaguarJack
230ea26a1b update: 获取上传默认驱动 2020-07-29 07:29:42 +08:00
JaguarJack
d1a42637fe fixed:批量删除 2020-07-28 16:40:05 +08:00
JaguarJack
fae47bf246 update:优化代码 2020-07-28 08:19:51 +08:00
JaguarJack
cba66dfe58 fixed:migration 表前缀 2020-07-27 07:58:11 +08:00
JaguarJack
cc34e058f0 update:配置更新 2020-07-26 18:43:09 +08:00
JaguarJack
3ab7e207c9 update:修改attachments URL 路径地址 2020-07-26 08:28:54 +08:00
JaguarJack
e232062ba6 update:修改can方法 2020-07-25 21:33:20 +08:00
JaguarJack
3a0c537ce0 update:优化代码 2020-07-25 10:04:13 +08:00
JaguarJack
d9faa42905 新增issue模版 2020-07-25 08:46:01 +08:00
JaguarJack
99727f1c7d Merge branch 'master' of https://github.com/yanwenwu/catch-admin 2020-07-25 08:34:24 +08:00
JaguarJack
7fc50c9916 Merge pull request #13 from qingmang/patch-1
后台增加权限判断
2020-07-25 07:50:13 +08:00
青芒科技
454fa43f8c Update Users.php 2020-07-24 22:16:34 +08:00
青芒科技
cdf6efde1d Update Users.php 2020-07-24 22:16:19 +08:00
JaguarJack
c65863d606 update:更新权限方法 2020-07-24 21:40:26 +08:00
青芒科技
c5650e80bd 后台增加权限判断
后台可以快捷的通过 `request()->user()->can('权限标识');` 来判断某个用户是否拥有某个权限,便于权限区分
2020-07-24 21:36:40 +08:00
JaguarJack
8d21dc8acc http客户端新增属性 2020-07-23 16:43:01 +08:00
JaguarJack
263c036e49 降低symfony/finder版本 2020-07-23 07:34:19 +08:00
JaguarJack
f0351246fc 新增zip&composer工具 2020-07-21 08:01:20 +08:00
JaguarJack
30f405f233 delete composer.lock 2020-07-21 07:57:58 +08:00
JaguarJack
94052b6e01 fixed bug 2020-07-20 17:03:49 +08:00
JaguarJack
ab9302e790 fixed:修复Finder not found 2020-07-20 17:01:01 +08:00
JaguarJack
f396732544 新增symfony/finder 2020-07-20 16:48:27 +08:00
JaguarJack
0fb344fcf3 update:修改微信粉丝同步 2020-07-19 16:55:38 +08:00
JaguarJack
78bb8bccd7 数据库备份 2020-07-19 16:47:58 +08:00
JaguarJack
027ba1acdb 优化catchConsole代码 2020-07-19 10:06:08 +08:00
JaguarJack
2757873ef2 新增文件操作 2020-07-19 09:15:15 +08:00
JaguarJack
6e1fdb2b74 优化模块下 commands 在cli模式下注入 2020-07-19 08:46:12 +08:00
JaguarJack
929f9b2a75 优化commands只有在Cli模式下注入 2020-07-19 08:40:49 +08:00
JaguarJack
db18e71906 Merge pull request #8 from tlerbao/master
登录日志新增数据搜索功能,修改路由Path单词用反了的问题
2020-07-18 20:51:11 +08:00
tlerbao
3f5b84ba45 操作日志和登录日志的路由Path单词用反了 2020-07-18 17:16:04 +08:00
tlerbao
bb1dd9b207 登录日志新增数据搜索功能 2020-07-18 17:12:07 +08:00
JaguarJack
eee53b3131 Merge branch 'master' of https://github.com/yanwenwu/catch-admin 2020-07-16 14:35:19 +08:00
JaguarJack
a86387a47e fixed:修复表信息获取 2020-07-16 14:12:44 +08:00
JaguarJack
b538c08b88 Merge pull request #6 from tlerbao/master
操作日志新增批量删除
2020-07-15 14:57:59 +08:00
JaguarJack
ce38bc741b Merge pull request #5 from qingmang/patch-2
设置departments获取的默认值
2020-07-15 14:55:23 +08:00
tlerbao
142fd71b56 操作日志新增条件查询,并简单优化了操作日志控制器 2020-07-15 11:39:55 +08:00
tlerbao
a6ad9b63dd 操作日志新增批量删除 2020-07-14 21:06:10 +08:00
JaguarJack
8a901e89cb 删除冗余代码&修复bug 2020-07-14 17:35:16 +08:00
JaguarJack
fc93826016 修改auth认证 2020-07-14 12:21:29 +08:00
青芒科技
98b2d7d31b 设置departments获取的默认值
只有自定义数据才存在departments
2020-07-13 19:00:53 +08:00
JaguarJack
33bdd01933 移除不必要的包 2020-07-13 17:57:57 +08:00
JaguarJack
32b87baeee 优化 Request 认证 2020-07-13 17:07:18 +08:00
JaguarJack
19c092dffc 删除冗余代码 2020-07-13 17:06:54 +08:00
JaguarJack
81e7f78419 新增模块上传 2020-07-13 17:06:21 +08:00
JaguarJack
a5416bd0ad 修复生成代码 2020-07-13 17:05:34 +08:00
JaguarJack
6d51b5bc76 新增开发者认证配置 2020-07-13 17:04:53 +08:00
JaguarJack
04e008fcfa 开发者认证 2020-07-13 17:04:35 +08:00
JaguarJack
7ef4efa37a 新增开发者 2020-07-13 15:28:38 +08:00
JaguarJack
1644076abe Guard 未设置抛出异常 2020-07-13 09:04:57 +08:00
JaguarJack
5b43786432 插件上传 2020-07-12 18:03:48 +08:00
JaguarJack
1e8b5510f1 修复远程下载模块 2020-07-11 21:44:39 +08:00
JaguarJack
7adfc93190 新增安装模块命令 2020-07-11 16:13:06 +08:00
JaguarJack
b9c156e5a7 修改打包命令 2020-07-11 16:12:17 +08:00
JaguarJack
bcdf6cd9c7 修改catchadmin根目录 2020-07-11 15:52:30 +08:00
root
e17846571c 新增下载保存地址方法 2020-07-11 15:02:05 +08:00
JaguarJack
359381fec6 生成代码新增回滚功能 2020-07-11 10:59:57 +08:00
root
42e75f50ff 修改日志记录方式 2020-07-11 10:10:42 +08:00
JaguarJack
454e1fcd55 去除不必要的包 2020-07-10 16:38:42 +08:00
JaguarJack
5584fa66da 修复定时任务秒级执行 2020-07-10 08:49:31 +08:00
JaguarJack
87ec38d1dd 新增调度中心 2020-07-10 08:35:14 +08:00
JaguarJack
6db13b9eab 修改信号处理 2020-07-09 22:01:52 +08:00
JaguarJack
e678b4ce51 新增调度配置 2020-07-09 21:56:39 +08:00
JaguarJack
b8de40a60f 新增守护控制选项 2020-07-09 21:56:17 +08:00
JaguarJack
c84d5a2a17 修复创建最大进程数目之后可继续创建 2020-07-09 21:17:34 +08:00
JaguarJack
9335556197 worker状态切换到table内存操作 2020-07-09 21:03:16 +08:00
JaguarJack
40ed25816c 新增 swoole table 2020-07-09 21:02:44 +08:00
JaguarJack
2a593b179a 异常日志记录 2020-07-09 15:41:53 +08:00
JaguarJack
a5b6b479ce 增加USR1信号,实时获取 worker 信息 2020-07-09 10:04:31 +08:00
JaguarJack
104ad3f744 修复worker等待状态bug 2020-07-09 08:37:03 +08:00
JaguarJack
ea32a4cd33 worker状态管理 2020-07-09 08:28:29 +08:00
JaguarJack
a3f378eca8 写入 worker 状态信息 2020-07-08 19:47:35 +08:00
JaguarJack
bcc4237140 修复定时任务无法准时启动 2020-07-08 17:48:45 +08:00
JaguarJack
4fec98f939 新增 crontab 组件 2020-07-07 16:58:34 +08:00
JaguarJack
f15eedfa9c 新增调度命令 2020-07-07 16:58:16 +08:00
JaguarJack
da683a3592 Merge branch 'master' of https://github.com/yanwenwu/catch-admin 2020-07-06 08:54:33 +08:00
JaguarJack
7adfb6a0ae Merge pull request #4 from qingmang/patch-1
fix:自定义数据范围更新追加部门数据更新
2020-07-06 08:54:11 +08:00
青芒科技
a73883cc79 fix:自定义数据范围更新追加部门数据更新 2020-07-05 20:15:40 +08:00
JaguarJack
3235e98c38 新增版本信息 2020-07-05 16:36:28 +08:00
JaguarJack
bb38e3bdac 修复更新权限父类未更新子类模块 2020-07-05 07:20:01 +08:00
JaguarJack
9092b64c1f 新增超级管理员判断&权限范围 2020-07-04 21:56:47 +08:00
JaguarJack
e798098a05 修改数据范围 2020-07-04 21:35:01 +08:00
JaguarJack
c2da2e5806 修复数据权限 bug 2020-07-04 14:28:59 +08:00
JaguarJack
6e1be051e2 修改模版 2020-07-04 11:32:04 +08:00
JaguarJack
a34d687203 新增request post方法加入 creator_id 2020-07-04 10:44:39 +08:00
JaguarJack
2746d565e4 修复添加部门没有存入creator_id 2020-07-04 10:43:09 +08:00
JaguarJack
fda520bad3 修改modulejson信息 2020-07-03 21:24:42 +08:00
JaguarJack
1abcc5045f 新增令牌桶限流 2020-07-02 18:41:47 +08:00
JaguarJack
5e076a6eb7 新增滑动窗口限流 2020-07-02 17:28:01 +08:00
JaguarJack
349f36df21 降低phpunit版本 2020-07-02 14:30:25 +08:00
JaguarJack
9ec043ba34 catchConsole加入容器,提高性能 2020-07-02 14:22:02 +08:00
JaguarJack
e51cbc6850 修改wechat commands 注入方式 2020-07-02 14:01:47 +08:00
JaguarJack
26e26b60a7 新增 console 统一注入 2020-07-02 14:01:05 +08:00
JaguarJack
e35b14a883 新增文件处理 2020-07-02 13:19:23 +08:00
JaguarJack
24e1506743 修改启用/禁用模块删除对应的菜单 2020-07-01 15:47:06 +08:00
JaguarJack
51672734a6 优化sql生成&添加creator_id 2020-07-01 15:24:42 +08:00
JaguarJack
1a20159776 新增redis固定窗口限流 2020-06-30 18:06:01 +08:00
JaguarJack
bd840134ad 修改异常信息 2020-06-30 17:42:07 +08:00
JaguarJack
9740df6a97 修改路由生成 2020-06-30 10:46:39 +08:00
JaguarJack
0ef84fea08 修改模型模版 2020-06-30 10:31:27 +08:00
JaguarJack
2b4f9823ff 优化代码生成 2020-06-30 10:14:27 +08:00
JaguarJack
051627547e 优化微信图文 2020-06-30 08:40:00 +08:00
JaguarJack
16a19312a9 回复搜索 2020-06-30 07:36:38 +08:00
JaguarJack
7dedec17d9 修复回复media_id 2020-06-30 07:17:55 +08:00
JaguarJack
b9f055e052 新增上传文件类型 2020-06-30 07:17:13 +08:00
JaguarJack
57d26f8003 完善回复功能 2020-06-29 22:04:40 +08:00
JaguarJack
655541210a 新增禁用/启用 2020-06-29 22:01:47 +08:00
JaguarJack
f2affda157 新增上传 2020-06-29 20:02:33 +08:00
JaguarJack
08fb8b3397 微信回复功能 2020-06-29 19:51:44 +08:00
JaguarJack
09c409fc76 修改权限数据 2020-06-28 15:09:42 +08:00
JaguarJack
6841f6c385 新增系统权限数据 2020-06-28 15:09:15 +08:00
JaguarJack
99136f33d1 修改微信权限数据 2020-06-28 15:08:56 +08:00
JaguarJack
41eb836634 优化提示 2020-06-28 11:32:50 +08:00
JaguarJack
db9428961f 微信权限菜单 2020-06-28 08:45:14 +08:00
JaguarJack
cc5805f410 修改上传 2020-06-28 08:34:19 +08:00
JaguarJack
1c9e98ff2a 新增微信图文 2020-06-28 08:33:49 +08:00
JaguarJack
7152661210 修改本地存储路径 2020-06-28 08:33:34 +08:00
JaguarJack
59774e7958 新增微信认证url 2020-06-26 22:08:27 +08:00
JaguarJack
bcd7215333 新增事件消息 2020-06-26 22:08:01 +08:00
JaguarJack
a232f555c3 微信菜单 2020-06-26 16:27:20 +08:00
JaguarJack
ce71b10d1c 修改数据库基础操作 2020-06-25 09:25:34 +08:00
JaguarJack
707070a06e 修改创建模块命令 2020-06-25 09:25:02 +08:00
JaguarJack
fca8980715 新增角色初始化数据 2020-06-25 08:36:59 +08:00
JaguarJack
4dc2978d61 新增模块权限导出 2020-06-25 08:36:29 +08:00
JaguarJack
cfaec3fbc3 新增seedPath创建方法 2020-06-25 08:35:52 +08:00
JaguarJack
d2bc7a25c0 优化Catchadmin服务 2020-06-24 10:07:53 +08:00
JaguarJack
5f5260a639 优化开启/关闭模块 2020-06-24 10:07:11 +08:00
JaguarJack
f6783cb13e 优化服务发现 2020-06-24 09:46:21 +08:00
JaguarJack
ee04005d69 架构调整,服务调整 2020-06-24 09:11:48 +08:00
JaguarJack
9125292aa8 新增模块抽象服务 2020-06-24 09:11:30 +08:00
JaguarJack
2c18af0aa7 架构调整路由加载 2020-06-24 09:11:08 +08:00
JaguarJack
2d95212973 调整架构,新增微信模块服务 2020-06-24 09:10:24 +08:00
JaguarJack
0e7453a6fe 调整架构,新增系统模块服务 2020-06-24 09:10:01 +08:00
JaguarJack
8c32893c91 调整架构,新增权限模块服务 2020-06-24 09:09:37 +08:00
JaguarJack
805b04a7f8 新增事件监听 2020-06-24 09:09:10 +08:00
JaguarJack
8dfd4596be 删除配置 2020-06-24 09:08:06 +08:00
JaguarJack
8b4404df55 login新增Service 2020-06-24 08:47:46 +08:00
JaguarJack
23fa6ab097 新增禁止开启模块 2020-06-23 21:37:37 +08:00
JaguarJack
f18766c20a 优化范围查询 2020-06-22 15:19:50 +08:00
JaguarJack
d873ba10f9 修复模块服务发现导致的兼容问题 2020-06-22 12:36:25 +08:00
JaguarJack
51d237d0f0 安装新增模块服务发现 2020-06-22 08:05:51 +08:00
JaguarJack
6e76c173a7 优化catchQuery 2020-06-22 07:55:39 +08:00
JaguarJack
a3dd8282b3 完善微信粉丝和标签 2020-06-22 07:55:16 +08:00
JaguarJack
317a9ef595 优化角色权限分配 2020-06-21 21:07:15 +08:00
JaguarJack
e6d7ee8f55 修改命令 2020-06-21 18:04:55 +08:00
JaguarJack
fbf9c11191 微信标签管理 2020-06-21 18:04:30 +08:00
JaguarJack
4392f25e97 优化微信错误码 2020-06-21 16:20:02 +08:00
JaguarJack
73c7788218 新增微信错误码 2020-06-21 14:42:02 +08:00
JaguarJack
835b93eaaf 优化微信服务 2020-06-21 14:41:46 +08:00
JaguarJack
092567a169 新增微信用户 2020-06-21 14:41:22 +08:00
JaguarJack
028333fae3 新增基类仓库 2020-06-21 13:24:15 +08:00
JaguarJack
7b0aa49c21 新增微信响应错误 2020-06-21 13:23:43 +08:00
JaguarJack
c624dc1777 新增微信公众号错误 2020-06-21 13:23:22 +08:00
JaguarJack
dc08715bc7 新增命令行进度条 2020-06-21 10:50:29 +08:00
JaguarJack
11f6419b4f 抽象scope trait 2020-06-21 10:50:05 +08:00
JaguarJack
448154f363 微信用户列表 2020-06-21 10:48:55 +08:00
JaguarJack
cd8ff84f02 微信用户同步 2020-06-21 10:48:11 +08:00
JaguarJack
97724b04df 新增catchadmin模块发现 2020-06-20 16:57:37 +08:00
JaguarJack
6e9c0aed32 删除输出 2020-06-20 09:29:45 +08:00
JaguarJack
de6470fd0e 优化模块服务发现 2020-06-20 09:13:11 +08:00
JaguarJack
bd21242410 删除登陆模块service 2020-06-20 09:12:19 +08:00
JaguarJack
f21716d5a6 修复获取模块信息bug 2020-06-20 08:51:28 +08:00
JaguarJack
49500956dd 删除冗余代码 2020-06-20 08:51:11 +08:00
JaguarJack
9ff6c8d883 新增模块服务安装命令 2020-06-20 08:50:49 +08:00
JaguarJack
6612dfd8b7 优化安装 2020-06-20 08:50:21 +08:00
JaguarJack
93c1c11853 新增模块json信息 2020-06-20 08:49:44 +08:00
JaguarJack
49a8d04157 新增微信服务 2020-06-20 08:49:16 +08:00
JaguarJack
1d1afe468c 新增微信用户同步表 2020-06-19 20:58:11 +08:00
JaguarJack
20b3fd477f 新增用户管理 2020-06-19 19:29:21 +08:00
JaguarJack
e4273e5a1a 新增微信动态调用 2020-06-19 19:28:56 +08:00
JaguarJack
2c9e22ac6c 新增敏感词库菜单 2020-06-18 17:45:45 +08:00
JaguarJack
e717f56416 优化导出命令 2020-06-18 17:45:04 +08:00
JaguarJack
96f04545db 新增trie tree缓存命令 2020-06-18 17:08:47 +08:00
JaguarJack
cbfcce919f 新增敏感词请求验证 2020-06-18 16:30:25 +08:00
JaguarJack
1f3c025f36 新增敏感词验证 2020-06-18 16:29:54 +08:00
JaguarJack
b4b0d624a6 fixed dfa bug 2020-06-18 16:29:26 +08:00
JaguarJack
5a198f8f0b 新增phpunit 2020-06-18 10:50:38 +08:00
JaguarJack
fcc6fd035d 新增redis配置 2020-06-17 23:03:04 +08:00
JaguarJack
4fc4577be3 新增DFA算法过滤敏感词 2020-06-17 23:02:52 +08:00
JaguarJack
dec79f2b28 新增敏感词缓存key 2020-06-17 23:02:12 +08:00
JaguarJack
f14107dc44 新增敏感词搜索 2020-06-17 16:19:51 +08:00
JaguarJack
727640396e 新增子查询方法 addSelectSub 2020-06-17 16:19:21 +08:00
JaguarJack
e105492d27 修改排序 2020-06-17 14:40:01 +08:00
JaguarJack
c450c4afc5 新增敏感词库 2020-06-17 14:29:31 +08:00
JaguarJack
13d3734dba 修改排序 2020-06-17 13:24:02 +08:00
JaguarJack
6977442b05 去除重写Order 方法,新增 CatchOrder 2020-06-17 13:23:43 +08:00
JaguarJack
3b063ac1fd fixed conflict 2020-06-08 08:56:05 +08:00
JaguarJack
5609d4fd09 fixed 2020-06-08 08:54:50 +08:00
JaguarJack
66acbeee8b 优化微信发布命令 2020-06-07 14:23:26 +08:00
JaguarJack
5231770bab 新增微信扩展 2020-06-07 14:23:07 +08:00
JaguarJack
ec5a5a8402 新增微信模块 2020-06-07 14:22:41 +08:00
JaguarJack
e9c8940730 新增微信发布 2020-06-06 22:37:36 +08:00
JaguarJack
333d0be409 修改readme 2020-06-06 21:50:36 +08:00
JaguarJack
ffeec69333 数据范围查询 2020-06-06 18:57:58 +08:00
JaguarJack
ac56a7b80d 添加必要注释 2020-06-06 09:21:24 +08:00
JaguarJack
9a07ae1e1b 修改readme 2020-06-06 08:58:55 +08:00
JaguarJack
08b7a1b17c 修改parseclass 2020-06-05 16:20:50 +08:00
JaguarJack
d232ebb207 优化 2020-06-05 15:58:16 +08:00
JaguarJack
8550c99133 新增parseclass组件 2020-06-05 15:35:51 +08:00
JaguarJack
f55ff91554 修改方法获取 2020-06-05 15:35:31 +08:00
JaguarJack
f9ed43017f 新增权限方法获取 2020-06-05 15:20:22 +08:00
JaguarJack
c06e7b8694 更新附件模型 2020-06-01 21:28:04 +08:00
JaguarJack
fe6ea82014 新增附件事件 2020-06-01 21:25:46 +08:00
JaguarJack
39c0ec4c48 删除冗余代码 2020-05-28 08:24:49 +08:00
JaguarJack
107a7d48da 优化模型生成命令 2020-05-28 06:38:10 +08:00
JaguarJack
b57d7f95c3 优化模型代码生成 2020-05-28 06:37:32 +08:00
JaguarJack
5face1c077 优化excel导出 2020-05-26 22:55:02 +08:00
JaguarJack
a5a05b1e88 增加内存设置选项 2020-05-26 22:44:48 +08:00
JaguarJack
ea6a4b15a8 修改搜索 2020-05-26 22:39:06 +08:00
JaguarJack
c60d8d2dc9 优化搜索 2020-05-26 09:32:52 +08:00
JaguarJack
bae43ad382 优化excel导出 2020-05-25 22:50:51 +08:00
JaguarJack
74a42e7022 修改设置开始列无效bug 2020-05-25 22:39:00 +08:00
JaguarJack
c04530a1be 优化 excel 2020-05-25 19:55:25 +08:00
JaguarJack
2074c1f65d 新增 excel 工具 2020-05-25 19:47:54 +08:00
JaguarJack
c0e3726775 修改README 2020-05-25 15:07:01 +08:00
JaguarJack
0f59685ae3 修服左侧菜单排序不生效 bug 2020-05-25 14:30:28 +08:00
JaguarJack
dfcec7394f 修改readme 2020-05-24 10:56:08 +08:00
JaguarJack
8bf7380d82 优化 auth 单例获取用户,支持 guard 获取 2020-05-23 14:04:23 +08:00
JaguarJack
fa04341608 优化 auth 单例获取用户,防止多次查询 2020-05-23 11:10:28 +08:00
JaguarJack
167ea743a0 优化 http 客户端 2020-05-22 18:24:10 +08:00
JaguarJack
30e7829d21 优化 2020-05-22 15:56:28 +08:00
JaguarJack
1d1eaa0338 优化打包类 2020-05-22 15:45:33 +08:00
JaguarJack
a60880d327 优化 http 客户端 2020-05-22 15:45:14 +08:00
JaguarJack
19c62e049c 修复异常错误显示 2020-05-22 15:22:21 +08:00
JaguarJack
0df821d1a4 优化用户立标 2020-05-22 15:21:05 +08:00
JaguarJack
00a37a05f2 优化command 2020-05-22 14:09:59 +08:00
JaguarJack
93f22ab338 修改方法为静态 2020-05-22 14:09:48 +08:00
JaguarJack
ca5e76497c 完善 http 客户端 2020-05-22 14:08:53 +08:00
JaguarJack
b7d951bdb7 新增facade方法注释,以便用户访问 2020-05-22 14:08:35 +08:00
JaguarJack
bfc576b437 新增前缀获取 2020-05-22 14:07:55 +08:00
JaguarJack
5ac51366f2 新增http客户端 2020-05-21 23:08:16 +08:00
yanwenwu
853ebe7437 优化配置 2020-05-20 19:21:28 +08:00
yanwenwu
c635a322bb 修改配置获取类型错误导致前端报错 2020-05-20 12:52:25 +08:00
yanwenwu
70b6b0407c 菜单新增隐藏显示功能 2020-05-20 11:31:04 +08:00
yanwenwu
ff1d7dfd2e 修复代码生成器bug 2020-05-20 11:03:21 +08:00
yanwenwu
181ceefd55 修复migraions地址 2020-05-20 10:06:42 +08:00
yanwenwu
48f572168f 修复未定义table 2020-05-19 11:03:42 +08:00
yanwenwu
64ce1243b4 fixed bug 2020-05-19 08:22:48 +08:00
yanwenwu
9da4072b30 新增字段 2020-05-18 15:47:32 +08:00
yanwenwu
52e25103d0 新增状态码 2020-05-18 13:42:26 +08:00
yanwenwu
2361be7d71 修改过期token返回码 2020-05-18 13:42:08 +08:00
yanwenwu
5057f3eb9e refresh token 2020-05-18 13:41:46 +08:00
yanwenwu
b4bb0a1910 logout 2020-05-18 10:12:33 +08:00
yanwenwu
f913f76bd2 修改readme 2020-05-17 22:41:14 +08:00
yanwenwu
45383c2230 修改readme 2020-05-17 17:09:53 +08:00
JaguarJack
dbc6eb2b48 修改菜单 2020-05-17 16:08:40 +08:00
JaguarJack
3f814116de 修改安装命令 2020-05-17 15:49:42 +08:00
JaguarJack
db2aba9b1a update readme 2020-05-16 23:44:22 +08:00
JaguarJack
68cdec973a update README.md. 2020-05-16 21:26:39 +08:00
JaguarJack
82a99d7d17 修改readme 2020-05-16 21:09:05 +08:00
JaguarJack
a90f289792 修改READ 2020-05-16 21:06:50 +08:00
JaguarJack
9b2c4aa905 新增添加菜单命令 2020-05-08 20:56:21 +08:00
JaguarJack
d68891035b fixed 生成表 2020-05-08 19:21:31 +08:00
JaguarJack
6f8552fa70 fixed bug 2020-05-07 13:45:31 +08:00
JaguarJack
278b078937 修复创建人ID无法获取 2020-05-06 22:16:55 +08:00
JaguarJack
0cc8dc7927 增加扩展 2020-05-06 17:55:16 +08:00
JaguarJack
9dda665ddc 新增工具方法 2020-05-06 17:41:36 +08:00
JaguarJack
056abcd9f1 新增操作中间件 2020-05-06 17:41:09 +08:00
JaguarJack
98c99e05f3 分离日志操作权限 2020-05-06 17:40:51 +08:00
JaguarJack
339f441d4f 优化角色权限 2020-05-06 11:46:40 +08:00
JaguarJack
72eb174946 优化代码生成 2020-05-05 21:52:44 +08:00
JaguarJack
635f3e00d0 修改SQL生成 2020-05-05 12:35:36 +08:00
JaguarJack
9e5bbeae5a 修改模版 2020-05-05 12:34:32 +08:00
JaguarJack
0bc448f8e8 readme 2020-05-02 06:39:18 +08:00
JaguarJack
dd1ce48646 fixed bug 2020-05-01 01:00:55 +08:00
JaguarJack
ae01ba64b2 fixed bug 2020-05-01 00:59:46 +08:00
JaguarJack
892f8f2aad fixed bug 2020-05-01 00:38:41 +08:00
JaguarJack
4e38e7ede2 fiexed bug 2020-04-30 18:15:48 +08:00
JaguarJack
fbc4a6201a 增加注释 2020-04-30 18:15:34 +08:00
JaguarJack
5fb45c0d49 修改操作日志参数长度 2020-04-30 18:10:38 +08:00
JaguarJack
2febc2bb56 修改部门排序 2020-04-30 17:58:55 +08:00
JaguarJack
e1abef2319 新增order 2020-04-30 17:58:36 +08:00
JaguarJack
dd0ad744e6 优化打包命令 2020-04-30 15:24:16 +08:00
JaguarJack
b86347a993 优化 2020-04-30 15:24:02 +08:00
JaguarJack
196dfbcbda 新增http客户端 2020-04-30 15:23:36 +08:00
JaguarJack
cfc7d8a48c 新增包的更新和打包 2020-04-30 14:52:01 +08:00
JaguarJack
06ee75d496 修改打包命令 2020-04-30 14:51:32 +08:00
JaguarJack
b192a0151f recover 2020-04-29 17:37:45 +08:00
JaguarJack
4d444e9bbc 新增解析功能 2020-04-29 17:35:29 +08:00
JaguarJack
45af3fbc5f fixed install biug 2020-04-29 16:03:24 +08:00
JaguarJack
4a5e4353be 新增扩展 2020-04-29 15:54:30 +08:00
JaguarJack
ab3e420085 delete 2020-04-29 15:30:49 +08:00
JaguarJack
a437d2ed40 fixed bug 2020-04-29 15:25:41 +08:00
JaguarJack
d8ad1f6b87 修改数据初始化 2020-04-29 15:06:38 +08:00
JaguarJack
610f48b4ec 新增tools 2020-04-29 15:06:13 +08:00
JaguarJack
514bb6b520 新增导入树状数据方法 2020-04-29 15:05:49 +08:00
JaguarJack
76855d6b5d 生成控制器 2020-04-29 11:42:48 +08:00
JaguarJack
b30e57bf01 优化代码生成 2020-04-29 11:41:54 +08:00
JaguarJack
f8fb57c9c6 移除方法 2020-04-29 09:02:43 +08:00
JaguarJack
64c03bdfd3 优化代码生成 2020-04-29 09:02:20 +08:00
JaguarJack
7f72784bfb 修改用户 2020-04-28 22:04:01 +08:00
JaguarJack
08aee72ab9 修改日志列表 2020-04-28 22:02:50 +08:00
JaguarJack
50bcb7e289 新增列表查询 2020-04-28 22:02:23 +08:00
JaguarJack
0b546a20be 代码生成器 2020-04-28 22:02:03 +08:00
JaguarJack
d044ac6d8a 新增模型 2020-04-28 16:34:55 +08:00
JaguarJack
011c138439 修改操作事件 2020-04-28 16:34:31 +08:00
JaguarJack
435e1b6399 修改登陆事件 2020-04-28 16:34:17 +08:00
JaguarJack
760ad2a51b readme 2020-04-26 11:06:48 +08:00
JaguarJack
5fa78eda58 修改Query 2020-04-24 14:31:46 +08:00
JaguarJack
3f888f909a fixed migrate create failed 2020-04-23 19:47:00 +08:00
JaguarJack
fbbfc70d39 修改 2020-04-23 14:09:27 +08:00
JaguarJack
9e56f9f85e 优化权限keepalive字端 2020-04-23 14:04:26 +08:00
JaguarJack
e7295fa767 fixed bug 2020-04-22 22:47:31 +08:00
JaguarJack
b3682b1ee6 修改初始化数据 2020-04-22 22:16:41 +08:00
JaguarJack
498b45059b 修改数据 2020-04-22 22:10:47 +08:00
JaguarJack
306c36df85 优化角色 2020-04-22 21:29:13 +08:00
JaguarJack
b71bba6a1e 新增基础操作 2020-04-22 20:17:39 +08:00
JaguarJack
e7491555e8 修改权限 2020-04-22 20:17:19 +08:00
JaguarJack
ef64b8a8cb 权限表新增 level 字段 2020-04-22 20:16:48 +08:00
JaguarJack
05abc92ad9 修改配置 2020-04-22 07:08:07 +08:00
JaguarJack
90241e9a8f 优化auth 2020-04-22 07:02:40 +08:00
JaguarJack
3469cc2adf 优化代码 2020-04-22 07:00:38 +08:00
JaguarJack
6ac556e819 修改权限 2020-04-22 06:43:26 +08:00
JaguarJack
0fd9d3dcb4 修改数据 2020-04-22 06:38:12 +08:00
JaguarJack
aa56154a28 修改用户路由 2020-04-22 06:08:40 +08:00
JaguarJack
57abdd4fd9 删除冗余代码 2020-04-22 06:07:53 +08:00
JaguarJack
6b227688e4 优化登陆 2020-04-22 06:07:14 +08:00
JaguarJack
308ee3120e 迁移用户模块 2020-04-22 06:06:57 +08:00
JaguarJack
fd9ce382db 更改依赖 2020-04-22 05:54:15 +08:00
JaguarJack
67b810b06f delete user module 2020-04-22 05:53:38 +08:00
JaguarJack
86dfe36714 修改数据 2020-04-21 22:22:27 +08:00
JaguarJack
6ac0e3ebf2 修复权限不全bug 2020-04-21 22:19:10 +08:00
JaguarJack
33fee182d2 优化安装 2020-04-21 21:36:25 +08:00
JaguarJack
20410ba52c 修改错误数据 2020-04-21 21:23:58 +08:00
JaguarJack
49f948fdd1 新增createdBy方法 2020-04-21 21:16:23 +08:00
JaguarJack
3d65d111ee fixed bug 2020-04-21 21:16:04 +08:00
JaguarJack
129582a446 部门数据 2020-04-21 21:09:09 +08:00
JaguarJack
8084e11805 新增seed 2020-04-21 21:06:53 +08:00
JaguarJack
dd46a28096 新增数据 2020-04-21 19:56:44 +08:00
JaguarJack
9b2ac5fd49 修改配置 2020-04-21 19:45:58 +08:00
JaguarJack
4f9cf56e69 修改初始化数据 2020-04-21 19:38:27 +08:00
JaguarJack
5e59f507af fixed bug 2020-04-21 19:34:03 +08:00
JaguarJack
9594ea0fc4 修改操作日志 2020-04-21 19:26:35 +08:00
JaguarJack
2f77658f41 修改权限中间件 2020-04-21 19:24:16 +08:00
JaguarJack
6cd67c6498 权限更新 2020-04-21 19:22:11 +08:00
JaguarJack
cfe2a005c0 fixed bug 2020-04-21 19:18:32 +08:00
JaguarJack
7131a6c878 合并配置 2020-04-21 17:07:19 +08:00
JaguarJack
010cc10d53 配置管理优化 2020-04-21 14:07:06 +08:00
JaguarJack
e82e058550 修复循环插入数据导致数据错乱 2020-04-21 10:51:25 +08:00
JaguarJack
1b954c1b16 新增配置管理 2020-04-21 10:34:50 +08:00
JaguarJack
be743d9d23 优化模型生成命令 2020-04-17 17:10:39 +08:00
JaguarJack
2c350cbceb fixed bug 2020-04-17 16:36:24 +08:00
JaguarJack
20091aaf43 日志动态分页数量 2020-04-17 15:02:50 +08:00
JaguarJack
a5c193f192 防止中文转义 2020-04-17 14:30:49 +08:00
JaguarJack
f777816e18 修复命名不规范 2020-04-17 06:48:14 +08:00
JaguarJack
f1f3df2bc8 重写路由 2020-04-17 06:47:19 +08:00
JaguarJack
c4d29b5cbf 重写事件 2020-04-17 06:47:04 +08:00
JaguarJack
1b8f0df628 修改权限 2020-04-16 17:14:56 +08:00
JaguarJack
def5e396e1 新增搜索 2020-04-16 17:14:37 +08:00
JaguarJack
6da68f09cd 修改权限返回数据结构 2020-04-14 20:31:38 +08:00
JaguarJack
9ddc932e89 修改模型生成 2020-04-14 19:17:13 +08:00
JaguarJack
b47ff98bb6 新增权限模型 2020-04-14 19:16:28 +08:00
JaguarJack
48298273dd 禁止项目安装时候cache router 2020-04-13 19:25:32 +08:00
JaguarJack
9548cb34fd permission修改文件 2020-04-13 15:36:22 +08:00
吴彦文
56f6ba90a6 优化install 2020-04-08 17:44:35 +08:00
吴彦文
8d10baa35f 修复重复env导致安装失败 2020-04-06 19:18:31 +08:00
吴彦文
e61f3a4115 异常退出删除.env 2020-04-06 18:29:14 +08:00
wuyanwen
4271a70b16 fixed bug 2020-03-11 14:14:27 +08:00
wuyanwen
49a4e56f48 delete 2020-03-10 16:51:05 +08:00
wuyanwen
29482f4e31 优化 2020-03-10 16:50:04 +08:00
wuyanwen
a90fd31b87 delete 2020-03-07 12:20:55 +08:00
wuyanwen
35a9ecbc82 修改ipv6长度 2020-03-06 17:06:44 +08:00
wuyanwen
defd10ab91 修改服务 2020-02-26 11:47:27 +08:00
wuyanwen
f812033ccc 修改readme 2020-02-26 09:06:35 +08:00
wuyanwen
4c48d0c71d Merge branch 'master' of https://github.com/yanwenwu/catch-admin 2020-02-24 10:58:29 +08:00
wuyanwen
52e166b330 修改 2020-02-24 10:58:08 +08:00
jaguarjack
91d4f4a54d fixed conflict 2020-02-21 22:34:33 +08:00
jaguarjack
6b7146486c 修改 2020-02-21 22:32:50 +08:00
wuyanwen
3a58e928b6 修改install 2020-02-21 08:09:33 +08:00
wuyanwen
b998d58dea 删除冗余路由 2020-02-20 18:09:30 +08:00
wuyanwen
ff1aecce37 修改readme 2020-02-20 15:45:29 +08:00
wuyanwen
4e1a2d07d6 修改composer 2020-02-20 15:45:21 +08:00
wuyanwen
b0ee2e84d2 删除form 2020-02-20 13:46:06 +08:00
wuyanwen
42059247b2 新增事件配置 2020-02-20 13:45:13 +08:00
wuyanwen
6c5383f83c 益处service 2020-02-20 13:44:54 +08:00
wuyanwen
bcb671697c 切换service 2020-02-20 13:44:25 +08:00
wuyanwen
a9aa28bd77 修复win环境下apache头信息丢失 2020-02-18 17:27:24 +08:00
wuyanwen
bf98751ed5 切换路由中间件可配置 2020-02-18 14:52:32 +08:00
wuyanwen
ebe5f5757a 切换中间件,防止串应用 2020-02-18 14:44:16 +08:00
wuyanwen
fd1798875f 修改配置 2020-02-15 18:05:25 +08:00
wuyanwen
c4bdcd4152 新增wechat 2020-02-15 18:05:13 +08:00
wuyanwen
98f2e4bc31 修改异常错误信息 2020-02-13 19:55:01 +08:00
wuyanwen
0952e8f6f8 修改readme 2020-02-13 16:35:42 +08:00
wuyanwen
13d5b1a7fc 修改数据错误 2020-02-13 14:34:56 +08:00
wuyanwen
2c00ae5bdd 修改 apache 重写规则 2020-02-13 12:30:18 +08:00
wuyanwen
f562a3e8bc 修改readme 2020-02-13 11:55:58 +08:00
yanwenwu
81abf41e31 修改用户名 2020-02-10 13:04:27 +08:00
yanwenwu
db9a9327e5 修改登录 2020-02-08 18:30:56 +08:00
yanwenwu
1377a3a589 支持编辑器跳转 2020-02-06 12:02:38 +08:00
yanwenwu
4b0e9f24b9 删除package 2020-02-03 14:22:55 +08:00
yanwenwu
766d156bf8 新增附件管理 2020-02-02 22:11:38 +08:00
yanwenwu
a752c7914a 重置 2020-02-02 22:11:12 +08:00
yanwenwu
ae37218fcd 重新绑定异常处理 2020-02-02 22:10:52 +08:00
yanwenwu
6040ee4873 新增异常处理 2020-02-02 22:10:30 +08:00
yanwenwu
0c0238f664 修改上传 2020-02-02 22:10:14 +08:00
yanwenwu
fad98021e4 修改工具类 2020-02-02 22:09:53 +08:00
yanwenwu
e5ebc34d84 修改readme 2020-02-02 18:11:27 +08:00
yanwenwu
50410d640a 新增上传设置 2020-02-01 16:55:07 +08:00
yanwenwu
d0687df4de 修改服务 2020-02-01 15:42:13 +08:00
wuyanwen
b18390739f 修改request 2020-01-25 22:23:21 +08:00
wuyanwen
9c1eb59961 新增工具方法 2020-01-25 22:23:10 +08:00
wuyanwen
04b491621e 修改上传 2020-01-25 22:22:56 +08:00
wuyanwen
7dd40dc4aa 修改配置 2020-01-25 22:22:42 +08:00
wuyanwen
a8c98a0a05 新增附件管理 2020-01-25 22:22:29 +08:00
wuyanwen
5181915e3c 新增上传 2020-01-25 22:22:13 +08:00
wuyanwen
021041218b 修改权限 2020-01-25 20:33:04 +08:00
wuyanwen
88971b672d 修改权限 2020-01-25 20:32:31 +08:00
yanwenwu
09f8ef88ea 修改配置 2020-01-25 20:16:28 +08:00
wuyanwen
3e7106f9aa 修改 2020-01-25 20:08:53 +08:00
yanwenwu
10687ea93c 增加composer插件 2020-01-25 20:07:08 +08:00
yanwenwu
714837c8df 新增cloud配置 2020-01-25 20:06:36 +08:00
yanwenwu
b9acfbea2b 新增上传插件 2020-01-25 20:06:13 +08:00
yanwenwu
6f31f12be7 新增commands 2020-01-25 20:05:57 +08:00
yanwenwu
6b0eb5f849 fixed bugs 2020-01-25 20:03:18 +08:00
yanwenwu
3001ba26b1 修改ignore 2020-01-25 17:07:33 +08:00
yanwenwu
1ce6ddc060 修改composer 2020-01-25 17:07:12 +08:00
yanwenwu
0db7f7d3e9 修改composer 2020-01-25 16:24:44 +08:00
yanwenwu
886e86ef24 修改composer 2020-01-25 16:24:11 +08:00
yanwenwu
44eba6b389 修改权限中间件 2020-01-25 11:34:59 +08:00
yanwenwu
07442c8292 修改权限 2020-01-25 11:20:27 +08:00
yanwenwu
e61b61a220 修改服务 2020-01-24 08:40:04 +08:00
yanwenwu
5450edb490 修改权限中间件 2020-01-24 08:39:52 +08:00
yanwenwu
f8f20ab955 修改权限配置 2020-01-24 08:39:34 +08:00
yanwenwu
bea3e43937 删除不必要的引入 2020-01-23 21:26:45 +08:00
yanwenwu
0708d4ce61 新增ws worker命令 2020-01-23 21:26:30 +08:00
wuyanwen
e1ae8fd084 修改模块创建 2020-01-23 18:21:08 +08:00
wuyanwen
46c7307736 Merge branch 'master' of https://github.com/yanwenwu/catch-admin 2020-01-23 17:16:04 +08:00
wuyanwen
98e74c95dc 修改命令 2020-01-23 17:16:02 +08:00
wuyanwen
7b67e47059 修改rollback 2020-01-23 17:02:03 +08:00
wuyanwen
ac2dab4fa7 删除 2020-01-23 17:01:09 +08:00
yanwenwu
db37e71782 删除viewe目录的生成 2020-01-23 16:57:46 +08:00
yanwenwu
055f3d5aa9 统一命令格式 2020-01-23 16:55:51 +08:00
yanwenwu
cb90f5f6d3 修改migration rollback 2020-01-23 13:18:01 +08:00
wuyanwen
4f5476c270 修改数据填充 2020-01-22 17:56:00 +08:00
wuyanwen
9e4883ead6 增加分页常量 2020-01-21 17:57:33 +08:00
wuyanwen
ac74827130 重写分页方法 2020-01-21 17:56:28 +08:00
wuyanwen
f8a97527f6 修改分页 2020-01-21 17:56:10 +08:00
wuyanwen
5c8072e0b8 修改分页 2020-01-21 17:55:54 +08:00
wuyanwen
9f9a83f157 修改 2020-01-21 17:43:40 +08:00
wuyanwen
a719129b64 修改数据备份 2020-01-21 17:43:09 +08:00
wuyanwen
dfd0be23c6 修改初始化数据 2020-01-21 17:22:51 +08:00
wuyanwen
dc5e46e974 修改服务 2020-01-21 17:00:45 +08:00
wuyanwen
2c732555b0 新增rollback和create migration 命令 2020-01-21 17:00:17 +08:00
wuyanwen
ef545b8732 新增stubs 2020-01-21 16:59:40 +08:00
wuyanwen
b06a5300cb 新增登录退出 2020-01-20 14:38:50 +08:00
wuyanwen
1a03783d26 修改登录和权限路由 2020-01-20 14:38:32 +08:00
wuyanwen
bb372844dc 修改 whereLike 方法 2020-01-20 11:46:32 +08:00
wuyanwen
5f9e90ec67 修改权限管理错误 2020-01-19 15:50:27 +08:00
wuyanwen
257c29391e 修改用户搜索错误 2020-01-19 15:50:15 +08:00
wuyanwen
92d4092f1c 删除冗余路由 2020-01-19 15:49:58 +08:00
wuyanwen
a528ee83ae 修改response返回错误 2020-01-19 15:49:40 +08:00
wuyanwen
d09bcba9f3 修改readme 2020-01-19 15:49:19 +08:00
wuyanwen
4442944cc6 删除不必要的依赖 2020-01-19 09:58:40 +08:00
wuyanwen
51f9873d6e 修改readme 2020-01-17 17:56:54 +08:00
wuyanwen
3e4eca9d45 修改license 2020-01-17 16:07:55 +08:00
wuyanwen
9c7a01406d 修改更新方法 2020-01-17 15:49:42 +08:00
wuyanwen
8b216f2bc4 修改权限 2020-01-17 15:49:29 +08:00
wuyanwen
c6c0446c4e 新增配置 2020-01-17 15:49:18 +08:00
wuyanwen
691518c8c8 修改权限 2020-01-17 15:17:51 +08:00
wuyanwen
fb482ded01 修改request 2020-01-17 11:30:39 +08:00
wuyanwen
f427efd2c8 修改权限 2020-01-17 11:29:33 +08:00
wuyanwen
04d942c7db 缓存用户权限 2020-01-17 11:29:17 +08:00
wuyanwen
7eeade987a 更新框架核心 2020-01-16 14:09:07 +08:00
wuyanwen
5f34bac033 修改composer 2020-01-15 18:11:57 +08:00
wuyanwen
05e22d4db8 修改服务注入 2020-01-14 18:32:30 +08:00
wuyanwen
418a6d5418 修改用户模块 2020-01-14 18:31:18 +08:00
wuyanwen
3983c413f6 修改验证为配置注入 2020-01-14 18:31:08 +08:00
wuyanwen
2acf23d296 修改权限模型 2020-01-14 08:23:29 +08:00
wuyanwen
b6b0b5170d 修改用户模块 2020-01-14 08:23:15 +08:00
wuyanwen
09132deb78 新增角色权限traits 2020-01-14 08:22:53 +08:00
wuyanwen
7e41702de8 修改角色管理 2020-01-14 08:22:31 +08:00
wuyanwen
f63706eb0a 新增addFields方法 2020-01-13 21:40:07 +08:00
wuyanwen
5ba918f1a5 修改部门搜索 2020-01-13 21:39:42 +08:00
wuyanwen
64cd112d43 新增过滤搜索参数方法 2020-01-13 21:24:45 +08:00
wuyanwen
2cc2ecae40 新增query方法 2020-01-13 21:24:27 +08:00
wuyanwen
cffcf11192 新增traits方法 2020-01-13 21:24:12 +08:00
wuyanwen
3e0717c339 新增搜索器 2020-01-13 21:23:45 +08:00
wuyanwen
be02170697 新增搜索器 2020-01-13 21:23:24 +08:00
wuyanwen
3b67f3fb5f 注入Query类 2020-01-13 16:23:08 +08:00
wuyanwen
9e2c84dd54 新增query类 2020-01-13 16:22:16 +08:00
wuyanwen
152cd8738a 修改协议 2020-01-13 07:35:26 +08:00
yanwenwu
0fde164059 修改协议 2020-01-12 12:55:28 +08:00
yanwenwu
1b7cc3fcf5 新增角色部门 2020-01-12 12:54:59 +08:00
JaguarJack
313a396ba8 Update LICENSE.txt 2020-01-12 09:44:37 +08:00
yanwenwu
7c09bcf0cf 新增用户岗位关联表 2020-01-12 09:32:32 +08:00
yanwenwu
8b93c63883 新增部门和岗位 2020-01-12 09:30:56 +08:00
wuyanwen
5ec9939cbf 修改readme 2020-01-09 22:24:06 +08:00
wuyanwen
9673c62a14 修改request 2020-01-09 22:20:57 +08:00
wuyanwen
6cc76c9f8e 修改部门和岗位 2020-01-09 22:20:36 +08:00
wuyanwen
dfcfd78557 修改登录 2020-01-09 22:20:18 +08:00
wuyanwen
e994d14537 去除助手函数 2020-01-09 08:22:50 +08:00
wuyanwen
9bcb7466bd 修改基类 2020-01-09 08:22:38 +08:00
wuyanwen
4fa1c9638e 修改服务 2020-01-09 08:22:25 +08:00
wuyanwen
4387bbb7f9 切换request 2020-01-09 08:22:17 +08:00
wuyanwen
2a805b6709 切换request 2020-01-09 08:21:59 +08:00
wuyanwen
88c3bb432d 新增部门和岗位 2020-01-09 08:21:44 +08:00
wuyanwen
e5c8c71011 修改request 2020-01-08 22:43:40 +08:00
wuyanwen
a5242b3aea 修改request基类 2020-01-08 22:31:17 +08:00
wuyanwen
480aadd38b 修改用户数据 2020-01-08 22:18:04 +08:00
wuyanwen
ca0bf90615 修改权限数据 2020-01-08 22:17:48 +08:00
wuyanwen
2dc1270348 修改yonghu 2020-01-08 22:02:25 +08:00
wuyanwen
ce0eb575e9 修改权限 2020-01-08 22:02:16 +08:00
wuyanwen
a03f3c3699 删除文件 2020-01-07 21:52:38 +08:00
wuyanwen
a041504243 删除助手函数 2020-01-07 21:51:15 +08:00
wuyanwen
3ef506d129 修改readme 2020-01-07 21:50:12 +08:00
wuyanwen
9e28cbd91d 登录 2020-01-07 19:18:24 +08:00
wuyanwen
ba91154ee8 增加auth配置 2020-01-07 19:00:17 +08:00
wuyanwen
cf4ef949b5 修改用户信息 2020-01-07 19:00:04 +08:00
wuyanwen
b41121e35b 修改分享 2020-01-07 18:04:05 +08:00
wuyanwen
c9b39327a5 修改auth认证 2020-01-07 17:27:55 +08:00
wuyanwen
f7ac1a23bf 修改命令 2020-01-06 20:20:24 +08:00
wuyanwen
4a8a0b90e8 delete view 2020-01-06 17:42:51 +08:00
wuyanwen
4bf6d5168f 修改readme 2020-01-06 17:10:34 +08:00
wuyanwen
c53c40487c 修改异常 2020-01-06 17:08:10 +08:00
wuyanwen
9b591340a1 delete 2020-01-06 14:47:21 +08:00
wuyanwen
66e4f8f74f 修改路由规则 2019-12-30 17:45:36 +08:00
wuyanwen
ae084819fe 修改 2019-12-30 17:05:42 +08:00
wuyanwen
b061ab5225 修改服务 2019-12-29 17:01:25 +08:00
wuyanwen
872f6b9dfb 增加icon 2019-12-29 17:01:06 +08:00
root
9988c7c00c 删除静态文件 2019-12-29 08:31:14 +08:00
wuyanwen
ef44acee7a 编辑未初始化数据BUG 2019-12-29 08:17:29 +08:00
wuyanwen
998c8edf24 修改服务 2019-12-29 07:48:59 +08:00
wuyanwen
b2bdb12e5b 修改生产的api 2019-12-28 22:19:05 +08:00
wuyanwen
06726f8fc0 修改权限 2019-12-28 21:21:05 +08:00
wuyanwen
1798cbcd0c 修改权限 2019-12-28 21:20:27 +08:00
wuyanwen
a634aa4f93 新增系统模块 2019-12-27 17:01:32 +08:00
wuyanwen
fcc2e04b85 修改 2019-12-27 15:56:56 +08:00
wuyanwen
ef30c07f4a 修改权限 2019-12-27 09:52:03 +08:00
wuyanwen
b94800033f 修改类库 2019-12-27 09:51:48 +08:00
wuyanwen
201cb455f5 修改类库 2019-12-26 09:03:19 +08:00
wuyanwen
1dcce85c3a 修改权限管理 2019-12-26 09:03:09 +08:00
wuyanwen
4a3f043166 角色和用户管理 2019-12-25 22:12:16 +08:00
wuyanwen
ceda3a224a 修改 2019-12-24 18:21:57 +08:00
wuyanwen
8d5ec7966a 修改依赖 2019-12-23 08:40:42 +08:00
wuyanwen
2dc5321128 delete views 2019-12-22 22:04:01 +08:00
yanwenwu
a258ba6cc2 修改用户 2019-12-22 14:18:21 +08:00
yanwenwu
b27ef2570a first commit 2019-12-22 09:37:52 +08:00
yanwenwu
cf1dedabd4 冲突 2019-12-20 22:22:32 +08:00
yanwenwu
fc885476ef 修改 2019-12-20 22:15:45 +08:00
wuyanwen
aefa972804 修改用户管理 2019-12-19 07:23:32 +08:00
wuyanwen
c02f762537 修改权限管理 2019-12-19 07:23:18 +08:00
wuyanwen
122b624580 新增模块创建命令 2019-12-19 07:19:15 +08:00
wuyanwen
7e304cacf0 修改基类 2019-12-19 07:18:39 +08:00
wuyanwen
11854ec33e 修改服务 2019-12-19 07:18:18 +08:00
wuyanwen
a36603f7c2 修改系统管理 2019-12-19 07:17:51 +08:00
wuyanwen
6e0a405f09 修改首页 2019-12-19 07:17:33 +08:00
wuyanwen
2f71ba5380 Merge branch 'master' of https://gitee.com/jaguarjack/catchAdmin 2019-12-18 18:54:07 +08:00
wuyanwen
57f6597e77 添加初始化账号 2019-12-18 18:54:01 +08:00
zhangfayuan
300e536053 Apache环境下出现 No input file specified. 2019-12-18 14:34:45 +08:00
wuyanwen
3d8b31b2dc 修改composer镜像 2019-12-17 13:57:03 +08:00
wuyanwen
4e8aa4ae31 修改error页面 2019-12-17 12:35:25 +08:00
wuyanwen
daf6d1f760 修改响应 2019-12-17 12:35:12 +08:00
wuyanwen
7be9b78ac4 修改readme 2019-12-17 12:21:57 +08:00
wuyanwen
b4a411f343 新增解压包命令 2019-12-17 09:03:32 +08:00
wuyanwen
46a41c86ea 新增layout 2019-12-17 09:03:04 +08:00
wuyanwen
2c349e0832 优化 2019-12-17 09:02:49 +08:00
wuyanwen
5d1da432c7 修改服务 2019-12-17 09:02:29 +08:00
wuyanwen
3e91f16f27 修改继承 2019-12-17 09:02:16 +08:00
wuyanwen
efd0dd8e8f 修改继承 2019-12-17 09:02:09 +08:00
wuyanwen
f1c9f3db53 修改继承 2019-12-17 09:02:00 +08:00
wuyanwen
6f33180f9f 修改 js 2019-12-16 17:28:26 +08:00
wuyanwen
6e73f78bd3 修改 js 2019-12-16 17:25:40 +08:00
wuyanwen
438582ad6a 修改配置 2019-12-15 18:55:41 +08:00
wuyanwen
6caafbf4ca 修改配置 2019-12-15 18:55:14 +08:00
wuyanwen
0bc1b3c30c 修改 2019-12-15 17:47:30 +08:00
wuyanwen
a1c135f5d0 修改 2019-12-15 17:45:47 +08:00
wuyanwen
bfeb14b597 新增子域名设置 2019-12-15 17:27:01 +08:00
wuyanwen
27b30a8704 新增域名路由 2019-12-15 17:26:40 +08:00
wuyanwen
aea9eb6a17 修改路由加载 2019-12-15 15:51:00 +08:00
wuyanwen
0d05e4ecbd 修改exception 2019-12-15 15:50:31 +08:00
wuyanwen
f1ca73e05f 新增清空日志 2019-12-15 15:50:10 +08:00
wuyanwen
b365ec1db8 修改logo地址 2019-12-15 15:13:37 +08:00
wuyanwen
cd16d4314e 替换logo 2019-12-15 15:13:15 +08:00
wuyanwen
aba362dbad 新增基类异常 2019-12-15 13:38:47 +08:00
wuyanwen
79863215b3 修改request 2019-12-15 13:38:25 +08:00
wuyanwen
6c12887f8d 修复登录异常 2019-12-15 13:38:02 +08:00
wuyanwen
a018373013 修改验证码 2019-12-14 23:09:03 +08:00
wuyanwen
a9a857389a 修改登录 2019-12-14 22:59:38 +08:00
wuyanwen
5fec0b01b7 修改基类 2019-12-14 22:55:25 +08:00
wuyanwen
a62b1d54d6 修改服务 2019-12-14 22:55:05 +08:00
wuyanwen
4bfc021cdf 修改首页 2019-12-14 22:54:55 +08:00
wuyanwen
e3ececc277 修改权限路由 2019-12-14 22:54:41 +08:00
wuyanwen
2d6d074d94 修改登录 2019-12-14 22:54:24 +08:00
wuyanwen
6ac4b8784e 新增体验地址 2019-12-14 18:29:08 +08:00
wuyanwen
34d75c3f46 修改路由加载 2019-12-14 18:21:29 +08:00
wuyanwen
d21126882b 修改权限 2019-12-14 18:17:22 +08:00
wuyanwen
d7f0e6c949 新增拦截 2019-12-14 18:16:52 +08:00
wuyanwen
dc5ffd6ab1 修改权限 2019-12-14 18:16:44 +08:00
wuyanwen
d1d497076b 修改 2019-12-14 18:02:09 +08:00
wuyanwen
e6d1517429 修改 2019-12-14 17:59:11 +08:00
wuyanwen
eb2fd14f07 修改备份地址 2019-12-14 17:54:06 +08:00
wuyanwen
1bcc0f217e 修改备份地址 2019-12-14 17:53:40 +08:00
wuyanwen
6724da9e8f 修改基类 2019-12-14 17:50:54 +08:00
wuyanwen
d3e0c64b58 修改权限路由 2019-12-14 17:37:45 +08:00
wuyanwen
722b8cfa7f 修改路由缓存 2019-12-14 17:37:00 +08:00
wuyanwen
0d0abf3ea0 tree-table 2019-12-14 17:08:21 +08:00
wuyanwen
485432acfb 修改路由 2019-12-14 16:56:59 +08:00
wuyanwen
3ec10515fb 修改权限 2019-12-14 16:54:56 +08:00
wuyanwen
d3dfe38d60 发布 2019-12-14 16:02:09 +08:00
wuyanwen
74841b0717 修改readme 2019-12-14 15:57:55 +08:00
wuyanwen
5bcfe3c52d 安装新增数据填充 2019-12-14 15:57:32 +08:00
wuyanwen
6ac0562470 新增用户seed 2019-12-14 15:57:15 +08:00
wuyanwen
d27b7442d8 新增seed 2019-12-14 15:56:59 +08:00
wuyanwen
8479522970 安装修改 2019-12-14 15:03:39 +08:00
wuyanwen
1ce4c7122a 修改安装命令 2019-12-14 14:58:08 +08:00
wuyanwen
e35a76a80e 新增备份 2019-12-13 17:26:54 +08:00
wuyanwen
dacf005117 新增助手函数 2019-12-13 17:26:40 +08:00
wuyanwen
fad0f9770d 新增助手函数 2019-12-13 17:26:19 +08:00
wuyanwen
b5e90dd14f 修改权限管理 2019-12-13 17:26:09 +08:00
wuyanwen
17d30f1cc3 修改系统管理 2019-12-13 17:25:47 +08:00
wuyanwen
a4a03857ac 修改用户管理 2019-12-13 17:25:34 +08:00
wuyanwen
0d0cc6eeb6 修改服务 2019-12-13 17:25:22 +08:00
wuyanwen
d40deeff60 修改app 2019-12-13 17:25:05 +08:00
wuyanwen
6f7e0d71c2 更新公共库 2019-12-12 22:34:27 +08:00
wuyanwen
86a198d66a 注册事件 2019-12-12 22:34:08 +08:00
wuyanwen
5976ebb235 增加操作事件 2019-12-12 22:33:58 +08:00
wuyanwen
02b973d0b5 增加登录事件 2019-12-12 22:33:45 +08:00
wuyanwen
bdbf812941 修改菜单 2019-12-12 22:33:28 +08:00
wuyanwen
15be66ec26 新增系统管理 2019-12-12 22:33:12 +08:00
wuyanwen
d53b0bae73 新增后台基础公共库 2019-12-12 18:54:07 +08:00
wuyanwen
4a5993160f 修改session时间 2019-12-12 18:53:34 +08:00
wuyanwen
67e79bfa19 增加后台配置 2019-12-12 18:53:25 +08:00
wuyanwen
c8eedead00 注册中间件 2019-12-12 18:53:10 +08:00
wuyanwen
109cb7279a 修改登录 2019-12-12 18:52:56 +08:00
wuyanwen
a0a62b5640 增加默认错误页面 2019-12-12 18:52:44 +08:00
wuyanwen
5c7c976869 权限管理 2019-12-12 18:52:33 +08:00
wuyanwen
6c423e5fc5 用户管理 2019-12-12 18:52:24 +08:00
wuyanwen
5f6a7cf24e 增加基础 2019-12-12 18:52:11 +08:00
wuyanwen
ca4272d7a6 公共库 2019-12-12 09:14:08 +08:00
wuyanwen
d154f3e1ac 用户模块 2019-12-12 09:13:53 +08:00
wuyanwen
66e72c6537 登录模块 2019-12-12 09:13:44 +08:00
wuyanwen
7a6628a95f 权限管理 2019-12-12 09:13:29 +08:00
wuyanwen
ecae3e90f1 Merge branch 'master' of https://gitee.com/jaguarjack/catchAdmin 2019-12-11 21:00:27 +08:00
wuyanwen
c48d9154ad 首页 2019-12-11 21:00:24 +08:00
wuyanwen
6624a0cc6b 权限管理 2019-12-11 21:00:14 +08:00
wuyanwen
22064c6178 用户管理 2019-12-11 20:59:59 +08:00
zhangfayuan
7ac37e235b catch-seed:run 2019-12-10 14:03:28 +08:00
wuyanwen
ae7fd47a5d 新增theme 2019-12-09 16:48:09 +08:00
wuyanwen
dfa045726b 修改 2019-12-09 16:22:00 +08:00
wuyanwen
e6b443043a 修改忽略文件 2019-12-09 09:58:52 +08:00
wuyanwen
330a19e8c3 用户管理 2019-12-07 17:31:38 +08:00
wuyanwen
fa4837487b 增加分页响应 2019-12-06 14:44:41 +08:00
wuyanwen
5c7765c97f 扩展功能 2019-12-06 09:17:40 +08:00
wuyanwen
397c8bb7f7 基础功能 2019-12-06 08:24:07 +08:00
wuyanwen
6b4dd70752 用户管理模块 2019-12-03 21:43:37 +08:00
wuyanwen
2651ed6305 修改 2019-12-03 08:15:31 +08:00
wuyanwen
849db90b32 Merge branch 'master' of https://gitee.com/jaguarjack/catchAdmin 2019-12-02 23:05:47 +08:00
wuyanwen
40676f8b14 first commit 2019-12-02 23:04:43 +08:00
wuyanwen
38bcb43e70 删除 2019-12-02 22:58:11 +08:00
538 changed files with 21844 additions and 40713 deletions

View File

@@ -1,15 +0,0 @@
app_debug=true
app_trace=true
db_connection=mysql
db_host=localhost
db_database=thinking
db_username=user
db_port=3306
db_password=password
redis_host=
redis_port=
redis_password=

1
.example.env Normal file
View File

@@ -0,0 +1 @@
APP_DEBUG = false

View File

@@ -0,0 +1,24 @@
# 环境
- 操作系统:
- php 版本:
- thinkphp 版本:
- Mysql 版本:
- web 服务器:
# 问题
- 问题描述:
- 问题截图:
# 结果
- 实际结果:
- 预期结果:
# 分析
- 所做的尝试:
-
-
# 方案:
- 解决方案:
> 请在问题解决后关闭 issue

25
.github/issue_template.md vendored Normal file
View File

@@ -0,0 +1,25 @@
# 环境
- 操作系统:
- php 版本:
- thinkphp 版本:
- Mysql 版本:
- web 服务器:
# 问题
- 问题描述:
- 问题截图:
# 结果
- 实际结果:
- 预期结果:
# 分析
- 所做的尝试:
-
-
# 方案:
- 解决方案:
> 请在问题解决后关闭 issue

5
.gitignore vendored
View File

@@ -1,7 +1,8 @@
/.idea /.idea
/.vscode /.vscode
/vendor /vendor
/package
*.log *.log
thinkphp
.env .env
.DS_Store composer.lock

20
LICENSE
View File

@@ -1,20 +0,0 @@
The MIT License (MIT)
Copyright (c) 2018 JaguarJack
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

201
LICENSE.txt Normal file
View File

@@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright {yyyy} {name of copyright owner}
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

168
README.md
View File

@@ -1,81 +1,119 @@
# think-admin <p align="center">
# ENV <img src="https://cdn.learnku.com/uploads/images/202005/17/18206/zSuf7Ce5kM.png!large">
- php >= 7.1.3 </p>
- mysql >= 5.5
# install
- curl -sS http://install.phpcomposer.com/installer | php
- composer config -g repo.packagist composer https://packagist.laravel-china.org
- composer update
- 修改根目录下 .env.emp .env
- .env 配置数据库信息
- php think migrate:run
- php think seed:run
# Use <p align="center"><code>CatchAdmin</code>是一款基于<a href="http://www.thinkphp.cn/" target="_blank">thinkphp framework</a>
- 配置虚拟域名 OR 在根目录下执行 php think run <a href="https://pro.loacg.com/docs/getting-started">ant degisn pro vue</a>二次开发而成的后台管理系统,采用了目前趋势的前后端分离开发模式,后端仅需要提供简洁的 API 数据结构,前端负责呈现数据。目前前端采用数据驱动,大大提高了开发效率。这不仅仅是一个项目,更是后端更新技术栈的一次实践</p>
- yourUrl/login
- 默认用户名 admin 密码 admin
# nginx 配置 <p align="center">
``` <a href="http://doc.catchadmin.com/">文档</a> |
server { <a href="http://vue.catchadmin.com">演示地址</a> |
listen 端口; <a href="http://apidoc.catchadmin.com">接口文档</a> |
server_name 域名; <a href="https://gitee.com/jaguarjack/catchAdmin">项目源码</a> |
<a href="https://www.kancloud.cn/akasishikelu/thinkphp6">看云分析</a>
<a href="#extensions">扩展</a>
</p>
access_log logs/wenwen.access.log; <p align="center">
<a href="https://gitee.com/jaguarjack/catchAdmin" target="_blank">
<img src="https://svg.hamm.cn/gitee.svg?type=star&user=jaguarjack&project=catchAdmin"/>
</a >
<a href="https://gitee.com/jaguarjack/catchAdmin" target="_blank">
<img src="https://svg.hamm.cn/gitee.svg?type=fork&user=jaguarjack&project=catchAdmin"/>
</a >
<img src="https://svg.hamm.cn/badge.svg?key=Base&value=ThinkPHP6"/>
<img src="https://svg.hamm.cn/badge.svg?key=Data&value=MySQL5.5"/>
<img src="https://svg.hamm.cn/badge.svg?key=Runtime&value=PHP7.1"/>
<img src="https://svg.hamm.cn/badge.svg?key=License&value=Apache-2.0"/>
</p >
root 项目目录/public; ## 项目地址
index index.php index.html index.htm; - [github 地址](https://github.com/yanwenwu/catch-admin)
- [gitee 地址](https://gitee.com/jaguarjack/catchAdmin)
- [前端 Vue 项目地址](https://github.com/yanwenwu/catch-admin-vue)
- [文档地址](https://github.com/catch-admin/document)[个人精力实在有限,希望可以小伙伴们可以一起维护文档]
## 预览
<p align="center">
<img src="https://cdn.learnku.com/uploads/images/202005/17/18206/0ECPy72zUZ.png!large">
</p>
<p align="center">
<img src="https://cdn.learnku.com/uploads/images/202005/17/18206/ngzSU0A9SI.png!large">
</p>
location / { ## 环境要求
index index.php index.html index.htm; - php7.1+ (需以下扩展)
- [x] mbstring
- [x] json
- [x] openssl
- [x] xml
- [x] pdo
- nginx
- mysql
if (!-e $request_filename) { ### 如何安装
rewrite ^(.*)$ /index.php?s=$1 last; > 安装之前请确保已安装 Composer
break;
}
}
#error_page 404 /404.html; #### 下载项目
error_page 500 502 503 504 /50x.html; - 通过 Git 下载(推荐)
location = /50x.html { ```shell
root html; git clone https://gitee.com/jaguarjack/catchAdmin && cd catchAdmin
}
location ~ \.php$ { curl -sS https://install.phpcomposer.com/installer | php
root 项目目录/public;
fastcgi_pass phpfastcgi;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
location ^~ /data { composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/
deny all;
} composer install
}
``` ```
# Problem - composer 安装
> SQLSTATE[42000]: Syntax error or access violation: 1067 Invalid default value for 'updated_at' ```shell
composer create-project jaguarjack/catchadmin:dev-master
```
设置 sql_mode; #### 安装
下载完成之后通过命令来进行安装, 一键安装 🚀
```shell
php think catch:install
``` ```
show variables like 'sql_mode' ;
```
> remove 'NO_ZERO_IN_DATE,NO_ZERO_DATE'
```
SET GLOBAL sql_mode='STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'
```
# Test Address
<a href="http://tp5.whwww.net" target="__BLANK">测试地址</a>
- 账号admin
- 密码: 123456
# Talking ## 体验地址
- 可以提 ISSUE请按照 issue 模板提问
- 欢迎进入 Q 群,可以及时反馈一些问题。
- ![输入图片说明](https://images.gitee.com/uploads/images/2018/1219/110300_0257b6c0_810218.jpeg "微信图片_20181219105915.jpg")
仅供学习 [体验地址](http://vue.catchadmin.com)
- 账号: admin@gmail.com
- 密码: admin
[catchadmin 文档地址](http://doc.catchadmin.com)
### 系列文章
如果是刚开始使用 thinkphp6, 以下文章可能会对你有些许帮助,文章基于 RC3 版本。整体架构是不变的。
- [Tp6 启动分析](https://www.kancloud.cn/akasishikelu/thinkphp6/1129385)
- [Tp6 Request 解析](https://www.kancloud.cn/akasishikelu/thinkphp6/1134496)
- [TP6 应用初始化](https://www.kancloud.cn/akasishikelu/thinkphp6/1130427)
- [Tp6 中间件分析](https://www.kancloud.cn/akasishikelu/thinkphp6/1136616)
- [Tp6 请求流程](https://www.kancloud.cn/akasishikelu/thinkphp6/1136608)
### Donate
如果你觉得项目对你有帮助,可以请作者喝杯咖啡☕️!鼓励下
<img src="https://cdn.learnku.com/uploads/images/202008/11/18206/e6qAAM8Bod.jpg!large">
### Talking
- [论坛讨论](http://bbs.catchadmin.com)
- 可以提 `ISSUE`,请按照 `issue` 模板提问
- 加入 Q 群 `302266230` 讨论以及反馈一些问题。
- 加群需要付费,所以请使用能支持群费的客户端。(不喜勿喷,过滤一部分不看文档和 TP 框架文档并且衣来伸手饭来张口的用户)
- 不建议你付费入群,认真阅读文档可以解决所有问题
- 更愿意以 `ISSUE` 的方式提问
- 付费入群,群里的各位也是没有义务回答各种各样的基础问题。请 GOOGLE。
### Thanks
> 排名部分先后
- [top-think/think](https://github.com/top-think/think)
- [ant-design-pro-vue](https://github.com/sendya/ant-design-pro-vue)
- [thans/tp-jwt-auth](https://packagist.org/packages/thans/tp-jwt-auth)
- [workerman/workerman](https://github.com/walkor/Workerman)
- [jaguarjack/think-filesystem-cloud](https://github.com/yanwenwu/think-filesystem-cloud)
- [overtrue/wechat](https://github.com/overtrue/wechat)
- [jaguarjack/migration-generator](https://github.com/yanwenwu/migration-generator)
- [phpoffice/phpspreadsheet](https://github.com/PHPOffice/PhpSpreadsheet)

93
app/BaseController.php Normal file
View File

@@ -0,0 +1,93 @@
<?php
declare (strict_types = 1);
namespace app;
use think\App;
use think\exception\ValidateException;
use think\Validate;
/**
* 控制器基础类
*/
abstract class BaseController
{
/**
* Request实例
* @var \think\Request
*/
protected $request;
/**
* 应用实例
* @var \think\App
*/
protected $app;
/**
* 是否批量验证
* @var bool
*/
protected $batchValidate = false;
/**
* 控制器中间件
* @var array
*/
protected $middleware = [];
/**
* 构造方法
* @access public
* @param App $app 应用对象
*/
public function __construct(App $app)
{
$this->app = $app;
$this->request = $this->app->request;
// 控制器初始化
$this->initialize();
}
// 初始化
protected function initialize()
{}
/**
* 验证数据
* @access protected
* @param array $data 数据
* @param string|array $validate 验证器名或者验证规则数组
* @param array $message 提示信息
* @param bool $batch 是否批量验证
* @return array|string|true
* @throws ValidateException
*/
protected function validate(array $data, $validate, array $message = [], bool $batch = false)
{
if (is_array($validate)) {
$v = new Validate();
$v->rule($validate);
} else {
if (strpos($validate, '.')) {
// 支持场景
list($validate, $scene) = explode('.', $validate);
}
$class = false !== strpos($validate, '\\') ? $validate : $this->app->parseClass('validate', $validate);
$v = new $class();
if (!empty($scene)) {
$v->scene($scene);
}
}
$v->message($message);
// 是否批量验证
if ($batch || $this->batchValidate) {
$v->batch(true);
}
return $v->failException(true)->check($data);
}
}

57
app/ExceptionHandle.php Normal file
View File

@@ -0,0 +1,57 @@
<?php
namespace app;
use think\db\exception\DataNotFoundException;
use think\db\exception\ModelNotFoundException;
use think\exception\Handle;
use think\exception\HttpException;
use think\exception\HttpResponseException;
use think\exception\ValidateException;
use think\Response;
use Throwable;
/**
* 应用异常处理类
*/
class ExceptionHandle extends Handle
{
/**
* 不需要记录信息(日志)的异常类列表
* @var array
*/
protected $ignoreReport = [
HttpException::class,
HttpResponseException::class,
ModelNotFoundException::class,
DataNotFoundException::class,
ValidateException::class,
];
/**
* 记录异常信息(包括日志或者其它方式记录)
*
* @access public
* @param Throwable $exception
* @return void
*/
public function report(Throwable $exception): void
{
// 使用内置的方式记录异常日志
parent::report($exception);
}
/**
* Render an exception into an HTTP response.
*
* @access public
* @param \think\Request $request
* @param Throwable $e
* @return Response
* @throws \Exception
*/
public function render($request, Throwable $e): Response
{
// 其他错误交给系统处理
return parent::render($request, $e);
}
}

53
app/Request.php Normal file
View File

@@ -0,0 +1,53 @@
<?php
namespace app;
// 应用请求对象类
use catchAdmin\permissions\model\Users;
use catcher\CatchAuth;
use catcher\Code;
use catcher\exceptions\FailedException;
use catcher\exceptions\LoginFailedException;
use thans\jwt\exception\TokenBlacklistException;
use thans\jwt\exception\TokenExpiredException;
use thans\jwt\exception\TokenInvalidException;
class Request extends \think\Request
{
protected $auth;
/**
* login user
*
* @time 2020年01月09日
* @param null $guard
* @return mixed
*/
public function user($guard = null)
{
if (!$this->auth) {
$this->auth = new CatchAuth;
}
try {
$user = $this->auth->guard($guard ? : config('catch.auth.default.guard'))->user();
if ($user->status == Users::DISABLE) {
throw new LoginFailedException('该用户已被禁用');
}
} catch (\Exception $e) {
if ($e instanceof TokenExpiredException) {
throw new FailedException('token 过期', Code::LOGIN_EXPIRED);
}
if ($e instanceof TokenBlacklistException) {
throw new FailedException('token 被加入黑名单', Code::LOGIN_BLACKLIST);
}
if ($e instanceof TokenInvalidException) {
throw new FailedException('token 不合法', Code::LOST_LOGIN);
}
throw new FailedException('认证失败: '. $e->getMessage(), Code::LOST_LOGIN);
}
return $user;
}
}

2
app/common.php Normal file
View File

@@ -0,0 +1,2 @@
<?php
// 应用公共文件

18
app/event.php Normal file
View File

@@ -0,0 +1,18 @@
<?php
// 事件定义文件
return [
'bind' => [],
'listen' => [
'AppInit' => [],
'HttpRun' => [],
'HttpEnd' => [],
'LogLevel' => [],
'LogWrite' => [],
'RouteLoaded' => [],
],
'subscribe' => [
],
];

11
app/middleware.php Normal file
View File

@@ -0,0 +1,11 @@
<?php
// 全局中间件定义文件
return [
// 全局请求缓存
// \think\middleware\CheckRequestCache::class,
// 多语言加载
// \think\middleware\LoadLangPack::class,
// Session初始化
// \think\middleware\SessionInit::class
\think\middleware\AllowCrossDomain::class,
];

9
app/provider.php Normal file
View File

@@ -0,0 +1,9 @@
<?php
use app\ExceptionHandle;
use app\Request;
// 容器Provider定义文件
return [
'think\Request' => Request::class,
'think\exception\Handle' => ExceptionHandle::class,
];

4
app/service.php Normal file
View File

@@ -0,0 +1,4 @@
<?php
return [
\catcher\CatchAdminService::class,
];

View File

@@ -1,48 +0,0 @@
<?php
namespace app\admin\controller;
use think\Controller;
use app\traits\ControllerTrait;
abstract class Base extends Controller
{
use ControllerTrait;
protected $limit = 10;
protected $page = 1;
protected $middleware = ['checkLogin', 'auth', 'logRecord'];
/**
* 过滤参数
*
* @time at 2018年11月15日
* @param $params
* @return void
*/
protected function checkParams(&$params)
{
$this->limit = $params['limit'] ?? $this->limit;
$this->page = $params['page'] ?? $this->page;
foreach ($params as $key => $param) {
if (!$param || $key == 'limit' || $key == 'page') {
unset($params[$key]);
}
}
$this->start = $this->start();
}
/**
* Table ID Start
*
* @time at 2018年11月16日
* @return float|int
*/
protected function start()
{
return (int)$this->limit * ((int)$this->page - 1) + 1;
}
}

View File

@@ -1,63 +0,0 @@
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2019/1/18
* Time: 10:36
*/
namespace app\admin\controller;
use think\Db;
class Database extends Base
{
/**
* 数据字典列表
*
* @time at 2019年01月18日
* @return mixed
*/
public function index()
{
$this->tables = Db::query('SHOW TABLE STATUS');
return $this->fetch();
}
/**
* 优化表
*
* @time at 2019年01月18日
* @return void
*/
public function optimize()
{
$table = $this->request->post('table');
if (!$table) {
$this->error('参数错误, 未指定表');
}
Db::query(sprintf('optimize table %s', $table)) ? $this->success('优化成功') : $this->error('优化失败');
}
/**
*
*
* @time at 2019年01月18日
* @return void
*/
public function view()
{
$table = $this->request->param('table');
if (!$table) {
$this->error('参数错误', '未指定表');
}
$this->table = Db::query('show full columns from ' . $table);
return $this->fetch();
}
}

View File

@@ -1,43 +0,0 @@
<?php
namespace app\admin\controller;
use think\permissions\facade\Permissions;
use think\permissions\facade\Roles;
use app\service\MenuService;
class Index extends Base
{
protected $middleware = [ 'checkLogin' ];
/**
* 首页
*
* @time at 2018年11月15日
* @return mixed|string
*/
public function index(MenuService $menuService)
{
$loginUser = $this->getLoginUser();
$userHasRoles = $loginUser->getRoles();
$permissionIds = [];
$userHasRoles->each(function ($role, $key) use (&$permissionIds) {
$permissionIds = array_merge($permissionIds, Roles::getRoleBy($role->id)->getPermissions(false));
});
$permissions = Permissions::whereIn('id', $permissionIds)->where('is_show', 1)->select();
$this->permissions = $menuService->tree($permissions);
$this->loginUser = $loginUser;
return $this->fetch();
}
/**
* main
*
* @time at 2018年11月16日
* @return mixed|string
*/
public function main()
{
return $this->fetch();
}
}

View File

@@ -1,30 +0,0 @@
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2019/1/18
* Time: 9:01
*/
namespace app\admin\controller;
use app\model\LogRecordModel;
class Log extends Base
{
/**
* 日志列表
*
* @time at 2019年01月18日
* @param LogRecordModel $logRecordModel
* @return mixed
*/
public function index(LogRecordModel $logRecordModel)
{
$params = $this->request->param();
$this->checkParams($params);
$this->list = $logRecordModel->getAll($params, $this->limit);
return $this->fetch();
}
}

View File

@@ -1,55 +0,0 @@
<?php
namespace app\admin\controller;
use app\traits\Auth;
use think\Controller;
class Login extends Controller
{
use Auth;
protected $redirect = '/index';
/**
* Login Page
*
* @return mixed
*/
public function login()
{
// 登录逻辑
if ($this->request->isPost()) {
$this->authLogin($this->request);
}
return $this->fetch('/index/login');
}
/**
* 登出
*
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector|\think\response\Redirect
*/
public function logout()
{
$this->authLogout();
return redirect(url('login'));
}
/**
* 验证规则
*
* @time at 2018年11月13日
* @return array
*/
protected function rule()
{
return [
$this->name() => 'require',
'password|密码' => 'require',
'captcha|验证码' => 'require|captcha'
];
}
}

View File

@@ -1,78 +0,0 @@
<?php
namespace app\admin\controller;
use think\Collection;
use think\permissions\facade\Permissions;
use app\admin\request\PermissionRequest;
use app\service\MenuService;
class Permission extends Base
{
public function index(MenuService $menuService)
{
$this->permissions = new Collection($menuService->sort(Permissions::select()));
return $this->fetch();
}
/**
* Create Data
*
* @time at 2018年11月13日
* @return mixed|string
*/
public function create(PermissionRequest $request, MenuService $menuService)
{
if ($request->isPost()) {
$data = $request->post();
Permissions::store($data) ? $this->success('添加成功', url('permission/index')) : $this->error('添加失败');
}
$this->permissions = $menuService->sort(Permissions::select());
$this->permissionId = $this->request->param('id') ?? 0;
return $this->fetch();
}
/**
* Edit Data
*
* @time at 2018年11月13日
* @return mixed|string
*/
public function edit(PermissionRequest $request, MenuService $menuService)
{
if ($request->isPost()) {
$data = $request->post();
Permissions::updateBy($data['id'], $data) !== false ? $this->success('编辑成功', url('permission/index')) : $this->error('');
}
$permissionId = $this->request->param('id');
if (!$permissionId) {
$this->error('不存在的数据');
}
$this->permissions = $menuService->sort(Permissions::select());
$this->permission = Permissions::getPermissionBy($permissionId);
return $this->fetch();
}
/**
* Delete Data
*
* @time at 2018年11月13日
* @return void
*/
public function delete()
{
$permissionId = $this->request->post('id');
if (!$permissionId) {
$this->error('不存在数据');
}
if (Permissions::where('pid', $permissionId)->find()) {
$this->error('请先删除子菜单');
}
// 删除权限关联的角色信息
Permissions::detachRole($permissionId);
if (Permissions::deleteBy($permissionId)) {
$this->success('删除成功', url('permission/index'));
}
$this->error('删除失败');
}
}

View File

@@ -1,115 +0,0 @@
<?php
namespace app\admin\controller;
use think\permissions\facade\Roles;
use app\admin\request\RoleRequest;
use think\permissions\facade\Permissions;
use app\service\MenuService;
class Role extends Base
{
public function index()
{
$this->roles = Roles::paginate(10);
return $this->fetch();
}
/**
* create Data
*
* @time at 2018年11月13日
* @return mixed|string
*/
public function create(RoleRequest $request)
{
if ($request->isPost()) {
Roles::store($request->post()) ? $this->success('创建成功', url('role/index')) : $this->error('创建失败');
}
return $this->fetch();
}
/**
* Edit Data
*
* @time at 2018年11月13日
* @return mixed|string
*/
public function edit(RoleRequest $request)
{
if ($this->request->isPost()) {
Roles::updateBy($request->post('id'), $request->post()) !== false ? $this->success('编辑成功', url('role/index')) : $this->error('编辑失败');
}
$this->role = Roles::getRoleBy($this->request->param('id'));
return $this->fetch();
}
/**
* Delete Data
*
* @time at 2018年11月13日
* @return void
*/
public function delete()
{
$roleId = $this->request->post('id');
if (!$roleId) {
$this->error('角色信息不存在');
}
// 删除角色相关的用户
Roles::detachUsers($roleId);
// 删除角色相关的权限
Roles::detachPermissions($roleId);
if (Roles::deleteBy($roleId)) {
$this->success('删除成功', url('role/index'));
}
$this->error('删除失败');
}
/**
* 获取角色权限
*
* @time at 2018年09月21日
* @return void
*/
public function getPermissionsOfRole(MenuService $menuService)
{
$field = ['name', 'id', 'pid'];
$roleId = $this->request->post('role_id');
$permissions = Permissions::field($field)->all();
$roleHasPermissions = Roles::getRoleBy($roleId)->getPermissions(false);
$permissions = $permissions->each(function ($item, $key) use ($roleHasPermissions){
if (!$item->pid) {
$item->open = true;
}
$item->checked = in_array($item->id, $roleHasPermissions) ? true : false;
return $item;
});
header('content-Type: application/json');
exit(json_encode($menuService->sort($permissions)));
}
/**
* 分配权限
*
* @time at 2018年11月15日
* @return mixed|string
*/
public function givePermissions()
{
if ($this->request->isPost()) {
$postData = $this->request->post();
$roleId = $postData['role_id'];
if (!isset($postData['permissions'])) {
Roles::detachPermissions($roleId);
$this->success('分配成功', url('role/index'));
}
$permissions = $postData['permissions'];
Roles::detachPermissions($roleId);
Roles::attachPermissions($roleId, $permissions) ? $this->success('分配成功', url('role/index')) : $this->error('分配失败');
}
$this->role_id = $this->request->param('id');
return $this->fetch('role/givePermissions');
}
}

View File

@@ -1,126 +0,0 @@
<?php
namespace app\admin\controller;
use app\model\UserModel;
use app\admin\request\UserRequest;
use think\permissions\facade\Roles;
class User extends Base
{
/**
* User List
*
* @time at 2018年11月12日
* @return mixed|string
*/
public function index(UserModel $userModel)
{
$params = $this->request->param();
$this->checkParams($params);
$this->users = $userModel->getList($params, $this->limit);
return $this->fetch();
}
/**
* create Data
*
* @time at 2018年11月12日
* @return mixed|string
*/
public function create(UserModel $userModel, UserRequest $request)
{
if ($request->isPost()) {
$data = $request->post();
$data['password'] = generatePassword($data['password']);
if ($userId = $userModel->store($data)) {
// 分配角色
$this->giveRoles($userModel, $userId, $data);
$this->success('添加成功', url('user/index'));
}
$this->error('添加失败');
}
$this->roles = Roles::all();
return $this->fetch();
}
/**
* Edit Data
*
* @time at 2018年11月12日
* @return mixed|string
*/
public function edit(UserModel $userModel, UserRequest $request)
{
if ($request->isPost()) {
$data = $request->post();
$this->giveRoles($userModel, $data['id'], $data);
$data['password'] = generatePassword($data['password']);
$userModel->updateBy($data['id'], $data) ? $this->success('修改成功', url('user/index')) : $this->error('修改失败');
}
$id = $this->request->param('id');
if (!$id) {
$this->error('数据不存在');
}
$user = $userModel->findBy($id);
$userHasRoles = $user->getRoles(false);
$roles = Roles::all()->each(function($item, $key) use ($userHasRoles){
$item->checked = in_array($item->id, $userHasRoles) ? true : false;
return $item;
});
$this->user = $user;
$this->roles = $roles;
return $this->fetch();
}
/**
* Delete Data
*
* @time at 2018年11月12日
* @return void
*/
public function delete(UserModel $userModel)
{
$id = $this->request->post('id');
if (!$id) {
$this->error('不存在的数据');
}
// 删除用户相关的角色
$userModel->detachRoles($id);
if ($userModel->deleteBy($id)) {
$this->success('删除成功', url('user/index'));
}
$this->error('删除失败');
}
/**
* 分配角色
*
* @time at 2018年11月15日
* @param \app\model\UserModel $userModel
* @param int $userId
* @param $data
* @return bool
*/
protected function giveRoles(UserModel $userModel, int $userId, &$data)
{
if (isset($data['roles'])) {
$rolesIds = $data['roles'];
if (!is_array($rolesIds)) {
$rolesIds = [$rolesIds];
}
$userModel->detachRoles($userId);
$userModel->attachRoles($userId, $rolesIds);
unset($data['roles']);
return true;
}
$userModel->detachRoles($userId);
return true;
}
}

View File

@@ -1,30 +0,0 @@
<?php
/**
* UserRequest.php
* Created by wuyanwen <wuyanwen1992@gmail.com>
* Date: 2018/11/29 0029 21:56
*/
namespace app\admin\request;
use think\exception\HttpResponseException;
use think\Request;
abstract class FormRequest extends Request
{
/**
* FormRequest constructor.
*/
public function __construct()
{
parent::__construct();
if ($this->withServer($_SERVER)->isAjax(true) && $err = $this->validate()) {
throw new HttpResponseException(json([
'code' => 0,
'msg' => $err,
'wait' => 3,
]));
}
}
}

View File

@@ -1,17 +0,0 @@
<?php
/**
* UserRequest.php
* Created by wuyanwen <wuyanwen1992@gmail.com>
* Date: 2018/11/29 0029 21:56
*/
namespace app\admin\request;
use app\admin\validates\PermissionValidate;
class PermissionRequest extends FormRequest
{
public function validate()
{
return (new PermissionValidate())->getErrors($this->post());
}
}

View File

@@ -1,17 +0,0 @@
<?php
/**
* UserRequest.php
* Created by wuyanwen <wuyanwen1992@gmail.com>
* Date: 2018/11/29 0029 21:56
*/
namespace app\admin\request;
use app\admin\validates\RoleValidate;
class RoleRequest extends FormRequest
{
public function validate()
{
return (new RoleValidate())->getErrors($this->post());
}
}

View File

@@ -1,17 +0,0 @@
<?php
/**
* UserRequest.php
* Created by wuyanwen <wuyanwen1992@gmail.com>
* Date: 2018/11/29 0029 21:56
*/
namespace app\admin\request;
use app\admin\validates\UserValidate;
class UserRequest extends FormRequest
{
public function validate()
{
return (new UserValidate())->getErrors($this->post());
}
}

View File

@@ -1,35 +0,0 @@
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2018/11/12 0012
* Time: 下午 16:31
*/
namespace app\admin\validates;;
use think\Validate;
abstract class AbstractValidate extends Validate
{
/**
* Get Validate Errors
*
* @time at 2018年11月12日
* @param $data
* @return array
*/
public function getErrors($data)
{
$this->check($data);
return $this->getError();
}
public function __set($name, $value)
{
// TODO: Implement __set() method.
$this->rule[$name] = $value;
}
}

View File

@@ -1,19 +0,0 @@
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2018/11/14 0014
* Time: 下午 18:21
*/
namespace app\admin\validates;
class PermissionValidate extends AbstractValidate
{
protected $rule = [
'name|菜单名称' => 'require|min:2|max:10|chs|unique:permissions',
'module|模块名称' => 'require|min:2|max:10|alpha',
'controller|控制器名称' => 'require|min:2|max:50|alpha',
'action|方法名称' => 'require|min:2|max:50|alpha',
];
}

View File

@@ -1,15 +0,0 @@
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2018/11/14 0014
* Time: 下午 17:42
*/
namespace app\admin\validates;
class RoleValidate extends AbstractValidate
{
protected $rule = [
'name|角色名' => 'require|min:3|max:15|chs|unique:roles',
];
}

View File

@@ -1,18 +0,0 @@
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2018/11/12 0012
* Time: 下午 16:38
*/
namespace app\admin\validates;
class UserValidate extends AbstractValidate
{
protected $rule = [
'name|用户名' => 'require|min:3|max:15|alphaNum|unique:users',
'email|邮箱' => 'email|unique:users',
'password|密码' => 'confirm|min:6|max:20|alphaDash',
];
}

View File

@@ -1,20 +0,0 @@
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2018/11/13 0013
* Time: 上午 9:33
*/
namespace app\behavior;
class LoginRecord
{
public function run($params)
{
$user = $params['user'];
## 登录记录
$user->login_at = date('Y-m-d h:i:s', time());
$user->login_ip = request()->ip();
$user->save();
}
}

View File

@@ -1,15 +0,0 @@
<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: yunwuxin <448901948@qq.com>
// +----------------------------------------------------------------------
return [
'make:curd' => app\command\MakeCurd::class,
'rbac:publish' => think\permissions\command\PermissionPublish::class,
];

View File

@@ -1,154 +0,0 @@
<?php
namespace app\command;
use think\console\Command;
use think\console\Input;
use think\console\input\Argument;
use think\console\input\Option;
use think\console\Output;
use think\DB;
class MakeCurd extends Command
{
protected $appPath;
protected $stubPath;
// view 默认的三个模板
protected $views = ['index', 'create', 'edit'];
public function __construct()
{
parent::__construct();
$this->appPath = env('app_path');
$this->stubPath = $this->appPath . 'command' . DIRECTORY_SEPARATOR . 'stub' .DIRECTORY_SEPARATOR;
}
protected function configure()
{
$this->setName('make:curd')
->addArgument('controller', Argument::OPTIONAL, "controller name")
->addArgument('model', Argument::OPTIONAL, "model name")
->addOption('module', null, Option::VALUE_REQUIRED, 'module name')
->setDescription('Create curd option controller model --module?');
}
protected function execute(Input $input, Output $output)
{
// 首先获取默认模块
$moduleName = config('app.default_module');
$controllerName = trim($input->getArgument('controller'));
if (!$controllerName) {
$output->writeln('Controller Name Must Set');exit;
}
$modelName = trim($input->getArgument('model'));
if (!$modelName) {
$output->writeln('Model Name Must Set');exit;
}
if ($input->hasOption('module')) {
$moduleName = $input->getOption('module');
}
$this->makeController($controllerName, $moduleName);
$output->writeln($controllerName . ' controller create success');
$this->makeModel($modelName, $moduleName);
$output->writeln($modelName . ' model create success');
$this->makeView($controllerName, $moduleName);
$output->writeln($controllerName . ' view create success');
}
// 创建控制器文件
protected function makeController($controllerName, $moduleName)
{
$controllerStub = $this->stubPath . 'Controller.stub';
$controllerStub = str_replace(['$controller', '$module'], [ucfirst($controllerName), strtolower($moduleName)], file_get_contents($controllerStub));
$controllerPath = $this->appPath . $moduleName . DIRECTORY_SEPARATOR . 'controller' . DIRECTORY_SEPARATOR;
if (!is_dir($controllerPath)) {
mkdir($controllerPath, 0777, true);
}
return file_put_contents( $controllerPath . $controllerName . '.php', $controllerStub);
}
// 创建模型文件
public function makeModel($modelName, $moduleName)
{
$modelPath = $this->appPath . DIRECTORY_SEPARATOR . 'model';
if (!is_dir($modelPath)) {
mkdir($modelPath, 0777, true);
}
$modelContents = "<?php \r\n \r\n";
$modelContents .= "namespace app\model;\r\n \r\n";
$modelContents .= 'class $modelModel extends BaseModel';
$modelContents .= "\r\n { \r\n \t";
$modelContents .= 'protected $table = \'' . config('database.prefix') . '$_table\';';
$modelContents = $this->writeField($modelContents, $modelName);
$modelContents = str_replace('$model', ucfirst($modelName), $modelContents);
$modelContents = str_replace('$_table', $this->unCamelize($modelName), $modelContents);
$modelContents .= "\r\n }";
return file_put_contents($modelPath . DIRECTORY_SEPARATOR . $modelName . 'Model.php', $modelContents);
}
private function writeField($modelContents, $modelName)
{
$info = Db::query('show full columns from ' . config('database.prefix') . $this->unCamelize($modelName));
foreach ($info as $value) {
$modelContents .= sprintf("\r\n %s \t protected $%s = '%s'; \r\n", $this->fieldComment($value['Comment']), $this->combine($value['Field']), $value['Field']);
}
return $modelContents;
}
// 创建模板
public function makeView($controllerName, $moduleName)
{
$viewStub = $this->stubPath . 'View.stub';
$viewPath = (config('template.view_base') ? config('template.view_base') . $moduleName . DIRECTORY_SEPARATOR : env('app_path') . $moduleName . DIRECTORY_SEPARATOR . 'views' . DIRECTORY_SEPARATOR) . strtolower($controllerName);
if (!is_dir($viewPath)) {
mkdir($viewPath, 0777, true);
}
$stub = explode('||', file_get_contents($viewStub));
foreach ($this->views as $view) {
if ($view == 'index') {
file_put_contents($viewPath . DIRECTORY_SEPARATOR . $view .'.html', trim($stub[0]));
} else {
file_put_contents($viewPath . DIRECTORY_SEPARATOR . $view .'.html', trim($stub[1]));
}
}
}
/**
* 字符注释
*
* @time at 2019年01月08日
* @param $comment
* @return string
*/
private function fieldComment($comment)
{
return sprintf("\t /** \r\n \t * @var string \r\n \t * @desc %s \r\n \t */ \r\n", $comment);
}
/**
* 驼峰分割
*
* @time at 2019年01月02日
* @param string $camelCaps
* @param string $separator
* @return string
*/
private function unCamelize(string $string, string $separator = '_')
{
return strtolower(preg_replace('/(?<=[a-z])([A-Z])/', $separator . '$1', $string));
}
private function combine(string $string)
{
$s = explode('_', $string);
array_walk($s, function (&$value, $key) {
if ($key) {
$value = ucfirst($value);
}
});
return implode($s, '');
}
}

View File

@@ -1,12 +0,0 @@
{extend name="public:base" /}
{block name="menu"}{/block}
{block name="search"}{/block}
{block name="button-create"}{/block}
{block name="table-head"}{/block}
{block name="table-body"}{/block}
{block name="paginate"}{/block}
||
{extend name="public:form" /}
{block name="menu"}{/block}
{block name='action'}{/block}
{block name="form"}{/block}

View File

@@ -1,67 +0,0 @@
<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: 流年 <liu21st@gmail.com>
// +----------------------------------------------------------------------
// 应用公共文件
/**
* 钩子行为
*/
if (!function_exists('hook')) {
function hook($behavior, $params) {
\think\facade\Hook::exec($behavior, $params);
}
}
/**
* 编辑按钮
*/
if (!function_exists('editButton')) {
function editButton(string $url, string $name = '编辑') {
return sprintf('<a href="%s"><button class="btn btn-info btn-xs edit" type="button"><i class="fa fa-paste"></i> %s</button></a>', $url, $name);
}
}
/**
* 增加按钮
*/
if (!function_exists('createButton')) {
function createButton(string $url, string $name, $isBig = true) {
return $isBig ? sprintf('<a href="%s"> <button type="button" class="btn btn-w-m btn-primary"><i class="fa fa-check-square-o"></i> %s</button></a>', $url, $name) :
sprintf('<a href="%s"> <button type="button" class="btn btn-xs btn-primary"><i class="fa fa-check-square-o"></i> %s</button></a>', $url, $name);
}
}
/**
* 删除按钮
*/
if (!function_exists('deleteButton')) {
function deleteButton(string $url, int $id, string $name="删除") {
return sprintf('<button class="btn btn-danger btn-xs delete" data-url="%s" data=%d type="button"><i class="fa fa-trash"></i> %s</button>', $url, $id, $name);
}
}
/**
* 搜索按钮
*/
if (!function_exists('searchButton')) {
function searchButton(string $name="搜索") {
return sprintf('<button class="btn btn-white" type="submit"><i class="fa fa-search"></i> %s</button>', $name);
}
}
/**
* 生成密码
*/
if (!function_exists('generatePassword')) {
function generatePassword(string $password, int $algo = PASSWORD_DEFAULT) {
return password_hash($password, $algo);
}
}

View File

@@ -1,60 +0,0 @@
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2018/11/16 0016
* Time: 下午 14:51
*/
namespace app\component\upload;
use think\exception\ThrowableError;
use think\facade\Request;
use app\exceptions\UploadException;
class LocalUpload implements UploadInterface
{
protected $name = null;
/**
* Upload File
*
* @time at 2018年11月16日
* @return string
*/
public function file(){}
/**
* Upload Image
*
* @time at 2018年11月16日
* @return string
*/
public function image()
{
try {
$file = Request::file($this->name);
if (!$this->name) {
throw new UploadException('请选择上传的图片');
}
$info = $file->validate(config('admin.image'))->move(config('admin.local_upload_path'));
if (!$info) {
throw new UploadException($file->getError());
}
return $info->getSaveName();
} catch (UploadException $exception) {
return $exception->getMessage();
}
}
/**
* Set Image Name
*
* @time at 2018年11月16日
* @param $name
* @return $this
*/
public function name($name)
{
$this->name = $name;
return $this;
}
}

View File

@@ -1,15 +0,0 @@
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2018/11/16 0016
* Time: 下午 14:50
*/
namespace app\component\upload;
interface UploadInterface
{
public function file();
public function image();
}

View File

@@ -1,13 +0,0 @@
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2018/11/13 0013
* Time: 上午 10:49
*/
namespace app\exceptions;
class AppException extends \Exception
{
}

View File

@@ -1,14 +0,0 @@
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2018/11/16 0016
* Time: 下午 15:03
*/
namespace app\exceptions;
class UploadException extends \Exception
{
}

View File

@@ -1,15 +0,0 @@
<?php
namespace app\http\middleware;
class CheckLogin
{
public function handle($request, \Closure $next)
{
if (!$request->session('user')) {
return redirect(url('login'));
}
return $next($request);
}
}

View File

@@ -1,16 +0,0 @@
<?php
namespace app\http\middleware;
use app\service\LogService;
class LogRecord
{
public function handle($request, \Closure $next)
{
(new LogService())->record($request);
return $next($request);
}
}

View File

@@ -1,64 +0,0 @@
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2018/11/12 0012
* Time: 上午 11:05
*/
namespace app\model;
use think\Model;
class BaseModel extends Model
{
const LIMIT = 10;
/**
* Store Data
*
* @time at 2018年11月12日
* @param array $data
* @return bool
*/
public function store(array $data)
{
return $this->save($data) ? $this->id : false;
}
/**
* Find By ID
*
* @time at 2018年11月12日
* @param int $id
* @return array|false|\PDOStatement|string|\think\Model
*/
public function findBy(int $id)
{
return $this->where('id', $id)->find();
}
/**
* Update By ID && Data
*
* @time at 2018年11月12日
* @param int $id
* @param array $data
* @return bool
*/
public function updateBy(int $id, array $data)
{
return $this->save($data, ['id' => $id]);
}
/**
* Delete By ID
*
* @time at 2018年11月12日
* @param int $id
* @return bool|null
*/
public function deleteBy(int $id)
{
return $this->where('id', $id)->delete();
}
}

View File

@@ -1,36 +0,0 @@
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2019/1/17
* Time: 18:09
*/
namespace app\model;
use http\Env\Request;
class LogRecordModel extends BaseModel
{
protected $name = 'option_log';
/**
* 日志列表
*
* @time at 2019年01月18日
* @param array $params
* @param int $limit
* @return mixed
*/
public function getAll(array $params, $limit = self::LIMIT)
{
if (!count($params)) {
return $this->order('created_at', 'desc')->paginate($limit, false, ['query' => request()->param()]);
}
if (isset($params['name'])) {
$list = $this->whereLike('user_name', '%'.$params['name'].'%');
}
return $list->order('created_at', 'desc')->paginate($limit, false, ['query' => request()->param()]);
}
}

View File

@@ -1,37 +0,0 @@
<?php
namespace app\model;
use think\permissions\traits\hasRoles;
class UserModel extends BaseModel
{
use hasRoles;
protected $name = 'users';
/**
* Users List
*
* @time at 2018年11月14日
* @param $params
* @return \think\Paginator
*/
public function getList($params, $limit = self::LIMIT)
{
if (!count($params)) {
return $this->paginate($limit);
}
if (isset($params['name'])) {
$user = $this->whereLike('name', '%'.$params['name'].'%');
}
if (isset($params['email'])) {
$user = $this->whereLike('email', '%'.$params['email'].'%');
}
return $user->paginate($limit, false, ['query' => request()->param()]);
}
}

View File

@@ -1,35 +0,0 @@
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2019/1/17
* Time: 18:06
*/
namespace app\service;
use think\permissions\facade\Permissions;
use think\Request;
use app\model\LogRecordModel;
class LogService
{
public function record(Request $request)
{
$module = $request->module();
$controller = $request->controller();
$action = $request->action();
$user = $request->session('user');
$permission = Permissions::getPermissionByModuleAnd($module, $controller, $action);
(new LogRecordModel())->store([
'user_id' => $user->id,
'user_name' => $user->name,
'module' => $module,
'controller' => $controller,
'action' => $action,
'option' => $permission->name,
'method' => $request->method(),
]);
}
}

View File

@@ -1,55 +0,0 @@
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2018/11/13 0013
* Time: 上午 10:50
*/
namespace app\service;
use think\Collection;
class MenuService
{
/**
* 树形结构
*
* @time at 2018年11月13日
* @param $menu
* @return Collection
*/
public function tree(Collection $menus, int $pid = 0)
{
$collection = new Collection();
$menus->each(function ($item, $key) use ($pid, $menus, $collection){
if ($item->pid == $pid) {
$collection[$key] = $item;
$collection[$key][$item->id] = $this->tree($menus, $item->id);
}
});
return $collection;
}
/**
* 顺序结构
*
* @time at 2018年11月13日
* @param $menu
* @return Collection
*/
public function sort(Collection $menus, int $pid = 0, int $level = 0)
{
$collection = [];
foreach ($menus as $menu) {
if ($menu->pid == $pid) {
$menu->level = $level;
$collection[] = $menu;
$collection = array_merge($collection, $this->sort($menus, $menu->id, $level+1));
}
}
return $collection;
}
}

View File

@@ -1,63 +0,0 @@
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2018/11/16 0016
* Time: 上午 11:01
*/
namespace app\service;
use think\paginator\driver\Bootstrap;
class PaginateService extends Bootstrap
{
/**
* 渲染分页html
* @return mixed
*/
public function render()
{
if ($this->hasPages()) {
if ($this->simple) {
return sprintf(
'<ul class="pager">%s %s</ul>',
$this->getPreviousButton(),
$this->getNextButton()
);
} else {
return sprintf(
'<ul class="pagination">%s %s %s %s</ul>',
$this->getPreviousButton(),
$this->getLinks(),
$this->getNextButton(),
$this->changeLimit()
);
}
}
}
protected function changeLimit()
{
$query = $this->options['query'];
$html = '&nbsp;<li class="project_page">';
$pageLimit = config('admin.page_limit');
$html .= '<select class="page-form-control limit" name="limit">';
foreach ($pageLimit as $limit) {
if (isset($query['limit']) && $query['limit'] == $limit) {
$html .= sprintf('<option value="%s" selected>%s条/页</option>', $limit, $limit);
} else {
$html .= sprintf('<option value="%s">%s条/页</option>', $limit, $limit);
}
}
$html .= '</select></li>&nbsp;<li>';
$html .= sprintf('<input name="page" class="page-form-control-input" value="%s"> 页 ', $query['page'] ?? 1);
$html .='</li>';
$html .= '<li><button class="btn btn-primary btn-xs hrefTo"><i class="fa fa-location-arrow"></i> 跳转</button></li>';
return $html;
}
}

View File

@@ -1,28 +0,0 @@
<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------
// 应用行为扩展定义文件
return [
// 应用初始化
'app_init' => [],
// 应用开始
'app_begin' => [],
// 模块初始化
'module_init' => [],
// 操作开始执行
'action_begin' => [],
// 视图内容过滤
'view_filter' => [],
// 日志写入
'log_write' => [],
// 应用结束
'app_end' => [],
];

View File

@@ -1,183 +0,0 @@
<?php
namespace app\traits;
use think\Request;
use think\Validate;
use think\facade\Session;
use think\facade\Cookie;
use app\model\UserModel as User;
use app\behavior\LoginRecord;
trait Auth
{
protected $loginUserKey = 'user';
public function authLogin(Request $request)
{
$err = $this->validateLogin($request);
if ($err) {
$this->error($err);
}
// 正常输入登录
$userModel = new User();
$field = explode('|', $this->name());
$user = $userModel::where($field[0], $request->param($field[0]))->find();
if (!$user) {
$this->error('登录失败');
}
if (password_verify($request->param('password'), $user->password)) {
Session::set($this->loginUserKey, $user);
# 记住登录
$this->LoginRemember($user, $request);
# 登录记录
hook(LoginRecord::class, ['user' => $user]);
$this->success('登录成功', url($this->redirect));
}
$this->error('登录失败');
}
/**
* 记住登录
* @return bool
*/
public function rememberLogin()
{
// 如果记住登录
if (!Session::get($this->loginUserKey) && Cookie::get('remember_token') && $this->checkRememberToken()) {
return true;
}
return false;
}
/**
* 退出
* @return void
*/
public function authLogout()
{
$user = Session::get($this->loginUserKey);
$this->deleteToken($user);
Session::delete($this->loginUserKey);
}
protected function deleteToken($user)
{
if ($user->remember_token) {
$user->remember_token = null;
$user->save();
Cookie::delete('remember_token');
}
}
/**
* 验证
* @param Request $request
* @return array|bool
*/
protected function validateLogin(Request $request)
{
$validate = new Validate($this->rule());
if (!$validate->check($request->except(['remember']))) {
return $validate->getError();
}
return false;
}
/**
* 登录验证规则
* @return array
*/
protected function rule()
{
return [
$this->name() => 'require|token|alphaDash',
'password|密码' => 'require|alphaDash',
'captcha|验证码' => 'require|captcha'
];
}
/**
* 设置登录字段
*
* @return string
*/
protected function name()
{
return 'name|用户名';
}
/**
* Remember Token
*
* @return string
*/
public function generateRememberToken()
{
return uniqid(md5(time()+rand(10000, 99999)));
}
/**
* 加密 TOKEN
*
* @param $user_id
* @param $remember_token
* @return string
*/
protected function secretRememberToken($user_id, $remember_token)
{
list($key, $method, $iv) = $this->getSecret();
return base64_encode(openssl_encrypt($user_id . ':' . $remember_token, $method, $key, OPENSSL_RAW_DATA, $iv));
}
/**
* 检查remember token 是否正确
*
* @return bool
*/
protected function checkRememberToken()
{
if (!Cookie::has('remember_token')) {
return false;
}
$rememberToken = Cookie::get('remember_token');
// 解密
list($key, $method, $iv) = $this->getSecret();
list($userID) = explode(':', (openssl_decrypt(base64_decode($rememberToken), $method, $key, OPENSSL_RAW_DATA, $iv)));
// 校验
$user = (new User())->findBy($userID);
Session::set('user', $user);
return $user->remember_token == $rememberToken;
}
/**
* 加密
*
* @return array
*/
protected function getSecret()
{
return ['admin_auth', 'AES-128-CBC', '1234567890123412'];
}
/**
* 记住
*
* @param $user
* @return void
*/
protected function LoginRemember($user, Request $request)
{
if ($request->has('remember')) {
$rememberToken = $this->secretRememberToken($user->id, $this->generateRememberToken());
$user->remember_token = $rememberToken;
Cookie::forever('remember_token', $rememberToken);
}
}
}

View File

@@ -1,80 +0,0 @@
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2018/11/12 0012
* Time: 上午 11:43
*/
namespace app\traits;
use think\facade\Session;
use app\component\upload\UploadInterface;
use app\component\upload\LocalUpload;
trait ControllerTrait
{
protected $vars = [];
/**
* 绑定实现
*
* @time at 2018年11月16日
* @return void
*/
public function initialize()
{
bind(UploadInterface::class, LocalUpload::class);
}
/**
* 是否登录
*
* @time at 2018年11月15日
* @return bool
*/
protected function isLogin()
{
return $this->getLoginUser() ? true : false;
}
/**
* 获取登录用户
*
* @time at 2018年11月15日
* @return mixed
*/
protected function getLoginUser()
{
return Session::get('user');
}
/**
* fetch 重写
*
* @time at 2018年11月15日
* @param string $template
* @param array $vars
* @param array $config
* @return mixed
*/
protected function fetch($template = '', $vars = [], $config = [])
{
$vars = array_merge($this->vars, $vars);
return $this->view->fetch($template, $vars, $config);
}
/**
* Set Template Vars
*
* @time at 2018年11月12日
* @param $name
* @param $value
* @return void
*/
public function __set($name, $value)
{
// TODO: Implement __set() method.
$this->vars[$name] = $value;
}
}

View File

@@ -1,26 +0,0 @@
<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------
return [
// 生成应用公共文件
'__file__' => ['common.php'],
// 定义demo模块的自动生成 (按照实际定义的文件名生成)
'demo' => [
'__file__' => ['common.php'],
'__dir__' => ['behavior', 'controller', 'model', 'view'],
'controller' => ['Index', 'Test', 'UserType'],
'model' => ['User', 'UserType'],
'view' => ['index/index'],
],
// 其他更多的模块定义
];

View File

@@ -0,0 +1,82 @@
<?php
namespace catchAdmin\login;
use catchAdmin\permissions\model\Users;
use catchAdmin\system\model\LoginLog;
use think\facade\Db;
class LoginLogEvent
{
public function handle($params)
{
$agent = request()->header('user-agent');
$username = Users::where('email', $params['email'])->value('username');
app(LoginLog::class)->storeBy([
'login_name' => $username ? : $params['email'],
'login_ip' => request()->ip(),
'browser' => $this->getBrowser($agent),
'os' => $this->getOs($agent),
'login_at' => time(),
'status' => $params['success'] ? 1 : 2,
]);
}
/**
*
* @time 2019年12月12日
* @param $agent
* @return string
*/
private function getOs($agent): string
{
if (false !== stripos($agent, 'win') && preg_match('/nt 6.1/i', $agent)) {
return 'Windows 7';
}
if (false !== stripos($agent, 'win') && preg_match('/nt 6.2/i', $agent)) {
return 'Windows 8';
}
if(false !== stripos($agent, 'win') && preg_match('/nt 10.0/i', $agent)) {
return 'Windows 10';#添加win10判断
}
if (false !== stripos($agent, 'win') && preg_match('/nt 5.1/i', $agent)) {
return 'Windows XP';
}
if (false !== stripos($agent, 'linux')) {
return 'Linux';
}
if (false !== stripos($agent, 'mac')) {
return 'mac';
}
return '未知';
}
/**
*
* @time 2019年12月12日
* @param $agent
* @return string
*/
private function getBrowser($agent): string
{
if (false !== stripos($agent, "MSIE")) {
return 'MSIE';
}
if (false !== stripos($agent, "Firefox")) {
return 'Firefox';
}
if (false !== stripos($agent, "Chrome")) {
return 'Chrome';
}
if (false !== stripos($agent, "Safari")) {
return 'Safari';
}
if (false !== stripos($agent, "Opera")) {
return 'Opera';
}
return '未知';
}
}

View File

@@ -0,0 +1,30 @@
<?php
// +----------------------------------------------------------------------
// | CatchAdmin [Just Like ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2020 http://catchadmin.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( https://github.com/yanwenwu/catch-admin/blob/master/LICENSE.txt )
// +----------------------------------------------------------------------
// | Author: JaguarJack [ njphper@gmail.com ]
// +----------------------------------------------------------------------
namespace catchAdmin\login;
use catcher\ModuleService;
use think\Service;
class LoginService extends ModuleService
{
public function loadRouteFrom()
{
// TODO: Implement loadRouteFrom() method.
return __DIR__ . DIRECTORY_SEPARATOR . 'route.php';
}
public function loadEvents()
{
return [
'loginLog' => [ LoginLogEvent::class ],
];
}
}

View File

@@ -0,0 +1,74 @@
<?php
namespace catchAdmin\login\controller;
use catchAdmin\login\request\LoginRequest;
use catchAdmin\permissions\model\Users;
use catcher\base\CatchController;
use catcher\CatchAuth;
use catcher\CatchResponse;
use catcher\exceptions\LoginFailedException;
use thans\jwt\facade\JWTAuth;
class Index extends CatchController
{
/**
* 登陆
*
* @time 2019年11月28日
* @param LoginRequest $request
* @param CatchAuth $auth
* @return bool|string
*/
public function login(LoginRequest $request, CatchAuth $auth)
{
$params = $request->param();
$token = $auth->attempt($params);
$user = $auth->user();
if ($user->status == Users::DISABLE) {
throw new LoginFailedException('该用户已被禁用');
}
// 记录用户登录
$user->last_login_ip = request()->ip();
$user->last_login_time = time();
$user->save();
// 登录事件
$params['success'] = $token;
event('loginLog', $params);
return $token ? CatchResponse::success([
'token' => $token,
], '登录成功') : CatchResponse::success('', '登录失败');
}
/**
* 登出
*
* @time 2019年11月28日
* @return \think\response\Json
*/
public function logout(): \think\response\Json
{
return CatchResponse::success();
}
/**
* refresh token
*
* @author JaguarJack
* @email njphper@gmail.com
* @time 2020/5/18
* @return \think\response\Json
*/
public function refreshToken()
{
return CatchResponse::success([
'token' => JWTAuth::refresh()
]);
}
}

15
catch/login/module.json Normal file
View File

@@ -0,0 +1,15 @@
{
"name": "登陆",
"alias": "login",
"description": "login 模块",
"version": "1.0.0",
"keywords": [],
"order": 1,
"services": [
"\\catchAdmin\\login\\LoginService"
],
"aliases": {},
"files": [],
"requires": [],
"enable": true
}

View File

@@ -0,0 +1,26 @@
<?php
namespace catchAdmin\login\request;
use catcher\base\CatchRequest;
class LoginRequest extends CatchRequest
{
protected $needCreatorId = false;
protected function rules(): array
{
// TODO: Implement rules() method.
return [
'email|用户名' => 'email',
'password|密码' => 'require',
// 'captcha|验证码' => 'require|captcha'
];
}
protected function message(): array
{
// TODO: Implement message() method.
return [];
}
}

9
catch/login/route.php Normal file
View File

@@ -0,0 +1,9 @@
<?php
$router->group(function () use ($router){
# 登入
$router->post('login', '\catchAdmin\login\controller\Index@login');
$router->post('logout', '\catchAdmin\login\controller\Index@logout');
$router->post('refresh/token', '\catchAdmin\login\controller\Index@refreshToken');
});

View File

@@ -0,0 +1,54 @@
<?php
// +----------------------------------------------------------------------
// | CatchAdmin [Just Like ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2020 http://catchadmin.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( https://github.com/yanwenwu/catch-admin/blob/master/LICENSE.txt )
// +----------------------------------------------------------------------
// | Author: JaguarJack [ njphper@gmail.com ]
// +----------------------------------------------------------------------
namespace catchAdmin\permissions;
use catchAdmin\permissions\event\OperateLogEvent;
use catchAdmin\permissions\middleware\AuthTokenMiddleware;
use catchAdmin\permissions\middleware\PermissionsMiddleware;
use catchAdmin\permissions\middleware\RecordOperateMiddleware;
use catcher\ModuleService;
class PermissionService extends ModuleService
{
public function register()
{
parent::register(); // TODO: Change the autogenerated stub
$this->registerMiddleWares();
}
public function loadEvents()
{
return [
'operateLog' => [ OperateLogEvent::class ],
];
}
public function loadRouteFrom()
{
// TODO: Implement loadRouteFrom() method.
return __DIR__ . DIRECTORY_SEPARATOR . 'route.php';
}
protected function registerMiddleWares()
{
$middleware = $this->app->config->get('middleware');
$middleware['alias']['auth'] = [
AuthTokenMiddleware::class,
PermissionsMiddleware::class,
RecordOperateMiddleware::class
];
$this->app->config->set($middleware, 'middleware');
}
}

View File

@@ -0,0 +1,68 @@
<?php
namespace catchAdmin\permissions\controller;
use catcher\base\CatchController;
use catchAdmin\permissions\model\Department as DepartmentModel;
use catcher\base\CatchRequest;
use catcher\CatchResponse;
use catcher\Tree;
class Department extends CatchController
{
protected $department;
public function __construct(DepartmentModel $department)
{
$this->department = $department;
}
/**
* 列表
*
* @time 2020年01月09日
* @param CatchRequest $request
* @return \think\response\Json
* @throws \think\db\exception\DbException
*/
public function index(): \think\response\Json
{
return CatchResponse::success(Tree::done($this->department->getList()));
}
/**
* 保存
*
* @time 2020年01月09日
* @param CatchRequest $request
* @return \think\response\Json
*/
public function save(CatchRequest $request): \think\response\Json
{
return CatchResponse::success($this->department->storeBy($request->param()));
}
/**
* 更新
*
* @time 2020年01月09日
* @param $id
* @param CatchRequest $request
* @return \think\response\Json
*/
public function update($id, CatchRequest $request): \think\response\Json
{
return CatchResponse::success($this->department->updateBy($id, $request->param()));
}
/**
* 删除
*
* @time 2020年01月09日
* @param $id
* @return \think\response\Json
*/
public function delete($id): \think\response\Json
{
return CatchResponse::success($this->department->deleteBy($id));
}
}

View File

@@ -0,0 +1,80 @@
<?php
namespace catchAdmin\permissions\controller;
use catchAdmin\permissions\model\Job as JobModel;
use catcher\base\CatchController;
use catcher\base\CatchRequest;
use catcher\CatchResponse;
class Job extends CatchController
{
protected $job;
public function __construct(JobModel $job)
{
$this->job = $job;
}
/**
* 列表
*
* @time 2020年01月09日
* @param CatchRequest $request
* @return \think\response\Json
* @throws \think\db\exception\DbException
*/
public function index(): \think\response\Json
{
return CatchResponse::paginate($this->job->getList());
}
/**
* 保存
*
* @time 2020年01月09日
* @param CatchRequest $request
* @return \think\response\Json
*/
public function save(CatchRequest $request): \think\response\Json
{
return CatchResponse::success($this->job->storeBy($request->post()));
}
/**
* 更新
*
* @time 2020年01月09日
* @param $id
* @param CatchRequest $request
* @return \think\response\Json
*/
public function update($id, CatchRequest $request): \think\response\Json
{
return CatchResponse::success($this->job->updateBy($id, $request->post()));
}
/**
* 删除
*
* @time 2020年01月09日
* @param $id
* @return \think\response\Json
*/
public function delete($id): \think\response\Json
{
return CatchResponse::success($this->job->deleteBy($id));
}
/**
* 获取所有
*
* @return \think\response\Json
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function getAll()
{
return CatchResponse::success($this->job->field(['id', 'job_name'])->select());
}
}

View File

@@ -0,0 +1,174 @@
<?php
namespace catchAdmin\permissions\controller;
use catcher\base\CatchRequest as Request;
use catcher\base\CatchController;
use catcher\CatchResponse;
use catcher\exceptions\FailedException;
use catcher\library\ParseClass;
use catcher\Tree;
use catchAdmin\permissions\model\Permissions;
use think\response\Json;
class Permission extends CatchController
{
protected $permissions;
public function __construct(Permissions $permissions)
{
$this->permissions = $permissions;
}
/**
*
* @time 2019年12月11日
* @param Request $request
* @return Json
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\db\exception\DataNotFoundException
*/
public function index(Request $request): Json
{
// 获取菜单类型
$menuList = $this->permissions->getList(true);
// 获取按钮类型并且重新排列
$buttonList = [];
$this->permissions
->whereIn('parent_id', array_unique($menuList->column('id')))
->where('type', Permissions::BTN_TYPE)
->select()->each(function ($item) use (&$buttonList){
$buttonList[$item['parent_id']][] = $item->toArray();
});
// 子节点的 key
$children = $request->param('actionList') ?? 'children';
// 返回树结构
return CatchResponse::success(Tree::done($menuList->each(function (&$item) use ($buttonList, $children){
$item[$children] = $buttonList[$item['id']] ?? [];
})->toArray()));
}
/**
*
* @time 2019年12月11日
* @param Request $request
* @return Json
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\db\exception\DataNotFoundException
*/
public function save(Request $request): Json
{
$params = $request->param();
// 如果是子分类 自动写入父类模块
$parentId = $params['parent_id'] ?? 0;
if ($parentId) {
$parent = $this->permissions->findBy($parentId);
$params['module'] = $parent->module;
}
return CatchResponse::success($this->permissions->storeBy($params));
}
/**
*
* @time 2019年12月11日
* @param $id
* @param Request $request
* @return Json
*/
public function update($id, Request $request): Json
{
$permission = $this->permissions->findBy($id);
$params = array_merge($request->param(), [
'parent_id' => $permission->parent_id,
'level' => $permission->level
]);
if ($permission->updateBy($id, $params)) {
if ($params['module'] ?? false) {
$this->permissions->updateBy($permission->id, [
'module' => $params['module'],
], 'parent_id');
}
return CatchResponse::success();
}
throw new FailedException('更新失败');
}
/**
*
* @time 2019年12月11日
* @param $id
* @throws FailedException
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
* @return Json
*/
public function delete($id): Json
{
if ($this->permissions->where('parent_id', $id)->find()) {
throw new FailedException('存在子菜单,无法删除');
}
$this->permissions->findBy($id)->roles()->detach();
return CatchResponse::success($this->permissions->deleteBy($id));
}
/**
* 显示/隐藏
*
* @author JaguarJack
* @email njphper@gmail.com
* @time 2020/5/19
* @param $id
* @return Json
*/
public function show($id)
{
$permission = $this->permissions->findBy($id);
$permission->status = $permission->status == Permissions::ENABLE ? Permissions::DISABLE : Permissions::ENABLE;
if ($permission->save()) {
$this->permissions->where('parent_id', $id)->update([
'status' => $permission->status,
]);
}
return CatchResponse::success($permission->save());
}
/**
*
* @time 2020年06月05日
* @param $id
* @param ParseClass $parseClass
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
* @return Json
*/
public function getMethods($id, ParseClass $parseClass)
{
$permission = Permissions::where('id', $id)->find();
$module = $permission->module;
$controller = explode('@', $permission->permission_mark)[0];
$methods = $parseClass->setModule('catch')->setRule($module, $controller)->onlySelfMethods();
return CatchResponse::success($methods);
}
}

View File

@@ -0,0 +1,182 @@
<?php
namespace catchAdmin\permissions\controller;
use catchAdmin\permissions\model\Permissions;
use catcher\base\CatchRequest as Request;
use catcher\base\CatchController;
use catcher\CatchResponse;
use catcher\exceptions\FailedException;
use catcher\Tree;
use think\response\Json;
class Role extends CatchController
{
protected $role;
public function __construct(\catchAdmin\permissions\model\Roles $role)
{
$this->role = $role;
}
/**
*
* @time 2019年12月09日
* @param Request $request
* @return string
*/
public function index()
{
return CatchResponse::success(Tree::done($this->role->getList()));
}
/**
*
* @time 2019年12月11日
* @param Request $request
* @return Json
* @throws \think\db\exception\DbException
*/
public function save(Request $request)
{
$this->role->storeBy($request->param());
$permissions = $request->param('permissions');
if (!empty($permissions)) {
$this->role->attachPermissions(array_unique($permissions));
}
if (!empty($request->param('departments'))) {
$this->role->attachDepartments($request->param('departments'));
}
// 添加角色
return CatchResponse::success();
}
public function read($id)
{
$role = $this->role->findBy($id);
$role->permissions = $role->getPermissions();
$role->departments = $role->getDepartments();
return CatchResponse::success($role);
}
/**
*
* @time 2019年12月11日
* @param $id
* @param Request $request
* @return Json
* @throws \think\db\exception\DbException
*/
public function update($id, Request $request): Json
{
$this->role->updateBy($id, $request->param());
$role = $this->role->findBy($id);
$hasPermissionIds = $role->getPermissions()->column('id');
$permissionIds = $request->param('permissions');
// 已存在权限 IDS
$existedPermissionIds = [];
foreach ($hasPermissionIds as $hasPermissionId) {
if (in_array($hasPermissionId, $permissionIds)) {
$existedPermissionIds[] = $hasPermissionId;
}
}
$attachIds = array_diff($permissionIds, $existedPermissionIds);
$detachIds = array_diff($hasPermissionIds, $existedPermissionIds);
if (!empty($detachIds)) {
$role->detachPermissions($detachIds);
}
if (!empty($attachIds)) {
$role->attachPermissions(array_unique($attachIds));
}
// 更新department
$hasDepartmentIds = $role->getDepartments()->column('id');
$departmentIds = $request->param('departments',[]);
// 已存在部门 IDS
$existedDepartmentIds = [];
foreach ($hasDepartmentIds as $hasDepartmentId) {
if (in_array($hasDepartmentId, $departmentIds)) {
$existedDepartmentIds[] = $hasDepartmentId;
}
}
$attachDepartmentIds = array_diff($departmentIds, $existedDepartmentIds);
$detachDepartmentIds = array_diff($hasDepartmentIds, $existedDepartmentIds);
if (!empty($detachDepartmentIds)) {
$role->detachDepartments($detachDepartmentIds);
}
if (!empty($attachDepartmentIds)) {
$role->attachDepartments(array_unique($attachDepartmentIds));
}
return CatchResponse::success();
}
/**
*
* @time 2019年12月11日
* @param $id
* @throws FailedException
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
* @return Json
*/
public function delete($id): Json
{
if ($this->role->where('parent_id', $id)->find()) {
throw new FailedException('存在子角色,无法删除');
}
$role = $this->role->findBy($id);
// 删除权限
$role->detachPermissions();
// 删除部门关联
$role->detachDepartments();
// 删除用户关联
$role->users()->detach();
// 删除
$this->role->deleteBy($id);
return CatchResponse::success();
}
/**
*
* @time 2019年12月11日
* @param Request $request
* @param \catchAdmin\permissions\model\Permissions $permission
* @return Json
*/
public function getPermissions(Request $request, \catchAdmin\permissions\model\Permissions $permission): Json
{
$parentRoleHasPermissionIds = [];
if ($request->param('parent_id')) {
$permissions = $this->role->findBy($request->param('parent_id'))->getPermissions();
foreach ($permissions as $_permission) {
$parentRoleHasPermissionIds[] = $_permission->pivot->permission_id;
}
}
$permissions = Tree::done(Permissions::whereIn('id', $parentRoleHasPermissionIds)->select()->toArray());
$permissionIds = [];
if ($request->param('role_id')) {
$roleHasPermissions = $this->role->findBy($request->param('role_id'))->getPermissions();
foreach ($roleHasPermissions as $_permission) {
$permissionIds[] = $_permission->pivot->permission_id;
}
}
return CatchResponse::success([
'permissions' => $permissions,
'hasPermissions' => $permissionIds,
]);
}
}

View File

@@ -0,0 +1,228 @@
<?php
namespace catchAdmin\permissions\controller;
use catcher\base\CatchRequest as Request;
use catchAdmin\permissions\model\Permissions;
use catchAdmin\permissions\model\Roles;
use catchAdmin\permissions\model\Users;
use catchAdmin\permissions\request\CreateRequest;
use catchAdmin\permissions\request\UpdateRequest;
use catcher\base\CatchController;
use catcher\CatchAuth;
use catcher\CatchCacheKeys;
use catcher\CatchResponse;
use catcher\Tree;
use catcher\Utils;
use think\facade\Cache;
class User extends CatchController
{
protected $user;
public function __construct(Users $user)
{
$this->user = $user;
}
/**
*
* @time 2020年04月24日
* @throws \think\db\exception\DbException
* @return \think\response\Json
*/
public function index()
{
return CatchResponse::paginate($this->user->getList());
}
/**
* 获取用户信息
*
* @time 2020年01月07日
* @param CatchAuth $auth
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
* @return \think\response\Json
*/
public function info(CatchAuth $auth)
{
$user = $auth->user();
$roles = $user->getRoles();
$permissionIds = $user->getPermissionsBy($user->id);
// 缓存用户权限
Cache::set(CatchCacheKeys::USER_PERMISSIONS . $user->id, $permissionIds);
$user->permissions = Permissions::getCurrentUserPermissions($permissionIds);
$user->roles = $roles;
// 用户数据权限
// $user->data_range = Roles::getDepartmentUserIdsBy($roles);
return CatchResponse::success($user);
}
/**
*
* @time 2019年12月06日
* @throws \Exception
* @return string
*/
public function create()
{}
/**
*
* @param CreateRequest $request
* @time 2019年12月06日
* @return \think\response\Json
*/
public function save(CreateRequest $request)
{
$this->user->storeBy($request->param());
$this->user->attachRoles($request->param('roles'));
$this->user->attachJobs($request->param('jobs'));
return CatchResponse::success('', '添加成功');
}
/**
*
* @time 2019年12月04日
* @param $id
* @return \think\response\Json
*/
public function read($id)
{
$user = $this->user->findBy($id);
$user->roles = $user->getRoles();
$user->jobs = $user->getJobs();
return CatchResponse::success($user);
}
/**
* @param $id
* @return string
* @throws \Exception
*/
public function edit($id){}
/**
*
* @time 2019年12月04日
* @param $id
* @param UpdateRequest $request
* @return \think\response\Json
*/
public function update($id, UpdateRequest $request)
{
$this->user->updateBy($id, $request->param());
$user = $this->user->findBy($id);
$user->detachRoles();
$user->detachJobs();
if (!empty($request->param('roles'))) {
$user->attachRoles($request->param('roles'));
}
if (!empty($request->param('jobs'))) {
$user->attachJobs($request->param('jobs'));
}
return CatchResponse::success();
}
/**
*
* @time 2019年12月04日
* @param $id
* @return \think\response\Json
*/
public function delete($id)
{
$ids = Utils::stringToArrayBy($id);
foreach ($ids as $_id) {
$user = $this->user->findBy($_id);
// 删除角色
$user->detachRoles();
// 删除岗位
$user->detachJobs();
$this->user->deleteBy($_id);
}
return CatchResponse::success();
}
/**
*
* @time 2019年12月07日
* @param $id
* @return \think\response\Json
*/
public function switchStatus($id): \think\response\Json
{
$ids = Utils::stringToArrayBy($id);
foreach ($ids as $_id) {
$user = $this->user->findBy($_id);
$this->user->updateBy($_id, [
'status' => $user->status == Users::ENABLE ? Users::DISABLE : Users::ENABLE,
]);
}
return CatchResponse::success([], '操作成功');
}
/**
*
* @time 2019年12月07日
* @param $id
* @return \think\response\Json
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\db\exception\DataNotFoundException
*/
public function recover($id): \think\response\Json
{
$trashedUser = $this->user->findBy($id, ['*'], true);
if ($this->user->where('email', $trashedUser->email)->find()) {
return CatchResponse::fail(sprintf('该恢复用户的邮箱 [%s] 已被占用', $trashedUser->email));
}
return CatchResponse::success($this->user->recover($id));
}
/**
*
* @time 2019年12月11日
* @param Request $request
* @param Roles $roles
* @return \think\response\Json
*/
public function getRoles(Request $request, Roles $roles): \think\response\Json
{
$roles = Tree::done($roles->getList());
$roleIds = [];
if ($request->param('uid')) {
$userHasRoles = $this->user->findBy($request->param('uid'))->getRoles();
foreach ($userHasRoles as $role) {
$roleIds[] = $role->pivot->role_id;
}
}
return CatchResponse::success([
'roles' => $roles,
'hasRoles' => $roleIds,
]);
}
}

View File

@@ -0,0 +1,45 @@
<?php
use think\migration\Migrator;
use think\migration\db\Column;
class Users extends Migrator
{
/**
* Change Method.
*
* Write your reversible migrations using this method.
*
* More information on writing migrations is available here:
* http://docs.phinx.org/en/latest/migrations.html#the-abstractmigration-class
*
* The following commands can be used in this method and Phinx will
* automatically reverse them when rolling back:
*
* createTable
* renameTable
* addColumn
* renameColumn
* addIndex
* addForeignKey
*
* Remember to call "create()" or "update()" and NOT "save()" when working
* with the Table class.
*/
public function change()
{
$table = $this->table('users',array('engine'=>'Innodb', 'comment' => '用户表', 'signed' => false));
$table->addColumn('username', 'string',array('limit' => 15,'default'=>'','comment'=>'用户名'))
->addColumn('password', 'string',array('limit' => 255,'comment'=>'用户密码'))
->addColumn('email', 'string',array('limit' => 100, 'comment'=>'邮箱 登录'))
->addColumn('creator_id', 'integer',['default' => 0, 'comment'=>'创建人ID'])
->addColumn('department_id', 'integer',['default' => 0, 'comment'=>'部门ID'])
->addColumn('status', 'boolean',array('limit' => 1,'default'=> 1,'comment'=>'用户状态 1 正常 2 禁用'))
->addColumn('last_login_ip', 'string',array('limit' => 50,'default'=>0,'comment'=>'最后登录IP'))
->addColumn('last_login_time', 'integer',array('default'=>0,'comment'=>'最后登录时间', 'signed' => false))
->addColumn('created_at', 'integer', array('default'=>0,'comment'=>'创建时间', 'signed' => false ))
->addColumn('updated_at', 'integer', array('default'=>0,'comment'=>'更新时间', 'signed' => false))
->addColumn('deleted_at', 'integer', array('default'=>0,'comment'=>'删除状态0未删除 >0 已删除', 'signed' => false))
->create();
}
}

View File

@@ -0,0 +1,42 @@
<?php
use think\migration\Migrator;
use think\migration\db\Column;
class Roles extends Migrator
{
/**
* Change Method.
*
* Write your reversible migrations using this method.
*
* More information on writing migrations is available here:
* http://docs.phinx.org/en/latest/migrations.html#the-abstractmigration-class
*
* The following commands can be used in this method and Phinx will
* automatically reverse them when rolling back:
*
* createTable
* renameTable
* addColumn
* renameColumn
* addIndex
* addForeignKey
*
* Remember to call "create()" or "update()" and NOT "save()" when working
* with the Table class.
*/
public function change()
{
$table = $this->table('roles',['engine'=>'Innodb', 'comment' => '角色表', 'signed' => false]);
$table->addColumn('role_name', 'string',['limit' => 15,'default'=>'','comment'=>'角色名'])
->addColumn('parent_id', 'integer',['default'=>0,'comment'=>'父级ID', 'signed' => false])
->addColumn('description', 'string',['default'=> '','comment'=>'角色备注'])
->addColumn('data_range', 'integer',['limit' => \Phinx\Db\Adapter\MysqlAdapter::INT_TINY,'default'=> 0,'comment'=>'1 全部数据 2 自定义数据 3 仅本人数据 4 部门数据 5 部门及以下数据'])
->addColumn('creator_id', 'integer',['default' => 0, 'comment'=>'创建人ID'])
->addColumn('created_at', 'integer', array('default'=>0,'comment'=>'创建时间', 'signed' => false ))
->addColumn('updated_at', 'integer', array('default'=>0,'comment'=>'更新时间', 'signed' => false))
->addColumn('deleted_at', 'integer', array('default'=>0,'comment'=>'删除状态0未删除 >0 已删除', 'signed' => false))
->create();
}
}

View File

@@ -0,0 +1,48 @@
<?php
use think\migration\Migrator;
use think\migration\db\Column;
class Permissions extends Migrator
{
/**
* Change Method.
*
* Write your reversible migrations using this method.
*
* More information on writing migrations is available here:
* http://docs.phinx.org/en/latest/migrations.html#the-abstractmigration-class
*
* The following commands can be used in this method and Phinx will
* automatically reverse them when rolling back:
*
* createTable
* renameTable
* addColumn
* renameColumn
* addIndex
* addForeignKey
*
* Remember to call "create()" or "update()" and NOT "save()" when working
* with the Table class.
*/
public function change()
{
$table = $this->table('permissions',['engine'=>'Innodb', 'comment' => '菜单表', 'signed' => false]);
$table->addColumn('permission_name', 'string',['limit' => 15,'default'=>'','comment'=>'菜单名称'])
->addColumn('parent_id', 'integer',['default'=>0,'comment'=>'父级ID', 'signed' => false])
->addColumn('route', 'string', ['default' => '', 'comment' => '路由', 'limit' => 50])
->addColumn('icon', 'string', ['default' => '', 'comment' => '菜单图标', 'limit' => 50])
->addColumn('module', 'string', ['default' => '', 'comment' => '模块', 'limit' => 20])
->addColumn('creator_id', 'integer',['default' => 0, 'comment'=>'创建人ID'])
->addColumn('method', 'string', ['default' => 'get', 'comment' => '路由请求方法', 'limit' => 15])
->addColumn('permission_mark', 'string', ['null' => false, 'comment' => '权限标识', 'limit' => 50])
->addColumn('type', 'integer',['limit' => \Phinx\Db\Adapter\MysqlAdapter::INT_TINY,'default'=> 1,'comment'=>'1 菜单 2 按钮'])
->addColumn('sort', 'integer',['default'=> 0,'comment'=>'排序字段'])
->addColumn('created_at', 'integer', array('default'=>0,'comment'=>'创建时间', 'signed' => false ))
->addColumn('updated_at', 'integer', array('default'=>0,'comment'=>'更新时间', 'signed' => false))
->addColumn('deleted_at', 'integer', array('default'=>0,'comment'=>'删除状态null 未删除 timestamp 已删除', 'signed' => false))
->create();
}
}

View File

@@ -0,0 +1,36 @@
<?php
use think\migration\Migrator;
use think\migration\db\Column;
class UserHasRoles extends Migrator
{
/**
* Change Method.
*
* Write your reversible migrations using this method.
*
* More information on writing migrations is available here:
* http://docs.phinx.org/en/latest/migrations.html#the-abstractmigration-class
*
* The following commands can be used in this method and Phinx will
* automatically reverse them when rolling back:
*
* createTable
* renameTable
* addColumn
* renameColumn
* addIndex
* addForeignKey
*
* Remember to call "create()" or "update()" and NOT "save()" when working
* with the Table class.
*/
public function change()
{
$table = $this->table('user_has_roles',['engine'=>'Innodb', 'comment' => '用户角色表', 'signed' => false]);
$table->addColumn('uid', 'integer',['comment'=>'用户ID', 'signed' => false])
->addColumn('role_id', 'integer', ['comment'=>'角色ID', 'signed' => false])
->create();
}
}

View File

@@ -0,0 +1,36 @@
<?php
use think\migration\Migrator;
use think\migration\db\Column;
class RoleHasPermissions extends Migrator
{
/**
* Change Method.
*
* Write your reversible migrations using this method.
*
* More information on writing migrations is available here:
* http://docs.phinx.org/en/latest/migrations.html#the-abstractmigration-class
*
* The following commands can be used in this method and Phinx will
* automatically reverse them when rolling back:
*
* createTable
* renameTable
* addColumn
* renameColumn
* addIndex
* addForeignKey
*
* Remember to call "create()" or "update()" and NOT "save()" when working
* with the Table class.
*/
public function change()
{
$table = $this->table('role_has_permissions',['engine'=>'Innodb', 'comment' => '角色权限表', 'signed' => false]);
$table->addColumn('role_id', 'integer',['comment'=>'角色ID', 'signed' => false])
->addColumn('permission_id', 'integer', ['comment'=>'权限ID', 'signed' => false])
->create();
}
}

View File

@@ -0,0 +1,45 @@
<?php
use think\migration\Migrator;
use think\migration\db\Column;
class Department extends Migrator
{
/**
* Change Method.
*
* Write your reversible migrations using this method.
*
* More information on writing migrations is available here:
* http://docs.phinx.org/en/latest/migrations.html#the-abstractmigration-class
*
* The following commands can be used in this method and Phinx will
* automatically reverse them when rolling back:
*
* createTable
* renameTable
* addColumn
* renameColumn
* addIndex
* addForeignKey
*
* Remember to call "create()" or "update()" and NOT "save()" when working
* with the Table class.
*/
public function change()
{
$table = $this->table('departments',['engine'=>'Innodb', 'comment' => '部门表', 'signed' => false]);
$table->addColumn('department_name', 'string',['limit' => 15,'default'=>'','comment'=>'部门名称'])
->addColumn('parent_id', 'integer',['default'=>0,'comment'=>'父级ID', 'signed' => false])
->addColumn('principal', 'string', ['default' => '', 'comment' => '负责人', 'limit' => 20])
->addColumn('mobile', 'string', ['default' => '', 'comment' => '联系电话', 'limit' => 20])
->addColumn('email', 'string', ['default' => '', 'comment' => '联系又想', 'limit' => 100])
->addColumn('creator_id', 'integer',['default' => 0, 'comment'=>'创建人ID'])
->addColumn('status', 'integer',['limit' => \Phinx\Db\Adapter\MysqlAdapter::INT_TINY,'default'=> 1,'comment'=>'1 正常 2 停用'])
->addColumn('sort', 'integer',['default'=> 0,'comment'=>'排序字段'])
->addColumn('created_at', 'integer', array('default'=>0,'comment'=>'创建时间', 'signed' => false ))
->addColumn('updated_at', 'integer', array('default'=>0,'comment'=>'更新时间', 'signed' => false))
->addColumn('deleted_at', 'integer', array('default'=>0,'comment'=>'删除状态null 未删除 timestamp 已删除', 'signed' => false))
->create();
}
}

View File

@@ -0,0 +1,43 @@
<?php
use think\migration\Migrator;
use think\migration\db\Column;
class Job extends Migrator
{
/**
* Change Method.
*
* Write your reversible migrations using this method.
*
* More information on writing migrations is available here:
* http://docs.phinx.org/en/latest/migrations.html#the-abstractmigration-class
*
* The following commands can be used in this method and Phinx will
* automatically reverse them when rolling back:
*
* createTable
* renameTable
* addColumn
* renameColumn
* addIndex
* addForeignKey
*
* Remember to call "create()" or "update()" and NOT "save()" when working
* with the Table class.
*/
public function change()
{
$table = $this->table('jobs',['engine'=>'Innodb', 'comment' => '岗位表', 'signed' => false]);
$table->addColumn('job_name', 'string',['limit' => 15,'default'=>'','comment'=>'岗位名称'])
->addColumn('coding', 'string', ['default' => '', 'comment' => '编码', 'limit' => 50])
->addColumn('creator_id', 'integer',['default' => 0, 'comment'=>'创建人ID'])
->addColumn('status', 'integer',['limit' => \Phinx\Db\Adapter\MysqlAdapter::INT_TINY,'default'=> 1,'comment'=>'1 正常 2 停用'])
->addColumn('sort', 'integer',['default'=> 0,'comment'=>'排序字段'])
->addColumn('description', 'string', ['default' => '', 'comment' => '描述', 'limit' => 255])
->addColumn('created_at', 'integer', array('default'=>0,'comment'=>'创建时间', 'signed' => false ))
->addColumn('updated_at', 'integer', array('default'=>0,'comment'=>'更新时间', 'signed' => false))
->addColumn('deleted_at', 'integer', array('default'=>0,'comment'=>'删除状态null 未删除 timestamp 已删除', 'signed' => false))
->create();
}
}

View File

@@ -0,0 +1,36 @@
<?php
use think\migration\Migrator;
use think\migration\db\Column;
class UserRelateJob extends Migrator
{
/**
* Change Method.
*
* Write your reversible migrations using this method.
*
* More information on writing migrations is available here:
* http://docs.phinx.org/en/latest/migrations.html#the-abstractmigration-class
*
* The following commands can be used in this method and Phinx will
* automatically reverse them when rolling back:
*
* createTable
* renameTable
* addColumn
* renameColumn
* addIndex
* addForeignKey
*
* Remember to call "create()" or "update()" and NOT "save()" when working
* with the Table class.
*/
public function change()
{
$table = $this->table('user_has_jobs',['engine'=>'Innodb', 'comment' => '用户角色表', 'signed' => false]);
$table->addColumn('uid', 'integer',['comment'=>'用户ID', 'signed' => false])
->addColumn('job_id', 'integer', ['comment'=>'岗位ID', 'signed' => false])
->create();
}
}

View File

@@ -0,0 +1,36 @@
<?php
use think\migration\Migrator;
use think\migration\db\Column;
class RoleHasDepartments extends Migrator
{
/**
* Change Method.
*
* Write your reversible migrations using this method.
*
* More information on writing migrations is available here:
* http://docs.phinx.org/en/latest/migrations.html#the-abstractmigration-class
*
* The following commands can be used in this method and Phinx will
* automatically reverse them when rolling back:
*
* createTable
* renameTable
* addColumn
* renameColumn
* addIndex
* addForeignKey
*
* Remember to call "create()" or "update()" and NOT "save()" when working
* with the Table class.
*/
public function change()
{
$table = $this->table('role_has_departments',['engine'=>'Innodb', 'comment' => '角色部门表', 'signed' => false]);
$table->addColumn('role_id', 'integer',['comment'=>'角色ID', 'signed' => false])
->addColumn('department_id', 'integer', ['comment'=>'部门ID', 'signed' => false])
->create();
}
}

View File

@@ -0,0 +1,41 @@
<?php
use think\migration\Migrator;
use think\migration\db\Column;
class ChangePermissions extends Migrator
{
/**
* Change Method.
*
* Write your reversible migrations using this method.
*
* More information on writing migrations is available here:
* http://docs.phinx.org/en/latest/migrations.html#the-abstractmigration-class
*
* The following commands can be used in this method and Phinx will
* automatically reverse them when rolling back:
*
* createTable
* renameTable
* addColumn
* renameColumn
* addIndex
* addForeignKey
*
* Remember to call "create()" or "update()" and NOT "save()" when working
* with the Table class.
*/
public function change()
{
if ($this->hasTable('permissions')) {
$table = $this->table('permissions');
$table->addColumn('component', 'string', ['default' => '', 'comment' => '组件名称', 'limit' => '255', 'after' => 'permission_mark'])
->addColumn('redirect', 'string', ['default' => '', 'comment' => '跳转地址', 'limit' => '255', 'after' => 'component'])
->addColumn('hide_children_in_menu', 'integer', ['limit' => \Phinx\Db\Adapter\MysqlAdapter::INT_TINY, 'default' => 1, 'comment' => '1 显示 2隐藏', 'after' => 'redirect'])
->addColumn('keepalive', 'integer', ['limit' => \Phinx\Db\Adapter\MysqlAdapter::INT_TINY, 'default' => 1, 'comment' => '1 缓存 2 不存在 ', 'after' => 'hide_children_in_menu'])
->update();
}
}
}

View File

@@ -0,0 +1,38 @@
<?php
use think\migration\Migrator;
use think\migration\db\Column;
class PermissionsAddColumn extends Migrator
{
/**
* Change Method.
*
* Write your reversible migrations using this method.
*
* More information on writing migrations is available here:
* http://docs.phinx.org/en/latest/migrations.html#the-abstractmigration-class
*
* The following commands can be used in this method and Phinx will
* automatically reverse them when rolling back:
*
* createTable
* renameTable
* addColumn
* renameColumn
* addIndex
* addForeignKey
*
* Remember to call "create()" or "update()" and NOT "save()" when working
* with the Table class.
*/
public function change()
{
if ($this->hasTable('permissions')) {
$table = $this->table('permissions');
$table->addColumn('level', 'string', ['default' => '', 'comment' => '层级', 'limit' => '50', 'after' => 'parent_id'])
->update();
}
}
}

View File

@@ -0,0 +1,42 @@
<?php
use think\migration\Migrator;
use think\migration\db\Column;
class AddPermissionStatusColumn extends Migrator
{
/**
* Change Method.
*
* Write your reversible migrations using this method.
*
* More information on writing migrations is available here:
* http://docs.phinx.org/en/latest/migrations.html#the-abstractmigration-class
*
* The following commands can be used in this method and Phinx will
* automatically reverse them when rolling back:
*
* createTable
* renameTable
* addColumn
* renameColumn
* addIndex
* addForeignKey
*
* Remember to call "create()" or "update()" and NOT "save()" when working
* with the Table class.
*/
public function change()
{
if ($this->hasTable('permissions')) {
$table = $this->table('permissions');
$table->addColumn('status', 'integer', [
'limit' => \Phinx\Db\Adapter\MysqlAdapter::INT_TINY,
'default' => 1,
'comment' => '1 显示 2 隐藏',
'after' => 'type'])
->update();
}
}
}

View File

@@ -0,0 +1,39 @@
<?php
use think\migration\Seeder;
class DepartmentsSeed extends Seeder
{
/**
* Run Method.
*
* Write your database seeder using this method.
*
* More information on writing seeders is available here:
* http://docs.phinx.org/en/latest/seeding.html
*/
public function run()
{
$data = [
[
'id' => 1,
'department_name' => '总部',
'parent_id' => 0,
],
[
'id' => 2,
'department_name' => '北京总部',
'parent_id' => 1,
],
[
'id' => 3,
'department_name' => '南京总部',
'parent_id' => 1,
],
];
foreach ($data as $item) {
\catchAdmin\permissions\model\Department::create($item);
}
}
}

View File

@@ -0,0 +1,871 @@
<?php
use think\migration\Seeder;
class PermissionSeed extends Seeder
{
/**
* Run Method.
*
* Write your database seeder using this method.
*
* More information on writing seeders is available here:
* http://docs.phinx.org/en/latest/seeding.html
*/
public function run()
{
\catcher\Utils::importTreeData($this->getPermissions(), 'permissions', 'parent_id');
}
protected function getPermissions()
{
return array (
0 =>
array (
'id' => 1,
'permission_name' => '权限管理',
'parent_id' => 0,
'level' => '',
'route' => '/permissions',
'icon' => 'appstore',
'module' => 'permissions',
'creator_id' => 1,
'method' => 'get',
'permission_mark' => 'permission@index',
'component' => 'pageView',
'redirect' => '',
'hide_children_in_menu' => 2,
'keepalive' => 1,
'type' => 1,
'status' => 1,
'sort' => 100,
'created_at' => 1587461455,
'updated_at' => 1593044101,
'deleted_at' => 0,
'children' =>
array (
0 =>
array (
'id' => 2,
'permission_name' => '用户管理',
'parent_id' => 1,
'level' => '1',
'route' => '/permissions/users',
'icon' => 'user',
'module' => 'permissions',
'creator_id' => 1,
'method' => 'get',
'permission_mark' => 'user@index',
'component' => 'users',
'redirect' => '',
'hide_children_in_menu' => 2,
'keepalive' => 1,
'type' => 1,
'status' => 1,
'sort' => 10,
'created_at' => 1587461597,
'updated_at' => 1592371975,
'deleted_at' => 0,
'children' =>
array (
0 =>
array (
'id' => 3,
'permission_name' => '列表',
'parent_id' => 2,
'level' => '1-2',
'route' => '',
'icon' => '',
'module' => 'permissions',
'creator_id' => 1,
'method' => 'get',
'permission_mark' => 'user@index',
'component' => '',
'redirect' => '',
'hide_children_in_menu' => 1,
'keepalive' => 1,
'type' => 2,
'status' => 1,
'sort' => 1,
'created_at' => 1587461647,
'updated_at' => 1591316160,
'deleted_at' => 0,
),
1 =>
array (
'id' => 4,
'permission_name' => '创建',
'parent_id' => 2,
'level' => '1-2',
'route' => '',
'icon' => '',
'module' => 'permissions',
'creator_id' => 1,
'method' => 'get',
'permission_mark' => 'user@create',
'component' => '',
'redirect' => '',
'hide_children_in_menu' => 1,
'keepalive' => 1,
'type' => 2,
'status' => 1,
'sort' => 1,
'created_at' => 1587461696,
'updated_at' => 1587547118,
'deleted_at' => 0,
),
2 =>
array (
'id' => 5,
'permission_name' => '保存',
'parent_id' => 2,
'level' => '1-2',
'route' => '',
'icon' => '',
'module' => 'permissions',
'creator_id' => 1,
'method' => 'get',
'permission_mark' => 'user@save',
'component' => '',
'redirect' => '',
'hide_children_in_menu' => 1,
'keepalive' => 1,
'type' => 2,
'status' => 1,
'sort' => 1,
'created_at' => 1587461721,
'updated_at' => 1591345475,
'deleted_at' => 0,
),
3 =>
array (
'id' => 6,
'permission_name' => '查看',
'parent_id' => 2,
'level' => '1-2',
'route' => '',
'icon' => '',
'module' => 'permissions',
'creator_id' => 1,
'method' => 'get',
'permission_mark' => 'user@edit',
'component' => '',
'redirect' => '',
'hide_children_in_menu' => 1,
'keepalive' => 1,
'type' => 2,
'status' => 1,
'sort' => 1,
'created_at' => 1587461742,
'updated_at' => 1591345504,
'deleted_at' => 0,
),
4 =>
array (
'id' => 7,
'permission_name' => '更新',
'parent_id' => 2,
'level' => '1-2',
'route' => '',
'icon' => '',
'module' => 'permissions',
'creator_id' => 1,
'method' => 'get',
'permission_mark' => 'user@update',
'component' => '',
'redirect' => '',
'hide_children_in_menu' => 1,
'keepalive' => 1,
'type' => 2,
'status' => 1,
'sort' => 1,
'created_at' => 1587461762,
'updated_at' => 1587547118,
'deleted_at' => 0,
),
5 =>
array (
'id' => 8,
'permission_name' => '删除',
'parent_id' => 2,
'level' => '1-2',
'route' => '',
'icon' => '',
'module' => 'permissions',
'creator_id' => 1,
'method' => 'get',
'permission_mark' => 'user@delete',
'component' => '',
'redirect' => '',
'hide_children_in_menu' => 1,
'keepalive' => 1,
'type' => 2,
'status' => 1,
'sort' => 1,
'created_at' => 1587461841,
'updated_at' => 1587547118,
'deleted_at' => 0,
),
6 =>
array (
'id' => 9,
'permission_name' => '禁用',
'parent_id' => 2,
'level' => '1-2',
'route' => '',
'icon' => '',
'module' => 'permissions',
'creator_id' => 1,
'method' => 'get',
'permission_mark' => 'user@switchStatus',
'component' => '',
'redirect' => '',
'hide_children_in_menu' => 1,
'keepalive' => 1,
'type' => 2,
'status' => 1,
'sort' => 1,
'created_at' => 1587461876,
'updated_at' => 1587547118,
'deleted_at' => 0,
),
7 =>
array (
'id' => 10,
'permission_name' => '恢复',
'parent_id' => 2,
'level' => '1-2',
'route' => '',
'icon' => '',
'module' => 'permissions',
'creator_id' => 1,
'method' => 'get',
'permission_mark' => 'user@recover',
'component' => '',
'redirect' => '',
'hide_children_in_menu' => 1,
'keepalive' => 1,
'type' => 2,
'status' => 1,
'sort' => 1,
'created_at' => 1587461901,
'updated_at' => 1587547118,
'deleted_at' => 0,
),
),
),
1 =>
array (
'id' => 11,
'permission_name' => '角色管理',
'parent_id' => 1,
'level' => '1',
'route' => '/permissions/roles',
'icon' => 'usergroup-add',
'module' => 'permissions',
'creator_id' => 1,
'method' => 'get',
'permission_mark' => 'role@index',
'component' => 'roles',
'redirect' => '',
'hide_children_in_menu' => 2,
'keepalive' => 1,
'type' => 1,
'status' => 1,
'sort' => 9,
'created_at' => 1587461939,
'updated_at' => 1592371974,
'deleted_at' => 0,
'children' =>
array (
0 =>
array (
'id' => 12,
'permission_name' => '列表',
'parent_id' => 11,
'level' => '1-11',
'route' => '',
'icon' => '',
'module' => 'permissions',
'creator_id' => 1,
'method' => 'get',
'permission_mark' => 'role@index',
'component' => '',
'redirect' => '',
'hide_children_in_menu' => 1,
'keepalive' => 1,
'type' => 2,
'status' => 1,
'sort' => 1,
'created_at' => 1587461984,
'updated_at' => 1591341461,
'deleted_at' => 0,
),
1 =>
array (
'id' => 13,
'permission_name' => '创建',
'parent_id' => 11,
'level' => '1-11',
'route' => '',
'icon' => '',
'module' => 'permissions',
'creator_id' => 1,
'method' => 'get',
'permission_mark' => 'role@create',
'component' => '',
'redirect' => '',
'hide_children_in_menu' => 1,
'keepalive' => 1,
'type' => 2,
'status' => 1,
'sort' => 1,
'created_at' => 1587462007,
'updated_at' => 1587547118,
'deleted_at' => 0,
),
2 =>
array (
'id' => 14,
'permission_name' => '保存',
'parent_id' => 11,
'level' => '1-11',
'route' => '',
'icon' => '',
'module' => 'permissions',
'creator_id' => 1,
'method' => 'get',
'permission_mark' => 'role@save',
'component' => '',
'redirect' => '',
'hide_children_in_menu' => 1,
'keepalive' => 1,
'type' => 2,
'status' => 1,
'sort' => 1,
'created_at' => 1587462021,
'updated_at' => 1587547118,
'deleted_at' => 0,
),
3 =>
array (
'id' => 15,
'permission_name' => '查看',
'parent_id' => 11,
'level' => '1-11',
'route' => '',
'icon' => '',
'module' => 'permissions',
'creator_id' => 1,
'method' => 'get',
'permission_mark' => 'role@edit',
'component' => '',
'redirect' => '',
'hide_children_in_menu' => 1,
'keepalive' => 1,
'type' => 2,
'status' => 1,
'sort' => 1,
'created_at' => 1587462040,
'updated_at' => 1587547118,
'deleted_at' => 0,
),
4 =>
array (
'id' => 16,
'permission_name' => '更新',
'parent_id' => 11,
'level' => '1-11',
'route' => '',
'icon' => '',
'module' => 'permissions',
'creator_id' => 1,
'method' => 'get',
'permission_mark' => 'role@update',
'component' => '',
'redirect' => '',
'hide_children_in_menu' => 1,
'keepalive' => 1,
'type' => 2,
'status' => 1,
'sort' => 1,
'created_at' => 1587462058,
'updated_at' => 1587547118,
'deleted_at' => 0,
),
5 =>
array (
'id' => 17,
'permission_name' => '删除',
'parent_id' => 11,
'level' => '1-11',
'route' => '',
'icon' => '',
'module' => 'permissions',
'creator_id' => 1,
'method' => 'get',
'permission_mark' => 'role@delete',
'component' => '',
'redirect' => '',
'hide_children_in_menu' => 1,
'keepalive' => 1,
'type' => 2,
'status' => 1,
'sort' => 1,
'created_at' => 1587462070,
'updated_at' => 1587547118,
'deleted_at' => 0,
),
6 =>
array (
'id' => 18,
'permission_name' => '权限获取',
'parent_id' => 11,
'level' => '1-11',
'route' => '',
'icon' => '',
'module' => 'permissions',
'creator_id' => 1,
'method' => 'get',
'permission_mark' => 'role@getPermissions',
'component' => '',
'redirect' => '',
'hide_children_in_menu' => 1,
'keepalive' => 1,
'type' => 2,
'status' => 1,
'sort' => 1,
'created_at' => 1587462094,
'updated_at' => 1587547118,
'deleted_at' => 0,
),
),
),
2 =>
array (
'id' => 19,
'permission_name' => '菜单管理',
'parent_id' => 1,
'level' => '1',
'route' => '/permissions/rules',
'icon' => 'build',
'module' => 'permissions',
'creator_id' => 1,
'method' => 'get',
'permission_mark' => 'permission@index',
'component' => 'rules',
'redirect' => '',
'hide_children_in_menu' => 2,
'keepalive' => 1,
'type' => 1,
'status' => 1,
'sort' => 8,
'created_at' => 1587462147,
'updated_at' => 1592371979,
'deleted_at' => 0,
'children' =>
array (
0 =>
array (
'id' => 20,
'permission_name' => '列表',
'parent_id' => 19,
'level' => '1-19',
'route' => '',
'icon' => '',
'module' => 'permissions',
'creator_id' => 1,
'method' => 'get',
'permission_mark' => 'permission@index',
'component' => '',
'redirect' => '',
'hide_children_in_menu' => 1,
'keepalive' => 1,
'type' => 2,
'status' => 1,
'sort' => 1,
'created_at' => 1587462205,
'updated_at' => 1587547118,
'deleted_at' => 0,
),
1 =>
array (
'id' => 21,
'permission_name' => '创建',
'parent_id' => 19,
'level' => '1-19',
'route' => '',
'icon' => '',
'module' => 'permissions',
'creator_id' => 1,
'method' => 'get',
'permission_mark' => 'permission@create',
'component' => '',
'redirect' => '',
'hide_children_in_menu' => 1,
'keepalive' => 1,
'type' => 2,
'status' => 1,
'sort' => 1,
'created_at' => 1587462232,
'updated_at' => 1587547118,
'deleted_at' => 0,
),
2 =>
array (
'id' => 22,
'permission_name' => '保存',
'parent_id' => 19,
'level' => '1-19',
'route' => '',
'icon' => '',
'module' => 'permissions',
'creator_id' => 1,
'method' => 'get',
'permission_mark' => 'permission@save',
'component' => '',
'redirect' => '',
'hide_children_in_menu' => 1,
'keepalive' => 1,
'type' => 2,
'status' => 1,
'sort' => 1,
'created_at' => 1587462250,
'updated_at' => 1587547118,
'deleted_at' => 0,
),
3 =>
array (
'id' => 23,
'permission_name' => '查看',
'parent_id' => 19,
'level' => '1-19',
'route' => '',
'icon' => '',
'module' => 'permissions',
'creator_id' => 1,
'method' => 'get',
'permission_mark' => 'permission@edit',
'component' => '',
'redirect' => '',
'hide_children_in_menu' => 1,
'keepalive' => 1,
'type' => 2,
'status' => 1,
'sort' => 1,
'created_at' => 1587462273,
'updated_at' => 1587547118,
'deleted_at' => 0,
),
4 =>
array (
'id' => 24,
'permission_name' => '更新',
'parent_id' => 19,
'level' => '1-19',
'route' => '',
'icon' => '',
'module' => 'permissions',
'creator_id' => 1,
'method' => 'get',
'permission_mark' => 'permission@update',
'component' => '',
'redirect' => '',
'hide_children_in_menu' => 1,
'keepalive' => 1,
'type' => 2,
'status' => 1,
'sort' => 1,
'created_at' => 1587462284,
'updated_at' => 1587547118,
'deleted_at' => 0,
),
5 =>
array (
'id' => 25,
'permission_name' => '删除',
'parent_id' => 19,
'level' => '1-19',
'route' => '',
'icon' => '',
'module' => 'permissions',
'creator_id' => 1,
'method' => 'get',
'permission_mark' => 'permission@delete',
'component' => '',
'redirect' => '',
'hide_children_in_menu' => 1,
'keepalive' => 1,
'type' => 2,
'status' => 1,
'sort' => 1,
'created_at' => 1587462296,
'updated_at' => 1587547118,
'deleted_at' => 0,
),
),
),
3 =>
array (
'id' => 26,
'permission_name' => '部门管理',
'parent_id' => 1,
'level' => '1',
'route' => '/permissions/departments',
'icon' => 'desktop',
'module' => 'permissions',
'creator_id' => 1,
'method' => 'get',
'permission_mark' => 'departments',
'component' => 'departments',
'redirect' => '',
'hide_children_in_menu' => 2,
'keepalive' => 1,
'type' => 1,
'status' => 1,
'sort' => 7,
'created_at' => 1587462488,
'updated_at' => 1587547118,
'deleted_at' => 0,
'children' =>
array (
0 =>
array (
'id' => 27,
'permission_name' => '列表',
'parent_id' => 26,
'level' => '1-26',
'route' => '',
'icon' => '',
'module' => 'permissions',
'creator_id' => 1,
'method' => 'get',
'permission_mark' => 'department@index',
'component' => '',
'redirect' => '',
'hide_children_in_menu' => 1,
'keepalive' => 1,
'type' => 2,
'status' => 1,
'sort' => 1,
'created_at' => 1587462529,
'updated_at' => 1587547118,
'deleted_at' => 0,
),
1 =>
array (
'id' => 28,
'permission_name' => '保存',
'parent_id' => 26,
'level' => '1-26',
'route' => '',
'icon' => '',
'module' => 'permissions',
'creator_id' => 1,
'method' => 'get',
'permission_mark' => 'department@save',
'component' => '',
'redirect' => '',
'hide_children_in_menu' => 1,
'keepalive' => 1,
'type' => 2,
'status' => 1,
'sort' => 1,
'created_at' => 1587462548,
'updated_at' => 1587547118,
'deleted_at' => 0,
),
2 =>
array (
'id' => 29,
'permission_name' => '更新',
'parent_id' => 26,
'level' => '1-26',
'route' => '',
'icon' => '',
'module' => 'permissions',
'creator_id' => 1,
'method' => 'get',
'permission_mark' => 'department@update',
'component' => '',
'redirect' => '',
'hide_children_in_menu' => 1,
'keepalive' => 1,
'type' => 2,
'status' => 1,
'sort' => 1,
'created_at' => 1587462579,
'updated_at' => 1587547118,
'deleted_at' => 0,
),
3 =>
array (
'id' => 30,
'permission_name' => '删除',
'parent_id' => 26,
'level' => '1-26',
'route' => '',
'icon' => '',
'module' => 'permissions',
'creator_id' => 1,
'method' => 'get',
'permission_mark' => 'department@delete',
'component' => '',
'redirect' => '',
'hide_children_in_menu' => 1,
'keepalive' => 1,
'type' => 2,
'status' => 1,
'sort' => 1,
'created_at' => 1587462592,
'updated_at' => 1587547118,
'deleted_at' => 0,
),
),
),
4 =>
array (
'id' => 31,
'permission_name' => '岗位管理',
'parent_id' => 1,
'level' => '1',
'route' => '/permissions/jobs',
'icon' => 'skin',
'module' => 'permissions',
'creator_id' => 1,
'method' => 'get',
'permission_mark' => 'job',
'component' => 'jobs',
'redirect' => '',
'hide_children_in_menu' => 2,
'keepalive' => 1,
'type' => 1,
'status' => 1,
'sort' => 1,
'created_at' => 1587462707,
'updated_at' => 1587547118,
'deleted_at' => 0,
'children' =>
array (
0 =>
array (
'id' => 32,
'permission_name' => '列表',
'parent_id' => 31,
'level' => '1-31',
'route' => '',
'icon' => '',
'module' => 'permissions',
'creator_id' => 1,
'method' => 'get',
'permission_mark' => 'job@index',
'component' => '',
'redirect' => '',
'hide_children_in_menu' => 1,
'keepalive' => 1,
'type' => 2,
'status' => 1,
'sort' => 1,
'created_at' => 1587462757,
'updated_at' => 1587547118,
'deleted_at' => 0,
),
1 =>
array (
'id' => 33,
'permission_name' => '保存',
'parent_id' => 31,
'level' => '1-31',
'route' => '',
'icon' => '',
'module' => 'permissions',
'creator_id' => 1,
'method' => 'get',
'permission_mark' => 'job@save',
'component' => '',
'redirect' => '',
'hide_children_in_menu' => 1,
'keepalive' => 1,
'type' => 2,
'status' => 1,
'sort' => 1,
'created_at' => 1587462774,
'updated_at' => 1587547118,
'deleted_at' => 0,
),
2 =>
array (
'id' => 34,
'permission_name' => '更新',
'parent_id' => 31,
'level' => '1-31',
'route' => '',
'icon' => '',
'module' => 'permissions',
'creator_id' => 1,
'method' => 'get',
'permission_mark' => 'job@update',
'component' => '',
'redirect' => '',
'hide_children_in_menu' => 1,
'keepalive' => 1,
'type' => 2,
'status' => 1,
'sort' => 1,
'created_at' => 1587462785,
'updated_at' => 1587547118,
'deleted_at' => 0,
),
3 =>
array (
'id' => 35,
'permission_name' => '删除',
'parent_id' => 31,
'level' => '1-31',
'route' => '',
'icon' => '',
'module' => 'permissions',
'creator_id' => 1,
'method' => 'get',
'permission_mark' => 'job@delete',
'component' => '',
'redirect' => '',
'hide_children_in_menu' => 1,
'keepalive' => 1,
'type' => 2,
'status' => 1,
'sort' => 1,
'created_at' => 1587462794,
'updated_at' => 1587547118,
'deleted_at' => 0,
),
4 =>
array (
'id' => 36,
'permission_name' => '获取全部',
'parent_id' => 31,
'level' => '1-31',
'route' => '',
'icon' => '',
'module' => 'permissions',
'creator_id' => 1,
'method' => 'get',
'permission_mark' => 'job@getAll',
'component' => '',
'redirect' => '',
'hide_children_in_menu' => 1,
'keepalive' => 1,
'type' => 2,
'status' => 1,
'sort' => 1,
'created_at' => 1587462818,
'updated_at' => 1587547118,
'deleted_at' => 0,
),
),
),
),
),
);
}
}

View File

@@ -0,0 +1,36 @@
<?php
// +----------------------------------------------------------------------
// | CatchAdmin [Just Like ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2020 http://catchadmin.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( https://github.com/yanwenwu/catch-admin/blob/master/LICENSE.txt )
// +----------------------------------------------------------------------
// | Author: JaguarJack [ njphper@gmail.com ]
// +----------------------------------------------------------------------
use think\migration\Seeder;
class RolesSeed extends Seeder
{
/**
* Run Method.
*
* Write your database seeder using this method.
*
* More information on writing seeders is available here:
* http://docs.phinx.org/en/latest/seeding.html
*/
public function run()
{
\catchAdmin\permissions\model\Roles::create([
'role_name' => '超级管理员',
'description' => 'super user',
'creator_id' => 1,
]);
\think\facade\Db::name( 'user_has_roles')->insert([
'role_id' => 1,
'uid' => 1,
]);
}
}

View File

@@ -0,0 +1,24 @@
<?php
use think\migration\Seeder;
class UsersSeed extends Seeder
{
/**
* Run Method.
*
* Write your database seeder using this method.
*
* More information on writing seeders is available here:
* http://docs.phinx.org/en/latest/seeding.html
*/
public function run()
{
return \catchAdmin\permissions\model\Users::create([
'username' => 'admin',
'password' => 'admin',
'email' => 'admin@gmail.com',
'creator_id' => 1,
]);
}
}

View File

@@ -0,0 +1,38 @@
<?php
namespace catchAdmin\permissions\event;
use catchAdmin\permissions\model\Permissions;
use catchAdmin\system\model\OperateLog;
use catcher\CatchAdmin;
use think\facade\Db;
class OperateLogEvent
{
public function handle($params)
{
$permission = $params['permission'];
$parentPermission = Permissions::where('id', $permission->parent_id)->value('permission_name');
$requestParams = request()->param();
// 如果参数过长则不记录
if (!empty($requestParams)) {
if (strlen(\json_encode($requestParams)) > 1000) {
$requestParams = [];
}
}
app(OperateLog::class)->storeBy([
'creator_id' => $params['creator_id'],
'module' => $parentPermission ? : '',
'method' => request()->method(),
'operate' => $permission->permission_name,
'route' => $permission->permission_mark,
'params' => !empty($requestParams) ? json_encode($requestParams, JSON_UNESCAPED_UNICODE) : '',
'created_at' => time(),
'ip' => request()->ip(),
]);
}
}

View File

@@ -0,0 +1,34 @@
<?php
namespace catchAdmin\permissions\middleware;
use catcher\Code;
use catcher\exceptions\FailedException;
use thans\jwt\exception\TokenBlacklistException;
use thans\jwt\exception\TokenExpiredException;
use thans\jwt\exception\TokenInvalidException;
use thans\jwt\facade\JWTAuth;
use think\Middleware;
class AuthTokenMiddleware extends Middleware
{
public function handle($request, \Closure $next)
{
try {
JWTAuth::auth();
} catch (\Exception $e) {
if ($e instanceof TokenExpiredException) {
throw new FailedException('token 过期', Code::LOGIN_EXPIRED);
}
if ($e instanceof TokenBlacklistException) {
throw new FailedException('token 被加入黑名单', Code::LOGIN_BLACKLIST);
}
if ($e instanceof TokenInvalidException) {
throw new FailedException('token 不合法', Code::LOST_LOGIN);
}
throw new FailedException('登录用户不合法', Code::LOST_LOGIN);
}
return $next($request);
}
}

View File

@@ -0,0 +1,109 @@
<?php
namespace catchAdmin\permissions\middleware;
use app\Request;
use catchAdmin\permissions\model\Permissions;
use catcher\CatchCacheKeys;
use catcher\Code;
use catcher\exceptions\PermissionForbiddenException;
use think\facade\Cache;
use catcher\Utils;
class PermissionsMiddleware
{
/**
*
* @time 2019年12月12日
* @param Request $request
* @param \Closure $next
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
* @throws PermissionForbiddenException
*/
public function handle(Request $request, \Closure $next)
{
$rule = $request->rule()->getName();
if (!$rule) {
return $next($request);
}
// 模块忽略
[$module, $controller, $action] = Utils::parseRule($rule);
// toad
if (in_array($module, $this->ignoreModule())) {
return $next($request);
}
// 用户未登录
$user = $request->user();
if (!$user) {
throw new PermissionForbiddenException('Login is invalid', Code::LOST_LOGIN);
}
// 超级管理员
if ($request->user()->id === config('catch.permissions.super_admin_id')) {
return $next($request);
}
// Get 请求
if ($request->isGet() && config('catch.permissions.is_allow_get')) {
return $next($request);
}
// 判断权限
$permission = property_exists($request, 'permission') ? $request->permission :
$this->getPermission($module, $controller, $action);
if (!$permission || !in_array($permission->id, Cache::get(CatchCacheKeys::USER_PERMISSIONS . $user->id))) {
throw new PermissionForbiddenException();
}
return $next($request);
}
/**
*
* @time 2019年12月14日
* @param $module
* @param $controllerName
* @param $action
* @param $request
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
* @return array|bool|\think\Model|null
*/
protected function getPermission($module, $controllerName, $action)
{
$permissionMark = sprintf('%s@%s', $controllerName, $action);
return Permissions::where('module', $module)->where('permission_mark', $permissionMark)->find();
}
/**
* 忽略模块
*
* @time 2020年04月16日
* @return array
*/
protected function ignoreModule()
{
return ['login'];
}
/**
* 操作日志
*
* @time 2020年04月16日
* @param $creatorId
* @param $permission
* @return void
*/
protected function operateEvent($creatorId, $permission)
{
// 操作日志
$permission && event('operateLog', [
'creator_id' => $creatorId,
'permission' => $permission,
]);
}
}

View File

@@ -0,0 +1,76 @@
<?php
namespace catchAdmin\permissions\middleware;
use app\Request;
use catchAdmin\permissions\model\Permissions;
use catcher\CatchCacheKeys;
use catcher\Code;
use catcher\exceptions\PermissionForbiddenException;
use think\facade\Cache;
use catcher\Utils;
class RecordOperateMiddleware
{
/**
*
* @time 2019年12月12日
* @param Request $request
* @param \Closure $next
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
* @throws PermissionForbiddenException
*/
public function handle(Request $request, \Closure $next)
{
$rule = $request->rule()->getName();
// 模块忽略
[$module, $controller, $action] = Utils::parseRule($rule);
$permission = $this->getPermission($module, $controller, $action);
$this->operateEvent($request->user()->id, $permission);
// 将权限带入
$request->permission = $permission;
return $next($request);
}
/**
*
* @time 2019年12月14日
* @param $module
* @param $controllerName
* @param $action
* @param $request
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
* @return array|bool|\think\Model|null
*/
protected function getPermission($module, $controllerName, $action)
{
$permissionMark = sprintf('%s@%s', $controllerName, $action);
return Permissions::where('module', $module)->where('permission_mark', $permissionMark)->find();
}
/**
* 操作日志
*
* @time 2020年04月16日
* @param $creatorId
* @param $permission
* @return void
*/
protected function operateEvent($creatorId, $permission)
{
// 操作日志
$permission && event('operateLog', [
'creator_id' => $creatorId,
'permission' => $permission,
]);
}
}

View File

@@ -0,0 +1,87 @@
<?php
namespace catchAdmin\permissions\model;
use catcher\Utils;
trait DataRangScopeTrait
{
/**
* 数据范围查询
*
* @param $roles
* @return mixed
* @author JaguarJack <njphper@gmail.com>
* @date 2020/6/6
*/
protected function dataRange($roles)
{
if (Utils::isSuperAdmin()) {
return $this;
}
$userIds = $this->getDepartmentUserIdsBy($roles);
if (empty($userIds)) {
return $this;
}
return $this->whereIn($this->aliasField('creator_id'), $userIds);
}
/**
* 获取部门IDs
*
* @param $roles
* @return array
* @author JaguarJack <njphper@gmail.com>
* @date 2020/6/6
*/
public function getDepartmentUserIdsBy($roles)
{
$userIds = [];
$isAll = false;
$user = request()->user();
foreach ($roles as $role) {
switch ($role->data_range) {
case Roles::ALL_DATA:
$isAll = true;
break;
case Roles::SELF_CHOOSE:
$departmentIds = array_merge(array_column($role->getDepartments()->toArray(), 'id'));
$userIds = array_merge($userIds, $this->getUserIdsByDepartmentId($departmentIds));
break;
case Roles::SELF_DATA:
$userIds[] = $user->id;
break;
case Roles::DEPARTMENT_DOWN_DATA:
case Roles::DEPARTMENT_DATA:
$userIds = array_merge($userIds, $this->getUserIdsByDepartmentId([$user->department_id]));
break;
default:
break;
}
// 如果有全部数据 直接跳出
if ($isAll) {
break;
}
}
return $userIds;
}
/**
* 获取UserID
*
* @time 2020年07月04日
* @param $id
* @return array
*/
protected function getUserIdsByDepartmentId(array $id)
{
return Users::whereIn('department_id', $id)->column('id');
}
}

View File

@@ -0,0 +1,44 @@
<?php
namespace catchAdmin\permissions\model;
use catchAdmin\permissions\model\search\DepartmentSearch;
use catcher\base\CatchModel;
class Department extends CatchModel
{
use DepartmentSearch;
protected $name = 'departments';
protected $field = [
'id', //
'department_name', // 部门名称
'parent_id', // 父级ID
'principal', // 负责人
'mobile', // 联系电话
'email', // 联系又想
'creator_id', // 创建人ID
'status', // 1 正常 2 停用
'sort', // 排序字段
'created_at', // 创建时间
'updated_at', // 更新时间
'deleted_at', // 删除状态null 未删除 timestamp 已删除
];
/**
* 列表数据
*
* @time 2020年01月09日
* @param $params
* @return array
* @throws \think\db\exception\DbException
*/
public function getList(): array
{
return $this->withoutField(['department_name'])
->addFields(['department_name as title'])
->catchSearch()
->catchOrder()
->select()->toArray();
}
}

View File

@@ -0,0 +1,57 @@
<?php
namespace catchAdmin\permissions\model;
trait HasDepartmentsTrait
{
/**
*
* @time 2019年12月08日
* @return mixed
*/
public function departments()
{
return $this->belongsToMany(Department::class, 'role_has_departments', 'department_id', 'role_id');
}
/**
*
* @time 2019年12月08日
* @return mixed
*/
public function getDepartments()
{
return $this->departments()->select();
}
/**
*
* @time 2019年12月08日
* @param array $departments
* @return mixed
*/
public function attachDepartments(array $departments)
{
if (empty($departments)) {
return true;
}
sort($departments);
return $this->departments()->attach($departments);
}
/**
*
* @time 2019年12月08日
* @param array $departments
* @return mixed
*/
public function detachDepartments(array $departments = [])
{
if (empty($departments)) {
return $this->departments()->detach();
}
return $this->departments()->detach($departments);
}
}

View File

@@ -0,0 +1,58 @@
<?php
namespace catchAdmin\permissions\model;
trait HasJobsTrait
{
/**
*
* @time 2019年12月08日
* @return mixed
*/
public function jobs()
{
return $this->belongsToMany(Job::class, 'user_has_jobs', 'job_id', 'uid');
}
/**
*
* @time 2019年12月08日
* @param array $fields
* @return mixed
*/
public function getJobs()
{
return $this->jobs()->select();
}
/**
*
* @time 2019年12月08日
* @param array $jobs
* @return mixed
*/
public function attachJobs(array $jobs)
{
if (empty($jobs)) {
return true;
}
sort($jobs);
return $this->jobs()->attach($jobs);
}
/**
*
* @time 2019年12月08日
* @param array $jobs
* @return mixed
*/
public function detachJobs(array $jobs = [])
{
if (empty($jobs)) {
return $this->jobs()->detach();
}
return $this->jobs()->detach($jobs);
}
}

View File

@@ -0,0 +1,76 @@
<?php
/**
* @filename HasPermissionsTrait.php
* @createdAt 2020/1/14
* @project https://github.com/yanwenwu/catch-admin
* @document http://doc.catchadmin.com
* @author JaguarJack <njphper@gmail.com>
* @copyright By CatchAdmin
* @license https://github.com/yanwenwu/catch-admin/blob/master/LICENSE.txt
*/
namespace catchAdmin\permissions\model;
trait HasPermissionsTrait
{
/**
*
* @time 2019年12月09日
* @return \think\model\relation\BelongsToMany
*/
public function permissions(): \think\model\relation\BelongsToMany
{
return $this->belongsToMany(Permissions::class, 'role_has_permissions', 'permission_id', 'role_id');
}
/**
*
* @time 2019年12月08日
* @param array $condition
* @param array $field
* @return mixed
*/
public function getPermissions($condition = [], $field = [])
{
return $this->permissions()
->when(!empty($field), function ($query) use ($field){
$query->field($field);
})
->when(!empty($condition), function ($query) use ($condition){
$query->where($condition);
})
->select();
}
/**
*
* @time 2019年12月08日
* @param array $permissions
* @return mixed
* @throws \think\db\exception\DbException
*/
public function attachPermissions(array $permissions)
{
if (empty($permissions)) {
return true;
}
sort($permissions);
return $this->permissions()->attach($permissions);
}
/**
*
* @time 2019年12月08日
* @param array $permissions
* @return mixed
*/
public function detachPermissions(array $permissions = [])
{
if (empty($permissions)) {
return $this->permissions()->detach();
}
return $this->permissions()->detach($permissions);
}
}

View File

@@ -0,0 +1,58 @@
<?php
namespace catchAdmin\permissions\model;
trait HasRolesTrait
{
/**
*
* @time 2019年12月08日
* @return mixed
*/
public function roles()
{
return $this->belongsToMany(Roles::class, 'user_has_roles', 'role_id', 'uid');
}
/**
*
* @time 2019年12月08日
* @param array $fields
* @return mixed
*/
public function getRoles()
{
return $this->roles()->select();
}
/**
*
* @time 2019年12月08日
* @param array $roles
* @return mixed
*/
public function attachRoles(array $roles)
{
if (empty($roles)) {
return true;
}
sort($roles);
return $this->roles()->attach($roles);
}
/**
*
* @time 2019年12月08日
* @param array $roles
* @return mixed
*/
public function detachRoles(array $roles = [])
{
if (empty($roles)) {
return $this->roles()->detach();
}
return $this->roles()->detach($roles);
}
}

View File

@@ -0,0 +1,39 @@
<?php
namespace catchAdmin\permissions\model;
use catchAdmin\permissions\model\search\JobsSearch;
use catcher\base\CatchModel;
class Job extends CatchModel
{
use JobsSearch;
protected $name = 'jobs';
protected $field = [
'id', //
'job_name', // 岗位名称
'coding', // 编码
'creator_id', // 创建人ID
'status', // 1 正常 2 停用
'sort', // 排序字段
'description', // 描述
'created_at', // 创建时间
'updated_at', // 更新时间
'deleted_at', // 删除状态null 未删除 timestamp 已删除
];
/**
* 列表
*
* @time 2020年01月09日
* @param $params
* @throws \think\db\exception\DbException
* @return \think\Paginator
*/
public function getList()
{
return $this->catchSearch()
->paginate();
}
}

View File

@@ -0,0 +1,104 @@
<?php
namespace catchAdmin\permissions\model;
use catchAdmin\permissions\model\search\PermissionsSearch;
use catcher\base\CatchModel;
use think\Model;
class Permissions extends CatchModel
{
use PermissionsSearch;
protected $name = 'permissions';
protected $field = [
'id', //
'permission_name', // 菜单名称
'parent_id', // 父级ID
'icon',
'component', // 组件
'redirect',
'keepalive',
'hide_children_in_menu',
'creator_id',
'status',
'module', // 模块
'route', // 路由
'method', // 请求方法
'permission_mark', // 权限标识
'type', // 1 菜单 2 按钮
'sort', // 排序字段
'created_at', // 创建时间
'updated_at', // 更新时间
'deleted_at', // 删除状态null 未删除 timestamp 已删除
];
public const MENU_TYPE = 1;
public const BTN_TYPE = 2;
public const GET = 'get';
public const POST = 'post';
public const PUT = 'put';
public const DELETE = 'delete';
public function getList($isMenu = false)
{
return $this->catchSearch()
->catchOrder()
->when($isMenu, function ($query){
$query->where('type', self::MENU_TYPE);
})
->select();
}
public function roles(): \think\model\relation\BelongsToMany
{
return $this->belongsToMany(Roles::class, 'role_has_permissions', 'role_id', 'permission_id');
}
/**
* 获取当前用户权限
*
* @time 2020年01月14日
* @param array $permissionIds
* @return \think\Collection
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\db\exception\DataNotFoundException
*/
public static function getCurrentUserPermissions(array $permissionIds): \think\Collection
{
return parent::whereIn('id', $permissionIds)
->field(['permission_name as title', 'id', 'parent_id',
'route', 'icon', 'component', 'redirect', 'module',
'keepalive as keepAlive', 'hide_children_in_menu', 'type', 'permission_mark', 'status'
])
->catchOrder()
->select();
}
/**
* 插入后回调 更新 level
*
* @time 2020年04月22日
* @param Model $model
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
* @return array|bool|Model|void|null
*/
public static function onAfterInsert(Model $model)
{
$model = self::where('id', $model->id)->find();
if ($model && $model->parent_id) {
$parent = self::where('id', $model->parent_id)->find();
$level = $parent->level ? $parent->level . '-' . $parent->id : $parent->id;
return $model->where('id', $model->id)->update([
'level' => $level
]);
}
return true;
}
}

View File

@@ -0,0 +1,52 @@
<?php
namespace catchAdmin\permissions\model;
use catchAdmin\permissions\model\search\RolesSearch;
use catcher\base\CatchModel;
class Roles extends CatchModel
{
use HasDepartmentsTrait;
use HasPermissionsTrait;
use RolesSearch;
protected $name = 'roles';
public const ALL_DATA = 1; // 全部数据
public const SELF_CHOOSE = 2; // 自定义数据
public const SELF_DATA = 3; // 本人数据
public const DEPARTMENT_DATA = 4; // 部门数据
public const DEPARTMENT_DOWN_DATA = 5; // 部门及以下数据
protected $field = [
'id', //
'role_name', // 角色名
'parent_id', // 父级ID
'creator_id', // 创建者
'data_range', // 数据范围
'description', // 角色备注
'created_at', // 创建时间
'updated_at', // 更新时间
'deleted_at', // 删除状态0未删除 >0 已删除
];
public function getList()
{
return $this->catchSearch()
->order('id', 'desc')
->select()
->toArray();
}
/**
*
* @time 2019年12月08日
* @return \think\model\relation\BelongsToMany
*/
public function users(): \think\model\relation\BelongsToMany
{
return $this->belongsToMany(Users::class, 'user_has_roles', 'uid', 'role_id');
}
}

View File

@@ -0,0 +1,110 @@
<?php
namespace catchAdmin\permissions\model;
use catchAdmin\permissions\model\search\UserSearch;
use catcher\base\CatchModel;
use catcher\exceptions\FailedException;
use catcher\Utils;
class Users extends CatchModel
{
use HasRolesTrait;
use HasJobsTrait;
use UserSearch;
protected $name = 'users';
protected $field = [
'id', //
'username', // 用户名
'password', // 用户密码
'email', // 邮箱 登录
'creator_id', // 创建者ID
'department_id', // 部门ID
'status', // 用户状态 1 正常 2 禁用
'last_login_ip', // 最后登录IP
'last_login_time', // 最后登录时间
'created_at', // 创建时间
'updated_at', // 更新时间
'deleted_at', // 删除状态0未删除 >0 已删除
];
/**
* set password
*
* @time 2019年12月07日
* @param $value
* @return false|string
*/
public function setPasswordAttr($value)
{
return password_hash($value, PASSWORD_DEFAULT);
}
/**
* 用户列表
*
* @time 2019年12月08日
* @throws \think\db\exception\DbException
* @return \think\Paginator
*/
public function getList(): \think\Paginator
{
return $this->withoutField(['updated_at'], true)
->catchSearch()
->catchLeftJoin(Department::class, 'id', 'department_id', ['department_name'])
->order($this->aliasField('id'), 'desc')
->paginate();
}
/**
* 获取权限
*
* @time 2019年12月12日
* @param $uid
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
* @return array
*/
public function getPermissionsBy($uid = 0): array
{
// 获取超级管理配置 超级管理员全部权限
if ($uid == config('catch.permissions.super_admin_id')) {
return Permissions::select()->column('id');
}
$roles = $uid ? $this->findBy($uid)->getRoles() : $this->getRoles();
$permissionIds = [];
foreach ($roles as $role) {
$permissionIds = array_merge($permissionIds, $role->getPermissions()->column('id'));
}
return array_unique($permissionIds);
}
/**
* 后台根据权限标识判断用户是否拥有某个权限
* @param string $permission_mark
* @return bool
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*
* 用法 request()->user()->can('permission@create');
*/
public function can($permission_mark)
{
// 超级管理员直接返回true
if (Utils::isSuperAdmin()){
return true;
}
// 查询当前用户的权限
return in_array(
Permissions::where('permission_mark',$permission_mark)->value('id') ? : 0,
$this->getPermissionsBy()
);
}
}

View File

@@ -0,0 +1,15 @@
<?php
namespace catchAdmin\permissions\model\search;
trait DepartmentSearch
{
public function searchDepartmentNameAttr($query, $value, $data)
{
return $query->whereLike('department_name', $value);
}
public function searchStatusAttr($query, $value, $data)
{
return $query->where('status', $value);
}
}

View File

@@ -0,0 +1,20 @@
<?php
namespace catchAdmin\permissions\model\search;
trait JobsSearch
{
public function searchJobNameAttr($query, $value, $data)
{
return $query->whereLike('job_name', $value);
}
public function searchCodingAttr($query, $value, $data)
{
return $query->whereLike('coding', $value);
}
public function searchStatusAttr($query, $value, $data)
{
return $query->where('status', $value);
}
}

View File

@@ -0,0 +1,31 @@
<?php
namespace catchAdmin\permissions\model\search;
use catchAdmin\permissions\model\Roles;
trait PermissionsSearch
{
public function searchPermissionNameAttr($query, $value, $data)
{
return $query->whereLike('permission_name', $value);
}
public function searchIdAttr($query, $value, $data)
{
$query->where('parent_id', $value)->whereOr('id', $value);
}
public function searchRoleIdAttr($query, $value, $data)
{
$permissionIds = [];
$permissions = Roles::where('id', $value)->find()->getPermissions();
foreach ($permissions as $_permission) {
$permissionIds[] = $_permission->pivot->permission_id;
}
if(!empty($permissionIds)) {
$query->whereIn('id', $permissionIds);
}
}
}

View File

@@ -0,0 +1,16 @@
<?php
namespace catchAdmin\permissions\model\search;
trait RolesSearch
{
public function searchRoleNameAttr($query, $value, $data)
{
return $query->whereLike('role_name', $value);
}
public function searchIdAttr($query, $value, $data)
{
$query->where('parent_id', $value)->whereOr('id', $value);
}
}

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