| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028 |
- <?php
- namespace bizHd\recharge\classes;
- use biz\shop\classes\ShopClass;
- use bizGhs\shop\classes\ShopMoneyClass;
- use bizHd\balance\classes\BalanceChangeClass;
- use bizHd\balance\classes\BalanceGiveChangeClass;
- use bizHd\balance\classes\BalancePayChangeClass;
- use bizHd\custom\classes\CustomClass;
- use bizHd\custom\classes\HdClass;
- use bizHd\hb\classes\HbClass;
- use bizHd\hb\classes\HbManageClass;
- use bizHd\order\classes\OrderClass;
- use bizHd\order\classes\SettleClass;
- 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)
- {
- //创建充值单时,要把过去的充值单和结账单取消掉
- $customId = $data['customId'] ?? 0;
- if (empty($customId)) {
- util::fail('没有客户信息');
- }
- $shopId = $data['shopId'] ?? 0;
- $hasList = self::getAllByCondition(['customId' => $customId, 'status' => 0], null, '*', null, true);
- if (!empty($hasList)) {
- $shop = \bizHd\merchant\classes\ShopClass::getById($shopId, true);
- if (empty($shop)) {
- util::fail('没有找到门店');
- }
- foreach ($hasList as $k => $recharge) {
- $payRequest = $recharge->payRequest ?? 0;
- if ($payRequest == 1 || $payRequest == 2) {
- $closeOrderSn = $recharge->orderSn;
- $merchantPrivateKeyPath = Yii::getAlias("@vendor/lakala") . '/production/api_private_key.pem';
- $lklCertificatePath = Yii::getAlias("@vendor/lakala") . '/production/lkl-apigw-v1.cer';
- $params = [
- 'appid' => 'OP00002119',
- 'serial_no' => '018b08cfddbd',
- 'merchant_no' => $shop->lklSjNo,
- 'term_no' => $shop->lklScanTermNo,
- 'merchantPrivateKeyPath' => $merchantPrivateKeyPath,
- 'lklCertificatePath' => $lklCertificatePath,
- ];
- $laResource = new Lakala($params);
- $closeParams = ['orderSn' => $closeOrderSn];
- if ($payRequest == 1) {
- //聚合支付
- $response = $laResource->close($closeParams);
- if (!isset($response['code']) || $response['code'] != 'BBS00000') {
- $msg = $response['msg'] ?? '';
- noticeUtil::push('充值换单,聚合支付,没有成功,单号:' . $closeOrderSn . ',关单没有成功,编号966558,' . $msg, '15280215347');
- //util::fail('老订单取消失败,请联系管理员');
- }
- } else {
- //收银台支付
- $response = $laResource->cashClose($closeParams);
- if (!isset($response['code']) || $response['code'] != '000000') {
- $msg = $response['msg'] ?? '';
- noticeUtil::push('充值换单,收银台的单号:' . $closeOrderSn . ',关单没有成功,编号66996,' . $msg, '15280215347');
- //util::fail('旧订单取消失败,请联系管理员');
- }
- }
- }
- $recharge->status = 2;
- $recharge->save();
- $settleId = $recharge->settleId ?? 0;
- $settle = SettleClass::getById($settleId, true);
- if (!empty($settle)) {
- $settle->status = 3;
- $settle->save();
- }
- }
- }
- return self::add($data, true);
- }
- //第三支付后流程 ssh 2021.4.27
- public static function thirdPay($payWay, $orderSn, $totalFee, $attach, $transactionId = '')
- {
- $recharge = RechargeClass::getByCondition(['orderSn' => $orderSn], true);
- if (empty($recharge)) {
- noticeUtil::push('充值付款成功,收到回调,但没有找到充值记录,orderSn:' . $orderSn, '15280215347');
- return false;
- }
- if ($totalFee != $recharge->amount) {
- noticeUtil::push("充值付款成功,收到回调,但金额不一致 {$totalFee} {$recharge->amount},orderSn:" . $orderSn, '15280215347');
- return false;
- }
- if ($recharge->payStatus == 1) {
- noticeUtil::push("充值付款成功,收到回调,但订单是已经支付过了,orderSn:" . $orderSn, '15280215347');
- return false;
- }
- $id = $recharge->id;
- $recharge = RechargeClass::getLockById($id);
- $params = [
- 'onlinePay' => 2,
- 'side' => 1,
- ];
- $recharge->returnCode = $transactionId;
- $recharge->save(false);
- self::complete($recharge, $payWay, $params);
- return $recharge;
- }
- //处理充值流程 ssh 20250321
- public static function complete($recharge, $payWay, $params)
- {
- $onlinePay = $params['onlinePay'];
- //0 花店端操作,1 客户端操作
- $side = $params['side'] ?? 0;
- $recharge->onlinePay = $onlinePay;
- $recharge->payWay = $payWay;
- $recharge->payStatus = 1;
- $recharge->status = 1;
- $recharge->save();
- $shopId = $recharge->shopId;
- $mainId = $recharge->mainId;
- $hdId = $recharge->hdId;
- $hdInfo = HdClass::getById($hdId, true);
- $hdName = $hdInfo->name ?? "";
- $amount = $recharge->amount;
- $staffId = $recharge->staffId;
- $payWay = $recharge->payWay;
- $staffName = $recharge->staffName;
- $customId = $recharge->customId;
- $customName = $recharge->customName;
- $capitalType = dict::getDict('capitalType', 'xhRecharge', 'id');
- $relateId = $recharge->id;
- $shOrderId = $recharge->shOrderId ?? 0;
- $shOrderSn = $recharge->shOrderSn ?? '';
- $custom = CustomClass::getLockById($customId);
- if (empty($custom)) {
- $msg = '充值回调失败,没有找到客户';
- util::fail($msg);
- }
- $hd = HdClass::getLockById($hdId);
- if (empty($hd)) {
- $msg = '充值回调失败,没有找到花店';
- util::fail($msg);
- }
- $shop = ShopClass::getById($shopId, true);
- $rechargeWeal = $shop->rechargeWeal ?? 0; //充值赠送: 0未设置 2充值送红包--红包非余额支付可用,3充值送红包--红包非余额支付不可用
- $balanceGive = 0;
- //如果客户有欠款、结账充值、售后充值、售后付款充值,不参与优惠
- if ($custom->balance >= 0 && $recharge->settleId == 0 && $recharge->shOrderId == 0 && $recharge->refundOrderId == 0) {
- if ($rechargeWeal == 1) {
- $weal = RechargeSqClass::getAllByCondition(['shopId' => $shopId], 'recharge ASC', '*');
- if (!empty($weal)) {
- //优惠方式2:充多少送多少
- foreach ($weal as $k => $v) {
- $thisRecharge = $v['recharge'] ?? 0;
- $thisGive = $v['give'] ?? 0;
- if ($amount >= $thisRecharge) {
- $recharge->giveAmount = $thisGive;
- $recharge->save();
- //增加赠送的金额
- $balanceGive = $thisGive;
- }
- }
- }
- } elseif ($rechargeWeal == 2 || $rechargeWeal == 3) {
- //充值送红包
- // 1.根据充值金额,查询符合条件的红包规则
- $maxHbRule = RechargeShbClass::getByCondition(['shopId' => $shopId, 'amount<=' => $amount], false, 'allHbAmount DESC');
-
- if (!empty($maxHbRule)) {
- $currentTime = time();
-
- $rulesJson = $maxHbRule['rules'] ?? '';
- $rulesArr = json_decode($rulesJson, true);
-
- if (is_array($rulesArr) && !empty($rulesArr)) {
- foreach ($rulesArr as $rule) {
- $hbAmount = $rule['hbAmount'];
- $hbNum = $rule['hbNum'];
- $miniCost = $rule['miniCost'];
- $duration = $rule['duration'];
- $effectiveType = $rule['effectiveType'] ?? 2;
- $effectiveDate = $rule['effectiveDate'] ?? '';
- $effectiveDays = $rule['effectiveDays'] ?? 0;
- if ($effectiveType == 1 && !empty($effectiveDate) && $effectiveDate != '0000-00-00') {
- $beginTime = strtotime($effectiveDate);
- if (!$beginTime) {
- $beginTime = $currentTime;
- }
- } else {
- $beginTime = $currentTime + 86400 * $effectiveDays;
- }
- //给用户生成红包
- $data = [
- 'mainId' => $mainId,
- 'shopId' => $shopId,
- 'userId' => $recharge->userId,
- 'customId' => $customId,
- 'amount' => $hbAmount,
- 'minConsume' => $miniCost,
- 'beginTime' => $beginTime,
- 'endTime' => $duration == 0 ? 4102416000 : ($beginTime + 86400 * $duration),
- 'willTime' => $duration == 0 ? 4102416000 : ($beginTime + 86400 * $duration),
- 'duration' => $duration,
- 'getType' => 2, //取得方式 0新人领取 1门店发放 2充值赠送
- 'remark' => '充值赠送红包',
- ];
-
- $manageData = [
- 'getType' => 2,
- 'getTargetId' => 0,
- 'createStaffId' => 0,
- 'createStaffName' => '',
- 'remark' => $data['remark'] ?? '',
- ];
- for ($i = 0; $i < $hbNum; $i++) {
- $hb = HbClass::add($data);
-
- $manageData['hbId'] = $hb['id'];
- HbManageClass::add($manageData);
- }
- }
- }
- }
- } else {
- //其他
- }
- }
- //是否开启充值满多少成为 VIP
- $shopExt = ShopExtClass::getByCondition(['shopId' => $shopId], false, 'reachVip');
- if (!empty($shopExt) && $shopExt['reachVip'] > 0.00 && bccomp($amount, $shopExt['reachVip'], 2) >= 0) {
- $custom->vip = 1;
- }
- $balancePay = $amount;
- if ($onlinePay == 2) {
- $event = $payWay == 0 ? '线上微信 充值' : '线上支付宝 充值';
- } else {
- $payWayName = dict::getDict('payWayName');
- $channel = $payWayName[$payWay] ?? '微信';
- $event = "线下{$channel} 充值";
- }
- $event .= floatval($balancePay);
- //赠送的余额
- if ($balanceGive > 0) {
- $event .= "(送" . floatval($balanceGive) . ")";
- $custom->balanceGive = bcadd($custom->balanceGive, $balanceGive, 2);
- $hd->balanceGive = bcadd($hd->balanceGive, $balanceGive, 2);
- }
- //充值的余额
- $beforeBalancePay = $custom->balancePay;
- $custom->balancePay = bcadd($custom->balancePay, $balancePay, 2);
- $hd->balancePay = bcadd($hd->balancePay, $balancePay, 2);
- //总余额
- $totalBalance = bcadd($balancePay, $balanceGive, 2);
- $custom->balance = bcadd($custom->balance, $totalBalance, 2);
- $hd->balance = bcadd($hd->balance, $totalBalance, 2);
- $changeAmount = bccomp($beforeBalancePay, 0, 2) === -1 ? $custom->balancePay : $balancePay; // 根据余额欠款,计算变化金额,用于计算积分与成长值
- $addIntegralAndGrowth = bccomp($changeAmount, 0, 2) === 1; // 如果变化金额大于0,则计算积分与成长值
- if ($addIntegralAndGrowth) {
- //积分与成长值
- $custom->integral = bcadd($custom->integral, $changeAmount, 2);
- $custom->growth = bcadd($custom->growth, $changeAmount, 2);
- // 由于没有更新 buyAmount,所以得额外添加更新等级
- $memberData = CustomClass::getCustomExpenseLevel($custom->growth, $mainId); // 设置等级多处需要同步修改的,请搜索:getCustomExpenseLevel
- CustomClass::updateById($customId, [
- 'member' => (int) ($memberData['level'] ?? 0),
- 'memberName' => (string) ($memberData['name'] ?? ''),
- 'discount' => bcdiv(floatval($memberData['discount']), 10, 2)
- ]);
- }
- $custom->save();
- $hd->save();
- if ($hd->balance != $custom->balance) {
- $msg = '充值金额不一致。编号:' . floatval($hd->balance) . ' / ' . floatval($custom->balance);
- Yii::info($msg);
- util::fail($msg);
- }
- if ($hd->balancePay != $custom->balancePay) {
- $msg = '充值金额有异常。编号:' . floatval($hd->balancePay) . ' / ' . floatval($custom->balancePay);
- Yii::info($msg);
- util::fail($msg);
- }
- if ($hd->balanceGive != $custom->balanceGive) {
- $msg = '充值金额异常。编号:' . floatval($hd->balanceGive) . ' / ' . floatval($custom->balanceGive);
- Yii::info($msg);
- util::fail($msg);
- }
- $addBalance = bcadd($hd->balanceGive, $hd->balancePay, 2);
- if (floatval($hd->balance) != floatval($addBalance)) {
- util::fail('充值金额有问题哦,编号:' . $customId);
- }
- $settleId = $recharge->settleId;
- $settleAmount = 0;
- $settleNo = '';
- $realClearAmount = 0;
- if (!empty($settleId)) {
- //如果有结账单,按结账单销账
- $set = SettleClass::getById($settleId, true);
- $res = SettleClass::clearSettle($set, $recharge);
- $realClearAmount = $res['totalClearAmount'] ?? 0;
- $settleAmount = $set->actPrice ?? 0;
- $settleNo = $set->orderSn ?? '';
- } else {
- //没有结账单,按顺序去销订单欠款
- $orderList = OrderClass::getAllByCondition(['customId' => $customId, 'debt' => 1], 'id asc', '*', null, true);
- if (!empty($orderList)) {
- $lastRemainDebtAmount = 0;
- $needClearIdMap = [];
- $hasOver = false;
- foreach ($orderList as $order) {
- $orderId = $order->id ?? 0;
- $orderSn = $order->orderSn ?? '';
- //销订单全部的欠款!!!
- $remainDebtPrice = $order->remainDebtPrice ?? 0;
- $currentTotalDebtAmount = bcadd($lastRemainDebtAmount, $remainDebtPrice, 2);
- if ($currentTotalDebtAmount > $totalBalance) {
- if (!$hasOver) {
- $lastClearOrderAmount = bcsub($totalBalance, $lastRemainDebtAmount, 2);
- if ($lastClearOrderAmount > 0) {
- //销订单部分的欠款!!!
- $lastClearOrderId = $orderId;
- $needClearIdMap[] = ['orderId' => $lastClearOrderId, 'clearAmount' => $lastClearOrderAmount, 'orderSn' => $orderSn];
- }
- }
- $hasOver = true;
- continue;
- }
- $lastRemainDebtAmount = bcadd($lastRemainDebtAmount, $remainDebtPrice, 2);
- $needClearIdMap[] = ['orderId' => $orderId, 'clearAmount' => $remainDebtPrice, 'orderSn' => $orderSn];
- }
- if (!empty($needClearIdMap)) {
- //创建结账单,并且销结账单
- $staffId = $recharge->staffId ?? 0;
- $staffName = $recharge->staffName ?? '';
- $settleParams = ['staffId' => $staffId, 'staffName' => $staffName];
- $set = SettleClass::addSettle($needClearIdMap, $shop, $custom, $hd, $settleParams);
- $settleId = $set->id;
- $settleNo = $set->orderSn ?? '';
- $settleAmount = $set->actPrice ?? 0;
- $res = SettleClass::clearSettle($set);
- $realClearAmount = $res['totalClearAmount'] ?? 0;
- }
- }
- }
- if ($settleId > 0) {
- if (floatval($totalBalance) != floatval($realClearAmount) && $hd->balance < 0) {
- $rechargeId = $recharge->id;
- noticeUtil::push("注意,充值单,结账金额不一致:getBalance:{$totalBalance} totalAmount:{$realClearAmount},recharge:{$rechargeId}", '15280215347');
- util::fail('充值和结账金额异常哈');
- }
- if (floatval($totalBalance) != floatval($settleAmount) && $hd->balance < 0) {
- $rechargeId = $recharge->id;
- noticeUtil::push("注意,充值单,结账单不一致:getBalance:{$totalBalance} settleAmount:{$settleAmount},settleId:{$settleId} recharge:{$rechargeId}", '15280215347');
- util::fail('充值和结账金额异常呢');
- }
- if (floatval($realClearAmount) != floatval($settleAmount)) {
- $rechargeId = $recharge->id;
- noticeUtil::push("注意,结账金额有问题,编号 settleId:{$settleId} recharge:{$rechargeId}", '15280215347');
- util::fail('充值结账金额异常呢');
- }
- }
- $recharge->settleId = $settleId;
- $recharge->settleAmount = $settleAmount;
- $recharge->settleNo = $settleNo;
- $recharge->save();
- $remark = $recharge->remark;
- $change = [
- 'customId' => $customId,
- 'customName' => $customName,
- 'relateId' => $relateId,
- 'onlinePay' => $onlinePay,
- 'capitalType' => $capitalType,
- 'giveAmount' => $balanceGive,
- 'amount' => $totalBalance,
- 'balance' => $hd->balance,
- 'io' => 1,
- 'side' => $side,
- 'payWay' => $payWay,
- 'event' => $event,
- 'staffId' => $staffId,
- 'staffName' => $staffName,
- 'shopId' => $shopId,
- 'mainId' => $mainId,
- 'settleId' => $settleId,
- 'settleNo' => $settleNo,
- 'settleAmount' => $settleAmount,
- 'remark' => $remark,
- 'shOrderId' => $shOrderId,
- 'shOrderSn' => $shOrderSn,
- 'hdId' => $hdId,
- 'hdName' => $hdName,
- ];
- $returnChange = BalanceChangeClass::add($change, true);
- $payChange = [
- 'customId' => $customId,
- 'customName' => $customName,
- 'relateId' => $relateId,
- 'onlinePay' => $onlinePay,
- 'capitalType' => $capitalType,
- 'amount' => $balancePay,
- 'balance' => $hd->balancePay,
- 'io' => 1,
- 'side' => $side,
- 'payWay' => $payWay,
- 'event' => $event,
- 'staffId' => $staffId,
- 'staffName' => $staffName,
- 'shopId' => $shopId,
- 'mainId' => $mainId,
- 'settleId' => $settleId,
- 'settleNo' => $settleNo,
- 'settleAmount' => $settleAmount,
- 'remark' => $remark,
- 'shOrderId' => $shOrderId,
- 'shOrderSn' => $shOrderSn,
- 'hdId' => $hdId,
- 'hdName' => $hdName,
- ];
- BalancePayChangeClass::add($payChange, true);
- if ($balanceGive > 0) {
- $givChange = [
- 'customId' => $customId,
- 'customName' => $customName,
- 'relateId' => $relateId,
- 'onlinePay' => $onlinePay,
- 'capitalType' => $capitalType,
- 'amount' => $balanceGive,
- 'balance' => $hd->balanceGive,
- 'io' => 1,
- 'side' => $side,
- 'payWay' => $payWay,
- 'event' => $event,
- 'staffId' => $staffId,
- 'staffName' => $staffName,
- 'shopId' => $shopId,
- 'mainId' => $mainId,
- 'remark' => $remark,
- 'hdId' => $hdId,
- 'hdName' => $hdName,
- ];
- BalanceGiveChangeClass::add($givChange, true);
- }
- if ($recharge->onlinePay == 2) {
- //如果线上充值,门店余额增加
- $shop = ShopClass::getLockById($shopId);
- $main = MainClass::getLockById($mainId);
- ShopClass::skRechargeAddBalance($main, $shop, $recharge);
- } else {
- if ($recharge->payWay == 4) {
- //现在现金充值要增加现金
- $main = MainClass::getLockById($mainId);
- $cashData = [];
- $cashData['mainId'] = $mainId;
- $cashData['sjId'] = 0;
- $cashData['amount'] = $amount;
- $cashData['staffId'] = $staffId;
- $cashData['staffName'] = $staffName;
- $cashData['customName'] = $customName;
- $cashData['ptStyle'] = dict::getDict('ptStyle', 'hd');
- ShopMoneyClass::skRecharge($cashData, $main);
- }
- }
- if ($addIntegralAndGrowth) {
- $createTime = date('Y-m-d H:i:s');
- //成长值变动记录
- $growthData = [
- 'shopId' => $shopId,
- 'userId' => $custom->userId,
- 'userName' => $custom->name,
- 'event' => $event,
- 'relateId' => $relateId,
- 'relateType' => 0,
- 'num' => $changeAmount,
- 'growth' => $custom->growth,
- 'staffId' => $staffId, //操作人(员工id)
- 'staffName' => $staffName, //员工名称
- 'createTime' => $createTime,
- ];
- UserGrowthClass::add($growthData);
- //积分变动记录
- $integralData = [
- 'shopId' => $shopId,
- 'userId' => $custom->userId,
- 'userName' => $custom->name,
- 'event' => $event,
- 'relateId' => $relateId,
- 'relateType' => 0,
- 'num' => $changeAmount,
- 'integral' => $custom->integral,
- 'staffId' => $staffId, //操作人(员工id)
- 'staffName' => $staffName, //员工名称
- 'createTime' => $createTime,
- ];
- UserIntegralClass::add($integralData);
- }
- 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
- */
- public static function checkShOrderRecharge($order)
- {
- $orderId = $order->id;
- $has = self::getByCondition(['shOrderId' => $orderId, 'payStatus' => 1]);
- if (!empty($has)) {
- util::fail('已经充值过了,无需再次操作');
- }
- }
- 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, '.', '');
- }
- }
|