DepositService.php 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | LARAVEL8.0 框架 [ LARAVEL ][ RXThinkCMF ]
  4. // +----------------------------------------------------------------------
  5. // | 版权所有 2017~2021 LARAVEL研发中心
  6. // +----------------------------------------------------------------------
  7. // | 官方网站: http://www.laravel.cn
  8. // +----------------------------------------------------------------------
  9. // | Author: laravel开发员 <laravel.qq.com>
  10. // +----------------------------------------------------------------------
  11. namespace App\Services\Common;
  12. use App\Models\AccountLogModel;
  13. use App\Models\ActionLogModel;
  14. use App\Models\ConfigModel;
  15. use App\Models\DepositModel;
  16. use App\Models\MemberModel;
  17. use App\Models\MessageModel;
  18. use App\Services\BaseService;
  19. use App\Services\ConfigService;
  20. use App\Services\PaymentService;
  21. use App\Services\RedisService;
  22. use App\Services\SmsService;
  23. use Illuminate\Support\Facades\DB;
  24. /**
  25. * 保证金订单管理-服务类
  26. * @author laravel开发员
  27. * @since 2020/11/11
  28. * @package App\Services\Api
  29. */
  30. class DepositService extends BaseService
  31. {
  32. // 静态对象
  33. protected static $instance = null;
  34. /**
  35. * 构造函数
  36. * @author laravel开发员
  37. * @since 2020/11/11
  38. */
  39. public function __construct()
  40. {
  41. $this->model = new DepositModel();
  42. }
  43. /**
  44. * 静态入口
  45. */
  46. public static function make()
  47. {
  48. if (!self::$instance) {
  49. self::$instance = new static();
  50. }
  51. return self::$instance;
  52. }
  53. /**
  54. * 列表数据
  55. * @param $params
  56. * @param int $pageSize
  57. * @return array
  58. */
  59. public function getDataList($params, $pageSize = 15)
  60. {
  61. $query = $this->getQuery($params);
  62. $refundStatus = isset($params['refund_status']) ? $params['refund_status'] : -1;
  63. $model = clone $query;
  64. $counts = [
  65. 'count'=> $model->count('a.id'),
  66. 'total'=> $model->sum($refundStatus>=0?'a.refund_money':'a.money'),
  67. ];
  68. if($refundStatus==0){
  69. $query->orderBy('a.refund_status', 'asc')
  70. ->orderBy('a.refund_at', 'desc')
  71. ->orderBy('a.id', 'desc');
  72. }else if($refundStatus>0){
  73. $query->orderBy('a.refund_at', 'desc')
  74. ->orderBy('a.id', 'desc');
  75. }else{
  76. $query->orderBy('a.create_time', 'desc')
  77. ->orderBy('a.id', 'desc');
  78. }
  79. $field = ["a.*"];
  80. $list = $query->select($field)
  81. ->paginate($pageSize > 0 ? $pageSize : 9999999);
  82. $list = $list ? $list->toArray() : [];
  83. if ($list) {
  84. foreach ($list['data'] as &$item){
  85. $item['create_time'] = $item['create_time']? datetime($item['create_time'],'Y-m-d H:i:s') : '';
  86. $item['time_text'] = $item['create_time']? datetime($item['create_time'],'Y年m月d日') : '';
  87. }
  88. $datas = [
  89. 'pageSize' => $pageSize,
  90. 'total' => isset($list['total']) ? $list['total'] : 0,
  91. 'list' => isset($list['data']) ? $list['data'] : [],
  92. 'counts' => $counts,
  93. ];
  94. // 消息已读
  95. MessageModel::where(['is_read'=>2,'type'=>$refundStatus>=0?4:3,'mark'=>1])->update(['is_read'=>1,'update_time'=>time()]);
  96. }
  97. return $datas;
  98. }
  99. /**
  100. * 查询条件
  101. * @param $params
  102. * @return mixed
  103. */
  104. public function getQuery($params)
  105. {
  106. $where = ['a.status' => 0, 'a.mark' => 1];
  107. $status = isset($params['status']) ? $params['status'] : 0;
  108. if ($status > 0) {
  109. $where['a.status'] = $status;
  110. } else {
  111. unset($where['a.status']);
  112. }
  113. $model = $this->model->with(['user'])->from('deposit_orders as a')
  114. ->leftJoin('member as b','b.id','=','a.user_id')
  115. ->where($where)
  116. ->where(function ($query) use ($params) {
  117. $refundNo= isset($params['refund_no']) ? trim($params['refund_no']) : '';
  118. $orderNo = isset($params['order_no']) ? trim($params['order_no']) : '';
  119. $refundStatus = isset($params['refund_status']) ? $params['refund_status'] : -1;
  120. if($refundNo){
  121. $query->where(function($query) use($refundNo){
  122. $query->where('a.refund_no', 'like', "%{$refundNo}%")
  123. ->orWhere('a.refund_transaction_id', 'like', "%{$refundNo}%");
  124. });
  125. }else if($orderNo){
  126. $query->where(function($query) use($orderNo){
  127. $query->where('a.order_no', 'like', "%{$orderNo}%")
  128. ->orWhere('a.transaction_id', 'like', "%{$orderNo}%");
  129. });
  130. }
  131. if($refundStatus==0){
  132. $query->where(['a.status'=>3])->where('a.refund_status','>',1);
  133. }else if($refundStatus>0){
  134. $query->where(['a.status'=>3])->where('a.refund_status', $refundStatus);
  135. }
  136. // 用户
  137. $account = isset($params['account']) ? trim($params['account']) : '';
  138. if ($account) {
  139. $query->where(function ($query) use ($account) {
  140. $query->where('b.mobile', 'like', "%{$account}%")
  141. ->orWhere('b.nickname', 'like', "%{$account}%");
  142. });
  143. }
  144. $userId = isset($params['user_id']) ? intval($params['user_id']) : 0;
  145. if ($userId>0) {
  146. $query->where('a.user_id', $userId);
  147. }
  148. });
  149. return $model;
  150. }
  151. /**
  152. * 详情信息
  153. * @param $id
  154. * @return mixed
  155. */
  156. public function getInfo($id)
  157. {
  158. $cacheKey = "caches:deposit:info_{$id}";
  159. $info = RedisService::get($cacheKey);
  160. if($info){
  161. return $info;
  162. }
  163. $info = $this->model->with(['user'])->where(['order_id' => $id])->first();
  164. $info = $info? $info->toArray() :[];
  165. if($info){
  166. RedisService::set($cacheKey, $info, rand(5,10));
  167. }
  168. return $info;
  169. }
  170. /**
  171. * 获取保证金配置
  172. * @return array
  173. */
  174. public function getSetting()
  175. {
  176. $config = ConfigService::make()->getConfigByGroup(5);
  177. return [
  178. 'deposit_money'=> isset($config['deposit_money']['value'])? $config['deposit_money']['value'] : '',
  179. 'deposit_desc'=> isset($config['deposit_desc']['value'])? $config['deposit_desc']['value'] : '',
  180. 'deposit_refund_desc'=> isset($config['deposit_refund_desc']['value'])? $config['deposit_refund_desc']['value'] : '',
  181. ];
  182. }
  183. /**
  184. * 保存保证金配置
  185. * @return array
  186. */
  187. public function saveSetting($userId, $params)
  188. {
  189. $check = false;
  190. $names = ['deposit_money'=>'接单保证金','deposit_desc'=>'保证金充值说明','deposit_refund_desc'=>'保证金退保说明'];
  191. $notes = ['deposit_money'=>'接单保证金金额/元。'];
  192. foreach ($params as $key => $value){
  193. $name = isset($names[$key])? $names[$key] : '';
  194. $note = isset($notes[$key])? $notes[$key] : '';
  195. if($name){
  196. $check = true;
  197. $oldValue = ConfigService::make()->getConfigByCode($key);
  198. if($value && $oldValue != $value){
  199. $id = ConfigModel::where(['code'=> $key,'mark'=>1])->value('id');
  200. if($id){
  201. ConfigModel::where(['id'=> $id])->update(['value'=>$value, 'update_time'=>time()]);
  202. }else{
  203. ConfigModel::insetGetId(['title'=> $name,'config_group_id'=>5,'type'=>$key=='deposit_money'? 'readonly': 'textarea','code'=>$key,'value'=>$value,'note'=>$note,'create_time'=>time(),'status'=>1,'mark'=>1, 'update_time'=>time()]);
  204. }
  205. // 清除缓存
  206. RedisService::clear("caches:config:code:".$key);
  207. }
  208. }
  209. }
  210. if(!$check){
  211. $this->error = '未修改';
  212. return false;
  213. }
  214. $this->error = '设置成功';
  215. RedisService::clear("caches:config:groups:5");
  216. RedisService::keyDel("caches:config:app*");
  217. RedisService::keyDel(env('APP_NAME')."_cache:*");
  218. ActionLogModel::setRecord(session('userId'), ['type' => 1, 'title' => "修改保证金配置", 'content' => json_encode(request()->post(), 256), 'module' => 'admin']);
  219. ActionLogModel::record();
  220. return true;
  221. }
  222. /**
  223. * 审核
  224. * @param $adminId
  225. * @param $params
  226. * @return array|false
  227. */
  228. public function confirm($adminId, $params)
  229. {
  230. $id = isset($params['id'])? intval($params['id']) : 0;
  231. $status = isset($params['refund_status'])? intval($params['refund_status']) : 0;
  232. $confirmRemark = isset($params['refund_confirm_remark'])? trim($params['refund_confirm_remark']) : '';
  233. $info = $this->model->with(['user'])->where(['id'=> $id,'mark'=>1])->first();
  234. $userInfo = isset($info['user'])? $info['user'] : [];
  235. $orderStatus = isset($info['refund_status'])? $info['refund_status'] : 0;
  236. $orderUserId = isset($info['user_id'])? $info['user_id'] : 0;
  237. $refundMoney = isset($info['refund_money'])? $info['refund_money'] : 0;
  238. if(empty($info) || empty($userInfo) || $orderUserId<=0 || $refundMoney<=0){
  239. $this->error = '退保申请信息不存在或参数错误';
  240. return false;
  241. }
  242. if($orderStatus != 1){
  243. $this->error = '退保订单状态不可操作';
  244. return false;
  245. }
  246. if(!in_array($status,[2,3])){
  247. $this->error = '退保审核状态错误';
  248. return false;
  249. }
  250. if($status == 3 && empty($confirmRemark)){
  251. $this->error = '请填写审核驳回备注';
  252. return false;
  253. }
  254. DB::beginTransaction();
  255. $updateOrder = ['refund_status'=>$status,'confirm_admin_id'=>$adminId,'update_time'=>time(),'refund_confirm_remark'=>$confirmRemark];
  256. // 如果驳回
  257. if($status == 3){
  258. $updateData = ['deposit'=> $refundMoney,'update_time'=>time()];
  259. if(!MemberModel::where(['id'=> $orderUserId])->update($updateData)){
  260. DB::rollBack();
  261. $this->error = '退保审核处理失败';
  262. return false;
  263. }
  264. }else if($status == 2){
  265. // 线上直接退款逻辑
  266. $payType = isset($info['pay_type'])? $info['pay_type'] : 0;
  267. $order = [
  268. 'money' => $refundMoney,
  269. 'pay_type' => $payType,
  270. 'order_no' => isset($info['order_no'])? $info['order_no'] : '',
  271. 'out_trade_no' => isset($info['refund_no'])? $info['refund_no'] : '',
  272. 'transaction_id' => isset($info['transaction_id'])? $info['transaction_id'] : '',
  273. 'remark'=> '退保'
  274. ];
  275. if(!PaymentService::make()->refund($order)){
  276. DB::rollBack();
  277. $this->error = '退保退款处理失败';
  278. return false;
  279. }
  280. // 支付宝调用成功直接完成
  281. if($payType == 20){
  282. $updateOrder['refund_status'] = 4;
  283. $updateOrder['remark'] = '已退保';
  284. }
  285. }
  286. if(!$this->model->where(['id'=> $id])->update($updateOrder)){
  287. DB::rollBack();
  288. $this->error = '退款审核处理失败';
  289. return false;
  290. }
  291. DB::commit();
  292. $this->error = '退款审核成功';
  293. ActionLogModel::setRecord(session('userId'), ['type' => 1, 'title' => "保证金退保审核", 'content' => json_encode(request()->post(), 256), 'module' => 'admin']);
  294. ActionLogModel::record();
  295. return ['id'=>$id,'money'=>$refundMoney,'refund_status'=>$status];
  296. }
  297. /**
  298. * 打款
  299. * @param $adminId
  300. * @param $params
  301. * @return array|false
  302. */
  303. public function payment($adminId, $params)
  304. {
  305. $id = isset($params['id'])? intval($params['id']) : 0;
  306. $info = $this->model->with(['user'])->where(['id'=> $id,'mark'=>1])->first();
  307. $userInfo = isset($info['user'])? $info['user'] : [];
  308. $orderStatus = isset($info['refund_status'])? $info['refund_status'] : 0;
  309. $orderUserId = isset($info['user_id'])? $info['user_id'] : 0;
  310. $refundMoney = isset($info['refund_money'])? $info['refund_money'] : 0;
  311. if(empty($info) || empty($userInfo) || $orderUserId<=0 || $refundMoney<=0){
  312. $this->error = '退保申请信息不存在或参数错误';
  313. return false;
  314. }
  315. if($orderStatus == 4){
  316. $this->error = '退保订单已打款';
  317. return false;
  318. }
  319. if($orderStatus != 2){
  320. $this->error = '退保订单状态不可操作';
  321. return false;
  322. }
  323. // 线上直接退款逻辑
  324. $payType = isset($info['pay_type'])? $info['pay_type'] : 0;
  325. $order = [
  326. 'money' => $refundMoney,
  327. 'pay_type' => $payType,
  328. 'order_no' => isset($info['order_no'])? $info['order_no'] : '',
  329. 'out_trade_no' => isset($info['refund_no'])? $info['refund_no'] : '',
  330. 'transaction_id' => isset($info['transaction_id'])? $info['transaction_id'] : '',
  331. 'remark'=> '退保'
  332. ];
  333. DB::beginTransaction();
  334. if(!PaymentService::make()->refund($order)){
  335. DB::rollBack();
  336. $this->error = '退保退款处理请求失败';
  337. return false;
  338. }
  339. if($payType == 20 && !$this->model->where(['id'=> $id])->update(['refund_status'=>4,'remark'=>'已退保','update_time'=>time()])){
  340. DB::rollBack();
  341. $this->error = '退保退款处理失败';
  342. return false;
  343. }
  344. DB::commit();
  345. $this->error = '退保打款请求成功';
  346. ActionLogModel::setRecord(session('userId'), ['type' => 1, 'title' => "保证金退款打款", 'content' => json_encode(request()->post(), 256), 'module' => 'admin']);
  347. ActionLogModel::record();
  348. return ['id'=>$id,'money'=>$refundMoney,'status'=>$orderStatus];
  349. }
  350. /**
  351. * 统计
  352. * @param int $type
  353. * @return array|mixed
  354. */
  355. public function getTotal($type=0)
  356. {
  357. $cacheKey = "caches:deposit:total_{$type}";
  358. $data = RedisService::get($cacheKey);
  359. if($data){
  360. return $data;
  361. }
  362. $data = $this->model->where(['mark'=>1])
  363. ->where(function($query) use($type){
  364. if($type== 1){
  365. $query->where(['status'=>3])->whereIn('refund_status',[2,4]);
  366. }else {
  367. $query->where(['status'=>3]);
  368. }
  369. })->sum('money');
  370. if($data){
  371. RedisService::set($cacheKey, $data, rand(300, 600));
  372. }
  373. return $data;
  374. }
  375. }