This commit is contained in:
Your Name
2026-08-25 09:36:25 +08:00
parent 01c38d8c5b
commit 47094cc617
7 changed files with 823 additions and 0 deletions
@@ -0,0 +1,71 @@
<?php
declare(strict_types=1);
use app\common\service\qywx\QywxCustomerAcquisitionLinkService;
require dirname(__DIR__) . '/vendor/autoload.php';
$assert = static function (bool $condition, string $message): void {
if (!$condition) {
throw new RuntimeException($message);
}
};
$base = 'https://work.weixin.qq.com/ca/cawcdea778939b9097';
$channelUrl = QywxCustomerAcquisitionLinkService::withCustomerChannel($base, 'zyt_pool:123');
$assert(
$channelUrl === $base . '?customer_channel=zyt_pool:123',
'官方获客链接未按约定追加 customer_channel'
);
$replaced = QywxCustomerAcquisitionLinkService::withCustomerChannel(
$base . '?foo=1&customer_channel=old#wechat_redirect',
'zyt_pool:456'
);
$assert(
$replaced === $base . '?foo=1&customer_channel=zyt_pool:456#wechat_redirect',
'已有 customer_channel 未被安全替换'
);
$assert(
QywxCustomerAcquisitionLinkService::withCustomerChannel('https://example.com/ca/test', 'zyt_pool:1') === '',
'非企业微信获客链接不应生成渠道地址'
);
$assert(
QywxCustomerAcquisitionLinkService::withCustomerChannel($base, str_repeat('a', 65)) === '',
'超过 64 字节的渠道标识不应被接受'
);
$officialDetail = QywxCustomerAcquisitionLinkService::normaliseRemoteResponse([
'errcode' => 0,
'errmsg' => 'ok',
'link' => [
'link_name' => '官网获客',
'url' => $base,
'create_time' => 1787610000,
'skip_verify' => true,
],
'range' => [
'user_list' => ['HuoYiSheng', 'HuoYiSheng', 'Li'],
'department_list' => ['2'],
],
'priority_option' => ['priority_type' => 1],
], 'cawcdea778939b9097');
$assert(
$officialDetail['range_userids'] === ['HuoYiSheng', 'Li'],
'get 接口根级 range.user_list 未被正确解析'
);
$assert(
$officialDetail['range_department_ids'] === ['2'],
'get 接口根级 range.department_list 未被正确解析'
);
$assert(
($officialDetail['priority_option']['priority_type'] ?? 0) === 1,
'get 接口根级 priority_option 未被正确解析'
);
$assert(
isset($officialDetail['snapshot']['range']),
'远端快照应保留完整响应,而不是只保留 link 节点'
);
echo "QYWX_CUSTOMER_ACQUISITION_LINK_SERVICE_OK\n";
@@ -0,0 +1,46 @@
<?php
declare(strict_types=1);
use app\common\service\qywx\QywxPromotionMemberSchedulerService;
use app\common\service\qywx\QywxPromotionWeightedRandom;
require dirname(__DIR__) . '/vendor/autoload.php';
$assert = static function (bool $condition, string $message): void {
if (!$condition) {
throw new RuntimeException($message);
}
};
$today = '2026-08-25';
$now = strtotime($today . ' 12:00:00');
$members = [
['id' => 1, 'enabled' => 1, 'weight' => 2, 'current_weight' => 9, 'daily_limit' => 0, 'today_count' => 0, 'today_date' => $today],
['id' => 2, 'enabled' => 1, 'weight' => 1, 'current_weight' => -3, 'daily_limit' => 0, 'today_count' => 0, 'today_date' => $today],
['id' => 3, 'enabled' => 1, 'weight' => 1, 'current_weight' => 4, 'daily_limit' => 0, 'today_count' => 0, 'today_date' => $today],
];
$assert(QywxPromotionWeightedRandom::select($members, $today, $now, 1)['selected_id'] === 1, '权重 2 的第一个区间映射错误');
$assert(QywxPromotionWeightedRandom::select($members, $today, $now, 2)['selected_id'] === 1, '权重 2 的第二个区间映射错误');
$assert(QywxPromotionWeightedRandom::select($members, $today, $now, 3)['selected_id'] === 2, '第二名成员的随机区间映射错误');
$fourth = QywxPromotionWeightedRandom::select($members, $today, $now, 4);
$assert($fourth['selected_id'] === 3, '第三名成员的随机区间映射错误');
$assert($fourth['total_weight'] === 4 && $fourth['eligible_count'] === 3, '随机池权重合计错误');
$assert(array_column($fourth['members'], 'current_weight') === [0, 0, 0], '旧版平滑游标没有归零');
$limited = QywxPromotionWeightedRandom::select([
['id' => 1, 'enabled' => 0, 'weight' => 10, 'current_weight' => 0, 'daily_limit' => 0, 'today_count' => 0, 'today_date' => $today],
['id' => 2, 'enabled' => 1, 'weight' => 5, 'current_weight' => 0, 'daily_limit' => 3, 'today_count' => 3, 'today_date' => $today],
['id' => 3, 'enabled' => 1, 'weight' => 1, 'current_weight' => 0, 'daily_limit' => 0, 'today_count' => 8, 'today_date' => $today],
], $today, $now, 1);
$assert($limited['selected_id'] === 3 && $limited['eligible_count'] === 1, '禁用成员或达到上限的成员仍进入随机池');
$reset = QywxPromotionWeightedRandom::select([
['id' => 4, 'enabled' => 1, 'weight' => 1, 'current_weight' => 0, 'daily_limit' => 1, 'today_count' => 1, 'today_date' => '2026-08-24'],
], $today, $now, 1);
$assert($reset['selected_id'] === 4 && $reset['members'][0]['today_count'] === 0, '跨日数量没有自动重置');
$assert(QywxPromotionMemberSchedulerService::poolIdFromState('zyt_pool:123') === 123, 'customer_channel 方案 ID 解析失败');
$assert(QywxPromotionMemberSchedulerService::poolIdFromState('qywx_ca:123') === 0, '不应接管其他系统的 customer_channel');
echo "QYWX_PROMOTION_WEIGHTED_RANDOM_OK\n";