fix(model): 覆写 performInsertOrIgnore 兼容 MySQL

L13 默认走 insertOrIgnoreReturning(INSERT ... ON CONFLICT ... RETURNING),
MySQL/MariaDB grammar 不支持该变体,导致全仓 saveOrIgnore() 调用抛异常。
改用 INSERT IGNORE + lastInsertId() 回填自增ID,保持与框架一致的返回语义。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
kuaifan 2026-06-13 08:09:30 +00:00
parent 8d9082f7a1
commit b544c9d7f6

View File

@ -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 的底层插入逻辑。
*
* 框架默认走 insertOrIgnoreReturningINSERT ... 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