whereTime('end_time', '>', date('Y-m-d H:i:s')); $totalQuery = $totalQuery->whereTime('end_time', '>', date('Y-m-d H:i:s')); break; case '2': $query = $query->whereTime('end_time', '<', date('Y-m-d H:i:s'))->where('sign_status', '=', PreHkdStockModel::SIGN_STATUS_NO); $totalQuery = $totalQuery->whereTime('end_time', '<', date('Y-m-d H:i:s'))->where('sign_status', '=', PreHkdStockModel::SIGN_STATUS_NO); break; case '3': $query = $query->where('sign_status', '=', PreHkdStockModel::SIGN_STATUS_DONE)->where('open_status', PreHkdStockModel::OPEN_STATUS_NO); $totalQuery = $totalQuery->where('sign_status', '=', PreHkdStockModel::SIGN_STATUS_DONE)->where('open_status', PreHkdStockModel::OPEN_STATUS_NO); break; case '4': $query = $query->where('open_status', PreHkdStockModel::OPEN_STATUS_HAD); $totalQuery = $totalQuery->where('open_status', PreHkdStockModel::OPEN_STATUS_HAD); break; } } $list = $query->page($param['page'], $param['limit'])->select(); $total = $totalQuery->count(); $rows = []; if (!$list->isEmpty()) { foreach ($list as $item) { // 是否延期开盘 $is_defer = '0'; if ($item->open_time < date('Y-m-d H:i:s') && $item->open_status == PreHkdStockModel::OPEN_STATUS_NO) { $is_defer = '1'; } $is_start = '0'; if ($item->start_time <= date('Y-m-d H:i:s') && $item->end_time >= date('Y-m-d H:i:s')) { $is_start = '1'; } $progressStatus = 1; if (time() >= $item->end_time) $progressStatus = 2; if ($item->sign_status == PreHkdStockModel::SIGN_STATUS_DONE) $progressStatus = 3; if ($item->is_post_pay == PreHkdStockModel::IS_POST_PAY_YES && $item->pay_deadline_time < date('Y-m-d H:i:s')) $progressStatus = 4; if ($item->open_status == PreHkdStockModel::OPEN_STATUS_HAD) $progressStatus = $item->is_post_pay == PreHkdStockModel::IS_POST_PAY_YES ? 5 : 4; $rows[] = [ 'id' => $item->id, 'stock_code' => $item->stock_code, 'stock_name' => $item->stock_name, 'stock_type' => $item->stock_type, 'price' => $item->price, 'min' => $item->min, 'total' => $item->total, 'tape' => $item->tape, 'start_time' => $item->start_time, 'end_time' => $item->end_time, 'get_time' => $item->get_time, 'open_time' => $item->open_time, 'rate' => $item->rate, 'is_defer' => $is_defer, 'is_start' => $is_start, 'is_post_pay' => $item->is_post_pay, 'logo' => $item->logo, 'company_info' => $item->company_info, 'company_open_time' => $item->company_open_time, 'company_reg_amount' => $item->company_reg_amount, 'pay_deadline_time' => $item->pay_deadline_time, 'progress_status' => $progressStatus, ]; } } return $this->toData('0', 'SUCCESS', ['list' => $rows, 'total' => $total, 'extend' => [ 'tape_list' => StockHkdListModel::$tapeList, 'stock_type_list' => PreHkdStockModel::$stockTypeList, ]]); } catch (\Exception $exception) { return $this->toData('1', 'System error', []); } } // 股票详情 public function stockDetail($param) { try { if (empty($param['id']) || !is_numeric($param['id'])) { return $this->toData('1', 'Params error', []); } $preStock = PreHkdStockModel::where('id', $param['id'])->where('is_delete', PreHkdStockModel::IS_DELETE_NO)->where('status', PreHkdStockModel::STATUS_ON)->find(); if (empty($preStock)) { return $this->toData('1', 'Params error', []); } $is_defer = '0'; if ($preStock->open_time < date('Y-m-d H:i:s') && $preStock->open_status == PreHkdStockModel::OPEN_STATUS_NO) { $is_defer = '1'; } $is_start = '0'; if ($preStock->start_time <= date('Y-m-d H:i:s') && $preStock->end_time >= date('Y-m-d H:i:s')) { $is_start = '1'; } $progressStatus = 1; if (time() >= $preStock->end_time) $progressStatus = 2; if ($preStock->sign_status == PreHkdStockModel::SIGN_STATUS_DONE) $progressStatus = 3; if ($preStock->is_post_pay == PreHkdStockModel::IS_POST_PAY_YES && $preStock->pay_deadline_time < date('Y-m-d H:i:s')) $progressStatus = 4; if ($preStock->open_status == PreHkdStockModel::OPEN_STATUS_HAD) $progressStatus = $preStock->is_post_pay == PreHkdStockModel::IS_POST_PAY_YES ? 5 : 4; $data = [ 'id' => $preStock->id, 'stock_code' => $preStock->stock_code, 'stock_name' => $preStock->stock_name, 'stock_type' => $preStock->stock_type, 'price' => $preStock->price, 'min' => $preStock->min, 'total' => $preStock->total, 'tape' => $preStock->tape, 'start_time' => $preStock->start_time, 'end_time' => $preStock->end_time, 'get_time' => $preStock->get_time, 'open_time' => $preStock->open_time, 'rate' => $preStock->rate, 'is_defer' => $is_defer, 'is_start' => $is_start, 'is_post_pay' => $preStock->is_post_pay, 'logo' => $preStock->logo, 'company_info' => $preStock->company_info, 'company_open_time' => $preStock->company_open_time, 'company_reg_amount' => $preStock->company_reg_amount, 'pay_deadline_time' => $preStock->pay_deadline_time, 'progress_status' => $progressStatus, ]; return $this->toData('0', 'SUCCESS', ['data' => $data, 'extend' => [ 'tape_list' => StockHkdListModel::$tapeList, 'stock_type_list' => PreHkdStockModel::$stockTypeList, ]]); } catch (\Exception $exception) { return $this->toData('1', 'System error', []); } } // 申购操作 public function order($param, $userId) { try { if (empty($param['id']) || !is_numeric($param['id'])) { return $this->toData('1', 'Params error', []); } $preHkdStock = PreHkdStockModel::where('id', $param['id']) ->where('status', PreHkdStockModel::STATUS_ON) ->where('is_delete', PreHkdStockModel::IS_DELETE_NO) ->whereTime('start_time', '<=', date('Y-m-d H:i:s')) ->whereTime('end_time', '>=', date('Y-m-d H:i:s')) ->find(); if (empty($preHkdStock)) { return $this->toData('1', 'Params error', []); } $hasOrder = UserHkdPreStockOrderModel::where('user_id', $userId)->where('pre_stock_id', $param['id'])->count(); if ($preHkdStock->limit_get_num <= $hasOrder) { return $this->toData('1', 'Had Purchased', []); } // 下单参数 if (empty($param['num']) || !is_numeric($param['num']) || ceil($param['num']) != $param['num'] || $param['num'] <= 0) { return $this->toData('1', 'Params error', []); } if ($param['num'] < $preHkdStock->min) { return $this->toData('1', 'Order quantity less than the minimum', []); } if ($preHkdStock->max > 0 && $param['num'] > $preHkdStock->max) { return $this->toData('1', 'Order quantity greater than maximum', []); } if ($preHkdStock->price <= 0) { return $this->toData('1', 'Price error', []); } // 支付类型 if (empty($param['pay_type']) || !is_numeric($param['pay_type']) || !in_array($param['pay_type'], [UserHkdPreStockOrderModel::PAY_TYPE_ONE, UserHkdPreStockOrderModel::PAY_TYPE_TWO])) { return $this->toData('1', 'Params error', []); } // 计算金额 $amount = bcmul($param['num'], $preHkdStock->price, 18); // 计算手续费 $purchaseFee = FeeSettingModel::where('market_type', StockMarketModel::STOCK_MARKET_HK)->value('purchase_fee'); if ($purchaseFee <= 0) { $fee = 0; } else { $fee = bcmul($amount, $purchaseFee, 18); } Db::startTrans(); // 生成订单 $orderNo = $this->generateOrderNumber(20); $order = new UserHkdPreStockOrderModel; $order->user_id = $userId; $order->pre_stock_id = $preHkdStock->id; $order->status = $param['pay_type'] == 1 ? UserHkdPreStockOrderModel::STATUS_DOING : UserHkdPreStockOrderModel::STATUS_POST_PAY; $order->pay_type = $param['pay_type']; $order->order_no = $orderNo; $order->num = $param['num']; $order->get_num = 0; $order->price = $preHkdStock->price; $order->amount = $amount; $order->get_amount = 0; $order->fee = $fee; $order->get_fee = 0; $order->fee_rate = $purchaseFee; $order->get_time = $preHkdStock->get_time; $bool = $order->save(); if (!$bool) { Db::rollback(); return $this->toData('1', 'create order error', []); } if ($param['pay_type'] == 2) { Db::commit(); return $this->toData('0', 'SUCCESS', []); } // 扣除用户资产 $beforeAmount = UserStockHkdModel::where('stock_id', 'HKD')->where('user_id', $userId)->value('usable_num'); if ($beforeAmount < $amount) { Db::rollback(); return $this->toData('1', 'assert not enough', []); } $updateNum = UserStockHkdModel::where('stock_id', 'HKD')->where('user_id', $userId) ->where('usable_num', '>=', $amount)->dec('usable_num', $amount) ->inc('frozen_num', $amount) ->update(['update_time' => date('Y-m-d H:i:s')]); if ($updateNum <= 0) { Db::rollback(); return $this->toData('1', 'Update user amount error', []); } // 生成流水 $userStockLog = new UserStockHkdLogModel(); $userStockLog->user_id = $userId; $userStockLog->change_type = 15; // 新股申购扣减费用 $userStockLog->stock_id = 'HKD'; $userStockLog->before_num = $beforeAmount; $userStockLog->change_num = '-' . $amount; $userStockLog->order_id = $orderNo; $userStockLog->create_time = date('Y-m-d H:i:s'); $userStockLog->update_time = date('Y-m-d H:i:s'); $updateNum2 = $userStockLog->save(); if ($updateNum2 <= 0) { Db::rollback(); return $this->toData('1', 'create user log error', []); } // 扣除手续费 if ($fee > 0) { $beforeFee = UserStockHkdModel::where('stock_id', 'HKD')->where('user_id', $userId)->value('usable_num'); if ($beforeFee < $fee) { Db::rollback(); return $this->toData('1', 'assert not enough', []); } $updateNum = UserStockHkdModel::where('stock_id', 'HKD')->where('user_id', $userId) ->where('usable_num', '>=', $fee)->dec('usable_num', $fee) ->inc('frozen_num', $fee) ->update(['update_time' => date('Y-m-d H:i:s')]); if ($updateNum <= 0) { Db::rollback(); return $this->toData('1', 'Update user amount error', []); } // 生成流水 $userStockLog = new UserStockHkdLogModel; $userStockLog->user_id = $userId; $userStockLog->change_type = 16; $userStockLog->stock_id = 'HKD'; $userStockLog->before_num = $beforeFee; $userStockLog->change_num = '-' . $fee; $userStockLog->order_id = $orderNo; $userStockLog->create_time = date('Y-m-d H:i:s'); $userStockLog->update_time = date('Y-m-d H:i:s'); $updateNum3 = $userStockLog->save(); if ($updateNum3 <= 0) { Db::rollback(); return $this->toData('1', 'create user fee log error', []); } } Db::commit(); return $this->toData('0', 'SUCCESS', [ ]); } catch (\Exception $exception) { Db::rollback(); return $this->toData('1', 'System error', []); } } // 后支付 - 支付 public function postPay($param, $userId) { try { if (empty($param['id']) || empty($param['stock_code']) || !is_numeric($param['id'])) { return $this->toData('1', 'Params error2', []); } $now = date('Y-m-d H:i:s'); $preHkdStock = PreHkdStockModel::where('stock_code', $param['stock_code']) ->where('status', PreHkdStockModel::STATUS_ON) ->where('is_delete', PreHkdStockModel::IS_DELETE_NO) ->where('is_post_pay', PreHkdStockModel::IS_POST_PAY_YES) ->whereTime('pay_deadline_time', '>=', $now) ->find(); if (empty($preHkdStock)) { return $this->toData('1', 'Payment deadline exceeded', []); } $hasOrder = UserHkdPreStockOrderModel::where('user_id', $userId)->where('id', $param['id'])->where('pay_type', UserHkdPreStockOrderModel::PAY_TYPE_TWO)->where('status', UserHkdPreStockOrderModel::STATUS_POST_PAY)->find(); if (empty($hasOrder)) { return $this->toData('1', 'Params error3', []); } $orderNo = $hasOrder->order_no; Db::startTrans(); if ($preHkdStock->sign_status == PreHkdStockModel::SIGN_STATUS_DONE && strtotime($preHkdStock->get_time) < strtotime($now)) { //已签名 $amount = $hasOrder->get_amount; $fee = $hasOrder->get_fee; $getNum = $hasOrder->get_num; if ($getNum <= 0) { Db::rollback(); return $this->toData('1', 'get num error', []); } // 扣除用户资产 $beforeAmount = UserStockHkdModel::where('stock_id', 'HKD')->where('user_id', $userId)->value('usable_num'); if ($beforeAmount < $amount) { Db::rollback(); return $this->toData('1', 'assert not enough', []); } $updateNum = UserStockHkdModel::where('stock_id', 'HKD')->where('user_id', $userId) ->where('usable_num', '>=', $amount)->dec('usable_num', $amount) ->inc('frozen_num', $amount) ->update(['update_time' => $now]); if ($updateNum <= 0) { Db::rollback(); return $this->toData('1', 'Update user amount error', []); } // 生成流水 $userStockLog = new UserStockHkdLogModel(); $userStockLog->user_id = $userId; $userStockLog->change_type = 15; // 新股申购扣减费用 $userStockLog->stock_id = 'HKD'; $userStockLog->before_num = $beforeAmount; $userStockLog->change_num = '-' . $amount; $userStockLog->order_id = $orderNo; $userStockLog->create_time = $now; $userStockLog->update_time = $now; $updateNum2 = $userStockLog->save(); if ($updateNum2 <= 0) { Db::rollback(); return $this->toData('1', 'create user log error', []); } // 扣除手续费 if ($fee > 0) { $beforeFee = UserStockHkdModel::where('stock_id', 'HKD')->where('user_id', $userId)->value('usable_num'); if ($beforeFee < $fee) { Db::rollback(); return $this->toData('1', 'assert not enough', []); } $updateNum = UserStockHkdModel::where('stock_id', 'HKD')->where('user_id', $userId) ->where('usable_num', '>=', $fee)->dec('usable_num', $fee) ->inc('frozen_num', $fee) ->update(['update_time' => date('Y-m-d H:i:s')]); if ($updateNum <= 0) { Db::rollback(); return $this->toData('1', 'Update user amount error', []); } // 生成流水 $userStockLog = new UserStockHkdLogModel; $userStockLog->user_id = $userId; $userStockLog->change_type = 16; $userStockLog->stock_id = 'HKD'; $userStockLog->before_num = $beforeFee; $userStockLog->change_num = '-' . $fee; $userStockLog->order_id = $orderNo; $userStockLog->create_time = $now; $userStockLog->update_time = $now; $updateNum3 = $userStockLog->save(); if ($updateNum3 <= 0) { Db::rollback(); return $this->toData('1', 'create user fee log error', []); } } $bool = UserHkdPreStockOrderModel::where('id', $param['id'])->update(['status' => UserHkdPreStockOrderModel::STATUS_SIGNING, 'update_time' => $now]); if (!$bool) { Db::rollback(); return $this->toData('1', 'update order error', []); } } elseif ($preHkdStock->sign_status == PreHkdStockModel::SIGN_STATUS_NO && strtotime($preHkdStock->get_time) >= strtotime($now)) { //未签名 $amount = $hasOrder->amount; $fee = $hasOrder->fee; // 扣除用户资产 $beforeAmount = UserStockHkdModel::where('stock_id', 'HKD')->where('user_id', $userId)->value('usable_num'); if ($beforeAmount < $amount) { Db::rollback(); return $this->toData('1', 'assert not enough', []); } $updateNum = UserStockHkdModel::where('stock_id', 'HKD')->where('user_id', $userId) ->where('usable_num', '>=', $amount)->dec('usable_num', $amount) ->inc('frozen_num', $amount) ->update(['update_time' => $now]); if ($updateNum <= 0) { Db::rollback(); return $this->toData('1', 'Update user amount error', []); } // 生成流水 $userStockLog = new UserStockHkdLogModel(); $userStockLog->user_id = $userId; $userStockLog->change_type = 15; // 新股申购扣减费用 $userStockLog->stock_id = 'HKD'; $userStockLog->before_num = $beforeAmount; $userStockLog->change_num = '-' . $amount; $userStockLog->order_id = $orderNo; $userStockLog->create_time = $now; $userStockLog->update_time = $now; $updateNum2 = $userStockLog->save(); if ($updateNum2 <= 0) { Db::rollback(); return $this->toData('1', 'create user log error', []); } // 扣除手续费 if ($fee > 0) { $beforeFee = UserStockHkdModel::where('stock_id', 'HKD')->where('user_id', $userId)->value('usable_num'); if ($beforeFee < $fee) { Db::rollback(); return $this->toData('1', 'assert not enough', []); } $updateNum = UserStockHkdModel::where('stock_id', 'HKD')->where('user_id', $userId) ->where('usable_num', '>=', $fee)->dec('usable_num', $fee) ->inc('frozen_num', $fee) ->update(['update_time' => date('Y-m-d H:i:s')]); if ($updateNum <= 0) { Db::rollback(); return $this->toData('1', 'Update user amount error', []); } // 生成流水 $userStockLog = new UserStockHkdLogModel; $userStockLog->user_id = $userId; $userStockLog->change_type = 16; $userStockLog->stock_id = 'HKD'; $userStockLog->before_num = $beforeFee; $userStockLog->change_num = '-' . $fee; $userStockLog->order_id = $orderNo; $userStockLog->create_time = $now; $userStockLog->update_time = $now; $updateNum3 = $userStockLog->save(); if ($updateNum3 <= 0) { Db::rollback(); return $this->toData('1', 'create user fee log error', []); } } $bool = UserHkdPreStockOrderModel::where('id', $param['id'])->update(['status' => UserHkdPreStockOrderModel::STATUS_DOING, 'update_time' => $now]); if (!$bool) { Db::rollback(); return $this->toData('1', 'update order error', []); } } else { Db::rollback(); return $this->toData('1', 'Params error4', []); } Db::commit(); return $this->toData('0', 'SUCCESS', []); } catch (\Exception $exception) { Db::rollback(); return $this->toData('1', 'System error', [$exception->getMessage()]); } } // 申购记录 public function list($param, $userId) { try { if (empty($param['page']) || !is_numeric($param['page']) || empty($param['limit']) || !is_numeric($param['limit'])) { $param['page'] = 1; $param['limit'] = 20; } if (empty($param['status'])) { return $this->toData('1', 'Params error'); } $statusArr = explode(",", $param['status']); $list = UserHkdPreStockOrderModel::whereIn('status', $statusArr)->where('user_id', $userId)->order('update_time', 'desc')->page($param['page'], $param['limit'])->select(); $total = UserHkdPreStockOrderModel::whereIn('status',$statusArr)->where('user_id', $userId)->count(); $rows = []; if (!$list->isEmpty()) { $stockIdList = []; foreach ($list as $item) { $stockIdList[] = $item->pre_stock_id; } $stockList = PreHkdStockModel::where('id', 'in', $stockIdList)->column(['*'], 'id'); $purchaseFee = FeeSettingModel::where('market_type', StockMarketModel::STOCK_MARKET_HK)->value('purchase_fee'); foreach ($list as $item) { $stock = $stockList[$item->pre_stock_id] ?? []; $openTime = $stock['open_time'] ?? ''; $openStatus = $stock['open_status'] ?? '0'; // 是否延期开盘 $is_defer = '0'; if ($openTime && $openTime < date('Y-m-d H:i:s') && $openStatus == PreHkdStockModel::OPEN_STATUS_NO) { $is_defer = '1'; } $arr = [ 'id' => $item->id, 'order_no' => $item->order_no, 'stock_code' => $stock['stock_code'] ?? '-', 'stock_name' => $stock['stock_name'] ?? '-', 'get_time' => $stock['get_time'] ?? '-', 'open_time' => $stock['open_time'] ?? '-', 'num' => $item->num, 'get_num' => $item->get_num, 'price' => $item->price, 'amount' => $item->amount, 'get_amount' => $item->get_amount, 'create_time' => $item->create_time, 'fee' => $item->fee, 'get_fee' => $item->get_fee, 'status' => $item->status, 'tape' => $stock['tape'] ?? '-', 'stock_type' => $stock['stock_type'] ?? '-', 'is_defer' => $is_defer, 'stock_data' => $stock, 'pay_deadline_time' => $stock['pay_deadline_time'] ?? '-', ]; if ($item->pay_type == UserHkdPreStockOrderModel::PAY_TYPE_TWO && $item->status == UserHkdPreStockOrderModel::STATUS_POST_PAY && empty($item->get_time)) { $arr['amount'] = bcmul($item->get_num, $item->price, 18); if ($purchaseFee <= 0) { $arr['fee'] = 0; } else { $arr['fee'] = bcmul($arr['amount'], $purchaseFee, 18); } } $rows[] = $arr; } } return $this->toData('0', 'SUCCESS', ['list' => $rows, 'total' => $total, 'extend' => [ 'tape_list' => StockHkdListModel::$tapeList, 'stock_type_list' => PreHkdStockModel::$stockTypeList, ]]); } catch (\Exception $exception) { return $this->toData('1', 'System error', []); } } // 申购订单详情 public function detail($param, $userId) { try { if (empty($param['id']) || !is_numeric($param['id'])) { return $this->toData('1', 'Params error', []); } $order = UserHkdPreStockOrderModel::where('user_id', $userId)->where('id', $param['id'])->find(); if (empty($order)) { return $this->toData('1', 'Params error', []); } $stock = PreHkdStockModel::where('id', $order->pre_stock_id)->find(); if (empty($stock)) { return $this->toData('1', 'Params error', []); } $is_defer = '0'; if ($stock->open_time < date('Y-m-d H:i:s') && $stock->open_status == PreHkdStockModel::OPEN_STATUS_NO) { $is_defer = '1'; } $data = [ 'logo' => $stock->logo, 'stock_code' => $stock->stock_code, 'stock_name' => $stock->stock_name, 'stock_type' => $stock->stock_type, 'num' => $order->num, 'get_num' => $order->get_num, 'amount' => $order->amount, 'get_amount' => $order->get_amount, 'price' => $order->price, 'fee' => $order->fee, 'order_no' => $order->order_no, 'get_fee' => $order->get_fee, 'create_time' => $order->create_time, 'get_time' => $order->get_time, 'open_time' => $stock->open_time, 'tape' => $stock->tape, 'is_defer' => $is_defer, 'stock_data' => $stock, 'pay_deadline_time' => $stock->pay_deadline_time, 'status' => $order->status ]; return $this->toData('0', 'SUCCESS', ['data' => $data, 'extend' => [ 'tape_list' => StockHkdListModel::$tapeList, 'stock_type_list' => PreHkdStockModel::$stockTypeList, ]]); } catch (\Exception $exception) { return $this->toData('1', 'System error', []); } } }