adminOnly(); } /** * AF1 资金流水 * GET /api/v1/admin/finance/flows 入参 {type?,page,size} * → 分页 {list:[{id,flowNo,type,scene,amount,balance,createdAt}],page,size,total,hasMore} */ public function flows() { $type = trim((string)$this->input('type', '')); // 闭包重建查询:TP5.0 的 count() 会清空 Query::options,不能复用同一对象 list($rows, $total, $page, $size) = $this->pageQuery(function ($forCount) use ($type) { $q = Db::name('fc_finance_flow'); if ($type !== '') { $q->where('type', $type); } if ($forCount) { return $q; } return $q->order('createtime desc'); }); $list = []; foreach ($rows as $row) { $list[] = [ 'id' => (int)$row['id'], 'flowNo' => (string)$row['flow_no'], 'type' => (string)$row['type'], 'scene' => (string)$row['scene'], 'amount' => (float)$row['amount'], 'balance' => (float)$row['balance'], 'createdAt' => $this->iso($row['createtime']), ]; } $this->ok($this->paginate($list, $total, $page, $size)); } /** * AF2 财务报表 * GET /api/v1/admin/finance/report 入参 {period: day|month|year} * → {period, rows:[{period,postIncome,memberIncome,rechargeIncome,withdraw,net}]} */ public function report() { $period = trim((string)$this->input('period', 'day')); if (!in_array($period, ['day', 'month', 'year'], true)) { $period = 'day'; } $fmtMap = ['day' => '%Y-%m-%d', 'month' => '%Y-%m', 'year' => '%Y']; $fmt = $fmtMap[$period]; $post = $this->periodOrderSum('post', $fmt); $member = $this->periodOrderSum('member', $fmt); $recharge = $this->periodOrderSum('recharge', $fmt); $withdraw = $this->periodWithdrawSum($fmt); $keys = array_unique(array_merge( array_keys($post), array_keys($member), array_keys($recharge), array_keys($withdraw) )); sort($keys); $rows = []; foreach ($keys as $k) { $p = isset($post[$k]) ? (float)$post[$k] : 0; $m = isset($member[$k]) ? (float)$member[$k] : 0; $r = isset($recharge[$k]) ? (float)$recharge[$k] : 0; $w = isset($withdraw[$k]) ? (float)$withdraw[$k] : 0; $rows[] = [ 'period' => (string)$k, 'postIncome' => $p, 'memberIncome' => $m, 'rechargeIncome' => $r, 'withdraw' => $w, 'net' => round($p + $m + $r - $w, 2), ]; } $this->ok(['period' => $period, 'rows' => $rows]); } /** 按周期聚合某类已支付订单金额,返回 [period => total] */ protected function periodOrderSum($type, $fmt) { $rows = Db::name('fc_order') ->where('status', 'paid') ->where('type', $type) ->field("FROM_UNIXTIME(createtime, '{$fmt}') AS period, SUM(amount) AS total") ->group('period') ->select(); $map = []; foreach ($rows as $row) { $map[$row['period']] = (float)$row['total']; } return $map; } /** 按周期聚合已打款提现金额,返回 [period => total] */ protected function periodWithdrawSum($fmt) { $rows = Db::name('fc_withdraw') ->where('status', 'paid') ->whereNotNull('paytime') ->field("FROM_UNIXTIME(paytime, '{$fmt}') AS period, SUM(amount) AS total") ->group('period') ->select(); $map = []; foreach ($rows as $row) { $map[$row['period']] = (float)$row['total']; } return $map; } }