admin adds a token
wip fixed update fixed account update wip wip wip wip fixed tokens wip admin token
This commit is contained in:
parent
920689fbee
commit
67d1b85952
|
|
@ -0,0 +1,40 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* BrandController.php
|
||||||
|
*
|
||||||
|
* @copyright 2022 beikeshop.com - All Rights Reserved
|
||||||
|
* @link https://beikeshop.com
|
||||||
|
* @author TL <mengwb@guangda.work>
|
||||||
|
* @created 2022-07-27 21:17:04
|
||||||
|
* @modified 2022-07-27 21:17:04
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Beike\Admin\Http\Controllers;
|
||||||
|
|
||||||
|
use Beike\Admin\Repositories\AdminUserRepo;
|
||||||
|
use Beike\Repositories\AdminUserTokenRepo;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
class AccountController extends Controller
|
||||||
|
{
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
$user = current_user();
|
||||||
|
$data = [
|
||||||
|
'current_user' => $user,
|
||||||
|
'tokens' => AdminUserTokenRepo::getTokenByAdminUser($user)->pluck('token')->toArray()
|
||||||
|
];
|
||||||
|
|
||||||
|
return view('admin::pages.account.index', $data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function update(Request $request)
|
||||||
|
{
|
||||||
|
$user = current_user();
|
||||||
|
|
||||||
|
$adminUserData = $request->all();
|
||||||
|
AdminUserRepo::updateAdminUser($user->id, $adminUserData);
|
||||||
|
return response()->redirectTo('admin/account')->with('success', trans('common.updated_success'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -13,6 +13,7 @@ namespace Beike\Admin\Repositories;
|
||||||
|
|
||||||
use Beike\Admin\Http\Resources\AdminUserDetail;
|
use Beike\Admin\Http\Resources\AdminUserDetail;
|
||||||
use Beike\Models\AdminUser;
|
use Beike\Models\AdminUser;
|
||||||
|
use Beike\Repositories\AdminUserTokenRepo;
|
||||||
use Symfony\Component\HttpKernel\Exception\NotAcceptableHttpException;
|
use Symfony\Component\HttpKernel\Exception\NotAcceptableHttpException;
|
||||||
|
|
||||||
class AdminUserRepo
|
class AdminUserRepo
|
||||||
|
|
@ -73,7 +74,14 @@ class AdminUserRepo
|
||||||
$userData['password'] = bcrypt($password);
|
$userData['password'] = bcrypt($password);
|
||||||
}
|
}
|
||||||
$adminUser->update($userData);
|
$adminUser->update($userData);
|
||||||
$adminUser->syncRoles($data['roles']);
|
|
||||||
|
$roles = $data['roles'] ?? [];
|
||||||
|
if ($roles) {
|
||||||
|
$adminUser->syncRoles($roles);
|
||||||
|
}
|
||||||
|
|
||||||
|
$tokens = $data['tokens'] ?? [];
|
||||||
|
AdminUserTokenRepo::updateTokensByUser($adminUser, $tokens);
|
||||||
|
|
||||||
return $adminUser;
|
return $adminUser;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,10 @@ Route::prefix($adminName)
|
||||||
->group(function () {
|
->group(function () {
|
||||||
Route::get('/', [Controllers\HomeController::class, 'index'])->name('home.index');
|
Route::get('/', [Controllers\HomeController::class, 'index'])->name('home.index');
|
||||||
|
|
||||||
|
//个人中心
|
||||||
|
Route::middleware('can:account_index')->get('account', [Controllers\AccountController::class, 'index'])->name('account.index');
|
||||||
|
Route::middleware('can:account_update')->put('account', [Controllers\AccountController::class, 'update'])->name('account.update');
|
||||||
|
|
||||||
// 属性
|
// 属性
|
||||||
Route::middleware('can:attributes_update')->post('attributes/{id}/values', [Controllers\AttributeController::class, 'storeValue'])->name('attributes.values.store');
|
Route::middleware('can:attributes_update')->post('attributes/{id}/values', [Controllers\AttributeController::class, 'storeValue'])->name('attributes.values.store');
|
||||||
Route::middleware('can:attributes_show')->get('attributes/{id}/values/autocomplete', [Controllers\AttributeController::class, 'autocompleteValue'])->name('attributes.values.autocomplete');
|
Route::middleware('can:attributes_show')->get('attributes/{id}/values/autocomplete', [Controllers\AttributeController::class, 'autocompleteValue'])->name('attributes.values.autocomplete');
|
||||||
|
|
|
||||||
|
|
@ -162,7 +162,7 @@ class Sidebar extends Component
|
||||||
*/
|
*/
|
||||||
private function getSettingSubPrefix()
|
private function getSettingSubPrefix()
|
||||||
{
|
{
|
||||||
$prefix = ['settings.', 'admin_users.', 'admin_roles.', 'plugins.', 'theme.', 'marketing.', 'tax_classes', 'tax_rates', 'regions', 'currencies', 'languages', 'design_menu', 'countries', 'zones'];
|
$prefix = ['settings.', 'account.', 'admin_users.', 'admin_roles.', 'plugins.', 'theme.', 'marketing.', 'tax_classes', 'tax_rates', 'regions', 'currencies', 'languages', 'design_menu', 'countries', 'zones'];
|
||||||
|
|
||||||
return hook_filter('admin.sidebar.setting.prefix', $prefix);
|
return hook_filter('admin.sidebar.setting.prefix', $prefix);
|
||||||
}
|
}
|
||||||
|
|
@ -252,6 +252,7 @@ class Sidebar extends Component
|
||||||
{
|
{
|
||||||
$routes = [
|
$routes = [
|
||||||
['route' => 'settings.index', 'icon' => 'fa fa-tachometer-alt'],
|
['route' => 'settings.index', 'icon' => 'fa fa-tachometer-alt'],
|
||||||
|
['route' => 'account.index', 'icon' => 'fa fa-tachometer-alt'],
|
||||||
['route' => 'admin_users.index', 'icon' => 'fa fa-tachometer-alt'],
|
['route' => 'admin_users.index', 'icon' => 'fa fa-tachometer-alt'],
|
||||||
['route' => 'plugins.index', 'icon' => 'fa fa-tachometer-alt', 'hide_mobile' => 1],
|
['route' => 'plugins.index', 'icon' => 'fa fa-tachometer-alt', 'hide_mobile' => 1],
|
||||||
['route' => 'theme.index', 'icon' => 'fa fa-tachometer-alt', 'hide_mobile' => 1],
|
['route' => 'theme.index', 'icon' => 'fa fa-tachometer-alt', 'hide_mobile' => 1],
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ namespace Beike\Models;
|
||||||
|
|
||||||
use Beike\Notifications\AdminForgottenNotification;
|
use Beike\Notifications\AdminForgottenNotification;
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
|
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||||
use Illuminate\Foundation\Auth\User as AuthUser;
|
use Illuminate\Foundation\Auth\User as AuthUser;
|
||||||
use Illuminate\Notifications\Notifiable;
|
use Illuminate\Notifications\Notifiable;
|
||||||
use Spatie\Permission\Traits\HasRoles;
|
use Spatie\Permission\Traits\HasRoles;
|
||||||
|
|
@ -17,6 +18,11 @@ class AdminUser extends AuthUser
|
||||||
|
|
||||||
protected $fillable = ['name', 'email', 'locale', 'password', 'active'];
|
protected $fillable = ['name', 'email', 'locale', 'password', 'active'];
|
||||||
|
|
||||||
|
public function tokens(): HasMany
|
||||||
|
{
|
||||||
|
return $this->hasMany(AdminUserToken::class);
|
||||||
|
}
|
||||||
|
|
||||||
public function notifyVerifyCodeForForgotten($code)
|
public function notifyVerifyCodeForForgotten($code)
|
||||||
{
|
{
|
||||||
$useQueue = system_setting('base.use_queue', true);
|
$useQueue = system_setting('base.use_queue', true);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* AdminUserToken.php
|
||||||
|
*
|
||||||
|
* @copyright 2023 beikeshop.com - All Rights Reserved
|
||||||
|
* @link https://beikeshop.com
|
||||||
|
* @author Edward Yang <yangjin@guangda.work>
|
||||||
|
* @created 2023-04-20 10:18:56
|
||||||
|
* @modified 2023-04-20 10:18:56
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Beike\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||||
|
|
||||||
|
class AdminUserToken extends Model
|
||||||
|
{
|
||||||
|
protected $fillable = ['admin_user_id', 'token'];
|
||||||
|
|
||||||
|
|
||||||
|
public function adminUser(): BelongsTo
|
||||||
|
{
|
||||||
|
return $this->belongsTo(AdminUser::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,60 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* AdminUserTokenRepo.php
|
||||||
|
*
|
||||||
|
* @copyright 2023 beikeshop.com - All Rights Reserved
|
||||||
|
* @link https://beikeshop.com
|
||||||
|
* @author Edward Yang <yangjin@guangda.work>
|
||||||
|
* @created 2023-04-20 10:21:25
|
||||||
|
* @modified 2023-04-20 10:21:25
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Beike\Repositories;
|
||||||
|
|
||||||
|
use Beike\Models\AdminUser;
|
||||||
|
use Beike\Models\AdminUserToken;
|
||||||
|
|
||||||
|
class AdminUserTokenRepo
|
||||||
|
{
|
||||||
|
public static function getTokenByAdminUser($adminUser)
|
||||||
|
{
|
||||||
|
$adminUserId = self::getAdminUserId($adminUser);
|
||||||
|
if (empty($adminUserId)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return AdminUserToken::query()->where('admin_user_id', $adminUserId)->get();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static function updateTokensByUser($adminUser, $tokens)
|
||||||
|
{
|
||||||
|
$adminUserId = self::getAdminUserId($adminUser);
|
||||||
|
if (empty($adminUserId)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
AdminUserToken::query()->where('admin_user_id', $adminUserId)->delete();
|
||||||
|
if (empty($tokens)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($tokens as $token) {
|
||||||
|
AdminUserToken::query()->create([
|
||||||
|
'admin_user_id' => $adminUserId,
|
||||||
|
'token' => $token
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static function getAdminUserId($adminUser)
|
||||||
|
{
|
||||||
|
$adminUserId = 0;
|
||||||
|
if ($adminUser instanceof AdminUser) {
|
||||||
|
$adminUserId = $adminUser->id;
|
||||||
|
} elseif (is_int($adminUser)) {
|
||||||
|
$adminUserId = $adminUser;
|
||||||
|
}
|
||||||
|
return $adminUserId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,33 @@
|
||||||
|
<?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('admin_user_tokens', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->integer('admin_user_id');
|
||||||
|
$table->string('token', 64);
|
||||||
|
$table->timestamps();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('admin_user_tokens');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
* @link https://beikeshop.com
|
* @link https://beikeshop.com
|
||||||
* @Author pu shuo <pushuo@guangda.work>
|
* @Author pu shuo <pushuo@guangda.work>
|
||||||
* @Date 2022-08-22 18:32:26
|
* @Date 2022-08-22 18:32:26
|
||||||
* @LastEditTime 2023-04-10 15:47:07
|
* @LastEditTime 2023-04-19 15:26:41
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
|
@ -44,10 +44,13 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
// 生成随机字符串
|
// 生成随机字符串
|
||||||
randomString(length) {
|
randomString(length = 32) {
|
||||||
let str = '';
|
let str = '';
|
||||||
for (; str.length < length; str += Math.random().toString(36).substr(2));
|
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
||||||
return str.substr(0, length);
|
for (let i = 0; i < length; i++) {
|
||||||
|
str += chars.charAt(Math.floor(Math.random() * chars.length));
|
||||||
|
}
|
||||||
|
return str;
|
||||||
},
|
},
|
||||||
|
|
||||||
// 获取url参数
|
// 获取url参数
|
||||||
|
|
|
||||||
|
|
@ -67,6 +67,7 @@
|
||||||
<li>
|
<li>
|
||||||
<a target="_blank" href="{{ shop_route('home.index') }}" class="dropdown-item"><i class="bi bi-send me-1"></i> @lang('admin/common.access_frontend')</a>
|
<a target="_blank" href="{{ shop_route('home.index') }}" class="dropdown-item"><i class="bi bi-send me-1"></i> @lang('admin/common.access_frontend')</a>
|
||||||
</li>
|
</li>
|
||||||
|
<li><a href="{{ admin_route('account.index') }}" class="dropdown-item"><i class="bi bi-person-circle"></i> {{ __('admin/common.account_index') }}</a></li>
|
||||||
<li><hr class="dropdown-divider"></li>
|
<li><hr class="dropdown-divider"></li>
|
||||||
<li><a href="{{ admin_route('logout.index') }}" class="dropdown-item"><i class="bi bi-box-arrow-left me-1"></i> {{ __('common.sign_out') }}</a></li>
|
<li><a href="{{ admin_route('logout.index') }}" class="dropdown-item"><i class="bi bi-box-arrow-left me-1"></i> {{ __('common.sign_out') }}</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,86 @@
|
||||||
|
@extends('admin::layouts.master')
|
||||||
|
|
||||||
|
@section('title', __('admin/common.account_index'))
|
||||||
|
|
||||||
|
@section('page-title-right')
|
||||||
|
<button type="button" class="btn btn-lg btn-primary submit-form" form="form-account">{{ __('common.save') }}</button>
|
||||||
|
@endsection
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
<div id="plugins-app-form" class="card h-min-600">
|
||||||
|
<div class="card-body">
|
||||||
|
<form action="{{ admin_route('account.update') }}" id="form-account" class="needs-validation" novalidate method="post">
|
||||||
|
@csrf
|
||||||
|
@method('PUT')
|
||||||
|
@if (session('success'))
|
||||||
|
<x-admin-alert type="success" msg="{{ session('success') }}" class="mt-4"/>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
<ul class="nav nav-tabs nav-bordered mb-5" role="tablist">
|
||||||
|
<li class="nav-item" role="presentation">
|
||||||
|
<a class="nav-link active" data-bs-toggle="tab" href="#tab-general">{{ __('admin/setting.basic_settings') }}</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item" role="presentation">
|
||||||
|
<a class="nav-link" data-bs-toggle="tab" href="#tab-token">{{ __('admin/account.create_token') }}</a>
|
||||||
|
</li>
|
||||||
|
@hook('admin.account.nav.after')
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<div class="tab-content">
|
||||||
|
<div class="tab-pane fade show active" id="tab-general">
|
||||||
|
<x-admin-form-input name="name" title="{{ __('common.name') }}" value="{{ old('name', $current_user->name) }}" />
|
||||||
|
<x-admin-form-input name="email" title="{{ __('common.email') }}" type="email" value="{{ old('email', $current_user->email) }}" />
|
||||||
|
<x-admin-form-input name="password" title="{{ __('shop/login.password') }}" value="{{ old('password', '') }}">
|
||||||
|
<div class="help-text font-size-12 lh-base">{{ __('admin/account.password_text') }}</div>
|
||||||
|
</x-admin-form-input>
|
||||||
|
<x-admin-form-select title="{{ __('common.language') }}" name="locale" :value="old('locale', $current_user->locale)" :options="$admin_languages" key="code" label="name" />
|
||||||
|
</div>
|
||||||
|
<div class="tab-pane fade show" id="tab-token">
|
||||||
|
<x-admin::form.row :title="__('admin/account.create_token')">
|
||||||
|
<div class="col-auto wp-200-">
|
||||||
|
<table class="table table-bordered w-max-500" id="token-app">
|
||||||
|
<thead>
|
||||||
|
<th>Token</th>
|
||||||
|
<th class="text-center wp-100">{{ __('common.action') }}</th>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr v-for="item, index in tokens" :key="index">
|
||||||
|
<td>
|
||||||
|
<textarea class="form-control bg-light" :name="'tokens['+ index +']'" readonly>@{{ item }}</textarea>
|
||||||
|
</td>
|
||||||
|
<td class="text-center wp-100">
|
||||||
|
<button type="button" class="btn btn-outline-secondary btn-sm" @click="tokens.splice(index, 1)">{{ __('common.delete') }}</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="1"><input v-if="!tokens.length" name="tokens" value="" class="d-none"></td>
|
||||||
|
<td class="text-center">
|
||||||
|
<button type="button" class="btn btn-outline-info btn-sm" @click="addToken">{{ __('common.add') }}</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</x-admin::form.row>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endsection
|
||||||
|
|
||||||
|
@push('footer')
|
||||||
|
<script>
|
||||||
|
const tokenApp = new Vue({
|
||||||
|
el: '#token-app',
|
||||||
|
data: {
|
||||||
|
tokens: @json(old('tokens', $current_user->tokens->pluck('token')->toArray() ?? [])),
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
addToken() {
|
||||||
|
this.tokens.push(bk.randomString(64));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
@endpush
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* header.php
|
||||||
|
*
|
||||||
|
* @copyright 2022 beikeshop.com - All Rights Reserved
|
||||||
|
* @link https://beikeshop.com
|
||||||
|
* @author Edward Yang <yangjin@guangda.work>
|
||||||
|
* @created 2022-08-02 19:03:19
|
||||||
|
* @modified 2022-08-02 19:03:19
|
||||||
|
*/
|
||||||
|
|
||||||
|
return [
|
||||||
|
'create_token' => 'Create Token',
|
||||||
|
'password_text' => 'If the password is left blank, it will not be modified',
|
||||||
|
];
|
||||||
|
|
@ -52,6 +52,7 @@ return [
|
||||||
'copyright_buy' => 'Copyright Buy',
|
'copyright_buy' => 'Copyright Buy',
|
||||||
|
|
||||||
// sidebar
|
// sidebar
|
||||||
|
'account_index' => 'Personal Center',
|
||||||
'multi_filter_index' => 'Advanced Filter',
|
'multi_filter_index' => 'Advanced Filter',
|
||||||
'theme_index' => 'Theme Setting',
|
'theme_index' => 'Theme Setting',
|
||||||
'attribute_groups_index' => 'Attribute Group',
|
'attribute_groups_index' => 'Attribute Group',
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* header.php
|
||||||
|
*
|
||||||
|
* @copyright 2022 beikeshop.com - All Rights Reserved
|
||||||
|
* @link https://beikeshop.com
|
||||||
|
* @author Edward Yang <yangjin@guangda.work>
|
||||||
|
* @created 2022-08-02 19:03:19
|
||||||
|
* @modified 2022-08-02 19:03:19
|
||||||
|
*/
|
||||||
|
|
||||||
|
return [
|
||||||
|
'create_token' => '生成 Token',
|
||||||
|
'password_text' => '密码留空则不修改',
|
||||||
|
];
|
||||||
|
|
@ -52,6 +52,7 @@ return [
|
||||||
'copyright_buy' => '版权购买',
|
'copyright_buy' => '版权购买',
|
||||||
|
|
||||||
// sidebar
|
// sidebar
|
||||||
|
'account_index' => '个人中心',
|
||||||
'multi_filter_index' => '高级筛选',
|
'multi_filter_index' => '高级筛选',
|
||||||
'theme_index' => '模板设置',
|
'theme_index' => '模板设置',
|
||||||
'attribute_groups_index' => '属性组',
|
'attribute_groups_index' => '属性组',
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue