高考版优化
审核模式优化
This commit is contained in:
@@ -348,6 +348,63 @@ class DataMigration extends BaseController
|
||||
Db::name('user_profile')->insert($base);
|
||||
}
|
||||
|
||||
/**
|
||||
* 归属目标企业且仍存在 personal(NULL) 画像行的用户,逐批合并(避免一次载入全部 userId / 超长事务)。
|
||||
*
|
||||
* @return int 实际调用合并逻辑的用户数
|
||||
*/
|
||||
private function mergePersonalProfilesForEnterpriseInBatches(int $targetEnterpriseId, int $now, int $batchSize = 400): int
|
||||
{
|
||||
if ($targetEnterpriseId <= 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
$tUp = Db::name('user_profile')->getTable();
|
||||
$tWu = Db::name('wechat_users')->getTable();
|
||||
$batchSize = max(50, min($batchSize, 2000));
|
||||
$lastUid = 0;
|
||||
$merged = 0;
|
||||
|
||||
while (true) {
|
||||
$sql = 'SELECT DISTINCT `up`.`userId` AS `uid` FROM `' . $tUp . '` `up` '
|
||||
. 'INNER JOIN `' . $tWu . '` `w` ON `w`.`id` = `up`.`userId` '
|
||||
. 'WHERE `up`.`userType` = \'personal\' '
|
||||
. 'AND (`up`.`enterpriseId` IS NULL OR `up`.`enterpriseId` = 0) '
|
||||
. 'AND `w`.`enterpriseId` = ? '
|
||||
. 'AND `up`.`userId` > ? '
|
||||
. 'ORDER BY `up`.`userId` ASC '
|
||||
. 'LIMIT ' . $batchSize;
|
||||
|
||||
$rows = Db::query($sql, [$targetEnterpriseId, $lastUid]);
|
||||
if ($rows === null || $rows === [] || !is_array($rows)) {
|
||||
break;
|
||||
}
|
||||
|
||||
$uids = [];
|
||||
foreach ($rows as $row) {
|
||||
$uid = (int) ($row['uid'] ?? 0);
|
||||
if ($uid > 0) {
|
||||
$uids[] = $uid;
|
||||
}
|
||||
}
|
||||
if ($uids === []) {
|
||||
break;
|
||||
}
|
||||
|
||||
foreach ($uids as $uid) {
|
||||
$this->mergePersonalUserProfileIntoEnterprise($uid, $targetEnterpriseId, $now);
|
||||
$merged++;
|
||||
}
|
||||
|
||||
$lastUid = max($uids);
|
||||
if (count($rows) < $batchSize) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $merged;
|
||||
}
|
||||
|
||||
/**
|
||||
* 存客宝归并:wechat_users 无企业用户写入目标企业;
|
||||
* 已/将归属该企业的用户下,test_results 中 enterpriseId 为空的记录补写目标企业;
|
||||
@@ -386,27 +443,25 @@ class DataMigration extends BaseController
|
||||
return error('目标企业不存在', 404);
|
||||
}
|
||||
|
||||
$orphanUserIds = Db::name('wechat_users')
|
||||
$eid = $targetEnterpriseId;
|
||||
|
||||
$wechatAffected = (int) Db::name('wechat_users')
|
||||
->whereRaw($this->sqlWechatUserUnassignedEnterprise())
|
||||
->column('id');
|
||||
$orphanUserIds = array_values(array_unique(array_filter(array_map('intval', $orphanUserIds))));
|
||||
$wechatAffected = count($orphanUserIds);
|
||||
|
||||
$boundNow = Db::name('wechat_users')
|
||||
->where('enterpriseId', $targetEnterpriseId)
|
||||
->column('id');
|
||||
$boundNow = array_values(array_unique(array_filter(array_map('intval', $boundNow))));
|
||||
$usersInScope = array_values(array_unique(array_merge($boundNow, $orphanUserIds)));
|
||||
|
||||
$testResultsAffected = empty($usersInScope) ? 0 : (int) Db::name('test_results')
|
||||
->whereIn('userId', $usersInScope)
|
||||
->whereRaw($this->sqlTestResultUnassignedEnterprise())
|
||||
->count();
|
||||
|
||||
$userProfilePersonalRows = empty($usersInScope) ? 0 : (int) Db::name('user_profile')
|
||||
->where('userType', 'personal')
|
||||
->whereRaw('(`enterpriseId` IS NULL OR `enterpriseId` = 0)')
|
||||
->whereIn('userId', $usersInScope)
|
||||
$wechatScopeExpr = '((w.`enterpriseId` IS NULL OR w.`enterpriseId` = 0) OR w.`enterpriseId` = ' . $eid . ')';
|
||||
|
||||
$testResultsAffected = (int) Db::name('test_results')->alias('tr')
|
||||
->join('wechat_users w', 'w.id = tr.userId')
|
||||
->whereRaw('(tr.`enterpriseId` IS NULL OR tr.`enterpriseId` = 0)')
|
||||
->whereRaw($wechatScopeExpr)
|
||||
->count();
|
||||
|
||||
$userProfilePersonalRows = (int) Db::name('user_profile')->alias('up')
|
||||
->join('wechat_users w', 'w.id = up.userId')
|
||||
->where('up.userType', 'personal')
|
||||
->whereRaw('(up.`enterpriseId` IS NULL OR up.`enterpriseId` = 0)')
|
||||
->whereRaw($wechatScopeExpr)
|
||||
->count();
|
||||
|
||||
$preview = [
|
||||
@@ -434,47 +489,52 @@ class DataMigration extends BaseController
|
||||
return success($preview, '无需归并');
|
||||
}
|
||||
|
||||
if (function_exists('set_time_limit')) {
|
||||
@set_time_limit(0);
|
||||
}
|
||||
@ignore_user_abort(true);
|
||||
|
||||
$now = time();
|
||||
|
||||
Db::startTrans();
|
||||
try {
|
||||
if (!empty($orphanUserIds)) {
|
||||
Db::name('wechat_users')
|
||||
->whereIn('id', $orphanUserIds)
|
||||
->whereRaw($this->sqlWechatUserUnassignedEnterprise())
|
||||
->update([
|
||||
'enterpriseId' => $targetEnterpriseId,
|
||||
'updatedAt' => $now,
|
||||
]);
|
||||
}
|
||||
Db::name('wechat_users')
|
||||
->whereRaw($this->sqlWechatUserUnassignedEnterprise())
|
||||
->update([
|
||||
'enterpriseId' => $targetEnterpriseId,
|
||||
'updatedAt' => $now,
|
||||
]);
|
||||
|
||||
$boundAfter = Db::name('wechat_users')
|
||||
->where('enterpriseId', $targetEnterpriseId)
|
||||
->column('id');
|
||||
$boundAfter = array_values(array_unique(array_filter(array_map('intval', $boundAfter))));
|
||||
|
||||
if (!empty($boundAfter)) {
|
||||
Db::name('test_results')
|
||||
->whereIn('userId', $boundAfter)
|
||||
->whereRaw($this->sqlTestResultUnassignedEnterprise())
|
||||
->update([
|
||||
'enterpriseId' => $targetEnterpriseId,
|
||||
'testScope' => 'enterprise',
|
||||
'updatedAt' => $now,
|
||||
]);
|
||||
|
||||
foreach ($boundAfter as $uid) {
|
||||
$this->mergePersonalUserProfileIntoEnterprise((int) $uid, $targetEnterpriseId, $now);
|
||||
}
|
||||
}
|
||||
$trTable = Db::name('test_results')->getTable();
|
||||
$wuTable = Db::name('wechat_users')->getTable();
|
||||
Db::execute(
|
||||
'UPDATE `' . $trTable . '` AS `tr` INNER JOIN `' . $wuTable . '` AS `w` ON `tr`.`userId` = `w`.`id` '
|
||||
. 'SET `tr`.`enterpriseId` = ?, `tr`.`testScope` = \'enterprise\', `tr`.`updatedAt` = ? '
|
||||
. 'WHERE `w`.`enterpriseId` = ? AND (`tr`.`enterpriseId` IS NULL OR `tr`.`enterpriseId` = 0)',
|
||||
[$targetEnterpriseId, $now, $targetEnterpriseId]
|
||||
);
|
||||
|
||||
Db::commit();
|
||||
} catch (\Throwable $e) {
|
||||
Db::rollback();
|
||||
return error('归并失败:' . $e->getMessage(), 500);
|
||||
|
||||
return error('归并失败(用户/测试写入):' . $e->getMessage(), 500);
|
||||
}
|
||||
|
||||
$preview['executed'] = true;
|
||||
$preview['hint'] = '已写入:小程序用户归属、无企业测试记录、画像 personal 行合并已完成。';
|
||||
try {
|
||||
$mergedProfiles = $this->mergePersonalProfilesForEnterpriseInBatches($targetEnterpriseId, $now);
|
||||
} catch (\Throwable $e) {
|
||||
return error(
|
||||
'用户与测试记录已写入,但画像合并失败(可重试本接口):' . $e->getMessage(),
|
||||
500
|
||||
);
|
||||
}
|
||||
|
||||
$preview['executed'] = true;
|
||||
$preview['profileMergeProcessed'] = $mergedProfiles;
|
||||
$preview['hint'] = '已写入:小程序用户归属、无企业测试记录已批量更新;personal 画像已合并 '
|
||||
. $mergedProfiles . ' 人次。';
|
||||
|
||||
return success($preview, '归并完成');
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user