generated from liutk/owl-admin-base
0.85
parent
ea174e3b88
commit
26dc3dfa6f
|
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\ContactRequest;
|
||||
use App\Models\{Contact,Keyword};
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Http\Resources\{KeywordResource};
|
||||
|
||||
class ContactController extends Controller
|
||||
{
|
||||
|
||||
public function store(ContactRequest $request)
|
||||
{
|
||||
$inputParams = $request->input();
|
||||
try {
|
||||
DB::beginTransaction();
|
||||
Contact::create($inputParams);
|
||||
DB::commit();
|
||||
} catch(\Throwable $th) {
|
||||
DB::rollBack();
|
||||
report($th);
|
||||
|
||||
return $this->error('提交失败,请稍后再试');
|
||||
}
|
||||
|
||||
return $this->success('提交成功!');
|
||||
}
|
||||
|
||||
/**
|
||||
* 标签列表
|
||||
*/
|
||||
public function types(Request $request){
|
||||
$query = Keyword::allChildrenOfKey('contact_types');
|
||||
$list = $query->sort()->get();
|
||||
return $this->json(KeywordResource::collection($list));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Contracts\Validation\Validator;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Http\Exceptions\HttpResponseException;
|
||||
use App\Rules\CaptchaRule;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class ContactRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'name' => 'required|string|max:20',
|
||||
'phone' => 'required|string|regex:/^1[3-9]\d{9}$/|unique:contacts,phone',
|
||||
'captcha' => ['required', 'string', new CaptchaRule(request()->input('key'))],
|
||||
'company' => 'required|string|max:50',
|
||||
'type' => ['required', 'integer', Rule::exists('keywords', 'id')->where('parent_key', 'contact_types')],
|
||||
'content' => 'required|string|max:255',
|
||||
'key' => 'required|string|max:255',
|
||||
];
|
||||
}
|
||||
|
||||
public function messages()
|
||||
{
|
||||
$messages = [
|
||||
'name.required' => '姓名不能为空',
|
||||
'name.max' => '姓名最大不能超过20长度',
|
||||
'phone.required' => '手机号不能为空',
|
||||
'phone.regex' => '手机号格式不正确',
|
||||
'phone.unique' => '该手机号已提交过询价,请耐心等待工作人员联系',
|
||||
'company.required' => '公司不能为空',
|
||||
'company.max' => '公司名称最大不能超过50长度',
|
||||
'content.required' => '需求描述不能为空',
|
||||
'content.max' => '需求描述最大不能超过200长度',
|
||||
'captcha.required' => '请输入验证码',
|
||||
'type.required' => '请选择业务需求',
|
||||
'type.exists' => '业务需求类型不存在',
|
||||
'key.required' => '非法请求',
|
||||
];
|
||||
|
||||
return $messages;
|
||||
}
|
||||
|
||||
protected function failedValidation(Validator $validator)
|
||||
{
|
||||
$error = $validator->errors()->all();
|
||||
throw new HttpResponseException(response()->json(['data' => [], 'code' => 400, 'message' => $error[0]]));
|
||||
}
|
||||
}
|
||||
|
|
@ -4,8 +4,35 @@ namespace App\Models;
|
|||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use EloquentFilter\Filterable;
|
||||
|
||||
class Contact extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
use Filterable;
|
||||
|
||||
protected function serializeDate(\DateTimeInterface $date)
|
||||
{
|
||||
return $date->format('Y-m-d H:i:s');
|
||||
}
|
||||
|
||||
protected $casts = [
|
||||
'created_at' => 'datetime:Y-m-d H:i:s',
|
||||
'updated_at' => 'datetime:Y-m-d H:i:s',
|
||||
'status' => 'boolean',
|
||||
];
|
||||
|
||||
protected $fillable = [
|
||||
'name',
|
||||
'phone',
|
||||
'company',
|
||||
'type',
|
||||
'content',
|
||||
];
|
||||
|
||||
|
||||
public function scopeSort($q)
|
||||
{
|
||||
$q->orderBy('created_at', 'desc');
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,43 @@
|
|||
<?php
|
||||
|
||||
namespace App\Rules;
|
||||
|
||||
use App\Services\CaptchaService;
|
||||
use Closure;
|
||||
use Illuminate\Contracts\Validation\ValidationRule;
|
||||
use Illuminate\Support\Facades\App;
|
||||
|
||||
class CaptchaRule implements ValidationRule
|
||||
{
|
||||
|
||||
/**
|
||||
* @var string 验证码类型键名
|
||||
*/
|
||||
protected string $key;
|
||||
|
||||
/**
|
||||
* @var bool 验证后是否销毁
|
||||
*/
|
||||
protected bool $destroy;
|
||||
|
||||
public function __construct(string $key = 'default', bool $destroy = true)
|
||||
{
|
||||
$this->key = $key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Run the validation rule.
|
||||
*
|
||||
* @param \Closure(string): \Illuminate\Translation\PotentiallyTranslatedString $fail
|
||||
*/
|
||||
public function validate(string $attribute, mixed $value, Closure $fail): void
|
||||
{
|
||||
//
|
||||
// 从容器获取 Service(便于测试和依赖注入)
|
||||
$captchaService = App::make(CaptchaService::class);
|
||||
|
||||
if (!$captchaService->testPhrase($this->key, $value)) {
|
||||
$fail('验证码错误,请重新输入');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -65,7 +65,7 @@ class CaptchaService
|
|||
public function validatePhrase(string $key, string $phrase): void
|
||||
{
|
||||
if (! $this->testPhrase($key, $phrase)) {
|
||||
throw new BizException(__('Invalid captcha'));
|
||||
throw new BizException(__('无效验证码'));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -26,6 +26,9 @@ class KeywordSeeder extends Seeder
|
|||
]],
|
||||
['key' => 'honors', 'name' => '资质荣誉', 'list' => [
|
||||
'honor1'=>'核心资质认证', 'honor2'=>'管理体系认证','honor3'=>'重要荣誉奖项'
|
||||
]],
|
||||
['key' => 'contact_types', 'name' => '业务需求类别', 'list' => [
|
||||
|
||||
]],
|
||||
['key' => 'case_study_tag', 'name' => '服务案例标签', 'list' => [//标签value填写色号,指定标签颜色
|
||||
'case_study_tag1'=>'全项目保洁',
|
||||
|
|
|
|||
|
|
@ -45,4 +45,7 @@ Route::middleware('api')->group(function () {
|
|||
Route::get('/honors', [HonorController::class, 'index']);
|
||||
//发展历程
|
||||
Route::get('/timelines', [TimelineController::class, 'index']);
|
||||
//联系我们
|
||||
Route::get('/contact_types', [ContactController::class, 'types']);
|
||||
Route::post('/contacts', [ContactController::class, 'store']);
|
||||
});
|
||||
Loading…
Reference in New Issue