mirror of
https://gitee.com/apiadmin/ApiAdmin.git
synced 2025-06-26 18:19:16 +08:00
Compare commits
No commits in common. "v3.0.5" and "master" have entirely different histories.
1
.env
Normal file
1
.env
Normal file
@ -0,0 +1 @@
|
||||
APP_DEBUG = true
[APP]
DEFAULT_TIMEZONE = Asia/Shanghai
[DATABASE]
TYPE = mysql
HOSTNAME = 127.0.0.1
DATABASE = apiadmin
USERNAME = root
PASSWORD = 123456
HOSTPORT = 3306
CHARSET = utf8
DEBUG = true
[LANG]
default_lang = zh-cn
|
6
.gitignore
vendored
6
.gitignore
vendored
@ -1 +1,5 @@
|
||||
.idea/
|
||||
/.idea
|
||||
/.vscode
|
||||
/vendor
|
||||
*.log
|
||||
composer.lock
|
||||
|
42
.travis.yml
Normal file
42
.travis.yml
Normal file
@ -0,0 +1,42 @@
|
||||
sudo: false
|
||||
|
||||
language: php
|
||||
|
||||
branches:
|
||||
only:
|
||||
- stable
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- $HOME/.composer/cache
|
||||
|
||||
before_install:
|
||||
- composer self-update
|
||||
|
||||
install:
|
||||
- composer install --no-dev --no-interaction --ignore-platform-reqs
|
||||
- zip -r --exclude='*.git*' --exclude='*.zip' --exclude='*.travis.yml' ThinkPHP_Core.zip .
|
||||
- composer require --update-no-dev --no-interaction "topthink/think-image:^1.0"
|
||||
- composer require --update-no-dev --no-interaction "topthink/think-migration:^1.0"
|
||||
- composer require --update-no-dev --no-interaction "topthink/think-captcha:^1.0"
|
||||
- composer require --update-no-dev --no-interaction "topthink/think-mongo:^1.0"
|
||||
- composer require --update-no-dev --no-interaction "topthink/think-worker:^1.0"
|
||||
- composer require --update-no-dev --no-interaction "topthink/think-helper:^1.0"
|
||||
- composer require --update-no-dev --no-interaction "topthink/think-queue:^1.0"
|
||||
- composer require --update-no-dev --no-interaction "topthink/think-angular:^1.0"
|
||||
- composer require --dev --update-no-dev --no-interaction "topthink/think-testing:^1.0"
|
||||
- zip -r --exclude='*.git*' --exclude='*.zip' --exclude='*.travis.yml' ThinkPHP_Full.zip .
|
||||
|
||||
script:
|
||||
- php think unit
|
||||
|
||||
deploy:
|
||||
provider: releases
|
||||
api_key:
|
||||
secure: TSF6bnl2JYN72UQOORAJYL+CqIryP2gHVKt6grfveQ7d9rleAEoxlq6PWxbvTI4jZ5nrPpUcBUpWIJHNgVcs+bzLFtyh5THaLqm39uCgBbrW7M8rI26L8sBh/6nsdtGgdeQrO/cLu31QoTzbwuz1WfAVoCdCkOSZeXyT/CclH99qV6RYyQYqaD2wpRjrhA5O4fSsEkiPVuk0GaOogFlrQHx+C+lHnf6pa1KxEoN1A0UxxVfGX6K4y5g4WQDO5zT4bLeubkWOXK0G51XSvACDOZVIyLdjApaOFTwamPcD3S1tfvuxRWWvsCD5ljFvb2kSmx5BIBNwN80MzuBmrGIC27XLGOxyMerwKxB6DskNUO9PflKHDPI61DRq0FTy1fv70SFMSiAtUv9aJRT41NQh9iJJ0vC8dl+xcxrWIjU1GG6+l/ZcRqVx9V1VuGQsLKndGhja7SQ+X1slHl76fRq223sMOql7MFCd0vvvxVQ2V39CcFKao/LB1aPH3VhODDEyxwx6aXoTznvC/QPepgWsHOWQzKj9ftsgDbsNiyFlXL4cu8DWUty6rQy8zT2b4O8b1xjcwSUCsy+auEjBamzQkMJFNlZAIUrukL/NbUhQU37TAbwsFyz7X0E/u/VMle/nBCNAzgkMwAUjiHM6FqrKKBRWFbPrSIixjfjkCnrMEPw=
|
||||
file:
|
||||
- ThinkPHP_Core.zip
|
||||
- ThinkPHP_Full.zip
|
||||
skip_cleanup: true
|
||||
on:
|
||||
tags: true
|
50
DISCLAIMER.md
Normal file
50
DISCLAIMER.md
Normal file
@ -0,0 +1,50 @@
|
||||
<div align="center"><h3>ApiAdmin 开源框架法律声明与授权条款</h3></div>
|
||||
|
||||
```
|
||||
任何用户在使用由 ApiAdmin 技术开发团队(以下简称「本团队」)研发的系列框架(以下简称「ApiAdmin 通用权限开发框架」)前,请您仔细阅读并透彻理解本声明。若您一旦使用 ApiAdmin 通用权限开发框架,您的使用行为即被视为对本声明全部内容的认可和接受。
|
||||
```
|
||||
|
||||
**免责声明**
|
||||
|
||||
1. ApiAdmin 通用权限开发框架仅属于快速开发框架并不涉及具体业务应用场景,其尊重并保护所有用户的个人隐私权,不窃取任何用户计算机中的信息,更不具备用户数据存储等网络传输功能。
|
||||
|
||||
2. 任何单位或个人因下载使用 ApiAdmin 通用权限开发框架而产生的任何意外、疏忽、合约毁坏、诽谤、数据丢失、系统故障、服务中断、经济损失、商誉损害、版权或知识产权侵犯及其造成的损失 (包括但不限于直接、间接、附带或衍生的损失等),本团队不承担任何法律责任。
|
||||
|
||||
3. 任何单位或个人在阅读本免责声明后,应在开源许可证所允许的范围内进行合法的发布、传播和使用 ApiAdmin 通用权限开发框架等行为,若违反本免责声明条款或违反法律法规所造成的法律责任(包括但不限于民事赔偿和刑事责任),由违约者自行承担,本团队不承担任何法律责任。
|
||||
|
||||
4. 本团队对 ApiAdmin 通用权限开发框架拥有知识产权(包括但不限于商标权、专利权、著作权、商业秘密等),上述产品均受到相关法律法规的保护。任何单位或个人不得在未经本团队书面授权的情况下对 ApiAdmin 通用权限开发框架本身申请相关的知识产权。
|
||||
|
||||
5. 使用者必须在适用法律和法规允许的范围内正确使用 ApiAdmin,严禁将其用于非法、欺诈、恶意或侵犯他人合法权益的目的,亦不将运用于任何违反我国法律法规的平台。若发现任何未经授权或违法使用本框架的情况,我们将依据相关法律追究责任,并有权采取必要的措施予以制止。
|
||||
|
||||
6. 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动。任何基于本项目二次开发而产生的一切法律纠纷和责任,均与作者无关。
|
||||
|
||||
7. 用户明确并同意本声明条款列举的全部内容,对使用 ApiAdmin 通用权限开发框架可能存在的风险和相关后果将完全由用户自行承担,本团队不承担任何法律责任。
|
||||
|
||||
8. 如果本声明的任何部分被认为无效或不可执行,则该部分将被解释为反映本团队的初衷,其余部分仍具有完全效力。不可执行的部分声明,并不构成我们放弃执行该声明的权利。
|
||||
|
||||
|
||||
**授权条款**
|
||||
|
||||
ApiAdmin 是一个基于 .NET 构建的开源通用权限开发框架,您可以在 MIT 许可证的条款下自由地使用、复制、分发、修改和贡献此项目。这意味着您可以根据自身需求和法律要求选择更适合您的许可条款:
|
||||
|
||||
1. **MIT 许可证**:另一种选择是遵循 MIT 许可协议,详情参见 [LICENSE-MIT](https://gitee.com/apiadmin/ApiAdmin/blob/master/LICENSE)。
|
||||
|
||||
|
||||
**责任限制**
|
||||
|
||||
ApiAdmin 团队及社区成员尽力提供完善的文档和技术支持,但并不对因使用框架过程中产生的问题提供绝对的解决方案保障。所有用户提供或推荐的解决方案、代码片段、最佳实践等均“按原样”提供,使用者须自行判断并承担使用后的一切风险。
|
||||
|
||||
|
||||
**法律义务与合规性**
|
||||
|
||||
使用者在利用 ApiAdmin 开发应用程序时,负有确保其应用程序符合所有适用法律、行业标准以及信息安全规范的全部责任。使用者应自行评估并确保其产品不会滥用框架功能,尤其是防止被用于潜在有害或不道德的目的。
|
||||
|
||||
|
||||
**技术交流**
|
||||
|
||||
ApiAdmin 交流群提供的支持和资源旨在辅助开发过程,但不应视为全面的技术指导或保证。我们鼓励用户积极参与开源过程,同时也提醒用户充分测试其开发成果,确保其安全性和稳定性。
|
||||
|
||||
|
||||
**变更说明**
|
||||
|
||||
本团队有权随时对声明条款及附件内容进行单方面的变更或更新,变更或更新后立即自动生效,无需另行单独通知您或任何第三方;若您在声明内容公告变更后继续使用的,表示您已充分阅读、理解并接受修改后的声明内容。
|
204
LICENSE
204
LICENSE
@ -1,191 +1,21 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
MIT License
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
Copyright (c) 2021 Zhao
|
||||
|
||||
1. Definitions.
|
||||
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:
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction, and
|
||||
distribution as defined by Sections 1 through 9 of this document.
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
"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:
|
||||
|
||||
You must give any other recipients of the Work or Derivative Works a copy of
|
||||
this License; and
|
||||
You must cause any modified files to carry prominent notices stating that You
|
||||
changed the files; and
|
||||
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
|
||||
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 2018 Zhao
|
||||
|
||||
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.
|
||||
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.
|
||||
|
67
README.md
67
README.md
@ -3,12 +3,57 @@
|
||||
|
||||
# ApiAdmin
|
||||
[](http://www.apiadmin.org/)
|
||||
[](http://www.apiadmin.org/)
|
||||
[](http://www.apiadmin.org/)
|
||||
[](http://www.apiadmin.org/)
|
||||
[](http://www.apiadmin.org/)
|
||||
[](http://www.apiadmin.org/)
|
||||
[](http://www.apiadmin.org/)
|
||||
|
||||
|
||||
## 特别推荐
|
||||
博主新开的开源项目[EasyTiktok](https://gitee.com/apiadmin/tiktok),如果你正在做抖音开发,相信你会需要它!目前项目还是dev状态,如果你有啥意见或者遇到BUG,及时提交,我会随时关注,及时更新!
|
||||
|
||||
|
||||
## 前端页面
|
||||
ApiAdmin3.0是一个前后端完全分离的项目,前端采用Vue构建,如需要可视化配置的请移步:[ApiAdmin-WEB](https://gitee.com/apiadmin/ApiAdmin-WEB)
|
||||
ApiAdmin5.0是一个前后端完全分离的项目,前端采用Vue构建,如需要可视化配置的请移步:[ApiAdmin-WEB](https://gitee.com/apiadmin/ApiAdmin-WEB)
|
||||
|
||||
## 快速安装
|
||||
|
||||
> 第一步:安装代码
|
||||
|
||||
```
|
||||
composer create-project apiadmin/apiadmin
|
||||
```
|
||||
```
|
||||
你也可以:先获取基础代码 git clone https://gitee.com/apiadmin/ApiAdmin.git 再使用composer安装 composer install
|
||||
```
|
||||
|
||||
> 第二步:检测环境以及配置数据库
|
||||
|
||||
```
|
||||
php think apiadmin:install
|
||||
```
|
||||
|
||||
> 第三步:完成数据迁移
|
||||
|
||||
```
|
||||
php think migrate:run
|
||||
|
||||
* 如出现报错:There are no commands defined in the "migrate" namespace.
|
||||
* 请先更新下think版本:composer update topthink/framework
|
||||
* 再执行:php think migrate:run
|
||||
* 特别鸣谢:@孙晔华
|
||||
```
|
||||
|
||||
> 第四步:构建后端路由
|
||||
|
||||
```
|
||||
php think apiadmin:adminRouter
|
||||
```
|
||||
|
||||
> 第五步:获取管理后台账号密码
|
||||
|
||||
```
|
||||
cat install/lock.ini
|
||||
```
|
||||
|
||||
## 灵 感
|
||||
|
||||
@ -25,15 +70,14 @@ ApiAdmin3.0是一个前后端完全分离的项目,前端采用Vue构建,如
|
||||
|
||||
**系统需求**
|
||||
|
||||
- PHP >= 5.6
|
||||
- PHP >= 7.2.5
|
||||
- MySQL >= 5.5.3
|
||||
- Redis
|
||||
|
||||
**项目构成**
|
||||
|
||||
- ThinkPHP v5.0.11
|
||||
- Vue 2.0
|
||||
- semanticUI
|
||||
- ThinkPHP v6.0.*
|
||||
- Vue 2.*
|
||||
- ...
|
||||
|
||||
**功能简介**
|
||||
@ -44,8 +88,7 @@ ApiAdmin3.0是一个前后端完全分离的项目,前端采用Vue构建,如
|
||||
4. 灵活的参数规则设定
|
||||
5. 支持三方Api无缝融合
|
||||
6. 本地二次开发友好
|
||||
7. 使用Datatables完成数据JS加载
|
||||
8. ...
|
||||
7. ...
|
||||
|
||||
```
|
||||
ApiAdmin(PHP部分)
|
||||
@ -82,8 +125,8 @@ ApiAdmin3.0是一个前后端完全分离的项目,前端采用Vue构建,如
|
||||
|
||||
## 鸣谢
|
||||
|
||||
ApiAdmin走到今天,也正式迈入3.0时代了,同时,ApiAdmin也迎来了它的一岁生日,我们怀着激动的心情迎来这次发布。在新版本发布之际,我们真诚的感谢从1.0到2.0陪我们一路走来的朋友们。感谢你们的支持和信任!当然也感谢#开源中国#给大陆本土开源提供这样一个优秀的平台。
|
||||
ApiAdmin走到今天,也正式迈入4.1时代了,我们怀着激动的心情迎来这次发布。在新版本发布之际,我们真诚的感谢从1.0到5.0陪我们一路走来的朋友们。感谢你们的支持和信任!当然也感谢#开源中国#给大陆本土开源提供这样一个优秀的平台。
|
||||
|
||||
## 附:升级指南
|
||||
|
||||
很抱歉的告诉大家,虽然我们尽可能的和往期版本进行了兼容,但是,由于整体架构变化很大,所以想要零成本升级有点困难。我们建议大家可以使用3.0做新接口,慢慢的将2.0版本的接口移植到3.0。
|
||||
很抱歉的告诉大家,虽然我们尽可能的和往期版本进行了兼容,但是,由于整体架构变化很大,所以想要零成本升级有点困难。我们建议大家可以使用5.0做新接口,慢慢的将4.1版本的接口移植到5.0。
|
||||
|
22
app/AppService.php
Normal file
22
app/AppService.php
Normal file
@ -0,0 +1,22 @@
|
||||
<?php
|
||||
declare (strict_types = 1);
|
||||
|
||||
namespace app;
|
||||
|
||||
use think\Service;
|
||||
|
||||
/**
|
||||
* 应用服务类
|
||||
*/
|
||||
class AppService extends Service
|
||||
{
|
||||
public function register()
|
||||
{
|
||||
// 服务注册
|
||||
}
|
||||
|
||||
public function boot()
|
||||
{
|
||||
// 服务启动
|
||||
}
|
||||
}
|
94
app/BaseController.php
Normal file
94
app/BaseController.php
Normal file
@ -0,0 +1,94 @@
|
||||
<?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, '.')) {
|
||||
// 支持场景
|
||||
[$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);
|
||||
}
|
||||
|
||||
}
|
58
app/ExceptionHandle.php
Normal file
58
app/ExceptionHandle.php
Normal file
@ -0,0 +1,58 @@
|
||||
<?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
|
||||
*/
|
||||
public function render($request, Throwable $e): Response
|
||||
{
|
||||
// 添加自定义异常处理机制
|
||||
|
||||
// 其他错误交给系统处理
|
||||
return parent::render($request, $e)->header(config('apiadmin.CROSS_DOMAIN'));
|
||||
}
|
||||
}
|
8
app/Request.php
Normal file
8
app/Request.php
Normal file
@ -0,0 +1,8 @@
|
||||
<?php
|
||||
namespace app;
|
||||
|
||||
// 应用请求对象类
|
||||
class Request extends \think\Request
|
||||
{
|
||||
|
||||
}
|
26
app/command/ApiAdmin.php
Normal file
26
app/command/ApiAdmin.php
Normal file
@ -0,0 +1,26 @@
|
||||
<?php
|
||||
declare (strict_types=1);
|
||||
|
||||
namespace app\command;
|
||||
|
||||
use think\console\Command;
|
||||
use think\console\Input;
|
||||
use think\console\Output;
|
||||
|
||||
class ApiAdmin extends Command {
|
||||
protected function configure() {
|
||||
// 指令配置
|
||||
$this->setName('apiadmin:test')
|
||||
->setDescription('ApiAdmin默认命令行脚本,主要用于内部测试和研究');
|
||||
}
|
||||
|
||||
protected function execute(Input $input, Output $output): void {
|
||||
$a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
|
||||
foreach ($a as $k => &$v) {
|
||||
if ($v === 5) {
|
||||
$v = 55;
|
||||
}
|
||||
}
|
||||
dump($a);
|
||||
}
|
||||
}
|
112
app/command/AutoBuildFile.php
Normal file
112
app/command/AutoBuildFile.php
Normal file
@ -0,0 +1,112 @@
|
||||
<?php
|
||||
declare (strict_types=1);
|
||||
|
||||
namespace app\command;
|
||||
|
||||
use app\util\AutoBuild;
|
||||
use think\console\Command;
|
||||
use think\console\Input;
|
||||
use think\console\Output;
|
||||
|
||||
class AutoBuildFile extends Command {
|
||||
protected function configure() {
|
||||
// 指令配置
|
||||
$this->setName('apiadmin:autoBuild')->setDescription('ApiAdmin自动构建文件');
|
||||
}
|
||||
|
||||
/**
|
||||
* 自动构建
|
||||
* @param Input $input
|
||||
* @param Output $output
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
protected function execute(Input $input, Output $output): void {
|
||||
$config = $this->parseConfig($output);
|
||||
(new AutoBuild())->run($config);
|
||||
|
||||
$output->info('Build files successful');
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取cli配置输入
|
||||
* @param $output
|
||||
* @return array
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
private function parseConfig($output): array {
|
||||
$output->comment('Do you need to build a control? 1 or 0 (default 1)');
|
||||
$input = trim(fgets(fopen('php://stdin', 'r')));
|
||||
$dsn['control'] = strlen($input) ? $input : 1;
|
||||
|
||||
if ($dsn['control']) {
|
||||
$dsn['name'] = $this->getControlName($output);
|
||||
|
||||
$output->comment('Please choose module (1:admin;2:api, default 1):');
|
||||
$input = trim(fgets(fopen('php://stdin', 'r')));
|
||||
$dsn['module'] = strlen($input) ? $input : 1;
|
||||
|
||||
$output->comment('Do you need to build a menu? 1 or 0 (default 1):');
|
||||
$input = trim(fgets(fopen('php://stdin', 'r')));
|
||||
$dsn['menu'] = strlen($input) ? $input : 1;
|
||||
|
||||
if ($dsn['menu']) {
|
||||
$output->comment('Please input menu fid (default 0):');
|
||||
$input = trim(fgets(fopen('php://stdin', 'r')));
|
||||
$dsn['fid'] = strlen($input) ? $input : 0;
|
||||
|
||||
$output->comment('Do you need to create a route? 1 or 0 (default 0):');
|
||||
$input = trim(fgets(fopen('php://stdin', 'r')));
|
||||
$dsn['route'] = strlen($input) ? $input : 0;
|
||||
}
|
||||
}
|
||||
|
||||
$output->comment('Do you need to build a model? 1 or 0 (default 0):');
|
||||
$input = trim(fgets(fopen('php://stdin', 'r')));
|
||||
$dsn['model'] = strlen($input) ? $input : 0;
|
||||
|
||||
if ($dsn['model']) {
|
||||
$dsn['modelName'] = $this->getModelName($output);
|
||||
|
||||
$output->comment('Do you need to create a table? 1 or 0 (default 0):');
|
||||
$input = trim(fgets(fopen('php://stdin', 'r')));
|
||||
$dsn['table'] = strlen($input) ? $input : 0;
|
||||
}
|
||||
|
||||
return $dsn;
|
||||
}
|
||||
|
||||
/**
|
||||
* 递归获取控制器名称
|
||||
* @param $output
|
||||
* @return string
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
private function getModelName($output): string {
|
||||
$output->comment('Please input model name');
|
||||
$input = trim(fgets(fopen('php://stdin', 'r')));
|
||||
if ($input) {
|
||||
return $input;
|
||||
} else {
|
||||
return $this->getModelName($output);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 递归获取控制器名称
|
||||
* @param $output
|
||||
* @return string
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
private function getControlName($output): string {
|
||||
$output->comment('Please input controller name');
|
||||
$input = trim(fgets(fopen('php://stdin', 'r')));
|
||||
if ($input) {
|
||||
return $input;
|
||||
} else {
|
||||
return $this->getControlName($output);
|
||||
}
|
||||
}
|
||||
}
|
31
app/command/FreshAdminRouter.php
Normal file
31
app/command/FreshAdminRouter.php
Normal file
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
declare (strict_types=1);
|
||||
|
||||
namespace app\command;
|
||||
|
||||
use app\util\RouterTool;
|
||||
use think\console\Command;
|
||||
use think\console\Input;
|
||||
use think\console\Output;
|
||||
|
||||
class FreshAdminRouter extends Command {
|
||||
|
||||
protected function configure(): void {
|
||||
// 指令配置
|
||||
$this->setName('apiadmin:adminRouter')->setDescription('自动构建后端路由');
|
||||
}
|
||||
|
||||
/**
|
||||
* php think apiadmin:adminRouter
|
||||
* @param Input $input
|
||||
* @param Output $output
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
protected function execute(Input $input, Output $output): void {
|
||||
RouterTool::buildAdminRouter();
|
||||
$output->info('路由构建成功');
|
||||
}
|
||||
}
|
120
app/command/Install.php
Normal file
120
app/command/Install.php
Normal file
@ -0,0 +1,120 @@
|
||||
<?php
|
||||
declare (strict_types=1);
|
||||
|
||||
namespace app\command;
|
||||
|
||||
use app\util\Strs;
|
||||
use think\console\Command;
|
||||
use think\console\Input;
|
||||
use think\console\Output;
|
||||
|
||||
class Install extends Command {
|
||||
|
||||
protected function configure(): void {
|
||||
$this->setName('apiadmin:install')->setDescription('ApiAdmin安装脚本');
|
||||
}
|
||||
|
||||
/**
|
||||
* php think apiadmin:install --db mysql://root:123456@127.0.0.1:3306/apiadmin#utf8mb4
|
||||
* @param Input $input
|
||||
* @param Output $output
|
||||
* @return int|void|null
|
||||
* @throws \think\Exception
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
protected function execute(Input $input, Output $output) {
|
||||
$tplPath = root_path() . 'install' . DIRECTORY_SEPARATOR;
|
||||
$lockFile = $tplPath . 'lock.ini';
|
||||
|
||||
if (file_exists($lockFile)) {
|
||||
$output->highlight("You have already installed it, please do not reinstall!");
|
||||
$output->highlight("If necessary, delete the install/lock.ini and try again");
|
||||
exit;
|
||||
}
|
||||
|
||||
if (!is_writable($tplPath)) {
|
||||
$output->highlight($tplPath . 'cannot be modified!');
|
||||
exit;
|
||||
}
|
||||
|
||||
$tempPath = runtime_path();
|
||||
if (!is_writable($tempPath)) {
|
||||
$output->highlight($tempPath . 'cannot be modified!');
|
||||
exit;
|
||||
}
|
||||
|
||||
if (!extension_loaded('redis')) {
|
||||
$output->highlight('Redis extension missing!');
|
||||
exit;
|
||||
}
|
||||
|
||||
try {
|
||||
$options = $this->parseDsnConfig($output);
|
||||
$dsn = "{$options['type']}:dbname={$options['database']};host={$options['hostname']};port={$options['hostport']};charset={$options['charset']}";
|
||||
new \PDO($dsn, $options['username'], $options['password']);
|
||||
|
||||
//处理数据库配置文件
|
||||
$dbConf = str_replace([
|
||||
'{$DB_TYPE}', '{$DB_HOST}', '{$DB_NAME}',
|
||||
'{$DB_USER}', '{$DB_PASSWORD}', '{$DB_PORT}',
|
||||
'{$DB_CHAR}'
|
||||
], [
|
||||
$options['type'], $options['hostname'], $options['database'],
|
||||
$options['username'], $options['password'], $options['hostport'],
|
||||
$options['charset']
|
||||
], file_get_contents($tplPath . 'db.tpl'));
|
||||
file_put_contents(root_path() . '.env', $dbConf);
|
||||
$output->info('Database configuration updated successfully');
|
||||
|
||||
//处理ApiAdmin自定义配置
|
||||
$authKey = substr(Strs::uuid(), 1, -1);
|
||||
$apiConf = str_replace('{$AUTH_KEY}', $authKey, file_get_contents($tplPath . 'apiadmin.tpl'));
|
||||
file_put_contents(config_path() . 'apiadmin.php', $apiConf);
|
||||
$output->info('ApiAdmin configuration updated successfully');
|
||||
|
||||
//生成lock文件,并且写入用户名密码
|
||||
file_put_contents($lockFile, $authKey);
|
||||
$output->info('Lock file initialization successful');
|
||||
} catch (\PDOException $e) {
|
||||
$output->highlight($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* DSN解析
|
||||
* @param $output
|
||||
* @return array
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
private function parseDsnConfig($output): array {
|
||||
$output->comment('please input database type(default mysql):');
|
||||
$input = trim(fgets(fopen('php://stdin', 'r')));
|
||||
$dsn['type'] = $input ? $input : 'mysql';
|
||||
|
||||
$output->comment('please input database username(default root):');
|
||||
$input = trim(fgets(fopen('php://stdin', 'r')));
|
||||
$dsn['username'] = $input ? $input : 'root';
|
||||
|
||||
$output->comment('please input database password(default 123456):');
|
||||
$input = trim(fgets(fopen('php://stdin', 'r')));
|
||||
$dsn['password'] = $input ? $input : '123456';
|
||||
|
||||
$output->comment('please input database host(default 127.0.0.1):');
|
||||
$input = trim(fgets(fopen('php://stdin', 'r')));
|
||||
$dsn['hostname'] = $input ? $input : '127.0.0.1';
|
||||
|
||||
$output->comment('please input database port(default 3306):');
|
||||
$input = trim(fgets(fopen('php://stdin', 'r')));
|
||||
$dsn['hostport'] = $input ? $input : '3306';
|
||||
|
||||
$output->comment('please input database name(default apiadmin):');
|
||||
$input = trim(fgets(fopen('php://stdin', 'r')));
|
||||
$dsn['database'] = $input ? $input : 'apiadmin';
|
||||
|
||||
$output->comment('please input database charset(default utf8mb4):');
|
||||
$input = trim(fgets(fopen('php://stdin', 'r')));
|
||||
$dsn['charset'] = $input ? $input : 'utf8mb4';
|
||||
|
||||
return $dsn;
|
||||
}
|
||||
}
|
2
app/common.php
Normal file
2
app/common.php
Normal file
@ -0,0 +1,2 @@
|
||||
<?php
|
||||
// 应用公共文件
|
@ -1,12 +1,12 @@
|
||||
<?php
|
||||
declare (strict_types=1);
|
||||
/**
|
||||
* 应用管理
|
||||
* @since 2018-02-11
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
|
||||
namespace app\admin\controller;
|
||||
|
||||
namespace app\controller\admin;
|
||||
|
||||
use app\model\AdminApp;
|
||||
use app\model\AdminList;
|
||||
@ -14,65 +14,64 @@ use app\model\AdminGroup;
|
||||
use app\util\ReturnCode;
|
||||
use app\util\Strs;
|
||||
use app\util\Tools;
|
||||
use think\Response;
|
||||
|
||||
class App extends Base {
|
||||
|
||||
/**
|
||||
* 获取应用列表
|
||||
* @return array
|
||||
* @throws \think\exception\DbException
|
||||
* @return Response
|
||||
* @throws \think\db\exception\DbException
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function index() {
|
||||
|
||||
$limit = $this->request->get('size', config('apiAdmin.ADMIN_LIST_DEFAULT'));
|
||||
$start = $limit * ($this->request->get('page', 1) - 1);
|
||||
public function index(): Response {
|
||||
$limit = $this->request->get('size', config('apiadmin.ADMIN_LIST_DEFAULT'));
|
||||
$start = $this->request->get('page', 1);
|
||||
$keywords = $this->request->get('keywords', '');
|
||||
$type = $this->request->get('type', '');
|
||||
$status = $this->request->get('status', '');
|
||||
|
||||
$where = [];
|
||||
if ($status === '1' || $status === '0') {
|
||||
$where['app_status'] = $status;
|
||||
$obj = new AdminApp();
|
||||
if (strlen($status)) {
|
||||
$obj = $obj->where('app_status', $status);
|
||||
}
|
||||
if ($type) {
|
||||
switch ($type) {
|
||||
case 1:
|
||||
$where['app_id'] = $keywords;
|
||||
$obj = $obj->where('app_id', $keywords);
|
||||
break;
|
||||
case 2:
|
||||
$where['app_name'] = ['like', "%{$keywords}%"];
|
||||
$obj = $obj->whereLike('app_name', "%{$keywords}%");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$listInfo = (new AdminApp())->where($where)->order('app_addTime', 'DESC')->limit($start, $limit)->select();
|
||||
$count = (new AdminApp())->where($where)->count();
|
||||
$listInfo = Tools::buildArrFromObj($listInfo);
|
||||
$listObj = $obj->order('app_add_time', 'DESC')->paginate(['page' => $start, 'list_rows' => $limit])->toArray();
|
||||
|
||||
return $this->buildSuccess([
|
||||
'list' => $listInfo,
|
||||
'count' => $count
|
||||
'list' => $listObj['data'],
|
||||
'count' => $listObj['total']
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取AppId,AppSecret,接口列表,应用接口权限细节
|
||||
* @return Response
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
* @return array
|
||||
* @throws \think\Exception
|
||||
* @throws \think\exception\DbException
|
||||
*/
|
||||
public function getAppInfo() {
|
||||
$apiArr = AdminList::all();
|
||||
public function getAppInfo(): Response {
|
||||
$apiArr = (new AdminList())->select();
|
||||
foreach ($apiArr as $api) {
|
||||
$res['apiList'][$api['groupHash']][] = $api;
|
||||
$res['apiList'][$api['group_hash']][] = $api;
|
||||
}
|
||||
$groupArr = AdminGroup::all();
|
||||
$groupArr = (new AdminGroup())->select();
|
||||
$groupArr = Tools::buildArrFromObj($groupArr);
|
||||
$res['groupInfo'] = array_column($groupArr, 'name', 'hash');
|
||||
$id = $this->request->get('id', 0);
|
||||
if ($id) {
|
||||
$appInfo = AdminApp::get($id)->toArray();
|
||||
$appInfo = (new AdminApp())->where('id', $id)->find()->toArray();
|
||||
$res['app_detail'] = json_decode($appInfo['app_api_show'], true);
|
||||
} else {
|
||||
$res['app_id'] = mt_rand(1, 9) . Strs::randString(7, 1);
|
||||
@ -83,11 +82,22 @@ class App extends Base {
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增应用
|
||||
* @return array
|
||||
* 刷新APPSecret
|
||||
* @return Response
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function add() {
|
||||
public function refreshAppSecret(): Response {
|
||||
$data['app_secret'] = Strs::randString(32);
|
||||
|
||||
return $this->buildSuccess($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增应用
|
||||
* @return Response
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function add(): Response {
|
||||
$postData = $this->request->post();
|
||||
$data = [
|
||||
'app_id' => $postData['app_id'],
|
||||
@ -95,9 +105,9 @@ class App extends Base {
|
||||
'app_name' => $postData['app_name'],
|
||||
'app_info' => $postData['app_info'],
|
||||
'app_group' => $postData['app_group'],
|
||||
'app_addTime' => time(),
|
||||
'app_add_time' => time(),
|
||||
'app_api' => '',
|
||||
'app_api_show' => '',
|
||||
'app_api_show' => ''
|
||||
];
|
||||
if (isset($postData['app_api']) && $postData['app_api']) {
|
||||
$appApi = [];
|
||||
@ -109,45 +119,56 @@ class App extends Base {
|
||||
}
|
||||
$res = AdminApp::create($data);
|
||||
if ($res === false) {
|
||||
return $this->buildFailed(ReturnCode::DB_SAVE_ERROR, '操作失败');
|
||||
} else {
|
||||
return $this->buildSuccess([]);
|
||||
return $this->buildFailed(ReturnCode::DB_SAVE_ERROR);
|
||||
}
|
||||
|
||||
return $this->buildSuccess();
|
||||
}
|
||||
|
||||
/**
|
||||
* 应用状态编辑
|
||||
* @return array
|
||||
* @return Response
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function changeStatus() {
|
||||
public function changeStatus(): Response {
|
||||
$id = $this->request->get('id');
|
||||
$status = $this->request->get('status');
|
||||
$res = AdminApp::update([
|
||||
'id' => $id,
|
||||
'app_status' => $status
|
||||
], [
|
||||
'id' => $id
|
||||
]);
|
||||
if ($res === false) {
|
||||
return $this->buildFailed(ReturnCode::DB_SAVE_ERROR, '操作失败');
|
||||
} else {
|
||||
return $this->buildSuccess([]);
|
||||
return $this->buildFailed(ReturnCode::DB_SAVE_ERROR);
|
||||
}
|
||||
$appInfo = (new AdminApp())->where('id', $id)->find();
|
||||
cache('AccessToken:Easy:' . $appInfo['app_secret'], null);
|
||||
if ($oldWiki = cache('WikiLogin:' . $id)) {
|
||||
cache('WikiLogin:' . $oldWiki, null);
|
||||
}
|
||||
|
||||
return $this->buildSuccess();
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑应用
|
||||
* @return array
|
||||
* @return Response
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function edit() {
|
||||
public function edit(): Response {
|
||||
$postData = $this->request->post();
|
||||
$data = [
|
||||
'app_secret' => $postData['app_secret'],
|
||||
'app_name' => $postData['app_name'],
|
||||
'app_info' => $postData['app_info'],
|
||||
'app_group' => $postData['app_group'],
|
||||
'app_api' => '',
|
||||
'app_api_show' => '',
|
||||
'app_api_show' => ''
|
||||
];
|
||||
if (isset($postData['app_api']) && $postData['app_api']) {
|
||||
$appApi = [];
|
||||
@ -159,24 +180,39 @@ class App extends Base {
|
||||
}
|
||||
$res = AdminApp::update($data, ['id' => $postData['id']]);
|
||||
if ($res === false) {
|
||||
return $this->buildFailed(ReturnCode::DB_SAVE_ERROR, '操作失败');
|
||||
} else {
|
||||
return $this->buildSuccess([]);
|
||||
return $this->buildFailed(ReturnCode::DB_SAVE_ERROR);
|
||||
}
|
||||
$appInfo = (new AdminApp())->where('id', $postData['id'])->find();
|
||||
cache('AccessToken:Easy:' . $appInfo['app_secret'], null);
|
||||
if ($oldWiki = cache('WikiLogin:' . $postData['id'])) {
|
||||
cache('WikiLogin:' . $oldWiki, null);
|
||||
}
|
||||
|
||||
return $this->buildSuccess();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除应用
|
||||
* @return array
|
||||
* @return Response
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function del() {
|
||||
public function del(): Response {
|
||||
$id = $this->request->get('id');
|
||||
if (!$id) {
|
||||
return $this->buildFailed(ReturnCode::EMPTY_PARAMS, '缺少必要参数');
|
||||
}
|
||||
AdminApp::destroy($id);
|
||||
$appInfo = (new AdminApp())->where('id', $id)->find();
|
||||
cache('AccessToken:Easy:' . $appInfo['app_secret'], null);
|
||||
|
||||
return $this->buildSuccess([]);
|
||||
AdminApp::destroy($id);
|
||||
if ($oldWiki = cache('WikiLogin:' . $id)) {
|
||||
cache('WikiLogin:' . $oldWiki, null);
|
||||
}
|
||||
|
||||
return $this->buildSuccess();
|
||||
}
|
||||
}
|
@ -1,67 +1,66 @@
|
||||
<?php
|
||||
declare (strict_types=1);
|
||||
/**
|
||||
*
|
||||
* @since 2018-02-11
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
|
||||
namespace app\admin\controller;
|
||||
|
||||
namespace app\controller\admin;
|
||||
|
||||
use app\model\AdminApp;
|
||||
use app\model\AdminAppGroup;
|
||||
use app\util\ReturnCode;
|
||||
use app\util\Tools;
|
||||
use think\Response;
|
||||
|
||||
class AppGroup extends Base {
|
||||
|
||||
/**
|
||||
* 获取应用组列表
|
||||
* @return \think\Response
|
||||
* @throws \think\db\exception\DbException
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
* @return array
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @throws \think\exception\DbException
|
||||
*/
|
||||
public function index() {
|
||||
$limit = $this->request->get('size', config('apiAdmin.ADMIN_LIST_DEFAULT'));
|
||||
$start = $limit * ($this->request->get('page', 1) - 1);
|
||||
public function index(): Response {
|
||||
$limit = $this->request->get('size', config('apiadmin.ADMIN_LIST_DEFAULT'));
|
||||
$start = $this->request->get('page', 1);
|
||||
$keywords = $this->request->get('keywords', '');
|
||||
$type = $this->request->get('type', '');
|
||||
$status = $this->request->get('status', '');
|
||||
|
||||
$where = [];
|
||||
if ($status === '1' || $status === '0') {
|
||||
$where['status'] = $status;
|
||||
$obj = new AdminAppGroup();
|
||||
if (strlen($status)) {
|
||||
$obj = $obj->where('status', $status);
|
||||
}
|
||||
if ($type) {
|
||||
switch ($type) {
|
||||
case 1:
|
||||
$where['hash'] = $keywords;
|
||||
if (strlen($keywords)) {
|
||||
$obj = $obj->where('hash', $keywords);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
$where['name'] = ['like', "%{$keywords}%"];
|
||||
$obj = $obj->whereLike('name', "%{$keywords}%");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$listInfo = (new AdminAppGroup())->where($where)->limit($start, $limit)->select();
|
||||
$count = (new AdminAppGroup())->where($where)->count();
|
||||
$listInfo = Tools::buildArrFromObj($listInfo);
|
||||
$listObj = $obj->paginate(['page' => $start, 'list_rows' => $limit])->toArray();
|
||||
|
||||
return $this->buildSuccess([
|
||||
'list' => $listInfo,
|
||||
'count' => $count
|
||||
'list' => $listObj['data'],
|
||||
'count' => $listObj['total']
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取全部有效的应用组
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
* @return Response
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @throws \think\exception\DbException
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function getAll() {
|
||||
public function getAll(): Response {
|
||||
$listInfo = (new AdminAppGroup())->where(['status' => 1])->select();
|
||||
|
||||
return $this->buildSuccess([
|
||||
@ -71,60 +70,59 @@ class AppGroup extends Base {
|
||||
|
||||
/**
|
||||
* 应用组状态编辑
|
||||
* @return array
|
||||
* @return Response
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function changeStatus() {
|
||||
public function changeStatus(): Response {
|
||||
$id = $this->request->get('id');
|
||||
$status = $this->request->get('status');
|
||||
$res = AdminAppGroup::update([
|
||||
'id' => $id,
|
||||
'status' => $status
|
||||
], [
|
||||
'id' => $id
|
||||
]);
|
||||
if ($res === false) {
|
||||
return $this->buildFailed(ReturnCode::DB_SAVE_ERROR, '操作失败');
|
||||
} else {
|
||||
return $this->buildSuccess([]);
|
||||
return $this->buildFailed(ReturnCode::DB_SAVE_ERROR);
|
||||
}
|
||||
|
||||
return $this->buildSuccess();
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加应用组
|
||||
* @return Response
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
* @return array
|
||||
*/
|
||||
public function add() {
|
||||
public function add(): Response {
|
||||
$postData = $this->request->post();
|
||||
$res = AdminAppGroup::create($postData);
|
||||
if ($res === false) {
|
||||
return $this->buildFailed(ReturnCode::DB_SAVE_ERROR, '操作失败');
|
||||
} else {
|
||||
return $this->buildSuccess([]);
|
||||
return $this->buildFailed(ReturnCode::DB_SAVE_ERROR);
|
||||
}
|
||||
|
||||
return $this->buildSuccess();
|
||||
}
|
||||
|
||||
/**
|
||||
* 应用组编辑
|
||||
* @return Response
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
* @return array
|
||||
*/
|
||||
public function edit() {
|
||||
public function edit(): Response {
|
||||
$postData = $this->request->post();
|
||||
$res = AdminAppGroup::update($postData);
|
||||
if ($res === false) {
|
||||
return $this->buildFailed(ReturnCode::DB_SAVE_ERROR, '操作失败');
|
||||
} else {
|
||||
return $this->buildSuccess([]);
|
||||
return $this->buildFailed(ReturnCode::DB_SAVE_ERROR);
|
||||
}
|
||||
|
||||
return $this->buildSuccess();
|
||||
}
|
||||
|
||||
/**
|
||||
* 应用组删除
|
||||
* @return Response
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
* @return array
|
||||
*/
|
||||
public function del() {
|
||||
public function del(): Response {
|
||||
$hash = $this->request->get('hash');
|
||||
if (!$hash) {
|
||||
return $this->buildFailed(ReturnCode::EMPTY_PARAMS, '缺少必要参数');
|
||||
@ -137,6 +135,6 @@ class AppGroup extends Base {
|
||||
|
||||
AdminAppGroup::destroy(['hash' => $hash]);
|
||||
|
||||
return $this->buildSuccess([]);
|
||||
return $this->buildSuccess();
|
||||
}
|
||||
}
|
277
app/controller/admin/Auth.php
Normal file
277
app/controller/admin/Auth.php
Normal file
@ -0,0 +1,277 @@
|
||||
<?php
|
||||
declare (strict_types=1);
|
||||
/**
|
||||
* 权限相关配置
|
||||
* @since 2018-02-06
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
|
||||
namespace app\controller\admin;
|
||||
|
||||
use app\model\AdminAuthGroup;
|
||||
use app\model\AdminAuthGroupAccess;
|
||||
use app\model\AdminAuthRule;
|
||||
use app\model\AdminMenu;
|
||||
use app\util\ReturnCode;
|
||||
use app\util\Tools;
|
||||
use think\Response;
|
||||
|
||||
class Auth extends Base {
|
||||
|
||||
/**
|
||||
* 获取权限组列表
|
||||
* @return Response
|
||||
* @throws \think\db\exception\DbException
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function index(): Response {
|
||||
$limit = $this->request->get('size', config('apiadmin.ADMIN_LIST_DEFAULT'));
|
||||
$start = $this->request->get('page', 1);
|
||||
$keywords = $this->request->get('keywords', '');
|
||||
$status = $this->request->get('status', '');
|
||||
|
||||
$obj = new AdminAuthGroup();
|
||||
if (strlen($status)) {
|
||||
$obj = $obj->where('status', $status);
|
||||
}
|
||||
if ($keywords) {
|
||||
$obj = $obj->whereLike('name', "%{$keywords}%");
|
||||
}
|
||||
|
||||
$listObj = $obj->order('id', 'DESC')->paginate(['page' => $start, 'list_rows' => $limit])->toArray();
|
||||
|
||||
return $this->buildSuccess([
|
||||
'list' => $listObj['data'],
|
||||
'count' => $listObj['total']
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取全部已开放的可选组
|
||||
* @return Response
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function getGroups(): Response {
|
||||
$listInfo = (new AdminAuthGroup())->where(['status' => 1])->order('id', 'DESC')->select();
|
||||
$count = count($listInfo);
|
||||
$listInfo = Tools::buildArrFromObj($listInfo);
|
||||
|
||||
return $this->buildSuccess([
|
||||
'list' => $listInfo,
|
||||
'count' => $count
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取组所在权限列表
|
||||
* @return Response
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function getRuleList(): Response {
|
||||
$groupId = $this->request->get('group_id', 0);
|
||||
|
||||
$list = (new AdminMenu)->order('sort', 'ASC')->select();
|
||||
$list = Tools::buildArrFromObj($list);
|
||||
$list = Tools::listToTree($list);
|
||||
|
||||
$rules = [];
|
||||
if ($groupId) {
|
||||
$rules = (new AdminAuthRule())->where(['group_id' => $groupId])->select();
|
||||
$rules = Tools::buildArrFromObj($rules);
|
||||
$rules = array_column($rules, 'url');
|
||||
}
|
||||
$newList = $this->buildList($list, $rules);
|
||||
|
||||
return $this->buildSuccess([
|
||||
'list' => $newList
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增组
|
||||
* @return Response
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function add(): Response {
|
||||
$res = AdminAuthGroup::create([
|
||||
'name' => $this->request->post('name', ''),
|
||||
'description' => $this->request->post('description', '')
|
||||
]);
|
||||
if ($res === false) {
|
||||
return $this->buildFailed(ReturnCode::DB_SAVE_ERROR);
|
||||
}
|
||||
|
||||
return $this->buildSuccess();
|
||||
}
|
||||
|
||||
/**
|
||||
* 权限组状态编辑
|
||||
* @return Response
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function changeStatus(): Response {
|
||||
$id = $this->request->get('id');
|
||||
$status = $this->request->get('status');
|
||||
$res = AdminAuthGroup::update([
|
||||
'id' => $id,
|
||||
'status' => $status
|
||||
]);
|
||||
if ($res === false) {
|
||||
return $this->buildFailed(ReturnCode::DB_SAVE_ERROR);
|
||||
}
|
||||
|
||||
return $this->buildSuccess();
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑用户
|
||||
* @return Response
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function edit(): Response {
|
||||
$res = AdminAuthGroup::update([
|
||||
'id' => $this->request->post('id', 0),
|
||||
'name' => $this->request->post('name', ''),
|
||||
'description' => $this->request->post('description', '')
|
||||
]);
|
||||
if ($res === false) {
|
||||
return $this->buildFailed(ReturnCode::DB_SAVE_ERROR);
|
||||
}
|
||||
|
||||
return $this->buildSuccess();
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除组
|
||||
* @return Response
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function del(): Response {
|
||||
$id = $this->request->get('id');
|
||||
if (!$id) {
|
||||
return $this->buildFailed(ReturnCode::EMPTY_PARAMS, '缺少必要参数');
|
||||
}
|
||||
|
||||
$listInfo = (new AdminAuthGroupAccess())->where('find_in_set("' . $id . '", `group_id`)')->select();
|
||||
if ($listInfo) {
|
||||
foreach ($listInfo as $value) {
|
||||
$oldGroupArr = explode(',', $value->group_id);
|
||||
$key = array_search($id, $oldGroupArr);
|
||||
unset($oldGroupArr[$key]);
|
||||
$newData = implode(',', $oldGroupArr);
|
||||
$value->group_id = $newData;
|
||||
$value->save();
|
||||
}
|
||||
}
|
||||
|
||||
AdminAuthGroup::destroy($id);
|
||||
AdminAuthRule::destroy(['group_id' => $id]);
|
||||
|
||||
return $this->buildSuccess();
|
||||
}
|
||||
|
||||
/**
|
||||
* 从指定组中删除指定用户
|
||||
* @return Response
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function delMember(): Response {
|
||||
$gid = $this->request->get('gid', 0);
|
||||
$uid = $this->request->get('uid', 0);
|
||||
if (!$gid || !$uid) {
|
||||
return $this->buildFailed(ReturnCode::EMPTY_PARAMS, '缺少必要参数');
|
||||
}
|
||||
$oldInfo = (new AdminAuthGroupAccess())->where('uid', $uid)->find()->toArray();
|
||||
$oldGroupArr = explode(',', $oldInfo['group_id']);
|
||||
$key = array_search($gid, $oldGroupArr);
|
||||
unset($oldGroupArr[$key]);
|
||||
$newData = implode(',', $oldGroupArr);
|
||||
$res = AdminAuthGroupAccess::update([
|
||||
'group_id' => $newData
|
||||
], [
|
||||
'uid' => $uid
|
||||
]);
|
||||
if ($res === false) {
|
||||
return $this->buildFailed(ReturnCode::DB_SAVE_ERROR);
|
||||
}
|
||||
|
||||
return $this->buildSuccess();
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建适用前端的权限数据
|
||||
* @param $list
|
||||
* @param $rules
|
||||
* @return array
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
private function buildList($list, $rules): array {
|
||||
$newList = [];
|
||||
foreach ($list as $key => $value) {
|
||||
$newList[$key]['title'] = $value['title'];
|
||||
$newList[$key]['key'] = $value['url'];
|
||||
if (isset($value['children'])) {
|
||||
$newList[$key]['expand'] = true;
|
||||
$newList[$key]['children'] = $this->buildList($value['children'], $rules);
|
||||
} else {
|
||||
if (in_array($value['url'], $rules)) {
|
||||
$newList[$key]['checked'] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $newList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑权限细节
|
||||
* @return Response
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function editRule(): Response {
|
||||
$id = $this->request->post('id', 0);
|
||||
$rules = $this->request->post('rules', []);
|
||||
if (is_array($rules)) {
|
||||
$needAdd = [];
|
||||
$has = (new AdminAuthRule())->where(['group_id' => $id])->select();
|
||||
$has = Tools::buildArrFromObj($has);
|
||||
$hasRule = array_column($has, 'url');
|
||||
$needDel = array_flip($hasRule);
|
||||
foreach ($rules as $key => $value) {
|
||||
if (!empty($value)) {
|
||||
if (!in_array($value, $hasRule)) {
|
||||
$data['url'] = $value;
|
||||
$data['group_id'] = $id;
|
||||
$needAdd[] = $data;
|
||||
} else {
|
||||
unset($needDel[$value]);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (count($needAdd)) {
|
||||
(new AdminAuthRule())->saveAll($needAdd);
|
||||
}
|
||||
if (count($needDel)) {
|
||||
$urlArr = array_keys($needDel);
|
||||
(new AdminAuthRule())->whereIn('url', $urlArr)->where('group_id', $id)->delete();
|
||||
}
|
||||
}
|
||||
|
||||
return $this->buildSuccess();
|
||||
}
|
||||
}
|
105
app/controller/admin/Base.php
Normal file
105
app/controller/admin/Base.php
Normal file
@ -0,0 +1,105 @@
|
||||
<?php
|
||||
declare (strict_types=1);
|
||||
/**
|
||||
* 工程基类
|
||||
* @since 2017/02/28 创建
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
|
||||
namespace app\controller\admin;
|
||||
|
||||
use app\model\AdminUser;
|
||||
use app\model\AdminUserData;
|
||||
use app\util\ReturnCode;
|
||||
use app\BaseController;
|
||||
use think\App;
|
||||
use think\facade\Env;
|
||||
use think\Response;
|
||||
|
||||
class Base extends BaseController {
|
||||
|
||||
private $debug = [];
|
||||
protected $userInfo;
|
||||
|
||||
public function __construct(App $app) {
|
||||
parent::__construct($app);
|
||||
$this->userInfo = $this->request->API_ADMIN_USER_INFO;
|
||||
}
|
||||
|
||||
/**
|
||||
* 成功的返回
|
||||
* @param array $data
|
||||
* @param string $msg
|
||||
* @param int $code
|
||||
* @return Response
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function buildSuccess(array $data = [], string $msg = '操作成功', int $code = ReturnCode::SUCCESS): Response {
|
||||
$return = [
|
||||
'code' => $code,
|
||||
'msg' => $msg,
|
||||
'data' => $data
|
||||
];
|
||||
if (Env::get('APP_DEBUG') && $this->debug) {
|
||||
$return['debug'] = $this->debug;
|
||||
}
|
||||
|
||||
return json($return);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新用户信息
|
||||
* @param array $data
|
||||
* @param bool $isDetail
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function updateUserInfo(array $data, bool $isDetail = false): void {
|
||||
$apiAuth = $this->request->header('Api-Auth');
|
||||
if ($isDetail) {
|
||||
AdminUserData::update($data, ['uid' => $this->userInfo['id']]);
|
||||
$this->userInfo['userData'] = (new AdminUserData())->where('uid', $this->userInfo['id'])->find();
|
||||
} else {
|
||||
AdminUser::update($data, ['id' => $this->userInfo['id']]);
|
||||
$detail = $this->userInfo['userData'];
|
||||
$this->userInfo = (new AdminUser())->where('id', $this->userInfo['id'])->find();
|
||||
$this->userInfo['userData'] = $detail;
|
||||
}
|
||||
|
||||
cache('Login:' . $apiAuth, json_encode($this->userInfo), config('apiadmin.ONLINE_TIME'));
|
||||
}
|
||||
|
||||
/**
|
||||
* 错误的返回
|
||||
* @param int $code
|
||||
* @param string $msg
|
||||
* @param array $data
|
||||
* @return Response
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function buildFailed(int $code, string $msg = '操作失败', array $data = []): Response {
|
||||
$return = [
|
||||
'code' => $code,
|
||||
'msg' => $msg,
|
||||
'data' => $data
|
||||
];
|
||||
if (Env::get('APP_DEBUG') && $this->debug) {
|
||||
$return['debug'] = $this->debug;
|
||||
}
|
||||
|
||||
return json($return);
|
||||
}
|
||||
|
||||
/**
|
||||
* debug参数收集
|
||||
* @param $data
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
protected function debug($data): void {
|
||||
if ($data) {
|
||||
$this->debug[] = $data;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,21 +1,23 @@
|
||||
<?php
|
||||
declare (strict_types=1);
|
||||
/**
|
||||
* 接口输入输出字段维护
|
||||
* @since 2018-02-21
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
|
||||
namespace app\admin\controller;
|
||||
|
||||
namespace app\controller\admin;
|
||||
|
||||
use app\model\AdminFields;
|
||||
use app\model\AdminList;
|
||||
use app\util\DataType;
|
||||
use app\util\ReturnCode;
|
||||
use app\util\Tools;
|
||||
use think\Response;
|
||||
|
||||
class Fields extends Base {
|
||||
private $dataType = array(
|
||||
|
||||
private $dataType = [
|
||||
DataType::TYPE_INTEGER => 'Integer',
|
||||
DataType::TYPE_STRING => 'String',
|
||||
DataType::TYPE_BOOLEAN => 'Boolean',
|
||||
@ -25,75 +27,82 @@ class Fields extends Base {
|
||||
DataType::TYPE_MOBILE => 'Mobile',
|
||||
DataType::TYPE_OBJECT => 'Object',
|
||||
DataType::TYPE_ARRAY => 'Array'
|
||||
);
|
||||
];
|
||||
|
||||
public function index() {
|
||||
/**
|
||||
* @return Response
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function index(): Response {
|
||||
return $this->buildSuccess($this->dataType);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取请求参数
|
||||
* @return Response
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @throws \think\exception\DbException
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function request() {
|
||||
$limit = $this->request->get('size', config('apiAdmin.ADMIN_LIST_DEFAULT'));
|
||||
$start = $limit * ($this->request->get('page', 1) - 1);
|
||||
public function request(): Response {
|
||||
$limit = $this->request->get('size', config('apiadmin.ADMIN_LIST_DEFAULT'));
|
||||
$start = $this->request->get('page', 1);
|
||||
$hash = $this->request->get('hash', '');
|
||||
|
||||
if (!empty($hash)) {
|
||||
$listInfo = (new AdminFields())->where(['hash' => $hash, 'type' => 0])->limit($start, $limit)->select();
|
||||
$count = (new AdminFields())->where(['hash' => $hash, 'type' => 0])->count();
|
||||
$listInfo = Tools::buildArrFromObj($listInfo);
|
||||
|
||||
return $this->buildSuccess([
|
||||
'list' => $listInfo,
|
||||
'count' => $count,
|
||||
'dataType' => $this->dataType
|
||||
]);
|
||||
} else {
|
||||
if (empty($hash)) {
|
||||
return $this->buildFailed(ReturnCode::EMPTY_PARAMS, '缺少必要参数');
|
||||
}
|
||||
$listObj = (new AdminFields())->where('hash', $hash)->where('type', 0)
|
||||
->paginate(['page' => $start, 'list_rows' => $limit])->toArray();
|
||||
|
||||
$apiInfo = (new AdminList())->where('hash', $hash)->find();
|
||||
|
||||
return $this->buildSuccess([
|
||||
'list' => $listObj['data'],
|
||||
'count' => $listObj['total'],
|
||||
'dataType' => $this->dataType,
|
||||
'apiInfo' => $apiInfo
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取返回参数
|
||||
* @return array
|
||||
* @return Response
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @throws \think\exception\DbException
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function response() {
|
||||
$limit = $this->request->get('size', config('apiAdmin.ADMIN_LIST_DEFAULT'));
|
||||
$start = $limit * ($this->request->get('page', 1) - 1);
|
||||
public function response(): Response {
|
||||
$limit = $this->request->get('size', config('apiadmin.ADMIN_LIST_DEFAULT'));
|
||||
$start = $this->request->get('page', 1);
|
||||
$hash = $this->request->get('hash', '');
|
||||
|
||||
if (!empty($hash)) {
|
||||
$listInfo = (new AdminFields())->where(['hash' => $hash, 'type' => 1])->limit($start, $limit)->select();
|
||||
$count = (new AdminFields())->where(['hash' => $hash, 'type' => 1])->count();
|
||||
$listInfo = Tools::buildArrFromObj($listInfo);
|
||||
|
||||
return $this->buildSuccess([
|
||||
'list' => $listInfo,
|
||||
'count' => $count,
|
||||
'dataType' => $this->dataType
|
||||
]);
|
||||
} else {
|
||||
if (empty($hash)) {
|
||||
return $this->buildFailed(ReturnCode::EMPTY_PARAMS, '缺少必要参数');
|
||||
}
|
||||
$listObj = (new AdminFields())->where('hash', $hash)->where('type', 1)
|
||||
->paginate(['page' => $start, 'list_rows' => $limit])->toArray();
|
||||
|
||||
$apiInfo = (new AdminList())->where('hash', $hash)->find();
|
||||
|
||||
return $this->buildSuccess([
|
||||
'list' => $listObj['data'],
|
||||
'count' => $listObj['total'],
|
||||
'dataType' => $this->dataType,
|
||||
'apiInfo' => $apiInfo
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增字段
|
||||
* @return Response
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
* @return array
|
||||
*/
|
||||
public function add() {
|
||||
public function add(): Response {
|
||||
$postData = $this->request->post();
|
||||
$postData['showName'] = $postData['fieldName'];
|
||||
$postData['show_name'] = $postData['field_name'];
|
||||
$postData['default'] = $postData['defaults'];
|
||||
unset($postData['defaults']);
|
||||
$res = AdminFields::create($postData);
|
||||
@ -103,20 +112,20 @@ class Fields extends Base {
|
||||
cache('ResponseFieldsRule:' . $postData['hash'], null);
|
||||
|
||||
if ($res === false) {
|
||||
return $this->buildFailed(ReturnCode::DB_SAVE_ERROR, '操作失败');
|
||||
} else {
|
||||
return $this->buildSuccess('操作成功');
|
||||
return $this->buildFailed(ReturnCode::DB_SAVE_ERROR);
|
||||
}
|
||||
|
||||
return $this->buildSuccess();
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段编辑
|
||||
* @return Response
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
* @return array
|
||||
*/
|
||||
public function edit() {
|
||||
public function edit(): Response {
|
||||
$postData = $this->request->post();
|
||||
$postData['showName'] = $postData['fieldName'];
|
||||
$postData['show_name'] = $postData['field_name'];
|
||||
$postData['default'] = $postData['defaults'];
|
||||
unset($postData['defaults']);
|
||||
$res = AdminFields::update($postData);
|
||||
@ -126,43 +135,45 @@ class Fields extends Base {
|
||||
cache('ResponseFieldsRule:' . $postData['hash'], null);
|
||||
|
||||
if ($res === false) {
|
||||
return $this->buildFailed(ReturnCode::DB_SAVE_ERROR, '操作失败');
|
||||
} else {
|
||||
return $this->buildSuccess([]);
|
||||
return $this->buildFailed(ReturnCode::DB_SAVE_ERROR);
|
||||
}
|
||||
|
||||
return $this->buildSuccess();
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段删除
|
||||
* @return Response
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
* @return array
|
||||
* @throws \think\exception\DbException
|
||||
*/
|
||||
public function del() {
|
||||
public function del(): Response {
|
||||
$id = $this->request->get('id');
|
||||
if (!$id) {
|
||||
return $this->buildFailed(ReturnCode::EMPTY_PARAMS, '缺少必要参数');
|
||||
}
|
||||
|
||||
$fieldsInfo = AdminFields::get($id);
|
||||
$fieldsInfo = (new AdminFields())->where('id', $id)->find();
|
||||
cache('RequestFields:NewRule:' . $fieldsInfo->hash, null);
|
||||
cache('RequestFields:Rule:' . $fieldsInfo->hash, null);
|
||||
cache('ResponseFieldsRule:' . $fieldsInfo->hash, null);
|
||||
|
||||
AdminFields::destroy($id);
|
||||
|
||||
return $this->buildSuccess([]);
|
||||
return $this->buildSuccess();
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量上传返回字段
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
* @return array
|
||||
* @return Response
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @throws \think\exception\DbException
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function upload() {
|
||||
public function upload(): Response {
|
||||
$hash = $this->request->post('hash');
|
||||
$type = $this->request->post('type');
|
||||
$jsonStr = $this->request->post('jsonStr');
|
||||
@ -171,24 +182,22 @@ class Fields extends Base {
|
||||
if ($data === null) {
|
||||
return $this->buildFailed(ReturnCode::EXCEPTION, 'JSON数据格式有误');
|
||||
}
|
||||
AdminList::update(['returnStr' => json_encode($data)], ['hash' => $hash]);
|
||||
AdminList::update(['return_str' => json_encode($data)], ['hash' => $hash]);
|
||||
$this->handle($data['data'], $dataArr);
|
||||
$old = (new AdminFields())->where([
|
||||
'hash' => $hash,
|
||||
'type' => $type
|
||||
])->select();
|
||||
$old = (new AdminFields())->where('hash', $hash)->where('type', $type)->select();
|
||||
$old = Tools::buildArrFromObj($old);
|
||||
$oldArr = array_column($old, 'showName');
|
||||
$newArr = array_column($dataArr, 'showName');
|
||||
$oldArr = array_column($old, 'show_name');
|
||||
$newArr = array_column($dataArr, 'show_name');
|
||||
$addArr = array_diff($newArr, $oldArr);
|
||||
$delArr = array_diff($oldArr, $newArr);
|
||||
if ($delArr) {
|
||||
AdminFields::destroy(['showName' => ['in', $delArr]]);
|
||||
$delArr = array_values($delArr);
|
||||
(new AdminFields())->whereIn('show_name', $delArr)->delete();
|
||||
}
|
||||
if ($addArr) {
|
||||
$addData = [];
|
||||
foreach ($dataArr as $item) {
|
||||
if (in_array($item['showName'], $addArr)) {
|
||||
if (in_array($item['show_name'], $addArr)) {
|
||||
$addData[] = $item;
|
||||
}
|
||||
}
|
||||
@ -199,56 +208,63 @@ class Fields extends Base {
|
||||
cache('RequestFields:Rule:' . $hash, null);
|
||||
cache('ResponseFieldsRule:' . $hash, null);
|
||||
|
||||
return $this->buildSuccess([]);
|
||||
return $this->buildSuccess();
|
||||
}
|
||||
|
||||
private function handle($data, &$dataArr, $prefix = 'data', $index = 'data') {
|
||||
/**
|
||||
* @param $data
|
||||
* @param $dataArr
|
||||
* @param string $prefix
|
||||
* @param string $index
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
private function handle(array $data, &$dataArr, string $prefix = 'data', string $index = 'data'): void {
|
||||
if (!$this->isAssoc($data)) {
|
||||
$addArr = array(
|
||||
'fieldName' => $index,
|
||||
'showName' => $prefix,
|
||||
'hash' => $this->request->post('hash'),
|
||||
'isMust' => 1,
|
||||
'dataType' => DataType::TYPE_ARRAY,
|
||||
'type' => $this->request->post('type')
|
||||
);
|
||||
$addArr = [
|
||||
'field_name' => $index,
|
||||
'show_name' => $prefix,
|
||||
'hash' => $this->request->post('hash'),
|
||||
'is_must' => 1,
|
||||
'data_type' => DataType::TYPE_ARRAY,
|
||||
'type' => $this->request->post('type')
|
||||
];
|
||||
$dataArr[] = $addArr;
|
||||
$prefix .= '[]';
|
||||
if (is_array($data[0])) {
|
||||
if (isset($data[0]) && is_array($data[0])) {
|
||||
$this->handle($data[0], $dataArr, $prefix);
|
||||
}
|
||||
} else {
|
||||
$addArr = array(
|
||||
'fieldName' => $index,
|
||||
'showName' => $prefix,
|
||||
'hash' => $this->request->post('hash'),
|
||||
'isMust' => 1,
|
||||
'dataType' => DataType::TYPE_OBJECT,
|
||||
'type' => $this->request->post('type')
|
||||
);
|
||||
$addArr = [
|
||||
'field_name' => $index,
|
||||
'show_name' => $prefix,
|
||||
'hash' => $this->request->post('hash'),
|
||||
'is_must' => 1,
|
||||
'data_type' => DataType::TYPE_OBJECT,
|
||||
'type' => $this->request->post('type')
|
||||
];
|
||||
$dataArr[] = $addArr;
|
||||
$prefix .= '{}';
|
||||
foreach ($data as $index => $datum) {
|
||||
$myPre = $prefix . $index;
|
||||
$addArr = array(
|
||||
'fieldName' => $index,
|
||||
'showName' => $myPre,
|
||||
'hash' => $this->request->post('hash'),
|
||||
'isMust' => 1,
|
||||
'dataType' => DataType::TYPE_STRING,
|
||||
'type' => $this->request->post('type')
|
||||
'field_name' => $index,
|
||||
'show_name' => $myPre,
|
||||
'hash' => $this->request->post('hash'),
|
||||
'is_must' => 1,
|
||||
'data_type' => DataType::TYPE_STRING,
|
||||
'type' => $this->request->post('type')
|
||||
);
|
||||
if (is_numeric($datum)) {
|
||||
if (preg_match('/^\d*$/', $datum)) {
|
||||
$addArr['dataType'] = DataType::TYPE_INTEGER;
|
||||
$addArr['data_type'] = DataType::TYPE_INTEGER;
|
||||
} else {
|
||||
$addArr['dataType'] = DataType::TYPE_FLOAT;
|
||||
$addArr['data_type'] = DataType::TYPE_FLOAT;
|
||||
}
|
||||
$dataArr[] = $addArr;
|
||||
} elseif (is_array($datum)) {
|
||||
$this->handle($datum, $dataArr, $myPre, $index);
|
||||
} else {
|
||||
$addArr['dataType'] = DataType::TYPE_STRING;
|
||||
$addArr['data_type'] = DataType::TYPE_STRING;
|
||||
$dataArr[] = $addArr;
|
||||
}
|
||||
}
|
||||
@ -258,10 +274,10 @@ class Fields extends Base {
|
||||
/**
|
||||
* 判断是否是关联数组(true表示是关联数组)
|
||||
* @param array $arr
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
* @return bool
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
private function isAssoc(array $arr) {
|
||||
private function isAssoc(array $arr): bool {
|
||||
if (array() === $arr) return false;
|
||||
|
||||
return array_keys($arr) !== range(0, count($arr) - 1);
|
@ -1,16 +1,14 @@
|
||||
<?php
|
||||
declare (strict_types=1);
|
||||
|
||||
namespace app\admin\controller;
|
||||
|
||||
namespace app\controller\admin;
|
||||
|
||||
use app\util\ReturnCode;
|
||||
use think\Response;
|
||||
|
||||
class Index extends Base {
|
||||
public function index() {
|
||||
return json(['welcome']);
|
||||
}
|
||||
|
||||
public function upload() {
|
||||
public function upload(): Response {
|
||||
$path = '/upload/' . date('Ymd', time()) . '/';
|
||||
$name = $_FILES['file']['name'];
|
||||
$tmp_name = $_FILES['file']['tmp_name'];
|
||||
@ -18,19 +16,19 @@ class Index extends Base {
|
||||
//过滤错误
|
||||
if ($error) {
|
||||
switch ($error) {
|
||||
case 1 :
|
||||
case 1:
|
||||
$error_message = '您上传的文件超过了PHP.INI配置文件中UPLOAD_MAX-FILESIZE的大小';
|
||||
break;
|
||||
case 2 :
|
||||
case 2:
|
||||
$error_message = '您上传的文件超过了PHP.INI配置文件中的post_max_size的大小';
|
||||
break;
|
||||
case 3 :
|
||||
case 3:
|
||||
$error_message = '文件只被部分上传';
|
||||
break;
|
||||
case 4 :
|
||||
case 4:
|
||||
$error_message = '文件不能为空';
|
||||
break;
|
||||
default :
|
||||
default:
|
||||
$error_message = '未知错误';
|
||||
}
|
||||
die($error_message);
|
@ -1,68 +1,65 @@
|
||||
<?php
|
||||
declare (strict_types=1);
|
||||
/**
|
||||
* 接口组维护
|
||||
* @since 2018-02-11
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
|
||||
namespace app\admin\controller;
|
||||
|
||||
namespace app\controller\admin;
|
||||
|
||||
use app\model\AdminApp;
|
||||
use app\model\AdminGroup;
|
||||
use app\model\AdminList;
|
||||
use app\util\ReturnCode;
|
||||
use app\util\Tools;
|
||||
use think\Response;
|
||||
|
||||
class InterfaceGroup extends Base {
|
||||
|
||||
/**
|
||||
* 获取接口组列表
|
||||
* @return Response
|
||||
* @throws \think\db\exception\DbException
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
* @return array
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @throws \think\exception\DbException
|
||||
*/
|
||||
public function index() {
|
||||
$limit = $this->request->get('size', config('apiAdmin.ADMIN_LIST_DEFAULT'));
|
||||
$start = $limit * ($this->request->get('page', 1) - 1);
|
||||
public function index(): Response {
|
||||
$limit = $this->request->get('size', config('apiadmin.ADMIN_LIST_DEFAULT'));
|
||||
$start = $this->request->get('page', 1);
|
||||
$keywords = $this->request->get('keywords', '');
|
||||
$type = $this->request->get('type', '');
|
||||
$status = $this->request->get('status', '');
|
||||
|
||||
$where = [];
|
||||
if ($status === '1' || $status === '0') {
|
||||
$where['status'] = $status;
|
||||
$obj = new AdminGroup();
|
||||
if (strlen($status)) {
|
||||
$obj = $obj->where('status', $status);
|
||||
}
|
||||
if ($type) {
|
||||
switch ($type) {
|
||||
case 1:
|
||||
$where['hash'] = $keywords;
|
||||
$obj = $obj->where('hash', $keywords);
|
||||
break;
|
||||
case 2:
|
||||
$where['name'] = ['like', "%{$keywords}%"];
|
||||
$obj = $obj->whereLike('name', "%{$keywords}%");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$listInfo = (new AdminGroup())->where($where)->limit($start, $limit)->select();
|
||||
$count = (new AdminGroup())->where($where)->count();
|
||||
$listInfo = Tools::buildArrFromObj($listInfo);
|
||||
$listObj = $obj->order('create_time', 'desc')->paginate(['page' => $start, 'list_rows' => $limit])->toArray();
|
||||
|
||||
return $this->buildSuccess([
|
||||
'list' => $listInfo,
|
||||
'count' => $count
|
||||
'list' => $listObj['data'],
|
||||
'count' => $listObj['total']
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取全部有效的接口组
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
* @return Response
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @throws \think\exception\DbException
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function getAll() {
|
||||
public function getAll(): Response {
|
||||
$listInfo = (new AdminGroup())->where(['status' => 1])->select();
|
||||
|
||||
return $this->buildSuccess([
|
||||
@ -72,63 +69,62 @@ class InterfaceGroup extends Base {
|
||||
|
||||
/**
|
||||
* 接口组状态编辑
|
||||
* @return array
|
||||
* @return Response
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function changeStatus() {
|
||||
public function changeStatus(): Response {
|
||||
$id = $this->request->get('id');
|
||||
$status = $this->request->get('status');
|
||||
$res = AdminGroup::update([
|
||||
'status' => $status
|
||||
], [
|
||||
'id' => $id
|
||||
'id' => $id,
|
||||
'status' => $status,
|
||||
]);
|
||||
if ($res === false) {
|
||||
return $this->buildFailed(ReturnCode::DB_SAVE_ERROR, '操作失败');
|
||||
} else {
|
||||
return $this->buildSuccess([]);
|
||||
return $this->buildFailed(ReturnCode::DB_SAVE_ERROR);
|
||||
}
|
||||
|
||||
return $this->buildSuccess();
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加接口组
|
||||
* @return Response
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
* @return array
|
||||
*/
|
||||
public function add() {
|
||||
public function add(): Response {
|
||||
$postData = $this->request->post();
|
||||
$postData['addTime'] = $postData['updateTime'] = time();
|
||||
$res = AdminGroup::create($postData);
|
||||
if ($res === false) {
|
||||
return $this->buildFailed(ReturnCode::DB_SAVE_ERROR, '操作失败');
|
||||
} else {
|
||||
return $this->buildSuccess([]);
|
||||
return $this->buildFailed(ReturnCode::DB_SAVE_ERROR);
|
||||
}
|
||||
|
||||
return $this->buildSuccess();
|
||||
}
|
||||
|
||||
/**
|
||||
* 接口组编辑
|
||||
* @return Response
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
* @return array
|
||||
*/
|
||||
public function edit() {
|
||||
public function edit(): Response {
|
||||
$postData = $this->request->post();
|
||||
$postData['updateTime'] = time();
|
||||
$res = AdminGroup::update($postData);
|
||||
if ($res === false) {
|
||||
return $this->buildFailed(ReturnCode::DB_SAVE_ERROR, '操作失败');
|
||||
} else {
|
||||
return $this->buildSuccess([]);
|
||||
return $this->buildFailed(ReturnCode::DB_SAVE_ERROR);
|
||||
}
|
||||
|
||||
return $this->buildSuccess();
|
||||
}
|
||||
|
||||
/**
|
||||
* 接口组删除
|
||||
* @return array
|
||||
* @throws \think\exception\DbException
|
||||
* @return Response
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function del() {
|
||||
public function del(): Response {
|
||||
$hash = $this->request->get('hash');
|
||||
if (!$hash) {
|
||||
return $this->buildFailed(ReturnCode::EMPTY_PARAMS, '缺少必要参数');
|
||||
@ -137,11 +133,8 @@ class InterfaceGroup extends Base {
|
||||
return $this->buildFailed(ReturnCode::INVALID, '系统预留关键数据,禁止删除!');
|
||||
}
|
||||
|
||||
AdminList::update(['groupHash' => 'default'], ['groupHash' => $hash]);
|
||||
|
||||
$hashRule = AdminApp::all([
|
||||
'app_api_show' => ['like', "%$hash%"]
|
||||
]);
|
||||
AdminList::update(['group_hash' => 'default'], ['group_hash' => $hash]);
|
||||
$hashRule = (new AdminApp())->whereLike('app_api_show', "%$hash%")->select();
|
||||
if ($hashRule) {
|
||||
foreach ($hashRule as $rule) {
|
||||
$appApiShowArr = json_decode($rule->app_api_show, true);
|
||||
@ -160,6 +153,6 @@ class InterfaceGroup extends Base {
|
||||
|
||||
AdminGroup::destroy(['hash' => $hash]);
|
||||
|
||||
return $this->buildSuccess([]);
|
||||
return $this->buildSuccess();
|
||||
}
|
||||
}
|
201
app/controller/admin/InterfaceList.php
Normal file
201
app/controller/admin/InterfaceList.php
Normal file
@ -0,0 +1,201 @@
|
||||
<?php
|
||||
declare (strict_types=1);
|
||||
/**
|
||||
* 接口管理
|
||||
* @since 2018-02-11
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
|
||||
namespace app\controller\admin;
|
||||
|
||||
use app\model\AdminApp;
|
||||
use app\model\AdminFields;
|
||||
use app\model\AdminList;
|
||||
use app\util\ReturnCode;
|
||||
use think\facade\Env;
|
||||
use think\Response;
|
||||
|
||||
class InterfaceList extends Base {
|
||||
|
||||
/**
|
||||
* 获取接口列表
|
||||
* @return Response
|
||||
* @throws \think\db\exception\DbException
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function index(): Response {
|
||||
$limit = $this->request->get('size', config('apiadmin.ADMIN_LIST_DEFAULT'));
|
||||
$start = $this->request->get('page', 1);
|
||||
$keywords = $this->request->get('keywords', '');
|
||||
$type = $this->request->get('type', '');
|
||||
$status = $this->request->get('status', '');
|
||||
|
||||
$obj = new AdminList();
|
||||
if (strlen($status)) {
|
||||
$obj = $obj->where('status', $status);
|
||||
}
|
||||
if ($type) {
|
||||
switch ($type) {
|
||||
case 1:
|
||||
$obj = $obj->where('hash', $keywords);
|
||||
break;
|
||||
case 2:
|
||||
$obj = $obj->whereLike('info', "%{$keywords}%");
|
||||
break;
|
||||
case 3:
|
||||
$obj = $obj->whereLike('api_class', "%{$keywords}%");
|
||||
break;
|
||||
}
|
||||
}
|
||||
$listObj = $obj->order('id', 'DESC')->paginate(['page' => $start, 'list_rows' => $limit])->toArray();
|
||||
|
||||
return $this->buildSuccess([
|
||||
'list' => $listObj['data'],
|
||||
'count' => $listObj['total']
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取接口唯一标识
|
||||
* @return Response
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function getHash(): Response {
|
||||
$res['hash'] = uniqid();
|
||||
|
||||
return $this->buildSuccess($res);
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增接口
|
||||
* @return Response
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function add(): Response {
|
||||
$postData = $this->request->post();
|
||||
if (!preg_match("/^[A-Za-z0-9_\/]+$/", $postData['api_class'])) {
|
||||
return $this->buildFailed(ReturnCode::DB_SAVE_ERROR, '真实类名只允许填写字母,数字和/');
|
||||
}
|
||||
|
||||
$res = AdminList::create($postData);
|
||||
if ($res === false) {
|
||||
return $this->buildFailed(ReturnCode::DB_SAVE_ERROR);
|
||||
}
|
||||
|
||||
return $this->buildSuccess();
|
||||
}
|
||||
|
||||
/**
|
||||
* 接口状态编辑
|
||||
* @return Response
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function changeStatus(): Response {
|
||||
$hash = $this->request->get('hash');
|
||||
$status = $this->request->get('status');
|
||||
$res = AdminList::update([
|
||||
'status' => $status
|
||||
], [
|
||||
'hash' => $hash
|
||||
]);
|
||||
if ($res === false) {
|
||||
return $this->buildFailed(ReturnCode::DB_SAVE_ERROR);
|
||||
}
|
||||
cache('ApiInfo:' . $hash, null);
|
||||
|
||||
return $this->buildSuccess();
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑接口
|
||||
* @return Response
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function edit(): Response {
|
||||
$postData = $this->request->post();
|
||||
if (!preg_match("/^[A-Za-z0-9_\/]+$/", $postData['api_class'])) {
|
||||
return $this->buildFailed(ReturnCode::DB_SAVE_ERROR, '真实类名只允许填写字母,数字和/');
|
||||
}
|
||||
|
||||
$res = AdminList::update($postData);
|
||||
if ($res === false) {
|
||||
return $this->buildFailed(ReturnCode::DB_SAVE_ERROR);
|
||||
}
|
||||
cache('ApiInfo:' . $postData['hash'], null);
|
||||
|
||||
return $this->buildSuccess();
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除接口
|
||||
* @return Response
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function del(): Response {
|
||||
$hash = $this->request->get('hash');
|
||||
if (!$hash) {
|
||||
return $this->buildFailed(ReturnCode::EMPTY_PARAMS, '缺少必要参数');
|
||||
}
|
||||
|
||||
$hashRule = (new AdminApp())->whereLike('app_api', "%$hash%")->select();
|
||||
if ($hashRule) {
|
||||
$oldInfo = (new AdminList())->where('hash', $hash)->find();
|
||||
foreach ($hashRule as $rule) {
|
||||
$appApiArr = explode(',', $rule->app_api);
|
||||
$appApiIndex = array_search($hash, $appApiArr);
|
||||
array_splice($appApiArr, $appApiIndex, 1);
|
||||
$rule->app_api = implode(',', $appApiArr);
|
||||
|
||||
$appApiShowArrOld = json_decode($rule->app_api_show, true);
|
||||
$appApiShowArr = $appApiShowArrOld[$oldInfo->group_hash];
|
||||
$appApiShowIndex = array_search($hash, $appApiShowArr);
|
||||
array_splice($appApiShowArr, $appApiShowIndex, 1);
|
||||
$appApiShowArrOld[$oldInfo->group_hash] = $appApiShowArr;
|
||||
$rule->app_api_show = json_encode($appApiShowArrOld);
|
||||
|
||||
$rule->save();
|
||||
}
|
||||
}
|
||||
|
||||
AdminList::destroy(['hash' => $hash]);
|
||||
AdminFields::destroy(['hash' => $hash]);
|
||||
|
||||
cache('ApiInfo:' . $hash, null);
|
||||
|
||||
return $this->buildSuccess();
|
||||
}
|
||||
|
||||
/**
|
||||
* 刷新接口路由
|
||||
* @return Response
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function refresh(): Response {
|
||||
$rootPath = root_path();
|
||||
$apiRoutePath = $rootPath . 'route/apiRoute.php';
|
||||
$tplPath = $rootPath . 'install/apiRoute.tpl';
|
||||
$methodArr = ['*', 'POST', 'GET'];
|
||||
|
||||
$tplOriginStr = file_get_contents($tplPath);
|
||||
$listInfo = (new AdminList())->where('status', 1)->select();
|
||||
$tplStr = [];
|
||||
foreach ($listInfo as $value) {
|
||||
if ($value['hash_type'] === 1) {
|
||||
array_push($tplStr, 'Route::rule(\'' . addslashes($value->api_class) . '\',\'api.' . addslashes($value->api_class) . '\', \'' . $methodArr[$value->method] . '\')->middleware([app\middleware\ApiAuth::class, app\middleware\ApiPermission::class, app\middleware\RequestFilter::class, app\middleware\ApiLog::class]);');
|
||||
} else {
|
||||
array_push($tplStr, 'Route::rule(\'' . addslashes($value->hash) . '\',\'api.' . addslashes($value->api_class) . '\', \'' . $methodArr[$value->method] . '\')->middleware([app\middleware\ApiAuth::class, app\middleware\ApiPermission::class, app\middleware\RequestFilter::class, app\middleware\ApiLog::class]);');
|
||||
}
|
||||
}
|
||||
$tplOriginStr = str_replace(['{$API_RULE}'], [implode(PHP_EOL . ' ', $tplStr)], $tplOriginStr);
|
||||
|
||||
file_put_contents($apiRoutePath, $tplOriginStr);
|
||||
|
||||
return $this->buildSuccess();
|
||||
}
|
||||
}
|
65
app/controller/admin/Log.php
Normal file
65
app/controller/admin/Log.php
Normal file
@ -0,0 +1,65 @@
|
||||
<?php
|
||||
declare (strict_types=1);
|
||||
/**
|
||||
* 后台操作日志管理
|
||||
* @since 2018-02-06
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
|
||||
namespace app\controller\admin;
|
||||
|
||||
use app\model\AdminUserAction;
|
||||
use app\util\ReturnCode;
|
||||
use think\Response;
|
||||
|
||||
class Log extends Base {
|
||||
|
||||
/**
|
||||
* 获取操作日志列表
|
||||
* @return Response
|
||||
* @throws \think\db\exception\DbException
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function index(): Response {
|
||||
$limit = $this->request->get('size', config('apiadmin.ADMIN_LIST_DEFAULT'));
|
||||
$start = $this->request->get('page', 1);
|
||||
$type = $this->request->get('type', '');
|
||||
$keywords = $this->request->get('keywords', '');
|
||||
|
||||
$obj = new AdminUserAction();
|
||||
if ($type) {
|
||||
switch ($type) {
|
||||
case 1:
|
||||
$obj = $obj->whereLike('url', "%{$keywords}%");
|
||||
break;
|
||||
case 2:
|
||||
$obj = $obj->whereLike('nickname', "%{$keywords}%");
|
||||
break;
|
||||
case 3:
|
||||
$obj = $obj->where('uid', $keywords);
|
||||
break;
|
||||
}
|
||||
}
|
||||
$listObj = $obj->order('add_time', 'DESC')->paginate(['page' => $start, 'list_rows' => $limit])->toArray();
|
||||
|
||||
return $this->buildSuccess([
|
||||
'list' => $listObj['data'],
|
||||
'count' => $listObj['total']
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除日志
|
||||
* @return Response
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function del(): Response {
|
||||
$id = $this->request->get('id');
|
||||
if (!$id) {
|
||||
return $this->buildFailed(ReturnCode::EMPTY_PARAMS, '缺少必要参数');
|
||||
}
|
||||
AdminUserAction::destroy($id);
|
||||
|
||||
return $this->buildSuccess();
|
||||
}
|
||||
}
|
173
app/controller/admin/Login.php
Normal file
173
app/controller/admin/Login.php
Normal file
@ -0,0 +1,173 @@
|
||||
<?php
|
||||
declare (strict_types=1);
|
||||
/**
|
||||
* 登录登出
|
||||
* @since 2017-11-02
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
|
||||
namespace app\controller\admin;
|
||||
|
||||
use app\model\AdminAuthGroupAccess;
|
||||
use app\model\AdminAuthRule;
|
||||
use app\model\AdminMenu;
|
||||
use app\model\AdminUser;
|
||||
use app\model\AdminUserData;
|
||||
use app\util\ReturnCode;
|
||||
use app\util\RouterTool;
|
||||
use app\util\Tools;
|
||||
use think\Response;
|
||||
|
||||
class Login extends Base {
|
||||
|
||||
/**
|
||||
* 用户登录【账号密码登录】
|
||||
* @return Response
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function index(): Response {
|
||||
$username = $this->request->post('username');
|
||||
$password = $this->request->post('password');
|
||||
if (!$username) {
|
||||
return $this->buildFailed(ReturnCode::LOGIN_ERROR, '缺少用户名!');
|
||||
}
|
||||
if (!$password) {
|
||||
return $this->buildFailed(ReturnCode::LOGIN_ERROR, '缺少密码!');
|
||||
} else {
|
||||
$password = Tools::userMd5($password);
|
||||
}
|
||||
$userInfo = (new AdminUser())->where('username', $username)->where('password', $password)->find();
|
||||
if (!empty($userInfo)) {
|
||||
if ($userInfo['status']) {
|
||||
//更新用户数据
|
||||
$userData = $userInfo->userData;
|
||||
$data = [];
|
||||
if ($userData) {
|
||||
$userData->login_times++;
|
||||
$userData->last_login_ip = sprintf("%u", ip2long($this->request->ip()));
|
||||
$userData->last_login_time = time();
|
||||
$userData->save();
|
||||
} else {
|
||||
$data['login_times'] = 1;
|
||||
$data['uid'] = $userInfo['id'];
|
||||
$data['last_login_ip'] = sprintf("%u", ip2long($this->request->ip()));
|
||||
$data['last_login_time'] = time();
|
||||
$data['head_img'] = '';
|
||||
AdminUserData::create($data);
|
||||
|
||||
$userInfo['userData'] = $data;
|
||||
}
|
||||
} else {
|
||||
return $this->buildFailed(ReturnCode::LOGIN_ERROR, '用户已被封禁,请联系管理员');
|
||||
}
|
||||
} else {
|
||||
return $this->buildFailed(ReturnCode::LOGIN_ERROR, '用户名密码不正确');
|
||||
}
|
||||
$userInfo['access'] = $this->getAccess($userInfo['id']);
|
||||
$userInfo['menu'] = $this->getAccessMenuData($userInfo['id']);
|
||||
|
||||
$apiAuth = md5(uniqid() . time());
|
||||
cache('Login:' . $apiAuth, json_encode($userInfo), config('apiadmin.ONLINE_TIME'));
|
||||
cache('Login:' . $userInfo['id'], $apiAuth, config('apiadmin.ONLINE_TIME'));
|
||||
|
||||
$userInfo['apiAuth'] = $apiAuth;
|
||||
|
||||
return $this->buildSuccess($userInfo->toArray(), '登录成功');
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户信息
|
||||
* @return Response
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function getUserInfo(): Response {
|
||||
return $this->buildSuccess($this->userInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户登出
|
||||
* @return Response
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function logout(): Response {
|
||||
$ApiAuth = $this->request->header('Api-Auth');
|
||||
cache('Login:' . $ApiAuth, null);
|
||||
cache('Login:' . $this->userInfo['id'], null);
|
||||
|
||||
return $this->buildSuccess([], '登出成功');
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前用户的允许菜单
|
||||
* @return Response
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function getAccessMenu(): Response {
|
||||
return $this->buildSuccess($this->getAccessMenuData($this->userInfo['id']));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前用户的允许菜单
|
||||
* @param int $uid
|
||||
* @return array
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function getAccessMenuData(int $uid): array {
|
||||
$returnData = [];
|
||||
$isSupper = Tools::isAdministrator($uid);
|
||||
if ($isSupper) {
|
||||
$access = (new AdminMenu())->where('router', '<>', '')->select();
|
||||
$returnData = Tools::listToTree(Tools::buildArrFromObj($access));
|
||||
} else {
|
||||
$groups = (new AdminAuthGroupAccess())->where('uid', $uid)->find();
|
||||
if (isset($groups) && $groups->group_id) {
|
||||
$access = (new AdminAuthRule())->whereIn('group_id', $groups->group_id)->select();
|
||||
$access = array_unique(array_column(Tools::buildArrFromObj($access), 'url'));
|
||||
array_push($access, "");
|
||||
$menus = (new AdminMenu())->whereIn('url', $access)->where('show', 1)->select();
|
||||
$returnData = Tools::listToTree(Tools::buildArrFromObj($menus));
|
||||
RouterTool::buildVueRouter($returnData);
|
||||
}
|
||||
}
|
||||
|
||||
return array_values($returnData);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户权限数据
|
||||
* @param $uid
|
||||
* @return array
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function getAccess(int $uid): array {
|
||||
$isSupper = Tools::isAdministrator($uid);
|
||||
if ($isSupper) {
|
||||
$access = (new AdminMenu())->select();
|
||||
$access = Tools::buildArrFromObj($access);
|
||||
|
||||
return array_values(array_filter(array_column($access, 'url')));
|
||||
} else {
|
||||
$groups = (new AdminAuthGroupAccess())->where('uid', $uid)->find();
|
||||
if (isset($groups) && $groups->group_id) {
|
||||
$access = (new AdminAuthRule())->whereIn('group_id', $groups->group_id)->select();
|
||||
$access = Tools::buildArrFromObj($access);
|
||||
|
||||
return array_values(array_unique(array_column($access, 'url')));
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,108 +1,112 @@
|
||||
<?php
|
||||
declare (strict_types=1);
|
||||
/**
|
||||
* 目录管理
|
||||
* @since 2018-01-16
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
|
||||
namespace app\admin\controller;
|
||||
|
||||
namespace app\controller\admin;
|
||||
|
||||
use app\model\AdminMenu;
|
||||
use app\util\ReturnCode;
|
||||
use app\util\Tools;
|
||||
use think\Response;
|
||||
|
||||
class Menu extends Base {
|
||||
|
||||
/**
|
||||
* 获取菜单列表
|
||||
* @return array
|
||||
* @throws \think\exception\DbException
|
||||
* @return \think\Response
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function index() {
|
||||
$list = (new AdminMenu)->where([])->order('sort', 'ASC')->select();
|
||||
$list = Tools::buildArrFromObj($list);
|
||||
$list = formatTree(listToTree($list));
|
||||
public function index(): Response {
|
||||
$keywords = $this->request->get('keywords', '');
|
||||
$obj = new AdminMenu();
|
||||
if ($keywords) {
|
||||
$obj = $obj->whereLike('title', "%{$keywords}%");
|
||||
}
|
||||
$obj = $obj->order('sort', 'ASC')->select();
|
||||
$list = Tools::buildArrFromObj($obj);
|
||||
if (!$keywords) {
|
||||
$list = Tools::listToTree($list);
|
||||
}
|
||||
|
||||
return $this->buildSuccess([
|
||||
'list' => $list
|
||||
], '登录成功');
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增菜单
|
||||
* @return array
|
||||
* @return \think\Response
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function add() {
|
||||
public function add(): Response {
|
||||
$postData = $this->request->post();
|
||||
if ($postData['url']) {
|
||||
$postData['url'] = 'admin/' . $postData['url'];
|
||||
}
|
||||
$res = AdminMenu::create($postData);
|
||||
if ($res === false) {
|
||||
return $this->buildFailed(ReturnCode::DB_SAVE_ERROR, '操作失败');
|
||||
return $this->buildFailed(ReturnCode::DB_SAVE_ERROR);
|
||||
} else {
|
||||
return $this->buildSuccess([]);
|
||||
return $this->buildSuccess();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 菜单状态编辑
|
||||
* @return array
|
||||
* @return Response
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function changeStatus() {
|
||||
public function changeStatus(): Response {
|
||||
$id = $this->request->get('id');
|
||||
$status = $this->request->get('status');
|
||||
$res = AdminMenu::update([
|
||||
'id' => $id,
|
||||
'hide' => $status
|
||||
'show' => $status
|
||||
]);
|
||||
if ($res === false) {
|
||||
return $this->buildFailed(ReturnCode::DB_SAVE_ERROR, '操作失败');
|
||||
} else {
|
||||
return $this->buildSuccess([]);
|
||||
return $this->buildFailed(ReturnCode::DB_SAVE_ERROR);
|
||||
}
|
||||
|
||||
return $this->buildSuccess();
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑菜单
|
||||
* @return array
|
||||
* @return Response
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function edit() {
|
||||
public function edit(): Response {
|
||||
$postData = $this->request->post();
|
||||
if ($postData['url']) {
|
||||
$postData['url'] = 'admin/' . $postData['url'];
|
||||
}
|
||||
$res = AdminMenu::update($postData);
|
||||
if ($res === false) {
|
||||
return $this->buildFailed(ReturnCode::DB_SAVE_ERROR, '操作失败');
|
||||
} else {
|
||||
return $this->buildSuccess([]);
|
||||
return $this->buildFailed(ReturnCode::DB_SAVE_ERROR);
|
||||
}
|
||||
|
||||
return $this->buildSuccess();
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除菜单
|
||||
* @return array
|
||||
* @return Response
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function del() {
|
||||
public function del(): Response {
|
||||
$id = $this->request->get('id');
|
||||
if (!$id) {
|
||||
return $this->buildFailed(ReturnCode::EMPTY_PARAMS, '缺少必要参数');
|
||||
}
|
||||
$childNum = AdminMenu::where(['fid' => $id])->count();
|
||||
if ($childNum) {
|
||||
return $this->buildFailed(ReturnCode::INVALID, '当前菜单存在子菜单,不可以被删除!');
|
||||
} else {
|
||||
AdminMenu::destroy($id);
|
||||
(new AdminMenu())->whereIn('id', $id)->delete();
|
||||
|
||||
return $this->buildSuccess([]);
|
||||
}
|
||||
return $this->buildSuccess();
|
||||
}
|
||||
|
||||
}
|
18
app/controller/admin/Miss.php
Normal file
18
app/controller/admin/Miss.php
Normal file
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
declare (strict_types=1);
|
||||
|
||||
namespace app\controller\admin;
|
||||
|
||||
use app\util\ReturnCode;
|
||||
use think\Response;
|
||||
|
||||
class Miss extends Base {
|
||||
|
||||
public function index(): Response {
|
||||
if ($this->request->isOptions()) {
|
||||
return $this->buildSuccess();
|
||||
} else {
|
||||
return $this->buildFailed(ReturnCode::INVALID, '接口地址异常');
|
||||
}
|
||||
}
|
||||
}
|
350
app/controller/admin/ThirdLogin.php
Normal file
350
app/controller/admin/ThirdLogin.php
Normal file
@ -0,0 +1,350 @@
|
||||
<?php
|
||||
declare (strict_types=1);
|
||||
/**
|
||||
* 三方一键登录平台
|
||||
* @since 2018-03-28
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
|
||||
namespace app\controller\admin;
|
||||
|
||||
use app\model\AdminAuthGroupAccess;
|
||||
use app\model\AdminUser;
|
||||
use app\util\ReturnCode;
|
||||
use app\util\Strs;
|
||||
use app\util\Tools;
|
||||
use Endroid\QrCode\ErrorCorrectionLevel;
|
||||
use Endroid\QrCode\QrCode;
|
||||
use think\facade\Cache;
|
||||
use think\facade\Env;
|
||||
use think\Response;
|
||||
|
||||
class ThirdLogin extends Base {
|
||||
|
||||
/**
|
||||
* QQ一键登录配置
|
||||
* @var array
|
||||
*/
|
||||
private $qqConfig = [
|
||||
'appId' => '',
|
||||
'appSecret' => '',
|
||||
'redirectUri' => 'https://admin.apiadmin.org/#/login/qq'
|
||||
];
|
||||
|
||||
/**
|
||||
* 微信认证服务号一键登录配置
|
||||
* @var array
|
||||
*/
|
||||
private $wxConfig = [
|
||||
'appId' => '',
|
||||
'appSecret' => ''
|
||||
];
|
||||
|
||||
/**
|
||||
* 微信开放平台一键登录配置
|
||||
* @var array
|
||||
*/
|
||||
private $wxOpenConfig = [
|
||||
'appId' => '',
|
||||
'appSecret' => '',
|
||||
'redirectUri' => 'https://admin.apiadmin.org/#/login/wx'
|
||||
];
|
||||
|
||||
/**
|
||||
* 使用微信开放平台登录
|
||||
* @return Response
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function wx(): Response {
|
||||
$state = $this->request->get('state', '');
|
||||
$code = $this->request->get('code', '');
|
||||
|
||||
//验证合法性
|
||||
$cacheData = Cache::has($state);
|
||||
if (!$cacheData) {
|
||||
return $this->buildFailed(ReturnCode::SESSION_TIMEOUT, 'state已过期');
|
||||
} else {
|
||||
cache($state, null);
|
||||
}
|
||||
|
||||
//获取AccessToken
|
||||
$getAccessTokenUrl = 'https://api.weixin.qq.com/sns/oauth2/access_token?appid=' .
|
||||
$this->wxOpenConfig['appId'] . '&secret=' . $this->wxOpenConfig['appSecret'] . '&code=' . $code .
|
||||
'&grant_type=authorization_code';
|
||||
|
||||
$tokenArr = file_get_contents($getAccessTokenUrl);
|
||||
$accessTokenArr = json_decode($tokenArr, true);
|
||||
|
||||
//获取openId
|
||||
$getUserIdUrl = 'https://api.weixin.qq.com/sns/userinfo?access_token=' . $accessTokenArr['access_token'] . '&openid=' . $accessTokenArr['openid'];
|
||||
$userIdArr = file_get_contents($getUserIdUrl);
|
||||
$userIdArr = json_decode($userIdArr, true);
|
||||
|
||||
return $this->doLogin($userIdArr['openid'], [
|
||||
'nickname' => $userIdArr['nickname'],
|
||||
'head_img' => $userIdArr['headimgurl']
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取授权登录的二维码
|
||||
* @return Response
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function getQr(): Response {
|
||||
$state = uniqid();
|
||||
$query = [
|
||||
'appid' => $this->wxConfig['appId'],
|
||||
'redirect_uri' => 'https://api.apiadmin.org/admin/ThirdLogin/loginByWx',
|
||||
'response_type' => 'code',
|
||||
'scope' => 'snsapi_userinfo',
|
||||
'state' => $state
|
||||
];
|
||||
$authUrl = 'https://open.weixin.qq.com/connect/oauth2/authorize?' . http_build_query($query) . '#wechat_redirect';
|
||||
|
||||
$qrCode = new QrCode($authUrl);
|
||||
$qrCode->setSize(300);
|
||||
$qrCode->setWriterByName('png');
|
||||
$qrCode->setMargin(10);
|
||||
$qrCode->setEncoding('UTF-8');
|
||||
$qrCode->setErrorCorrectionLevel(new ErrorCorrectionLevel(ErrorCorrectionLevel::HIGH));
|
||||
$qrCode->setForegroundColor(['r' => 0, 'g' => 0, 'b' => 0, 'a' => 0]);
|
||||
$qrCode->setBackgroundColor(['r' => 255, 'g' => 255, 'b' => 255, 'a' => 0]);
|
||||
$qrCode->setRoundBlockSize(true);
|
||||
$qrCode->setValidateResult(false);
|
||||
$qrCode->writeFile(Env::get('root_path') . 'public/qr/' . $state . '.png');
|
||||
|
||||
cache($state, 1, 300);
|
||||
|
||||
return $this->buildSuccess([
|
||||
'qrUrl' => 'https://api.apiadmin.org/qr/' . $state . '.png',
|
||||
'state' => $state
|
||||
]);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 接受微信回调,处理用户登录
|
||||
* @return Response
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function loginByWx(): Response {
|
||||
$code = $this->request->get('code');
|
||||
$state = $this->request->get('state');
|
||||
|
||||
$auth = cache($state);
|
||||
if (!$auth) {
|
||||
return view('wiki@index/login_res', [
|
||||
'info' => '当前二维码已失效',
|
||||
'code' => ReturnCode::RECORD_NOT_FOUND
|
||||
]);
|
||||
}
|
||||
|
||||
$query = [
|
||||
'appid' => $this->wxConfig['appId'],
|
||||
'secret' => $this->wxConfig['appSecret'],
|
||||
'grant_type' => 'authorization_code',
|
||||
'code' => $code
|
||||
];
|
||||
$url = 'https://api.weixin.qq.com/sns/oauth2/access_token?' . http_build_query($query);
|
||||
$accessToken = json_decode(file_get_contents($url), true);
|
||||
|
||||
$getUserInfoQuery = [
|
||||
'access_token' => $accessToken['access_token'],
|
||||
'openid' => $accessToken['openid'],
|
||||
'lang' => 'zh_CN'
|
||||
];
|
||||
$getUserInfoUrl = 'https://api.weixin.qq.com/sns/userinfo?' . http_build_query($getUserInfoQuery);
|
||||
|
||||
$userInfoArr = file_get_contents($getUserInfoUrl);
|
||||
$userInfoArr = json_decode($userInfoArr, true);
|
||||
|
||||
if ($userInfoArr) {
|
||||
cache($state, [
|
||||
'nickname' => $userInfoArr['nickname'],
|
||||
'head_img' => $userInfoArr['headimgurl'],
|
||||
'openid' => $accessToken['openid']
|
||||
], 300);
|
||||
|
||||
return view('wiki@index/login_res', [
|
||||
'info' => '登录成功',
|
||||
'code' => ReturnCode::SUCCESS
|
||||
]);
|
||||
} else {
|
||||
return view('wiki@index/login_res', [
|
||||
'info' => '操作失败',
|
||||
'code' => ReturnCode::DB_SAVE_ERROR
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理微信用户登录
|
||||
* @return Response
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function checkWxLogin(): Response {
|
||||
$state = $this->request->get('state');
|
||||
$userInfo = cache($state);
|
||||
|
||||
if (is_numeric($userInfo)) {
|
||||
return $this->buildFailed(666, '等待扫码');
|
||||
} else {
|
||||
@unlink(Env::get('root_path') . 'public/qr/' . $state . '.png');
|
||||
if (is_array($userInfo)) {
|
||||
cache($state, null);
|
||||
|
||||
return $this->doLogin($userInfo['openid'], [
|
||||
'nickname' => $userInfo['nickname'],
|
||||
'head_img' => $userInfo['head_img']
|
||||
]);
|
||||
} else {
|
||||
return $this->buildFailed(ReturnCode::INVALID, '登录状态已失效,请重新登录');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取qq登录必要参数
|
||||
* @return Response
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function getWxCode(): Response {
|
||||
$state = md5(uniqid() . time());
|
||||
cache($state, $state, 300);
|
||||
|
||||
return $this->buildSuccess([
|
||||
'appId' => $this->wxOpenConfig['appId'],
|
||||
'redirectUri' => urlencode($this->wxOpenConfig['redirectUri']),
|
||||
'state' => $state
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取qq登录必要参数
|
||||
* @return Response
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function getQQCode(): Response {
|
||||
$state = md5(uniqid() . time());
|
||||
cache($state, $state, 300);
|
||||
|
||||
return $this->buildSuccess([
|
||||
'appId' => $this->qqConfig['appId'],
|
||||
'redirectUri' => urlencode($this->qqConfig['redirectUri']),
|
||||
'state' => $state
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用QQ登录
|
||||
* @return Response
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function loginByQQ(): Response {
|
||||
$state = $this->request->get('state', '');
|
||||
$code = $this->request->get('code', '');
|
||||
|
||||
//验证合法性
|
||||
$cacheData = Cache::has($state);
|
||||
if (!$cacheData) {
|
||||
return $this->buildFailed(ReturnCode::SESSION_TIMEOUT, 'state已过期');
|
||||
} else {
|
||||
cache($state, null);
|
||||
}
|
||||
|
||||
//获取AccessToken
|
||||
$getAccessTokenUrl = 'https://graph.qq.com/oauth2.0/token?grant_type=authorization_code&client_id=' .
|
||||
$this->qqConfig['appId'] . '&client_secret=' . $this->qqConfig['appSecret'] . '&code=' . $code .
|
||||
'&redirect_uri=' . urlencode($this->qqConfig['redirectUri']);
|
||||
|
||||
$tokenArr = file_get_contents($getAccessTokenUrl);
|
||||
parse_str($tokenArr, $accessTokenArr);
|
||||
|
||||
//获取openId
|
||||
$getUserIdUrl = 'https://graph.qq.com/oauth2.0/me?access_token=' . $accessTokenArr['access_token'];
|
||||
$userIdArr = file_get_contents($getUserIdUrl);
|
||||
$userIdArr = str_replace('callback( ', '', $userIdArr);
|
||||
$userIdArr = str_replace(' );', '', $userIdArr);
|
||||
$userIdArr = json_decode($userIdArr, true);
|
||||
|
||||
$getUserInfoUrl = 'https://graph.qq.com/user/get_user_info?access_token=' . $accessTokenArr['access_token'] . '&oauth_consumer_key=' .
|
||||
$this->qqConfig['appId'] . '&openid=' . $userIdArr['openid'];
|
||||
$userInfoArr = file_get_contents($getUserInfoUrl);
|
||||
$userInfoArr = json_decode($userInfoArr, true);
|
||||
|
||||
return $this->doLogin($userIdArr['openid'], [
|
||||
'nickname' => $userInfoArr['nickname'],
|
||||
'head_img' => $userInfoArr['figureurl_qq_2']
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 统一处理用户登录
|
||||
* @param $openid
|
||||
* @param $userDetail
|
||||
* @return Response
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
private function doLogin(string $openid, array $userDetail): Response {
|
||||
$userInfo = (new AdminUser())->where('openid', $openid)->find();
|
||||
if (empty($userInfo)) {
|
||||
$userInfo = AdminUser::create([
|
||||
'nickname' => $userDetail['nickname'],
|
||||
'username' => 'ApiAdmin_qq_' . Strs::randString(8),
|
||||
'openid' => $openid,
|
||||
'create_ip' => sprintf("%u", ip2long($this->request->ip())),
|
||||
'status' => 1,
|
||||
'create_time' => time(),
|
||||
'password' => Tools::userMd5('ApiAdmin')
|
||||
]);
|
||||
$userDataArr = [
|
||||
'login_times' => 1,
|
||||
'uid' => $userInfo->id,
|
||||
'last_login_ip' => sprintf("%u", ip2long($this->request->ip())),
|
||||
'last_login_time' => time(),
|
||||
'head_img' => $userDetail['head_img']
|
||||
];
|
||||
$userInfo->userData()->save($userDataArr);
|
||||
$userInfo['userData'] = $userDataArr;
|
||||
|
||||
AdminAuthGroupAccess::create([
|
||||
'uid' => $userInfo->id,
|
||||
'group_id' => 1
|
||||
]);
|
||||
} else {
|
||||
if ($userInfo['status']) {
|
||||
//更新用户数据
|
||||
$userInfo->userData->login_times++;
|
||||
$userInfo->userData->last_login_ip = sprintf("%u", ip2long($this->request->ip()));
|
||||
$userInfo->userData->last_login_time = time();
|
||||
$userInfo->userData->save();
|
||||
} else {
|
||||
return $this->buildFailed(ReturnCode::LOGIN_ERROR, '用户已被封禁,请联系管理员');
|
||||
}
|
||||
}
|
||||
|
||||
$userInfo['access'] = (new Login(App()))->getAccess(intval($userInfo['id']));
|
||||
$userInfo['menu'] = (new Login(App()))->getAccessMenuData(intval($userInfo['id']));
|
||||
|
||||
$apiAuth = md5(uniqid() . time());
|
||||
cache('Login:' . $apiAuth, json_encode($userInfo), config('apiadmin.ONLINE_TIME'));
|
||||
cache('Login:' . $userInfo['id'], $apiAuth, config('apiadmin.ONLINE_TIME'));
|
||||
|
||||
$userInfo['apiAuth'] = $apiAuth;
|
||||
|
||||
return $this->buildSuccess($userInfo->toArray(), '登录成功');
|
||||
}
|
||||
}
|
277
app/controller/admin/User.php
Normal file
277
app/controller/admin/User.php
Normal file
@ -0,0 +1,277 @@
|
||||
<?php
|
||||
declare (strict_types=1);
|
||||
/**
|
||||
* 用户管理
|
||||
* @since 2018-02-06
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
|
||||
namespace app\controller\admin;
|
||||
|
||||
use app\model\AdminAuthGroupAccess;
|
||||
use app\model\AdminUser;
|
||||
use app\model\AdminUserData;
|
||||
use app\util\ReturnCode;
|
||||
use app\util\Tools;
|
||||
use think\facade\Db;
|
||||
use think\Response;
|
||||
|
||||
class User extends Base {
|
||||
|
||||
/**
|
||||
* 获取用户列表
|
||||
* @return Response
|
||||
* @throws \think\db\exception\DbException
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function index(): Response {
|
||||
$limit = $this->request->get('size', config('apiadmin.ADMIN_LIST_DEFAULT'));
|
||||
$start = $this->request->get('page', 1);
|
||||
$type = $this->request->get('type', '', 'intval');
|
||||
$keywords = $this->request->get('keywords', '');
|
||||
$status = $this->request->get('status', '');
|
||||
|
||||
$obj = new AdminUser();
|
||||
if (strlen($status)) {
|
||||
$obj = $obj->where('status', $status);
|
||||
}
|
||||
if ($type) {
|
||||
switch ($type) {
|
||||
case 1:
|
||||
$obj = $obj->whereLike('username', "%{$keywords}%");
|
||||
break;
|
||||
case 2:
|
||||
$obj = $obj->whereLike('nickname', "%{$keywords}%");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$listObj = $obj->order('create_time', 'DESC')
|
||||
->paginate(['page' => $start, 'list_rows' => $limit])->each(function($item, $key) {
|
||||
$item->userData;
|
||||
})->toArray();
|
||||
$listInfo = $listObj['data'];
|
||||
$idArr = array_column($listInfo, 'id');
|
||||
|
||||
$userGroup = (new AdminAuthGroupAccess())->whereIn('uid', $idArr)->select();
|
||||
$userGroup = Tools::buildArrFromObj($userGroup);
|
||||
$userGroup = Tools::buildArrByNewKey($userGroup, 'uid');
|
||||
|
||||
|
||||
foreach ($listInfo as $key => &$value) {
|
||||
if ($value['userData']) {
|
||||
$value['userData']['last_login_ip'] = long2ip($value['userData']['last_login_ip']);
|
||||
$value['userData']['last_login_time'] = date('Y-m-d H:i:s', $value['userData']['last_login_time']);
|
||||
$value['create_ip'] = long2ip($value['create_ip']);
|
||||
}
|
||||
if (isset($userGroup[$value['id']])) {
|
||||
$value['group_id'] = explode(',', $userGroup[$value['id']]['group_id']);
|
||||
} else {
|
||||
$value['group_id'] = [];
|
||||
}
|
||||
}
|
||||
|
||||
return $this->buildSuccess([
|
||||
'list' => $listInfo,
|
||||
'count' => $listObj['total']
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增用户
|
||||
* @return Response
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function add() {
|
||||
$groups = '';
|
||||
$postData = $this->request->post();
|
||||
$postData['create_ip'] = sprintf("%u", ip2long($this->request->ip()));
|
||||
$postData['password'] = Tools::userMd5($postData['password']);
|
||||
if (isset($postData['group_id']) && $postData['group_id']) {
|
||||
$groups = trim(implode(',', $postData['group_id']), ',');
|
||||
unset($postData['group_id']);
|
||||
}
|
||||
$res = AdminUser::create($postData);
|
||||
if ($res === false) {
|
||||
return $this->buildFailed(ReturnCode::DB_SAVE_ERROR);
|
||||
}
|
||||
AdminAuthGroupAccess::create([
|
||||
'uid' => $res->id,
|
||||
'group_id' => $groups
|
||||
]);
|
||||
|
||||
return $this->buildSuccess();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前组的全部用户
|
||||
* @return Response
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function getUsers() {
|
||||
$limit = $this->request->get('size', config('apiadmin.ADMIN_LIST_DEFAULT'));
|
||||
$page = $this->request->get('page', 1);
|
||||
$gid = $this->request->get('gid', 0);
|
||||
if (!$gid) {
|
||||
return $this->buildFailed(ReturnCode::PARAM_INVALID, '非法操作');
|
||||
}
|
||||
|
||||
$totalNum = (new AdminAuthGroupAccess())->where('find_in_set("' . $gid . '", `group_id`)')->count();
|
||||
$start = $limit * ($page - 1);
|
||||
$sql = "SELECT au.* FROM admin_user as au LEFT JOIN admin_auth_group_access as aaga " .
|
||||
" ON aaga.`uid` = au.`id` WHERE find_in_set('{$gid}', aaga.`group_id`) " .
|
||||
" ORDER BY au.create_time DESC LIMIT {$start}, {$limit}";
|
||||
$userInfo = Db::query($sql);
|
||||
|
||||
$uidArr = array_column($userInfo, 'id');
|
||||
$userData = (new AdminUserData())->whereIn('uid', $uidArr)->select();
|
||||
$userData = Tools::buildArrByNewKey($userData, 'uid');
|
||||
|
||||
foreach ($userInfo as $key => $value) {
|
||||
if (isset($userData[$value['id']])) {
|
||||
$userInfo[$key]['last_login_ip'] = long2ip($userData[$value['id']]['last_login_ip']);
|
||||
$userInfo[$key]['login_times'] = $userData[$value['id']]['login_times'];
|
||||
$userInfo[$key]['last_login_time'] = date('Y-m-d H:i:s', $userData[$value['id']]['last_login_time']);
|
||||
}
|
||||
$userInfo[$key]['create_ip'] = long2ip($userInfo[$key]['create_ip']);
|
||||
}
|
||||
|
||||
return $this->buildSuccess([
|
||||
'list' => $userInfo,
|
||||
'count' => $totalNum
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户状态编辑
|
||||
* @return Response
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function changeStatus() {
|
||||
$id = $this->request->get('id');
|
||||
$status = $this->request->get('status');
|
||||
$res = AdminUser::update([
|
||||
'id' => $id,
|
||||
'status' => $status
|
||||
]);
|
||||
if ($res === false) {
|
||||
return $this->buildFailed(ReturnCode::DB_SAVE_ERROR);
|
||||
}
|
||||
if ($oldAdmin = cache('Login:' . $id)) {
|
||||
cache('Login:' . $oldAdmin, null);
|
||||
}
|
||||
|
||||
return $this->buildSuccess();
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑用户
|
||||
* @return Response
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function edit() {
|
||||
$groups = '';
|
||||
$postData = $this->request->post();
|
||||
if ($postData['password'] === 'ApiAdmin') {
|
||||
unset($postData['password']);
|
||||
} else {
|
||||
$postData['password'] = Tools::userMd5($postData['password']);
|
||||
}
|
||||
if (isset($postData['group_id']) && $postData['group_id']) {
|
||||
$groups = trim(implode(',', $postData['group_id']), ',');
|
||||
unset($postData['group_id']);
|
||||
}
|
||||
$res = AdminUser::update($postData);
|
||||
if ($res === false) {
|
||||
return $this->buildFailed(ReturnCode::DB_SAVE_ERROR);
|
||||
}
|
||||
$has = (new AdminAuthGroupAccess())->where('uid', $postData['id'])->select();
|
||||
if ($has) {
|
||||
AdminAuthGroupAccess::update([
|
||||
'group_id' => $groups
|
||||
], [
|
||||
'uid' => $postData['id'],
|
||||
]);
|
||||
} else {
|
||||
AdminAuthGroupAccess::create([
|
||||
'uid' => $postData['id'],
|
||||
'group_id' => $groups
|
||||
]);
|
||||
}
|
||||
if ($oldAdmin = cache('Login:' . $postData['id'])) {
|
||||
cache('Login:' . $oldAdmin, null);
|
||||
}
|
||||
|
||||
return $this->buildSuccess();
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改自己的信息
|
||||
* @return Response
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function own() {
|
||||
$postData = $this->request->post();
|
||||
$headImg = $postData['head_img'];
|
||||
|
||||
if ($postData['password'] && $postData['oldPassword']) {
|
||||
$oldPass = Tools::userMd5($postData['oldPassword']);
|
||||
unset($postData['oldPassword']);
|
||||
if ($oldPass === $this->userInfo['password']) {
|
||||
$postData['password'] = Tools::userMd5($postData['password']);
|
||||
} else {
|
||||
return $this->buildFailed(ReturnCode::INVALID, '原始密码不正确');
|
||||
}
|
||||
} else {
|
||||
unset($postData['password']);
|
||||
unset($postData['oldPassword']);
|
||||
}
|
||||
$postData['id'] = $this->userInfo['id'];
|
||||
unset($postData['head_img']);
|
||||
$res = AdminUser::update($postData);
|
||||
if ($res === false) {
|
||||
return $this->buildFailed(ReturnCode::DB_SAVE_ERROR);
|
||||
}
|
||||
$userData = (new AdminUserData())->where('uid', $postData['id'])->find();
|
||||
$userData->head_img = $headImg;
|
||||
$userData->save();
|
||||
if ($oldWiki = cache('WikiLogin:' . $postData['id'])) {
|
||||
cache('WikiLogin:' . $oldWiki, null);
|
||||
}
|
||||
|
||||
return $this->buildSuccess();
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除用户
|
||||
* @return Response
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function del() {
|
||||
$id = $this->request->get('id/d');
|
||||
if (!$id) {
|
||||
return $this->buildFailed(ReturnCode::EMPTY_PARAMS, '缺少必要参数');
|
||||
}
|
||||
|
||||
$isAdmin = Tools::isAdministrator($id);
|
||||
if ($isAdmin) {
|
||||
return $this->buildFailed(ReturnCode::INVALID, '超级管理员不能被删除');
|
||||
}
|
||||
AdminUser::destroy($id);
|
||||
AdminAuthGroupAccess::destroy(['uid' => $id]);
|
||||
if ($oldAdmin = cache('Login:' . $id)) {
|
||||
cache('Login:' . $oldAdmin, null);
|
||||
}
|
||||
|
||||
return $this->buildSuccess();
|
||||
}
|
||||
}
|
@ -1,56 +1,56 @@
|
||||
<?php
|
||||
declare (strict_types=1);
|
||||
/**
|
||||
* 工程基类
|
||||
* @since 2017/02/28 创建
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
|
||||
namespace app\api\controller;
|
||||
namespace app\controller\api;
|
||||
|
||||
|
||||
use app\util\ApiLog;
|
||||
use app\BaseController;
|
||||
use app\util\ReturnCode;
|
||||
use think\Controller;
|
||||
use think\facade\Env;
|
||||
use think\Response;
|
||||
|
||||
class Base extends Controller {
|
||||
class Base extends BaseController {
|
||||
|
||||
private $debug = [];
|
||||
protected $userInfo = [];
|
||||
|
||||
public function _initialize() {
|
||||
$this->userInfo = ApiLog::getUserInfo();
|
||||
// $this->userInfo = ''; 这部分初始化用户信息可以参考admin模块下的Base去自行处理
|
||||
}
|
||||
|
||||
public function buildSuccess($data, $msg = '操作成功', $code = ReturnCode::SUCCESS) {
|
||||
public function buildSuccess(array $data = [], string $msg = '操作成功', int $code = ReturnCode::SUCCESS): Response {
|
||||
$return = [
|
||||
'code' => $code,
|
||||
'msg' => $msg,
|
||||
'data' => $data
|
||||
];
|
||||
if ($this->debug) {
|
||||
if (Env::get('APP_DEBUG') && $this->debug) {
|
||||
$return['debug'] = $this->debug;
|
||||
}
|
||||
|
||||
return json($return);
|
||||
}
|
||||
|
||||
public function buildFailed($code, $msg, $data = []) {
|
||||
public function buildFailed(int $code, string $msg = '操作失败', array $data = []): Response {
|
||||
$return = [
|
||||
'code' => $code,
|
||||
'msg' => $msg,
|
||||
'data' => $data
|
||||
];
|
||||
if ($this->debug) {
|
||||
if (Env::get('APP_DEBUG') && $this->debug) {
|
||||
$return['debug'] = $this->debug;
|
||||
}
|
||||
|
||||
return json($return);
|
||||
}
|
||||
|
||||
protected function debug($data) {
|
||||
protected function debug($data): void {
|
||||
if ($data) {
|
||||
$this->debug[] = $data;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -5,11 +5,9 @@
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
|
||||
namespace app\api\controller;
|
||||
|
||||
namespace app\controller\api;
|
||||
|
||||
use app\model\AdminApp;
|
||||
use app\util\ApiLog;
|
||||
use app\util\ReturnCode;
|
||||
use app\util\Strs;
|
||||
|
||||
@ -17,30 +15,30 @@ class BuildToken extends Base {
|
||||
|
||||
/**
|
||||
* 构建AccessToken
|
||||
* @return \think\response\Json
|
||||
* @return \think\Response
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @throws \think\exception\DbException
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function getAccessToken() {
|
||||
$param = $this->request->param();
|
||||
if (empty($param['app_id'])) {
|
||||
return $this->buildFailed(ReturnCode::EMPTY_PARAMS, '缺少app_id');
|
||||
}
|
||||
$appInfo = (new AdminApp())->where(['app_id' => $param['app_id'], 'app_status' => 1])->find();
|
||||
if (empty($appInfo)) {
|
||||
return $this->buildFailed(ReturnCode::INVALID, '应用ID非法');
|
||||
} else {
|
||||
$appInfo = $appInfo->toArray();
|
||||
}
|
||||
|
||||
$signature = $param['signature'];
|
||||
unset($param['signature']);
|
||||
unset($param['Access-Token']);
|
||||
$sign = $this->getAuthToken($appInfo['app_secret'], $param);
|
||||
$this->debug($sign);
|
||||
if ($sign !== $signature) {
|
||||
return $this->buildFailed(ReturnCode::INVALID, '身份令牌验证失败');
|
||||
}
|
||||
$expires = config('apiAdmin.ACCESS_TOKEN_TIME_OUT');
|
||||
$expires = config('apiadmin.ACCESS_TOKEN_TIME_OUT');
|
||||
$accessToken = cache('AccessToken:' . $param['device_id']);
|
||||
if ($accessToken) {
|
||||
cache('AccessToken:' . $accessToken, null);
|
||||
@ -48,7 +46,6 @@ class BuildToken extends Base {
|
||||
}
|
||||
$accessToken = $this->buildAccessToken($appInfo['app_id'], $appInfo['app_secret']);
|
||||
$appInfo['device_id'] = $param['device_id'];
|
||||
ApiLog::setAppInfo($appInfo);
|
||||
cache('AccessToken:' . $accessToken, $appInfo, $expires);
|
||||
cache('AccessToken:' . $param['device_id'], $accessToken, $expires);
|
||||
$return['access_token'] = $accessToken;
|
||||
@ -57,14 +54,6 @@ class BuildToken extends Base {
|
||||
return $this->buildSuccess($return);
|
||||
}
|
||||
|
||||
public function e1() {
|
||||
return $this->buildSuccess(['e1']);
|
||||
}
|
||||
|
||||
public function e2() {
|
||||
return $this->buildSuccess(['e2']);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据AppSecret和数据生成相对应的身份认证秘钥
|
||||
* @param $appSecret
|
||||
@ -75,6 +64,7 @@ class BuildToken extends Base {
|
||||
if (empty($data)) {
|
||||
return '';
|
||||
} else {
|
||||
unset($data['APP_CONF_DETAIL'], $data['API_CONF_DETAIL']);
|
||||
$preArr = array_merge($data, ['app_secret' => $appSecret]);
|
||||
ksort($preArr);
|
||||
$preStr = http_build_query($preArr);
|
||||
@ -94,5 +84,4 @@ class BuildToken extends Base {
|
||||
|
||||
return md5($preStr);
|
||||
}
|
||||
|
||||
}
|
26
app/controller/api/Miss.php
Normal file
26
app/controller/api/Miss.php
Normal file
@ -0,0 +1,26 @@
|
||||
<?php
|
||||
declare (strict_types=1);
|
||||
|
||||
namespace app\controller\api;
|
||||
|
||||
use think\Exception;
|
||||
use think\facade\App;
|
||||
use think\Response;
|
||||
|
||||
class Miss extends Base {
|
||||
|
||||
public function index(): Response {
|
||||
$version = config('apiadmin.APP_VERSION');
|
||||
if (!$version) {
|
||||
throw new Exception('请先执行安装脚本,完成项目初始化!');
|
||||
} else {
|
||||
return $this->buildSuccess([
|
||||
'Product' => config('apiadmin.APP_NAME'),
|
||||
'ApiVersion' => $version,
|
||||
'TpVersion' => App::version(),
|
||||
'Company' => config('apiadmin.COMPANY_NAME'),
|
||||
'ToYou' => "I'm glad to meet you(终于等到你!)"
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
188
app/controller/wiki/Api.php
Normal file
188
app/controller/wiki/Api.php
Normal file
@ -0,0 +1,188 @@
|
||||
<?php
|
||||
declare (strict_types=1);
|
||||
/**
|
||||
* @since 2019-08-11
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
|
||||
namespace app\controller\wiki;
|
||||
|
||||
use app\model\AdminApp;
|
||||
use app\model\AdminFields;
|
||||
use app\model\AdminGroup;
|
||||
use app\model\AdminList;
|
||||
use app\util\DataType;
|
||||
use app\util\ReturnCode;
|
||||
use app\util\Tools;
|
||||
use think\Response;
|
||||
|
||||
class Api extends Base {
|
||||
|
||||
public function errorCode(): Response {
|
||||
$codeArr = ReturnCode::getConstants();
|
||||
$codeArr = array_flip($codeArr);
|
||||
$result = [];
|
||||
$errorInfo = [
|
||||
ReturnCode::SUCCESS => '请求成功',
|
||||
ReturnCode::INVALID => '非法操作',
|
||||
ReturnCode::DB_SAVE_ERROR => '数据存储失败',
|
||||
ReturnCode::DB_READ_ERROR => '数据读取失败',
|
||||
ReturnCode::CACHE_SAVE_ERROR => '缓存存储失败',
|
||||
ReturnCode::CACHE_READ_ERROR => '缓存读取失败',
|
||||
ReturnCode::FILE_SAVE_ERROR => '文件读取失败',
|
||||
ReturnCode::LOGIN_ERROR => '登录失败',
|
||||
ReturnCode::NOT_EXISTS => '不存在',
|
||||
ReturnCode::JSON_PARSE_FAIL => 'JSON数据格式错误',
|
||||
ReturnCode::TYPE_ERROR => '类型错误',
|
||||
ReturnCode::NUMBER_MATCH_ERROR => '数字匹配失败',
|
||||
ReturnCode::EMPTY_PARAMS => '丢失必要数据',
|
||||
ReturnCode::DATA_EXISTS => '数据已经存在',
|
||||
ReturnCode::AUTH_ERROR => '权限认证失败',
|
||||
ReturnCode::OTHER_LOGIN => '别的终端登录',
|
||||
ReturnCode::VERSION_INVALID => 'API版本非法',
|
||||
ReturnCode::CURL_ERROR => 'CURL操作异常',
|
||||
ReturnCode::RECORD_NOT_FOUND => '记录未找到',
|
||||
ReturnCode::DELETE_FAILED => '删除失败',
|
||||
ReturnCode::ADD_FAILED => '添加记录失败',
|
||||
ReturnCode::UPDATE_FAILED => '更新记录失败',
|
||||
ReturnCode::PARAM_INVALID => '数据类型非法',
|
||||
ReturnCode::ACCESS_TOKEN_TIMEOUT => '身份令牌过期',
|
||||
ReturnCode::SESSION_TIMEOUT => 'SESSION过期',
|
||||
ReturnCode::UNKNOWN => '未知错误',
|
||||
ReturnCode::EXCEPTION => '系统异常',
|
||||
];
|
||||
|
||||
foreach ($errorInfo as $key => $value) {
|
||||
$result[] = [
|
||||
'en_code' => $codeArr[$key],
|
||||
'code' => $key,
|
||||
'chinese' => $value,
|
||||
];
|
||||
}
|
||||
|
||||
return $this->buildSuccess([
|
||||
'data' => $result,
|
||||
'co' => config('apiadmin.APP_NAME') . ' ' . config('apiadmin.APP_VERSION')
|
||||
]);
|
||||
}
|
||||
|
||||
public function login(): Response {
|
||||
$appId = $this->request->post('username');
|
||||
$appSecret = $this->request->post('password');
|
||||
|
||||
$appInfo = (new AdminApp())->where('app_id', $appId)->where('app_secret', $appSecret)->find();
|
||||
if (!empty($appInfo)) {
|
||||
if ($appInfo->app_status) {
|
||||
//保存用户信息和登录凭证
|
||||
$appInfo = $appInfo->toArray();
|
||||
|
||||
$apiAuth = md5(uniqid() . time());
|
||||
cache('WikiLogin:' . $apiAuth, $appInfo, config('apiadmin.ONLINE_TIME'));
|
||||
cache('WikiLogin:' . $appInfo['id'], $apiAuth, config('apiadmin.ONLINE_TIME'));
|
||||
$appInfo['apiAuth'] = $apiAuth;
|
||||
|
||||
return $this->buildSuccess($appInfo, '登录成功');
|
||||
} else {
|
||||
return $this->buildFailed(ReturnCode::LOGIN_ERROR, '当前应用已被封禁,请联系管理员');
|
||||
}
|
||||
} else {
|
||||
return $this->buildFailed(ReturnCode::LOGIN_ERROR, 'AppId或AppSecret错误');
|
||||
}
|
||||
}
|
||||
|
||||
public function groupList(): Response {
|
||||
$groupInfo = (new AdminGroup())->select();
|
||||
$apiInfo = (new AdminList())->select();
|
||||
|
||||
$listInfo = [];
|
||||
if ($this->appInfo['app_id'] === -1) {
|
||||
$_apiInfo = [];
|
||||
foreach ($apiInfo as $aVal) {
|
||||
$_apiInfo[$aVal['group_hash']][] = $aVal;
|
||||
}
|
||||
foreach ($groupInfo as $gVal) {
|
||||
if (isset($_apiInfo[$gVal['hash']])) {
|
||||
$gVal['api_info'] = $_apiInfo[$gVal['hash']];
|
||||
}
|
||||
$listInfo[] = $gVal;
|
||||
}
|
||||
} else {
|
||||
$apiInfo = Tools::buildArrFromObj($apiInfo, 'hash');
|
||||
$groupInfo = Tools::buildArrFromObj($groupInfo, 'hash');
|
||||
$app_api_show = json_decode($this->appInfo['app_api_show'], true);
|
||||
foreach ($app_api_show as $key => $item) {
|
||||
$_listInfo = $groupInfo[$key];
|
||||
foreach ($item as $apiItem) {
|
||||
$_listInfo['api_info'][] = $apiInfo[$apiItem];
|
||||
}
|
||||
if (isset($_listInfo['api_info'])) {
|
||||
$listInfo[] = $_listInfo;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this->buildSuccess([
|
||||
'data' => $listInfo,
|
||||
'co' => config('apiadmin.APP_NAME') . ' ' . config('apiadmin.APP_VERSION')
|
||||
]);
|
||||
}
|
||||
|
||||
public function detail(): Response {
|
||||
$hash = $this->request->get('hash');
|
||||
if (!$hash) {
|
||||
return $this->buildFailed(ReturnCode::NOT_EXISTS, '缺少必要参数');
|
||||
}
|
||||
|
||||
$apiList = (new AdminList())->whereIn('hash', $hash)->find();
|
||||
if (!$apiList) {
|
||||
return $this->buildFailed(ReturnCode::NOT_EXISTS, '接口hash非法');
|
||||
}
|
||||
$request = (new AdminFields())->where('hash', $hash)->where('type', 0)->select();
|
||||
$response = (new AdminFields())->where('hash', $hash)->where('type', 1)->select();
|
||||
$dataType = array(
|
||||
DataType::TYPE_INTEGER => 'Integer',
|
||||
DataType::TYPE_STRING => 'String',
|
||||
DataType::TYPE_BOOLEAN => 'Boolean',
|
||||
DataType::TYPE_ENUM => 'Enum',
|
||||
DataType::TYPE_FLOAT => 'Float',
|
||||
DataType::TYPE_FILE => 'File',
|
||||
DataType::TYPE_ARRAY => 'Array',
|
||||
DataType::TYPE_OBJECT => 'Object',
|
||||
DataType::TYPE_MOBILE => 'Mobile'
|
||||
);
|
||||
|
||||
$groupInfo = (new AdminGroup())->where('hash', $apiList['group_hash'])->find();
|
||||
$groupInfo->hot = $groupInfo->hot + 1;
|
||||
$groupInfo->save();
|
||||
|
||||
if ($apiList['hash_type'] === 1) {
|
||||
$url = $this->request->domain() . '/api/' . $apiList['api_class'];
|
||||
} else {
|
||||
$url = $this->request->domain() . '/api/' . $hash;
|
||||
}
|
||||
|
||||
return $this->buildSuccess([
|
||||
'request' => $request,
|
||||
'response' => $response,
|
||||
'dataType' => $dataType,
|
||||
'apiList' => $apiList,
|
||||
'url' => $url,
|
||||
'co' => config('apiadmin.APP_NAME') . ' ' . config('apiadmin.APP_VERSION')
|
||||
]);
|
||||
}
|
||||
|
||||
public function logout(): Response {
|
||||
$ApiAuth = $this->request->header('ApiAuth');
|
||||
cache('WikiLogin:' . $ApiAuth, null);
|
||||
cache('WikiLogin:' . $this->appInfo['id'], null);
|
||||
|
||||
$oldAdmin = cache('Login:' . $ApiAuth);
|
||||
if ($oldAdmin) {
|
||||
$oldAdmin = json_decode($oldAdmin, true);
|
||||
cache('Login:' . $ApiAuth, null);
|
||||
cache('Login:' . $oldAdmin['id'], null);
|
||||
}
|
||||
|
||||
return $this->buildSuccess([], '登出成功');
|
||||
}
|
||||
}
|
43
app/controller/wiki/Base.php
Normal file
43
app/controller/wiki/Base.php
Normal file
@ -0,0 +1,43 @@
|
||||
<?php
|
||||
declare (strict_types=1);
|
||||
/**
|
||||
* 工程基类
|
||||
* @since 2017/02/28 创建
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
|
||||
namespace app\controller\wiki;
|
||||
|
||||
use app\BaseController;
|
||||
use app\util\ReturnCode;
|
||||
use think\Response;
|
||||
|
||||
class Base extends BaseController {
|
||||
|
||||
protected $appInfo;
|
||||
|
||||
public function __construct() {
|
||||
parent::__construct(App());
|
||||
$this->appInfo = $this->request->API_WIKI_USER_INFO;
|
||||
}
|
||||
|
||||
public function buildSuccess($data = [], $msg = '操作成功', $code = ReturnCode::SUCCESS): Response {
|
||||
$return = [
|
||||
'code' => $code,
|
||||
'msg' => $msg,
|
||||
'data' => $data
|
||||
];
|
||||
|
||||
return json($return);
|
||||
}
|
||||
|
||||
public function buildFailed($code, $msg = '操作失败', $data = []): Response {
|
||||
$return = [
|
||||
'code' => $code,
|
||||
'msg' => $msg,
|
||||
'data' => $data
|
||||
];
|
||||
|
||||
return json($return);
|
||||
}
|
||||
}
|
17
app/event.php
Normal file
17
app/event.php
Normal file
@ -0,0 +1,17 @@
|
||||
<?php
|
||||
// 事件定义文件
|
||||
return [
|
||||
'bind' => [
|
||||
],
|
||||
|
||||
'listen' => [
|
||||
'AppInit' => [],
|
||||
'HttpRun' => [],
|
||||
'HttpEnd' => [],
|
||||
'LogLevel' => [],
|
||||
'LogWrite' => [],
|
||||
],
|
||||
|
||||
'subscribe' => [
|
||||
],
|
||||
];
|
10
app/middleware.php
Normal file
10
app/middleware.php
Normal file
@ -0,0 +1,10 @@
|
||||
<?php
|
||||
// 全局中间件定义文件
|
||||
return [
|
||||
// 全局请求缓存
|
||||
// \think\middleware\CheckRequestCache::class,
|
||||
// 多语言加载
|
||||
// \think\middleware\LoadLangPack::class,
|
||||
// Session初始化
|
||||
// \think\middleware\SessionInit::class
|
||||
];
|
45
app/middleware/AdminAuth.php
Normal file
45
app/middleware/AdminAuth.php
Normal file
@ -0,0 +1,45 @@
|
||||
<?php
|
||||
declare (strict_types=1);
|
||||
|
||||
namespace app\middleware;
|
||||
|
||||
use app\util\ReturnCode;
|
||||
use think\Response;
|
||||
|
||||
class AdminAuth {
|
||||
|
||||
/**
|
||||
* ApiAuth鉴权
|
||||
* @param \think\facade\Request $request
|
||||
* @param \Closure $next
|
||||
* @return mixed|\think\response\Json
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function handle($request, \Closure $next): Response {
|
||||
$header = config('apiadmin.CROSS_DOMAIN');
|
||||
$ApiAuth = $request->header('Api-Auth', '');
|
||||
if ($ApiAuth) {
|
||||
$userInfo = cache('Login:' . $ApiAuth);
|
||||
if ($userInfo) {
|
||||
$userInfo = json_decode($userInfo, true);
|
||||
}
|
||||
if (!$userInfo || !isset($userInfo['id'])) {
|
||||
return json([
|
||||
'code' => ReturnCode::AUTH_ERROR,
|
||||
'msg' => 'ApiAuth不匹配',
|
||||
'data' => []
|
||||
])->header($header);
|
||||
} else {
|
||||
$request->API_ADMIN_USER_INFO = $userInfo;
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
} else {
|
||||
return json([
|
||||
'code' => ReturnCode::AUTH_ERROR,
|
||||
'msg' => '缺少ApiAuth',
|
||||
'data' => []
|
||||
])->header($header);
|
||||
}
|
||||
}
|
||||
}
|
45
app/middleware/AdminLog.php
Normal file
45
app/middleware/AdminLog.php
Normal file
@ -0,0 +1,45 @@
|
||||
<?php
|
||||
declare (strict_types=1);
|
||||
|
||||
namespace app\middleware;
|
||||
|
||||
use app\model\AdminMenu;
|
||||
use app\model\AdminUserAction;
|
||||
use app\util\ReturnCode;
|
||||
use think\Response;
|
||||
|
||||
class AdminLog {
|
||||
|
||||
/**
|
||||
* @param \think\facade\Request $request
|
||||
* @param \Closure $next
|
||||
* @return \think\response\Json
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function handle($request, \Closure $next): Response {
|
||||
$userInfo = $request->API_ADMIN_USER_INFO;
|
||||
$menuInfo = (new AdminMenu())->where('url', $request->pathinfo())->find();
|
||||
|
||||
if ($menuInfo) {
|
||||
$menuInfo = $menuInfo->toArray();
|
||||
} else {
|
||||
|
||||
return json([
|
||||
'code' => ReturnCode::INVALID,
|
||||
'msg' => '当前路由非法:' . $request->pathinfo(),
|
||||
'data' => []
|
||||
])->header(config('apiadmin.CROSS_DOMAIN'));
|
||||
}
|
||||
|
||||
AdminUserAction::create([
|
||||
'action_name' => $menuInfo['title'],
|
||||
'uid' => $userInfo['id'],
|
||||
'nickname' => $userInfo['nickname'],
|
||||
'add_time' => time(),
|
||||
'url' => $request->pathinfo(),
|
||||
'data' => json_encode($request->param())
|
||||
]);
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
}
|
@ -1,42 +1,38 @@
|
||||
<?php
|
||||
/**
|
||||
* 处理后台接口请求权限
|
||||
* @since 2017-07-25
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
|
||||
namespace app\admin\behavior;
|
||||
declare (strict_types=1);
|
||||
|
||||
namespace app\middleware;
|
||||
|
||||
use app\model\AdminAuthGroup;
|
||||
use app\model\AdminAuthGroupAccess;
|
||||
use app\model\AdminAuthRule;
|
||||
use app\util\ReturnCode;
|
||||
use app\util\Tools;
|
||||
use think\Request;
|
||||
use think\Response;
|
||||
|
||||
class ApiPermission {
|
||||
class AdminPermission {
|
||||
|
||||
/**
|
||||
* 用户权限检测
|
||||
* @return \think\response\Json
|
||||
* @param \think\facade\Request $request
|
||||
* @param \Closure $next
|
||||
* @return mixed|\think\response\Json
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @throws \think\exception\DbException
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function run() {
|
||||
$request = Request::instance();
|
||||
$route = $request->routeInfo();
|
||||
$header = config('apiAdmin.CROSS_DOMAIN');
|
||||
$ApiAuth = $request->header('ApiAuth', '');
|
||||
$userInfo = cache('Login:' . $ApiAuth);
|
||||
$userInfo = json_decode($userInfo, true);
|
||||
if (!$this->checkAuth($userInfo['id'], $route['route'])) {
|
||||
$data = ['code' => ReturnCode::INVALID, 'msg' => '非常抱歉,您没有权限怎么做!', 'data' => []];
|
||||
|
||||
return json($data, 200, $header);
|
||||
public function handle($request, \Closure $next): Response {
|
||||
$userInfo = $request->API_ADMIN_USER_INFO;
|
||||
// rule里包含了rule(路由规则), ruoter(完整路由)
|
||||
if (!$this->checkAuth($userInfo['id'], $request->rule()->getRule())) {
|
||||
return json([
|
||||
'code' => ReturnCode::INVALID,
|
||||
'msg' => '非常抱歉,您没有权限这么做!',
|
||||
'data' => []
|
||||
])->header(config('apiadmin.CROSS_DOMAIN'));
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -58,7 +54,6 @@ class ApiPermission {
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -71,15 +66,15 @@ class ApiPermission {
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
private function getAuth($uid) {
|
||||
$groups = AdminAuthGroupAccess::get(['uid' => $uid]);
|
||||
if (isset($groups) && $groups->groupId) {
|
||||
$openGroup = (new AdminAuthGroup())->whereIn('id', $groups->groupId)->where(['status' => 1])->select();
|
||||
$groups = (new AdminAuthGroupAccess())->where('uid', $uid)->find();
|
||||
if (isset($groups) && $groups->group_id) {
|
||||
$openGroup = (new AdminAuthGroup())->whereIn('id', $groups->group_id)->where(['status' => 1])->select();
|
||||
if (isset($openGroup)) {
|
||||
$openGroupArr = [];
|
||||
foreach ($openGroup as $group) {
|
||||
$openGroupArr[] = $group->id;
|
||||
}
|
||||
$allRules = (new AdminAuthRule())->whereIn('groupId', $openGroupArr)->select();
|
||||
$allRules = (new AdminAuthRule())->whereIn('group_id', $openGroupArr)->select();
|
||||
if (isset($allRules)) {
|
||||
$rules = [];
|
||||
foreach ($allRules as $rule) {
|
||||
@ -98,6 +93,4 @@ class ApiPermission {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
14
app/middleware/AdminResponse.php
Normal file
14
app/middleware/AdminResponse.php
Normal file
@ -0,0 +1,14 @@
|
||||
<?php
|
||||
declare (strict_types=1);
|
||||
|
||||
namespace app\middleware;
|
||||
|
||||
use think\facade\Config;
|
||||
use think\Response;
|
||||
|
||||
class AdminResponse {
|
||||
|
||||
public function handle($request, \Closure $next): Response {
|
||||
return $next($request)->header(Config::get('apiadmin.CROSS_DOMAIN'));
|
||||
}
|
||||
}
|
145
app/middleware/ApiAuth.php
Normal file
145
app/middleware/ApiAuth.php
Normal file
@ -0,0 +1,145 @@
|
||||
<?php
|
||||
declare (strict_types=1);
|
||||
|
||||
namespace app\middleware;
|
||||
|
||||
use app\model\AdminApp;
|
||||
use app\model\AdminList;
|
||||
use app\util\ReturnCode;
|
||||
use think\facade\Cache;
|
||||
use think\Request;
|
||||
|
||||
class ApiAuth {
|
||||
|
||||
/**
|
||||
* 获取接口基本配置参数,校验接口Hash是否合法,校验APP_ID是否合法等
|
||||
* @param Request $request
|
||||
* @param \Closure $next
|
||||
* @return mixed|\think\response\Json
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function handle($request, \Closure $next) {
|
||||
$header = config('apiadmin.CROSS_DOMAIN');
|
||||
|
||||
$pathParam = [];
|
||||
$pathParamStr = str_replace($request->rule()->getRule() . '/', '', $request->pathinfo());
|
||||
$pathArr = explode('/', $pathParamStr);
|
||||
$pathArrLen = count($pathArr);
|
||||
for ($index = 0; $index < $pathArrLen; $index += 2) {
|
||||
if ($index + 1 < $pathArrLen) {
|
||||
$pathParam[$pathArr[$index]] = $pathArr[$index + 1];
|
||||
}
|
||||
}
|
||||
$apiHash = str_replace('api/', '', $request->rule()->getRule());
|
||||
|
||||
if ($apiHash) {
|
||||
$cached = Cache::has('ApiInfo:' . $apiHash);
|
||||
if ($cached) {
|
||||
$apiInfo = Cache::get('ApiInfo:' . $apiHash);
|
||||
} else {
|
||||
$apiInfo = (new AdminList())->where('hash', $apiHash)->where('hash_type', 2)->find();
|
||||
if ($apiInfo) {
|
||||
$apiInfo = $apiInfo->toArray();
|
||||
Cache::delete('ApiInfo:' . $apiInfo['api_class']);
|
||||
Cache::set('ApiInfo:' . $apiHash, $apiInfo);
|
||||
} else {
|
||||
$apiInfo = (new AdminList())->where('api_class', $apiHash)->where('hash_type', 1)->find();
|
||||
if ($apiInfo) {
|
||||
$apiInfo = $apiInfo->toArray();
|
||||
Cache::delete('ApiInfo:' . $apiInfo['hash']);
|
||||
Cache::set('ApiInfo:' . $apiHash, $apiInfo);
|
||||
} else {
|
||||
return json([
|
||||
'code' => ReturnCode::DB_READ_ERROR,
|
||||
'msg' => '获取接口配置数据失败',
|
||||
'data' => []
|
||||
])->header($header);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$accessToken = $request->header('Access-Token', '');
|
||||
if (!$accessToken) {
|
||||
$accessToken = $request->post('Access-Token', '');
|
||||
}
|
||||
if (!$accessToken) {
|
||||
$accessToken = $request->get('Access-Token', '');
|
||||
}
|
||||
if (!$accessToken && !empty($pathParam['Access-Token'])) {
|
||||
$accessToken = $pathParam['Access-Token'];
|
||||
}
|
||||
if (!$accessToken) {
|
||||
return json([
|
||||
'code' => ReturnCode::AUTH_ERROR,
|
||||
'msg' => '缺少必要参数Access-Token',
|
||||
'data' => []
|
||||
])->header($header);
|
||||
}
|
||||
if ($apiInfo['access_token']) {
|
||||
$appInfo = $this->doCheck($accessToken);
|
||||
} else {
|
||||
$appInfo = $this->doEasyCheck($accessToken);
|
||||
}
|
||||
if ($appInfo === false) {
|
||||
return json([
|
||||
'code' => ReturnCode::ACCESS_TOKEN_TIMEOUT,
|
||||
'msg' => 'Access-Token已过期',
|
||||
'data' => []
|
||||
])->header($header);
|
||||
}
|
||||
|
||||
$request->APP_CONF_DETAIL = $appInfo;
|
||||
$request->API_CONF_DETAIL = $apiInfo;
|
||||
|
||||
return $next($request);
|
||||
} else {
|
||||
return json([
|
||||
'code' => ReturnCode::AUTH_ERROR,
|
||||
'msg' => '缺少接口Hash',
|
||||
'data' => []
|
||||
])->header($header);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 简易鉴权,更具APP_SECRET获取应用信息
|
||||
* @param $accessToken
|
||||
* @return array|false|mixed|object|\think\App
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
private function doEasyCheck($accessToken) {
|
||||
$appInfo = cache('AccessToken:Easy:' . $accessToken);
|
||||
if (!$appInfo) {
|
||||
$appInfo = (new AdminApp())->where('app_secret', $accessToken)->find();
|
||||
if (!$appInfo) {
|
||||
return false;
|
||||
} else {
|
||||
$appInfo = $appInfo->toArray();
|
||||
cache('AccessToken:Easy:' . $accessToken, $appInfo);
|
||||
}
|
||||
}
|
||||
|
||||
return $appInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* 复杂鉴权,需要先通过接口获取AccessToken
|
||||
* @param $accessToken
|
||||
* @return bool|mixed
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
private function doCheck($accessToken) {
|
||||
$appInfo = cache('AccessToken:' . $accessToken);
|
||||
if (!$appInfo) {
|
||||
return false;
|
||||
} else {
|
||||
return $appInfo;
|
||||
}
|
||||
}
|
||||
}
|
31
app/middleware/ApiLog.php
Normal file
31
app/middleware/ApiLog.php
Normal file
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
declare (strict_types=1);
|
||||
|
||||
namespace app\middleware;
|
||||
|
||||
use app\util\ApiLogTool;
|
||||
|
||||
class ApiLog {
|
||||
|
||||
/**
|
||||
* @param $request
|
||||
* @param \Closure $next
|
||||
* @return mixed
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function handle($request, \Closure $next) {
|
||||
$response = $next($request);
|
||||
$requestInfo = $request->param();
|
||||
unset($requestInfo['API_CONF_DETAIL']);
|
||||
unset($requestInfo['APP_CONF_DETAIL']);
|
||||
|
||||
ApiLogTool::setApiInfo((array)$request->API_CONF_DETAIL);
|
||||
ApiLogTool::setAppInfo((array)$request->APP_CONF_DETAIL);
|
||||
ApiLogTool::setRequest($requestInfo);
|
||||
ApiLogTool::setResponse($response->getData(), isset($response->getData()['code']) ? strval($response->getData()['code']) : 'null');
|
||||
ApiLogTool::setHeader((array)$request->header());
|
||||
ApiLogTool::save();
|
||||
|
||||
return $response;
|
||||
}
|
||||
}
|
33
app/middleware/ApiPermission.php
Normal file
33
app/middleware/ApiPermission.php
Normal file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
declare (strict_types=1);
|
||||
|
||||
namespace app\middleware;
|
||||
|
||||
use app\util\ReturnCode;
|
||||
|
||||
class ApiPermission {
|
||||
|
||||
/**
|
||||
* 校验当前App是否有请求当前接口的权限
|
||||
* @param $request
|
||||
* @param \Closure $next
|
||||
* @return mixed|\think\response\Json
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function handle($request, \Closure $next) {
|
||||
$header = config('apiadmin.CROSS_DOMAIN');
|
||||
$appInfo = $request->APP_CONF_DETAIL;
|
||||
$apiInfo = $request->API_CONF_DETAIL;
|
||||
|
||||
$allRules = explode(',', $appInfo['app_api']);
|
||||
if (!in_array($apiInfo['hash'], $allRules)) {
|
||||
return json([
|
||||
'code' => ReturnCode::INVALID,
|
||||
'msg' => '非常抱歉,您没有权限这么做!',
|
||||
'data' => []
|
||||
])->header($header);
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
}
|
13
app/middleware/ApiResponse.php
Normal file
13
app/middleware/ApiResponse.php
Normal file
@ -0,0 +1,13 @@
|
||||
<?php
|
||||
declare (strict_types=1);
|
||||
|
||||
namespace app\middleware;
|
||||
|
||||
use think\facade\Config;
|
||||
|
||||
class ApiResponse {
|
||||
|
||||
public function handle($request, \Closure $next) {
|
||||
return $next($request)->header(Config::get('apiadmin.CROSS_DOMAIN'));
|
||||
}
|
||||
}
|
128
app/middleware/RequestFilter.php
Normal file
128
app/middleware/RequestFilter.php
Normal file
@ -0,0 +1,128 @@
|
||||
<?php
|
||||
declare (strict_types=1);
|
||||
|
||||
namespace app\middleware;
|
||||
|
||||
use app\model\AdminFields;
|
||||
use app\util\DataType;
|
||||
use app\util\ReturnCode;
|
||||
use think\facade\Cache;
|
||||
use think\facade\Validate;
|
||||
|
||||
class RequestFilter {
|
||||
|
||||
/**
|
||||
* 接口请求字段过滤【只验证数据的合法性,不再过滤数据】
|
||||
* @param $request
|
||||
* @param \Closure $next
|
||||
* @return mixed|\think\response\Json
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function handle($request, \Closure $next) {
|
||||
$apiInfo = $request->API_CONF_DETAIL;
|
||||
$data = $request->param();
|
||||
|
||||
$has = Cache::has('RequestFields:NewRule:' . $apiInfo['hash']);
|
||||
if ($has) {
|
||||
$newRule = cache('RequestFields:NewRule:' . $apiInfo['hash']);
|
||||
} else {
|
||||
$rule = (new AdminFields())->where('hash', $apiInfo['hash'])->where('type', 0)->select();
|
||||
$newRule = $this->buildValidateRule($rule);
|
||||
cache('RequestFields:NewRule:' . $apiInfo['hash'], $newRule);
|
||||
}
|
||||
|
||||
if ($newRule) {
|
||||
$validate = Validate::rule($newRule);
|
||||
if (!$validate->check($data)) {
|
||||
return json(['code' => ReturnCode::PARAM_INVALID, 'msg' => $validate->getError(), 'data' => []]);
|
||||
}
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将数据库中的规则转换成TP_Validate使用的规则数组
|
||||
* @param array $rule
|
||||
* @return array
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function buildValidateRule($rule = []) {
|
||||
$newRule = [];
|
||||
if ($rule) {
|
||||
foreach ($rule as $value) {
|
||||
if ($value['is_must']) {
|
||||
$newRule[$value['field_name'] . '|' . $value['info']][] = 'require';
|
||||
}
|
||||
switch ($value['data_type']) {
|
||||
case DataType::TYPE_INTEGER:
|
||||
$newRule[$value['field_name'] . '|' . $value['info']][] = 'number';
|
||||
if ($value['range']) {
|
||||
$range = htmlspecialchars_decode($value['range']);
|
||||
$range = json_decode($range, true);
|
||||
if (isset($range['min'])) {
|
||||
$newRule[$value['field_name'] . '|' . $value['info']]['egt'] = $range['min'];
|
||||
}
|
||||
if (isset($range['max'])) {
|
||||
$newRule[$value['field_name'] . '|' . $value['info']]['elt'] = $range['max'];
|
||||
}
|
||||
}
|
||||
break;
|
||||
case DataType::TYPE_STRING:
|
||||
if ($value['range']) {
|
||||
$range = htmlspecialchars_decode($value['range']);
|
||||
$range = json_decode($range, true);
|
||||
if (isset($range['min'])) {
|
||||
$newRule[$value['field_name'] . '|' . $value['info']]['min'] = $range['min'];
|
||||
}
|
||||
if (isset($range['max'])) {
|
||||
$newRule[$value['field_name'] . '|' . $value['info']]['max'] = $range['max'];
|
||||
}
|
||||
}
|
||||
break;
|
||||
case DataType::TYPE_ENUM:
|
||||
if ($value['range']) {
|
||||
$range = htmlspecialchars_decode($value['range']);
|
||||
$range = json_decode($range, true);
|
||||
$newRule[$value['field_name'] . '|' . $value['info']]['in'] = implode(',', $range);
|
||||
}
|
||||
break;
|
||||
case DataType::TYPE_FLOAT:
|
||||
$newRule[$value['field_name'] . '|' . $value['info']][] = 'float';
|
||||
if ($value['range']) {
|
||||
$range = htmlspecialchars_decode($value['range']);
|
||||
$range = json_decode($range, true);
|
||||
if (isset($range['min'])) {
|
||||
$newRule[$value['field_name'] . '|' . $value['info']]['egt'] = $range['min'];
|
||||
}
|
||||
if (isset($range['max'])) {
|
||||
$newRule[$value['field_name'] . '|' . $value['info']]['elt'] = $range['max'];
|
||||
}
|
||||
}
|
||||
break;
|
||||
case DataType::TYPE_ARRAY:
|
||||
$newRule[$value['field_name']][] = 'array';
|
||||
if ($value['range']) {
|
||||
$range = htmlspecialchars_decode($value['range']);
|
||||
$range = json_decode($range, true);
|
||||
if (isset($range['min'])) {
|
||||
$newRule[$value['field_name'] . '|' . $value['info']]['min'] = $range['min'];
|
||||
}
|
||||
if (isset($range['max'])) {
|
||||
$newRule[$value['field_name'] . '|' . $value['info']]['max'] = $range['max'];
|
||||
}
|
||||
}
|
||||
break;
|
||||
case DataType::TYPE_MOBILE:
|
||||
$newRule[$value['field_name'] . '|' . $value['info']]['regex'] = '/^1[3456789]\d{9}$/';
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $newRule;
|
||||
}
|
||||
}
|
47
app/middleware/WikiAuth.php
Normal file
47
app/middleware/WikiAuth.php
Normal file
@ -0,0 +1,47 @@
|
||||
<?php
|
||||
declare (strict_types=1);
|
||||
|
||||
namespace app\middleware;
|
||||
|
||||
use app\util\ReturnCode;
|
||||
|
||||
class WikiAuth {
|
||||
|
||||
/**
|
||||
* ApiAuth鉴权
|
||||
* @param \think\facade\Request $request
|
||||
* @param \Closure $next
|
||||
* @return mixed|\think\response\Json
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function handle($request, \Closure $next) {
|
||||
$header = config('apiadmin.CROSS_DOMAIN');
|
||||
$ApiAuth = $request->header('Api-Auth', '');
|
||||
if ($ApiAuth) {
|
||||
$userInfo = cache('Login:' . $ApiAuth);
|
||||
if (!$userInfo) {
|
||||
$userInfo = cache('WikiLogin:' . $ApiAuth);
|
||||
} else {
|
||||
$userInfo = json_decode($userInfo, true);
|
||||
$userInfo['app_id'] = -1;
|
||||
}
|
||||
if (!$userInfo || !isset($userInfo['id'])) {
|
||||
return json([
|
||||
'code' => ReturnCode::AUTH_ERROR,
|
||||
'msg' => 'ApiAuth不匹配',
|
||||
'data' => []
|
||||
])->header($header);
|
||||
} else {
|
||||
$request->API_WIKI_USER_INFO = $userInfo;
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
} else {
|
||||
return json([
|
||||
'code' => ReturnCode::AUTH_ERROR,
|
||||
'msg' => '缺少ApiAuth',
|
||||
'data' => []
|
||||
])->header($header);
|
||||
}
|
||||
}
|
||||
}
|
@ -2,7 +2,6 @@
|
||||
|
||||
namespace app\model;
|
||||
|
||||
|
||||
class AdminApp extends Base {
|
||||
|
||||
}
|
@ -7,7 +7,6 @@
|
||||
|
||||
namespace app\model;
|
||||
|
||||
|
||||
class AdminAppGroup extends Base {
|
||||
|
||||
}
|
17
app/model/AdminAuthGroup.php
Normal file
17
app/model/AdminAuthGroup.php
Normal file
@ -0,0 +1,17 @@
|
||||
<?php
|
||||
declare (strict_types=1);
|
||||
/**
|
||||
*
|
||||
* @since 2018-02-08
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
namespace app\model;
|
||||
|
||||
use think\model\relation\HasMany;
|
||||
|
||||
class AdminAuthGroup extends Base {
|
||||
|
||||
public function rules(): HasMany {
|
||||
return $this->hasMany('AdminAuthRule', 'group_id', 'id');
|
||||
}
|
||||
}
|
@ -7,7 +7,6 @@
|
||||
|
||||
namespace app\model;
|
||||
|
||||
|
||||
class AdminAuthGroupAccess extends Base {
|
||||
|
||||
}
|
@ -7,7 +7,6 @@
|
||||
|
||||
namespace app\model;
|
||||
|
||||
|
||||
class AdminAuthRule extends Base {
|
||||
|
||||
}
|
@ -7,7 +7,7 @@
|
||||
|
||||
namespace app\model;
|
||||
|
||||
|
||||
class AdminGroup extends Base {
|
||||
|
||||
protected $autoWriteTimestamp = true;
|
||||
}
|
@ -2,7 +2,6 @@
|
||||
|
||||
namespace app\model;
|
||||
|
||||
|
||||
class AdminMenu extends Base {
|
||||
//
|
||||
|
||||
}
|
19
app/model/AdminUser.php
Normal file
19
app/model/AdminUser.php
Normal file
@ -0,0 +1,19 @@
|
||||
<?php
|
||||
declare (strict_types=1);
|
||||
/**
|
||||
* @since 2017-11-02
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
|
||||
namespace app\model;
|
||||
|
||||
use think\model\relation\HasOne;
|
||||
|
||||
class AdminUser extends Base {
|
||||
|
||||
protected $autoWriteTimestamp = true;
|
||||
|
||||
public function userData(): HasOne {
|
||||
return $this->hasOne('AdminUserData', 'uid', 'id');
|
||||
}
|
||||
}
|
@ -7,7 +7,6 @@
|
||||
|
||||
namespace app\model;
|
||||
|
||||
|
||||
class AdminUserAction extends Base {
|
||||
|
||||
}
|
@ -6,7 +6,6 @@
|
||||
|
||||
namespace app\model;
|
||||
|
||||
|
||||
class AdminUserData extends Base {
|
||||
|
||||
}
|
@ -1,13 +1,12 @@
|
||||
<?php
|
||||
/**
|
||||
* 模型基类
|
||||
* @since 2017/07/25 创建
|
||||
*
|
||||
* @since 2019-04-23
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
|
||||
namespace app\model;
|
||||
|
||||
|
||||
use think\Model;
|
||||
|
||||
class Base extends Model {
|
9
app/provider.php
Normal file
9
app/provider.php
Normal file
@ -0,0 +1,9 @@
|
||||
<?php
|
||||
use app\ExceptionHandle;
|
||||
use app\Request;
|
||||
|
||||
// 容器Provider定义文件
|
||||
return [
|
||||
'think\Request' => Request::class,
|
||||
'think\exception\Handle' => ExceptionHandle::class,
|
||||
];
|
9
app/service.php
Normal file
9
app/service.php
Normal file
@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
use app\AppService;
|
||||
|
||||
// 系统服务定义文件
|
||||
// 服务在完成全局初始化之后执行
|
||||
return [
|
||||
AppService::class,
|
||||
];
|
138
app/util/ApiLogTool.php
Normal file
138
app/util/ApiLogTool.php
Normal file
@ -0,0 +1,138 @@
|
||||
<?php
|
||||
declare (strict_types=1);
|
||||
/**
|
||||
* @since 2017-04-14
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
|
||||
namespace app\util;
|
||||
|
||||
use think\facade\Env;
|
||||
|
||||
class ApiLogTool {
|
||||
|
||||
private static $appInfo = 'null';
|
||||
private static $apiInfo = 'null';
|
||||
private static $request = 'null';
|
||||
private static $response = 'null';
|
||||
private static $header = 'null';
|
||||
private static $userInfo = 'null';
|
||||
private static $separator = ' | ';
|
||||
|
||||
/**
|
||||
* 设置应用信息
|
||||
* @param array $data
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
* @desc appId|appName|deviceId
|
||||
*/
|
||||
public static function setAppInfo(array $data): void {
|
||||
self::$appInfo =
|
||||
($data['app_id'] ?? 'null') . self::$separator .
|
||||
($data['app_name'] ?? 'null') . self::$separator .
|
||||
($data['device_id'] ?? 'null');
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置请求头日志数据
|
||||
* @param array $data
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
* @desc accessToken|version
|
||||
*/
|
||||
public static function setHeader(array $data): void {
|
||||
$accessToken = (isset($data['access-token']) && !empty($data['access-token'])) ? $data['access-token'] : 'null';
|
||||
$version = (isset($data['version']) && !empty($data['version'])) ? $data['version'] : 'null';
|
||||
self::$header = $accessToken . self::$separator . $version;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置Api日志数据
|
||||
* @param array $data
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
* @desc hash|apiClass
|
||||
*/
|
||||
public static function setApiInfo(array $data): void {
|
||||
self::$apiInfo =
|
||||
($data['hash'] ?? 'null') . self::$separator .
|
||||
($data['api_class'] ?? 'null');
|
||||
}
|
||||
|
||||
/**
|
||||
* 这部分的日志其实很关键,但是由于不再强制检测UserToken,所以这部分日志暂时不生效,请大家各自适配
|
||||
* @param $data
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public static function setUserInfo($data): void {
|
||||
if (is_array($data) || is_object($data)) {
|
||||
$data = json_encode($data);
|
||||
self::$userInfo = $data;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置请求信息
|
||||
* @param $data
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public static function setRequest($data): void {
|
||||
if (is_array($data) || is_object($data)) {
|
||||
$data = json_encode($data);
|
||||
}
|
||||
self::$request = $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置返回的信息
|
||||
* @param $data
|
||||
* @param string $code
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
* @desc 返回码|数据
|
||||
*/
|
||||
public static function setResponse($data, string $code = ''): void {
|
||||
if (is_array($data) || is_object($data)) {
|
||||
$data = json_encode($data);
|
||||
}
|
||||
self::$response = $code . self::$separator . $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存接口日志数据
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public static function save(): void {
|
||||
$logPath = runtime_path() . 'ApiLog' . DIRECTORY_SEPARATOR;
|
||||
$logStr = implode(self::$separator, array(
|
||||
'[' . date('Y-m-d H:i:s') . ']',
|
||||
self::$apiInfo,
|
||||
self::$request,
|
||||
self::$header,
|
||||
self::$response,
|
||||
self::$appInfo,
|
||||
self::$userInfo
|
||||
));
|
||||
if (!file_exists($logPath)) {
|
||||
mkdir($logPath, 0755, true);
|
||||
}
|
||||
@file_put_contents($logPath . date('YmdH') . '.log', $logStr . "\n", FILE_APPEND);
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存日志文件
|
||||
* @param string $log 被记录的内容
|
||||
* @param string $type 日志文件名称
|
||||
* @param string $filePath
|
||||
*/
|
||||
public static function writeLog(string $log, string $type = 'sql', string $filePath = ''): void {
|
||||
if (!$filePath) {
|
||||
$filePath = runtime_path() . $type . DIRECTORY_SEPARATOR;
|
||||
} else {
|
||||
$filePath = $filePath . $type . DIRECTORY_SEPARATOR;
|
||||
}
|
||||
$filename = $filePath . date("YmdH") . ".log";
|
||||
if (!file_exists($filePath)) {
|
||||
mkdir($filePath, 0755, true);
|
||||
}
|
||||
@$handle = fopen($filename, "a+");
|
||||
@fwrite($handle, date('Y-m-d H:i:s') . "\t" . $log . "\r\n");
|
||||
@fclose($handle);
|
||||
}
|
||||
}
|
203
app/util/AutoBuild.php
Normal file
203
app/util/AutoBuild.php
Normal file
@ -0,0 +1,203 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* @since 2021-02-18
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
|
||||
namespace app\util;
|
||||
|
||||
|
||||
use app\model\AdminMenu;
|
||||
use think\facade\Db;
|
||||
|
||||
class AutoBuild {
|
||||
|
||||
private $config = [
|
||||
'model' => 0, // 是否需要构建模型
|
||||
'control' => 1, // 是否需要构建控制器
|
||||
'menu' => 1, // 是否需要构建目录
|
||||
'route' => 1, // 是否需要构建路由
|
||||
'name' => '', // 唯一标识
|
||||
'module' => 1, // 构建类型 1:admin;2:api
|
||||
'table' => 0, // 是否创建表
|
||||
'modelName' => '', // 表名称
|
||||
'fid' => 0 // 父级ID
|
||||
];
|
||||
|
||||
/**
|
||||
* 自动构建
|
||||
* @param array $config
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function run($config = []) {
|
||||
$this->config = array_merge($this->config, $config);
|
||||
|
||||
if ($this->config['model'] == 1) {
|
||||
$this->buildModel();
|
||||
|
||||
if ($this->config['table'] == 1) {
|
||||
$this->createTable();
|
||||
}
|
||||
}
|
||||
if ($this->config['control'] && $this->config['name']) {
|
||||
$this->buildControl();
|
||||
|
||||
if ($this->config['menu'] && $this->config['module'] == 1) {
|
||||
$this->buildMenu();
|
||||
}
|
||||
|
||||
if ($this->config['route'] && $this->config['module'] == 1) {
|
||||
$this->buildRoute();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 驼峰命名转下划线命名
|
||||
* @param $camelCaps
|
||||
* @param string $separator
|
||||
* @return string
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
private function unCamelize($camelCaps, $separator = '_'): string {
|
||||
return strtolower(preg_replace('/([a-z])([A-Z])/', "$1" . $separator . "$2", $camelCaps));
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建控制器
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
private function buildControl() {
|
||||
$tplPath = root_path() . 'install' . DIRECTORY_SEPARATOR;
|
||||
if ($this->config['module'] == 1) {
|
||||
$module = 'admin';
|
||||
} else {
|
||||
$module = 'api';
|
||||
}
|
||||
|
||||
$controlStr = str_replace(
|
||||
['{$MODULE}', '{$NAME}'],
|
||||
[$module, $this->config['name']],
|
||||
file_get_contents($tplPath . 'control.tpl')
|
||||
);
|
||||
file_put_contents(
|
||||
base_path() . 'controller' . DIRECTORY_SEPARATOR . $module . DIRECTORY_SEPARATOR . $this->config['name'] . '.php',
|
||||
$controlStr
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建模型
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
private function buildModel() {
|
||||
$modelStr = '<?php' . PHP_EOL;
|
||||
$modelStr .= '/**' . PHP_EOL;
|
||||
$modelStr .= ' * 由ApiAdmin自动构建' . PHP_EOL;
|
||||
$modelStr .= ' * @author apiadmin <apiadmin.org>' . PHP_EOL;
|
||||
$modelStr .= ' */' . PHP_EOL;
|
||||
$modelStr .= 'namespace app\model;' . PHP_EOL;
|
||||
$modelStr .= 'class ' . $this->config['modelName'] . ' extends Base {' . PHP_EOL;
|
||||
$modelStr .= '}' . PHP_EOL;
|
||||
|
||||
file_put_contents(
|
||||
base_path() . 'model' . DIRECTORY_SEPARATOR . $this->config['modelName'] . '.php',
|
||||
$modelStr
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建表
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
private function createTable() {
|
||||
$tableName = $this->unCamelize($this->config['modelName']);
|
||||
$cmd = "CREATE TABLE `{$tableName}` (`id` int NOT NULL AUTO_INCREMENT,PRIMARY KEY (`id`)) COMMENT='由ApiAdmin自动构建';";
|
||||
Db::execute($cmd);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建菜单
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
private function buildMenu() {
|
||||
$menus = [
|
||||
[
|
||||
'title' => '新增',
|
||||
'fid' => $this->config['fid'],
|
||||
'url' => "admin/{$this->config['name']}/add",
|
||||
'auth' => 1,
|
||||
'sort' => 0,
|
||||
'show' => 1,
|
||||
'icon' => '',
|
||||
'level' => 3,
|
||||
'component' => '',
|
||||
'router' => '',
|
||||
'log' => 1,
|
||||
'permission' => 1,
|
||||
'method' => 2
|
||||
],
|
||||
[
|
||||
'title' => '编辑',
|
||||
'fid' => $this->config['fid'],
|
||||
'url' => "admin/{$this->config['name']}/edit",
|
||||
'auth' => 1,
|
||||
'sort' => 0,
|
||||
'show' => 1,
|
||||
'icon' => '',
|
||||
'level' => 3,
|
||||
'component' => '',
|
||||
'router' => '',
|
||||
'log' => 1,
|
||||
'permission' => 1,
|
||||
'method' => 2
|
||||
],
|
||||
[
|
||||
'title' => '删除',
|
||||
'fid' => $this->config['fid'],
|
||||
'url' => "admin/{$this->config['name']}/del",
|
||||
'auth' => 1,
|
||||
'sort' => 0,
|
||||
'show' => 1,
|
||||
'icon' => '',
|
||||
'level' => 3,
|
||||
'component' => '',
|
||||
'router' => '',
|
||||
'log' => 1,
|
||||
'permission' => 1,
|
||||
'method' => 1
|
||||
],
|
||||
[
|
||||
'title' => '列表',
|
||||
'fid' => $this->config['fid'],
|
||||
'url' => "admin/{$this->config['name']}/index",
|
||||
'auth' => 1,
|
||||
'sort' => 0,
|
||||
'show' => 1,
|
||||
'icon' => '',
|
||||
'level' => 3,
|
||||
'component' => '',
|
||||
'router' => '',
|
||||
'log' => 1,
|
||||
'permission' => 1,
|
||||
'method' => 1
|
||||
]
|
||||
];
|
||||
(new AdminMenu())->insertAll($menus);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建路由
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
private function buildRoute() {
|
||||
RouterTool::buildAdminRouter();
|
||||
}
|
||||
}
|
@ -8,7 +8,6 @@
|
||||
|
||||
namespace app\util;
|
||||
|
||||
|
||||
class DataType {
|
||||
|
||||
const TYPE_INTEGER = 1;
|
||||
@ -20,5 +19,4 @@ class DataType {
|
||||
const TYPE_ENUM = 7;
|
||||
const TYPE_MOBILE = 8;
|
||||
const TYPE_OBJECT = 9;
|
||||
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
<?php
|
||||
declare (strict_types=1);
|
||||
/**
|
||||
* 错误码统一维护
|
||||
* @since 2017/02/28 创建
|
||||
@ -41,9 +42,9 @@ class ReturnCode {
|
||||
const UNKNOWN = -998;
|
||||
const EXCEPTION = -999;
|
||||
|
||||
static public function getConstants() {
|
||||
public static function getConstants(): array {
|
||||
$oClass = new \ReflectionClass(__CLASS__);
|
||||
|
||||
return $oClass->getConstants();
|
||||
}
|
||||
|
||||
}
|
107
app/util/RouterTool.php
Normal file
107
app/util/RouterTool.php
Normal file
@ -0,0 +1,107 @@
|
||||
<?php
|
||||
declare (strict_types=1);
|
||||
/**
|
||||
*
|
||||
* @since 2020-05-14
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
|
||||
namespace app\util;
|
||||
|
||||
|
||||
use app\model\AdminMenu;
|
||||
use think\App;
|
||||
|
||||
class RouterTool {
|
||||
|
||||
/**
|
||||
* 构建后端路由
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public static function buildAdminRouter(): void {
|
||||
$methodArr = ['*', 'get', 'post', 'put', 'delete'];
|
||||
$routePath = (new App())->getRootPath() . 'route' . DIRECTORY_SEPARATOR . 'app.php';
|
||||
$bakPath = (new App())->getRootPath() . 'route' . DIRECTORY_SEPARATOR . 'app.bak';
|
||||
|
||||
if (file_exists($bakPath)) {
|
||||
unlink($bakPath);
|
||||
}
|
||||
if (file_exists($routePath)) {
|
||||
rename($routePath, $bakPath);
|
||||
}
|
||||
|
||||
$context = '<?php' . PHP_EOL;
|
||||
$context .= 'use think\facade\Route;' . PHP_EOL;
|
||||
$context .= "Route::group('admin', function() {" . PHP_EOL;
|
||||
|
||||
$menus = (new AdminMenu())->select();
|
||||
if ($menus) {
|
||||
foreach ($menus as $menu) {
|
||||
$menu = $menu->toArray();
|
||||
$menuUrl = str_replace('admin/', '', $menu['url']);
|
||||
if ($menu['url']) {
|
||||
$context .= " Route::rule('{$menuUrl}', 'admin.{$menuUrl}', '"
|
||||
. $methodArr[$menu['method']] . "')" . self::getAdminMiddleware($menu) . PHP_EOL;
|
||||
}
|
||||
}
|
||||
}
|
||||
$context .= " Route::miss('admin.Miss/index');" . PHP_EOL . "});" . PHP_EOL;
|
||||
|
||||
file_put_contents($routePath, $context);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建前端路由
|
||||
* TODO::待算法优化
|
||||
* @param $menus
|
||||
* @return mixed
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public static function buildVueRouter(array &$menus): void {
|
||||
foreach ($menus as $key => $menu) {
|
||||
if (isset($menu['children'])) {
|
||||
foreach ($menu['children'] as $cKey => $child) {
|
||||
if (!isset($child['children'])) {
|
||||
unset($menus[$key]['children'][$cKey]);
|
||||
} else {
|
||||
$menus[$key]['children'][$cKey]['children'] = [];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
unset($menus[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($menus as $k => $m) {
|
||||
if (isset($m['children']) && !empty($m['children'])) {
|
||||
$menus[$k]['children'] = array_values($m['children']);
|
||||
} else {
|
||||
unset($menus[$k]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建菜单权限细节
|
||||
* @param $menu
|
||||
* @return string
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
private static function getAdminMiddleware(array $menu): string {
|
||||
$middle = ['app\middleware\AdminResponse::class'];
|
||||
if ($menu['log']) {
|
||||
array_unshift($middle, 'app\middleware\AdminLog::class');
|
||||
}
|
||||
if ($menu['permission']) {
|
||||
array_unshift($middle, 'app\middleware\AdminPermission::class');
|
||||
}
|
||||
if ($menu['auth']) {
|
||||
array_unshift($middle, 'app\middleware\AdminAuth::class');
|
||||
}
|
||||
|
||||
return '->middleware([' . implode(', ', $middle) . ']);';
|
||||
}
|
||||
}
|
185
app/util/StrRandom.php
Normal file
185
app/util/StrRandom.php
Normal file
@ -0,0 +1,185 @@
|
||||
<?php
|
||||
declare (strict_types=1);
|
||||
/**
|
||||
* 构建各类有意义的随机数
|
||||
* @since 2018-08-07
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
|
||||
namespace app\util;
|
||||
|
||||
class StrRandom {
|
||||
|
||||
/**
|
||||
* 构建一个随机浮点数
|
||||
* @param int $min 整数部分的最小值,默认值为-999999999
|
||||
* @param int $max 整数部分的最大值,默认值为999999999
|
||||
* @param int $dmin 小数部分位数的最小值,默认值为 0
|
||||
* @param int $dmax 小数部分位数的最大值,默认值为 8
|
||||
* @return float
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public static function randomFloat(int $min = -999999999, int $max = 999999999, int $dmin = 0, int $dmax = 8): float {
|
||||
$rand = '';
|
||||
$intNum = mt_rand($min, $max);
|
||||
$floatLength = mt_rand($dmin, $dmax);
|
||||
if ($floatLength > 1) {
|
||||
$rand = Strs::randString($floatLength - 1, 1);
|
||||
}
|
||||
$floatEnd = mt_rand(1, 9);
|
||||
|
||||
return floatval($intNum . '.' . $rand . $floatEnd);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取随机的时间
|
||||
* @param string $format PHP的时间日期格式化字符
|
||||
* @return false|string
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public static function randomDate(string $format = 'Y-m-d H:i:s'): string {
|
||||
$timestamp = time() - mt_rand(0, 86400 * 3650);
|
||||
|
||||
return date($format, $timestamp);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建随机IP地址
|
||||
* @return string
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public static function randomIp(): string {
|
||||
$ipLong = [
|
||||
['607649792', '608174079'], // 36.56.0.0-36.63.255.255
|
||||
['1038614528', '1039007743'], // 61.232.0.0-61.237.255.255
|
||||
['1783627776', '1784676351'], // 106.80.0.0-106.95.255.255
|
||||
['2035023872', '2035154943'], // 121.76.0.0-121.77.255.255
|
||||
['2078801920', '2079064063'], // 123.232.0.0-123.235.255.255
|
||||
['-1950089216', '-1948778497'], // 139.196.0.0-139.215.255.255
|
||||
['-1425539072', '-1425014785'], // 171.8.0.0-171.15.255.255
|
||||
['-1236271104', '-1235419137'], // 182.80.0.0-182.92.255.255
|
||||
['-770113536', '-768606209'], // 210.25.0.0-210.47.255.255
|
||||
['-569376768', '-564133889'], // 222.16.0.0-222.95.255.255
|
||||
];
|
||||
$randKey = mt_rand(0, 9);
|
||||
|
||||
return $ip = long2ip(mt_rand($ipLong[$randKey][0], $ipLong[$randKey][1]));
|
||||
}
|
||||
|
||||
/**
|
||||
* 随机生成一个 URL 协议
|
||||
* @return mixed
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail','com>
|
||||
*/
|
||||
public static function randomProtocol(): string {
|
||||
$proArr = [
|
||||
'http',
|
||||
'ftp',
|
||||
'gopher',
|
||||
'mailto',
|
||||
'mid',
|
||||
'cid',
|
||||
'news',
|
||||
'nntp',
|
||||
'prospero',
|
||||
'telnet',
|
||||
'rlogin',
|
||||
'tn3270',
|
||||
'wais'
|
||||
];
|
||||
shuffle($proArr);
|
||||
|
||||
return $proArr[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* 随机生成一个顶级域名
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail','com>
|
||||
*/
|
||||
public static function randomTld(): string {
|
||||
$tldArr = [
|
||||
'com', 'cn', 'xin', 'net', 'top', '在线',
|
||||
'xyz', 'wang', 'shop', 'site', 'club', 'cc',
|
||||
'fun', 'online', 'biz', 'red', 'link', 'ltd',
|
||||
'mobi', 'info', 'org', 'edu', 'com.cn', 'net.cn',
|
||||
'org.cn', 'gov.cn', 'name', 'vip', 'pro', 'work',
|
||||
'tv', 'co', 'kim', 'group', 'tech', 'store', 'ren',
|
||||
'ink', 'pub', 'live', 'wiki', 'design', '中文网',
|
||||
'我爱你', '中国', '网址', '网店', '公司', '网络', '集团', 'app'
|
||||
];
|
||||
shuffle($tldArr);
|
||||
|
||||
return $tldArr[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取一个随机的域名
|
||||
* @return string
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public static function randomDomain(): string {
|
||||
$len = mt_rand(6, 16);
|
||||
|
||||
return strtolower(Strs::randString($len)) . '.' . self::randomTld();
|
||||
}
|
||||
|
||||
/**
|
||||
* 随机生成一个URL
|
||||
* @param string $protocol 协议名称,可以不用指定
|
||||
* @return string
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public static function randomUrl($protocol = ''): string {
|
||||
$protocol = $protocol ? $protocol : self::randomProtocol();
|
||||
|
||||
return $protocol . '://' . self::randomDomain();
|
||||
}
|
||||
|
||||
/**
|
||||
* 随机生成一个邮箱地址
|
||||
* @param string $domain 可以指定邮箱域名
|
||||
* @return string
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public static function randomEmail($domain = ''): string {
|
||||
$len = mt_rand(6, 16);
|
||||
$domain = $domain ? $domain : self::randomDomain();
|
||||
|
||||
return Strs::randString($len) . '@' . $domain;
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static function randomPhone(): string {
|
||||
$prefixArr = [133, 153, 173, 177, 180, 181, 189, 199, 134, 135,
|
||||
136, 137, 138, 139, 150, 151, 152, 157, 158, 159, 172, 178,
|
||||
182, 183, 184, 187, 188, 198, 130, 131, 132, 155, 156, 166,
|
||||
175, 176, 185, 186, 145, 147, 149, 170, 171];
|
||||
shuffle($prefixArr);
|
||||
|
||||
return $prefixArr[0] . Strs::randString(8, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 随机创建一个身份证号码
|
||||
* @return string
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public static function randomId(): string {
|
||||
$prefixArr = [
|
||||
11, 12, 13, 14, 15,
|
||||
21, 22, 23,
|
||||
31, 32, 33, 34, 35, 36, 37,
|
||||
41, 42, 43, 44, 45, 46,
|
||||
50, 51, 52, 53, 54,
|
||||
61, 62, 63, 64, 65,
|
||||
71, 81, 82
|
||||
];
|
||||
shuffle($prefixArr);
|
||||
|
||||
$suffixArr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 'X'];
|
||||
shuffle($suffixArr);
|
||||
|
||||
return $prefixArr[0] . '0000' . self::randomDate('Ymd') . Strs::randString(3, 1) . $suffixArr[0];
|
||||
}
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
<?php
|
||||
declare (strict_types=1);
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
|
||||
// +----------------------------------------------------------------------
|
||||
@ -8,6 +9,7 @@
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: liu21st <liu21st@gmail.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\util;
|
||||
|
||||
class Strs {
|
||||
@ -17,8 +19,8 @@ class Strs {
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
static public function uuid() {
|
||||
$charId = md5(uniqid(mt_rand(), true));
|
||||
public static function uuid(): string {
|
||||
$charId = md5(uniqid(strval(mt_rand()), true));
|
||||
$hyphen = chr(45);
|
||||
$uuid = chr(123)
|
||||
. substr($charId, 0, 8) . $hyphen
|
||||
@ -35,7 +37,7 @@ class Strs {
|
||||
* 生成Guid主键
|
||||
* @return Boolean
|
||||
*/
|
||||
static public function keyGen() {
|
||||
public static function keyGen(): string {
|
||||
return str_replace('-', '', substr(self::uuid(), 1, -1));
|
||||
}
|
||||
|
||||
@ -44,7 +46,7 @@ class Strs {
|
||||
* @param string $string 字符串
|
||||
* @return Boolean
|
||||
*/
|
||||
static public function isUtf8($string) {
|
||||
public static function isUtf8($string): bool {
|
||||
$len = strlen($string);
|
||||
for ($i = 0; $i < $len; $i++) {
|
||||
$c = ord($string[$i]);
|
||||
@ -71,15 +73,15 @@ class Strs {
|
||||
|
||||
/**
|
||||
* 字符串截取,支持中文和其他编码
|
||||
* @access public
|
||||
* @param string $str 需要转换的字符串
|
||||
* @param integer $start 开始位置
|
||||
* @param string $length 截取长度
|
||||
* @param string $charset 编码格式
|
||||
* @param bool $suffix 截断显示字符
|
||||
* @param string $str
|
||||
* @param float $start
|
||||
* @param int $length
|
||||
* @param string $charset
|
||||
* @param bool $suffix
|
||||
* @return string
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
static public function mSubStr($str, $start = 0, $length, $charset = "utf-8", $suffix = true) {
|
||||
public static function mSubStr(string $str, int $length, float $start = 0, string $charset = "utf-8", bool $suffix = true): string {
|
||||
if (function_exists("mb_substr"))
|
||||
$slice = mb_substr($str, $start, $length, $charset);
|
||||
elseif (function_exists('iconv_substr')) {
|
||||
@ -100,12 +102,12 @@ class Strs {
|
||||
* 产生随机字串,可用来自动生成密码
|
||||
* 默认长度6位 字母和数字混合 支持中文
|
||||
* @param integer $len 长度
|
||||
* @param string $type 字串类型
|
||||
* @param int $type 字串类型
|
||||
* 0 字母 1 数字 其它 混合
|
||||
* @param string $addChars 额外字符
|
||||
* @return string
|
||||
*/
|
||||
static public function randString($len = 6, $type = '', $addChars = '') {
|
||||
public static function randString(int $len = 6, int $type = 0, string $addChars = ''): string {
|
||||
$str = '';
|
||||
switch ($type) {
|
||||
case 0:
|
||||
@ -137,7 +139,7 @@ class Strs {
|
||||
} else {
|
||||
// 中文随机字
|
||||
for ($i = 0; $i < $len; $i++) {
|
||||
$str .= self::msubstr($chars, floor(mt_rand(0, mb_strlen($chars, 'utf-8') - 1)), 1, 'utf-8', false);
|
||||
$str .= self::msubstr($chars, 1, floor(mt_rand(0, mb_strlen($chars, 'utf-8') - 1)), 'utf-8', false);
|
||||
}
|
||||
}
|
||||
|
||||
@ -150,14 +152,14 @@ class Strs {
|
||||
* @param integer $length 长度
|
||||
* @param integer $mode 字串类型
|
||||
* 0 字母 1 数字 其它 混合
|
||||
* @return string
|
||||
* @return array
|
||||
*/
|
||||
static public function buildCountRand($number, $length = 4, $mode = 1) {
|
||||
public static function buildCountRand(int $number, int $length = 4, int $mode = 1): array {
|
||||
if ($mode == 1 && $length < strlen($number)) {
|
||||
//不足以生成一定数量的不重复数字
|
||||
return false;
|
||||
return [];
|
||||
}
|
||||
$rand = array();
|
||||
$rand = [];
|
||||
for ($i = 0; $i < $number; $i++) {
|
||||
$rand[] = self::randString($length, $mode);
|
||||
}
|
||||
@ -180,10 +182,10 @@ class Strs {
|
||||
* @param string $format 字符格式
|
||||
* # 表示数字 * 表示字母和数字 $ 表示字母
|
||||
* @param integer $number 生成数量
|
||||
* @return string | array
|
||||
* @return array
|
||||
*/
|
||||
static public function buildFormatRand($format, $number = 1) {
|
||||
$str = array();
|
||||
public static function buildFormatRand(string $format, int $number = 1): array {
|
||||
$str = [];
|
||||
$length = strlen($format);
|
||||
for ($j = 0; $j < $number; $j++) {
|
||||
$strTemp = '';
|
||||
@ -207,7 +209,7 @@ class Strs {
|
||||
$str[] = $strTemp;
|
||||
}
|
||||
|
||||
return $number == 1 ? $strTemp : $str;
|
||||
return $str;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -216,12 +218,12 @@ class Strs {
|
||||
* @param integer $max 最大值
|
||||
* @return string
|
||||
*/
|
||||
static public function randNumber($min, $max) {
|
||||
public static function randNumber(int $min, int $max): string {
|
||||
return sprintf("%0" . strlen($max) . "d", mt_rand($min, $max));
|
||||
}
|
||||
|
||||
// 自动转换字符集 支持数组转换
|
||||
static public function autoCharset($string, $from = 'gbk', $to = 'utf-8') {
|
||||
public static function autoCharset(string $string, string $from = 'gbk', string $to = 'utf-8'): string {
|
||||
$from = strtoupper($from) == 'UTF8' ? 'utf-8' : $from;
|
||||
$to = strtoupper($to) == 'UTF8' ? 'utf-8' : $to;
|
||||
if (strtoupper($from) === strtoupper($to) || empty($string) || (is_scalar($string) && !is_string($string))) {
|
192
app/util/Tools.php
Normal file
192
app/util/Tools.php
Normal file
@ -0,0 +1,192 @@
|
||||
<?php
|
||||
declare (strict_types=1);
|
||||
/**
|
||||
*
|
||||
* @since 2017-11-01
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
|
||||
namespace app\util;
|
||||
|
||||
class Tools {
|
||||
|
||||
/**
|
||||
* 获取相对时间
|
||||
* @param int $timestamp
|
||||
* @return string
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public static function getDate(int $timestamp): string {
|
||||
$now = time();
|
||||
$diff = $now - $timestamp;
|
||||
if ($diff <= 60) {
|
||||
return $diff . '秒前';
|
||||
} elseif ($diff <= 3600) {
|
||||
return floor($diff / 60) . '分钟前';
|
||||
} elseif ($diff <= 86400) {
|
||||
return floor($diff / 3600) . '小时前';
|
||||
} elseif ($diff <= 2592000) {
|
||||
return floor($diff / 86400) . '天前';
|
||||
} else {
|
||||
return '一个月前';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 二次封装的密码加密
|
||||
* @param $str
|
||||
* @param string $auth_key
|
||||
* @return string
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public static function userMd5(string $str, string $auth_key = ''): string {
|
||||
if (!$auth_key) {
|
||||
$auth_key = config('apiadmin.AUTH_KEY');
|
||||
}
|
||||
|
||||
return '' === $str ? '' : md5(sha1($str) . $auth_key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断当前用户是否是超级管理员
|
||||
* @param int $uid
|
||||
* @return bool
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public static function isAdministrator(int $uid = 0): bool {
|
||||
if (!empty($uid)) {
|
||||
$adminConf = config('apiadmin.USER_ADMINISTRATOR');
|
||||
if (is_array($adminConf)) {
|
||||
if (is_array($uid)) {
|
||||
$m = array_intersect($adminConf, $uid);
|
||||
if (count($m)) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
if (in_array($uid, $adminConf)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (is_array($uid)) {
|
||||
if (in_array($adminConf, $uid)) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
if ($uid == $adminConf) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将查询的二维对象转换成二维数组
|
||||
* @param $res
|
||||
* @param string $key 允许指定索引值
|
||||
* @return array
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public static function buildArrFromObj($res, string $key = ''): array {
|
||||
$arr = [];
|
||||
foreach ($res as $value) {
|
||||
$value = $value->toArray();
|
||||
if ($key) {
|
||||
$arr[$value[$key]] = $value;
|
||||
} else {
|
||||
$arr[] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
return $arr;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将二维数组变成指定key
|
||||
* @param $array
|
||||
* @param string $keyName
|
||||
* @return array
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public static function buildArrByNewKey($array, string $keyName = 'id'): array {
|
||||
$list = [];
|
||||
foreach ($array as $item) {
|
||||
$list[$item[$keyName]] = $item;
|
||||
}
|
||||
|
||||
return $list;
|
||||
}
|
||||
|
||||
/**
|
||||
* 把返回的数据集转换成Tree
|
||||
* @param $list
|
||||
* @param string $pk
|
||||
* @param string $pid
|
||||
* @param string $child
|
||||
* @param string $root
|
||||
* @return array
|
||||
*/
|
||||
public static function listToTree(
|
||||
array $list,
|
||||
string $pk = 'id',
|
||||
string $pid = 'fid',
|
||||
string $child = 'children',
|
||||
string $root = '0'
|
||||
): array {
|
||||
$tree = [];
|
||||
if (is_array($list)) {
|
||||
$refer = [];
|
||||
foreach ($list as $key => $data) {
|
||||
$refer[$data[$pk]] = &$list[$key];
|
||||
}
|
||||
foreach ($list as $key => $data) {
|
||||
$parentId = $data[$pid];
|
||||
if ($root == $parentId) {
|
||||
$tree[] = &$list[$key];
|
||||
} else {
|
||||
if (isset($refer[$parentId])) {
|
||||
$parent = &$refer[$parentId];
|
||||
$parent[$child][] = &$list[$key];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $tree;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将层级数组遍历成一维数组
|
||||
* @param array $list
|
||||
* @param int $lv
|
||||
* @param string $title
|
||||
* @return array
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public static function formatTree(array $list, int $lv = 0, string $title = 'title'): array {
|
||||
$formatTree = [];
|
||||
foreach ($list as $key => $val) {
|
||||
$title_prefix = '';
|
||||
for ($i = 0; $i < $lv; $i++) {
|
||||
$title_prefix .= "|---";
|
||||
}
|
||||
$val['lv'] = $lv;
|
||||
$val['namePrefix'] = $lv == 0 ? '' : $title_prefix;
|
||||
$val['showName'] = $lv == 0 ? $val[$title] : $title_prefix . $val[$title];
|
||||
if (!array_key_exists('children', $val)) {
|
||||
array_push($formatTree, $val);
|
||||
} else {
|
||||
$child = $val['children'];
|
||||
unset($val['children']);
|
||||
array_push($formatTree, $val);
|
||||
$middle = self::formatTree($child, $lv + 1, $title); //进行下一层递归
|
||||
$formatTree = array_merge($formatTree, $middle);
|
||||
}
|
||||
}
|
||||
|
||||
return $formatTree;
|
||||
}
|
||||
}
|
@ -1,52 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* 后台操作日志记录
|
||||
* @since 2018-02-28
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
|
||||
namespace app\admin\behavior;
|
||||
|
||||
|
||||
use app\model\AdminMenu;
|
||||
use app\model\AdminUserAction;
|
||||
use app\util\ReturnCode;
|
||||
use think\Request;
|
||||
|
||||
class AdminLog {
|
||||
|
||||
/**
|
||||
* 后台操作日志记录
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
* @return \think\response\Json
|
||||
* @throws \think\Exception
|
||||
* @throws \think\exception\DbException
|
||||
*/
|
||||
public function run() {
|
||||
$header = config('apiAdmin.CROSS_DOMAIN');
|
||||
$request = Request::instance();
|
||||
$route = $request->routeInfo();
|
||||
$ApiAuth = $request->header('ApiAuth', '');
|
||||
$userInfo = cache('Login:' . $ApiAuth);
|
||||
$userInfo = json_decode($userInfo, true);
|
||||
$menuInfo = AdminMenu::get(['url' => $route['route']]);
|
||||
|
||||
if ($menuInfo) {
|
||||
$menuInfo = $menuInfo->toArray();
|
||||
} else {
|
||||
$data = ['code' => ReturnCode::INVALID, 'msg' => '当前路由非法:'. $route['route'], 'data' => []];
|
||||
|
||||
return json($data, 200, $header);
|
||||
}
|
||||
|
||||
AdminUserAction::create([
|
||||
'actionName' => $menuInfo['name'],
|
||||
'uid' => $userInfo['id'],
|
||||
'nickname' => $userInfo['nickname'],
|
||||
'addTime' => time(),
|
||||
'url' => $route['route'],
|
||||
'data' => json_encode($request->param())
|
||||
]);
|
||||
}
|
||||
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* 处理Api接入认证
|
||||
* @since 2017-07-25
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
|
||||
namespace app\admin\behavior;
|
||||
|
||||
|
||||
use app\util\ReturnCode;
|
||||
use think\Request;
|
||||
|
||||
class ApiAuth {
|
||||
|
||||
/**
|
||||
* 默认行为函数
|
||||
* @return \think\response\Json
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function run() {
|
||||
$request = Request::instance();
|
||||
$header = config('apiAdmin.CROSS_DOMAIN');
|
||||
$ApiAuth = $request->header('ApiAuth', '');
|
||||
if ($ApiAuth) {
|
||||
$userInfo = cache('Login:' . $ApiAuth);
|
||||
$userInfo = json_decode($userInfo, true);
|
||||
if (!$userInfo || !isset($userInfo['id'])) {
|
||||
$data = ['code' => ReturnCode::AUTH_ERROR, 'msg' => 'ApiAuth不匹配', 'data' => []];
|
||||
return json($data, 200, $header);
|
||||
}
|
||||
} else {
|
||||
$data = ['code' => ReturnCode::AUTH_ERROR, 'msg' => '缺少ApiAuth', 'data' => []];
|
||||
return json($data, 200, $header);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* 统一支持跨域
|
||||
* @since 2017-07-25
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
|
||||
namespace app\admin\behavior;
|
||||
|
||||
|
||||
use think\Config;
|
||||
use think\Response;
|
||||
|
||||
class BuildResponse {
|
||||
|
||||
/**
|
||||
* 返回参数过滤(主要是将返回参数的数据类型给规范)
|
||||
* @param $response
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function run(Response $response) {
|
||||
$header = Config::get('apiAdmin.CROSS_DOMAIN');
|
||||
$response->header($header);
|
||||
}
|
||||
|
||||
}
|
@ -1,299 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* 权限相关配置
|
||||
* @since 2018-02-06
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
|
||||
namespace app\admin\controller;
|
||||
|
||||
|
||||
use app\model\AdminAuthGroup;
|
||||
use app\model\AdminAuthGroupAccess;
|
||||
use app\model\AdminAuthRule;
|
||||
use app\model\AdminMenu;
|
||||
use app\util\ReturnCode;
|
||||
use app\util\Tools;
|
||||
|
||||
class Auth extends Base {
|
||||
|
||||
/**
|
||||
* 获取权限组列表
|
||||
* @return array
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @throws \think\exception\DbException
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function index() {
|
||||
|
||||
$limit = $this->request->get('size', config('apiAdmin.ADMIN_LIST_DEFAULT'));
|
||||
$start = $limit * ($this->request->get('page', 1) - 1);
|
||||
$keywords = $this->request->get('keywords', '');
|
||||
$status = $this->request->get('status', '');
|
||||
|
||||
$where['name'] = ['like', "%{$keywords}%"];
|
||||
if ($status === '1' || $status === '0') {
|
||||
$where['status'] = $status;
|
||||
}
|
||||
|
||||
$listInfo = (new AdminAuthGroup())->where($where)->order('id', 'DESC')->limit($start, $limit)->select();
|
||||
$count = (new AdminAuthGroup())->where($where)->count();
|
||||
$listInfo = Tools::buildArrFromObj($listInfo);
|
||||
|
||||
return $this->buildSuccess([
|
||||
'list' => $listInfo,
|
||||
'count' => $count
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取全部已开放的可选组
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
* @return array
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @throws \think\exception\DbException
|
||||
*/
|
||||
public function getGroups() {
|
||||
$listInfo = (new AdminAuthGroup())->where(['status' => 1])->order('id', 'DESC')->select();
|
||||
$count = count($listInfo);
|
||||
$listInfo = Tools::buildArrFromObj($listInfo);
|
||||
|
||||
return $this->buildSuccess([
|
||||
'list' => $listInfo,
|
||||
'count' => $count
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取组所在权限列表
|
||||
* @return array
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @throws \think\exception\DbException
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function getRuleList() {
|
||||
$groupId = $this->request->get('groupId', 0);
|
||||
|
||||
$list = (new AdminMenu)->where([])->order('sort', 'ASC')->select();
|
||||
$list = Tools::buildArrFromObj($list);
|
||||
$list = listToTree($list);
|
||||
|
||||
$rules = [];
|
||||
if ($groupId) {
|
||||
$rules = (new AdminAuthRule())->where(['groupId' => $groupId])->select();
|
||||
$rules = array_column($rules, 'url');
|
||||
}
|
||||
$newList = $this->buildList($list, $rules);
|
||||
|
||||
return $this->buildSuccess([
|
||||
'list' => $newList
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增组
|
||||
* @return array
|
||||
* @throws \Exception
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function add() {
|
||||
$rules = [];
|
||||
$postData = $this->request->post();
|
||||
if ($postData['rules']) {
|
||||
$rules = $postData['rules'];
|
||||
$rules = array_filter($rules);
|
||||
}
|
||||
unset($postData['rules']);
|
||||
$res = AdminAuthGroup::create($postData);
|
||||
if ($res === false) {
|
||||
return $this->buildFailed(ReturnCode::DB_SAVE_ERROR, '操作失败');
|
||||
} else {
|
||||
if ($rules) {
|
||||
$insertData = [];
|
||||
foreach ($rules as $value) {
|
||||
if ($value) {
|
||||
$insertData[] = [
|
||||
'groupId' => $res->id,
|
||||
'url' => $value
|
||||
];
|
||||
}
|
||||
}
|
||||
(new AdminAuthRule())->saveAll($insertData);
|
||||
}
|
||||
|
||||
return $this->buildSuccess([]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 权限组状态编辑
|
||||
* @return array
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function changeStatus() {
|
||||
$id = $this->request->get('id');
|
||||
$status = $this->request->get('status');
|
||||
$res = AdminAuthGroup::update([
|
||||
'id' => $id,
|
||||
'status' => $status
|
||||
]);
|
||||
if ($res === false) {
|
||||
return $this->buildFailed(ReturnCode::DB_SAVE_ERROR, '操作失败');
|
||||
} else {
|
||||
return $this->buildSuccess([]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑用户
|
||||
* @return array
|
||||
* @throws \Exception
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @throws \think\exception\DbException
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function edit() {
|
||||
$postData = $this->request->post();
|
||||
if ($postData['rules']) {
|
||||
$this->editRule();
|
||||
}
|
||||
unset($postData['rules']);
|
||||
$res = AdminAuthGroup::update($postData);
|
||||
if ($res === false) {
|
||||
return $this->buildFailed(ReturnCode::DB_SAVE_ERROR, '操作失败');
|
||||
} else {
|
||||
return $this->buildSuccess([]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除组
|
||||
* @return array
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @throws \think\exception\DbException
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function del() {
|
||||
$id = $this->request->get('id');
|
||||
if (!$id) {
|
||||
return $this->buildFailed(ReturnCode::EMPTY_PARAMS, '缺少必要参数');
|
||||
}
|
||||
|
||||
$listInfo = (new AdminAuthGroupAccess())->where(['groupId' => ['like', "%{$id}%"]])->select();
|
||||
if ($listInfo) {
|
||||
foreach ($listInfo as $value) {
|
||||
$valueArr = $value->toArray();
|
||||
$oldGroupArr = explode(',', $valueArr['groupId']);
|
||||
$key = array_search($id, $oldGroupArr);
|
||||
unset($oldGroupArr[$key]);
|
||||
$newData = implode(',', $oldGroupArr);
|
||||
$value->groupId = $newData;
|
||||
$value->save();
|
||||
}
|
||||
}
|
||||
|
||||
AdminAuthGroup::destroy($id);
|
||||
AdminAuthRule::destroy(['groupId' => $id]);
|
||||
|
||||
return $this->buildSuccess([]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从指定组中删除指定用户
|
||||
* @return array
|
||||
* @throws \think\Exception
|
||||
* @throws \think\exception\DbException
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function delMember() {
|
||||
$gid = $this->request->get('gid', 0);
|
||||
$uid = $this->request->get('uid', 0);
|
||||
if (!$gid || !$uid) {
|
||||
return $this->buildFailed(ReturnCode::EMPTY_PARAMS, '缺少必要参数');
|
||||
}
|
||||
$oldInfo = AdminAuthGroupAccess::get(['uid' => $uid])->toArray();
|
||||
$oldGroupArr = explode(',', $oldInfo['groupId']);
|
||||
$key = array_search($gid, $oldGroupArr);
|
||||
unset($oldGroupArr[$key]);
|
||||
$newData = implode(',', $oldGroupArr);
|
||||
$res = AdminAuthGroupAccess::update([
|
||||
'groupId' => $newData
|
||||
], [
|
||||
'uid' => $uid
|
||||
]);
|
||||
if ($res === false) {
|
||||
return $this->buildFailed(ReturnCode::DB_SAVE_ERROR, '操作失败');
|
||||
} else {
|
||||
return $this->buildSuccess([]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建适用前端的权限数据
|
||||
* @param $list
|
||||
* @param $rules
|
||||
* @return array
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
private function buildList($list, $rules) {
|
||||
$newList = [];
|
||||
foreach ($list as $key => $value) {
|
||||
$newList[$key]['title'] = $value['name'];
|
||||
$newList[$key]['key'] = $value['url'];
|
||||
if (isset($value['_child'])) {
|
||||
$newList[$key]['expand'] = true;
|
||||
$newList[$key]['children'] = $this->buildList($value['_child'], $rules);
|
||||
} else {
|
||||
if (in_array($value['url'], $rules)) {
|
||||
$newList[$key]['checked'] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $newList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑权限细节
|
||||
* @throws \Exception
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @throws \think\exception\DbException
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
private function editRule() {
|
||||
$postData = $this->request->post();
|
||||
$needAdd = [];
|
||||
$has = (new AdminAuthRule())->where(['groupId' => $postData['id']])->select();
|
||||
$has = Tools::buildArrFromObj($has);
|
||||
$hasRule = array_column($has, 'url');
|
||||
$needDel = array_flip($hasRule);
|
||||
foreach ($postData['rules'] as $key => $value) {
|
||||
if (!empty($value)) {
|
||||
if (!in_array($value, $hasRule)) {
|
||||
$data['url'] = $value;
|
||||
$data['groupId'] = $postData['id'];
|
||||
$needAdd[] = $data;
|
||||
} else {
|
||||
unset($needDel[$value]);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (count($needAdd)) {
|
||||
(new AdminAuthRule())->saveAll($needAdd);
|
||||
}
|
||||
if (count($needDel)) {
|
||||
$urlArr = array_keys($needDel);
|
||||
AdminAuthRule::destroy([
|
||||
'groupId' => $postData['id'],
|
||||
'url' => ['in', $urlArr]
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,57 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* 工程基类
|
||||
* @since 2017/02/28 创建
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
|
||||
namespace app\admin\controller;
|
||||
use app\util\ReturnCode;
|
||||
use think\Controller;
|
||||
|
||||
class Base extends Controller {
|
||||
|
||||
private $debug = [];
|
||||
protected $userInfo;
|
||||
|
||||
public function _initialize() {
|
||||
$ApiAuth = $this->request->header('ApiAuth');
|
||||
if ($ApiAuth) {
|
||||
$userInfo = cache('Login:' . $ApiAuth);
|
||||
$this->userInfo = json_decode($userInfo, true);
|
||||
}
|
||||
}
|
||||
|
||||
public function buildSuccess($data, $msg = '操作成功', $code = ReturnCode::SUCCESS) {
|
||||
$return = [
|
||||
'code' => $code,
|
||||
'msg' => $msg,
|
||||
'data' => $data
|
||||
];
|
||||
if ($this->debug) {
|
||||
$return['debug'] = $this->debug;
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
public function buildFailed($code, $msg, $data = []) {
|
||||
$return = [
|
||||
'code' => $code,
|
||||
'msg' => $msg,
|
||||
'data' => $data
|
||||
];
|
||||
if ($this->debug) {
|
||||
$return['debug'] = $this->debug;
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
protected function debug($data) {
|
||||
if ($data) {
|
||||
$this->debug[] = $data;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,187 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* 接口管理
|
||||
* @since 2018-02-11
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
|
||||
namespace app\admin\controller;
|
||||
|
||||
|
||||
use app\model\AdminApp;
|
||||
use app\model\AdminFields;
|
||||
use app\model\AdminList;
|
||||
use app\util\ReturnCode;
|
||||
use app\util\Tools;
|
||||
|
||||
class InterfaceList extends Base {
|
||||
/**
|
||||
* 获取接口列表
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
* @return array
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @throws \think\exception\DbException
|
||||
*/
|
||||
public function index() {
|
||||
|
||||
$limit = $this->request->get('size', config('apiAdmin.ADMIN_LIST_DEFAULT'));
|
||||
$start = $limit * ($this->request->get('page', 1) - 1);
|
||||
$keywords = $this->request->get('keywords', '');
|
||||
$type = $this->request->get('type', '');
|
||||
$status = $this->request->get('status', '');
|
||||
|
||||
$where = [];
|
||||
if ($status === '1' || $status === '0') {
|
||||
$where['status'] = $status;
|
||||
}
|
||||
if ($type) {
|
||||
switch ($type) {
|
||||
case 1:
|
||||
$where['hash'] = $keywords;
|
||||
break;
|
||||
case 2:
|
||||
$where['info'] = ['like', "%{$keywords}%"];
|
||||
break;
|
||||
case 3:
|
||||
$where['apiClass'] = ['like', "%{$keywords}%"];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$listInfo = (new AdminList())->where($where)->order('id', 'DESC')->limit($start, $limit)->select();
|
||||
$count = (new AdminList())->where($where)->count();
|
||||
$listInfo = Tools::buildArrFromObj($listInfo);
|
||||
|
||||
return $this->buildSuccess([
|
||||
'list' => $listInfo,
|
||||
'count' => $count
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取接口唯一标识
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
* @return array
|
||||
*/
|
||||
public function getHash() {
|
||||
$res['hash'] = uniqid();
|
||||
|
||||
return $this->buildSuccess($res);
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增接口
|
||||
* @return array
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function add() {
|
||||
$postData = $this->request->post();
|
||||
$res = AdminList::create($postData);
|
||||
if ($res === false) {
|
||||
return $this->buildFailed(ReturnCode::DB_SAVE_ERROR, '操作失败');
|
||||
} else {
|
||||
return $this->buildSuccess([]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 接口状态编辑
|
||||
* @return array
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function changeStatus() {
|
||||
$hash = $this->request->get('hash');
|
||||
$status = $this->request->get('status');
|
||||
$res = AdminList::update([
|
||||
'status' => $status
|
||||
], [
|
||||
'hash' => $hash
|
||||
]);
|
||||
if ($res === false) {
|
||||
return $this->buildFailed(ReturnCode::DB_SAVE_ERROR, '操作失败');
|
||||
} else {
|
||||
cache('ApiInfo:' . $hash, null);
|
||||
return $this->buildSuccess([]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑接口
|
||||
* @return array
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function edit() {
|
||||
$postData = $this->request->post();
|
||||
$res = AdminList::update($postData);
|
||||
if ($res === false) {
|
||||
return $this->buildFailed(ReturnCode::DB_SAVE_ERROR, '操作失败');
|
||||
} else {
|
||||
cache('ApiInfo:' . $postData['hash'], null);
|
||||
return $this->buildSuccess([]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除接口
|
||||
* @return array
|
||||
* @throws \think\exception\DbException
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function del() {
|
||||
$hash = $this->request->get('hash');
|
||||
if (!$hash) {
|
||||
return $this->buildFailed(ReturnCode::EMPTY_PARAMS, '缺少必要参数');
|
||||
}
|
||||
|
||||
$hashRule = AdminApp::all([
|
||||
'app_api' => ['like', "%$hash%"]
|
||||
]);
|
||||
if ($hashRule) {
|
||||
$oldInfo = AdminList::get(['hash' => $hash]);
|
||||
foreach ($hashRule as $rule) {
|
||||
$appApiArr = explode(',', $rule->app_api);
|
||||
$appApiIndex = array_search($hash, $appApiArr);
|
||||
array_splice($appApiArr, $appApiIndex, 1);
|
||||
$rule->app_api = implode(',', $appApiArr);
|
||||
|
||||
$appApiShowArrOld = json_decode($rule->app_api_show, true);
|
||||
$appApiShowArr = $appApiShowArrOld[$oldInfo->groupHash];
|
||||
$appApiShowIndex = array_search($hash, $appApiShowArr);
|
||||
array_splice($appApiShowArr, $appApiShowIndex, 1);
|
||||
$appApiShowArrOld[$oldInfo->groupHash] = $appApiShowArr;
|
||||
$rule->app_api_show = json_encode($appApiShowArrOld);
|
||||
|
||||
$rule->save();
|
||||
}
|
||||
}
|
||||
|
||||
AdminList::destroy(['hash' => $hash]);
|
||||
AdminFields::destroy(['hash' => $hash]);
|
||||
|
||||
cache('ApiInfo:' . $hash, null);
|
||||
|
||||
return $this->buildSuccess([]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 刷新接口路由
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
* @return array
|
||||
* @throws \think\exception\DbException
|
||||
*/
|
||||
public function refresh() {
|
||||
$apiRoutePath = ROOT_PATH . 'application/apiRoute.php';
|
||||
$tplPath = ROOT_PATH . 'data/apiRoute.tpl';
|
||||
$methodArr = ['*','POST','GET'];
|
||||
|
||||
$tplStr = file_get_contents($tplPath);
|
||||
$listInfo = AdminList::all(['status' => 1]);
|
||||
foreach ($listInfo as $value) {
|
||||
$tplStr .= 'Route::rule(\'api/'.$value->hash.'\',\'api/'.$value->apiClass.'\', \''.$methodArr[$value->method].'\', [\'after_behavior\' => $afterBehavior]);';
|
||||
}
|
||||
|
||||
file_put_contents($apiRoutePath, $tplStr);
|
||||
return $this->buildSuccess([]);
|
||||
}
|
||||
}
|
@ -1,76 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* 后台操作日志管理
|
||||
* @since 2018-02-06
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
|
||||
namespace app\admin\controller;
|
||||
|
||||
|
||||
use app\model\AdminAuthGroupAccess;
|
||||
use app\model\AdminUser;
|
||||
use app\model\AdminUserAction;
|
||||
use app\model\AdminUserData;
|
||||
use app\util\ReturnCode;
|
||||
use app\util\Tools;
|
||||
|
||||
class Log extends Base {
|
||||
|
||||
/**
|
||||
* 获取操作日志列表
|
||||
* @return array
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @throws \think\exception\DbException
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function index() {
|
||||
|
||||
$limit = $this->request->get('size', config('apiAdmin.ADMIN_LIST_DEFAULT'));
|
||||
$start = $limit * ($this->request->get('page', 1) - 1);
|
||||
$type = $this->request->get('type', '');
|
||||
$keywords = $this->request->get('keywords', '');
|
||||
|
||||
$where = [];
|
||||
if ($type) {
|
||||
switch ($type) {
|
||||
case 1:
|
||||
$where['url'] = ['like', "%{$keywords}%"];
|
||||
break;
|
||||
case 2:
|
||||
$where['nickname'] = ['like', "%{$keywords}%"];
|
||||
break;
|
||||
case 3:
|
||||
$where['uid'] = $keywords;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$listInfo = (new AdminUserAction())->where($where)->order('addTime', 'DESC')->limit($start, $limit)->select();
|
||||
$count = (new AdminUserAction())->where($where)->count();
|
||||
$listInfo = Tools::buildArrFromObj($listInfo);
|
||||
|
||||
return $this->buildSuccess([
|
||||
'list' => $listInfo,
|
||||
'count' => $count
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除日志
|
||||
* @return array
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function del() {
|
||||
$id = $this->request->get('id');
|
||||
if (!$id) {
|
||||
return $this->buildFailed(ReturnCode::EMPTY_PARAMS, '缺少必要参数');
|
||||
}
|
||||
AdminUserAction::destroy($id);
|
||||
|
||||
return $this->buildSuccess([]);
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,101 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* 登录登出
|
||||
* @since 2017-11-02
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
|
||||
namespace app\admin\controller;
|
||||
|
||||
|
||||
use app\model\AdminAuthGroupAccess;
|
||||
use app\model\AdminAuthRule;
|
||||
use app\model\AdminMenu;
|
||||
use app\model\AdminUser;
|
||||
use app\model\AdminUserData;
|
||||
use app\util\ReturnCode;
|
||||
use app\util\Tools;
|
||||
|
||||
class Login extends Base {
|
||||
|
||||
/**
|
||||
* 用户登录
|
||||
* @return array
|
||||
* @throws \think\Exception
|
||||
* @throws \think\exception\DbException
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function index() {
|
||||
$username = $this->request->post('username');
|
||||
$password = $this->request->post('password');
|
||||
if (!$username) {
|
||||
return $this->buildFailed(ReturnCode::LOGIN_ERROR, '缺少用户名!');
|
||||
}
|
||||
if (!$password) {
|
||||
return $this->buildFailed(ReturnCode::LOGIN_ERROR, '缺少密码!');
|
||||
} else {
|
||||
$password = Tools::userMd5($password);
|
||||
}
|
||||
$userInfo = AdminUser::get(['username' => $username, 'password' => $password]);
|
||||
if (!empty($userInfo)) {
|
||||
if ($userInfo['status']) {
|
||||
//更新用户数据
|
||||
$userData = AdminUserData::get(['uid' => $userInfo['id']]);
|
||||
$data = [];
|
||||
if ($userData) {
|
||||
$userData->loginTimes ++;
|
||||
$userData->lastLoginIp = $this->request->ip(1);
|
||||
$userData->lastLoginTime = time();
|
||||
$return['headImg'] = $userData['headImg'];
|
||||
$userData->save();
|
||||
} else {
|
||||
$data['loginTimes'] = 1;
|
||||
$data['uid'] = $userInfo['id'];
|
||||
$data['lastLoginIp'] = $this->request->ip(1);
|
||||
$data['lastLoginTime'] = time();
|
||||
$data['headImg'] = '';
|
||||
$return['headImg'] = '';
|
||||
AdminUserData::create($data);
|
||||
}
|
||||
} else {
|
||||
return $this->buildFailed(ReturnCode::LOGIN_ERROR, '用户已被封禁,请联系管理员');
|
||||
}
|
||||
} else {
|
||||
return $this->buildFailed(ReturnCode::LOGIN_ERROR, '用户名密码不正确');
|
||||
}
|
||||
$apiAuth = md5(uniqid() . time());
|
||||
cache('Login:' . $apiAuth, json_encode($userInfo), config('apiAdmin.ONLINE_TIME'));
|
||||
cache('Login:' . $userInfo['id'], $apiAuth, config('apiAdmin.ONLINE_TIME'));
|
||||
|
||||
$return['access'] = [];
|
||||
$isSupper = Tools::isAdministrator($userInfo['id']);
|
||||
if ($isSupper) {
|
||||
$access = AdminMenu::all(['hide' => 0]);
|
||||
$access = Tools::buildArrFromObj($access);
|
||||
$return['access'] = array_values(array_filter(array_column($access, 'url')));
|
||||
} else {
|
||||
$groups = AdminAuthGroupAccess::get(['uid' => $userInfo['id']]);
|
||||
if (isset($groups) || $groups->groupId) {
|
||||
$access = (new AdminAuthRule())->whereIn('groupId', $groups->groupId)->select();
|
||||
$access = Tools::buildArrFromObj($access);
|
||||
$return['access'] = array_values(array_unique(array_column($access, 'url')));
|
||||
}
|
||||
}
|
||||
|
||||
$return['id'] = $userInfo['id'];
|
||||
$return['username'] = $userInfo['username'];
|
||||
$return['nickname'] = $userInfo['nickname'];
|
||||
$return['apiAuth'] = $apiAuth;
|
||||
|
||||
return $this->buildSuccess($return, '登录成功');
|
||||
}
|
||||
|
||||
public function logout() {
|
||||
$ApiAuth = $this->request->header('ApiAuth');
|
||||
cache('Login:' . $ApiAuth, null);
|
||||
cache('Login:' . $this->userInfo['id'], null);
|
||||
|
||||
return $this->buildSuccess([], '登出成功');
|
||||
}
|
||||
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\controller;
|
||||
use app\util\ReturnCode;
|
||||
use think\Request;
|
||||
|
||||
class Miss extends Base {
|
||||
public function index() {
|
||||
if (Request::instance()->isOptions()) {
|
||||
return $this->buildSuccess([]);
|
||||
} else {
|
||||
return $this->buildFailed(ReturnCode::INVALID, '接口地址异常', []);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,274 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* 用户管理
|
||||
* @since 2018-02-06
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
|
||||
namespace app\admin\controller;
|
||||
|
||||
|
||||
use app\model\AdminAuthGroupAccess;
|
||||
use app\model\AdminUser;
|
||||
use app\model\AdminUserData;
|
||||
use app\util\ReturnCode;
|
||||
use app\util\Tools;
|
||||
|
||||
class User extends Base {
|
||||
|
||||
/**
|
||||
* 获取用户列表
|
||||
* @return array
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @throws \think\exception\DbException
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function index() {
|
||||
|
||||
$limit = $this->request->get('size', config('apiAdmin.ADMIN_LIST_DEFAULT'));
|
||||
$start = $limit * ($this->request->get('page', 1) - 1);
|
||||
$type = $this->request->get('type', '');
|
||||
$keywords = $this->request->get('keywords', '');
|
||||
$status = $this->request->get('status', '');
|
||||
|
||||
$where = [];
|
||||
if ($status === '1' || $status === '0') {
|
||||
$where['status'] = $status;
|
||||
}
|
||||
if ($type) {
|
||||
switch ($type) {
|
||||
case 1:
|
||||
$where['username'] = ['like', "%{$keywords}%"];
|
||||
break;
|
||||
case 2:
|
||||
$where['nickname'] = ['like', "%{$keywords}%"];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$listInfo = (new AdminUser())->where($where)->order('regTime', 'DESC')->limit($start, $limit)->select();
|
||||
$count = (new AdminUser())->where($where)->count();
|
||||
$listInfo = Tools::buildArrFromObj($listInfo);
|
||||
$idArr = array_column($listInfo, 'id');
|
||||
|
||||
$userData = AdminUserData::all(function($query) use ($idArr) {
|
||||
$query->whereIn('uid', $idArr);
|
||||
});
|
||||
$userData = Tools::buildArrFromObj($userData);
|
||||
$userData = Tools::buildArrByNewKey($userData, 'uid');
|
||||
|
||||
$userGroup = AdminAuthGroupAccess::all(function($query) use ($idArr) {
|
||||
$query->whereIn('uid', $idArr);
|
||||
});
|
||||
$userGroup = Tools::buildArrFromObj($userGroup);
|
||||
$userGroup = Tools::buildArrByNewKey($userGroup, 'uid');
|
||||
|
||||
foreach ($listInfo as $key => $value) {
|
||||
if (isset($userData[$value['id']])) {
|
||||
$listInfo[$key]['lastLoginIp'] = long2ip($userData[$value['id']]['lastLoginIp']);
|
||||
$listInfo[$key]['loginTimes'] = $userData[$value['id']]['loginTimes'];
|
||||
$listInfo[$key]['lastLoginTime'] = date('Y-m-d H:i:s', $userData[$value['id']]['lastLoginTime']);
|
||||
}
|
||||
$listInfo[$key]['regIp'] = long2ip($listInfo[$key]['regIp']);
|
||||
if (isset($userGroup[$value['id']])) {
|
||||
$listInfo[$key]['groupId'] = explode(',', $userGroup[$value['id']]['groupId']);
|
||||
} else {
|
||||
$listInfo[$key]['groupId'] = [];
|
||||
}
|
||||
}
|
||||
|
||||
return $this->buildSuccess([
|
||||
'list' => $listInfo,
|
||||
'count' => $count
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增用户
|
||||
* @return array
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function add() {
|
||||
$groups = '';
|
||||
$postData = $this->request->post();
|
||||
$postData['regIp'] = request()->ip(1);
|
||||
$postData['regTime'] = time();
|
||||
$postData['password'] = Tools::userMd5($postData['password']);
|
||||
if ($postData['groupId']) {
|
||||
$groups = trim(implode(',', $postData['groupId']), ',');
|
||||
}
|
||||
unset($postData['groupId']);
|
||||
$res = AdminUser::create($postData);
|
||||
if ($res === false) {
|
||||
return $this->buildFailed(ReturnCode::DB_SAVE_ERROR, '操作失败');
|
||||
} else {
|
||||
AdminAuthGroupAccess::create([
|
||||
'uid' => $res->id,
|
||||
'groupId' => $groups
|
||||
]);
|
||||
|
||||
return $this->buildSuccess([]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前组的全部用户
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
* @return array
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @throws \think\exception\DbException
|
||||
*/
|
||||
public function getUsers() {
|
||||
$limit = $this->request->get('size', config('apiAdmin.ADMIN_LIST_DEFAULT'));
|
||||
$start = $limit * ($this->request->get('page', 1) - 1);
|
||||
$gid = $this->request->get('gid', 0);
|
||||
if (!$gid) {
|
||||
return $this->buildFailed(ReturnCode::PARAM_INVALID, '非法操作');
|
||||
}
|
||||
|
||||
$listInfo = (new AdminAuthGroupAccess())->where(['groupId' => ['like', "%{$gid}%"]])->select();
|
||||
$listInfo = Tools::buildArrFromObj($listInfo);
|
||||
$uidArr = array_column($listInfo, 'uid');
|
||||
|
||||
$userInfo = (new AdminUser())->whereIn('id', $uidArr)->order('regTime', 'DESC')->limit($start, $limit)->select();
|
||||
$count = (new AdminUser())->whereIn('id', $uidArr)->count();
|
||||
$userInfo = Tools::buildArrFromObj($userInfo);
|
||||
|
||||
$userData = AdminUserData::all(function($query) use ($uidArr) {
|
||||
$query->whereIn('uid', $uidArr);
|
||||
});
|
||||
$userData = Tools::buildArrFromObj($userData);
|
||||
$userData = Tools::buildArrByNewKey($userData, 'uid');
|
||||
|
||||
foreach ($userInfo as $key => $value) {
|
||||
if (isset($userData[$value['id']])) {
|
||||
$userInfo[$key]['lastLoginIp'] = long2ip($userData[$value['id']]['lastLoginIp']);
|
||||
$userInfo[$key]['loginTimes'] = $userData[$value['id']]['loginTimes'];
|
||||
$userInfo[$key]['lastLoginTime'] = date('Y-m-d H:i:s', $userData[$value['id']]['lastLoginTime']);
|
||||
}
|
||||
$userInfo[$key]['regIp'] = long2ip($userInfo[$key]['regIp']);
|
||||
}
|
||||
|
||||
return $this->buildSuccess([
|
||||
'list' => $userInfo,
|
||||
'count' => $count
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户状态编辑
|
||||
* @return array
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function changeStatus() {
|
||||
$id = $this->request->get('id');
|
||||
$status = $this->request->get('status');
|
||||
$res = AdminUser::update([
|
||||
'id' => $id,
|
||||
'status' => $status,
|
||||
'updateTime' => time()
|
||||
]);
|
||||
if ($res === false) {
|
||||
return $this->buildFailed(ReturnCode::DB_SAVE_ERROR, '操作失败');
|
||||
} else {
|
||||
return $this->buildSuccess([]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑用户
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
* @return array
|
||||
* @throws \think\exception\DbException
|
||||
*/
|
||||
public function edit() {
|
||||
$groups = '';
|
||||
$postData = $this->request->post();
|
||||
if ($postData['password'] === 'ApiAdmin') {
|
||||
unset($postData['password']);
|
||||
} else {
|
||||
$postData['password'] = Tools::userMd5($postData['password']);
|
||||
}
|
||||
if ($postData['groupId']) {
|
||||
$groups = trim(implode(',', $postData['groupId']), ',');
|
||||
}
|
||||
$postData['updateTime'] = time();
|
||||
unset($postData['groupId']);
|
||||
$res = AdminUser::update($postData);
|
||||
if ($res === false) {
|
||||
return $this->buildFailed(ReturnCode::DB_SAVE_ERROR, '操作失败');
|
||||
} else {
|
||||
$has = AdminAuthGroupAccess::get(['uid' => $postData['id']]);
|
||||
if ($has) {
|
||||
AdminAuthGroupAccess::update([
|
||||
'groupId' => $groups
|
||||
], [
|
||||
'uid' => $postData['id'],
|
||||
]);
|
||||
} else {
|
||||
AdminAuthGroupAccess::create([
|
||||
'uid' => $postData['id'],
|
||||
'groupId' => $groups
|
||||
]);
|
||||
}
|
||||
|
||||
return $this->buildSuccess([]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改自己的信息
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
* @return array
|
||||
* @throws \think\exception\DbException
|
||||
*/
|
||||
public function own() {
|
||||
$postData = $this->request->post();
|
||||
$headImg = $postData['headImg'];
|
||||
if ($postData['password'] && $postData['oldPassword']) {
|
||||
$oldPass = Tools::userMd5($postData['oldPassword']);
|
||||
unset($postData['oldPassword']);
|
||||
if ($oldPass === $this->userInfo['password']) {
|
||||
$postData['password'] = Tools::userMd5($postData['password']);
|
||||
} else {
|
||||
return $this->buildFailed(ReturnCode::INVALID, '原始密码不正确');
|
||||
}
|
||||
} else {
|
||||
unset($postData['password']);
|
||||
unset($postData['oldPassword']);
|
||||
}
|
||||
$postData['id'] = $this->userInfo['id'];
|
||||
$postData['updateTime'] = time();
|
||||
unset($postData['headImg']);
|
||||
$res = AdminUser::update($postData);
|
||||
if ($res === false) {
|
||||
return $this->buildFailed(ReturnCode::DB_SAVE_ERROR, '操作失败');
|
||||
} else {
|
||||
$userData = AdminUserData::get(['uid' => $postData['id']]);
|
||||
$userData->headImg = $headImg;
|
||||
$userData->save();
|
||||
|
||||
return $this->buildSuccess([]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除用户
|
||||
* @return array
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function del() {
|
||||
$id = $this->request->get('id');
|
||||
if (!$id) {
|
||||
return $this->buildFailed(ReturnCode::EMPTY_PARAMS, '缺少必要参数');
|
||||
}
|
||||
AdminUser::destroy($id);
|
||||
AdminAuthGroupAccess::destroy(['uid' => $id]);
|
||||
|
||||
return $this->buildSuccess([]);
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,18 +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 <liu21st@gmail.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
// 应用行为扩展定义文件
|
||||
return [
|
||||
// 输出结束
|
||||
'response_send' => [
|
||||
'app\\admin\\behavior\\BuildResponse',
|
||||
],
|
||||
];
|
@ -1,240 +0,0 @@
|
||||
<?php
|
||||
$afterBehavior = [
|
||||
'\app\admin\behavior\ApiAuth',
|
||||
'\app\admin\behavior\ApiPermission',
|
||||
'\app\admin\behavior\AdminLog'
|
||||
];
|
||||
|
||||
return [
|
||||
'[admin]' => [
|
||||
'Login/index' => [
|
||||
'admin/Login/index',
|
||||
['method' => 'post']
|
||||
],
|
||||
'Index/upload' => [
|
||||
'admin/Index/upload',
|
||||
['method' => 'post', 'after_behavior' => ['\app\admin\behavior\ApiAuth', '\app\admin\behavior\AdminLog']]
|
||||
],
|
||||
'Login/logout' => [
|
||||
'admin/Login/logout',
|
||||
['method' => 'get', 'after_behavior' => ['\app\admin\behavior\ApiAuth', '\app\admin\behavior\AdminLog']]
|
||||
],
|
||||
'Menu/index' => [
|
||||
'admin/Menu/index',
|
||||
['method' => 'get', 'after_behavior' => $afterBehavior]
|
||||
],
|
||||
'Menu/changeStatus' => [
|
||||
'admin/Menu/changeStatus',
|
||||
['method' => 'get', 'after_behavior' => $afterBehavior]
|
||||
],
|
||||
'Menu/add' => [
|
||||
'admin/Menu/add',
|
||||
['method' => 'post', 'after_behavior' => $afterBehavior]
|
||||
],
|
||||
'Menu/edit' => [
|
||||
'admin/Menu/edit',
|
||||
['method' => 'post', 'after_behavior' => $afterBehavior]
|
||||
],
|
||||
'Menu/del' => [
|
||||
'admin/Menu/del',
|
||||
['method' => 'get', 'after_behavior' => $afterBehavior]
|
||||
],
|
||||
'User/index' => [
|
||||
'admin/User/index',
|
||||
['method' => 'get', 'after_behavior' => $afterBehavior]
|
||||
],
|
||||
'User/getUsers' => [
|
||||
'admin/User/getUsers',
|
||||
['method' => 'get', 'after_behavior' => $afterBehavior]
|
||||
],
|
||||
'User/changeStatus' => [
|
||||
'admin/User/changeStatus',
|
||||
['method' => 'get', 'after_behavior' => $afterBehavior]
|
||||
],
|
||||
'User/add' => [
|
||||
'admin/User/add',
|
||||
['method' => 'post', 'after_behavior' => $afterBehavior]
|
||||
],
|
||||
'User/own' => [
|
||||
'admin/User/own',
|
||||
['method' => 'post', 'after_behavior' => $afterBehavior]
|
||||
],
|
||||
'User/edit' => [
|
||||
'admin/User/edit',
|
||||
['method' => 'post', 'after_behavior' => $afterBehavior]
|
||||
],
|
||||
'User/del' => [
|
||||
'admin/User/del',
|
||||
['method' => 'get', 'after_behavior' => $afterBehavior]
|
||||
],
|
||||
'Auth/index' => [
|
||||
'admin/Auth/index',
|
||||
['method' => 'get', 'after_behavior' => $afterBehavior]
|
||||
],
|
||||
'Auth/changeStatus' => [
|
||||
'admin/Auth/changeStatus',
|
||||
['method' => 'get', 'after_behavior' => $afterBehavior]
|
||||
],
|
||||
'Auth/delMember' => [
|
||||
'admin/Auth/delMember',
|
||||
['method' => 'get', 'after_behavior' => $afterBehavior]
|
||||
],
|
||||
'Auth/add' => [
|
||||
'admin/Auth/add',
|
||||
['method' => 'post', 'after_behavior' => $afterBehavior]
|
||||
],
|
||||
'Auth/edit' => [
|
||||
'admin/Auth/edit',
|
||||
['method' => 'post', 'after_behavior' => $afterBehavior]
|
||||
],
|
||||
'Auth/del' => [
|
||||
'admin/Auth/del',
|
||||
['method' => 'get', 'after_behavior' => $afterBehavior]
|
||||
],
|
||||
'Auth/getGroups' => [
|
||||
'admin/Auth/getGroups',
|
||||
['method' => 'get', 'after_behavior' => $afterBehavior]
|
||||
],
|
||||
'Auth/getRuleList' => [
|
||||
'admin/Auth/getRuleList',
|
||||
['method' => 'get', 'after_behavior' => $afterBehavior]
|
||||
],
|
||||
'App/index' => [
|
||||
'admin/App/index',
|
||||
['method' => 'get', 'after_behavior' => $afterBehavior]
|
||||
],
|
||||
'App/changeStatus' => [
|
||||
'admin/App/changeStatus',
|
||||
['method' => 'get', 'after_behavior' => $afterBehavior]
|
||||
],
|
||||
'App/getAppInfo' => [
|
||||
'admin/App/getAppInfo',
|
||||
['method' => 'get', 'after_behavior' => $afterBehavior]
|
||||
],
|
||||
'App/add' => [
|
||||
'admin/App/add',
|
||||
['method' => 'post', 'after_behavior' => $afterBehavior]
|
||||
],
|
||||
'App/edit' => [
|
||||
'admin/App/edit',
|
||||
['method' => 'post', 'after_behavior' => $afterBehavior]
|
||||
],
|
||||
'App/del' => [
|
||||
'admin/App/del',
|
||||
['method' => 'get', 'after_behavior' => $afterBehavior]
|
||||
],
|
||||
'InterfaceList/index' => [
|
||||
'admin/InterfaceList/index',
|
||||
['method' => 'get', 'after_behavior' => $afterBehavior]
|
||||
],
|
||||
'InterfaceList/refresh' => [
|
||||
'admin/InterfaceList/refresh',
|
||||
['method' => 'get', 'after_behavior' => $afterBehavior]
|
||||
],
|
||||
'InterfaceList/changeStatus' => [
|
||||
'admin/InterfaceList/changeStatus',
|
||||
['method' => 'get', 'after_behavior' => $afterBehavior]
|
||||
],
|
||||
'InterfaceList/getHash' => [
|
||||
'admin/InterfaceList/getHash',
|
||||
['method' => 'get', 'after_behavior' => $afterBehavior]
|
||||
],
|
||||
'InterfaceList/add' => [
|
||||
'admin/InterfaceList/add',
|
||||
['method' => 'post', 'after_behavior' => $afterBehavior]
|
||||
],
|
||||
'InterfaceList/edit' => [
|
||||
'admin/InterfaceList/edit',
|
||||
['method' => 'post', 'after_behavior' => $afterBehavior]
|
||||
],
|
||||
'InterfaceList/del' => [
|
||||
'admin/InterfaceList/del',
|
||||
['method' => 'get', 'after_behavior' => $afterBehavior]
|
||||
],
|
||||
'Fields/index' => [
|
||||
'admin/Fields/index',
|
||||
['method' => 'get', 'after_behavior' => $afterBehavior]
|
||||
],
|
||||
'Fields/request' => [
|
||||
'admin/Fields/request',
|
||||
['method' => 'get', 'after_behavior' => $afterBehavior]
|
||||
],
|
||||
'Fields/response' => [
|
||||
'admin/Fields/response',
|
||||
['method' => 'get', 'after_behavior' => $afterBehavior]
|
||||
],
|
||||
'Fields/add' => [
|
||||
'admin/Fields/add',
|
||||
['method' => 'post', 'after_behavior' => $afterBehavior]
|
||||
],
|
||||
'Fields/upload' => [
|
||||
'admin/Fields/upload',
|
||||
['method' => 'post', 'after_behavior' => $afterBehavior]
|
||||
],
|
||||
'Fields/edit' => [
|
||||
'admin/Fields/edit',
|
||||
['method' => 'post', 'after_behavior' => $afterBehavior]
|
||||
],
|
||||
'Fields/del' => [
|
||||
'admin/Fields/del',
|
||||
['method' => 'get', 'after_behavior' => $afterBehavior]
|
||||
],
|
||||
'InterfaceGroup/index' => [
|
||||
'admin/InterfaceGroup/index',
|
||||
['method' => 'get', 'after_behavior' => $afterBehavior]
|
||||
],
|
||||
'InterfaceGroup/add' => [
|
||||
'admin/InterfaceGroup/add',
|
||||
['method' => 'post', 'after_behavior' => $afterBehavior]
|
||||
],
|
||||
'InterfaceGroup/edit' => [
|
||||
'admin/InterfaceGroup/edit',
|
||||
['method' => 'post', 'after_behavior' => $afterBehavior]
|
||||
],
|
||||
'InterfaceGroup/del' => [
|
||||
'admin/InterfaceGroup/del',
|
||||
['method' => 'get', 'after_behavior' => $afterBehavior]
|
||||
],
|
||||
'InterfaceGroup/getAll' => [
|
||||
'admin/InterfaceGroup/getAll',
|
||||
['method' => 'get', 'after_behavior' => $afterBehavior]
|
||||
],
|
||||
'InterfaceGroup/changeStatus' => [
|
||||
'admin/InterfaceGroup/changeStatus',
|
||||
['method' => 'get', 'after_behavior' => $afterBehavior]
|
||||
],
|
||||
'AppGroup/index' => [
|
||||
'admin/AppGroup/index',
|
||||
['method' => 'get', 'after_behavior' => $afterBehavior]
|
||||
],
|
||||
'AppGroup/add' => [
|
||||
'admin/AppGroup/add',
|
||||
['method' => 'post', 'after_behavior' => $afterBehavior]
|
||||
],
|
||||
'AppGroup/edit' => [
|
||||
'admin/AppGroup/edit',
|
||||
['method' => 'post', 'after_behavior' => $afterBehavior]
|
||||
],
|
||||
'AppGroup/del' => [
|
||||
'admin/AppGroup/del',
|
||||
['method' => 'get', 'after_behavior' => $afterBehavior]
|
||||
],
|
||||
'AppGroup/getAll' => [
|
||||
'admin/AppGroup/getAll',
|
||||
['method' => 'get', 'after_behavior' => $afterBehavior]
|
||||
],
|
||||
'AppGroup/changeStatus' => [
|
||||
'admin/AppGroup/changeStatus',
|
||||
['method' => 'get', 'after_behavior' => $afterBehavior]
|
||||
],
|
||||
'Log/index' => [
|
||||
'admin/Log/index',
|
||||
['method' => 'get', 'after_behavior' => $afterBehavior]
|
||||
],
|
||||
'Log/del' => [
|
||||
'admin/Log/del',
|
||||
['method' => 'get', 'after_behavior' => $afterBehavior]
|
||||
],
|
||||
'__miss__' => ['admin/Miss/index'],
|
||||
],
|
||||
];
|
@ -1,122 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* 处理Api接入认证
|
||||
* @since 2017-07-25
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
|
||||
namespace app\api\behavior;
|
||||
|
||||
|
||||
use app\model\AdminList;
|
||||
use app\util\ApiLog;
|
||||
use app\util\ReturnCode;
|
||||
use think\Cache;
|
||||
use think\Request;
|
||||
|
||||
class ApiAuth {
|
||||
|
||||
/**
|
||||
* @var Request
|
||||
*/
|
||||
private $request;
|
||||
private $apiInfo;
|
||||
|
||||
/**
|
||||
* 默认行为函数
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
* @return \think\response\Json
|
||||
* @throws \think\Exception
|
||||
* @throws \think\exception\DbException
|
||||
*/
|
||||
public function run() {
|
||||
$this->request = Request::instance();
|
||||
$hash = $this->request->routeInfo();
|
||||
if (isset($hash['rule'][1])) {
|
||||
$hash = $hash['rule'][1];
|
||||
|
||||
$cached = Cache::has('ApiInfo:' . $hash);
|
||||
if ($cached) {
|
||||
$this->apiInfo = Cache::get('ApiInfo:' . $hash);
|
||||
} else {
|
||||
$apiInfo = AdminList::get(['hash' => $hash]);
|
||||
if ($apiInfo) {
|
||||
$this->apiInfo = $apiInfo->toArray();
|
||||
Cache::set('ApiInfo:' . $hash, $this->apiInfo);
|
||||
} else {
|
||||
return json(['code' => ReturnCode::DB_READ_ERROR, 'msg' => '获取接口配置数据失1败', 'data' => []]);
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->apiInfo['accessToken'] && !$this->apiInfo['isTest']) {
|
||||
$accessRes = $this->checkAccessToken();
|
||||
if ($accessRes) {
|
||||
return $accessRes;
|
||||
}
|
||||
}
|
||||
if (!$this->apiInfo['isTest']) {
|
||||
$versionRes = $this->checkVersion();
|
||||
if ($versionRes) {
|
||||
return $versionRes;
|
||||
}
|
||||
}
|
||||
$loginRes = $this->checkLogin();
|
||||
if ($loginRes) {
|
||||
return $loginRes;
|
||||
}
|
||||
|
||||
ApiLog::setApiInfo($this->apiInfo);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Api接口合法性检测
|
||||
*/
|
||||
private function checkAccessToken() {
|
||||
$access_token = $this->request->header('access-token');
|
||||
if (!isset($access_token) || !$access_token) {
|
||||
return json(['code' => ReturnCode::ACCESS_TOKEN_TIMEOUT, 'msg' => '缺少参数access-token', 'data' => []]);
|
||||
} else {
|
||||
$appInfo = cache('AccessToken:' . $access_token);
|
||||
if (!$appInfo) {
|
||||
return json(['code' => ReturnCode::ACCESS_TOKEN_TIMEOUT, 'msg' => 'access-token已过期', 'data' => []]);
|
||||
}
|
||||
ApiLog::setAppInfo($appInfo);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Api版本参数校验
|
||||
*/
|
||||
private function checkVersion() {
|
||||
$version = $this->request->header('version');
|
||||
if (!isset($version) || !$version) {
|
||||
return json(['code' => ReturnCode::EMPTY_PARAMS, 'msg' => '缺少参数version', 'data' => []]);
|
||||
} else {
|
||||
if ($version != config('apiAdmin.APP_VERSION')) {
|
||||
return json(['code' => ReturnCode::VERSION_INVALID, 'msg' => 'API版本不匹配', 'data' => []]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO::需要根据实际情况另外改写
|
||||
* 检测用户登录情况 检测通过请赋予USER_INFO值
|
||||
*/
|
||||
private function checkLogin() {
|
||||
$userToken = $this->request->header('user-token', '');
|
||||
if ($this->apiInfo['needLogin']) {
|
||||
if (!$userToken) {
|
||||
return json(['code' => ReturnCode::AUTH_ERROR, 'msg' => '缺少user-token', 'data' => []]);
|
||||
}
|
||||
}
|
||||
if ($userToken) {
|
||||
$userInfo = cache('wx:openId:' . $userToken);
|
||||
if (!is_array($userInfo) || !isset($userInfo['openId'])) {
|
||||
return json(['code' => ReturnCode::AUTH_ERROR, 'msg' => 'user-token不匹配', 'data' => []]);
|
||||
}
|
||||
ApiLog::setUserInfo($userInfo);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* 处理app_id接入接口权限 需要重新签发AccessToken才能生效新的权限
|
||||
* @since 2017-07-25
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
|
||||
namespace app\api\behavior;
|
||||
|
||||
|
||||
use app\util\ReturnCode;
|
||||
use think\Request;
|
||||
|
||||
class ApiPermission {
|
||||
|
||||
/**
|
||||
* @var Request
|
||||
*/
|
||||
private $request;
|
||||
|
||||
/**
|
||||
* 接口鉴权
|
||||
* @return \think\response\Json
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function run() {
|
||||
$this->request = Request::instance();
|
||||
$hash = $this->request->routeInfo();
|
||||
if (isset($hash['rule'][1])) {
|
||||
$hash = $hash['rule'][1];
|
||||
$access_token = $this->request->header('access-token');
|
||||
if ($access_token) {
|
||||
$appInfo = cache('AccessToken:' . $access_token);
|
||||
$allRules = explode(',', $appInfo['app_api']);
|
||||
if (!in_array($hash, $allRules)) {
|
||||
$data = ['code' => ReturnCode::INVALID, 'msg' => '非常抱歉,您没有权限怎么做!', 'data' => []];
|
||||
|
||||
return json($data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -1,97 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* 输出结果规整
|
||||
* @since 2017-07-25
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
|
||||
namespace app\api\behavior;
|
||||
|
||||
|
||||
use app\model\AdminFields;
|
||||
use app\util\ApiLog;
|
||||
use app\util\DataType;
|
||||
use think\Cache;
|
||||
use think\Request;
|
||||
|
||||
class BuildResponse {
|
||||
|
||||
/**
|
||||
* 返回参数过滤(主要是将返回参数的数据类型给规范)
|
||||
* @param $response \think\Response
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
* @throws \think\exception\DbException
|
||||
*/
|
||||
public function run($response) {
|
||||
$data = $response->getData();
|
||||
$request = Request::instance();
|
||||
$hash = $request->routeInfo();
|
||||
if (isset($hash['rule'][1])) {
|
||||
$hash = $hash['rule'][1];
|
||||
|
||||
$has = Cache::has('ResponseFieldsRule:' . $hash);
|
||||
if ($has) {
|
||||
$rule = cache('ResponseFieldsRule:' . $hash);
|
||||
} else {
|
||||
$rule = AdminFields::all(['hash' => $hash, 'type' => 1]);
|
||||
cache('ResponseFieldsRule:' . $hash, $rule);
|
||||
}
|
||||
|
||||
if ($rule) {
|
||||
$rule = json_decode(json_encode($rule), true);
|
||||
$newRule = array_column($rule, 'dataType', 'showName');
|
||||
if (is_array($data)) {
|
||||
$this->handle($data['data'], $newRule);
|
||||
} elseif (empty($data)) {
|
||||
if ($newRule['data'] == DataType::TYPE_OBJECT) {
|
||||
$data = (object)[];
|
||||
} elseif ($newRule['data'] == DataType::TYPE_ARRAY) {
|
||||
$data = [];
|
||||
}
|
||||
}
|
||||
$response->data($data);
|
||||
}
|
||||
}
|
||||
ApiLog::setResponse($data);
|
||||
ApiLog::save();
|
||||
}
|
||||
|
||||
private function handle(&$data, $rule, $prefix = 'data') {
|
||||
if (empty($data)) {
|
||||
if ($rule[$prefix] == DataType::TYPE_OBJECT) {
|
||||
$data = (object)[];
|
||||
}
|
||||
} else {
|
||||
if ($rule[$prefix] == DataType::TYPE_OBJECT) {
|
||||
$prefix .= '{}';
|
||||
foreach ($data as $index => &$datum) {
|
||||
$myPre = $prefix . $index;
|
||||
if (isset($rule[$myPre])) {
|
||||
switch ($rule[$myPre]) {
|
||||
case DataType::TYPE_INTEGER:
|
||||
$datum = intval($datum);
|
||||
break;
|
||||
case DataType::TYPE_FLOAT:
|
||||
$datum = floatval($datum);
|
||||
break;
|
||||
case DataType::TYPE_STRING:
|
||||
$datum = strval($datum);
|
||||
break;
|
||||
default:
|
||||
$this->handle($datum, $rule, $myPre);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$prefix .= '[]';
|
||||
if (is_array($data[0])) {
|
||||
foreach ($data as &$datum) {
|
||||
$this->handle($datum, $rule, $prefix);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,177 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* 输入参数过滤行为
|
||||
* @since 2017-07-25
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
|
||||
namespace app\api\behavior;
|
||||
|
||||
|
||||
use app\model\AdminFields;
|
||||
use app\util\ApiLog;
|
||||
use app\util\ReturnCode;
|
||||
use app\util\DataType;
|
||||
use think\Cache;
|
||||
use think\Request;
|
||||
use think\Validate;
|
||||
|
||||
class RequestFilter {
|
||||
|
||||
/**
|
||||
* 默认行为函数
|
||||
* @throws \think\exception\DbException
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public function run() {
|
||||
$request = Request::instance();
|
||||
$method = strtoupper($request->method());
|
||||
switch ($method) {
|
||||
case 'GET':
|
||||
$data = $request->get();
|
||||
break;
|
||||
case 'POST':
|
||||
$data = $request->post();
|
||||
break;
|
||||
case 'DELETE':
|
||||
$data = $request->delete();
|
||||
break;
|
||||
case 'PUT':
|
||||
$data = $request->put();
|
||||
break;
|
||||
default :
|
||||
$data = [];
|
||||
break;
|
||||
}
|
||||
ApiLog::setRequest($data);
|
||||
$hash = $request->routeInfo();
|
||||
if (isset($hash['rule'][1])) {
|
||||
$hash = $hash['rule'][1];
|
||||
|
||||
$has = Cache::has('RequestFields:NewRule:' . $hash);
|
||||
if ($has) {
|
||||
$newRule = cache('RequestFields:NewRule:' . $hash);
|
||||
$rule = cache('RequestFields:Rule:' . $hash);
|
||||
} else {
|
||||
$rule = AdminFields::all(['hash' => $hash, 'type' => 0]);
|
||||
$newRule = $this->buildValidateRule($rule);
|
||||
cache('RequestFields:NewRule:' . $hash, $newRule);
|
||||
cache('RequestFields:Rule:' . $hash, $rule);
|
||||
}
|
||||
|
||||
if ($newRule) {
|
||||
$validate = new Validate($newRule);
|
||||
if (!$validate->check($data)) {
|
||||
return json(['code' => ReturnCode::PARAM_INVALID, 'msg' => $validate->getError(), 'data' => []]);
|
||||
}
|
||||
}
|
||||
|
||||
$newData = [];
|
||||
foreach ($rule as $item) {
|
||||
$newData[$item['fieldName']] = $data[$item['fieldName']];
|
||||
if (!$item['isMust'] && $item['default'] !== '' && !isset($data[$item['fieldName']])) {
|
||||
$newData[$item['fieldName']] = $item['default'];
|
||||
}
|
||||
}
|
||||
|
||||
switch ($method) {
|
||||
case 'GET':
|
||||
$request->get($newData);
|
||||
break;
|
||||
case 'POST':
|
||||
$request->post($newData);
|
||||
break;
|
||||
case 'DELETE':
|
||||
$request->delete($newData);
|
||||
break;
|
||||
case 'PUT':
|
||||
$request->put($newData);
|
||||
break;
|
||||
}
|
||||
ApiLog::setRequestAfterFilter($newData);
|
||||
}
|
||||
ApiLog::setHeader($request->header());
|
||||
}
|
||||
|
||||
/**
|
||||
* 将数据库中的规则转换成TP_Validate使用的规则数组
|
||||
* @param array $rule
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
* @return array
|
||||
*/
|
||||
public function buildValidateRule($rule = array()) {
|
||||
$newRule = [];
|
||||
if ($rule) {
|
||||
foreach ($rule as $value) {
|
||||
if ($value['isMust']) {
|
||||
$newRule[$value['fieldName']][] = 'require';
|
||||
}
|
||||
switch ($value['dataType']) {
|
||||
case DataType::TYPE_INTEGER:
|
||||
$newRule[$value['fieldName']][] = 'number';
|
||||
if ($value['range']) {
|
||||
$range = htmlspecialchars_decode($value['range']);
|
||||
$range = json_decode($range, true);
|
||||
if (isset($range['min'])) {
|
||||
$newRule[$value['fieldName']]['egt'] = $range['min'];
|
||||
}
|
||||
if (isset($range['max'])) {
|
||||
$newRule[$value['fieldName']]['elt'] = $range['max'];
|
||||
}
|
||||
}
|
||||
break;
|
||||
case DataType::TYPE_STRING:
|
||||
if ($value['range']) {
|
||||
$range = htmlspecialchars_decode($value['range']);
|
||||
$range = json_decode($range, true);
|
||||
if (isset($range['min'])) {
|
||||
$newRule[$value['fieldName']]['min'] = $range['min'];
|
||||
}
|
||||
if (isset($range['max'])) {
|
||||
$newRule[$value['fieldName']]['max'] = $range['max'];
|
||||
}
|
||||
}
|
||||
break;
|
||||
case DataType::TYPE_ENUM:
|
||||
if ($value['range']) {
|
||||
$range = htmlspecialchars_decode($value['range']);
|
||||
$range = json_decode($range, true);
|
||||
$newRule[$value['fieldName']]['in'] = implode(',', $range);
|
||||
}
|
||||
break;
|
||||
case DataType::TYPE_FLOAT:
|
||||
$newRule[$value['fieldName']][] = 'float';
|
||||
if ($value['range']) {
|
||||
$range = htmlspecialchars_decode($value['range']);
|
||||
$range = json_decode($range, true);
|
||||
if (isset($range['min'])) {
|
||||
$newRule[$value['fieldName']]['egt'] = $range['min'];
|
||||
}
|
||||
if (isset($range['max'])) {
|
||||
$newRule[$value['fieldName']]['elt'] = $range['max'];
|
||||
}
|
||||
}
|
||||
break;
|
||||
case DataType::TYPE_ARRAY:
|
||||
$newRule[$value['fieldName']][] = 'array';
|
||||
if ($value['range']) {
|
||||
$range = htmlspecialchars_decode($value['range']);
|
||||
$range = json_decode($range, true);
|
||||
if (isset($range['min'])) {
|
||||
$newRule[$value['fieldName']]['min'] = $range['min'];
|
||||
}
|
||||
if (isset($range['max'])) {
|
||||
$newRule[$value['fieldName']]['max'] = $range['max'];
|
||||
}
|
||||
}
|
||||
break;
|
||||
case DataType::TYPE_MOBILE:
|
||||
$newRule[$value['fieldName']]['regex'] = '/^1[34578]\d{9}$/';
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $newRule;
|
||||
}
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace app\api\controller;
|
||||
|
||||
|
||||
class Index extends Base {
|
||||
public function index() {
|
||||
$this->debug([
|
||||
'TpVersion' => THINK_VERSION
|
||||
]);
|
||||
|
||||
return $this->buildSuccess([
|
||||
'Product' => config('apiAdmin.APP_NAME'),
|
||||
'Version' => config('apiAdmin.APP_VERSION'),
|
||||
'Company' => config('apiAdmin.COMPANY_NAME'),
|
||||
'ToYou' => "I'm glad to meet you(终于等到你!)"
|
||||
]);
|
||||
}
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace app\api\controller;
|
||||
|
||||
|
||||
use app\util\ReturnCode;
|
||||
|
||||
class Miss extends Base {
|
||||
public function index() {
|
||||
return $this->buildFailed(ReturnCode::NOT_EXISTS, '接口Hash异常');
|
||||
}
|
||||
}
|
@ -1,18 +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 <liu21st@gmail.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
// 应用行为扩展定义文件
|
||||
return [
|
||||
// 输出结束
|
||||
'response_send' => [
|
||||
'app\\api\\behavior\\BuildResponse',
|
||||
],
|
||||
];
|
@ -1,8 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Api路由
|
||||
*/
|
||||
use think\Route;
|
||||
|
||||
Route::miss('api/Index/index');
|
||||
$afterBehavior = ['\app\api\behavior\ApiAuth', '\app\api\behavior\ApiPermission', '\app\api\behavior\RequestFilter'];
|
@ -1,12 +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 [];
|
@ -1,65 +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>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
// 应用公共文件
|
||||
/**
|
||||
* 把返回的数据集转换成Tree
|
||||
* @param $list
|
||||
* @param string $pk
|
||||
* @param string $pid
|
||||
* @param string $child
|
||||
* @param string $root
|
||||
* @return array
|
||||
*/
|
||||
function listToTree($list, $pk='id', $pid = 'fid', $child = '_child', $root = '0') {
|
||||
$tree = array();
|
||||
if(is_array($list)) {
|
||||
$refer = array();
|
||||
foreach ($list as $key => $data) {
|
||||
$refer[$data[$pk]] = &$list[$key];
|
||||
}
|
||||
foreach ($list as $key => $data) {
|
||||
$parentId = $data[$pid];
|
||||
if ($root == $parentId) {
|
||||
$tree[] = &$list[$key];
|
||||
}else{
|
||||
if (isset($refer[$parentId])) {
|
||||
$parent = &$refer[$parentId];
|
||||
$parent[$child][] = &$list[$key];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $tree;
|
||||
}
|
||||
|
||||
function formatTree($list, $lv = 0, $title = 'name'){
|
||||
$formatTree = array();
|
||||
foreach($list as $key => $val){
|
||||
$title_prefix = '';
|
||||
for( $i=0;$i<$lv;$i++ ){
|
||||
$title_prefix .= "|---";
|
||||
}
|
||||
$val['lv'] = $lv;
|
||||
$val['namePrefix'] = $lv == 0 ? '' : $title_prefix;
|
||||
$val['showName'] = $lv == 0 ? $val[$title] : $title_prefix.$val[$title];
|
||||
if(!array_key_exists('_child', $val)){
|
||||
array_push($formatTree, $val);
|
||||
}else{
|
||||
$child = $val['_child'];
|
||||
unset($val['_child']);
|
||||
array_push($formatTree, $val);
|
||||
$middle = formatTree($child, $lv+1, $title); //进行下一层递归
|
||||
$formatTree = array_merge($formatTree, $middle);
|
||||
}
|
||||
}
|
||||
return $formatTree;
|
||||
}
|
@ -1,241 +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_namespace' => 'app',
|
||||
// 应用调试模式
|
||||
'app_debug' => true,
|
||||
// 应用Trace
|
||||
'app_trace' => false,
|
||||
// 应用模式状态
|
||||
'app_status' => '',
|
||||
// 是否支持多模块
|
||||
'app_multi_module' => true,
|
||||
// 入口自动绑定模块
|
||||
'auto_bind_module' => false,
|
||||
// 注册的根命名空间
|
||||
'root_namespace' => [],
|
||||
// 扩展函数文件
|
||||
'extra_file_list' => [THINK_PATH . 'helper' . EXT],
|
||||
// 默认输出类型
|
||||
'default_return_type' => 'json',
|
||||
// 默认AJAX 数据返回格式,可选json xml ...
|
||||
'default_ajax_return' => 'json',
|
||||
// 默认JSONP格式返回的处理方法
|
||||
'default_jsonp_handler' => 'jsonpReturn',
|
||||
// 默认JSONP处理方法
|
||||
'var_jsonp_handler' => 'callback',
|
||||
// 默认时区
|
||||
'default_timezone' => 'PRC',
|
||||
// 是否开启多语言
|
||||
'lang_switch_on' => false,
|
||||
// 默认全局过滤方法 用逗号分隔多个
|
||||
'default_filter' => '',
|
||||
// 默认语言
|
||||
'default_lang' => 'zh-cn',
|
||||
// 应用类库后缀
|
||||
'class_suffix' => false,
|
||||
// 控制器类后缀
|
||||
'controller_suffix' => false,
|
||||
|
||||
// +----------------------------------------------------------------------
|
||||
// | 模块设置
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
// 默认模块名
|
||||
'default_module' => 'api',
|
||||
// 禁止访问模块
|
||||
'deny_module_list' => ['common'],
|
||||
// 默认控制器名
|
||||
'default_controller' => 'Index',
|
||||
// 默认操作名
|
||||
'default_action' => 'index',
|
||||
// 默认验证器
|
||||
'default_validate' => '',
|
||||
// 默认的空控制器名
|
||||
'empty_controller' => 'Error',
|
||||
// 操作方法后缀
|
||||
'action_suffix' => '',
|
||||
// 自动搜索控制器
|
||||
'controller_auto_search' => false,
|
||||
|
||||
// +----------------------------------------------------------------------
|
||||
// | URL设置
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
// PATHINFO变量名 用于兼容模式
|
||||
'var_pathinfo' => 's',
|
||||
// 兼容PATH_INFO获取
|
||||
'pathinfo_fetch' => ['ORIG_PATH_INFO', 'REDIRECT_PATH_INFO', 'REDIRECT_URL'],
|
||||
// pathinfo分隔符
|
||||
'pathinfo_depr' => '/',
|
||||
// URL伪静态后缀
|
||||
'url_html_suffix' => 'html',
|
||||
// URL普通方式参数 用于自动生成
|
||||
'url_common_param' => false,
|
||||
// URL参数方式 0 按名称成对解析 1 按顺序解析
|
||||
'url_param_type' => 0,
|
||||
// 是否开启路由
|
||||
'url_route_on' => true,
|
||||
// 路由使用完整匹配
|
||||
'route_complete_match' => false,
|
||||
// 路由配置文件(支持配置多个)
|
||||
'route_config_file' => ['adminRoute', 'apiRoute', 'wikiRoute'],
|
||||
// 是否强制使用路由
|
||||
'url_route_must' => true,
|
||||
// 域名部署
|
||||
'url_domain_deploy' => false,
|
||||
// 域名根,如thinkphp.cn
|
||||
'url_domain_root' => '',
|
||||
// 是否自动转换URL中的控制器和操作名
|
||||
'url_convert' => true,
|
||||
// 默认的访问控制器层
|
||||
'url_controller_layer' => 'controller',
|
||||
// 表单请求类型伪装变量
|
||||
'var_method' => '_method',
|
||||
// 表单ajax伪装变量
|
||||
'var_ajax' => '_ajax',
|
||||
// 表单pjax伪装变量
|
||||
'var_pjax' => '_pjax',
|
||||
// 是否开启请求缓存 true自动缓存 支持设置请求缓存规则
|
||||
'request_cache' => false,
|
||||
// 请求缓存有效期
|
||||
'request_cache_expire' => null,
|
||||
// 全局请求缓存排除规则
|
||||
'request_cache_except' => [],
|
||||
|
||||
// +----------------------------------------------------------------------
|
||||
// | 模板设置
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
'template' => [
|
||||
// 模板引擎类型 支持 php think 支持扩展
|
||||
'type' => 'Think',
|
||||
// 模板路径
|
||||
'view_path' => '',
|
||||
// 模板后缀
|
||||
'view_suffix' => 'html',
|
||||
// 模板文件名分隔符
|
||||
'view_depr' => DS,
|
||||
// 模板引擎普通标签开始标记
|
||||
'tpl_begin' => '{',
|
||||
// 模板引擎普通标签结束标记
|
||||
'tpl_end' => '}',
|
||||
// 标签库标签开始标记
|
||||
'taglib_begin' => '{',
|
||||
// 标签库标签结束标记
|
||||
'taglib_end' => '}',
|
||||
],
|
||||
|
||||
// 视图输出字符串内容替换
|
||||
'view_replace_str' => [],
|
||||
// 默认跳转页面对应的模板文件
|
||||
'dispatch_success_tmpl' => THINK_PATH . 'tpl' . DS . 'dispatch_jump.tpl',
|
||||
'dispatch_error_tmpl' => THINK_PATH . 'tpl' . DS . 'dispatch_jump.tpl',
|
||||
|
||||
// +----------------------------------------------------------------------
|
||||
// | 异常及错误设置
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
// 异常页面的模板文件
|
||||
'exception_tmpl' => THINK_PATH . 'tpl' . DS . 'think_exception.tpl',
|
||||
|
||||
// 错误显示信息,非调试模式有效
|
||||
'error_message' => '页面错误!请稍后再试~',
|
||||
// 显示错误信息
|
||||
'show_error_msg' => false,
|
||||
// 异常处理handle类 留空使用 \think\exception\Handle
|
||||
'exception_handle' => '',
|
||||
|
||||
// +----------------------------------------------------------------------
|
||||
// | 日志设置
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
'log' => [
|
||||
// 日志记录方式,内置 file socket 支持扩展
|
||||
'type' => 'File',
|
||||
// 日志保存目录
|
||||
'path' => LOG_PATH,
|
||||
// 日志记录级别
|
||||
'level' => [],
|
||||
],
|
||||
|
||||
// +----------------------------------------------------------------------
|
||||
// | Trace设置 开启 app_trace 后 有效
|
||||
// +----------------------------------------------------------------------
|
||||
'trace' => [
|
||||
// 内置Html Console 支持扩展
|
||||
'type' => 'Html',
|
||||
],
|
||||
|
||||
// +----------------------------------------------------------------------
|
||||
// | 缓存设置
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
'cache' => [
|
||||
// 驱动方式
|
||||
'type' => 'Redis',
|
||||
// 缓存保存目录
|
||||
'path' => CACHE_PATH,
|
||||
// 缓存前缀
|
||||
'prefix' => 'ApiAdmin:',
|
||||
// 缓存有效期 0表示永久缓存
|
||||
'expire' => 0,
|
||||
],
|
||||
|
||||
// +----------------------------------------------------------------------
|
||||
// | 会话设置
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
'session' => [
|
||||
'id' => '',
|
||||
// SESSION_ID的提交变量,解决flash上传跨域
|
||||
'var_session_id' => '',
|
||||
// SESSION 前缀
|
||||
'prefix' => 'think',
|
||||
// 驱动方式 支持redis memcache memcached
|
||||
'type' => '',
|
||||
// 是否自动开启 SESSION
|
||||
'auto_start' => true,
|
||||
],
|
||||
|
||||
// +----------------------------------------------------------------------
|
||||
// | Cookie设置
|
||||
// +----------------------------------------------------------------------
|
||||
'cookie' => [
|
||||
// cookie 名称前缀
|
||||
'prefix' => '',
|
||||
// cookie 保存时间
|
||||
'expire' => 0,
|
||||
// cookie 保存路径
|
||||
'path' => '/',
|
||||
// cookie 有效域名
|
||||
'domain' => '',
|
||||
// cookie 启用安全传输
|
||||
'secure' => false,
|
||||
// httponly设置
|
||||
'httponly' => '',
|
||||
// 是否使用 setcookie
|
||||
'setcookie' => true,
|
||||
],
|
||||
|
||||
//分页配置
|
||||
'paginate' => [
|
||||
'type' => 'bootstrap',
|
||||
'var_page' => 'page',
|
||||
'list_rows' => 15,
|
||||
],
|
||||
];
|
@ -1,53 +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 [
|
||||
// 数据库类型
|
||||
'type' => 'mysql',
|
||||
// 服务器地址
|
||||
'hostname' => '127.0.0.1',
|
||||
// 数据库名
|
||||
'database' => 'apiadmin',
|
||||
// 用户名
|
||||
'username' => 'root',
|
||||
// 密码
|
||||
'password' => '123456',
|
||||
// 端口
|
||||
'hostport' => '',
|
||||
// 连接dsn
|
||||
'dsn' => '',
|
||||
// 数据库连接参数
|
||||
'params' => [],
|
||||
// 数据库编码默认采用utf8
|
||||
'charset' => 'utf8',
|
||||
// 数据库表前缀
|
||||
'prefix' => '',
|
||||
// 数据库调试模式
|
||||
'debug' => true,
|
||||
// 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器)
|
||||
'deploy' => 0,
|
||||
// 数据库读写是否分离 主从式有效
|
||||
'rw_separate' => false,
|
||||
// 读写分离后 主服务器数量
|
||||
'master_num' => 1,
|
||||
// 指定从服务器序号
|
||||
'slave_no' => '',
|
||||
// 是否严格检查字段是否存在
|
||||
'fields_strict' => true,
|
||||
// 数据集返回类型
|
||||
'resultset_type' => 'array',
|
||||
// 自动写入时间戳字段
|
||||
'auto_timestamp' => false,
|
||||
// 时间字段取出后的默认时间格式
|
||||
'datetime_format' => 'Y-m-d H:i:s',
|
||||
// 是否需要进行SQL性能分析
|
||||
'sql_explain' => false,
|
||||
];
|
@ -1,38 +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 <liu21st@gmail.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
return [
|
||||
'APP_VERSION' => 'v3.0',
|
||||
'APP_NAME' => 'ApiAdmin',
|
||||
|
||||
//鉴权相关
|
||||
'USER_ADMINISTRATOR' => [1],
|
||||
|
||||
//安全秘钥
|
||||
'AUTH_KEY' => 'I&TC{pft>L,C`wFQ>&#ROW>k{Kxlt1>ryW(>r<#R',
|
||||
|
||||
//后台登录状态维持时间[目前只有登录和解锁会重置登录时间]
|
||||
'ONLINE_TIME' => 7200,
|
||||
//AccessToken失效时间
|
||||
'ACCESS_TOKEN_TIME_OUT' => 7200,
|
||||
'COMPANY_NAME' => 'ApiAdmin开发维护团队',
|
||||
|
||||
//跨域配置
|
||||
'CROSS_DOMAIN' => [
|
||||
'Access-Control-Allow-Origin' => '*',
|
||||
'Access-Control-Allow-Methods' => 'POST,PUT,GET,DELETE',
|
||||
'Access-Control-Allow-Headers' => 'ApiAuth, User-Agent, Keep-Alive, Origin, No-Cache, X-Requested-With, If-Modified-Since, Pragma, Last-Modified, Cache-Control, Expires, Content-Type, X-E4M-With',
|
||||
'Access-Control-Allow-Credentials' => 'true'
|
||||
],
|
||||
|
||||
//后台列表默认一页显示数量
|
||||
'ADMIN_LIST_DEFAULT' => 20,
|
||||
];
|
@ -1,17 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* @since 2018-02-08
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
|
||||
namespace app\model;
|
||||
|
||||
|
||||
class AdminAuthGroup extends Base {
|
||||
|
||||
public function rules() {
|
||||
return $this->hasMany('AdminAuthRule', 'groupId', 'id');
|
||||
}
|
||||
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @since 2017-11-02
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
|
||||
namespace app\model;
|
||||
|
||||
|
||||
class AdminUser extends Base {
|
||||
|
||||
}
|
@ -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' => [],
|
||||
];
|
@ -1,109 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @since 2017-04-14
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
|
||||
namespace app\util;
|
||||
|
||||
|
||||
class ApiLog {
|
||||
|
||||
private static $appInfo = 'null';
|
||||
private static $apiInfo = 'null';
|
||||
private static $request = 'null';
|
||||
private static $requestAfterFilter = 'null';
|
||||
private static $response = 'null';
|
||||
private static $header = 'null';
|
||||
private static $userInfo = 'null';
|
||||
private static $separator = '###';
|
||||
|
||||
public static function setAppInfo($data) {
|
||||
self::$appInfo =
|
||||
isset($data['app_id']) ? $data['app_id'] : '' . self::$separator .
|
||||
isset($data['app_name']) ? $data['app_name'] : '' . self::$separator .
|
||||
isset($data['device_id']) ? $data['device_id'] : '';
|
||||
}
|
||||
|
||||
public static function setHeader($data) {
|
||||
$userToken = (isset($data['user-token']) && !empty($data['user-token'])) ? $data['user-token'] : 'null';
|
||||
$accessToken = (isset($data['access-token']) && !empty($data['access-token'])) ? $data['access-token'] : 'null';
|
||||
$version = (isset($data['version']) && !empty($data['version'])) ? $data['version'] : 'null';
|
||||
self::$header = $accessToken . self::$separator . $userToken . self::$separator . $version;
|
||||
}
|
||||
|
||||
public static function setApiInfo($data) {
|
||||
self::$apiInfo = isset($data['apiClass']) ? $data['apiClass'] : '' . self::$separator . isset($data['hash']) ? $data['hash'] : '';
|
||||
}
|
||||
|
||||
public static function setUserInfo($data) {
|
||||
if (is_array($data) || is_object($data)) {
|
||||
$data = json_encode($data);
|
||||
}
|
||||
self::$userInfo = $data;
|
||||
}
|
||||
|
||||
public static function getUserInfo() {
|
||||
return json_decode(self::$userInfo, true);
|
||||
}
|
||||
|
||||
public static function setRequest($data) {
|
||||
if (is_array($data) || is_object($data)) {
|
||||
$data = json_encode($data);
|
||||
}
|
||||
self::$request = $data;
|
||||
}
|
||||
|
||||
public static function setRequestAfterFilter($data) {
|
||||
if (is_array($data) || is_object($data)) {
|
||||
$data = json_encode($data);
|
||||
}
|
||||
self::$requestAfterFilter = $data;
|
||||
}
|
||||
|
||||
public static function setResponse($data, $code = '') {
|
||||
if (is_array($data) || is_object($data)) {
|
||||
$data = json_encode($data);
|
||||
}
|
||||
self::$response = $code . self::$separator . $data;
|
||||
}
|
||||
|
||||
public static function save() {
|
||||
$logPath = RUNTIME_PATH . 'ApiLog' . DS;
|
||||
if (self::$appInfo == 'null') {
|
||||
self::$appInfo = 'null' . self::$separator . 'null' . self::$separator . 'null';
|
||||
}
|
||||
$logStr = implode(self::$separator, array(
|
||||
self::$apiInfo,
|
||||
date('Y-m-d H:i:s'),
|
||||
self::$request,
|
||||
self::$header,
|
||||
self::$response,
|
||||
self::$requestAfterFilter,
|
||||
self::$appInfo,
|
||||
self::$userInfo
|
||||
));
|
||||
if (!file_exists($logPath)) {
|
||||
mkdir($logPath, 0755, true);
|
||||
}
|
||||
@file_put_contents($logPath . date('YmdH') . '.log', $logStr . "\n", FILE_APPEND);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $log 被记录的内容
|
||||
* @param string $type 日志文件名称
|
||||
* @param string $filePath
|
||||
*/
|
||||
public static function writeLog($log, $type = 'sql', $filePath = '') {
|
||||
if(!$filePath) {
|
||||
$filePath = '.' . DS . 'runtime' . DS;
|
||||
}
|
||||
$filename = $filePath . date("Ymd") . '_' . $type . ".log";
|
||||
@$handle = fopen($filename, "a+");
|
||||
@fwrite($handle, date('Y-m-d H:i:s') . "\t" . $log . "\r\n");
|
||||
@fclose($handle);
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -1,115 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* @since 2017-11-01
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
|
||||
namespace app\util;
|
||||
|
||||
|
||||
class Tools {
|
||||
|
||||
public static function getDate($timestamp) {
|
||||
$now = time();
|
||||
$diff = $now - $timestamp;
|
||||
if ($diff <= 60) {
|
||||
return $diff . '秒前';
|
||||
} elseif ($diff <= 3600) {
|
||||
return floor($diff / 60) . '分钟前';
|
||||
} elseif ($diff <= 86400) {
|
||||
return floor($diff / 3600) . '小时前';
|
||||
} elseif ($diff <= 2592000) {
|
||||
return floor($diff / 86400) . '天前';
|
||||
} else {
|
||||
return '一个月前';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 二次封装的密码加密
|
||||
* @param $str
|
||||
* @param string $auth_key
|
||||
* @return string
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public static function userMd5($str, $auth_key = '') {
|
||||
if (!$auth_key) {
|
||||
$auth_key = config('apiAdmin.AUTH_KEY');
|
||||
}
|
||||
|
||||
return '' === $str ? '' : md5(sha1($str) . $auth_key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断当前用户是否是超级管理员
|
||||
* @param string $uid
|
||||
* @return bool
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public static function isAdministrator($uid = '') {
|
||||
if (!empty($uid)) {
|
||||
$adminConf = config('apiAdmin.USER_ADMINISTRATOR');
|
||||
if (is_array($adminConf)) {
|
||||
if (is_array($uid)) {
|
||||
$m = array_intersect($adminConf, $uid);
|
||||
if (count($m)) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
if (in_array($uid, $adminConf)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (is_array($uid)) {
|
||||
if (in_array($adminConf, $uid)) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
if ($uid == $adminConf) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将查询的二维对象转换成二维数组
|
||||
* @param array $res
|
||||
* @param string $key 允许指定索引值
|
||||
* @return array
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
*/
|
||||
public static function buildArrFromObj($res, $key = '') {
|
||||
$arr = [];
|
||||
foreach ($res as $value) {
|
||||
$value = $value->toArray();
|
||||
if ($key) {
|
||||
$arr[$value[$key]] = $value;
|
||||
} else {
|
||||
$arr[] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
return $arr;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将二维数组变成指定key
|
||||
* @param $array
|
||||
* @param $keyName
|
||||
* @author zhaoxiang <zhaoxiang051405@gmail.com>
|
||||
* @return array
|
||||
*/
|
||||
public static function buildArrByNewKey($array, $keyName = 'id') {
|
||||
$list = array();
|
||||
foreach ($array as $item) {
|
||||
$list[$item[$keyName]] = $item;
|
||||
}
|
||||
return $list;
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user