bianjunhui 2 ماه پیش
والد
کامیت
813753c24b

+ 158 - 14
packages/Longyi/RewardPoints/src/Console/Commands/InitializeGrowthSettings.php

@@ -5,12 +5,13 @@ namespace Longyi\RewardPoints\Console\Commands;
 use Illuminate\Console\Command;
 use Longyi\RewardPoints\Repositories\RewardPointSettingRepository;
 use Longyi\DynamicMenu\Models\MenuItem;
+use Webkul\Customer\Models\CustomerGroup;
 
 class InitializeGrowthSettings extends Command
 {
     protected $signature = 'reward-points:init-growth-settings';
 
-    protected $description = 'Initialize reward points settings in database';
+    protected $description = 'Initialize reward points growth value settings and menu items';
 
     protected $settingRepository;
 
@@ -22,41 +23,184 @@ class InitializeGrowthSettings extends Command
 
     public function handle()
     {
-        $this->info('Initializing reward points settings...');
+        $this->info('Initializing reward points growth value settings...');
 
         try {
-            $this->settingRepository->initializeDefaultSettings();
+            $this->initializeGrowthLevelsInCustomerGroups();
 
-            $this->info('✓ Default settings initialized successfully!');
-            $this->info('You can now configure reward points in admin panel.');
+            $this->initializeGrowthSettings();
 
-            // 添加数据
-            $this->addItems();
+            $this->addMenuItems();
+
+            $this->info('✓ Growth value settings initialized successfully!');
+            $this->info('✓ Menu items added to admin panel!');
+            $this->info('You can now configure growth value in: Admin > Settings > Growth Value');
 
             return 0;
 
         } catch (\Exception $e) {
             $this->error('Error initializing settings: ' . $e->getMessage());
+            $this->error($e->getTraceAsString());
             return 1;
         }
     }
 
     /**
-     * 添加积分模块的菜单项到动态菜单
+     * 在 ly_customer_groups 表中初始化成长值等级数据
      */
-    protected function addItems()
+    protected function initializeGrowthLevelsInCustomerGroups()
     {
-        $this->info('Adding reward points menu items to dynamic menu...');
+        $this->info('Initializing growth value levels in customer groups...');
+
+        $generalGroup = CustomerGroup::where('code', 'general')->first();
+        $wholesaleGroup = CustomerGroup::where('code', 'wholesale')->first();
+
+        if ($generalGroup) {
+            $generalGroup->update([
+                'min_growth_value' => 0,
+                'require_first_order' => false,
+                'growth_level_name' => 'General-V0',
+                'growth_discount_rate' => 0,
+                'growth_benefits' => ['基础会员服务'],
+                'growth_level_icon' => null,
+            ]);
+            $this->info('✓ General group updated with V0 level');
+        }
+
+        if ($generalGroup) {
+            CustomerGroup::updateOrCreate(
+                ['code' => 'general_v1'],
+                [
+                    'name' => '普通会员-V1',
+                    'min_growth_value' => 0,
+                    'require_first_order' => true,
+                    'growth_level_name' => 'V1',
+                    'growth_discount_rate' => 2,
+                    'growth_benefits' => ['完成首单升级', '享受2%额外折扣', '优先客服支持'],
+                    'growth_level_icon' => null,
+                    'is_user_defined' => 1,
+                ]
+            );
+            $this->info('✓ Created V1 level (General V1)');
+        }
+
+        if ($generalGroup) {
+            CustomerGroup::updateOrCreate(
+                ['code' => 'general_v2'],
+                [
+                    'name' => '普通会员-V2',
+                    'min_growth_value' => 1000,
+                    'require_first_order' => false,
+                    'growth_level_name' => 'V2',
+                    'growth_discount_rate' => 5,
+                    'growth_benefits' => ['享受5%额外折扣', '专属优惠券', '生日礼品', '优先发货'],
+                    'growth_level_icon' => null,
+                    'is_user_defined' => 1,
+                ]
+            );
+            $this->info('✓ Created V2 level (General V2)');
+        }
 
-        // 检查是否已存在积分模块的菜单项
-        $existingParent = MenuItem::where('key', 'settings.reward-points')->first();
+        if ($wholesaleGroup) {
+            $wholesaleGroup->update([
+                'min_growth_value' => 5000,
+                'require_first_order' => false,
+                'growth_level_name' => 'V3',
+                'growth_discount_rate' => 10,
+                'growth_benefits' => ['享受10%额外折扣', '专属客服经理', '新品优先体验', '免费配送', '专属活动邀请'],
+                'growth_level_icon' => null,
+            ]);
+            $this->info('✓ Wholesale group updated with V3 level');
+        }
+
+        $this->info('✓ Growth value levels initialized in ly_customer_groups table');
+    }
+
+    /**
+     * 初始化成长值配置项
+     */
+    protected function initializeGrowthSettings()
+    {
+        $this->info('Initializing growth value settings...');
+
+        $settings = [
+            [
+                'code' => 'growth_value_ratio',
+                'name' => '成长值计算比例',
+                'value' => '1',
+                'type' => 'number',
+                'group' => 'growth_value',
+                'description' => '每消费1元获得的成长值数量',
+                'is_enabled' => true,
+            ],
+            [
+                'code' => 'growth_value_validity_days',
+                'name' => '成长值有效期(天)',
+                'value' => '365',
+                'type' => 'number',
+                'group' => 'growth_value',
+                'description' => '成长值的有效期,0表示永久有效',
+                'is_enabled' => true,
+            ],
+        ];
+
+        foreach ($settings as $settingData) {
+            \Longyi\RewardPoints\Models\RewardPointSetting::updateOrCreate(
+                ['code' => $settingData['code']],
+                $settingData
+            );
+        }
+
+        $this->info('✓ Growth value settings initialized');
+    }
+
+    /**
+     * 添加成长值模块的菜单项到动态菜单
+     */
+    protected function addMenuItems()
+    {
+        $this->info('Adding growth value menu items to dynamic menu...');
+
+        // 检查是否已存在成长值模块的菜单项
+        $existingParent = MenuItem::where('key', 'settings.growth-value')->first();
 
         if ($existingParent) {
-            $this->warn('Reward points menu items already exist in dynamic menu.');
+            $this->warn('Growth value menu items already exist in dynamic menu.');
             return;
         }
 
+        // 创建子菜单项
+        $childItems = [
+            [
+                'name' => '会员成长值',
+                'key' => 'customers.growth-value',
+                'route' => 'admin.growth-value.index',
+                'icon' => 'icon-users',
+                'sort_order' => 1,
+            ],
+            [
+                'name' => '等级配置',
+                'key' => 'customers.growth-levels',
+                'route' => 'admin.growth-value.levels',
+                'icon' => 'icon-list',
+                'sort_order' => 2,
+            ],
+        ];
+
+        foreach ($childItems as $item) {
+            MenuItem::create([
+                'name' => $item['name'],
+                'key' => $item['key'],
+                'route' => $item['route'],
+                'icon' => $item['icon'],
+                'sort_order' => $item['sort_order'],
+                'parent_id' => 999,
+                'status' => 1,
+                'created_by' => 1,
+            ]);
+        }
 
-        $this->info('✓ Reward points menu items added to dynamic menu successfully!');
+        $this->info('✓ Growth value menu items added to dynamic menu successfully!');
     }
 }
+

+ 89 - 0
packages/Longyi/RewardPoints/src/Console/Commands/TestRegistrationPoints.php

@@ -0,0 +1,89 @@
+<?php
+
+namespace Longyi\RewardPoints\Console\Commands;
+
+use Illuminate\Console\Command;
+use Longyi\RewardPoints\Repositories\RewardPointRepository;
+use Longyi\RewardPoints\Models\RewardActiveRule;
+use Webkul\Customer\Models\Customer;
+
+class TestRegistrationPoints extends Command
+{
+    protected $signature = 'reward-points:test-registration {email?}';
+
+    protected $description = 'Test registration points for a customer';
+
+    protected $rewardPointRepository;
+
+    public function __construct(RewardPointRepository $rewardPointRepository)
+    {
+        parent::__construct();
+        $this->rewardPointRepository = $rewardPointRepository;
+    }
+
+    public function handle()
+    {
+        $email = $this->argument('email');
+
+        if (!$email) {
+            // 获取最后一个注册的客户
+            $customer = Customer::orderBy('id', 'desc')->first();
+        } else {
+            $customer = Customer::where('email', $email)->first();
+        }
+
+        if (!$customer) {
+            $this->error('Customer not found!');
+            return 1;
+        }
+
+        $this->info("Testing registration points for customer: {$customer->name} ({$customer->email})");
+        $this->info("Customer ID: {$customer->id}");
+
+        // 检查是否有注册规则
+        $registrationRule = RewardActiveRule::where('type_of_transaction', RewardActiveRule::TYPE_REGISTRATION)
+            ->where('status', 1)
+            ->first();
+
+        if ($registrationRule) {
+            $this->info("Found registration rule:");
+            $this->table(
+                ['ID', 'Name', 'Points', 'Status'],
+                [[
+                    $registrationRule->id,
+                    $registrationRule->name,
+                    $registrationRule->reward_point,
+                    $registrationRule->status ? 'Active' : 'Inactive'
+                ]]
+            );
+        } else {
+            $this->warn("No active registration rule found. Using config value.");
+            $pointsFromConfig = config('rewardpoints.registration.points_per_registration', 100);
+            $this->info("Points from config: {$pointsFromConfig}");
+        }
+
+        // 手动触发注册积分
+        $this->info("\nManually adding registration points...");
+
+        try {
+            $event = new \stdClass();
+            $event->id = $customer->id;
+
+            $listener = new \Longyi\RewardPoints\Listeners\CustomerEvents($this->rewardPointRepository);
+            $listener->handleCustomerRegistration($customer);
+
+            $this->info("✓ Points added successfully!");
+
+            // 显示当前积分
+            $currentPoints = $this->rewardPointRepository->getCustomerPoints($customer->id);
+            $this->info("Current points balance: {$currentPoints}");
+
+        } catch (\Exception $e) {
+            $this->error("Error: " . $e->getMessage());
+            $this->error($e->getTraceAsString());
+            return 1;
+        }
+
+        return 0;
+    }
+}

+ 28 - 20
packages/Longyi/RewardPoints/src/Database/Migrations/2026_01_01_000002_create_points_tables.php

@@ -11,6 +11,22 @@ return new class extends Migration
      */
     public function up(): void
     {
+        // 为 ly_customer_groups 表添加成长值相关字段
+        if (!Schema::hasColumn('customer_groups', 'min_growth_value')) {
+            Schema::table('customer_groups', function (Blueprint $table) {
+                $table->integer('min_growth_value')->default(0)->after('is_user_defined')->comment('最低成长值要求');
+                $table->boolean('require_first_order')->default(false)->after('min_growth_value')->comment('是否需要完成首单');
+                $table->string('growth_level_name', 100)->nullable()->after('require_first_order')->comment('成长值等级显示名称,如V1、V2');
+                $table->integer('growth_discount_rate')->default(0)->after('growth_level_name')->comment('成长值等级额外折扣率(百分比)');
+                $table->text('growth_benefits')->nullable()->after('growth_discount_rate')->comment('成长值等级权益说明(JSON格式)');
+                $table->string('growth_level_icon', 255)->nullable()->after('growth_benefits')->comment('成长值等级图标URL');
+            });
+
+            echo "✓ Added growth value columns to ly_customer_groups table\n";
+        } else {
+            echo "✓ Growth value columns already exist in ly_customer_groups table\n";
+        }
+
         if (!Schema::hasTable('mw_growth_value_customer')) {
             Schema::create('mw_growth_value_customer', function (Blueprint $table) {
                 $table->increments('id');
@@ -51,32 +67,24 @@ return new class extends Migration
             });
         }
 
-        if (!Schema::hasTable('mw_growth_value_levels')) {
-            Schema::create('mw_growth_value_levels', function (Blueprint $table) {
-                $table->increments('id');
-                $table->string('level_code', 20)->unique()->comment('等级代码:V0, V1, V2, V3...');
-                $table->string('level_name', 100)->comment('等级名称:普通会员、铜牌会员、银牌会员...');
-                $table->integer('min_growth_value')->default(0)->comment('最低成长值要求');
-                $table->integer('max_growth_value')->nullable()->comment('最高成长值要求,NULL表示无上限');
-                $table->boolean('require_first_order')->default(false)->comment('是否需要完成首单');
-                $table->integer('discount_rate')->default(0)->comment('额外折扣率(百分比),在会员组折扣基础上叠加');
-                $table->text('benefits')->nullable()->comment('权益说明(JSON格式)');
-                $table->string('icon', 255)->nullable()->comment('等级图标URL');
-                $table->integer('sort_order')->default(0)->comment('排序');
-                $table->boolean('is_active')->default(true)->comment('是否启用');
-                $table->timestamps();
-
-                $table->index('sort_order', 'idx_sort_order');
-                $table->index('min_growth_value', 'idx_min_growth_value');
-            });
-        }
     }
     /**
      * Reverse the migrations.
      */
     public function down(): void
     {
-        Schema::dropIfExists('mw_growth_value_levels');
+        if (Schema::hasColumn('customer_groups', 'min_growth_value')) {
+            Schema::table('customer_groups', function (Blueprint $table) {
+                $table->dropColumn([
+                    'min_growth_value',
+                    'require_first_order',
+                    'growth_level_name',
+                    'growth_discount_rate',
+                    'growth_benefits',
+                    'growth_level_icon',
+                ]);
+            });
+        }
         Schema::dropIfExists('mw_growth_value_history');
         Schema::dropIfExists('mw_growth_value_customer');
     }

+ 63 - 34
packages/Longyi/RewardPoints/src/Http/Controllers/Admin/GrowthValueController.php

@@ -19,15 +19,38 @@ class GrowthValueController extends Controller
         $this->growthValueService = $growthValueService;
     }
 
+    /**
+     * 显示所有会员的成长值列表
+     */
     public function index()
     {
-        $customers = GrowthValueCustomer::with(['customer.group', 'levelConfig'])
-            ->orderBy('growth_value', 'desc')
-            ->paginate(20);
+        $query = GrowthValueCustomer::with(['customer.group']);
+
+        // 邮箱筛选
+        if (request('email')) {
+            $query->whereHas('customer', function($q) {
+                $q->where('email', 'like', '%' . request('email') . '%');
+            });
+        }
+
+        // 最小成长值筛选
+        if (request('min_growth_value') !== null && request('min_growth_value') !== '') {
+            $query->where('growth_value', '>=', request('min_growth_value'));
+        }
+
+        // 最大成长值筛选
+        if (request('max_growth_value') !== null && request('max_growth_value') !== '') {
+            $query->where('growth_value', '<=', request('max_growth_value'));
+        }
+
+        $customers = $query->orderBy('growth_value', 'desc')->paginate(20);
 
         return view('rewardpoints::admin.growth-value.index', compact('customers'));
     }
 
+    /**
+     * 显示某个会员的成长值详情
+     */
     public function show($customerId)
     {
         $growthValueInfo = $this->growthValueService->getCustomerGrowthValue($customerId);
@@ -39,6 +62,9 @@ class GrowthValueController extends Controller
         return view('rewardpoints::admin.growth-value.show', compact('growthValueInfo', 'history', 'customer'));
     }
 
+    /**
+     * 手动调整会员成长值
+     */
     public function adjust($customerId)
     {
         if (request()->isMethod('post')) {
@@ -72,64 +98,67 @@ class GrowthValueController extends Controller
         return view('rewardpoints::admin.growth-value.adjust', compact('customer', 'growthValueInfo'));
     }
 
+    /**
+     * 显示成长值等级配置列表
+     */
     public function levels()
     {
-        $levels = $this->growthValueService->getAllLevels();
+        $levels = $this->growthValueService->getAllGrowthLevels();
 
         return view('rewardpoints::admin.growth-value.levels', compact('levels'));
     }
 
+    /**
+     * 保存成长值等级配置
+     */
     public function saveLevel()
     {
         $validator = Validator::make(request()->all(), [
-            'level_code' => 'required|string|max:20|unique:mw_growth_value_levels,level_code,' . request('id'),
-            'level_name' => 'required|string|max:100',
+            'id' => 'required|integer|exists:ly_customer_groups,id',
             'min_growth_value' => 'required|integer|min:0',
-            'max_growth_value' => 'nullable|integer|min:0',
             'require_first_order' => 'boolean',
-            'discount_rate' => 'integer|min:0|max:100',
-            'sort_order' => 'integer|min:0',
+            'growth_level_name' => 'nullable|string|max:100',
+            'growth_discount_rate' => 'integer|min:0|max:100',
         ]);
 
         if ($validator->fails()) {
             return response()->json(['errors' => $validator->errors()], 422);
         }
 
-        $id = request('id');
+        $group = GrowthValueLevel::findOrFail(request('id'));
 
-        if ($id) {
-            $level = GrowthValueLevel::findOrFail($id);
-        } else {
-            $level = new GrowthValueLevel();
-        }
+        $group->update([
+            'min_growth_value' => request('min_growth_value'),
+            'require_first_order' => request('require_first_order', false),
+            'growth_level_name' => request('growth_level_name'),
+            'growth_discount_rate' => request('growth_discount_rate', 0),
+        ]);
 
-        $level->fill(request()->only([
-            'level_code',
-            'level_name',
-            'min_growth_value',
-            'max_growth_value',
-            'require_first_order',
-            'discount_rate',
-            'icon',
-            'sort_order',
-        ]));
-
-        $benefits = request('benefits');
+        $benefits = request('growth_benefits');
         if (is_array($benefits)) {
-            $level->benefits = $benefits;
+            $group->growth_benefits = $benefits;
+            $group->save();
         }
 
-        $level->is_active = request('is_active', true);
-        $level->save();
-
         return response()->json(['success' => true, 'message' => '等级配置保存成功']);
     }
 
+    /**
+     * 删除成长值等级配置
+     */
     public function deleteLevel($id)
     {
-        $level = GrowthValueLevel::findOrFail($id);
-        $level->delete();
+        $group = GrowthValueLevel::findOrFail($id);
+
+        $group->update([
+            'min_growth_value' => null,
+            'require_first_order' => false,
+            'growth_level_name' => null,
+            'growth_discount_rate' => 0,
+            'growth_benefits' => null,
+            'growth_level_icon' => null,
+        ]);
 
-        return response()->json(['success' => true, 'message' => '删除成功']);
+        return response()->json(['success' => true, 'message' => '等级配置已清除']);
     }
 }

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

@@ -18,6 +18,7 @@ class CustomerEvents
 
     public function handleCustomerRegistration($event)
     {
+        Log::info('Points added for customer registration');
         // 检查事件参数类型
         if (is_object($event) && method_exists($event, 'getAttribute')) {
             $customer = $event;
@@ -55,7 +56,7 @@ class CustomerEvents
             'rewardpoints.registration.points_per_registration',
             100
         );
-        
+
         if ($registrationPoints > 0) {
             $pointsList[] = [
                 'amount' => $registrationPoints,
@@ -80,7 +81,7 @@ class CustomerEvents
                 'rewardpoints.newsletter_subscribe.points_per_subscription',
                 200
             );
-            
+
             if ($subscribePoints > 0) {
                 $pointsList[] = [
                     'amount' => $subscribePoints,
@@ -94,7 +95,7 @@ class CustomerEvents
         // 如果有积分需要添加,使用批量添加方法
         if (!empty($pointsList)) {
             $histories = $this->rewardPointRepository->addPointsBatch($customer->id, $pointsList);
-            
+
             Log::info('Points added for customer registration', [
                 'customer_id' => $customer->id,
                 'points_count' => count($pointsList),
@@ -112,7 +113,7 @@ class CustomerEvents
         if ($rule && $rule->reward_point > 0) {
             return (int) $rule->reward_point;
         }
-        
+
         return (int) config($configKey, $defaultValue);
     }
-}
+}

+ 45 - 30
packages/Longyi/RewardPoints/src/Models/GrowthValueLevel.php

@@ -4,79 +4,84 @@ namespace Longyi\RewardPoints\Models;
 
 use Illuminate\Database\Eloquent\Model;
 
+/**
+ * 成长值等级配置模型
+ * 用于操作 ly_customer_groups 表中的成长值相关字段
+ */
 class GrowthValueLevel extends Model
 {
-    protected $table = 'mw_growth_value_levels';
+    protected $table = 'customer_groups';
 
+    // 只选择需要的字段
     protected $fillable = [
-        'level_code',
-        'level_name',
         'min_growth_value',
-        'max_growth_value',
         'require_first_order',
-        'discount_rate',
-        'benefits',
-        'icon',
-        'sort_order',
-        'is_active',
+        'growth_level_name',
+        'growth_discount_rate',
+        'growth_benefits',
+        'growth_level_icon',
     ];
 
     protected $casts = [
         'min_growth_value' => 'integer',
-        'max_growth_value' => 'integer',
         'require_first_order' => 'boolean',
-        'discount_rate' => 'integer',
-        'sort_order' => 'integer',
-        'is_active' => 'boolean',
+        'growth_discount_rate' => 'integer',
     ];
 
-    public function getBenefitsAttribute($value)
+    public $timestamps = false;
+
+    /**
+     * 获取 benefits 属性
+     */
+    public function getGrowthBenefitsAttribute($value)
     {
         return $value ? json_decode($value, true) : [];
     }
 
-    public function setBenefitsAttribute($value)
+    /**
+     * 设置 benefits 属性
+     */
+    public function setGrowthBenefitsAttribute($value)
     {
-        $this->attributes['benefits'] = is_array($value) ? json_encode($value, JSON_UNESCAPED_UNICODE) : $value;
+        $this->attributes['growth_benefits'] = is_array($value) ? json_encode($value, JSON_UNESCAPED_UNICODE) : $value;
     }
 
     /**
-     * 根据成长值和首单状态获取对应的等级
+     * 根据成长值和首单状态获取对应的会员组
      */
     public static function getLevelByGrowthValue($growthValue, $hasFirstOrder = false)
     {
-        $levels = self::where('is_active', true)
+        $groups = self::whereNotNull('min_growth_value')
             ->orderBy('min_growth_value', 'desc')
             ->get();
 
-        foreach ($levels as $level) {
-            if ($level->require_first_order && !$hasFirstOrder) {
+        foreach ($groups as $group) {
+            if ($group->require_first_order && !$hasFirstOrder) {
                 continue;
             }
 
-            if ($growthValue >= $level->min_growth_value) {
-                if ($level->max_growth_value === null || $growthValue <= $level->max_growth_value) {
-                    return $level;
-                }
+            if ($growthValue >= $group->min_growth_value) {
+                return $group;
             }
         }
 
-        return self::where('level_code', 'V0')->where('is_active', true)->first();
+        // 默认返回 general 组
+        return self::where('code', 'general')->first();
     }
 
     /**
      * 获取下一个等级
      */
-    public static function getNextLevel($currentLevelCode, $hasFirstOrder = false)
+    public static function getNextLevel($currentGroupId, $hasFirstOrder = false)
     {
-        $currentLevel = self::where('level_code', $currentLevelCode)->first();
+        $currentGroup = self::find($currentGroupId);
 
-        if (!$currentLevel) {
+        if (!$currentGroup || !$currentGroup->min_growth_value) {
             return null;
         }
 
-        return self::where('is_active', true)
-            ->where('min_growth_value', '>', $currentLevel->min_growth_value)
+        return self::whereNotNull('min_growth_value')
+            ->where('min_growth_value', '>', $currentGroup->min_growth_value)
             ->where(function($query) use ($hasFirstOrder) {
                 if (!$hasFirstOrder) {
                     $query->where('require_first_order', false);
@@ -85,4 +90,14 @@ class GrowthValueLevel extends Model
             ->orderBy('min_growth_value', 'asc')
             ->first();
     }
+
+    /**
+     * 获取所有配置了成长值的会员组
+     */
+    public static function getAllGrowthLevels()
+    {
+        return self::whereNotNull('min_growth_value')
+            ->orderBy('min_growth_value')
+            ->get();
+    }
 }

+ 1 - 1
packages/Longyi/RewardPoints/src/Providers/RewardPointsServiceProvider.php

@@ -53,7 +53,7 @@ class RewardPointsServiceProvider extends ServiceProvider
                 \Longyi\RewardPoints\Console\Commands\CheckExpiredPoints::class,
                 \Longyi\RewardPoints\Console\Commands\InitializeSettings::class,
                 \Longyi\RewardPoints\Console\Commands\InitializeGrowthSettings::class,
-                \Longyi\RewardPoints\Console\Commands\CheckExpiredGrowthValues::class,
+                \Longyi\RewardPoints\Console\Commands\CheckExpiredGrowthValues::class
             ]);
         }
     }

+ 7 - 6
packages/Longyi/RewardPoints/src/Resources/lang/en/rewardpoints.php

@@ -92,7 +92,6 @@ return [
         'no-customers-found' => 'No customers found',
         'no-reward-points-records' => 'No reward points records available',
 
-        // 交易类型映射(使用字符串而不是数组)
         'transaction-types' => [
             'order' => 'Order',
             'registration' => 'Registration',
@@ -113,12 +112,10 @@ return [
         'submit' => 'Submit',
         'action' => 'Action',
 
-        // 总交易数
         'total-transactions' => 'Total Transactions',
         'total-points-earned' => 'Total Points Earned',
         'total-points-redeemed' => 'Total Points Redeemed',
 
-        // 搜索相关
         'search' => 'Search',
         'reset' => 'Reset',
         'customer-email' => 'Customer Email',
@@ -130,7 +127,6 @@ return [
         'admin-adjustment' => 'Admin Adjustment',
         'admin-action' => 'Admin Action',
 
-        // 表格表头
         'id' => 'ID',
         'customer' => 'Customer',
         'amount' => 'Amount',
@@ -138,13 +134,17 @@ return [
         'description' => 'Description',
         'balance' => 'Balance',
 
-        // 提示信息
         'no-transactions-found' => 'No transactions found',
         'try-adjusting-filters' => 'Try adjusting your filters',
 
-        // 其他
         'points' => 'Points',
         'transactions-count' => 'Transactions',
+
+        'menu' => [
+            'growth-value' => 'Growth Value Management',
+            'growth-value-customers' => 'Member Growth Value',
+            'growth-value-levels' => 'Level Configuration',
+        ],
     ],
 
     'validation' => [
@@ -154,3 +154,4 @@ return [
         'rule-not-found' => 'Rule not found',
     ],
 ];
+

+ 156 - 0
packages/Longyi/RewardPoints/src/Resources/lang/zh_CN/rewardpoints.php

@@ -0,0 +1,156 @@
+<?php
+
+return [
+    'customer' => [
+        'my-reward-points' => '我的积分',
+        'available-points' => '可用积分',
+        'daily-sign-in' => '每日签到',
+        'sign-in-now' => '立即签到',
+        'signed-today' => '今日已签到',
+        'sign-in-success' => '签到成功!您获得了',
+        'sign-in-failed' => '签到失败',
+        'sign-in-error' => '签到时发生错误',
+        'current-streak' => '当前连续签到',
+        'days' => '天',
+        'points-history' => '积分历史',
+        'date' => '日期',
+        'type' => '类型',
+        'description' => '描述',
+        'points' => '积分',
+        'balance' => '余额',
+        'status' => '状态',
+        'order' => '订单',
+        'registration' => '注册',
+        'review' => '评价',
+        'sign-in' => '签到',
+        'referral' => '推荐',
+        'birthday' => '生日',
+        'other' => '其他',
+        'pending' => '待处理',
+        'completed' => '已完成',
+        'cancelled' => '已取消',
+        'expired' => '已过期',
+        'no-history' => '暂无积分历史记录',
+    ],
+
+    'admin' => [
+        'reward-points' => '积分管理',
+        'rules' => '规则',
+        'customers' => '客户',
+        'reports' => '报表',
+        'add-rule' => '添加规则',
+        'transactions' => '交易记录',
+        'earned-transactions' => '获得积分记录',
+        'view-all-transactions' => '全部交易',
+        'view-earned-only' => '仅获得积分',
+        'total' => '总计',
+        'edit-rule' => '编辑规则',
+        'delete-rule' => '删除规则',
+        'rule-name' => '规则名称',
+        'transaction-type' => '交易类型',
+        'status' => '状态',
+        'active' => '启用',
+        'inactive' => '禁用',
+        'actions' => '操作',
+        'edit' => '编辑',
+        'delete' => '删除',
+        'create-rule' => '创建规则',
+        'update-rule' => '更新规则',
+        'back' => '返回',
+        'save' => '保存',
+        'cancel' => '取消',
+        'customer-list' => '客户列表',
+        'customer-name' => '客户姓名',
+        'email' => '邮箱',
+        'points-balance' => '积分余额',
+        'add-points' => '增加积分',
+        'deduct-points' => '扣除积分',
+        'reason' => '原因',
+        'total-points' => '总积分',
+        'total-customers' => '总客户数',
+        'average-points' => '平均积分',
+        'export' => '导出',
+        'bulk-update' => '批量更新',
+        'date-range' => '日期范围',
+        'start-date' => '开始日期',
+        'end-date' => '结束日期',
+        'points-earned' => '获得积分',
+        'points-redeemed' => '使用积分',
+        'title' => '客户积分',
+        'details-title' => ':name 的积分详情',
+        'customer-info' => '客户信息',
+        'points-history' => '积分历史',
+        'adjust-points' => '调整积分',
+        'type' => '类型',
+        'amount' => '数量',
+        'balance' => '余额',
+        'date' => '日期',
+        'description' => '描述',
+        'customer-id' => '客户ID',
+        'name' => '姓名',
+        'view' => '查看',
+        'no-customers-found' => '未找到客户',
+        'no-reward-points-records' => '暂无积分记录',
+
+        'transaction-types' => [
+            'order' => '订单',
+            'registration' => '注册',
+            'review' => '商品评价',
+            'sign-in' => '每日签到',
+            'referral' => '推荐好友',
+            'birthday' => '生日',
+            'share' => '分享',
+            'subscribe' => '订阅',
+        ],
+
+        'adjust-points-by-identifier' => '通过邮箱或ID调整积分',
+        'identifier' => '标识符',
+        'email-or-id' => '邮箱或ID',
+        'enter-email-or-id' => '输入客户邮箱或ID',
+        'enter-points' => '输入积分数量',
+        'enter-reason' => '输入调整原因',
+        'submit' => '提交',
+        'action' => '操作',
+
+        'total-transactions' => '总交易数',
+        'total-points-earned' => '总获得积分',
+        'total-points-redeemed' => '总使用积分',
+
+        'search' => '搜索',
+        'reset' => '重置',
+        'customer-email' => '客户邮箱',
+        'amount-type' => '积分类型',
+        'earned' => '获得',
+        'redeemed' => '使用',
+        'all' => '全部',
+        'all-types' => '全部类型',
+        'admin-adjustment' => '管理员调整',
+        'admin-action' => '管理员操作',
+
+        'id' => 'ID',
+        'customer' => '客户',
+        'amount' => '数量',
+        'date' => '日期',
+        'description' => '描述',
+        'balance' => '余额',
+
+        'no-transactions-found' => '未找到交易记录',
+        'try-adjusting-filters' => '请尝试调整筛选条件',
+
+        'points' => '积分',
+        'transactions-count' => '交易记录',
+
+        'menu' => [
+            'growth-value' => '成长值管理',
+            'growth-value-customers' => '会员成长值',
+            'growth-value-levels' => '等级配置',
+        ],
+    ],
+
+    'validation' => [
+        'points-required' => '积分不能为空',
+        'points-invalid' => '积分数量无效',
+        'customer-not-found' => '客户不存在',
+        'rule-not-found' => '规则不存在',
+    ],
+];

+ 86 - 0
packages/Longyi/RewardPoints/src/Resources/views/admin/growth-value/adjust.blade.php

@@ -0,0 +1,86 @@
+<x-admin::layouts>
+    <x-slot:title>
+        调整成长值 - {{ $customer->name ?? '' }}
+        </x-slot>
+
+        <div class="flex gap-4 justify-between items-center max-sm:flex-wrap">
+            <div class="flex items-center gap-4">
+                <a href="{{ route('admin.growth-value.show', $customer->id) }}" class="icon-arrow-left text-2xl"></a>
+                <p class="text-xl text-gray-800 dark:text-white font-bold">
+                    调整成长值 - {{ $customer->name ?? '' }}
+                </p>
+            </div>
+        </div>
+
+        <div class="mt-4 bg-white dark:bg-cherry-900 rounded-lg p-6 shadow">
+            <form method="POST" action="{{ route('admin.growth-value.adjust', $customer->id) }}">
+                @csrf
+
+                <!-- 当前信息 -->
+                <div class="grid grid-cols-2 gap-4 mb-6">
+                    <div>
+                        <label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
+                            当前成长值
+                        </label>
+                        <div class="text-2xl font-bold text-blue-600">
+                            {{ number_format($growthValueInfo['growth_value']) }}
+                        </div>
+                    </div>
+
+                    <div>
+                        <label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
+                            当前等级
+                        </label>
+                        <div class="text-2xl font-bold text-purple-600">
+                            {{ $growthValueInfo['growth_level_name'] ?? 'V0' }}
+                        </div>
+                    </div>
+                </div>
+
+                <!-- 调整数量 -->
+                <div class="mb-4">
+                    <label for="amount" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
+                        调整数量(正数增加,负数减少)
+                    </label>
+                    <input
+                        type="number"
+                        name="amount"
+                        id="amount"
+                        class="border rounded-md px-3 py-2 w-full dark:bg-cherry-800 dark:border-cherry-700"
+                        placeholder="例如:100 或 -50"
+                        required
+                    />
+                    @error('amount')
+                    <p class="text-red-500 text-sm mt-1">{{ $message }}</p>
+                    @enderror
+                </div>
+
+                <!-- 调整原因 -->
+                <div class="mb-4">
+                    <label for="description" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
+                        调整原因
+                    </label>
+                    <textarea
+                        name="description"
+                        id="description"
+                        rows="3"
+                        class="border rounded-md px-3 py-2 w-full dark:bg-cherry-800 dark:border-cherry-700"
+                        placeholder="请输入调整原因..."
+                    ></textarea>
+                    @error('description')
+                    <p class="text-red-500 text-sm mt-1">{{ $message }}</p>
+                    @enderror
+                </div>
+
+                <!-- 提交按钮 -->
+                <div class="flex gap-2">
+                    <button type="submit" class="primary-button">
+                        提交调整
+                    </button>
+                    <a href="{{ route('admin.growth-value.show', $customer->id) }}" class="secondary-button">
+                        取消
+                    </a>
+                </div>
+            </form>
+        </div>
+</x-admin::layouts>

+ 416 - 0
packages/Longyi/RewardPoints/src/Resources/views/admin/growth-value/index.blade.php

@@ -0,0 +1,416 @@
+<x-admin::layouts>
+    <x-slot:title>
+        会员成长值
+        </x-slot>
+
+        {{-- 页面标题和操作按钮 --}}
+        <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-purple-500"></div>
+                <p class="text-2xl text-gray-800 dark:text-white font-bold">
+                    会员成长值
+                </p>
+                <span class="px-2.5 py-0.5 text-sm bg-purple-100 dark:bg-purple-900 text-purple-800 dark:text-purple-200 rounded-full">
+                {{ $customers->total() }} 位会员
+            </span>
+            </div>
+
+            <div class="flex gap-x-2.5 items-center">
+                {{-- 调整成长值按钮 --}}
+                <button
+                    onclick="openAdjustModal()"
+                    style="padding: 0.5rem 1rem; background-color: #8b5cf6; color: white; font-weight: 500; border-radius: 0.5rem; border: none; cursor: pointer; transition: all 0.15s ease;"
+                    onmouseover="this.style.backgroundColor='#7c3aed'"
+                    onmouseout="this.style.backgroundColor='#8b5cf6'"
+                >
+                    <span class="icon-plus text-lg"></span>
+                    调整成长值
+                </button>
+
+                {{-- 等级配置按钮 --}}
+                <a
+                    href="{{ route('admin.growth-value.levels') }}"
+                    class="secondary-button"
+                >
+                    <span class="icon-settings text-lg"></span>
+                    等级配置
+                </a>
+            </div>
+        </div>
+
+        {{-- 统计卡片 --}}
+        <div class="flex flex-wrap gap-4 mb-6">
+            <div class="flex-1 min-w-[200px] bg-gradient-to-br from-purple-50 to-purple-100 dark:from-purple-900/20 dark:to-purple-800/20 rounded-xl p-5 border border-purple-200 dark:border-purple-800">
+                <div class="flex items-center justify-between">
+                    <div>
+                        <p class="text-sm text-gray-600 dark:text-gray-400 mb-1">
+                            总会员数
+                        </p>
+                        <p class="text-3xl font-bold text-purple-600 dark:text-purple-400">
+                            {{ $customers->total() }}
+                        </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-users text-2xl text-purple-600 dark:text-purple-400"></span>
+                    </div>
+                </div>
+            </div>
+
+            <div class="flex-1 min-w-[200px] bg-gradient-to-br from-blue-50 to-blue-100 dark:from-blue-900/20 dark:to-blue-800/20 rounded-xl p-5 border border-blue-200 dark:border-blue-800">
+                <div class="flex items-center justify-between">
+                    <div>
+                        <p class="text-sm text-gray-600 dark:text-gray-400 mb-1">
+                            总成长值
+                        </p>
+                        <p class="text-3xl font-bold text-blue-600 dark:text-blue-400">
+                            {{ number_format($customers->sum('growth_value')) }}
+                        </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-star text-2xl text-blue-600 dark:text-blue-400"></span>
+                    </div>
+                </div>
+            </div>
+
+            <div class="flex-1 min-w-[200px] bg-gradient-to-br from-green-50 to-green-100 dark:from-green-900/20 dark:to-green-800/20 rounded-xl p-5 border border-green-200 dark:border-green-800">
+                <div class="flex items-center justify-between">
+                    <div>
+                        <p class="text-sm text-gray-600 dark:text-gray-400 mb-1">
+                            平均成长值
+                        </p>
+                        <p class="text-3xl font-bold text-green-600 dark:text-green-400">
+                            {{ $customers->total() > 0 ? number_format(round($customers->sum('growth_value') / $customers->total(), 2)) : 0 }}
+                        </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-chart-line text-2xl text-green-600 dark:text-green-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 p-4 mb-6">
+            <form method="GET" action="{{ route('admin.growth-value.index') }}" class="grid grid-cols-1 md:grid-cols-4 gap-4">
+                {{-- 邮箱查询 --}}
+                <div>
+                    <label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
+                        客户邮箱
+                    </label>
+                    <input
+                        type="text"
+                        name="email"
+                        value="{{ request('email') }}"
+                        placeholder="搜索客户邮箱..."
+                        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>
+                    <label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
+                        最小成长值
+                    </label>
+                    <input
+                        type="number"
+                        name="min_growth_value"
+                        value="{{ request('min_growth_value') }}"
+                        placeholder="0"
+                        min="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"
+                    >
+                </div>
+
+                {{-- 成长值最大值 --}}
+                <div>
+                    <label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
+                        最大成长值
+                    </label>
+                    <input
+                        type="number"
+                        name="max_growth_value"
+                        value="{{ request('max_growth_value') }}"
+                        placeholder="10000"
+                        min="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"
+                    >
+                </div>
+
+                {{-- 操作按钮 --}}
+                <div class="flex items-end gap-2">
+                    <button
+                        type="submit"
+                        class="primary-button flex-1"
+                    >
+                        <span class="icon-search text-lg"></span>
+                        搜索
+                    </button>
+
+                    <a
+                        href="{{ route('admin.growth-value.index') }}"
+                        class="secondary-button"
+                    >
+                        <span class="icon-reset text-lg"></span>
+                        重置
+                    </a>
+                </div>
+            </form>
+        </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">
+                            客户ID
+                        </th>
+                        <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">
+                            客户姓名
+                        </th>
+                        <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">
+                            邮箱
+                        </th>
+                        <th class="px-6 py-3 text-right text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">
+                            成长值
+                        </th>
+                        <th class="px-6 py-3 text-center text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">
+                            等级
+                        </th>
+                        <th class="px-6 py-3 text-center text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">
+                            首单时间
+                        </th>
+                        <th class="px-6 py-3 text-right text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">
+                            操作
+                        </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->name ?? 'N/A' }}
+                            </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 text-right">
+                                <div class="flex items-center justify-end gap-1">
+                                    <span class="text-xl font-bold text-blue-600 dark:text-blue-500">
+                                        {{ number_format($customer->growth_value) }}
+                                    </span>
+                                    <span class="text-xs text-gray-500">分</span>
+                                </div>
+                            </td>
+                            <td class="px-6 py-4 whitespace-nowrap text-center">
+                                @if($customer->customer && $customer->customer->group && $customer->customer->group->growth_level_name)
+                                    <span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-purple-100 text-purple-800 dark:bg-purple-900 dark:text-purple-200">
+                                        {{ $customer->customer->group->growth_level_name }}
+                                    </span>
+                                @else
+                                    <span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-gray-100 text-gray-800 dark:bg-gray-700 dark:text-gray-200">
+                                        V0
+                                    </span>
+                                @endif
+                            </td>
+                            <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-600 dark:text-gray-400 text-center">
+                                {{ $customer->first_order_completed_at ? \Carbon\Carbon::parse($customer->first_order_completed_at)->format('Y-m-d') : '-' }}
+                            </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.growth-value.show', $customer->customer_id) }}"
+                                       class="text-blue-600 hover:text-blue-900 dark:text-blue-400 dark:hover:text-blue-300"
+                                       title="查看详情">
+                                        <span class="icon-view text-lg"></span>
+                                    </a>
+                                    <a href="#"
+                                       onclick="quickAdjust({{ $customer->customer_id }}, '{{ $customer->customer->name ?? '' }}')"
+                                       class="text-green-600 hover:text-green-900 dark:text-green-400 dark:hover:text-green-300"
+                                       title="快速调整">
+                                        <span class="icon-edit text-lg"></span>
+                                    </a>
+                                </div>
+                            </td>
+                        </tr>
+                    @empty
+                        <tr>
+                            <td colspan="7" 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">
+                                            暂无会员成长值数据
+                                        </p>
+                                        <p class="text-sm text-gray-500 dark:text-gray-500">
+                                            当会员完成订单后,将自动记录成长值
+                                        </p>
+                                    </div>
+                                </div>
+                            </td>
+                        </tr>
+                    @endforelse
+                    </tbody>
+                </table>
+            </div>
+
+            {{-- 分页 --}}
+            @if($customers->hasPages())
+                <div class="px-6 py-4 border-t dark:border-gray-800">
+                    {{ $customers->links() }}
+                </div>
+            @endif
+        </div>
+
+        {{-- 调整成长值模态框 --}}
+        <div id="adjustModal" class="hidden fixed inset-0 bg-black bg-opacity-50 z-50 flex items-center justify-center">
+            <div class="bg-white dark:bg-cherry-900 rounded-lg shadow-xl max-w-md w-full mx-4">
+                <div class="px-6 py-4 border-b dark:border-cherry-700">
+                    <h3 class="text-lg font-bold text-gray-900 dark:text-white">
+                        调整成长值
+                    </h3>
+                </div>
+
+                <form id="adjustForm" method="POST">
+                    @csrf
+                    <div class="px-6 py-4 space-y-4">
+                        {{-- 客户信息 --}}
+                        <div>
+                            <label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
+                                客户
+                            </label>
+                            <select
+                                id="customerId"
+                                name="customer_id"
+                                class="border rounded-md px-3 py-2 w-full dark:bg-cherry-800 dark:border-cherry-700"
+                                required
+                            >
+                                <option value="">请选择客户</option>
+                                @foreach($customers as $customer)
+                                    <option value="{{ $customer->customer_id }}">
+                                        {{ $customer->customer->name ?? 'Unknown' }} ({{ $customer->customer->email ?? '' }})
+                                    </option>
+                                @endforeach
+                            </select>
+                        </div>
+
+                        {{-- 调整数量 --}}
+                        <div>
+                            <label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
+                                调整数量
+                            </label>
+                            <input
+                                type="number"
+                                name="amount"
+                                id="amount"
+                                class="border rounded-md px-3 py-2 w-full dark:bg-cherry-800 dark:border-cherry-700"
+                                placeholder="正数增加,负数减少(例如:100 或 -50)"
+                                required
+                            />
+                            <p class="text-xs text-gray-500 dark:text-gray-400 mt-1">
+                                输入正数增加成长值,输入负数减少成长值
+                            </p>
+                        </div>
+
+                        {{-- 调整原因 --}}
+                        <div>
+                            <label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
+                                调整原因
+                            </label>
+                            <textarea
+                                name="description"
+                                id="description"
+                                rows="3"
+                                class="border rounded-md px-3 py-2 w-full dark:bg-cherry-800 dark:border-cherry-700"
+                                placeholder="请输入调整原因..."
+                            ></textarea>
+                        </div>
+                    </div>
+
+                    <div class="px-6 py-4 border-t dark:border-cherry-700 flex justify-end gap-2">
+                        <button
+                            type="button"
+                            onclick="closeAdjustModal()"
+                            class="secondary-button"
+                        >
+                            取消
+                        </button>
+                        <button
+                            type="submit"
+                            class="primary-button"
+                        >
+                            提交
+                        </button>
+                    </div>
+                </form>
+            </div>
+        </div>
+
+        <script>
+            // 打开调整模态框
+            function openAdjustModal() {
+                document.getElementById('adjustModal').classList.remove('hidden');
+                document.getElementById('adjustForm').action = '';
+                document.getElementById('customerId').value = '';
+                document.getElementById('amount').value = '';
+                document.getElementById('description').value = '';
+            }
+
+            // 关闭调整模态框
+            function closeAdjustModal() {
+                document.getElementById('adjustModal').classList.add('hidden');
+            }
+
+            // 快速调整指定客户
+            function quickAdjust(customerId, customerName) {
+                document.getElementById('adjustModal').classList.remove('hidden');
+                document.getElementById('adjustForm').action = "{{ url('admin/reward-points/growth-value') }}/" + customerId + "/adjust";
+                document.getElementById('customerId').value = customerId;
+                document.getElementById('amount').value = '';
+                document.getElementById('description').value = '';
+                document.getElementById('amount').focus();
+            }
+
+            // 表单提交
+            document.getElementById('adjustForm').addEventListener('submit', function(e) {
+                e.preventDefault();
+
+                const formData = new FormData(this);
+                const action = this.action;
+
+                fetch(action, {
+                    method: 'POST',
+                    body: formData,
+                    headers: {
+                        'X-CSRF-TOKEN': '{{ csrf_token() }}',
+                    }
+                })
+                    .then(response => {
+                        if (response.ok || response.redirected) {
+                            alert('调整成功!');
+                            location.reload();
+                        } else {
+                            return response.text().then(text => {
+                                throw new Error(text);
+                            });
+                        }
+                    })
+                    .catch(error => {
+                        console.error('Error:', error);
+                        alert('调整失败:' + error.message);
+                    });
+            });
+
+            // 点击模态框外部关闭
+            document.getElementById('adjustModal').addEventListener('click', function(e) {
+                if (e.target === this) {
+                    closeAdjustModal();
+                }
+            });
+        </script>
+</x-admin::layouts>

+ 154 - 0
packages/Longyi/RewardPoints/src/Resources/views/admin/growth-value/levels.blade.php

@@ -0,0 +1,154 @@
+<x-admin::layouts>
+    <x-slot:title>
+        等级配置
+        </x-slot>
+
+        <div class="flex gap-4 justify-between items-center max-sm:flex-wrap">
+            <p class="text-xl text-gray-800 dark:text-white font-bold">
+                等级配置
+            </p>
+        </div>
+
+        <div class="mt-4 space-y-4">
+            @foreach($levels as $level)
+                <div class="bg-white dark:bg-cherry-900 rounded-lg p-6 shadow">
+                    <div class="flex justify-between items-start mb-4">
+                        <div>
+                            <h3 class="text-xl font-bold flex items-center gap-2">
+                                @if($level->growth_level_icon)
+                                    <img src="{{ $level->growth_level_icon }}" alt="{{ $level->growth_level_name }}" class="w-8 h-8">
+                                @endif
+                                {{ $level->growth_level_name ?? $level->name }}
+                            </h3>
+                            <p class="text-gray-500 dark:text-gray-400 text-sm mt-1">{{ $level->name }}</p>
+                        </div>
+                        <button
+                            onclick="editLevel({{ $level->id }})"
+                            class="primary-button"
+                        >
+                            编辑
+                        </button>
+                    </div>
+
+                    <div class="grid grid-cols-4 gap-4 mb-4">
+                        <div>
+                            <label class="block text-sm text-gray-500 dark:text-gray-400 mb-1">最低成长值</label>
+                            <p class="text-lg font-semibold">{{ number_format($level->min_growth_value) }}</p>
+                        </div>
+                        <div>
+                            <label class="block text-sm text-gray-500 dark:text-gray-400 mb-1">需要首单</label>
+                            <p class="text-lg font-semibold">{{ $level->require_first_order ? '是' : '否' }}</p>
+                        </div>
+                        <div>
+                            <label class="block text-sm text-gray-500 dark:text-gray-400 mb-1">额外折扣</label>
+                            <p class="text-lg font-semibold text-green-600">{{ $level->growth_discount_rate }}%</p>
+                        </div>
+                        <div>
+                            <label class="block text-sm text-gray-500 dark:text-gray-400 mb-1">会员组代码</label>
+                            <p class="text-lg font-semibold">{{ $level->code }}</p>
+                        </div>
+                    </div>
+
+                    @if(!empty($level->growth_benefits))
+                        <div>
+                            <label class="block text-sm text-gray-500 dark:text-gray-400 mb-2">等级权益</label>
+                            <ul class="space-y-1">
+                                @foreach($level->growth_benefits as $benefit)
+                                    <li class="flex items-center gap-2 text-sm">
+                                        <span class="icon-tick text-green-500"></span>
+                                        <span>{{ $benefit }}</span>
+                                    </li>
+                                @endforeach
+                            </ul>
+                        </div>
+                    @endif
+
+                    <!-- 编辑表单(隐藏) -->
+                    <div id="edit-form-{{ $level->id }}" class="hidden mt-4 pt-4 border-t dark:border-cherry-700">
+                        <form onsubmit="saveLevel(event, {{ $level->id }})">
+                            @csrf
+                            <div class="grid grid-cols-2 gap-4 mb-4">
+                                <div>
+                                    <label class="block text-sm font-medium mb-2">最低成长值</label>
+                                    <input type="number" name="min_growth_value" value="{{ $level->min_growth_value }}" class="border rounded-md px-3 py-2 w-full dark:bg-cherry-800 dark:border-cherry-700" required>
+                                </div>
+                                <div>
+                                    <label class="block text-sm font-medium mb-2">等级名称</label>
+                                    <input type="text" name="growth_level_name" value="{{ $level->growth_level_name }}" class="border rounded-md px-3 py-2 w-full dark:bg-cherry-800 dark:border-cherry-700">
+                                </div>
+                            </div>
+
+                            <div class="grid grid-cols-2 gap-4 mb-4">
+                                <div>
+                                    <label class="block text-sm font-medium mb-2">额外折扣率(%)</label>
+                                    <input type="number" name="growth_discount_rate" value="{{ $level->growth_discount_rate }}" min="0" max="100" class="border rounded-md px-3 py-2 w-full dark:bg-cherry-800 dark:border-cherry-700">
+                                </div>
+                                <div>
+                                    <label class="block text-sm font-medium mb-2">需要首单</label>
+                                    <select name="require_first_order" class="border rounded-md px-3 py-2 w-full dark:bg-cherry-800 dark:border-cherry-700">
+                                        <option value="0" {{ !$level->require_first_order ? 'selected' : '' }}>否</option>
+                                        <option value="1" {{ $level->require_first_order ? 'selected' : '' }}>是</option>
+                                    </select>
+                                </div>
+                            </div>
+
+                            <div class="mb-4">
+                                <label class="block text-sm font-medium mb-2">权益说明(每行一个)</label>
+                                <textarea name="growth_benefits_text" rows="3" class="border rounded-md px-3 py-2 w-full dark:bg-cherry-800 dark:border-cherry-700" placeholder="每行输入一个权益...">{{ is_array($level->growth_benefits) ? implode("\n", $level->growth_benefits) : '' }}</textarea>
+                            </div>
+
+                            <div class="flex gap-2">
+                                <button type="submit" class="primary-button">保存</button>
+                                <button type="button" onclick="cancelEdit({{ $level->id }})" class="secondary-button">取消</button>
+                            </div>
+                        </form>
+                    </div>
+                </div>
+            @endforeach
+        </div>
+
+        <script>
+            function editLevel(id) {
+                document.getElementById('edit-form-' + id).classList.remove('hidden');
+            }
+
+            function cancelEdit(id) {
+                document.getElementById('edit-form-' + id).classList.add('hidden');
+            }
+
+            function saveLevel(event, id) {
+                event.preventDefault();
+
+                const form = event.target;
+                const formData = new FormData(form);
+                formData.append('id', id);
+
+                // 将文本转换为数组
+                const benefitsText = formData.get('growth_benefits_text');
+                const benefits = benefitsText.split('\n').filter(line => line.trim());
+                formData.set('growth_benefits', JSON.stringify(benefits));
+
+                fetch('{{ route("admin.growth-value.levels.save") }}', {
+                    method: 'POST',
+                    body: formData,
+                    headers: {
+                        'X-CSRF-TOKEN': '{{ csrf_token() }}',
+                        'Accept': 'application/json',
+                    }
+                })
+                    .then(response => response.json())
+                    .then(data => {
+                        if (data.success) {
+                            alert('保存成功!');
+                            location.reload();
+                        } else {
+                            alert('保存失败:' + (data.message || '未知错误'));
+                        }
+                    })
+                    .catch(error => {
+                        console.error('Error:', error);
+                        alert('保存失败,请重试');
+                    });
+            }
+        </script>
+</x-admin::layouts>

+ 120 - 0
packages/Longyi/RewardPoints/src/Resources/views/admin/growth-value/show.blade.php

@@ -0,0 +1,120 @@
+<x-admin::layouts>
+    <x-slot:title>
+        {{ $customer->name ?? '' }} - 成长值详情
+        </x-slot>
+
+        <div class="flex gap-4 justify-between items-center max-sm:flex-wrap">
+            <div class="flex items-center gap-4">
+                <a href="{{ route('admin.growth-value.index') }}" class="icon-arrow-left text-2xl"></a>
+                <p class="text-xl text-gray-800 dark:text-white font-bold">
+                    {{ $customer->name ?? '' }} - 成长值详情
+                </p>
+            </div>
+
+            <a href="{{ route('admin.growth-value.adjust', $customer->id) }}" class="primary-button">
+                调整成长值
+            </a>
+        </div>
+
+        <!-- 成长值信息卡片 -->
+        <div class="grid grid-cols-3 gap-4 mt-4">
+            <div class="bg-white dark:bg-cherry-900 rounded-lg p-6 shadow">
+                <div class="text-gray-500 dark:text-gray-400 text-sm mb-2">当前成长值</div>
+                <div class="text-3xl font-bold text-blue-600">{{ number_format($growthValueInfo['growth_value']) }}</div>
+            </div>
+
+            <div class="bg-white dark:bg-cherry-900 rounded-lg p-6 shadow">
+                <div class="text-gray-500 dark:text-gray-400 text-sm mb-2">当前等级</div>
+                <div class="text-3xl font-bold text-purple-600">
+                    {{ $growthValueInfo['growth_level_name'] ?? 'V0' }}
+                </div>
+            </div>
+
+            <div class="bg-white dark:bg-cherry-900 rounded-lg p-6 shadow">
+                <div class="text-gray-500 dark:text-gray-400 text-sm mb-2">折扣率</div>
+                <div class="text-3xl font-bold text-green-600">
+                    {{ $growthValueInfo['growth_discount_rate'] ?? 0 }}%
+                </div>
+            </div>
+        </div>
+
+        <!-- 下一等级信息 -->
+        @if($growthValueInfo['next_level'])
+            <div class="bg-gradient-to-r from-purple-50 to-blue-50 dark:from-cherry-800 dark:to-cherry-900 rounded-lg p-6 mt-4">
+                <h3 class="text-lg font-bold mb-4">下一等级:{{ $growthValueInfo['next_level']['growth_level_name'] }}</h3>
+                <div class="grid grid-cols-2 gap-4">
+                    <div>
+                        <p class="text-sm text-gray-600 dark:text-gray-400">需要成长值</p>
+                        <p class="text-2xl font-bold">{{ number_format($growthValueInfo['next_level']['min_growth_value']) }}</p>
+                    </div>
+                    <div>
+                        <p class="text-sm text-gray-600 dark:text-gray-400">还需成长值</p>
+                        <p class="text-2xl font-bold text-orange-600">{{ number_format($growthValueInfo['points_to_next_level']) }}</p>
+                    </div>
+                </div>
+            </div>
+        @endif
+
+        <!-- 权益说明 -->
+        @if(!empty($growthValueInfo['growth_benefits']))
+            <div class="bg-white dark:bg-cherry-900 rounded-lg p-6 mt-4 shadow">
+                <h3 class="text-lg font-bold mb-4">当前等级权益</h3>
+                <ul class="space-y-2">
+                    @foreach($growthValueInfo['growth_benefits'] as $benefit)
+                        <li class="flex items-center gap-2">
+                            <span class="icon-tick text-green-500"></span>
+                            <span>{{ $benefit }}</span>
+                        </li>
+                    @endforeach
+                </ul>
+            </div>
+        @endif
+
+        <!-- 成长值历史 -->
+        <div class="bg-white dark:bg-cherry-900 rounded-lg p-6 mt-4 shadow">
+            <h3 class="text-lg font-bold mb-4">成长值历史记录</h3>
+
+            <table class="w-full">
+                <thead>
+                <tr class="border-b dark:border-cherry-700">
+                    <th class="text-left py-3 px-4">日期</th>
+                    <th class="text-left py-3 px-4">类型</th>
+                    <th class="text-right py-3 px-4">获得成长值</th>
+                    <th class="text-right py-3 px-4">累计成长值</th>
+                    <th class="text-left py-3 px-4">描述</th>
+                </tr>
+                </thead>
+                <tbody>
+                @forelse($history as $item)
+                    <tr class="border-b dark:border-cherry-700">
+                        <td class="py-3 px-4">{{ $item->created_at->format('Y-m-d H:i:s') }}</td>
+                        <td class="py-3 px-4">
+                            @if($item->event_type === 'order')
+                                <span class="badge badge-success">订单</span>
+                            @elseif($item->event_type === 'admin_adjust')
+                                <span class="badge badge-warning">管理员调整</span>
+                            @else
+                                <span class="badge badge-info">{{ $item->event_type }}</span>
+                            @endif
+                        </td>
+                        <td class="text-right py-3 px-4">
+                        <span class="{{ $item->growth_value_earned >= 0 ? 'text-green-600' : 'text-red-600' }}">
+                            {{ $item->growth_value_earned >= 0 ? '+' : '' }}{{ number_format($item->growth_value_earned) }}
+                        </span>
+                        </td>
+                        <td class="text-right py-3 px-4">{{ number_format($item->total_growth_value) }}</td>
+                        <td class="py-3 px-4">{{ $item->description }}</td>
+                    </tr>
+                @empty
+                    <tr>
+                        <td colspan="5" class="text-center py-8 text-gray-500">暂无成长值历史记录</td>
+                    </tr>
+                @endforelse
+                </tbody>
+            </table>
+
+            <div class="mt-4">
+                {{ $history->links() }}
+            </div>
+        </div>
+</x-admin::layouts>

+ 41 - 16
packages/Longyi/RewardPoints/src/Routes/routes.php

@@ -1,6 +1,7 @@
 <?php
 
 use Illuminate\Support\Facades\Route;
+use Longyi\RewardPoints\Http\Controllers\Admin\GrowthValueController;
 
 // 前台路由 - 客户中心
 Route::group(['middleware' => ['web', 'customer'], 'prefix' => 'customer'], function () {
@@ -131,47 +132,71 @@ Route::group(['middleware' => ['web', 'admin'], 'prefix' => 'admin/reward-points
     ]);
 
     // ========== 客户管理 - 动态路由 ==========
-    // 客户列表(放在动态路由前面也可以,但为了清晰,放在这里)
     Route::get('customers', [
         'as' => 'admin.reward-points.customers.index',
         'uses' => 'Longyi\RewardPoints\Http\Controllers\Admin\CustomerController@index'
     ]);
 
-    // 客户详情(动态参数路由,必须放在所有静态路由之后)
     Route::get('customers/{customerId}', [
         'as' => 'admin.reward-points.customers.show',
         'uses' => 'Longyi\RewardPoints\Http\Controllers\Admin\CustomerController@show'
     ]);
 
-    // ========== 报表管理 - 静态路由 ==========
-    Route::get('reports/export', [
-        'as' => 'admin.reward-points.reports.export',
-        'uses' => 'Longyi\RewardPoints\Http\Controllers\Admin\ReportController@export'
-    ]);
-// ========== 报表管理 - 动态路由 ==========
+    // ========== 报表管理 ==========
     Route::get('reports', [
         'as' => 'admin.reward-points.reports.index',
         'uses' => 'Longyi\RewardPoints\Http\Controllers\Admin\ReportController@index'
     ]);
-// 积分获取记录专用路由
+
+    Route::get('reports/export', [
+        'as' => 'admin.reward-points.reports.export',
+        'uses' => 'Longyi\RewardPoints\Http\Controllers\Admin\ReportController@export'
+    ]);
+
+    // 积分获取记录专用路由
     Route::get('transactions/earned', [
         'as' => 'admin.reward-points.transactions.earned',
         'uses' => 'Longyi\RewardPoints\Http\Controllers\Admin\TransactionController@earnedIndex'
     ]);
+
     Route::get('transactions', [
         'as' => 'admin.reward-points.transactions.index',
         'uses' => 'Longyi\RewardPoints\Http\Controllers\Admin\TransactionController@index'
     ]);
+
     Route::get('transactions/export', [
         'as' => 'admin.reward-points.transactions.export',
         'uses' => 'Longyi\RewardPoints\Http\Controllers\Admin\TransactionController@export'
     ]);
-    //成长值
-    Route::get('/growth-value', [GrowthValueController::class, 'index'])->name('admin.growth-value.index');
-    Route::get('/growth-value/{customerId}', [GrowthValueController::class, 'show'])->name('admin.growth-value.show');
-    Route::post('/growth-value/{customerId}/adjust', [GrowthValueController::class, 'adjust'])->name('admin.growth-value.adjust');
 
-    Route::get('/growth-value-levels', [GrowthValueController::class, 'levels'])->name('admin.growth-value.levels');
-    Route::post('/growth-value-levels/save', [GrowthValueController::class, 'saveLevel'])->name('admin.growth-value.levels.save');
-    Route::delete('/growth-value-levels/{id}', [GrowthValueController::class, 'deleteLevel'])->name('admin.growth-value.levels.delete');
+    // ========== 成长值管理路由 ==========
+    Route::get('growth-value', [
+        'as' => 'admin.growth-value.index',
+        'uses' => 'Longyi\RewardPoints\Http\Controllers\Admin\GrowthValueController@index'
+    ]);
+
+    Route::get('growth-value/{customerId}', [
+        'as' => 'admin.growth-value.show',
+        'uses' => 'Longyi\RewardPoints\Http\Controllers\Admin\GrowthValueController@show'
+    ]);
+
+    Route::post('growth-value/{customerId}/adjust', [
+        'as' => 'admin.growth-value.adjust',
+        'uses' => 'Longyi\RewardPoints\Http\Controllers\Admin\GrowthValueController@adjust'
+    ]);
+
+    Route::get('growth-value-levels', [
+        'as' => 'admin.growth-value.levels',
+        'uses' => 'Longyi\RewardPoints\Http\Controllers\Admin\GrowthValueController@levels'
+    ]);
+
+    Route::post('growth-value-levels/save', [
+        'as' => 'admin.growth-value.levels.save',
+        'uses' => 'Longyi\RewardPoints\Http\Controllers\Admin\GrowthValueController@saveLevel'
+    ]);
+
+    Route::delete('growth-value-levels/{id}', [
+        'as' => 'admin.growth-value.levels.delete',
+        'uses' => 'Longyi\RewardPoints\Http\Controllers\Admin\GrowthValueController@deleteLevel'
+    ]);
 });

+ 28 - 71
packages/Longyi/RewardPoints/src/Services/GrowthValueService.php

@@ -13,7 +13,7 @@ use Illuminate\Support\Facades\Log;
 class GrowthValueService
 {
     /**
-     * 处理订单完成事件,增加成长值并检查升级
+     * 处理订单完成事件,增加成长值
      */
     public function handleOrderCompleted($order)
     {
@@ -30,12 +30,9 @@ class GrowthValueService
                     ['customer_id' => $customerId],
                     [
                         'growth_value' => 0,
-                        'growth_level' => 'V0',
-                        'level_updated_at' => now(),
                     ]
                 );
 
-                $levelBefore = $growthValueCustomer->growth_level;
                 $hasFirstOrder = !is_null($growthValueCustomer->first_order_completed_at);
 
                 if (!$hasFirstOrder) {
@@ -56,14 +53,6 @@ class GrowthValueService
                     $growthValueCustomer->growth_value_expires_at = $expiresAt;
                 }
 
-                $newLevel = GrowthValueLevel::getLevelByGrowthValue($newGrowthValue, true);
-                $levelAfter = $newLevel ? $newLevel->level_code : 'V0';
-
-                if ($levelBefore !== $levelAfter) {
-                    $growthValueCustomer->growth_level = $levelAfter;
-                    $growthValueCustomer->level_updated_at = now();
-                }
-
                 $growthValueCustomer->save();
 
                 GrowthValueHistory::create([
@@ -72,22 +61,18 @@ class GrowthValueService
                     'order_amount' => $orderAmount,
                     'growth_value_earned' => $earnedGrowthValue,
                     'total_growth_value' => $newGrowthValue,
-                    'level_before' => $levelBefore,
-                    'level_after' => $levelAfter,
                     'event_type' => GrowthValueHistory::EVENT_TYPE_ORDER,
                     'description' => "订单 #{$order->increment_id} 完成,获得 {$earnedGrowthValue} 成长值",
                     'expires_at' => $expiresAt,
                     'created_at' => now(),
                 ]);
 
-                Log::info('Growth value added and level checked', [
+                Log::info('Growth value added', [
                     'customer_id' => $customerId,
                     'order_id' => $order->id,
                     'order_amount' => $orderAmount,
                     'earned_growth_value' => $earnedGrowthValue,
                     'new_total' => $newGrowthValue,
-                    'level_before' => $levelBefore,
-                    'level_after' => $levelAfter,
                 ]);
             });
         } catch (\Exception $e) {
@@ -151,16 +136,12 @@ class GrowthValueService
         foreach ($expiredRecords as $record) {
             try {
                 DB::transaction(function () use ($record) {
-                    $levelBefore = $record->growth_level;
-
                     GrowthValueHistory::create([
                         'customer_id' => $record->customer_id,
                         'order_id' => null,
                         'order_amount' => 0,
                         'growth_value_earned' => -$record->growth_value,
                         'total_growth_value' => 0,
-                        'level_before' => $levelBefore,
-                        'level_after' => 'V0',
                         'event_type' => GrowthValueHistory::EVENT_TYPE_EXPIRATION,
                         'description' => '成长值过期清零',
                         'expires_at' => null,
@@ -168,15 +149,12 @@ class GrowthValueService
                     ]);
 
                     $record->growth_value = 0;
-                    $record->growth_level = 'V0';
-                    $record->level_updated_at = now();
                     $record->growth_value_expires_at = null;
                     $record->save();
 
-                    Log::info('Growth value expired and level reset', [
+                    Log::info('Growth value expired', [
                         'customer_id' => $record->customer_id,
                         'expired_value' => $record->growth_value,
-                        'level_before' => $levelBefore,
                     ]);
                 });
             } catch (\Exception $e) {
@@ -193,51 +171,48 @@ class GrowthValueService
      */
     public function getCustomerGrowthValue($customerId)
     {
-        $growthValueCustomer = GrowthValueCustomer::with('levelConfig')->where('customer_id', $customerId)->first();
-        $customer = \Webkul\Customer\Models\Customer::find($customerId);
+        $growthValueCustomer = GrowthValueCustomer::where('customer_id', $customerId)->first();
+        $customer = \Webkul\Customer\Models\Customer::with('group')->find($customerId);
 
         if (!$growthValueCustomer) {
-            $defaultLevel = GrowthValueLevel::where('level_code', 'V0')->first();
+            $defaultGroup = GrowthValueLevel::where('code', 'general')->first();
             return [
                 'growth_value' => 0,
-                'growth_level' => 'V0',
-                'level_name' => $defaultLevel ? $defaultLevel->level_name : '普通会员',
-                'level_icon' => $defaultLevel ? $defaultLevel->icon : null,
-                'discount_rate' => $defaultLevel ? $defaultLevel->discount_rate : 0,
-                'benefits' => $defaultLevel ? $defaultLevel->benefits : [],
+                'current_group' => $customer ? $customer->group : null,
+                'growth_level_name' => $defaultGroup ? $defaultGroup->growth_level_name : 'V0',
+                'growth_discount_rate' => $defaultGroup ? $defaultGroup->growth_discount_rate : 0,
+                'growth_benefits' => $defaultGroup ? $defaultGroup->growth_benefits : [],
                 'next_level' => null,
                 'points_to_next_level' => null,
                 'expires_at' => null,
                 'first_order_completed' => false,
-                'customer_group' => $customer ? $customer->group : null,
             ];
         }
 
-        $levelConfig = $growthValueCustomer->levelConfig;
+        $currentGroup = $customer ? $customer->group : null;
 
-        $nextLevel = GrowthValueLevel::getNextLevel(
-            $growthValueCustomer->growth_level,
+        $nextGroup = GrowthValueLevel::getNextLevel(
+            $customer ? $customer->customer_group_id : null,
             !is_null($growthValueCustomer->first_order_completed_at)
         );
 
         return [
             'growth_value' => $growthValueCustomer->growth_value,
-            'growth_level' => $growthValueCustomer->growth_level,
-            'level_name' => $levelConfig ? $levelConfig->level_name : '普通会员',
-            'level_icon' => $levelConfig ? $levelConfig->icon : null,
-            'discount_rate' => $levelConfig ? $levelConfig->discount_rate : 0,
-            'benefits' => $levelConfig ? $levelConfig->benefits : [],
-            'next_level' => $nextLevel ? [
-                'level_code' => $nextLevel->level_code,
-                'level_name' => $nextLevel->level_name,
-                'min_growth_value' => $nextLevel->min_growth_value,
-                'icon' => $nextLevel->icon,
+            'current_group' => $currentGroup,
+            'growth_level_name' => $currentGroup ? $currentGroup->growth_level_name : 'V0',
+            'growth_discount_rate' => $currentGroup ? $currentGroup->growth_discount_rate : 0,
+            'growth_benefits' => $currentGroup ? $currentGroup->growth_benefits : [],
+            'growth_level_icon' => $currentGroup ? $currentGroup->growth_level_icon : null,
+            'next_level' => $nextGroup ? [
+                'group_id' => $nextGroup->id,
+                'group_name' => $nextGroup->name,
+                'growth_level_name' => $nextGroup->growth_level_name,
+                'min_growth_value' => $nextGroup->min_growth_value,
+                'icon' => $nextGroup->growth_level_icon,
             ] : null,
-            'points_to_next_level' => $nextLevel ? ($nextLevel->min_growth_value - $growthValueCustomer->growth_value) : null,
+            'points_to_next_level' => $nextGroup ? ($nextGroup->min_growth_value - $growthValueCustomer->growth_value) : null,
             'expires_at' => $growthValueCustomer->growth_value_expires_at,
             'first_order_completed' => !is_null($growthValueCustomer->first_order_completed_at),
-            'customer_group' => $customer ? $customer->group : null,
-            'level_updated_at' => $growthValueCustomer->level_updated_at,
         ];
     }
 
@@ -252,24 +227,12 @@ class GrowthValueService
                     ['customer_id' => $customerId],
                     [
                         'growth_value' => 0,
-                        'growth_level' => 'V0',
-                        'level_updated_at' => now(),
                     ]
                 );
 
-                $levelBefore = $growthValueCustomer->growth_level;
                 $currentGrowthValue = $growthValueCustomer->growth_value;
                 $newGrowthValue = max(0, $currentGrowthValue + $amount);
 
-                $hasFirstOrder = !is_null($growthValueCustomer->first_order_completed_at);
-                $newLevel = GrowthValueLevel::getLevelByGrowthValue($newGrowthValue, $hasFirstOrder);
-                $levelAfter = $newLevel ? $newLevel->level_code : 'V0';
-
-                if ($levelBefore !== $levelAfter) {
-                    $growthValueCustomer->growth_level = $levelAfter;
-                    $growthValueCustomer->level_updated_at = now();
-                }
-
                 $growthValueCustomer->growth_value = $newGrowthValue;
                 $growthValueCustomer->save();
 
@@ -279,8 +242,6 @@ class GrowthValueService
                     'order_amount' => 0,
                     'growth_value_earned' => $amount,
                     'total_growth_value' => $newGrowthValue,
-                    'level_before' => $levelBefore,
-                    'level_after' => $levelAfter,
                     'event_type' => GrowthValueHistory::EVENT_TYPE_ADMIN_ADJUST,
                     'description' => $description,
                     'expires_at' => null,
@@ -291,8 +252,6 @@ class GrowthValueService
                     'customer_id' => $customerId,
                     'amount' => $amount,
                     'new_total' => $newGrowthValue,
-                    'level_before' => $levelBefore,
-                    'level_after' => $levelAfter,
                 ]);
 
                 return $history;
@@ -308,12 +267,10 @@ class GrowthValueService
     }
 
     /**
-     * 获取所有等级配置
+     * 获取所有配置了成长值的会员组
      */
-    public function getAllLevels()
+    public function getAllGrowthLevels()
     {
-        return GrowthValueLevel::where('is_active', true)
-            ->orderBy('sort_order')
-            ->get();
+        return GrowthValueLevel::getAllGrowthLevels();
     }
 }