소스 검색

用户注册获取积分

bianjunhui 4 주 전
부모
커밋
a072d42b75

+ 108 - 104
packages/Longyi/RewardPoints/src/Http/Controllers/Admin/CustomerController.php

@@ -60,134 +60,85 @@ class CustomerController extends Controller
         return view($this->_config['view'], compact('customer', 'rewardData', 'history', 'signRecords'));
     }
 
-    /**
-     * Add points to customer
-     */
-    public function addPoints(Request $request)
+    public function adjustPointsForm()
     {
-        $this->validate($request, [
-            'customer_id' => 'required|integer|exists:customers,id',
-            'points' => 'required|integer|min:1',
-            'type' => 'required|integer|in:1,2,3,4,5,6',
-            'reason' => 'nullable|string|max:500'
-        ]);
-
-        try {
-            $customerId = $request->input('customer_id');
-            $points = $request->input('points');
-            $type = $request->input('type');
-            $reason = $request->input('reason', 'Admin adjustment');
-
-            $history = $this->rewardPointRepository->addPoints(
-                $customerId,
-                $type,
-                $points,
-                null,
-                "Admin: " . $reason
-            );
-
-            if ($history) {
-                session()->flash('success', "Successfully added {$points} points to customer.");
-            } else {
-                session()->flash('error', 'Failed to add points.');
-            }
-
-            return redirect()->back();
-
-        } catch (\Exception $e) {
-            session()->flash('error', 'Error adding points: ' . $e->getMessage());
-            return redirect()->back()->withInput();
-        }
+         
+        $view = isset($this->_config['view']) ? $this->_config['view'] : 'rewardpoints::admin.customers.adjust-points';
+        return view($view);
     }
 
-    /**
-     * Deduct points from customer
+     /**
+     * Adjust points by email or ID
      */
-    public function deductPoints(Request $request)
+    public function adjustPointsByIdOrEmail(Request $request)
     {
         $this->validate($request, [
-            'customer_id' => 'required|integer|exists:customers,id',
+            'identifier' => 'required|string',
+            'action' => 'required|in:add,deduct',
             'points' => 'required|integer|min:1',
             'reason' => 'nullable|string|max:500'
         ]);
 
         try {
-            $customerId = $request->input('customer_id');
+            $identifier = trim($request->input('identifier'));
+            $action = $request->input('action');
             $points = $request->input('points');
             $reason = $request->input('reason', 'Admin adjustment');
 
-            $result = $this->rewardPointRepository->deductPoints(
-                $customerId,
-                $points,
-                null,
-                "Admin: " . $reason
-            );
+            // 首先尝试按邮箱查找用户
+            $customer = Customer::where('email', $identifier)->first();
+            
+            // 如果没找到邮箱,尝试按ID查找
+            if (!$customer) {
+                $customerId = (int)$identifier;
+                if (is_numeric($identifier)) {
+                    $customer = Customer::find($customerId);
+                }
+            }
+
+            if (!$customer) {
+                session()->flash('error', 'Customer not found with provided email or ID: ' . $identifier);
+                return redirect()->back()->withInput();
+            }
 
-            if ($result) {
-                session()->flash('success', "Successfully deducted {$points} points from customer.");
+            // 调用现有的积分调整方法
+            if ($action === 'add') {
+                $result = $this->rewardPointRepository->addPoints(
+                    $customer->id,
+                    0, // 0 for admin action
+                    $points,
+                    null,
+                    "Admin: " . $reason
+                );
+                
+                if ($result) {
+                    session()->flash('success', "Successfully added {$points} points to customer {$customer->email}.");
+                } else {
+                    session()->flash('error', 'Failed to add points to customer.');
+                }
             } else {
-                session()->flash('error', 'Insufficient points or customer not found.');
+                $result = $this->rewardPointRepository->deductPoints(
+                    $customer->id,
+                    $points,
+                    null,
+                    "Admin: " . $reason
+                );
+                
+                if ($result) {
+                    session()->flash('success', "Successfully deducted {$points} points from customer {$customer->email}.");
+                } else {
+                    session()->flash('error', 'Insufficient points or customer not found.');
+                }
             }
 
-            return redirect()->back();
+            return redirect()->route('admin.reward-points.customers.index');
 
         } catch (\Exception $e) {
-            session()->flash('error', 'Error deducting points: ' . $e->getMessage());
+            session()->flash('error', 'Error adjusting points: ' . $e->getMessage());
             return redirect()->back()->withInput();
         }
     }
 
-    /**
-     * Export customer points report
-     */
-    public function export(Request $request)
-    {
-        $customers = RewardPointCustomer::with('customer')
-            ->orderBy('mw_reward_point', 'desc')
-            ->get();
-
-        $filename = "reward_points_report_" . Carbon::now()->format('Y-m-d_H-i-s') . ".csv";
-
-        $headers = [
-            'Content-Type' => 'text/csv',
-            'Content-Disposition' => "attachment; filename={$filename}",
-        ];
-
-        $callback = function() use ($customers) {
-            $file = fopen('php://output', 'w');
-
-            // Add CSV headers
-            fputcsv($file, [
-                'Customer ID',
-                'Customer Email',
-                'Customer Name',
-                'Reward Points',
-                'Friend ID',
-                'Subscribed Balance Update',
-                'Subscribed Point Expiration',
-                'Last Checkout'
-            ]);
-
-            // Add data rows
-            foreach ($customers as $customer) {
-                fputcsv($file, [
-                    $customer->customer_id,
-                    $customer->customer->email ?? '',
-                    $customer->customer->first_name . ' ' . $customer->customer->last_name,
-                    $customer->mw_reward_point,
-                    $customer->mw_friend_id,
-                    $customer->subscribed_balance_update ? 'Yes' : 'No',
-                    $customer->subscribed_point_expiration ? 'Yes' : 'No',
-                    $customer->last_checkout
-                ]);
-            }
-
-            fclose($file);
-        };
-
-        return response()->stream($callback, 200, $headers);
-    }
-
     /**
      * Bulk update points
      */
@@ -264,4 +215,57 @@ class CustomerController extends Controller
             return redirect()->back()->withInput();
         }
     }
+
+    /**
+     * Export customer points report
+     */
+    public function export(Request $request)
+    {
+        $customers = RewardPointCustomer::with('customer')
+            ->orderBy('mw_reward_point', 'desc')
+            ->get();
+
+        $filename = "reward_points_report_" . Carbon::now()->format('Y-m-d_H-i-s') . ".csv";
+
+        $headers = [
+            'Content-Type' => 'text/csv',
+            'Content-Disposition' => "attachment; filename={$filename}",
+        ];
+
+        $callback = function() use ($customers) {
+            $file = fopen('php://output', 'w');
+
+            // Add CSV headers
+            fputcsv($file, [
+                'Customer ID',
+                'Customer Email',
+                'Customer Name',
+                'Reward Points',
+                'Friend ID',
+                'Subscribed Balance Update',
+                'Subscribed Point Expiration',
+                'Last Checkout'
+            ]);
+
+            // Add data rows
+            foreach ($customers as $customer) {
+                fputcsv($file, [
+                    $customer->customer_id,
+                    $customer->customer->email ?? '',
+                    $customer->customer->first_name . ' ' . $customer->customer->last_name,
+                    $customer->mw_reward_point,
+                    $customer->mw_friend_id,
+                    $customer->subscribed_balance_update ? 'Yes' : 'No',
+                    $customer->subscribed_point_expiration ? 'Yes' : 'No',
+                    $customer->last_checkout
+                ]);
+            }
+
+            fclose($file);
+        };
+
+        return response()->stream($callback, 200, $headers);
+    }
+
+
 }

+ 32 - 6
packages/Longyi/RewardPoints/src/Listeners/CustomerEvents.php

@@ -4,6 +4,7 @@ namespace Longyi\RewardPoints\Listeners;
 
 use Longyi\RewardPoints\Repositories\RewardPointRepository;
 use Longyi\RewardPoints\Models\RewardActiveRule;
+use Longyi\RewardPoints\Models\RewardPointCustomer;
 
 class CustomerEvents
 {
@@ -14,20 +15,45 @@ class CustomerEvents
         $this->rewardPointRepository = $rewardPointRepository;
     }
 
-    public function handleCustomerRegistration($customer)
+    public function handleCustomerRegistration($event)
     {
-        $rule = RewardActiveRule::where('type_of_transaction', RewardActiveRule::TYPE_REGISTRATION)
+        // 检查是否是 Customer 模型实例
+        if (is_object($event) && method_exists($event, 'getAttribute')) {
+            $customer = $event;
+        } else {
+            // 如果传递的是 customer ID,则需要查询数据库
+            $customerId = $event;
+            $customer = \Webkul\Customer\Models\Customer::find($customerId);
+        }
+
+        if (!$customer) {
+            return;
+        }
+
+        // 尝试通过规则获取积分
+        $rule = RewardActiveRule::where('type_of_transaction', RewardActiveRule::TYPE_REGISTRATION ?? 2) // 默认值为2
             ->where('status', 1)
             ->first();
 
+        $pointsToAdd = 0;
+        $pointsSource = 'rule'; // 默认从规则获取
+
         if ($rule && $rule->reward_point > 0) {
+            $pointsToAdd = $rule->reward_point;
+        } else {
+            // 如果没有规则或者规则无效,尝试从配置获取
+            $pointsToAdd = config('rewardpoints.registration.points_per_registration', 100); // 默认100分
+            $pointsSource = 'config';
+        }
+
+        if ($pointsToAdd > 0) {
             $this->rewardPointRepository->addPoints(
                 $customer->id,
-                RewardActiveRule::TYPE_REGISTRATION,
-                $rule->reward_point,
+                RewardActiveRule::TYPE_REGISTRATION ?? 2, // 使用常量,如果没有则使用默认值
+                $pointsToAdd,
                 null,
-                'Registration bonus'
+                "Registration bonus (via {$pointsSource})"
             );
         }
     }
-}
+}

+ 9 - 0
packages/Longyi/RewardPoints/src/Models/RewardActiveRule.php

@@ -6,6 +6,15 @@ use Illuminate\Database\Eloquent\Model;
 
 class RewardActiveRule extends Model
 {
+    // 定义交易类型常量
+    const TYPE_REGISTRATION = 2;   // 注册
+    const TYPE_SIGN_IN = 1;        // 登录
+    const TYPE_ORDER = 3;          // 订单
+    const TYPE_REVIEW = 4;         // 评价
+    const TYPE_REFERRAL = 5;       // 推荐
+    const TYPE_BIRTHDAY = 6;       // 生日
+    const TYPE_CUSTOM = 7;         // 自定义
+    
     protected $table = 'mw_reward_active_rules';
 
     protected $primaryKey = 'rule_id';

+ 72 - 69
packages/Longyi/RewardPoints/src/Resources/lang/en/rewardpoints.php

@@ -1,73 +1,6 @@
 <?php
 
 return [
-    // Admin 部分
-    'admin' => [
-        'title' => 'Reward Points',
-        'customers' => 'Customers',
-        'customer-id' => 'Customer ID',
-        'name' => 'Name',
-        'email' => 'Email',
-        'reward-points' => 'Reward Points',
-        'total-customers' => 'Total Customers',
-        'total-points' => 'Total Points',
-        'average-points' => 'Average Points',
-        'view' => 'View',
-        'edit' => 'Edit',
-        'delete' => 'Delete',
-        'actions' => 'Actions',
-        'export' => 'Export',
-        'adjust-points' => 'Adjust Points',
-        'add-points' => 'Add Points',
-        'deduct-points' => 'Deduct Points',
-        'reason' => 'Reason',
-        'transactions' => 'Transactions',
-        'date' => 'Date',
-        'type' => 'Type',
-        'description' => 'Description',
-        'points' => 'Points',
-        'balance' => 'Balance',
-        'status' => 'Status',
-        'active' => 'Active',
-        'inactive' => 'Inactive',
-        'rules' => 'Rules',
-        'rule-name' => 'Rule Name',
-        'transaction-type' => 'Transaction Type',
-        'create-rule' => 'Create Rule',
-        'edit-rule' => 'Edit Rule',
-        'delete-rule' => 'Delete Rule',
-        'save' => 'Save',
-        'cancel' => 'Cancel',
-        'back' => 'Back',
-        'reports' => 'Reports',
-        'date-range' => 'Date Range',
-        'start-date' => 'Start Date',
-        'end-date' => 'End Date',
-        'points-earned' => 'Points Earned',
-        'points-redeemed' => 'Points Redeemed',
-        'bulk-update' => 'Bulk Update',
-        'customer-list' => 'Customer List',
-        'customer-name' => 'Customer Name',
-        'points-balance' => 'Points Balance',
-        'last-activity' => 'Last Activity',
-        'search-by-name-or-email' => 'Search by name or email...',
-        'points-high-to-low' => 'Points: High to Low',
-        'points-low-to-high' => 'Points: Low to High',
-        'name-a-to-z' => 'Name: A to Z',
-        'name-z-to-a' => 'Name: Z to A',
-        'view-details' => 'View Details',
-        'transactions' => [
-            'order' => 'Order',
-            'registration' => 'Registration',
-            'review' => 'Review',
-            'sign-in' => 'Sign In',
-            'referral' => 'Referral',
-            'birthday' => 'Birthday',
-            'share' => 'Share',
-        ],
-    ],
-    
-    // Customer 部分
     'customer' => [
         'my-reward-points' => 'My Reward Points',
         'available-points' => 'Available Points',
@@ -92,7 +25,6 @@ return [
         'sign-in' => 'Sign In',
         'referral' => 'Referral',
         'birthday' => 'Birthday',
-        'share' => 'Share',
         'other' => 'Other',
         'pending' => 'Pending',
         'completed' => 'Completed',
@@ -101,7 +33,78 @@ return [
         'no-history' => 'No points history yet',
     ],
     
-    // 验证消息
+    'admin' => [
+        'reward-points' => 'Reward Points',
+        'rules' => 'Rules',
+        'customers' => 'Customers',
+        'reports' => 'Reports',
+        'add-rule' => 'Add Rule',
+        'edit-rule' => 'Edit Rule',
+        'delete-rule' => 'Delete Rule',
+        'rule-name' => 'Rule Name',
+        'transaction-type' => 'Transaction Type',
+        'status' => 'Status',
+        'active' => 'Active',
+        'inactive' => 'Inactive',
+        'actions' => 'Actions',
+        'edit' => 'Edit',
+        'delete' => 'Delete',
+        'create-rule' => 'Create Rule',
+        'update-rule' => 'Update Rule',
+        'back' => 'Back',
+        'save' => 'Save',
+        'cancel' => 'Cancel',
+        'customer-list' => 'Customer List',
+        'customer-name' => 'Customer Name',
+        'email' => 'Email',
+        'points-balance' => 'Points Balance',
+        'add-points' => 'Add Points',
+        'deduct-points' => 'Deduct Points',
+        'reason' => 'Reason',
+        'total-points' => 'Total Points',
+        'total-customers' => 'Total Customers',
+        'average-points' => 'Average Points',
+        'export' => 'Export',
+        'bulk-update' => 'Bulk Update',
+        'date-range' => 'Date Range',
+        'start-date' => 'Start Date',
+        'end-date' => 'End Date',
+        'points-earned' => 'Points Earned',
+        'points-redeemed' => 'Points Redeemed',
+        'transactions' => 'Transactions',
+        'title' => 'Customer Reward Points',
+        'details-title' => ':name\'s Reward Points Details',
+        'customer-info' => 'Customer Information',
+        'points-history' => 'Points History',
+        'adjust-points' => 'Adjust Points',
+        'type' => 'Type',
+        'amount' => 'Amount',
+        'balance' => 'Balance',
+        'date' => 'Date',
+        'description' => 'Description',
+        'customer-id' => 'Customer ID',
+        'name' => 'Name',
+        'view' => 'View',
+        'no-customers-found' => 'No customers found',
+        'no-reward-points-records' => 'No reward points records available',
+        'transactions' => [
+            'order' => 'Order',
+            'registration' => 'Registration',
+            'review' => 'Review',
+            'sign-in' => 'Sign In',
+            'referral' => 'Referral',
+            'birthday' => 'Birthday',
+        ],
+        'adjust-points-by-identifier' => 'Adjust Points by Email or ID',
+        'identifier' => 'Identifier',
+        'email-or-id' => 'Email or ID',
+        'enter-email-or-id' => 'Enter customer email or ID',
+        'enter-points' => 'Enter points amount',
+        'enter-reason' => 'Enter reason for adjustment',
+        'submit' => 'Submit',
+        'action' => 'Action',
+    ],
+    
     'validation' => [
         'points-required' => 'Points are required',
         'points-invalid' => 'Invalid points amount',

+ 105 - 0
packages/Longyi/RewardPoints/src/Resources/views/admin/customers/adjust-points.blade.php

@@ -0,0 +1,105 @@
+<x-admin::layouts>
+    <x-slot:title>
+        @lang('rewardpoints::rewardpoints.admin.adjust-points-by-identifier')
+    </x-slot:title>
+
+    <div class="flex gap-4 justify-between items-center mb-4">
+        <p class="text-xl text-gray-800 dark:text-white font-bold">
+            @lang('rewardpoints::rewardpoints.admin.adjust-points-by-identifier')
+        </p>
+    </div>
+
+    <div class="bg-white dark:bg-gray-900 rounded box-shadow">
+        <form method="POST" action="{{ route('admin.reward-points.customers.adjust-points.submit') }}" class="p-4">
+            @csrf
+            <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
+                <div class="mb-4">
+                    <label for="identifier" class="block text-gray-700 dark:text-gray-300 mb-2">
+                        @lang('rewardpoints::rewardpoints.admin.identifier') (@lang('rewardpoints::rewardpoints.admin.email-or-id'))
+                    </label>
+                    <input 
+                        type="text" 
+                        id="identifier" 
+                        name="identifier" 
+                        value="{{ old('identifier') }}"
+                        class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-800 dark:text-white"
+                        placeholder="@lang('rewardpoints::rewardpoints.admin.enter-email-or-id')"
+                        required
+                    >
+                    @error('identifier')
+                        <div class="text-red-500 mt-1 text-sm">{{ $message }}</div>
+                    @enderror
+                </div>
+
+                <div class="mb-4">
+                    <label for="action" class="block text-gray-700 dark:text-gray-300 mb-2">
+                        @lang('rewardpoints::rewardpoints.admin.action')
+                    </label>
+                    <select 
+                        id="action" 
+                        name="action" 
+                        class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-800 dark:text-white"
+                        required
+                    >
+                        <option value="add">@lang('rewardpoints::rewardpoints.admin.add-points')</option>
+                        <option value="deduct">@lang('rewardpoints::rewardpoints.admin.deduct-points')</option>
+                    </select>
+                    @error('action')
+                        <div class="text-red-500 mt-1 text-sm">{{ $message }}</div>
+                    @enderror
+                </div>
+
+                <div class="mb-4">
+                    <label for="points" class="block text-gray-700 dark:text-gray-300 mb-2">
+                        @lang('rewardpoints::rewardpoints.admin.points')
+                    </label>
+                    <input 
+                        type="number" 
+                        id="points" 
+                        name="points" 
+                        value="{{ old('points') }}"
+                        min="1"
+                        class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-800 dark:text-white"
+                        placeholder="@lang('rewardpoints::rewardpoints.admin.enter-points')"
+                        required
+                    >
+                    @error('points')
+                        <div class="text-red-500 mt-1 text-sm">{{ $message }}</div>
+                    @enderror
+                </div>
+
+                <div class="mb-4">
+                    <label for="reason" class="block text-gray-700 dark:text-gray-300 mb-2">
+                        @lang('rewardpoints::rewardpoints.admin.reason')
+                    </label>
+                    <input 
+                        type="text" 
+                        id="reason" 
+                        name="reason" 
+                        value="{{ old('reason', 'Admin adjustment') }}"
+                        class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-800 dark:text-white"
+                        placeholder="@lang('rewardpoints::rewardpoints.admin.enter-reason')"
+                    >
+                    @error('reason')
+                        <div class="text-red-500 mt-1 text-sm">{{ $message }}</div>
+                    @enderror
+                </div>
+            </div>
+
+            <div class="mt-6">
+                <button 
+                    type="submit" 
+                    class="px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 dark:focus:ring-offset-gray-800"
+                >
+                    @lang('rewardpoints::rewardpoints.admin.submit')
+                </button>
+                <a 
+                    href="{{ route('admin.reward-points.customers.index') }}"
+                    class="px-4 py-2 ml-2 bg-gray-500 text-white rounded-md hover:bg-gray-600 focus:outline-none focus:ring-2 focus:ring-gray-500 focus:ring-offset-2 dark:focus:ring-offset-gray-800"
+                >
+                    @lang('rewardpoints::rewardpoints.admin.cancel')
+                </a>
+            </div>
+        </form>
+    </div>
+</x-admin::layouts>

+ 31 - 21
packages/Longyi/RewardPoints/src/Resources/views/admin/customers/index.blade.php

@@ -1,6 +1,6 @@
 <x-admin::layouts>
     <x-slot:title>
-        @lang('rewardpoints::admin.customers')
+        @lang('rewardpoints::rewardpoints.admin.title')
     </x-slot:title>
 
     {{-- 页面标题和操作按钮 --}}
@@ -8,31 +8,41 @@
         <div class="flex items-center gap-3">
             <div class="icon-users text-2xl text-blue-500"></div>
             <p class="text-2xl text-gray-800 dark:text-white font-bold">
-                @lang('rewardpoints::admin.customers')
+                @lang('rewardpoints::rewardpoints.admin.customers')
             </p>
             <span class="px-2.5 py-0.5 text-sm bg-blue-100 dark:bg-blue-900 text-blue-800 dark:text-blue-200 rounded-full">
-                {{ $totalCustomers }} @lang('rewardpoints::admin.total-customers')
+                {{ $totalCustomers }} @lang('rewardpoints::rewardpoints.admin.total-customers')
             </span>
         </div>
 
         <div class="flex gap-x-2.5 items-center">
+            {{-- 调整积分按钮 --}}
+            <a 
+                href="{{ route('admin.reward-points.customers.adjust-form') }}" 
+                style="padding: 0.5rem 1rem; background-color: #10b981; color: white; font-weight: 500; border-radius: 0.5rem; text-decoration: none; transition: all 0.15s ease;"
+                onmouseover="this.style.backgroundColor='#059669'"
+                onmouseout="this.style.backgroundColor='#10b981'"
+            >
+                + Adjust Points
+            </a>
+            
+            {{-- 导出按钮 --}}
             <a 
                 href="{{ route('admin.reward-points.customers.export') }}" 
-                class="secondary-button flex items-center gap-2"
+                class="secondary-button"
             >
-                <span class="icon-download text-lg"></span>
-                @lang('rewardpoints::admin.export')
+                Export
             </a>
         </div>
     </div>
 
     {{-- 统计卡片 --}}
-    <div class="grid grid-cols-1 md:grid-cols-3 gap-4 mb-6">
-        <div class="bg-gradient-to-br from-blue-50 to-blue-100 dark:from-blue-900/20 dark:to-blue-800/20 rounded-xl p-5 border border-blue-200 dark:border-blue-800">
+    <div class="flex flex-wrap gap-4 mb-6">
+        <div class="flex-1 min-w-[200px] bg-gradient-to-br from-blue-50 to-blue-100 dark:from-blue-900/20 dark:to-blue-800/20 rounded-xl p-5 border border-blue-200 dark:border-blue-800">
             <div class="flex items-center justify-between">
                 <div>
                     <p class="text-sm text-gray-600 dark:text-gray-400 mb-1">
-                        @lang('rewardpoints::admin.total-customers')
+                        @lang('rewardpoints::rewardpoints.admin.total-customers')
                     </p>
                     <p class="text-3xl font-bold text-blue-600 dark:text-blue-400">
                         {{ $totalCustomers }}
@@ -44,11 +54,11 @@
             </div>
         </div>
         
-        <div class="bg-gradient-to-br from-green-50 to-green-100 dark:from-green-900/20 dark:to-green-800/20 rounded-xl p-5 border border-green-200 dark:border-green-800">
+        <div class="flex-1 min-w-[200px] bg-gradient-to-br from-green-50 to-green-100 dark:from-green-900/20 dark:to-green-800/20 rounded-xl p-5 border border-green-200 dark:border-green-800">
             <div class="flex items-center justify-between">
                 <div>
                     <p class="text-sm text-gray-600 dark:text-gray-400 mb-1">
-                        @lang('rewardpoints::admin.total-points')
+                        @lang('rewardpoints::rewardpoints.admin.total-points')
                     </p>
                     <p class="text-3xl font-bold text-green-600 dark:text-green-400">
                         {{ number_format($totalPoints) }}
@@ -60,11 +70,11 @@
             </div>
         </div>
         
-        <div class="bg-gradient-to-br from-purple-50 to-purple-100 dark:from-purple-900/20 dark:to-purple-800/20 rounded-xl p-5 border border-purple-200 dark:border-purple-800">
+        <div class="flex-1 min-w-[200px] bg-gradient-to-br from-purple-50 to-purple-100 dark:from-purple-900/20 dark:to-purple-800/20 rounded-xl p-5 border border-purple-200 dark:border-purple-800">
             <div class="flex items-center justify-between">
                 <div>
                     <p class="text-sm text-gray-600 dark:text-gray-400 mb-1">
-                        @lang('rewardpoints::admin.average-points')
+                        @lang('rewardpoints::rewardpoints.admin.average-points')
                     </p>
                     <p class="text-3xl font-bold text-purple-600 dark:text-purple-400">
                         {{ number_format(round($averagePoints, 2), 2) }}
@@ -84,19 +94,19 @@
                 <thead class="bg-gray-50 dark:bg-gray-800">
                     <tr>
                         <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">
-                            @lang('rewardpoints::admin.customer-id')
+                            @lang('rewardpoints::rewardpoints.admin.customer-id')
                         </th>
                         <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">
-                            @lang('rewardpoints::admin.name')
+                            @lang('rewardpoints::rewardpoints.admin.name')
                         </th>
                         <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">
-                            @lang('rewardpoints::admin.email')
+                            @lang('rewardpoints::rewardpoints.admin.email')
                         </th>
                         <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">
-                            @lang('rewardpoints::admin.reward-points')
+                            @lang('rewardpoints::rewardpoints.admin.reward-points')
                         </th>
                         <th class="px-6 py-3 text-right text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">
-                            @lang('rewardpoints::admin.actions')
+                            @lang('rewardpoints::rewardpoints.admin.actions')
                         </th>
                     </tr>
                 </thead>
@@ -126,7 +136,7 @@
                                     class="inline-flex items-center gap-1 px-3 py-1.5 bg-blue-50 dark:bg-blue-900/20 text-blue-600 dark:text-blue-400 hover:bg-blue-100 dark:hover:bg-blue-900/30 rounded-lg transition-colors"
                                 >
                                     <span class="icon-eye text-sm"></span>
-                                    <span class="text-sm">@lang('rewardpoints::admin.view')</span>
+                                    <span class="text-sm">@lang('rewardpoints::rewardpoints.admin.view')</span>
                                 </a>
                             </td>
                         </tr>
@@ -139,10 +149,10 @@
                                     </div>
                                     <div>
                                         <p class="text-lg font-medium text-gray-600 dark:text-gray-400 mb-1">
-                                            @lang('No customers found')
+                                            @lang('rewardpoints::rewardpoints.admin.no-customers-found')
                                         </p>
                                         <p class="text-sm text-gray-500 dark:text-gray-500">
-                                            @lang('No reward points records available')
+                                            @lang('rewardpoints::rewardpoints.admin.no-reward-points-records')
                                         </p>
                                     </div>
                                 </div>

+ 69 - 39
packages/Longyi/RewardPoints/src/Routes/routes.php

@@ -1,6 +1,8 @@
 <?php
+
 use Illuminate\Support\Facades\Route;
 
+// 前台路由 - 客户中心
 Route::group(['middleware' => ['web', 'customer'], 'prefix' => 'customer'], function () {
     Route::get('reward-points', [
         'as' => 'customer.reward-points.index',
@@ -17,7 +19,8 @@ Route::group(['middleware' => ['web', 'customer'], 'prefix' => 'customer'], func
         'as' => 'customer.reward-points.sign-status',
         'uses' => 'Longyi\RewardPoints\Http\Controllers\RewardPointsController@getSignStatus'
     ]);
-        Route::post('apply-reward-points', [
+    
+    Route::post('apply-reward-points', [
         'as' => 'checkout.apply-reward-points',
         'uses' => 'Longyi\RewardPoints\Http\Controllers\RewardPointsController@applyPoints'
     ]);
@@ -33,8 +36,10 @@ Route::group(['middleware' => ['web', 'customer'], 'prefix' => 'customer'], func
     ]);
 });
 
-// Admin routes
+// 后台路由
 Route::group(['middleware' => ['web', 'admin'], 'prefix' => 'admin/reward-points'], function () {
+    
+    // ========== 规则管理 - 静态路由 ==========
     Route::get('rules', [
         'as' => 'admin.reward-points.rules.index',
         'uses' => 'Longyi\RewardPoints\Http\Controllers\Admin\RuleController@index'
@@ -50,6 +55,61 @@ Route::group(['middleware' => ['web', 'admin'], 'prefix' => 'admin/reward-points
         'uses' => 'Longyi\RewardPoints\Http\Controllers\Admin\RuleController@store'
     ]);
 
+    // ========== 客户管理 - 静态路由(重要:放在动态路由之前) ==========
+    // 导出路由
+    Route::get('customers/export', [
+        'as' => 'admin.reward-points.customers.export',
+        'uses' => 'Longyi\RewardPoints\Http\Controllers\Admin\CustomerController@export'
+    ]);
+    
+    // 调整积分表单路由
+    Route::get('customers/adjust-points', [
+        'as' => 'admin.reward-points.customers.adjust-form',
+        'uses' => 'Longyi\RewardPoints\Http\Controllers\Admin\CustomerController@adjustPointsForm'
+    ]);
+    
+    // 提交调整积分
+    Route::post('customers/adjust-points', [
+        'as' => 'admin.reward-points.customers.adjust-points.submit',
+        'uses' => 'Longyi\RewardPoints\Http\Controllers\Admin\CustomerController@adjustPointsByIdOrEmail'
+    ]);
+    
+    // 批量更新
+    Route::post('customers/bulk-update', [
+        'as' => 'admin.reward-points.customers.bulk-update',
+        'uses' => 'Longyi\RewardPoints\Http\Controllers\Admin\CustomerController@bulkUpdate'
+    ]);
+    
+    // 添加积分
+    Route::post('customers/add-points', [
+        'as' => 'admin.reward-points.customers.add-points',
+        'uses' => 'Longyi\RewardPoints\Http\Controllers\Admin\CustomerController@addPoints'
+    ]);
+    
+    // 扣除积分
+    Route::post('customers/deduct-points', [
+        'as' => 'admin.reward-points.customers.deduct-points',
+        'uses' => 'Longyi\RewardPoints\Http\Controllers\Admin\CustomerController@deductPoints'
+    ]);
+    
+    // ========== 报表管理 - 静态路由 ==========
+    Route::get('reports/export', [
+        'as' => 'admin.reward-points.reports.export',
+        'uses' => 'Longyi\RewardPoints\Http\Controllers\Admin\ReportController@export'
+    ]);
+    
+    // ========== 设置管理 - 静态路由 ==========
+    Route::get('settings', [
+        'as' => 'admin.reward-points.settings.index',
+        'uses' => 'Longyi\RewardPoints\Http\Controllers\Admin\SettingController@index'
+    ]);
+
+    Route::post('settings', [
+        'as' => 'admin.reward-points.settings.save',
+        'uses' => 'Longyi\RewardPoints\Http\Controllers\Admin\SettingController@save'
+    ]);
+    
+    // ========== 规则管理 - 动态路由 ==========
     Route::get('rules/{id}/edit', [
         'as' => 'admin.reward-points.rules.edit',
         'uses' => 'Longyi\RewardPoints\Http\Controllers\Admin\RuleController@edit'
@@ -69,53 +129,23 @@ Route::group(['middleware' => ['web', 'admin'], 'prefix' => 'admin/reward-points
         'as' => 'admin.reward-points.rules.update-status',
         'uses' => 'Longyi\RewardPoints\Http\Controllers\Admin\RuleController@updateStatus'
     ]);
-
+    
+    // ========== 客户管理 - 动态路由 ==========
+    // 客户列表(放在动态路由前面也可以,但为了清晰,放在这里)
     Route::get('customers', [
         'as' => 'admin.reward-points.customers.index',
         'uses' => 'Longyi\RewardPoints\Http\Controllers\Admin\CustomerController@index'
     ]);
-
+    
+    // 客户详情(动态参数路由,必须放在所有静态路由之后)
     Route::get('customers/{customerId}', [
         'as' => 'admin.reward-points.customers.show',
         'uses' => 'Longyi\RewardPoints\Http\Controllers\Admin\CustomerController@show'
     ]);
-
-    Route::post('customers/add-points', [
-        'as' => 'admin.reward-points.customers.add-points',
-        'uses' => 'Longyi\RewardPoints\Http\Controllers\Admin\CustomerController@addPoints'
-    ]);
-
-    Route::post('customers/deduct-points', [
-        'as' => 'admin.reward-points.customers.deduct-points',
-        'uses' => 'Longyi\RewardPoints\Http\Controllers\Admin\CustomerController@deductPoints'
-    ]);
-
-    Route::post('customers/bulk-update', [
-        'as' => 'admin.reward-points.customers.bulk-update',
-        'uses' => 'Longyi\RewardPoints\Http\Controllers\Admin\CustomerController@bulkUpdate'
-    ]);
-
-    Route::get('customers/export', [
-        'as' => 'admin.reward-points.customers.export',
-        'uses' => 'Longyi\RewardPoints\Http\Controllers\Admin\CustomerController@export'
-    ]);
-
+    
+    // ========== 报表管理 - 动态路由 ==========
     Route::get('reports', [
         'as' => 'admin.reward-points.reports.index',
         'uses' => 'Longyi\RewardPoints\Http\Controllers\Admin\ReportController@index'
     ]);
-
-    Route::get('reports/export', [
-        'as' => 'admin.reward-points.reports.export',
-        'uses' => 'Longyi\RewardPoints\Http\Controllers\Admin\ReportController@export'
-    ]);
-    Route::get('settings', [
-        'as' => 'admin.reward-points.settings.index',
-        'uses' => 'Longyi\RewardPoints\Http\Controllers\Admin\SettingController@index'
-    ]);
-
-    Route::post('settings', [
-        'as' => 'admin.reward-points.settings.save',
-        'uses' => 'Longyi\RewardPoints\Http\Controllers\Admin\SettingController@save'
-    ]);
 });