bianjunhui hai 4 semanas
pai
achega
50a5da6529

+ 3 - 3
packages/Longyi/DynamicMenu/src/Database/Seeders/MenuItemSeeder.php

@@ -8,7 +8,7 @@ class MenuItemSeeder extends Seeder
     public function run()
     public function run()
     {
     {
         $dynamicMenu = MenuItem::create([
         $dynamicMenu = MenuItem::create([
-            'name' => 'Dynamic Menu',
+            'name' => '自定义菜单',
             'key' => 'dynamicmenu',
             'key' => 'dynamicmenu',
             'route' => 'admin.dynamicmenu.index',
             'route' => 'admin.dynamicmenu.index',
             'icon' => 'icon-menu',
             'icon' => 'icon-menu',
@@ -17,7 +17,7 @@ class MenuItemSeeder extends Seeder
         ]);
         ]);
 
 
         MenuItem::create([
         MenuItem::create([
-            'name' => 'Menu Items',
+            'name' => '菜单列表',
             'key' => 'dynamicmenu.menu',
             'key' => 'dynamicmenu.menu',
             'route' => 'admin.dynamicmenu.index',
             'route' => 'admin.dynamicmenu.index',
             'icon' => 'icon-list',
             'icon' => 'icon-list',
@@ -27,7 +27,7 @@ class MenuItemSeeder extends Seeder
         ]);
         ]);
 
 
         MenuItem::create([
         MenuItem::create([
-            'name' => 'Menu Permissions',
+            'name' => '权限管理',
             'key' => 'dynamicmenu.permission',
             'key' => 'dynamicmenu.permission',
             'route' => 'admin.dynamicmenu.permission',
             'route' => 'admin.dynamicmenu.permission',
             'icon' => 'icon-lock',
             'icon' => 'icon-lock',

+ 2 - 1
packages/Longyi/RewardPoints/src/Database/Migrations/2026_01_01_000001_create_points_tables.php

@@ -17,7 +17,8 @@ return new class extends Migration
                 $table->string('rule_name', 255)->default('');
                 $table->string('rule_name', 255)->default('');
                 $table->integer('type_of_transaction')->default(0);
                 $table->integer('type_of_transaction')->default(0);
                 $table->string('store_view', 255)->default('0');
                 $table->string('store_view', 255)->default('0');
-                $table->string('customer_group_ids', 255)->default('');
+                $table->string('enable_different_points_by_group', 255)->default('');
+                $table->string('customer_group_ids', 255)->default(false);
                 $table->integer('default_expired')->nullable()->default(1);
                 $table->integer('default_expired')->nullable()->default(1);
                 $table->integer('expired_day')->nullable()->default(0);
                 $table->integer('expired_day')->nullable()->default(0);
                 $table->string('date_event', 255)->default('');
                 $table->string('date_event', 255)->default('');

+ 4 - 3
packages/Longyi/RewardPoints/src/Http/Controllers/Admin/CustomerController.php

@@ -18,13 +18,13 @@ class CustomerController extends Controller
     public function __construct(RewardPointRepository $rewardPointRepository)
     public function __construct(RewardPointRepository $rewardPointRepository)
     {
     {
         $this->rewardPointRepository = $rewardPointRepository;
         $this->rewardPointRepository = $rewardPointRepository;
-        $this->_config = request('_config');
+        $this->_config = request('_config') ?: [];
     }
     }
 
 
     /**
     /**
      * Display a listing of customers with reward points
      * Display a listing of customers with reward points
      */
      */
-    public function index()
+     public function index()
     {
     {
         $customers = RewardPointCustomer::with('customer')
         $customers = RewardPointCustomer::with('customer')
             ->orderBy('mw_reward_point', 'desc')
             ->orderBy('mw_reward_point', 'desc')
@@ -34,7 +34,8 @@ class CustomerController extends Controller
         $totalCustomers = RewardPointCustomer::count();
         $totalCustomers = RewardPointCustomer::count();
         $averagePoints = $totalCustomers > 0 ? $totalPoints / $totalCustomers : 0;
         $averagePoints = $totalCustomers > 0 ? $totalPoints / $totalCustomers : 0;
 
 
-        return view($this->_config['view'], compact('customers', 'totalPoints', 'totalCustomers', 'averagePoints'));
+        $view = isset($this->_config['view']) ? $this->_config['view'] : 'rewardpoints::admin.customers.index';
+        return view($view, compact('customers', 'totalPoints', 'totalCustomers', 'averagePoints'));
     }
     }
 
 
     /**
     /**

+ 152 - 42
packages/Longyi/RewardPoints/src/Http/Controllers/Admin/RuleController.php

@@ -15,7 +15,7 @@ class RuleController extends Controller
     public function __construct(RewardPointRepository $rewardPointRepository)
     public function __construct(RewardPointRepository $rewardPointRepository)
     {
     {
         $this->rewardPointRepository = $rewardPointRepository;
         $this->rewardPointRepository = $rewardPointRepository;
-        $this->_config = request('_config');
+        $this->_config = request('_config') ?: [];
     }
     }
 
 
     /**
     /**
@@ -24,8 +24,29 @@ class RuleController extends Controller
     public function index()
     public function index()
     {
     {
         $rules = RewardActiveRule::orderBy('rule_id', 'desc')->paginate(15);
         $rules = RewardActiveRule::orderBy('rule_id', 'desc')->paginate(15);
+        $customerGroupsList = $this->getCustomerGroups(); // 获取群组列表
+        
+        $view = isset($this->_config['view']) ? $this->_config['view'] : 'rewardpoints::admin.rules.index';
+        
+        return view($view, compact('rules', 'customerGroupsList'));
+    }
 
 
-        return view($this->_config['view'], compact('rules'));
+    /**
+     * Helper method to get transaction type name
+     */
+    protected function getTransactionTypeName($typeId)
+    {
+        $types = [
+            1 => 'Order',
+            2 => 'Registration',
+            3 => 'Product Review',
+            4 => 'Daily Sign In',
+            5 => 'Referral',
+            6 => 'Birthday',
+            7 => 'Share'
+        ];
+
+        return $types[$typeId] ?? 'Unknown';
     }
     }
 
 
     /**
     /**
@@ -39,13 +60,17 @@ class RuleController extends Controller
             3 => 'Product Review',
             3 => 'Product Review',
             4 => 'Daily Sign In',
             4 => 'Daily Sign In',
             5 => 'Referral',
             5 => 'Referral',
-            6 => 'Birthday'
+            6 => 'Birthday',
+            7 => 'Share'  // 添加分享类型的交易
         ];
         ];
 
 
         $storeViews = $this->getStoreViews();
         $storeViews = $this->getStoreViews();
         $customerGroups = $this->getCustomerGroups();
         $customerGroups = $this->getCustomerGroups();
 
 
-        return view($this->_config['view'], compact('transactionTypes', 'storeViews', 'customerGroups'));
+        // 确保 _config 存在且包含必要的键
+        $view = isset($this->_config['view']) ? $this->_config['view'] : 'rewardpoints::admin.rules.create';
+        
+        return view($view, compact('transactionTypes', 'storeViews', 'customerGroups'));
     }
     }
 
 
     /**
     /**
@@ -55,31 +80,63 @@ class RuleController extends Controller
     {
     {
         $this->validate($request, [
         $this->validate($request, [
             'rule_name' => 'required|string|max:255',
             'rule_name' => 'required|string|max:255',
-            'type_of_transaction' => 'required|integer|in:1,2,3,4,5,6',
-            'reward_point' => 'required|integer|min:0',
+            'type_of_transaction' => 'required|integer|in:1,2,3,4,5,6,7',
             'status' => 'required|boolean',
             'status' => 'required|boolean',
-            'default_expired' => 'nullable|boolean',
+            'enable_different_points_by_group' => 'nullable|boolean',
+            //'default_expired' => 'nullable|boolean',
             'expired_day' => 'nullable|integer|min:0',
             'expired_day' => 'nullable|integer|min:0',
-            'coupon_code' => 'nullable|string|max:255'
+            //'coupon_code' => 'nullable|string|max:255',
         ]);
         ]);
 
 
         try {
         try {
-            $data = $request->all();
-
-            // Handle customer group IDs
-            if (isset($data['customer_group_ids']) && is_array($data['customer_group_ids'])) {
-                $data['customer_group_ids'] = implode(',', $data['customer_group_ids']);
-            }
+            $data = $request->only([
+                'rule_name',
+                'type_of_transaction',
+                'store_view',
+                //'default_expired',
+                'expired_day',
+                //'date_event',
+                'comment',
+                //'coupon_code',
+                'status',
+                'enable_different_points_by_group'
+            ]);
 
 
-            // Handle store views
+            // 处理 store views
             if (isset($data['store_view']) && is_array($data['store_view'])) {
             if (isset($data['store_view']) && is_array($data['store_view'])) {
                 $data['store_view'] = implode(',', $data['store_view']);
                 $data['store_view'] = implode(',', $data['store_view']);
+            } else {
+                $data['store_view'] = '0';
+            }
+
+            // 根据是否启用不同群组不同积分来处理客户群组和积分
+            if ($request->get('enable_different_points_by_group')) {
+                // 当启用不同群组不同积分时,将群组积分数据存储为JSON
+                $groupPoints = $request->get('group_points', []);
+                $data['customer_group_ids'] = json_encode($groupPoints);
+                // 统一积分为0,因为实际积分存储在customer_group_ids中
+                $data['reward_point'] = 0;
+            } else {
+                // 验证统一积分值
+                $this->validate($request, [
+                    'reward_point' => 'required|integer|min:0',
+                ]);
+                $data['reward_point'] = $request->get('reward_point');
+                
+                // 处理客户群组IDs
+                if (isset($request['customer_group_ids']) && is_array($request['customer_group_ids'])) {
+                    $data['customer_group_ids'] = implode(',', $request['customer_group_ids']);
+                } else {
+                    $data['customer_group_ids'] = '';
+                }
             }
             }
 
 
             $rule = RewardActiveRule::create($data);
             $rule = RewardActiveRule::create($data);
 
 
             session()->flash('success', 'Reward rule created successfully.');
             session()->flash('success', 'Reward rule created successfully.');
-            return redirect()->route('admin.reward-points.rules.index');
+            
+            $redirectRoute = isset($this->_config['redirect']) ? $this->_config['redirect'] : 'admin.reward-points.rules.index';
+            return redirect()->route($redirectRoute);
 
 
         } catch (\Exception $e) {
         } catch (\Exception $e) {
             session()->flash('error', 'Error creating reward rule: ' . $e->getMessage());
             session()->flash('error', 'Error creating reward rule: ' . $e->getMessage());
@@ -100,17 +157,27 @@ class RuleController extends Controller
             3 => 'Product Review',
             3 => 'Product Review',
             4 => 'Daily Sign In',
             4 => 'Daily Sign In',
             5 => 'Referral',
             5 => 'Referral',
-            6 => 'Birthday'
+            6 => 'Birthday',
+            7 => 'Share'  // 添加分享类型的交易
         ];
         ];
 
 
         $storeViews = $this->getStoreViews();
         $storeViews = $this->getStoreViews();
         $customerGroups = $this->getCustomerGroups();
         $customerGroups = $this->getCustomerGroups();
 
 
-        // Parse stored values
+        // 解析存储的值
         $selectedStoreViews = $rule->store_view ? explode(',', $rule->store_view) : [];
         $selectedStoreViews = $rule->store_view ? explode(',', $rule->store_view) : [];
-        $selectedCustomerGroups = $rule->customer_group_ids ? explode(',', $rule->customer_group_ids) : [];
+        
+        // 如果启用了不同群组不同积分,则解析customer_group_ids为数组
+        if ($rule->enable_different_points_by_group) {
+            $selectedCustomerGroups = json_decode($rule->customer_group_ids, true) ?: [];
+        } else {
+            $selectedCustomerGroups = $rule->customer_group_ids ? explode(',', $rule->customer_group_ids) : [];
+        }
 
 
-        return view($this->_config['view'], compact(
+        // 确保 _config 存在且包含必要的键
+        $view = isset($this->_config['view']) ? $this->_config['view'] : 'rewardpoints::admin.rules.edit';
+        
+        return view($view, compact(
             'rule',
             'rule',
             'transactionTypes',
             'transactionTypes',
             'storeViews',
             'storeViews',
@@ -127,36 +194,65 @@ class RuleController extends Controller
     {
     {
         $this->validate($request, [
         $this->validate($request, [
             'rule_name' => 'required|string|max:255',
             'rule_name' => 'required|string|max:255',
-            'type_of_transaction' => 'required|integer|in:1,2,3,4,5,6',
-            'reward_point' => 'required|integer|min:0',
+            'type_of_transaction' => 'required|integer|in:1,2,3,4,5,6,7',
             'status' => 'required|boolean',
             'status' => 'required|boolean',
+            'enable_different_points_by_group' => 'nullable|boolean',
             'default_expired' => 'nullable|boolean',
             'default_expired' => 'nullable|boolean',
             'expired_day' => 'nullable|integer|min:0',
             'expired_day' => 'nullable|integer|min:0',
-            'coupon_code' => 'nullable|string|max:255'
+            'coupon_code' => 'nullable|string|max:255',
         ]);
         ]);
 
 
         try {
         try {
             $rule = RewardActiveRule::findOrFail($id);
             $rule = RewardActiveRule::findOrFail($id);
-            $data = $request->all();
-
-            // Handle customer group IDs
-            if (isset($data['customer_group_ids']) && is_array($data['customer_group_ids'])) {
-                $data['customer_group_ids'] = implode(',', $data['customer_group_ids']);
-            } else {
-                $data['customer_group_ids'] = '';
-            }
+            
+            $data = $request->only([
+                'rule_name',
+                'type_of_transaction',
+                'store_view',
+                'default_expired',
+                'expired_day',
+                'date_event',
+                'comment',
+                'coupon_code',
+                'status',
+                'enable_different_points_by_group'
+            ]);
 
 
-            // Handle store views
+            // 处理 store views
             if (isset($data['store_view']) && is_array($data['store_view'])) {
             if (isset($data['store_view']) && is_array($data['store_view'])) {
                 $data['store_view'] = implode(',', $data['store_view']);
                 $data['store_view'] = implode(',', $data['store_view']);
             } else {
             } else {
                 $data['store_view'] = '0';
                 $data['store_view'] = '0';
             }
             }
 
 
+            // 根据是否启用不同群组不同积分来处理客户群组和积分
+            if ($request->get('enable_different_points_by_group')) {
+                // 当启用不同群组不同积分时,将群组积分数据存储为JSON
+                $groupPoints = $request->get('group_points', []);
+                $data['customer_group_ids'] = json_encode($groupPoints);
+                // 统一积分为0,因为实际积分存储在customer_group_ids中
+                $data['reward_point'] = 0;
+            } else {
+                // 验证统一积分值
+                $this->validate($request, [
+                    'reward_point' => 'required|integer|min:0',
+                ]);
+                $data['reward_point'] = $request->get('reward_point');
+                
+                // 处理客户群组IDs
+                if (isset($request['customer_group_ids']) && is_array($request['customer_group_ids'])) {
+                    $data['customer_group_ids'] = implode(',', $request['customer_group_ids']);
+                } else {
+                    $data['customer_group_ids'] = '';
+                }
+            }
+
             $rule->update($data);
             $rule->update($data);
 
 
             session()->flash('success', 'Reward rule updated successfully.');
             session()->flash('success', 'Reward rule updated successfully.');
-            return redirect()->route('admin.reward-points.rules.index');
+            
+            $redirectRoute = isset($this->_config['redirect']) ? $this->_config['redirect'] : 'admin.reward-points.rules.index';
+            return redirect()->route($redirectRoute);
 
 
         } catch (\Exception $e) {
         } catch (\Exception $e) {
             session()->flash('error', 'Error updating reward rule: ' . $e->getMessage());
             session()->flash('error', 'Error updating reward rule: ' . $e->getMessage());
@@ -174,17 +270,31 @@ class RuleController extends Controller
             $rule->delete();
             $rule->delete();
 
 
             session()->flash('success', 'Reward rule deleted successfully.');
             session()->flash('success', 'Reward rule deleted successfully.');
-            return response()->json([
-                'status' => true,
-                'message' => 'Reward rule deleted successfully.'
-            ]);
+            
+            // 检查请求是否是 AJAX 请求
+            if (request()->ajax()) {
+                return response()->json([
+                    'status' => true,
+                    'message' => 'Reward rule deleted successfully.'
+                ]);
+            } else {
+                // 非 AJAX 请求则进行重定向
+                $redirectRoute = isset($this->_config['redirect']) ? $this->_config['redirect'] : 'admin.reward-points.rules.index';
+                return redirect()->route($redirectRoute);
+            }
 
 
         } catch (\Exception $e) {
         } catch (\Exception $e) {
             session()->flash('error', 'Error deleting reward rule: ' . $e->getMessage());
             session()->flash('error', 'Error deleting reward rule: ' . $e->getMessage());
-            return response()->json([
-                'status' => false,
-                'message' => 'Error deleting reward rule.'
-            ]);
+            
+            if (request()->ajax()) {
+                return response()->json([
+                    'status' => false,
+                    'message' => 'Error deleting reward rule.'
+                ]);
+            } else {
+                $redirectRoute = isset($this->_config['redirect']) ? $this->_config['redirect'] : 'admin.reward-points.rules.index';
+                return redirect()->route($redirectRoute)->with('error', 'Error deleting reward rule: ' . $e->getMessage());
+            }
         }
         }
     }
     }
 
 
@@ -234,4 +344,4 @@ class RuleController extends Controller
             return ['0' => 'All Groups'];
             return ['0' => 'All Groups'];
         }
         }
     }
     }
-}
+}

+ 36 - 9
packages/Longyi/RewardPoints/src/Http/Controllers/Admin/SettingController.php

@@ -15,7 +15,7 @@ class SettingController extends Controller
         RewardPointSettingRepository $settingRepository
         RewardPointSettingRepository $settingRepository
     ) {
     ) {
         $this->settingRepository = $settingRepository;
         $this->settingRepository = $settingRepository;
-        $this->_config = request('_config');
+        $this->_config = request('_config') ?: [];
     }
     }
 
 
     /**
     /**
@@ -27,7 +27,13 @@ class SettingController extends Controller
         $currentGroup = request('group', 'general');
         $currentGroup = request('group', 'general');
         $settings = $this->settingRepository->getSettingsByGroup($currentGroup);
         $settings = $this->settingRepository->getSettingsByGroup($currentGroup);
         
         
-        return view($this->_config['view'], compact('groups', 'currentGroup', 'settings'));
+        // 获取分组数据(包含名称和排序)
+        $groupData = $this->getGroupData($groups);
+        
+        // 确保 _config 存在且包含必要的键
+        $view = isset($this->_config['view']) ? $this->_config['view'] : 'rewardpoints::admin.settings.index';
+        
+        return view($view, compact('groups', 'currentGroup', 'settings', 'groupData'));
     }
     }
 
 
     /**
     /**
@@ -51,7 +57,8 @@ class SettingController extends Controller
             
             
             session()->flash('success', '配置保存成功');
             session()->flash('success', '配置保存成功');
             
             
-            return redirect()->route($this->_config['redirect'], ['group' => $request->input('group', 'general')]);
+            $redirectRoute = isset($this->_config['redirect']) ? $this->_config['redirect'] : 'admin.reward-points.settings.index';
+            return redirect()->route($redirectRoute, ['group' => $request->input('group', 'general')]);
             
             
         } catch (\Exception $e) {
         } catch (\Exception $e) {
             session()->flash('error', '保存配置失败:' . $e->getMessage());
             session()->flash('error', '保存配置失败:' . $e->getMessage());
@@ -59,6 +66,32 @@ class SettingController extends Controller
         }
         }
     }
     }
     
     
+    /**
+     * 获取分组数据(包含名称和排序)
+     */
+    protected function getGroupData($groups)
+    {
+        // 定义分组排序顺序
+        $groupOrder = [
+            'general' => 1,      // 通用设置
+        ];
+        
+        $groupData = [];
+        foreach ($groups as $group) {
+            $groupData[$group] = [
+                'name' => $this->getGroupName($group),
+                'order' => $groupOrder[$group] ?? 99, // 如果未定义顺序,默认排在最后
+            ];
+        }
+        
+        // 按照排序顺序排列
+        uasort($groupData, function($a, $b) {
+            return $a['order'] <=> $b['order'];
+        });
+        
+        return $groupData;
+    }
+    
     /**
     /**
      * 获取分组名称
      * 获取分组名称
      */
      */
@@ -66,12 +99,6 @@ class SettingController extends Controller
     {
     {
         $names = [
         $names = [
             'general' => '通用设置',
             'general' => '通用设置',
-            'signin' => '签到设置',
-            'order' => '订单设置',
-            'registration' => '注册设置',
-            'review' => '评价设置',
-            'referral' => '推荐设置',
-            'birthday' => '生日设置',
         ];
         ];
         return $names[$group] ?? ucfirst($group);
         return $names[$group] ?? ucfirst($group);
     }
     }

+ 43 - 12
packages/Longyi/RewardPoints/src/Models/RewardActiveRule.php

@@ -7,7 +7,9 @@ use Illuminate\Database\Eloquent\Model;
 class RewardActiveRule extends Model
 class RewardActiveRule extends Model
 {
 {
     protected $table = 'mw_reward_active_rules';
     protected $table = 'mw_reward_active_rules';
+
     protected $primaryKey = 'rule_id';
     protected $primaryKey = 'rule_id';
+
     public $timestamps = false;
     public $timestamps = false;
 
 
     protected $fillable = [
     protected $fillable = [
@@ -15,26 +17,55 @@ class RewardActiveRule extends Model
         'type_of_transaction',
         'type_of_transaction',
         'store_view',
         'store_view',
         'customer_group_ids',
         'customer_group_ids',
+        'enable_different_points_by_group',
         'default_expired',
         'default_expired',
         'expired_day',
         'expired_day',
         'date_event',
         'date_event',
         'comment',
         'comment',
         'coupon_code',
         'coupon_code',
         'reward_point',
         'reward_point',
-        'status'
+        'status',
     ];
     ];
 
 
     protected $casts = [
     protected $casts = [
-        'type_of_transaction' => 'integer',
-        'default_expired' => 'integer',
-        'expired_day' => 'integer',
-        'status' => 'integer'
+        'default_expired' => 'boolean',
+        'status' => 'boolean',
+        'enable_different_points_by_group' => 'boolean',
     ];
     ];
 
 
-    const TYPE_ORDER = 1;
-    const TYPE_REGISTRATION = 2;
-    const TYPE_REVIEW = 3;
-    const TYPE_SIGN_IN = 4;
-    const TYPE_REFERRAL = 5;
-    const TYPE_BIRTHDAY = 6;
-}
+    /**
+     * 获取客户群组积分设置
+     */
+    public function getCustomerGroupPointsAttribute()
+    {
+        if ($this->enable_different_points_by_group) {
+            $groupPoints = json_decode($this->customer_group_ids, true);
+            return is_array($groupPoints) ? $groupPoints : [];
+        }
+        return [];
+    }
+
+    /**
+     * 设置客户群组积分设置
+     */
+    public function setCustomerGroupPointsAttribute($value)
+    {
+        if ($this->enable_different_points_by_group) {
+            $this->attributes['customer_group_ids'] = json_encode($value);
+        }
+    }
+
+    /**
+     * 获取特定客户群组的积分值
+     */
+    public function getRewardPointForCustomerGroup($customerGroupId)
+    {
+        if ($this->enable_different_points_by_group) {
+            $groupPoints = $this->getCustomerGroupPointsAttribute();
+            return isset($groupPoints[$customerGroupId]) ? (int)$groupPoints[$customerGroupId] : 0;
+        }
+
+        // 如果不启用不同群组不同积分,则返回统一的积分值
+        return (int)$this->reward_point;
+    }
+}

+ 0 - 111
packages/Longyi/RewardPoints/src/Repositories/RewardPointSettingRepository.php

@@ -166,117 +166,6 @@ class RewardPointSettingRepository extends Repository
                 'sort_order' => 4,
                 'sort_order' => 4,
                 'description' => '最低可使用的积分数量'
                 'description' => '最低可使用的积分数量'
             ],
             ],
-            
-            // 签到设置
-            [
-                'code' => 'signin_base_points',
-                'name' => '基础签到积分',
-                'value' => '10',
-                'type' => 'number',
-                'group' => 'signin',
-                'sort_order' => 1,
-                'description' => '每日签到的基础积分'
-            ],
-            [
-                'code' => 'signin_week_bonus',
-                'name' => '周奖励积分',
-                'value' => '20',
-                'type' => 'number',
-                'group' => 'signin',
-                'sort_order' => 2,
-                'description' => '连续签到 7 天的额外奖励积分'
-            ],
-            [
-                'code' => 'signin_month_bonus',
-                'name' => '月奖励积分',
-                'value' => '100',
-                'type' => 'number',
-                'group' => 'signin',
-                'sort_order' => 3,
-                'description' => '连续签到 30 天的额外奖励积分'
-            ],
-            
-            // 订单设置
-            [
-                'code' => 'order_points_per_currency',
-                'name' => '每元获得积分',
-                'value' => '10',
-                'type' => 'number',
-                'group' => 'order',
-                'sort_order' => 1,
-                'description' => '每消费 1 元获得的积分数量'
-            ],
-            [
-                'code' => 'order_min_amount',
-                'name' => '最低订单金额',
-                'value' => '0',
-                'type' => 'number',
-                'group' => 'order',
-                'sort_order' => 2,
-                'description' => '获得积分的最低订单金额要求'
-            ],
-            
-            // 注册设置
-            [
-                'code' => 'registration_points',
-                'name' => '注册赠送积分',
-                'value' => '100',
-                'type' => 'number',
-                'group' => 'registration',
-                'sort_order' => 1,
-                'description' => '新客户注册赠送的积分'
-            ],
-            
-            // 评价设置
-            [
-                'code' => 'review_points',
-                'name' => '评价赠送积分',
-                'value' => '50',
-                'type' => 'number',
-                'group' => 'review',
-                'sort_order' => 1,
-                'description' => '发表商品评价获得的积分'
-            ],
-            [
-                'code' => 'review_require_approval',
-                'name' => '评价需要审核',
-                'value' => '1',
-                'type' => 'boolean',
-                'group' => 'review',
-                'sort_order' => 2,
-                'description' => '是否需要审核通过后才给积分'
-            ],
-            
-            // 推荐设置
-            [
-                'code' => 'referral_points',
-                'name' => '推荐好友积分',
-                'value' => '200',
-                'type' => 'number',
-                'group' => 'referral',
-                'sort_order' => 1,
-                'description' => '成功推荐好友获得的积分'
-            ],
-            [
-                'code' => 'referral_require_order',
-                'name' => '需要首单',
-                'value' => '1',
-                'type' => 'boolean',
-                'group' => 'referral',
-                'sort_order' => 2,
-                'description' => '是否需要好友完成首单才给积分'
-            ],
-            
-            // 生日设置
-            [
-                'code' => 'birthday_points',
-                'name' => '生日赠送积分',
-                'value' => '500',
-                'type' => 'number',
-                'group' => 'birthday',
-                'sort_order' => 1,
-                'description' => '客户生日赠送的积分'
-            ],
         ];
         ];
     }
     }
 }
 }

+ 156 - 0
packages/Longyi/RewardPoints/src/Resources/views/admin/customers/index.blade.php

@@ -0,0 +1,156 @@
+<x-admin::layouts>
+    <x-slot:title>
+        @lang('rewardpoints::admin.customers')
+    </x-slot:title>
+
+    {{-- 页面标题和操作按钮 --}}
+    <div class="flex flex-wrap gap-4 justify-between items-center mb-6">
+        <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')
+            </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')
+            </span>
+        </div>
+
+        <div class="flex gap-x-2.5 items-center">
+            <a 
+                href="{{ route('admin.reward-points.customers.export') }}" 
+                class="secondary-button flex items-center gap-2"
+            >
+                <span class="icon-download text-lg"></span>
+                @lang('rewardpoints::admin.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 items-center justify-between">
+                <div>
+                    <p class="text-sm text-gray-600 dark:text-gray-400 mb-1">
+                        @lang('rewardpoints::admin.total-customers')
+                    </p>
+                    <p class="text-3xl font-bold text-blue-600 dark:text-blue-400">
+                        {{ $totalCustomers }}
+                    </p>
+                </div>
+                <div class="w-12 h-12 bg-blue-100 dark:bg-blue-900/50 rounded-full flex items-center justify-center">
+                    <span class="icon-users text-2xl text-blue-600 dark:text-blue-400"></span>
+                </div>
+            </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 items-center justify-between">
+                <div>
+                    <p class="text-sm text-gray-600 dark:text-gray-400 mb-1">
+                        @lang('rewardpoints::admin.total-points')
+                    </p>
+                    <p class="text-3xl font-bold text-green-600 dark:text-green-400">
+                        {{ number_format($totalPoints) }}
+                    </p>
+                </div>
+                <div class="w-12 h-12 bg-green-100 dark:bg-green-900/50 rounded-full flex items-center justify-center">
+                    <span class="icon-star text-2xl text-green-600 dark:text-green-400"></span>
+                </div>
+            </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 items-center justify-between">
+                <div>
+                    <p class="text-sm text-gray-600 dark:text-gray-400 mb-1">
+                        @lang('rewardpoints::admin.average-points')
+                    </p>
+                    <p class="text-3xl font-bold text-purple-600 dark:text-purple-400">
+                        {{ number_format(round($averagePoints, 2), 2) }}
+                    </p>
+                </div>
+                <div class="w-12 h-12 bg-purple-100 dark:bg-purple-900/50 rounded-full flex items-center justify-center">
+                    <span class="icon-chart-line text-2xl text-purple-600 dark:text-purple-400"></span>
+                </div>
+            </div>
+        </div>
+    </div>
+
+    {{-- 表格头部 --}}
+    <div class="bg-white dark:bg-gray-900 rounded-lg shadow-sm border border-gray-200 dark:border-gray-800 overflow-hidden">
+        <div class="overflow-x-auto">
+            <table class="min-w-full divide-y divide-gray-200 dark:divide-gray-800">
+                <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')
+                        </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')
+                        </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')
+                        </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')
+                        </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')
+                        </th>
+                    </tr>
+                </thead>
+                <tbody class="bg-white dark:bg-gray-900 divide-y divide-gray-200 dark:divide-gray-800">
+                    @forelse($customers as $customer)
+                        <tr class="hover:bg-gray-50 dark:hover:bg-gray-800 transition-colors">
+                            <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900 dark:text-gray-300">
+                                #{{ $customer->customer_id }}
+                            </td>
+                            <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900 dark:text-gray-300">
+                                {{ $customer->customer->first_name ?? 'N/A' }} {{ $customer->customer->last_name ?? '' }}
+                            </td>
+                            <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-600 dark:text-gray-400">
+                                {{ $customer->customer->email ?? 'N/A' }}
+                            </td>
+                            <td class="px-6 py-4 whitespace-nowrap">
+                                <div class="flex items-center gap-1">
+                                    <span class="text-xl font-bold text-yellow-600 dark:text-yellow-500">
+                                        {{ number_format($customer->mw_reward_point) }}
+                                    </span>
+                                    <span class="text-xs text-gray-500">pts</span>
+                                </div>
+                            </td>
+                            <td class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
+                                <a 
+                                    href="{{ route('admin.reward-points.customers.show', $customer->customer_id) }}" 
+                                    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>
+                                </a>
+                            </td>
+                        </tr>
+                    @empty
+                        <tr>
+                            <td colspan="5" class="px-6 py-12 text-center">
+                                <div class="flex flex-col items-center gap-4">
+                                    <div class="w-20 h-20 bg-gray-100 dark:bg-gray-800 rounded-full flex items-center justify-center">
+                                        <span class="icon-users text-4xl text-gray-400"></span>
+                                    </div>
+                                    <div>
+                                        <p class="text-lg font-medium text-gray-600 dark:text-gray-400 mb-1">
+                                            @lang('No customers found')
+                                        </p>
+                                        <p class="text-sm text-gray-500 dark:text-gray-500">
+                                            @lang('No reward points records available')
+                                        </p>
+                                    </div>
+                                </div>
+                            </td>
+                        </tr>
+                    @endforelse
+                </tbody>
+            </table>
+        </div>
+    </div>
+</x-admin::layouts>

+ 121 - 0
packages/Longyi/RewardPoints/src/Resources/views/admin/customers/show.blade.php

@@ -0,0 +1,121 @@
+@extends('admin::layouts.content')
+
+@section('page_title')
+    {{ __('rewardpoints::app.admin.customers.details-title', ['name' => $customer->first_name . ' ' . $customer->last_name]) }}
+@stop
+
+@section('content')
+    <div class="content">
+        <div class="page-header">
+            <div class="page-title">
+                <h1>{{ $customer->first_name . ' ' . $customer->last_name }}</h1>
+            </div>
+        </div>
+
+        <div class="page-content">
+            <accordian :title="'{{ __('rewardpoints::app.admin.customers.customer-info') }}'" :active="true">
+                <div slot="body">
+                    <div class="form-container">
+                        <div class="control-group">
+                            <label>{{ __('rewardpoints::app.admin.customers.name') }}</label>
+                            <input type="text" class="control" value="{{ $customer->first_name . ' ' . $customer->last_name }}" readonly>
+                        </div>
+
+                        <div class="control-group">
+                            <label>{{ __('rewardpoints::app.admin.customers.email') }}</label>
+                            <input type="text" class="control" value="{{ $customer->email }}" readonly>
+                        </div>
+
+                        <div class="control-group">
+                            <label>{{ __('rewardpoints::app.admin.customers.reward-points') }}</label>
+                            <input type="text" class="control" value="{{ $rewardData->mw_reward_point }}" readonly>
+                        </div>
+                    </div>
+                </div>
+            </accordian>
+
+            <accordian :title="'{{ __('rewardpoints::app.admin.customers.points-history') }}'" :active="true">
+                <div slot="body">
+                    <div class="table">
+                        <table>
+                            <thead>
+                                <tr>
+                                    <th>{{ __('rewardpoints::app.admin.customers.type') }}</th>
+                                    <th>{{ __('rewardpoints::app.admin.customers.amount') }}</th>
+                                    <th>{{ __('rewardpoints::app.admin.customers.balance') }}</th>
+                                    <th>{{ __('rewardpoints::app.admin.customers.date') }}</th>
+                                    <th>{{ __('rewardpoints::app.admin.customers.description') }}</th>
+                                </tr>
+                            </thead>
+                            <tbody>
+                                @foreach ($history as $record)
+                                <tr>
+                                    <td>{{ $record->type_of_transaction }}</td>
+                                    <td>{{ $record->amount }}</td>
+                                    <td>{{ $record->balance }}</td>
+                                    <td>{{ $record->transaction_time }}</td>
+                                    <td>{{ $record->transaction_detail }}</td>
+                                </tr>
+                                @endforeach
+                            </tbody>
+                        </table>
+                    </div>
+                </div>
+            </accordian>
+
+            <accordian :title="'{{ __('rewardpoints::app.admin.customers.adjust-points') }}'" :active="false">
+                <div slot="body">
+                    <form method="POST" action="{{ route('admin.reward-points.customers.add-points') }}">
+                        @csrf
+                        <input type="hidden" name="customer_id" value="{{ $customer->id }}">
+
+                        <div class="form-container">
+                            <div class="control-group">
+                                <label for="points">{{ __('rewardpoints::app.admin.customers.points') }}</label>
+                                <input type="number" class="control" id="points" name="points" required>
+                            </div>
+
+                            <div class="control-group">
+                                <label for="type">{{ __('rewardpoints::app.admin.customers.type') }}</label>
+                                <select class="control" id="type" name="type" required>
+                                    <option value="1">{{ __('rewardpoints::app.admin.transactions.order') }}</option>
+                                    <option value="2">{{ __('rewardpoints::app.admin.transactions.registration') }}</option>
+                                    <option value="3">{{ __('rewardpoints::app.admin.transactions.review') }}</option>
+                                    <option value="4">{{ __('rewardpoints::app.admin.transactions.sign-in') }}</option>
+                                    <option value="5">{{ __('rewardpoints::app.admin.transactions.referral') }}</option>
+                                    <option value="6">{{ __('rewardpoints::app.admin.transactions.birthday') }}</option>
+                                </select>
+                            </div>
+
+                            <div class="control-group">
+                                <label for="reason">{{ __('rewardpoints::app.admin.customers.reason') }}</label>
+                                <input type="text" class="control" id="reason" name="reason">
+                            </div>
+
+                            <button type="submit" class="btn btn-md btn-primary">{{ __('rewardpoints::app.admin.customers.add-points') }}</button>
+                        </div>
+                    </form>
+
+                    <form method="POST" action="{{ route('admin.reward-points.customers.deduct-points') }}" style="margin-top: 20px;">
+                        @csrf
+                        <input type="hidden" name="customer_id" value="{{ $customer->id }}">
+
+                        <div class="form-container">
+                            <div class="control-group">
+                                <label for="deduct_points">{{ __('rewardpoints::app.admin.customers.points') }}</label>
+                                <input type="number" class="control" id="deduct_points" name="points" required>
+                            </div>
+
+                            <div class="control-group">
+                                <label for="deduct_reason">{{ __('rewardpoints::app.admin.customers.reason') }}</label>
+                                <input type="text" class="control" id="deduct_reason" name="reason">
+                            </div>
+
+                            <button type="submit" class="btn btn-md btn-danger">{{ __('rewardpoints::app.admin.customers.deduct-points') }}</button>
+                        </div>
+                    </form>
+                </div>
+            </accordian>
+        </div>
+    </div>
+@endsection

+ 291 - 98
packages/Longyi/RewardPoints/src/Resources/views/admin/rules/create.blade.php

@@ -1,111 +1,304 @@
-@extends('admin::layouts.master')
+<x-admin::layouts>
+    <x-slot:title>
+        @lang('Create Reward Rule')
+    </x-slot>
 
 
-@section('page_title')
-    Create Reward Rule
-@stop
-
-@section('content-wrapper')
-    <div class="content full-page">
-        <div class="page-header">
-            <div class="page-title">
-                <h1>Create Reward Rule</h1>
-            </div>
-            <div class="page-action">
-                <a href="{{ route('admin.reward-points.rules.index') }}" class="btn btn-lg btn-primary">
-                    Back
-                </a>
-            </div>
-        </div>
-
-        <div class="page-content">
-            <form method="POST" action="{{ route('admin.reward-points.rules.store') }}">
-                @csrf
-
-                <div class="form-group">
-                    <label>Rule Name *</label>
-                    <input type="text" name="rule_name" class="form-control" required>
-                    @error('rule_name')
-                    <span class="text-danger">{{ $message }}</span>
-                    @enderror
-                </div>
+    <div class="flex gap-4 justify-between items-center mb-4">
+        <p class="text-xl text-gray-800 dark:text-white font-bold">
+            @lang('Create Reward Rule')
+        </p>
+    </div>
 
 
-                <div class="form-group">
-                    <label>Transaction Type *</label>
-                    <select name="type_of_transaction" class="form-control" required>
-                        <option value="">Select Type</option>
-                        @foreach($transactionTypes as $key => $value)
-                            <option value="{{ $key }}">{{ $value }}</option>
-                        @endforeach
-                    </select>
-                    @error('type_of_transaction')
-                    <span class="text-danger">{{ $message }}</span>
-                    @enderror
-                </div>
+    <div class="flex gap-2.5 mt-3.5">
+        <div class="flex flex-col gap-2 flex-1 max-xl:flex-auto">
+            <div class="p-4 bg-white dark:bg-gray-900 rounded box-shadow">
+                <form method="POST" action="{{ route('admin.reward-points.rules.store') }}" id="ruleForm">
+                    @csrf
 
 
-                <div class="form-group">
-                    <label>Store View</label>
-                    <select name="store_view[]" class="form-control" multiple>
-                        @foreach($storeViews as $key => $value)
-                            <option value="{{ $key }}">{{ $value }}</option>
-                        @endforeach
-                    </select>
-                    <small class="form-text text-muted">Leave empty for all stores</small>
-                </div>
+                    <div class="grid grid-cols-2 gap-2.5">
+                        <div class="mb-2.5">
+                            <label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1 required">
+                                @lang('Rule Name')
+                            </label>
+                            <input
+                                type="text"
+                                name="rule_name"
+                                value="{{ old('rule_name') }}"
+                                class="flex w-full min-h-[39px] py-2 px-3 border border-gray-300 dark:border-gray-800 rounded-md text-sm text-gray-600 dark:text-gray-300 transition-all hover:border-gray-400 dark:hover:border-gray-400 focus:border-gray-400 dark:focus:border-gray-400"
+                                required
+                                placeholder="@lang('E.g.: Sign-In Points')"
+                            >
+                            @error('rule_name')
+                                <p class="mt-1 text-xs text-red-600">
+                                    {{ $message }}
+                                </p>
+                            @enderror
+                        </div>
+                        
+                        <div class="mb-2.5">
+                            <label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1 required">
+                                @lang('Transaction Type')
+                            </label>
+                            <select
+                                name="type_of_transaction"
+                                id="transactionType"
+                                class="flex w-full min-h-[39px] py-2 px-3 border border-gray-300 dark:border-gray-800 rounded-md text-sm text-gray-600 dark:text-gray-300 transition-all hover:border-gray-400 dark:hover:border-gray-400 focus:border-gray-400 dark:focus:border-gray-400"
+                                required
+                            >
+                                <option value="">@lang('Select Type')</option>
+                                @foreach($transactionTypes as $key => $value)
+                                    <option value="{{ $key }}" {{ old('type_of_transaction') == $key ? 'selected' : '' }}>
+                                        @lang($value)
+                                    </option>
+                                @endforeach
+                            </select>
+                            @error('type_of_transaction')
+                                <p class="mt-1 text-xs text-red-600">
+                                    {{ $message }}
+                                </p>
+                            @enderror
+                        </div>
+                         
+                    </div>
 
 
-                <div class="form-group">
-                    <label>Customer Groups</label>
-                    <select name="customer_group_ids[]" class="form-control" multiple>
-                        @foreach($customerGroups as $key => $value)
-                            <option value="{{ $key }}">{{ $value }}</option>
-                        @endforeach
-                    </select>
-                    <small class="form-text text-muted">Leave empty for all customer groups</small>
-                </div>
+                    <div class="mb-2.5">
+                        <label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
+                            @lang('Store View')
+                        </label>
+                        <select
+                            name="store_view[]"
+                            class="flex w-full min-h-[39px] py-2 px-3 border border-gray-300 dark:border-gray-800 rounded-md text-sm text-gray-600 dark:text-gray-300 transition-all hover:border-gray-400 dark:hover:border-gray-400 focus:border-gray-400 dark:focus:border-gray-400"
+                            multiple
+                        >
+                            @foreach($storeViews as $key => $value)
+                                <option value="{{ $key }}" {{ in_array($key, old('store_view', [])) ? 'selected' : '' }}>
+                                    {{ $value }}
+                                </option>
+                            @endforeach
+                        </select>
+                        <p class="mt-1 text-xs text-gray-500">
+                            @lang('Leave empty for all stores')
+                        </p>
+                    </div>
 
 
-                <div class="form-group">
-                    <label>Reward Points *</label>
-                    <input type="number" name="reward_point" class="form-control" required min="0">
-                    @error('reward_point')
-                    <span class="text-danger">{{ $message }}</span>
-                    @enderror
-                </div>
+                    <!-- 启用不同群组不同积分的开关 -->
+                    <div class="mb-2.5">
+                        <label class="flex items-center gap-2">
+                            <input
+                                type="checkbox"
+                                name="enable_different_points_by_group"
+                                id="enableDifferentPointsByGroup"
+                                value="1"
+                                class="rounded-md border-gray-300 text-blue-600 shadow-sm focus:border-blue-300 focus:ring focus:ring-blue-200 focus:ring-opacity-50"
+                                {{ old('enable_different_points_by_group') ? 'checked' : '' }}
+                            >
+                            <span class="text-sm font-medium text-gray-700 dark:text-gray-300">
+                                @lang('Enable different points for different customer groups')
+                            </span>
+                        </label>
+                    </div>
 
 
-                <div class="form-group">
-                    <label>Status</label>
-                    <select name="status" class="form-control">
-                        <option value="1">Active</option>
-                        <option value="0">Inactive</option>
-                    </select>
-                </div>
+                    <!-- 统一积分设置部分 -->
+                    <div id="uniformPointsSection" style="{{ old('enable_different_points_by_group') ? 'display: none;' : '' }}">
+                        <div class="mb-2.5">
+                            <label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
+                                @lang('Customer Groups')
+                            </label>
+                            <select
+                                name="customer_group_ids[]"
+                                id="customerGroups"
+                                class="flex w-full min-h-[39px] py-2 px-3 border border-gray-300 dark:border-gray-800 rounded-md text-sm text-gray-600 dark:text-gray-300 transition-all hover:border-gray-400 dark:hover:border-gray-400 focus:border-gray-400 dark:focus:border-gray-400"
+                                multiple
+                            >
+                                @foreach($customerGroups as $key => $value)
+                                    <option value="{{ $key }}" {{ in_array($key, old('customer_group_ids', [])) ? 'selected' : '' }}>
+                                        {{ $value }}
+                                    </option>
+                                @endforeach
+                            </select>
+                        </div>
 
 
-                <div class="form-group">
-                    <label>Default Expired</label>
-                    <select name="default_expired" class="form-control">
-                        <option value="1">Yes</option>
-                        <option value="0">No</option>
-                    </select>
-                </div>
+                        <div class="grid grid-cols-2 gap-2.5">
+                            <div class="mb-2.5">
+                                <label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1 required">
+                                    @lang('Reward Points')
+                                </label>
+                                <input
+                                    type="number"
+                                    name="reward_point"
+                                    id="rewardPoints"
+                                    value="{{ old('reward_point', 0) }}"
+                                    class="flex w-full min-h-[39px] py-2 px-3 border border-gray-300 dark:border-gray-800 rounded-md text-sm text-gray-600 dark:text-gray-300 transition-all hover:border-gray-400 dark:hover:border-gray-400 focus:border-gray-400 dark:focus:border-gray-400"
+                                    required
+                                    min="0"
+                                >
+                                @error('reward_point')
+                                    <p class="mt-1 text-xs text-red-600">
+                                        {{ $message }}
+                                    </p>
+                                @enderror
+                            </div>
+                        </div>
+                    </div>
 
 
-                <div class="form-group">
-                    <label>Expired Day</label>
-                    <input type="number" name="expired_day" class="form-control" value="0">
-                    <small class="form-text text-muted">0 means never expires</small>
-                </div>
+                    <!-- 客户群组特定积分设置部分 -->
+                    <div id="groupSpecificPointsSection" style="{{ !old('enable_different_points_by_group') ? 'display: none;' : '' }}">
+                        <div class="mb-2.5">
+                            <label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
+                                @lang('Customer Group Specific Points')
+                            </label>
+                            <p class="mt-1 text-xs text-gray-500">
+                                @lang('Set different points for each customer group')
+                            </p>
+                            
+                            <div class="mt-2 space-y-3">
+                                @foreach($customerGroups as $key => $value)
+                                    <div class="flex items-center gap-2">
+                                        <label class="w-32 text-sm text-gray-600 dark:text-gray-300">
+                                            {{ $value }}:
+                                        </label>
+                                        <input
+                                            type="number"
+                                            name="group_points[{{ $key }}]"
+                                            value="{{ old("group_points.{$key}", 0) }}"
+                                            class="flex w-32 min-h-[39px] py-2 px-3 border border-gray-300 dark:border-gray-800 rounded-md text-sm text-gray-600 dark:text-gray-300 transition-all hover:border-gray-400 dark:hover:border-gray-400 focus:border-gray-400 dark:focus:border-gray-400"
+                                            min="0"
+                                            placeholder="0"
+                                        >
+                                    </div>
+                                @endforeach
+                            </div>
+                        </div>
+                    </div>
 
 
-                <div class="form-group">
-                    <label>Coupon Code</label>
-                    <input type="text" name="coupon_code" class="form-control">
-                </div>
+                    <div class="grid grid-cols-2 gap-2.5">
+                        <div class="mb-2.5">
+                            <label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
+                                @lang('Status')
+                            </label>
+                            <select
+                                name="status"
+                                class="flex w-full min-h-[39px] py-2 px-3 border border-gray-300 dark:border-gray-800 rounded-md text-sm text-gray-600 dark:text-gray-300 transition-all hover:border-gray-400 dark:hover:border-gray-400 focus:border-gray-400 dark:focus:border-gray-400"
+                            >
+                                <option value="1" {{ old('status', 1) == 1 ? 'selected' : '' }}>@lang('Active')</option>
+                                <option value="0" {{ old('status', 1) == 0 ? 'selected' : '' }}>@lang('Inactive')</option>
+                            </select>
+                        </div>
+                    </div>
 
 
-                <div class="form-group">
-                    <label>Comment</label>
-                    <textarea name="comment" class="form-control" rows="3"></textarea>
-                </div>
+                    <div class="grid grid-cols-2 gap-2.5">
+                        <!--
+                        <div class="mb-2.5">
+                            <label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
+                                @lang('Default Expired')
+                            </label>
+                            <select
+                                name="default_expired"
+                                class="flex w-full min-h-[39px] py-2 px-3 border border-gray-300 dark:border-gray-800 rounded-md text-sm text-gray-600 dark:text-gray-300 transition-all hover:border-gray-400 dark:hover:border-gray-400 focus:border-gray-400 dark:focus:border-gray-400"
+                            >
+                                <option value="1" {{ old('default_expired', 0) == 1 ? 'selected' : '' }}>@lang('Yes')</option>
+                                <option value="0" {{ old('default_expired', 0) == 0 ? 'selected' : '' }}>@lang('No')</option>
+                            </select>
+                        </div>
+                        -->
+                        <div class="mb-2.5">
+                            <label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
+                                @lang('Expired Day')
+                            </label>
+                            <input
+                                type="number"
+                                name="expired_day"
+                                value="{{ old('expired_day', 0) }}"
+                                class="flex w-full min-h-[39px] py-2 px-3 border border-gray-300 dark:border-gray-800 rounded-md text-sm text-gray-600 dark:text-gray-300 transition-all hover:border-gray-400 dark:hover:border-gray-400 focus:border-gray-400 dark:focus:border-gray-400"
+                                min="0"
+                            >
+                            <p class="mt-1 text-xs text-gray-500">
+                                @lang('0 means never expires')
+                            </p>
+                        </div>
+                    </div>
+    
+                    <!--
+                    <div class="mb-2.5">
+                        <label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
+                            @lang('Coupon Code')
+                        </label>
+                        <input
+                            type="text"
+                            name="coupon_code"
+                            value="{{ old('coupon_code') }}"
+                            class="flex w-full min-h-[39px] py-2 px-3 border border-gray-300 dark:border-gray-800 rounded-md text-sm text-gray-600 dark:text-gray-300 transition-all hover:border-gray-400 dark:hover:border-gray-400 focus:border-gray-400 dark:focus:border-gray-400"
+                        >
+                    </div>
+                    -->
+                    <div class="mb-2.5">
+                        <label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
+                            @lang('Comment')
+                        </label>
+                        <textarea
+                            name="comment"
+                            rows="3"
+                            class="flex w-full min-h-[39px] py-2 px-3 border border-gray-300 dark:border-gray-800 rounded-md text-sm text-gray-600 dark:text-gray-300 transition-all hover:border-gray-400 dark:hover:border-gray-400 focus:border-gray-400 dark:focus:border-gray-400"
+                        >{{ old('comment') }}</textarea>
+                    </div>
 
 
-                <div class="form-group">
-                    <button type="submit" class="btn btn-lg btn-primary">Create Rule</button>
-                </div>
-            </form>
+                    <div class="flex gap-2.5 items-center">
+                        <button 
+                            type="submit"
+                            class="primary-button"
+                        >
+                            @lang('Create Rule')
+                        </button>
+                        <a href="{{ route('admin.reward-points.rules.index') }}" class="secondary-button">
+                            @lang('Back')
+                        </a>
+                    </div>
+                </form>
+            </div>
         </div>
         </div>
     </div>
     </div>
-@stop
+
+    <style>
+    /* 确保隐藏样式生效 */
+    .hidden {
+        display: none !important;
+    }
+    </style>
+
+   <script>
+    (function() {
+        // 定义更新显示的函数
+        function updateSectionsVisibility() {
+            const checkbox = document.getElementById('enableDifferentPointsByGroup');
+            const uniformSection = document.getElementById('uniformPointsSection');
+            const groupSection = document.getElementById('groupSpecificPointsSection');
+            
+            if (!checkbox || !uniformSection || !groupSection) {
+                return;
+            }
+            
+            if (checkbox.checked) {
+                uniformSection.style.display = 'none';
+                groupSection.style.display = 'block';
+            } else {
+                uniformSection.style.display = 'block';
+                groupSection.style.display = 'none';
+            }
+        }
+        
+        // 使用事件委托捕获所有 change 事件
+        document.body.addEventListener('change', function(e) {
+            if (e.target && e.target.id === 'enableDifferentPointsByGroup') {
+                updateSectionsVisibility();
+            }
+        });
+        
+        // DOM 加载完成后初始化显示状态
+        if (document.readyState === 'loading') {
+            document.addEventListener('DOMContentLoaded', updateSectionsVisibility);
+        } else {
+            updateSectionsVisibility();
+        }
+    })();
+    </script>
+</x-admin::layouts>

+ 320 - 0
packages/Longyi/RewardPoints/src/Resources/views/admin/rules/edit.blade.php

@@ -0,0 +1,320 @@
+<x-admin::layouts>
+    <x-slot:title>
+        @lang('Edit Reward Rule')
+    </x-slot>
+
+    <div class="flex gap-4 justify-between items-center mb-4">
+        <p class="text-xl text-gray-800 dark:text-white font-bold">
+            @lang('Edit Reward Rule')
+        </p>
+    </div>
+
+    <div class="flex gap-2.5 mt-3.5">
+        <div class="flex flex-col gap-2 flex-1 max-xl:flex-auto">
+            <div class="p-6 bg-white dark:bg-gray-900 rounded-lg shadow-sm border border-gray-200 dark:border-gray-800">
+                <form method="POST" action="{{ route('admin.reward-points.rules.update', $rule->rule_id) }}" id="ruleForm">
+                    @csrf
+                    @method('PUT')
+
+                    {{-- 基本信息 --}}
+                    <div class="mb-6 pb-6 border-b border-gray-200 dark:border-gray-800">
+                        <h3 class="text-lg font-semibold text-gray-800 dark:text-white mb-4">
+                            @lang('Basic Information')
+                        </h3>
+                        
+                        <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
+                            <div class="mb-2.5">
+                                <label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1 required">
+                                    @lang('Rule Name')
+                                </label>
+                                <input
+                                    type="text"
+                                    name="rule_name"
+                                    value="{{ old('rule_name', $rule->rule_name) }}"
+                                    class="flex w-full min-h-[39px] py-2 px-3 border border-gray-300 dark:border-gray-700 rounded-lg text-sm text-gray-600 dark:text-gray-300 transition-all hover:border-gray-400 dark:hover:border-gray-600 focus:border-blue-500 focus:ring-2 focus:ring-blue-200 dark:focus:ring-blue-800"
+                                    required
+                                    placeholder="@lang('E.g.: Sign-In Points')"
+                                >
+                                @error('rule_name')
+                                    <p class="mt-1 text-xs text-red-600">
+                                        {{ $message }}
+                                    </p>
+                                @enderror
+                            </div>
+                        <div class="mb-2.5">
+                                <label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1 required">
+                                    @lang('Transaction Type')
+                                </label>
+                                <select
+                                    name="type_of_transaction"
+                                    id="transactionType"
+                                    class="flex w-full min-h-[39px] py-2 px-3 border border-gray-300 dark:border-gray-800 rounded-md text-sm text-gray-600 dark:text-gray-300 transition-all hover:border-gray-400 dark:hover:border-gray-400 focus:border-gray-400 dark:focus:border-gray-400"
+                                    required
+                                >
+                                    <option value="">@lang('Select Type')</option>
+                                    @foreach($transactionTypes as $key => $value)
+                                        <option value="{{ $key }}" {{ old('type_of_transaction', $rule->type_of_transaction) == $key ? 'selected' : '' }}>
+                                            @lang($value)
+                                        </option>
+                                    @endforeach
+                                </select>
+                                @error('type_of_transaction')
+                                    <p class="mt-1 text-xs text-red-600">
+                                        {{ $message }}
+                                    </p>
+                                @enderror
+                            </div>
+                            <div class="mb-2.5">
+                                <label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1 required">
+                                    @lang('Status')
+                                </label>
+                                <select
+                                    name="status"
+                                    class="flex w-full min-h-[39px] py-2 px-3 border border-gray-300 dark:border-gray-700 rounded-lg text-sm text-gray-600 dark:text-gray-300 transition-all hover:border-gray-400 dark:hover:border-gray-600 focus:border-blue-500 focus:ring-2 focus:ring-blue-200 dark:focus:ring-blue-800"
+                                >
+                                    <option value="1" {{ old('status', $rule->status) == 1 ? 'selected' : '' }}>
+                                        @lang('Active')
+                                    </option>
+                                    <option value="0" {{ old('status', $rule->status) == 0 ? 'selected' : '' }}>
+                                        @lang('Inactive')
+                                    </option>
+                                </select>
+                            </div>
+                        </div>
+
+                        <div class="mb-2.5">
+                            <label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
+                                @lang('Store View')
+                            </label>
+                            <select
+                                name="store_view[]"
+                                class="flex w-full min-h-[39px] py-2 px-3 border border-gray-300 dark:border-gray-700 rounded-lg text-sm text-gray-600 dark:text-gray-300 transition-all hover:border-gray-400 dark:hover:border-gray-600 focus:border-blue-500 focus:ring-2 focus:ring-blue-200 dark:focus:ring-blue-800"
+                                multiple
+                            >
+                                @foreach($storeViews as $key => $value)
+                                    <option value="{{ $key }}" {{ in_array($key, old('store_view', $selectedStoreViews)) ? 'selected' : '' }}>
+                                        {{ $value }}
+                                    </option>
+                                @endforeach
+                            </select>
+                            <p class="mt-1 text-xs text-gray-500">
+                                @lang('Leave empty for all stores')
+                            </p>
+                        </div>
+                    </div>
+
+                    {{-- 积分设置 --}}
+                    <div class="mb-6 pb-6 border-b border-gray-200 dark:border-gray-800">
+                        <h3 class="text-lg font-semibold text-gray-800 dark:text-white mb-4">
+                            @lang('Points Configuration')
+                        </h3>
+
+                        {{-- 启用不同群组不同积分的开关 --}}
+                        <div class="mb-4">
+                            <label class="flex items-center gap-2 cursor-pointer">
+                                <input
+                                    type="checkbox"
+                                    name="enable_different_points_by_group"
+                                    id="enableDifferentPointsByGroup"
+                                    value="1"
+                                    class="rounded border-gray-300 text-blue-600 shadow-sm focus:border-blue-300 focus:ring focus:ring-blue-200 focus:ring-opacity-50"
+                                    {{ old('enable_different_points_by_group', $rule->enable_different_points_by_group) ? 'checked' : '' }}
+                                >
+                                <span class="text-sm font-medium text-gray-700 dark:text-gray-300">
+                                    @lang('Enable different points for different customer groups')
+                                </span>
+                            </label>
+                        </div>
+
+                        {{-- 统一积分设置部分 --}}
+                        <div id="uniformPointsSection" style="{{ old('enable_different_points_by_group', $rule->enable_different_points_by_group) ? 'display: none;' : '' }}">
+                            <div class="mb-4">
+                                <label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
+                                    @lang('Customer Groups')
+                                </label>
+                                <select
+                                    name="customer_group_ids[]"
+                                    id="customerGroups"
+                                    class="flex w-full min-h-[39px] py-2 px-3 border border-gray-300 dark:border-gray-700 rounded-lg text-sm text-gray-600 dark:text-gray-300 transition-all hover:border-gray-400 dark:hover:border-gray-600 focus:border-blue-500 focus:ring-2 focus:ring-blue-200 dark:focus:ring-blue-800"
+                                    multiple
+                                >
+                                    @foreach($customerGroups as $key => $value)
+                                        <option value="{{ $key }}" {{ in_array($key, old('customer_group_ids', $selectedCustomerGroups)) ? 'selected' : '' }}>
+                                            {{ $value }}
+                                        </option>
+                                    @endforeach
+                                </select>
+                                <p class="mt-1 text-xs text-gray-500">
+                                    @lang('Select customer groups that can earn these points. Leave empty for all groups.')
+                                </p>
+                            </div>
+
+                            <div class="mb-2.5">
+                                <label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1 required">
+                                    @lang('Reward Points')
+                                </label>
+                                <input
+                                    type="number"
+                                    name="reward_point"
+                                    id="rewardPoints"
+                                    value="{{ old('reward_point', $rule->reward_point) }}"
+                                    class="flex w-full min-h-[39px] py-2 px-3 border border-gray-300 dark:border-gray-700 rounded-lg text-sm text-gray-600 dark:text-gray-300 transition-all hover:border-gray-400 dark:hover:border-gray-600 focus:border-blue-500 focus:ring-2 focus:ring-blue-200 dark:focus:ring-blue-800"
+                                    required
+                                    min="0"
+                                    step="1"
+                                >
+                                <p class="mt-1 text-xs text-gray-500">
+                                    @lang('Number of points to award for this transaction')
+                                </p>
+                                @error('reward_point')
+                                    <p class="mt-1 text-xs text-red-600">
+                                        {{ $message }}
+                                    </p>
+                                @enderror
+                            </div>
+                        </div>
+
+                        {{-- 客户群组特定积分设置部分 --}}
+                        <div id="groupSpecificPointsSection" style="{{ old('enable_different_points_by_group', $rule->enable_different_points_by_group) ? 'display: block;' : 'display: none;' }}">
+                            <div class="mb-2.5">
+                                <label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
+                                    @lang('Customer Group Specific Points')
+                                </label>
+                                <p class="mt-1 text-xs text-gray-500 mb-3">
+                                    @lang('Set different points for each customer group')
+                                </p>
+                                
+                                <div class="bg-gray-50 dark:bg-gray-800 rounded-lg p-4 space-y-3">
+                                    @php
+                                        $groupPointsData = [];
+                                        if ($rule->enable_different_points_by_group) {
+                                            $groupPointsData = json_decode($rule->customer_group_ids, true) ?: [];
+                                        }
+                                    @endphp
+                                    
+                                    @foreach($customerGroups as $key => $value)
+                                        <div class="flex flex-wrap items-center gap-3">
+                                            <label class="w-32 text-sm font-medium text-gray-700 dark:text-gray-300">
+                                                {{ $value }}:
+                                            </label>
+                                            <input
+                                                type="number"
+                                                name="group_points[{{ $key }}]"
+                                                value="{{ old("group_points.{$key}", $groupPointsData[$key] ?? 0) }}"
+                                                class="flex w-40 min-h-[39px] py-2 px-3 border border-gray-300 dark:border-gray-700 rounded-lg text-sm text-gray-600 dark:text-gray-300 transition-all hover:border-gray-400 dark:hover:border-gray-600 focus:border-blue-500 focus:ring-2 focus:ring-blue-200 dark:focus:ring-blue-800"
+                                                min="0"
+                                                step="1"
+                                                placeholder="0"
+                                            >
+                                            <span class="text-xs text-gray-500">@lang('points')</span>
+                                        </div>
+                                    @endforeach
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+
+                    {{-- 过期设置 --}}
+                    <div class="mb-6 pb-6 border-b border-gray-200 dark:border-gray-800">
+                        <h3 class="text-lg font-semibold text-gray-800 dark:text-white mb-4">
+                            @lang('Expiration Settings')
+                        </h3>
+                        
+                        <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
+                        
+                            <div class="mb-2.5">
+                                <label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
+                                    @lang('Expired Day')
+                                </label>
+                                <input
+                                    type="number"
+                                    name="expired_day"
+                                    value="{{ old('expired_day', $rule->expired_day) }}"
+                                    class="flex w-full min-h-[39px] py-2 px-3 border border-gray-300 dark:border-gray-700 rounded-lg text-sm text-gray-600 dark:text-gray-300 transition-all hover:border-gray-400 dark:hover:border-gray-600 focus:border-blue-500 focus:ring-2 focus:ring-blue-200 dark:focus:ring-blue-800"
+                                    min="0"
+                                    step="1"
+                                >
+                                <p class="mt-1 text-xs text-gray-500">
+                                    @lang('Number of days after which points expire. 0 means never expires (if Default Expired is set to No).')
+                                </p>
+                            </div>
+                        </div>
+                    </div>
+
+                    {{-- 其他设置 --}}
+                    <div class="mb-6 pb-6 border-b border-gray-200 dark:border-gray-800">
+                        <h3 class="text-lg font-semibold text-gray-800 dark:text-white mb-4">
+                            @lang('Additional Settings')
+                        </h3>
+                        
+                       
+
+                        <div class="mb-2.5">
+                            <label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
+                                @lang('Comment')
+                            </label>
+                            <textarea
+                                name="comment"
+                                rows="3"
+                                class="flex w-full min-h-[39px] py-2 px-3 border border-gray-300 dark:border-gray-700 rounded-lg text-sm text-gray-600 dark:text-gray-300 transition-all hover:border-gray-400 dark:hover:border-gray-600 focus:border-blue-500 focus:ring-2 focus:ring-blue-200 dark:focus:ring-blue-800"
+                                placeholder="@lang('Optional: Add internal notes or comments about this rule')"
+                            >{{ old('comment', $rule->comment) }}</textarea>
+                        </div>
+                    </div>
+
+                    {{-- 操作按钮 --}}
+                    <div class="flex gap-2.5 items-center justify-end">
+                        <a href="{{ route('admin.reward-points.rules.index') }}" class="px-4 py-2 text-sm font-medium text-gray-700 dark:text-gray-300 bg-gray-100 dark:bg-gray-800 rounded-lg hover:bg-gray-200 dark:hover:bg-gray-700 transition-colors">
+                            @lang('Cancel')
+                        </a>
+                        <button type="submit" class="px-4 py-2 text-sm font-medium text-white bg-blue-600 rounded-lg hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 transition-colors">
+                            <span class="icon-save text-sm mr-1"></span>
+                            @lang('Update Rule')
+                        </button>
+                    </div>
+                </form>
+            </div>
+        </div>
+    </div>
+
+    <script>
+    /**
+     * 动态切换积分规则设置区域
+     * 根据"启用不同群组不同积分"开关的状态,显示/隐藏对应的设置表单
+     */
+    (function() {
+        // 定义更新显示的函数
+        function updateSectionsVisibility() {
+            const checkbox = document.getElementById('enableDifferentPointsByGroup');
+            const uniformSection = document.getElementById('uniformPointsSection');
+            const groupSection = document.getElementById('groupSpecificPointsSection');
+            
+            if (!checkbox || !uniformSection || !groupSection) {
+                return;
+            }
+            
+            if (checkbox.checked) {
+                uniformSection.style.display = 'none';
+                groupSection.style.display = 'block';
+            } else {
+                uniformSection.style.display = 'block';
+                groupSection.style.display = 'none';
+            }
+        }
+        
+        // 使用事件委托捕获所有 change 事件
+        document.body.addEventListener('change', function(e) {
+            if (e.target && e.target.id === 'enableDifferentPointsByGroup') {
+                updateSectionsVisibility();
+            }
+        });
+        
+        // DOM 加载完成后初始化显示状态
+        if (document.readyState === 'loading') {
+            document.addEventListener('DOMContentLoaded', updateSectionsVisibility);
+        } else {
+            updateSectionsVisibility();
+        }
+    })();
+    </script>
+</x-admin::layouts>

+ 486 - 61
packages/Longyi/RewardPoints/src/Resources/views/admin/rules/index.blade.php

@@ -1,74 +1,499 @@
-@extends('admin::layouts.master')
+<x-admin::layouts>
+    <x-slot:title>
+        @lang('Reward Rules')
+    </x-slot>
 
 
-@section('page_title')
-    Reward Rules
-@stop
+    {{-- 页面标题和操作按钮 --}}
+    <div class="flex flex-wrap gap-4 justify-between items-center mb-6">
+        <div class="flex items-center gap-3">
+            <div class="icon-star text-2xl text-yellow-500"></div>
+            <p class="text-2xl text-gray-800 dark:text-white font-bold">
+                @lang('Reward Rules')
+            </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">
+                {{ $rules->total() }} @lang('Total')
+            </span>
+        </div>
 
 
-@section('content-wrapper')
-    <div class="content full-page">
-        <div class="page-header">
-            <div class="page-title">
-                <h1>Reward Rules</h1>
-            </div>
-            <div class="page-action">
-                <a href="{{ route('admin.reward-points.rules.create') }}" class="btn btn-lg btn-primary">
-                    Add Rule
-                </a>
+        <div class="flex gap-x-2.5 items-center">
+            <a href="{{ route('admin.reward-points.rules.create') }}" class="primary-button flex items-center gap-2">
+                <span class="icon-plus text-lg"></span>
+                @lang('Add Rule')
+            </a>
+        </div>
+    </div>
+
+    {{-- 搜索和筛选区域 --}}
+    <div class="mb-6 bg-white dark:bg-gray-900 rounded-lg shadow-sm p-4 border border-gray-200 dark:border-gray-800">
+        <div class="flex flex-wrap gap-4 items-center justify-between">
+            <div class="flex flex-wrap gap-3">
+                <div class="relative">
+                    <input 
+                        type="text" 
+                        id="searchInput"
+                        placeholder="@lang('Search by rule name...')" 
+                        class="pl-9 pr-3 py-2 w-64 border border-gray-300 dark:border-gray-700 rounded-lg text-sm focus:ring-2 focus:ring-blue-500 focus:border-transparent dark:bg-gray-800 dark:text-gray-300"
+                    >
+                    <span class="absolute left-3 top-2.5 icon-search text-gray-400 text-sm"></span>
+                </div>
+                
+                <select 
+                    id="transactionTypeFilter"
+                    class="px-3 py-2 border border-gray-300 dark:border-gray-700 rounded-lg text-sm focus:ring-2 focus:ring-blue-500 dark:bg-gray-800 dark:text-gray-300"
+                >
+                    <option value="">@lang('All Types')</option>
+                    <option value="1">@lang('Order')</option>
+                    <option value="2">@lang('Registration')</option>
+                    <option value="3">@lang('Product Review')</option>
+                    <option value="4">@lang('Daily Sign In')</option>
+                    <option value="5">@lang('Referral')</option>
+                    <option value="6">@lang('Birthday')</option>
+                    <option value="7">@lang('Share')</option>
+                </select>
+                
+                <select 
+                    id="statusFilter"
+                    class="px-3 py-2 border border-gray-300 dark:border-gray-700 rounded-lg text-sm focus:ring-2 focus:ring-blue-500 dark:bg-gray-800 dark:text-gray-300"
+                >
+                    <option value="">@lang('All Status')</option>
+                    <option value="1">@lang('Active')</option>
+                    <option value="0">@lang('Inactive')</option>
+                </select>
+
+                <select 
+                    id="groupPointsFilter"
+                    class="px-3 py-2 border border-gray-300 dark:border-gray-700 rounded-lg text-sm focus:ring-2 focus:ring-blue-500 dark:bg-gray-800 dark:text-gray-300"
+                >
+                    <option value="">@lang('All Rules')</option>
+                    <option value="1">@lang('Different Points by Group')</option>
+                    <option value="0">@lang('Uniform Points')</option>
+                </select>
             </div>
             </div>
         </div>
         </div>
+    </div>
 
 
-        <div class="page-content">
-            <div class="table">
-                <table class="table table-bordered">
-                    <thead>
+    {{-- 表格列表 --}}
+    <div class="bg-white dark:bg-gray-900 rounded-lg shadow-sm border border-gray-200 dark:border-gray-800 overflow-hidden">
+        <div class="overflow-x-auto">
+            <table class="min-w-full divide-y divide-gray-200 dark:divide-gray-800">
+                <thead class="bg-gray-50 dark:bg-gray-800">
                     <tr>
                     <tr>
-                        <th>ID</th>
-                        <th>Rule Name</th>
-                        <th>Transaction Type</th>
-                        <th>Reward Points</th>
-                        <th>Status</th>
-                        <th>Actions</th>
+                        <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">
+                            @lang('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('Rule 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('Transaction Type')
+                        </th>
+                        <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">
+                            @lang('Group Settings')
+                        </th>
+                        <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">
+                            @lang('Points Configuration')
+                        </th>
+                        <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">
+                            @lang('Status')
+                        </th>
+                        <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">
+                            @lang('Expiry')
+                        </th>
+                        <th class="px-6 py-3 text-right text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">
+                            @lang('Actions')
+                        </th>
                     </tr>
                     </tr>
-                    </thead>
-                    <tbody>
-                    @foreach($rules as $rule)
-                        <tr>
-                            <td>{{ $rule->rule_id }}</td>
-                            <td>{{ $rule->rule_name }}</td>
-                            <td>
-                                @switch($rule->type_of_transaction)
-                                    @case(1) Order @break
-                                    @case(2) Registration @break
-                                    @case(3) Product Review @break
-                                    @case(4) Daily Sign In @break
-                                    @case(5) Referral @break
-                                    @case(6) Birthday @break
-                                @endswitch
+                </thead>
+                <tbody class="bg-white dark:bg-gray-900 divide-y divide-gray-200 dark:divide-gray-800">
+                    @forelse($rules as $rule)
+                        <tr class="hover:bg-gray-50 dark:hover:bg-gray-800 transition-colors">
+                            {{-- ID --}}
+                            <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900 dark:text-gray-300">
+                                #{{ $rule->rule_id }}
                             </td>
                             </td>
-                            <td>{{ $rule->reward_point }}</td>
-                            <td>
-                                <span class="badge badge-{{ $rule->status ? 'success' : 'danger' }}">
-                                    {{ $rule->status ? 'Active' : 'Inactive' }}
-                                </span>
+
+                            {{-- 规则名称 --}}
+                            <td class="px-6 py-4">
+                                <div class="text-sm font-medium text-gray-900 dark:text-white">
+                                    {{ $rule->rule_name }}
+                                </div>
+                                @if($rule->comment)
+                                    <div class="text-xs text-gray-500 dark:text-gray-400 mt-1 line-clamp-1">
+                                        {{ $rule->comment }}
+                                    </div>
+                                @endif
                             </td>
                             </td>
-                            <td>
-                                <a href="{{ route('admin.reward-points.rules.edit', $rule->rule_id) }}" class="btn btn-sm btn-primary">
-                                    Edit
-                                </a>
-                                <form action="{{ route('admin.reward-points.rules.delete', $rule->rule_id) }}" method="POST" style="display:inline">
-                                    @csrf
-                                    @method('DELETE')
-                                    <button type="submit" class="btn btn-sm btn-danger" onclick="return confirm('Are you sure?')">
-                                        Delete
-                                    </button>
-                                </form>
+
+                            {{-- 交易类型 --}}
+                            <td class="px-6 py-4 whitespace-nowrap">
+                                <div class="flex items-center gap-2">
+                                    @switch($rule->type_of_transaction)
+                                        @case(1)
+                                            <span class="inline-flex items-center gap-1 px-2 py-1 rounded-full text-xs font-medium bg-blue-100 dark:bg-blue-900 text-blue-700 dark:text-blue-300">
+                                                <span class="icon-shopping-cart text-xs"></span>
+                                                @lang('Order')
+                                            </span>
+                                            @break
+                                        @case(2)
+                                            <span class="inline-flex items-center gap-1 px-2 py-1 rounded-full text-xs font-medium bg-green-100 dark:bg-green-900 text-green-700 dark:text-green-300">
+                                                <span class="icon-user text-xs"></span>
+                                                @lang('Registration')
+                                            </span>
+                                            @break
+                                        @case(3)
+                                            <span class="inline-flex items-center gap-1 px-2 py-1 rounded-full text-xs font-medium bg-yellow-100 dark:bg-yellow-900 text-yellow-700 dark:text-yellow-300">
+                                                <span class="icon-star text-xs"></span>
+                                                @lang('Product Review')
+                                            </span>
+                                            @break
+                                        @case(4)
+                                            <span class="inline-flex items-center gap-1 px-2 py-1 rounded-full text-xs font-medium bg-purple-100 dark:bg-purple-900 text-purple-700 dark:text-purple-300">
+                                                <span class="icon-calendar text-xs"></span>
+                                                @lang('Daily Sign In')
+                                            </span>
+                                            @break
+                                        @case(5)
+                                            <span class="inline-flex items-center gap-1 px-2 py-1 rounded-full text-xs font-medium bg-indigo-100 dark:bg-indigo-900 text-indigo-700 dark:text-indigo-300">
+                                                <span class="icon-share text-xs"></span>
+                                                @lang('Referral')
+                                            </span>
+                                            @break
+                                        @case(6)
+                                            <span class="inline-flex items-center gap-1 px-2 py-1 rounded-full text-xs font-medium bg-pink-100 dark:bg-pink-900 text-pink-700 dark:text-pink-300">
+                                                <span class="icon-gift text-xs"></span>
+                                                @lang('Birthday')
+                                            </span>
+                                            @break
+                                        @case(7)
+                                            <span class="inline-flex items-center gap-1 px-2 py-1 rounded-full text-xs font-medium bg-orange-100 dark:bg-orange-900 text-orange-700 dark:text-orange-300">
+                                                <span class="icon-share-alt text-xs"></span>
+                                                @lang('Share')
+                                            </span>
+                                            @break
+                                        @default
+                                            <span class="inline-flex items-center gap-1 px-2 py-1 rounded-full text-xs font-medium bg-gray-100 dark:bg-gray-800 text-gray-500 dark:text-gray-400">
+                                                <span class="icon-question text-xs"></span>
+                                                @lang('Unknown')
+                                            </span>
+                                    @endswitch
+                                </div>
+                            </td>
+
+                            {{-- 群组设置类型 --}}
+                            <td class="px-6 py-4 whitespace-nowrap">
+                                @if($rule->enable_different_points_by_group)
+                                    <span class="inline-flex items-center gap-1 px-2 py-1 rounded-full text-xs font-medium bg-purple-100 dark:bg-purple-900 text-purple-700 dark:text-purple-300">
+                                        <span class="icon-users text-xs"></span>
+                                        @lang('积分不同')
+                                    </span>
+                                @else
+                                    <span class="inline-flex items-center gap-1 px-2 py-1 rounded-full text-xs font-medium bg-green-100 dark:bg-green-900 text-green-700 dark:text-green-300">
+                                        <span class="icon-star text-xs"></span>
+                                        @lang('积分相同')
+                                    </span>
+                                @endif
+                            </td>
+
+                            {{-- 积分配置 --}}
+                            <td class="px-6 py-4">
+                                @if($rule->enable_different_points_by_group)
+                                    {{-- 积分不同模式:显示群组和对应积分 --}}
+                                    @php
+                                        $groupPoints = json_decode($rule->customer_group_ids, true) ?: [];
+                                    @endphp
+                                    
+                                    @if(!empty($groupPoints))
+                                        <div class="space-y-1">
+                                            @foreach($groupPoints as $groupId => $points)
+                                                @if(!empty($groupId) && $groupId !== '')
+                                                    <div class="flex items-center justify-between gap-2 text-sm">
+                                                        <span class="text-gray-600 dark:text-gray-400">
+                                                            {{ $customerGroupsList[$groupId] ?? 'Group ' . $groupId }}:
+                                                        </span>
+                                                        <span class="font-medium text-yellow-600 dark:text-yellow-500">
+                                                            {{ $points }} @lang('pts')
+                                                        </span>
+                                                    </div>
+                                                @endif
+                                            @endforeach
+                                        </div>
+                                    @else
+                                        <span class="text-sm text-gray-400 dark:text-gray-500">
+                                            @lang('No groups configured')
+                                        </span>
+                                    @endif
+                                @else
+                                    {{-- 积分相同模式:显示统一积分 --}}
+                                    <div class="flex items-center gap-1">
+                                        <span class="text-2xl font-bold text-yellow-600 dark:text-yellow-500">
+                                            {{ $rule->reward_point }}
+                                        </span>
+                                        <span class="text-xs text-gray-500">@lang('points')</span>
+                                        
+                                        {{-- 显示适用的客户群组 --}}
+                                        @php
+                                            $customerGroups = $rule->customer_group_ids ? explode(',', $rule->customer_group_ids) : [];
+                                        @endphp
+                                        @if(!empty($customerGroups) && $customerGroups[0] !== '')
+                                            <div class="ml-2 flex flex-wrap gap-1">
+                                                @foreach(array_slice($customerGroups, 0, 2) as $groupId)
+                                                    <span class="inline-flex items-center px-1.5 py-0.5 rounded text-xs font-medium bg-blue-100 dark:bg-blue-900 text-blue-800 dark:text-blue-200">
+                                                        {{ $customerGroupsList[$groupId] ?? 'Group ' . $groupId }}
+                                                    </span>
+                                                @endforeach
+                                                @if(count($customerGroups) > 2)
+                                                    <span class="inline-flex items-center px-1.5 py-0.5 rounded text-xs font-medium bg-gray-100 dark:bg-gray-800 text-gray-600 dark:text-gray-400">
+                                                        +{{ count($customerGroups) - 2 }}
+                                                    </span>
+                                                @endif
+                                            </div>
+                                        @else
+                                            <span class="ml-2 text-xs text-gray-400">
+                                                (All Groups)
+                                            </span>
+                                        @endif
+                                    </div>
+                                @endif
+                            </td>
+
+                            {{-- 状态 --}}
+                            <td class="px-6 py-4 whitespace-nowrap">
+                                @if($rule->status)
+                                    <span class="inline-flex items-center gap-1 px-2 py-1 rounded-full text-xs font-medium bg-green-100 dark:bg-green-900 text-green-700 dark:text-green-300">
+                                        <span class="icon-check-circle text-xs"></span>
+                                        @lang('Active')
+                                    </span>
+                                @else
+                                    <span class="inline-flex items-center gap-1 px-2 py-1 rounded-full text-xs font-medium bg-gray-100 dark:bg-gray-800 text-gray-500 dark:text-gray-400">
+                                        <span class="icon-x-circle text-xs"></span>
+                                        @lang('Inactive')
+                                    </span>
+                                @endif
+                            </td>
+
+                            {{-- 过期信息 --}}
+                            <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500 dark:text-gray-400">
+                                @if($rule->expired_day > 0)
+                                    <span class="flex items-center gap-1">
+                                        <span class="icon-calendar text-xs"></span>
+                                        {{ $rule->expired_day }} @lang('days')
+                                    </span>
+                                @else
+                                    <span class="flex items-center gap-1">
+                                        <span class="icon-minus text-xs"></span>
+                                        @lang('Never')
+                                    </span>
+                                @endif
+                            </td>
+
+                            {{-- 操作按钮 --}}
+                            <td class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
+                                <div class="flex items-center justify-end gap-2">
+                                    <a 
+                                        href="{{ route('admin.reward-points.rules.edit', $rule->rule_id) }}" 
+                                        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"
+                                        title="@lang('Edit')"
+                                    >
+                                        <span class="icon-pencil text-sm"></span>
+                                        <span class="text-sm">@lang('Edit')</span>
+                                    </a>
+                                    
+                                    <form 
+                                        method="POST"
+                                        action="{{ route('admin.reward-points.rules.delete', $rule->rule_id) }}"
+                                        class="inline"
+                                        onsubmit="return confirm('@lang('Are you sure you want to delete this rule? This action cannot be undone.')');"
+                                    >
+                                        @csrf
+                                        @method('DELETE')
+                                        <button 
+                                            type="submit" 
+                                            class="inline-flex items-center gap-1 px-3 py-1.5 bg-red-50 dark:bg-red-900/20 text-red-600 dark:text-red-400 hover:bg-red-100 dark:hover:bg-red-900/30 rounded-lg transition-colors"
+                                            title="@lang('Delete')"
+                                        >
+                                            <span class="icon-delete text-sm"></span>
+                                            <span class="text-sm">@lang('Delete')</span>
+                                        </button>
+                                    </form>
+                                </div>
                             </td>
                             </td>
                         </tr>
                         </tr>
-                    @endforeach
-                    </tbody>
-                </table>
-                {{ $rules->links() }}
-            </div>
+                    @empty
+                        <tr>
+                            <td colspan="8" class="px-6 py-12 text-center">
+                                <div class="flex flex-col items-center gap-4">
+                                    <div class="w-20 h-20 bg-gray-100 dark:bg-gray-800 rounded-full flex items-center justify-center">
+                                        <span class="icon-star text-4xl text-gray-400"></span>
+                                    </div>
+                                    <div>
+                                        <p class="text-lg font-medium text-gray-600 dark:text-gray-400 mb-1">
+                                            @lang('No Reward Rules Found')
+                                        </p>
+                                        <p class="text-sm text-gray-500 dark:text-gray-500">
+                                            @lang('Get started by creating your first reward rule')
+                                        </p>
+                                    </div>
+                                    <a href="{{ route('admin.reward-points.rules.create') }}" class="primary-button mt-2">
+                                        @lang('Create Your First Rule')
+                                    </a>
+                                </div>
+                            </td>
+                        </tr>
+                    @endforelse
+                </tbody>
+            </table>
         </div>
         </div>
+
+        {{-- 分页 --}}
+        @if($rules->hasPages())
+            <div class="border-t border-gray-200 dark:border-gray-800 px-6 py-4">
+                <div class="flex flex-col sm:flex-row justify-between items-center gap-4">
+                    <div class="text-sm text-gray-600 dark:text-gray-400">
+                        {!! __('Showing :firstItem to :lastItem of :total items', [
+                            'firstItem' => $rules->firstItem(),
+                            'lastItem' => $rules->lastItem(),
+                            'total' => $rules->total()
+                        ]) !!}
+                    </div>
+
+                    <div class="flex gap-1">
+                        {{-- 上一页 --}}
+                        @if($rules->onFirstPage())
+                            <span class="px-3 py-2 rounded-lg bg-gray-100 dark:bg-gray-800 text-gray-400 cursor-not-allowed">
+                                <span class="icon-chevron-left text-sm"></span>
+                            </span>
+                        @else
+                            <a href="{{ $rules->previousPageUrl() }}" class="px-3 py-2 rounded-lg bg-white dark:bg-gray-800 border border-gray-300 dark:border-gray-700 text-gray-700 dark:text-gray-300 hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors">
+                                <span class="icon-chevron-left text-sm"></span>
+                            </a>
+                        @endif
+
+                        {{-- 页码 --}}
+                        @php
+                            $currentPage = $rules->currentPage();
+                            $lastPage = $rules->lastPage();
+                            $start = max(1, $currentPage - 2);
+                            $end = min($lastPage, $currentPage + 2);
+                        @endphp
+
+                        @if($start > 1)
+                            <a href="{{ $rules->url(1) }}" class="px-3 py-2 rounded-lg bg-white dark:bg-gray-800 border border-gray-300 dark:border-gray-700 text-gray-700 dark:text-gray-300 hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors">
+                                1
+                            </a>
+                            @if($start > 2)
+                                <span class="px-3 py-2 text-gray-500">...</span>
+                            @endif
+                        @endif
+
+                        @for($i = $start; $i <= $end; $i++)
+                            @if($i == $currentPage)
+                                <span class="px-3 py-2 rounded-lg bg-blue-600 text-white cursor-default">
+                                    {{ $i }}
+                                </span>
+                            @else
+                                <a href="{{ $rules->url($i) }}" class="px-3 py-2 rounded-lg bg-white dark:bg-gray-800 border border-gray-300 dark:border-gray-700 text-gray-700 dark:text-gray-300 hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors">
+                                    {{ $i }}
+                                </a>
+                            @endif
+                        @endfor
+
+                        @if($end < $lastPage)
+                            @if($end < $lastPage - 1)
+                                <span class="px-3 py-2 text-gray-500">...</span>
+                            @endif
+                            <a href="{{ $rules->url($lastPage) }}" class="px-3 py-2 rounded-lg bg-white dark:bg-gray-800 border border-gray-300 dark:border-gray-700 text-gray-700 dark:text-gray-300 hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors">
+                                {{ $lastPage }}
+                            </a>
+                        @endif
+
+                        {{-- 下一页 --}}
+                        @if($rules->hasMorePages())
+                            <a href="{{ $rules->nextPageUrl() }}" class="px-3 py-2 rounded-lg bg-white dark:bg-gray-800 border border-gray-300 dark:border-gray-700 text-gray-700 dark:text-gray-300 hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors">
+                                <span class="icon-chevron-right text-sm"></span>
+                            </a>
+                        @else
+                            <span class="px-3 py-2 rounded-lg bg-gray-100 dark:bg-gray-800 text-gray-400 cursor-not-allowed">
+                                <span class="icon-chevron-right text-sm"></span>
+                            </span>
+                        @endif
+                    </div>
+                </div>
+            </div>
+        @endif
     </div>
     </div>
-@stop
+
+    <script>
+    // 实时搜索和筛选功能
+    document.addEventListener('DOMContentLoaded', function() {
+        const searchInput = document.getElementById('searchInput');
+        const transactionTypeFilter = document.getElementById('transactionTypeFilter');
+        const statusFilter = document.getElementById('statusFilter');
+        const groupPointsFilter = document.getElementById('groupPointsFilter');
+        
+        function filterRules() {
+            const searchTerm = searchInput.value.toLowerCase();
+            const transactionTypeValue = transactionTypeFilter.value;
+            const statusValue = statusFilter.value;
+            const groupPointsValue = groupPointsFilter.value;
+            
+            const rows = document.querySelectorAll('tbody tr');
+            
+            rows.forEach(row => {
+                if (row.querySelector('td[colspan]')) return; // 跳过空状态行
+                
+                const ruleName = row.querySelector('td:nth-child(2) .font-medium')?.innerText.toLowerCase() || '';
+                const transactionTypeText = row.querySelector('td:nth-child(3) .rounded-full')?.innerText || '';
+                const statusBadge = row.querySelector('td:nth-child(6) .rounded-full')?.innerText.includes('Active') || false;
+                const groupPointsType = row.querySelector('td:nth-child(4) .rounded-full')?.innerText.includes('积分不同') || false;
+                
+                let show = true;
+                
+                // 搜索过滤
+                if (searchTerm && !ruleName.includes(searchTerm)) {
+                    show = false;
+                }
+                
+                // 交易类型过滤
+                if (transactionTypeValue !== '') {
+                    const typeMap = {
+                        '1': 'Order',
+                        '2': 'Registration',
+                        '3': 'Product Review',
+                        '4': 'Daily Sign In',
+                        '5': 'Referral',
+                        '6': 'Birthday',
+                        '7': 'Share'
+                    };
+                    const expectedType = typeMap[transactionTypeValue];
+                    if (!transactionTypeText.includes(expectedType)) {
+                        show = false;
+                    }
+                }
+                
+                // 状态过滤
+                if (statusValue !== '') {
+                    const isActive = statusValue === '1';
+                    if (statusBadge !== isActive) {
+                        show = false;
+                    }
+                }
+                
+                // 群组积分类型过滤
+                if (groupPointsValue !== '') {
+                    const isDifferentPoints = groupPointsValue === '1';
+                    if (groupPointsType !== isDifferentPoints) {
+                        show = false;
+                    }
+                }
+                
+                row.style.display = show ? '' : 'none';
+            });
+        }
+        
+        if (searchInput) searchInput.addEventListener('keyup', filterRules);
+        if (transactionTypeFilter) transactionTypeFilter.addEventListener('change', filterRules);
+        if (statusFilter) statusFilter.addEventListener('change', filterRules);
+        if (groupPointsFilter) groupPointsFilter.addEventListener('change', filterRules);
+    });
+    </script>
+</x-admin::layouts>

+ 2 - 2
packages/Longyi/RewardPoints/src/Resources/views/admin/settings/index.blade.php

@@ -25,10 +25,10 @@
         {{-- 分组标签页 --}}
         {{-- 分组标签页 --}}
         <div class="bg-white dark:bg-gray-900 rounded-lg shadow mb-6">
         <div class="bg-white dark:bg-gray-900 rounded-lg shadow mb-6">
             <div class="flex border-b border-gray-200 dark:border-gray-800 overflow-x-auto">
             <div class="flex border-b border-gray-200 dark:border-gray-800 overflow-x-auto">
-                @foreach($groups as $group)
+                @foreach($groupData as $group => $data)
                     <a href="{{ route('admin.reward-points.settings.index', ['group' => $group]) }}"
                     <a href="{{ route('admin.reward-points.settings.index', ['group' => $group]) }}"
                        class="px-6 py-3 text-sm font-medium whitespace-nowrap {{ $currentGroup === $group ? 'border-b-2 border-blue-600 text-blue-600' : 'text-gray-600 hover:text-gray-800 dark:text-gray-400 dark:hover:text-gray-200' }}">
                        class="px-6 py-3 text-sm font-medium whitespace-nowrap {{ $currentGroup === $group ? 'border-b-2 border-blue-600 text-blue-600' : 'text-gray-600 hover:text-gray-800 dark:text-gray-400 dark:hover:text-gray-200' }}">
-                        @lang($this->getGroupName($group))
+                        @lang($data['name'])
                     </a>
                     </a>
                 @endforeach
                 @endforeach
             </div>
             </div>

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

@@ -1,6 +1,73 @@
 <?php
 <?php
 
 
 return [
 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' => [
     'customer' => [
         'my-reward-points' => 'My Reward Points',
         'my-reward-points' => 'My Reward Points',
         'available-points' => 'Available Points',
         'available-points' => 'Available Points',
@@ -25,6 +92,7 @@ return [
         'sign-in' => 'Sign In',
         'sign-in' => 'Sign In',
         'referral' => 'Referral',
         'referral' => 'Referral',
         'birthday' => 'Birthday',
         'birthday' => 'Birthday',
+        'share' => 'Share',
         'other' => 'Other',
         'other' => 'Other',
         'pending' => 'Pending',
         'pending' => 'Pending',
         'completed' => 'Completed',
         'completed' => 'Completed',
@@ -33,48 +101,7 @@ return [
         'no-history' => 'No points history yet',
         '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',
-        'reward-points' => 'Reward Points',
-        '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',
-    ],
-    
+    // 验证消息
     'validation' => [
     'validation' => [
         'points-required' => 'Points are required',
         'points-required' => 'Points are required',
         'points-invalid' => 'Invalid points amount',
         'points-invalid' => 'Invalid points amount',