112 lines
3.8 KiB
PHP
112 lines
3.8 KiB
PHP
|
|
<?php
|
|||
|
|
// +----------------------------------------------------------------------
|
|||
|
|
// | 范氏国香 fsgx — 积分释放服务
|
|||
|
|
// +----------------------------------------------------------------------
|
|||
|
|
|
|||
|
|
namespace app\services\hjf;
|
|||
|
|
|
|||
|
|
use app\dao\user\UserDao;
|
|||
|
|
use app\services\BaseServices;
|
|||
|
|
use app\services\user\UserBillServices;
|
|||
|
|
use think\facade\Db;
|
|||
|
|
use think\facade\Log;
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 待释放积分每日释放服务
|
|||
|
|
* 规则:每日将 frozen_points 的 0.4‰ 转入 available_points
|
|||
|
|
* 触发:定时任务 mark=fsgx_release_frozen_points(每天执行一次)
|
|||
|
|
*/
|
|||
|
|
class HjfPointsServices extends BaseServices
|
|||
|
|
{
|
|||
|
|
protected float $releaseRate = 0.0004; // 0.4‰
|
|||
|
|
|
|||
|
|
public function __construct(UserDao $dao)
|
|||
|
|
{
|
|||
|
|
$this->dao = $dao;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 每日批量释放待释放积分
|
|||
|
|
* 批量处理,每批 200 条,避免内存溢出
|
|||
|
|
*/
|
|||
|
|
public function dailyReleasePoints(): bool
|
|||
|
|
{
|
|||
|
|
$page = 1;
|
|||
|
|
$limit = 200;
|
|||
|
|
$processedCount = 0;
|
|||
|
|
|
|||
|
|
do {
|
|||
|
|
$users = Db::table('eb_user')
|
|||
|
|
->where('frozen_points', '>', 0)
|
|||
|
|
->field('uid, frozen_points, available_points')
|
|||
|
|
->page($page, $limit)
|
|||
|
|
->select()
|
|||
|
|
->toArray();
|
|||
|
|
|
|||
|
|
foreach ($users as $user) {
|
|||
|
|
try {
|
|||
|
|
$release = (int)floor($user['frozen_points'] * $this->releaseRate);
|
|||
|
|
if ($release <= 0) continue;
|
|||
|
|
|
|||
|
|
$newFrozen = $user['frozen_points'] - $release;
|
|||
|
|
$newAvailable = $user['available_points'] + $release;
|
|||
|
|
|
|||
|
|
Db::table('eb_user')->where('uid', $user['uid'])->update([
|
|||
|
|
'frozen_points' => max(0, $newFrozen),
|
|||
|
|
'available_points' => $newAvailable,
|
|||
|
|
]);
|
|||
|
|
|
|||
|
|
// 写积分日志
|
|||
|
|
/** @var UserBillServices $billServices */
|
|||
|
|
$billServices = app()->make(UserBillServices::class);
|
|||
|
|
$billServices->income('frozen_points_release', $user['uid'], [
|
|||
|
|
'number' => $release,
|
|||
|
|
'mark' => '待释放积分每日释放',
|
|||
|
|
'balance' => $newAvailable,
|
|||
|
|
'type' => 'integral',
|
|||
|
|
'title' => '积分释放',
|
|||
|
|
'pm' => 1,
|
|||
|
|
], $newAvailable, 0);
|
|||
|
|
|
|||
|
|
$processedCount++;
|
|||
|
|
} catch (\Throwable $e) {
|
|||
|
|
Log::error('fsgx dailyReleasePoints uid=' . $user['uid'] . ' error: ' . $e->getMessage());
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
$page++;
|
|||
|
|
} while (count($users) === $limit);
|
|||
|
|
|
|||
|
|
Log::info("fsgx dailyReleasePoints done, processed={$processedCount}");
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 扣减已释放积分(用于积分消费)
|
|||
|
|
* @param int $uid
|
|||
|
|
* @param int $points 消费积分数
|
|||
|
|
* @return bool
|
|||
|
|
*/
|
|||
|
|
public function deductAvailablePoints(int $uid, int $points): bool
|
|||
|
|
{
|
|||
|
|
$user = Db::table('eb_user')->where('uid', $uid)->field('uid, available_points')->find();
|
|||
|
|
if (!$user || $user['available_points'] < $points) return false;
|
|||
|
|
|
|||
|
|
$newAvailable = $user['available_points'] - $points;
|
|||
|
|
Db::table('eb_user')->where('uid', $uid)->update(['available_points' => $newAvailable]);
|
|||
|
|
|
|||
|
|
/** @var UserBillServices $billServices */
|
|||
|
|
$billServices = app()->make(UserBillServices::class);
|
|||
|
|
$billServices->expenditure('available_points_use', $uid, [
|
|||
|
|
'number' => $points,
|
|||
|
|
'mark' => '积分消费',
|
|||
|
|
'balance' => $newAvailable,
|
|||
|
|
'type' => 'integral',
|
|||
|
|
'title' => '积分消费',
|
|||
|
|
'pm' => 0,
|
|||
|
|
], $newAvailable, 0);
|
|||
|
|
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
}
|