From 5abb8277e3ea5c58800895052c6184fca3ca7b30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=89=AB=E5=9C=B0=E5=83=A7?= <357099073@qq.com> Date: Fri, 29 May 2026 23:41:58 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=88=86=E7=B1=BB=E9=94=81?= =?UTF-8?q?=E7=9A=84bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controllers/GoodsGroupController.php | 23 ++++- app/Http/Controllers/Home/HomeController.php | 28 +++++- app/Models/GoodsGroup.php | 4 - app/Service/GoodsService.php | 46 ++++++++- public/assets/luna/main.js | 10 +- resources/views/hyper/errors/error.blade.php | 4 +- .../views/hyper/static_pages/home.blade.php | 96 ++++++++++++++++++- resources/views/luna/errors/error.blade.php | 4 +- .../views/unicorn/errors/error.blade.php | 2 +- .../views/unicorn/static_pages/home.blade.php | 60 +++++++++++- routes/common/web.php | 2 + 11 files changed, 251 insertions(+), 28 deletions(-) diff --git a/app/Admin/Controllers/GoodsGroupController.php b/app/Admin/Controllers/GoodsGroupController.php index b17303d..5c2abef 100644 --- a/app/Admin/Controllers/GoodsGroupController.php +++ b/app/Admin/Controllers/GoodsGroupController.php @@ -92,13 +92,26 @@ class GoodsGroupController extends AdminController { return Form::make(new GoodsGroup(), function (Form $form) { $form->display('id'); - $form->text('gp_name'); - $form->switch('is_open')->default(GoodsGroupModel::STATUS_OPEN); - $form->switch('is_open_group_pwd')->default(GoodsGroupModel::STATUS_CLOSE); - $form->text('group_pwd')->help(admin_trans('goods-group.fields.group_pwd_help')); - $form->number('ord')->default(1)->help(admin_trans('dujiaoka.ord')); + $form->text('gp_name', admin_trans('goods-group.fields.gp_name')); + $form->switch('is_open', admin_trans('goods-group.fields.is_open'))->default(GoodsGroupModel::STATUS_OPEN); + + $form->divider('分类密码访问'); + $form->switch('is_open_group_pwd', admin_trans('goods-group.fields.is_open_group_pwd'))->default(GoodsGroupModel::STATUS_CLOSE); + $form->text('group_pwd', admin_trans('goods-group.fields.group_pwd')) + ->help(admin_trans('goods-group.fields.group_pwd_help')); + + $form->number('ord', admin_trans('goods-group.fields.ord'))->default(1)->help(admin_trans('dujiaoka.ord')); $form->display('created_at'); $form->display('updated_at'); + + $form->saving(function (Form $form) { + if ((int) $form->is_open_group_pwd !== GoodsGroupModel::STATUS_OPEN) { + $form->group_pwd = null; + } elseif ($form->isEditing() && $form->group_pwd === null) { + $form->deleteInput('group_pwd'); + } + }); + $form->disableViewButton(); $form->footer(function ($footer) { // 去掉`查看`checkbox diff --git a/app/Http/Controllers/Home/HomeController.php b/app/Http/Controllers/Home/HomeController.php index baf8692..0a0bafa 100644 --- a/app/Http/Controllers/Home/HomeController.php +++ b/app/Http/Controllers/Home/HomeController.php @@ -46,6 +46,9 @@ class HomeController extends BaseController */ public function index(Request $request) { + // 每次打开/刷新首页都重新要求输入分类访问密码 + session()->forget('dujiaoka_group_pwd_access'); + $goods = $this->goodsService->withGroup(); return $this->render('static_pages/home', ['data' => $goods], __('dujiaoka.page-title.home')); } @@ -97,13 +100,34 @@ class HomeController extends BaseController 'group_id' => 'required|integer', 'password' => 'required|string', ]); - $this->goodsService->verifyGroupPassword((int) $request->input('group_id'), (string) $request->input('password')); - return response()->json(['code' => 200, 'msg' => __('dujiaoka.prompt.goods_group_password_success')]); + $group = $this->goodsService->verifyGroupPassword((int) $request->input('group_id'), (string) $request->input('password')); + return response()->json([ + 'code' => 200, + 'msg' => __('dujiaoka.prompt.goods_group_password_success'), + 'data' => $group, + ]); } catch (RuleValidationException $ruleValidationException) { return response()->json(['code' => 400, 'msg' => $ruleValidationException->getMessage()]); } } + /** + * 取消商品分类密码访问授权 + * + * @param Request $request + * @return \Illuminate\Http\JsonResponse + */ + public function forgetGroupPasswordAccess(Request $request) + { + $request->validate([ + 'group_id' => 'required|integer', + ]); + + $this->goodsService->forgetGroupAccess((int) $request->input('group_id')); + + return response()->json(['code' => 200, 'msg' => 'ok']); + } + /** * 极验行为验证 * diff --git a/app/Models/GoodsGroup.php b/app/Models/GoodsGroup.php index 1a4a831..6c054f6 100644 --- a/app/Models/GoodsGroup.php +++ b/app/Models/GoodsGroup.php @@ -17,10 +17,6 @@ class GoodsGroup extends BaseModel 'deleted' => GoodsGroupDeleted::class ]; - protected $hidden = [ - 'group_pwd', - ]; - protected $casts = [ 'is_open_group_pwd' => 'integer', ]; diff --git a/app/Service/GoodsService.php b/app/Service/GoodsService.php index 649cb82..e1074c3 100644 --- a/app/Service/GoodsService.php +++ b/app/Service/GoodsService.php @@ -112,11 +112,16 @@ class GoodsService * * @param int $groupID 分类id * @param string $password 访问密码 - * @return bool + * @return array */ - public function verifyGroupPassword(int $groupID, string $password): bool + public function verifyGroupPassword(int $groupID, string $password): array { $group = GoodsGroup::query() + ->with(['goods' => function($query) { + $query->withCount(['carmis' => function($query) { + $query->where('status', Carmis::STATUS_UNSOLD); + }])->where('is_open', Goods::STATUS_OPEN)->orderBy('ord', 'DESC'); + }]) ->where('is_open', GoodsGroup::STATUS_OPEN) ->where('id', $groupID) ->first(); @@ -127,7 +132,7 @@ class GoodsService if (!$this->isGroupPasswordProtected($group)) { $this->grantGroupAccess($group->id); - return true; + return $this->formatGroupForResponse($group); } if (!hash_equals((string) $group->group_pwd, (string) $password)) { @@ -135,7 +140,24 @@ class GoodsService } $this->grantGroupAccess($group->id); - return true; + return $this->formatGroupForResponse($group); + } + + /** + * 格式化分类接口返回数据 + * + * @param GoodsGroup $group 分类模型 + * @return array + */ + private function formatGroupForResponse(GoodsGroup $group): array + { + $data = $group->toArray(); + foreach ($data['goods'] as &$goods) { + $goods['picture_url'] = picture_ulr($goods['picture']); + } + unset($goods); + + return $data; } /** @@ -152,6 +174,22 @@ class GoodsService } } + /** + * 取消当前会话访问指定分类的授权 + * + * @param int $groupID 分类id + * @return void + */ + public function forgetGroupAccess(int $groupID): void + { + $groupIDs = session('dujiaoka_group_pwd_access', []); + $groupIDs = array_values(array_filter($groupIDs, function ($id) use ($groupID) { + return (int) $id !== $groupID; + })); + + session(['dujiaoka_group_pwd_access' => $groupIDs]); + } + /** * 授权当前会话访问分类 * diff --git a/public/assets/luna/main.js b/public/assets/luna/main.js index 97ae5ed..31cc666 100644 --- a/public/assets/luna/main.js +++ b/public/assets/luna/main.js @@ -64,7 +64,15 @@ }, function (res) { if (res.code === 200) { layer.close(index); - window.location.reload(); + + res.data.key = group.key; + res.data.is_group_locked = 0; + goodsMsg[group.key] = res.data; + + laytpl(cateTpl).render(res.data, function (html) { + $('.cate-box').eq(group.key).replaceWith(html); + }); + changeCate(group.key, true); } else { layer.msg(res.msg); } diff --git a/resources/views/hyper/errors/error.blade.php b/resources/views/hyper/errors/error.blade.php index 9e18d11..fe9a64f 100644 --- a/resources/views/hyper/errors/error.blade.php +++ b/resources/views/hyper/errors/error.blade.php @@ -14,11 +14,11 @@
error

{{ $content }}

@if(!$url) - {{ __('hyper.error_back_btn') }} + {{ __('hyper.error_back_btn') }} @else {{ __('hyper.error_back_btn') }} @endif -@stop \ No newline at end of file +@stop diff --git a/resources/views/hyper/static_pages/home.blade.php b/resources/views/hyper/static_pages/home.blade.php index 30ca84a..b7b7edc 100644 --- a/resources/views/hyper/static_pages/home.blade.php +++ b/resources/views/hyper/static_pages/home.blade.php @@ -6,7 +6,7 @@
@@ -142,6 +142,11 @@ $('#notice-open').click(function() { $('#notice-modal').modal(); }); + var groupPasswordPassed = false; + + clearSearchInput(); + setTimeout(clearSearchInput, 300); + $("#search").on("input",function(e){ var txt = $("#search").val(); if($.trim(txt)!="") { @@ -150,27 +155,110 @@ $(".category").show(); } }); - $('.group-password-link').click(function() { + + $('.tab-link:not(.group-password-link)').click(function() { + resetPasswordGroups(); + forgetAllPasswordGroupAccess(); + clearSearchInput(); + }); + + $(document).on('click', '.group-password-link', function() { $('#group-password-id').val($(this).data('group-id')); $('#group-password-name').text($(this).data('group-name')); $('#group-password-input').val(''); $('#group-password-modal').modal(); }); + $('#group-password-modal').on('hidden.bs.modal', function() { + if (!groupPasswordPassed) { + resetPasswordGroups(); + forgetAllPasswordGroupAccess(); + clearSearchInput(); + showAllGroup(); + } + groupPasswordPassed = false; + }); + $('#group-password-submit').click(function() { + var groupId = $('#group-password-id').val(); + $.post("{{ url('verify-group-password') }}", { _token: "{{ csrf_token() }}", - group_id: $('#group-password-id').val(), + group_id: groupId, password: $('#group-password-input').val() }, function(res) { if (res.code === 200) { - window.location.reload(); + groupPasswordPassed = true; + unlockGroup(groupId, res.data); + clearSearchInput(); + $('#group-password-modal').modal('hide'); } else { $.NotificationApp.send("{{ __('hyper.home_tip') }}", res.msg, "top-center", "rgba(0,0,0,0.2)", "error"); } }); }); + function unlockGroup(groupId, group) { + resetPasswordGroups(groupId); + + var $link = $('.group-password-link[data-group-id="' + groupId + '"]'); + $('#group-' + groupId + ' .hyper-wrapper').html(renderGroupGoods(group.goods || [])); + + $('.tab-link').removeClass('active'); + $('.tab-pane').removeClass('active show'); + $link.addClass('active'); + $('#group-' + groupId).addClass('active show'); + } + + function resetPasswordGroups(exceptGroupId) { + $('.group-password-link').each(function() { + var groupId = String($(this).data('group-id')); + if (exceptGroupId && groupId === String(exceptGroupId)) { + return; + } + + $('#group-' + groupId + ' .hyper-wrapper').empty(); + $(this).removeClass('active'); + }); + } + + function forgetAllPasswordGroupAccess() { + $('.group-password-link').each(function() { + $.post("{{ url('forget-group-password-access') }}", { + _token: "{{ csrf_token() }}", + group_id: $(this).data('group-id') + }); + }); + } + + function showAllGroup() { + $('.tab-link').removeClass('active'); + $('.tab-pane').removeClass('active show'); + $('.tab-link[href="#group-all"]').addClass('active'); + $('#group-all').addClass('active show'); + } + + function clearSearchInput() { + $('#search').val(''); + $('.category').show(); + } + + function renderGroupGoods(goodsList) { + var html = ''; + $.each(goodsList, function(index, goods) { + if (parseInt(goods.in_stock) > 0) { + html += ''; + } else { + html += ''; + html += '
{{ __('hyper.home_out_of_stock') }}
'; + } + html += ''; + html += '

' + goods.gd_name + '

'; + html += '
{{ __('hyper.global_currency') }}' + goods.actual_price + '
'; + }); + return html; + } + function sell_out_tip() { $.NotificationApp.send("{{ __('hyper.home_tip') }}","{{ __('hyper.home_sell_out_tip') }}","top-center","rgba(0,0,0,0.2)","info"); } diff --git a/resources/views/luna/errors/error.blade.php b/resources/views/luna/errors/error.blade.php index 0dd3921..94591ab 100644 --- a/resources/views/luna/errors/error.blade.php +++ b/resources/views/luna/errors/error.blade.php @@ -14,7 +14,7 @@
{{ $content }}
@if(!$url)
- + {{ __('dujiaoka.callback') }}
@@ -48,5 +48,3 @@
@endsection - - diff --git a/resources/views/unicorn/errors/error.blade.php b/resources/views/unicorn/errors/error.blade.php index fff4d8a..66b475a 100644 --- a/resources/views/unicorn/errors/error.blade.php +++ b/resources/views/unicorn/errors/error.blade.php @@ -21,7 +21,7 @@
@if(!$url) - {{ __('dujiaoka.callback') }} + {{ __('dujiaoka.callback') }} @else {{ __('dujiaoka.callback') }} @endif diff --git a/resources/views/unicorn/static_pages/home.blade.php b/resources/views/unicorn/static_pages/home.blade.php index 9079fbf..746b17a 100644 --- a/resources/views/unicorn/static_pages/home.blade.php +++ b/resources/views/unicorn/static_pages/home.blade.php @@ -226,17 +226,73 @@ }); $('#group-password-submit').click(function() { + var groupId = $('#group-password-id').val(); + $.post("{{ url('verify-group-password') }}", { _token: "{{ csrf_token() }}", - group_id: $('#group-password-id').val(), + group_id: groupId, password: $('#group-password-input').val() }, function(res) { if (res.code === 200) { - window.location.reload(); + unlockGroup(groupId, res.data); + hideGroupPasswordModal(); } else { alert(res.msg); } }); }); + + function hideGroupPasswordModal() { + var modalEl = document.getElementById('group-password-modal'); + if (typeof bootstrap !== 'undefined' && bootstrap.Modal) { + bootstrap.Modal.getOrCreateInstance(modalEl).hide(); + } else { + $('#group-password-modal').modal('hide'); + } + } + + function unlockGroup(groupId, group) { + var $link = $('.group-password-link[data-group-id="' + groupId + '"]'); + $link.removeClass('group-password-link') + .attr('href', '#group-' + groupId) + .attr('data-bs-toggle', 'tab') + .find('.ali-icon') + .remove(); + + $('#group-' + groupId + ' .row').html(renderGroupGoods(group.goods || [])); + + if (typeof bootstrap !== 'undefined' && bootstrap.Tab) { + bootstrap.Tab.getOrCreateInstance($link[0]).show(); + } else if (typeof $link.tab === 'function') { + $link.tab('show'); + } else { + $('.category-menus a').removeClass('active'); + $('.tab-pane').removeClass('active show'); + $link.addClass('active'); + $('#group-' + groupId).addClass('active show'); + } + } + + function renderGroupGoods(goodsList) { + var html = ''; + $.each(goodsList, function(index, goods) { + html += '
'; + if (parseInt(goods.type) === {{ \App\Models\Goods::AUTOMATIC_DELIVERY }}) { + html += ' {{ __('goods.fields.automatic_delivery') }}'; + } else { + html += ' {{ __('goods.fields.manual_processing') }}'; + } + html += '' + goods.gd_name + ''; + html += '
' + goods.gd_name + '
'; + html += ''; + if (goods.wholesale_price_cnf) { + html += ' '; + } + html += '
{{ __('goods.fields.in_stock') }}:' + goods.in_stock + '
'; + html += ' {{ __('dujiaoka.order_now') }}'; + html += '
'; + }); + return html; + } @stop diff --git a/routes/common/web.php b/routes/common/web.php index 4c8a466..f278df6 100644 --- a/routes/common/web.php +++ b/routes/common/web.php @@ -18,6 +18,8 @@ Route::group(['middleware' => ['dujiaoka.boot'],'namespace' => 'Home'], function Route::get('buy/{id}', 'HomeController@buy'); // 验证商品分类访问密码 Route::post('verify-group-password', 'HomeController@verifyGroupPassword'); + // 取消商品分类密码访问授权 + Route::post('forget-group-password-access', 'HomeController@forgetGroupPasswordAccess'); // 提交订单 Route::post('create-order', 'OrderController@createOrder'); // 结算页