load(); \support\App::loadAllConfig(['route']); date_default_timezone_set('Asia/Shanghai'); use plugin\saiadmin\app\model\water\{WaterModel,WaterAgent,WaterEnterprise,WaterOperator,WaterLedger,WaterAccount,WaterOrder,WaterDelivery,WaterSku,WaterDevice}; use plugin\saiadmin\app\service\{WaterBusiness,WaterEnterpriseDashboard}; const CUSTOMER_DEMO_BATCH = 'TEST-WATER-AGENT-CUSTOMERS-20260916'; const CUSTOMER_DEMO_TAG = '【代理测试0916】'; function ensure(bool $ok,string $message): void { if (!$ok) throw new RuntimeException($message); } function protectedData(): array { $hashes=[]; foreach ([WaterAgent::class,WaterAccount::class,WaterOrder::class,WaterDelivery::class,WaterSku::class,WaterDevice::class] as $model) { $hashes[$model]=hash('sha256',serialize($model::query()->orderBy('id')->get()->toArray())); } return $hashes; } $samples=['星澜科技','青禾创意','云帆商贸','沐光设计','森屿办公','远航服务']; $agents=WaterAgent::query()->where('status',1)->orderBy('id')->limit(3)->get(['id','name','region'])->toArray(); $result=['applied'=>false,'agents'=>$agents,'planned_customers'=>count($samples),'tag'=>CUSTOMER_DEMO_TAG]; if (in_array('--apply',$argv,true)) { $result=WaterModel::transaction(function () use ($samples,$agents): array { ensure((bool)WaterOperator::query()->where('id',1)->lockForUpdate()->first(),'缺少操作账号'); if (WaterLedger::query()->where(['kind'=>'demo_seed','reference'=>CUSTOMER_DEMO_BATCH])->exists()) return ['applied'=>true,'replayed'=>true]; ensure(count($agents)>0,'没有启用代理,无法创建代理客户'); ensure(!WaterEnterprise::query()->where('name','like',CUSTOMER_DEMO_TAG.'%')->exists(),'存在同名批次,请先核对,禁止覆盖'); $before=protectedData(); $old=WaterEnterprise::query()->orderBy('id')->get()->toArray(); $oldIds=array_column($old,'id'); $business=new WaterBusiness(); $dashboard=new WaterEnterpriseDashboard(); $ids=[]; $byAgent=[]; foreach ($samples as $index=>$name) { $agent=$agents[intdiv($index,2)%count($agents)]; $id=$business->save('enterprise',[ 'name'=>CUSTOMER_DEMO_TAG.$name,'contact'=>'测试联系人'.($index+1),'phone'=>'TEST-0916-'.str_pad((string)($index+1),2,'0',STR_PAD_LEFT), 'agent_id'=>(int)$agent['id'],'region'=>$agent['region'] ?: '测试区域', 'address'=>'【虚构测试地址,请勿实际配送】代理客户测试园区'.($index+1).'号', 'longitude'=>null,'latitude'=>null,'status'=>$index===5?2:1, ],1)['id']; $ids[]=$id; $byAgent[(int)$agent['id']][]=$id; $detail=$dashboard->detail($id); ensure($detail['enterprise']['agent_id']===(int)$agent['id'] && $detail['enterprise']['agent_name']===$agent['name'],'详情代理关联不正确'); ensure($detail['accounts']===[] && $detail['orders']===[],'档案测试不应生成账户或订单'); } $page=$dashboard->dashboard(['keyword'=>CUSTOMER_DEMO_TAG,'limit'=>6]); ensure($page['list']['total']===6 && count($page['list']['data'])===6,'客户搜索或列表验证失败'); foreach ($byAgent as $agentId=>$agentIds) { $filtered=$dashboard->dashboard(['keyword'=>CUSTOMER_DEMO_TAG,'agent_id'=>$agentId]); ensure($filtered['list']['total']===count($agentIds),'代理筛选验证失败'); } ensure($dashboard->dashboard(['keyword'=>CUSTOMER_DEMO_TAG,'status'=>'1'])['list']['total']===5,'启用筛选验证失败'); ensure($dashboard->dashboard(['keyword'=>CUSTOMER_DEMO_TAG,'status'=>'2'])['list']['total']===1,'停用筛选验证失败'); ensure($dashboard->dashboard(['keyword'=>CUSTOMER_DEMO_TAG,'agent_id'=>0])['list']['total']===0,'测试客户不应混入直营'); ensure($before===protectedData(),'非目标业务数据发生变化'); ensure($old===WaterEnterprise::query()->whereIn('id',$oldIds)->orderBy('id')->get()->toArray(),'已有客户被修改'); WaterLedger::query()->create(['kind'=>'demo_seed','reference'=>CUSTOMER_DEMO_BATCH,'created_by'=>1,'enterprise_id'=>0,'sku_id'=>0,'quantity'=>0, 'note'=>'代理客户档案测试,IDs='.implode(',',$ids),'created_at'=>date('Y-m-d H:i:s')]); return ['applied'=>true,'replayed'=>false,'created_ids'=>$ids,'checks'=>'list, agent/status filters, details and existing-data preservation passed']; }); $rows=(new WaterEnterpriseDashboard())->dashboard(['keyword'=>CUSTOMER_DEMO_TAG,'limit'=>100])['list']['data']; $result['customers']=array_map(fn($r)=>array_intersect_key($r,array_flip(['id','name','agent_id','agent_name','status','replenishment_status'])),$rows); } if (in_array('--http',$argv,true)) { $token=\Tinywan\Jwt\JwtToken::generateToken(['id'=>1,'username'=>'admin','plat'=>'saiadmin','type'=>'web', 'client'=>CUSTOMER_DEMO_BATCH,'access_exp'=>120,'refresh_exp'=>120])['access_token']; $cases=[['keyword'=>CUSTOMER_DEMO_TAG]]; foreach ($agents as $agent) $cases[]=['keyword'=>CUSTOMER_DEMO_TAG,'agent_id'=>(int)$agent['id']]; foreach (['1','2'] as $status) $cases[]=['keyword'=>CUSTOMER_DEMO_TAG,'status'=>$status]; $dashboard=new WaterEnterpriseDashboard(); $checks=0; foreach ($cases as $filters) { $url='http://127.0.0.1:8787/core/water/enterprises/dashboard?'.http_build_query($filters+['limit'=>100]); $ch=curl_init($url); curl_setopt_array($ch,[CURLOPT_RETURNTRANSFER=>true,CURLOPT_TIMEOUT=>15,CURLOPT_HTTPHEADER=>['Authorization: Bearer '.$token]]); $raw=curl_exec($ch); $status=curl_getinfo($ch,CURLINFO_HTTP_CODE); curl_close($ch); $body=json_decode((string)$raw,true); ensure($status===200 && ($body['code']??0)===200,'HTTP客户查询失败'); $expected=$dashboard->dashboard($filters+['limit'=>100])['list']; ensure(($body['data']['list']['total']??null)===$expected['total'],'HTTP筛选数量不一致'); ensure(array_column($body['data']['list']['data'],'id')===array_column($expected['data'],'id'),'HTTP列表客户不一致'); $checks++; } $result['http_read_checks']=$checks; unset($token); } echo json_encode($result,JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT).PHP_EOL;