xieruidong 2 年之前
父節點
當前提交
14ee6c54ce
共有 5 個文件被更改,包括 361 次插入7 次删除
  1. 1 1
      app/ExceptionHandle.php
  2. 1 0
      app/admin/view/error.php
  3. 3 2
      app/data/controller/api/Login.php
  4. 9 4
      config/apidoc.php
  5. 347 0
      public/api.html

+ 1 - 1
app/ExceptionHandle.php

@@ -21,7 +21,7 @@ class ExceptionHandle extends Handle {
             return [
                 'code'    => $this->getCode($exception),
                 'message' => $this->getMessage($exception),
-                'trace'   => $exception->getTrace(),
+                'traces'   => [],
             ];
         }
         return parent::convertExceptionToArray($exception); // TODO: Change the autogenerated stub

+ 1 - 0
app/admin/view/error.php

@@ -372,6 +372,7 @@ if (!function_exists('echo_value')) {
     </style>
 </head>
 <body>
+<h2><?php echo $message; ?></h2>
 <?php if (\think\facade\App::isDebug()) { ?>
     <?php foreach ($traces as $index => $trace) { ?>
         <div class="exception">

+ 3 - 2
app/data/controller/api/Login.php

@@ -5,10 +5,11 @@ namespace app\data\controller\api;
 use app\data\model\DataUser;
 use app\data\service\MessageService;
 use app\data\service\UserAdminService;
+use hg\apidoc\annotation\Title;
 use think\admin\Controller;
 
 /**
- * 用户登录注册接口
+ * @Title("用户登录注册接口")
  * Class Login
  * @package app\data\controller\api
  */
@@ -106,4 +107,4 @@ class Login extends Controller
         [$state, $message, $data] = MessageService::instance()->sendVerifyCode($data['phone']);
         $state ? $this->success($message, $data) : $this->error($message, $data);
     }
-}
+}

+ 9 - 4
config/apidoc.php

@@ -12,10 +12,15 @@ return [
     'apps'           => [
         [
             'title'=>'前台api接口',
-            'path'=>'app\api\controller',
-            'folder'=>'api',
-            'controllers'=>[
-            ]
+            'path'=>'app\data\controller',
+            'folder'=>'data',
+            'groups'  => [
+                ['title'=>'多级模块','name'=>'api','controller'=>'Login',
+                    'children'=>[
+                        ['title'=>'多级v1','name'=>'in',],
+                    ]
+                ],
+            ],
         ]
     ],
     // 自动生成url规则

+ 347 - 0
public/api.html

@@ -0,0 +1,347 @@
+<!DOCTYPE html><html lang="zh-cn"><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="description" content=""><title>测试的API文档</title><!-- Bootstrap Core CSS --><link href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"><!-- Plugin CSS --><link href="https://cdn.staticfile.org/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"><!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries --><!--[if lt IE 9]><script src="https://cdn.staticfile.org/html5shiv/3.7.3/html5shiv.min.js"></script><script src="https://cdn.staticfile.org/respond.js/1.4.2/respond.min.js"></script><![endif]--><style type="text/css">
+        body {
+            padding-top: 70px; margin-bottom: 15px;
+            -webkit-font-smoothing: antialiased;
+            -moz-osx-font-smoothing: grayscale;
+            font-family: "Roboto", "SF Pro SC", "SF Pro Display", "SF Pro Icons", "PingFang SC", BlinkMacSystemFont, -apple-system, "Segoe UI", "Microsoft Yahei", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", "Helvetica", "Arial", sans-serif;
+            font-weight: 400;
+        }
+        h2        { font-size: 1.2em; }
+        hr        { margin-top: 10px; }
+        .tab-pane { padding-top: 10px; }
+        .mt0      { margin-top: 0px; }
+        .footer   { font-size: 12px; color: #666; }
+        .docs-list .label    { display: inline-block; min-width: 65px; padding: 0.3em 0.6em 0.3em; }
+        .string   { color: green; }
+        .number   { color: darkorange; }
+        .boolean  { color: blue; }
+        .null     { color: magenta; }
+        .key      { color: red; }
+        .popover  { max-width: 400px; max-height: 400px; overflow-y: auto;}
+        .list-group.panel > .list-group-item {
+        }
+		.panel-title>a{color:#777;}
+		.label-success{background-color:#49cc90;}
+		.panel-success{border-color: #49cc90;}
+		.panel-success>.panel-heading{background: rgba(73,204,144,.1);}
+		.label-primary{background-color:#61affe;}
+		.panel-primary{border-color: #61affe;}
+		.panel-primary>.panel-heading{background: rgba(97,175,254,.1);}
+		.label-warning{background-color:#fca130;}
+		.panel-warning{border-color: #fca130;}
+		.panel-warning>.panel-heading{background: rgba(252,161,48,.1);}
+		.label-danger{background-color:#f93e3e;}
+		.panel-danger{border-color: #f93e3e;}
+		.panel-danger>.panel-heading{background: rgba(249,62,62,.1);}
+		a:focus, a:hover{text-decoration:none;}
+        .list-group-item:last-child {
+            border-radius:0;
+        }
+        h4.panel-title a {
+            font-weight:normal;
+            font-size:14px;
+        }
+        h4.panel-title a .text-muted {
+            font-size:12px;
+            font-weight:normal;
+            font-family: 'Verdana';
+			color:#3b4151;font-weight:600;
+        }
+        #sidebar {
+            width: 220px;
+            position: fixed;
+            margin-left: -240px;
+            overflow-y:auto;
+        }
+        #sidebar > .list-group {
+            margin-bottom:0;
+        }
+        #sidebar > .list-group > a{
+            text-indent:0;
+        }
+        #sidebar .child > a .tag{
+            position: absolute;
+            right: 10px;
+            top: 11px;
+        }
+        #sidebar .child > a .pull-right{
+            margin-left:3px;
+        }
+        #sidebar .child {
+            border:1px solid #ddd;
+            border-bottom:none;
+        }
+        #sidebar .child:last-child {
+            border-bottom:1px solid #ddd;
+        }
+        #sidebar .child > a {
+            border:0;
+            min-height: 40px;
+        }
+        #sidebar .list-group a.current {
+            background:#f5f5f5;
+        }
+        @media (max-width: 1620px){
+            #sidebar {
+                margin:0;
+            }
+            #accordion {
+                padding-left:235px;
+            }
+        }
+        @media (max-width: 768px){
+            #sidebar {
+                display: none;
+            }
+            #accordion {
+                padding-left:0px;
+            }
+        }
+        .label-primary {
+            background-color: #248aff;
+        }
+        .docs-list .panel .panel-body .table {
+            margin-bottom: 0;
+        }
+		.navbar-default{
+			background-color:#1b1b1b;
+			color:#fff;
+		}
+		.navbar-brand{
+			color:#fff!important;
+		}
+		.panel-heading > strong{
+			color:#3b4151;
+		}
+		.alert{padding:10px!important}
+    </style></head><body><!-- Fixed navbar --><div class="navbar navbar-default navbar-fixed-top" role="navigation"><div class="container"><div class="navbar-header"><button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse"><span class="sr-only">Toggle navigation</span><span class="icon-bar"></span><span class="icon-bar"></span><span class="icon-bar"></span></button><a class="navbar-brand" href="./" target="_blank">测试的API文档</a></div><div class="navbar-collapse collapse"><form class="navbar-form navbar-right"><div class="form-group">
+                    Apiurl:
+                </div><div class="form-group"><input id="apiUrl" type="text" class="form-control input-sm" data-toggle="tooltip" title="" placeholder="https://api.mydomain.com" value="" /></div><div class="form-group"><button type="button" class="btn btn-success btn-sm" data-toggle="tooltip" title="" id="save_data"><span class="glyphicon glyphicon-floppy-disk" aria-hidden="true"></span></button></div></form></div><!--/.nav-collapse --></div></div><div class="container"><!-- menu --><div id="sidebar"><div class="list-group panel"></div></div><div class="panel-group docs-list" id="accordion"></div><hr><div class="row mt0 footer"><div class="col-md-6" align="left"></div><div class="col-md-6" align="right">
+            Generated on 2022-11-07 15:22:28<a href="./" target="_blank"></a></div></div></div><!-- /container --><!-- jQuery --><script src="https://cdn.staticfile.org/jquery/2.1.4/jquery.min.js"></script><!-- Bootstrap Core JavaScript --><script src="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script><script type="text/javascript">
+    function syntaxHighlight(json) {
+        if (typeof json != 'string') {
+            json = JSON.stringify(json, undefined, 2);
+        }
+        json = json.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
+        return json.replace(/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g, function (match) {
+            var cls = 'number';
+            if (/^"/.test(match)) {
+                if (/:$/.test(match)) {
+                    cls = 'key';
+                } else {
+                    cls = 'string';
+                }
+            } else if (/true|false/.test(match)) {
+                cls = 'boolean';
+            } else if (/null/.test(match)) {
+                cls = 'null';
+            }
+            return '<span class="' + cls + '">' + match + '</span>';
+        });
+    }
+
+    function prepareStr(str) {
+        try {
+            return syntaxHighlight(JSON.stringify(JSON.parse(str.replace(/'/g, '"')), null, 2));
+        } catch (e) {
+            return str;
+        }
+    }
+    var storage = (function () {
+        var uid = new Date;
+        var storage;
+        var result;
+        try {
+            (storage = window.localStorage).setItem(uid, uid);
+            result = storage.getItem(uid) == uid;
+            storage.removeItem(uid);
+            return result && storage;
+        } catch (exception) {
+        }
+    }());
+
+    $.fn.serializeObject = function ()
+    {
+        var o = {};
+        var a = this.serializeArray();
+        $.each(a, function () {
+            if (!this.value) {
+                return;
+            }
+            if (o[this.name] !== undefined) {
+                if (!o[this.name].push) {
+                    o[this.name] = [o[this.name]];
+                }
+                o[this.name].push(this.value || '');
+            } else {
+                o[this.name] = this.value || '';
+            }
+        });
+        return o;
+    };
+
+    $(document).ready(function () {
+
+        if (storage) {
+            storage.getItem('token') && $('#token').val(storage.getItem('token'));
+            storage.getItem('apiUrl') && $('#apiUrl').val(storage.getItem('apiUrl'));
+        }
+
+        $('[data-toggle="tooltip"]').tooltip({
+            placement: 'bottom'
+        });
+
+        $(window).on("resize", function(){
+            $("#sidebar").css("max-height", $(window).height()-80);
+        });
+
+        $(window).trigger("resize");
+
+        $(document).on("click", "#sidebar .list-group > .list-group-item", function(){
+            $("#sidebar .list-group > .list-group-item").removeClass("current");
+            $(this).addClass("current");
+        });
+        $(document).on("click", "#sidebar .child a", function(){
+            var heading = $("#heading-"+$(this).data("id"));
+            if(!heading.next().hasClass("in")){
+                $("a", heading).trigger("click");
+            }
+            $("html,body").animate({scrollTop:heading.offset().top-70});
+        });
+
+        $('code[id^=response]').hide();
+
+        $.each($('pre[id^=sample_response],pre[id^=sample_post_body]'), function () {
+            if ($(this).html() == 'NA') {
+                return;
+            }
+            var str = prepareStr($(this).html());
+            $(this).html(str);
+        });
+
+        $("[data-toggle=popover]").popover({placement: 'right'});
+
+        $('[data-toggle=popover]').on('shown.bs.popover', function () {
+            var $sample = $(this).parent().find(".popover-content"),
+                str = $(this).data('content');
+            if (typeof str == "undefined" || str === "") {
+                return;
+            }
+            var str = prepareStr(str);
+            $sample.html('<pre>' + str + '</pre>');
+        });
+
+        $(document).on('click', '#save_data', function (e) {
+            if (storage) {
+                storage.setItem('token', $('#token').val());
+                storage.setItem('apiUrl', $('#apiUrl').val());
+            } else {
+                alert('Your browser does not support local storage');
+            }
+        });
+        $(document).on('click', '.btn-append', function (e) {
+            $($("#appendtpl").html()).insertBefore($(this).closest(".panel").find(".form-group-submit"));
+            return false;
+        });
+        $(document).on('click', '.btn-remove', function (e) {
+            $(this).closest(".form-group").remove();
+            return false;
+        });
+        $(document).on('keyup', '.input-custom-name', function (e) {
+            $(this).closest(".row").find(".input-custom-value").attr("name", $(this).val());
+            return false;
+        });
+
+        $(document).on('click', '.send', function (e) {
+            e.preventDefault();
+            var form = $(this).closest('form');
+            //added /g to get all the matched params instead of only first
+            var matchedParamsInRoute = $(form).attr('action').match(/[^{]+(?=\})/g);
+            var theId = $(this).attr('rel');
+            //keep a copy of action attribute in order to modify the copy
+            //instead of the initial attribute
+            var url = $(form).attr('action');
+            var method = $(form).prop('method').toLowerCase() || 'get';
+
+            var formData = new FormData();
+
+            $(form).find('input').each(function (i, input) {
+                if ($(input).attr('type').toLowerCase() == 'file') {
+                    formData.append($(input).attr('name'), $(input)[0].files[0]);
+                    method = 'post';
+                } else {
+                    formData.append($(input).attr('name'), $(input).val())
+                }
+            });
+
+            var index, key, value;
+
+            if (matchedParamsInRoute) {
+                var params = {};
+                formData.forEach(function(value, key){
+                    params[key] = value;
+                });
+                for (index = 0; index < matchedParamsInRoute.length; ++index) {
+                    try {
+                        key = matchedParamsInRoute[index];
+                        value = params[key];
+                        if (typeof value == "undefined")
+                            value = "";
+                        url = url.replace("\{" + key + "\}", value);
+                        formData.delete(key);
+                    } catch (err) {
+                        console.log(err);
+                    }
+                }
+            }
+
+            var headers = {};
+
+            var token = $('#token').val();
+            if (token.length > 0) {
+                headers['token'] = token;
+            }
+
+            $("#sandbox" + theId + " .headers input[type=text]").each(function () {
+                val = $(this).val();
+                if (val.length > 0) {
+                    headers[$(this).prop('name')] = val;
+                }
+            });
+
+            $.ajax({
+                url: $('#apiUrl').val() + url,
+                data: method == 'get' ? $(form).serialize() : formData,
+                type: method,
+                dataType: 'json',
+                contentType: false,
+                processData: false,
+                headers: headers,
+                xhrFields: {
+                    withCredentials: true
+                },
+                success: function (data, textStatus, xhr) {
+                    if (typeof data === 'object') {
+                        var str = JSON.stringify(data, null, 2);
+                        $('#response' + theId).html(syntaxHighlight(str));
+                    } else {
+                        $('#response' + theId).html(data || '');
+                    }
+                    $('#response_headers' + theId).html('HTTP ' + xhr.status + ' ' + xhr.statusText + '<br/><br/>' + xhr.getAllResponseHeaders());
+                    $('#response' + theId).show();
+                },
+                error: function (xhr, textStatus, error) {
+                    try {
+                        var str = JSON.stringify($.parseJSON(xhr.responseText), null, 2);
+                    } catch (e) {
+                        var str = xhr.responseText;
+                    }
+                    $('#response_headers' + theId).html('HTTP ' + xhr.status + ' ' + xhr.statusText + '<br/><br/>' + xhr.getAllResponseHeaders());
+                    $('#response' + theId).html(syntaxHighlight(str));
+                    $('#response' + theId).show();
+                }
+            });
+            return false;
+        });
+    });
+</script><script type="text/html" id="appendtpl"><div class="form-group"><label class="control-label">自定义</label><div class="row"><div class="col-xs-4"><input type="text" class="form-control input-sm input-custom-name" placeholder="名称"></div><div class="col-xs-6"><input type="text" class="form-control input-sm input-custom-value" placeholder="值"></div><div class="col-xs-2 text-center"><a href="javascript:" class="btn btn-sm btn-danger btn-remove">删除</a></div></div></div></script></body></html>