From b544c9d7f69ac08854bdea9534176271f78ce47e Mon Sep 17 00:00:00 2001 From: kuaifan Date: Sat, 13 Jun 2026 08:09:30 +0000 Subject: [PATCH] =?UTF-8?q?fix(model):=20=E8=A6=86=E5=86=99=20performInser?= =?UTF-8?q?tOrIgnore=20=E5=85=BC=E5=AE=B9=20MySQL?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit L13 默认走 insertOrIgnoreReturning(INSERT ... ON CONFLICT ... RETURNING), MySQL/MariaDB grammar 不支持该变体,导致全仓 saveOrIgnore() 调用抛异常。 改用 INSERT IGNORE + lastInsertId() 回填自增ID,保持与框架一致的返回语义。 Co-Authored-By: Claude Opus 4.8 (1M context) --- app/Models/AbstractModel.php | 53 ++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/app/Models/AbstractModel.php b/app/Models/AbstractModel.php index f9c1e06b6..59981a3b1 100644 --- a/app/Models/AbstractModel.php +++ b/app/Models/AbstractModel.php @@ -5,6 +5,7 @@ namespace App\Models; use App\Exceptions\ApiException; use App\Module\Base; use DateTimeInterface; +use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Facades\DB; @@ -201,6 +202,58 @@ class AbstractModel extends Model return $instance; } + /** + * 覆写框架 saveOrIgnore 的底层插入逻辑。 + * + * 框架默认走 insertOrIgnoreReturning(INSERT ... ON CONFLICT ... RETURNING), + * MySQL/MariaDB 的 grammar 不支持该变体,会抛 + * "This database engine does not support insert or ignore with returning."。 + * 这里改用 MySQL 支持的 INSERT IGNORE,并在成功插入时手动回填自增ID, + * 保持与框架一致的返回语义(冲突被忽略时返回 false)。 + * + * @param \Illuminate\Database\Eloquent\Builder $query + * @param array|string|null $uniqueBy + * @return bool + */ + protected function performInsertOrIgnore(Builder $query, array|string|null $uniqueBy) + { + if ($this->usesUniqueIds()) { + $this->setUniqueIds(); + } + + if ($this->fireModelEvent('creating') === false) { + return false; + } + + if ($this->usesTimestamps()) { + $this->updateTimestamps(); + } + + $attributes = $this->getAttributesForInsert(); + + if (empty($attributes)) { + return true; + } + + if ($query->toBase()->insertOrIgnore($attributes) === 0) { + return false; + } + + if ($this->getIncrementing()) { + $this->setAttribute( + $this->getKeyName(), + $query->getConnection()->getPdo()->lastInsertId() + ); + } + + $this->exists = true; + $this->wasRecentlyCreated = true; + + $this->fireModelEvent('created', false); + + return true; + } + /** * 更新数据校验 * @param array $param