where('status', 1)->value('goods_id')) ?: 195; } try { setupTestUserMoney($userMoney); $area = setupTestAddresses($goodsId); echo "\n配送区域内地址: {$area['province_name']}{$area['city_name']}{$area['area_name']}\n"; echo "测试用户余额: {$userMoney} 元\n"; echo "请重新进入下单页或刷新后再提交订单。\n"; } catch (\Throwable $e) { fwrite(STDERR, "失败: " . $e->getMessage() . "\n"); exit(1); } exit(0); } Db::startTrans(); try { setupCommissionConfig(); setupAgentLevels(); setupUsersAndAgents(); setupTestUserMoney($userMoney); $goodsId = setupCommissionGoods($goodsId); if ($goodsId) { setupTestAddresses($goodsId); } Db::commit(); } catch (\Throwable $e) { Db::rollback(); fwrite(STDERR, "失败: " . $e->getMessage() . "\n"); exit(1); } echo "\n========================================\n"; echo " 初始化完成 · 登录信息如下\n"; echo "========================================\n\n"; echo "小程序登录:我的 → 账号登录\n"; echo "统一密码:" . TEST_PASSWORD . "\n"; echo "测试余额:{$userMoney} 元(可用 --money= 自定义)\n\n"; $users = getTestUserDefs(); foreach ($users as $u) { echo sprintf(" [%s] %s\n", $u['role'], $u['nickname']); echo sprintf(" 手机号: %s(推荐,账号登录填这个)\n", $u['mobile']); echo sprintf(" 用户名: %s\n", $u['username']); echo sprintf(" 用户ID: %d\n\n", $u['id']); } echo "推荐验证账号:\n"; echo " 首购场景 → 用【测试D-买家】19900000004 下单\n"; echo " 自购场景 → 用【测试C-直推】19900000003 自己下单\n"; echo " 复购场景 → D 先下一单,再下一单\n\n"; if ($goodsId) { $goods = Db::name('shopro_goods')->where('id', $goodsId)->field('id,title,price')->find(); echo "测试商品: ID={$goodsId} {$goods['title']} 价格={$goods['price']}元\n"; echo "(请用该商品下单,单价1000左右最易对照预期佣金)\n\n"; $addr = Db::name('shopro_user_address')->where('user_id', 900004)->where('is_default', '1')->find(); if ($addr) { echo "默认收货地址(D): {$addr['province_name']}{$addr['city_name']}{$addr['area_name']}{$addr['address']}\n\n"; } } echo "支付后验证:\n"; echo " php addons/shopro/tests/commission_verify.php verify-item {订单明细ID}\n\n"; echo "关系链: A(三级) ← B(二级) ← C(直推) ← D(买家)\n"; function getTestUserDefs() { return [ ['id' => 900001, 'username' => 'test_agent_a', 'nickname' => '测试A-三级', 'mobile' => '19900000001', 'parent' => 0, 'role' => '三级分销商A'], ['id' => 900002, 'username' => 'test_agent_b', 'nickname' => '测试B-二级', 'mobile' => '19900000002', 'parent' => 900001, 'role' => '二级分销商B'], ['id' => 900003, 'username' => 'test_agent_c', 'nickname' => '测试C-直推', 'mobile' => '19900000003', 'parent' => 900002, 'role' => '一级分销商C'], ['id' => 900004, 'username' => 'test_buyer_d', 'nickname' => '测试D-买家', 'mobile' => '19900000004', 'parent' => 900003, 'role' => '买家D'], ]; } function setupCommissionConfig() { $pairs = [ 30 => ['chain_commission_enable', '1', 'basic', '关系链分佣开关'], 31 => ['differential_commission_enable', '1', 'basic', '级差奖开关'], ]; foreach ($pairs as $id => $row) { $exists = Db::name('shopro_commission_config')->where('id', $id)->find(); if ($exists) { Db::name('shopro_commission_config')->where('id', $id)->update(['value' => $row[1]]); } else { Db::name('shopro_commission_config')->insert([ 'id' => $id, 'name' => $row[0], 'value' => $row[1], 'group' => $row[2], 'description' => $row[3], ]); } } $updates = [ 'management_award_enable' => '1', 'repurchase_referrer_enable' => '1', 'repurchase_self_enable' => '1', 'repurchase_self_type' => 'fixed', 'repurchase_self_amount' => '5', 'chain_commission_enable' => '1', 'differential_commission_enable' => '1', 'commission_level' => '3', 'self_buy' => '1', 'commission_price_type' => 'goods_price', 'commission_event' => 'payed', 'agent_check' => '0', ]; foreach ($updates as $name => $value) { Db::name('shopro_commission_config')->where('name', $name)->update(['value' => $value]); } echo "[OK] 分销配置已更新(三级、内购开、支付后结算、商品价、免审核)\n"; } function setupAgentLevels() { $levels = [ 1 => '{"commission_1":"10.00","commission_2":"0.00","commission_3":"0.00","differential_amount":"40","management_rate":"5"}', 2 => '{"commission_1":"10.00","commission_2":"5.00","commission_3":"0.00","differential_amount":"80","management_rate":"3"}', 3 => '{"commission_1":"10.00","commission_2":"5.00","commission_3":"3.00","differential_amount":"120","management_rate":"2"}', ]; foreach ($levels as $level => $rules) { $row = Db::name('shopro_commission_agent_level')->where('level', $level)->find(); if ($row) { Db::name('shopro_commission_agent_level')->where('level', $level)->update(['commission_rules' => $rules]); } else { Db::name('shopro_commission_agent_level')->insert([ 'level' => $level, 'name' => '测试等级' . $level, 'image' => '', 'commission_rules' => $rules, 'upgrade_type' => 0, 'upgrade_rules' => '{}', ]); } } echo "[OK] 分销商等级档位已设置(L1:40/5% L2:80/3% L3:120/2%)\n"; } function setupUsersAndAgents() { $ts = time(); $host = 'test.local'; $agents = [ 900001 => ['level' => 3, 'parent_agent_id' => 0], 900002 => ['level' => 2, 'parent_agent_id' => 900001], 900003 => ['level' => 1, 'parent_agent_id' => 900002], ]; foreach (getTestUserDefs() as $u) { $conflict = Db::name('user')->where('mobile', $u['mobile'])->where('id', '<>', $u['id'])->find(); if ($conflict) { Db::name('user')->where('id', $conflict['id'])->update([ 'mobile' => $u['mobile'] . '_old' . $conflict['id'], 'updatetime' => $ts, ]); echo "[WARN] 手机号 {$u['mobile']} 曾被用户 {$conflict['id']} 占用,已改号\n"; } $exists = Db::name('user')->where('id', $u['id'])->find(); $base = [ 'username' => $u['username'], 'nickname' => $u['nickname'], 'password' => TEST_PASSWORD_HASH, 'salt' => TEST_SALT, 'mobile' => $u['mobile'], 'email' => $u['mobile'] . '@' . $host, 'parent_user_id' => $u['parent'], 'status' => 'normal', 'updatetime' => $ts, 'level' => 1, 'score' => 0, 'total_consume' => 0, ]; if ($exists) { Db::name('user')->where('id', $u['id'])->update($base); echo "[UPD] 用户 {$u['nickname']} ({$u['id']})\n"; } else { $base['id'] = $u['id']; $base['createtime'] = $ts; $base['jointime'] = $ts; $base['joinip'] = '127.0.0.1'; $base['loginip'] = '127.0.0.1'; $base['logintime'] = $ts; $base['prevtime'] = $ts; Db::name('user')->insert($base); echo "[NEW] 用户 {$u['nickname']} ({$u['id']})\n"; } } foreach ($agents as $userId => $agent) { $exists = Db::name('shopro_commission_agent')->where('user_id', $userId)->find(); $data = [ 'level' => $agent['level'], 'parent_agent_id' => $agent['parent_agent_id'], 'status' => 'normal', 'info_status' => 1, 'becometime' => $ts, 'updatetime' => $ts, ]; if ($exists) { Db::name('shopro_commission_agent')->where('user_id', $userId)->update($data); } else { $data['user_id'] = $userId; $data['createtime'] = $ts; Db::name('shopro_commission_agent')->insert($data); } } echo "[OK] 分销商 A/B/C 已就绪,D 为普通买家\n"; } function setupTestUserMoney($money) { $money = number_format(floatval($money), 2, '.', ''); $ts = time(); foreach (getTestUserDefs() as $u) { $exists = Db::name('user')->where('id', $u['id'])->find(); if (!$exists) { echo "[SKIP] 用户 {$u['id']} 不存在,跳过充值\n"; continue; } Db::name('user')->where('id', $u['id'])->update([ 'money' => $money, 'updatetime' => $ts, ]); echo "[OK] 余额 {$u['nickname']} ({$u['id']}) = {$money} 元\n"; } } function setupCommissionGoods($goodsId) { if (!$goodsId) { $row = Db::name('shopro_commission_goods') ->alias('cg') ->join('shopro_goods g', 'g.id = cg.goods_id') ->where('cg.status', 1) ->where('cg.differential_enable', 1) ->field('cg.goods_id, g.title') ->find(); if ($row) { $goodsId = intval($row['goods_id']); echo "[OK] 使用已有分销商品 ID={$goodsId} {$row['title']}\n"; } } if (!$goodsId) { $row = Db::name('shopro_goods')->where('status', 'up')->order('id desc')->field('id,title,price')->find(); if ($row) { $goodsId = intval($row['id']); echo "[INFO] 自动选用上架商品 ID={$goodsId} {$row['title']}\n"; } } if (!$goodsId) { echo "[WARN] 未找到可用商品,请手动在后台配置分销商品,或执行: --goods-id=商品ID\n"; return 0; } $exists = Db::name('shopro_commission_goods')->where('goods_id', $goodsId)->find(); $data = [ 'status' => 1, 'self_rules' => 0, 'commission_rules' => '{}', 'commission_config' => '', 'commission_order_status' => 1, 'differential_enable' => 1, 'management_enable' => 1, 'repurchase_enable' => 1, ]; if ($exists) { Db::name('shopro_commission_goods')->where('goods_id', $goodsId)->update($data); } else { $data['goods_id'] = $goodsId; Db::name('shopro_commission_goods')->insert($data); } echo "[OK] 商品 {$goodsId} 已开启:参与分销 + 级差 + 管理奖 + 复购返现\n"; return $goodsId; } function setupTestAddresses($goodsId) { $area = resolveDeliveryAreaForGoods($goodsId); if (!$area) { throw new \Exception('无法解析商品配送区域,请检查运费模板'); } $ts = time(); foreach (getTestUserDefs() as $u) { $exists = Db::name('shopro_user_address') ->where('user_id', $u['id']) ->where(function ($query) { $query->whereNull('deletetime')->whereOr('deletetime', 0); }) ->order('id asc') ->find(); $data = [ 'is_default' => '1', 'consignee' => str_replace('测试', '', $u['nickname']), 'phone' => $u['mobile'], 'province_name' => $area['province_name'], 'city_name' => $area['city_name'], 'area_name' => $area['area_name'], 'address' => '分销测试地址1号', 'province_id' => $area['province_id'], 'city_id' => $area['city_id'], 'area_id' => $area['area_id'], 'updatetime' => $ts, ]; if ($exists) { Db::name('shopro_user_address')->where('user_id', $u['id'])->update(['is_default' => '0']); Db::name('shopro_user_address')->where('id', $exists['id'])->update($data); echo "[UPD] 地址 {$u['nickname']} -> {$area['province_name']}{$area['city_name']}{$area['area_name']}\n"; } else { $data['user_id'] = $u['id']; $data['createtime'] = $ts; Db::name('shopro_user_address')->insert($data); echo "[NEW] 地址 {$u['nickname']} -> {$area['province_name']}{$area['city_name']}{$area['area_name']}\n"; } } echo "[OK] 测试用户默认收货地址已写入(与商品运费模板配送范围一致)\n"; return $area; } function resolveDeliveryAreaForGoods($goodsId) { $goods = Db::name('shopro_goods')->where('id', $goodsId)->field('dispatch_ids,dispatch_type')->find(); if ($goods && strpos($goods['dispatch_type'] ?? '', 'express') !== false && !empty($goods['dispatch_ids'])) { $dispatchIds = array_filter(explode(',', $goods['dispatch_ids'])); $dispatch = Db::name('shopro_dispatch')->where('type', 'express')->where('id', 'in', $dispatchIds)->find(); if ($dispatch && !empty($dispatch['type_ids'])) { $expressIds = array_filter(explode(',', $dispatch['type_ids'])); $expressList = Db::name('shopro_dispatch_express') ->where('id', 'in', $expressIds) ->where(function ($query) { $query->whereNull('deletetime')->whereOr('deletetime', 0); }) ->order('weigh desc,id asc') ->select(); foreach ($expressList as $express) { $area = pickAreaFromExpress($express); if ($area) { return $area; } } } } // 默认:贵州省贵阳市南明区(多数本地店铺配送范围) return buildAreaInfo(520102); } function pickAreaFromExpress($express) { foreach (['area_ids', 'city_ids', 'province_ids'] as $field) { if (empty($express[$field])) { continue; } $ids = array_filter(array_map('trim', explode(',', $express[$field]))); foreach ($ids as $id) { $id = intval($id); if ($id <= 0) { continue; } $row = Db::name('shopro_area')->where('id', $id)->find(); if (!$row) { continue; } if (intval($row['level']) === 3) { $area = buildAreaInfo($id); if ($area) { return $area; } } if (intval($row['level']) === 2) { $areaRow = Db::name('shopro_area')->where('pid', $id)->where('level', 3)->order('id asc')->find(); if ($areaRow) { $area = buildAreaInfo($areaRow['id']); if ($area) { return $area; } } } if (intval($row['level']) === 1) { $city = Db::name('shopro_area')->where('pid', $id)->where('level', 2)->order('id asc')->find(); if ($city) { $areaRow = Db::name('shopro_area')->where('pid', $city['id'])->where('level', 3)->order('id asc')->find(); if ($areaRow) { $area = buildAreaInfo($areaRow['id']); if ($area) { return $area; } } } } } } return null; } function buildAreaInfo($areaId) { $area = Db::name('shopro_area')->where('id', $areaId)->find(); if (!$area || intval($area['level']) !== 3) { return null; } $city = Db::name('shopro_area')->where('id', $area['pid'])->find(); if (!$city) { return null; } $province = Db::name('shopro_area')->where('id', $city['pid'])->find(); if (!$province) { return null; } return [ 'province_id' => intval($province['id']), 'province_name' => $province['name'], 'city_id' => intval($city['id']), 'city_name' => $city['name'], 'area_id' => intval($area['id']), 'area_name' => $area['name'], ]; }