admin adds a token

wip

fixed update

fixed account update

wip

wip

wip

wip

fixed tokens

wip

admin token
This commit is contained in:
pushuo 2023-04-19 15:54:40 +08:00 committed by Edward Yang
parent 920689fbee
commit 67d1b85952
15 changed files with 307 additions and 6 deletions

View File

@ -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'));
}
}

View File

@ -13,6 +13,7 @@ namespace Beike\Admin\Repositories;
use Beike\Admin\Http\Resources\AdminUserDetail;
use Beike\Models\AdminUser;
use Beike\Repositories\AdminUserTokenRepo;
use Symfony\Component\HttpKernel\Exception\NotAcceptableHttpException;
class AdminUserRepo
@ -73,7 +74,14 @@ class AdminUserRepo
$userData['password'] = bcrypt($password);
}
$adminUser->update($userData);
$adminUser->syncRoles($data['roles']);
$roles = $data['roles'] ?? [];
if ($roles) {
$adminUser->syncRoles($roles);
}
$tokens = $data['tokens'] ?? [];
AdminUserTokenRepo::updateTokensByUser($adminUser, $tokens);
return $adminUser;
}

View File

@ -20,6 +20,10 @@ Route::prefix($adminName)
->group(function () {
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_show')->get('attributes/{id}/values/autocomplete', [Controllers\AttributeController::class, 'autocompleteValue'])->name('attributes.values.autocomplete');

View File

@ -162,7 +162,7 @@ class Sidebar extends Component
*/
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);
}
@ -252,6 +252,7 @@ class Sidebar extends Component
{
$routes = [
['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' => 'plugins.index', 'icon' => 'fa fa-tachometer-alt', 'hide_mobile' => 1],
['route' => 'theme.index', 'icon' => 'fa fa-tachometer-alt', 'hide_mobile' => 1],

View File

@ -4,6 +4,7 @@ namespace Beike\Models;
use Beike\Notifications\AdminForgottenNotification;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Foundation\Auth\User as AuthUser;
use Illuminate\Notifications\Notifiable;
use Spatie\Permission\Traits\HasRoles;
@ -17,6 +18,11 @@ class AdminUser extends AuthUser
protected $fillable = ['name', 'email', 'locale', 'password', 'active'];
public function tokens(): HasMany
{
return $this->hasMany(AdminUserToken::class);
}
public function notifyVerifyCodeForForgotten($code)
{
$useQueue = system_setting('base.use_queue', true);

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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');
}
};

View File

@ -3,7 +3,7 @@
* @link https://beikeshop.com
* @Author pu shuo <pushuo@guangda.work>
* @Date 2022-08-22 18:32:26
* @LastEditTime 2023-04-10 15:47:07
* @LastEditTime 2023-04-19 15:26:41
*/
export default {
@ -44,10 +44,13 @@ export default {
},
// 生成随机字符串
randomString(length) {
randomString(length = 32) {
let str = '';
for (; str.length < length; str += Math.random().toString(36).substr(2));
return str.substr(0, length);
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
for (let i = 0; i < length; i++) {
str += chars.charAt(Math.floor(Math.random() * chars.length));
}
return str;
},
// 获取url参数

View File

@ -67,6 +67,7 @@
<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>
</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><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>

View File

@ -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

View File

@ -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',
];

View File

@ -52,6 +52,7 @@ return [
'copyright_buy' => 'Copyright Buy',
// sidebar
'account_index' => 'Personal Center',
'multi_filter_index' => 'Advanced Filter',
'theme_index' => 'Theme Setting',
'attribute_groups_index' => 'Attribute Group',

View File

@ -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' => '密码留空则不修改',
];

View File

@ -52,6 +52,7 @@ return [
'copyright_buy' => '版权购买',
// sidebar
'account_index' => '个人中心',
'multi_filter_index' => '高级筛选',
'theme_index' => '模板设置',
'attribute_groups_index' => '属性组',