|
|
@@ -17,17 +17,97 @@ use bizHd\shop\classes\ShopExtClass;
|
|
|
use bizHd\shop\classes\MainClass;
|
|
|
use bizHd\user\classes\UserGrowthClass;
|
|
|
use bizHd\user\classes\UserIntegralClass;
|
|
|
+use common\components\dateUtil;
|
|
|
use common\components\dict;
|
|
|
use common\components\lakala\Lakala;
|
|
|
use common\components\noticeUtil;
|
|
|
+use common\components\orderSn;
|
|
|
use common\components\util;
|
|
|
use Yii;
|
|
|
use bizHd\base\classes\BaseClass;
|
|
|
+use yii\db\Expression;
|
|
|
|
|
|
class RechargeClass extends BaseClass
|
|
|
{
|
|
|
|
|
|
public static $baseFile = '\bizHd\recharge\models\Recharge';
|
|
|
+ const STAT_CACHE_TTL = 300; //统计数据缓存时长
|
|
|
+
|
|
|
+ //充值记录
|
|
|
+ public static function getRechargeList($where, $channelKey = 'all', $io = null)
|
|
|
+ {
|
|
|
+ switch ($channelKey) {
|
|
|
+ case 'system':
|
|
|
+ $where['onlinePay'] = 2;
|
|
|
+ break;
|
|
|
+ case 'online_0':
|
|
|
+ $where['onlinePay'] = 2;
|
|
|
+ $where['payWay'] = 0;
|
|
|
+ break;
|
|
|
+ case 'online_1':
|
|
|
+ $where['onlinePay'] = 2;
|
|
|
+ $where['payWay'] = 1;
|
|
|
+ break;
|
|
|
+ case 'pay_0':
|
|
|
+ $where['onlinePay!='] = 2;
|
|
|
+ $where['payWay'] = 0;
|
|
|
+ break;
|
|
|
+ case 'pay_1':
|
|
|
+ $where['onlinePay!='] = 2;
|
|
|
+ $where['payWay'] = 1;
|
|
|
+ break;
|
|
|
+ case 'pay_4':
|
|
|
+ $where['onlinePay!='] = 2;
|
|
|
+ $where['payWay'] = 4;
|
|
|
+ break;
|
|
|
+ case 'pay_5':
|
|
|
+ $where['onlinePay!='] = 2;
|
|
|
+ $where['payWay'] = 5;
|
|
|
+ break;
|
|
|
+ case 'other':
|
|
|
+ $where['onlinePay!='] = 2;
|
|
|
+ $where['payWay'] = ['not in', [0, 1, 4, 5]];
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ if ($io === null || $io === '') {
|
|
|
+ return self::getList('*', $where, 'addTime DESC,id DESC');
|
|
|
+ }
|
|
|
+
|
|
|
+ $model = self::getModel();
|
|
|
+ $query = $model->conditionQuery($where)->select('*');
|
|
|
+ if ((int)$io === 1) {
|
|
|
+ $query->andWhere('IFNULL(amount, 0) + IFNULL(giveAmount, 0) > 0');
|
|
|
+ } else {
|
|
|
+ $query->andWhere(['isRefund' => 1]);
|
|
|
+ }
|
|
|
+
|
|
|
+ return self::getRechargePageList($query, 'addTime DESC,id DESC');
|
|
|
+ }
|
|
|
+
|
|
|
+ private static function getRechargePageList($query, $order = '')
|
|
|
+ {
|
|
|
+ $get = Yii::$app->request->get();
|
|
|
+ $page = isset($get['page']) ? $get['page'] : 1;
|
|
|
+ Yii::$app->params['page'] = $page;
|
|
|
+ $pageSize = isset($get['pageSize']) && !empty($get['pageSize']) ? $get['pageSize'] : Yii::$app->params['pageSize'];
|
|
|
+ $offset = ($page - 1) * $pageSize;
|
|
|
+
|
|
|
+ $clone = clone $query;
|
|
|
+ $count = $clone->count();
|
|
|
+ $totalPage = ceil($count / $pageSize);
|
|
|
+ $data['totalNum'] = $count;
|
|
|
+ $data['totalPage'] = $totalPage;
|
|
|
+ $data['moreData'] = $totalPage > $page ? 1 : 0;
|
|
|
+
|
|
|
+ if (!empty($order)) {
|
|
|
+ $query->orderBy($order);
|
|
|
+ }
|
|
|
+ $data['list'] = $query->offset($offset)->limit($pageSize)->asArray()->all();
|
|
|
+ return $data;
|
|
|
+ }
|
|
|
|
|
|
public static function addRecharge($data)
|
|
|
{
|
|
|
@@ -91,7 +171,7 @@ class RechargeClass extends BaseClass
|
|
|
}
|
|
|
|
|
|
//第三支付后流程 ssh 2021.4.27
|
|
|
- public static function thirdPay($payWay, $orderSn, $totalFee, $attach)
|
|
|
+ public static function thirdPay($payWay, $orderSn, $totalFee, $attach, $transactionId = '')
|
|
|
{
|
|
|
$recharge = RechargeClass::getByCondition(['orderSn' => $orderSn], true);
|
|
|
if (empty($recharge)) {
|
|
|
@@ -112,6 +192,8 @@ class RechargeClass extends BaseClass
|
|
|
'onlinePay' => 2,
|
|
|
'side' => 1,
|
|
|
];
|
|
|
+ $recharge->returnCode = $transactionId;
|
|
|
+ $recharge->save(false);
|
|
|
self::complete($recharge, $payWay, $params);
|
|
|
return $recharge;
|
|
|
}
|
|
|
@@ -382,6 +464,11 @@ class RechargeClass extends BaseClass
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ $recharge->settleId = $settleId;
|
|
|
+ $recharge->settleAmount = $settleAmount;
|
|
|
+ $recharge->settleNo = $settleNo;
|
|
|
+ $recharge->save();
|
|
|
+
|
|
|
$remark = $recharge->remark;
|
|
|
$change = [
|
|
|
'customId' => $customId,
|
|
|
@@ -521,6 +608,236 @@ class RechargeClass extends BaseClass
|
|
|
return $returnChange;
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 花店后台:对已付款客户充值单退款。线上原路退,线下扣减客户余额;xhRecharge.isRefund 标记退款状态。
|
|
|
+ */
|
|
|
+ public static function refundPaidRecharge($rechargeId, $shop, $staff)
|
|
|
+ {
|
|
|
+ $rechargeId = intval($rechargeId);
|
|
|
+ if ($rechargeId <= 0) {
|
|
|
+ util::fail('参数错误');
|
|
|
+ }
|
|
|
+ $recharge = self::getLockById($rechargeId);
|
|
|
+ if (empty($recharge)) {
|
|
|
+ util::fail('没有找到充值记录');
|
|
|
+ }
|
|
|
+ if (intval($recharge->mainId ?? 0) !== intval($shop->mainId ?? 0) || intval($recharge->shopId ?? 0) !== intval($shop->id ?? 0)) {
|
|
|
+ util::fail('没有权限操作该充值记录');
|
|
|
+ }
|
|
|
+ if (intval($recharge->payStatus ?? 0) !== 1 || intval($recharge->status ?? 0) !== 1) {
|
|
|
+ util::fail('仅已付款的充值可退款');
|
|
|
+ }
|
|
|
+ if (self::isRechargeRefunded($recharge)) {
|
|
|
+ util::fail('该充值已退款');
|
|
|
+ }
|
|
|
+
|
|
|
+ $amount = bcadd((string)($recharge->amount ?? '0'), '0', 2);
|
|
|
+ if (bccomp($amount, '0', 2) <= 0) {
|
|
|
+ util::fail('充值金额有误');
|
|
|
+ }
|
|
|
+
|
|
|
+ $customId = intval($recharge->customId ?? 0);
|
|
|
+ $hdId = intval($recharge->hdId ?? 0);
|
|
|
+ $custom = CustomClass::getLockById($customId);
|
|
|
+ $hd = HdClass::getLockById($hdId);
|
|
|
+ if (empty($custom) || empty($hd)) {
|
|
|
+ util::fail('没有找到客户余额账户');
|
|
|
+ }
|
|
|
+
|
|
|
+ $isOnline = intval($recharge->onlinePay ?? 0) === 2;
|
|
|
+ $payWay = intval($recharge->payWay ?? -1);
|
|
|
+ $wxPay = intval(dict::getDict('payWay', 'wxPay'));
|
|
|
+ $aliPay = intval(dict::getDict('payWay', 'alipay'));
|
|
|
+ $cashPay = intval(dict::getDict('payWay', 'cash'));
|
|
|
+ $onlineMain = null;
|
|
|
+
|
|
|
+ if ($isOnline) {
|
|
|
+ if ($payWay !== $wxPay && $payWay !== $aliPay) {
|
|
|
+ util::fail('暂不支持该支付方式原路退款');
|
|
|
+ }
|
|
|
+ $returnCode = trim((string)($recharge->returnCode ?? ''));
|
|
|
+ if ($returnCode === '') {
|
|
|
+ util::fail('缺少支付流水号,无法原路退款');
|
|
|
+ }
|
|
|
+ $onlineMain = MainClass::getLockById($shop->mainId ?? 0);
|
|
|
+ if (empty($onlineMain)) {
|
|
|
+ util::fail('没有找到资产信息');
|
|
|
+ }
|
|
|
+ if (bccomp((string)($onlineMain->balance ?? '0'), $amount, 2) < 0) {
|
|
|
+ util::fail('门店余额不足,无法退款');
|
|
|
+ }
|
|
|
+ self::refundOnlineByLakala($recharge, $shop, $amount, $returnCode);
|
|
|
+ }
|
|
|
+
|
|
|
+ $giveAmount = bcadd((string)($recharge->giveAmount ?? '0'), '0', 2);
|
|
|
+ if (bccomp($giveAmount, '0', 2) < 0) {
|
|
|
+ $giveAmount = '0.00';
|
|
|
+ }
|
|
|
+ $currentGive = bcadd((string)($hd->balanceGive ?? '0'), '0', 2);
|
|
|
+ $deductGive = '0.00';
|
|
|
+ if (bccomp($giveAmount, '0', 2) === 1 && bccomp($currentGive, '0', 2) === 1) {
|
|
|
+ $deductGive = bccomp($currentGive, $giveAmount, 2) >= 0 ? $giveAmount : $currentGive;
|
|
|
+ }
|
|
|
+ $deductPay = bcadd($amount, bcsub($giveAmount, $deductGive, 2), 2);
|
|
|
+ $totalDeduct = bcadd($deductPay, $deductGive, 2);
|
|
|
+
|
|
|
+ $custom->balancePay = bcsub((string)($custom->balancePay ?? '0'), $deductPay, 2);
|
|
|
+ $hd->balancePay = bcsub((string)($hd->balancePay ?? '0'), $deductPay, 2);
|
|
|
+ if (bccomp($deductGive, '0', 2) === 1) {
|
|
|
+ $custom->balanceGive = bcsub((string)($custom->balanceGive ?? '0'), $deductGive, 2);
|
|
|
+ $hd->balanceGive = bcsub((string)($hd->balanceGive ?? '0'), $deductGive, 2);
|
|
|
+ }
|
|
|
+ $custom->balance = bcsub((string)($custom->balance ?? '0'), $totalDeduct, 2);
|
|
|
+ $hd->balance = bcsub((string)($hd->balance ?? '0'), $totalDeduct, 2);
|
|
|
+ $custom->save(false);
|
|
|
+ $hd->save(false);
|
|
|
+
|
|
|
+ if (floatval($custom->balance) != floatval($hd->balance) || floatval($custom->balancePay) != floatval($hd->balancePay) || floatval($custom->balanceGive) != floatval($hd->balanceGive)) {
|
|
|
+ util::fail('账户余额有问题,请联系管理员');
|
|
|
+ }
|
|
|
+
|
|
|
+ $staffId = intval($staff->id ?? 0);
|
|
|
+ $staffName = (string)($staff->name ?? '');
|
|
|
+ $capitalType = dict::getDict('capitalType', 'customRechargeRefund', 'id');
|
|
|
+ $event = '充值退款(操作人:' . $staffName . ')单号:' . ($recharge->orderSn ?? '');
|
|
|
+ $changeBase = [
|
|
|
+ 'hdId' => $hdId,
|
|
|
+ 'hdName' => $hd->name ?? ($recharge->hdName ?? ''),
|
|
|
+ 'customId' => $customId,
|
|
|
+ 'customName' => $custom->name ?? ($recharge->customName ?? ''),
|
|
|
+ 'relateId' => $rechargeId,
|
|
|
+ 'onlinePay' => $recharge->onlinePay ?? 1,
|
|
|
+ 'capitalType' => $capitalType,
|
|
|
+ 'side' => 0,
|
|
|
+ 'payWay' => $payWay,
|
|
|
+ 'event' => $event,
|
|
|
+ 'staffId' => $staffId,
|
|
|
+ 'staffName' => $staffName,
|
|
|
+ 'shopId' => $recharge->shopId ?? 0,
|
|
|
+ 'mainId' => $recharge->mainId ?? 0,
|
|
|
+ 'remark' => '',
|
|
|
+ ];
|
|
|
+
|
|
|
+ BalanceChangeClass::add(array_merge($changeBase, [
|
|
|
+ 'amount' => $totalDeduct,
|
|
|
+ 'balance' => $hd->balance,
|
|
|
+ 'io' => 0,
|
|
|
+ ]), true);
|
|
|
+
|
|
|
+ BalancePayChangeClass::add(array_merge($changeBase, [
|
|
|
+ 'amount' => $deductPay,
|
|
|
+ 'balance' => $hd->balancePay,
|
|
|
+ 'io' => 0,
|
|
|
+ ]), true);
|
|
|
+
|
|
|
+ if (bccomp($deductGive, '0', 2) === 1) {
|
|
|
+ BalanceGiveChangeClass::add(array_merge($changeBase, [
|
|
|
+ 'amount' => $deductGive,
|
|
|
+ 'balance' => $hd->balanceGive,
|
|
|
+ 'io' => 0,
|
|
|
+ ]), true);
|
|
|
+ }
|
|
|
+
|
|
|
+ if ($isOnline) {
|
|
|
+ $main = $onlineMain ?: MainClass::getLockById($shop->mainId ?? 0);
|
|
|
+ if (empty($main)) {
|
|
|
+ util::fail('没有找到资产信息');
|
|
|
+ }
|
|
|
+ ShopClass::customRechargeRefundReduceBalance($main, $shop, $recharge, dict::getDict('capitalType', 'xhRecharge', 'id'), $staffName);
|
|
|
+ } elseif ($payWay === $cashPay) {
|
|
|
+ self::cashRechargeRefundReduceMoney($recharge, $shop, $staffName, $amount);
|
|
|
+ }
|
|
|
+
|
|
|
+ self::markRechargeRefunded($recharge);
|
|
|
+ $recharge->balance = $hd->balance;
|
|
|
+ $recharge->save(false);
|
|
|
+
|
|
|
+ return $recharge;
|
|
|
+ }
|
|
|
+
|
|
|
+ protected static function cashRechargeRefundReduceMoney($recharge, $shop, $staffName, $amount)
|
|
|
+ {
|
|
|
+ $main = MainClass::getLockById($shop->mainId ?? 0);
|
|
|
+ if (empty($main)) {
|
|
|
+ util::fail('没有找到现金账户');
|
|
|
+ }
|
|
|
+ if (bccomp((string)($main->money ?? '0'), $amount, 2) < 0) {
|
|
|
+ util::fail('现金不足' . floatval($amount) . '元');
|
|
|
+ }
|
|
|
+ $main->money = bcsub((string)$main->money, $amount, 2);
|
|
|
+ $main->save(false);
|
|
|
+ ShopMoneyClass::addData([
|
|
|
+ 'mainId' => $shop->mainId ?? 0,
|
|
|
+ 'sjId' => 0,
|
|
|
+ 'amount' => $amount,
|
|
|
+ 'balance' => $main->money,
|
|
|
+ 'io' => 0,
|
|
|
+ 'staffId' => $recharge->staffId ?? 0,
|
|
|
+ 'staffName' => $staffName,
|
|
|
+ 'customName' => $recharge->customName ?? '',
|
|
|
+ 'ptStyle' => dict::getDict('ptStyle', 'hd'),
|
|
|
+ 'capitalType' => dict::getDict('capitalType', 'xhRecharge', 'id'),
|
|
|
+ 'event' => ($recharge->customName ?? '客户') . '现金充值退款' . floatval($amount) . '元',
|
|
|
+ 'remark' => '操作人:' . $staffName,
|
|
|
+ ]);
|
|
|
+ }
|
|
|
+
|
|
|
+ protected static function refundOnlineByLakala($recharge, $shop, $amount, $returnCode)
|
|
|
+ {
|
|
|
+ $termNo = $shop->lklScanTermNo ?? '';
|
|
|
+ if (intval($recharge->payWay ?? 0) === intval(dict::getDict('payWay', 'alipay'))) {
|
|
|
+ $termNo = $shop->lklB2BTermNo ?? '';
|
|
|
+ }
|
|
|
+ if (empty($shop->lklSjNo) || empty($termNo)) {
|
|
|
+ util::fail('门店未配置拉卡拉商户信息');
|
|
|
+ }
|
|
|
+ $merchantPrivateKeyPath = Yii::getAlias('@vendor/lakala') . '/production/api_private_key.pem';
|
|
|
+ $lklCertificatePath = Yii::getAlias('@vendor/lakala') . '/production/lkl-apigw-v1.cer';
|
|
|
+ $laResource = new Lakala([
|
|
|
+ 'appid' => 'OP00002119',
|
|
|
+ 'serial_no' => '018b08cfddbd',
|
|
|
+ 'merchant_no' => $shop->lklSjNo,
|
|
|
+ 'term_no' => $termNo,
|
|
|
+ 'merchantPrivateKeyPath' => $merchantPrivateKeyPath,
|
|
|
+ 'lklCertificatePath' => $lklCertificatePath,
|
|
|
+ ]);
|
|
|
+ $response = $laResource->refund([
|
|
|
+ 'refundSn' => orderSn::getRechargeSn(),
|
|
|
+ 'orderSn' => $recharge->orderSn ?? '',
|
|
|
+ 'refundAmount' => bcmul($amount, 100),
|
|
|
+ 'refundReason' => '充值退款',
|
|
|
+ 'thirdNo' => $returnCode,
|
|
|
+ ]);
|
|
|
+ if (!isset($response['code']) || $response['code'] != 'BBS00000') {
|
|
|
+ util::fail('原路退款失败:' . ($response['msg'] ?? '退款失败'));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ protected static function isRechargeRefunded($recharge)
|
|
|
+ {
|
|
|
+ if (empty($recharge)) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ if (self::modelHasAttr($recharge, 'isRefund')) {
|
|
|
+ return intval($recharge->isRefund ?? 0) === 1;
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ protected static function markRechargeRefunded($recharge)
|
|
|
+ {
|
|
|
+ if (empty($recharge) || !self::modelHasAttr($recharge, 'isRefund')) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ $recharge->isRefund = 1;
|
|
|
+ $recharge->save(false, ['isRefund']);
|
|
|
+ }
|
|
|
+
|
|
|
+ protected static function modelHasAttr($model, $attr)
|
|
|
+ {
|
|
|
+ return is_object($model) && method_exists($model, 'hasAttribute') && $model->hasAttribute($attr);
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* 售后付款单是否已经充值过了 ssh 20250801
|
|
|
*/
|
|
|
@@ -533,4 +850,179 @@ class RechargeClass extends BaseClass
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-}
|
|
|
+ public static function getStatProfile($shopId, $params = [])
|
|
|
+ {
|
|
|
+ $searchTime = $params['searchTime'] ?? 'today';
|
|
|
+ $startTime = $params['startTime'] ?? '';
|
|
|
+ $endTime = $params['endTime'] ?? '';
|
|
|
+ $range = dateUtil::formatTime($searchTime, $startTime, $endTime);
|
|
|
+ $start = $range['startTime'];
|
|
|
+ $end = $range['endTime'];
|
|
|
+ $cacheKey = 'hd_recharge_stat:' . $shopId . '_' . md5($start . '_' . $end);
|
|
|
+ $cache = Yii::$app->redis->executeCommand('GET', [$cacheKey]);
|
|
|
+ if (!empty($cache)) {
|
|
|
+ $data = json_decode($cache, true);
|
|
|
+ if (is_array($data)) {
|
|
|
+ return $data;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ $summary = self::getRechargeStatSummary($shopId, $start, $end);
|
|
|
+ $channelList = self::getRechargeStatChannelList($shopId, $start, $end);
|
|
|
+ $customerList = self::getRechargeStatCustomerList($shopId, $start, $end);
|
|
|
+
|
|
|
+ $data = [
|
|
|
+ 'summary' => $summary,
|
|
|
+ 'channelList' => $channelList,
|
|
|
+ 'customerList' => $customerList,
|
|
|
+ 'startTime' => $start,
|
|
|
+ 'endTime' => $end,
|
|
|
+ ];
|
|
|
+ Yii::$app->redis->executeCommand('SETEX', [$cacheKey, self::STAT_CACHE_TTL, json_encode($data, JSON_UNESCAPED_UNICODE)]);
|
|
|
+ return $data;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static function getPaidQuery($shopId, $start, $end)
|
|
|
+ {
|
|
|
+ $model = self::getActiveRecord();
|
|
|
+ return $model::find()
|
|
|
+ ->where([
|
|
|
+ 'shopId' => $shopId,
|
|
|
+ 'payStatus' => 1,
|
|
|
+ 'status' => 1,
|
|
|
+ ])
|
|
|
+ ->andWhere(['between', 'addTime', $start, $end]);
|
|
|
+ }
|
|
|
+
|
|
|
+ private static function getRechargeStatSummary($shopId, $start, $end)
|
|
|
+ {
|
|
|
+ $row = self::getPaidQuery($shopId, $start, $end)
|
|
|
+ ->select([
|
|
|
+ 'rechargeCount' => new Expression('SUM(CASE WHEN IFNULL(amount, 0) + IFNULL(giveAmount, 0) > 0 THEN 1 ELSE 0 END)'),
|
|
|
+ 'reduceCount' => new Expression('SUM(CASE WHEN IFNULL(isRefund, 0) = 1 THEN 1 ELSE 0 END)'),
|
|
|
+ 'realAmount' => new Expression('IFNULL(SUM(amount), 0)'),
|
|
|
+ 'giveAmount' => new Expression('IFNULL(SUM(giveAmount), 0)'),
|
|
|
+ 'reduceAmount' => new Expression('IFNULL(SUM(CASE WHEN IFNULL(isRefund, 0) = 1 THEN amount ELSE 0 END), 0)'),
|
|
|
+ ])
|
|
|
+ ->asArray()
|
|
|
+ ->one();
|
|
|
+
|
|
|
+ $realAmount = $row['realAmount'] ?? 0;
|
|
|
+ $giveAmount = $row['giveAmount'] ?? 0;
|
|
|
+ $reduceAmount = $row['reduceAmount'] ?? 0;
|
|
|
+ return [
|
|
|
+ 'rechargeAmount' => self::moneyAdd($realAmount, $giveAmount),
|
|
|
+ 'rechargeCount' => intval($row['rechargeCount'] ?? 0),
|
|
|
+ 'reduceAmount' => self::moneyValue($reduceAmount),
|
|
|
+ 'reduceCount' => intval($row['reduceCount'] ?? 0),
|
|
|
+ 'realAmount' => self::moneyValue($realAmount),
|
|
|
+ ];
|
|
|
+ }
|
|
|
+
|
|
|
+ private static function getRechargeStatChannelList($shopId, $start, $end)
|
|
|
+ {
|
|
|
+ $rows = self::getPaidQuery($shopId, $start, $end)
|
|
|
+ ->select([
|
|
|
+ 'channelKey' => new Expression("IF(onlinePay = 2, CONCAT('online_', payWay), CONCAT('pay_', payWay))"),
|
|
|
+ 'rechargeCount' => new Expression('SUM(CASE WHEN IFNULL(amount, 0) + IFNULL(giveAmount, 0) > 0 THEN 1 ELSE 0 END)'),
|
|
|
+ 'reduceCount' => new Expression('SUM(CASE WHEN IFNULL(isRefund, 0) = 1 THEN 1 ELSE 0 END)'),
|
|
|
+ 'realAmount' => new Expression('IFNULL(SUM(amount), 0)'),
|
|
|
+ 'giveAmount' => new Expression('IFNULL(SUM(giveAmount), 0)'),
|
|
|
+ 'reduceAmount' => new Expression('IFNULL(SUM(CASE WHEN IFNULL(isRefund, 0) = 1 THEN amount ELSE 0 END), 0)'),
|
|
|
+ ])
|
|
|
+ ->groupBy(new Expression("IF(onlinePay = 2, CONCAT('online_', payWay), CONCAT('pay_', payWay))"))
|
|
|
+ ->asArray()
|
|
|
+ ->all();
|
|
|
+
|
|
|
+ $payWayName = dict::getDict('payWayName');
|
|
|
+ $defaultList = [
|
|
|
+ 'online_0' => '线上微信',
|
|
|
+ 'online_1' => '线上支付宝',
|
|
|
+ 'pay_0' => '线下微信',
|
|
|
+ 'pay_1' => '线下支付宝',
|
|
|
+ 'pay_4' => '现金',
|
|
|
+ 'pay_5' => '银行卡',
|
|
|
+ ];
|
|
|
+ $map = [];
|
|
|
+ foreach ($rows as $row) {
|
|
|
+ $key = $row['channelKey'] ?? '';
|
|
|
+ $payWay = intval(str_replace('pay_', '', $key));
|
|
|
+ $map[$key] = self::buildStatRow(
|
|
|
+ $defaultList[$key] ?? ($payWayName[$payWay] ?? '其它'),
|
|
|
+ $row
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ $list = [];
|
|
|
+ foreach ($defaultList as $key => $name) {
|
|
|
+ $list[] = $map[$key] ?? self::emptyStatRow($name);
|
|
|
+ unset($map[$key]);
|
|
|
+ }
|
|
|
+ foreach ($map as $item) {
|
|
|
+ $list[] = $item;
|
|
|
+ }
|
|
|
+ return $list;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static function getRechargeStatCustomerList($shopId, $start, $end)
|
|
|
+ {
|
|
|
+ $rows = self::getPaidQuery($shopId, $start, $end)
|
|
|
+ ->select([
|
|
|
+ 'customId',
|
|
|
+ 'customName',
|
|
|
+ 'rechargeCount' => new Expression('SUM(CASE WHEN IFNULL(amount, 0) + IFNULL(giveAmount, 0) > 0 THEN 1 ELSE 0 END)'),
|
|
|
+ 'reduceCount' => new Expression('SUM(CASE WHEN IFNULL(isRefund, 0) = 1 THEN 1 ELSE 0 END)'),
|
|
|
+ 'realAmount' => new Expression('IFNULL(SUM(amount), 0)'),
|
|
|
+ 'giveAmount' => new Expression('IFNULL(SUM(giveAmount), 0)'),
|
|
|
+ 'reduceAmount' => new Expression('IFNULL(SUM(CASE WHEN IFNULL(isRefund, 0) = 1 THEN amount ELSE 0 END), 0)'),
|
|
|
+ ])
|
|
|
+ ->groupBy(['customId', 'customName'])
|
|
|
+ ->orderBy(new Expression('IFNULL(SUM(amount), 0) + IFNULL(SUM(giveAmount), 0) DESC'))
|
|
|
+ ->limit(100)
|
|
|
+ ->asArray()
|
|
|
+ ->all();
|
|
|
+
|
|
|
+ $list = [];
|
|
|
+ foreach ($rows as $row) {
|
|
|
+ $list[] = self::buildStatRow($row['customName'] ?: '未命名', $row);
|
|
|
+ }
|
|
|
+ return $list;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static function buildStatRow($name, $row)
|
|
|
+ {
|
|
|
+ $realAmount = $row['realAmount'] ?? 0;
|
|
|
+ $giveAmount = $row['giveAmount'] ?? 0;
|
|
|
+ return [
|
|
|
+ 'customId' => $row['customId'] ?? 0,
|
|
|
+ 'name' => $name,
|
|
|
+ 'rechargeAmount' => self::moneyAdd($realAmount, $giveAmount),
|
|
|
+ 'rechargeCount' => intval($row['rechargeCount'] ?? 0),
|
|
|
+ 'reduceAmount' => self::moneyValue($row['reduceAmount'] ?? 0),
|
|
|
+ 'reduceCount' => intval($row['reduceCount'] ?? 0),
|
|
|
+ 'realAmount' => self::moneyValue($realAmount),
|
|
|
+ ];
|
|
|
+ }
|
|
|
+
|
|
|
+ private static function emptyStatRow($name)
|
|
|
+ {
|
|
|
+ return [
|
|
|
+ 'name' => $name,
|
|
|
+ 'rechargeAmount' => '0.00',
|
|
|
+ 'rechargeCount' => 0,
|
|
|
+ 'reduceAmount' => '0.00',
|
|
|
+ 'reduceCount' => 0,
|
|
|
+ 'realAmount' => '0.00',
|
|
|
+ ];
|
|
|
+ }
|
|
|
+
|
|
|
+ private static function moneyAdd($left, $right)
|
|
|
+ {
|
|
|
+ return self::moneyValue(bcadd((string)$left, (string)$right, 2));
|
|
|
+ }
|
|
|
+
|
|
|
+ private static function moneyValue($amount)
|
|
|
+ {
|
|
|
+ return number_format((float)$amount, 2, '.', '');
|
|
|
+ }
|
|
|
+}
|