QueryRefund.php 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | likeadmin快速开发前后端分离管理后台(PHP版)
  4. // +----------------------------------------------------------------------
  5. // | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
  6. // | 开源版本可自由商用,可去除界面版权logo
  7. // | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
  8. // | github下载:https://github.com/likeshop-github/likeadmin
  9. // | 访问官网:https://www.likeadmin.cn
  10. // | likeadmin团队 版权所有 拥有最终解释权
  11. // +----------------------------------------------------------------------
  12. // | author: likeadminTeam
  13. // +----------------------------------------------------------------------
  14. namespace app\common\command;
  15. use app\common\enum\PayEnum;
  16. use app\common\enum\RefundEnum;
  17. use app\common\enum\worker\WorkerAccountLogEnum;
  18. use app\common\logic\RetentionMoneyLogic;
  19. use app\common\logic\WorkerAccountLogLogic;
  20. use app\common\model\master_worker\MasterWorkerAccountLog;
  21. use app\common\model\master_worker\MasterWorkerRetentionMoneyLog;
  22. use app\common\model\property\PropertyCommission;
  23. use app\common\model\property\PropertyHead;
  24. use app\common\model\property\PropertyOrder;
  25. use app\common\model\property\PropertySurplusLog;
  26. use app\common\model\recharge\RechargeOrder;
  27. use app\common\model\refund\RefundLog;
  28. use app\common\model\refund\RefundRecord;
  29. use app\common\model\works\ServiceWork;
  30. use app\common\service\pay\WeChatPayService;
  31. use think\console\Command;
  32. use think\console\Input;
  33. use think\console\Output;
  34. use think\facade\Db;
  35. use think\facade\Log;
  36. class QueryRefund extends Command
  37. {
  38. protected function configure()
  39. {
  40. $this->setName('query_refund')
  41. ->setDescription('订单退款状态处理');
  42. }
  43. protected function execute(Input $input, Output $output)
  44. {
  45. while (true) {
  46. try {
  47. // 查找退款中的退款记录(微信,支付宝支付)
  48. $refundRecords = (new RefundLog())->alias('l')
  49. ->join('refund_record r', 'r.id = l.record_id')
  50. ->field([
  51. 'l.id' => 'log_id', 'l.sn' => 'log_sn',
  52. 'r.id' => 'record_id', 'r.order_id', 'r.sn' => 'record_sn', 'r.order_type'
  53. ])
  54. ->where(['l.refund_status' => RefundEnum::REFUND_ING])
  55. ->select()->toArray();
  56. if (empty($refundRecords)) {
  57. sleep(10);
  58. continue;
  59. }
  60. // 分别处理各个类型订单
  61. $rechargeRecords = array_filter($refundRecords, function ($item) {
  62. return $item['order_type'] == RefundEnum::ORDER_TYPE_ORDER;
  63. });
  64. if (!empty($rechargeRecords)) {
  65. $this->handleRechargeOrder($rechargeRecords);
  66. }
  67. } catch (\Exception $e) {
  68. Log::write('订单退款状态查询失败,失败原因:' . $e->getMessage());
  69. sleep(5);
  70. continue;
  71. }
  72. sleep(1);
  73. }
  74. }
  75. /**
  76. * @notes 处理充值订单
  77. * @param $refundRecords
  78. * @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException
  79. * @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException
  80. * @author 段誉
  81. * @date 2023/3/1 15:55
  82. */
  83. public function handleRechargeOrder($refundRecords)
  84. {
  85. $orderIds = array_unique(array_column($refundRecords, 'order_id'));
  86. $Orders = RechargeOrder::whereIn('id', $orderIds)->column('*', 'id');
  87. foreach ($refundRecords as $record) {
  88. if (!isset($Orders[$record['order_id']])) {
  89. continue;
  90. }
  91. $order = $Orders[$record['order_id']];
  92. if (!in_array($order['pay_way'], [PayEnum::WECHAT_PAY, PayEnum::ALI_PAY])) {
  93. continue;
  94. }
  95. $this->checkReFundStatus([
  96. 'record_id' => $record['record_id'],
  97. 'log_id' => $record['log_id'],
  98. 'log_sn' => $record['log_sn'],
  99. 'pay_way' => $order['pay_way'],
  100. 'order_terminal' => $order['order_terminal'],
  101. 'order_id'=>$order['id']
  102. ]);
  103. }
  104. }
  105. /**
  106. * @notes 校验退款状态
  107. * @param $refundData
  108. * @return bool
  109. * @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException
  110. * @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException
  111. * @author 段誉
  112. * @date 2023/3/1 15:54
  113. */
  114. public function checkReFundStatus($refundData)
  115. {
  116. $result = null;
  117. switch ($refundData['pay_way']) {
  118. case PayEnum::WECHAT_PAY:
  119. $result = self::checkWechatRefund($refundData['order_terminal'], $refundData['log_sn']);
  120. break;
  121. }
  122. if (is_null($result)) {
  123. return false;
  124. }
  125. if (true === $result) {
  126. $this->updateRefundSuccess($refundData['log_id'], $refundData['record_id'],$refundData['order_id']);
  127. } else {
  128. $this->updateRefundMsg($refundData['log_id'], $result);
  129. }
  130. return true;
  131. }
  132. /**
  133. * @notes 查询微信支付退款状态
  134. * @param $orderTerminal
  135. * @param $refundLogSn
  136. * @return bool|string|null
  137. * @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException
  138. * @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException
  139. * @author 段誉
  140. * @date 2023/3/1 15:47
  141. */
  142. public function checkWechatRefund($orderTerminal, $refundLogSn)
  143. {
  144. // 根据商户退款单号查询退款
  145. $result = (new WeChatPayService($orderTerminal))->queryRefund($refundLogSn);
  146. if (!empty($result['status']) && $result['status'] == 'SUCCESS') {
  147. return true;
  148. }
  149. if (!empty($result['code']) || !empty($result['message'])) {
  150. return '微信:' . $result['code'] . '-' . $result['message'];
  151. }
  152. return null;
  153. }
  154. /**
  155. * @notes 更新记录为成功
  156. * @param $logId
  157. * @param $recordId
  158. * @author 段誉
  159. * @date 2023/3/1 15:38
  160. */
  161. public function updateRefundSuccess($logId, $recordId,$order_id)
  162. {
  163. // 更新日志
  164. RefundLog::update([
  165. 'id' => $logId,
  166. 'refund_status' => RefundEnum::REFUND_SUCCESS,
  167. ]);
  168. // 更新记录
  169. RefundRecord::update([
  170. 'id' => $recordId,
  171. 'refund_status' => RefundEnum::REFUND_SUCCESS,
  172. ]);
  173. Log::channel('re_fund')->info('1');
  174. //更新工单退款状态以及处理工程师金额和物业金额
  175. $order = RechargeOrder::where('id',$order_id)->findOrEmpty();
  176. $work = ServiceWork::where('id',$order->work_id)->findOrEmpty();
  177. Log::channel('re_fund')->info(json_encode($work,JSON_UNESCAPED_UNICODE));
  178. if(!$work->isEmpty()){
  179. if(($work->work_pay_status == '1' || $work->work_pay_status == '2') and $work->service_status != '5' and $work->work_status != '9'){
  180. Log::channel('re_fund')->info(2);
  181. //工程师余额变动
  182. $change_amount = MasterWorkerAccountLog::where(['work_sn'=>$work->work_sn,'action'=>1])->value('change_amount');
  183. WorkerAccountLogLogic::addAccountLog($work,$change_amount,WorkerAccountLogEnum::UM_DEC_ADMIN,WorkerAccountLogEnum::DEC);
  184. //工程师质保金变动 - 退质保金
  185. $retentionAmount = MasterWorkerRetentionMoneyLog::where(['action'=>WorkerAccountLogEnum::INC,'source'=>2,'worker_id'=>$work->master_worker_id,'work_id'=>$work->id])->value('amount');
  186. if($retentionAmount){
  187. $remark = '工单号:'.$work->work_sn.',退款金额:'.$retentionAmount.',退款原因:工单退款';
  188. RetentionMoneyLogic::refundRetention([
  189. 'work_id'=>$work->id,'worker_id'=>$work->master_worker_id,'amount'=>$retentionAmount,'remark'=>$remark,'source'=>2
  190. ],false);
  191. }
  192. //物业余额变动
  193. $property_commission = PropertyCommission::where('work_id',$order->work_id)->findOrEmpty();
  194. if(!$property_commission->isEmpty()){
  195. $propertyHeadInfo = PropertyHead::where('id',$property_commission->property_head_id)->findOrEmpty();
  196. $propertyHeadInfo = $propertyHeadInfo->toArray();
  197. $propertyHeadId = $propertyHeadInfo['id'];
  198. // 出账记录 - 扣除
  199. PropertySurplusLog::create([
  200. 'in_out' => 2,
  201. 'property_head_id' => $propertyHeadId,
  202. 'amount' => $property_commission['commission_amount'],
  203. 'status' => 1,
  204. 'remark'=> '用户已退款,分成金额已退回'
  205. ]);
  206. // 更新 物业负责人余额收益
  207. PropertyHead::where(['id' => $propertyHeadId])->update([
  208. 'surplus_profit_amount' => Db::raw('surplus_profit_amount-'.$property_commission['commission_amount'])
  209. ]);
  210. }
  211. }
  212. $work->refund_approval = 2;
  213. $work->service_status = 5;
  214. $work->work_status = 9;
  215. $work->save();
  216. }
  217. }
  218. /**
  219. * @notes 更新退款信息
  220. * @param $logId
  221. * @param $msg
  222. * @author 段誉
  223. * @date 2023/3/1 15:47
  224. */
  225. public function updateRefundMsg($logId, $msg)
  226. {
  227. // 更新日志
  228. RefundLog::update([
  229. 'id' => $logId,
  230. 'refund_msg' => $msg,
  231. ]);
  232. }
  233. }