model('commission_legumes_log')->getSum($where, 'get_legumes'), 'total_order_money' => model('commission_legumes_log')->getSum($where, 'order_money'), 'total_get_integral' => model('commission_legumes_log')->getSum($where, 'get_integral'), 'total_use_integral' => model('commission_legumes_log')->getSum($where, 'use_integral'), 'total_freeze_integral' => model('commission_legumes_log')->getSum($freezeWhere, 'get_integral'), ]; } /** * Common: 获取豆豆周期结算信息 * Author: wu-hui * Time: 2024/05/09 11:49 * @param $page * @param $params * @return array */ public function getCycleList($page, $params) { // 生成查询条件 $where = []; // 关联查询 $result = model('commission_legumes')->pageList($where, true, 'id DESC', $page, PAGE_LIST_ROWS); return $this->success($result); } /** * Common: 获取豆豆分配明细 * Author: wu-hui * Time: 2024/05/09 11:58 * @param $page * @param $params * @return array */ public function getLegumesLogList($page, $params) { $pageSize = $params['page_size'] ?? PAGE_LIST_ROWS; // 生成查询条件 $where = []; if (isset($params['member_id']) && $params['member_id'] !== '') { if (is_array($params['member_id'])) $where[] = ['a.member_id', 'in', $params['member_id']]; else $where[] = ['a.member_id', '=', $params['member_id']]; } if (isset($params['legumes_id']) && $params['legumes_id'] !== '') $where[] = ['a.legumes_id', '=', $params['legumes_id']]; if (isset($params['status']) && $params['status'] !== '') $where[] = ['a.status', '=', $params['status']]; // 关联查询 $join = [ ['member m', 'm.member_id = a.member_id', 'left'], ]; $field = [ 'a.*', 'm.nickname', 'm.username', 'm.headimg', ]; $result = model('commission_legumes_log')->pageList($where, $field, 'id DESC', $page, $pageSize, 'a', $join); return $this->success($result); } /** * Common: 获取积分释放明细 * Author: wu-hui * Time: 2024/05/15 15:06 * @param $params * @return array */ public function legumesReleaseLog($params) { $pageSize = $params['page_size'] ?? PAGE_LIST_ROWS; $page = $params['page'] ?? 1; // 生成查询条件 $where = []; if (isset($params['member_id']) && $params['member_id'] !== '') $where[] = ['member_id', '=', $params['member_id']]; if (isset($params['legumes_log_id']) && $params['legumes_log_id'] !== '') $where[] = ['legumes_log_id', '=', $params['legumes_log_id']]; // 关联查询 $result = model('commission_legumes_release_log')->pageList($where, true, 'id DESC', $page, $pageSize); return $this->success($result); } /** * Common: 获取用户持有信息 * Author: wu-hui * Time: 2024/05/09 13:45 * @param $page * @param $params * @return array */ public function getHoldList($page, $params) { $result = $this->getHoldListData($page, $params); return $this->success($result); } /** * Common: 获取用户持有信息(返回信息数组) * Author: wu-hui * Time: 2024/05/29 11:23 * @return mixed */ public function getHoldListData($page, $params) { // 生成查询条件 $where = [ ['a.status', 'in', [0, 1]], ]; if (isset($params['member_id']) && $params['member_id'] !== '') { if (is_array($params['member_id'])) $where[] = ['a.member_id', 'in', $params['member_id']]; else $where[] = ['a.member_id', '=', $params['member_id']]; } // 关联查询 $join = [ ['member m', 'm.member_id = a.member_id', 'left'], ]; $field = [ 'a.member_id', 'sum(a.order_money) as total_order_money', 'sum(a.get_legumes) as total_get_legumes', 'sum(a.refund_order_money) as total_refund_order_money', 'sum(a.refund_get_legumes) as total_refund_get_legumes', 'sum(a.get_integral) as total_get_integral', 'sum(a.use_integral) as total_use_integral', 'm.nickname', 'm.username', 'm.headimg', ]; $result = model('commission_legumes_log')->pageList($where, $field, 'id DESC', $page, PAGE_LIST_ROWS, 'a', $join, 'a.member_id'); // 获取冻结中积分 $memberIds = array_column($result['list'], 'member_id'); $freezeWhere = [ ['member_id', 'in', $memberIds], ['status', '=', 0], ]; $freezeField = 'member_id,sum(get_integral) as total_get_integral'; $freeze = model('commission_legumes_log')->getList($freezeWhere, $freezeField, '', 'a', [], 'member_id'); $freeze = array_column($freeze, 'total_get_integral', 'member_id'); foreach ($result['list'] as &$singleInfo) { // 总冻结积分 $singleInfo['total_freeze_integral'] = $freeze[$singleInfo['member_id']] ?? 0; // 可使用积分 $reduce = (float)sprintf("%.2f", $singleInfo['total_freeze_integral'] + $singleInfo['total_use_integral']);// 冻结 + 已使用积分 $singleInfo['surplus_use_integral'] = (float)sprintf("%.2f", $singleInfo['total_get_integral'] - $reduce); } return $result; } /** * Common: 获取单个用户持有信息 * Author: wu-hui * Time: 2024/05/09 16:06 * @param $memberId * @return array|mixed */ public function getMemberHoldInfo($memberId) { $result = $this->getHoldListData(1, ['member_id' => $memberId]); $info = $result['list'] ?? []; return $info[0] ?? []; } /** * Common: 获取全平台用户持有总积分信息 * Author: wu-hui * Time: 2024/05/29 11:40 * @param $memberId * @return array */ public function getAllSiteHoldInfo($memberId) { $memberId = (new Member())->getAllMemberIds($memberId); // 根据用户id 获取全部相关持有信息 $list = $this->getAllSiteHoldAllList(1, $memberId, true); return [ 'total_order_money' => sprintf("%.2f", array_sum(array_column($list, 'total_order_money'))), 'total_get_legumes' => sprintf("%.2f", array_sum(array_column($list, 'total_get_legumes'))), 'total_refund_order_money' => sprintf("%.2f", array_sum(array_column($list, 'total_refund_order_money'))), 'total_refund_get_legumes' => sprintf("%.2f", array_sum(array_column($list, 'total_refund_get_legumes'))), 'total_get_integral' => sprintf("%.2f", array_sum(array_column($list, 'total_get_integral'))), 'total_use_integral' => sprintf("%.2f", array_sum(array_column($list, 'total_use_integral'))), 'total_freeze_integral' => sprintf("%.2f", array_sum(array_column($list, 'total_freeze_integral'))), 'surplus_use_integral' => sprintf("%.2f", array_sum(array_column($list, 'surplus_use_integral'))) ]; } /** * Common: 获取全平台用户持有积分信息列表(递归获取全部列表) * Author: wu-hui * Time: 2024/05/29 11:34 * @param $page * @param $memberId * @param false $isGetAll * @param array $allList * @return array */ public function getAllSiteHoldAllList($page, $memberId, $isGetAll = false, $allList = []) { // 获取信息 $result = $this->getHoldListData($page, ['member_id' => $memberId]); $pageCount = $result['page_count'] ?? 1; $allList = array_merge($allList, $result['list']); // 判断:是否递归查询全部 if ($pageCount > $page && $isGetAll) { return $this->getAllSiteHoldAllList(++$page, $memberId, true, $allList); } // 返回列表信息 return $allList; } /** * Common: 豆豆计算 - 计算昨天产生的豆豆总数 * Author: wu-hui * Time: 2024/05/08 18:13 */ public function computeYesterdayLegumes() { // 获取总平台配置信息 $config = (new Setting())->getConfig(); $legumesPrice = (new Setting())->getLegumesPrice(); // 获取周期时间 [$startTime, $endTime] = getTimeStamp('yesterday');// 天 Db::startTrans(); try { // 判断:当前时间周期是否已经结算 $maxTime = model('commission_legumes')->getMax([], 'end_time'); if ($endTime <= $maxTime) throw new Exception('当前周期积分抽成已结算!'); // [$startTime,$endTime] = getTimeStamp('today');// todo:调试信息 // $startTime = mktime(0, 0, 0, date('m'), date('d') - 1, date('Y')); // $endTime = mktime(0, 0, 0, date('m'), date('d'), date('Y')); // 获取周期内积分抽成信息 $integralInfo = $this->getIntegralInfo($startTime, $endTime); if ((float)$integralInfo['reality_money'] <= 0) throw new Exception('周期内无积分抽成信息'); // 计算豆豆数量 豆豆数量 = 积分抽成金额(昨日总金额) * 0.2 / 豆豆当前价格 $legumesNum = (float)sprintf("%.4f", (float)$integralInfo['reality_money'] * 0.2 / $legumesPrice); // 今日豆豆数量 // 计算豆豆价格 下次豆豆价格 = 积分抽成金额(全平台总金额) ➗ 文创豆数量(全平台总数量) $allIntegralInfo = $this->getIntegralInfo(); $allLegumes = model('commission_legumes')->getSum([], 'legumes_num'); $tomorrowLegumesPrice = sprintf("%.4f", $allIntegralInfo['reality_money'] / ($allLegumes + $legumesNum)); // 记录 $recordId = model('commission_legumes')->add([ 'total_integral_money' => $integralInfo['total_money'], 'refund_money' => $integralInfo['refund_money'], 'reality_money' => $integralInfo['reality_money'], 'legumes_price' => $legumesPrice, 'legumes_num' => $legumesNum, 'tomorrow_legumes_price' => $tomorrowLegumesPrice, 'start_time' => $startTime, 'end_time' => $endTime, ]); // 修改豆豆实时价格 (new Setting())->setLegumesPrice(0, $tomorrowLegumesPrice); // 触发事件 开始给每个消费用户分豆豆 Queue::push(AllocationLegumesJob::class, [ 'legumes_id' => $recordId ]); Db::commit(); } catch (Exception $e) { Db::rollback(); $data = [ 'start' => date("Y-m-d H:i:s", $startTime), 'end' => date("Y-m-d H:i:s", $endTime), 'msg' => $e->getMessage() ]; trace($data, '计算昨天产生的豆豆总数 - 错误'); } } /** * Common: 豆豆计算 - 获取时间段内总积分抽成金额 * Author: wu-hui * Time: 2024/05/08 17:50 * @param int $startTime * @param int $endTime * @return array */ public function getIntegralInfo(int $startTime = 0, int $endTime = 0): array { $where = []; if ($startTime > 0 && $endTime > 0) { $where[] = ['create_time', 'between', [date("Y-m-d H:i:s", $startTime), date("Y-m-d H:i:s", $endTime)]]; } // 总佣金 $info['total_money'] = (float)model('commission_record')->getSum($where, 'integral_money'); // 获取退款金额 $info['refund_money'] = (float)model('commission_record')->getValue($where, 'sum((integral_money * refund_ratio / 100)) as refund_money'); // 实际金额 $info['reality_money'] = (float)sprintf("%.3f", (float)$info['total_money'] - (float)$info['refund_money']); return $info; } /** * Common: 查询需要使用的分配信息 尽可能仅查询需要使用的信息 * Author: wu-hui * Time: 2024/05/11 9:45 * @param int $memberId * @param float $useLegumesIntegral * @param int $page * @return array|mixed */ public function getUseList(int $memberId, float $useLegumesIntegral, int $limit = 10) { $where = [ ['status', '=', 1], // [ 'member_id', '=', $memberId], ['', 'exp', Db::raw('get_integral > use_integral')] ]; // 多平台同用户积分兼容 $memberId = (new Member())->getAllMemberIds($memberId); if (is_array($memberId)) $where[] = ['member_id', 'in', $memberId]; else $where[] = ['member_id', '=', $memberId]; // 查询 $field = 'id,member_id,get_integral,use_integral,(get_integral - use_integral) as surplus_integral'; $result = model('commission_legumes_log')->pageList($where, $field, 'id ASC', 1, $limit); $list = $result['list'] ?? []; $pageCount = $result['page_count'] ?? 1; // 判断:总页数 大于当前页 判断是否需要递归 if ($pageCount > 1) { $totalSurplusIntegral = array_sum(array_column($list, 'surplus_integral')); if ($useLegumesIntegral > $totalSurplusIntegral) { $limit += 10; return $this->getUseList($memberId, $useLegumesIntegral, $limit); } } return $list; } /** * Common: 查询已使用积分的分配信息 尽可能查询需要的信息 * Author: wu-hui * Time: 2024/05/13 16:19 * @param int $memberId * @param float $maxIntegral * @param int $limit * @return array|mixed */ public function getUsedList(int $memberId, float $maxIntegral, int $limit = 10) { $where = [ ['status', '=', 1], // [ 'member_id', '=', $memberId], ['use_integral', '>', 0], ]; // 多平台同用户积分兼容 $memberId = (new Member())->getAllMemberIds($memberId); if (is_array($memberId)) $where[] = ['member_id', 'in', $memberId]; else $where[] = ['member_id', '=', $memberId]; // 查询 $result = model('commission_legumes_log')->pageList($where, 'id,get_integral,use_integral', 'id DESC', 1, $limit); $list = $result['list'] ?? []; $pageCount = $result['page_count'] ?? 1; if ($pageCount > 1) { $totalSurplusIntegral = array_sum(array_column($list, 'use_integral')); if ($maxIntegral > $totalSurplusIntegral) { $limit += 10; return $this->getUseList($memberId, $maxIntegral, $limit); } } return $list; } /** * Common: 获取统计信息 * Author: wu-hui * Time: 2024/05/11 15:09 * @param array $params * @return array */ public function getStatistics(array $params) { // 获取当前用户可用豆豆积分 $legumes = (new Legumes())->getAllSiteHoldInfo((int)$params['member_id']); // 获取统计信息 $data = [ 'integral_upper_limit' => $this->getModel($params)->sum('order_money'),// 积分释放上限(总) 'get_legumes' => $this->getModel($params)->sum('get_legumes'),// 总获得豆豆 'refund_get_legumes' => $this->getModel($params)->sum('refund_get_legumes'),// 退款减少豆豆 'get_integral' => $this->getModel($params)->sum('get_integral'),// 获得积分 'freeze_integral' => $this->getModel($params)->where('status', 0)->sum('get_integral'),// 冻结中积分 'used_integral' => $legumes['surplus_use_integral'] ?? 0,// 可用积分 'use_integral' => $this->getModel($params)->sum('use_integral'),// 已使用积分 ]; // 未释放积分 = 积分释放上限 - 已获得积分 $data['not_integral'] = (float)sprintf("%.4f", $data['integral_upper_limit'] - $data['get_integral']); // 实际获得豆豆 $data['reality_get_legumes'] = (float)sprintf("%.4f", $data['get_legumes'] - $data['refund_get_legumes']); return $data; } /** * Common: 查询model(统计查询使用) * Author: wu-hui * Time: 2024/05/11 15:00 * @param $params * @return Db */ public function getModel($params) { return Db::name('commission_legumes_log') ->when((int)$params['member_id'] > 0, function ($query) use ($params) { $memberId = (new Member())->getAllMemberIds((int)$params['member_id']); if (is_array($memberId)) $query->whereIn('member_id', $memberId); else $query->where('member_id', $memberId); }) ->when(isset($params['status']) && $params['status'] !== '', function ($query) use ($params) { $query->where('status', $params['status']); }) ->whereIn('status', [0, 1]); } }