orderBy('id')->lockForUpdate()->get(['id','parent_id','status'])->toArray(); $id=WaterBusiness::positive($input['id']??0,'代理ID',true); if (array_key_exists('parent_id',$input)) { $parent=$input['parent_id']===null?null:WaterBusiness::positive($input['parent_id'],'上级代理',true); (new AgentHierarchyPolicy())->validate($agents,$id?:-1,$parent); } $result=(new WaterBusiness())->save('agent',$input,$actor); if (array_key_exists('parent_id',$input)) WaterAgent::query()->where('id',$result['id'])->update(['parent_id'=>$parent]); return $result; }); } public function openAccount(array $input,int $actor): array { if ($actor!==1) throw new ApiException('仅超级管理员可开通代理登录账号',403); $username=$input['username']??''; $password=$input['password']??''; if (!is_string($username)||!preg_match('/^[A-Za-z0-9_.-]{3,64}$/D',$username)) throw new ApiException('登录账号须为3至64位字母、数字、点、下划线或短横线'); if (!is_string($password)||strlen($password)<8||strlen($password)>72) throw new ApiException('密码须为8至72字节'); return WaterModel::transaction(function () use ($input,$actor,$username,$password) { // Lock root operator to serialize new usernames across this opening workflow. WaterOperator::query()->where('id',1)->lockForUpdate()->first(); if (WaterOperator::query()->where('username',$username)->exists()) throw new ApiException('登录账号已存在'); $id=WaterBusiness::positive($input['id']??0,'代理ID',true); if ($id) { $agent=WaterAgent::query()->where('id',$id)->lockForUpdate()->first(); if (!$agent) throw new ApiException('代理不存在'); if ($agent->user_id) throw new ApiException('该代理已有关联账号,请勿重复开通'); } else { $id=$this->save($input,$actor)['id']; $agent=WaterAgent::query()->findOrFail($id); } if (mb_strlen($agent->phone)>20 || mb_strlen($agent->contact)>64) throw new ApiException('账号联系电话不可超过20字,联系人不可超过64字'); $now=date('Y-m-d H:i:s'); $user=WaterOperator::query()->create(['username'=>$username,'password'=>password_hash($password,PASSWORD_DEFAULT), 'realname'=>$agent->contact,'phone'=>$agent->phone,'dept_id'=>null,'is_super'=>0,'status'=>1, 'remark'=>'供水代理待授权账号','created_by'=>$actor,'updated_by'=>$actor,'create_time'=>$now,'update_time'=>$now]); $agent->user_id=$user->id; $agent->updated_at=$now; $agent->save(); WaterLedger::query()->create(['kind'=>'archive','created_by'=>$actor,'sku_id'=>0,'enterprise_id'=>0,'quantity'=>0, 'reference'=>'agent:'.$id,'note'=>'开通代理登录账号,待分配角色;user_id='.$user->id,'created_at'=>$now]); return ['id'=>$id,'user_id'=>(int)$user->id,'authorization'=>'pending']; }); } }