| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455 |
- <?php
- declare(strict_types=1);
- namespace plugin\saiadmin\app\service;
- use plugin\saiadmin\app\model\water\{WaterModel,WaterAgent,WaterOperator,WaterLedger};
- use plugin\saiadmin\app\service\agent\AgentHierarchyPolicy;
- use plugin\saiadmin\exception\ApiException;
- /** Transactional archive/account commands. Opening an account never assigns roles or global data access. */
- final class WaterAgentManagement
- {
- public function save(array $input,int $actor): array {
- return WaterModel::transaction(function () use ($input,$actor) {
- // Serialize hierarchy changes so concurrent reparenting cannot introduce cycles.
- $agents=WaterAgent::query()->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'];
- });
- }
- }
|