CashTradeOrder.php 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509
  1. <?php
  2. namespace app\models\trade;
  3. use app\models\user\User;
  4. use app\models\user\UserBill;
  5. use app\models\user\UserMoney;
  6. use app\models\user\UserMoneyOrder;
  7. use crmeb\traits\ModelTrait;
  8. use crmeb\basic\BaseModel;
  9. use think\db\exception\DataNotFoundException;
  10. use think\db\exception\DbException;
  11. use think\db\exception\ModelNotFoundException;
  12. use think\Exception;
  13. use think\Model;
  14. class CashTradeOrder extends BaseModel
  15. {
  16. /**
  17. * 数据表主键
  18. * @var string
  19. */
  20. protected $pk = 'id';
  21. /**
  22. * 模型名称
  23. * @var string
  24. */
  25. protected $name = 'cash_trade_order';
  26. use ModelTrait;
  27. /**
  28. * @param $money_type
  29. * @return int|string|null
  30. */
  31. public static function averagePrice($money_type)
  32. {
  33. $all_money = self::whereTime('trade_time', 'yesterday')->where('status', 2)->where('money_type', $money_type)->sum('money_num');
  34. $all_cash = self::whereTime('trade_time', 'yesterday')->where('status', 2)->where('money_type', $money_type)->sum('all_price');
  35. if ($all_money > 0)
  36. return bcdiv($all_cash, $all_money, 8);
  37. else
  38. return "0";
  39. }
  40. /**
  41. * @param $where
  42. * @return self
  43. */
  44. public static function setStatus($where)
  45. {
  46. if (is_array($where)) {
  47. if (isset($where['status'])) {
  48. $status = $where['status'];
  49. } else {
  50. return new self();
  51. }
  52. } else {
  53. $status = $where;
  54. }
  55. switch ($status) {
  56. case 1://挂出中
  57. return self::where('status', 'in', [0, -1])->where('end_time', '>', time())->where('trade_uid', null);
  58. case 2://已完成
  59. return self::where('status', 1);
  60. case 3://挂出时间结束
  61. return self::where('status', 'in', [0, -1, 2])->where('end_time', '<', time());
  62. case 4://挂出时间结束,未领回
  63. return self::where('status', 'in', [0, -1])->where('end_time', '<', time())->where('close_time', '<', time());
  64. case 5://已领回
  65. return self::where('status', 2);
  66. case 6://交易中,已上传凭证
  67. return self::where('status', 3);
  68. case 7://未结束 但是关闭
  69. return self::where('status', 'in', [0, -1])->where('end_time', '>', time())->where('close_time', '<', time());
  70. default:
  71. return new self();
  72. }
  73. }
  74. /**
  75. * @param $where
  76. * @return array
  77. */
  78. public static function getList($where)
  79. {
  80. $model = self::setStatus($where);
  81. // if (isset($where['uid']) && $where['uid']) {
  82. // $model = $model->where('uid|trade_uid', $where['uid']);
  83. // }
  84. if (isset($where['trade_type']) && $where['trade_type'] != '') {
  85. if (isset($where['uid']) && $where['uid']) {
  86. $model = $model->where(function ($query) use ($where) {
  87. $query->where('trade_uid', $where['uid'])
  88. ->where('trade_type', $where['trade_type']);
  89. })->whereOr(function ($query) use ($where) {
  90. $query->where('uid', $where['uid'])
  91. ->where('trade_type', '<>', $where['trade_type']);
  92. });
  93. } else {
  94. $model = $model->where('trade_type', $where['trade_type']);
  95. }
  96. }
  97. if (isset($where['money_type']) && $where['money_type'] != '') {
  98. $model = $model->where('money_type', $where['money_type']);
  99. }
  100. $count = $model->count();
  101. // var_dump(self::getLastSql());
  102. $list = $model->order('add_time', 'desc')->page((int)$where['page'], (int)$where['limit'])->select()
  103. // var_dump(self::getLastSql());
  104. ->each(function ($item) {
  105. $item['user'] = User::getUserInfo($item['uid']);
  106. $item['trade_user'] = User::getUserInfo($item['trade_uid']);
  107. // $item['_add_time'] = time_format($item['add_time']);
  108. // $item['_end_time'] = time_format($item['end_time']);
  109. // $item['_trade_time'] = time_format($item['trade_time']);
  110. $money_type = init_money_type();
  111. $item['_user'] = User::getUserInfo($item['uid'])['nickname'] . '/' . $item['uid'];
  112. $item['_trade_user'] = $item['trade_uid'] ? User::getUserInfo($item['trade_uid'])['nickname'] . '/' . $item['trade_uid'] : '--';
  113. $item['_add_time'] = time_format($item['add_time']);
  114. $item['_end_time'] = $item['end_time'] ? time_format($item['end_time']) : '--';
  115. $item['_trade_time'] = $item['trade_time'] ? time_format($item['trade_time']) : '--';
  116. $item['_money_type'] = $money_type[$item['money_type']];
  117. $item['_trade_type'] = $item['trade_type'] == 2 ? '挂买' : '挂卖';
  118. $item['_proof'] = $item['proof'] ? "<img src='" . $item['proof'] . "'>" : '--';
  119. switch ($item['status']) {
  120. case -1:
  121. $item['_status'] = '未支付';
  122. break;
  123. case 0:
  124. $item['_status'] = '未完成';
  125. break;
  126. case 1:
  127. $item['_status'] = '已完成';
  128. break;
  129. case 2:
  130. $item['_status'] = '已收回';
  131. break;
  132. case 3:
  133. $item['_status'] = '交易中【‘已提交交易凭证’】';
  134. break;
  135. default:
  136. $item['_status'] = '未知';
  137. break;
  138. }
  139. });
  140. // var_dump($list);
  141. return compact('count', 'list');
  142. }
  143. public static function getOneUserList($where)
  144. {
  145. $model = self::setStatus($where);
  146. $model = $model->where('uid|trade_uid', $where['uid']);
  147. // if (isset($where['trade_type']) && $where['trade_type'] != '') {
  148. // if (isset($where['uid']) && $where['uid']) {
  149. // $model = $model->where(function ($query) use ($where) {
  150. // $query->where('trade_uid', $where['uid'])
  151. // ->where('trade_type', $where['trade_type']);
  152. // })->whereOr(function ($query) use ($where) {
  153. // $query->where('uid', $where['uid'])
  154. // ->where('trade_type', '<>', $where['trade_type']);
  155. // });
  156. // } else {
  157. // $model = $model->where('trade_type', $where['trade_type']);
  158. // }
  159. // }
  160. // if (isset($where['money_type']) && $where['money_type'] != '') {
  161. // $model = $model->where('money_type', $where['money_type']);
  162. // }
  163. // $count = $model->count();
  164. // var_dump(self::getLastSql());
  165. $list = $model->page((int)$where['page'], (int)$where['limit'])->select()
  166. // var_dump(self::getLastSql());
  167. ->each(function ($item) use ($where) {
  168. $money_type = init_money_type();
  169. $item['_user'] = User::getUserInfo($item['uid'])['nickname'] . '/' . $item['uid'];
  170. $item['_trade_user'] = $item['trade_uid'] ? User::getUserInfo($item['trade_uid'])['nickname'] . '/' . $item['trade_uid'] : '--';
  171. $item['_add_time'] = time_format($item['add_time']);
  172. $item['_end_time'] = $item['_end_time'] ? time_format($item['end_time']) : '--';
  173. $item['_trade_time'] = $item['trade_time'] ? time_format($item['trade_time']) : '--';
  174. $item['_money_type'] = $money_type[$item['money_type']];
  175. $item['_trade_type'] = $item['trade_type'] == 2 ? '挂买' : '挂卖';
  176. $item['_proof'] = $item['proof'] ? "<img src='" . $item['proof'] . "'>" : '--';
  177. switch ($item['status']) {
  178. case -1:
  179. $item['_status'] = '未支付';
  180. break;
  181. case 0:
  182. $item['_status'] = '未完成';
  183. break;
  184. case 1:
  185. $item['_status'] = '已完成';
  186. break;
  187. case 2:
  188. $item['_status'] = '已收回';
  189. break;
  190. case 3:
  191. $item['_status'] = '交易中【‘已提交交易凭证’】';
  192. break;
  193. default:
  194. $item['_status'] = '未知';
  195. break;
  196. }
  197. });
  198. return $list;
  199. }
  200. public static function hangSale($uid, $money_type, $money_num, $price, $hang_time)
  201. {
  202. $user = User::getUserInfo($uid);
  203. if (!$user['bank_code'] && !$user['alipay_code'] && !$user['alipay_account'] && !$user['wechat_code'] && !$user['wechat_account']) {
  204. return self::setErrorInfo('请先设置收款方式!');
  205. }
  206. $money = UserMoney::initialUserMoney($uid, $money_type);
  207. if ($money['money'] < $money_num) return self::setErrorInfo('账户不足!');
  208. $sum = bcmul($money_num, $price, 2);
  209. BaseModel::beginTrans();
  210. try {
  211. $res = UserMoney::expendMoney($uid, $money_type, $money_num, 'hang_sale', '挂卖', '挂卖' . $money_num);
  212. if (!$res) {
  213. return self::setErrorInfo(UserMoney::getErrorInfo('支付失败'), true);
  214. }
  215. $res = self::create([
  216. 'order_id' => self::getOrderId(),
  217. 'uid' => $uid,
  218. 'money_type' => $money_type,
  219. 'money_num' => $money_num,
  220. 'price' => $price,
  221. 'all_price' => $sum,
  222. 'trade_type' => 1,
  223. 'add_time' => time(),
  224. 'hang_time' => $hang_time,
  225. 'end_time' => bcadd(time(), bcmul($hang_time, 3600)),
  226. ]);
  227. if ($res) {
  228. BaseModel::commitTrans();
  229. return $res;
  230. } else {
  231. return self::setErrorInfo('挂卖失败', true);
  232. }
  233. } catch (Exception $e) {
  234. return self::setErrorInfo($e->getMessage(), true);
  235. }
  236. }
  237. public static function hangBuy2($uid, $money_type, $money_num, $price, $hang_time)
  238. {
  239. $sum = bcmul($money_num, $price, 2);
  240. BaseModel::beginTrans();
  241. try {
  242. // $res = UserMoney::expendMoney($uid, $money_type, $money_num, 'hang_sale', '挂卖', '挂卖' . $money_num);
  243. // if (!$res) {
  244. // return self::setErrorInfo(UserMoney::getErrorInfo('支付失败'), true);
  245. // }
  246. $res = self::create([
  247. 'order_id' => self::getOrderId(),
  248. 'uid' => $uid,
  249. 'money_type' => $money_type,
  250. 'money_num' => $money_num,
  251. 'price' => $price,
  252. 'all_price' => $sum,
  253. 'trade_type' => 2,
  254. 'add_time' => time(),
  255. 'hang_time' => $hang_time,
  256. 'status' => -1,//未支付虚拟货币
  257. 'end_time' => bcadd(time(), bcmul($hang_time, 3600)),
  258. ]);
  259. if ($res) {
  260. BaseModel::commitTrans();
  261. return $res;
  262. } else {
  263. return self::setErrorInfo('挂买失败', true);
  264. }
  265. } catch (Exception $e) {
  266. return self::setErrorInfo($e->getMessage(), true);
  267. }
  268. }
  269. public static function hangBuy($uid, $money_type, $money_num, $price, $hang_time)
  270. {
  271. $sum = bcmul($money_num, $price, 2);
  272. BaseModel::beginTrans();
  273. try {
  274. $res = CashTradeOrderPayment::create([
  275. 'uid' => $uid,
  276. 'order_id' => CashTradeOrderPayment::getOrderId(),
  277. 'order_type' => 1,
  278. 'pay_money' => $sum,
  279. 'add_time' => time(),
  280. 'order_info' => json_encode([
  281. 'uid' => $uid,
  282. 'money_type' => $money_type,
  283. 'money_num' => $money_num,
  284. 'price' => $price,
  285. 'all_price' => $sum,
  286. 'trade_type' => 2,
  287. 'hang_time' => $hang_time,]),
  288. ]);
  289. if ($res) {
  290. BaseModel::commitTrans();
  291. return $res;
  292. } else {
  293. return self::setErrorInfo('订单生成失败', true);
  294. }
  295. } catch (Exception $e) {
  296. return self::setErrorInfo($e->getMessage(), true);
  297. }
  298. }
  299. public static function getOrderId()
  300. {
  301. list($msec, $sec) = explode(' ', microtime());
  302. $msectime = number_format((floatval($msec) + floatval($sec)) * 1000, 0, '', '');
  303. do {
  304. $str = 'ct' . $msectime . mt_rand(10000, 99999);
  305. } while (self::be(['order_id' => $str]));
  306. return $str;
  307. }
  308. public static function sale($uid, $id)
  309. {
  310. $order = self::setStatus(1)->where('id', $id)->find();
  311. if (!$order) {
  312. return self::setErrorInfo('订单不存在或已结束挂出');
  313. }
  314. $user = User::getUserInfo($uid);
  315. if (!$user['bank_code'] && !$user['alipay_code'] && !$user['alipay_account'] && !$user['wechat_code'] && !$user['wechat_account']) {
  316. return self::setErrorInfo('请先设置收款方式!');
  317. }
  318. $money = UserMoney::initialUserMoney($uid, $order['money_type']);
  319. if ($money['money'] < $order['money_num']) return self::setErrorInfo('账户不足!');
  320. BaseModel::beginTrans();
  321. try {
  322. $res = UserMoney::expendMoney($uid, $order['money_type'], $order['money_num'], 'sale', '售币成功', '售币成功,购买方:' . $order['uid']);
  323. if (!$res) {
  324. return self::setErrorInfo(UserMoney::getErrorInfo('支付失败'), true);
  325. }
  326. $res = self::where('id', $id)->update([
  327. 'status' => 0,
  328. 'trade_uid' => $uid,
  329. //'trade_way' => $order['pay_type'],
  330. // 'trade_time' => time(),
  331. ]);
  332. // $userInfo = User::getUserInfo($uid);
  333. // $res = $res && UserMoney::incomeMoney($order['uid'], $order['money_type'], $order['money_num'], 'buy_success', '购币成功', '购币成功,出售方:' . $uid);
  334. // $res = $res && (false !== User::bcInc($userInfo['uid'], 'now_money', $order['all_price'], 'uid'));
  335. // $res = $res && UserBill::income('售币成功', $userInfo['uid'], 'now_money', 'sale_success', $order['all_price'], $order['id'], $userInfo['now_money'] + $order['all_price'], '售币成功,购买方:' . $order['uid']);
  336. if ($res) {
  337. BaseModel::commitTrans();
  338. return $res;
  339. } else {
  340. return self::setErrorInfo('出售失败', true);
  341. }
  342. } catch (Exception $e) {
  343. return self::setErrorInfo($e->getMessage(), true);
  344. }
  345. }
  346. public static function buy($uid, $id)
  347. {
  348. $order = self::setStatus(1)->where('id', $id)->find();
  349. if (!$order) {
  350. return self::setErrorInfo('订单不存在或已结束挂出');
  351. }
  352. BaseModel::beginTrans();
  353. try {
  354. $res = CashTradeOrderPayment::create([
  355. 'uid' => $uid,
  356. 'order_id' => CashTradeOrderPayment::getOrderId(),
  357. 'bind_order' => $id,
  358. 'order_type' => 2,
  359. 'pay_money' => $order['all_price'],
  360. 'add_time' => time()
  361. ]);
  362. if ($res) {
  363. BaseModel::commitTrans();
  364. return $res;
  365. } else {
  366. return self::setErrorInfo('订单生成失败', true);
  367. }
  368. } catch (Exception $e) {
  369. return self::setErrorInfo($e->getMessage(), true);
  370. }
  371. }
  372. public static function buy2($uid, $id)
  373. {
  374. $order = self::setStatus(1)->where('id', $id)->find();
  375. if (!$order) {
  376. return self::setErrorInfo('订单不存在或已结束挂出');
  377. }
  378. $money = UserMoney::initialUserMoney($uid, $order['money_type']);
  379. if ($money['money'] < $order['money_num']) return self::setErrorInfo('账户不足!');
  380. BaseModel::beginTrans();
  381. try {
  382. $res = UserMoney::expendMoney($uid, $order['money_type'], $order['money_num'], 'sale', '售币成功', '售币成功,购买方:' . $order['uid']);
  383. if (!$res) {
  384. return self::setErrorInfo(UserMoney::getErrorInfo('支付失败'), true);
  385. }
  386. $res = self::where('id', $id)->update([
  387. 'status' => -1,
  388. 'trade_uid' => $uid,
  389. // 'trade_time' => time(),
  390. ]);
  391. if ($res) {
  392. BaseModel::commitTrans();
  393. return $res;
  394. } else {
  395. return self::setErrorInfo('申请购买失败', true);
  396. }
  397. } catch (Exception $e) {
  398. return self::setErrorInfo($e->getMessage(), true);
  399. }
  400. }
  401. public static function getBack()
  402. {
  403. $list = self::setStatus(4)->select();
  404. BaseModel::beginTrans();
  405. $res = true;
  406. foreach ($list as $v) {
  407. switch ($v['trade_type']) {
  408. case 1:
  409. //退回币
  410. $res = $res && UserMoney::incomeMoney($v['uid'], $v['money_type'], $v['money_num'], 'hang_sale_send_back', '挂卖退回', '挂卖时间结束,退回钱包');
  411. $res = $res && self::where('id', $v['id'])->update(['status' => 2]);
  412. break;
  413. case 2:
  414. // $userInfo = User::getUserInfo($v['uid']);
  415. // $res = $res && (false !== User::bcInc($v['uid'], 'now_money', $v['all_price'], 'uid'));
  416. // $res = $res && UserBill::income('售币成功', $v['uid'], 'now_money', 'hang_buy_send_back', $v['all_price'], $v['id'], $userInfo['now_money'] + $v['all_price'], '挂买时间结束,退回余额');
  417. // $res = $res && self::where('id', $v['id'])->update(['status' => 2]);
  418. if ($v['trade_uid'])
  419. $res = $res && UserMoney::incomeMoney($v['trade_uid'], $v['money_type'], $v['money_num'], 'hang_buy_send_back', '挂买退回', '挂买时间结束,退回钱包');
  420. $res = $res && self::where('id', $v['id'])->update(['status' => 2]);
  421. break;
  422. default:
  423. break;
  424. }
  425. }
  426. BaseModel::checkTrans($res);
  427. return $res;
  428. }
  429. public static function orderClose()
  430. {
  431. $list = self::setStatus(7)->select();
  432. BaseModel::beginTrans();
  433. $res = true;
  434. foreach ($list as $v) {
  435. switch ($v['trade_type']) {
  436. case 1:
  437. //退回币
  438. // $res = $res && UserMoney::incomeMoney($v['uid'], $v['money_type'], $v['money_num'], 'hang_sale_send_back', '挂卖退回', '挂卖时间结束,退回钱包');
  439. $res = $res && self::where('id', $v['id'])->update(['trade_uid' => null, 'status' => 0, 'close_time' => null]);
  440. break;
  441. case 2:
  442. // $userInfo = User::getUserInfo($v['uid']);
  443. // $res = $res && (false !== User::bcInc($v['uid'], 'now_money', $v['all_price'], 'uid'));
  444. // $res = $res && UserBill::income('售币成功', $v['uid'], 'now_money', 'hang_buy_send_back', $v['all_price'], $v['id'], $userInfo['now_money'] + $v['all_price'], '挂买时间结束,退回余额');
  445. // $res = $res && self::where('id', $v['id'])->update(['status' => 2]);
  446. if ($v['trade_uid'])
  447. $res = $res && UserMoney::incomeMoney($v['trade_uid'], $v['money_type'], $v['money_num'], 'hang_sale_send_back', '挂卖退回', '挂卖时间结束,退回钱包');
  448. $res = $res && self::where('id', $v['id'])->update(['trade_uid' => null, 'status' => -1, 'close_time' => null]);
  449. break;
  450. default:
  451. break;
  452. }
  453. }
  454. BaseModel::checkTrans($res);
  455. return $res;
  456. }
  457. public static function brokerage($id)
  458. {
  459. $info = self::get($id);
  460. if ($info['trade_type'] == 2)
  461. $user = User::getUserInfo($info['uid']);
  462. else
  463. $user = User::getUserInfo($info['trade_uid']);
  464. $uper = User::getUserInfo($user['spread_uid']);
  465. // var_dump($info);
  466. // var_dump($user['uid']);
  467. // var_dump($user['spread_uid']);
  468. // exit;
  469. $send = 0;
  470. $res = true;
  471. while ($uper) {
  472. $ratio = bcdiv($uper['return_uper'], 100, 2);
  473. if ($ratio > 0) {
  474. $brokerage = bcmul($ratio, $info['money_num'], 8);
  475. if ($brokerage > $send) {
  476. $brokerage = bcdiv($brokerage, $send, 8);
  477. $res = $res && UserMoney::incomeMoney($uper['uid'], $info['money_type'], $brokerage, 'return_uper', '佣金', $user['nickname'] . '发生交易,获得佣金');
  478. $send = bcadd($brokerage, $send, 8);
  479. }
  480. }
  481. $uper = User::getUserInfo($uper['spread_uid']);
  482. }
  483. return $res;
  484. }
  485. }