Files
huangjingfen/pro_v3.5.1/app/services/hjf/PointsReleaseServices.php
mac 451918bc73 fix(fsgx): 修复5个未修复Bug — 积分解耦/定时任务/积分日志/团队统计/历史补偿
Bug3: 解耦积分奖励与佣金发放,报单订单只要推荐人存在即触发积分,
不再依赖 brokeragePrice > 0;grantFrozenPointsByBrokerage 移至
佣金判断之前独立执行。

Bug1: 定时任务手动触发返回真实结果 —— 补充 fsgx_release_frozen_points
到 taskName 映射;runNow() try/catch 后抛出异常;控制器捕获并返回
fail;修复 SystemTimer listener catch 块运算符优先级 bug。

Bug5: PointsReleaseServices 每日释放同步写入 eb_user_bill,使管理
后台积分日志页面可见;UserPointServices::pointRecord $status 数组
补充 hjf_frozen_direct/hjf_frozen_umbrella/frozen_points_release 等
fsgx 类型映射,防止未知类型报错。

Bug2: hjfMember.js getTeamData 改为 POST 与路由匹配;loadTeamData
字段映射 total/totalLevel/order_count → 界面展示字段。

Bug4: 新增 HjfPatchMissingRewards 命令(hjf:patch-rewards),支持
扫描全量/指定订单补发缺失积分奖励,支持 --dry-run 预览;注册命令
到 config/console.php。

Made-with: Cursor
2026-03-24 20:40:46 +08:00

129 lines
4.3 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
declare(strict_types=1);
namespace app\services\hjf;
use app\dao\hjf\PointsReleaseLogDao;
use app\dao\user\UserDao;
use app\services\BaseServices;
use app\services\user\UserBillServices;
use crmeb\services\SystemConfigService;
use think\annotation\Inject;
use think\facade\Db;
use think\facade\Log;
/**
* 积分每日释放服务
*
* 由定时任务每天凌晨00:01或 Command 触发。
* 计算公式release_amount = FLOOR(frozen_points × rate / 1000)
* 其中 rate = hjf_release_rate默认 4即 4‰
*
* Class PointsReleaseServices
* @package app\services\hjf
*/
class PointsReleaseServices extends BaseServices
{
#[Inject]
protected PointsReleaseLogDao $logDao;
#[Inject]
protected UserDao $userDao;
#[Inject]
protected UserBillServices $userBillServices;
/**
* 执行今日积分释放(批量)
*
* @return array 统计:['processed' => int, 'total_released' => int]
*/
public function executeRelease(): array
{
$rate = (int)SystemConfigService::get('hjf_release_rate', 4);
$releaseDate = date('Y-m-d');
$processed = 0;
$totalReleased = 0;
// 分批处理,每批 200 条,避免内存溢合
$page = 1;
$limit = 200;
do {
$users = $this->userDao->selectList(
['frozen_points' => ['>', 0]],
'uid,frozen_points,available_points',
$page,
$limit,
'uid',
'asc'
);
if (empty($users)) {
break;
}
foreach ($users as $user) {
$frozenBefore = (int)$user['frozen_points'];
// 使用 bcmath 确保精度
$releaseAmount = (int)bcdiv(bcmul((string)$frozenBefore, (string)$rate), '1000');
if ($releaseAmount <= 0) {
continue;
}
$frozenAfter = $frozenBefore - $releaseAmount;
try {
Db::transaction(function () use ($user, $releaseAmount, $frozenBefore, $frozenAfter, $releaseDate) {
// 更新用户积分字段
$this->userDao->update($user['uid'], [
'frozen_points' => $frozenAfter,
'available_points' => Db::raw('available_points + ' . $releaseAmount),
], 'uid');
// 写 points_release_log本次每日释放记录
$this->logDao->save([
'uid' => $user['uid'],
'points' => $releaseAmount,
'pm' => 1,
'type' => 'release',
'title' => '每日释放',
'mark' => "积分每日自动解冻,释放日期 {$releaseDate}",
'status' => 'released',
'release_date' => $releaseDate,
]);
// 同步写入 eb_user_bill使管理后台积分日志页面可见
$integralBalance = (int)($this->userDao->value(['uid' => $user['uid']], 'integral') ?: 0);
$this->userBillServices->income(
'frozen_points_release',
(int)$user['uid'],
(int)$releaseAmount,
$integralBalance,
0,
0,
"积分每日自动解冻,释放日期 {$releaseDate}"
);
});
$totalReleased += $releaseAmount;
$processed++;
} catch (\Throwable $e) {
Log::error("[PointsRelease] uid={$user['uid']} 释放失败: " . $e->getMessage());
}
}
$page++;
} while (count($users) === $limit);
Log::info("[PointsRelease] 完成processed={$processed} total_released={$totalReleased}");
return [
'processed' => $processed,
'total_released' => $totalReleased,
'release_date' => $releaseDate,
];
}
}