This commit is contained in:
2026-05-22 16:45:28 +08:00
parent e4f181e4fe
commit 003810114b
6 changed files with 83 additions and 39 deletions
@@ -22,10 +22,8 @@ class PersonalAccountCostLogic extends BaseLogic
return false;
}
$conflict = self::findCostConflict($costDate, $mediaSource);
if ($conflict['conflict']) {
$by = $conflict['creator_name'] !== '' ? '(录入人:' . $conflict['creator_name'] . '' : '';
self::setError('该日期下该渠道的账户消耗已存在' . $by . ',请直接编辑该记录,避免重复汇总');
if (self::isCostDuplicate($adminId, $costDate, $mediaSource)) {
self::setError('您在该日期下已录入过该渠道的账户消耗,请直接编辑');
return false;
}
@@ -200,43 +200,32 @@ trait PersonalStatsScopeTrait
}
/**
* 同一天 + 同一渠道全局唯一(不录入人):避免重复汇总
* 命中时返回首个已存在记录的录入人姓名,便于前端提示。
*
* @return array{conflict: bool, creator_name: string}
* 同一录入人 + 同一天 + 同一渠道唯一(不录入人可同日同渠道各录一条)
*/
protected static function findYejiConflict(string $yejiDate, string $mediaSource, int $excludeId = 0): array
protected static function isYejiDuplicate(int $creatorId, string $yejiDate, string $mediaSource, int $excludeId = 0): bool
{
$query = PersonalYeji::where('yeji_date', $yejiDate)
$query = PersonalYeji::where('creator_id', $creatorId)
->where('yeji_date', $yejiDate)
->where('media_source', $mediaSource);
if ($excludeId > 0) {
$query->where('id', '<>', $excludeId);
}
$row = $query->field('id, creator_name')->find();
if (!$row) {
return ['conflict' => false, 'creator_name' => ''];
}
return ['conflict' => true, 'creator_name' => (string) ($row['creator_name'] ?? '')];
return $query->count() > 0;
}
/**
* 同一天 + 同一渠道全局唯一(不录入人):避免重复汇总
*
* @return array{conflict: bool, creator_name: string}
* 同一录入人 + 同一天 + 同一渠道唯一(不录入人可同日同渠道各录一条)
*/
protected static function findCostConflict(string $costDate, string $mediaSource, int $excludeId = 0): array
protected static function isCostDuplicate(int $creatorId, string $costDate, string $mediaSource, int $excludeId = 0): bool
{
$query = PersonalAccountCost::where('cost_date', $costDate)
$query = PersonalAccountCost::where('creator_id', $creatorId)
->where('cost_date', $costDate)
->where('media_source', $mediaSource);
if ($excludeId > 0) {
$query->where('id', '<>', $excludeId);
}
$row = $query->field('id, creator_name')->find();
if (!$row) {
return ['conflict' => false, 'creator_name' => ''];
}
return ['conflict' => true, 'creator_name' => (string) ($row['creator_name'] ?? '')];
return $query->count() > 0;
}
}
@@ -22,10 +22,8 @@ class PersonalYejiLogic extends BaseLogic
return false;
}
$conflict = self::findYejiConflict($yejiDate, $mediaSource);
if ($conflict['conflict']) {
$by = $conflict['creator_name'] !== '' ? '(录入人:' . $conflict['creator_name'] . '' : '';
self::setError('该日期下该渠道的业绩已存在' . $by . ',请直接编辑该记录,避免重复汇总');
if (self::isYejiDuplicate($adminId, $yejiDate, $mediaSource)) {
self::setError('您在该日期下已录入过该渠道的业绩,请直接编辑');
return false;
}
@@ -1,10 +1,69 @@
-- 业绩 & 账户消耗:将「同录入人+同日+同渠道」唯一改为「同日+同渠道」全局唯一,避免重复汇总
-- 注意:执行前请先清理同一天同一渠道下多录入人重复的数据,否则索引创建会失败
-- 自录业绩/账户消耗:确保唯一索引为「同录入人 + 同日 + 同渠道」
-- 可重复执行:不存在则跳过删除;目标索引已存在则跳过添加
--
-- 适用场景:
-- 1) 曾改为 uk_date_media(全局唯一)的环境 → 删除 uk_date_media,恢复 uk_creator_date_media
-- 2) 一直是 uk_creator_date_media 的环境 → 本脚本全部跳过,不会报 1091
-- 3) 尚无唯一索引的环境 → 直接添加 uk_creator_date_media
-- zyt_personal_yeji
ALTER TABLE `zyt_personal_yeji` DROP INDEX `uk_creator_date_media`;
ALTER TABLE `zyt_personal_yeji` ADD UNIQUE KEY `uk_date_media` (`yeji_date`, `media_source`);
-- ========== 查看当前索引(可选) ==========
SELECT
TABLE_NAME,
INDEX_NAME,
GROUP_CONCAT(COLUMN_NAME ORDER BY SEQ_IN_INDEX) AS COLUMNS
FROM information_schema.STATISTICS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME IN ('zyt_personal_yeji', 'zyt_personal_account_cost')
AND INDEX_NAME IN ('uk_date_media', 'uk_creator_date_media')
GROUP BY TABLE_NAME, INDEX_NAME
ORDER BY TABLE_NAME, INDEX_NAME;
-- zyt_personal_account_cost
ALTER TABLE `zyt_personal_account_cost` DROP INDEX `uk_creator_date_media`;
ALTER TABLE `zyt_personal_account_cost` ADD UNIQUE KEY `uk_date_media` (`cost_date`, `media_source`);
-- ========== zyt_personal_yeji ==========
SET @sql = IF(
(SELECT COUNT(*) FROM information_schema.STATISTICS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'zyt_personal_yeji'
AND INDEX_NAME = 'uk_date_media') > 0,
'ALTER TABLE `zyt_personal_yeji` DROP INDEX `uk_date_media`',
'SELECT ''zyt_personal_yeji: 无 uk_date_media,跳过删除'' AS message'
);
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET @sql = IF(
(SELECT COUNT(*) FROM information_schema.STATISTICS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'zyt_personal_yeji'
AND INDEX_NAME = 'uk_creator_date_media') = 0,
'ALTER TABLE `zyt_personal_yeji` ADD UNIQUE KEY `uk_creator_date_media` (`creator_id`, `yeji_date`, `media_source`)',
'SELECT ''zyt_personal_yeji: uk_creator_date_media 已存在,跳过添加'' AS message'
);
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
-- ========== zyt_personal_account_cost ==========
SET @sql = IF(
(SELECT COUNT(*) FROM information_schema.STATISTICS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'zyt_personal_account_cost'
AND INDEX_NAME = 'uk_date_media') > 0,
'ALTER TABLE `zyt_personal_account_cost` DROP INDEX `uk_date_media`',
'SELECT ''zyt_personal_account_cost: 无 uk_date_media,跳过删除'' AS message'
);
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET @sql = IF(
(SELECT COUNT(*) FROM information_schema.STATISTICS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'zyt_personal_account_cost'
AND INDEX_NAME = 'uk_creator_date_media') = 0,
'ALTER TABLE `zyt_personal_account_cost` ADD UNIQUE KEY `uk_creator_date_media` (`creator_id`, `cost_date`, `media_source`)',
'SELECT ''zyt_personal_account_cost: uk_creator_date_media 已存在,跳过添加'' AS message'
);
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
@@ -13,7 +13,7 @@ CREATE TABLE IF NOT EXISTS `zyt_personal_account_cost` (
`update_time` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '更新时间',
`delete_time` int(11) unsigned DEFAULT NULL COMMENT '删除时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_date_media` (`cost_date`, `media_source`),
UNIQUE KEY `uk_creator_date_media` (`creator_id`, `cost_date`, `media_source`),
KEY `idx_cost_date` (`cost_date`),
KEY `idx_creator_id` (`creator_id`),
KEY `idx_dept_id` (`dept_id`)
@@ -20,7 +20,7 @@ CREATE TABLE IF NOT EXISTS `zyt_personal_yeji` (
`update_time` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '更新时间',
`delete_time` int(11) unsigned DEFAULT NULL COMMENT '删除时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_date_media` (`yeji_date`, `media_source`),
UNIQUE KEY `uk_creator_date_media` (`creator_id`, `yeji_date`, `media_source`),
KEY `idx_yeji_date` (`yeji_date`),
KEY `idx_creator_id` (`creator_id`),
KEY `idx_dept_id` (`dept_id`)