'integer', 'update_time' => 'integer', 'locked_points' => 'integer', 'available_points' => 'integer', 'today_limit' => 'integer', 'today_claimed' => 'integer', 'admin_id' => 'integer', ]; /** * H5 临时登录:按用户名查找或创建资产行,playx_user_id 使用 mall_{id} */ public static function ensureForUsername(string $username): self { $username = trim($username); $existing = self::where('username', $username)->find(); if ($existing) { return $existing; } // 创建用户时:phone 与 username 同值(H5 临时账号) $phone = $username; $phoneExisting = self::where('phone', $phone)->find(); if ($phoneExisting) { // 若历史数据存在“手机号=用户名”的行,直接复用;若不一致则拒绝创建,避免污染 if (trim((string) ($phoneExisting->username ?? '')) === $username) { return $phoneExisting; } throw new \RuntimeException('Username is already used by another account'); } $pwd = hash_password(Random::build('alnum', 16)); $now = time(); $temporaryPlayxId = 'tmp_' . bin2hex(random_bytes(16)); $created = self::create([ 'playx_user_id' => $temporaryPlayxId, 'username' => $username, 'phone' => $phone, 'password' => $pwd, 'admin_id' => 0, 'locked_points' => 0, 'available_points' => 0, 'today_limit' => 0, 'today_claimed' => 0, 'today_limit_date' => null, 'create_time' => $now, 'update_time' => $now, ]); if (!$created) { throw new \RuntimeException('Failed to create mall_user_asset'); } $id = $created->getKey(); $finalPlayxId = 'mall_' . $id; if (self::where('playx_user_id', $finalPlayxId)->where('id', '<>', $id)->find()) { $finalPlayxId = 'mall_' . $id . '_' . bin2hex(random_bytes(4)); } $created->playx_user_id = $finalPlayxId; $created->save(); return $created; } // allocateUniquePhone 已废弃:临时登录场景下 phone=用户名 }