讲师中心 微信公众号

工具推荐

视频效率加速
立刻MV
立刻MV

低成本歌曲 MV、视频生成

updream

一键生成高质量推广成片

AniShort
AniShort

AI短剧协同制作平台

剧云
剧云

中文短剧剧本制作平台

Laravel 中按销售计算推荐人佣金的完整实现方案

冬伟吖_8480

冬伟吖_8480

发布时间:2026-03-19 14:12:23

|

249人浏览过

|

来源于php中文网

原创

Laravel 中按销售计算推荐人佣金的完整实现方案

本文详解如何在 laravel 应用中基于 sales 表与 user 表的关联关系,高效、准确地为每位推荐人(sponsor)按销售订单计算并汇总佣金(如 10%),支持时间范围筛选与空 sponsor_id 的健壮处理。

本文详解如何在 laravel 应用中基于 sales 表与 user 表的关联关系,高效、准确地为每位推荐人(sponsor)按销售订单计算并汇总佣金(如 10%),支持时间范围筛选与空 sponsor_id 的健壮处理。

在电商或分销类系统中,为推荐人(sponsor)按实际促成的销售发放佣金,是核心业务逻辑之一。典型场景是:每笔订单记录中通过 sponsor_id 字段标识推荐人,而该字段可为空(即自然流量成交);产品价格存储在独立 products 表中,需关联后按比例(如 10%)计算单笔奖励金额,并最终按 sponsor_id 聚合总奖励。

✅ 正确的数据建模与关系定义

首先确保 Eloquent 关系清晰准确。由于 sponsor_id 存在于 sales 表并指向 users.id,推荐人应作为 被关联方,因此 User 模型需定义反向一对多关系:

// app/Models/User.php
class User extends Model
{
    protected $fillable = ['name', 'email']; // 根据实际调整

    public function sponsoredSales()
    {
        return $this->hasMany(Sale::class, 'sponsor_id', 'id');
    }
}

同时,Sale 模型应关联 Product 以获取价格(假设 products 表含 price 字段):

// app/Models/Sale.php
class Sale extends Model
{
    protected $fillable = ['user_id', 'product_id', 'sponsor_id'];

    public function product()
    {
        return $this->belongsTo(Product::class);
    }

    public function sponsor()
    {
        return $this->belongsTo(User::class, 'sponsor_id');
    }
}

✅ 高效聚合计算:避免 N+1,使用 JOIN 与 SUM

不建议先查出所有带 sponsor_id 的销售再循环计算(如原始代码中的 foreach($sales as $sale)),尤其在数据量大时性能差且难以聚合。推荐使用数据库层聚合,一次查询返回每个 sponsor 的总奖励:

use Illuminate\Support\Facades\DB;

$rewardRate = 0.1; // 10%
$start = now()->subDays(30);
$end = now();

$results = DB::table('sales')
    ->select(
        'sales.sponsor_id',
        'users.name as sponsor_name',
        DB::raw('COUNT(*) as total_sales'),
        DB::raw('SUM(products.price * ?) as total_reward', [$rewardRate])
    )
    ->join('products', 'sales.product_id', '=', 'products.id')
    ->join('users', 'sales.sponsor_id', '=', 'users.id')
    ->whereBetween('sales.created_at', [$start, $end])
    ->whereNotNull('sales.sponsor_id')
    ->groupBy('sales.sponsor_id', 'users.name')
    ->orderByDesc('total_reward')
    ->get();

// 输出示例:
// [
//   { "sponsor_id": 30, "sponsor_name": "Alice", "total_sales": 2, "total_reward": "25.80" },
//   { "sponsor_id": 31, "sponsor_name": "Bob",   "total_sales": 1, "total_reward": "12.90" }
// ]

? 提示:DB::raw('SUM(products.price * ?)') 中使用参数绑定(?)可防止 SQL 注入,比拼接字符串更安全。

✅ 进阶:封装为 Eloquent 查询构建器(推荐)

若偏好全 Eloquent 风格,可利用 withSum()(Laravel 8.77+)或手动 selectRaw + join:

$sponsorsWithRewards = User::select('users.id', 'users.name')
    ->join('sales', 'users.id', '=', 'sales.sponsor_id')
    ->join('products', 'sales.product_id', '=', 'products.id')
    ->whereBetween('sales.created_at', [$start, $end])
    ->selectRaw('COUNT(*) as sales_count')
    ->selectRaw('SUM(products.price * ?) as reward_amount', [$rewardRate])
    ->groupBy('users.id', 'users.name')
    ->orderByDesc('reward_amount')
    ->get();

⚠️ 关键注意事项

  • 空 sponsor_id 处理:务必使用 whereNotNull('sponsor_id') 排除无推荐人的订单,避免 NULL 参与分组导致意外结果;
  • 时间范围字段确认:确保 sales.created_at 存在且已索引;若使用自定义时间字段(如 paid_at),请同步调整;
  • 精度与货币安全:佣金计算涉及金额,建议在数据库中使用 DECIMAL(10,2) 类型存储价格,并在 PHP 层使用 bcadd()/bcmul() 进行高精度运算(尤其涉及多币种或复杂分成);
  • 权限与数据隔离:生产环境需校验当前管理员是否有权查看指定 sponsor 的佣金数据,避免越权访问;
  • 缓存策略:对高频访问的“本月推荐榜”等报表,可结合 Cache::remember() 缓存 15 分钟,减轻数据库压力。

✅ 总结

计算推荐人佣金的本质是「带条件的跨表聚合」。最佳实践是:
① 基于清晰的外键关系定义 Eloquent 关联;
② 利用数据库原生聚合函数(SUM, COUNT, GROUP BY)在 SQL 层完成计算,而非 PHP 循环;
③ 严格过滤 sponsor_id IS NOT NULL 和时间范围;
④ 对金额运算保持精度意识,必要时引入 BCMath。

此方案兼具性能、可读性与可维护性,可直接集成至后台报表、结算任务或 API 接口。

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

SkildArt
SkildArt Hot

SkildArt是一款AI文本写作工具,一站式 AI 视觉创作平台。

讯飞智作

讯飞智作是一款AI视频创作工具,AI文本配音工具,数字人课程、营销视频制作。

UpDream
UpDream Hot

一款AI视频创作工具,主要用于哔哩哔哩推出的自研AI视频创作工具,适合需要提升相关任务效率的用户。

码上飞
码上飞 Hot

一款基于自然语言的AI应用开发平台,可根据用户描述自动生成应用程序,帮助个人和团队快速完成应用原型与开发。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

蛙蛙写作

一款AI论文写作工具,主要用于超级AI智能写作助手,适合需要提升相关任务效率的用户。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

Seko
Seko Hot

一款AI视频创作工具,主要用于商汤科技推出的创编一体的AI短视频创作Agent,适合需要提升相关任务效率的用户。

相关专题

更多
php文件怎么打开
php文件怎么打开

打开php文件步骤:1、选择文本编辑器;2、在选择的文本编辑器中,创建一个新的文件,并将其保存为.php文件;3、在创建的PHP文件中,编写PHP代码;4、要在本地计算机上运行PHP文件,需要设置一个服务器环境;5、安装服务器环境后,需要将PHP文件放入服务器目录中;6、一旦将PHP文件放入服务器目录中,就可以通过浏览器来运行它。

12784

2023.09.01

php怎么取出数组的前几个元素
php怎么取出数组的前几个元素

取出php数组的前几个元素的方法有使用array_slice()函数、使用array_splice()函数、使用循环遍历、使用array_slice()函数和array_values()函数等。本专题为大家提供php数组相关的文章、下载、课程内容,供大家免费下载体验。

7321

2023.10.11

php反序列化失败怎么办
php反序列化失败怎么办

php反序列化失败的解决办法检查序列化数据。检查类定义、检查错误日志、更新PHP版本和应用安全措施等。本专题为大家提供php反序列化相关的文章、下载、课程内容,供大家免费下载体验。

2255

2023.10.11

php怎么连接mssql数据库
php怎么连接mssql数据库

连接方法:1、通过mssql_系列函数;2、通过sqlsrv_系列函数;3、通过odbc方式连接;4、通过PDO方式;5、通过COM方式连接。想了解php怎么连接mssql数据库的详细内容,可以访问下面的文章。

4628

2023.10.23

php连接mssql数据库的方法
php连接mssql数据库的方法

php连接mssql数据库的方法有使用PHP的MSSQL扩展、使用PDO等。想了解更多php连接mssql数据库相关内容,可以阅读本专题下面的文章。

5334

2023.10.23

html怎么上传
html怎么上传

html通过使用HTML表单、JavaScript和PHP上传。更多关于html的问题详细请看本专题下面的文章。php中文网欢迎大家前来学习。

4211

2023.11.03

PHP出现乱码怎么解决
PHP出现乱码怎么解决

PHP出现乱码可以通过修改PHP文件头部的字符编码设置、检查PHP文件的编码格式、检查数据库连接设置和检查HTML页面的字符编码设置来解决。更多关于php乱码的问题详情请看本专题下面的文章。php中文网欢迎大家前来学习。

6097

2023.11.09

php文件怎么在手机上打开
php文件怎么在手机上打开

php文件在手机上打开需要在手机上搭建一个能够运行php的服务器环境,并将php文件上传到服务器上。再在手机上的浏览器中输入服务器的IP地址或域名,加上php文件的路径,即可打开php文件并查看其内容。更多关于php相关问题,详情请看本专题下面的文章。php中文网欢迎大家前来学习。

4782

2023.11.13

Go-Zero API开发使用教程
Go-Zero API开发使用教程

本专题聚焦Go-Zero的API开发,拆解.api描述文件的语法结构、路由与分组定义、参数绑定与校验规则,说明统一响应体、JWT鉴权、跨域与接口文档生成的落地方式,并给出网关聚合与接口测试的实践建议。

20

2026.11.12

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn