Merge branch 'cursor/self-input-stats'

This commit is contained in:
2026-05-22 17:02:27 +08:00
6 changed files with 71 additions and 26 deletions
@@ -22,8 +22,9 @@ class PersonalAccountCostLogic extends BaseLogic
return false;
}
if (self::isCostDuplicate($adminId, $costDate, $mediaSource)) {
self::setError('您在该日期下已录入过该渠道的账户消耗,请直接编辑');
$dupId = self::findCostDuplicateId($adminId, $costDate, $mediaSource);
if ($dupId > 0) {
self::setError("您在 {$costDate} 已录入过【{$mediaSource}】账户消耗(记录#{$dupId}),请直接编辑该记录");
return false;
}
@@ -42,7 +43,11 @@ class PersonalAccountCostLogic extends BaseLogic
return true;
} catch (\Throwable $e) {
self::setError($e->getMessage());
if (self::isUniqueConstraintViolation($e)) {
self::setError('该日期下该渠道的账户消耗已存在(唯一索引冲突),请刷新列表后直接编辑');
} else {
self::setError($e->getMessage());
}
return false;
}
@@ -201,31 +201,52 @@ trait PersonalStatsScopeTrait
/**
* 同一录入人 + 同一天 + 同一渠道唯一(不同录入人可同日同渠道各录一条)。
* 命中返回冲突记录 ID,未命中返回 0。
*/
protected static function isYejiDuplicate(int $creatorId, string $yejiDate, string $mediaSource, int $excludeId = 0): bool
protected static function findYejiDuplicateId(int $creatorId, string $yejiDate, string $mediaSource, int $excludeId = 0): int
{
$query = PersonalYeji::where('creator_id', $creatorId)
->where('yeji_date', $yejiDate)
->where('media_source', $mediaSource);
->where('media_source', $mediaSource)
->whereNull('delete_time');
if ($excludeId > 0) {
$query->where('id', '<>', $excludeId);
}
return $query->count() > 0;
return (int) ($query->value('id') ?? 0);
}
protected static function isYejiDuplicate(int $creatorId, string $yejiDate, string $mediaSource, int $excludeId = 0): bool
{
return self::findYejiDuplicateId($creatorId, $yejiDate, $mediaSource, $excludeId) > 0;
}
/**
* 同一录入人 + 同一天 + 同一渠道唯一(不同录入人可同日同渠道各录一条)。
*/
protected static function isCostDuplicate(int $creatorId, string $costDate, string $mediaSource, int $excludeId = 0): bool
protected static function findCostDuplicateId(int $creatorId, string $costDate, string $mediaSource, int $excludeId = 0): int
{
$query = PersonalAccountCost::where('creator_id', $creatorId)
->where('cost_date', $costDate)
->where('media_source', $mediaSource);
->where('media_source', $mediaSource)
->whereNull('delete_time');
if ($excludeId > 0) {
$query->where('id', '<>', $excludeId);
}
return $query->count() > 0;
return (int) ($query->value('id') ?? 0);
}
protected static function isCostDuplicate(int $creatorId, string $costDate, string $mediaSource, int $excludeId = 0): bool
{
return self::findCostDuplicateId($creatorId, $costDate, $mediaSource, $excludeId) > 0;
}
/**
* MySQL 唯一索引冲突 1062 兜底转友好提示(避免裸 SQL 异常)。
*/
protected static function isUniqueConstraintViolation(\Throwable $e): bool
{
return (int) $e->getCode() === 23000 || str_contains($e->getMessage(), '1062');
}
}
@@ -22,8 +22,9 @@ class PersonalYejiLogic extends BaseLogic
return false;
}
if (self::isYejiDuplicate($adminId, $yejiDate, $mediaSource)) {
self::setError('您在该日期下已录入过该渠道的业绩,请直接编辑');
$dupId = self::findYejiDuplicateId($adminId, $yejiDate, $mediaSource);
if ($dupId > 0) {
self::setError("您在 {$yejiDate} 已录入过【{$mediaSource}】业绩(记录#{$dupId}),请直接编辑该记录");
return false;
}
@@ -49,7 +50,11 @@ class PersonalYejiLogic extends BaseLogic
return true;
} catch (\Throwable $e) {
self::setError($e->getMessage());
if (self::isUniqueConstraintViolation($e)) {
self::setError('该日期下该渠道的业绩已存在(唯一索引冲突),请刷新列表后直接编辑');
} else {
self::setError($e->getMessage());
}
return false;
}