From bbad7e717e21dd67d6cca89f11a7135b6a11778e Mon Sep 17 00:00:00 2001 From: chuan <2154243450@qq.com> Date: Fri, 17 Jan 2025 11:07:50 +0800 Subject: [PATCH] =?UTF-8?q?=E6=81=A2=E5=A4=8D=E4=BA=8E=E6=B5=8B=E8=AF=95?= =?UTF-8?q?=E7=8E=AF=E5=A2=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/admin/controller/Test.php | 2 +- app/admin/controller/Upload.php | 2 + app/admin/route/app.php | 9 +- app/admin/service/AdminService.php | 12 +- app/admin/service/AgentService.php | 13 +- app/admin/service/RechargeService.php | 3 +- app/home/controller/News.php | 15 +- app/home/controller/User.php | 13 + app/home/controller/Video.php | 8 + app/home/route/app.php | 9 +- .../service/Copy of Copy of UserService.php | 1605 +++++++++++++++++ app/home/service/Copy of UserService.php | 1605 +++++++++++++++++ app/home/service/PreHkdStockService.php | 665 +++++++ app/home/service/PreIdnStockService.php | 675 +++++++ app/home/service/PreInStockService.php | 670 +++++++ app/home/service/PreMysStockService.php | 672 +++++++ app/home/service/PreSgdStockService.php | 670 +++++++ app/home/service/PreThaStockService.php | 672 +++++++ app/home/service/PreUsStockService.php | 681 +++++++ app/home/service/UserService.php | 121 +- app/home/service/VideoService.php | 17 + app/home/validate/UserValidate.php | 4 +- app/model/ForexListMode.php | 79 + app/model/PurchaseVipModel.php | 7 + composer.lock | 726 ++++---- config/common.php | 8 +- 26 files changed, 8595 insertions(+), 368 deletions(-) create mode 100644 app/home/service/Copy of Copy of UserService.php create mode 100644 app/home/service/Copy of UserService.php create mode 100644 app/home/service/PreHkdStockService.php create mode 100644 app/home/service/PreIdnStockService.php create mode 100644 app/home/service/PreInStockService.php create mode 100644 app/home/service/PreMysStockService.php create mode 100644 app/home/service/PreSgdStockService.php create mode 100644 app/home/service/PreThaStockService.php create mode 100644 app/home/service/PreUsStockService.php create mode 100644 app/model/ForexListMode.php create mode 100644 app/model/PurchaseVipModel.php diff --git a/app/admin/controller/Test.php b/app/admin/controller/Test.php index 185f7ce..772bcdb 100644 --- a/app/admin/controller/Test.php +++ b/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")]]); } } \ No newline at end of file diff --git a/app/admin/controller/Upload.php b/app/admin/controller/Upload.php index d2b38df..2b82a91 100644 --- a/app/admin/controller/Upload.php +++ b/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', // 设置文件为公开可读 ]); // 记录上传的文件 diff --git a/app/admin/route/app.php b/app/admin/route/app.php index a8fa100..41be364 100644 --- a/app/admin/route/app.php +++ b/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'); diff --git a/app/admin/service/AdminService.php b/app/admin/service/AdminService.php index a50fed9..762e543 100644 --- a/app/admin/service/AdminService.php +++ b/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()]); } diff --git a/app/admin/service/AgentService.php b/app/admin/service/AgentService.php index cec7c6e..7a6231d 100644 --- a/app/admin/service/AgentService.php +++ b/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'], diff --git a/app/admin/service/RechargeService.php b/app/admin/service/RechargeService.php index e758e49..e6c29ce 100644 --- a/app/admin/service/RechargeService.php +++ b/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 } } -} \ No newline at end of file +} diff --git a/app/home/controller/News.php b/app/home/controller/News.php index aeec1e1..ba249de 100644 --- a/app/home/controller/News.php +++ b/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'] ]); } diff --git a/app/home/controller/User.php b/app/home/controller/User.php index 8fa5169..fe6a274 100644 --- a/app/home/controller/User.php +++ b/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); diff --git a/app/home/controller/Video.php b/app/home/controller/Video.php index 34db895..727c01a 100644 --- a/app/home/controller/Video.php +++ b/app/home/controller/Video.php @@ -1,5 +1,6 @@ getVideoOnDemandList($this->request->post()); return json($returnData); } + + // 获取某个点播配置详情 + public function videoOnDemandDetail(): Json + { + $returnData = (new VideoService())->getVideoOnDemandDetail($this->request->post()); + return json($returnData); + } } diff --git a/app/home/route/app.php b/app/home/route/app.php index 9db9446..2a92661 100644 --- a/app/home/route/app.php +++ b/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); diff --git a/app/home/service/Copy of Copy of UserService.php b/app/home/service/Copy of Copy of UserService.php new file mode 100644 index 0000000..42697a9 --- /dev/null +++ b/app/home/service/Copy of Copy of UserService.php @@ -0,0 +1,1605 @@ +createUserLevel($user_id, $parent_id); + (new TeamService())->regBrokerage($data['parent_id'], $data['grandpa_id'], $data['top_id']); + } + $this->initUserWallet($user_id); + } + + /** + * 处理用户等级关系 + * @param int $user_id + * @param int $parent_id + * @return bool + */ + private function createUserLevel(int $user_id, int $parent_id) + { + //插入用户等级关系 + if ($parent_id > 0) { + $parent_info = UserLevelModel::getUserLevelById($parent_id); + $grandpa_id = $parent_info['parent_id']; + $top_id = $parent_info['grandpa_id']; + } else { + $grandpa_id = 0; + $top_id = 0; + } + $data['user_id'] = $user_id; + $data['parent_id'] = $parent_id; + $data['grandpa_id'] = $grandpa_id; + $data['top_id'] = $top_id; + UserLevelModel::InsertUserLevel($data); + return $data; + } + + public function getUserLevel(int $user_id) + { + $level_info = UserLevelModel::getUserLevelById($user_id); + $this->setUserLevel($user_id, $level_info); + } + + /** + * 初始化各钱包数据 U数据 + * @param int $user_id + * @return void + */ + private function initUserWallet(int $user_id) + { + if(env('ACCOUT_TYPE.ALL_IN_ONE')==1){ + UserMoneyModel::InsertUserMoneyk([ + 'user_id' => $user_id, + 'stock_id' => 'USD', + 'usable_num' => 0, + 'frozen_num' => 0, + ]); + }else{ + if (env('FEATURE.HAS_STOCK_US')) { + UserStockModel::InsertUserStock([ + 'user_id' => $user_id, + 'stock_id' => 'USD', + 'usable_num' => 0, + 'frozen_num' => 0, + ]); + } + if (env('FEATURE.HAS_DIGITAL')) { + UserDigitalModel::InsertUserDigital([ + 'user_id' => $user_id, + 'digital_id' => 'USDT', + 'usable_num' => 0, + 'frozen_num' => 0, + ]); + } + if (env('FEATURE.HAS_CONTRACT')) { + UserContractModel::InsertUserContract([ + 'user_id' => $user_id, + 'contract_id' => 'USDT', + 'usable_num' => 0, + 'frozen_num' => 0, + ]); + } + } + + + } + + /** + * @desc 获取用户信息 + * @param $userId + * @return array + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\DbException + * @throws \think\db\exception\ModelNotFoundException + */ + public function getUserInfo($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,is_real,head_img_id,invite_code,is_test_user', $userId); + if (empty($info)) { + return $this->toData('100400', 'The user does not exist.', []); + } + + // 获取国家名称 + $countryId = $info['country_id']; + + $countryName = ''; + if ($countryId > 0) { + $countryName = CountryModel::getNameById($countryId); + } + + // 获取头像 + $headPath = env('USER.DEFAULT_HEAD_IMG_PATH'); + if ($info['head_img_id'] > 0) { + $headPath = FileModel::getFilePath($info['head_img_id']); + } + + $key = 'LEVERAGE:' . $userId; + $leverageNum = Cache::store('redis')->get($key); + if (empty($leverageNum)) { + $key = 'LEVERAGE:0'; + $leverageNum = Cache::store('redis')->get($key); + } + $leverageNum= empty($leverageNum) ? 1: $leverageNum; + + // 查询用户的chat_uuid + $userChatInfo = UserChatLinkModel::where('user_id', $userId)->find(); + $userChatUuid = ""; + $userChatName = ""; + if (!empty($userChatInfo)) { + $userChatUuid = $userChatInfo->chat_uuid; + $userChatName = $userChatInfo->chat_name; + } + // 查询用户绑定的客服chat_uuid + $customerChatUuid = ""; + $customerChatName = ""; + Log::info("查询user_info user_id=".$userId); + $customerRelationInfo = CustomerRelationalModel::where('user_id', $userId)->find(); //查询用户关联的客服账号信息 + if ($customerRelationInfo) { + $customerChatInfo = UserChatLinkModel::where(['user_id'=>$customerRelationInfo->customer_id, 'user_type'=>2])->find(); //查询客服的chat账号 + if ($customerChatInfo) { + $customerChatUuid = $customerChatInfo->chat_uuid; + $customerChatName = $customerChatInfo->chat_name; + } + } + + + // 返回数据 + return $this->toData('0', 'Modification successful.', [ + 'logo' => $headPath, + 'userId' => $userId, + 'userNo' => $info['user_no'], + 'nickName' => $info['nick_name'], + 'nation' => $info['country_code'], + 'phone' => $info['phone_number'], + 'email' => $info['email'], + 'isReal' => $info['is_real'], + 'is_test_user' => $info['is_test_user'], + 'real_status' => $info['real_status'], + 'inviteCode' => $info['invite_code'], + 'firstName' => $info['first_name'], + 'lastName' => $info['last_name'], + 'gender' => (string)$info['gender'], + 'isSetPayPassword' => $info['trade_password'] ? '1' : '0', + 'country' => $countryName, + 'countryId' => $countryId, + 'lever_status' => $info['lever_status'], + 'leverage_num' =>$leverageNum, + 'user_chat_uuid' => $userChatUuid, + 'user_chat_name' => $userChatName, + 'customer_chat_uuid' => $customerChatUuid, + 'customer_chat_name' => $customerChatName + ]); + } catch (\Exception $exception) { + return $this->toData('100500', 'The system is busy.', [$exception->getMessage(), $exception->getTrace()]); + } + } + + /** + * @desc 设置用户国家 + * @param $userId + * @param $param + * @return array + */ + public function setCountry($userId, $param): array + { + try { + // 主键 + if (empty($userId) || $userId <= 0) { + return $this->toData('100403', 'Please log in first.', []); + } + // 邮件注册参数校验 + validate(UserValidate::class)->scene('setCountry')->check($param); + $countryId = $param['country_id']; + + // 国家是否存在 + $country = CountryModel::getById($countryId); + if (empty($country)) { + return $this->toData('100400', 'Unsupported country or region.', []); + } + + // 是否是黑名单国家 + if ($this->checkForbidNation($country['code'])) { + return $this->toData('100400', 'Unsupported country or region.', []); + } + + // 设置 + UserModel::updateFieldsByUserId(['country_id' => $country['id']], $userId); + return $this->toData('0', 'Modification successful.'); + } catch (ValidateException $validateException) { + $message = $validateException->getMessage(); + return $this->toData('100400', $message, []); + } catch (\Exception $exception) { + return $this->toData('100500', 'The system is busy.', [$exception->getMessage(), $exception->getTrace()]); + } + } + + /** + * @desc 更新用户头像 + * @param $userId + * @param $param + * @return array + */ + public function updateHeadImg($userId, $param): array + { + try { + // 主键 + if (empty($userId) || $userId <= 0) { + return $this->toData('100403', 'Please log in first.', []); + } + + // 参数校验 + validate(UserValidate::class)->scene('updateHeadImg')->check($param); + $fileId = $param['file_id']; + + // 文件是否存在 + $file = FileModel::getById($fileId); + if (empty($file)) { + return $this->toData('100400', 'The file does not exist.', []); + } + + + // 设置 + UserModel::updateFieldsByUserId(['head_img_id' => $fileId], $userId); + return $this->toData('0', 'Modification successful.'); + } catch (ValidateException $validateException) { + $message = $validateException->getMessage(); + return $this->toData('100400', $message, []); + } catch (\Exception $exception) { + return $this->toData('100500', 'The system is busy.', []); + } + } + + /** + * @desc 设置用户 昵称 性别 名字信息 + * @param $userId + * @param $param + * @return array + */ + public function updateInfo($userId, $param): array + { + try { + // 主键 + if (empty($userId) || $userId <= 0) { + return $this->toData('100403', 'Please log in first.', []); + } + + // 参数校验 + validate(UserValidate::class)->scene('updateInfo')->check($param); + + // 查找用户信息 + $user = UserModel::getFieldsByUserId('user_id,nick_name,first_name,first_name,gender', $userId); + if (empty($user)) { + return $this->toData('100403', 'Please log in first.', []); + } + + $nickName = $param['nick_name']; + $gender = $param['gender']; + $lastName = $param['last_name'] ?? $user['last_name']; + $first_name = $param['first_name'] ?? $user['first_name']; + + UserModel::updateFieldsByUserId([ + 'nick_name' => $nickName, + 'first_name' => $first_name, + 'last_name' => $lastName, + 'gender' => $gender, + ], $userId); + + // 返回 + return $this->toData('0', 'Modification successful.', []); + } catch (ValidateException $validateException) { + $message = $validateException->getError(); + return $this->toData('100400', $message); + } catch (\Exception $exception) { + return $this->toData('100500', 'The system is busy.', [$exception->getMessage()]); + } + + } + + /** + * @desc 登陆状态下发送短信 + * @param $userId + * @param $param + * @return array + * @throws \Psr\SimpleCache\InvalidArgumentException + */ + public function sendEmail($userId, $param) + { + try { + $ip = $this->getClientRealIp(); + + // 主键 + if (empty($userId) || $userId <= 0) { + return $this->toData('100403', 'Please log in first.', []); + } + + // 参数校验 + validate(UserValidate::class)->scene('sendEmail')->check($param); + + // 如果是非交易业务 需要判断验证码获取次数 + $key = 'USER:SEND_CODE_NUM:' . $ip; + if ($param['business'] == '1') { + if ($this->checkGetNoTradeCodeNum($key)) { + return $this->toData('100300', 'No worries. Please feel free to reach out again tomorrow.', []); + } + } + + // 提取参数 + $emailType = $param['email_type']; // 1 给已经绑定的邮箱发 2 给新邮箱发 + $email = $param['email'] ?? ''; + if ($emailType == 1) { + $email = UserModel::getEmailById($userId); + if (empty($email)) { + return $this->toData('100400', '邮箱未绑定', []); + } + } + + // 获取邮件内容 + $content = $this->getEmailContent(); + $content['email'] = $email; + $code = $content['code']; + Queue::push('app\home\job\SendEmail', $content, 'sendEmail'); + + // 设置缓存 + $sendEmailCacheKey = 'USER:sendEmailLoginTrade:' . $email; + if ($param['business'] == '1') { + $sendEmailCacheKey = 'USER:sendEmailLoginNoTrade:' . $email; + // 累加ip获取的次数 + $this->updateHadGetCodeNumCache($key); + } + + $this->insertCodeToCache($sendEmailCacheKey, $code, 300); + + // 返回结果 + return $this->toData('0', 'Modification successful.'); + } catch (ValidateException $validateException) { + // 参数校验失败 异常类 + $message = $validateException->getError(); + return $this->toData('100400', $message); + } catch (\Exception $exception) { + return $this->toData('100500', 'The system is busy.', [$exception->getMessage()]); + } + } + + /** + * @desc 登陆状态下发送短信 + * @param $userId + * @param $param + * @return array + * @throws \Psr\SimpleCache\InvalidArgumentException + */ + public function sendSms($userId, $param): array + { + try { + $ip = $this->getClientRealIp(); + + // 主键 + if (empty($userId) || $userId <= 0) { + return $this->toData('100403', 'Please log in first.', []); + } + + // 参数校验 + validate(UserValidate::class)->scene('sendSms')->check($param); + + // 如果是非交易业务 需要判断验证码获取次数 + $key = 'USER:SEND_CODE_NUM:' . $ip; + if ($param['business'] == '1') { + if ($this->checkGetNoTradeCodeNum($key)) { + return $this->toData('100300', 'No worries. Please feel free to reach out again tomorrow.', []); + } + } + + // 提取参数 + $phoneType = $param['phone_type']; // 1 给已经绑定的手机发 2 给新手机发 + $phone = $param['phone'] ?? ''; + $nation = $param['nation'] ?? ''; + if ($phoneType == 1) { + $user = UserModel::getFieldsByUserId('country_code,phone_number', $userId); + if (empty($user)) { + return $this->toData('100400', 'The phone number is not linked/bound.', []); + } + $phone = $user['phone_number']; + $nation = $user['country_code']; + } else { + // 如果给新手机发 判断国家码是否存在 + $nationCheck = CountryModel::checkCodeExists($nation); + if (!$nationCheck) { + return $this->toData('100400', 'Unsupported country or region.', []); + } + } + + $mobile = $nation . $phone; + + // 获取邮件内容 + $content = $this->getSmsContent(1); + $content['mobile'] = $mobile; + $code = $content['code']; + Queue::push('app\home\job\SendSms', $content, 'sendSms'); + + // 设置缓存 + $sendCodeKey = 'USER:sendSmsLoginTrade:' . $mobile; + + if ($param['business'] == '1') { + $sendCodeKey = 'USER:sendSmsLoginNoTrade:' . $mobile; + // 累加已经获取的次数 + $this->updateHadGetCodeNumCache($key); + } + $this->insertCodeToCache($sendCodeKey, $code, 300); + + + // 返回结果 + return $this->toData('0', 'Modification successful.'); + } catch (ValidateException $validateException) { + // 参数校验失败 异常类 + $message = $validateException->getError(); + return $this->toData('100400', $message); + } catch (\Exception $exception) { + return $this->toData('100500', 'The system is busy.', [$exception->getMessage()]); + } + } + + public function setPayPasswordByEmail($userId, $param) + { + try { + // 主键 + if (empty($userId) || $userId <= 0) { + return $this->toData('100403', 'Please log in first.', []); + } + + // 参数校验 email_code pay_password + validate(UserValidate::class)->scene('setPayPasswordByEmail')->check($param); + + // 获取用户 + $user = UserModel::getFieldsByUserId('email,user_id,trade_password', $userId); + if (empty($user)) { + return $this->toData('100403', 'Please log in first.', []); + } + +// // 校验验证码 +// $key = 'USER:sendEmailLoginNoTrade:'.$user['email']; +// $emailCache = Cache::store('redis')->get($key); +// if(empty($param['email_code']) || $emailCache != $param['email_code']){ +// return $this->toData('100400', 'The verification code is incorrect.', []); +// } + + // 如果已经存在交易密码 则不能设置 + if (!empty($user['trade_password'])) { + return $this->toData('100400', 'The payment password has already been set.', []); + } + + // 加密密码 + $payPassword = $param['pay_password']; + $salt = env('ENCRYPT.SALT'); + $payPassword = (new UnqId())->encryptPassword($payPassword, $salt); + + // 设置密码 + UserModel::setPayPassword($payPassword, $salt, $userId); + + return $this->toData('0', 'Modification successful.', []); + } catch (ValidateException $validateException) { + // 参数校验失败 异常类 + $message = $validateException->getError(); + return $this->toData('100400', $message); + } catch (\Exception $exception) { + return $this->toData('100500', 'The system is busy.', []); + } + } + + /** + * @desc 通过短信设置取款密码 + * @param $userId + * @param $param + * @return array + * @throws \Psr\SimpleCache\InvalidArgumentException + */ + public function setPayPasswordBySms($userId, $param) + { + try { + // 主键 + if (empty($userId) || $userId <= 0) { + return $this->toData('100403', 'Please log in first.', []); + } + + // 参数校验 nation phone pay_password + validate(UserValidate::class)->scene('setPayPasswordBySms')->check($param); + + // 获取用户信息 + $user = UserModel::getFieldsByUserId('country_code,phone_number,user_id,trade_password', $userId); + if (empty($user)) { + return $this->toData('100403', 'Please log in first.', []); + } + + if (!empty($user['trade_password'])) { + return $this->toData('100400', 'The payment password has already been set.', []); + } + +// // 校验验证码 +// $mobile = $user['country_code'].$user['phone_number']; +// $key = 'USER:sendSmsLoginNoTrade:'.$mobile; +// if(Cache::store('redis')->get($key) != $param['sms_code']){ +// return $this->toData('100400', 'The verification code is incorrect.', []); +// } + + // 校验验证码 + $payPassword = $param['pay_password']; + $salt = env('ENCRYPT.SALT'); + $payPassword = (new UnqId())->encryptPassword($payPassword, $salt); + + + // 设置密码 + UserModel::setPayPassword($payPassword, $salt, $userId); + + return $this->toData('0', 'Modification successful.', []); + } catch (ValidateException $validateException) { + // 参数校验失败 异常类 + $message = $validateException->getError(); + return $this->toData('100400', $message); + } catch (\Exception $exception) { + return $this->toData('100500', 'The system is busy.', [$exception->getMessage()]); + } + + } + + /** + * @desc 通过手机号修改交易密码 + * @param $userId + * @param $param + * @return array + * @throws \Psr\SimpleCache\InvalidArgumentException + */ + public function updatePayPasswordBySms($userId, $param) + { + try { + // user_id + if (empty($userId) || $userId <= 0) { + return $this->toData('100403', 'Please log in first.', []); + } + + // 参数校验 email_code email + validate(UserValidate::class)->scene('updatePayPasswordBySms')->check($param); + + // 获取用户信息 + $user = UserModel::getFieldsByUserId('user_id,trade_password,salt,phone_number,country_code', $userId); + if (empty($user)) { + return $this->toData('100403', 'Please log in first.', []); + } + + // 提取参数 +// $nation = $user['country_code']; +// $phone = $user['phone_number']; +// $smsCode = $param['sms_code']; + $payPassword = $param['pay_password']; + $payPasswordNew = $param['pay_password_new']; + + // 校验验证码 +// $mobile = $nation.$phone; +// $cacheSmsKey = 'USER:sendSmsLoginNoTrade:'.$mobile; +// $cacheSmsCode = Cache::store('redis')->get($cacheSmsKey); +// if(empty($smsCode) || $smsCode != $cacheSmsCode){ +// return $this->toData('100400', 'The verification code is incorrect.', []); +// } + + // 校验旧密码 + $checkPasswordBool = (new UnqId())->checkPassword($payPassword, $user['trade_password'], $user['salt']); + if (!$checkPasswordBool) { + return $this->toData('100400', 'Incorrect password.'); + } + + // 设置密码 + $newPassword = (new UnqId())->encryptPassword($payPasswordNew, $user['salt']); + UserModel::updateFieldsByUserId(['trade_password' => $newPassword], $userId); + + // 返回结果 + return $this->toData('0', 'Modification successful.', []); + + } catch (ValidateException $validateException) { + // 参数校验失败 异常类 + $message = $validateException->getError(); + return $this->toData('100400', $message); + } catch (\Exception $exception) { + return $this->toData('100500', 'The system is busy.', [$exception->getMessage()]); + } + + } + + /** + * @desc 根据邮箱修改交易密码 + * @param $userId + * @param $param + * @return array + * @throws \Psr\SimpleCache\InvalidArgumentException + */ + public function updatePayPasswordByEmail($userId, $param) + { + // 通过 邮箱 收款密码 重新设置收款密码 + try { + // user_id + if (empty($userId) || $userId <= 0) { + return $this->toData('100403', 'Please log in first.', []); + } + + // 参数校验 email_code email + validate(UserValidate::class)->scene('updatePayPasswordByEmail')->check($param); + + // 获取用户信息 + $user = UserModel::getFieldsByUserId('user_id,trade_password,salt,email', $userId); + if (empty($user)) { + return $this->toData('100403', 'Please log in first.', []); + } + + // 提取参数 +// $email = $user['email']; +// $emailCode = $param['email_code']; + $payPassword = $param['pay_password']; + $payPasswordNew = $param['pay_password_new']; + + // 校验验证码 +// $cacheEmailKey = 'USER:sendEmailLoginNoTrade:'.$email; +// $cacheEmailCode = Cache::store('redis')->get($cacheEmailKey); +// if(empty($emailCode) || $emailCode != $cacheEmailCode){ +// return $this->toData('100400', 'The verification code is incorrect.', []); +// } + + // 校验旧密码 + $checkPasswordBool = (new UnqId())->checkPassword($payPassword, $user['trade_password'], $user['salt']); + if (!$checkPasswordBool) { + return $this->toData('100400', 'Incorrect password.', []); + } + + // 设置密码 + $newPassword = (new UnqId())->encryptPassword($payPasswordNew, $user['salt']); + UserModel::updateFieldsByUserId(['trade_password' => $newPassword], $userId); + + // 返回结果 + return $this->toData('0', 'Modification successful.', []); + + } catch (ValidateException $validateException) { + // 参数校验失败 异常类 + $message = $validateException->getError(); + return $this->toData('100400', $message); + } catch (\Exception $exception) { + return $this->toData('100500', 'The system is busy.', [$exception->getMessage()]); + } + + } + + /** + * @desc 根据短信重新设置交易密码 + * @param $userId + * @param $param + * @return array + * @throws \Psr\SimpleCache\InvalidArgumentException + */ + public function resetPayPasswordBySms($userId, $param) + { + try { + // user_id + if (empty($userId) || $userId <= 0) { + return $this->toData('100403', 'Please log in first.', []); + } + + // 参数校验 email_code email + validate(UserValidate::class)->scene('resetPayPasswordBySms')->check($param); + + // 获取用户信息 + $user = UserModel::getFieldsByUserId('user_id,salt,phone_number,country_code', $userId); + if (empty($user)) { + return $this->toData('100403', 'Please log in first.', []); + } + + // 提取参数 +// $nation = $user['country_code']; +// $phone = $user['phone_number']; +// $smsCode = $param['sms_code']; + $payPasswordNew = $param['pay_password_new']; + + // 校验验证码 +// $mobile = $nation.$phone; +// $cacheSmsKey = 'USER:sendSmsLoginNoTrade:'.$mobile; +// $cacheSmsCode = Cache::store('redis')->get($cacheSmsKey); +// if(empty($smsCode) || $smsCode != $cacheSmsCode){ +// return $this->toData('100400', 'The verification code is incorrect.', []); +// } + + // 设置密码 + $newPassword = (new UnqId())->encryptPassword($payPasswordNew, $user['salt']); + UserModel::updateFieldsByUserId(['trade_password' => $newPassword], $userId); + + // 返回结果 + return $this->toData('0', 'Modification successful.', []); + + } catch (ValidateException $validateException) { + // 参数校验失败 异常类 + $message = $validateException->getError(); + return $this->toData('100400', $message); + } catch (\Exception $exception) { + return $this->toData('100500', 'The system is busy.', [$exception->getMessage()]); + } + + } + + /** + * @desc 通过邮箱重新设置交易密码 + * @param $userId + * @param $param + * @return array + * @throws \Psr\SimpleCache\InvalidArgumentException + */ + public function resetPayPasswordByEmail($userId, $param) + { + // 通过邮箱验证码 新密码 设置交易密码 + try { + // user_id + if (empty($userId) || $userId <= 0) { + return $this->toData('100403', 'Please log in first.', []); + } + + // 参数校验 email_code email + validate(UserValidate::class)->scene('resetPayPasswordByEmail')->check($param); + + // 获取用户信息 + $user = UserModel::getFieldsByUserId('user_id,salt,email', $userId); + if (empty($user)) { + return $this->toData('100403', 'Please log in first.', []); + } + + // 提取参数 +// $email = $user['email']; +// $emailCode = $param['email_code']; + $payPasswordNew = $param['pay_password_new']; + + // 校验验证码 +// $cacheEmailKey = 'USER:sendEmailLoginNoTrade:'.$email; +// $cacheEmailCode = Cache::store('redis')->get($cacheEmailKey); +// if(empty($emailCode) || $emailCode != $cacheEmailCode){ +// return $this->toData('100400', 'The verification code is incorrect.', []); +// } + + // 设置密码 + $newPassword = (new UnqId())->encryptPassword($payPasswordNew, $user['salt']); + UserModel::updateFieldsByUserId(['trade_password' => $newPassword], $userId); + + // 返回结果 + return $this->toData('0', 'Modification successful.', []); + + } catch (ValidateException $validateException) { + // 参数校验失败 异常类 + $message = $validateException->getError(); + return $this->toData('100400', $message); + } catch (\Exception $exception) { + return $this->toData('100500', 'The system is busy.', [$exception->getMessage()]); + } + } + + public function updatePasswordBySms($userId, $param) + { + try { + if (empty($userId) || $userId <= 0) { + return $this->toData('100403', 'Please log in first.', []); + } + + // 参数校验 email_code email + validate(UserValidate::class)->scene('updatePasswordBySms')->check($param); + + // 获取用户信息 + $user = UserModel::getFieldsByUserId('user_id,login_password,salt,phone_number,country_code', $userId); + if (empty($user)) { + return $this->toData('100403', 'Please log in first.', []); + } + + // 提取参数 +// $nation = $user['country_code']; +// $phone = $user['phone_number']; +// $smsCode = $param['sms_code']; + $password = $param['password']; + $passwordNew = $param['password_new']; + + // 校验验证码 +// $mobile = $nation.$phone; +// $cacheSmsKey = 'USER:sendSmsLoginNoTrade:'.$mobile; +// $cacheSmsCode = Cache::store('redis')->get($cacheSmsKey); +// if(empty($smsCode) || $smsCode != $cacheSmsCode){ +// return $this->toData('100400', 'The verification code is incorrect.', []); +// } + + // 校验旧密码 + $checkPasswordBool = (new UnqId())->checkPassword($password, $user['login_password'], $user['salt']); + if (!$checkPasswordBool) { + return $this->toData('100400', 'Incorrect password.', []); + } + + // 设置密码 + $newPassword = (new UnqId())->encryptPassword($passwordNew, $user['salt']); + UserModel::updateFieldsByUserId(['login_password' => $newPassword], $userId); + + // 返回结果 + return $this->toData('0', 'Modification successful.', []); + + } catch (ValidateException $validateException) { + // 参数校验失败 异常类 + $message = $validateException->getError(); + return $this->toData('100400', $message); + } catch (\Exception $exception) { + return $this->toData('100500', 'The system is busy.', [$exception->getMessage()]); + } + + } + + /** + * @desc 邮箱修改登陆密码 + * @param $userId + * @param $param + * @return array + * @throws \Psr\SimpleCache\InvalidArgumentException + */ + public function updatePasswordByEmail($userId, $param) + { + try { + // user_id + if (empty($userId) || $userId <= 0) { + return $this->toData('100403', 'Please log in first.', []); + } + + // 参数校验 + validate(UserValidate::class)->scene('updatePasswordByEmail')->check($param); + + // 获取用户信息 + $user = UserModel::getFieldsByUserId('user_id,login_password,salt,email', $userId); + if (empty($user)) { + return $this->toData('100403', 'Please log in first.', []); + } + + // 提取参数 +// $email = $user['email']; +// $emailCode = $param['email_code']; + $password = $param['password']; + $passwordNew = $param['password_new']; + + // 校验验证码 +// $cacheEmailKey = 'USER:sendEmailLoginNoTrade:'.$email; +// $cacheEmailCode = Cache::store('redis')->get($cacheEmailKey); +// if(empty($emailCode) || $emailCode != $cacheEmailCode){ +// return $this->toData('100400', 'The verification code is incorrect.', []); +// } + + // 校验旧密码 + $checkPasswordBool = (new UnqId())->checkPassword($password, $user['login_password'], $user['salt']); + if (!$checkPasswordBool) { + return $this->toData('100400', 'Incorrect password.', []); + } + + // 设置密码 + $newPassword = (new UnqId())->encryptPassword($passwordNew, $user['salt']); + UserModel::updateFieldsByUserId(['login_password' => $newPassword], $userId); + + // 返回结果 + return $this->toData('0', 'Modification successful.', []); + + } catch (ValidateException $validateException) { + // 参数校验失败 异常类 + $message = $validateException->getError(); + return $this->toData('100400', $message); + } catch (\Exception $exception) { + return $this->toData('100500', 'The system is busy.', [$exception->getMessage()]); + } + + } + + /** + * @desc 短信重新设置登陆密码 + * @param $userId + * @param $param + * @return array + * @throws \Psr\SimpleCache\InvalidArgumentException + */ + public function resetPasswordBySms($userId, $param) + { + try { + if (empty($userId) || $userId <= 0) { + return $this->toData('100403', 'Please log in first.', []); + } + + // 参数校验 email_code email + validate(UserValidate::class)->scene('resetPasswordBySms')->check($param); + + // 获取用户信息 + $user = UserModel::getFieldsByUserId('user_id,salt,phone_number,country_code', $userId); + if (empty($user)) { + return $this->toData('100403', 'Please log in first.', []); + } + + // 提取参数 +// $nation = $user['country_code']; +// $phone = $user['phone_number']; +// $smsCode = $param['sms_code']; + $passwordNew = $param['password_new']; + + // 校验验证码 +// $mobile = $nation.$phone; +// $cacheSmsKey = 'USER:sendSmsLoginNoTrade:'.$mobile; +// $cacheSmsCode = Cache::store('redis')->get($cacheSmsKey); +// if(empty($smsCode) || $smsCode != $cacheSmsCode){ +// return $this->toData('100400', 'The verification code is incorrect.', []); +// } + + // 设置密码 + $newPassword = (new UnqId())->encryptPassword($passwordNew, $user['salt']); + UserModel::updateFieldsByUserId(['login_password' => $newPassword], $userId); + + // 返回结果 + return $this->toData('0', 'Modification successful.', []); + + } catch (ValidateException $validateException) { + // 参数校验失败 异常类 + $message = $validateException->getError(); + return $this->toData('100400', $message); + } catch (\Exception $exception) { + return $this->toData('100500', 'The system is busy.', [$exception->getMessage()]); + } + + } + + /** + * @desc 邮箱重新设置登陆密码 + * @param $userId + * @param $param + * @return array + * @throws \Psr\SimpleCache\InvalidArgumentException + */ + public function resetPasswordByEmail($userId, $param) + { + try { + // user_id + if (empty($userId) || $userId <= 0) { + return $this->toData('100403', 'Please log in first.', []); + } + + // 参数校验 email_code email + validate(UserValidate::class)->scene('resetPasswordByEmail')->check($param); + + // 获取用户信息 + $user = UserModel::getFieldsByUserId('user_id,salt,email', $userId); + if (empty($user)) { + return $this->toData('100403', 'Please log in first.', []); + } + + // 提取参数 +// $email = $user['email']; +// $emailCode = $param['email_code']; + $passwordNew = $param['password_new']; + + // 校验验证码 +// $cacheEmailKey = 'USER:sendEmailLoginNoTrade:'.$email; +// $cacheEmailCode = Cache::store('redis')->get($cacheEmailKey); +// if(empty($emailCode) || $emailCode != $cacheEmailCode){ +// return $this->toData('100400', 'The verification code is incorrect.', []); +// } + + // 设置密码 + $newPassword = (new UnqId())->encryptPassword($passwordNew, $user['salt']); + UserModel::updateFieldsByUserId(['login_password' => $newPassword], $userId); + + // 返回结果 + return $this->toData('0', 'Modification successful.', []); + + } catch (ValidateException $validateException) { + // 参数校验失败 异常类 + $message = $validateException->getError(); + return $this->toData('100400', $message); + } catch (\Exception $exception) { + return $this->toData('100500', 'The system is busy.', [$exception->getMessage()]); + } + } + + public function bindEmail($userId, $param) + { + try { + // user_id + if (empty($userId) || $userId <= 0) { + return $this->toData('100403', 'Please log in first.', []); + } + + // 参数校验 email_code email + validate(UserValidate::class)->scene('bindEmail')->check($param); + + // 判断验证码 +// $emailCode = $param['email_code']; + $email = $param['email']; +// $cacheCodeKey = 'USER:sendEmailLoginNoTrade:'.$email; +// $cacheSmsCode = Cache::store('redis')->get($cacheCodeKey); +// if(empty($emailCode) || $emailCode != $cacheSmsCode){ +// return $this->toData('100400', 'The verification code is incorrect.', []); +// } + + // 获取用户信息 + $user = UserModel::getFieldsByUserId('email,user_id', $userId); + if (empty($user)) { + return $this->toData('100403', 'Please log in first.', []); + } + + // 判读是否已经绑定 + if (!empty($user['email'])) { + return $this->toData('100400', 'You have already bound your email', []); + } + + //判断手机号是否已经被别人绑定 + $emailExits = UserModel::checkEmailExists($email); + if ($emailExits) { + return $this->toData('100400', 'The email has been bound', []); + } + + // 执行入库操作 + UserModel::updateFieldsByUserId(['email' => $email], $userId); + + // 返回结果 + return $this->toData('0', 'Binding successful', []); + + } catch (ValidateException $validateException) { + // 参数校验失败 异常类 + $message = $validateException->getError(); + return $this->toData('100400', $message); + } catch (\Exception $exception) { + return $this->toData('100500', 'The system is busy.', [$exception->getMessage()]); + } + } + + /** + * @desc 修改已经绑定的手机号 + * @param $userId + * @param $param + * @return array + * @throws \Psr\SimpleCache\InvalidArgumentException + */ + public function updateEmail($userId, $param): array + { + try { + // user_id + if (empty($userId) || $userId <= 0) { + return $this->toData('100403', 'Please log in first.', []); + } + + // 参数校验 nation phone sms_code + validate(UserValidate::class)->scene('updateEmail')->check($param); + + // 判断验证码 +// $emailCode = $param['email_code']; + $email = $param['email']; +// $cacheCodeKey = 'USER:sendEmailLoginNoTrade:'.$email; +// $cacheSmsCode = Cache::store('redis')->get($cacheCodeKey); +// if(empty($emailCode) || $emailCode != $cacheSmsCode){ +// return $this->toData('100400', 'The verification code is incorrect.', []); +// } + + // 获取用户信息 + $user = UserModel::getFieldsByUserId('login_password,email,user_id,salt', $userId); + if (empty($user)) { + return $this->toData('100403', 'Please log in first.', []); + } + + // 判读是否已经绑定 需要已经绑定 + if (empty($user['email'])) { + return $this->toData('100400', 'Email is not linked/bound.', []); + } + + //校验登陆密码 + $passwordCheck = (new UnqId())->checkPassword($param['password'], $user['login_password'], $user['salt']); + if (!$passwordCheck) { + return $this->toData('100400', 'Incorrect password.', []); + } + + //判断手机号是否已经被别人绑定 + $emailExits = UserModel::checkEmailExists($email); + if ($emailExits) { + return $this->toData('100400', 'The email has already been linked/bound.', []); + } + + // 执行入库操作 + UserModel::updateFieldsByUserId(['email' => $email], $userId); + + // 返回结果 + return $this->toData('0', 'Modification successful.', []); + } catch (ValidateException $validateException) { + // 参数校验失败 异常类 + $message = $validateException->getError(); + return $this->toData('100400', $message); + } catch (\Exception $exception) { + return $this->toData('100500', 'The system is busy.', [$exception->getMessage()]); + } + } + + + public function bindPhone($userId, $param) + { + try { + // user_id + if (empty($userId) || $userId <= 0) { + return $this->toData('100403', 'Please log in first.', []); + } + + // 参数校验 nation phone sms_code + validate(UserValidate::class)->scene('bindPhone')->check($param); + + // 判断验证码 +// $smsCode = $param['sms_code']; +// $mobile = $param['nation'].$param['phone']; +// $cacheSmsKey = 'USER:sendSmsLoginNoTrade:'.$mobile; +// $cacheSmsCode = Cache::store('redis')->get($cacheSmsKey); +// if(empty($smsCode) || $smsCode != $cacheSmsCode){ +// return $this->toData('100400', 'The verification code is incorrect.', []); +// } + + // 获取用户信息 + $user = UserModel::getFieldsByUserId('user_id,country_code,phone_number', $userId); + if (empty($user)) { + return $this->toData('100403', 'Please log in first.', []); + } + + // 判读是否已经绑定 + if (!empty($user['phone_number'])) { + return $this->toData('100400', 'The phone number has already been linked/bound.', []); + } + + //判断手机号是否已经被别人绑定 + $phoneExits = UserModel::checkPhoneExists($param['phone']); + if ($phoneExits) { + return $this->toData('100400', 'The phone number has already been linked/bound.', []); + } + + // 判断国家码是否存在 + $codeExists = CountryModel::checkCodeExists($param['nation']); + if (!$codeExists) { + return $this->toData('100400', 'Unsupported country or region.', []); + } + + // 执行入库操作 + UserModel::updateFieldsByUserId(['phone_number' => $param['phone'], 'country_code' => $param['nation']], $userId); + + // 返回结果 + return $this->toData('0', 'Binding successful.', []); + + } catch (ValidateException $validateException) { + // 参数校验失败 异常类 + $message = $validateException->getError(); + return $this->toData('100400', $message); + } catch (\Exception $exception) { + return $this->toData('100500', 'The system is busy.', [$exception->getMessage()]); + } + } + + /** + * @desc 修改已经绑定的手机号 + * @param $userId + * @param $param + * @return array + * @throws \Psr\SimpleCache\InvalidArgumentException + */ + public function updatePhone($userId, $param): array + { + try { + // user_id + if (empty($userId) || $userId <= 0) { + return $this->toData('100403', 'Please log in first.', []); + } + + // 参数校验 nation phone sms_code + validate(UserValidate::class)->scene('updatePhone')->check($param); + + // 判断验证码 +// $smsCode = $param['sms_code']; +// $mobile = $param['nation'].$param['phone']; +// $cacheSmsKey = 'USER:sendSmsLoginNoTrade:'.$mobile; +// $cacheSmsCode = Cache::store('redis')->get($cacheSmsKey); +// if(empty($smsCode) || $smsCode != $cacheSmsCode){ +// return $this->toData('100400', 'The verification code is incorrect.', []); +// } + + // 判断国家码是否存在 + $codeExists = CountryModel::checkCodeExists($param['nation']); + if (!$codeExists) { + return $this->toData('100400', 'Unsupported country or region', []); + } + + //判断手机号是否已经被别人绑定 + $phoneExits = UserModel::checkPhoneExists($param['phone']); + if ($phoneExits) { + return $this->toData('100400', 'The phone number has already been linked/bound.', []); + } + + // 获取用户信息 + $user = UserModel::getFieldsByUserId('salt,login_password,user_id,country_code,phone_number', $userId); + if (empty($user)) { + return $this->toData('100403', 'Please log in first.', []); + } + + // 判读是否已经绑定 需要已经绑定手机 + if (empty($user['phone_number'])) { + return $this->toData('100400', 'The phone number is not linked/bound.', []); + } + + //校验登陆密码 + $passwordCheck = (new UnqId())->checkPassword($param['password'], $user['login_password'], $user['salt']); + if (!$passwordCheck) { + return $this->toData('100400', 'Incorrect password.', []); + } + + // 执行入库操作 + UserModel::updateFieldsByUserId(['phone_number' => $param['phone'], 'country_code' => $param['nation']], $userId); + + // 返回结果 + return $this->toData('0', 'Modification successful.', []); + } catch (ValidateException $validateException) { + // 参数校验失败 异常类 + $message = $validateException->getError(); + return $this->toData('100400', $message); + } catch (\Exception $exception) { + return $this->toData('100500', 'The system is busy.', [$exception->getMessage()]); + } + } + public function apply_loan($userId, $param) + { + try { + // user_id + if (empty($userId) || $userId <= 0) { + return $this->toData('100403', 'Please log in first.', []); + } + + // 参数校验 nation phone sms_code + validate(UserValidate::class)->scene('apply_loan')->check($param); + $count=UserLoanModel::where('status',0)->where('user_id',$userId)->count(); + if($count>0){ + return $this->toData('100402', 'You have applied, please be patient and wait.', []); + } + + $userloan=new UserLoanModel(); + $userloan->user_id=$userId; + $userloan->num= intval($param['num']); + $userloan->day= intval($param['day']); + $userloan->status= 0; + $userloan->is_delete= 0; + $userloan->create_time=date('Y-m-d H:i:s'); + $userloan->save(); + + // 返回结果 + return $this->toData('0', 'Binding successful.', []); + + } catch (ValidateException $validateException) { + // 参数校验失败 异常类 + $message = $validateException->getError(); + return $this->toData('100400', $message); + } catch (\Exception $exception) { + return $this->toData('100500', 'The system is busy.', [$exception->getMessage()]); + } + } + public function loan($userId, $param) + { + try { + // user_id + if (empty($userId) || $userId <= 0) { + return $this->toData('100403', 'Please log in first.', []); + } + $data['where']['user_id']=$userId; + $data['page']=isset($param['page']) ? intval($param['page']) : 1; + $data['size']=isset($param['size']) ? intval($param['size']) : 10; + $list=UserLoanModel::getUserLoanList($data); + // 返回结果 + return $this->toData('0', 'successful.', $list); + + } catch (ValidateException $validateException) { + // 参数校验失败 异常类 + $message = $validateException->getError(); + return $this->toData('100400', $message); + } catch (\Exception $exception) { + return $this->toData('100500', 'The system is busy.', [$exception->getMessage()]); + } + } + + + /** + * @desc 退出登陆 + * @param $userId + * @return array + */ + public function logout($userId) + { + try { + // 删除缓存 + $this->delUserTokenCache($userId); + return $this->toData('0', 'Modification successful.'); + } catch (\Exception $exception) { + return $this->toData('100500', 'The system is busy.', [$exception->getMessage()]); + } + + } + + /** + * @desc 获取用户登陆信息 + * @param $userId + * @return array + */ + public function loginLog($userId): array + { + try { + if (empty($userId) || $userId <= 0) { + return $this->toData('100403', 'Please log in first.', []); + } + + $data = UserLoginLog::getLog($userId); + if (empty($data)) { + return $this->toData('0', 'Modification successful.', []); + } + + $res = []; + foreach ($data as $item) { + $countryCn = ''; + $countryEn = ''; + $cityCn = ''; + $cityEn = ''; + if (!empty($item['country'])) { + $countryArr = json_decode($item['country'], true); + $countryCn = $countryArr['cn']; + $countryEn = $countryArr['en']; + } + + if (!empty($item['city'])) { + $cityArr = json_decode($item['city'], true); + $cityCn = $cityArr['cn']; + $cityEn = $cityArr['en']; + } + + $res[] = [ + 'device' => $item['device'], + 'ip' => $item['ip'], + 'countryCn' => $countryCn, + 'countryEn' => $countryEn, + 'cityCn' => $cityCn, + 'cityEn' => $cityEn, + 'loginDate' => $item['login_date'], + ]; + } + + return $this->toData('0', 'Modification successful.', $res); + } catch (\Exception $exception) { + return $this->toData('100500', 'The system is busy.', []); + } + } + + /** + * 用户申请使用杠杆 + * @param $userId + * @return array + */ + public function leverApply($userId) + { + try { + if (empty($userId) || $userId <= 0) { + return $this->toData('100403', 'Please log in first.', []); + } + + // 获取用户信息 + $user = UserModel::getFieldsByUserId('lever_status,user_id', $userId); + if (empty($user)) { + return $this->toData('100403', 'Please log in first.', []); + } + + if (in_array($user['lever_status'], [UserModel::LEVER_STATUS_NO, UserModel::LEVER_STATUS_FAIL])) { + $level_status=env('USER_LEVEL.NO_APPLY')==1 ? UserModel::LEVER_STATUS_PASSED : UserModel::LEVER_STATUS_APPLY; + UserModel::update(['lever_status' => $level_status, 'update_time' => date('Y-m-d H:i:s')], ['user_id' => $userId]); + return $this->toData('0', 'success.', []); + } + + return $this->toData('0', 'Already submitted.', []); + + } catch (\Exception $exception) { + return $this->toData('100500', 'The system is busy.', []); + } + } + public function applyTestAccount($userId) + { + + if (empty($userId) || $userId <= 0) { + return $this->toData('100403', 'Please log in first.', []); + } + + // 获取用户信息 + $user = UserModel::getFieldsByUserId('test_account,user_id,user_no', $userId); + if (empty($user)) { + return $this->toData('100401', 'Please log in first.', []); + } + if(!empty($user['test_account'])){ + return $this->toData('0', 'success.', []); + } + //添加模拟账号 + $userNo=$this->getUniqUserNo(); + $email="test_".$userNo."@test.com"; + $salt = env('ENCRYPT.SALT'); + $password = (new UnqId())->encryptPassword('test12345', $salt); + $userInviteCode=$this->getUniqInviteCode(); + $parentUserId = $userId; + $ip = (new BaseHomeService())->getClientRealIp(); + $test_userId = UserModel::emailRegister($email, $userNo, $userInviteCode, $parentUserId, $password, $ip, $salt, 2, 0); + if($test_userId){ + $this->doRegInitUserInfo($test_userId,$parentUserId); + UserModel::where('user_id', $userId)->update([ + 'test_account' => $test_userId + ]); + UserModel::where('user_id', $test_userId)->update([ + 'is_real' => 0, + 'real_status'=>3 + ]); + if(env('ACCOUT_TYPE.ALL_IN_ONE')==1){ + UserMoneyModel::where('user_id', $test_userId)->update([ + 'user_id' => $test_userId, + 'stock_id' => 'USD', + 'usable_num' => 100000, + 'frozen_num' => 0, + ]); + }else{ + UserDigitalModel::where('user_id', $test_userId)->update([ + 'user_id' => $test_userId, + 'digital_id' => 'USDT', + 'usable_num' => 100000, + 'frozen_num' => 0, + ]); + UserContractModel::where('user_id', $test_userId)->update([ + 'user_id' => $test_userId, + 'contract_id' => 'USDT', + 'usable_num' => 100000, + 'frozen_num' => 0, + ]); + UserForexModel::InsertUserForex([ + 'user_id' => $test_userId, + 'contract_id' => 'USD', + 'usable_num' => 100000, + 'frozen_num' => 0, + ]); + UserStockHkdModel::InsertUserStock([ + 'user_id' => $test_userId, + 'stock_id' => 'HKD', + 'usable_num' => 100000, + 'frozen_num' => 0, + ]); + } + + } + return $this->toData('0', 'success.', []); + } + public function applyTestMoney($userId,$param){ + if (empty($userId) || $userId <= 0) { + return $this->toData('100403', 'Please log in first.', []); + } + + // 获取用户信息 + $user = UserModel::getFieldsByUserId('is_test_user,user_id,user_no', $userId); + if (empty($user)) { + return $this->toData('100401', 'Please log in first.', []); + } + if($user['is_test_user']!=2){ + return $this->toData('100402', 'error.', []); + } + $num=isset($param['num']) ? intval($param['num']) : 0; + if($num<=0 || $num>100000){ + return $this->toData('100401', 'error.', []); + } + $user_money=UserMoneyModel::getUserUSDByUserId(['user_id'=>$userId]); + $update_num=$user_money['usable_num']+$num; + UserMoneyModel::where('user_id', $userId)->update([ + 'stock_id' => 'USD', + 'usable_num' => $update_num, + 'update_time' => date('Y-m-d H:i:s'), + ]); + + return $this->toData('0', 'success.', []); + } + public function testLogin($userId) + { + // 获取用户信息 + $user = UserModel::getFieldsByUserId('test_account,user_id,user_no', $userId); + if (empty($user)) { + return $this->toData('100401', 'Please log in first.', []); + } + if(empty($user['test_account'])){ + return $this->toData('100402', 'Please log in first.', []); + } + //登录模拟账号 + $test_user=UserModel::getFieldsByUserId('test_account,user_id,user_no,nick_name,invite_code,is_real,is_test_user', $user['test_account']); + // 生成token + $token = (new Jwt())->getToken($test_user['user_id'], env('ENCRYPT.SALT')); + if (empty($token)) { + return $this->toData('100300', 'The system is busy.', []); + } + + // 将token存致缓存 覆盖新的缓存 实现单设备登陆 + $this->setUserTokenCache($token, $test_user['user_id']); + // 删除缓存 + $this->delUserTokenCache($userId); + // 返回结果以及用户信息 + return $this->toData('0', 'Request successful.', [ + 'userId' => $test_user['user_id'], + 'userNo' => $test_user['user_no'], + 'nickName' => $test_user['nick_name'], + 'inviteCode' => $test_user['invite_code'], + 'isReal' => $test_user['is_real'], + 'is_test_user' => $test_user['is_test_user'], + 'logo' => env('USER.DEFAULT_HEAD_IMG_PATH'), + 'token' => $token, + ]); + } + public function formalLogin($userId) + { + // 获取用户信息 + $user = UserModel::getFieldsByUserId('parent_id,user_id,user_no,is_test_user', $userId); + if (empty($user)) { + return $this->toData('100401', 'Please log in first.', []); + } + if(empty($user['parent_id'])){ + return $this->toData('100402', 'The system is busy.', []); + } + if(empty($user['is_test_user'])){ + return $this->toData('100403', 'The system is busy.', []); + } + //登录模拟账号 + $test_user=UserModel::getFieldsByUserId('test_account,user_id,user_no,nick_name,invite_code,is_real,is_test_user', $user['parent_id']); + if($test_user['test_account']!=$userId){ + return $this->toData('100404', 'The system is busy.', []); + } + // 生成token + $token = (new Jwt())->getToken($test_user['user_id'], env('ENCRYPT.SALT')); + if (empty($token)) { + return $this->toData('100300', 'The system is busy.', []); + } + + // 将token存致缓存 覆盖新的缓存 实现单设备登陆 + $this->setUserTokenCache($token, $test_user['user_id']); + // 删除缓存 + $this->delUserTokenCache($userId); + // 返回结果以及用户信息 + return $this->toData('0', 'Request successful.', [ + 'userId' => $test_user['user_id'], + 'userNo' => $test_user['user_no'], + 'nickName' => $test_user['nick_name'], + 'inviteCode' => $test_user['invite_code'], + 'isReal' => $test_user['is_real'], + 'is_test_user' => $test_user['is_test_user'], + 'logo' => env('USER.DEFAULT_HEAD_IMG_PATH'), + 'token' => $token, + ]); + } +} diff --git a/app/home/service/Copy of UserService.php b/app/home/service/Copy of UserService.php new file mode 100644 index 0000000..7c99e68 --- /dev/null +++ b/app/home/service/Copy of UserService.php @@ -0,0 +1,1605 @@ +createUserLevel($user_id, $parent_id); + (new TeamService())->regBrokerage($data['parent_id'], $data['grandpa_id'], $data['top_id']); + } + $this->initUserWallet($user_id); + } + + /** + * 处理用户等级关系 + * @param int $user_id + * @param int $parent_id + * @return bool + */ + private function createUserLevel(int $user_id, int $parent_id) + { + //插入用户等级关系 + if ($parent_id > 0) { + $parent_info = UserLevelModel::getUserLevelById($parent_id); + $grandpa_id = $parent_info['parent_id']; + $top_id = $parent_info['grandpa_id']; + } else { + $grandpa_id = 0; + $top_id = 0; + } + $data['user_id'] = $user_id; + $data['parent_id'] = $parent_id; + $data['grandpa_id'] = $grandpa_id; + $data['top_id'] = $top_id; + UserLevelModel::InsertUserLevel($data); + return $data; + } + + public function getUserLevel(int $user_id) + { + $level_info = UserLevelModel::getUserLevelById($user_id); + $this->setUserLevel($user_id, $level_info); + } + + /** + * 初始化各钱包数据 U数据 + * @param int $user_id + * @return void + */ + private function initUserWallet(int $user_id) + { + if(env('ACCOUT_TYPE.ALL_IN_ONE')==1){ + UserMoneyModel::InsertUserMoneyk([ + 'user_id' => $user_id, + 'stock_id' => 'USD', + 'usable_num' => 0, + 'frozen_num' => 0, + ]); + }else{ + if (env('FEATURE.HAS_STOCK_US')) { + UserStockModel::InsertUserStock([ + 'user_id' => $user_id, + 'stock_id' => 'USD', + 'usable_num' => 0, + 'frozen_num' => 0, + ]); + } + if (env('FEATURE.HAS_DIGITAL')) { + UserDigitalModel::InsertUserDigital([ + 'user_id' => $user_id, + 'digital_id' => 'USDT', + 'usable_num' => 0, + 'frozen_num' => 0, + ]); + } + if (env('FEATURE.HAS_CONTRACT')) { + UserContractModel::InsertUserContract([ + 'user_id' => $user_id, + 'contract_id' => 'USDT', + 'usable_num' => 0, + 'frozen_num' => 0, + ]); + } + } + + + } + + /** + * @desc 获取用户信息 + * @param $userId + * @return array + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\DbException + * @throws \think\db\exception\ModelNotFoundException + */ + public function getUserInfo($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,is_real,head_img_id,invite_code,is_test_user', $userId); + if (empty($info)) { + return $this->toData('100400', 'The user does not exist.', []); + } + + // 获取国家名称 + $countryId = $info['country_id']; + + $countryName = ''; + if ($countryId > 0) { + $countryName = CountryModel::getNameById($countryId); + } + + // 获取头像 + $headPath = env('USER.DEFAULT_HEAD_IMG_PATH'); + if ($info['head_img_id'] > 0) { + $headPath = FileModel::getFilePath($info['head_img_id']); + } + + $key = 'LEVERAGE:' . $userId; + $leverageNum = Cache::store('redis')->get($key); + if (empty($leverageNum)) { + $key = 'LEVERAGE:0'; + $leverageNum = Cache::store('redis')->get($key); + } + $leverageNum= empty($leverageNum) ? 1: $leverageNum; + + // 查询用户的chat_uuid + $userChatInfo = UserChatLinkModel::where('user_id', $userId)->find(); + $userChatUuid = ""; + $userChatName = ""; + if (!empty($userChatInfo)) { + $userChatUuid = $userChatInfo->chat_uuid; + $userChatName = $userChatInfo->chat_name; + } + // 查询用户绑定的客服chat_uuid + $customerChatUuid = ""; + $customerChatName = ""; + Log::info("查询user_info user_id=".$userId); + $customerRelationInfo = CustomerRelationalModel::where('user_id', $userId)->find(); //查询用户关联的客服账号信息 + if ($customerRelationInfo) { + $customerChatInfo = UserChatLinkModel::where(['user_id',$customerRelationInfo->customer_id, 'user_type'=>2])->find(); //查询客服的chat账号 + if ($customerChatInfo) { + $customerChatUuid = $customerChatInfo->chat_uuid; + $customerChatName = $customerChatInfo->chat_name; + } + } + + + // 返回数据 + return $this->toData('0', 'Modification successful.', [ + 'logo' => $headPath, + 'userId' => $userId, + 'userNo' => $info['user_no'], + 'nickName' => $info['nick_name'], + 'nation' => $info['country_code'], + 'phone' => $info['phone_number'], + 'email' => $info['email'], + 'isReal' => $info['is_real'], + 'is_test_user' => $info['is_test_user'], + 'real_status' => $info['real_status'], + 'inviteCode' => $info['invite_code'], + 'firstName' => $info['first_name'], + 'lastName' => $info['last_name'], + 'gender' => (string)$info['gender'], + 'isSetPayPassword' => $info['trade_password'] ? '1' : '0', + 'country' => $countryName, + 'countryId' => $countryId, + 'lever_status' => $info['lever_status'], + 'leverage_num' =>$leverageNum, + 'user_chat_uuid' => $userChatUuid, + 'user_chat_name' => $userChatName, + 'customer_chat_uuid' => $customerChatUuid, + 'customer_chat_name' => $customerChatName + ]); + } catch (\Exception $exception) { + return $this->toData('100500', 'The system is busy.', [$exception->getMessage(), $exception->getTrace()]); + } + } + + /** + * @desc 设置用户国家 + * @param $userId + * @param $param + * @return array + */ + public function setCountry($userId, $param): array + { + try { + // 主键 + if (empty($userId) || $userId <= 0) { + return $this->toData('100403', 'Please log in first.', []); + } + // 邮件注册参数校验 + validate(UserValidate::class)->scene('setCountry')->check($param); + $countryId = $param['country_id']; + + // 国家是否存在 + $country = CountryModel::getById($countryId); + if (empty($country)) { + return $this->toData('100400', 'Unsupported country or region.', []); + } + + // 是否是黑名单国家 + if ($this->checkForbidNation($country['code'])) { + return $this->toData('100400', 'Unsupported country or region.', []); + } + + // 设置 + UserModel::updateFieldsByUserId(['country_id' => $country['id']], $userId); + return $this->toData('0', 'Modification successful.'); + } catch (ValidateException $validateException) { + $message = $validateException->getMessage(); + return $this->toData('100400', $message, []); + } catch (\Exception $exception) { + return $this->toData('100500', 'The system is busy.', [$exception->getMessage(), $exception->getTrace()]); + } + } + + /** + * @desc 更新用户头像 + * @param $userId + * @param $param + * @return array + */ + public function updateHeadImg($userId, $param): array + { + try { + // 主键 + if (empty($userId) || $userId <= 0) { + return $this->toData('100403', 'Please log in first.', []); + } + + // 参数校验 + validate(UserValidate::class)->scene('updateHeadImg')->check($param); + $fileId = $param['file_id']; + + // 文件是否存在 + $file = FileModel::getById($fileId); + if (empty($file)) { + return $this->toData('100400', 'The file does not exist.', []); + } + + + // 设置 + UserModel::updateFieldsByUserId(['head_img_id' => $fileId], $userId); + return $this->toData('0', 'Modification successful.'); + } catch (ValidateException $validateException) { + $message = $validateException->getMessage(); + return $this->toData('100400', $message, []); + } catch (\Exception $exception) { + return $this->toData('100500', 'The system is busy.', []); + } + } + + /** + * @desc 设置用户 昵称 性别 名字信息 + * @param $userId + * @param $param + * @return array + */ + public function updateInfo($userId, $param): array + { + try { + // 主键 + if (empty($userId) || $userId <= 0) { + return $this->toData('100403', 'Please log in first.', []); + } + + // 参数校验 + validate(UserValidate::class)->scene('updateInfo')->check($param); + + // 查找用户信息 + $user = UserModel::getFieldsByUserId('user_id,nick_name,first_name,first_name,gender', $userId); + if (empty($user)) { + return $this->toData('100403', 'Please log in first.', []); + } + + $nickName = $param['nick_name']; + $gender = $param['gender']; + $lastName = $param['last_name'] ?? $user['last_name']; + $first_name = $param['first_name'] ?? $user['first_name']; + + UserModel::updateFieldsByUserId([ + 'nick_name' => $nickName, + 'first_name' => $first_name, + 'last_name' => $lastName, + 'gender' => $gender, + ], $userId); + + // 返回 + return $this->toData('0', 'Modification successful.', []); + } catch (ValidateException $validateException) { + $message = $validateException->getError(); + return $this->toData('100400', $message); + } catch (\Exception $exception) { + return $this->toData('100500', 'The system is busy.', [$exception->getMessage()]); + } + + } + + /** + * @desc 登陆状态下发送短信 + * @param $userId + * @param $param + * @return array + * @throws \Psr\SimpleCache\InvalidArgumentException + */ + public function sendEmail($userId, $param) + { + try { + $ip = $this->getClientRealIp(); + + // 主键 + if (empty($userId) || $userId <= 0) { + return $this->toData('100403', 'Please log in first.', []); + } + + // 参数校验 + validate(UserValidate::class)->scene('sendEmail')->check($param); + + // 如果是非交易业务 需要判断验证码获取次数 + $key = 'USER:SEND_CODE_NUM:' . $ip; + if ($param['business'] == '1') { + if ($this->checkGetNoTradeCodeNum($key)) { + return $this->toData('100300', 'No worries. Please feel free to reach out again tomorrow.', []); + } + } + + // 提取参数 + $emailType = $param['email_type']; // 1 给已经绑定的邮箱发 2 给新邮箱发 + $email = $param['email'] ?? ''; + if ($emailType == 1) { + $email = UserModel::getEmailById($userId); + if (empty($email)) { + return $this->toData('100400', '邮箱未绑定', []); + } + } + + // 获取邮件内容 + $content = $this->getEmailContent(); + $content['email'] = $email; + $code = $content['code']; + Queue::push('app\home\job\SendEmail', $content, 'sendEmail'); + + // 设置缓存 + $sendEmailCacheKey = 'USER:sendEmailLoginTrade:' . $email; + if ($param['business'] == '1') { + $sendEmailCacheKey = 'USER:sendEmailLoginNoTrade:' . $email; + // 累加ip获取的次数 + $this->updateHadGetCodeNumCache($key); + } + + $this->insertCodeToCache($sendEmailCacheKey, $code, 300); + + // 返回结果 + return $this->toData('0', 'Modification successful.'); + } catch (ValidateException $validateException) { + // 参数校验失败 异常类 + $message = $validateException->getError(); + return $this->toData('100400', $message); + } catch (\Exception $exception) { + return $this->toData('100500', 'The system is busy.', [$exception->getMessage()]); + } + } + + /** + * @desc 登陆状态下发送短信 + * @param $userId + * @param $param + * @return array + * @throws \Psr\SimpleCache\InvalidArgumentException + */ + public function sendSms($userId, $param): array + { + try { + $ip = $this->getClientRealIp(); + + // 主键 + if (empty($userId) || $userId <= 0) { + return $this->toData('100403', 'Please log in first.', []); + } + + // 参数校验 + validate(UserValidate::class)->scene('sendSms')->check($param); + + // 如果是非交易业务 需要判断验证码获取次数 + $key = 'USER:SEND_CODE_NUM:' . $ip; + if ($param['business'] == '1') { + if ($this->checkGetNoTradeCodeNum($key)) { + return $this->toData('100300', 'No worries. Please feel free to reach out again tomorrow.', []); + } + } + + // 提取参数 + $phoneType = $param['phone_type']; // 1 给已经绑定的手机发 2 给新手机发 + $phone = $param['phone'] ?? ''; + $nation = $param['nation'] ?? ''; + if ($phoneType == 1) { + $user = UserModel::getFieldsByUserId('country_code,phone_number', $userId); + if (empty($user)) { + return $this->toData('100400', 'The phone number is not linked/bound.', []); + } + $phone = $user['phone_number']; + $nation = $user['country_code']; + } else { + // 如果给新手机发 判断国家码是否存在 + $nationCheck = CountryModel::checkCodeExists($nation); + if (!$nationCheck) { + return $this->toData('100400', 'Unsupported country or region.', []); + } + } + + $mobile = $nation . $phone; + + // 获取邮件内容 + $content = $this->getSmsContent(1); + $content['mobile'] = $mobile; + $code = $content['code']; + Queue::push('app\home\job\SendSms', $content, 'sendSms'); + + // 设置缓存 + $sendCodeKey = 'USER:sendSmsLoginTrade:' . $mobile; + + if ($param['business'] == '1') { + $sendCodeKey = 'USER:sendSmsLoginNoTrade:' . $mobile; + // 累加已经获取的次数 + $this->updateHadGetCodeNumCache($key); + } + $this->insertCodeToCache($sendCodeKey, $code, 300); + + + // 返回结果 + return $this->toData('0', 'Modification successful.'); + } catch (ValidateException $validateException) { + // 参数校验失败 异常类 + $message = $validateException->getError(); + return $this->toData('100400', $message); + } catch (\Exception $exception) { + return $this->toData('100500', 'The system is busy.', [$exception->getMessage()]); + } + } + + public function setPayPasswordByEmail($userId, $param) + { + try { + // 主键 + if (empty($userId) || $userId <= 0) { + return $this->toData('100403', 'Please log in first.', []); + } + + // 参数校验 email_code pay_password + validate(UserValidate::class)->scene('setPayPasswordByEmail')->check($param); + + // 获取用户 + $user = UserModel::getFieldsByUserId('email,user_id,trade_password', $userId); + if (empty($user)) { + return $this->toData('100403', 'Please log in first.', []); + } + +// // 校验验证码 +// $key = 'USER:sendEmailLoginNoTrade:'.$user['email']; +// $emailCache = Cache::store('redis')->get($key); +// if(empty($param['email_code']) || $emailCache != $param['email_code']){ +// return $this->toData('100400', 'The verification code is incorrect.', []); +// } + + // 如果已经存在交易密码 则不能设置 + if (!empty($user['trade_password'])) { + return $this->toData('100400', 'The payment password has already been set.', []); + } + + // 加密密码 + $payPassword = $param['pay_password']; + $salt = env('ENCRYPT.SALT'); + $payPassword = (new UnqId())->encryptPassword($payPassword, $salt); + + // 设置密码 + UserModel::setPayPassword($payPassword, $salt, $userId); + + return $this->toData('0', 'Modification successful.', []); + } catch (ValidateException $validateException) { + // 参数校验失败 异常类 + $message = $validateException->getError(); + return $this->toData('100400', $message); + } catch (\Exception $exception) { + return $this->toData('100500', 'The system is busy.', []); + } + } + + /** + * @desc 通过短信设置取款密码 + * @param $userId + * @param $param + * @return array + * @throws \Psr\SimpleCache\InvalidArgumentException + */ + public function setPayPasswordBySms($userId, $param) + { + try { + // 主键 + if (empty($userId) || $userId <= 0) { + return $this->toData('100403', 'Please log in first.', []); + } + + // 参数校验 nation phone pay_password + validate(UserValidate::class)->scene('setPayPasswordBySms')->check($param); + + // 获取用户信息 + $user = UserModel::getFieldsByUserId('country_code,phone_number,user_id,trade_password', $userId); + if (empty($user)) { + return $this->toData('100403', 'Please log in first.', []); + } + + if (!empty($user['trade_password'])) { + return $this->toData('100400', 'The payment password has already been set.', []); + } + +// // 校验验证码 +// $mobile = $user['country_code'].$user['phone_number']; +// $key = 'USER:sendSmsLoginNoTrade:'.$mobile; +// if(Cache::store('redis')->get($key) != $param['sms_code']){ +// return $this->toData('100400', 'The verification code is incorrect.', []); +// } + + // 校验验证码 + $payPassword = $param['pay_password']; + $salt = env('ENCRYPT.SALT'); + $payPassword = (new UnqId())->encryptPassword($payPassword, $salt); + + + // 设置密码 + UserModel::setPayPassword($payPassword, $salt, $userId); + + return $this->toData('0', 'Modification successful.', []); + } catch (ValidateException $validateException) { + // 参数校验失败 异常类 + $message = $validateException->getError(); + return $this->toData('100400', $message); + } catch (\Exception $exception) { + return $this->toData('100500', 'The system is busy.', [$exception->getMessage()]); + } + + } + + /** + * @desc 通过手机号修改交易密码 + * @param $userId + * @param $param + * @return array + * @throws \Psr\SimpleCache\InvalidArgumentException + */ + public function updatePayPasswordBySms($userId, $param) + { + try { + // user_id + if (empty($userId) || $userId <= 0) { + return $this->toData('100403', 'Please log in first.', []); + } + + // 参数校验 email_code email + validate(UserValidate::class)->scene('updatePayPasswordBySms')->check($param); + + // 获取用户信息 + $user = UserModel::getFieldsByUserId('user_id,trade_password,salt,phone_number,country_code', $userId); + if (empty($user)) { + return $this->toData('100403', 'Please log in first.', []); + } + + // 提取参数 +// $nation = $user['country_code']; +// $phone = $user['phone_number']; +// $smsCode = $param['sms_code']; + $payPassword = $param['pay_password']; + $payPasswordNew = $param['pay_password_new']; + + // 校验验证码 +// $mobile = $nation.$phone; +// $cacheSmsKey = 'USER:sendSmsLoginNoTrade:'.$mobile; +// $cacheSmsCode = Cache::store('redis')->get($cacheSmsKey); +// if(empty($smsCode) || $smsCode != $cacheSmsCode){ +// return $this->toData('100400', 'The verification code is incorrect.', []); +// } + + // 校验旧密码 + $checkPasswordBool = (new UnqId())->checkPassword($payPassword, $user['trade_password'], $user['salt']); + if (!$checkPasswordBool) { + return $this->toData('100400', 'Incorrect password.'); + } + + // 设置密码 + $newPassword = (new UnqId())->encryptPassword($payPasswordNew, $user['salt']); + UserModel::updateFieldsByUserId(['trade_password' => $newPassword], $userId); + + // 返回结果 + return $this->toData('0', 'Modification successful.', []); + + } catch (ValidateException $validateException) { + // 参数校验失败 异常类 + $message = $validateException->getError(); + return $this->toData('100400', $message); + } catch (\Exception $exception) { + return $this->toData('100500', 'The system is busy.', [$exception->getMessage()]); + } + + } + + /** + * @desc 根据邮箱修改交易密码 + * @param $userId + * @param $param + * @return array + * @throws \Psr\SimpleCache\InvalidArgumentException + */ + public function updatePayPasswordByEmail($userId, $param) + { + // 通过 邮箱 收款密码 重新设置收款密码 + try { + // user_id + if (empty($userId) || $userId <= 0) { + return $this->toData('100403', 'Please log in first.', []); + } + + // 参数校验 email_code email + validate(UserValidate::class)->scene('updatePayPasswordByEmail')->check($param); + + // 获取用户信息 + $user = UserModel::getFieldsByUserId('user_id,trade_password,salt,email', $userId); + if (empty($user)) { + return $this->toData('100403', 'Please log in first.', []); + } + + // 提取参数 +// $email = $user['email']; +// $emailCode = $param['email_code']; + $payPassword = $param['pay_password']; + $payPasswordNew = $param['pay_password_new']; + + // 校验验证码 +// $cacheEmailKey = 'USER:sendEmailLoginNoTrade:'.$email; +// $cacheEmailCode = Cache::store('redis')->get($cacheEmailKey); +// if(empty($emailCode) || $emailCode != $cacheEmailCode){ +// return $this->toData('100400', 'The verification code is incorrect.', []); +// } + + // 校验旧密码 + $checkPasswordBool = (new UnqId())->checkPassword($payPassword, $user['trade_password'], $user['salt']); + if (!$checkPasswordBool) { + return $this->toData('100400', 'Incorrect password.', []); + } + + // 设置密码 + $newPassword = (new UnqId())->encryptPassword($payPasswordNew, $user['salt']); + UserModel::updateFieldsByUserId(['trade_password' => $newPassword], $userId); + + // 返回结果 + return $this->toData('0', 'Modification successful.', []); + + } catch (ValidateException $validateException) { + // 参数校验失败 异常类 + $message = $validateException->getError(); + return $this->toData('100400', $message); + } catch (\Exception $exception) { + return $this->toData('100500', 'The system is busy.', [$exception->getMessage()]); + } + + } + + /** + * @desc 根据短信重新设置交易密码 + * @param $userId + * @param $param + * @return array + * @throws \Psr\SimpleCache\InvalidArgumentException + */ + public function resetPayPasswordBySms($userId, $param) + { + try { + // user_id + if (empty($userId) || $userId <= 0) { + return $this->toData('100403', 'Please log in first.', []); + } + + // 参数校验 email_code email + validate(UserValidate::class)->scene('resetPayPasswordBySms')->check($param); + + // 获取用户信息 + $user = UserModel::getFieldsByUserId('user_id,salt,phone_number,country_code', $userId); + if (empty($user)) { + return $this->toData('100403', 'Please log in first.', []); + } + + // 提取参数 +// $nation = $user['country_code']; +// $phone = $user['phone_number']; +// $smsCode = $param['sms_code']; + $payPasswordNew = $param['pay_password_new']; + + // 校验验证码 +// $mobile = $nation.$phone; +// $cacheSmsKey = 'USER:sendSmsLoginNoTrade:'.$mobile; +// $cacheSmsCode = Cache::store('redis')->get($cacheSmsKey); +// if(empty($smsCode) || $smsCode != $cacheSmsCode){ +// return $this->toData('100400', 'The verification code is incorrect.', []); +// } + + // 设置密码 + $newPassword = (new UnqId())->encryptPassword($payPasswordNew, $user['salt']); + UserModel::updateFieldsByUserId(['trade_password' => $newPassword], $userId); + + // 返回结果 + return $this->toData('0', 'Modification successful.', []); + + } catch (ValidateException $validateException) { + // 参数校验失败 异常类 + $message = $validateException->getError(); + return $this->toData('100400', $message); + } catch (\Exception $exception) { + return $this->toData('100500', 'The system is busy.', [$exception->getMessage()]); + } + + } + + /** + * @desc 通过邮箱重新设置交易密码 + * @param $userId + * @param $param + * @return array + * @throws \Psr\SimpleCache\InvalidArgumentException + */ + public function resetPayPasswordByEmail($userId, $param) + { + // 通过邮箱验证码 新密码 设置交易密码 + try { + // user_id + if (empty($userId) || $userId <= 0) { + return $this->toData('100403', 'Please log in first.', []); + } + + // 参数校验 email_code email + validate(UserValidate::class)->scene('resetPayPasswordByEmail')->check($param); + + // 获取用户信息 + $user = UserModel::getFieldsByUserId('user_id,salt,email', $userId); + if (empty($user)) { + return $this->toData('100403', 'Please log in first.', []); + } + + // 提取参数 +// $email = $user['email']; +// $emailCode = $param['email_code']; + $payPasswordNew = $param['pay_password_new']; + + // 校验验证码 +// $cacheEmailKey = 'USER:sendEmailLoginNoTrade:'.$email; +// $cacheEmailCode = Cache::store('redis')->get($cacheEmailKey); +// if(empty($emailCode) || $emailCode != $cacheEmailCode){ +// return $this->toData('100400', 'The verification code is incorrect.', []); +// } + + // 设置密码 + $newPassword = (new UnqId())->encryptPassword($payPasswordNew, $user['salt']); + UserModel::updateFieldsByUserId(['trade_password' => $newPassword], $userId); + + // 返回结果 + return $this->toData('0', 'Modification successful.', []); + + } catch (ValidateException $validateException) { + // 参数校验失败 异常类 + $message = $validateException->getError(); + return $this->toData('100400', $message); + } catch (\Exception $exception) { + return $this->toData('100500', 'The system is busy.', [$exception->getMessage()]); + } + } + + public function updatePasswordBySms($userId, $param) + { + try { + if (empty($userId) || $userId <= 0) { + return $this->toData('100403', 'Please log in first.', []); + } + + // 参数校验 email_code email + validate(UserValidate::class)->scene('updatePasswordBySms')->check($param); + + // 获取用户信息 + $user = UserModel::getFieldsByUserId('user_id,login_password,salt,phone_number,country_code', $userId); + if (empty($user)) { + return $this->toData('100403', 'Please log in first.', []); + } + + // 提取参数 +// $nation = $user['country_code']; +// $phone = $user['phone_number']; +// $smsCode = $param['sms_code']; + $password = $param['password']; + $passwordNew = $param['password_new']; + + // 校验验证码 +// $mobile = $nation.$phone; +// $cacheSmsKey = 'USER:sendSmsLoginNoTrade:'.$mobile; +// $cacheSmsCode = Cache::store('redis')->get($cacheSmsKey); +// if(empty($smsCode) || $smsCode != $cacheSmsCode){ +// return $this->toData('100400', 'The verification code is incorrect.', []); +// } + + // 校验旧密码 + $checkPasswordBool = (new UnqId())->checkPassword($password, $user['login_password'], $user['salt']); + if (!$checkPasswordBool) { + return $this->toData('100400', 'Incorrect password.', []); + } + + // 设置密码 + $newPassword = (new UnqId())->encryptPassword($passwordNew, $user['salt']); + UserModel::updateFieldsByUserId(['login_password' => $newPassword], $userId); + + // 返回结果 + return $this->toData('0', 'Modification successful.', []); + + } catch (ValidateException $validateException) { + // 参数校验失败 异常类 + $message = $validateException->getError(); + return $this->toData('100400', $message); + } catch (\Exception $exception) { + return $this->toData('100500', 'The system is busy.', [$exception->getMessage()]); + } + + } + + /** + * @desc 邮箱修改登陆密码 + * @param $userId + * @param $param + * @return array + * @throws \Psr\SimpleCache\InvalidArgumentException + */ + public function updatePasswordByEmail($userId, $param) + { + try { + // user_id + if (empty($userId) || $userId <= 0) { + return $this->toData('100403', 'Please log in first.', []); + } + + // 参数校验 + validate(UserValidate::class)->scene('updatePasswordByEmail')->check($param); + + // 获取用户信息 + $user = UserModel::getFieldsByUserId('user_id,login_password,salt,email', $userId); + if (empty($user)) { + return $this->toData('100403', 'Please log in first.', []); + } + + // 提取参数 +// $email = $user['email']; +// $emailCode = $param['email_code']; + $password = $param['password']; + $passwordNew = $param['password_new']; + + // 校验验证码 +// $cacheEmailKey = 'USER:sendEmailLoginNoTrade:'.$email; +// $cacheEmailCode = Cache::store('redis')->get($cacheEmailKey); +// if(empty($emailCode) || $emailCode != $cacheEmailCode){ +// return $this->toData('100400', 'The verification code is incorrect.', []); +// } + + // 校验旧密码 + $checkPasswordBool = (new UnqId())->checkPassword($password, $user['login_password'], $user['salt']); + if (!$checkPasswordBool) { + return $this->toData('100400', 'Incorrect password.', []); + } + + // 设置密码 + $newPassword = (new UnqId())->encryptPassword($passwordNew, $user['salt']); + UserModel::updateFieldsByUserId(['login_password' => $newPassword], $userId); + + // 返回结果 + return $this->toData('0', 'Modification successful.', []); + + } catch (ValidateException $validateException) { + // 参数校验失败 异常类 + $message = $validateException->getError(); + return $this->toData('100400', $message); + } catch (\Exception $exception) { + return $this->toData('100500', 'The system is busy.', [$exception->getMessage()]); + } + + } + + /** + * @desc 短信重新设置登陆密码 + * @param $userId + * @param $param + * @return array + * @throws \Psr\SimpleCache\InvalidArgumentException + */ + public function resetPasswordBySms($userId, $param) + { + try { + if (empty($userId) || $userId <= 0) { + return $this->toData('100403', 'Please log in first.', []); + } + + // 参数校验 email_code email + validate(UserValidate::class)->scene('resetPasswordBySms')->check($param); + + // 获取用户信息 + $user = UserModel::getFieldsByUserId('user_id,salt,phone_number,country_code', $userId); + if (empty($user)) { + return $this->toData('100403', 'Please log in first.', []); + } + + // 提取参数 +// $nation = $user['country_code']; +// $phone = $user['phone_number']; +// $smsCode = $param['sms_code']; + $passwordNew = $param['password_new']; + + // 校验验证码 +// $mobile = $nation.$phone; +// $cacheSmsKey = 'USER:sendSmsLoginNoTrade:'.$mobile; +// $cacheSmsCode = Cache::store('redis')->get($cacheSmsKey); +// if(empty($smsCode) || $smsCode != $cacheSmsCode){ +// return $this->toData('100400', 'The verification code is incorrect.', []); +// } + + // 设置密码 + $newPassword = (new UnqId())->encryptPassword($passwordNew, $user['salt']); + UserModel::updateFieldsByUserId(['login_password' => $newPassword], $userId); + + // 返回结果 + return $this->toData('0', 'Modification successful.', []); + + } catch (ValidateException $validateException) { + // 参数校验失败 异常类 + $message = $validateException->getError(); + return $this->toData('100400', $message); + } catch (\Exception $exception) { + return $this->toData('100500', 'The system is busy.', [$exception->getMessage()]); + } + + } + + /** + * @desc 邮箱重新设置登陆密码 + * @param $userId + * @param $param + * @return array + * @throws \Psr\SimpleCache\InvalidArgumentException + */ + public function resetPasswordByEmail($userId, $param) + { + try { + // user_id + if (empty($userId) || $userId <= 0) { + return $this->toData('100403', 'Please log in first.', []); + } + + // 参数校验 email_code email + validate(UserValidate::class)->scene('resetPasswordByEmail')->check($param); + + // 获取用户信息 + $user = UserModel::getFieldsByUserId('user_id,salt,email', $userId); + if (empty($user)) { + return $this->toData('100403', 'Please log in first.', []); + } + + // 提取参数 +// $email = $user['email']; +// $emailCode = $param['email_code']; + $passwordNew = $param['password_new']; + + // 校验验证码 +// $cacheEmailKey = 'USER:sendEmailLoginNoTrade:'.$email; +// $cacheEmailCode = Cache::store('redis')->get($cacheEmailKey); +// if(empty($emailCode) || $emailCode != $cacheEmailCode){ +// return $this->toData('100400', 'The verification code is incorrect.', []); +// } + + // 设置密码 + $newPassword = (new UnqId())->encryptPassword($passwordNew, $user['salt']); + UserModel::updateFieldsByUserId(['login_password' => $newPassword], $userId); + + // 返回结果 + return $this->toData('0', 'Modification successful.', []); + + } catch (ValidateException $validateException) { + // 参数校验失败 异常类 + $message = $validateException->getError(); + return $this->toData('100400', $message); + } catch (\Exception $exception) { + return $this->toData('100500', 'The system is busy.', [$exception->getMessage()]); + } + } + + public function bindEmail($userId, $param) + { + try { + // user_id + if (empty($userId) || $userId <= 0) { + return $this->toData('100403', 'Please log in first.', []); + } + + // 参数校验 email_code email + validate(UserValidate::class)->scene('bindEmail')->check($param); + + // 判断验证码 +// $emailCode = $param['email_code']; + $email = $param['email']; +// $cacheCodeKey = 'USER:sendEmailLoginNoTrade:'.$email; +// $cacheSmsCode = Cache::store('redis')->get($cacheCodeKey); +// if(empty($emailCode) || $emailCode != $cacheSmsCode){ +// return $this->toData('100400', 'The verification code is incorrect.', []); +// } + + // 获取用户信息 + $user = UserModel::getFieldsByUserId('email,user_id', $userId); + if (empty($user)) { + return $this->toData('100403', 'Please log in first.', []); + } + + // 判读是否已经绑定 + if (!empty($user['email'])) { + return $this->toData('100400', 'You have already bound your email', []); + } + + //判断手机号是否已经被别人绑定 + $emailExits = UserModel::checkEmailExists($email); + if ($emailExits) { + return $this->toData('100400', 'The email has been bound', []); + } + + // 执行入库操作 + UserModel::updateFieldsByUserId(['email' => $email], $userId); + + // 返回结果 + return $this->toData('0', 'Binding successful', []); + + } catch (ValidateException $validateException) { + // 参数校验失败 异常类 + $message = $validateException->getError(); + return $this->toData('100400', $message); + } catch (\Exception $exception) { + return $this->toData('100500', 'The system is busy.', [$exception->getMessage()]); + } + } + + /** + * @desc 修改已经绑定的手机号 + * @param $userId + * @param $param + * @return array + * @throws \Psr\SimpleCache\InvalidArgumentException + */ + public function updateEmail($userId, $param): array + { + try { + // user_id + if (empty($userId) || $userId <= 0) { + return $this->toData('100403', 'Please log in first.', []); + } + + // 参数校验 nation phone sms_code + validate(UserValidate::class)->scene('updateEmail')->check($param); + + // 判断验证码 +// $emailCode = $param['email_code']; + $email = $param['email']; +// $cacheCodeKey = 'USER:sendEmailLoginNoTrade:'.$email; +// $cacheSmsCode = Cache::store('redis')->get($cacheCodeKey); +// if(empty($emailCode) || $emailCode != $cacheSmsCode){ +// return $this->toData('100400', 'The verification code is incorrect.', []); +// } + + // 获取用户信息 + $user = UserModel::getFieldsByUserId('login_password,email,user_id,salt', $userId); + if (empty($user)) { + return $this->toData('100403', 'Please log in first.', []); + } + + // 判读是否已经绑定 需要已经绑定 + if (empty($user['email'])) { + return $this->toData('100400', 'Email is not linked/bound.', []); + } + + //校验登陆密码 + $passwordCheck = (new UnqId())->checkPassword($param['password'], $user['login_password'], $user['salt']); + if (!$passwordCheck) { + return $this->toData('100400', 'Incorrect password.', []); + } + + //判断手机号是否已经被别人绑定 + $emailExits = UserModel::checkEmailExists($email); + if ($emailExits) { + return $this->toData('100400', 'The email has already been linked/bound.', []); + } + + // 执行入库操作 + UserModel::updateFieldsByUserId(['email' => $email], $userId); + + // 返回结果 + return $this->toData('0', 'Modification successful.', []); + } catch (ValidateException $validateException) { + // 参数校验失败 异常类 + $message = $validateException->getError(); + return $this->toData('100400', $message); + } catch (\Exception $exception) { + return $this->toData('100500', 'The system is busy.', [$exception->getMessage()]); + } + } + + + public function bindPhone($userId, $param) + { + try { + // user_id + if (empty($userId) || $userId <= 0) { + return $this->toData('100403', 'Please log in first.', []); + } + + // 参数校验 nation phone sms_code + validate(UserValidate::class)->scene('bindPhone')->check($param); + + // 判断验证码 +// $smsCode = $param['sms_code']; +// $mobile = $param['nation'].$param['phone']; +// $cacheSmsKey = 'USER:sendSmsLoginNoTrade:'.$mobile; +// $cacheSmsCode = Cache::store('redis')->get($cacheSmsKey); +// if(empty($smsCode) || $smsCode != $cacheSmsCode){ +// return $this->toData('100400', 'The verification code is incorrect.', []); +// } + + // 获取用户信息 + $user = UserModel::getFieldsByUserId('user_id,country_code,phone_number', $userId); + if (empty($user)) { + return $this->toData('100403', 'Please log in first.', []); + } + + // 判读是否已经绑定 + if (!empty($user['phone_number'])) { + return $this->toData('100400', 'The phone number has already been linked/bound.', []); + } + + //判断手机号是否已经被别人绑定 + $phoneExits = UserModel::checkPhoneExists($param['phone']); + if ($phoneExits) { + return $this->toData('100400', 'The phone number has already been linked/bound.', []); + } + + // 判断国家码是否存在 + $codeExists = CountryModel::checkCodeExists($param['nation']); + if (!$codeExists) { + return $this->toData('100400', 'Unsupported country or region.', []); + } + + // 执行入库操作 + UserModel::updateFieldsByUserId(['phone_number' => $param['phone'], 'country_code' => $param['nation']], $userId); + + // 返回结果 + return $this->toData('0', 'Binding successful.', []); + + } catch (ValidateException $validateException) { + // 参数校验失败 异常类 + $message = $validateException->getError(); + return $this->toData('100400', $message); + } catch (\Exception $exception) { + return $this->toData('100500', 'The system is busy.', [$exception->getMessage()]); + } + } + + /** + * @desc 修改已经绑定的手机号 + * @param $userId + * @param $param + * @return array + * @throws \Psr\SimpleCache\InvalidArgumentException + */ + public function updatePhone($userId, $param): array + { + try { + // user_id + if (empty($userId) || $userId <= 0) { + return $this->toData('100403', 'Please log in first.', []); + } + + // 参数校验 nation phone sms_code + validate(UserValidate::class)->scene('updatePhone')->check($param); + + // 判断验证码 +// $smsCode = $param['sms_code']; +// $mobile = $param['nation'].$param['phone']; +// $cacheSmsKey = 'USER:sendSmsLoginNoTrade:'.$mobile; +// $cacheSmsCode = Cache::store('redis')->get($cacheSmsKey); +// if(empty($smsCode) || $smsCode != $cacheSmsCode){ +// return $this->toData('100400', 'The verification code is incorrect.', []); +// } + + // 判断国家码是否存在 + $codeExists = CountryModel::checkCodeExists($param['nation']); + if (!$codeExists) { + return $this->toData('100400', 'Unsupported country or region', []); + } + + //判断手机号是否已经被别人绑定 + $phoneExits = UserModel::checkPhoneExists($param['phone']); + if ($phoneExits) { + return $this->toData('100400', 'The phone number has already been linked/bound.', []); + } + + // 获取用户信息 + $user = UserModel::getFieldsByUserId('salt,login_password,user_id,country_code,phone_number', $userId); + if (empty($user)) { + return $this->toData('100403', 'Please log in first.', []); + } + + // 判读是否已经绑定 需要已经绑定手机 + if (empty($user['phone_number'])) { + return $this->toData('100400', 'The phone number is not linked/bound.', []); + } + + //校验登陆密码 + $passwordCheck = (new UnqId())->checkPassword($param['password'], $user['login_password'], $user['salt']); + if (!$passwordCheck) { + return $this->toData('100400', 'Incorrect password.', []); + } + + // 执行入库操作 + UserModel::updateFieldsByUserId(['phone_number' => $param['phone'], 'country_code' => $param['nation']], $userId); + + // 返回结果 + return $this->toData('0', 'Modification successful.', []); + } catch (ValidateException $validateException) { + // 参数校验失败 异常类 + $message = $validateException->getError(); + return $this->toData('100400', $message); + } catch (\Exception $exception) { + return $this->toData('100500', 'The system is busy.', [$exception->getMessage()]); + } + } + public function apply_loan($userId, $param) + { + try { + // user_id + if (empty($userId) || $userId <= 0) { + return $this->toData('100403', 'Please log in first.', []); + } + + // 参数校验 nation phone sms_code + validate(UserValidate::class)->scene('apply_loan')->check($param); + $count=UserLoanModel::where('status',0)->where('user_id',$userId)->count(); + if($count>0){ + return $this->toData('100402', 'You have applied, please be patient and wait.', []); + } + + $userloan=new UserLoanModel(); + $userloan->user_id=$userId; + $userloan->num= intval($param['num']); + $userloan->day= intval($param['day']); + $userloan->status= 0; + $userloan->is_delete= 0; + $userloan->create_time=date('Y-m-d H:i:s'); + $userloan->save(); + + // 返回结果 + return $this->toData('0', 'Binding successful.', []); + + } catch (ValidateException $validateException) { + // 参数校验失败 异常类 + $message = $validateException->getError(); + return $this->toData('100400', $message); + } catch (\Exception $exception) { + return $this->toData('100500', 'The system is busy.', [$exception->getMessage()]); + } + } + public function loan($userId, $param) + { + try { + // user_id + if (empty($userId) || $userId <= 0) { + return $this->toData('100403', 'Please log in first.', []); + } + $data['where']['user_id']=$userId; + $data['page']=isset($param['page']) ? intval($param['page']) : 1; + $data['size']=isset($param['size']) ? intval($param['size']) : 10; + $list=UserLoanModel::getUserLoanList($data); + // 返回结果 + return $this->toData('0', 'successful.', $list); + + } catch (ValidateException $validateException) { + // 参数校验失败 异常类 + $message = $validateException->getError(); + return $this->toData('100400', $message); + } catch (\Exception $exception) { + return $this->toData('100500', 'The system is busy.', [$exception->getMessage()]); + } + } + + + /** + * @desc 退出登陆 + * @param $userId + * @return array + */ + public function logout($userId) + { + try { + // 删除缓存 + $this->delUserTokenCache($userId); + return $this->toData('0', 'Modification successful.'); + } catch (\Exception $exception) { + return $this->toData('100500', 'The system is busy.', [$exception->getMessage()]); + } + + } + + /** + * @desc 获取用户登陆信息 + * @param $userId + * @return array + */ + public function loginLog($userId): array + { + try { + if (empty($userId) || $userId <= 0) { + return $this->toData('100403', 'Please log in first.', []); + } + + $data = UserLoginLog::getLog($userId); + if (empty($data)) { + return $this->toData('0', 'Modification successful.', []); + } + + $res = []; + foreach ($data as $item) { + $countryCn = ''; + $countryEn = ''; + $cityCn = ''; + $cityEn = ''; + if (!empty($item['country'])) { + $countryArr = json_decode($item['country'], true); + $countryCn = $countryArr['cn']; + $countryEn = $countryArr['en']; + } + + if (!empty($item['city'])) { + $cityArr = json_decode($item['city'], true); + $cityCn = $cityArr['cn']; + $cityEn = $cityArr['en']; + } + + $res[] = [ + 'device' => $item['device'], + 'ip' => $item['ip'], + 'countryCn' => $countryCn, + 'countryEn' => $countryEn, + 'cityCn' => $cityCn, + 'cityEn' => $cityEn, + 'loginDate' => $item['login_date'], + ]; + } + + return $this->toData('0', 'Modification successful.', $res); + } catch (\Exception $exception) { + return $this->toData('100500', 'The system is busy.', []); + } + } + + /** + * 用户申请使用杠杆 + * @param $userId + * @return array + */ + public function leverApply($userId) + { + try { + if (empty($userId) || $userId <= 0) { + return $this->toData('100403', 'Please log in first.', []); + } + + // 获取用户信息 + $user = UserModel::getFieldsByUserId('lever_status,user_id', $userId); + if (empty($user)) { + return $this->toData('100403', 'Please log in first.', []); + } + + if (in_array($user['lever_status'], [UserModel::LEVER_STATUS_NO, UserModel::LEVER_STATUS_FAIL])) { + $level_status=env('USER_LEVEL.NO_APPLY')==1 ? UserModel::LEVER_STATUS_PASSED : UserModel::LEVER_STATUS_APPLY; + UserModel::update(['lever_status' => $level_status, 'update_time' => date('Y-m-d H:i:s')], ['user_id' => $userId]); + return $this->toData('0', 'success.', []); + } + + return $this->toData('0', 'Already submitted.', []); + + } catch (\Exception $exception) { + return $this->toData('100500', 'The system is busy.', []); + } + } + public function applyTestAccount($userId) + { + + if (empty($userId) || $userId <= 0) { + return $this->toData('100403', 'Please log in first.', []); + } + + // 获取用户信息 + $user = UserModel::getFieldsByUserId('test_account,user_id,user_no', $userId); + if (empty($user)) { + return $this->toData('100401', 'Please log in first.', []); + } + if(!empty($user['test_account'])){ + return $this->toData('0', 'success.', []); + } + //添加模拟账号 + $userNo=$this->getUniqUserNo(); + $email="test_".$userNo."@test.com"; + $salt = env('ENCRYPT.SALT'); + $password = (new UnqId())->encryptPassword('test12345', $salt); + $userInviteCode=$this->getUniqInviteCode(); + $parentUserId = $userId; + $ip = (new BaseHomeService())->getClientRealIp(); + $test_userId = UserModel::emailRegister($email, $userNo, $userInviteCode, $parentUserId, $password, $ip, $salt, 2, 0); + if($test_userId){ + $this->doRegInitUserInfo($test_userId,$parentUserId); + UserModel::where('user_id', $userId)->update([ + 'test_account' => $test_userId + ]); + UserModel::where('user_id', $test_userId)->update([ + 'is_real' => 0, + 'real_status'=>3 + ]); + if(env('ACCOUT_TYPE.ALL_IN_ONE')==1){ + UserMoneyModel::where('user_id', $test_userId)->update([ + 'user_id' => $test_userId, + 'stock_id' => 'USD', + 'usable_num' => 100000, + 'frozen_num' => 0, + ]); + }else{ + UserDigitalModel::where('user_id', $test_userId)->update([ + 'user_id' => $test_userId, + 'digital_id' => 'USDT', + 'usable_num' => 100000, + 'frozen_num' => 0, + ]); + UserContractModel::where('user_id', $test_userId)->update([ + 'user_id' => $test_userId, + 'contract_id' => 'USDT', + 'usable_num' => 100000, + 'frozen_num' => 0, + ]); + UserForexModel::InsertUserForex([ + 'user_id' => $test_userId, + 'contract_id' => 'USD', + 'usable_num' => 100000, + 'frozen_num' => 0, + ]); + UserStockHkdModel::InsertUserStock([ + 'user_id' => $test_userId, + 'stock_id' => 'HKD', + 'usable_num' => 100000, + 'frozen_num' => 0, + ]); + } + + } + return $this->toData('0', 'success.', []); + } + public function applyTestMoney($userId,$param){ + if (empty($userId) || $userId <= 0) { + return $this->toData('100403', 'Please log in first.', []); + } + + // 获取用户信息 + $user = UserModel::getFieldsByUserId('is_test_user,user_id,user_no', $userId); + if (empty($user)) { + return $this->toData('100401', 'Please log in first.', []); + } + if($user['is_test_user']!=2){ + return $this->toData('100402', 'error.', []); + } + $num=isset($param['num']) ? intval($param['num']) : 0; + if($num<=0 || $num>100000){ + return $this->toData('100401', 'error.', []); + } + $user_money=UserMoneyModel::getUserUSDByUserId(['user_id'=>$userId]); + $update_num=$user_money['usable_num']+$num; + UserMoneyModel::where('user_id', $userId)->update([ + 'stock_id' => 'USD', + 'usable_num' => $update_num, + 'update_time' => date('Y-m-d H:i:s'), + ]); + + return $this->toData('0', 'success.', []); + } + public function testLogin($userId) + { + // 获取用户信息 + $user = UserModel::getFieldsByUserId('test_account,user_id,user_no', $userId); + if (empty($user)) { + return $this->toData('100401', 'Please log in first.', []); + } + if(empty($user['test_account'])){ + return $this->toData('100402', 'Please log in first.', []); + } + //登录模拟账号 + $test_user=UserModel::getFieldsByUserId('test_account,user_id,user_no,nick_name,invite_code,is_real,is_test_user', $user['test_account']); + // 生成token + $token = (new Jwt())->getToken($test_user['user_id'], env('ENCRYPT.SALT')); + if (empty($token)) { + return $this->toData('100300', 'The system is busy.', []); + } + + // 将token存致缓存 覆盖新的缓存 实现单设备登陆 + $this->setUserTokenCache($token, $test_user['user_id']); + // 删除缓存 + $this->delUserTokenCache($userId); + // 返回结果以及用户信息 + return $this->toData('0', 'Request successful.', [ + 'userId' => $test_user['user_id'], + 'userNo' => $test_user['user_no'], + 'nickName' => $test_user['nick_name'], + 'inviteCode' => $test_user['invite_code'], + 'isReal' => $test_user['is_real'], + 'is_test_user' => $test_user['is_test_user'], + 'logo' => env('USER.DEFAULT_HEAD_IMG_PATH'), + 'token' => $token, + ]); + } + public function formalLogin($userId) + { + // 获取用户信息 + $user = UserModel::getFieldsByUserId('parent_id,user_id,user_no,is_test_user', $userId); + if (empty($user)) { + return $this->toData('100401', 'Please log in first.', []); + } + if(empty($user['parent_id'])){ + return $this->toData('100402', 'The system is busy.', []); + } + if(empty($user['is_test_user'])){ + return $this->toData('100403', 'The system is busy.', []); + } + //登录模拟账号 + $test_user=UserModel::getFieldsByUserId('test_account,user_id,user_no,nick_name,invite_code,is_real,is_test_user', $user['parent_id']); + if($test_user['test_account']!=$userId){ + return $this->toData('100404', 'The system is busy.', []); + } + // 生成token + $token = (new Jwt())->getToken($test_user['user_id'], env('ENCRYPT.SALT')); + if (empty($token)) { + return $this->toData('100300', 'The system is busy.', []); + } + + // 将token存致缓存 覆盖新的缓存 实现单设备登陆 + $this->setUserTokenCache($token, $test_user['user_id']); + // 删除缓存 + $this->delUserTokenCache($userId); + // 返回结果以及用户信息 + return $this->toData('0', 'Request successful.', [ + 'userId' => $test_user['user_id'], + 'userNo' => $test_user['user_no'], + 'nickName' => $test_user['nick_name'], + 'inviteCode' => $test_user['invite_code'], + 'isReal' => $test_user['is_real'], + 'is_test_user' => $test_user['is_test_user'], + 'logo' => env('USER.DEFAULT_HEAD_IMG_PATH'), + 'token' => $token, + ]); + } +} diff --git a/app/home/service/PreHkdStockService.php b/app/home/service/PreHkdStockService.php new file mode 100644 index 0000000..e281a8e --- /dev/null +++ b/app/home/service/PreHkdStockService.php @@ -0,0 +1,665 @@ +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', []); + } + } +} \ No newline at end of file diff --git a/app/home/service/PreIdnStockService.php b/app/home/service/PreIdnStockService.php new file mode 100644 index 0000000..357542b --- /dev/null +++ b/app/home/service/PreIdnStockService.php @@ -0,0 +1,675 @@ +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', []); + } + } +} \ No newline at end of file diff --git a/app/home/service/PreInStockService.php b/app/home/service/PreInStockService.php new file mode 100644 index 0000000..2eef475 --- /dev/null +++ b/app/home/service/PreInStockService.php @@ -0,0 +1,670 @@ +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', []); + } + } +} \ No newline at end of file diff --git a/app/home/service/PreMysStockService.php b/app/home/service/PreMysStockService.php new file mode 100644 index 0000000..7e2001e --- /dev/null +++ b/app/home/service/PreMysStockService.php @@ -0,0 +1,672 @@ +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', []); + } + } +} \ No newline at end of file diff --git a/app/home/service/PreSgdStockService.php b/app/home/service/PreSgdStockService.php new file mode 100644 index 0000000..6a3b94b --- /dev/null +++ b/app/home/service/PreSgdStockService.php @@ -0,0 +1,670 @@ +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', []); + } + } +} \ No newline at end of file diff --git a/app/home/service/PreThaStockService.php b/app/home/service/PreThaStockService.php new file mode 100644 index 0000000..6eb8e65 --- /dev/null +++ b/app/home/service/PreThaStockService.php @@ -0,0 +1,672 @@ +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', []); + } + } +} \ No newline at end of file diff --git a/app/home/service/PreUsStockService.php b/app/home/service/PreUsStockService.php new file mode 100644 index 0000000..e0b882d --- /dev/null +++ b/app/home/service/PreUsStockService.php @@ -0,0 +1,681 @@ +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', []); + } + } +} \ No newline at end of file diff --git a/app/home/service/UserService.php b/app/home/service/UserService.php index 2222886..6711436 100644 --- a/app/home/service/UserService.php +++ b/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) { diff --git a/app/home/service/VideoService.php b/app/home/service/VideoService.php index bd3cbc8..f9d98cd 100644 --- a/app/home/service/VideoService.php +++ b/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.', []); + } + } } \ No newline at end of file diff --git a/app/home/validate/UserValidate.php b/app/home/validate/UserValidate.php index 78c4963..f52dec8 100644 --- a/app/home/validate/UserValidate.php +++ b/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', ]; diff --git a/app/model/ForexListMode.php b/app/model/ForexListMode.php new file mode 100644 index 0000000..aed24df --- /dev/null +++ b/app/model/ForexListMode.php @@ -0,0 +1,79 @@ +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; + } + + + +} \ No newline at end of file diff --git a/app/model/PurchaseVipModel.php b/app/model/PurchaseVipModel.php new file mode 100644 index 0000000..b5b42cf --- /dev/null +++ b/app/model/PurchaseVipModel.php @@ -0,0 +1,7 @@ +=5.0.0" + "doctrine/dbal": "<3.7.0 || >=4.0.0" }, "require-dev": { - "doctrine/dbal": "^4.0.0", + "doctrine/dbal": "^3.7.0", "nesbot/carbon": "^2.71.0 || ^3.0.0", "phpunit/phpunit": "^10.3" }, @@ -376,7 +376,7 @@ ], "support": { "issues": "https://github.com/CarbonPHP/carbon-doctrine-types/issues", - "source": "https://github.com/CarbonPHP/carbon-doctrine-types/tree/3.2.0" + "source": "https://github.com/CarbonPHP/carbon-doctrine-types/tree/2.1.0" }, "funding": [ { @@ -392,7 +392,7 @@ "type": "tidelift" } ], - "time": "2024-02-09T16:56:22+00:00" + "time": "2023-12-11T17:09:12+00:00" }, { "name": "clagiordano/weblibs-configmanager", @@ -720,16 +720,16 @@ }, { "name": "firebase/php-jwt", - "version": "v6.10.2", + "version": "v6.10.0", "source": { "type": "git", "url": "https://github.com/firebase/php-jwt.git", - "reference": "30c19ed0f3264cb660ea496895cfb6ef7ee3653b" + "reference": "a49db6f0a5033aef5143295342f1c95521b075ff" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/firebase/php-jwt/zipball/30c19ed0f3264cb660ea496895cfb6ef7ee3653b", - "reference": "30c19ed0f3264cb660ea496895cfb6ef7ee3653b", + "url": "https://api.github.com/repos/firebase/php-jwt/zipball/a49db6f0a5033aef5143295342f1c95521b075ff", + "reference": "a49db6f0a5033aef5143295342f1c95521b075ff", "shasum": "", "mirrors": [ { @@ -739,13 +739,13 @@ ] }, "require": { - "php": "^8.0" + "php": "^7.4||^8.0" }, "require-dev": { - "guzzlehttp/guzzle": "^7.4", + "guzzlehttp/guzzle": "^6.5||^7.4", "phpspec/prophecy-phpunit": "^2.0", "phpunit/phpunit": "^9.5", - "psr/cache": "^2.0||^3.0", + "psr/cache": "^1.0||^2.0", "psr/http-client": "^1.0", "psr/http-factory": "^1.0" }, @@ -783,9 +783,9 @@ ], "support": { "issues": "https://github.com/firebase/php-jwt/issues", - "source": "https://github.com/firebase/php-jwt/tree/v6.10.2" + "source": "https://github.com/firebase/php-jwt/tree/v6.10.0" }, - "time": "2024-11-24T11:22:49+00:00" + "time": "2023-12-01T16:26:39+00:00" }, { "name": "geoip2/geoip2", @@ -1258,16 +1258,16 @@ }, { "name": "lcobucci/clock", - "version": "2.3.0", + "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/lcobucci/clock.git", - "reference": "c7aadcd6fd97ed9e199114269c0be3f335e38876" + "reference": "353d83fe2e6ae95745b16b3d911813df6a05bfb3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/lcobucci/clock/zipball/c7aadcd6fd97ed9e199114269c0be3f335e38876", - "reference": "c7aadcd6fd97ed9e199114269c0be3f335e38876", + "url": "https://api.github.com/repos/lcobucci/clock/zipball/353d83fe2e6ae95745b16b3d911813df6a05bfb3", + "reference": "353d83fe2e6ae95745b16b3d911813df6a05bfb3", "shasum": "", "mirrors": [ { @@ -1277,21 +1277,18 @@ ] }, "require": { - "php": "~8.1.0 || ~8.2.0", - "stella-maris/clock": "^0.1.7" - }, - "provide": { - "psr/clock-implementation": "1.0" + "php": "^7.4 || ^8.0" }, "require-dev": { - "infection/infection": "^0.26", - "lcobucci/coding-standard": "^9.0", - "phpstan/extension-installer": "^1.2", - "phpstan/phpstan": "^1.9.4", - "phpstan/phpstan-deprecation-rules": "^1.1.1", - "phpstan/phpstan-phpunit": "^1.3.2", - "phpstan/phpstan-strict-rules": "^1.4.4", - "phpunit/phpunit": "^9.5.27" + "infection/infection": "^0.17", + "lcobucci/coding-standard": "^6.0", + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "^0.12", + "phpstan/phpstan-deprecation-rules": "^0.12", + "phpstan/phpstan-phpunit": "^0.12", + "phpstan/phpstan-strict-rules": "^0.12", + "phpunit/php-code-coverage": "9.1.4", + "phpunit/phpunit": "9.3.7" }, "type": "library", "autoload": { @@ -1312,7 +1309,7 @@ "description": "Yet another clock abstraction", "support": { "issues": "https://github.com/lcobucci/clock/issues", - "source": "https://github.com/lcobucci/clock/tree/2.3.0" + "source": "https://github.com/lcobucci/clock/tree/2.0.x" }, "funding": [ { @@ -1324,7 +1321,7 @@ "type": "patreon" } ], - "time": "2022-12-19T14:38:11+00:00" + "time": "2020-08-27T18:56:02+00:00" }, { "name": "lcobucci/jwt", @@ -1629,16 +1626,16 @@ }, { "name": "maennchen/zipstream-php", - "version": "3.1.1", + "version": "2.2.6", "source": { "type": "git", "url": "https://github.com/maennchen/ZipStream-PHP.git", - "reference": "6187e9cc4493da94b9b63eb2315821552015fca9" + "reference": "30ad6f93cf3efe4192bc7a4c9cad11ff8f4f237f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/maennchen/ZipStream-PHP/zipball/6187e9cc4493da94b9b63eb2315821552015fca9", - "reference": "6187e9cc4493da94b9b63eb2315821552015fca9", + "url": "https://api.github.com/repos/maennchen/ZipStream-PHP/zipball/30ad6f93cf3efe4192bc7a4c9cad11ff8f4f237f", + "reference": "30ad6f93cf3efe4192bc7a4c9cad11ff8f4f237f", "shasum": "", "mirrors": [ { @@ -1648,22 +1645,19 @@ ] }, "require": { - "ext-mbstring": "*", - "ext-zlib": "*", - "php-64bit": "^8.1" + "myclabs/php-enum": "^1.5", + "php": "^7.4 || ^8.0", + "psr/http-message": "^1.0", + "symfony/polyfill-mbstring": "^1.0" }, "require-dev": { "ext-zip": "*", - "friendsofphp/php-cs-fixer": "^3.16", - "guzzlehttp/guzzle": "^7.5", + "friendsofphp/php-cs-fixer": "^3.9", + "guzzlehttp/guzzle": "^6.5.3 || ^7.2.0", "mikey179/vfsstream": "^1.6", - "php-coveralls/php-coveralls": "^2.5", - "phpunit/phpunit": "^10.0", - "vimeo/psalm": "^5.0" - }, - "suggest": { - "guzzlehttp/psr7": "^2.4", - "psr/http-message": "^2.0" + "php-coveralls/php-coveralls": "^2.4", + "phpunit/phpunit": "^8.5.8 || ^9.4.2", + "vimeo/psalm": "^4.1" }, "type": "library", "autoload": { @@ -1700,15 +1694,19 @@ ], "support": { "issues": "https://github.com/maennchen/ZipStream-PHP/issues", - "source": "https://github.com/maennchen/ZipStream-PHP/tree/3.1.1" + "source": "https://github.com/maennchen/ZipStream-PHP/tree/2.2.6" }, "funding": [ { "url": "https://github.com/maennchen", "type": "github" + }, + { + "url": "https://opencollective.com/zipstream", + "type": "open_collective" } ], - "time": "2024-10-10T12:33:01+00:00" + "time": "2022-11-25T18:57:19+00:00" }, { "name": "markbaker/complex", @@ -1829,79 +1827,6 @@ }, "time": "2022-12-02T22:17:43+00:00" }, - { - "name": "masterminds/html5", - "version": "2.8.1", - "source": { - "type": "git", - "url": "https://github.com/Masterminds/html5-php.git", - "reference": "f47dcf3c70c584de14f21143c55d9939631bc6cf" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Masterminds/html5-php/zipball/f47dcf3c70c584de14f21143c55d9939631bc6cf", - "reference": "f47dcf3c70c584de14f21143c55d9939631bc6cf", - "shasum": "", - "mirrors": [ - { - "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "ext-dom": "*", - "php": ">=5.3.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.8.35 || ^5.7.21 || ^6 || ^7 || ^8" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.7-dev" - } - }, - "autoload": { - "psr-4": { - "Masterminds\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Matt Butcher", - "email": "technosophos@gmail.com" - }, - { - "name": "Matt Farina", - "email": "matt@mattfarina.com" - }, - { - "name": "Asmir Mustafic", - "email": "goetas@gmail.com" - } - ], - "description": "An HTML5 parser and serializer.", - "homepage": "http://masterminds.github.io/html5-php", - "keywords": [ - "HTML5", - "dom", - "html", - "parser", - "querypath", - "serializer", - "xml" - ], - "support": { - "issues": "https://github.com/Masterminds/html5-php/issues", - "source": "https://github.com/Masterminds/html5-php/tree/2.8.1" - }, - "time": "2023-05-10T11:58:31+00:00" - }, { "name": "maxmind-db/reader", "version": "v1.12.0", @@ -1973,16 +1898,16 @@ }, { "name": "maxmind/web-service-common", - "version": "v0.10.0", + "version": "v0.9.0", "source": { "type": "git", "url": "https://github.com/maxmind/web-service-common-php.git", - "reference": "d7c7c42fc31bff26e0ded73a6e187bcfb193f9c4" + "reference": "4dc5a3e8df38aea4ca3b1096cee3a038094e9b53" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/maxmind/web-service-common-php/zipball/d7c7c42fc31bff26e0ded73a6e187bcfb193f9c4", - "reference": "d7c7c42fc31bff26e0ded73a6e187bcfb193f9c4", + "url": "https://api.github.com/repos/maxmind/web-service-common-php/zipball/4dc5a3e8df38aea4ca3b1096cee3a038094e9b53", + "reference": "4dc5a3e8df38aea4ca3b1096cee3a038094e9b53", "shasum": "", "mirrors": [ { @@ -1995,7 +1920,7 @@ "composer/ca-bundle": "^1.0.3", "ext-curl": "*", "ext-json": "*", - "php": ">=8.1" + "php": ">=7.2" }, "require-dev": { "friendsofphp/php-cs-fixer": "3.*", @@ -2024,9 +1949,9 @@ "homepage": "https://github.com/maxmind/web-service-common-php", "support": { "issues": "https://github.com/maxmind/web-service-common-php/issues", - "source": "https://github.com/maxmind/web-service-common-php/tree/v0.10.0" + "source": "https://github.com/maxmind/web-service-common-php/tree/v0.9.0" }, - "time": "2024-11-14T23:14:52+00:00" + "time": "2022-03-28T17:43:20+00:00" }, { "name": "mtdowling/jmespath.php", @@ -2100,6 +2025,75 @@ }, "time": "2023-08-25T10:54:48+00:00" }, + { + "name": "myclabs/php-enum", + "version": "1.8.4", + "source": { + "type": "git", + "url": "https://github.com/myclabs/php-enum.git", + "reference": "a867478eae49c9f59ece437ae7f9506bfaa27483" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/php-enum/zipball/a867478eae49c9f59ece437ae7f9506bfaa27483", + "reference": "a867478eae49c9f59ece437ae7f9506bfaa27483", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "ext-json": "*", + "php": "^7.3 || ^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.5", + "squizlabs/php_codesniffer": "1.*", + "vimeo/psalm": "^4.6.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "MyCLabs\\Enum\\": "src/" + }, + "classmap": [ + "stubs/Stringable.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP Enum contributors", + "homepage": "https://github.com/myclabs/php-enum/graphs/contributors" + } + ], + "description": "PHP Enum implementation", + "homepage": "http://github.com/myclabs/php-enum", + "keywords": [ + "enum" + ], + "support": { + "issues": "https://github.com/myclabs/php-enum/issues", + "source": "https://github.com/myclabs/php-enum/tree/1.8.4" + }, + "funding": [ + { + "url": "https://github.com/mnapoli", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/myclabs/php-enum", + "type": "tidelift" + } + ], + "time": "2022-08-04T09:53:51+00:00" + }, { "name": "nesbot/carbon", "version": "2.72.6", @@ -2279,16 +2273,16 @@ }, { "name": "phpdocumentor/reflection-docblock", - "version": "3.1.1", + "version": "3.3.2", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "8331b5efe816ae05461b7ca1e721c01b46bafb3e" + "reference": "bf329f6c1aadea3299f08ee804682b7c45b326a2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/8331b5efe816ae05461b7ca1e721c01b46bafb3e", - "reference": "8331b5efe816ae05461b7ca1e721c01b46bafb3e", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/bf329f6c1aadea3299f08ee804682b7c45b326a2", + "reference": "bf329f6c1aadea3299f08ee804682b7c45b326a2", "shasum": "", "mirrors": [ { @@ -2298,9 +2292,9 @@ ] }, "require": { - "php": ">=5.5", - "phpdocumentor/reflection-common": "^1.0@dev", - "phpdocumentor/type-resolver": "^0.2.0", + "php": "^5.6 || ^7.0", + "phpdocumentor/reflection-common": "^1.0.0", + "phpdocumentor/type-resolver": "^0.4.0", "webmozart/assert": "^1.0" }, "require-dev": { @@ -2328,22 +2322,22 @@ "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", "support": { "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", - "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/master" + "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/release/3.x" }, - "time": "2016-09-30T07:12:33+00:00" + "time": "2017-11-10T14:09:06+00:00" }, { "name": "phpdocumentor/type-resolver", - "version": "0.2.1", + "version": "0.4.0", "source": { "type": "git", "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "e224fb2ea2fba6d3ad6fdaef91cd09a172155ccb" + "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/e224fb2ea2fba6d3ad6fdaef91cd09a172155ccb", - "reference": "e224fb2ea2fba6d3ad6fdaef91cd09a172155ccb", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/9c977708995954784726e25d0cd1dddf4e65b0f7", + "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7", "shasum": "", "mirrors": [ { @@ -2353,7 +2347,7 @@ ] }, "require": { - "php": ">=5.5", + "php": "^5.5 || ^7.0", "phpdocumentor/reflection-common": "^1.0" }, "require-dev": { @@ -2387,7 +2381,7 @@ "issues": "https://github.com/phpDocumentor/TypeResolver/issues", "source": "https://github.com/phpDocumentor/TypeResolver/tree/master" }, - "time": "2016-11-25T06:54:22+00:00" + "time": "2017-07-14T14:27:02+00:00" }, { "name": "phpmailer/phpmailer", @@ -3090,71 +3084,18 @@ }, "time": "2019-03-08T08:55:37+00:00" }, - { - "name": "stella-maris/clock", - "version": "0.1.7", - "source": { - "type": "git", - "url": "https://github.com/stella-maris-solutions/clock.git", - "reference": "fa23ce16019289a18bb3446fdecd45befcdd94f8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/stella-maris-solutions/clock/zipball/fa23ce16019289a18bb3446fdecd45befcdd94f8", - "reference": "fa23ce16019289a18bb3446fdecd45befcdd94f8", - "shasum": "", - "mirrors": [ - { - "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", - "preferred": true - } - ] - }, - "require": { - "php": "^7.0|^8.0", - "psr/clock": "^1.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "StellaMaris\\Clock\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Andreas Heigl", - "role": "Maintainer" - } - ], - "description": "A pre-release of the proposed PSR-20 Clock-Interface", - "homepage": "https://gitlab.com/stella-maris/clock", - "keywords": [ - "clock", - "datetime", - "point in time", - "psr20" - ], - "support": { - "source": "https://github.com/stella-maris-solutions/clock/tree/0.1.7" - }, - "time": "2022-11-25T16:15:06+00:00" - }, { "name": "symfony/browser-kit", - "version": "v6.4.13", + "version": "v5.4.45", "source": { "type": "git", "url": "https://github.com/symfony/browser-kit.git", - "reference": "65d4b3fd9556e4b5b41287bef93c671f8f9f86ab" + "reference": "03cce39764429e07fbab9b989a1182a24578341d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/browser-kit/zipball/65d4b3fd9556e4b5b41287bef93c671f8f9f86ab", - "reference": "65d4b3fd9556e4b5b41287bef93c671f8f9f86ab", + "url": "https://api.github.com/repos/symfony/browser-kit/zipball/03cce39764429e07fbab9b989a1182a24578341d", + "reference": "03cce39764429e07fbab9b989a1182a24578341d", "shasum": "", "mirrors": [ { @@ -3164,14 +3105,18 @@ ] }, "require": { - "php": ">=8.1", - "symfony/dom-crawler": "^5.4|^6.0|^7.0" + "php": ">=7.2.5", + "symfony/dom-crawler": "^4.4|^5.0|^6.0", + "symfony/polyfill-php80": "^1.16" }, "require-dev": { - "symfony/css-selector": "^5.4|^6.0|^7.0", - "symfony/http-client": "^5.4|^6.0|^7.0", - "symfony/mime": "^5.4|^6.0|^7.0", - "symfony/process": "^5.4|^6.0|^7.0" + "symfony/css-selector": "^4.4|^5.0|^6.0", + "symfony/http-client": "^4.4|^5.0|^6.0", + "symfony/mime": "^4.4|^5.0|^6.0", + "symfony/process": "^4.4|^5.0|^6.0" + }, + "suggest": { + "symfony/process": "" }, "type": "library", "autoload": { @@ -3199,7 +3144,7 @@ "description": "Simulates the behavior of a web browser, allowing you to make requests, click on links and submit forms programmatically", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/browser-kit/tree/v6.4.13" + "source": "https://github.com/symfony/browser-kit/tree/v5.4.45" }, "funding": [ { @@ -3215,7 +3160,7 @@ "type": "tidelift" } ], - "time": "2024-10-25T15:07:50+00:00" + "time": "2024-10-22T13:05:35+00:00" }, { "name": "symfony/class-loader", @@ -3294,16 +3239,16 @@ }, { "name": "symfony/css-selector", - "version": "v6.4.13", + "version": "v5.4.45", "source": { "type": "git", "url": "https://github.com/symfony/css-selector.git", - "reference": "cb23e97813c5837a041b73a6d63a9ddff0778f5e" + "reference": "4f7f3c35fba88146b56d0025d20ace3f3901f097" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/css-selector/zipball/cb23e97813c5837a041b73a6d63a9ddff0778f5e", - "reference": "cb23e97813c5837a041b73a6d63a9ddff0778f5e", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/4f7f3c35fba88146b56d0025d20ace3f3901f097", + "reference": "4f7f3c35fba88146b56d0025d20ace3f3901f097", "shasum": "", "mirrors": [ { @@ -3313,7 +3258,8 @@ ] }, "require": { - "php": ">=8.1" + "php": ">=7.2.5", + "symfony/polyfill-php80": "^1.16" }, "type": "library", "autoload": { @@ -3345,7 +3291,7 @@ "description": "Converts CSS selectors to XPath expressions", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/css-selector/tree/v6.4.13" + "source": "https://github.com/symfony/css-selector/tree/v5.4.45" }, "funding": [ { @@ -3361,20 +3307,20 @@ "type": "tidelift" } ], - "time": "2024-09-25T14:18:03+00:00" + "time": "2024-09-25T14:11:13+00:00" }, { "name": "symfony/deprecation-contracts", - "version": "v3.5.1", + "version": "v2.5.4", "source": { "type": "git", "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6" + "reference": "605389f2a7e5625f273b53960dc46aeaf9c62918" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6", - "reference": "74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/605389f2a7e5625f273b53960dc46aeaf9c62918", + "reference": "605389f2a7e5625f273b53960dc46aeaf9c62918", "shasum": "", "mirrors": [ { @@ -3384,12 +3330,12 @@ ] }, "require": { - "php": ">=8.1" + "php": ">=7.1" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "3.5-dev" + "dev-main": "2.5-dev" }, "thanks": { "name": "symfony/contracts", @@ -3418,7 +3364,7 @@ "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v3.5.1" + "source": "https://github.com/symfony/deprecation-contracts/tree/v2.5.4" }, "funding": [ { @@ -3434,20 +3380,20 @@ "type": "tidelift" } ], - "time": "2024-09-25T14:20:29+00:00" + "time": "2024-09-25T14:11:13+00:00" }, { "name": "symfony/dom-crawler", - "version": "v6.4.16", + "version": "v5.4.48", "source": { "type": "git", "url": "https://github.com/symfony/dom-crawler.git", - "reference": "4304e6ad5c894a9c72831ad459f627bfd35d766d" + "reference": "b57df76f4757a9a8dfbb57ba48d7780cc20776c6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/4304e6ad5c894a9c72831ad459f627bfd35d766d", - "reference": "4304e6ad5c894a9c72831ad459f627bfd35d766d", + "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/b57df76f4757a9a8dfbb57ba48d7780cc20776c6", + "reference": "b57df76f4757a9a8dfbb57ba48d7780cc20776c6", "shasum": "", "mirrors": [ { @@ -3457,13 +3403,21 @@ ] }, "require": { - "masterminds/html5": "^2.6", - "php": ">=8.1", + "php": ">=7.2.5", + "symfony/deprecation-contracts": "^2.1|^3", "symfony/polyfill-ctype": "~1.8", - "symfony/polyfill-mbstring": "~1.0" + "symfony/polyfill-mbstring": "~1.0", + "symfony/polyfill-php80": "^1.16" + }, + "conflict": { + "masterminds/html5": "<2.6" }, "require-dev": { - "symfony/css-selector": "^5.4|^6.0|^7.0" + "masterminds/html5": "^2.6", + "symfony/css-selector": "^4.4|^5.0|^6.0" + }, + "suggest": { + "symfony/css-selector": "" }, "type": "library", "autoload": { @@ -3491,7 +3445,7 @@ "description": "Eases DOM navigation for HTML and XML documents", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/dom-crawler/tree/v6.4.16" + "source": "https://github.com/symfony/dom-crawler/tree/v5.4.48" }, "funding": [ { @@ -3507,20 +3461,20 @@ "type": "tidelift" } ], - "time": "2024-11-13T15:06:22+00:00" + "time": "2024-11-13T14:36:38+00:00" }, { "name": "symfony/http-client", - "version": "v6.4.15", + "version": "v5.4.47", "source": { "type": "git", "url": "https://github.com/symfony/http-client.git", - "reference": "cb4073c905cd12b8496d24ac428a9228c1750670" + "reference": "3b643b83f87e1765d2e9b1e946bb56ee0b4b7bde" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client/zipball/cb4073c905cd12b8496d24ac428a9228c1750670", - "reference": "cb4073c905cd12b8496d24ac428a9228c1750670", + "url": "https://api.github.com/repos/symfony/http-client/zipball/3b643b83f87e1765d2e9b1e946bb56ee0b4b7bde", + "reference": "3b643b83f87e1765d2e9b1e946bb56ee0b4b7bde", "shasum": "", "mirrors": [ { @@ -3530,21 +3484,19 @@ ] }, "require": { - "php": ">=8.1", + "php": ">=7.2.5", "psr/log": "^1|^2|^3", - "symfony/deprecation-contracts": "^2.5|^3", - "symfony/http-client-contracts": "^3.4.1", - "symfony/service-contracts": "^2.5|^3" - }, - "conflict": { - "php-http/discovery": "<1.15", - "symfony/http-foundation": "<6.3" + "symfony/deprecation-contracts": "^2.1|^3", + "symfony/http-client-contracts": "^2.5.3", + "symfony/polyfill-php73": "^1.11", + "symfony/polyfill-php80": "^1.16", + "symfony/service-contracts": "^1.0|^2|^3" }, "provide": { "php-http/async-client-implementation": "*", "php-http/client-implementation": "*", "psr/http-client-implementation": "1.0", - "symfony/http-client-implementation": "3.0" + "symfony/http-client-implementation": "2.4" }, "require-dev": { "amphp/amp": "^2.5", @@ -3554,12 +3506,12 @@ "guzzlehttp/promises": "^1.4|^2.0", "nyholm/psr7": "^1.0", "php-http/httplug": "^1.0|^2.0", + "php-http/message-factory": "^1.0", "psr/http-client": "^1.0", - "symfony/dependency-injection": "^5.4|^6.0|^7.0", - "symfony/http-kernel": "^5.4|^6.0|^7.0", - "symfony/messenger": "^5.4|^6.0|^7.0", - "symfony/process": "^5.4|^6.0|^7.0", - "symfony/stopwatch": "^5.4|^6.0|^7.0" + "symfony/dependency-injection": "^4.4|^5.0|^6.0", + "symfony/http-kernel": "^4.4.13|^5.1.5|^6.0", + "symfony/process": "^4.4|^5.0|^6.0", + "symfony/stopwatch": "^4.4|^5.0|^6.0" }, "type": "library", "autoload": { @@ -3590,7 +3542,7 @@ "http" ], "support": { - "source": "https://github.com/symfony/http-client/tree/v6.4.15" + "source": "https://github.com/symfony/http-client/tree/v5.4.47" }, "funding": [ { @@ -3606,20 +3558,20 @@ "type": "tidelift" } ], - "time": "2024-11-13T13:40:18+00:00" + "time": "2024-11-13T12:18:12+00:00" }, { "name": "symfony/http-client-contracts", - "version": "v3.5.2", + "version": "v2.5.4", "source": { "type": "git", "url": "https://github.com/symfony/http-client-contracts.git", - "reference": "ee8d807ab20fcb51267fdace50fbe3494c31e645" + "reference": "fbfd73095ae958935396cf2243c47b01c677750c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/ee8d807ab20fcb51267fdace50fbe3494c31e645", - "reference": "ee8d807ab20fcb51267fdace50fbe3494c31e645", + "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/fbfd73095ae958935396cf2243c47b01c677750c", + "reference": "fbfd73095ae958935396cf2243c47b01c677750c", "shasum": "", "mirrors": [ { @@ -3629,7 +3581,10 @@ ] }, "require": { - "php": ">=8.1" + "php": ">=7.2.5" + }, + "suggest": { + "symfony/http-client-implementation": "" }, "type": "library", "extra": { @@ -3638,16 +3593,13 @@ "name": "symfony/contracts" }, "branch-alias": { - "dev-main": "3.5-dev" + "dev-main": "2.5-dev" } }, "autoload": { "psr-4": { "Symfony\\Contracts\\HttpClient\\": "" - }, - "exclude-from-classmap": [ - "/Test/" - ] + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -3674,7 +3626,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/http-client-contracts/tree/v3.5.2" + "source": "https://github.com/symfony/http-client-contracts/tree/v2.5.4" }, "funding": [ { @@ -3690,20 +3642,20 @@ "type": "tidelift" } ], - "time": "2024-12-07T08:49:48+00:00" + "time": "2024-11-25T09:13:00+00:00" }, { "name": "symfony/mime", - "version": "v5.1.11", + "version": "v5.2.1", "source": { "type": "git", "url": "https://github.com/symfony/mime.git", - "reference": "d7d899822da1fa89bcf658e8e8d836f5578e6f7a" + "reference": "de97005aef7426ba008c46ba840fc301df577ada" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mime/zipball/d7d899822da1fa89bcf658e8e8d836f5578e6f7a", - "reference": "d7d899822da1fa89bcf658e8e8d836f5578e6f7a", + "url": "https://api.github.com/repos/symfony/mime/zipball/de97005aef7426ba008c46ba840fc301df577ada", + "reference": "de97005aef7426ba008c46ba840fc301df577ada", "shasum": "", "mirrors": [ { @@ -3714,6 +3666,7 @@ }, "require": { "php": ">=7.2.5", + "symfony/deprecation-contracts": "^2.1", "symfony/polyfill-intl-idn": "^1.10", "symfony/polyfill-mbstring": "^1.0", "symfony/polyfill-php80": "^1.15" @@ -3723,7 +3676,11 @@ }, "require-dev": { "egulias/email-validator": "^2.1.10", - "symfony/dependency-injection": "^4.4|^5.0" + "phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0", + "symfony/dependency-injection": "^4.4|^5.0", + "symfony/property-access": "^4.4|^5.1", + "symfony/property-info": "^4.4|^5.1", + "symfony/serializer": "^5.2" }, "type": "library", "autoload": { @@ -3748,14 +3705,14 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Allows manipulating MIME messages", + "description": "A library to manipulate MIME messages", "homepage": "https://symfony.com", "keywords": [ "mime", "mime-type" ], "support": { - "source": "https://github.com/symfony/mime/tree/v5.1.11" + "source": "https://github.com/symfony/mime/tree/v5.2.1" }, "funding": [ { @@ -3771,7 +3728,7 @@ "type": "tidelift" } ], - "time": "2021-01-27T10:01:46+00:00" + "time": "2020-12-09T18:54:12+00:00" }, { "name": "symfony/polyfill-ctype", @@ -4120,6 +4077,88 @@ ], "time": "2024-09-09T11:45:10+00:00" }, + { + "name": "symfony/polyfill-php73", + "version": "v1.31.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php73.git", + "reference": "0f68c03565dcaaf25a890667542e8bd75fe7e5bb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/0f68c03565dcaaf25a890667542e8bd75fe7e5bb", + "reference": "0f68c03565dcaaf25a890667542e8bd75fe7e5bb", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": ">=7.2" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php73\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php73/tree/v1.31.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-09T11:45:10+00:00" + }, { "name": "symfony/polyfill-php80", "version": "v1.31.0", @@ -4208,16 +4247,16 @@ }, { "name": "symfony/process", - "version": "v7.1.7", + "version": "v5.4.46", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "9b8a40b7289767aa7117e957573c2a535efe6585" + "reference": "01906871cb9b5e3cf872863b91aba4ec9767daf4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/9b8a40b7289767aa7117e957573c2a535efe6585", - "reference": "9b8a40b7289767aa7117e957573c2a535efe6585", + "url": "https://api.github.com/repos/symfony/process/zipball/01906871cb9b5e3cf872863b91aba4ec9767daf4", + "reference": "01906871cb9b5e3cf872863b91aba4ec9767daf4", "shasum": "", "mirrors": [ { @@ -4227,7 +4266,8 @@ ] }, "require": { - "php": ">=8.2" + "php": ">=7.2.5", + "symfony/polyfill-php80": "^1.16" }, "type": "library", "autoload": { @@ -4255,7 +4295,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v7.1.7" + "source": "https://github.com/symfony/process/tree/v5.4.46" }, "funding": [ { @@ -4271,20 +4311,20 @@ "type": "tidelift" } ], - "time": "2024-11-06T09:25:12+00:00" + "time": "2024-11-06T09:18:28+00:00" }, { "name": "symfony/service-contracts", - "version": "v3.5.1", + "version": "v2.5.4", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "e53260aabf78fb3d63f8d79d69ece59f80d5eda0" + "reference": "f37b419f7aea2e9abf10abd261832cace12e3300" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/e53260aabf78fb3d63f8d79d69ece59f80d5eda0", - "reference": "e53260aabf78fb3d63f8d79d69ece59f80d5eda0", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/f37b419f7aea2e9abf10abd261832cace12e3300", + "reference": "f37b419f7aea2e9abf10abd261832cace12e3300", "shasum": "", "mirrors": [ { @@ -4294,17 +4334,20 @@ ] }, "require": { - "php": ">=8.1", - "psr/container": "^1.1|^2.0", - "symfony/deprecation-contracts": "^2.5|^3" + "php": ">=7.2.5", + "psr/container": "^1.1", + "symfony/deprecation-contracts": "^2.1|^3" }, "conflict": { "ext-psr": "<1.1|>=2" }, + "suggest": { + "symfony/service-implementation": "" + }, "type": "library", "extra": { "branch-alias": { - "dev-main": "3.5-dev" + "dev-main": "2.5-dev" }, "thanks": { "name": "symfony/contracts", @@ -4314,10 +4357,7 @@ "autoload": { "psr-4": { "Symfony\\Contracts\\Service\\": "" - }, - "exclude-from-classmap": [ - "/Test/" - ] + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -4344,7 +4384,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/service-contracts/tree/v3.5.1" + "source": "https://github.com/symfony/service-contracts/tree/v2.5.4" }, "funding": [ { @@ -4360,20 +4400,20 @@ "type": "tidelift" } ], - "time": "2024-09-25T14:20:29+00:00" + "time": "2024-09-25T14:11:13+00:00" }, { "name": "symfony/translation", - "version": "v6.4.13", + "version": "v5.4.45", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "bee9bfabfa8b4045a66bf82520e492cddbaffa66" + "reference": "98f26acc99341ca4bab345fb14d7b1d7cb825bed" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/bee9bfabfa8b4045a66bf82520e492cddbaffa66", - "reference": "bee9bfabfa8b4045a66bf82520e492cddbaffa66", + "url": "https://api.github.com/repos/symfony/translation/zipball/98f26acc99341ca4bab345fb14d7b1d7cb825bed", + "reference": "98f26acc99341ca4bab345fb14d7b1d7cb825bed", "shasum": "", "mirrors": [ { @@ -4383,38 +4423,40 @@ ] }, "require": { - "php": ">=8.1", - "symfony/deprecation-contracts": "^2.5|^3", + "php": ">=7.2.5", + "symfony/deprecation-contracts": "^2.1|^3", "symfony/polyfill-mbstring": "~1.0", - "symfony/translation-contracts": "^2.5|^3.0" + "symfony/polyfill-php80": "^1.16", + "symfony/translation-contracts": "^2.3" }, "conflict": { - "symfony/config": "<5.4", - "symfony/console": "<5.4", - "symfony/dependency-injection": "<5.4", - "symfony/http-client-contracts": "<2.5", - "symfony/http-kernel": "<5.4", - "symfony/service-contracts": "<2.5", - "symfony/twig-bundle": "<5.4", - "symfony/yaml": "<5.4" + "symfony/config": "<4.4", + "symfony/console": "<5.3", + "symfony/dependency-injection": "<5.0", + "symfony/http-kernel": "<5.0", + "symfony/twig-bundle": "<5.0", + "symfony/yaml": "<4.4" }, "provide": { - "symfony/translation-implementation": "2.3|3.0" + "symfony/translation-implementation": "2.3" }, "require-dev": { - "nikic/php-parser": "^4.18|^5.0", "psr/log": "^1|^2|^3", - "symfony/config": "^5.4|^6.0|^7.0", - "symfony/console": "^5.4|^6.0|^7.0", - "symfony/dependency-injection": "^5.4|^6.0|^7.0", - "symfony/finder": "^5.4|^6.0|^7.0", - "symfony/http-client-contracts": "^2.5|^3.0", - "symfony/http-kernel": "^5.4|^6.0|^7.0", - "symfony/intl": "^5.4|^6.0|^7.0", + "symfony/config": "^4.4|^5.0|^6.0", + "symfony/console": "^5.4|^6.0", + "symfony/dependency-injection": "^5.0|^6.0", + "symfony/finder": "^4.4|^5.0|^6.0", + "symfony/http-client-contracts": "^1.1|^2.0|^3.0", + "symfony/http-kernel": "^5.0|^6.0", + "symfony/intl": "^4.4|^5.0|^6.0", "symfony/polyfill-intl-icu": "^1.21", - "symfony/routing": "^5.4|^6.0|^7.0", - "symfony/service-contracts": "^2.5|^3", - "symfony/yaml": "^5.4|^6.0|^7.0" + "symfony/service-contracts": "^1.1.2|^2|^3", + "symfony/yaml": "^4.4|^5.0|^6.0" + }, + "suggest": { + "psr/log-implementation": "To use logging capability in translator", + "symfony/config": "", + "symfony/yaml": "" }, "type": "library", "autoload": { @@ -4445,7 +4487,7 @@ "description": "Provides tools to internationalize your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/translation/tree/v6.4.13" + "source": "https://github.com/symfony/translation/tree/v5.4.45" }, "funding": [ { @@ -4461,20 +4503,20 @@ "type": "tidelift" } ], - "time": "2024-09-27T18:14:25+00:00" + "time": "2024-09-25T14:11:13+00:00" }, { "name": "symfony/translation-contracts", - "version": "v3.5.1", + "version": "v2.5.4", "source": { "type": "git", "url": "https://github.com/symfony/translation-contracts.git", - "reference": "4667ff3bd513750603a09c8dedbea942487fb07c" + "reference": "450d4172653f38818657022252f9d81be89ee9a8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/4667ff3bd513750603a09c8dedbea942487fb07c", - "reference": "4667ff3bd513750603a09c8dedbea942487fb07c", + "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/450d4172653f38818657022252f9d81be89ee9a8", + "reference": "450d4172653f38818657022252f9d81be89ee9a8", "shasum": "", "mirrors": [ { @@ -4484,7 +4526,10 @@ ] }, "require": { - "php": ">=8.1" + "php": ">=7.2.5" + }, + "suggest": { + "symfony/translation-implementation": "" }, "type": "library", "extra": { @@ -4493,16 +4538,13 @@ "name": "symfony/contracts" }, "branch-alias": { - "dev-main": "3.5-dev" + "dev-main": "2.5-dev" } }, "autoload": { "psr-4": { "Symfony\\Contracts\\Translation\\": "" - }, - "exclude-from-classmap": [ - "/Test/" - ] + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -4529,7 +4571,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/translation-contracts/tree/v3.5.1" + "source": "https://github.com/symfony/translation-contracts/tree/v2.5.4" }, "funding": [ { @@ -4545,7 +4587,7 @@ "type": "tidelift" } ], - "time": "2024-09-25T14:20:29+00:00" + "time": "2024-09-25T14:11:13+00:00" }, { "name": "topthink/framework", diff --git a/config/common.php b/config/common.php index bb9a669..1dc4055 100644 --- a/config/common.php +++ b/config/common.php @@ -12,4 +12,10 @@ return [ 'chat_server' => [ 'bse_url' => 'https://chat.jdtest88.com', //测试环境-chat服务api域名 ], -]; \ No newline at end of file + // VIP购买配置 + 'vip_purchase' => [ + 'vip_price' => 30, // vip价格 + 'vip_day' => 30, // vip有效期 30天 + 'stock_id' => 'USD' // 购买VIP所需的货币类型 + ], +];