1
0
Fork 0

api keyword

main
panliang 2024-07-09 13:26:31 +08:00
parent a1173572db
commit 927cdb0b29
13 changed files with 557 additions and 25 deletions

View File

@ -0,0 +1,43 @@
<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Http\Resources\Json\AnonymousResourceCollection;
use Illuminate\Support\Facades\Auth;
use App\Models\User;
class BaseController extends Controller
{
public function json($data, $code = Response::HTTP_OK, $message = '', $additional = [])
{
$result = ['code' => $code, 'data' => $data, 'message' => $message];
if ($data instanceof AnonymousResourceCollection) {
$data = $data->resource;
}
if ($data instanceof LengthAwarePaginator) {
$result['data'] = $data->items();
$additional['meta'] = ['total' => $data->total()];
}
$result = array_merge($result, $additional);
return response()->json($result);
}
public function success($data = null, $message = '')
{
return $this->json($data, Response::HTTP_OK, $message);
}
public function error($message = '', $code = Response::HTTP_BAD_REQUEST, $data = null)
{
return $this->json($data, $code, $message);
}
public function user(): User
{
return Auth::guard('api')->user();
}
}

View File

@ -0,0 +1,28 @@
<?php
namespace App\Http\Controllers\Api;
use App\Http\Resources\KeywordResource;
use App\Models\Keyword;
use App\Services\KeywordService;
use Illuminate\Http\Request;
class KeywordController extends BaseController
{
public function index(Request $request)
{
$query = KeywordService::make()->query();
$list = $query->filter($request->all())->get();
return $this->json(KeywordResource::collection($list));
}
public function tree(Request $request)
{
$query = KeywordService::make()->query();
$list = $query->filter($request->all())->get();
$list_resource = KeywordResource::collection($list)->toArray($request);
$data = array2tree($list_resource, $list->min('parent_id') ?: 0);;
return $this->json($data);
}
}

View File

@ -0,0 +1,23 @@
<?php
namespace App\Http\Controllers\Api;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
class WebController extends BaseController
{
public function upload(Request $request)
{
$request->validate([
'file' => ['required', 'file']
]);
$disk = Storage::disk();
$path = $disk->putFile($request->input('path', 'upload'), $request->file('file'));
return $this->success([
'file' => $disk->url($path)
]);
}
}

View File

@ -0,0 +1,33 @@
<?php
namespace App\Http\Resources;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
class KeywordResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @return array<string, mixed>
*/
public function toArray(Request $request): array
{
return [
'id' => $this->id,
'key' => $this->key,
'name' => $this->name,
'value' => $this->value,
'parent_id' => $this->parent_id,
'path' => $this->path,
'sort' => $this->sort,
'options' => $this->options,
'image' => $this->image,
'images' => $this->images,
'description' => $this->description,
'content' => $this->content,
'created_at' => $this->created_at?->timestamp,
];
}
}

View File

@ -48,9 +48,4 @@ class KeywordFilter extends ModelFilter
{ {
$this->whereLike('path', '-'.$key.'-'); $this->whereLike('path', '-'.$key.'-');
} }
public function level($key)
{
$this->where('level', $key);
}
} }

View File

@ -14,7 +14,7 @@ class Keyword extends Model
{ {
use DatetimeFormatterTrait, Filterable, TreePath; use DatetimeFormatterTrait, Filterable, TreePath;
protected $fillable = ['id', 'name', 'key', 'value', 'parent_id', 'path', 'sort', 'level', 'options', 'image', 'images', 'description', 'content']; protected $fillable = ['id', 'name', 'key', 'value', 'parent_id', 'path', 'sort', 'options', 'image', 'images', 'description', 'content'];
protected $casts = [ protected $casts = [
'options' => 'array', 'options' => 'array',

View File

@ -17,7 +17,7 @@ class KeywordService extends AdminService
public function getTree($filters = []) public function getTree($filters = [])
{ {
$list = $this->query()->filter($filters)->sort()->get(); $list = $this->query()->filter($filters)->get();
return array2tree($list->toArray(), $list->min('parent_id') ?: 0); return array2tree($list->toArray(), $list->min('parent_id') ?: 0);
} }

View File

@ -66,19 +66,4 @@ trait TreePath
{ {
return $q->orderBy('parent_id')->orderBy('sort'); return $q->orderBy('parent_id')->orderBy('sort');
} }
public static function getTreeList($list, $pid = 0)
{
$tree = collect();
foreach ($list->where('parent_id', $pid)->all() as $item) {
$item->children = [];
$children = $list->where('parent_id', $item->id);
if ($children->count() > 0) {
$item->children = static::getTreeList($list, $item->id);
}
$tree->push($item);
}
return $tree;
}
} }

View File

@ -3,6 +3,8 @@
use Illuminate\Foundation\Application; use Illuminate\Foundation\Application;
use Illuminate\Foundation\Configuration\Exceptions; use Illuminate\Foundation\Configuration\Exceptions;
use Illuminate\Foundation\Configuration\Middleware; use Illuminate\Foundation\Configuration\Middleware;
use Illuminate\Http\Request;
use Illuminate\Validation\ValidationException;
return Application::configure(basePath: dirname(__DIR__)) return Application::configure(basePath: dirname(__DIR__))
->withRouting( ->withRouting(
@ -15,5 +17,13 @@ return Application::configure(basePath: dirname(__DIR__))
// //
}) })
->withExceptions(function (Exceptions $exceptions) { ->withExceptions(function (Exceptions $exceptions) {
// $exceptions->render(function (ValidationException $exception, Request $request) {
if ($request->acceptsJson()) {
return response()->json([
'code' => $exception->status,
'message' => $exception->getMessage(),
'data' => $exception->errors(),
]);
}
});
})->create(); })->create();

View File

@ -22,7 +22,6 @@ return new class extends Migration
$table->json('images')->nullable(); $table->json('images')->nullable();
$table->unsignedInteger('sort')->default(0)->comment('排序(正序)'); $table->unsignedInteger('sort')->default(0)->comment('排序(正序)');
$table->unsignedBigInteger('parent_id')->default(0)->comment('上级ID'); $table->unsignedBigInteger('parent_id')->default(0)->comment('上级ID');
$table->unsignedInteger('level')->default(1)->comment('层级');
$table->string('path')->default('-')->comment('所有的父级ID'); $table->string('path')->default('-')->comment('所有的父级ID');
$table->json('options')->nullable()->comment('扩展'); $table->json('options')->nullable()->comment('扩展');
$table->timestamps(); $table->timestamps();

View File

@ -0,0 +1,194 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Validation Language Lines
|--------------------------------------------------------------------------
|
| The following language lines contain the default error messages used by
| the validator class. Some of these rules have multiple versions such
| as the size rules. Feel free to tweak each of these messages here.
|
*/
'accepted' => 'The :attribute field must be accepted.',
'accepted_if' => 'The :attribute field must be accepted when :other is :value.',
'active_url' => 'The :attribute field must be a valid URL.',
'after' => 'The :attribute field must be a date after :date.',
'after_or_equal' => 'The :attribute field must be a date after or equal to :date.',
'alpha' => 'The :attribute field must only contain letters.',
'alpha_dash' => 'The :attribute field must only contain letters, numbers, dashes, and underscores.',
'alpha_num' => 'The :attribute field must only contain letters and numbers.',
'array' => 'The :attribute field must be an array.',
'ascii' => 'The :attribute field must only contain single-byte alphanumeric characters and symbols.',
'before' => 'The :attribute field must be a date before :date.',
'before_or_equal' => 'The :attribute field must be a date before or equal to :date.',
'between' => [
'array' => 'The :attribute field must have between :min and :max items.',
'file' => 'The :attribute field must be between :min and :max kilobytes.',
'numeric' => 'The :attribute field must be between :min and :max.',
'string' => 'The :attribute field must be between :min and :max characters.',
],
'boolean' => 'The :attribute field must be true or false.',
'can' => 'The :attribute field contains an unauthorized value.',
'confirmed' => 'The :attribute field confirmation does not match.',
'contains' => 'The :attribute field is missing a required value.',
'current_password' => 'The password is incorrect.',
'date' => 'The :attribute field must be a valid date.',
'date_equals' => 'The :attribute field must be a date equal to :date.',
'date_format' => 'The :attribute field must match the format :format.',
'decimal' => 'The :attribute field must have :decimal decimal places.',
'declined' => 'The :attribute field must be declined.',
'declined_if' => 'The :attribute field must be declined when :other is :value.',
'different' => 'The :attribute field and :other must be different.',
'digits' => 'The :attribute field must be :digits digits.',
'digits_between' => 'The :attribute field must be between :min and :max digits.',
'dimensions' => 'The :attribute field has invalid image dimensions.',
'distinct' => 'The :attribute field has a duplicate value.',
'doesnt_end_with' => 'The :attribute field must not end with one of the following: :values.',
'doesnt_start_with' => 'The :attribute field must not start with one of the following: :values.',
'email' => 'The :attribute field must be a valid email address.',
'ends_with' => 'The :attribute field must end with one of the following: :values.',
'enum' => 'The selected :attribute is invalid.',
'exists' => 'The selected :attribute is invalid.',
'extensions' => 'The :attribute field must have one of the following extensions: :values.',
'file' => 'The :attribute field must be a file.',
'filled' => 'The :attribute field must have a value.',
'gt' => [
'array' => 'The :attribute field must have more than :value items.',
'file' => 'The :attribute field must be greater than :value kilobytes.',
'numeric' => 'The :attribute field must be greater than :value.',
'string' => 'The :attribute field must be greater than :value characters.',
],
'gte' => [
'array' => 'The :attribute field must have :value items or more.',
'file' => 'The :attribute field must be greater than or equal to :value kilobytes.',
'numeric' => 'The :attribute field must be greater than or equal to :value.',
'string' => 'The :attribute field must be greater than or equal to :value characters.',
],
'hex_color' => 'The :attribute field must be a valid hexadecimal color.',
'image' => 'The :attribute field must be an image.',
'in' => 'The selected :attribute is invalid.',
'in_array' => 'The :attribute field must exist in :other.',
'integer' => 'The :attribute field must be an integer.',
'ip' => 'The :attribute field must be a valid IP address.',
'ipv4' => 'The :attribute field must be a valid IPv4 address.',
'ipv6' => 'The :attribute field must be a valid IPv6 address.',
'json' => 'The :attribute field must be a valid JSON string.',
'list' => 'The :attribute field must be a list.',
'lowercase' => 'The :attribute field must be lowercase.',
'lt' => [
'array' => 'The :attribute field must have less than :value items.',
'file' => 'The :attribute field must be less than :value kilobytes.',
'numeric' => 'The :attribute field must be less than :value.',
'string' => 'The :attribute field must be less than :value characters.',
],
'lte' => [
'array' => 'The :attribute field must not have more than :value items.',
'file' => 'The :attribute field must be less than or equal to :value kilobytes.',
'numeric' => 'The :attribute field must be less than or equal to :value.',
'string' => 'The :attribute field must be less than or equal to :value characters.',
],
'mac_address' => 'The :attribute field must be a valid MAC address.',
'max' => [
'array' => 'The :attribute field must not have more than :max items.',
'file' => 'The :attribute field must not be greater than :max kilobytes.',
'numeric' => 'The :attribute field must not be greater than :max.',
'string' => 'The :attribute field must not be greater than :max characters.',
],
'max_digits' => 'The :attribute field must not have more than :max digits.',
'mimes' => 'The :attribute field must be a file of type: :values.',
'mimetypes' => 'The :attribute field must be a file of type: :values.',
'min' => [
'array' => 'The :attribute field must have at least :min items.',
'file' => 'The :attribute field must be at least :min kilobytes.',
'numeric' => 'The :attribute field must be at least :min.',
'string' => 'The :attribute field must be at least :min characters.',
],
'min_digits' => 'The :attribute field must have at least :min digits.',
'missing' => 'The :attribute field must be missing.',
'missing_if' => 'The :attribute field must be missing when :other is :value.',
'missing_unless' => 'The :attribute field must be missing unless :other is :value.',
'missing_with' => 'The :attribute field must be missing when :values is present.',
'missing_with_all' => 'The :attribute field must be missing when :values are present.',
'multiple_of' => 'The :attribute field must be a multiple of :value.',
'not_in' => 'The selected :attribute is invalid.',
'not_regex' => 'The :attribute field format is invalid.',
'numeric' => 'The :attribute field must be a number.',
'password' => [
'letters' => 'The :attribute field must contain at least one letter.',
'mixed' => 'The :attribute field must contain at least one uppercase and one lowercase letter.',
'numbers' => 'The :attribute field must contain at least one number.',
'symbols' => 'The :attribute field must contain at least one symbol.',
'uncompromised' => 'The given :attribute has appeared in a data leak. Please choose a different :attribute.',
],
'present' => 'The :attribute field must be present.',
'present_if' => 'The :attribute field must be present when :other is :value.',
'present_unless' => 'The :attribute field must be present unless :other is :value.',
'present_with' => 'The :attribute field must be present when :values is present.',
'present_with_all' => 'The :attribute field must be present when :values are present.',
'prohibited' => 'The :attribute field is prohibited.',
'prohibited_if' => 'The :attribute field is prohibited when :other is :value.',
'prohibited_unless' => 'The :attribute field is prohibited unless :other is in :values.',
'prohibits' => 'The :attribute field prohibits :other from being present.',
'regex' => 'The :attribute field format is invalid.',
'required' => 'The :attribute field is required.',
'required_array_keys' => 'The :attribute field must contain entries for: :values.',
'required_if' => 'The :attribute field is required when :other is :value.',
'required_if_accepted' => 'The :attribute field is required when :other is accepted.',
'required_if_declined' => 'The :attribute field is required when :other is declined.',
'required_unless' => 'The :attribute field is required unless :other is in :values.',
'required_with' => 'The :attribute field is required when :values is present.',
'required_with_all' => 'The :attribute field is required when :values are present.',
'required_without' => 'The :attribute field is required when :values is not present.',
'required_without_all' => 'The :attribute field is required when none of :values are present.',
'same' => 'The :attribute field must match :other.',
'size' => [
'array' => 'The :attribute field must contain :size items.',
'file' => 'The :attribute field must be :size kilobytes.',
'numeric' => 'The :attribute field must be :size.',
'string' => 'The :attribute field must be :size characters.',
],
'starts_with' => 'The :attribute field must start with one of the following: :values.',
'string' => 'The :attribute field must be a string.',
'timezone' => 'The :attribute field must be a valid timezone.',
'unique' => 'The :attribute has already been taken.',
'uploaded' => 'The :attribute failed to upload.',
'uppercase' => 'The :attribute field must be uppercase.',
'url' => 'The :attribute field must be a valid URL.',
'ulid' => 'The :attribute field must be a valid ULID.',
'uuid' => 'The :attribute field must be a valid UUID.',
/*
|--------------------------------------------------------------------------
| Custom Validation Language Lines
|--------------------------------------------------------------------------
|
| Here you may specify custom validation messages for attributes using the
| convention "attribute.rule" to name the lines. This makes it quick to
| specify a specific custom language line for a given attribute rule.
|
*/
'custom' => [
'attribute-name' => [
'rule-name' => 'custom-message',
],
],
/*
|--------------------------------------------------------------------------
| Custom Validation Attributes
|--------------------------------------------------------------------------
|
| The following language lines are used to swap our attribute placeholder
| with something more reader friendly such as "E-Mail Address" instead
| of "email". This simply helps us make our message more expressive.
|
*/
'attributes' => [],
];

View File

@ -0,0 +1,217 @@
<?php
return [
'accepted' => '您必须接受 :attribute。',
'accepted_if' => '当 :other 为 :value 时,必须接受 :attribute。',
'active_url' => ':Attribute 不是一个有效的网址。',
'after' => ':Attribute 必须要晚于 :date。',
'after_or_equal' => ':Attribute 必须要等于 :date 或更晚。',
'alpha' => ':Attribute 只能由字母组成。',
'alpha_dash' => ':Attribute 只能由字母、数字、短划线(-)和下划线(_)组成。',
'alpha_num' => ':Attribute 只能由字母和数字组成。',
'array' => ':Attribute 必须是一个数组。',
'ascii' => ':Attribute 必须仅包含单字节字母数字字符和符号。',
'before' => ':Attribute 必须要早于 :date。',
'before_or_equal' => ':Attribute 必须要等于 :date 或更早。',
'between' => [
'array' => ':Attribute 必须只有 :min - :max 个单元。',
'file' => ':Attribute 必须介于 :min - :max KB 之间。',
'numeric' => ':Attribute 必须介于 :min - :max 之间。',
'string' => ':Attribute 必须介于 :min - :max 个字符之间。',
],
'boolean' => ':Attribute 必须为布尔值。',
'can' => ':Attribute 字段包含未经授权的值。',
'confirmed' => ':Attribute 两次输入不一致。',
'current_password' => '密码错误。',
'date' => ':Attribute 不是一个有效的日期。',
'date_equals' => ':Attribute 必须要等于 :date。',
'date_format' => ':Attribute 的格式必须为 :format。',
'decimal' => ':Attribute 必须有 :decimal 位小数。',
'declined' => ':Attribute 必须是拒绝的。',
'declined_if' => '当 :other 为 :value 时字段 :attribute 必须是拒绝的。',
'different' => ':Attribute 和 :other 必须不同。',
'digits' => ':Attribute 必须是 :digits 位数字。',
'digits_between' => ':Attribute 必须是介于 :min 和 :max 位的数字。',
'dimensions' => ':Attribute 图片尺寸不正确。',
'distinct' => ':Attribute 已经存在。',
'doesnt_end_with' => ':Attribute 不能以以下之一结尾: :values。',
'doesnt_start_with' => ':Attribute 不能以下列之一开头: :values。',
'email' => ':Attribute 不是一个合法的邮箱。',
'ends_with' => ':Attribute 必须以 :values 为结尾。',
'enum' => ':Attribute 值不正确。',
'exists' => ':Attribute 不存在。',
'file' => ':Attribute 必须是文件。',
'filled' => ':Attribute 不能为空。',
'gt' => [
'array' => ':Attribute 必须多于 :value 个元素。',
'file' => ':Attribute 必须大于 :value KB。',
'numeric' => ':Attribute 必须大于 :value。',
'string' => ':Attribute 必须多于 :value 个字符。',
],
'gte' => [
'array' => ':Attribute 必须多于或等于 :value 个元素。',
'file' => ':Attribute 必须大于或等于 :value KB。',
'numeric' => ':Attribute 必须大于或等于 :value。',
'string' => ':Attribute 必须多于或等于 :value 个字符。',
],
'image' => ':Attribute 必须是图片。',
'in' => '已选的属性 :attribute 无效。',
'in_array' => ':Attribute 必须在 :other 中。',
'integer' => ':Attribute 必须是整数。',
'ip' => ':Attribute 必须是有效的 IP 地址。',
'ipv4' => ':Attribute 必须是有效的 IPv4 地址。',
'ipv6' => ':Attribute 必须是有效的 IPv6 地址。',
'json' => ':Attribute 必须是正确的 JSON 格式。',
'lowercase' => ':Attribute 必须小写。',
'lt' => [
'array' => ':Attribute 必须少于 :value 个元素。',
'file' => ':Attribute 必须小于 :value KB。',
'numeric' => ':Attribute 必须小于 :value。',
'string' => ':Attribute 必须少于 :value 个字符。',
],
'lte' => [
'array' => ':Attribute 必须少于或等于 :value 个元素。',
'file' => ':Attribute 必须小于或等于 :value KB。',
'numeric' => ':Attribute 必须小于或等于 :value。',
'string' => ':Attribute 必须少于或等于 :value 个字符。',
],
'mac_address' => ':Attribute 必须是一个有效的 MAC 地址。',
'max' => [
'array' => ':Attribute 最多只有 :max 个单元。',
'file' => ':Attribute 不能大于 :max KB。',
'numeric' => ':Attribute 不能大于 :max。',
'string' => ':Attribute 不能大于 :max 个字符。',
],
'max_digits' => ':Attribute 不能超过 :max 位数。',
'mimes' => ':Attribute 必须是一个 :values 类型的文件。',
'mimetypes' => ':Attribute 必须是一个 :values 类型的文件。',
'min' => [
'array' => ':Attribute 至少有 :min 个单元。',
'file' => ':Attribute 大小不能小于 :min KB。',
'numeric' => ':Attribute 必须大于等于 :min。',
'string' => ':Attribute 至少为 :min 个字符。',
],
'min_digits' => ':Attribute 必须至少有 :min 位数。',
'missing' => '必须缺少 :attribute 字段。',
'missing_if' => '当 :other 为 :value 时,必须缺少 :attribute 字段。',
'missing_unless' => '必须缺少 :attribute 字段,除非 :other 是 :value。',
'missing_with' => '存在 :values 时,必须缺少 :attribute 字段。',
'missing_with_all' => '存在 :values 时,必须缺少 :attribute 字段。',
'multiple_of' => ':Attribute 必须是 :value 中的多个值。',
'not_in' => '已选的属性 :attribute 非法。',
'not_regex' => ':Attribute 的格式错误。',
'numeric' => ':Attribute 必须是一个数字。',
'password' => [
'letters' => ':Attribute 必须至少包含一个字母。',
'mixed' => ':Attribute 必须至少包含一个大写字母和一个小写字母。',
'numbers' => ':Attribute 必须至少包含一个数字。',
'symbols' => ':Attribute 必须至少包含一个符号。',
'uncompromised' => '给定的 :attribute 出现在已经泄漏的密码中。请选择不同的 :attribute。',
],
'present' => ':Attribute 必须存在。',
'prohibited' => ':Attribute 字段被禁止。',
'prohibited_if' => '当 :other 为 :value 时,禁止 :attribute 字段。',
'prohibited_unless' => ':Attribute 字段被禁止,除非 :other 位于 :values 中。',
'prohibits' => ':Attribute 字段禁止出现 :other。',
'regex' => ':Attribute 格式不正确。',
'required' => ':Attribute 不能为空。',
'required_array_keys' => ':Attribute 至少包含指定的键::values.',
'required_if' => '当 :other 为 :value 时 :attribute 不能为空。',
'required_if_accepted' => '当 :other 存在时,:attribute 不能为空。',
'required_unless' => '当 :other 不为 :values 时 :attribute 不能为空。',
'required_with' => '当 :values 存在时 :attribute 不能为空。',
'required_with_all' => '当 :values 存在时 :attribute 不能为空。',
'required_without' => '当 :values 不存在时 :attribute 不能为空。',
'required_without_all' => '当 :values 都不存在时 :attribute 不能为空。',
'same' => ':Attribute 和 :other 必须相同。',
'size' => [
'array' => ':Attribute 必须为 :size 个单元。',
'file' => ':Attribute 大小必须为 :size KB。',
'numeric' => ':Attribute 大小必须为 :size。',
'string' => ':Attribute 必须是 :size 个字符。',
],
'starts_with' => ':Attribute 必须以 :values 为开头。',
'string' => ':Attribute 必须是一个字符串。',
'timezone' => ':Attribute 必须是一个合法的时区值。',
'ulid' => ':Attribute 必须是有效的 ULID。',
'unique' => ':Attribute 已经存在。',
'uploaded' => ':Attribute 上传失败。',
'uppercase' => ':Attribute 必须大写',
'url' => ':Attribute 格式不正确。',
'uuid' => ':Attribute 必须是有效的 UUID。',
'attributes' => [
'address' => '地址',
'age' => '年龄',
'amount' => '数额',
'area' => '区域',
'available' => '可用的',
'birthday' => '生日',
'body' => '身体',
'city' => '城市',
'content' => '内容',
'country' => '国家',
'created_at' => '创建于',
'creator' => '创建者',
'current_password' => '当前密码',
'date' => '日期',
'date_of_birth' => '出生日期',
'day' => '天',
'deleted_at' => '删除于',
'description' => '描述',
'district' => '地区',
'duration' => '期间',
'email' => '邮箱',
'excerpt' => '摘要',
'filter' => '过滤',
'first_name' => '名',
'gender' => '性别',
'group' => '组',
'hour' => '时',
'image' => '图像',
'last_name' => '姓',
'lesson' => '课程',
'line_address_1' => '线路地址 1',
'line_address_2' => '线路地址 2',
'message' => '信息',
'middle_name' => '中间名字',
'minute' => '分',
'mobile' => '手机',
'month' => '月',
'name' => '名称',
'national_code' => '国家代码',
'number' => '数字',
'password' => '密码',
'password_confirmation' => '确认密码',
'phone' => '电话',
'photo' => '照片',
'postal_code' => '邮政编码',
'price' => '价格',
'province' => '省',
'recaptcha_response_field' => '重复验证码响应字段',
'remember' => '记住',
'restored_at' => '恢复于',
'result_text_under_image' => '图像下的结果文本',
'role' => '角色',
'second' => '秒',
'sex' => '性别',
'short_text' => '短文本',
'size' => '大小',
'state' => '状态',
'street' => '街道',
'student' => '学生',
'subject' => '主题',
'teacher' => '教师',
'terms' => '条款',
'test_description' => '测试说明',
'test_locale' => '测试语言环境',
'test_name' => '测试名称',
'text' => '文本',
'time' => '时间',
'title' => '标题',
'updated_at' => '更新于',
'username' => '用户名',
'year' => '年',
'money' => '金额',
],
'phone' => '不是一个有效的手机号',
];

View File

@ -1,5 +1,10 @@
<?php <?php
use Illuminate\Http\Request; use App\Http\Controllers\Api\KeywordController;
use App\Http\Controllers\Api\WebController;
use Illuminate\Support\Facades\Route; use Illuminate\Support\Facades\Route;
Route::get('keyword', [KeywordController::class, 'index']);
Route::get('keyword/tree', [KeywordController::class, 'tree']);
Route::post('web/upload', [WebController::class, 'upload']);