更新
This commit is contained in:
@@ -225,7 +225,12 @@ class WecomPromotionLogic
|
||||
];
|
||||
}
|
||||
|
||||
public static function savePool(array $params, int $adminId, array $adminInfo): array
|
||||
public static function savePool(
|
||||
array $params,
|
||||
int $adminId,
|
||||
array $adminInfo,
|
||||
bool $syncImmediately = true
|
||||
): array
|
||||
{
|
||||
self::assertMemberDispatchSchema();
|
||||
$id = max(0, (int) ($params['id'] ?? 0));
|
||||
@@ -425,11 +430,13 @@ class WecomPromotionLogic
|
||||
$syncError = '';
|
||||
if (!$createdRemote) {
|
||||
QywxPromotionMemberSchedulerService::requestPoolSync($id, $linkId);
|
||||
try {
|
||||
(new QywxPromotionRangeSyncService())->syncPool($id);
|
||||
} catch (\Throwable $e) {
|
||||
// 本地方案和成员规则已保存;后台分钟任务会继续重试最新完整范围。
|
||||
$syncError = $e->getMessage();
|
||||
if ($syncImmediately) {
|
||||
try {
|
||||
(new QywxPromotionRangeSyncService())->syncPool($id);
|
||||
} catch (\Throwable $e) {
|
||||
// 本地方案和成员规则已保存;后台分钟任务会继续重试最新完整范围。
|
||||
$syncError = $e->getMessage();
|
||||
}
|
||||
}
|
||||
}
|
||||
$savedLink = Db::name('qywx_promotion_link')->where('id', $linkId)->find() ?: [];
|
||||
@@ -448,6 +455,152 @@ class WecomPromotionLogic
|
||||
// 前端据此确认标签、欢迎语等扩展配置已和方案一并提交并完成回读校验。
|
||||
'automation_saved' => $automation !== null,
|
||||
'sync_error' => $syncError,
|
||||
'sync_queued' => !$createdRemote && !$syncImmediately,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量局部更新分流方案。changes 只覆盖显式传入的字段;每个方案仍复用
|
||||
* savePool 的成员、自动化、素材和企业微信同步校验。
|
||||
*
|
||||
* @return array{pool_ids:list<int>,updated:int,failed:int,sync_error_count:int,sync_queued_count:int,results:list<array<string,mixed>>}
|
||||
*/
|
||||
public static function batchUpdatePools(array $params, int $adminId, array $adminInfo): array
|
||||
{
|
||||
self::assertMemberDispatchSchema();
|
||||
self::assertBasePagePermission($adminId, $adminInfo);
|
||||
$poolIds = self::normalizePositiveIds((array) ($params['pool_ids'] ?? []));
|
||||
if ($poolIds === []) {
|
||||
throw new RuntimeException('请至少选择一个分流方案');
|
||||
}
|
||||
if (count($poolIds) > 100) {
|
||||
throw new RuntimeException('单次最多设置 100 个分流方案');
|
||||
}
|
||||
|
||||
$changes = $params['changes'] ?? null;
|
||||
if (!is_array($changes)) {
|
||||
throw new RuntimeException('批量修改内容格式不正确');
|
||||
}
|
||||
$allowedFields = ['skip_verify', 'fallback_url', 'status', 'automation_config'];
|
||||
$unknownFields = array_diff(array_keys($changes), $allowedFields);
|
||||
if ($unknownFields !== []) {
|
||||
throw new RuntimeException('批量修改包含不支持的字段');
|
||||
}
|
||||
if ($changes === []) {
|
||||
throw new RuntimeException('请至少选择一项需要批量修改的配置');
|
||||
}
|
||||
if (array_key_exists('fallback_url', $changes) && !is_string($changes['fallback_url'])) {
|
||||
throw new RuntimeException('兜底获客助手链接格式不正确');
|
||||
}
|
||||
|
||||
$automationPatch = null;
|
||||
if (array_key_exists('automation_config', $changes)) {
|
||||
if (!is_array($changes['automation_config']) || $changes['automation_config'] === []) {
|
||||
throw new RuntimeException('自动化配置格式不正确');
|
||||
}
|
||||
$allowedAutomationFields = [
|
||||
'reception_mode', 'reception_schedule', 'backup_member_admin_ids',
|
||||
'tags_enabled', 'tag_ids', 'remark_enabled', 'remark_template',
|
||||
'description_enabled', 'description', 'welcome_mode', 'welcome',
|
||||
'welcome_schedule_enabled', 'welcome_schedule',
|
||||
];
|
||||
if (array_diff(array_keys($changes['automation_config']), $allowedAutomationFields) !== []) {
|
||||
throw new RuntimeException('自动化配置包含不支持的字段');
|
||||
}
|
||||
QywxPromotionConfig::assertInstalled();
|
||||
$automationPatch = $changes['automation_config'];
|
||||
}
|
||||
|
||||
// 必须在任何方案写入前完成整批权限校验,避免越权请求产生部分更新。
|
||||
$pools = [];
|
||||
foreach ($poolIds as $poolId) {
|
||||
$pools[$poolId] = self::assertScopedRow(
|
||||
'qywx_promotion_pool',
|
||||
$poolId,
|
||||
$adminId,
|
||||
$adminInfo,
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
$results = [];
|
||||
$updated = 0;
|
||||
$failed = 0;
|
||||
$syncErrorCount = 0;
|
||||
$syncQueuedCount = 0;
|
||||
foreach ($poolIds as $poolId) {
|
||||
$pool = $pools[$poolId];
|
||||
$currentAutomation = QywxPromotionConfig::forPool($poolId);
|
||||
$memberAdminIds = self::normalizePositiveIds(Db::name('qywx_promotion_pool_member')
|
||||
->where('pool_id', $poolId)
|
||||
->whereNull('delete_time')
|
||||
->column('admin_id'));
|
||||
$primaryMemberAdminIds = array_values(array_diff(
|
||||
$memberAdminIds,
|
||||
self::normalizePositiveIds((array) ($currentAutomation['backup_member_admin_ids'] ?? []))
|
||||
));
|
||||
$officialLink = Db::name('qywx_promotion_link')
|
||||
->where('pool_id', $poolId)
|
||||
->whereNull('delete_time')
|
||||
->where('remote_link_id', '<>', '')
|
||||
->where('remote_status', '<>', 2)
|
||||
->order('id', 'desc')
|
||||
->find() ?: [];
|
||||
$saveParams = [
|
||||
'id' => $poolId,
|
||||
'name' => (string) ($pool['name'] ?? ''),
|
||||
'fallback_url' => array_key_exists('fallback_url', $changes)
|
||||
? trim($changes['fallback_url'])
|
||||
: (string) ($pool['fallback_url'] ?? ''),
|
||||
'status' => array_key_exists('status', $changes)
|
||||
? ((int) $changes['status'] === 1 ? 1 : 0)
|
||||
: (int) ($pool['status'] ?? 0),
|
||||
'member_admin_ids' => $primaryMemberAdminIds,
|
||||
'skip_verify' => array_key_exists('skip_verify', $changes)
|
||||
? ((int) $changes['skip_verify'] === 1 ? 1 : 0)
|
||||
: (int) ($officialLink['skip_verify'] ?? 0),
|
||||
];
|
||||
if ($automationPatch !== null) {
|
||||
$saveParams['automation_config'] = array_replace($currentAutomation, $automationPatch);
|
||||
}
|
||||
|
||||
try {
|
||||
// 批量操作只落本地并入同步队列,避免大量企微请求阻塞管理端 HTTP 请求。
|
||||
$saved = self::savePool($saveParams, $adminId, $adminInfo, false);
|
||||
$syncError = trim((string) ($saved['sync_error'] ?? ''));
|
||||
$updated++;
|
||||
if ($syncError !== '') {
|
||||
$syncErrorCount++;
|
||||
}
|
||||
$syncQueued = !empty($saved['sync_queued']);
|
||||
if ($syncQueued) {
|
||||
$syncQueuedCount++;
|
||||
}
|
||||
$results[] = [
|
||||
'id' => $poolId,
|
||||
'name' => (string) ($pool['name'] ?? ''),
|
||||
'success' => true,
|
||||
'sync_error' => $syncError,
|
||||
'sync_queued' => $syncQueued,
|
||||
];
|
||||
} catch (\Throwable $error) {
|
||||
$failed++;
|
||||
$results[] = [
|
||||
'id' => $poolId,
|
||||
'name' => (string) ($pool['name'] ?? ''),
|
||||
'success' => false,
|
||||
'error' => $error->getMessage(),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
'pool_ids' => $poolIds,
|
||||
'updated' => $updated,
|
||||
'failed' => $failed,
|
||||
'sync_error_count' => $syncErrorCount,
|
||||
'sync_queued_count' => $syncQueuedCount,
|
||||
'results' => $results,
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user