This commit is contained in:
Your Name
2026-08-31 15:17:34 +08:00
parent ed48f8be31
commit 456dd667df
439 changed files with 5720 additions and 422 deletions
@@ -8,6 +8,8 @@ use app\adminapi\logic\qywx\CustomerLogic;
use app\common\service\qywx\QywxCustomerAcquisitionCustomerService;
use app\common\service\qywx\QywxPromotionMemberSchedulerService;
use app\common\service\qywx\QywxPromotionRangeSyncService;
use app\common\service\qywx\QywxPromotionAutomationService;
use app\common\service\qywx\QywxPromotionEnqueueException;
use EasyWeChat\Kernel\Exceptions\BadRequestException;
use EasyWeChat\Work\Application;
use EasyWeChat\Work\Message;
@@ -64,6 +66,9 @@ class QywxExternalContactCallbackController extends BaseApiController
$server->addEventListener('change_external_contact', function (Message $message, \Closure $next) {
try {
$this->handleChangeExternalContact($message);
} catch (QywxPromotionEnqueueException $e) {
// 未持久化不能假应答成功:外层返回500,让企微重新投递。
throw $e;
} catch (\Throwable $e) {
Log::error('qywx external contact callback: ' . $e->getMessage(), [
'exception' => $e,
@@ -96,6 +101,11 @@ class QywxExternalContactCallbackController extends BaseApiController
}
return response($content, 200, $headers);
} catch (QywxPromotionEnqueueException) {
// 异常调用栈可能携带原始事件参数;这里只记固定信息,不记录WelcomeCode。
Log::error('qywx external contact callback: promotion event persistence failed');
return response('error', 500, ['Content-Type' => 'text/plain; charset=utf-8']);
} catch (BadRequestException $e) {
Log::warning('qywx external contact callback: bad request ' . $e->getMessage());
@@ -120,6 +130,13 @@ class QywxExternalContactCallbackController extends BaseApiController
$failReason = (string) ($message['FailReason'] ?? '');
$eventTime = (int) ($message['CreateTime'] ?? 0);
// 只接管已保存新配置且可核验方案/成员的推广事件;这里无任何远端请求。
// 同时处理带欢迎码的半客户,避免原来的半客户早返回吞掉20秒欢迎语窗口。
$event = $message instanceof Message ? $message->toArray() : (array) $message;
$queued = (new QywxPromotionAutomationService())->enqueueVerifiedEvent($event);
$auditEvent = $event;
unset($auditEvent['WelcomeCode']);
// 事件流水:一进来就落库(幂等),用于"今天进来多少人"等零误差统计;
// 独立于业务 UPSERT,即便后续 DB 逻辑抛错也不影响计数。
CustomerLogic::recordExternalContactEvent([
@@ -130,9 +147,14 @@ class QywxExternalContactCallbackController extends BaseApiController
'fail_reason' => $failReason,
'welcome_code' => $welcomeCode !== '' ? 1 : 0,
'event_time' => $eventTime,
'raw' => $message,
'raw' => $auditEvent,
]);
if ($queued) {
// 常驻worker先发欢迎语,分钟补偿完成标签/备注、成员记账、范围与客户资料同步。
return;
}
if ($extId === '') {
Log::info(sprintf('qywx external contact callback: 无 ExternalUserID type=%s user=%s', $changeType, $userId));