CashTradeOrder.php 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472
  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->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. });
  111. return compact('count', 'list');
  112. }
  113. public static function getOneUserList($where)
  114. {
  115. $model = self::setStatus($where);
  116. $model = $model->where('uid|trade_uid', $where['uid']);
  117. // if (isset($where['trade_type']) && $where['trade_type'] != '') {
  118. // if (isset($where['uid']) && $where['uid']) {
  119. // $model = $model->where(function ($query) use ($where) {
  120. // $query->where('trade_uid', $where['uid'])
  121. // ->where('trade_type', $where['trade_type']);
  122. // })->whereOr(function ($query) use ($where) {
  123. // $query->where('uid', $where['uid'])
  124. // ->where('trade_type', '<>', $where['trade_type']);
  125. // });
  126. // } else {
  127. // $model = $model->where('trade_type', $where['trade_type']);
  128. // }
  129. // }
  130. // if (isset($where['money_type']) && $where['money_type'] != '') {
  131. // $model = $model->where('money_type', $where['money_type']);
  132. // }
  133. // $count = $model->count();
  134. // var_dump(self::getLastSql());
  135. $list = $model->page((int)$where['page'], (int)$where['limit'])->select()
  136. // var_dump(self::getLastSql());
  137. ->each(function ($item) use ($where) {
  138. $money_type = init_money_type();
  139. $item['_user'] = User::getUserInfo($item['uid'])['nickname'] . '/' . $item['uid'];
  140. $item['_trade_user'] = $item['trade_uid'] ? User::getUserInfo($item['trade_uid'])['nickname'] . '/' . $item['trade_uid'] : '--';
  141. $item['_add_time'] = time_format($item['add_time']);
  142. $item['_end_time'] = $item['_end_time'] ? time_format($item['end_time']) : '--';
  143. $item['_trade_time'] = $item['trade_time'] ? time_format($item['trade_time']) : '--';
  144. $item['_money_type'] = $money_type[$item['money_type']];
  145. $item['_trade_type'] = $item['trade_type'] == 2 ? '挂买' : '挂卖';
  146. $item['_proof'] = $item['proof'] ? "<img src='" . $item['proof'] . "'>" : '--';
  147. switch ($item['status']) {
  148. case -1:
  149. $item['_status'] = '未支付';
  150. break;
  151. case 0:
  152. $item['_status'] = '未完成';
  153. break;
  154. case 1:
  155. $item['_status'] = '已完成';
  156. break;
  157. case 2:
  158. $item['_status'] = '已收回';
  159. break;
  160. case 3:
  161. $item['_status'] = '交易中【‘已提交交易凭证’】';
  162. break;
  163. default:
  164. $item['_status'] = '未知';
  165. break;
  166. }
  167. });
  168. return $list;
  169. }
  170. public static function hangSale($uid, $money_type, $money_num, $price, $hang_time)
  171. {
  172. $user = User::getUserInfo($uid);
  173. if (!$user['bank_code'] && !$user['alipay_code'] && !$user['alipay_account'] && !$user['wechat_code'] && !$user['wechat_account']) {
  174. return self::setErrorInfo('请先设置收款方式!');
  175. }
  176. $money = UserMoney::initialUserMoney($uid, $money_type);
  177. if ($money['money'] < $money_num) return self::setErrorInfo('账户不足!');
  178. $sum = bcmul($money_num, $price, 2);
  179. BaseModel::beginTrans();
  180. try {
  181. $res = UserMoney::expendMoney($uid, $money_type, $money_num, 'hang_sale', '挂卖', '挂卖' . $money_num);
  182. if (!$res) {
  183. return self::setErrorInfo(UserMoney::getErrorInfo('支付失败'), true);
  184. }
  185. $res = self::create([
  186. 'order_id' => self::getOrderId(),
  187. 'uid' => $uid,
  188. 'money_type' => $money_type,
  189. 'money_num' => $money_num,
  190. 'price' => $price,
  191. 'all_price' => $sum,
  192. 'trade_type' => 1,
  193. 'add_time' => time(),
  194. 'hang_time' => $hang_time,
  195. 'end_time' => bcadd(time(), bcmul($hang_time, 3600)),
  196. ]);
  197. if ($res) {
  198. BaseModel::commitTrans();
  199. return $res;
  200. } else {
  201. return self::setErrorInfo('挂卖失败', true);
  202. }
  203. } catch (Exception $e) {
  204. return self::setErrorInfo($e->getMessage(), true);
  205. }
  206. }
  207. public static function hangBuy2($uid, $money_type, $money_num, $price, $hang_time)
  208. {
  209. $sum = bcmul($money_num, $price, 2);
  210. BaseModel::beginTrans();
  211. try {
  212. // $res = UserMoney::expendMoney($uid, $money_type, $money_num, 'hang_sale', '挂卖', '挂卖' . $money_num);
  213. // if (!$res) {
  214. // return self::setErrorInfo(UserMoney::getErrorInfo('支付失败'), true);
  215. // }
  216. $res = self::create([
  217. 'order_id' => self::getOrderId(),
  218. 'uid' => $uid,
  219. 'money_type' => $money_type,
  220. 'money_num' => $money_num,
  221. 'price' => $price,
  222. 'all_price' => $sum,
  223. 'trade_type' => 2,
  224. 'add_time' => time(),
  225. 'hang_time' => $hang_time,
  226. 'status' => -1,//未支付虚拟货币
  227. 'end_time' => bcadd(time(), bcmul($hang_time, 3600)),
  228. ]);
  229. if ($res) {
  230. BaseModel::commitTrans();
  231. return $res;
  232. } else {
  233. return self::setErrorInfo('挂买失败', true);
  234. }
  235. } catch (Exception $e) {
  236. return self::setErrorInfo($e->getMessage(), true);
  237. }
  238. }
  239. public static function hangBuy($uid, $money_type, $money_num, $price, $hang_time)
  240. {
  241. $sum = bcmul($money_num, $price, 2);
  242. BaseModel::beginTrans();
  243. try {
  244. $res = CashTradeOrderPayment::create([
  245. 'uid' => $uid,
  246. 'order_id' => CashTradeOrderPayment::getOrderId(),
  247. 'order_type' => 1,
  248. 'pay_money' => $sum,
  249. 'add_time' => time(),
  250. 'order_info' => json_encode([
  251. 'uid' => $uid,
  252. 'money_type' => $money_type,
  253. 'money_num' => $money_num,
  254. 'price' => $price,
  255. 'all_price' => $sum,
  256. 'trade_type' => 2,
  257. 'hang_time' => $hang_time,]),
  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 getOrderId()
  270. {
  271. list($msec, $sec) = explode(' ', microtime());
  272. $msectime = number_format((floatval($msec) + floatval($sec)) * 1000, 0, '', '');
  273. do {
  274. $str = 'ct' . $msectime . mt_rand(10000, 99999);
  275. } while (self::be(['order_id' => $str]));
  276. return $str;
  277. }
  278. public static function sale($uid, $id)
  279. {
  280. $order = self::setStatus(1)->where('id', $id)->find();
  281. if (!$order) {
  282. return self::setErrorInfo('订单不存在或已结束挂出');
  283. }
  284. $user = User::getUserInfo($uid);
  285. if (!$user['bank_code'] && !$user['alipay_code'] && !$user['alipay_account'] && !$user['wechat_code'] && !$user['wechat_account']) {
  286. return self::setErrorInfo('请先设置收款方式!');
  287. }
  288. $money = UserMoney::initialUserMoney($uid, $order['money_type']);
  289. if ($money['money'] < $order['money_num']) return self::setErrorInfo('账户不足!');
  290. BaseModel::beginTrans();
  291. try {
  292. $res = UserMoney::expendMoney($uid, $order['money_type'], $order['money_num'], 'sale', '售币成功', '售币成功,购买方:' . $order['uid']);
  293. if (!$res) {
  294. return self::setErrorInfo(UserMoney::getErrorInfo('支付失败'), true);
  295. }
  296. $res = self::where('id', $id)->update([
  297. 'status' => 0,
  298. 'trade_uid' => $uid,
  299. //'trade_way' => $order['pay_type'],
  300. // 'trade_time' => time(),
  301. ]);
  302. // $userInfo = User::getUserInfo($uid);
  303. // $res = $res && UserMoney::incomeMoney($order['uid'], $order['money_type'], $order['money_num'], 'buy_success', '购币成功', '购币成功,出售方:' . $uid);
  304. // $res = $res && (false !== User::bcInc($userInfo['uid'], 'now_money', $order['all_price'], 'uid'));
  305. // $res = $res && UserBill::income('售币成功', $userInfo['uid'], 'now_money', 'sale_success', $order['all_price'], $order['id'], $userInfo['now_money'] + $order['all_price'], '售币成功,购买方:' . $order['uid']);
  306. if ($res) {
  307. BaseModel::commitTrans();
  308. return $res;
  309. } else {
  310. return self::setErrorInfo('出售失败', true);
  311. }
  312. } catch (Exception $e) {
  313. return self::setErrorInfo($e->getMessage(), true);
  314. }
  315. }
  316. public static function buy($uid, $id)
  317. {
  318. $order = self::setStatus(1)->where('id', $id)->find();
  319. if (!$order) {
  320. return self::setErrorInfo('订单不存在或已结束挂出');
  321. }
  322. BaseModel::beginTrans();
  323. try {
  324. $res = CashTradeOrderPayment::create([
  325. 'uid' => $uid,
  326. 'order_id' => CashTradeOrderPayment::getOrderId(),
  327. 'bind_order' => $id,
  328. 'order_type' => 2,
  329. 'pay_money' => $order['all_price'],
  330. 'add_time' => time()
  331. ]);
  332. if ($res) {
  333. BaseModel::commitTrans();
  334. return $res;
  335. } else {
  336. return self::setErrorInfo('订单生成失败', true);
  337. }
  338. } catch (Exception $e) {
  339. return self::setErrorInfo($e->getMessage(), true);
  340. }
  341. }
  342. public static function buy2($uid, $id)
  343. {
  344. $order = self::setStatus(1)->where('id', $id)->find();
  345. if (!$order) {
  346. return self::setErrorInfo('订单不存在或已结束挂出');
  347. }
  348. $money = UserMoney::initialUserMoney($uid, $order['money_type']);
  349. if ($money['money'] < $order['money_num']) return self::setErrorInfo('账户不足!');
  350. BaseModel::beginTrans();
  351. try {
  352. $res = UserMoney::expendMoney($uid, $order['money_type'], $order['money_num'], 'sale', '售币成功', '售币成功,购买方:' . $order['uid']);
  353. if (!$res) {
  354. return self::setErrorInfo(UserMoney::getErrorInfo('支付失败'), true);
  355. }
  356. $res = self::where('id', $id)->update([
  357. 'status' => -1,
  358. 'trade_uid' => $uid,
  359. // 'trade_time' => time(),
  360. ]);
  361. if ($res) {
  362. BaseModel::commitTrans();
  363. return $res;
  364. } else {
  365. return self::setErrorInfo('申请购买失败', true);
  366. }
  367. } catch (Exception $e) {
  368. return self::setErrorInfo($e->getMessage(), true);
  369. }
  370. }
  371. public static function getBack()
  372. {
  373. $list = self::setStatus(4)->select();
  374. BaseModel::beginTrans();
  375. $res = true;
  376. foreach ($list as $v) {
  377. switch ($v['trade_type']) {
  378. case 1:
  379. //退回币
  380. $res = $res && UserMoney::incomeMoney($v['uid'], $v['money_type'], $v['money_num'], 'hang_sale_send_back', '挂卖退回', '挂卖时间结束,退回钱包');
  381. $res = $res && self::where('id', $v['id'])->update(['status' => 2]);
  382. break;
  383. case 2:
  384. // $userInfo = User::getUserInfo($v['uid']);
  385. // $res = $res && (false !== User::bcInc($v['uid'], 'now_money', $v['all_price'], 'uid'));
  386. // $res = $res && UserBill::income('售币成功', $v['uid'], 'now_money', 'hang_buy_send_back', $v['all_price'], $v['id'], $userInfo['now_money'] + $v['all_price'], '挂买时间结束,退回余额');
  387. // $res = $res && self::where('id', $v['id'])->update(['status' => 2]);
  388. if ($v['trade_uid'])
  389. $res = $res && UserMoney::incomeMoney($v['trade_uid'], $v['money_type'], $v['money_num'], 'hang_buy_send_back', '挂买退回', '挂买时间结束,退回钱包');
  390. $res = $res && self::where('id', $v['id'])->update(['status' => 2]);
  391. break;
  392. default:
  393. break;
  394. }
  395. }
  396. BaseModel::checkTrans($res);
  397. return $res;
  398. }
  399. public static function orderClose()
  400. {
  401. $list = self::setStatus(7)->select();
  402. BaseModel::beginTrans();
  403. $res = true;
  404. foreach ($list as $v) {
  405. switch ($v['trade_type']) {
  406. case 1:
  407. //退回币
  408. // $res = $res && UserMoney::incomeMoney($v['uid'], $v['money_type'], $v['money_num'], 'hang_sale_send_back', '挂卖退回', '挂卖时间结束,退回钱包');
  409. $res = $res && self::where('id', $v['id'])->update(['trade_uid' => null, 'status' => 0, 'close_time' => null]);
  410. break;
  411. case 2:
  412. // $userInfo = User::getUserInfo($v['uid']);
  413. // $res = $res && (false !== User::bcInc($v['uid'], 'now_money', $v['all_price'], 'uid'));
  414. // $res = $res && UserBill::income('售币成功', $v['uid'], 'now_money', 'hang_buy_send_back', $v['all_price'], $v['id'], $userInfo['now_money'] + $v['all_price'], '挂买时间结束,退回余额');
  415. // $res = $res && self::where('id', $v['id'])->update(['status' => 2]);
  416. if ($v['trade_uid'])
  417. $res = $res && UserMoney::incomeMoney($v['trade_uid'], $v['money_type'], $v['money_num'], 'hang_sale_send_back', '挂卖退回', '挂卖时间结束,退回钱包');
  418. $res = $res && self::where('id', $v['id'])->update(['trade_uid' => null, 'status' => -1, 'close_time' => null]);
  419. break;
  420. default:
  421. break;
  422. }
  423. }
  424. BaseModel::checkTrans($res);
  425. return $res;
  426. }
  427. public static function brokerage($id)
  428. {
  429. $info = self::get($id);
  430. $user = User::getUserInfo($info['uid']);
  431. $uper = User::getUserInfo($user['spread_uid']);
  432. $send = 0;
  433. $res = true;
  434. while ($uper) {
  435. $ratio = bcdiv($uper['return_uper'], 100, 2);
  436. if ($ratio > 0) {
  437. $brokerage = bcmul($ratio, $info['money_num'], 8);
  438. if ($brokerage > $send) {
  439. $brokerage = bcdiv($brokerage, $send, 8);
  440. $res = $res && UserMoney::incomeMoney($uper['uid'], $info['money_type'], $brokerage, 'return_uper', '佣金', $user['nickname'] . '发生交易,获得佣金');
  441. $send = bcadd($brokerage, $send, 8);
  442. }
  443. }
  444. $uper = User::getUserInfo($uper['spread_uid']);
  445. }
  446. return $res;
  447. }
  448. }