├── README.md
├── composer.json
├── config
└── laravel-quick.php
├── resources
└── lang
│ └── zh-CN
│ ├── admin.php
│ ├── auth.php
│ ├── select2.php
│ └── validation.php
└── src
├── Console
├── CreateRepositoryCommand.php
├── CreateServiceCommand.php
├── CreateTraitCommand.php
└── stubs
│ ├── repository.stub
│ ├── service.stub
│ └── trait.stub
├── Exceptions
├── Api
│ ├── ApiNotFoundException.php
│ ├── ApiRequestException.php
│ ├── ApiSystemException.php
│ └── ApiUnAuthException.php
└── ApiException.php
├── Facades
└── CacheClient.php
├── Helpers
└── helper.php
├── LaravelQuickServiceProvider.php
├── Repositories
└── BaseRepository.php
├── Services
├── BaseService.php
└── CacheService.php
└── Traits
├── AttributeStatusTrait.php
└── JsonResponseTrait.php
/README.md:
--------------------------------------------------------------------------------
1 | # laravel-quick
2 |
3 | **laravel-quick** 封装了一些我们开发中常见的工具,使开发变得更高效
4 |
5 | ## 安装
6 | - `composer require yxx/laravel-quick`
7 | - 生成翻译好的中文包命令
8 |
9 | **linux 和 mac** `php artisan vendor:publish--provider="Yxx\\LaravelQuick\\LaravelQuickServiceProvider"`
10 | **windows** `php artisan vendor:publish --provider="Yxx\LaravelQuick\LaravelQuickServiceProvider"`
11 | ## 怎么使用
12 | ```$xslt
13 | // api 返回状态码
14 |
15 | // 异常使用例子
16 | use Yxx\LaravelQuick\Exceptions\Api\ApiNotFoundException;
17 | // 请求参数错误
18 | throw new ApiRequestException();
19 | // 404 未找到
20 | throw new ApiNotFoundException();
21 | // 系统错误
22 | throw new ApiSystemException()
23 | // 未授权
24 | throw new ApiUnAuthException()
25 | // 返回
26 |
27 | //自定义错误继承Yxx\LaravelQuick\Exceptions自己参照对应代码自定义
28 |
29 | // api接口使用
30 | use Yxx\LaravelQuick\Traits\JsonResponseTrait
31 |
32 | // 成功
33 | return $this->success("消息",['name'=>"张三"]);
34 | // 失败
35 | return $this->error("错误");
36 | // 自定义
37 | return $this->apiResponse(Response::HTTP_BAD_GATEWAY,"502错误");
38 |
39 | // 缓存的使用(封装了redis的一些方法)
40 | use Yxx\LaravelQuick\Facades\CacheClient;
41 |
42 | CacheClient::hSet("test","1","张三");
43 | CacheClient::hGet("test","1");
44 | CacheClient::lPush("test","1");
45 |
46 | 具体参考Yxx\LaravelQuick\Services\CacheService里面的方法....
47 | ```
48 |
49 | ## artisan 命令
50 | - 创建 Trait `php artisan quick:create-trait test`
51 | - 创建 Service `php artisan quick:create-service Test/TestService`
52 | - 创建 Repository `php artisan quick:create-repository Test`
53 |
54 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "yxx/laravel-quick",
3 | "keywords": ["laravel","php","tool","api","scaffold"],
4 | "description": "agile development",
5 | "type": "library",
6 | "license": "MIT",
7 | "authors": [
8 | {
9 | "name": "youxingxiang",
10 | "email": "1365831278@qq.com"
11 | }
12 | ],
13 | "require": {
14 | "php": ">=7.1.0",
15 | "laravel/framework": "~5.5|~6.0|~7.0|~8.0"
16 | },
17 | "autoload": {
18 | "psr-4": {
19 | "Yxx\\LaravelQuick\\": "src/"
20 | },
21 | "files": [
22 | "src/Helpers/helper.php"
23 | ]
24 | },
25 | "extra": {
26 | "laravel": {
27 | "providers": [
28 | "Yxx\\LaravelQuick\\LaravelQuickServiceProvider"
29 | ],
30 | "aliases": {
31 | "CacheClient": "Yxx\\LaravelQuick\\Facades\\CacheClient::class"
32 | }
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/config/laravel-quick.php:
--------------------------------------------------------------------------------
1 | env('REDIS_KEY_EXPIRE', 3600 * 24 * 30),
10 | ];
11 |
--------------------------------------------------------------------------------
/resources/lang/zh-CN/admin.php:
--------------------------------------------------------------------------------
1 | [
5 | 'header' => '代码生成器',
6 | 'choose' => '选择已有数据表',
7 | 'table' => '表名',
8 | 'model' => '模型',
9 | 'controller' => '控制器',
10 | 'repository' => '数据仓库',
11 | 'add_field' => '添加字段',
12 | 'pk' => '主键',
13 | 'soft_delete' => '软删除',
14 | 'create_migration' => '创建表迁移文件',
15 | 'create_model' => '创建模型',
16 | 'create_repository' => '创建数据仓库',
17 | 'create_controller' => '创建控制器',
18 | 'run_migrate' => '创建数据表',
19 | 'create_lang' => '创建翻译文件',
20 | 'field' => '字段',
21 | 'translation' => '翻译',
22 | 'comment' => '注释',
23 | 'default' => '默认值',
24 | 'field_name' => '字段名',
25 | 'type' => '类型',
26 | 'nullable' => '允许空值',
27 | 'key' => '索引',
28 | ],
29 | 'client' => [
30 | 'delete_confirm' => '确认删除?',
31 | 'confirm' => '确认',
32 | 'cancel' => '取消',
33 | 'refresh_succeeded' => '刷新成功 !',
34 | 'close' => '关闭',
35 | 'selected_options' => '已选中:num个选项',
36 | 'exceed_max_item' => '已超出最大可选数量',
37 |
38 | '500' => '系统繁忙,请稍后再试!',
39 | '403' => '对不起,您没有权限访问,请与管理员联系。',
40 | '401' => '请登录!',
41 | '419' => '对不起,当前页面已失效,请刷新浏览器。',
42 | ],
43 | 'home' => '主页',
44 | 'online' => '在线',
45 | 'login' => '登录',
46 | 'logout' => '登出',
47 | 'setting' => '设置',
48 | 'name' => '名称',
49 | 'username' => '用户名',
50 | 'old_password' => '旧密码',
51 | 'password' => '密码',
52 | 'password_confirmation' => '确认密码',
53 | 'old_password_error' => '请输入正确的旧密码',
54 | 'remember_me' => '记住我',
55 | 'user_setting' => '用户设置',
56 | 'avatar' => '头像',
57 | 'list' => '列表',
58 | 'new' => '新增',
59 | 'create' => '创建',
60 | 'delete' => '删除',
61 | 'remove' => '移除',
62 | 'edit' => '编辑',
63 | 'quick_edit' => '快捷编辑',
64 | 'continue_editing' => '继续编辑',
65 | 'continue_creating' => '继续创建',
66 | 'view' => '查看',
67 | 'detail' => '详细',
68 | 'browse' => '浏览',
69 | 'reset' => '重置',
70 | 'export' => '导出',
71 | 'batch_delete' => '批量删除',
72 | 'save' => '保存',
73 | 'refresh' => '刷新',
74 | 'order' => '排序',
75 | 'expand' => '展开',
76 | 'collapse' => '收起',
77 | 'filter' => '筛选',
78 | 'search' => '搜索',
79 | 'close' => '关闭',
80 | 'show' => '显示',
81 | 'entries' => '条',
82 | 'captcha' => '验证码',
83 | 'action' => '操作',
84 | 'title' => '标题',
85 | 'description' => '简介',
86 | 'back' => '返回',
87 | 'back_to_list' => '返回列表',
88 | 'submit' => '提交',
89 | 'menu' => '菜单',
90 | 'input' => '输入',
91 | 'succeeded' => '成功',
92 | 'failed' => '失败',
93 | 'delete_confirm' => '确认删除?',
94 | 'delete_succeeded' => '删除成功 !',
95 | 'delete_failed' => '删除失败 !',
96 | 'update_succeeded' => '更新成功 !',
97 | 'update_failed' => '更新失败 !',
98 | 'save_succeeded' => '保存成功 !',
99 | 'save_failed' => '保存失败 !',
100 | 'refresh_succeeded' => '刷新成功 !',
101 | 'login_successful' => '登录成功 !',
102 | 'choose' => '选择',
103 | 'choose_file' => '选择文件',
104 | 'choose_image' => '选择图片',
105 | 'more' => '更多',
106 | 'deny' => '无权访问',
107 | 'administrator' => '管理员',
108 | 'roles' => '角色',
109 | 'permissions' => '权限',
110 | 'slug' => '标识',
111 | 'created_at' => '创建时间',
112 | 'updated_at' => '更新时间',
113 | 'alert' => '注意',
114 | 'parent_id' => '父级',
115 | 'icon' => '图标',
116 | 'uri' => '路径',
117 | 'operation_log' => '操作日志',
118 | 'parent_select_error' => '父级选择错误',
119 | 'default' => '默认',
120 | 'table' => '表格',
121 | 'no_data' => '暂无数据',
122 | 'routes' => '路由',
123 | 'alias' => '别名',
124 | 'route_action' => '处理器',
125 | 'middleware' => '中间件',
126 | 'import' => '导入',
127 | 'is_not_import' => '未导入',
128 | 'selected_options' => '已选中:num个选项',
129 | 'method' => '方法',
130 | 'user' => '用户',
131 | 'pagination' => [
132 | 'range' => '从 :first 到 :last ,总共 :total 条',
133 | ],
134 | 'role' => '角色',
135 | 'permission' => '权限',
136 | 'route' => '路由',
137 | 'confirm' => '确认',
138 | 'cancel' => '取消',
139 | 'selectall' => '全选',
140 | 'http' => [
141 | 'method' => 'HTTP方法',
142 | 'path' => 'HTTP路径',
143 | ],
144 | 'all_methods_if_empty' => '为空默认为所有方法',
145 | 'all' => '全部',
146 | 'current_page' => '当前页',
147 | 'selected_rows' => '选择的行',
148 | 'upload' => '上传',
149 | 'new_folder' => '新建文件夹',
150 | 'time' => '时间',
151 | 'size' => '大小',
152 | 'between_start' => '起始',
153 | 'between_end' => '结束',
154 | 'next_page' => '下一页',
155 | 'prev_page' => '上一页',
156 | 'next_step' => '下一步',
157 | 'prev_step' => '上一步',
158 | 'done' => '完成',
159 | 'listbox' => [
160 | 'text_total' => '总共 {0} 项',
161 | 'text_empty' => '空列表',
162 | 'filtered' => '{0} / {1}',
163 | 'filter_clear' => '显示全部',
164 | 'filter_placeholder' => '过滤',
165 | ],
166 | 'responsive' => [
167 | 'display_all' => '显示全部',
168 | 'display' => '字段',
169 | 'focus' => '聚焦',
170 | ],
171 | 'uploader' => [
172 | 'add_new_media' => '添加文件',
173 | 'drag_file' => '或将文件拖到这里',
174 | 'max_file_limit' => 'The :attribute may not be greater than :max.',
175 | 'exceed_size' => '文件大小超出',
176 | 'interrupt' => '上传暂停',
177 | 'upload_failed' => '上传失败,请重试',
178 | 'selected_files' => '选中:num个文件,共:size。',
179 | 'selected_has_failed' => '已成功上传:success个文件,:fail个文件上传失败,重新上传失败文件或忽略',
180 | 'selected_success' => '共:num个(:size),已上传:success个。',
181 | 'dot' => ',',
182 | 'failed_num' => '失败:fail个。',
183 | 'pause_upload' => '暂停上传',
184 | 'go_on_upload' => '继续上传',
185 | 'start_upload' => '开始上传',
186 | 'upload_success_message' => '已成功上传:success个文件',
187 | 'go_on_add' => '继续添加',
188 | 'Q_TYPE_DENIED' => '对不起,不允许上传此类型文件',
189 | 'Q_EXCEED_NUM_LIMIT' => '对不起,已超出文件上传数量限制,最多只能上传:num个文件',
190 | 'F_EXCEED_SIZE' => '对不起,当前选择的文件过大',
191 | 'Q_EXCEED_SIZE_LIMIT' => '对不起,已超出文件大小限制',
192 | 'F_DUPLICATE' => '文件重复',
193 | 'confirm_delete_file' => '您确定要删除这个文件吗?',
194 | ],
195 | 'import_extension_confirm' => '确认导入拓展?',
196 | 'quick_create' => '快速创建',
197 | 'grid_items_selected' => '已选择 {n} 项',
198 | 'nothing_updated' => '没有任何数据被更改',
199 | 'welcome_back' => '欢迎回来,请登录您的账号。',
200 | 'documentation' => '文档',
201 | 'demo' => '示例',
202 | 'extensions' => '扩展',
203 | 'validation' => [
204 | 'match' => '与 :attribute 不匹配。',
205 | 'minlength' => ':attribute 字符长度不能少于 :min。',
206 | 'maxlength' => ':attribute 字符长度不能超出 :max。',
207 | ],
208 | 'menu_titles' => [
209 | 'index' => '主页',
210 | 'admin' => '系统',
211 | 'users' => '管理员',
212 | 'roles' => '角色',
213 | 'permission' => '权限',
214 | 'menu' => '菜单',
215 | 'operation_log' => '操作日志',
216 | 'helpers' => '开发工具',
217 | 'extensions' => '扩展',
218 | 'scaffold' => '代码生成器',
219 | 'icons' => '图标',
220 | ],
221 | ];
222 |
--------------------------------------------------------------------------------
/resources/lang/zh-CN/auth.php:
--------------------------------------------------------------------------------
1 | '用户名或密码错误。',
17 | 'throttle' => '您的尝试登录次数过多,请 :seconds 秒后再试。',
18 | 'The token has been blacklisted' => '令牌已列入黑名单',
19 | 'Token has expired' => 'Token 已过期',
20 | 'Token could not be parsed from the request.' => '无法从请求中解析令牌。',
21 |
22 | ];
23 |
--------------------------------------------------------------------------------
/resources/lang/zh-CN/select2.php:
--------------------------------------------------------------------------------
1 | '无法载入结果',
5 | 'input_too_long' => '请删除:num个字符',
6 | 'input_too_short' => '请输入至少:num个字符',
7 | 'loading_more' => '载入更多结果…',
8 | 'maximum_selected' => '最多只能选择:num个项目',
9 | 'no_results' => '未找到结果',
10 | 'searching' => '搜索中…',
11 | ];
12 |
--------------------------------------------------------------------------------
/resources/lang/zh-CN/validation.php:
--------------------------------------------------------------------------------
1 | ':attribute 必须接受。',
16 | 'active_url' => ':attribute 不是一个有效的网址。',
17 | 'after' => ':attribute 必须要晚于 :date。',
18 | 'after_or_equal' => ':attribute 必须要等于 :date 或更晚。',
19 | 'alpha' => ':attribute 只能由字母组成。',
20 | 'alpha_dash' => ':attribute 只能由字母、数字和斜杠组成。',
21 | 'alpha_num' => ':attribute 只能由字母和数字组成。',
22 | 'array' => ':attribute 必须是一个数组。',
23 | 'before' => ':attribute 必须要早于 :date。',
24 | 'before_or_equal' => ':attribute 必须要等于 :date 或更早。',
25 | 'between' => [
26 | 'numeric' => ':attribute 必须介于 :min - :max 之间。',
27 | 'file' => ':attribute 必须介于 :min - :max KB 之间。',
28 | 'string' => ':attribute 必须介于 :min - :max 个字符之间。',
29 | 'array' => ':attribute 必须只有 :min - :max 个单元。',
30 | ],
31 | 'boolean' => ':attribute 必须为布尔值。',
32 | 'confirmed' => ':attribute 两次输入不一致。',
33 | 'date' => ':attribute 不是一个有效的日期。',
34 | 'date_format' => ':attribute 的格式必须为 :format。',
35 | 'different' => ':attribute 和 :other 必须不同。',
36 | 'digits' => ':attribute 必须是 :digits 位的数字。',
37 | 'digits_between' => ':attribute 必须是介于 :min 和 :max 位的数字。',
38 | 'dimensions' => ':attribute 图片尺寸不正确。',
39 | 'distinct' => ':attribute 已经存在。',
40 | 'email' => ':attribute 不是一个合法的邮箱。',
41 | 'exists' => ':attribute 不存在。',
42 | 'file' => ':attribute 必须是文件。',
43 | 'filled' => ':attribute 不能为空。',
44 | 'gt' => [
45 | 'numeric' => ':attribute 必须大于 :value。',
46 | 'file' => ':attribute 必须大于 :value KB。',
47 | 'string' => ':attribute 必须多于 :value 个字符。',
48 | 'array' => ':attribute 必须多于 :value 个元素。',
49 | ],
50 | 'gte' => [
51 | 'numeric' => ':attribute 必须大于或等于 :value。',
52 | 'file' => ':attribute 必须大于或等于 :value KB。',
53 | 'string' => ':attribute 必须多于或等于 :value 个字符。',
54 | 'array' => ':attribute 必须多于或等于 :value 个元素。',
55 | ],
56 | 'image' => ':attribute 必须是图片。',
57 | 'in' => '已选的属性 :attribute 非法。',
58 | 'in_array' => ':attribute 没有在 :other 中。',
59 | 'integer' => ':attribute 必须是整数。',
60 | 'ip' => ':attribute 必须是有效的 IP 地址。',
61 | 'ipv4' => ':attribute 必须是有效的 IPv4 地址。',
62 | 'ipv6' => ':attribute 必须是有效的 IPv6 地址。',
63 | 'json' => ':attribute 必须是正确的 JSON 格式。',
64 | 'lt' => [
65 | 'numeric' => ':attribute 必须小于 :value。',
66 | 'file' => ':attribute 必须小于 :value KB。',
67 | 'string' => ':attribute 必须少于 :value 个字符。',
68 | 'array' => ':attribute 必须少于 :value 个元素。',
69 | ],
70 | 'lte' => [
71 | 'numeric' => ':attribute 必须小于或等于 :value。',
72 | 'file' => ':attribute 必须小于或等于 :value KB。',
73 | 'string' => ':attribute 必须少于或等于 :value 个字符。',
74 | 'array' => ':attribute 必须少于或等于 :value 个元素。',
75 | ],
76 | 'max' => [
77 | 'numeric' => ':attribute 不能大于 :max。',
78 | 'file' => ':attribute 不能大于 :max KB。',
79 | 'string' => ':attribute 不能大于 :max 个字符。',
80 | 'array' => ':attribute 最多允许 :max 个。',
81 | ],
82 | 'mimes' => ':attribute 必须是一个 :values 类型的文件。',
83 | 'mimetypes' => ':attribute 必须是一个 :values 类型的文件。',
84 | 'min' => [
85 | 'numeric' => ':attribute 必须大于等于 :min。',
86 | 'file' => ':attribute 大小不能小于 :min KB。',
87 | 'string' => ':attribute 至少 :min 个字符。',
88 | 'array' => ':attribute 至少要 :min 个。',
89 | ],
90 | 'not_in' => '已选的属性 :attribute 非法。',
91 | 'not_regex' => ':attribute 的格式错误。',
92 | 'numeric' => ':attribute 必须是一个数字。',
93 | 'present' => ':attribute 必须存在。',
94 | 'regex' => ':attribute 格式不正确。',
95 | 'required' => ':attribute 不能为空。',
96 | 'required_if' => '当 :other 为 :value 时 :attribute 不能为空。',
97 | 'required_unless' => '当 :other 不为 :value 时 :attribute 不能为空。',
98 | 'required_with' => '当 :values 存在时 :attribute 不能为空。',
99 | 'required_with_all' => '当 :values 存在时 :attribute 不能为空。',
100 | 'required_without' => '当 :values 不存在时 :attribute 不能为空。',
101 | 'required_without_all' => '当 :values 都不存在时 :attribute 不能为空。',
102 | 'same' => ':attribute 和 :other 必须相同。',
103 | 'size' => [
104 | 'numeric' => ':attribute 大小必须为 :size。',
105 | 'file' => ':attribute 大小必须为 :size KB。',
106 | 'string' => ':attribute 必须是 :size 个字符。',
107 | 'array' => ':attribute 必须为 :size 个。',
108 | ],
109 | 'string' => ':attribute 必须是一个字符串。',
110 | 'timezone' => ':attribute 必须是一个合法的时区值。',
111 | 'unique' => ':attribute 已经存在。',
112 | 'uploaded' => ':attribute 上传失败。',
113 | 'url' => ':attribute 格式不正确。',
114 | 'phone' => ':attribute 格式不正确。',
115 |
116 | /*
117 | |--------------------------------------------------------------------------
118 | | Custom Validation Language Lines
119 | |--------------------------------------------------------------------------
120 | |
121 | | Here you may specify custom validation messages for attributes using the
122 | | convention 'attribute.rule' to name the lines. This makes it quick to
123 | | specify a specific custom language line for a given attribute rule.
124 | |
125 | */
126 |
127 | 'custom' => [
128 | 'attribute-name' => [
129 | 'rule-name' => 'custom-message',
130 | ],
131 | ],
132 |
133 | /*
134 | |--------------------------------------------------------------------------
135 | | Custom Validation Attributes
136 | |--------------------------------------------------------------------------
137 | |
138 | | The following language lines are used to swap attribute place-holders
139 | | with something more reader friendly such as E-Mail Address instead
140 | | of 'email'. This simply helps us make messages a little cleaner.
141 | |
142 | */
143 |
144 | 'attributes' => [
145 | 'name' => '名称',
146 | 'username' => '用户名',
147 | 'email' => '邮箱',
148 | 'first_name' => '名',
149 | 'last_name' => '姓',
150 | 'password' => '密码',
151 | 'password_confirmation' => '确认密码',
152 | 'city' => '城市',
153 | 'country' => '国家',
154 | 'address' => '地址',
155 | 'phone' => '电话',
156 | 'mobile' => '手机',
157 | 'age' => '年龄',
158 | 'sex' => '性别',
159 | 'gender' => '性别',
160 | 'day' => '天',
161 | 'month' => '月',
162 | 'year' => '年',
163 | 'hour' => '时',
164 | 'minute' => '分',
165 | 'second' => '秒',
166 | 'title' => '标题',
167 | 'content' => '内容',
168 | 'description' => '描述',
169 | 'excerpt' => '摘要',
170 | 'date' => '日期',
171 | 'time' => '时间',
172 | 'available' => '可用的',
173 | 'size' => '大小',
174 |
175 | 'channel' => '支付渠道',
176 | 'pay_trade_no' => '付款交易流水号',
177 | 'merchant_id' => '商户ID',
178 | 'code_sn' => '付款码编号',
179 | 'merchant_account_name' => '收款账号',
180 | 'order_no' => '平台订单号',
181 | ],
182 | ];
183 |
--------------------------------------------------------------------------------
/src/Console/CreateRepositoryCommand.php:
--------------------------------------------------------------------------------
1 | noFound($this->getMessage());
19 | return parent::render();
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/Exceptions/Api/ApiRequestException.php:
--------------------------------------------------------------------------------
1 | requestError($this->getMessage());
19 | return parent::render();
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/Exceptions/Api/ApiSystemException.php:
--------------------------------------------------------------------------------
1 | sysError($this->getMessage());
18 | return parent::render();
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/Exceptions/Api/ApiUnAuthException.php:
--------------------------------------------------------------------------------
1 | unauthorized($this->getMessage());
18 | return parent::render();
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/Exceptions/ApiException.php:
--------------------------------------------------------------------------------
1 | errorData = $data;
30 | }
31 |
32 | public function noFound($message = '')
33 | {
34 | $this->message = $message ?: '没有找到对象';
35 | $this->code = self::NO_FOUND_ERROR;
36 | return $this;
37 | }
38 |
39 | public function unauthorized($message = '')
40 | {
41 | $this->message = $message ?: '验证失败,请先登录';
42 | $this->code = self::AUTH_ERROR;
43 | return $this;
44 | }
45 |
46 | public function requestError($message = '')
47 | {
48 | $this->message = $message ?: '参数错误';
49 | $this->code = self::BAD_REQUEST;
50 | return $this;
51 | }
52 |
53 | public function forbidden()
54 | {
55 | $this->message = '权限不足';
56 | $this->code = self::PERMISSION_ERROR;
57 | return $this;
58 | }
59 |
60 | public function dbError()
61 | {
62 | $this->message = '数据库错误';
63 | $this->code = self::DB_ERROR;
64 | return $this;
65 | }
66 |
67 | public function sysError($message = '')
68 | {
69 | $this->message = $message ?: '系统错误';
70 | $this->code = self::SYS_ERROR;
71 | return $this;
72 | }
73 |
74 | public function render()
75 | {
76 | if (request()->pjax()) {
77 | $error = new MessageBag([
78 | 'title' => '错误',
79 | 'message' => $this->getMessage(),
80 | ]);
81 | return back()->withInput()->with(compact('error'));
82 | } else {
83 | if (request()->input('_editable')) {
84 | return $this->apiResponse($this->getCode(), $this->getMessage(), $this->errorData, [
85 | 'status' => false,
86 | 'errors' => [$this->getMessage()],
87 | ]);
88 | } else {
89 | return $this->apiResponse($this->getCode(), $this->getMessage(), $this->errorData);
90 | }
91 | }
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/src/Facades/CacheClient.php:
--------------------------------------------------------------------------------
1 | url($url);
10 | }
11 |
12 | return $url;
13 | }
14 | }
15 | if (!function_exists('hash_generate')) {
16 | function hash_generate($length = 6)
17 | {
18 | $characters = str_repeat('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', $length);
19 |
20 | return substr(str_shuffle($characters), 0, $length);
21 | }
22 | }
23 |
24 | if (!function_exists('fmt')) {
25 | function fmt($format, ...$args)
26 | {
27 | if (count($args) > 0) {
28 | $format = preg_replace("/\{[^\{]+\}/", '%s', $format);
29 | return sprintf($format, ...$args);
30 | } else {
31 | return $format;
32 | }
33 | }
34 | }
35 |
36 | function mkdirs($dir, $mode = 0777)
37 | {
38 | if (is_dir($dir) || mkdir($dir, $mode)) {
39 | return true;
40 | }
41 | if (!mkdirs(dirname($dir), $mode)) {
42 | return false;
43 | }
44 | return mkdir($dir, $mode);
45 | }
46 |
--------------------------------------------------------------------------------
/src/LaravelQuickServiceProvider.php:
--------------------------------------------------------------------------------
1 | registerServices();
34 | $this->commands($this->commands);
35 | }
36 |
37 |
38 | public function boot()
39 | {
40 | $this->registerPublishing();
41 | }
42 |
43 | protected function registerServices()
44 | {
45 | $this->app->singleton('quick.cache.service', CacheService::class);
46 | }
47 |
48 | protected function registerPublishing()
49 | {
50 | if ($this->app->runningInConsole()) {
51 | $this->publishes([__DIR__ . '/../config' => config_path()]);
52 | $this->publishes([__DIR__ . '/../resources/lang' => resource_path('lang')]);
53 | }
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/src/Repositories/BaseRepository.php:
--------------------------------------------------------------------------------
1 | setDefaultCacheTime(config('laravel-quick.redis_key_expire'));
27 | }
28 |
29 | /**
30 | * @param $key
31 | * @param $field
32 | * @param $increment
33 | * @param null $ttl
34 | */
35 | public function hIncrBy($key, $field, $increment, $ttl = NULL)
36 | {
37 | RedisClient::hIncrBy(Cache::getPrefix() . $key, $field, $increment);
38 | if ($ttl) {
39 | $seconds = $this->getSeconds($ttl);
40 | $this->redisExpire($key, $seconds);
41 | }
42 | }
43 |
44 | /**
45 | * @param $sKey
46 | * @param $field
47 | *
48 | * @return array|mixed|string
49 | */
50 | public function hGet($sKey, $field)
51 | {
52 | $sData = RedisClient::hGet(Cache::getPrefix() . $sKey, $field);
53 | if ($sData) {
54 | $aData = json_decode($sData, true);
55 | if ($aData && (is_object($aData)) || (is_array($aData) && !empty($aData))) {
56 | $result = $aData;
57 | } else {
58 | $result = $sData;
59 | }
60 | return $result;
61 | } else {
62 | return NULL;
63 | }
64 | }
65 |
66 | /**
67 | * @param $key
68 | * @param $hashKey1
69 | * @param null $hashKey2
70 | * @param null $hashKeyN
71 | * @return mixed
72 | */
73 | public function hDel($key, $hashKey1, $hashKey2 = NULL, $hashKeyN = NULL)
74 | {
75 | return RedisClient::hDel(Cache::getPrefix() . $key, $hashKey1, $hashKey2, $hashKeyN);
76 | }
77 |
78 | /**
79 | * @param $sKey
80 | * @return mixed
81 | */
82 | public function hLen($sKey)
83 | {
84 | return RedisClient::hLen(Cache::getPrefix() . $sKey);
85 | }
86 |
87 | /**
88 | * @param $sKey
89 | * @param $field
90 | *
91 | * @return bool
92 | */
93 | public function hExists($sKey, $field)
94 | {
95 | return RedisClient::hExists($sKey, $field);
96 | }
97 |
98 | /**
99 | * @param $sKey
100 | * @param $field
101 | * @param $content
102 | * @param null $time
103 | *
104 | * @return bool|int
105 | */
106 | public function hSet($sKey, $field, $content, $time = NULL)
107 | {
108 | if (is_array($content) || is_object($content)) {
109 | $bRes = RedisClient::hSet(Cache::getPrefix() . $sKey, $field, json_encode($content, true));
110 | } else {
111 | $bRes = RedisClient::hSet(Cache::getPrefix() . $sKey, $field, $content);
112 | }
113 | self::redisExpire($sKey, $time);
114 | return $bRes;
115 | }
116 |
117 | /**
118 | * @param $sKey
119 | * @param $value
120 | * @param $count
121 | * @return mixed
122 | */
123 | public function lRem($sKey, $value, $count)
124 | {
125 | return RedisClient::lRem(Cache::getPrefix() . $sKey, $count, $value);
126 | }
127 |
128 | /**
129 | * @param $sKey
130 | * @param $start
131 | * @param $end
132 | *
133 | * @return array
134 | */
135 | public function lRange($sKey, $start, $end)
136 | {
137 | return RedisClient::lRange(Cache::getPrefix() . $sKey, $start, $end);
138 | }
139 |
140 | /**
141 | * @param $sKey
142 | * @return mixed
143 | */
144 | public function lLen($sKey)
145 | {
146 | return RedisClient::lLen(Cache::getPrefix() . $sKey);
147 | }
148 |
149 | /**
150 | * @param $sKey
151 | * @param $value
152 | * @return mixed
153 | */
154 | public function lPush($sKey, $value)
155 | {
156 | return RedisClient::lPush(Cache::getPrefix() . $sKey, $value);
157 | }
158 |
159 | /**
160 | * @param $sKey
161 | * @param $value
162 | * @return mixed
163 | */
164 | public function rPush($sKey, $value)
165 | {
166 | return RedisClient::rPush(Cache::getPrefix() . $sKey, $value);
167 | }
168 |
169 | /**
170 | * @param $sKey
171 | * @return mixed
172 | */
173 | public function rPop($sKey)
174 | {
175 | return RedisClient::rPop(Cache::getPrefix() . $sKey);
176 | }
177 |
178 | /**
179 | * @param $sKey
180 | * @return mixed
181 | */
182 | public function lPop($sKey)
183 | {
184 | return RedisClient::lPop(Cache::getPrefix() . $sKey);
185 | }
186 |
187 | /**
188 | * @param $sKey
189 | * @param $value
190 | * @return mixed
191 | */
192 | public function pfAdd($sKey, $value)
193 | {
194 | return RedisClient::pfAdd(Cache::getPrefix() . $sKey, $value);
195 | }
196 |
197 | /**
198 | * @param $sKey
199 | * @return mixed
200 | */
201 | public function pfCount($sKey)
202 | {
203 | return RedisClient::pfCount(Cache::getPrefix() . $sKey);
204 | }
205 |
206 | /**
207 | * @param $sKey
208 | * @param $score1
209 | * @param $value1
210 | */
211 | public function zAdd($sKey, $score1, $value1)
212 | {
213 | RedisClient::zAdd(Cache::getPrefix() . $sKey, $score1, $value1);
214 | return;
215 | }
216 |
217 | /**
218 | * @param $sKey
219 | * @param $start
220 | * @param $end
221 | * @return mixed
222 | */
223 | public function zCount($sKey, $start, $end)
224 | {
225 | return RedisClient::zCount(Cache::getPrefix() . $sKey, $start, $end);
226 | }
227 |
228 | /**
229 | * @param $sKey
230 | * @param $start
231 | * @param $end
232 | * @return mixed
233 | */
234 | public function zRemRangeByScore($sKey, $start, $end)
235 | {
236 | return RedisClient::zRemRangeByScore(Cache::getPrefix() . $sKey, $start, $end);
237 | }
238 |
239 | /**
240 | * @param $key
241 | * @param $ttl
242 | */
243 | public function redisExpire($key, $ttl)
244 | {
245 | RedisClient::expire(Cache::getPrefix() . $key, $ttl ?: $this->getDefaultCacheTime());
246 | }
247 |
248 | /**
249 | * @param $key
250 | * @param int $value
251 | * @param null $ttl
252 | * @return mixed
253 | */
254 | public function incrementEx($key, $value = 1, $ttl = NULL)
255 | {
256 | $res = $this->increment($key, $value);
257 | $seconds = $this->getSeconds($ttl);
258 | $this->redisExpire($key, $seconds);
259 | return $res;
260 | }
261 |
262 | /**
263 | * @param $key
264 | * @param int $value
265 | * @param null $ttl
266 | * @return mixed
267 | */
268 | public function decrementEx($key, $value = 1, $ttl = NULL)
269 | {
270 | $res = $this->decrement($key, $value);
271 | $seconds = $this->getSeconds($ttl);
272 | $this->redisExpire($key, $seconds);
273 | return $res;
274 | }
275 |
276 | /**
277 | * @param $key
278 | * @param $value
279 | * @return mixed
280 | */
281 | public function sAdd($key, $value)
282 | {
283 | return RedisClient::sAdd(Cache::getPrefix() . $key, $value);
284 | }
285 |
286 | /**
287 | * @param $key
288 | * @return mixed
289 | */
290 | public function sCard($key)
291 | {
292 | return RedisClient::sCard(Cache::getPrefix() . $key);
293 | }
294 |
295 | /**
296 | * @return mixed
297 | */
298 | public function flushAll()
299 | {
300 | return RedisClient::flushAll();
301 | }
302 |
303 | /**
304 | * @param $key
305 | * @return mixed
306 | */
307 | public function sRandMember($key)
308 | {
309 | return RedisClient::sRandMember(Cache::getPrefix() . $key);
310 | }
311 |
312 | /**
313 | * @param $method
314 | * @param $arguments
315 | * @return mixed
316 | */
317 | public function __call($method, $arguments)
318 | {
319 | return Cache::$method(... $arguments);
320 | }
321 |
322 | /**
323 | * @param $delay
324 | * @return Carbon
325 | */
326 | protected function parseDateInterval($delay)
327 | {
328 | if ($delay instanceof DateInterval) {
329 | $delay = Carbon::now()->add($delay);
330 | }
331 | return $delay;
332 | }
333 |
334 | /**
335 | * @param $ttl
336 | * @return Carbon|int
337 | */
338 | protected function getSeconds($ttl)
339 | {
340 | $duration = $this->parseDateInterval($ttl);
341 |
342 | if ($duration instanceof DateTimeInterface) {
343 | $duration = Carbon::now()->diffInRealSeconds($duration, false);
344 | }
345 |
346 | return (int)$duration > 0 ? $duration : 0;
347 | }
348 | }
349 |
--------------------------------------------------------------------------------
/src/Traits/AttributeStatusTrait.php:
--------------------------------------------------------------------------------
1 | getStatusLists();
16 | }
17 |
18 | /**
19 | * @return mixed
20 | */
21 | public function getStatusLists()
22 | {
23 | return $this->statusLists ?: ['停用', '启用'];
24 | }
25 |
26 | public function getStatusTextAttribute()
27 | {
28 | return $this->getStatusArrAttribute()[$this->status];
29 | }
30 |
31 | /**
32 | * 状态范围查询(可传参指定要限定的状态范围,默认为大于0的内容)
33 | *
34 | * @param $query
35 | * @param array $status
36 | *
37 | * @return mixed
38 | */
39 | public function scopeStatus($query, $status = [])
40 | {
41 | if (!is_array($status)) {
42 | $status = str2arr($status);
43 | }
44 | if (!empty($status)) {
45 | return $query->whereIn('status', $status);
46 | }
47 | return $query->where('status', '>', 0);
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/Traits/JsonResponseTrait.php:
--------------------------------------------------------------------------------
1 | $code['code'],
31 | 'message' => $code['message'],
32 | 'data' => $code['data'],
33 | ];
34 | } else {
35 | $res = [
36 | 'code' => $code,
37 | 'message' => $message,
38 | 'data' => $data,
39 | ];
40 | }
41 | return array_merge($res, $attach);
42 | }
43 |
44 |
45 | /**
46 | * @param int $code
47 | * @param string $message
48 | * @param null $data
49 | *
50 | * @return \Illuminate\Http\JsonResponse
51 | * 返回值规范说明:
52 | * 1、成功正数(多种成功情况,不同的正数数字标示,原则上是不样的message对应不同的code)
53 | * 2、报错、失败、异常负数(返回数据集,但数据集为[]或null,不属于报错、失败、异常,所以视为成功,仅仅暂无数据而已)
54 | * 3、404、403、500等http status code可以均直接加上`-`号(如:-404),作为错误code,方便大家一目了然
55 | */
56 | protected function apiResponse($code = FoundationResponse::HTTP_OK, $message = '', $data = NULL, $attach = [])
57 | {
58 | $res = $this->apiArray($code, $message, $data, $attach);
59 | if ($this->redirect_url) {
60 | $res['redirect_url'] = $this->redirect_url;
61 | }
62 | return Response::json($res)->setEncodingOptions(JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
63 | }
64 |
65 | /**
66 | * @param string $message
67 | * @param null $data
68 | * @param int $code
69 | * @param array $attach
70 | * @return \Illuminate\Http\JsonResponse
71 | */
72 | protected function success($message = '', $data = NULL, $code = FoundationResponse::HTTP_OK, $attach = [])
73 | {
74 | return $this->apiResponse($code, $message ?: 'Success', $data, $attach);
75 | }
76 |
77 | /**
78 | * @param string $message
79 | * @param null $data
80 | * @param int $code
81 | * @param array $attach
82 | * @return \Illuminate\Http\JsonResponse
83 | */
84 | protected function error($message = 'Error', $data = NULL, $code = -1, $attach = [])
85 | {
86 | return $this->apiResponse($code, $message, $data, $attach);
87 | }
88 |
89 | /**
90 | * 设置 data.url 的值
91 | *
92 | * @param $url
93 | * @param array $param
94 | *
95 | * @return $this
96 | */
97 | protected function redirectUrl($url, $param = [])
98 | {
99 | $this->redirect_url = url($url, $param);
100 | return $this;
101 | }
102 | }
103 |
--------------------------------------------------------------------------------