Modules_Manage_Controllers_OrderController.proxy.php 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675
  1. <?php
  2. /**
  3. * 订单相关
  4. * @author x.b
  5. *
  6. */
  7. declare (strict_types=1);
  8. namespace Modules\Manage\Controllers;
  9. use App\Constants\ChangeLogConstant;
  10. use App\Constants\CommonConstant;
  11. use App\Constants\OrderConstrant;
  12. use App\Model\CoinsOrderModel;
  13. use App\Model\PaymentModel;
  14. use App\Model\VipCardModel;
  15. use App\Model\VipOrderModel;
  16. use App\Repositories\ChangeLogRepository;
  17. use App\Repositories\Criterias\ChangeLogCriteria;
  18. use App\Repositories\Criterias\OrderLimitCriteria;
  19. use App\Repositories\OrderRepository as OrderRepository;
  20. use App\Model\UserModel;
  21. use App\Model\VipOrderModel as Model;
  22. use App\Repositories\Service\CommonService;
  23. use App\Repositories\Service\QueueService;
  24. use Carbon\Carbon;
  25. use Hyperf\DbConnection\Db;
  26. use Hyperf\Validation\Contract\ValidatorFactoryInterface;
  27. use Modules\Manage\Responses\OrderChangeListResponse;
  28. class OrderController extends BaseController
  29. {
  30. use \Hyperf\Di\Aop\ProxyTrait;
  31. use \Hyperf\Di\Aop\PropertyHandlerTrait;
  32. function __construct()
  33. {
  34. if (method_exists(parent::class, '__construct')) {
  35. parent::__construct(...func_get_args());
  36. }
  37. $this->__handlePropertyHandler(__CLASS__);
  38. }
  39. // 临时-写死,急上线,后续配置为动态的
  40. public $payment_data = ['white_shark' => '大白鲨'];
  41. /**
  42. * 订单列表
  43. * @return mixed
  44. * @example param_json_data string:
  45. * {"handshake":"","data":{"page":1,"page_size":5,"search":{"order_sn":"","nick":"","user_id":"","user_code":"","device_type":"","status":"","pay_gate_way":"","is_admin_action":"","vip_title":"","stime":"","otime":"","stime_pay":"","otime_pay":""},"order":"created_at","order_sort":"desc"}}
  46. * @deprecated 目前,从 支付方式id 等价于 查询出支付通道! pay_gate_way
  47. */
  48. public function list()
  49. {
  50. $inputData = $this->getJsonData();
  51. $page = isset($inputData['page']) ? (int) $inputData['page'] : 1;
  52. $page_size = isset($inputData['page_size']) ? (int) $inputData['page_size'] : 20;
  53. $select = ['vip_order.*', 'user.nick', 'user.id AS user_id', 'user.code AS user_code', 'user.device_type'];
  54. $model = Model::query();
  55. $order_key = isset($inputData['order']) ? $inputData['order'] : 'id';
  56. $order_value = isset($inputData['order_sort']) ? $inputData['order_sort'] : 'desc';
  57. if (!$order_key) {
  58. $order_key = 'id';
  59. //不要信任前端,他可能会传个空字符串过来!
  60. }
  61. if (!$order_value) {
  62. $order_value = 'desc';
  63. }
  64. // order_sn订单号,status 订单状态, pay_gate_way 支付方式ID(支付方式/支付通道), device_type设备类型,stime 订单创建时间-开始, otime 订单创建时间-结束, stime_pay 订单支付时间-开始, otime_pay 订单支付时间结束 is_admin_action 后台是否查到处理
  65. // nick 用户表-用户名,user_id 用户表-用户ID, user_code 用户表-用户邀请码,
  66. $search = isset($inputData['search']) ? $inputData['search'] : array();
  67. if ($search) {
  68. foreach ($search as $k => $v) {
  69. if (!strlen((string) $v)) {
  70. continue;
  71. }
  72. switch ($k) {
  73. case "nick":
  74. // 用户表-昵称
  75. $model->where('user.' . $k, 'like', "{$v}%");
  76. break;
  77. case "user_code":
  78. // 用户表-邀请码
  79. $model->where('user.' . $k, $v);
  80. break;
  81. case "order_sn":
  82. // 订单号
  83. $model->where('vip_order.' . $k, 'like', "{$v}%");
  84. break;
  85. case "stime":
  86. // 自定义-订单开始日期
  87. $model->where('vip_order.created_at', '>=', $v);
  88. break;
  89. case "otime":
  90. // 自定义-订单结束日期
  91. $model->where('vip_order.created_at', '<=', Carbon::parse($v)->endOfDay()->toDateTimeString());
  92. break;
  93. case "stime_pay":
  94. // 自定义-订单支付开始日期
  95. $model->where('vip_order.pay_time', '>=', $v);
  96. break;
  97. case "otime_pay":
  98. // 自定义-订单支付结束日期
  99. $model->where('vip_order.pay_time', '<=', $v);
  100. break;
  101. default:
  102. $model->where('vip_order.' . $k, $v);
  103. }
  104. }
  105. }
  106. $result = $model->select($select)->leftJoin('user', 'vip_order.user_id', '=', 'user.id')->orderBy((string) $order_key, (string) $order_value)->paginate($page_size, ['*'], 'page', $page);
  107. $payment = make(OrderRepository::class)->all(['name', 'pay_code'])->keyBy('pay_code');
  108. return json_success($result);
  109. }
  110. /**
  111. * 订单列表 - 支付方式/支付通道列表(下拉选项)
  112. * @return object
  113. * @example param_json_data string nobody
  114. */
  115. public function paymentData()
  116. {
  117. //return json_success(make(OrderRepository::class)->getPaymentData());
  118. $data = ['pay_gate_way' => []];
  119. $items = PaymentModel::query()->orderBy('id', 'DESC')->get();
  120. if ($items->count()) {
  121. foreach ($items as $item) {
  122. $data['pay_gate_way'][] = ['id' => $item->id, 'name' => $item->name];
  123. }
  124. }
  125. // 特殊处理,兼容目前前端的对接数据
  126. // $r = $this->payment_data;
  127. // $data = array();
  128. // foreach ($r as $k => $v) {
  129. // $data[] = [
  130. // 'id' => $k,
  131. // 'name' => $v,
  132. // ];
  133. // }
  134. return json_success($data);
  135. }
  136. /**
  137. * 订单列表 - 购买内容(下拉选项)
  138. * @return object
  139. * @example param_json_data string nobody
  140. */
  141. public function vipTitleData()
  142. {
  143. $data = [];
  144. $items = VipCardModel::query()->orderBy('sort', 'DESC')->get(['id', 'title']);
  145. if ($items->count()) {
  146. foreach ($items as $item) {
  147. $data[] = ['id' => $item->id, 'name' => $item->title];
  148. }
  149. }
  150. /*$select = ['vip_title'];
  151. $r = Model::query()
  152. ->select($select)
  153. ->groupBy('vip_title')
  154. ->get();
  155. $data = array();
  156. foreach ($r as $k => $v) {
  157. $data[] = [
  158. 'id' => $k,
  159. 'name' => $v->vip_title,
  160. ];
  161. }*/
  162. return json_success($data);
  163. }
  164. /**
  165. * 补单
  166. * @param ValidatorFactoryInterface $validatorFactory
  167. * @return mixed
  168. * @example param_json_data string: {"handshake":"","data":{"order_sn":"YV202002242305189073","trade_no":"xx支付单号","repair_remark":"xx补单备注"}}
  169. * 处理逻辑:vip_order 订单表标示已付款和付款日期; collections 表创建收款单记录, user表添加会员日期,
  170. * 成功之后,在mongodb中创建一个 补单记录。
  171. * 备注: 不需要去内调回调接口,不要验签!
  172. */
  173. public function again(ValidatorFactoryInterface $validatorFactory)
  174. {
  175. $inputData = $this->getJsonData();
  176. $rules = [
  177. 'order_sn' => 'required|string',
  178. 'trade_no' => 'required|string',
  179. //支付单号
  180. 'repair_remark' => 'required|string',
  181. ];
  182. $validator = $validatorFactory->make($inputData, $rules);
  183. if ($validator->fails()) {
  184. return json_fail($validator->errors()->first());
  185. }
  186. $order_sn = $inputData['order_sn'];
  187. $trade_no = $inputData['trade_no'];
  188. $repair_remark = isset($inputData['repair_remark']) ? $inputData['repair_remark'] : '';
  189. $order_info = make(OrderRepository::class)->getOrderInfo($order_sn);
  190. if (!$order_info) {
  191. return json_fail('订单不存在');
  192. }
  193. // if ($order_info['pay_time']) {
  194. // return json_fail('此订单已处理,请勿重复操作!');
  195. // }
  196. if ($order_info['status'] == 1) {
  197. return json_fail('此订单已处理,请勿重复操作!!');
  198. }
  199. $user_info = UserModel::query()->where('id', $order_info['user_id'])->first();
  200. //处理补单
  201. if (!make(OrderRepository::class)->again($order_sn, $trade_no, $repair_remark)) {
  202. return json_fail('处理失败');
  203. }
  204. // 创建管理员日志
  205. $oldItem = clone $user_info;
  206. $newitem = UserModel::query()->where('id', $order_info['user_id'])->first();
  207. $oldItem2 = clone $order_info;
  208. $newitem2 = make(OrderRepository::class)->getOrderInfo($order_sn);
  209. //返佣计算 异步
  210. make(QueueService::class)->rebateTwoUserJob(['user_id' => $newitem2->user_code, 'amount' => $newitem2->real_amount]);
  211. $logSubject = "补单,用户id:{$user_info['id']},来源订单号:{$order_sn}";
  212. $logSvalue = $oldItem->id;
  213. $logDbData = ['after_items' => [$newitem->toArray(), $newitem2->toArray()], 'before_items' => [$oldItem->toArray(), $oldItem2->toArray()]];
  214. $this->log($logSubject, $logSvalue, $logDbData);
  215. return json_success('', '处理成功');
  216. }
  217. /**
  218. * 每日充值(统计列表) ( v1 版本, 后续项目空闲 v2优化-会单独新设一个表,然后服务器定时任务去查一次,再往新表存下统计数据 )
  219. * @param ValidatorFactoryInterface $validatorFactory
  220. * @return mixed
  221. * @example param_json_data string:
  222. * {"handshake":"","data":{"search":{"pay_gate_way":"","stime":"","otime":""}}}
  223. *
  224. * {"handshake":"","data":{"search":{"pay_gate_way":"","stime":"2020-02-01","otime":"2020-02-28"}}}
  225. *
  226. * {"handshake":"","data":{"search":{"pay_gate_way":"","stime":"2020-02-01","otime":"2020-02-28"}}}
  227. */
  228. public function dayList()
  229. {
  230. $inputData = $this->getJsonData();
  231. $search = isset($inputData['search']) ? $inputData['search'] : array();
  232. $stime = isset($search['stime']) ? $search['stime'] : '';
  233. // 传参如: 2020-2-20
  234. if (!$stime) {
  235. //$stime = date('Y-m-d'); // 今天日期
  236. $stime = date('Y-m-1');
  237. // 此月1号
  238. }
  239. $otime = isset($search['otime']) ? Carbon::parse($search['otime'])->endOfDay()->toDateTimeString() : '';
  240. // 传参如: 2020-2-22
  241. if (!$otime) {
  242. $otime = date('Y-m-d', strtotime("+1 day"));
  243. //明天日期
  244. }
  245. $pay_gate_way = isset($search['pay_gate_way']) ? $search['pay_gate_way'] : '';
  246. // 查询所有数据统计
  247. if ($pay_gate_way) {
  248. $sql = "SELECT LEFT (created_at,10) AS created_date,count(*) AS order_all,sum(order_amount) AS order_amount_all,sum(real_amount) AS real_amount_all,pay_gate_way FROM vip_order WHERE pay_gate_way=? AND created_at>=? AND created_at<=? GROUP BY pay_gate_way,created_date ORDER BY created_date DESC,pay_gate_way ASC";
  249. $order_data_all = Db::select($sql, [$pay_gate_way, $stime, $otime]);
  250. } else {
  251. $sql = "SELECT LEFT (created_at,10) AS created_date,count(*) AS order_all,sum(order_amount) AS order_amount_all,sum(real_amount) AS real_amount_all,pay_gate_way FROM vip_order WHERE created_at>=? AND created_at<=? GROUP BY pay_gate_way,created_date ORDER BY created_date DESC,pay_gate_way ASC";
  252. $order_data_all = Db::select($sql, [$stime, $otime]);
  253. }
  254. if (!$order_data_all) {
  255. $order_data_all = array();
  256. } else {
  257. $order_data_all = json_decode(json_encode($order_data_all), true);
  258. }
  259. // 仅查支付成功的数据统计
  260. if ($pay_gate_way) {
  261. $sql = "SELECT LEFT (created_at,10) AS created_date,count(*) AS order_all,sum(order_amount) AS order_amount_all,sum(real_amount) AS real_amount_all,pay_gate_way FROM vip_order WHERE pay_gate_way=? AND status=1 AND created_at>=? AND created_at<=? GROUP BY pay_gate_way,created_date ORDER BY created_date DESC,pay_gate_way ASC";
  262. $order_data_pay = Db::select($sql, [$pay_gate_way, $stime, $otime]);
  263. } else {
  264. $sql = "SELECT LEFT (created_at,10) AS created_date,count(*) AS order_all,sum(order_amount) AS order_amount_all,sum(real_amount) AS real_amount_all,pay_gate_way FROM vip_order WHERE status=1 AND created_at>=? AND created_at<=? GROUP BY pay_gate_way,created_date ORDER BY created_date DESC,pay_gate_way ASC";
  265. $order_data_pay = Db::select($sql, [$stime, $otime]);
  266. }
  267. if (!$order_data_pay) {
  268. $order_data_pay = array();
  269. } else {
  270. $order_data_pay = json_decode(json_encode($order_data_pay), true);
  271. }
  272. // 开始业务处理和统计 ( 当前是v1版(不提供分页,便于统计),后续 优化时 由 服务器做个定时任务,比如早上1点,定时去查询统计昨日的数据后 往 指定的新表 记录统计后的数据;后台在直接从新表中原样展示数据(可提供分页) )
  273. $order_data_pay_action = array();
  274. if ($order_data_pay) {
  275. foreach ($order_data_pay as $v) {
  276. $order_data_pay_action[$v['pay_gate_way']][] = $v;
  277. }
  278. }
  279. // 组装数据: (日期,支付方式ID,支付通道,创建订单数,成功订单量,订单金额,成功金额,成功率% )
  280. $data = array();
  281. foreach ($order_data_all as $v) {
  282. $action_order_data_pay_info = self::actionOrderDataPayInfo($v['pay_gate_way'], $v['created_date'], $order_data_pay_action);
  283. $order_all_pay = isset($action_order_data_pay_info['order_all']) ? $action_order_data_pay_info['order_all'] : 0;
  284. $real_amount_all_pay = isset($action_order_data_pay_info['real_amount_all']) ? $action_order_data_pay_info['real_amount_all'] : 0;
  285. $conversion = round(round($order_all_pay / $v['order_all'], 4) * 100, 2);
  286. $data[] = array(
  287. 'created_date' => $v['created_date'],
  288. 'pay_gate_way' => $v['pay_gate_way'],
  289. 'order_all' => $v['order_all'],
  290. //创建订单数
  291. 'order_all_pay' => $order_all_pay,
  292. //成功订单量
  293. 'real_amount_all' => $v['real_amount_all'],
  294. //订单金额(以实付金额为准,咨询过 田七 ), order_amount_all 为订单原始金额
  295. 'real_amount_all_pay' => $real_amount_all_pay,
  296. //真实支付的金额(以实付金额为准,咨询过 田七 )-用户已付款的
  297. 'conversion' => $conversion,
  298. );
  299. }
  300. return json_success($data);
  301. }
  302. /**
  303. * @param $pay_gate_way
  304. * @param $created_date
  305. * @param $order_data_pay_action
  306. * @return array
  307. */
  308. protected function actionOrderDataPayInfo($pay_gate_way = '', $created_date = '', $order_data_pay_action = array())
  309. {
  310. if (isset($order_data_pay_action[$pay_gate_way])) {
  311. foreach ($order_data_pay_action[$pay_gate_way] as $kk => $vv) {
  312. if ($vv['created_date'] == $created_date) {
  313. return $vv;
  314. break;
  315. }
  316. }
  317. return array();
  318. } else {
  319. return array();
  320. }
  321. }
  322. /**
  323. * 每日用户成功率(统计列表) ( v1 版本, 后续项目空闲 v2优化-会单独新设一个表,然后服务器定时任务去查一次,再往新表存下统计数据 )
  324. * @param ValidatorFactoryInterface $validatorFactory
  325. * @return mixed
  326. * @example param_json_data string:
  327. * {"handshake":"","data":{"search":{"stime":"","otime":""}}}
  328. *
  329. * {"handshake":"","data":{"search":{"stime":"2020-02-01","otime":"2020-02-28"}}}
  330. *
  331. * {"handshake":"","data":{"search":{"stime":"2020-02-01","otime":"2020-02-28"}}}
  332. */
  333. public function dayListUser()
  334. {
  335. set_time_limit(0);
  336. $inputData = $this->getJsonData();
  337. $search = isset($inputData['search']) ? $inputData['search'] : array();
  338. $stime = isset($search['stime']) ? $search['stime'] : '';
  339. // 传参如: 2020-2-20
  340. if (!$stime) {
  341. $stime = date('Y-m-1');
  342. // 此月1号
  343. }
  344. $otime = isset($search['otime']) ? Carbon::parse($search['otime'])->endOfDay()->toDateTimeString() : '';
  345. // 传参如: 2020-2-22
  346. if (!$otime) {
  347. $otime = Carbon::tomorrow()->endOfDay()->toDateTimeString();
  348. //明天日期
  349. }
  350. $select = [
  351. Db::raw('LEFT (created_at,10) AS created_date'),
  352. //创建时间,转xxxx-xx-xx
  353. 'order_sn',
  354. 'user_id',
  355. // 用户id
  356. 'order_amount',
  357. // 订单金额
  358. 'real_amount',
  359. // 实付金额
  360. 'status',
  361. // 0待支付1已支付2已取消
  362. 'pay_time',
  363. // 付款时间
  364. 'trade_no',
  365. ];
  366. // 查询所有数据
  367. $result = VipOrderModel::query()->select($select)->where('created_at', '>=', $stime)->where('created_at', '<=', $otime)->orderByRaw('created_date desc')->get()->toArray();
  368. // 业务处理统计开始: $data_default 为容器变量,勿赋值,切记!
  369. $data_default = [
  370. 'created_date' => '',
  371. // 2020-02-21
  372. 'order_all' => 0,
  373. // 100 创建订单数
  374. 'order_all_pay' => 0,
  375. // 50 支付订单数
  376. 'user_all' => 0,
  377. // 30 下单用户量
  378. 'user_all_pay' => 0,
  379. // 10 支付用户量
  380. 'amount_all' => 0,
  381. // 订单金额(以实付金额为准,咨询过 田七 ), order_amount_all 为订单原始金额
  382. 'amount_all_pay' => 0,
  383. // 真实支付的金额(以实付金额为准,咨询过 田七 )-用户已付款的
  384. 'user_all_uid_data' => [],
  385. // 用户ID集合 - 便于统计用户量
  386. 'user_all_pay_uid_data' => [],
  387. // 付款的用户ID集合 - 便于统计用户量
  388. 'real_order' => 0,
  389. // 订单成功率 = 支付订单/创建订单 (单位%)
  390. 'real_user' => 0,
  391. // 用户成功率 = 支付用户/下单用户 (单位%)
  392. 'real_other' => 0,
  393. ];
  394. $data = [];
  395. if (!$result) {
  396. return json_success($data);
  397. }
  398. $_now_created_date = '';
  399. $k_max = count($result) - 1;
  400. // 下标
  401. foreach ($result as $k => $v) {
  402. if (!$_now_created_date) {
  403. // 初始
  404. $_now_created_date = $v['created_date'];
  405. $i = 0;
  406. $data[$i] = $data_default;
  407. $data[$i]['created_date'] = $_now_created_date;
  408. }
  409. if ($_now_created_date != $v['created_date']) {
  410. $_now_created_date = $v['created_date'];
  411. //第2日时
  412. $y = $i;
  413. $i++;
  414. $data[$i] = $data_default;
  415. $data[$i]['created_date'] = $_now_created_date;
  416. // 计算各成功率(上一天数据)
  417. $data[$y] = self::actionReal($data[$y]);
  418. }
  419. $data[$i]['order_all']++;
  420. $data[$i]['amount_all'] += $v['real_amount'];
  421. if (!in_array($v['user_id'], $data[$i]['user_all_uid_data'])) {
  422. $data[$i]['user_all_uid_data'][] = $v['user_id'];
  423. //同个ID用户仅算1个用户
  424. }
  425. if ($v['status'] == 1) {
  426. // 付款成功的
  427. $data[$i]['order_all_pay']++;
  428. $data[$i]['amount_all_pay'] += $v['real_amount'];
  429. if (!in_array($v['user_id'], $data[$i]['user_all_pay_uid_data'])) {
  430. $data[$i]['user_all_pay_uid_data'][] = $v['user_id'];
  431. //同个ID用户仅算1个用户
  432. }
  433. }
  434. //处理特殊情况-最后条数据时
  435. if ($k == $k_max) {
  436. $y = $i;
  437. $data[$y] = self::actionReal($data[$y]);
  438. }
  439. }
  440. return json_success($data);
  441. }
  442. /**
  443. * 内用 - 业务计算各种成功率 ( 已封装好,勿动 )
  444. * @author x.b
  445. * @example self::dayListUser()方法在内调这里,业务统计处理
  446. */
  447. private function actionReal($data = array())
  448. {
  449. if (!$data) {
  450. return $data;
  451. }
  452. $data['user_all'] = count($data['user_all_uid_data']);
  453. $data['user_all_pay'] = count($data['user_all_pay_uid_data']);
  454. $data['real_order'] = round(round($data['order_all_pay'] / $data['order_all'], 4) * 100, 2);
  455. $data['real_user'] = round(round($data['user_all_pay'] / $data['user_all'], 4) * 100, 2);
  456. $data['real_other'] = round($data['order_all_pay'] / $data['user_all'], 2);
  457. // 单位:个,表示平均1个人实付多少单
  458. // 测试OK-清除业务用户ID集合,此字段不需要返回给H5
  459. unset($data['user_all_uid_data']);
  460. unset($data['user_all_pay_uid_data']);
  461. return $data;
  462. }
  463. /**
  464. * 用户查单列表 ( 返回结构 与 订单列表 一致, 唯一区别: 这里是强制过滤用户已上传支付凭证的)
  465. * @param ValidatorFactoryInterface $validatorFactory
  466. * @return mixed
  467. * @example param_json_data string:
  468. * {"handshake":"","data":{"page":1,"page_size":5,"search":{"order_sn":"","nick":"","user_id":"","user_code":"","device_type":"","status":"","pay_gate_way":"","is_admin_action":"","stime":"","otime":"","stime_pay":"","otime_pay":""},"order":"created_at","order_sort":"desc"}}
  469. * @deprecated 目前,从 支付方式id 等价于 查询出支付通道! pay_gate_way
  470. */
  471. public function userOrderList(ValidatorFactoryInterface $validatorFactory)
  472. {
  473. $inputData = $this->getJsonData();
  474. $page = isset($inputData['page']) ? (int) $inputData['page'] : 1;
  475. $page_size = isset($inputData['page_size']) ? (int) $inputData['page_size'] : 20;
  476. $select = ['vip_order.*', 'user.nick', 'user.id AS user_id', 'user.code AS user_code', 'user.device_type'];
  477. $model = Model::query();
  478. $order_key = isset($inputData['order']) ? $inputData['order'] : 'id';
  479. $order_value = isset($inputData['order_sort']) ? $inputData['order_sort'] : 'desc';
  480. if (!$order_key) {
  481. $order_key = 'id';
  482. //不要信任前端,他可能会传个空字符串过来!
  483. }
  484. if (!$order_value) {
  485. $order_value = 'desc';
  486. }
  487. // order_sn订单号,status 订单状态, pay_gate_way (支付方式/支付通道), stime 订单创建时间-开始, otime 订单创建时间-结束, stime_pay 订单支付时间-开始, otime_pay 订单支付时间结束 is_admin_action 后台是否查到处理
  488. // nick 用户表-用户名,user_id 用户表-用户ID, user_code 用户表-用户邀请码,
  489. $search = isset($inputData['search']) ? $inputData['search'] : array();
  490. if ($search) {
  491. foreach ($search as $k => $v) {
  492. if (!strlen((string) $v)) {
  493. continue;
  494. }
  495. $operator = '=';
  496. if ($k == 'user_channel_id' && $v == 'official') {
  497. $v = '';
  498. }
  499. switch ($k) {
  500. case "nick":
  501. // 用户表-用户名
  502. case "user_code":
  503. // 用户表-用户邀请码
  504. $model->where('user.' . $k, 'like', "{$v}%");
  505. break;
  506. case "user_id":
  507. // 用户表-用户ID
  508. $model->where('user.id', 'like', "{$v}%");
  509. break;
  510. case "stime":
  511. // 自定义-订单开始日期
  512. $model->where('vip_card.created_at', '>=', $v);
  513. break;
  514. case "otime":
  515. // 自定义-订单结束日期
  516. $model->where('vip_card.created_at', '<=', Carbon::parse($v)->endOfDay()->toDateTimeString());
  517. break;
  518. case "stime_pay":
  519. // 自定义-订单支付开始日期
  520. $model->where('vip_card.pay_time', '>=', $v);
  521. break;
  522. case "otime_pay":
  523. // 自定义-订单支付结束日期
  524. $model->where('vip_card.pay_time', '<=', $v);
  525. break;
  526. default:
  527. $model->where('vip_order.' . $k, $operator, $v);
  528. }
  529. }
  530. }
  531. $model->where('vip_order.is_user_proof', '1');
  532. // 强制过滤,用户已经上传支付凭证的数据
  533. $result = $model->select($select)->leftJoin('user', 'vip_order.user_id', '=', 'user.id')->orderBy((string) $order_key, (string) $order_value)->paginate($page_size, ['*'], 'page', $page);
  534. //处理图片路径
  535. foreach ($result as $v) {
  536. $payproof_imgs_lists = array();
  537. $img = explode(',', $v->payproof_imgs);
  538. $payproof_imgs_lists = $img;
  539. // foreach ($img as $i) {
  540. // $payproof_imgs_lists[] = make(CommonService::class)->getImageUrl($i, true);
  541. // }
  542. $v->payproof_imgs_list = $payproof_imgs_lists;
  543. $v->pay_type = OrderConstrant::$messages[$v->pay_type];
  544. $v->pay_gate_way = $v->pay_gate_way;
  545. }
  546. return json_success($result);
  547. }
  548. /**
  549. * 用户查单列表-标记为 已查单
  550. * @param ValidatorFactoryInterface $validatorFactory
  551. * @return mixed
  552. * @example param_json_data string: {"handshake":"","data":{"order_sn":"YV202002242305189073"}}
  553. */
  554. public function setUserOrder(ValidatorFactoryInterface $validatorFactory)
  555. {
  556. $inputData = $this->getJsonData();
  557. $rules = ['order_sn' => 'required'];
  558. $validator = $validatorFactory->make($inputData, $rules);
  559. if ($validator->fails()) {
  560. return json_fail($validator->errors()->first());
  561. }
  562. $order_sn = $inputData['order_sn'];
  563. $order_info = make(OrderRepository::class)->getOrderInfo($order_sn);
  564. if (!$order_info) {
  565. return json_fail('订单不存在');
  566. }
  567. if ($order_info['is_admin_action']) {
  568. return json_fail('此订单已标示为已查单,请勿重复操作');
  569. }
  570. $r = make(OrderRepository::class)->setAdminAction($order_sn, 1);
  571. if (!$r) {
  572. return json_fail('处理失败');
  573. }
  574. // 创建管理员日志
  575. $oldItem = clone $order_info;
  576. $newitem = make(OrderRepository::class)->getOrderInfo($order_sn);
  577. $logSubject = "将订单标记为已查单,订单号为:{$order_sn}";
  578. $logSvalue = $oldItem->id;
  579. $logDbData = ['after_items' => [$newitem->toArray()], 'before_items' => [$oldItem->toArray()]];
  580. $this->log($logSubject, $logSvalue, $logDbData);
  581. return json_success('', '处理成功');
  582. }
  583. /**
  584. * 支付金币
  585. * @param ValidatorFactoryInterface $validatorFactory
  586. */
  587. public function coinsOrder(ValidatorFactoryInterface $validatorFactory)
  588. {
  589. $inputData = $this->getJsonData();
  590. $rules = ['page' => 'nullable|integer', 'page_size' => 'nullable|integer', 'order_sn' => 'nullable', 'user_uid' => 'nullable', 'status' => 'nullable|integer', 'stime' => 'nullable', 'otime' => 'nullable', 'otime_pay' => 'nullable', 'stime_pay' => 'nullable'];
  591. $validator = $validatorFactory->make($inputData, $rules);
  592. if ($validator->fails()) {
  593. return json_fail($validator->errors()->first());
  594. }
  595. $result = CoinsOrderModel::query()->orderByDesc('id')->where(function ($q) use($inputData) {
  596. if ($inputData['order_sn']) {
  597. $q->where('order_sn', $inputData['order_sn']);
  598. }
  599. if ($inputData['user_uid']) {
  600. $q->where('user_code', $inputData['user_uid']);
  601. }
  602. if ($inputData['status']) {
  603. $q->where('status', $inputData['status']);
  604. }
  605. if ($inputData['stime'] && $inputData['otime']) {
  606. $q->whereBetween('created_at', [Carbon::parse($inputData['stime'])->toDateString(), Carbon::parse($inputData['otime'])->toDateString()]);
  607. }
  608. if ($inputData['stime_pay'] && $inputData['otime_pay']) {
  609. $q->whereBetween('pay_time', [Carbon::parse($inputData['stime_pay'])->toDateString(), Carbon::parse($inputData['otime_pay'])->toDateString()]);
  610. }
  611. })->paginate((int) $inputData['page_size'], ['*'], 'page', (int) $inputData['page']);
  612. return json_success($result);
  613. }
  614. /**
  615. * 金币订单补单
  616. *
  617. * @param ValidatorFactoryInterface $validatorFactory
  618. * @return mixed
  619. */
  620. public function coinsAgain(ValidatorFactoryInterface $validatorFactory)
  621. {
  622. $inputData = $this->getJsonData();
  623. $rules = [
  624. 'order_sn' => 'required|string',
  625. //支付单号
  626. 'repair_remark' => 'nullable|string',
  627. ];
  628. $validator = $validatorFactory->make($inputData, $rules);
  629. if ($validator->fails()) {
  630. return json_fail($validator->errors()->first());
  631. }
  632. $orderInfo = make(OrderRepository::class)->getCoinsOrderInfo($inputData['order_sn']);
  633. if (empty($orderInfo)) {
  634. return json_fail('订单不存在');
  635. }
  636. if ($orderInfo['status'] == 1) {
  637. return json_fail('此订单已处理,请勿重复操作!');
  638. }
  639. $res = make(OrderRepository::class)->coinsAgain($inputData['order_sn'], $inputData['repair_remark'], $orderInfo['user_id'], $orderInfo['coins']);
  640. if (!$res) {
  641. return json_fail('补单失败');
  642. }
  643. $logSubject = "给用户{$orderInfo['user_id']}加金币" . $orderInfo['coins'];
  644. $logSvalue = $orderInfo['user_id'];
  645. $logDbData = ['after_items' => [], 'before_items' => []];
  646. $this->log($logSubject, $logSvalue, $logDbData);
  647. return json_success('', '操作成功');
  648. }
  649. /**
  650. * 帐变列表
  651. *
  652. * @param ValidatorFactoryInterface $validatorFactory
  653. * @return mixed|OrderChangeListResponse
  654. */
  655. public function changeList(ValidatorFactoryInterface $validatorFactory)
  656. {
  657. $inputData = $this->getJsonData();
  658. $rules = ['page' => 'required|integer', 'page_size' => 'required|integer', 'uid' => 'nullable|string', 'username' => 'nullable|string', 'user_uid' => 'nullable|string', 'type' => 'nullable|integer', 'way' => 'nullable|integer'];
  659. $validator = $validatorFactory->make($inputData, $rules);
  660. if ($validator->fails()) {
  661. // 如果有错误(可能是多个信息),这里只取第一个错误信息返回.
  662. return json_fail($validator->errors()->first());
  663. }
  664. $orders = [['created_at', 'DESC']];
  665. $pageSize = $inputData['page_size'] ?? CommonConstant::PAGE_SIZE;
  666. if ($pageSize > 500) {
  667. $pageSize = CommonConstant::PAGE_SIZE;
  668. }
  669. $page = format_page($inputData['page']);
  670. $res = make(ChangeLogRepository::class)->pushCriteria(new ChangeLogCriteria($inputData))->pushCriteria(new OrderLimitCriteria($orders))->paginate($pageSize, ['*'], $page);
  671. return new OrderChangeListResponse($res);
  672. }
  673. }