fix(partner): 修复30天保活倒计时方案A精确秒级顺延并实现HL规范昵称生成规则

这个提交包含在:
chen
2026-09-26 14:14:48 +08:00
父节点 452c2f22a2
当前提交 87fcb00389
共有 8 个文件被更改,包括 291 次插入 和 22 次删除

查看文件

@@ -273,23 +273,8 @@ class Agent extends Commission
$attached = \addons\shopro\service\partner\IdentityService::attachAgent($userAgent);
$user->setRelation('agent', $attached);
$last = intval($attached['last_self_order_time'] ?? 0);
$isActive = !empty($attached['active_30d']);
if ($isActive) {
if ($last > 0) {
$daysPassed = floor(($now - $last) / 86400);
$remaining = max(0, intval($windowDays - $daysPassed));
$user->active_status = ($remaining <= 5) ? 'expiring' : 'active';
$user->days_remaining = $remaining;
} else {
$user->active_status = 'active';
$user->days_remaining = $windowDays;
}
} else {
$user->active_status = 'inactive';
$user->days_remaining = 0;
}
$user->active_status = $attached['active_status'] ?? 'inactive';
$user->days_remaining = $attached['days_remaining'] ?? 0;
$user->order_count = intval($userAgent['child_order_count_0'] ?? 0);
$user->consume_amount = \addons\shopro\service\partner\IdentityService::formatMoney($userAgent['child_order_money_0'] ?? ($user->total_consume ?? 0));

查看文件

@@ -28,7 +28,9 @@ class ActiveService
$start = $this->windowStart($at);
if ($last) {
return intval($last) >= $start;
$lastTime = intval($last);
$days = PartnerConfig::activeDays();
return ($at <= $lastTime + $days * 86400) || ($lastTime >= $start);
}
if (!$userId) {
return false;

查看文件

@@ -185,8 +185,8 @@ class IdentityService
if ($isActive) {
if ($lastTime > 0) {
$orderDay = strtotime(date('Y-m-d 00:00:00', $lastTime));
$expireTime = $orderDay + $windowDays * 86400;
// 方案 A:以订单支付时刻精确顺延 30 天(秒级精确,满 720 小时)
$expireTime = $lastTime + $windowDays * 86400;
$remainingSeconds = max(0, $expireTime - $now);
$daysRemaining = intval(ceil($remainingSeconds / 86400));
$activeStatus = ($daysRemaining <= 5) ? 'expiring' : 'active';

查看文件

@@ -0,0 +1,105 @@
<?php
namespace addons\shopro\service\user;
use think\Db;
use fast\Random;
/**
* 用户昵称规范生成服务
* 规则:HL + 手机尾号后4位(如 HL5758);若重复则追加递增数字(如 HL57581, HL57582...)
*/
class NicknameService
{
/** 前缀 */
const PREFIX = 'HL';
/**
* 生成符合规范且数据库唯一的昵称
*
* @param string|null $mobile 手机号(可选)
* @param int $excludeUserId 排除的用户ID(用于修改资料校验重名时排除自身)
* @return string 规范昵称
*/
public static function generate($mobile = '', $excludeUserId = 0)
{
$suffix = self::extractMobileSuffix($mobile);
// 基础昵称:HL + 尾号4位
$baseNickname = self::PREFIX . $suffix;
// 查重并保证全局唯一
return self::ensureUnique($baseNickname, $excludeUserId);
}
/**
* 提取手机号后4位,若手机号无效则生成4位随机数字
*
* @param string|null $mobile
* @return string 4位数字字符
*/
public static function extractMobileSuffix($mobile = '')
{
if (!empty($mobile)) {
// 清除非数字字符(如 +86、空格、破折号)
$digits = preg_replace('/\D/', '', (string) $mobile);
if (strlen($digits) >= 4) {
return substr($digits, -4);
}
}
// 手机号不足4位或未提供时,生成4位随机数字
return sprintf('%04d', mt_rand(1000, 9999));
}
/**
* 确保昵称在数据库 fa_user 表中唯一
* 若已存在,则追加递增数字后缀(如 HL57581、HL57582...)
*
* @param string $baseNickname 基础昵称
* @param int $excludeUserId 排除的用户ID
* @return string 唯一昵称
*/
public static function ensureUnique($baseNickname, $excludeUserId = 0)
{
// 1. 若基础昵称未被占用,直接使用
if (!self::isNicknameTaken($baseNickname, $excludeUserId)) {
return $baseNickname;
}
// 2. 若被占用,从数字 1 开始追加尝试(HL57581, HL57582 ...)
$seq = 1;
while (true) {
$candidate = $baseNickname . $seq;
if (!self::isNicknameTaken($candidate, $excludeUserId)) {
return $candidate;
}
$seq++;
// 安全防死循环上限
if ($seq > 9999) {
return $baseNickname . mt_rand(1000, 9999);
}
}
}
/**
* 检查昵称是否已被占用
*
* @param string $nickname 候选昵称
* @param int $excludeUserId 排除的用户ID
* @return bool
*/
public static function isNicknameTaken($nickname, $excludeUserId = 0)
{
try {
$query = Db::name('user')->where('nickname', $nickname);
if ($excludeUserId > 0) {
$query->where('id', '<>', $excludeUserId);
}
return $query->count() > 0;
} catch (\Throwable $e) {
// 若在脱机/无DB连接测试环境,放行
return false;
}
}
}

查看文件

@@ -77,9 +77,12 @@ class UserAuth
$userDefaultConfig = $this->getUserDefaultConfig();
// 规范昵称:若外部未传入真实自定义昵称,按 HL + 手机尾号(重名追加递增数字)规范生成
$nickname = !empty($params['nickname']) ? $params['nickname'] : NicknameService::generate($mobile);
$extend = [
'avatar' => !empty($params['avatar']) ? $params['avatar'] : $userDefaultConfig['avatar'],
'nickname' => !empty($params['nickname']) ? $params['nickname'] : $userDefaultConfig['nickname'] . $username,
'nickname' => $nickname,
'group_id' => $userDefaultConfig['group_id'] ?? 1
];