为 管理系统 做铺垫
This commit is contained in:
parent
7c4f930fd5
commit
3c5b57b190
23
app/Models/Admin.php
Normal file
23
app/Models/Admin.php
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
|
|
||||||
|
class Admin extends Authenticatable
|
||||||
|
{
|
||||||
|
use HasFactory;
|
||||||
|
|
||||||
|
protected $table = 'admins';
|
||||||
|
|
||||||
|
protected $fillable = [
|
||||||
|
'email',
|
||||||
|
'password',
|
||||||
|
];
|
||||||
|
|
||||||
|
protected $hidden = [
|
||||||
|
'password',
|
||||||
|
'remember_token',
|
||||||
|
];
|
||||||
|
}
|
@ -3,6 +3,7 @@
|
|||||||
namespace App\Providers;
|
namespace App\Providers;
|
||||||
|
|
||||||
use App\Models\PersonalAccessToken;
|
use App\Models\PersonalAccessToken;
|
||||||
|
use Illuminate\Pagination\Paginator;
|
||||||
use Illuminate\Support\Facades\Http;
|
use Illuminate\Support\Facades\Http;
|
||||||
use Illuminate\Support\ServiceProvider;
|
use Illuminate\Support\ServiceProvider;
|
||||||
use Laravel\Sanctum\Sanctum;
|
use Laravel\Sanctum\Sanctum;
|
||||||
@ -28,6 +29,8 @@ public function boot()
|
|||||||
{
|
{
|
||||||
//
|
//
|
||||||
|
|
||||||
|
Paginator::useBootstrapFive();
|
||||||
|
|
||||||
Sanctum::usePersonalAccessTokenModel(PersonalAccessToken::class);
|
Sanctum::usePersonalAccessTokenModel(PersonalAccessToken::class);
|
||||||
|
|
||||||
Http::macro('remote', function ($api_token, $url) {
|
Http::macro('remote', function ($api_token, $url) {
|
||||||
|
@ -39,6 +39,11 @@ public function boot()
|
|||||||
->as('remote.')
|
->as('remote.')
|
||||||
->group(base_path('routes/remote.php'));
|
->group(base_path('routes/remote.php'));
|
||||||
|
|
||||||
|
Route::middleware('web')
|
||||||
|
->prefix('admin')
|
||||||
|
->as('admin.')
|
||||||
|
->group(base_path('routes/admin.php'));
|
||||||
|
|
||||||
Route::middleware('web')
|
Route::middleware('web')
|
||||||
->group(base_path('routes/web.php'));
|
->group(base_path('routes/web.php'));
|
||||||
});
|
});
|
||||||
|
@ -83,7 +83,7 @@
|
|||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'locale' => 'en',
|
'locale' => 'zh_CN',
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
|
@ -40,6 +40,12 @@
|
|||||||
'driver' => 'session',
|
'driver' => 'session',
|
||||||
'provider' => 'users',
|
'provider' => 'users',
|
||||||
],
|
],
|
||||||
|
|
||||||
|
'admins' => [
|
||||||
|
'driver' => 'eloquent',
|
||||||
|
'model' => App\Models\Admin::class,
|
||||||
|
],
|
||||||
|
|
||||||
'module' => [
|
'module' => [
|
||||||
'driver' => 'token',
|
'driver' => 'token',
|
||||||
'provider' => 'modules',
|
'provider' => 'modules',
|
||||||
|
@ -0,0 +1,40 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::create('admins', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
|
||||||
|
// email
|
||||||
|
$table->string('email')->unique();
|
||||||
|
|
||||||
|
// password
|
||||||
|
$table->string('password');
|
||||||
|
|
||||||
|
$table->rememberToken();
|
||||||
|
|
||||||
|
$table->timestamps();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('admins');
|
||||||
|
}
|
||||||
|
};
|
40
lang/zh_CN.json
Normal file
40
lang/zh_CN.json
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
{
|
||||||
|
"(and :count more error)": "(还有 :count 个错误)",
|
||||||
|
"(and :count more errors)": "(还有 :count 个错误)",
|
||||||
|
"All rights reserved.": "版权所有。",
|
||||||
|
"Forbidden": "访问被拒绝",
|
||||||
|
"Go to page :page": "前往第 :page 页",
|
||||||
|
"Hello!": "您好!",
|
||||||
|
"If you did not create an account, no further action is required.": "如果您未注册帐号,请忽略此邮件。",
|
||||||
|
"If you did not request a password reset, no further action is required.": "如果您未申请重设密码,请忽略此邮件。",
|
||||||
|
"If you're having trouble clicking the \":actionText\" button, copy and paste the URL below\ninto your web browser:": "如果您单击「:actionText」按钮时遇到问题,请复制下方链接到浏览器中访问:",
|
||||||
|
"Login": "登录",
|
||||||
|
"Logout": "登出",
|
||||||
|
"Not Found": "页面不存在",
|
||||||
|
"of": "于",
|
||||||
|
"Page Expired": "页面会话已超时",
|
||||||
|
"Pagination Navigation": "分页导航",
|
||||||
|
"Please click the button below to verify your email address.": "请点击下面按钮验证您的 E-mail:",
|
||||||
|
"Regards": "致敬",
|
||||||
|
"Register": "注册",
|
||||||
|
"Reset Password": "重置密码",
|
||||||
|
"Reset Password Notification": "重置密码通知",
|
||||||
|
"results": "结果",
|
||||||
|
"Server Error": "服务器错误",
|
||||||
|
"Service Unavailable": "服务不可用",
|
||||||
|
"Showing": "显示中",
|
||||||
|
"The :attribute must contain at least one letter.": ":Attribute 至少包含一个字母。",
|
||||||
|
"The :attribute must contain at least one number.": ":Attribute 至少包含一个数字。",
|
||||||
|
"The :attribute must contain at least one symbol.": ":Attribute 至少包含一个符号。",
|
||||||
|
"The :attribute must contain at least one uppercase and one lowercase letter.": ":Attribute 至少包含一个大写字母和一个小写字母。",
|
||||||
|
"The given :attribute has appeared in a data leak. Please choose a different :attribute.": "给定的 :attribute 出现在数据泄漏中。请选择不同的 :attribute。",
|
||||||
|
"The given data was invalid.": "给定的数据无效。",
|
||||||
|
"This password reset link will expire in :count minutes.": "这个重设密码链接将会在 :count 分钟后失效。",
|
||||||
|
"to": "至",
|
||||||
|
"Toggle navigation": "切换导航",
|
||||||
|
"Too Many Requests": "请求次数过多。",
|
||||||
|
"Unauthorized": "未授权",
|
||||||
|
"Verify Email Address": "验证 E-mail",
|
||||||
|
"Whoops!": "哎呀!",
|
||||||
|
"You are receiving this email because we received a password reset request for your account.": "您收到此电子邮件是因为我们收到了您帐户的密码重设请求。"
|
||||||
|
}
|
7
lang/zh_CN/auth.php
Normal file
7
lang/zh_CN/auth.php
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
'failed' => '用户名或密码错误。',
|
||||||
|
'password' => '密码错误',
|
||||||
|
'throttle' => '您尝试的登录次数过多,请 :seconds 秒后再试。',
|
||||||
|
];
|
6
lang/zh_CN/pagination.php
Normal file
6
lang/zh_CN/pagination.php
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
'next' => '下一页 »',
|
||||||
|
'previous' => '« 上一页',
|
||||||
|
];
|
9
lang/zh_CN/passwords.php
Normal file
9
lang/zh_CN/passwords.php
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
'reset' => '密码重置成功!',
|
||||||
|
'sent' => '密码重置邮件已发送!',
|
||||||
|
'throttled' => '请稍候再试。',
|
||||||
|
'token' => '密码重置令牌无效。',
|
||||||
|
'user' => '找不到该邮箱对应的用户。',
|
||||||
|
];
|
204
lang/zh_CN/validation.php
Normal file
204
lang/zh_CN/validation.php
Normal file
@ -0,0 +1,204 @@
|
|||||||
|
<?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 必须是一个数组。',
|
||||||
|
'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 必须为布尔值。',
|
||||||
|
'confirmed' => ':Attribute 两次输入不一致。',
|
||||||
|
'current_password' => '密码错误。',
|
||||||
|
'date' => ':Attribute 不是一个有效的日期。',
|
||||||
|
'date_equals' => ':Attribute 必须要等于 :date。',
|
||||||
|
'date_format' => ':Attribute 的格式必须为 :format。',
|
||||||
|
'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 格式。',
|
||||||
|
'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 位数。',
|
||||||
|
'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 必须是一个合法的时区值。',
|
||||||
|
'unique' => ':Attribute 已经存在。',
|
||||||
|
'uploaded' => ':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' => '年',
|
||||||
|
],
|
||||||
|
];
|
1446
package-lock.json
generated
Normal file
1446
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
@ -5,10 +5,13 @@
|
|||||||
"build": "vite build"
|
"build": "vite build"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@popperjs/core": "^2.10.2",
|
||||||
"axios": "^1.1.2",
|
"axios": "^1.1.2",
|
||||||
|
"bootstrap": "^5.1.3",
|
||||||
"laravel-vite-plugin": "^0.6.0",
|
"laravel-vite-plugin": "^0.6.0",
|
||||||
"lodash": "^4.17.19",
|
"lodash": "^4.17.19",
|
||||||
"postcss": "^8.1.14",
|
"postcss": "^8.1.14",
|
||||||
|
"sass": "^1.32.11",
|
||||||
"vite": "^3.0.0"
|
"vite": "^3.0.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
8
resources/js/bootstrap.js
vendored
8
resources/js/bootstrap.js
vendored
@ -1,13 +1,15 @@
|
|||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import axios from 'axios';
|
|
||||||
|
|
||||||
window._ = _;
|
window._ = _;
|
||||||
|
|
||||||
|
import 'bootstrap';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* We'll load the axios HTTP library which allows us to easily issue requests
|
* We'll load the axios HTTP library which allows us to easily issue requests
|
||||||
* to our Laravel back-end. This library automatically handles sending the
|
* to our Laravel back-end. This library automatically handles sending the
|
||||||
* CSRF token as a header based on the value of the "XSRF" token cookie.
|
* CSRF token as a header based on the value of the "XSRF" token cookie.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import axios from 'axios';
|
||||||
window.axios = axios;
|
window.axios = axios;
|
||||||
|
|
||||||
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
|
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
|
||||||
@ -26,7 +28,7 @@ window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
|
|||||||
// window.Echo = new Echo({
|
// window.Echo = new Echo({
|
||||||
// broadcaster: 'pusher',
|
// broadcaster: 'pusher',
|
||||||
// key: import.meta.env.VITE_PUSHER_APP_KEY,
|
// key: import.meta.env.VITE_PUSHER_APP_KEY,
|
||||||
// wsHost: import.meta.env.VITE_PUSHER_HOST ? import.meta.env.VITE_PUSHER_HOST : `ws-${import.meta.env.VITE_PUSHER_APP_CLUSTER}.pusher.com`,
|
// wsHost: import.meta.env.VITE_PUSHER_HOST ?? `ws-${import.meta.env.VITE_PUSHER_APP_CLUSTER}.pusher.com`,
|
||||||
// wsPort: import.meta.env.VITE_PUSHER_PORT ?? 80,
|
// wsPort: import.meta.env.VITE_PUSHER_PORT ?? 80,
|
||||||
// wssPort: import.meta.env.VITE_PUSHER_PORT ?? 443,
|
// wssPort: import.meta.env.VITE_PUSHER_PORT ?? 443,
|
||||||
// forceTLS: (import.meta.env.VITE_PUSHER_SCHEME ?? 'https') === 'https',
|
// forceTLS: (import.meta.env.VITE_PUSHER_SCHEME ?? 'https') === 'https',
|
||||||
|
7
resources/sass/_variables.scss
Normal file
7
resources/sass/_variables.scss
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
// Body
|
||||||
|
$body-bg: #f8fafc;
|
||||||
|
|
||||||
|
// Typography
|
||||||
|
$font-family-sans-serif: 'Nunito', sans-serif;
|
||||||
|
$font-size-base: 0.9rem;
|
||||||
|
$line-height-base: 1.6;
|
26
resources/sass/app.scss
Normal file
26
resources/sass/app.scss
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
// Fonts
|
||||||
|
@import url("https://fonts.bunny.net/css?family=Nunito");
|
||||||
|
|
||||||
|
// Variables
|
||||||
|
@import "variables";
|
||||||
|
|
||||||
|
// Bootstrap
|
||||||
|
@import "bootstrap/scss/bootstrap";
|
||||||
|
|
||||||
|
h1,
|
||||||
|
h2,
|
||||||
|
h3,
|
||||||
|
h4,
|
||||||
|
h5,
|
||||||
|
h6 {
|
||||||
|
font-weight: 400 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.pb-0 {
|
||||||
|
padding-bottom: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mb-0 {
|
||||||
|
margin-bottom: 0 !important;
|
||||||
|
}
|
73
resources/views/admin/auth/login.blade.php
Normal file
73
resources/views/admin/auth/login.blade.php
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
@extends('layouts.app')
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
<div class="container">
|
||||||
|
<div class="row justify-content-center">
|
||||||
|
<div class="col-md-8">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header">{{ __('Login') }}</div>
|
||||||
|
|
||||||
|
<div class="card-body">
|
||||||
|
<form method="POST" action="{{ route('login') }}">
|
||||||
|
@csrf
|
||||||
|
|
||||||
|
<div class="row mb-3">
|
||||||
|
<label for="email" class="col-md-4 col-form-label text-md-end">{{ __('Email Address') }}</label>
|
||||||
|
|
||||||
|
<div class="col-md-6">
|
||||||
|
<input id="email" type="email" class="form-control @error('email') is-invalid @enderror" name="email" value="{{ old('email') }}" required autocomplete="email" autofocus>
|
||||||
|
|
||||||
|
@error('email')
|
||||||
|
<span class="invalid-feedback" role="alert">
|
||||||
|
<strong>{{ $message }}</strong>
|
||||||
|
</span>
|
||||||
|
@enderror
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row mb-3">
|
||||||
|
<label for="password" class="col-md-4 col-form-label text-md-end">{{ __('Password') }}</label>
|
||||||
|
|
||||||
|
<div class="col-md-6">
|
||||||
|
<input id="password" type="password" class="form-control @error('password') is-invalid @enderror" name="password" required autocomplete="current-password">
|
||||||
|
|
||||||
|
@error('password')
|
||||||
|
<span class="invalid-feedback" role="alert">
|
||||||
|
<strong>{{ $message }}</strong>
|
||||||
|
</span>
|
||||||
|
@enderror
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row mb-3">
|
||||||
|
<div class="col-md-6 offset-md-4">
|
||||||
|
<div class="form-check">
|
||||||
|
<input class="form-check-input" type="checkbox" name="remember" id="remember" {{ old('remember') ? 'checked' : '' }}>
|
||||||
|
|
||||||
|
<label class="form-check-label" for="remember">
|
||||||
|
{{ __('Remember Me') }}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row mb-0">
|
||||||
|
<div class="col-md-8 offset-md-4">
|
||||||
|
<button type="submit" class="btn btn-primary">
|
||||||
|
{{ __('Login') }}
|
||||||
|
</button>
|
||||||
|
|
||||||
|
@if (Route::has('password.request'))
|
||||||
|
<a class="btn btn-link" href="{{ route('password.request') }}">
|
||||||
|
{{ __('Forgot Your Password?') }}
|
||||||
|
</a>
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endsection
|
84
resources/views/layouts/admin.blade.php
Normal file
84
resources/views/layouts/admin.blade.php
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
|
||||||
|
<!-- CSRF Token -->
|
||||||
|
<meta name="csrf-token" content="{{ csrf_token() }}">
|
||||||
|
|
||||||
|
<title>@yield('title')</title>
|
||||||
|
|
||||||
|
<!-- Fonts -->
|
||||||
|
<link rel="dns-prefetch" href="//fonts.gstatic.com">
|
||||||
|
<link href="https://fonts.bunny.net/css?family=Nunito" rel="stylesheet">
|
||||||
|
|
||||||
|
<!-- Scripts -->
|
||||||
|
@vite(['resources/sass/app.scss', 'resources/js/app.js'])
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div id="app">
|
||||||
|
<nav class="navbar navbar-expand-md navbar-light bg-white shadow-sm">
|
||||||
|
<div class="container">
|
||||||
|
<a class="navbar-brand" href="{{ route('admin.index') }}">
|
||||||
|
{{ config('app.name') }}
|
||||||
|
</a>
|
||||||
|
<button class="navbar-toggler" type="button" data-bs-toggle="collapse"
|
||||||
|
data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent"
|
||||||
|
aria-expanded="false" aria-label="{{ __('Toggle navigation') }}">
|
||||||
|
<span class="navbar-toggler-icon"></span>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<div class="collapse navbar-collapse" id="navbarSupportedContent">
|
||||||
|
<!-- Left Side Of Navbar -->
|
||||||
|
<ul class="navbar-nav me-auto">
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="{{ route('admin.merchants.index') }}">商户</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<!-- Right Side Of Navbar -->
|
||||||
|
<ul class="navbar-nav ms-auto">
|
||||||
|
<!-- Authentication Links -->
|
||||||
|
@guest
|
||||||
|
@if (Route::has('login'))
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="{{ route('login') }}">{{ __('Login') }}</a>
|
||||||
|
</li>
|
||||||
|
@endif
|
||||||
|
@else
|
||||||
|
<li class="nav-item dropdown">
|
||||||
|
<a id="navbarDropdown" class="nav-link dropdown-toggle" href="#" role="button"
|
||||||
|
data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false" v-pre>
|
||||||
|
{{ Auth::guard('admin')->user()->email }}
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<div class="dropdown-menu dropdown-menu-end" aria-labelledby="navbarDropdown">
|
||||||
|
<a class="dropdown-item" href="{{ route('admin.logout') }}"
|
||||||
|
onclick="event.preventDefault();
|
||||||
|
document.getElementById('logout-form').submit();">
|
||||||
|
{{ __('Logout') }}
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<form id="logout-form" action="{{ route('admin.logout') }}" method="POST"
|
||||||
|
class="d-none">
|
||||||
|
@csrf
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
@endguest
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<main class="py-4">
|
||||||
|
<x-alert />
|
||||||
|
@yield('content')
|
||||||
|
</main>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
@ -1,10 +1,13 @@
|
|||||||
import {defineConfig} from 'vite';
|
import { defineConfig } from 'vite';
|
||||||
import laravel from 'laravel-vite-plugin';
|
import laravel from 'laravel-vite-plugin';
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
plugins: [
|
plugins: [
|
||||||
laravel({
|
laravel({
|
||||||
input: ['resources/css/app.css', 'resources/js/app.js'],
|
input: [
|
||||||
|
'resources/sass/app.scss',
|
||||||
|
'resources/js/app.js',
|
||||||
|
],
|
||||||
refresh: true,
|
refresh: true,
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
|
Loading…
Reference in New Issue
Block a user