Browse Source

恢复于测试环境

master
chuan 2 months ago
parent
commit
bbad7e717e
  1. 2
      app/admin/controller/Test.php
  2. 2
      app/admin/controller/Upload.php
  3. 9
      app/admin/route/app.php
  4. 12
      app/admin/service/AdminService.php
  5. 13
      app/admin/service/AgentService.php
  6. 3
      app/admin/service/RechargeService.php
  7. 15
      app/home/controller/News.php
  8. 13
      app/home/controller/User.php
  9. 8
      app/home/controller/Video.php
  10. 9
      app/home/route/app.php
  11. 1605
      app/home/service/Copy of Copy of UserService.php
  12. 1605
      app/home/service/Copy of UserService.php
  13. 665
      app/home/service/PreHkdStockService.php
  14. 675
      app/home/service/PreIdnStockService.php
  15. 670
      app/home/service/PreInStockService.php
  16. 672
      app/home/service/PreMysStockService.php
  17. 670
      app/home/service/PreSgdStockService.php
  18. 672
      app/home/service/PreThaStockService.php
  19. 681
      app/home/service/PreUsStockService.php
  20. 121
      app/home/service/UserService.php
  21. 17
      app/home/service/VideoService.php
  22. 4
      app/home/validate/UserValidate.php
  23. 79
      app/model/ForexListMode.php
  24. 7
      app/model/PurchaseVipModel.php
  25. 726
      composer.lock
  26. 8
      config/common.php

2
app/admin/controller/Test.php

@ -8,6 +8,6 @@ class Test extends AdminBaseController
{
public function index()
{
return json(['code' => '0', 'msg' => 'SUCCESS', 'data' => [$fileName]]);
return json(['code' => '0', 'msg' => 'SUCCESS', 'data' => ['time'=>date("Y-m-d H:i:s")]]);
}
}

2
app/admin/controller/Upload.php

@ -70,6 +70,8 @@ class Upload extends AdminBaseController
'Bucket' => $s3Config['aws_bucket'],
'Key' => 'bourse-video-node/' . $fileName, // s3中的存储路径
'Body' => fopen($file->getRealPath(), 'r'),
'ContentType' => $file->getOriginalMime(), // 设置文件的MIME, 不然s3会以流式存储
'ACL' => 'public-read', // 设置文件为公开可读
]);
// 记录上传的文件

9
app/admin/route/app.php

@ -11,7 +11,8 @@ $header = [
// 需要登陆的接口 使用中间件校验 请求路径 XwkjlLbDcG/test
Route::get('/test', 'Test/index');
//Route::get('/test', 'Test/index');
Route::post('/test', 'Test/index');
Route::post('/test_upload', 'Upload/uploadVideo');
Route::group('/', function () {
// 上传图片
@ -160,9 +161,9 @@ Route::group('/', function () {
Route::post('/agent/manager', 'Agent/manager');
Route::post('/agent/customer_list', 'Agent/customerList'); //客服列表,支持搜索某个代理下的客服
Route::post('/agent/customer_user_list', 'Agent/customerUser'); //获取客服下所有用户
Route::post('/agent/aws_ivs_list', 'Agent/aws_ivs_list'); //直播推流列表
Route::post('/agent/aws_ivs_add', 'Agent/aws_ivs_add'); //直播推流配置添加
Route::post('/agent/aws_ivs_edit', 'Agent/aws_ivs_edit'); //直播推流配置编辑
Route::post('/agent/aws_ivs_list', 'Agent/awsIvsList'); //直播推流列表
Route::post('/agent/aws_ivs_add', 'Agent/awsIvsAdd'); //直播推流配置添加
Route::post('/agent/aws_ivs_edit', 'Agent/awsIvsEdit'); //直播推流配置编辑
// 用户管理
Route::post('/user/index', 'User/index');

12
app/admin/service/AdminService.php

@ -141,8 +141,18 @@ class AdminService extends AdminBaseService
if (empty($info)) {
return $this->toData('100400', 'The user does not exist.', []);
}
$infoArr = $info->toArray();
// 获取用户的聊天账号信息
$chatInfo = UserChatLinkModel::where(['user_id'=>$userId, 'user_type'=>2])->find();
$chat_uuid = 0;
if (!empty($chatInfo)) {
$chat_uuid = $chatInfo->chat_uuid;
}
$infoArr['chat_uuid'] = $chat_uuid;
// 返回数据
return $this->toData('0', 'Modification successful.', $info->toArray());
return $this->toData('0', 'Modification successful.', $infoArr);
} catch (\Exception $exception) {
return $this->toData('100500', 'The system is busy.', [$exception->getMessage(), $exception->getTrace()]);
}

13
app/admin/service/AgentService.php

@ -200,12 +200,15 @@ class AgentService extends AdminBaseService
}
// 查询当前客服下的用户
$list = CustomerRelationalModel::where('customer_id', $param['customer_id'])->order('id', 'desc')->paginate([
'list_rows' => 15, // 每页显示 10 条
'list_rows' => $param['limit'] ?? 15,
'page' => $param['page'], // 使用前端传递的页码
]);
$userIds = array_column($list->items(), 'user_id'); // 获取当前页的用户id
// 根据user_id查询用户列表
$userDetails = UserModel::whereIn('id', $userIds)->select()->toArray();
$userDetails = [];
if ($userIds) {
$userDetails = UserModel::whereIn('user_id', $userIds)->select()->toArray();
}
return $this->toData('0', 'SUCCESS', [
'list' => $list->items(), // 当前页的数据
@ -273,6 +276,12 @@ class AgentService extends AdminBaseService
if (empty($param['agent_id'])) {
return $this->toData('1', 'Missing param agent_id');
}
//判断一个代理下只能有一个推流配置
$ckInfo = AwsIvsModel::where('agent_id', $param['agent_id'])->find();
if ($ckInfo) {
return $this->toData('1', '一个代理下只能配置一个推流信息');
}
//保存推流配置
$res = AwsIvsModel::create([
'title' => $param['title'],
'anchor_name' => $param['anchor_name'],

3
app/admin/service/RechargeService.php

@ -145,6 +145,7 @@ class RechargeService extends AdminBaseService
if ($param['check_status'] == 1) {
if(env('ACCOUT_TYPE.ALL_IN_ONE')==1){
$result = $this->updateUserAssetNew($info['user_id'], 1, $info['market_amount'], 0, $info['order_no']);
\think\Log::error("审核充值订单 - 审核通过结果:". json_encode($result));
}else{
$result = $this->updateUserAsset($info['user_id'], $info['account_type'], 1, $info['market_amount'], 0, $info['order_no']);
}
@ -179,4 +180,4 @@ class RechargeService extends AdminBaseService
}
}
}
}

15
app/home/controller/News.php

@ -2,7 +2,6 @@
namespace app\home\controller;
use app\model\CustomerRelationalModel;
use app\model\UserChatLinkModel;
use Goutte\Client;
use think\facade\Cache;
@ -94,12 +93,11 @@ class News extends HomeBaseController
*/
public function testApi()
{
$chatData = [
'Username' => "20_agent",
'Username' => "ccc333519",
'Password' => '123456',
];
$chatUrl = env('CHAT_SERVER.BASE_URL') . '/api/user/register';
$chatUrl = env('CHAT_SERVER.BASE_URL') . '/user/register';
$res = (new \app\utility\RequestChatServer())->ReqChatServer($chatUrl, $chatData);
if (!isset($res['data']['uuid'])) {
return json([
@ -110,19 +108,16 @@ class News extends HomeBaseController
//将客服账号与聊天账号关联
UserChatLinkModel::create([
'user_id' => 20,
'user_type' => 2,
'user_id' => 999,
'user_type' => 1,
'chat_uuid' => $res['data']['uuid'],
'chat_name' => $res['data']['username']
]);
return json([
'code' => '0',
'message' => 'successful',
'data' => $res,
'uuid' => $res['data']['uuid'],
'req_url' => $chatUrl,
'req_dat' => $chatData,
'uuid' => $res['data']['uuid']
]);
}

13
app/home/controller/User.php

@ -19,6 +19,19 @@ class User extends HomeBaseController
return json($returnData);
}
// 用户购买VIP
public function purchaseVip(): Json
{
$returnData = (new UserService())->purchaseVip($this->request->userId);
return json($returnData);
}
// 用户购买vip记录列表
public function purchaseVipLog(): Json
{
$returnData = (new UserService())->purchaseVipLog($this->request->userId, $this->request->post());
return json($returnData);
}
public function getAnchorForAgent(): Json
{
$returnData = (new UserService())->getAnchorForAgent($this->request->userId);

8
app/home/controller/Video.php

@ -1,5 +1,6 @@
<?php
namespace app\home\controller;
use app\home\service\VideoService;
use think\response\Json;
@ -10,4 +11,11 @@ class Video extends HomeBaseController
$returnData = (new VideoService())->getVideoOnDemandList($this->request->post());
return json($returnData);
}
// 获取某个点播配置详情
public function videoOnDemandDetail(): Json
{
$returnData = (new VideoService())->getVideoOnDemandDetail($this->request->post());
return json($returnData);
}
}

9
app/home/route/app.php

@ -178,6 +178,8 @@ Route::group('/',function (){
Route::post('user/get_time', 'User/getTime');
// 获取用户基础信息
Route::post('user/info', 'User/getUserInfo');
Route::post('user/purchase_vip', 'User/purchaseVip'); //用户购买VIP
Route::post('user/purchase_vip_log', 'User/purchaseVipLog'); //用户购买VIP记录列表
// 获取用户的代理创建的群聊信息
Route::post('user/get_anchor_for_agent', 'User/getAnchorForAgent');
// 获取登陆记录
@ -266,7 +268,8 @@ Route::group('/',function (){
Route::post('user/loan', 'User/loan');
// 视频点播相关
Route::post('video/video_on_demand_list', 'video/videoOnDemandList'); // 获取视频点播列表
Route::post('video/video_on_demand_list', 'Video/videoOnDemandList'); // 获取视频点播列表
Route::post('video/video_on_demand_detail', 'Video/videoOnDemandDetail'); // 获取某个点播配置详情
})->middleware(\app\home\middleware\AuthMiddleware::class);
@ -280,8 +283,8 @@ Route::group('/',function (){
Route::post('get_ip', 'Login/getIP');
Route::get('get_news', 'News/index');
Route::get('test', 'News/test');
Route::get('test_api', 'video/videoOnDemandList');
Route::post('test', 'News/test');
Route::post('test_api', 'User/purchaseVipLog');
})->allowCrossDomain($header);

1605
app/home/service/Copy of Copy of UserService.php

File diff suppressed because it is too large

1605
app/home/service/Copy of UserService.php

File diff suppressed because it is too large

665
app/home/service/PreHkdStockService.php

@ -0,0 +1,665 @@
<?php
namespace app\home\service;
use app\model\FeeSettingModel;
use app\model\PreHkdStockModel;
use app\model\StockMarketModel;
use app\model\StockHkdListModel;
use app\model\UserHkdPreStockOrderModel;
use app\model\UserStockHkdLogModel;
use app\model\UserStockHkdModel;
use think\facade\Db;
class PreHkdStockService extends BaseHomeService
{
// 列表
public function index($param)
{
try {
if (empty($param['page']) || !is_numeric($param['page']) || empty($param['limit']) || !is_numeric($param['limit'])) {
$param['page'] = 1;
$param['limit'] = 10;
}
$where = [];
$where[] = ['is_delete', '=', PreHkdStockModel::IS_DELETE_NO];
$where[] = ['status', '=', PreHkdStockModel::STATUS_ON];
$query = PreHkdStockModel::where($where);
$totalQuery = PreHkdStockModel::where($where);
// 申购状态筛选 1 可申购 2 带中签 3 待上市 4 已上市
if (isset($param['open_status']) && in_array($param['open_status'], ['1', '2', '3', '4'])) {
switch ($param['open_status']) {
case '1':
$query = $query->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', []);
}
}
}

675
app/home/service/PreIdnStockService.php

@ -0,0 +1,675 @@
<?php
namespace app\home\service;
use app\model\FeeSettingModel;
use app\model\PreIdnStockModel;
use app\model\StockIdnListModel;
use app\model\StockMarketModel;
use app\model\UserIdnPreStockOrderModel;
use app\model\UserStockIdnLogModel;
use app\model\UserStockIdnModel;
use think\facade\Db;
class PreIdnStockService extends BaseHomeService
{
// 列表
public function index($param)
{
try {
if (empty($param['page']) || !is_numeric($param['page']) || empty($param['limit']) || !is_numeric($param['limit'])) {
$param['page'] = 1;
$param['limit'] = 10;
}
$where = [];
$where[] = ['is_delete', '=', PreIdnStockModel::IS_DELETE_NO];
$where[] = ['status', '=', PreIdnStockModel::STATUS_ON];
$query = PreIdnStockModel::where($where);
$totalQuery = PreIdnStockModel::where($where);
// 申购状态筛选 1 可申购 2 带中签 3 待上市 4 已上市
if (isset($param['open_status']) && in_array($param['open_status'], ['1', '2', '3', '4'])) {
switch ($param['open_status']) {
case '1':
$query = $query->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', '=', PreIdnStockModel::SIGN_STATUS_NO);
$totalQuery = $totalQuery->whereTime('end_time', '<', date('Y-m-d H:i:s'))->where('sign_status', '=', PreIdnStockModel::SIGN_STATUS_NO);
break;
case '3':
$query = $query->where('sign_status', '=', PreIdnStockModel::SIGN_STATUS_DONE)->where('open_status', PreIdnStockModel::OPEN_STATUS_NO);
$totalQuery = $totalQuery->where('sign_status', '=', PreIdnStockModel::SIGN_STATUS_DONE)->where('open_status', PreIdnStockModel::OPEN_STATUS_NO);
break;
case '4':
$query = $query->where('open_status', PreIdnStockModel::OPEN_STATUS_HAD);
$totalQuery = $totalQuery->where('open_status', PreIdnStockModel::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 == PreIdnStockModel::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 == PreIdnStockModel::SIGN_STATUS_DONE) $progressStatus = 3;
if ($item->is_post_pay == PreIdnStockModel::IS_POST_PAY_YES && $item->pay_deadline_time < date('Y-m-d H:i:s')) $progressStatus = 4;
if ($item->open_status == PreIdnStockModel::OPEN_STATUS_HAD) $progressStatus = $item->is_post_pay == PreIdnStockModel::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' => StockIdnListModel::$tapeList,
'stock_type_list' => PreIdnStockModel::$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 = PreIdnStockModel::where('id', $param['id'])->where('is_delete', PreIdnStockModel::IS_DELETE_NO)->where('status', PreIdnStockModel::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 == PreIdnStockModel::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 == PreIdnStockModel::SIGN_STATUS_DONE) $progressStatus = 3;
if ($preStock->is_post_pay == PreIdnStockModel::IS_POST_PAY_YES && $preStock->pay_deadline_time < date('Y-m-d H:i:s')) $progressStatus = 4;
if ($preStock->open_status == PreIdnStockModel::OPEN_STATUS_HAD) $progressStatus = $preStock->is_post_pay == PreIdnStockModel::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' => StockIdnListModel::$tapeList,
'stock_type_list' => PreIdnStockModel::$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', []);
}
$preIdnStock = PreIdnStockModel::where('id', $param['id'])
->where('status', PreIdnStockModel::STATUS_ON)
->where('is_delete', PreIdnStockModel::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($preIdnStock)) {
return $this->toData('1', 'Params error', []);
}
$hasOrder = UserIdnPreStockOrderModel::where('user_id', $userId)->where('pre_stock_id', $param['id'])->count();
if ($preIdnStock->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'] < $preIdnStock->min) {
return $this->toData('1', 'Order quantity less than the minimum', []);
}
if ($preIdnStock->max > 0 && $param['num'] > $preIdnStock->max) {
return $this->toData('1', 'Order quantity greater than maximum', []);
}
if ($preIdnStock->price <= 0) {
return $this->toData('1', 'Price error', []);
}
// 支付类型
if (empty($param['pay_type']) || !is_numeric($param['pay_type']) || !in_array($param['pay_type'], [UserIdnPreStockOrderModel::PAY_TYPE_ONE, UserIdnPreStockOrderModel::PAY_TYPE_TWO])) {
return $this->toData('1', 'Params error', []);
}
if ($param['pay_type'] == UserIdnPreStockOrderModel::PAY_TYPE_TWO && $preIdnStock->is_post_pay == PreIdnStockModel::IS_POST_PAY_NO) {
return $this->toData('1', 'Params error', []);
}
// 计算金额
$amount = bcmul($param['num'], $preIdnStock->price, 18);
// 计算手续费
$purchaseFee = FeeSettingModel::where('market_type', StockMarketModel::STOCK_MARKET_YNG)->value('purchase_fee');
if ($purchaseFee <= 0) {
$fee = 0;
} else {
$fee = bcmul($amount, $purchaseFee, 18);
}
Db::startTrans();
// 生成订单
$orderNo = $this->generateOrderNumber(20);
$order = new UserIdnPreStockOrderModel;
$order->user_id = $userId;
$order->pre_stock_id = $preIdnStock->id;
$order->status = $param['pay_type'] == 1 ? UserIdnPreStockOrderModel::STATUS_DOING : UserIdnPreStockOrderModel::STATUS_POST_PAY;
$order->pay_type = $param['pay_type'];
$order->order_no = $orderNo;
$order->num = $param['num'];
$order->get_num = 0;
$order->price = $preIdnStock->price;
$order->amount = $amount;
$order->get_amount = 0;
$order->fee = $fee;
$order->get_fee = 0;
$order->fee_rate = $purchaseFee;
$order->get_time = $preIdnStock->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', []);
}
// 扣除用户资产
$userStockIdnName = (new UserStockIdnModel())->getName();
$beforeAmount = Db::name($userStockIdnName)->where('stock_id', 'IDR')->where('user_id', $userId)->value('usable_num');
if ($beforeAmount < $amount) {
Db::rollback();
return $this->toData('1', 'assert not enough', []);
}
$updateNum = Db::name($userStockIdnName)->where('stock_id', 'IDR')->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 UserStockIdnLogModel();
$userStockLog->user_id = $userId;
$userStockLog->change_type = 15; // 新股申购扣减费用
$userStockLog->stock_id = 'IDR';
$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 = Db::name($userStockIdnName)->where('stock_id', 'IDR')->where('user_id', $userId)->value('usable_num');
if ($beforeFee < $fee) {
Db::rollback();
return $this->toData('1', 'assert not enough', []);
}
$updateNum = Db::name($userStockIdnName)->where('stock_id', 'IDR')->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 UserStockIdnLogModel;
$userStockLog->user_id = $userId;
$userStockLog->change_type = 16;
$userStockLog->stock_id = 'IDR';
$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');
$preIdnStock = PreIdnStockModel::where('stock_code', $param['stock_code'])
->where('status', PreIdnStockModel::STATUS_ON)
->where('is_delete', PreIdnStockModel::IS_DELETE_NO)
->where('is_post_pay', PreIdnStockModel::IS_POST_PAY_YES)
->whereTime('pay_deadline_time', '>=', $now)
->find();
if (empty($preIdnStock)) {
return $this->toData('1', 'Payment deadline exceeded', []);
}
$hasOrder = UserIdnPreStockOrderModel::where('user_id', $userId)->where('id', $param['id'])->where('pay_type', UserIdnPreStockOrderModel::PAY_TYPE_TWO)->where('status', UserIdnPreStockOrderModel::STATUS_POST_PAY)->find();
if (empty($hasOrder)) {
return $this->toData('1', 'Params error3', []);
}
$orderNo = $hasOrder->order_no;
Db::startTrans();
if ($preIdnStock->sign_status == PreIdnStockModel::SIGN_STATUS_DONE && strtotime($preIdnStock->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 = UserStockIdnModel::where('stock_id', 'IDR')->where('user_id', $userId)->value('usable_num');
if ($beforeAmount < $amount) {
Db::rollback();
return $this->toData('1', 'assert not enough', []);
}
$updateNum = UserStockIdnModel::where('stock_id', 'IDR')->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 UserStockIdnLogModel();
$userStockLog->user_id = $userId;
$userStockLog->change_type = 15; // 新股申购扣减费用
$userStockLog->stock_id = 'IDR';
$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 = UserStockIdnModel::where('stock_id', 'IDR')->where('user_id', $userId)->value('usable_num');
if ($beforeFee < $fee) {
Db::rollback();
return $this->toData('1', 'assert not enough', []);
}
$updateNum = UserStockIdnModel::where('stock_id', 'IDR')->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 UserStockIdnLogModel;
$userStockLog->user_id = $userId;
$userStockLog->change_type = 16;
$userStockLog->stock_id = 'IDR';
$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 = UserIdnPreStockOrderModel::where('id', $param['id'])->update(['status' => UserIdnPreStockOrderModel::STATUS_SIGNING, 'update_time' => $now]);
if (!$bool) {
Db::rollback();
return $this->toData('1', 'update order error', []);
}
} elseif ($preIdnStock->sign_status == PreIdnStockModel::SIGN_STATUS_NO && strtotime($preIdnStock->get_time) >= strtotime($now)) {
//未签名
$amount = $hasOrder->amount;
$fee = $hasOrder->fee;
// 扣除用户资产
$beforeAmount = UserStockIdnModel::where('stock_id', 'IDR')->where('user_id', $userId)->value('usable_num');
if ($beforeAmount < $amount) {
Db::rollback();
return $this->toData('1', 'assert not enough', []);
}
$updateNum = UserStockIdnModel::where('stock_id', 'IDR')->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 UserStockIdnLogModel();
$userStockLog->user_id = $userId;
$userStockLog->change_type = 15; // 新股申购扣减费用
$userStockLog->stock_id = 'IDR';
$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 = UserStockIdnModel::where('stock_id', 'IDR')->where('user_id', $userId)->value('usable_num');
if ($beforeFee < $fee) {
Db::rollback();
return $this->toData('1', 'assert not enough', []);
}
$updateNum = UserStockIdnModel::where('stock_id', 'IDR')->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 UserStockIdnLogModel;
$userStockLog->user_id = $userId;
$userStockLog->change_type = 16;
$userStockLog->stock_id = 'IDR';
$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 = UserIdnPreStockOrderModel::where('id', $param['id'])->update(['status' => UserIdnPreStockOrderModel::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 = UserIdnPreStockOrderModel::whereIn('status', $statusArr)->where('user_id', $userId)->order('update_time', 'desc')->page($param['page'], $param['limit'])->select();
$total = UserIdnPreStockOrderModel::whereIn('status', $statusArr)->where('user_id', $userId)->count();
$rows = [];
if (!$list->isEmpty()) {
$stockIdList = [];
foreach ($list as $item) {
$stockIdList[] = $item->pre_stock_id;
}
$stockList = PreIdnStockModel::where('id', 'in', $stockIdList)->column(['*'], 'id');
$purchaseFee = FeeSettingModel::where('market_type', StockMarketModel::STOCK_MARKET_YNG)->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 == PreIdnStockModel::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 == UserIdnPreStockOrderModel::PAY_TYPE_TWO && $item->status == UserIdnPreStockOrderModel::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' => StockIdnListModel::$tapeList,
'stock_type_list' => PreIdnStockModel::$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 = UserIdnPreStockOrderModel::where('user_id', $userId)->where('id', $param['id'])->find();
if (empty($order)) {
return $this->toData('1', 'Params error', []);
}
$stock = PreIdnStockModel::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 == PreIdnStockModel::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' => StockIdnListModel::$tapeList,
'stock_type_list' => PreIdnStockModel::$stockTypeList,
]]);
} catch (\Exception $exception) {
return $this->toData('1', 'System error', []);
}
}
}

670
app/home/service/PreInStockService.php

@ -0,0 +1,670 @@
<?php
namespace app\home\service;
use app\model\FeeSettingModel;
use app\model\PreInStockModel;
use app\model\StockInListModel;
use app\model\StockMarketModel;
use app\model\UserStockInLogModel;
use app\model\UserStockInModel;
use app\model\UserInPreStockOrderModel;
use think\facade\Db;
class PreInStockService extends BaseHomeService
{
// 列表
public function index($param)
{
try {
if (empty($param['page']) || !is_numeric($param['page']) || empty($param['limit']) || !is_numeric($param['limit'])) {
$param['page'] = 1;
$param['limit'] = 10;
}
$where = [];
$where[] = ['is_delete', '=', PreInStockModel::IS_DELETE_NO];
$where[] = ['status', '=', PreInStockModel::STATUS_ON];
$query = PreInStockModel::where($where);
$totalQuery = PreInStockModel::where($where);
// 申购状态筛选 1 可申购 2 带中签 3 待上市 4 已上市
if (isset($param['open_status']) && in_array($param['open_status'], ['1', '2', '3', '4'])) {
switch ($param['open_status']) {
case '1':
$query = $query->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', '=', PreInStockModel::SIGN_STATUS_NO);
$totalQuery = $totalQuery->whereTime('end_time', '<', date('Y-m-d H:i:s'))->where('sign_status', '=', PreInStockModel::SIGN_STATUS_NO);
break;
case '3':
$query = $query->where('sign_status', '=', PreInStockModel::SIGN_STATUS_DONE)->where('open_status', PreInStockModel::OPEN_STATUS_NO);
$totalQuery = $totalQuery->where('sign_status', '=', PreInStockModel::SIGN_STATUS_DONE)->where('open_status', PreInStockModel::OPEN_STATUS_NO);
break;
case '4':
$query = $query->where('open_status', PreInStockModel::OPEN_STATUS_HAD);
$totalQuery = $totalQuery->where('open_status', PreInStockModel::OPEN_STATUS_HAD);
break;
}
}
$list = $query->page($param['page'], $param['limit'])->order('open_time', 'desc')->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 == PreInStockModel::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 == PreInStockModel::SIGN_STATUS_DONE) $progressStatus = 3;
if ($item->is_post_pay == PreInStockModel::IS_POST_PAY_YES && $item->pay_deadline_time < date('Y-m-d H:i:s')) $progressStatus = 4;
if ($item->open_status == PreInStockModel::OPEN_STATUS_HAD) $progressStatus = $item->is_post_pay == PreInStockModel::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' => StockInListModel::$tapeList,
'stock_type_list' => PreInStockModel::$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 = PreInStockModel::where('id', $param['id'])->where('is_delete', PreInStockModel::IS_DELETE_NO)->where('status', PreInStockModel::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 == PreInStockModel::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 == PreInStockModel::SIGN_STATUS_DONE) $progressStatus = 3;
if ($preStock->is_post_pay == PreInStockModel::IS_POST_PAY_YES && $preStock->pay_deadline_time < date('Y-m-d H:i:s')) $progressStatus = 4;
if ($preStock->open_status == PreInStockModel::OPEN_STATUS_HAD) $progressStatus = $preStock->is_post_pay == PreInStockModel::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' => StockInListModel::$tapeList,
'stock_type_list' => PreInStockModel::$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', []);
}
$preInStock = PreInStockModel::where('id', $param['id'])
->where('status', PreInStockModel::STATUS_ON)
->where('is_delete', PreInStockModel::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($preInStock)) {
return $this->toData('1', 'Params error', []);
}
$hasOrder = UserInPreStockOrderModel::where('user_id', $userId)->where('pre_stock_id', $param['id'])->count();
if ($preInStock->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'] < $preInStock->min) {
return $this->toData('1', 'Order quantity less than the minimum', []);
}
if ($preInStock->max > 0 && $param['num'] > $preInStock->max) {
return $this->toData('1', 'Order quantity greater than maximum', []);
}
if ($preInStock->price <= 0) {
return $this->toData('1', 'Price error', []);
}
// 支付类型
if (empty($param['pay_type']) || !is_numeric($param['pay_type']) || !in_array($param['pay_type'], [UserInPreStockOrderModel::PAY_TYPE_ONE, UserInPreStockOrderModel::PAY_TYPE_TWO])) {
return $this->toData('1', 'Params error', []);
}
// 计算金额
$amount = bcmul($param['num'], $preInStock->price, 18);
// 计算手续费
$purchaseFee = FeeSettingModel::where('market_type', StockMarketModel::STOCK_MARKET_IN)->value('purchase_fee');
if ($purchaseFee <= 0) {
$fee = 0;
} else {
$fee = bcmul($amount, $purchaseFee, 18);
}
Db::startTrans();
// 生成订单
$orderNo = $this->generateOrderNumber(20);
$order = new UserInPreStockOrderModel;
$order->user_id = $userId;
$order->pre_stock_id = $preInStock->id;
$order->status = $param['pay_type'] == 1 ? UserInPreStockOrderModel::STATUS_DOING : UserInPreStockOrderModel::STATUS_POST_PAY;
$order->pay_type = $param['pay_type'];
$order->order_no = $orderNo;
$order->num = $param['num'];
$order->get_num = 0;
$order->price = $preInStock->price;
$order->amount = $amount;
$order->get_amount = 0;
$order->fee = $fee;
$order->get_fee = 0;
$order->fee_rate = $purchaseFee;
$order->get_time = $preInStock->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', []);
}
// 扣除用户资产
$userStockInName = (new UserStockInModel())->getName();
$beforeAmount = Db::name($userStockInName)->where('stock_id', 'INR')->where('user_id', $userId)->value('usable_num');
if ($beforeAmount < $amount) {
Db::rollback();
return $this->toData('1', 'assert not enough', []);
}
$updateNum = Db::name($userStockInName)->where('stock_id', 'INR')->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 UserStockInLogModel();
$userStockLog->user_id = $userId;
$userStockLog->change_type = 15; // 新股申购扣减费用
$userStockLog->stock_id = 'INR';
$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 = Db::name($userStockInName)->where('stock_id', 'INR')->where('user_id', $userId)->value('usable_num');
if ($beforeFee < $fee) {
Db::rollback();
return $this->toData('1', 'assert not enough', []);
}
$updateNum = Db::name($userStockInName)->where('stock_id', 'INR')->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 UserStockInLogModel;
$userStockLog->user_id = $userId;
$userStockLog->change_type = 16;
$userStockLog->stock_id = 'INR';
$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');
$preInStock = PreInStockModel::where('stock_code', $param['stock_code'])
->where('status', PreInStockModel::STATUS_ON)
->where('is_delete', PreInStockModel::IS_DELETE_NO)
->where('is_post_pay', PreInStockModel::IS_POST_PAY_YES)
->whereTime('pay_deadline_time', '>=', $now)
->find();
if (empty($preInStock)) {
return $this->toData('1', 'Payment deadline exceeded', []);
}
$hasOrder = UserInPreStockOrderModel::where('user_id', $userId)->where('id', $param['id'])->where('pay_type', UserInPreStockOrderModel::PAY_TYPE_TWO)->where('status', UserInPreStockOrderModel::STATUS_POST_PAY)->find();
if (empty($hasOrder)) {
return $this->toData('1', 'Params error3', []);
}
$orderNo = $hasOrder->order_no;
Db::startTrans();
if ($preInStock->sign_status == PreInStockModel::SIGN_STATUS_DONE && strtotime($preInStock->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 = UserStockInModel::where('stock_id', 'INR')->where('user_id', $userId)->value('usable_num');
if ($beforeAmount < $amount) {
Db::rollback();
return $this->toData('1', 'assert not enough', []);
}
$updateNum = UserStockInModel::where('stock_id', 'INR')->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 UserStockInLogModel();
$userStockLog->user_id = $userId;
$userStockLog->change_type = 15; // 新股申购扣减费用
$userStockLog->stock_id = 'INR';
$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 = UserStockInModel::where('stock_id', 'INR')->where('user_id', $userId)->value('usable_num');
if ($beforeFee < $fee) {
Db::rollback();
return $this->toData('1', 'assert not enough', []);
}
$updateNum = UserStockInModel::where('stock_id', 'INR')->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 UserStockInLogModel;
$userStockLog->user_id = $userId;
$userStockLog->change_type = 16;
$userStockLog->stock_id = 'INR';
$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 = UserInPreStockOrderModel::where('id', $param['id'])->update(['status' => UserInPreStockOrderModel::STATUS_SIGNING, 'update_time' => $now]);
if (!$bool) {
Db::rollback();
return $this->toData('1', 'update order error', []);
}
} elseif ($preInStock->sign_status == PreInStockModel::SIGN_STATUS_NO && strtotime($preInStock->get_time) >= strtotime($now)) {
//未签名
$amount = $hasOrder->amount;
$fee = $hasOrder->fee;
// 扣除用户资产
$beforeAmount = UserStockInModel::where('stock_id', 'INR')->where('user_id', $userId)->value('usable_num');
if ($beforeAmount < $amount) {
Db::rollback();
return $this->toData('1', 'assert not enough', []);
}
$updateNum = UserStockInModel::where('stock_id', 'INR')->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 UserStockInLogModel();
$userStockLog->user_id = $userId;
$userStockLog->change_type = 15; // 新股申购扣减费用
$userStockLog->stock_id = 'INR';
$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 = UserStockInModel::where('stock_id', 'INR')->where('user_id', $userId)->value('usable_num');
if ($beforeFee < $fee) {
Db::rollback();
return $this->toData('1', 'assert not enough', []);
}
$updateNum = UserStockInModel::where('stock_id', 'INR')->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 UserStockInLogModel;
$userStockLog->user_id = $userId;
$userStockLog->change_type = 16;
$userStockLog->stock_id = 'INR';
$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 = UserInPreStockOrderModel::where('id', $param['id'])->update(['status' => UserInPreStockOrderModel::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 = UserInPreStockOrderModel::whereIn('status', $statusArr)->where('user_id', $userId)->order('update_time', 'desc')->page($param['page'], $param['limit'])->select();
$total = UserInPreStockOrderModel::whereIn('status', $statusArr)->where('user_id', $userId)->count();
$rows = [];
if (!$list->isEmpty()) {
$stockIdList = [];
foreach ($list as $item) {
$stockIdList[] = $item->pre_stock_id;
}
$stockList = PreInStockModel::where('id', 'in', $stockIdList)->column(['*'], 'id');
// 计算手续费
$purchaseFee = FeeSettingModel::where('market_type', StockMarketModel::STOCK_MARKET_IN)->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 == PreInStockModel::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 == UserInPreStockOrderModel::PAY_TYPE_TWO && $item->status == UserInPreStockOrderModel::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' => StockInListModel::$tapeList,
'stock_type_list' => PreInStockModel::$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 = UserInPreStockOrderModel::where('user_id', $userId)->where('id', $param['id'])->find();
if (empty($order)) {
return $this->toData('1', 'Params error', []);
}
$stock = PreInStockModel::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 == PreInStockModel::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' => StockInListModel::$tapeList,
'stock_type_list' => PreInStockModel::$stockTypeList,
]]);
} catch (\Exception $exception) {
return $this->toData('1', 'System error', []);
}
}
}

672
app/home/service/PreMysStockService.php

@ -0,0 +1,672 @@
<?php
namespace app\home\service;
use app\model\FeeSettingModel;
use app\model\PreMysStockModel;
use app\model\StockMysListModel;
use app\model\StockMarketModel;
use app\model\UserMysPreStockOrderModel;
use app\model\UserStockMysLogModel;
use app\model\UserStockMysModel;
use think\facade\Db;
class PreMysStockService extends BaseHomeService
{
// 列表
public function index($param)
{
try {
if(empty($param['page']) || !is_numeric($param['page']) || empty($param['limit']) || !is_numeric($param['limit'])){
$param['page'] = 1;
$param['limit'] = 10;
}
$where = [];
$where[] = ['is_delete', '=',PreMysStockModel::IS_DELETE_NO];
$where[] = ['status', '=',PreMysStockModel::STATUS_ON];
$query = PreMysStockModel::where($where);
$totalQuery = PreMysStockModel::where($where);
// 申购状态筛选 1 可申购 2 带中签 3 待上市 4 已上市
if(isset($param['open_status']) && in_array($param['open_status'],['1','2','3','4'])){
switch ($param['open_status'])
{
case '1':
$query = $query->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', '=', PreMysStockModel::SIGN_STATUS_NO);
$totalQuery = $totalQuery->whereTime('end_time', '<', date('Y-m-d H:i:s'))->where('sign_status', '=', PreMysStockModel::SIGN_STATUS_NO);
break;
case '3':
$query = $query->where('sign_status', '=', PreMysStockModel::SIGN_STATUS_DONE)->where('open_status',PreMysStockModel::OPEN_STATUS_NO);
$totalQuery = $totalQuery->where('sign_status', '=', PreMysStockModel::SIGN_STATUS_DONE)->where('open_status',PreMysStockModel::OPEN_STATUS_NO);
break;
case '4':
$query = $query->where('open_status',PreMysStockModel::OPEN_STATUS_HAD);
$totalQuery = $totalQuery->where('open_status',PreMysStockModel::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 == PreMysStockModel::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 == PreMysStockModel::SIGN_STATUS_DONE) $progressStatus = 3;
if ($item->is_post_pay == PreMysStockModel::IS_POST_PAY_YES && $item->pay_deadline_time < date('Y-m-d H:i:s')) $progressStatus = 4;
if ($item->open_status == PreMysStockModel::OPEN_STATUS_HAD) $progressStatus = $item->is_post_pay == PreMysStockModel::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' => StockMysListModel::$tapeList,
'stock_type_list' => PreMysStockModel::$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 = PreMysStockModel::where('id', $param['id'])->where('is_delete', PreMysStockModel::IS_DELETE_NO)->where('status', PreMysStockModel::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 == PreMysStockModel::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 == PreMysStockModel::SIGN_STATUS_DONE) $progressStatus = 3;
if ($preStock->is_post_pay == PreMysStockModel::IS_POST_PAY_YES && $preStock->pay_deadline_time < date('Y-m-d H:i:s')) $progressStatus = 4;
if ($preStock->open_status == PreMysStockModel::OPEN_STATUS_HAD) $progressStatus = $preStock->is_post_pay == PreMysStockModel::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' => StockMysListModel::$tapeList,
'stock_type_list' => PreMysStockModel::$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', []);
}
$preMysStock = PreMysStockModel::where('id',$param['id'])
->where('status',PreMysStockModel::STATUS_ON)
->where('is_delete',PreMysStockModel::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($preMysStock)){
return $this->toData('1', 'Params error', []);
}
$hasOrder = UserMysPreStockOrderModel::where('user_id', $userId)->where('pre_stock_id', $param['id'])->count();
if ($preMysStock->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'] < $preMysStock->min){
return $this->toData('1', 'Order quantity less than the minimum', []);
}
if ($preMysStock->max > 0 && $param['num'] > $preMysStock->max) {
return $this->toData('1', 'Order quantity greater than maximum', []);
}
if($preMysStock->price <= 0){
return $this->toData('1', 'Price error', []);
}
// 支付类型
if (empty($param['pay_type']) || !is_numeric($param['pay_type']) || !in_array($param['pay_type'], [UserMysPreStockOrderModel::PAY_TYPE_ONE, UserMysPreStockOrderModel::PAY_TYPE_TWO])) {
return $this->toData('1', 'Params error', []);
}
// 计算金额
$amount = bcmul($param['num'],$preMysStock->price, 18);
// 计算手续费
$purchaseFee = FeeSettingModel::where('market_type', StockMarketModel::STOCK_MARKET_MG)->value('purchase_fee');
if($purchaseFee <= 0){
$fee = 0;
} else {
$fee = bcmul($amount, $purchaseFee,18);
}
Db::startTrans();
// 生成订单
$orderNo = $this->generateOrderNumber(20);
$order = new UserMysPreStockOrderModel;
$order->pre_stock_id = $preMysStock->id;
$order->user_id = $userId;
$order->status = $param['pay_type'] == 1 ? UserMysPreStockOrderModel::STATUS_DOING : UserMysPreStockOrderModel::STATUS_POST_PAY;
$order->pay_type = $param['pay_type'];
$order->order_no = $orderNo;
$order->num = $param['num'];
$order->get_num = 0;
$order->price = $preMysStock->price;
$order->amount = $amount;
$order->get_amount = 0;
$order->trade_status = 0;
$order->fee = $fee;
$order->get_fee = 0;
$order->fee_rate = $purchaseFee;
$order->get_time = $preMysStock->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', []);
}
// 扣除用户资产
$userStockMysName = (new UserStockMysModel())->getName();
$beforeAmount = Db::name($userStockMysName)->where('stock_id', 'MYR')->where('user_id',$userId)->value('usable_num');
if($beforeAmount < $amount){
Db::rollback();
return $this->toData('1', 'assert not enough', []);
}
$updateNum = Db::name($userStockMysName)->where('stock_id', 'MYR')->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 UserStockMysLogModel;
$userStockLog->user_id = $userId;
$userStockLog->change_type = 15; // 新股申购扣减费用
$userStockLog->stock_id = 'MYR';
$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 = Db::name($userStockMysName)->where('stock_id', 'MYR')->where('user_id',$userId)->value('usable_num');
if($beforeFee < $fee){
Db::rollback();
return $this->toData('1', 'assert not enough', []);
}
$updateNum = Db::name($userStockMysName)->where('stock_id', 'MYR')->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 UserStockMysLogModel;
$userStockLog->user_id = $userId;
$userStockLog->change_type = 16;
$userStockLog->stock_id = 'MYR';
$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');
$preInStock = PreMysStockModel::where('stock_code', $param['stock_code'])
->where('status', PreMysStockModel::STATUS_ON)
->where('is_delete', PreMysStockModel::IS_DELETE_NO)
->where('is_post_pay', PreMysStockModel::IS_POST_PAY_YES)
->whereTime('pay_deadline_time', '>=', $now)
->find();
if (empty($preInStock)) {
return $this->toData('1', 'Payment deadline exceeded', []);
}
$hasOrder = UserMysPreStockOrderModel::where('user_id', $userId)->where('id', $param['id'])->where('pay_type', UserMysPreStockOrderModel::PAY_TYPE_TWO)->where('status', UserMysPreStockOrderModel::STATUS_POST_PAY)->find();
if (empty($hasOrder)) {
return $this->toData('1', 'Params error3', []);
}
$orderNo = $hasOrder->order_no;
Db::startTrans();
if ($preInStock->sign_status == PreMysStockModel::SIGN_STATUS_DONE && strtotime($preInStock->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 = UserStockMysModel::where('stock_id', 'MYR')->where('user_id', $userId)->value('usable_num');
if ($beforeAmount < $amount) {
Db::rollback();
return $this->toData('1', 'assert not enough', []);
}
$updateNum = UserStockMysModel::where('stock_id', 'MYR')->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 UserStockMysLogModel();
$userStockLog->user_id = $userId;
$userStockLog->change_type = 15; // 新股申购扣减费用
$userStockLog->stock_id = 'MYR';
$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 = UserStockMysModel::where('stock_id', 'MYR')->where('user_id', $userId)->value('usable_num');
if ($beforeFee < $fee) {
Db::rollback();
return $this->toData('1', 'assert not enough', []);
}
$updateNum = UserStockMysModel::where('stock_id', 'MYR')->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 UserStockMysLogModel;
$userStockLog->user_id = $userId;
$userStockLog->change_type = 16;
$userStockLog->stock_id = 'MYR';
$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 = UserMysPreStockOrderModel::where('id', $param['id'])->update(['status' => UserMysPreStockOrderModel::STATUS_SIGNING, 'update_time' => $now]);
if (!$bool) {
Db::rollback();
return $this->toData('1', 'update order error', []);
}
} elseif ($preInStock->sign_status == PreMysStockModel::SIGN_STATUS_NO && strtotime($preInStock->get_time) >= strtotime($now)) {
//未签名
$amount = $hasOrder->amount;
$fee = $hasOrder->fee;
// 扣除用户资产
$beforeAmount = UserStockMysModel::where('stock_id', 'MYR')->where('user_id', $userId)->value('usable_num');
if ($beforeAmount < $amount) {
Db::rollback();
return $this->toData('1', 'assert not enough', []);
}
$updateNum = UserStockMysModel::where('stock_id', 'MYR')->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 UserStockMysLogModel();
$userStockLog->user_id = $userId;
$userStockLog->change_type = 15; // 新股申购扣减费用
$userStockLog->stock_id = 'MYR';
$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 = UserStockMysModel::where('stock_id', 'MYR')->where('user_id', $userId)->value('usable_num');
if ($beforeFee < $fee) {
Db::rollback();
return $this->toData('1', 'assert not enough', []);
}
$updateNum = UserStockMysModel::where('stock_id', 'MYR')->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 UserStockMysLogModel;
$userStockLog->user_id = $userId;
$userStockLog->change_type = 16;
$userStockLog->stock_id = 'MYR';
$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 = UserMysPreStockOrderModel::where('id', $param['id'])->update(['status' => UserMysPreStockOrderModel::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 = UserMysPreStockOrderModel::whereIn('status', $statusArr)->where('user_id', $userId)->order('update_time', 'desc')->page($param['page'], $param['limit'])->select();
$total = UserMysPreStockOrderModel::whereIn('status', $statusArr)->where('user_id', $userId)->count();
$rows = [];
if(!$list->isEmpty()){
$stockIdList = [];
foreach ($list as $item){
$stockIdList[] = $item->pre_stock_id;
}
$stockList = PreMysStockModel::where('id', 'in', $stockIdList)->column(['*'],'id');
// 计算手续费
$purchaseFee = FeeSettingModel::where('market_type', StockMarketModel::STOCK_MARKET_MG)->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 == PreMysStockModel::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 == UserMysPreStockOrderModel::PAY_TYPE_TWO && $item->status == UserMysPreStockOrderModel::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' => StockMysListModel::$tapeList,
'stock_type_list' => PreMysStockModel::$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 = UserMysPreStockOrderModel::where('user_id', $userId)->where('id', $param['id'])->find();
if(empty($order)){
return $this->toData('1', 'Params error', []);
}
$stock = PreMysStockModel::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 == PreMysStockModel::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,
'get_fee' =>$order->get_fee,
'order_no' =>$order->order_no,
'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' => StockMysListModel::$tapeList,
'stock_type_list' => PreMysStockModel::$stockTypeList,
]]);
}catch (\Exception $exception){
return $this->toData('1', 'System error', []);
}
}
}

670
app/home/service/PreSgdStockService.php

@ -0,0 +1,670 @@
<?php
namespace app\home\service;
use app\model\FeeSettingModel;
use app\model\PreSgdStockModel;
use app\model\StockMarketModel;
use app\model\StockOptionInrListModel;
use app\model\UserStockSgdLogModel;
use app\model\UserStockSgdModel;
use app\model\UserSgdPreStockOrderModel;
use think\facade\Db;
class PreSgdStockService extends BaseHomeService
{
// 列表
public function index($param)
{
try {
if (empty($param['page']) || !is_numeric($param['page']) || empty($param['limit']) || !is_numeric($param['limit'])) {
$param['page'] = 1;
$param['limit'] = 10;
}
$where = [];
$where[] = ['is_delete', '=', PreSgdStockModel::IS_DELETE_NO];
$where[] = ['status', '=', PreSgdStockModel::STATUS_ON];
$query = PreSgdStockModel::where($where);
$totalQuery = PreSgdStockModel::where($where);
// 申购状态筛选 1 可申购 2 带中签 3 待上市 4 已上市
if (isset($param['open_status']) && in_array($param['open_status'], ['1', '2', '3', '4'])) {
switch ($param['open_status']) {
case '1':
$query = $query->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', '=', PreSgdStockModel::SIGN_STATUS_NO);
$totalQuery = $totalQuery->whereTime('end_time', '<', date('Y-m-d H:i:s'))->where('sign_status', '=', PreSgdStockModel::SIGN_STATUS_NO);
break;
case '3':
$query = $query->where('sign_status', '=', PreSgdStockModel::SIGN_STATUS_DONE)->where('open_status', PreSgdStockModel::OPEN_STATUS_NO);
$totalQuery = $totalQuery->where('sign_status', '=', PreSgdStockModel::SIGN_STATUS_DONE)->where('open_status', PreSgdStockModel::OPEN_STATUS_NO);
break;
case '4':
$query = $query->where('open_status', PreSgdStockModel::OPEN_STATUS_HAD);
$totalQuery = $totalQuery->where('open_status', PreSgdStockModel::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 == PreSgdStockModel::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 == PreSgdStockModel::SIGN_STATUS_DONE) $progressStatus = 3;
if ($item->is_post_pay == PreSgdStockModel::IS_POST_PAY_YES && $item->pay_deadline_time < date('Y-m-d H:i:s')) $progressStatus = 4;
if ($item->open_status == PreSgdStockModel::OPEN_STATUS_HAD) $progressStatus = $item->is_post_pay == PreSgdStockModel::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' => StockOptionInrListModel::$tapeList,
'stock_type_list' => PreSgdStockModel::$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 = PreSgdStockModel::where('id', $param['id'])->where('is_delete', PreSgdStockModel::IS_DELETE_NO)->where('status', PreSgdStockModel::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 == PreSgdStockModel::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 == PreSgdStockModel::SIGN_STATUS_DONE) $progressStatus = 3;
if ($preStock->is_post_pay == PreSgdStockModel::IS_POST_PAY_YES && $preStock->pay_deadline_time < date('Y-m-d H:i:s')) $progressStatus = 4;
if ($preStock->open_status == PreSgdStockModel::OPEN_STATUS_HAD) $progressStatus = $preStock->is_post_pay == PreSgdStockModel::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' => StockOptionInrListModel::$tapeList,
'stock_type_list' => PreSgdStockModel::$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', []);
}
$preSgdStock = PreSgdStockModel::where('id', $param['id'])
->where('status', PreSgdStockModel::STATUS_ON)
->where('is_delete', PreSgdStockModel::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($preSgdStock)) {
return $this->toData('1', 'Params error', []);
}
$hasOrder = UserSgdPreStockOrderModel::where('user_id', $userId)->where('pre_stock_id', $param['id'])->count();
if ($preSgdStock->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'] < $preSgdStock->min) {
return $this->toData('1', 'Order quantity less than the minimum', []);
}
if ($preSgdStock->max > 0 && $param['num'] > $preSgdStock->max) {
return $this->toData('1', 'Order quantity greater than maximum', []);
}
if ($preSgdStock->price <= 0) {
return $this->toData('1', 'Price error', []);
}
// 支付类型
if (empty($param['pay_type']) || !is_numeric($param['pay_type']) || !in_array($param['pay_type'], [UserSgdPreStockOrderModel::PAY_TYPE_ONE, UserSgdPreStockOrderModel::PAY_TYPE_TWO])) {
return $this->toData('1', 'Params error', []);
}
// 计算金额
$amount = bcmul($param['num'], $preSgdStock->price, 18);
// 计算手续费
$purchaseFee = FeeSettingModel::where('market_type', StockMarketModel::STOCK_MARKET_SGD)->value('purchase_fee');
if ($purchaseFee <= 0) {
$fee = 0;
} else {
$fee = bcmul($amount, $purchaseFee, 18);
}
Db::startTrans();
// 生成订单
$orderNo = $this->generateOrderNumber(20);
$order = new UserSgdPreStockOrderModel;
$order->user_id = $userId;
$order->pre_stock_id = $preSgdStock->id;
$order->status = $param['pay_type'] == 1 ? UserSgdPreStockOrderModel::STATUS_DOING : UserSgdPreStockOrderModel::STATUS_POST_PAY;
$order->pay_type = $param['pay_type'];
$order->order_no = $orderNo;
$order->num = $param['num'];
$order->get_num = 0;
$order->price = $preSgdStock->price;
$order->amount = $amount;
$order->get_amount = 0;
$order->fee = $fee;
$order->get_fee = 0;
$order->fee_rate = $purchaseFee;
$order->get_time = $preSgdStock->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', []);
}
// 扣除用户资产
$userStockSgdName = (new UserStockSgdModel())->getName();
$beforeAmount = Db::name($userStockSgdName)->where('stock_id', 'SGD')->where('user_id', $userId)->value('usable_num');
if ($beforeAmount < $amount) {
Db::rollback();
return $this->toData('1', 'assert not enough', []);
}
$updateNum = Db::name($userStockSgdName)->where('stock_id', 'SGD')->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 UserStockSgdLogModel();
$userStockLog->user_id = $userId;
$userStockLog->change_type = 15; // 新股申购扣减费用
$userStockLog->stock_id = 'SGD';
$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 = Db::name($userStockSgdName)->where('stock_id', 'SGD')->where('user_id', $userId)->value('usable_num');
if ($beforeFee < $fee) {
Db::rollback();
return $this->toData('1', 'assert not enough', []);
}
$updateNum = Db::name($userStockSgdName)->where('stock_id', 'SGD')->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 UserStockSgdLogModel;
$userStockLog->user_id = $userId;
$userStockLog->change_type = 16;
$userStockLog->stock_id = 'SGD';
$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');
$preInStock = PreSgdStockModel::where('stock_code', $param['stock_code'])
->where('status', PreSgdStockModel::STATUS_ON)
->where('is_delete', PreSgdStockModel::IS_DELETE_NO)
->where('is_post_pay', PreSgdStockModel::IS_POST_PAY_YES)
->whereTime('pay_deadline_time', '>=', $now)
->find();
if (empty($preInStock)) {
return $this->toData('1', 'Payment deadline exceeded', []);
}
$hasOrder = UserSgdPreStockOrderModel::where('user_id', $userId)->where('id', $param['id'])->where('pay_type', UserSgdPreStockOrderModel::PAY_TYPE_TWO)->where('status', UserSgdPreStockOrderModel::STATUS_POST_PAY)->find();
if (empty($hasOrder)) {
return $this->toData('1', 'Params error3', []);
}
$orderNo = $hasOrder->order_no;
Db::startTrans();
if ($preInStock->sign_status == PreSgdStockModel::SIGN_STATUS_DONE && strtotime($preInStock->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 = UserStockSgdModel::where('stock_id', 'SGD')->where('user_id', $userId)->value('usable_num');
if ($beforeAmount < $amount) {
Db::rollback();
return $this->toData('1', 'assert not enough', []);
}
$updateNum = UserStockSgdModel::where('stock_id', 'SGD')->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 UserStockSgdLogModel();
$userStockLog->user_id = $userId;
$userStockLog->change_type = 15; // 新股申购扣减费用
$userStockLog->stock_id = 'SGD';
$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 = UserStockSgdModel::where('stock_id', 'SGD')->where('user_id', $userId)->value('usable_num');
if ($beforeFee < $fee) {
Db::rollback();
return $this->toData('1', 'assert not enough', []);
}
$updateNum = UserStockSgdModel::where('stock_id', 'SGD')->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 UserStockSgdLogModel;
$userStockLog->user_id = $userId;
$userStockLog->change_type = 16;
$userStockLog->stock_id = 'SGD';
$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 = UserSgdPreStockOrderModel::where('id', $param['id'])->update(['status' => UserSgdPreStockOrderModel::STATUS_SIGNING, 'update_time' => $now]);
if (!$bool) {
Db::rollback();
return $this->toData('1', 'update order error', []);
}
} elseif ($preInStock->sign_status == PreSgdStockModel::SIGN_STATUS_NO && strtotime($preInStock->get_time) >= strtotime($now)) {
//未签名
$amount = $hasOrder->amount;
$fee = $hasOrder->fee;
// 扣除用户资产
$beforeAmount = UserStockSgdModel::where('stock_id', 'SGD')->where('user_id', $userId)->value('usable_num');
if ($beforeAmount < $amount) {
Db::rollback();
return $this->toData('1', 'assert not enough', []);
}
$updateNum = UserStockSgdModel::where('stock_id', 'SGD')->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 UserStockSgdLogModel();
$userStockLog->user_id = $userId;
$userStockLog->change_type = 15; // 新股申购扣减费用
$userStockLog->stock_id = 'SGD';
$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 = UserStockSgdModel::where('stock_id', 'SGD')->where('user_id', $userId)->value('usable_num');
if ($beforeFee < $fee) {
Db::rollback();
return $this->toData('1', 'assert not enough', []);
}
$updateNum = UserStockSgdModel::where('stock_id', 'SGD')->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 UserStockSgdLogModel;
$userStockLog->user_id = $userId;
$userStockLog->change_type = 16;
$userStockLog->stock_id = 'SGD';
$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 = UserSgdPreStockOrderModel::where('id', $param['id'])->update(['status' => UserSgdPreStockOrderModel::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 = UserSgdPreStockOrderModel::whereIn('status',$statusArr)->where('user_id', $userId)->order('update_time','desc')->page($param['page'], $param['limit'])->select();
$total = UserSgdPreStockOrderModel::whereIn('status', $statusArr)->where('user_id', $userId)->count();
$rows = [];
if (!$list->isEmpty()) {
$stockIdList = [];
foreach ($list as $item) {
$stockIdList[] = $item->pre_stock_id;
}
$stockList = PreSgdStockModel::where('id', 'in', $stockIdList)->column(['*'], 'id');
// 计算手续费
$purchaseFee = FeeSettingModel::where('market_type', StockMarketModel::STOCK_MARKET_SGD)->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 == PreSgdStockModel::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 == UserSgdPreStockOrderModel::PAY_TYPE_TWO && $item->status == UserSgdPreStockOrderModel::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' => StockOptionInrListModel::$tapeList,
'stock_type_list' => PreSgdStockModel::$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 = UserSgdPreStockOrderModel::where('user_id', $userId)->where('id', $param['id'])->find();
if (empty($order)) {
return $this->toData('1', 'Params error', []);
}
$stock = PreSgdStockModel::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 == PreSgdStockModel::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' => StockOptionInrListModel::$tapeList,
'stock_type_list' => PreSgdStockModel::$stockTypeList,
]]);
} catch (\Exception $exception) {
return $this->toData('1', 'System error', []);
}
}
}

672
app/home/service/PreThaStockService.php

@ -0,0 +1,672 @@
<?php
namespace app\home\service;
use app\model\FeeSettingModel;
use app\model\PreThaStockModel;
use app\model\StockThaListModel;
use app\model\StockMarketModel;
use app\model\UserStockThaLogModel;
use app\model\UserStockThaModel;
use app\model\UserThaPreStockOrderModel;
use think\facade\Db;
use think\facade\Log;
class PreThaStockService extends BaseHomeService
{
// 列表
public function index($param)
{
try {
if (empty($param['page']) || !is_numeric($param['page']) || empty($param['limit']) || !is_numeric($param['limit'])) {
$param['page'] = 1;
$param['limit'] = 10;
}
$where = [];
$where[] = ['is_delete', '=', PreThaStockModel::IS_DELETE_NO];
$where[] = ['status', '=', PreThaStockModel::STATUS_ON];
$query = PreThaStockModel::where($where);
$totalQuery = PreThaStockModel::where($where);
// 申购状态筛选 1 可申购 2 带中签 3 待上市 4 已上市
if (isset($param['open_status']) && in_array($param['open_status'], ['1', '2', '3', '4'])) {
switch ($param['open_status']) {
case '1':
$query = $query->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', '=', PreThaStockModel::SIGN_STATUS_NO);
$totalQuery = $totalQuery->whereTime('end_time', '<', date('Y-m-d H:i:s'))->where('sign_status', '=', PreThaStockModel::SIGN_STATUS_NO);
break;
case '3':
$query = $query->where('sign_status', '=', PreThaStockModel::SIGN_STATUS_DONE)->where('open_status', PreThaStockModel::OPEN_STATUS_NO);
$totalQuery = $totalQuery->where('sign_status', '=', PreThaStockModel::SIGN_STATUS_DONE)->where('open_status', PreThaStockModel::OPEN_STATUS_NO);
break;
case '4':
$query = $query->where('open_status', PreThaStockModel::OPEN_STATUS_HAD);
$totalQuery = $totalQuery->where('open_status', PreThaStockModel::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 == PreThaStockModel::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 == PreThaStockModel::SIGN_STATUS_DONE) $progressStatus = 3;
if ($item->is_post_pay == PreThaStockModel::IS_POST_PAY_YES && $item->pay_deadline_time < date('Y-m-d H:i:s')) $progressStatus = 4;
if ($item->open_status == PreThaStockModel::OPEN_STATUS_HAD) $progressStatus = $item->is_post_pay == PreThaStockModel::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' => StockThaListModel::$tapeList,
'stock_type_list' => PreThaStockModel::$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 = PreThaStockModel::where('id', $param['id'])->where('is_delete', PreThaStockModel::IS_DELETE_NO)->where('status', PreThaStockModel::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 == PreThaStockModel::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 == PreThaStockModel::SIGN_STATUS_DONE) $progressStatus = 3;
if ($preStock->is_post_pay == PreThaStockModel::IS_POST_PAY_YES && $preStock->pay_deadline_time < date('Y-m-d H:i:s')) $progressStatus = 4;
if ($preStock->open_status == PreThaStockModel::OPEN_STATUS_HAD) $progressStatus = $preStock->is_post_pay == PreThaStockModel::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' => StockThaListModel::$tapeList,
'stock_type_list' => PreThaStockModel::$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', []);
}
$preThaStock = PreThaStockModel::where('id', $param['id'])
->where('status', PreThaStockModel::STATUS_ON)
->where('is_delete', PreThaStockModel::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($preThaStock)) {
return $this->toData('1', 'Params error', []);
}
$hasOrder = UserThaPreStockOrderModel::where('user_id', $userId)->where('pre_stock_id', $param['id'])->count();
if ($preThaStock->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'] < $preThaStock->min) {
return $this->toData('1', 'Order quantity less than the minimum', []);
}
if ($preThaStock->max > 0 && $param['num'] > $preThaStock->max) {
return $this->toData('1', 'Order quantity greater than maximum', []);
}
if ($preThaStock->price <= 0) {
return $this->toData('1', 'Price error', []);
}
// 支付类型
if (empty($param['pay_type']) || !is_numeric($param['pay_type']) || !in_array($param['pay_type'], [UserThaPreStockOrderModel::PAY_TYPE_ONE, UserThaPreStockOrderModel::PAY_TYPE_TWO])) {
return $this->toData('1', 'Params error', []);
}
// 计算金额
$amount = bcmul($param['num'], $preThaStock->price, 18);
// 计算手续费
$purchaseFee = FeeSettingModel::where('market_type', StockMarketModel::STOCK_MARKET_TG)->value('purchase_fee');
if ($purchaseFee <= 0) {
$fee = 0;
} else {
$fee = bcmul($amount, $purchaseFee, 18);
}
Db::startTrans();
// 生成订单
$orderNo = $this->generateOrderNumber(20);
$order = new UserThaPreStockOrderModel;
$order->user_id = $userId;
$order->pre_stock_id = $preThaStock->id;
$order->status = $param['pay_type'] == 1 ? UserThaPreStockOrderModel::STATUS_DOING : UserThaPreStockOrderModel::STATUS_POST_PAY;
$order->pay_type = $param['pay_type'];
$order->order_no = $orderNo;
$order->num = $param['num'];
$order->get_num = 0;
$order->price = $preThaStock->price;
$order->amount = $amount;
$order->get_amount = 0;
$order->fee = $fee;
$order->get_fee = 0;
$order->fee_rate = $purchaseFee;
$order->get_time = $preThaStock->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', []);
}
// 扣除用户资产
$userStockName = (new UserStockThaModel())->getName();
$beforeAmount = Db::name($userStockName)->where('stock_id', 'THB')->where('user_id', $userId)->value('usable_num');
if ($beforeAmount < $amount) {
Db::rollback();
return $this->toData('1', 'assert not enough', []);
}
$updateNum = Db::name($userStockName)->where('stock_id', 'THB')->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 UserStockThaLogModel;
$userStockLog->user_id = $userId;
$userStockLog->change_type = 15; // 新股申购扣减费用
$userStockLog->stock_id = 'THB';
$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 = Db::name($userStockName)->where('stock_id', 'THB')->where('user_id', $userId)->value('usable_num');
if ($beforeFee < $fee) {
Db::rollback();
return $this->toData('1', 'assert not enough', []);
}
$updateNum = Db::name($userStockName)->where('stock_id', 'THB')->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 UserStockThaLogModel();
$userStockLog->user_id = $userId;
$userStockLog->change_type = 16;
$userStockLog->stock_id = 'THB';
$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();
Log::error("order tha exception " . $exception->getMessage());
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');
$preInStock = PreThaStockModel::where('stock_code', $param['stock_code'])
->where('status', PreThaStockModel::STATUS_ON)
->where('is_delete', PreThaStockModel::IS_DELETE_NO)
->where('is_post_pay', PreThaStockModel::IS_POST_PAY_YES)
->whereTime('pay_deadline_time', '>=', $now)
->find();
if (empty($preInStock)) {
return $this->toData('1', 'Payment deadline exceeded', []);
}
$hasOrder = UserThaPreStockOrderModel::where('user_id', $userId)->where('id', $param['id'])->where('pay_type', UserThaPreStockOrderModel::PAY_TYPE_TWO)->where('status', UserThaPreStockOrderModel::STATUS_POST_PAY)->find();
if (empty($hasOrder)) {
return $this->toData('1', 'Params error3', []);
}
$orderNo = $hasOrder->order_no;
Db::startTrans();
if ($preInStock->sign_status == PreThaStockModel::SIGN_STATUS_DONE && strtotime($preInStock->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 = UserStockThaModel::where('stock_id', 'THB')->where('user_id', $userId)->value('usable_num');
if ($beforeAmount < $amount) {
Db::rollback();
return $this->toData('1', 'assert not enough', []);
}
$updateNum = UserStockThaModel::where('stock_id', 'THB')->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 UserStockThaLogModel();
$userStockLog->user_id = $userId;
$userStockLog->change_type = 15; // 新股申购扣减费用
$userStockLog->stock_id = 'THB';
$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 = UserStockThaModel::where('stock_id', 'THB')->where('user_id', $userId)->value('usable_num');
if ($beforeFee < $fee) {
Db::rollback();
return $this->toData('1', 'assert not enough', []);
}
$updateNum = UserStockThaModel::where('stock_id', 'THB')->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 UserStockThaLogModel;
$userStockLog->user_id = $userId;
$userStockLog->change_type = 16;
$userStockLog->stock_id = 'THB';
$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 = UserThaPreStockOrderModel::where('id', $param['id'])->update(['status' => UserThaPreStockOrderModel::STATUS_SIGNING, 'update_time' => $now]);
if (!$bool) {
Db::rollback();
return $this->toData('1', 'update order error', []);
}
} elseif ($preInStock->sign_status == PreThaStockModel::SIGN_STATUS_NO && strtotime($preInStock->get_time) >= strtotime($now)) {
//未签名
$amount = $hasOrder->amount;
$fee = $hasOrder->fee;
// 扣除用户资产
$beforeAmount = UserStockThaModel::where('stock_id', 'THB')->where('user_id', $userId)->value('usable_num');
if ($beforeAmount < $amount) {
Db::rollback();
return $this->toData('1', 'assert not enough', []);
}
$updateNum = UserStockThaModel::where('stock_id', 'THB')->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 UserStockThaLogModel();
$userStockLog->user_id = $userId;
$userStockLog->change_type = 15; // 新股申购扣减费用
$userStockLog->stock_id = 'THB';
$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 = UserStockThaModel::where('stock_id', 'THB')->where('user_id', $userId)->value('usable_num');
if ($beforeFee < $fee) {
Db::rollback();
return $this->toData('1', 'assert not enough', []);
}
$updateNum = UserStockThaModel::where('stock_id', 'THB')->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 UserStockThaLogModel;
$userStockLog->user_id = $userId;
$userStockLog->change_type = 16;
$userStockLog->stock_id = 'THB';
$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 = UserThaPreStockOrderModel::where('id', $param['id'])->update(['status' => UserThaPreStockOrderModel::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 = UserThaPreStockOrderModel::whereIn('status', $statusArr)->where('user_id', $userId)->order('update_time', 'desc')->page($param['page'], $param['limit'])->select();
$total = UserThaPreStockOrderModel::whereIn('status', $statusArr)->where('user_id', $userId)->count();
$rows = [];
if (!$list->isEmpty()) {
$stockIdList = [];
foreach ($list as $item) {
$stockIdList[] = $item->pre_stock_id;
}
$stockList = PreThaStockModel::where('id', 'in', $stockIdList)->column(['*'], 'id');
// 计算手续费
$purchaseFee = FeeSettingModel::where('market_type', StockMarketModel::STOCK_MARKET_TG)->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 == PreThaStockModel::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 == UserThaPreStockOrderModel::PAY_TYPE_TWO && $item->status == UserThaPreStockOrderModel::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' => StockThaListModel::$tapeList,
'stock_type_list' => PreThaStockModel::$stockTypeList,
]]);
} catch (\Exception $exception) {
return $this->toData('1', 'System error', [$exception->getMessage()]);
}
}
// 申购订单详情
public function detail($param, $userId)
{
try {
if (empty($param['id']) || !is_numeric($param['id'])) {
return $this->toData('1', 'Params error', []);
}
$order = UserThaPreStockOrderModel::where('user_id', $userId)->where('id', $param['id'])->find();
if (empty($order)) {
return $this->toData('1', 'Params error', []);
}
$stock = PreThaStockModel::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 == PreThaStockModel::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,
'order_no' => $order->order_no,
'fee' => $order->fee,
'get_fee' => $order->get_fee,
'create_time' => $order->create_time,
'get_time' => $order->get_time,
'open_time' => $stock->open_time,
'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' => StockThaListModel::$tapeList,
'stock_type_list' => PreThaStockModel::$stockTypeList,
]]);
} catch (\Exception $exception) {
return $this->toData('1', 'System error', []);
}
}
}

681
app/home/service/PreUsStockService.php

@ -0,0 +1,681 @@
<?php
namespace app\home\service;
use app\model\FeeSettingModel;
use app\model\PreUsStockModel;
use app\model\StockListModel;
use app\model\StockMarketModel;
use app\model\UserStockLogModel;
use app\model\UserStockModel;
use app\model\UserUsPreStockOrderModel;
use think\facade\Db;
class PreUsStockService extends BaseHomeService
{
// 列表
public function index($param)
{
try {
if (empty($param['page']) || !is_numeric($param['page']) || empty($param['limit']) || !is_numeric($param['limit'])) {
$param['page'] = 1;
$param['limit'] = 10;
}
$where = [];
$where[] = ['is_delete', '=', PreUsStockModel::IS_DELETE_NO];
$where[] = ['status', '=', PreUsStockModel::STATUS_ON];
$query = PreUsStockModel::where($where);
$totalQuery = PreUsStockModel::where($where);
// 申购状态筛选 1 可申购 2 带中签 3 待上市 4 已上市
if (isset($param['open_status']) && in_array($param['open_status'], ['1', '2', '3', '4'])) {
switch ($param['open_status']) {
case '1':
$query = $query->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', '=', PreUsStockModel::SIGN_STATUS_NO);
$totalQuery = $totalQuery->whereTime('end_time', '<', date('Y-m-d H:i:s'))->where('sign_status', '=', PreUsStockModel::SIGN_STATUS_NO);
break;
case '3':
$query = $query->where('sign_status', '=', PreUsStockModel::SIGN_STATUS_DONE)->where('open_status', PreUsStockModel::OPEN_STATUS_NO);
$totalQuery = $totalQuery->where('sign_status', '=', PreUsStockModel::SIGN_STATUS_DONE)->where('open_status', PreUsStockModel::OPEN_STATUS_NO);
break;
case '4':
$query = $query->where('open_status', PreUsStockModel::OPEN_STATUS_HAD);
$totalQuery = $totalQuery->where('open_status', PreUsStockModel::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 == PreUsStockModel::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 == PreUsStockModel::SIGN_STATUS_DONE) $progressStatus = 3;
if ($item->is_post_pay == PreUsStockModel::IS_POST_PAY_YES && $item->pay_deadline_time < date('Y-m-d H:i:s')) $progressStatus = 4;
if ($item->open_status == PreUsStockModel::OPEN_STATUS_HAD) $progressStatus = $item->is_post_pay == PreUsStockModel::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,
'pay_deadline_time' => $item->pay_deadline_time,
'progress_status' => $progressStatus,
'is_post_pay' => $item->is_post_pay,
];
}
}
return $this->toData('0', 'SUCCESS', ['list' => $rows, 'total' => $total, 'extend' => [
'tape_list' => StockListModel::$tapeList,
'stock_type_list' => PreUsStockModel::$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 = PreUsStockModel::where('id', $param['id'])->where('is_delete', PreUsStockModel::IS_DELETE_NO)->where('status', PreUsStockModel::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 == PreUsStockModel::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 == PreUsStockModel::SIGN_STATUS_DONE) $progressStatus = 3;
if ($preStock->is_post_pay == PreUsStockModel::IS_POST_PAY_YES && $preStock->pay_deadline_time < date('Y-m-d H:i:s')) $progressStatus = 4;
if ($preStock->open_status == PreUsStockModel::OPEN_STATUS_HAD) $progressStatus = $preStock->is_post_pay == PreUsStockModel::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' => StockListModel::$tapeList,
'stock_type_list' => PreUsStockModel::$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 error2', []);
}
$preUsStock = PreUsStockModel::where('id', $param['id'])
->where('status', PreUsStockModel::STATUS_ON)
->where('is_delete', PreUsStockModel::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($preUsStock)) {
return $this->toData('1', 'Params error3', []);
}
$hasOrder = UserUsPreStockOrderModel::where('user_id', $userId)->where('pre_stock_id', $param['id'])->count();
if ($preUsStock->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'] < $preUsStock->min) {
return $this->toData('1', 'Order quantity less than the minimum', []);
}
if ($preUsStock->max > 0 && $param['num'] > $preUsStock->max) {
return $this->toData('1', 'Order quantity greater than maximum', []);
}
if ($preUsStock->price <= 0) {
return $this->toData('1', 'Price error', []);
}
// 支付类型
if (empty($param['pay_type']) || !is_numeric($param['pay_type']) || !in_array($param['pay_type'], [UserUsPreStockOrderModel::PAY_TYPE_ONE, UserUsPreStockOrderModel::PAY_TYPE_TWO])) {
return $this->toData('1', 'Params error', []);
}
// 计算金额
$price = number_format($preUsStock->price, 18, '.', '');
$amount = bcmul($param['num'], $price, 18);
// 计算手续费
$purchaseFee = FeeSettingModel::where('market_type', StockMarketModel::STOCK_MARKET_USA)->value('purchase_fee');
if ($purchaseFee <= 0) {
$fee = 0;
} else {
$purchaseFee = number_format($purchaseFee, 18, '.', '');
$fee = bcmul($amount, $purchaseFee, 18);
}
Db::startTrans();
// 生成订单
$orderNo = $this->generateOrderNumber(20);
$order = new UserUsPreStockOrderModel;
$order->user_id = $userId;
$order->pre_stock_id = $preUsStock->id;
$order->status = $param['pay_type'] == 1 ? UserUsPreStockOrderModel::STATUS_DOING : UserUsPreStockOrderModel::STATUS_POST_PAY;
$order->pay_type = $param['pay_type'];
$order->order_no = $orderNo;
$order->num = $param['num'];
$order->get_num = 0;
$order->price = $preUsStock->price;
$order->amount = $amount;
$order->get_amount = 0;
$order->fee = $fee;
$order->get_fee = 0;
$order->fee_rate = $purchaseFee; // 手续费比率
$order->get_time = $preUsStock->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', []);
}
// 扣除用户资产
$userStockName = (new UserStockModel())->getName();
$beforeAmount = Db::name($userStockName)->where('stock_id', 'USD')->where('user_id', $userId)->value('usable_num');
if ($beforeAmount < $amount) {
Db::rollback();
return $this->toData('1', 'assert not enough', []);
}
$updateNum = Db::name($userStockName)->where('stock_id', 'USD')->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 UserStockLogModel;
$userStockLog->user_id = $userId;
$userStockLog->change_type = 15; // 新股申购扣减费用
$userStockLog->stock_id = 'USD';
$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 = Db::name($userStockName)->where('stock_id', 'USD')->where('user_id', $userId)->value('usable_num');
if ($beforeFee < $fee) {
Db::rollback();
return $this->toData('1', 'assert not enough', []);
}
$updateNum = Db::name($userStockName)->where('stock_id', 'USD')->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 UserStockLogModel;
$userStockLog->user_id = $userId;
$userStockLog->change_type = 16;
$userStockLog->stock_id = 'USD';
$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', []);
}
}
// 增加股票已经申购的数量
$num = Db::name((new PreUsStockModel())->getName())->where('id', $param['id'])->inc('had_get_num', $param['num'])->update(['update_time' => date('Y-m-d H:i:s')]);
if ($num <= 0) {
Db::rollback();
return $this->toData('1', 'update stock num error', []);
}
Db::commit();
return $this->toData('0', 'SUCCESS', [
]);
} catch (\Exception $exception) {
Db::rollback();
return $this->toData('1', 'System error', [$exception->getMessage()]);
}
}
// 后支付 - 支付
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');
$preUstock = PreUsStockModel::where('stock_code', $param['stock_code'])
->where('status', PreUsStockModel::STATUS_ON)
->where('is_delete', PreUsStockModel::IS_DELETE_NO)
->where('is_post_pay', PreUsStockModel::IS_POST_PAY_YES)
->whereTime('pay_deadline_time', '>=', $now)
->find();
if (empty($preUstock)) {
return $this->toData('1', 'Payment deadline exceeded', []);
}
$hasOrder = UserUsPreStockOrderModel::where('user_id', $userId)->where('id', $param['id'])->where('pay_type', UserUsPreStockOrderModel::PAY_TYPE_TWO)->where('status', UserUsPreStockOrderModel::STATUS_POST_PAY)->find();
if (empty($hasOrder)) {
return $this->toData('1', 'Params error3', []);
}
$orderNo = $hasOrder->order_no;
Db::startTrans();
if ($preUstock->sign_status == PreUsStockModel::SIGN_STATUS_DONE && strtotime($preUstock->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 = UserStockModel::where('stock_id', 'USD')->where('user_id', $userId)->value('usable_num');
if ($beforeAmount < $amount) {
Db::rollback();
return $this->toData('1', 'assert not enough', []);
}
$updateNum = UserStockModel::where('stock_id', 'USD')->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 UserStockLogModel();
$userStockLog->user_id = $userId;
$userStockLog->change_type = 15; // 新股申购扣减费用
$userStockLog->stock_id = 'USD';
$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 = UserStockModel::where('stock_id', 'USD')->where('user_id', $userId)->value('usable_num');
if ($beforeFee < $fee) {
Db::rollback();
return $this->toData('1', 'assert not enough', []);
}
$updateNum = UserStockModel::where('stock_id', 'USD')->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 UserStockLogModel;
$userStockLog->user_id = $userId;
$userStockLog->change_type = 16;
$userStockLog->stock_id = 'USD';
$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 = UserUsPreStockOrderModel::where('id', $param['id'])->update(['status' => UserUsPreStockOrderModel::STATUS_SIGNING, 'update_time' => $now]);
if (!$bool) {
Db::rollback();
return $this->toData('1', 'update order error', []);
}
} elseif ($preUstock->sign_status == PreUsStockModel::SIGN_STATUS_NO && strtotime($preUstock->get_time) >= strtotime($now)) {
//未签名
$amount = $hasOrder->amount;
$fee = $hasOrder->fee;
// 扣除用户资产
$beforeAmount = UserStockModel::where('stock_id', 'USD')->where('user_id', $userId)->value('usable_num');
if ($beforeAmount < $amount) {
Db::rollback();
return $this->toData('1', 'assert not enough', []);
}
$updateNum = UserStockModel::where('stock_id', 'USD')->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 UserStockLogModel();
$userStockLog->user_id = $userId;
$userStockLog->change_type = 15; // 新股申购扣减费用
$userStockLog->stock_id = 'USD';
$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 = UserStockModel::where('stock_id', 'USD')->where('user_id', $userId)->value('usable_num');
if ($beforeFee < $fee) {
Db::rollback();
return $this->toData('1', 'assert not enough', []);
}
$updateNum = UserStockModel::where('stock_id', 'USD')->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 UserStockLogModel;
$userStockLog->user_id = $userId;
$userStockLog->change_type = 16;
$userStockLog->stock_id = 'USD';
$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 = UserUsPreStockOrderModel::where('id', $param['id'])->update(['status' => UserUsPreStockOrderModel::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 = UserUsPreStockOrderModel::whereIn('status', $statusArr)->where('user_id', $userId)
->order('update_time', 'desc')->page($param['page'], $param['limit'])->select();
$total = UserUsPreStockOrderModel::where('status', $param['status'])->where('user_id', $userId)->count();
$rows = [];
if (!$list->isEmpty()) {
$stockIdList = [];
foreach ($list as $item) {
$stockIdList[] = $item->pre_stock_id;
}
$stockList = PreUsStockModel::where('id', 'in', $stockIdList)->column(['*'], 'id');
// 计算手续费
$purchaseFee = FeeSettingModel::where('market_type', StockMarketModel::STOCK_MARKET_USA)->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 == PreUsStockModel::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 == UserUsPreStockOrderModel::PAY_TYPE_TWO && $item->status == UserUsPreStockOrderModel::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' => StockListModel::$tapeList,
'stock_type_list' => PreUsStockModel::$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 = UserUsPreStockOrderModel::where('user_id', $userId)->where('id', $param['id'])->find();
if (empty($order)) {
return $this->toData('1', 'Params error', []);
}
$stock = PreUsStockModel::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 == PreUsStockModel::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,
'order_no' => $order->order_no,
'num' => $order->num,
'get_num' => $order->get_num,
'amount' => $order->amount,
'get_amount' => $order->get_amount,
'price' => $order->price,
'fee' => $order->fee,
'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' => StockListModel::$tapeList,
'stock_type_list' => PreUsStockModel::$stockTypeList,
]]);
} catch (\Exception $exception) {
return $this->toData('1', 'System error', []);
}
}
}

121
app/home/service/UserService.php

@ -7,6 +7,7 @@ use app\model\AwsIvsModel;
use app\model\CountryModel;
use app\model\CustomerRelationalModel;
use app\model\FileModel;
use app\model\PurchaseVipModel;
use app\model\UserChatGroupModel;
use app\model\UserChatLinkModel;
use app\model\UserContractModel;
@ -16,6 +17,7 @@ use app\model\UserLevelModel;
use app\model\UserLoanModel;
use app\model\UserLoginLog;
use app\model\UserModel;
use app\model\UserMoneyLogModel;
use app\model\UserMoneyModel;
use app\model\UserStockHkdModel;
use app\model\UserStockModel;
@ -24,6 +26,8 @@ use app\utility\UnqId;
use Couchbase\User;
use think\exception\ValidateException;
use think\facade\Cache;
use think\facade\Config;
use think\facade\Db;
use think\facade\Log;
use think\facade\Queue;
@ -193,7 +197,14 @@ class UserService extends BaseHomeService
$group_chat_uuid = $agentGroup->group_uuid;
}
// 检测用户是否充值过,充值过就标识为vip
// 检测用户是否为有效VIP [判断规则 - 用户购买过VIP, 每个VIP有效期30天]
$isVip = false;
$purchaseInfo = PurchaseVipModel::where(['user_id'=>$userId])->order('id', 'desc')->find();
if (!empty($purchaseInfo)) {
if ($purchaseInfo->expire >= date("Y-m-d H:i:s")) {
$isVip = true;
}
}
// 返回数据
return $this->toData('0', 'Modification successful.', [
@ -223,12 +234,120 @@ class UserService extends BaseHomeService
'customer_chat_avatar' => '/bs/image/default.jpeg',
'group_chat_name' => $group_chat_name,
'group_chat_uuid' => $group_chat_uuid,
'is_vip' => $isVip,
]);
} catch (\Exception $exception) {
return $this->toData('100500', 'The system is busy.', [$exception->getMessage(), $exception->getTrace()]);
}
}
// 用户购买VIP
public function purchaseVip($userId)
{
try {
if (empty($userId) || $userId <= 0) {
return $this->toData('100403', 'Please log in first', []);
}
$info = UserModel::getFieldsByUserId('trade_password,lever_status,gender,last_name,first_name,real_status,country_id,user_no,nick_name,email,phone_number,country_code,agent_id,is_real,head_img_id,invite_code,is_test_user', $userId);
if (empty($info)) {
return $this->toData('100400', 'The user does not exist.', []);
}
// 获取购买VIP所需的配置
$vipPurchaseCfg = Config::get('common.vip_purchase');
if (empty($vipPurchaseCfg)) {
return $this->toData('100400', 'vip config error', []);
}
// 购买vip所需的货币类型检测
if (empty($vipPurchaseCfg['stock_id'])) {
return $this->toData('100400', 'vip config error', []);
}
$stockId = $vipPurchaseCfg['stock_id'];
// vip价格检测
if (!isset($vipPurchaseCfg['vip_price']) || $vipPurchaseCfg['vip_price'] <= 0) {
return $this->toData('100400', 'vip config error', []);
}
$vipPrice = $vipPurchaseCfg['vip_price'];
// vip有效天数检测
if (!isset($vipPurchaseCfg['vip_day']) || $vipPurchaseCfg['vip_day'] <= 0) {
return $this->toData('100400', 'vip config error', []);
}
$vipDay = $vipPurchaseCfg['vip_day'];
// 查询用户余额是否足够
$userMoney = UserMoneyModel::where(['user_id'=>$userId,'stock_id'=>$stockId])->find();
if (empty($userMoney)) {
return $this->toData('100400', ' The user USD balance is insufficient ', []);
}
$userMoneyNum = $userMoney->usable_num;
if ($userMoneyNum < $vipPrice) {
return $this->toData('100400', ' The user USD balance is insufficient ', []);
}
// 查询是否有购买vip记录, 计算用户vip到期时间
$expireTime = date("Y-m-d H:i:s");
$vipLog = PurchaseVipModel::where(['user_id'=>$userId])->order('id', 'desc')->find();
if (!empty($vipLog)) {
if (empty($vipLog->expire)) {
return $this->toData('100400', ' The vip expire error ', []);
}
if ($vipLog->expire >= $expireTime) {
$expireTimestamp = strtotime('+30 days', strtotime($vipLog->expire));
$expireTime = date("Y-m-d H:i:s", $expireTimestamp);
}
} else {
$expireTimestamp = strtotime('+30 days', time());
$expireTime = date("Y-m-d H:i:s", $expireTimestamp);
}
// 记录购买vip信息, 扣除用户金额
Db::transaction(function () use ($userId, $userMoneyNum, $vipPrice, $expireTime, $stockId) {
// 添加购买vip记录
PurchaseVipModel::create([
'user_id' => $userId,
'amount' => $vipPrice,
'stock_id' => $stockId,
'expire' => $expireTime
]);
// 扣除用户USD
UserMoneyModel::where(['user_id'=>$userId,'stock_id'=>$stockId])->where('usable_num', ">=", $vipPrice)->dec('usable_num', $vipPrice)->update();
// 添加用户USD变更日志
UserMoneyLogModel::create([
'user_id' => $userId,
'change_type' => 101,
'stock_id' => $stockId,
'before_num' => $userMoneyNum,
'change_num' => -$vipPrice,
'order_id' => uniqid('vip_', true),
]);
});
return $this->toData('0', 'successful', ['expire'=>$expireTime]);
} catch (\Exception $exception) {
return $this->toData('100500', 'The system is busy.', [$exception->getMessage(), $exception->getTrace()]);
}
}
// 用户购买VIP记录列表
public function purchaseVipLog($userId, $param)
{
try {
if (!isset($param['page']) || !isset($param['limit'])) {
return $this->toData('100403', 'Missing parameter', []);
}
$list = PurchaseVipModel::where(['user_id'=>$userId])->order('id', 'desc')->paginate([
'list_rows' => $param['limit'],
'page' => $param['page'],
]);
return $this->toData('0', 'Successful', [
'list' => $list->items(), // 当前页的数据
'page' => $list->currentPage(), // 当前页码
'total' => $list->total(), // 总记录数
'last_page' => $list->lastPage(), // 最后一页页码
]);
} catch (\Exception $exception) {
return $this->toData('100500', 'The system is busy.', [$exception->getMessage(), $exception->getTrace()]);
}
}
// 查询代理下的一个主播信息
public function getAnchorForAgent($userId)
{

17
app/home/service/VideoService.php

@ -28,4 +28,21 @@ class VideoService extends BaseHomeService
return $this->toData('100500', 'The system is busy.', []);
}
}
public function getVideoOnDemandDetail($param): array
{
try {
if (empty($param['id']) || !is_numeric($param['id'])) {
return $this->toData('1', '参错错误');
}
$info = VideoOnDemandModel::where(['id'=>$param['id']])->find();
if (empty($info)) {
return $this->toData('0', 'Successful', []);
}
return $this->toData('0', 'Successful', $info->toArray());
} catch (\Exception $exception) {
return $this->toData('100500', 'The system is busy.', []);
}
}
}

4
app/home/validate/UserValidate.php

@ -22,8 +22,8 @@ class UserValidate extends BaseHomeValidate
'password' => 'require|isString',
'password_new' => 'require|isString|length:6,150',
'nick_name' => 'require|isString|length:2,100',
'first_name' => 'isString|length:1,100',
'last_name' => 'isString|length:1,100',
'first_name' => 'isString|length:2,100',
'last_name' => 'isString|length:2,100',
'gender' => 'isString|in:0,1,2',
];

79
app/model/ForexListMode.php

@ -0,0 +1,79 @@
<?php
namespace app\model;
/**
* @property int id
* @property string trade_name
* @property string status
* @property string is_owner
* @property string logo_link
* @property string face_value
* @property string info
* @property string sort
* @property string min_pry
* @property string max_pry
* @property string compel_num
* @property string keep_decimal
* @property string create_time
* @property string update_time
*/
class ForexListMode extends BaseModel
{
protected $name = 'forex_list';
protected $pk = 'id';
public static function getMarketList($data): array
{
$where=[
['status','=',1]
];
if(!empty($data['trade_name'])){
$where[]=[
'trade_name','like',strtoupper($data['trade_name']).'%'
];
}
if($data['page']<1){
$data['page']=1;
}
if($data['page_size']<1){
$data['page_size']=10;
}
$count=self::where($where)->count();
$list = self::where($where)->field('trade_name as name,trade_name as code')->page($data['page'],$data['page_size'])->select();
if(empty($list)){
return [];
}
return [
'total'=>$count,
'list'=>$list->toArray(),
];
}
public static function existMarket($trade_name):bool
{
$id=self::where('trade_name',$trade_name)->value('id');
return $id >0;
}
public static function getMarketFaceList($type=0)
{
$list=self::where('status',1)->field('face_value,trade_name as name,trade_name as code,sort,max_pry,min_pry')->select();
if(empty($list)){
return [];
}
$list=$list->toArray();
if($type==1){
foreach ($list as $val){
$face_list[$val['name']]=$val['face_value'];
}
}else{
$face_list=$list;
}
return $face_list;
}
}

7
app/model/PurchaseVipModel.php

@ -0,0 +1,7 @@
<?php
namespace app\model;
class PurchaseVipModel extends BaseModel
{
protected $name = 'purchase_vip';
}

726
composer.lock

File diff suppressed because it is too large

8
config/common.php

@ -12,4 +12,10 @@ return [
'chat_server' => [
'bse_url' => 'https://chat.jdtest88.com', //测试环境-chat服务api域名
],
];
// VIP购买配置
'vip_purchase' => [
'vip_price' => 30, // vip价格
'vip_day' => 30, // vip有效期 30天
'stock_id' => 'USD' // 购买VIP所需的货币类型
],
];

Loading…
Cancel
Save