diff --git a/.example.env b/.example.env
new file mode 100644
index 0000000..561daea
--- /dev/null
+++ b/.example.env
@@ -0,0 +1 @@
+APP_DEBUG =true
[APP]
DEFAULT_TIMEZONE = Asia/Shanghai
CROSS_ORIGIN = true
[DATABASE]
TYPE = mysql
HOSTNAME = 35.185.183.202
DATABASE = root
USERNAME = bourse
PASSWORD = ID}#3CZ^D\SXOZ+
HOSTPORT = 3306
CHARSET = utf8
DEBUG = true
prefix = bot_
[LANG]
default_lang = zh-cn
[REDIS]
HOST = 10.87.38.3
PORT = 6379
SELECT = 0
PASSWORD = 7d00cb62-1d1c-4c86-b50a-ebf9f00cc9fd
[EMAIL]
# 多个以逗号隔开
DENY_EMAIL_TYPE = 163.com,qq.com,126.com,sina.com,sohu.com.aliyun.com,139.com,189.cn
Host= smtpdm-ap-southeast-1.aliyun.com // sg-smtp.qcloudmail.com
Username=service@reg.twinim.com
Password=rE51XlFpjJeMhLoHooX6
From=service@reg.twinim.com
[NATION]
# 多个以逗号隔开
DENY_NATION = 86,886,852,853
[ENCRYPT]
SALT = #$%^issoeasy%$#$^
ADMINSALT = #1%^issoeasy%$%$^
[SMS]
# 短信秘钥对 可拼接多个 key@secret,key@secret
CONFIG = LTAI5tMYUS9asodB6n2qSL9Y@TIMy9s5m7mHSPZN4uRahok4GRdWH1p
[LOGIN]
PER_IP_REGISTER_NUM_EVERY_DAY = 100
PER_IP_GET_CODE_NUM = 1000
PER_PHONE_GET_CODE_NUM = 5
[USER]
DEFAULT_HEAD_IMG_PATH = /bs/image/default.jpeg
[BACKEND]
BASE_URL=http://testmg.coincosmic.net
[AGENT]
AGENT_GROUP_ID=6
[QUOTE]
BASE_URL=10.148.0.13:88
DEAL_BASE_URL=http://10.148.0.12:8000
[FEATURE]
HAS_TEAM = true
HAS_DIGITAL = true
HAS_CONTRACT = true
HAS_STOCK_US = true
[PAY]
NOTIFY_URL= https://api.sysdev8.cc
[WALLET]
NAME=test
WALLET_TYPE=TRC-20
HTTP_URL=https://wallet.orcoin.net
[QEAE_PAY]
#key
KEY=399fd368dbd84b3fbee7012f20ca0b45
#代付 key
DF_KEY=UQBCGZ3IWBVWUUDXYU8ZDXZ2QOQAC2DN
#商户号
MERCHANT=400029056
[REG_USER]
INVITE_CODE_REQUIRED = 1
[OPTION_REFRESH]
OPTION_REFRESH_IN_URL=https://quotes.sysdev8.cc/option/php/list?country=India
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..d465120
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,5 @@
+/.idea
+/.vscode
+/vendor
+*.log
+.env
\ No newline at end of file
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..36f7b6f
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,42 @@
+sudo: false
+
+language: php
+
+branches:
+ only:
+ - stable
+
+cache:
+ directories:
+ - $HOME/.composer/cache
+
+before_install:
+ - composer self-update
+
+install:
+ - composer install --no-dev --no-interaction --ignore-platform-reqs
+ - zip -r --exclude='*.git*' --exclude='*.zip' --exclude='*.travis.yml' ThinkPHP_Core.zip .
+ - composer require --update-no-dev --no-interaction "topthink/think-image:^1.0"
+ - composer require --update-no-dev --no-interaction "topthink/think-migration:^1.0"
+ - composer require --update-no-dev --no-interaction "topthink/think-captcha:^1.0"
+ - composer require --update-no-dev --no-interaction "topthink/think-mongo:^1.0"
+ - composer require --update-no-dev --no-interaction "topthink/think-worker:^1.0"
+ - composer require --update-no-dev --no-interaction "topthink/think-helper:^1.0"
+ - composer require --update-no-dev --no-interaction "topthink/think-queue:^1.0"
+ - composer require --update-no-dev --no-interaction "topthink/think-angular:^1.0"
+ - composer require --dev --update-no-dev --no-interaction "topthink/think-testing:^1.0"
+ - zip -r --exclude='*.git*' --exclude='*.zip' --exclude='*.travis.yml' ThinkPHP_Full.zip .
+
+script:
+ - php think unit
+
+deploy:
+ provider: releases
+ api_key:
+ secure: TSF6bnl2JYN72UQOORAJYL+CqIryP2gHVKt6grfveQ7d9rleAEoxlq6PWxbvTI4jZ5nrPpUcBUpWIJHNgVcs+bzLFtyh5THaLqm39uCgBbrW7M8rI26L8sBh/6nsdtGgdeQrO/cLu31QoTzbwuz1WfAVoCdCkOSZeXyT/CclH99qV6RYyQYqaD2wpRjrhA5O4fSsEkiPVuk0GaOogFlrQHx+C+lHnf6pa1KxEoN1A0UxxVfGX6K4y5g4WQDO5zT4bLeubkWOXK0G51XSvACDOZVIyLdjApaOFTwamPcD3S1tfvuxRWWvsCD5ljFvb2kSmx5BIBNwN80MzuBmrGIC27XLGOxyMerwKxB6DskNUO9PflKHDPI61DRq0FTy1fv70SFMSiAtUv9aJRT41NQh9iJJ0vC8dl+xcxrWIjU1GG6+l/ZcRqVx9V1VuGQsLKndGhja7SQ+X1slHl76fRq223sMOql7MFCd0vvvxVQ2V39CcFKao/LB1aPH3VhODDEyxwx6aXoTznvC/QPepgWsHOWQzKj9ftsgDbsNiyFlXL4cu8DWUty6rQy8zT2b4O8b1xjcwSUCsy+auEjBamzQkMJFNlZAIUrukL/NbUhQU37TAbwsFyz7X0E/u/VMle/nBCNAzgkMwAUjiHM6FqrKKBRWFbPrSIixjfjkCnrMEPw=
+ file:
+ - ThinkPHP_Core.zip
+ - ThinkPHP_Full.zip
+ skip_cleanup: true
+ on:
+ tags: true
diff --git a/LICENSE.txt b/LICENSE.txt
new file mode 100644
index 0000000..574a39c
--- /dev/null
+++ b/LICENSE.txt
@@ -0,0 +1,32 @@
+
+ThinkPHP遵循Apache2开源协议发布,并提供免费使用。
+版权所有Copyright © 2006-2016 by ThinkPHP (http://thinkphp.cn)
+All rights reserved。
+ThinkPHP® 商标和著作权所有者为上海顶想信息科技有限公司。
+
+Apache Licence是著名的非盈利开源组织Apache采用的协议。
+该协议和BSD类似,鼓励代码共享和尊重原作者的著作权,
+允许代码修改,再作为开源或商业软件发布。需要满足
+的条件:
+1. 需要给代码的用户一份Apache Licence ;
+2. 如果你修改了代码,需要在被修改的文件中说明;
+3. 在延伸的代码中(修改和有源代码衍生的代码中)需要
+带有原来代码中的协议,商标,专利声明和其他原来作者规
+定需要包含的说明;
+4. 如果再发布的产品中包含一个Notice文件,则在Notice文
+件中需要带有本协议内容。你可以在Notice中增加自己的
+许可,但不可以表现为对Apache Licence构成更改。
+具体的协议参考:http://www.apache.org/licenses/LICENSE-2.0
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
diff --git a/app/.htaccess b/app/.htaccess
new file mode 100644
index 0000000..f1adcc2
--- /dev/null
+++ b/app/.htaccess
@@ -0,0 +1,8 @@
+
+ Options +FollowSymlinks -Multiviews
+ RewriteEngine On
+
+ RewriteCond %{REQUEST_FILENAME} !-d
+ RewriteCond %{REQUEST_FILENAME} !-f
+ RewriteRule ^(.*)$ index.php/$1 [QSA,PT,L]
+
\ No newline at end of file
diff --git a/app/404.html b/app/404.html
new file mode 100644
index 0000000..92bf90c
--- /dev/null
+++ b/app/404.html
@@ -0,0 +1,10 @@
+
+
+
+
+ 404
+
+
+宝藏不见了
+
+
\ No newline at end of file
diff --git a/app/AppService.php b/app/AppService.php
new file mode 100644
index 0000000..96556e8
--- /dev/null
+++ b/app/AppService.php
@@ -0,0 +1,22 @@
+app = $app;
+ $this->request = $this->app->request;
+
+ // 控制器初始化
+ $this->initialize();
+ }
+
+ // 初始化
+ protected function initialize()
+ {}
+
+ /**
+ * 验证数据
+ * @access protected
+ * @param array $data 数据
+ * @param string|array $validate 验证器名或者验证规则数组
+ * @param array $message 提示信息
+ * @param bool $batch 是否批量验证
+ * @return array|string|true
+ * @throws ValidateException
+ */
+ protected function validate(array $data, $validate, array $message = [], bool $batch = false)
+ {
+ if (is_array($validate)) {
+ $v = new Validate();
+ $v->rule($validate);
+ } else {
+ if (strpos($validate, '.')) {
+ // 支持场景
+ [$validate, $scene] = explode('.', $validate);
+ }
+ $class = false !== strpos($validate, '\\') ? $validate : $this->app->parseClass('validate', $validate);
+ $v = new $class();
+ if (!empty($scene)) {
+ $v->scene($scene);
+ }
+ }
+
+ $v->message($message);
+
+ // 是否批量验证
+ if ($batch || $this->batchValidate) {
+ $v->batch(true);
+ }
+
+ return $v->failException(true)->check($data);
+ }
+
+}
diff --git a/app/ExceptionHandle.php b/app/ExceptionHandle.php
new file mode 100644
index 0000000..453d126
--- /dev/null
+++ b/app/ExceptionHandle.php
@@ -0,0 +1,58 @@
+addUser($this->request->param());
+ return json($result);
+ }
+
+ public function updateInfo()
+ {
+ $service = new AdminService();
+ $result = $service->updateInfo($this->request->user_id,$this->request->param());
+ return json($result);
+ }
+ public function getUserInfo()
+ {
+ $service = new AdminService();
+ $result = $service->getUserInfo($this->request->user_id);
+ return json($result);
+ }
+
+ public function updatePassword()
+ {
+ $service = new AdminService();
+ $result = $service->updatePassword($this->request->user_id,$this->request->param());
+ return json($result);
+ }
+
+ //账号列表
+ public function getUserList()
+ {
+ $returnData = (new AdminService())->getUserList($this->request->param());
+ return json($returnData);
+ }
+ //编辑账号
+ public function updateAccount(){
+ $returnData = (new AdminService())->updateAccount($this->request->param('id'),$this->request->param());
+ return json($returnData);
+ }
+
+ //更新账号状态
+ public function updateAccountStauts(){
+ $returnData = (new AdminService())->updateAccountStauts($this->request->param('id'),$this->request->param());
+ return json($returnData);
+ }
+
+ //删除指定用户
+ public function del(){
+ $returnData = (new AdminService())->del($this->request->param('id'));
+ return json($returnData);
+ }
+ //获取用户权限代码
+ public function getPermCode(){
+ $returnData = (new AdminService())->getPermCode($this->request->user_id);
+ return json($returnData);
+ }
+
+ //退出登陆
+ public function logout()
+ {
+ $returnData = (new AdminService())->logout($this->request->user_id);
+ return json($returnData);
+ }
+
+ //操作日志
+ public function log()
+ {
+ $returnData = (new AdminService())->logList($this->request->param());
+ return json($returnData);
+ }
+
+ public function inviteCode(){
+ $returnData = (new AdminService())->inviteCode();
+ return json($returnData);
+ }
+}
diff --git a/app/admin/controller/AdminBaseController.php b/app/admin/controller/AdminBaseController.php
new file mode 100644
index 0000000..56024f3
--- /dev/null
+++ b/app/admin/controller/AdminBaseController.php
@@ -0,0 +1,15 @@
+request->user_id;
+ }
+
+}
\ No newline at end of file
diff --git a/app/admin/controller/Agent.php b/app/admin/controller/Agent.php
new file mode 100644
index 0000000..93cfa9a
--- /dev/null
+++ b/app/admin/controller/Agent.php
@@ -0,0 +1,33 @@
+index();
+ return json($result);
+ }
+
+ // 代理用户列表
+ public function user()
+ {
+ $service = new AgentService();
+ $result = $service->user($this->request->param());
+ return json($result);
+ }
+
+ // 管理用户
+ public function manager()
+ {
+ $service = new AgentService();
+ $result = $service->manager($this->request->param());
+ return json($result);
+ }
+}
\ No newline at end of file
diff --git a/app/admin/controller/Config.php b/app/admin/controller/Config.php
new file mode 100644
index 0000000..660ee94
--- /dev/null
+++ b/app/admin/controller/Config.php
@@ -0,0 +1,58 @@
+request->param();
+ if (empty($param['name'])) return json(['code' => '1', 'message' => '参数错误', 'data' => []]);
+ $name = $param['name'];
+ $type = $param['type'] ?? 'string';
+ $value = $param['value'] ?? '';
+ $tip = $param['tip'] ?? '';
+
+ $insertData = [
+ 'name' => $name,
+ 'group' => 'config',
+ 'title' => $name,
+ 'tip' => $tip,
+ 'type' => $type,
+ 'value' => $value,
+ ];
+
+ $config = ConfigModel::where('name', $name)->find();
+ if (empty($config)) {
+ $bool = ConfigModel::insert($insertData);
+ if (!$bool) return json(['code' => '100500', 'message' => '设置失败', 'data' => []]);
+ } else {
+ $bool = ConfigModel::where('name', $name)->update($insertData);
+ if (!$bool) return json(['code' => '100500', 'message' => '设置失败', 'data' => []]);
+ }
+
+ return json(['code' => '0', 'message' => 'Request successful', 'data' => []]);
+ } catch (\Exception $exception) {
+ return json(['code' => '100500', 'message' => '系统繁忙', 'data' => [$exception->getMessage()]]);
+ }
+ }
+
+ public function getConfig()
+ {
+ try {
+ $param = $this->request->param();
+ if (empty($param['name'])) return json(['code' => '1', 'message' => '参数错误', 'data' => []]);
+ $name = $param['name'];
+ $value = ConfigModel::where('name', $name)->value('value');
+
+ return json(['code' => '0', 'message' => 'Request successful', 'data' => ['value' => $value]]);
+ } catch (\Exception $exception) {
+ return json(['code' => '100500', 'message' => '系统繁忙', 'data' => [$exception->getMessage()]]);
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/admin/controller/Country.php b/app/admin/controller/Country.php
new file mode 100644
index 0000000..081a8f7
--- /dev/null
+++ b/app/admin/controller/Country.php
@@ -0,0 +1,41 @@
+isEmpty()){
+ $deny = explode(',', env('NATION.DENY_NATION'));
+ foreach ($res as $item) {
+ $active = 1;
+ if(in_array($item['code'],$deny )){
+ $active = 0;
+ }
+ $returnData[] = [
+ 'id' => $item['id'],
+ 'nameCn' => $item['name_cn'],
+ 'nameEn' => $item['name_en'],
+ 'nation' => $item['code'],
+ 'active' => $active,
+ ];
+ }
+ }
+ return json(['code' => '0', 'message' => '请求成功','data' => $returnData]);
+ }catch (\Exception $exception){
+ return json(['code' => '100500', 'message' => '系统繁忙','data' => []]);
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/app/admin/controller/Flow.php b/app/admin/controller/Flow.php
new file mode 100644
index 0000000..accbacf
--- /dev/null
+++ b/app/admin/controller/Flow.php
@@ -0,0 +1,93 @@
+digital($this->request->param(),$this->getAdminId());
+ return json($result);
+ }
+
+ public function stock()
+ {
+ $service = new FlowService();
+ $result = $service->stock($this->request->param(),$this->getAdminId());
+ return json($result);
+ }
+
+ public function contract()
+ {
+ $service = new FlowService();
+ $result = $service->contract($this->request->param(),$this->getAdminId());
+ return json($result);
+ }
+
+ public function forex()
+ {
+ $service = new FlowService();
+ $result = $service->forex($this->request->param(),$this->getAdminId());
+ return json($result);
+ }
+
+ public function transfer()
+ {
+ $service = new FlowService();
+ $result = $service->transfer($this->request->param(),$this->getAdminId());
+ return json($result);
+ }
+
+ public function fee()
+ {
+ $service = new FlowService();
+ $result = $service->fee($this->request->param(),$this->getAdminId());
+ return json($result);
+ }
+
+ public function brokerage()
+ {
+ $service = new FlowService();
+ $result = $service->brokerage($this->request->param(),$this->getAdminId());
+ return json($result);
+ }
+
+ ################################ 股票资产流水 #####################################
+
+ // 股票流水
+ public function StockLogs()
+ {
+ $service = new FlowService();
+ $result = $service->StockLogs($this->request->param(),$this->getAdminId());
+ return json($result);
+ }
+
+ // 基金流水
+ public function fundStock()
+ {
+ $service = new FlowService();
+ $result = $service->fundStock($this->request->param(),$this->getAdminId());
+ return json($result);
+ }
+
+ // 印度期权流水
+ public function inOptionStock()
+ {
+ $service = new FlowService();
+ $result = $service->inOptionStock($this->request->param(),$this->getAdminId());
+ return json($result);
+ }
+
+ // 印度期权流水
+ public function blockStock()
+ {
+ $service = new FlowService();
+ $result = $service->blockStock($this->request->param(),$this->getAdminId());
+ return json($result);
+ }
+}
\ No newline at end of file
diff --git a/app/admin/controller/Index.php b/app/admin/controller/Index.php
new file mode 100644
index 0000000..86765b9
--- /dev/null
+++ b/app/admin/controller/Index.php
@@ -0,0 +1,1046 @@
+getName();
+ $digitalTradeTableName = $prefix . (new DigitalTradeModel())->getName();
+ $rechargeApplyTableName = $prefix . (new RechargeApplyModel())->getName();
+ $stockTradeTableName = $prefix . (new StockTradeModel())->getName();
+ $stockMysTradeTableName = $prefix . (new StockMysTradeModel())->getName();
+ $stockThaTradeTableName = $prefix . (new StockThaTradeModel())->getName();
+ $stockIdnTradeTableName = $prefix . (new StockIdnTradeModel())->getName();
+ $stockInTradeTableName = $prefix . (new StockInTradeModel())->getName();
+
+ $userTableName = $prefix . (new UserModel())->getName();
+ $userWithdrawTableName = $prefix . (new UserWithdrawalModel())->getName();
+
+
+ // 总注册人数(用户的总数)
+ $totalRegisterNum = Db::table($userTableName)->count();
+
+ // 总充值用户(充值用户的个数 以用户id分组)
+ $totalRechargeNum = Db::table($rechargeApplyTableName)->where('status', 1)->group('user_id')->count();
+
+ // 总交易用户(合约 股票 现货 交易的用户去重 订单状态为持仓 和 完成 订单)
+ $contractTradeUserId = Db::table($ContractTradeTableName)->where('status', 'in', [1, 3])->distinct(true)->column('user_id');
+ $stockTradeUserId = Db::table($stockTradeTableName)->where('status', 'in', [1, 3])->distinct(true)->column('user_id');
+ $stockMysTradeUserId = Db::table($stockMysTradeTableName)->where('status', 'in', [1, 3])->distinct(true)->column('user_id');
+ $stockThaTradeUserId = Db::table($stockThaTradeTableName)->where('status', 'in', [1, 3])->distinct(true)->column('user_id');
+ $stockIdnTradeUserId = Db::table($stockIdnTradeTableName)->where('status', 'in', [1, 3])->distinct(true)->column('user_id');
+ $stockInTradeUserId = Db::table($stockInTradeTableName)->where('status', 'in', [1, 3])->distinct(true)->column('user_id');
+ $digitalTradeUserId = Db::table($digitalTradeTableName)->where('status', 'in', [1, 3])->distinct(true)->column('user_id');
+
+ $totalArrayMerge = array_unique(array_merge($contractTradeUserId, $stockTradeUserId, $digitalTradeUserId, $stockMysTradeUserId, $stockIdnTradeUserId, $stockThaTradeUserId, $stockInTradeUserId));
+ $totalTradeNum = count($totalArrayMerge);
+
+ // 总提现用户(以用户id 分组查询数量)
+ $totalWithdrawalNum = Db::table($userWithdrawTableName)->group('user_id')->count();
+
+ // 总充值金额 充值完成
+ $totalRechargeAmount = Db::table($rechargeApplyTableName)->where('status', 1)->sum('recharge_num');
+
+ // 总提款金额 提款完成
+ $totalWithdrawAmount = Db::table($userWithdrawTableName)->where('status', 2)->sum('apply_num');
+
+
+ // 今日注册用户
+ $today = date('Y-m-d'); // 今天凌晨
+ $tomorrow = date('Y-m-d', strtotime('tomorrow')); // 明天凌晨
+ $todayRegisterNum = Db::table($userTableName)->whereTime('create_time', 'between', [$today, $tomorrow])->count();
+
+ // 今日充值用户 完成状态
+ $todayRechargeNum = Db::table($userTableName)->where('status', 1)
+ ->whereTime('create_time', 'between', [$today, $tomorrow])
+ ->group('user_id')->count();
+
+ // 今日交易用户
+ // 合约
+ $todayContractTradeUserId = Db::table($ContractTradeTableName)->where('status', 'in', [1, 3])
+ ->whereTime('create_time', 'between', [$today, $tomorrow])
+ ->distinct(true)->column('user_id');
+ //股票
+ $todayStockTradeUserId = Db::table($stockTradeTableName)->where('status', 'in', [1, 3])
+ ->whereTime('create_time', 'between', [$today, $tomorrow])
+ ->distinct(true)->column('user_id');
+ $todayStockMysTradeUserId = Db::table($stockMysTradeTableName)->where('status', 'in', [1, 3])
+ ->whereTime('create_time', 'between', [$today, $tomorrow])
+ ->distinct(true)->column('user_id');
+ $todayStockThaTradeUserId = Db::table($stockThaTradeTableName)->where('status', 'in', [1, 3])
+ ->whereTime('create_time', 'between', [$today, $tomorrow])
+ ->distinct(true)->column('user_id');
+ $todayStockIndTradeUserId = Db::table($stockIdnTradeTableName)->where('status', 'in', [1, 3])
+ ->whereTime('create_time', 'between', [$today, $tomorrow])
+ ->distinct(true)->column('user_id');
+ $todayStockInTradeUserId = Db::table($stockInTradeTableName)->where('status', 'in', [1, 3])
+ ->whereTime('create_time', 'between', [$today, $tomorrow])
+ ->distinct(true)->column('user_id');
+ // 现货
+ $todayDigitalTradeUserId = Db::table($digitalTradeTableName)->where('status', 'in', [1, 3])
+ ->whereTime('create_time', 'between', [$today, $tomorrow])
+ ->distinct(true)->column('user_id');
+
+ // 计算总数
+ $todayArrayMerge = array_unique(array_merge($todayStockInTradeUserId, $todayContractTradeUserId, $todayStockTradeUserId, $todayDigitalTradeUserId, $todayStockMysTradeUserId, $todayStockThaTradeUserId, $todayStockIndTradeUserId));
+ $todayTradeNum = count($todayArrayMerge);
+
+ // 今日提款用户
+ $todayWithdrawNum = Db::table($userWithdrawTableName)
+ ->whereTime('create_time', 'between', [$today, $tomorrow])
+ ->group('user_id')->count();
+
+ // 今日充值金额 完成状态
+ $todayRechargeAmount = Db::table($rechargeApplyTableName)
+ ->whereTime('create_time', 'between', [$today, $tomorrow])
+ ->where('status', 1)->sum('recharge_num');
+
+ // 今日提款金额 完成状态
+ $todayWithdrawAmount = Db::table($userWithdrawTableName)
+ ->whereTime('create_time', 'between', [$today, $tomorrow])
+ ->where('status', 2)->sum('apply_num');
+
+
+ $data = [
+ 'totalRegisterNum' => $totalRegisterNum, // 总注册人数
+ 'totalRechargeNum' => $totalRechargeNum,// 总充值用户
+ 'totalTradeNum' => $totalTradeNum,// 总交易用户
+ 'totalWithdrawalNum' => $totalWithdrawalNum,// 总提现用户
+ 'totalRechargeAmount' => $totalRechargeAmount,// 总充值金额
+ 'totalWithdrawAmount' => $totalWithdrawAmount, // 总提款金额
+
+ 'todayRegisterNum' => $todayRegisterNum, // 今日注册用户
+ 'todayRechargeNum' => $todayRechargeNum, // 今日充值用户
+ 'todayTradeNum' => $todayTradeNum, // 今日交易用户
+ 'todayWithdrawNum' => $todayWithdrawNum, // 今日提款用户
+ 'todayRechargeAmount' => $todayRechargeAmount, // 今日充值金额
+ 'todayWithdrawAmount' => $todayWithdrawAmount, // 今日提款金额
+ ];
+
+ return json(['code' => '0', 'message' => 'SUCCESS', 'data' => $data]);
+ } catch (\Exception $exception) {
+ return json(['code' => '1', 'message' => '系统繁忙']);
+ }
+ }
+
+ // 缓存美股数据
+ public function cacheUsStock()
+ {
+ try {
+ $list = StockListModel::where('id', '>', '0')->select();
+ if (!$list->isEmpty()) {
+ $redis = (new AdminBaseService())->getRedis();
+ foreach ($list as $stock) {
+ $list_key = "US:STOCK:LIST:" . $stock->stock_code;
+ $redis->del($list_key);
+ $redis->hMset($list_key, [
+ 'id' => $stock->id,
+ 'stock_name' => $stock->stock_name,
+ 'stock_code' => $stock->stock_code,
+ 'status' => $stock->status,
+ 'keep_decimal' => $stock->keep_decimal,
+ 'forced_closure' => $stock->forced_closure,
+ 'up_limit' => $stock->up_limit,
+ 'down_limit' => $stock->down_limit,
+ 'info' => $stock->info,
+ 'tape' => $stock->tape,
+ ]);
+ }
+ }
+ return json(['msg' => 'SUCCESS']);
+ } catch (\Exception $exception) {
+ return json(['msg' => $exception->getMessage()]);
+ }
+ }
+
+ // 缓存印尼
+ public function cacheIdnStock()
+ {
+ try {
+ $list = StockIdnListModel::where('id', '>', '0')->select();
+ if (!$list->isEmpty()) {
+ $redis = (new AdminBaseService())->getRedis();
+ foreach ($list as $stock) {
+ $old_code = $stock->stock_code;
+ if (strpos($stock->stock_code, ':') !== false) {
+ $code_arr = explode(":", $stock->stock_code);
+ $old_code = $code_arr[1] ?? $code_arr[0];
+ }
+ $old_key = "IDN:STOCK:LIST:" . $old_code;
+ $redis->del($old_key);
+
+ $list_key = "IDN:STOCK:LIST:" . $stock->stock_code;
+ $redis->hMset($list_key, [
+ 'id' => $stock->id,
+ 'stock_name' => $stock->stock_name,
+ 'stock_code' => $stock->stock_code,
+ 'status' => $stock->status,
+ 'keep_decimal' => $stock->keep_decimal,
+ 'forced_closure' => $stock->forced_closure,
+ 'up_limit' => $stock->up_limit,
+ 'down_limit' => $stock->down_limit,
+ 'info' => $stock->info,
+ 'tape' => $stock->tape,
+ ]);
+ }
+ }
+ return json(['msg' => 'SUCCESS']);
+ } catch (\Exception $exception) {
+ return json(['msg' => $exception->getMessage()]);
+ }
+ }
+
+ // 缓存马来西亚股票
+ public function cacheMysStock()
+ {
+ try {
+ $list = StockMysListModel::where('id', '>', '0')->select();
+ if (!$list->isEmpty()) {
+ $redis = (new AdminBaseService())->getRedis();
+ foreach ($list as $stock) {
+ $old_code = $stock->stock_code;
+ if (strpos($stock->stock_code, ':') !== false) {
+ $code_arr = explode(":", $stock->stock_code);
+ $old_code = $code_arr[1] ?? $code_arr[0];
+ }
+ $old_key = "MYS:STOCK:LIST:" . $old_code;
+ $redis->del($old_key);
+
+ $list_key = "MYS:STOCK:LIST:" . $stock->stock_code;
+ $redis->del($old_key);
+ $redis->hMset($list_key, [
+ 'id' => $stock->id,
+ 'stock_name' => $stock->stock_name,
+ 'stock_code' => $stock->stock_code,
+ 'numeric_code' => $stock->numeric_code,
+ 'status' => $stock->status,
+ 'keep_decimal' => $stock->keep_decimal,
+ 'forced_closure' => $stock->forced_closure,
+ 'up_limit' => $stock->up_limit,
+ 'down_limit' => $stock->down_limit,
+ 'info' => $stock->info,
+ 'tape' => $stock->tape,
+ ]);
+ }
+ }
+ return json(['msg' => 'SUCCESS']);
+ } catch (\Exception $exception) {
+ return json(['msg' => $exception->getMessage()]);
+ }
+ }
+
+ // 缓存泰股
+ public function cacheThaStock()
+ {
+ try {
+ $list = StockThaListModel::where('id', '>', '0')->select();
+ if (!$list->isEmpty()) {
+ $redis = (new AdminBaseService())->getRedis();
+ foreach ($list as $stock) {
+ $old_code = $stock->stock_code;
+ if (strpos($stock->stock_code, ':') !== false) {
+ $code_arr = explode(":", $stock->stock_code);
+ $old_code = $code_arr[1] ?? $code_arr[0];
+ }
+ $old_key = "THA:STOCK:LIST:" . $old_code;
+ $redis->del($old_key);
+
+ $list_key = "THA:STOCK:LIST:" . $stock->stock_code;
+ $redis->del($list_key);
+ $redis->hMset($list_key, [
+ 'id' => $stock->id,
+ 'stock_name' => $stock->stock_name,
+ 'stock_code' => $stock->stock_code,
+ 'status' => $stock->status,
+ 'keep_decimal' => $stock->keep_decimal,
+ 'forced_closure' => $stock->forced_closure,
+ 'up_limit' => $stock->up_limit,
+ 'down_limit' => $stock->down_limit,
+ 'info' => $stock->info,
+ 'tape' => $stock->tape,
+ ]);
+ }
+ }
+ return json(['msg' => 'SUCCESS']);
+ } catch (\Exception $exception) {
+ return json(['msg' => $exception->getMessage()]);
+ }
+ }
+
+ // 印度股票
+ public function cacheInStock()
+ {
+ try {
+ $list = StockInListModel::where('id', '>', '0')->select();
+ if (!$list->isEmpty()) {
+ $redis = (new AdminBaseService())->getRedis();
+ foreach ($list as $stock) {
+ $old_code = $stock->stock_code;
+ if (strpos($stock->stock_code, ':') !== false) {
+ $code_arr = explode(":", $stock->stock_code);
+ $old_code = $code_arr[1] ?? $code_arr[0];
+ }
+ $old_key = "IN:STOCK:LIST:" . $old_code;
+ $redis->del($old_key);
+
+ $list_key = "IN:STOCK:LIST:" . $stock->stock_code;
+ $redis->hMset($list_key, [
+ 'id' => $stock->id,
+ 'stock_name' => $stock->stock_name,
+ 'stock_code' => $stock->stock_code,
+ 'status' => $stock->status,
+ 'keep_decimal' => $stock->keep_decimal,
+ 'forced_closure' => $stock->forced_closure,
+ 'up_limit' => $stock->up_limit,
+ 'down_limit' => $stock->down_limit,
+ 'info' => $stock->info,
+ 'tape' => $stock->tape,
+ ]);
+ }
+ }
+ return json(['msg' => 'SUCCESS']);
+ } catch (\Exception $exception) {
+ return json(['msg' => $exception->getMessage()]);
+ }
+ }
+
+ // 新加坡股票
+ public function cacheSgdStock()
+ {
+ try {
+ $list = StockSgdListModel::where('id', '>', '0')->select();
+ if (!$list->isEmpty()) {
+ $redis = (new AdminBaseService())->getRedis();
+ foreach ($list as $stock) {
+ $old_code = $stock->stock_code;
+ if (strpos($stock->stock_code, ':') !== false) {
+ $code_arr = explode(":", $stock->stock_code);
+ $old_code = $code_arr[1] ?? $code_arr[0];
+ }
+ $old_key = "SGD:STOCK:LIST:" . $old_code;
+ $redis->del($old_key);
+
+ $list_key = "SGD:STOCK:LIST:" . $stock->stock_code;
+ $redis->hMset($list_key, [
+ 'id' => $stock->id,
+ 'stock_name' => $stock->stock_name,
+ 'stock_code' => $stock->stock_code,
+ 'status' => $stock->status,
+ 'keep_decimal' => $stock->keep_decimal,
+ 'forced_closure' => $stock->forced_closure,
+ 'up_limit' => $stock->up_limit,
+ 'down_limit' => $stock->down_limit,
+ 'info' => $stock->info,
+ 'tape' => $stock->tape,
+ ]);
+ }
+ }
+ return json(['msg' => 'SUCCESS']);
+ } catch (\Exception $exception) {
+ return json(['msg' => $exception->getMessage()]);
+ }
+ }
+
+ // 香港股票
+ public function cacheHkStock()
+ {
+ try {
+ $list = StockHkdListModel::where('id', '>', '0')->select();
+ if (!$list->isEmpty()) {
+ $redis = (new AdminBaseService())->getRedis();
+ foreach ($list as $stock) {
+ $old_code = $stock->stock_code;
+ if (strpos($stock->stock_code, ':') !== false) {
+ $code_arr = explode(":", $stock->stock_code);
+ $old_code = $code_arr[1] ?? $code_arr[0];
+ }
+ $old_key = "HKD:STOCK:LIST:" . $old_code;
+ $redis->del($old_key);
+
+ $list_key = "HKD:STOCK:LIST:" . $stock->stock_code;
+ $redis->hMset($list_key, [
+ 'id' => $stock->id,
+ 'stock_name' => $stock->stock_name,
+ 'stock_code' => $stock->stock_code,
+ 'status' => $stock->status,
+ 'keep_decimal' => 4,
+ 'forced_closure' => $stock->forced_closure,
+ 'up_limit' => $stock->up_limit,
+ 'down_limit' => $stock->down_limit,
+ 'info' => $stock->info,
+ 'tape' => $stock->tape,
+ ]);
+ }
+ }
+ return json(['msg' => 'SUCCESS']);
+ } catch (\Exception $exception) {
+ return json(['msg' => $exception->getMessage()]);
+ }
+ }
+
+ // 英国股票
+ public function cacheGbxStock()
+ {
+ try {
+ $list = StockGBXListModel::where('id', '>', '0')->select();
+ if (!$list->isEmpty()) {
+ $redis = (new AdminBaseService())->getRedis();
+ foreach ($list as $stock) {
+ $old_code = $stock->stock_code;
+ if (strpos($stock->stock_code, ':') !== false) {
+ $code_arr = explode(":", $stock->stock_code);
+ $old_code = $code_arr[1] ?? $code_arr[0];
+ }
+ $old_key = "UK:STOCK:LIST:" . $old_code;
+ $redis->del($old_key);
+
+ $list_key = "UK:STOCK:LIST:" . $stock->stock_code;
+ $redis->hMset($list_key, [
+ 'id' => $stock->id,
+ 'stock_name' => $stock->stock_name,
+ 'stock_code' => $stock->stock_code,
+ 'status' => $stock->status,
+ 'keep_decimal' => 4,
+ 'forced_closure' => $stock->forced_closure,
+ 'up_limit' => $stock->up_limit,
+ 'down_limit' => $stock->down_limit,
+ 'info' => $stock->info,
+ 'tape' => $stock->tape,
+ ]);
+ }
+ }
+ return json(['msg' => 'SUCCESS']);
+ } catch (\Exception $exception) {
+ return json(['msg' => $exception->getMessage()]);
+ }
+ }
+
+ public function cacheFurStock()
+ {
+ try {
+ $list = StockFurListModel::where('id', '>', '0')->select();
+ if (!$list->isEmpty()) {
+ $redis = (new AdminBaseService())->getRedis();
+ foreach ($list as $stock) {
+ $old_code = $stock->stock_code;
+ if (strpos($stock->stock_code, ':') !== false) {
+ $code_arr = explode(":", $stock->stock_code);
+ $old_code = $code_arr[1] ?? $code_arr[0];
+ }
+ $old_key = "FUR:STOCK:LIST:" . $old_code;
+ $redis->del($old_key);
+
+ $list_key = "FUR:STOCK:LIST:" . $stock->stock_code;
+ $redis->hMset($list_key, [
+ 'id' => $stock->id,
+ 'stock_name' => $stock->stock_name,
+ 'stock_code' => $stock->stock_code,
+ 'status' => $stock->status,
+ 'keep_decimal' => 4,
+ 'forced_closure' => $stock->forced_closure,
+ 'up_limit' => $stock->up_limit,
+ 'down_limit' => $stock->down_limit,
+ 'info' => $stock->info,
+ 'tape' => $stock->tape,
+ ]);
+ }
+ }
+ return json(['msg' => 'SUCCESS']);
+ } catch (\Exception $exception) {
+ return json(['msg' => $exception->getMessage()]);
+ }
+ }
+
+ public function cacheEurStock()
+ {
+ try {
+ $list = StockEurListModel::where('id', '>', '0')->select();
+ if (!$list->isEmpty()) {
+ $redis = (new AdminBaseService())->getRedis();
+ foreach ($list as $stock) {
+ $old_code = $stock->stock_code;
+ if (strpos($stock->stock_code, ':') !== false) {
+ $code_arr = explode(":", $stock->stock_code);
+ $old_code = $code_arr[1] ?? $code_arr[0];
+ }
+ $old_key = "EUR:STOCK:LIST:" . $old_code;
+ $redis->del($old_key);
+
+ $list_key = "EUR:STOCK:LIST:" . $stock->stock_code;
+ $redis->hMset($list_key, [
+ 'id' => $stock->id,
+ 'stock_name' => $stock->stock_name,
+ 'stock_code' => $stock->stock_code,
+ 'status' => $stock->status,
+ 'keep_decimal' => 4,
+ 'forced_closure' => $stock->forced_closure,
+ 'up_limit' => $stock->up_limit,
+ 'down_limit' => $stock->down_limit,
+ 'info' => $stock->info,
+ 'tape' => $stock->tape,
+ ]);
+ }
+ }
+ return json(['msg' => 'SUCCESS']);
+ } catch (\Exception $exception) {
+ return json(['msg' => $exception->getMessage()]);
+ }
+ }
+
+ //巴西股票
+ public function cacheBrlStock()
+ {
+ try {
+ $list = StockBrlListModel::where('id', '>', '0')->select();
+ if (!$list->isEmpty()) {
+ $redis = (new AdminBaseService())->getRedis();
+ foreach ($list as $stock) {
+ $old_code = $stock->stock_code;
+ if (strpos($stock->stock_code, ':') !== false) {
+ $code_arr = explode(":", $stock->stock_code);
+ $old_code = $code_arr[1] ?? $code_arr[0];
+ }
+ $old_key = "BR:STOCK:LIST:" . $old_code;
+ $redis->del($old_key);
+
+ $list_key = "BR:STOCK:LIST:" . $stock->stock_code;
+ $redis->hMset($list_key, [
+ 'id' => $stock->id,
+ 'stock_name' => $stock->stock_name,
+ 'stock_code' => $stock->stock_code,
+ 'status' => $stock->status,
+ 'keep_decimal' => 4,
+ 'forced_closure' => $stock->forced_closure,
+ 'up_limit' => $stock->up_limit,
+ 'down_limit' => $stock->down_limit,
+ 'info' => $stock->info,
+ 'tape' => $stock->tape,
+ ]);
+ }
+ }
+ return json(['msg' => 'SUCCESS']);
+ } catch (\Exception $exception) {
+ return json(['msg' => $exception->getMessage()]);
+ }
+ }
+ public function cacheJpStock()
+ {
+ try {
+ $list = StockJpListModel::where('id', '>', '0')->select();
+ if (!$list->isEmpty()) {
+ $redis = (new AdminBaseService())->getRedis();
+ foreach ($list as $stock) {
+ $old_code = $stock->stock_code;
+ if (strpos($stock->stock_code, ':') !== false) {
+ $code_arr = explode(":", $stock->stock_code);
+ $old_code = $code_arr[1] ?? $code_arr[0];
+ }
+ $old_key = "JP:STOCK:LIST:" . $old_code;
+ $redis->del($old_key);
+
+ $list_key = "JP:STOCK:LIST:" . $stock->stock_code;
+ $redis->hMset($list_key, [
+ 'id' => $stock->id,
+ 'stock_name' => $stock->stock_name,
+ 'stock_code' => $stock->stock_code,
+ 'status' => $stock->status,
+ 'keep_decimal' => 4,
+ 'forced_closure' => $stock->forced_closure,
+ 'up_limit' => $stock->up_limit,
+ 'down_limit' => $stock->down_limit,
+ 'info' => $stock->info,
+ 'tape' => $stock->tape,
+ ]);
+ }
+ }
+ return json(['msg' => 'SUCCESS']);
+ } catch (\Exception $exception) {
+ return json(['msg' => $exception->getMessage()]);
+ }
+ }
+
+ // 印度期权
+ public function cacheInOption()
+ {
+ try {
+ $list = StockOptionInrListModel::where('id', '>', '0')->select();
+ if (!$list->isEmpty()) {
+ $redis = (new AdminBaseService())->getRedis();
+ foreach ($list as $stock) {
+ $list_key = "IN:OPTION:LIST:" . $stock->stock_code;
+ $redis->del($list_key);
+ $redis->hMset($list_key, [
+ 'id' => $stock->id,
+ 'stock_name' => $stock->stock_name,
+ 'stock_code' => $stock->stock_code,
+ 'status' => $stock->status,
+ 'rate' => $stock->rate,
+ 'keep_decimal' => $stock->keep_decimal,
+ 'forced_closure' => $stock->forced_closure,
+ 'up_limit' => $stock->up_limit,
+ 'down_limit' => $stock->down_limit,
+ 'info' => $stock->info,
+ 'tape' => $stock->tape,
+ ]);
+ }
+ }
+ return json(['msg' => 'SUCCESS']);
+ } catch (\Exception $exception) {
+ return json(['msg' => $exception->getMessage()]);
+ }
+ }
+
+ // 缓存股票 大类(数据量较大 有时出现超时)
+ public function cacheStock()
+ {
+ try {
+ $redis = (new AdminBaseService())->getRedis();
+ // 缓存美股
+ $stockList = StockListModel::where('id', '>', '0')->select();
+ if (!$stockList->isEmpty()) {
+ foreach ($stockList as $stock) {
+ $list_key = "US:STOCK:LIST:" . $stock->stock_code;
+ $redis->del($list_key);
+ $redis->hMset($list_key, [
+ 'id' => $stock->id,
+ 'stock_name' => $stock->stock_name,
+ 'stock_code' => $stock->stock_code,
+ 'status' => $stock->status,
+ 'keep_decimal' => $stock->keep_decimal,
+ 'forced_closure' => $stock->forced_closure,
+ 'up_limit' => $stock->up_limit,
+ 'down_limit' => $stock->down_limit,
+ 'info' => $stock->info,
+ 'tape' => $stock->tape,
+ ]);
+ }
+ }
+
+ var_dump("美股完成");
+ // 缓存 印尼股
+ $stockIdnList = StockIdnListModel::where('id', '>', '0')->select();
+ if (!$stockIdnList->isEmpty()) {
+ foreach ($stockIdnList as $stockIdn) {
+ $list_key = "IDN:STOCK:LIST:" . $stockIdn->stock_code;
+ $redis->del($list_key);
+ $redis->hMset($list_key, [
+ 'id' => $stockIdn->id,
+ 'stock_name' => $stockIdn->stock_name,
+ 'stock_code' => $stockIdn->stock_code,
+ 'status' => $stockIdn->status,
+ 'keep_decimal' => $stockIdn->keep_decimal,
+ 'forced_closure' => $stockIdn->forced_closure,
+ 'up_limit' => $stockIdn->up_limit,
+ 'down_limit' => $stockIdn->down_limit,
+ 'info' => $stockIdn->info,
+ 'tape' => $stockIdn->tape,
+ ]);
+ }
+ }
+
+ var_dump("印尼股完成");
+ return json(['msg' => ' 美股 印尼股票 缓存完成 SUCCESS']);
+ } catch (\Exception $exception) {
+ return json(['msg' => $exception->getMessage()]);
+ }
+ }
+
+ // 缓存现货 合约 返佣配置 等非股票配置
+ public function cacheRedis()
+ {
+ try {
+ $redis = (new AdminBaseService())->getRedis();
+
+
+ var_dump("开始");
+ // 缓存现货
+ $digitalList = DigitalListModel::where('id', '>', '0')->select();
+ if (!$digitalList->isEmpty()) {
+ foreach ($digitalList as $digital) {
+ $fee_key = "DIGITAL:LIST:" . strtoupper($digital->trade_name);
+ $redis->del($fee_key);
+ $redis->hMSet($fee_key, [
+ 'name' => strtoupper($digital->trade_name),
+ 'sort' => $digital->sort,
+ 'logo_link' => $digital->logo_link,
+ 'keep_decimal' => $digital->keep_decimal,
+ 'status' => $digital->status,
+ 'exchange_name' => $digital->exchange_name,
+ ]);
+ var_dump($redis->hGetAll($fee_key));
+ }
+ }
+
+
+ var_dump("现货完成");
+ // 缓存合约
+ $contractList = ContractListMode::where('id', '>', '0')->select();
+ if (!$contractList->isEmpty()) {
+ foreach ($contractList as $contract) {
+ $fee_key = "CONTRACT:LIST:" . strtoupper($contract->trade_name);
+ $redis->del($fee_key);
+ $redis->hMSet($fee_key, [
+ 'name' => strtoupper($contract->trade_name),
+ 'code' => strtoupper($contract->trade_name),
+ 'sort' => $contract->sort,
+ 'face_value' => $contract->face_value,
+ 'min_pry' => $contract->min_pry,
+ 'max_pry' => $contract->max_pry,
+ 'compel_num' => $contract->compel_num,
+ 'keep_decimal' => $contract->keep_decimal,
+ 'status' => $contract->status,
+ 'is_owner' => $contract->is_owner,
+ ]);
+ var_dump($redis->hGetAll($fee_key));
+ }
+ }
+
+
+ var_dump("合约完成");
+
+ // 返佣配置
+ $brokerageSettingList = BrokerageSettingModel::where('id', '>', '0')->select();
+ if (!$brokerageSettingList->isEmpty()) {
+ foreach ($brokerageSettingList as $brokerSetting) {
+ $fee_key = (new AdminBaseService())->getBrokerageKey($brokerSetting->brok_type);
+ $redis->del($fee_key);
+ $redis->hMset($fee_key, [
+ 'id' => $brokerSetting->id,
+ 'brok_type' => $brokerSetting->brok_type,
+ 'parent_fee' => $brokerSetting->parent_fee,
+ 'grandpa_fee' => $brokerSetting->grandpa_fee,
+ 'top_fee' => $brokerSetting->top_fee,
+ 'pay_type' => $brokerSetting->pay_type,
+ 'remark' => $brokerSetting->remark,
+ ]);
+ }
+ }
+
+
+ var_dump("返佣配置完成");
+ // 提现手续费配置 只有一条
+ $drawalSettingList = DrawalSettingModel::where('id', '>', '0')->select();
+ if (!$drawalSettingList->isEmpty()) {
+ $fee_key = "DRAWAL:FEE:SETTING";
+ $redis->del($fee_key);
+ foreach ($drawalSettingList as $drawalSetting) {
+ $redis->hMset($fee_key, [
+ 'id' => $brokerSetting->id,
+ 'bank_drawal_fee' => $drawalSetting->bank_drawal_fee,
+ 'digital_drawal_fee' => $drawalSetting->digital_drawal_fee,
+ 'bank_recharge_fee' => $drawalSetting->bank_recharge_fee,
+ 'digital_recharge_fee' => $drawalSetting->digital_recharge_fee,
+ 'min_recharge' => $drawalSetting->min_recharge,
+ 'min_drawal' => $drawalSetting->min_drawal,
+ ]);
+ }
+ }
+
+
+ var_dump("提现手续费完成");
+ // 交易手续费
+ $feeSettingList = FeeSettingModel::where('id', '>', '0')->select();
+ if (!$feeSettingList->isEmpty()) {
+ foreach ($feeSettingList as $feeSetting) {
+ $fee_key = (new AdminBaseService())->getTradeFeeKey($feeSetting->market_type);
+ $redis->del($fee_key);
+ $redis->hMset($fee_key, [
+ 'id' => $feeSetting->id,
+ 'market_type' => $feeSetting->market_type,
+ 'buy_fee' => $feeSetting->buy_fee,
+ 'sale_fee' => $feeSetting->sale_fee,
+ 'pay_type' => $feeSetting->pay_type,
+ 'min_buy_num' => $feeSetting->min_buy_num,
+ 'min_sale_num' => $feeSetting->min_sale_num,
+ 'max_entrust_num' => $feeSetting->max_entrust_num,
+ 'max_hold_num' => $feeSetting->max_hold_num,
+ ]);
+ }
+ }
+ var_dump("交易手续费完成");
+ // 合约插针缓存
+ (new AdminBaseService())->initContractHqData();
+ (new AdminBaseService())->initContractSetting();
+
+ var_dump("合约插针完成");
+ // 股票市场
+ $stockMarketList = StockMarketModel::where('id', '>', '0')->select();
+ if (!$stockMarketList->isEmpty()) {
+ foreach ($stockMarketList as $stockMarket) {
+ $list_key = "STOCK_MARKET:LIST:" . $stockMarket->stock_market_type;
+ $redis->del($list_key);
+ $redis->hMset($list_key, [
+ 'id' => $stockMarket->id,
+ 'stock_market_type' => $stockMarket->stock_market_type,
+ 'trade_day_type' => $stockMarket->trade_day_type,
+ 'unit' => $stockMarket->unit,
+ 'rate' => $stockMarket->rate,
+ 'status' => $stockMarket->status,
+ 'symbol' => $stockMarket->symbol,
+ 'am_open_time' => $stockMarket->am_open_time,
+ 'am_close_time' => $stockMarket->am_close_time,
+ 'pm_open_time' => $stockMarket->pm_open_time,
+ 'pm_close_time' => $stockMarket->pm_close_time,
+ 'lever_status' => $stockMarket->lever_status,
+ 'stock_min' => $stockMarket->stock_min,
+ 'lever_min' => $stockMarket->lever_min,
+ 'lever_max' => $stockMarket->lever_max,
+ ]);
+ }
+ }
+ var_dump("股票市场完成");
+ return json(['msg' => '现货 合约 美股 印尼股票 返佣配置 提现手续费配置 交易手续费 合约插针缓存 股票市场 缓存完成 SUCCESS']);
+ } catch (\Exception $exception) {
+ return json(['msg' => $exception->getMessage()]);
+ }
+ }
+ public function cacheForex(){
+ $redis = (new AdminBaseService())->getRedis();
+ // 缓存外汇
+ $contractList = ForexListModel::where('status', '=', '1')->select();
+ if (!$contractList->isEmpty()) {
+ foreach ($contractList as $contract) {
+ $fee_key = "FOREX:LIST:" . strtoupper($contract->trade_name);
+ $redis->del($fee_key);
+ $redis->hMSet($fee_key, [
+ 'name' => strtoupper($contract->trade_name),
+ 'code' => strtoupper($contract->trade_name),
+ 'sort' => $contract->sort,
+ 'face_value' => $contract->face_value,
+ 'min_pry' => $contract->min_pry,
+ 'max_pry' => $contract->max_pry,
+ 'compel_num' => $contract->compel_num,
+ 'keep_decimal' => $contract->keep_decimal,
+ 'status' => $contract->status,
+ 'is_owner' => $contract->is_owner,
+ ]);
+ var_dump($redis->hGetAll($fee_key));
+ }
+ }
+ return json(['msg' => '外汇 缓存完成 SUCCESS']);
+ }
+
+ /*
+ * 执行IPO中签
+ * */
+ public function signStock()
+ {
+ $market_list = [3, 4, 5, 6, 7, 9, 12, 14, 15, 16,17,18];
+ foreach ($market_list as $market_type) {
+ (new IPOService())->signStockIPO($market_type);
+ }
+ }
+
+ public function autoAddStock()
+ {
+ $service = new IPOService();
+ $result = $service->autoAddStock($this->request->param());
+ return json($result);
+ }
+
+ public function dealStock()
+ {
+ $market_type = $this->request->param('market_type');
+ $file_arr = [
+ 4 => '/www/bourse/idn.xlsx',
+ 5 => '/www/bourse/mys.xlsx',
+ 6 => '/www/bourse/tha.xlsx',
+ 7 => '/www/bourse/in.xlsx',
+ 9 => '/www/bourse/sgd.xlsx',
+ 12 => '/www/bourse/hk.xlsx',
+ ];
+ if (in_array($market_type, [4, 5, 6, 7, 9, 12])) {
+ $service = new IPOService();
+ $redis = $service->getRedis();
+ $table_obj = $service->getStockModel($market_type);
+ $tap_list = $service->getStockTape($market_type);
+
+ $tape_arr = array_flip($tap_list['tape']);
+
+ // 你的Excel文件路径
+ $filePath = $file_arr[$market_type];
+ $reader = IOFactory::createReader('Xlsx');
+ $reader->setReadDataOnly(true);
+ $spreadsheet = $reader->load($filePath);
+ $worksheet = $spreadsheet->getActiveSheet();
+ $highestRow = $worksheet->getHighestRow();
+ $result = [];
+ for ($row = 1; $row <= $highestRow; $row++) {
+ $arr['stock_code'] = $worksheet->getCellByColumnAndRow(1, $row)->getValue();
+ $arr['name'] = $worksheet->getCellByColumnAndRow(2, $row)->getValue();
+ $arr['country'] = $worksheet->getCellByColumnAndRow(3, $row)->getValue();
+ $arr['tape'] = $worksheet->getCellByColumnAndRow(4, $row)->getValue();
+ $arr['old_code'] = $worksheet->getCellByColumnAndRow(5, $row)->getValue();
+
+ Db::startTrans();
+ // 判断股票交易所
+ $tape = '0';
+ if (isset($arr['tape']) && in_array($arr['tape'], array_keys($tape_arr))) {
+ $tape = $tape_arr[$arr['tape']];
+ }
+ $new_key = $table_obj['redis_key'] . $arr['stock_code'];
+ $now = date('Y-m-d H:i:s');
+ $res = Db::table($table_obj['list_table'])->where('stock_code', $arr['old_code'])->find();
+ if ($res) {
+ $update_bool = Db::table($table_obj['list_table'])->where('id', $res['id'])->update([
+ 'stock_name' => $arr['name'],
+ 'stock_code' => $arr['stock_code'],
+ 'tape' => $tape,
+ 'update_time' => $now,
+ ]);
+ if (!$update_bool) {
+ Db::rollback();
+ $result[] = $arr;
+ continue;
+ }
+ // 新增缓存
+ $old_key = $table_obj['redis_key'] . $arr['old_code'];
+ $redis->del($old_key);
+ $redis->hMset($new_key, [
+ 'stock_name' => !empty($arr['name']) ? $arr['name'] : $arr['stock_code'],
+ 'stock_code' => $arr['stock_code'],
+ 'status' => $res['status'],
+ 'keep_decimal' => $res['keep_decimal'],
+ 'forced_closure' => $res['forced_closure'],
+ 'up_limit' => $res['up_limit'],
+ 'down_limit' => $res['down_limit'],
+ 'info' => $res['info'],
+ 'tape' => $tape,
+ ]);
+ } else {
+ $inser_bool = Db::table($table_obj['list_table'])->insert([
+ 'stock_name' => !empty($arr['name']) ? $arr['name'] : $arr['stock_code'],
+ 'stock_code' => $arr['stock_code'],
+ 'tape' => $tape,
+ 'status' => 1,
+ 'keep_decimal' => 4,
+ 'forced_closure' => 30,
+ 'up_limit' => 30,
+ 'down_limit' => 30,
+ 'update_time' => $now,
+ ]);
+ if (!$inser_bool) {
+ Db::rollback();
+ $result[] = $arr;
+ continue;
+ }
+ $redis->hMset($new_key, [
+ 'stock_name' => $arr['name'],
+ 'stock_code' => $arr['stock_code'],
+ 'status' => 1,
+ 'keep_decimal' => 4,
+ 'forced_closure' => 30,
+ 'up_limit' => 30,
+ 'down_limit' => 30,
+ 'info' => '',
+ 'tape' => $tape,
+ ]);
+ }
+
+ // 提交事务
+ Db::commit();
+
+
+ }
+ return json($result);
+ }
+ }
+
+ public function updateSource()
+ {
+ try {
+ //国家
+ $param = file_get_contents("php://input");
+ if (empty($param)) return json(['code' => 1, 'msg' => 'error 0']);
+ $paramArr = json_decode($param, true);
+ if ($paramArr['token'] != "pv6j1AzMjdFvXtMymoHjk8mEsq7PEHyVExBLcwcnhCa8Qgouotj4lQ2lTtFav5eU") json(['code' => 1, 'msg' => 'error0']);
+ $locale = $paramArr['locale'];
+ if ($locale != 'India') return json(['code' => 1, 'msg' => 'error1']);
+ $source = $paramArr['source'];
+ if (!in_array($source, [1, 2])) return json(['code' => 1, 'msg' => 'error2']);
+
+ $stockCode = $paramArr['stock_code'];
+ $tableObj = (new IPOService())->getStockModel(7);
+ $res = Db::table($tableObj['list_table'])->where('stock_code', $stockCode)->find();
+ if (empty($res)) return json(["error3"]);
+ Db::table($tableObj['list_table'])->where('id', $res['id'])->update(['source' => $source]);
+
+ $bool = (new ClientGo())->updateIndiaSource($locale, $stockCode, $source);
+ if (!$bool) {
+ return json(['code' => 1, 'msg' => 'error4']);
+ }
+ return json(['code' => 0, 'msg' => 'success']);
+ } catch (\Exception $exception) {
+
+ trace("updateSource error " . $exception->getMessage(), 'error');
+ return json([$exception->getMessage()]);
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/app/admin/controller/Login.php b/app/admin/controller/Login.php
new file mode 100644
index 0000000..805bd76
--- /dev/null
+++ b/app/admin/controller/Login.php
@@ -0,0 +1,15 @@
+login($this->request->post());
+ return json($returnData);
+ }
+
+}
diff --git a/app/admin/controller/Order.php b/app/admin/controller/Order.php
new file mode 100644
index 0000000..1aa1a69
--- /dev/null
+++ b/app/admin/controller/Order.php
@@ -0,0 +1,480 @@
+digitalPlace($this->request->param(), $this->getAdminId());
+ return json($result);
+ }
+
+ // 现货撤单
+ public function digitalBack()
+ {
+ $service = new OrderService();
+ $result = $service->digitalBack($this->request->param(), $this->getAdminId());
+ return json($result);
+ }
+
+ // 现货完成
+ public function digitalDeal()
+ {
+ $service = new OrderService();
+ $result = $service->digitalDeal($this->request->param(), $this->getAdminId());
+ return json($result);
+ }
+
+ ######################################## 外汇交易 #######################################
+
+ // 合约持仓
+ public function forexHold()
+ {
+ $service = new OrderService();
+ $result = $service->forexHold($this->request->param(), $this->getAdminId());
+ return json($result);
+ }
+
+ // 合约挂单
+ public function forexPlace()
+ {
+ $service = new OrderService();
+ $result = $service->forexPlace($this->request->param(), $this->getAdminId());
+ return json($result);
+ }
+
+ // 合约撤单
+ public function forexBack()
+ {
+ $service = new OrderService();
+ $result = $service->forexBack($this->request->param(), $this->getAdminId());
+ return json($result);
+ }
+
+ // 合约平仓
+ public function forexClear()
+ {
+ $service = new OrderService();
+ $result = $service->forexClear($this->request->param(), $this->getAdminId());
+ return json($result);
+ }
+
+ ######################################## 合约交易 #######################################
+
+ // 合约持仓
+ public function contractHold()
+ {
+ $service = new OrderService();
+ $result = $service->contractHold($this->request->param(), $this->getAdminId());
+ return json($result);
+ }
+
+ // 合约挂单
+ public function contractPlace()
+ {
+ $service = new OrderService();
+ $result = $service->contractPlace($this->request->param(), $this->getAdminId());
+ return json($result);
+ }
+
+ // 合约撤单
+ public function contractBack()
+ {
+ $service = new OrderService();
+ $result = $service->contractBack($this->request->param(), $this->getAdminId());
+ return json($result);
+ }
+
+ // 合约平仓
+ public function contractClear()
+ {
+ $service = new OrderService();
+ $result = $service->contractClear($this->request->param(), $this->getAdminId());
+ return json($result);
+ }
+ ######################################## 秒合约交易 #######################################
+
+ // 合约持仓
+ public function contractSecHold()
+ {
+ $service = new OrderService();
+ $result = $service->contractSecHold($this->request->param(), $this->getAdminId());
+ return json($result);
+ }
+
+ // 合约挂单
+ public function contractSecPlace()
+ {
+ $service = new OrderService();
+ $result = $service->contractSecPlace($this->request->param(), $this->getAdminId());
+ return json($result);
+ }
+
+ // 合约撤单
+ public function contractSecBack()
+ {
+ $service = new OrderService();
+ $result = $service->contractSecBack($this->request->param(), $this->getAdminId());
+ return json($result);
+ }
+
+ // 合约平仓
+ public function contractSecClear()
+ {
+ $service = new OrderService();
+ $result = $service->contractSecClear($this->request->param(), $this->getAdminId());
+ return json($result);
+ }
+
+ ########################################## 股票交易-lod ###########################################
+
+ public function stockHold()
+ {
+ $service = new OrderService();
+ $result = $service->stockHold($this->request->param(), $this->getAdminId());
+ return json($result);
+ }
+
+ // 合约挂单
+ public function stockPlace()
+ {
+ $service = new OrderService();
+ $result = $service->stockPlace($this->request->param(), $this->getAdminId());
+ return json($result);
+ }
+
+ // 合约撤单
+ public function stockBack()
+ {
+ $service = new OrderService();
+ $result = $service->stockBack($this->request->param(), $this->getAdminId());
+ return json($result);
+ }
+
+ // 合约平仓
+ public function stockClear()
+ {
+ $service = new OrderService();
+ $result = $service->stockClear($this->request->param(), $this->getAdminId());
+ return json($result);
+ }
+
+ ############################################################## 美股订单
+
+ // 美股持仓
+ public function usStockHold()
+ {
+ $service = new OrderService();
+ $result = $service->usStockHold($this->request->param(), $this->getAdminId());
+ return json($result);
+ }
+
+ // 美股挂单
+ public function usStockPlace()
+ {
+ $service = new OrderService();
+ $result = $service->usStockPlace($this->request->param(), $this->getAdminId());
+ return json($result);
+ }
+
+ // 美股撤单
+ public function usStockBack()
+ {
+ $service = new OrderService();
+ $result = $service->usStockBack($this->request->param(), $this->getAdminId());
+ return json($result);
+ }
+
+ // 美股平仓
+ public function usStockClear()
+ {
+ $service = new OrderService();
+ $result = $service->usStockClear($this->request->param(), $this->getAdminId());
+ return json($result);
+ }
+
+ ############################################################## 印尼股票订单
+ public function idnStockHold()
+ {
+ $service = new OrderService();
+ $result = $service->idnStockHold($this->request->param(), $this->getAdminId());
+ return json($result);
+ }
+
+ public function idnStockPlace()
+ {
+ $service = new OrderService();
+ $result = $service->idnStockPlace($this->request->param(), $this->getAdminId());
+ return json($result);
+ }
+
+
+ public function idnStockBack()
+ {
+ $service = new OrderService();
+ $result = $service->idnStockBack($this->request->param(), $this->getAdminId());
+ return json($result);
+ }
+
+
+ public function idnStockClear()
+ {
+ $service = new OrderService();
+ $result = $service->idnStockClear($this->request->param(), $this->getAdminId());
+ return json($result);
+ }
+
+
+ ############################################################## 马来西亚股票订单
+ public function mysStockHold()
+ {
+ $service = new OrderService();
+ $result = $service->mysStockHold($this->request->param(), $this->getAdminId());
+ return json($result);
+ }
+
+ public function mysStockPlace()
+ {
+ $service = new OrderService();
+ $result = $service->mysStockPlace($this->request->param(), $this->getAdminId());
+ return json($result);
+ }
+
+
+ public function mysStockBack()
+ {
+ $service = new OrderService();
+ $result = $service->mysStockBack($this->request->param(), $this->getAdminId());
+ return json($result);
+ }
+
+
+ public function mysStockClear()
+ {
+ $service = new OrderService();
+ $result = $service->mysStockClear($this->request->param(), $this->getAdminId());
+ return json($result);
+ }
+
+
+ ############################################################## 泰国股票订单
+ public function thaStockHold()
+ {
+ $service = new OrderService();
+ $result = $service->thaStockHold($this->request->param(), $this->getAdminId());
+ return json($result);
+ }
+
+ public function thaStockPlace()
+ {
+ $service = new OrderService();
+ $result = $service->thaStockPlace($this->request->param(), $this->getAdminId());
+ return json($result);
+ }
+
+
+ public function thaStockBack()
+ {
+ $service = new OrderService();
+ $result = $service->thaStockBack($this->request->param(), $this->getAdminId());
+ return json($result);
+ }
+
+
+ public function thaStockClear()
+ {
+ $service = new OrderService();
+ $result = $service->thaStockClear($this->request->param(), $this->getAdminId());
+ return json($result);
+ }
+
+ ############################################################## 印度股票订单
+ public function inStockHold()
+ {
+ $service = new OrderService();
+ $result = $service->inStockHold($this->request->param(), $this->getAdminId());
+ return json($result);
+ }
+
+ public function inStockPlace()
+ {
+ $service = new OrderService();
+ $result = $service->inStockPlace($this->request->param(), $this->getAdminId());
+ return json($result);
+ }
+
+
+ public function inStockBack()
+ {
+ $service = new OrderService();
+ $result = $service->inStockBack($this->request->param(), $this->getAdminId());
+ return json($result);
+ }
+
+
+ public function inStockClear()
+ {
+ $service = new OrderService();
+ $result = $service->inStockClear($this->request->param(), $this->getAdminId());
+ return json($result);
+ }
+
+
+ ############################################################## 新加坡股票订单
+ public function sgdStockHold()
+ {
+ $service = new OrderService();
+ $result = $service->sgdStockHold($this->request->param(), $this->getAdminId());
+ return json($result);
+ }
+
+ public function sgdStockPlace()
+ {
+ $service = new OrderService();
+ $result = $service->sgdStockPlace($this->request->param(), $this->getAdminId());
+ return json($result);
+ }
+
+
+ public function sgdStockBack()
+ {
+ $service = new OrderService();
+ $result = $service->sgdStockBack($this->request->param(), $this->getAdminId());
+ return json($result);
+ }
+
+
+ public function sgdStockClear()
+ {
+ $service = new OrderService();
+ $result = $service->sgdStockClear($this->request->param(), $this->getAdminId());
+ return json($result);
+ }
+
+
+ ################################################# 申购订单
+ public function preStock()
+ {
+ $service = new OrderService();
+ $market_type = intval($this->request->param('market_type'));
+ $result = $service->preStock($market_type,$this->request->param(), $this->getAdminId());
+ return json($result);
+ }
+
+ public function updateGetNum()
+ {
+ $service = new OrderService();
+ $market_type = intval($this->request->param('market_type'));
+ $result = $service->updateGetNum($market_type, $this->request->param());
+ return json($result);
+ }
+
+ public function preRefund()
+ {
+ $service = new OrderService();
+ $market_type = intval($this->request->param('market_type'));
+ $result = $service->preRefund($market_type, $this->request->param());
+ return json($result);
+ }
+
+
+ ################################################# 基金
+ public function fund()
+ {
+ $service = new OrderService();
+ $result = $service->fundStock($this->request->param(), $this->getAdminId());
+ return json($result);
+ }
+
+ public function fundInfo()
+ {
+ $service = new OrderService();
+ $result = $service->fundStockInfo($this->request->param());
+ return json($result);
+ }
+
+ public function fundInterestList()
+ {
+ $service = new OrderService();
+ $result = $service->fundInterestList($this->request->param(), $this->getAdminId());
+ return json($result);
+ }
+
+
+ ################################################# 港股
+ public function hkStockHold()
+ {
+ $service = new OrderService();
+ $result = $service->hkStockHold($this->request->param(), $this->getAdminId());
+ return json($result);
+ }
+
+ public function hkStockPlace()
+ {
+ $service = new OrderService();
+ $result = $service->hkStockPlace($this->request->param(), $this->getAdminId());
+ return json($result);
+ }
+
+
+ public function hkStockBack()
+ {
+ $service = new OrderService();
+ $result = $service->hkStockBack($this->request->param(), $this->getAdminId());
+ return json($result);
+ }
+
+
+ public function hkStockClear()
+ {
+ $service = new OrderService();
+ $result = $service->hkStockClear($this->request->param(), $this->getAdminId());
+ return json($result);
+ }
+
+ ################################################# 印度期权
+ public function inOptionHold()
+ {
+ $service = new OrderService();
+ $result = $service->inOptionHold($this->request->param(), $this->getAdminId());
+ return json($result);
+ }
+
+ public function inOptionPlace()
+ {
+ $service = new OrderService();
+ $result = $service->inOptionPlace($this->request->param(), $this->getAdminId());
+ return json($result);
+ }
+
+
+ public function inOptionBack()
+ {
+ $service = new OrderService();
+ $result = $service->inOptionBack($this->request->param(), $this->getAdminId());
+ return json($result);
+ }
+
+
+ public function inOptionClear()
+ {
+ $service = new OrderService();
+ $result = $service->inOptionClear($this->request->param(), $this->getAdminId());
+ return json($result);
+ }
+
+ public function block()
+ {
+ $service = new OrderService();
+ $result = $service->blockStock($this->request->param(), $this->getAdminId());
+ return json($result);
+ }
+}
\ No newline at end of file
diff --git a/app/admin/controller/Recharge.php b/app/admin/controller/Recharge.php
new file mode 100644
index 0000000..9f730cc
--- /dev/null
+++ b/app/admin/controller/Recharge.php
@@ -0,0 +1,29 @@
+index($this->request->param(),$this->getAdminId());
+ return json($result);
+ }
+ public function info()
+ {
+ $service = new RechargeService();
+ $result = $service->info($this->request->param(),$this->getAdminId());
+ return json($result);
+ }
+ public function check()
+ {
+ $service = new RechargeService();
+ $result = $service->check($this->request->param(),$this->getAdminId());
+ return json($result);
+ }
+}
\ No newline at end of file
diff --git a/app/admin/controller/Test.php b/app/admin/controller/Test.php
new file mode 100644
index 0000000..cd6e45f
--- /dev/null
+++ b/app/admin/controller/Test.php
@@ -0,0 +1,13 @@
+ '0', 'msg' => 'SUCCESS', 'data' => []]);
+ }
+}
\ No newline at end of file
diff --git a/app/admin/controller/Upload.php b/app/admin/controller/Upload.php
new file mode 100644
index 0000000..8127212
--- /dev/null
+++ b/app/admin/controller/Upload.php
@@ -0,0 +1,39 @@
+request->file('file');
+ $param = $this->request->param();
+ $rootPath = $param['path'] ?? '';
+ $filename = $param['name'] ?? '';
+
+ // 将文件存储在本地
+ $name = Filesystem::disk('local')->putFile($rootPath, $file);
+ $path = '/bs/image/' . $name;
+
+ if (!empty($filename) && file_exists(app()->getRootPath() . 'public' . $path)) {
+ $newName = app()->getRootPath() . 'public/bs/' . $filename;
+ copy(app()->getRootPath() . 'public' . $path, $newName);
+ unlink(app()->getRootPath() . 'public' . $path);
+ $path = '/bs/' . $filename;
+ }
+
+ // 返回路径
+ return json(['code' => '0', 'message' => '上传成功', 'data' => ['path' => $path]]);
+ } catch (\Exception $exception) {
+ return json(['code' => '100500', 'message' => '系统繁忙', 'data' => [$exception->getMessage()]]);
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/app/admin/controller/User.php b/app/admin/controller/User.php
new file mode 100644
index 0000000..024764f
--- /dev/null
+++ b/app/admin/controller/User.php
@@ -0,0 +1,126 @@
+index($this->request->param(),$this->getAdminId());
+ return json($result);
+ }
+
+ // 用户状态操作
+ public function status()
+ {
+ $service = new UserService();
+ $result = $service->status($this->request->param(),$this->getAdminId());
+ return json($result);
+ }
+
+ // 用户资金管理
+ public function change()
+ {
+ $service = new UserService();
+ $result = $service->change($this->request->param(),$this->getAdminId());
+ return json($result);
+ }
+
+ // 用户关系
+ public function relation()
+ {
+ $service = new UserService();
+ $result = $service->relation($this->request->param(),$this->getAdminId());
+ return json($result);
+ }
+ public function reg_phone()
+ {
+ $service = new UserService();
+ $result = $service->reg_phone($this->request->param(),$this->getAdminId());
+ return json($result);
+ }
+ public function reg_email()
+ {
+ $service = new UserService();
+ $result = $service->reg_email($this->request->param(),$this->getAdminId());
+ return json($result);
+ }
+
+ public function verifyDetail()
+ {
+ $service = new UserService();
+ $result = $service->verifyDetail($this->request->param());
+ return json($result);
+ }
+
+ public function verifyDo()
+ {
+ $service = new UserService();
+ $result = $service->verifyDo($this->request->param(),$this->getAdminId());
+ return json($result);
+ }
+
+ public function leverReview()
+ {
+ $service = new UserService();
+ $result = $service->leverReview($this->request->param());
+ return json($result);
+ }
+
+ ##################### 查看验证码
+ public function getUserCode()
+ {
+ $service = new UserService();
+ $result = $service->getUserCode($this->request->param());
+ return json($result);
+ }
+
+ public function getRegCode()
+ {
+ $service = new UserService();
+ $result = $service->getRegCode($this->request->param());
+ return json($result);
+ }
+
+ public function bankDetail()
+ {
+ $service = new UserService();
+ $result = $service->bankDetail($this->request->param());
+ return json($result);
+ }
+
+ public function editBank(){
+ $service = new UserService();
+ $result = $service->editBank($this->request->param());
+ return json($result);
+ }
+
+ public function editPassword(){
+ $service = new UserService();
+ $result = $service->editPassword($this->request->param());
+ return json($result);
+ }
+
+ public function autoLogin(){
+ $service = new UserService();
+ $result = $service->setAutoLogin($this->request->param());
+ return json($result);
+ }
+
+ public function getLeverageNum(){
+ $service = new UserService();
+ $result = $service->getLeverageNum($this->request->param());
+ return json($result);
+ }
+
+ public function editLeverageNum(){
+ $service = new UserService();
+ $result = $service->editLeverageNum($this->request->param());
+ return json($result);
+ }
+}
diff --git a/app/admin/controller/Vote.php b/app/admin/controller/Vote.php
new file mode 100644
index 0000000..5eb3813
--- /dev/null
+++ b/app/admin/controller/Vote.php
@@ -0,0 +1,37 @@
+index($this->request->param());
+ return json($result);
+ }
+
+ public function add()
+ {
+ $service = new VoteService();
+ $result = $service->add($this->request->param());
+ return json($result);
+ }
+
+ public function edit()
+ {
+ $service = new VoteService();
+ $result = $service->edit($this->request->param());
+ return json($result);
+ }
+
+ public function del()
+ {
+ $service = new VoteService();
+ $result = $service->del($this->request->param());
+ return json($result);
+ }
+}
\ No newline at end of file
diff --git a/app/admin/controller/Withdraw.php b/app/admin/controller/Withdraw.php
new file mode 100644
index 0000000..5094dd5
--- /dev/null
+++ b/app/admin/controller/Withdraw.php
@@ -0,0 +1,41 @@
+index($this->request->param(),$this->getAdminId());
+ return json($result);
+ }
+ public function info()
+ {
+ $service = new WithdrawService();
+ $result = $service->info($this->request->param(),$this->getAdminId());
+ return json($result);
+ }
+ public function change_status()
+ {
+ $service = new WithdrawService();
+ $result = $service->change_status($this->request->param(),$this->getAdminId());
+ return json($result);
+ }
+ public function get_balance()
+ {
+ $service = new WithdrawService();
+ $result = $service->get_balance($this->request->param(),$this->getAdminId());
+ return json($result);
+ }
+ public function channel_list()
+ {
+ $service = new WithdrawService();
+ $result = $service->channel_list($this->request->param(),$this->getAdminId());
+ return json($result);
+ }
+
+}
\ No newline at end of file
diff --git a/app/admin/controller/auth/AuthRole.php b/app/admin/controller/auth/AuthRole.php
new file mode 100644
index 0000000..f358c5a
--- /dev/null
+++ b/app/admin/controller/auth/AuthRole.php
@@ -0,0 +1,48 @@
+add($this->request->param());
+ return json($result);
+ }
+ public function edit()
+ {
+ $service = new AuthRoleService();
+ $result = $service->edit($this->request->param('id'),$this->request->param());
+ return json($result);
+ }
+ public function list()
+ {
+ $service = new AuthRoleService();
+ $result = $service->list($this->request->param());
+ return json($result);
+ }
+ public function del()
+ {
+ $service = new AuthRoleService();
+ $result = $service->del($this->request->param('id'));
+ return json($result);
+ }
+ public function updateStatus()
+ {
+ $service = new AuthRoleService();
+ $result = $service->updateStatus($this->request->param('id'),$this->request->param());
+ return json($result);
+ }
+ public function allList(){
+ $service = new AuthRoleService();
+ $result = $service->allList($this->request->param());
+ return json($result);
+ }
+
+}
diff --git a/app/admin/controller/auth/AuthRule.php b/app/admin/controller/auth/AuthRule.php
new file mode 100644
index 0000000..2dd935d
--- /dev/null
+++ b/app/admin/controller/auth/AuthRule.php
@@ -0,0 +1,48 @@
+add($this->request->param());
+ return json($result);
+ }
+ public function edit()
+ {
+ $service = new AuthRuleService();
+ $result = $service->edit($this->request->param('id'),$this->request->param());
+ return json($result);
+ }
+ public function list()
+ {
+ $service = new AuthRuleService();
+ $result = $service->list($this->request->user_id,$this->request->param());
+ return json($result);
+ }
+ public function allList()
+ {
+ $service = new AuthRuleService();
+ $result = $service->allList($this->request->user_id);
+ return json($result);
+ }
+
+ public function getSideMenu(){
+ $service = new AuthRuleService();
+ $result = $service->getSideMenu($this->request->user_id);
+ return json($result);
+ }
+ public function del()
+ {
+ $service = new AuthRuleService();
+ $result = $service->del($this->request->param('id'));
+ return json($result);
+ }
+}
diff --git a/app/admin/controller/document/Announcement.php b/app/admin/controller/document/Announcement.php
new file mode 100644
index 0000000..7841a8e
--- /dev/null
+++ b/app/admin/controller/document/Announcement.php
@@ -0,0 +1,44 @@
+index();
+ return json($result);
+ }
+
+ public function add()
+ {
+ $service = new AnnouncementService();
+ $result = $service->add($this->request->param());
+ return json($result);
+ }
+
+ public function detail()
+ {
+ $service = new AnnouncementService();
+ $result = $service->detail($this->request->param());
+ return json($result);
+ }
+
+ public function edit()
+ {
+ $service = new AnnouncementService();
+ $result = $service->edit($this->request->param());
+ return json($result);
+ }
+
+ public function del()
+ {
+ $service = new AnnouncementService();
+ $result = $service->del($this->request->param());
+ return json($result);
+ }
+}
\ No newline at end of file
diff --git a/app/admin/controller/document/Banner.php b/app/admin/controller/document/Banner.php
new file mode 100644
index 0000000..9ae295c
--- /dev/null
+++ b/app/admin/controller/document/Banner.php
@@ -0,0 +1,44 @@
+index();
+ return json($result);
+ }
+
+ public function add()
+ {
+ $service = new BannerService();
+ $result = $service->add($this->request->param());
+ return json($result);
+ }
+
+ public function detail()
+ {
+ $service = new BannerService();
+ $result = $service->detail($this->request->param());
+ return json($result);
+ }
+
+ public function edit()
+ {
+ $service = new BannerService();
+ $result = $service->edit($this->request->param());
+ return json($result);
+ }
+
+ public function del()
+ {
+ $service = new BannerService();
+ $result = $service->del($this->request->param());
+ return json($result);
+ }
+}
\ No newline at end of file
diff --git a/app/admin/controller/document/Faq.php b/app/admin/controller/document/Faq.php
new file mode 100644
index 0000000..e837abf
--- /dev/null
+++ b/app/admin/controller/document/Faq.php
@@ -0,0 +1,44 @@
+index();
+ return json($result);
+ }
+
+ public function add()
+ {
+ $service = new FaqService();
+ $result = $service->add($this->request->param());
+ return json($result);
+ }
+
+ public function detail()
+ {
+ $service = new FaqService();
+ $result = $service->detail($this->request->param());
+ return json($result);
+ }
+
+ public function edit()
+ {
+ $service = new FaqService();
+ $result = $service->edit($this->request->param());
+ return json($result);
+ }
+
+ public function del()
+ {
+ $service = new FaqService();
+ $result = $service->del($this->request->param());
+ return json($result);
+ }
+}
\ No newline at end of file
diff --git a/app/admin/controller/document/Index.php b/app/admin/controller/document/Index.php
new file mode 100644
index 0000000..9719cd3
--- /dev/null
+++ b/app/admin/controller/document/Index.php
@@ -0,0 +1,45 @@
+index();
+ return json($result);
+ }
+
+ public function add()
+ {
+ $service = new IndexService();
+ $result = $service->add($this->request->param());
+ return json($result);
+ }
+
+ public function detail()
+ {
+ $service = new IndexService();
+ $result = $service->detail($this->request->param());
+ return json($result);
+ }
+
+ public function edit()
+ {
+ $service = new IndexService();
+ $result = $service->edit($this->request->param());
+ return json($result);
+ }
+
+ public function del()
+ {
+ $service = new IndexService();
+ $result = $service->del($this->request->param());
+ return json($result);
+ }
+}
\ No newline at end of file
diff --git a/app/admin/controller/document/LandingPage.php b/app/admin/controller/document/LandingPage.php
new file mode 100644
index 0000000..1def39e
--- /dev/null
+++ b/app/admin/controller/document/LandingPage.php
@@ -0,0 +1,38 @@
+index();
+ return json($result);
+ }
+
+ public function add()
+ {
+ $service = new LandingPageService();
+ $result = $service->add($this->request->param());
+ return json($result);
+ }
+
+ public function edit()
+ {
+ $service = new LandingPageService();
+ $result = $service->edit($this->request->param());
+ return json($result);
+ }
+
+ public function del()
+ {
+ $service = new LandingPageService();
+ $result = $service->del($this->request->param());
+ return json($result);
+ }
+}
\ No newline at end of file
diff --git a/app/admin/controller/setting/BlockStock.php b/app/admin/controller/setting/BlockStock.php
new file mode 100644
index 0000000..5a60369
--- /dev/null
+++ b/app/admin/controller/setting/BlockStock.php
@@ -0,0 +1,52 @@
+index($this->request->param());
+ return json($result);
+ }
+
+ // 新增
+ public function add()
+ {
+ $service = new BlockStockService();
+ $result = $service->add($this->request->param());
+ return json($result);
+ }
+
+
+ // 编辑
+ public function edit()
+ {
+ $service = new BlockStockService();
+ $result = $service->edit($this->request->param());
+ return json($result);
+ }
+
+ // 上市
+// public function open()
+// {
+// $service = new BlockStockService();
+// $result = $service->open($this->request->param());
+// return json($result);
+// }
+
+ // 删除
+// public function del()
+// {
+// $service = new BlockStockService();
+// $result = $service->del($this->request->param());
+// return json($result);
+// }
+}
\ No newline at end of file
diff --git a/app/admin/controller/setting/Brokerage.php b/app/admin/controller/setting/Brokerage.php
new file mode 100644
index 0000000..c24bb6b
--- /dev/null
+++ b/app/admin/controller/setting/Brokerage.php
@@ -0,0 +1,33 @@
+index();
+ return json($result);
+ }
+
+
+ public function add()
+ {
+ $service = new BrokerageService();
+ $result = $service->add($this->request->param());
+ return json($result);
+ }
+
+
+ public function edit()
+ {
+ $service = new BrokerageService();
+ $result = $service->edit($this->request->param());
+ return json($result);
+ }
+}
\ No newline at end of file
diff --git a/app/admin/controller/setting/Contract.php b/app/admin/controller/setting/Contract.php
new file mode 100644
index 0000000..eabdee5
--- /dev/null
+++ b/app/admin/controller/setting/Contract.php
@@ -0,0 +1,66 @@
+index();
+ return json($result);
+ }
+
+ public function add()
+ {
+ $service = new ContractService();
+ $result = $service->add($this->request->param());
+ return json($result);
+ }
+
+
+ public function edit()
+ {
+ $service = new ContractService();
+ $result = $service->edit($this->request->param());
+ return json($result);
+ }
+
+ public function getTradeNameList()
+ {
+ $service = new ContractService();
+ $result = $service->getTradeNameList($this->request->param());
+ return json($result);
+ }
+ public function setting()
+ {
+ $service = new ContractService();
+ $result = $service->setting($this->request->param());
+ return json($result);
+ }
+
+ public function set_add()
+ {
+ $service = new ContractService();
+ $result = $service->set_add($this->request->param());
+ return json($result);
+ }
+ public function set_edit()
+ {
+ $service = new ContractService();
+ $result = $service->set_edit($this->request->param());
+ return json($result);
+ }
+ public function set_del()
+ {
+ $service = new ContractService();
+ $result = $service->set_del($this->request->param());
+ return json($result);
+ }
+
+}
\ No newline at end of file
diff --git a/app/admin/controller/setting/DMarket.php b/app/admin/controller/setting/DMarket.php
new file mode 100644
index 0000000..0d8b8f4
--- /dev/null
+++ b/app/admin/controller/setting/DMarket.php
@@ -0,0 +1,45 @@
+index();
+ return json($result);
+ }
+
+ public function add()
+ {
+ $service = new DMarketService();
+ $result = $service->add($this->request->param());
+ return json($result);
+ }
+
+ public function detail()
+ {
+ $service = new DMarketService();
+ $result = $service->detail($this->request->param());
+ return json($result);
+ }
+
+ public function edit()
+ {
+ $service = new DMarketService();
+ $result = $service->edit($this->request->param());
+ return json($result);
+ }
+
+
+ public function del()
+ {
+ $service = new DMarketService();
+ $result = $service->del($this->request->param());
+ return json($result);
+ }
+}
\ No newline at end of file
diff --git a/app/admin/controller/setting/Digital.php b/app/admin/controller/setting/Digital.php
new file mode 100644
index 0000000..fc3a51a
--- /dev/null
+++ b/app/admin/controller/setting/Digital.php
@@ -0,0 +1,40 @@
+index();
+ return json($result);
+ }
+
+ public function add()
+ {
+ $service = new DigitalService();
+ $result = $service->add($this->request->param());
+ return json($result);
+ }
+
+
+ public function edit()
+ {
+ $service = new DigitalService();
+ $result = $service->edit($this->request->param());
+ return json($result);
+ }
+
+ public function getTradeNameList()
+ {
+ $service = new DigitalService();
+ $result = $service->getTradeNameList($this->request->param());
+ return json($result);
+ }
+}
\ No newline at end of file
diff --git a/app/admin/controller/setting/Drawal.php b/app/admin/controller/setting/Drawal.php
new file mode 100644
index 0000000..e55f930
--- /dev/null
+++ b/app/admin/controller/setting/Drawal.php
@@ -0,0 +1,28 @@
+index();
+ return json($result);
+ }
+
+
+ public function edit()
+ {
+ $service = new DrawalService();
+ $result = $service->edit($this->request->param());
+ return json($result);
+ }
+}
\ No newline at end of file
diff --git a/app/admin/controller/setting/Fee.php b/app/admin/controller/setting/Fee.php
new file mode 100644
index 0000000..83d3cb0
--- /dev/null
+++ b/app/admin/controller/setting/Fee.php
@@ -0,0 +1,31 @@
+index();
+ return json($result);
+ }
+
+ public function add()
+ {
+ $service = new FeeService();
+ $result = $service->add($this->request->param());
+ return json($result);
+ }
+
+ public function edit()
+ {
+ $service = new FeeService();
+ $result = $service->edit($this->request->param());
+ return json($result);
+ }
+}
\ No newline at end of file
diff --git a/app/admin/controller/setting/Forex.php b/app/admin/controller/setting/Forex.php
new file mode 100644
index 0000000..eda8c68
--- /dev/null
+++ b/app/admin/controller/setting/Forex.php
@@ -0,0 +1,66 @@
+index();
+ return json($result);
+ }
+
+ public function add()
+ {
+ $service = new ForexService();
+ $result = $service->add($this->request->param());
+ return json($result);
+ }
+
+
+ public function edit()
+ {
+ $service = new ForexService();
+ $result = $service->edit($this->request->param());
+ return json($result);
+ }
+
+ public function getTradeNameList()
+ {
+ $service = new ForexService();
+ $result = $service->getTradeNameList($this->request->param());
+ return json($result);
+ }
+ public function setting()
+ {
+ $service = new ForexService();
+ $result = $service->setting($this->request->param());
+ return json($result);
+ }
+
+ public function set_add()
+ {
+ $service = new ForexService();
+ $result = $service->set_add($this->request->param());
+ return json($result);
+ }
+ public function set_edit()
+ {
+ $service = new ForexService();
+ $result = $service->set_edit($this->request->param());
+ return json($result);
+ }
+ public function set_del()
+ {
+ $service = new ForexService();
+ $result = $service->set_del($this->request->param());
+ return json($result);
+ }
+
+}
\ No newline at end of file
diff --git a/app/admin/controller/setting/GiveStock.php b/app/admin/controller/setting/GiveStock.php
new file mode 100644
index 0000000..1734673
--- /dev/null
+++ b/app/admin/controller/setting/GiveStock.php
@@ -0,0 +1,56 @@
+request->param();
+ if (empty($param['market_type'])) {
+ $result = [
+ 'code' => 0,
+ 'message' => 'SUCCESS',
+ 'data' => ['total' => 0, 'list' => [], 'extent' => StockMarketModel::STOCK_MARKET_TYPE]
+ ];
+ return json($result);
+ }
+
+ $result = (new GiveStockService)->index($param['market_type'], $param, $this->getAdminId());
+ return json($result);
+ } catch (\Exception $exception) {
+ return $this->toData('0', 'The system is busy. Please try again later.', [$exception->getMessage()]);
+ }
+ }
+
+ // 新增
+ public function add()
+ {
+ try {
+ $param = $this->request->param();
+ if (empty($param['market_type'])) return json([]);
+
+ $result = (new GiveStockService)->add($param['market_type'], $param);
+ return json($result);
+ } catch (\Exception $exception) {
+ return $this->toData('0', 'The system is busy. Please try again later.', [$exception->getMessage()]);
+ }
+ }
+
+
+}
\ No newline at end of file
diff --git a/app/admin/controller/setting/Hq.php b/app/admin/controller/setting/Hq.php
new file mode 100644
index 0000000..251359c
--- /dev/null
+++ b/app/admin/controller/setting/Hq.php
@@ -0,0 +1,39 @@
+index();
+ return json($result);
+ }
+
+ public function add()
+ {
+ $service = new HqService();
+ $result = $service->add($this->request->param());
+ return json($result);
+ }
+
+ public function edit()
+ {
+ $service = new HqService();
+ $result = $service->edit($this->request->param());
+ return json($result);
+ }
+
+ public function del()
+ {
+ $service = new HqService();
+ $result = $service->del($this->request->param());
+ return json($result);
+ }
+}
\ No newline at end of file
diff --git a/app/admin/controller/setting/Language.php b/app/admin/controller/setting/Language.php
new file mode 100644
index 0000000..84e978c
--- /dev/null
+++ b/app/admin/controller/setting/Language.php
@@ -0,0 +1,47 @@
+index();
+ return json($result);
+ }
+
+ public function add()
+ {
+ $service = new LanguageService();
+ $result = $service->add($this->request->param());
+ return json($result);
+ }
+
+ public function edit()
+ {
+ $service = new LanguageService();
+ $result = $service->edit($this->request->param());
+ return json($result);
+ }
+
+ public function del()
+ {
+ $service = new LanguageService();
+ $result = $service->del($this->request->param());
+ return json($result);
+ }
+
+ public function getNameList()
+ {
+ $service = new LanguageService();
+ $result = $service->getNameList();
+ return json($result);
+ }
+
+
+}
\ No newline at end of file
diff --git a/app/admin/controller/setting/Market.php b/app/admin/controller/setting/Market.php
new file mode 100644
index 0000000..c339182
--- /dev/null
+++ b/app/admin/controller/setting/Market.php
@@ -0,0 +1,46 @@
+index();
+ return json($result);
+ }
+
+ public function add()
+ {
+ $service = new MarketService();
+ $result = $service->add($this->request->param());
+ return json($result);
+ }
+
+ public function detail()
+ {
+ $service = new MarketService();
+ $result = $service->detail($this->request->param());
+ return json($result);
+ }
+
+ public function edit()
+ {
+ $service = new MarketService();
+ $result = $service->edit($this->request->param());
+ return json($result);
+ }
+
+
+ public function del()
+ {
+ $service = new MarketService();
+ $result = $service->del($this->request->param());
+ return json($result);
+ }
+}
\ No newline at end of file
diff --git a/app/admin/controller/setting/Option.php b/app/admin/controller/setting/Option.php
new file mode 100644
index 0000000..eae5587
--- /dev/null
+++ b/app/admin/controller/setting/Option.php
@@ -0,0 +1,63 @@
+index($this->request->param());
+ return json($result);
+ }
+
+ public function addIn()
+ {
+ $service = new OptionInService();
+ $result = $service->add($this->request->param());
+ return json($result);
+ }
+
+
+ public function editIn()
+ {
+ $service = new OptionInService();
+ $result = $service->edit($this->request->param());
+ return json($result);
+ }
+
+ public function getTradeNameListIn()
+ {
+ $service = new OptionInService();
+ $result = $service->getTradeNameList();
+ return json($result);
+ }
+
+ public function onOffIn()
+ {
+ $service = new OptionInService();
+ $result = $service->onOff($this->request->param());
+ return json($result);
+ }
+
+ public function batchEditIn()
+ {
+ $service = new OptionInService();
+ $result = $service->batchEdit($this->request->param());
+ return json($result);
+ }
+
+ /*********************************印度期权*********************************/
+
+ public function refresh()
+ {
+ $result = (new OptionInService())->refresh();
+ return json([]);
+ }
+}
\ No newline at end of file
diff --git a/app/admin/controller/setting/Payment.php b/app/admin/controller/setting/Payment.php
new file mode 100644
index 0000000..171e302
--- /dev/null
+++ b/app/admin/controller/setting/Payment.php
@@ -0,0 +1,46 @@
+index($this->request->param());
+ return json($result);
+ }
+
+ public function add()
+ {
+ $service = new PaymentService();
+ $result = $service->add($this->request->param());
+ return json($result);
+ }
+
+
+ public function edit()
+ {
+ $service = new PaymentService();
+ $result = $service->edit($this->request->param());
+ return json($result);
+ }
+ public function info()
+ {
+ $service = new PaymentService();
+ $result = $service->info($this->request->param());
+ return json($result);
+ }
+ public function del()
+ {
+ $service = new PaymentService();
+ $result = $service->del($this->request->param());
+ return json($result);
+ }
+
+}
\ No newline at end of file
diff --git a/app/admin/controller/setting/PreFundStock.php b/app/admin/controller/setting/PreFundStock.php
new file mode 100644
index 0000000..82b80aa
--- /dev/null
+++ b/app/admin/controller/setting/PreFundStock.php
@@ -0,0 +1,91 @@
+index($this->request->param());
+ return json($result);
+ }
+
+
+ // 获取历史走势
+ public function history()
+ {
+ $service = new PreFundStockService();
+ $result = $service->history($this->request->param());
+ return json($result);
+ }
+
+
+ // 新增
+ public function add()
+ {
+ $service = new PreFundStockService();
+ $result = $service->add($this->request->param());
+ return json($result);
+ }
+
+
+ // 编辑
+ public function edit()
+ {
+ $service = new PreFundStockService();
+ $result = $service->edit($this->request->param());
+ return json($result);
+ }
+
+
+ // 上市
+ public function open()
+ {
+ $service = new PreFundStockService();
+ $result = $service->open($this->request->param());
+ return json($result);
+ }
+
+
+ // 退市
+ public function close()
+ {
+ $service = new PreFundStockService();
+ $result = $service->close($this->request->param());
+ return json($result);
+ }
+
+ // 编辑
+ public function del()
+ {
+ $service = new PreFundStockService();
+ $result = $service->del($this->request->param());
+ return json($result);
+ }
+
+ // 返息-定时任务
+ public function interest()
+ {
+ $service = new PreFundStockService();
+ $service->interest();
+ }
+
+ public function referStockAdd(){
+ $service = new PreFundStockService();
+ $result = $service->referStockAdd($this->request->param());
+ return json($result);
+ }
+
+ public function referStockDel(){
+ $service = new PreFundStockService();
+ $result = $service->referStockDel($this->request->param());
+ return json($result);
+ }
+}
\ No newline at end of file
diff --git a/app/admin/controller/setting/PreStock.php b/app/admin/controller/setting/PreStock.php
new file mode 100644
index 0000000..30d56d4
--- /dev/null
+++ b/app/admin/controller/setting/PreStock.php
@@ -0,0 +1,59 @@
+request->param('market_type'));
+ $result= (new IPOService())->stockIPOList($market_type,$this->request->param(),$this->getAdminId());
+ return json($result);
+ }
+ // 新增
+ public function add()
+ {
+ $market_type=intval($this->request->param('market_type'));
+ $result = (new IPOService())->addStockIPO($market_type,$this->request->param());
+ return json($result);
+ }
+ // 编辑
+ public function edit()
+ {
+ $market_type=intval($this->request->param('market_type'));
+ $result = (new IPOService())->editStockIPO($market_type,$this->request->param());
+ return json($result);
+ }
+ // 上市
+ public function open()
+ {
+ $market_type=intval($this->request->param('market_type'));
+ $result = (new IPOService())->stockIPO($market_type,$this->request->param());
+ return json($result);
+ }
+ public function note(){
+ $service = new IPOService();
+ $market_type=intval($this->request->param('market_type'));
+ $result = $service->repeatNoteGo($market_type,$this->request->param());
+ return json($result);
+ }
+ public function cancel(){
+ $market_type=intval($this->request->param('market_type'));
+ $result = (new IPOService())->cancelIPO($market_type,$this->request->param());
+ return json($result);
+ }
+
+ // 删除
+ public function del()
+ {
+ $market_type=intval($this->request->param('market_type'));
+ $result = (new IPOService())->delStockIPO($market_type,$this->request->param());
+ return json($result);
+ }
+}
\ No newline at end of file
diff --git a/app/admin/controller/setting/Service.php b/app/admin/controller/setting/Service.php
new file mode 100644
index 0000000..efb2561
--- /dev/null
+++ b/app/admin/controller/setting/Service.php
@@ -0,0 +1,39 @@
+index();
+ return json($result);
+ }
+
+ public function add()
+ {
+ $service = new ServiceService();
+ $result = $service->add($this->request->param());
+ return json($result);
+ }
+
+ public function edit()
+ {
+ $service = new ServiceService();
+ $result = $service->edit($this->request->param());
+ return json($result);
+ }
+
+ public function del()
+ {
+ $service = new ServiceService();
+ $result = $service->del($this->request->param());
+ return json($result);
+ }
+}
\ No newline at end of file
diff --git a/app/admin/controller/setting/Stock.php b/app/admin/controller/setting/Stock.php
new file mode 100644
index 0000000..be0770f
--- /dev/null
+++ b/app/admin/controller/setting/Stock.php
@@ -0,0 +1,41 @@
+request->param('market_type');
+ $result = (new IPOService())->stockList($market_type,$this->request->param());
+ return json($result);
+ }
+
+ public function add()
+ {
+ $market_type=$this->request->param('market_type');
+ $result = (new IPOService())->addStock($market_type,$this->request->param());
+ return json($result);
+ }
+
+
+ public function edit()
+ {
+ $market_type=$this->request->param('market_type');
+ $result = (new IPOService())->editStock($market_type,$this->request->param());
+ return json($result);
+ }
+
+ public function getTradeNameList()
+ {
+ $market_type=$this->request->param('market_type');
+ $result = (new IPOService())->getTradeNameList($market_type);
+ return json($result);
+ }
+}
\ No newline at end of file
diff --git a/app/admin/controller/setting/StockIndex.php b/app/admin/controller/setting/StockIndex.php
new file mode 100644
index 0000000..05e93a1
--- /dev/null
+++ b/app/admin/controller/setting/StockIndex.php
@@ -0,0 +1,25 @@
+index();
+ return json($result);
+ }
+
+ public function update()
+ {
+ $result = (new StockIndexService())->update($this->request->param());
+ return json($result);
+ }
+}
\ No newline at end of file
diff --git a/app/admin/controller/setting/StockMarket.php b/app/admin/controller/setting/StockMarket.php
new file mode 100644
index 0000000..bbfed3e
--- /dev/null
+++ b/app/admin/controller/setting/StockMarket.php
@@ -0,0 +1,40 @@
+index();
+ return json($result);
+ }
+
+ public function add()
+ {
+ $service = new StockMarketService();
+ $result = $service->add($this->request->param());
+ return json($result);
+ }
+
+ public function edit()
+ {
+ $service = new StockMarketService();
+ $result = $service->edit($this->request->param());
+ return json($result);
+ }
+
+ // 股票筛选 根据股票号 股票市场 模糊搜索股票数据
+ public function searchStock()
+ {
+ $service = new StockMarketService();
+ $result = $service->searchStock($this->request->param());
+ return json($result);
+ }
+}
\ No newline at end of file
diff --git a/app/admin/controller/setting/StockPrice.php b/app/admin/controller/setting/StockPrice.php
new file mode 100644
index 0000000..765646c
--- /dev/null
+++ b/app/admin/controller/setting/StockPrice.php
@@ -0,0 +1,42 @@
+index($this->request->param());
+ return json($result);
+ }
+
+ // 新增
+ public function add()
+ {
+ $service = new StockPriceSettingService();
+ $result = $service->add($this->request->param());
+ return json($result);
+ }
+
+ // 编辑
+ public function edit()
+ {
+ $service = new StockPriceSettingService();
+ $result = $service->edit($this->request->param());
+ return json($result);
+ }
+
+ public function del()
+ {
+ $service = new StockPriceSettingService();
+ $result = $service->del($this->request->param());
+ return json($result);
+ }
+}
\ No newline at end of file
diff --git a/app/admin/middleware/AdminLog.php b/app/admin/middleware/AdminLog.php
new file mode 100644
index 0000000..1f2edb6
--- /dev/null
+++ b/app/admin/middleware/AdminLog.php
@@ -0,0 +1,54 @@
+user_id;
+ $pathInfo = $request->pathinfo();
+ $host = $request->server("HTTP_HOST");
+ $uri = $request->server("REQUEST_URI");
+ $ua = $request->server("HTTP_USER_AGENT");
+ $ip = $request->ip();
+
+ //request参数 url上参数
+ $requestData = $request->request();
+
+ //body请求参数
+ $param = $request->param();
+
+ //放入数组
+ $content = [
+ "admin_id" => $adminId,
+ "host" => $host,
+ "uri" => $uri,
+ "ua" => $ua,
+ "ip" => $ip,
+ "request_param" => json_encode($requestData),
+ "body_param" => json_encode($param),
+ "path_info" => '/' . $pathInfo,
+ "create_date" => date("Y-m-d"),
+ "create_time" => date("Y-m-d H:i:s")
+ ];
+
+ //log
+ $log = new BusinessLog();
+ $log->log($content);
+
+ //返回
+ return $next($request);
+ }
+}
diff --git a/app/admin/middleware/Check.php b/app/admin/middleware/Check.php
new file mode 100644
index 0000000..a634962
--- /dev/null
+++ b/app/admin/middleware/Check.php
@@ -0,0 +1,22 @@
+header('Authorization');
+// print_r($token);
+// die();
+ //jwt进行校验token
+ $res = (new Jwt())->chekToken($token);
+ if ($res['code'] != 1 ){
+ return json(['code' => 401, 'message' => $res['msg'],'data' => $res]);
+ }
+ $request->user_id = $res['data']->user_id;
+ return $next($request);
+ }
+}
\ No newline at end of file
diff --git a/app/admin/route/app.php b/app/admin/route/app.php
new file mode 100644
index 0000000..5448570
--- /dev/null
+++ b/app/admin/route/app.php
@@ -0,0 +1,616 @@
+ 'true',
+ 'Access-Control-Max-Age' => 1800,
+ 'Access-Control-Allow-Methods' => 'GET, POST, PATCH, PUT, DELETE, OPTIONS',
+ 'Access-Control-Allow-Headers' => 'Authorization, Content-Type, If-Match, If-Modified-Since, If-None-Match, If-Unmodified-Since, X-CSRF-TOKEN, X-Requested-With,Token,Language,X-token,IgnoreCancelToken',
+];
+
+
+// 需要登陆的接口 使用中间件校验 请求路径 XwkjlLbDcG/test
+Route::get('/test', 'Test/index');
+Route::group('/', function () {
+ // 上传图片
+ Route::post('/upload', 'Upload/upload');
+ // 国家和地区
+ Route::post('/country', 'Country/getAll');
+ // 配置
+ Route::post('/set_config', 'Config/setConfig');
+ Route::post('/get_config', 'Config/getConfig');
+
+ // 首页数据
+ Route::post('/index', 'Index/index');
+
+ // 现货订单
+ Route::post('/order/digital_place', 'Order/digitalPlace');
+ Route::post('/order/digital_back', 'Order/digitalBack');
+ Route::post('/order/digital_deal', 'Order/digitalDeal');
+
+
+ // 合约订单
+ Route::post('/order/contract_hold', 'Order/contractHold');
+ Route::post('/order/contract_place', 'Order/contractPlace');
+ Route::post('/order/contract_back', 'Order/contractBack');
+ Route::post('/order/contract_clear', 'Order/contractClear');
+ // 秒合约订单
+ Route::post('/order/contract_sec_hold', 'Order/contractSecHold');
+ Route::post('/order/contract_sec_place', 'Order/contractSecPlace');
+ Route::post('/order/contract_sec_back', 'Order/contractSecBack');
+ Route::post('/order/contract_sec_clear', 'Order/contractSecClear');
+
+
+ // 外汇订单
+ Route::post('/order/forex_hold', 'Order/forexHold');
+ Route::post('/order/forex_place', 'Order/forexPlace');
+ Route::post('/order/forex_back', 'Order/forexBack');
+ Route::post('/order/forex_clear', 'Order/forexClear');
+
+
+ // 股票-废弃
+// Route::post('/order/stock_hold', 'Order/stockHold');
+// Route::post('/order/stock_place', 'Order/stockPlace');
+// Route::post('/order/stock_back', 'Order/stockBack');
+// Route::post('/order/stock_clear', 'Order/stockClear');
+
+ // 美股
+ Route::post('/order/us_stock_hold', 'Order/StockHold')->append(['market_type' =>3]);
+ Route::post('/order/us_stock_place', 'Order/StockPlace')->append(['market_type' =>3]);
+ Route::post('/order/us_stock_back', 'Order/StockBack')->append(['market_type' =>3]);
+ Route::post('/order/us_stock_clear', 'Order/StockClear')->append(['market_type' =>3]);
+
+ // 印尼股票
+ Route::post('/order/idn_stock_hold', 'Order/StockHold')->append(['market_type' =>4]);
+ Route::post('/order/idn_stock_place', 'Order/StockPlace')->append(['market_type' =>4]);
+ Route::post('/order/idn_stock_back', 'Order/StockBack')->append(['market_type' =>4]);
+ Route::post('/order/idn_stock_clear', 'Order/StockClear')->append(['market_type' =>4]);
+
+ // 马来西亚股票
+ Route::post('/order/mys_stock_hold', 'Order/StockHold')->append(['market_type' =>5]);
+ Route::post('/order/mys_stock_place', 'Order/StockPlace')->append(['market_type' =>5]);
+ Route::post('/order/mys_stock_back', 'Order/StockBack')->append(['market_type' =>5]);
+ Route::post('/order/mys_stock_clear', 'Order/StockClear')->append(['market_type' =>5]);
+
+ // 泰国股票
+ Route::post('/order/tha_stock_hold', 'Order/StockHold')->append(['market_type' =>6]);
+ Route::post('/order/tha_stock_place', 'Order/StockPlace')->append(['market_type' =>6]);
+ Route::post('/order/tha_stock_back', 'Order/StockBack')->append(['market_type' =>6]);
+ Route::post('/order/tha_stock_clear', 'Order/StockClear')->append(['market_type' =>6]);
+
+ // 印度股票
+ Route::post('/order/in_stock_hold', 'Order/StockHold')->append(['market_type' =>7]);
+ Route::post('/order/in_stock_place', 'Order/stockPlace')->append(['market_type' =>7]);
+ Route::post('/order/in_stock_back', 'Order/stockBack')->append(['market_type' =>7]);
+ Route::post('/order/in_stock_clear', 'Order/stockClear')->append(['market_type' =>7]);
+
+
+ // 新加坡股票
+ Route::post('/order/sgd_stock_hold', 'Order/StockHold')->append(['market_type' =>9]);
+ Route::post('/order/sgd_stock_place', 'Order/stockPlace')->append(['market_type' =>9]);
+ Route::post('/order/sgd_stock_back', 'Order/stockBack')->append(['market_type' =>9]);
+ Route::post('/order/sgd_stock_clear', 'Order/stockClear')->append(['market_type' =>9]);
+
+ // 香港股票
+ Route::post('/order/hk_stock_hold', 'Order/StockHold')->append(['market_type' =>12]);
+ Route::post('/order/hk_stock_place', 'Order/stockPlace')->append(['market_type' =>12]);
+ Route::post('/order/hk_stock_back', 'Order/stockBack')->append(['market_type' =>12]);
+ Route::post('/order/hk_stock_clear', 'Order/stockClear')->append(['market_type' =>12]);
+ // 英国股票
+ Route::post('/order/uk_stock_hold', 'Order/StockHold')->append(['market_type' =>14]); // 股票持仓
+ Route::post('/order/uk_stock_place', 'Order/StockPlace')->append(['market_type' =>14]); // 股票挂单
+ Route::post('/order/uk_stock_back', 'Order/StockBack')->append(['market_type' =>14]); // 股票撤单
+ Route::post('/order/uk_stock_clear', 'Order/StockClear')->append(['market_type' =>14]); // 股票平仓
+ // 法国股票
+ Route::post('/order/fur_stock_hold', 'Order/StockHold')->append(['market_type' =>15]); // 股票持仓
+ Route::post('/order/fur_stock_place', 'Order/StockPlace')->append(['market_type' =>15]); // 股票挂单
+ Route::post('/order/fur_stock_back', 'Order/StockBack')->append(['market_type' =>15]); // 股票撤单
+ Route::post('/order/fur_stock_clear', 'Order/StockClear')->append(['market_type' =>15]); // 股票平仓
+ // 德国股票
+ Route::post('/order/eur_stock_hold', 'Order/StockHold')->append(['market_type' =>16]); // 股票持仓
+ Route::post('/order/eur_stock_place', 'Order/StockPlace')->append(['market_type' =>16]); // 股票挂单
+ Route::post('/order/eur_stock_back', 'Order/StockBack')->append(['market_type' =>16]); // 股票撤单
+ Route::post('/order/eur_stock_clear', 'Order/StockClear')->append(['market_type' =>16]); // 股票平仓
+ // 巴西股票
+ Route::post('/order/eur_stock_hold', 'Order/StockHold')->append(['market_type' =>17]); // 股票持仓
+ Route::post('/order/eur_stock_place', 'Order/StockPlace')->append(['market_type' =>17]); // 股票挂单
+ Route::post('/order/eur_stock_back', 'Order/StockBack')->append(['market_type' =>17]); // 股票撤单
+ Route::post('/order/eur_stock_clear', 'Order/StockClear')->append(['market_type' =>17]); // 股票平仓
+ // 巴西股票
+ Route::post('/order/jp_stock_hold', 'Order/StockHold')->append(['market_type' =>18]); // 股票持仓
+ Route::post('/order/jp_stock_place', 'Order/StockPlace')->append(['market_type' =>18]); // 股票挂单
+ Route::post('/order/jp_stock_back', 'Order/StockBack')->append(['market_type' =>18]); // 股票撤单
+ Route::post('/order/jp_stock_clear', 'Order/StockClear')->append(['market_type' =>18]); // 股票平仓
+
+ // 印度期权
+ Route::post('/order/in_option_hold', 'Order/inOptionHold'); // 股票持仓
+ Route::post('/order/in_option_place', 'Order/inOptionPlace'); // 股票挂单
+ Route::post('/order/in_option_back', 'Order/inOptionBack'); // 股票撤单
+ Route::post('/order/in_option_clear', 'Order/inOptionClear'); // 股票平仓
+
+ // 申购订单
+ Route::post('/order/pre_stock_order', 'Order/preStock');
+ Route::post('/order/update_order_num', 'Order/updateGetNum')->middleware('admin_log'); // 修改中签数
+ Route::post('/order/pre_refund', 'Order/preRefund')->middleware('admin_log'); // ipo订单退款
+
+ //基金订单
+ Route::post('/order/fund_order', 'Order/fund');
+ Route::post('/order/fund_order_info', 'Order/fundInfo');
+ Route::post('/order/fund_interest_list', 'Order/fundInterestList');
+
+ //大宗交易订单
+ Route::post('/order/block_order', 'Order/block');
+
+ // 代理管理
+ Route::post('/agent/index', 'Agent/index');
+ Route::post('/agent/user', 'Agent/user');
+ Route::post('/agent/manager', 'Agent/manager');
+
+ // 用户管理
+ Route::post('/user/index', 'User/index');
+ Route::post('/user/status', 'User/status');
+ Route::post('/user/change', 'User/change')->middleware('admin_log');
+ Route::post('/user/relation', 'User/relation');
+ Route::post('/user/reg_phone', 'User/reg_phone')->middleware('admin_log');
+ Route::post('/user/reg_email', 'User/reg_email')->middleware('admin_log');
+ Route::post('/user/bank', 'User/bankDetail');
+ Route::post('/user/edit_bank', 'User/editBank')->middleware('admin_log');
+ Route::post('/user/edit_password', 'User/editPassword')->middleware('admin_log');
+ //送股
+ Route::post('/user/give_stock', 'setting.GiveStock/add')->middleware('admin_log');
+ Route::post('/user/give_stock_list', 'setting.GiveStock/index');
+
+ // 配置管理
+ // 合约插针行情
+ Route::post('/setting/hq_index', 'setting.Hq/index');
+ Route::post('/setting/hq_add', 'setting.Hq/add');
+ Route::post('/setting/hq_edit', 'setting.Hq/edit');
+ Route::post('/setting/hq_del', 'setting.Hq/del');
+
+ // 合约自发行情
+ Route::post('/setting/market_index', 'setting.Market/index');
+ Route::post('/setting/market_add', 'setting.Market/add');
+ Route::post('/setting/market_detail', 'setting.Market/detail');
+ Route::post('/setting/market_edit', 'setting.Market/edit');
+ Route::post('/setting/market_del', 'setting.Market/del');
+
+ // 现货行情
+ Route::post('/setting/d_market_index', 'setting.DMarket/index');
+ Route::post('/setting/d_market_add', 'setting.DMarket/add');
+ Route::post('/setting/d_market_detail', 'setting.DMarket/detail');
+ Route::post('/setting/d_market_edit', 'setting.DMarket/edit');
+ Route::post('/setting/d_market_del', 'setting.DMarket/del');
+
+ // 返佣配置
+ Route::post('/setting/brokerage_index', 'setting.Brokerage/index');
+ Route::post('/setting/brokerage_add', 'setting.Brokerage/add')->middleware('admin_log');
+ Route::post('/setting/brokerage_edit', 'setting.Brokerage/edit')->middleware('admin_log');
+
+ // 交易手续费
+ Route::post('/setting/fee_index', 'setting.Fee/index');
+ Route::post('/setting/fee_add', 'setting.Fee/add')->middleware('admin_log');
+ Route::post('/setting/fee_edit', 'setting.Fee/edit')->middleware('admin_log');
+
+ // 提现手续费
+ Route::post('/setting/drawal_index', 'setting.Drawal/index');
+ Route::post('/setting/drawal_edit', 'setting.Drawal/edit')->middleware('admin_log');
+
+ // 多语言
+ Route::post('/setting/lang_index', 'setting.Language/index');
+ Route::post('/setting/lang_add', 'setting.Language/add');
+ Route::post('/setting/lang_edit', 'setting.Language/edit');
+ Route::post('/setting/lang_del', 'setting.Language/del');
+ Route::post('/setting/lang_select', 'setting.Language/getNameList');
+
+ // 客服
+ Route::post('/setting/service_index', 'setting.Service/index');
+ Route::post('/setting/service_add', 'setting.Service/add');
+ Route::post('/setting/service_edit', 'setting.Service/edit');
+ Route::post('/setting/service_del', 'setting.Service/del');
+
+ // 现货交易对
+ Route::post('/setting/digital_index', 'setting.Digital/index');
+ Route::post('/setting/digital_add', 'setting.Digital/add')->middleware('admin_log');
+ Route::post('/setting/digital_edit', 'setting.Digital/edit')->middleware('admin_log');
+ Route::post('/setting/digital_select', 'setting.Digital/getTradeNameList');
+
+ // 美股股票交易对
+ Route::post('/setting/us_stock_index', 'setting.Stock/index')->append(['market_type' =>3]);
+ Route::post('/setting/us_stock_add', 'setting.Stock/add')->append(['market_type' =>3])->middleware('admin_log');
+ Route::post('/setting/us_stock_edit', 'setting.Stock/edit')->append(['market_type' =>3])->middleware('admin_log');
+ Route::post('/setting/us_stock_select', 'setting.Stock/getTradeNameList')->append(['market_type' =>3]);
+ // 印尼股股票交易对
+ Route::post('/setting/idn_stock_index', 'setting.Stock/index')->append(['market_type' =>4]);
+ Route::post('/setting/idn_stock_add', 'setting.Stock/add')->append(['market_type' =>4])->middleware('admin_log');
+ Route::post('/setting/idn_stock_edit', 'setting.Stock/edit')->append(['market_type' =>4])->middleware('admin_log');
+ Route::post('/setting/idn_stock_select', 'setting.Stock/getTradeNameList')->append(['market_type' =>4]);
+ // 马股股票交易对
+ Route::post('/setting/mys_stock_index', 'setting.Stock/index')->append(['market_type' =>5]);
+ Route::post('/setting/mys_stock_add', 'setting.Stock/add')->append(['market_type' =>5])->middleware('admin_log');
+ Route::post('/setting/mys_stock_edit', 'setting.Stock/edit')->append(['market_type' =>5])->middleware('admin_log');
+ Route::post('/setting/mys_stock_select', 'setting.Stock/getTradeNameList')->append(['market_type' =>5]);
+ // 泰股股票交易对
+ Route::post('/setting/tha_stock_index', 'setting.Stock/index')->append(['market_type' =>6]);
+ Route::post('/setting/tha_stock_add', 'setting.Stock/add')->append(['market_type' =>6])->middleware('admin_log');
+ Route::post('/setting/tha_stock_edit', 'setting.Stock/edit')->append(['market_type' =>6])->middleware('admin_log');
+ Route::post('/setting/tha_stock_select', 'setting.Stock/getTradeNameList')->append(['market_type' =>6]);
+ // 印度股票交易对
+ Route::post('/setting/in_stock_index', 'setting.Stock/index')->append(['market_type' =>7]);
+ Route::post('/setting/in_stock_add', 'setting.Stock/add')->append(['market_type' =>7])->middleware('admin_log');
+ Route::post('/setting/in_stock_edit', 'setting.Stock/edit')->append(['market_type' =>7])->middleware('admin_log');
+ Route::post('/setting/in_stock_select', 'setting.Stock/getTradeNameList')->append(['market_type' =>7]);
+ // 新加坡股票交易对
+ Route::post('/setting/sgd_stock_index', 'setting.Stock/index')->append(['market_type' =>9]);
+ Route::post('/setting/sgd_stock_add', 'setting.Stock/add')->append(['market_type' =>9])->middleware('admin_log');
+ Route::post('/setting/sgd_stock_edit', 'setting.Stock/edit')->append(['market_type' =>9])->middleware('admin_log');
+ Route::post('/setting/sgd_stock_select', 'setting.Stock/getTradeNameList')->append(['market_type' =>9]);
+ // 香港股票交易对
+ Route::post('/setting/hk_stock_index', 'setting.Stock/index')->append(['market_type' =>12]);
+ Route::post('/setting/hk_stock_add', 'setting.Stock/add')->append(['market_type' =>12])->middleware('admin_log');
+ Route::post('/setting/hk_stock_edit', 'setting.Stock/edit')->append(['market_type' =>12])->middleware('admin_log');
+ Route::post('/setting/hk_stock_select', 'setting.Stock/getTradeNameList')->append(['market_type' =>12]);
+ // 英国股票交易对
+ Route::post('/setting/uk_stock_index', 'setting.Stock/index')->append(['market_type' =>14]);
+ Route::post('/setting/uk_stock_add', 'setting.Stock/add')->append(['market_type' =>14])->middleware('admin_log');
+ Route::post('/setting/uk_stock_edit', 'setting.Stock/edit')->append(['market_type' =>14])->middleware('admin_log');
+ Route::post('/setting/uk_stock_select', 'setting.Stock/getTradeNameList')->append(['market_type' =>14]);
+
+ Route::post('/setting/fur_stock_index', 'setting.Stock/index')->append(['market_type' =>15]);
+ Route::post('/setting/fur_stock_add', 'setting.Stock/add')->append(['market_type' =>15])->middleware('admin_log');
+ Route::post('/setting/fur_stock_edit', 'setting.Stock/edit')->append(['market_type' =>15])->middleware('admin_log');
+ Route::post('/setting/fur_stock_select', 'setting.Stock/getTradeNameList')->append(['market_type' =>15]);
+
+ Route::post('/setting/eur_stock_index', 'setting.Stock/index')->append(['market_type' =>16]);
+ Route::post('/setting/eur_stock_add', 'setting.Stock/add')->append(['market_type' =>16])->middleware('admin_log');
+ Route::post('/setting/eur_stock_edit', 'setting.Stock/edit')->append(['market_type' =>16])->middleware('admin_log');
+ Route::post('/setting/eur_stock_select', 'setting.Stock/getTradeNameList')->append(['market_type' =>16]);
+
+ Route::post('/setting/brl_stock_index', 'setting.Stock/index')->append(['market_type' =>17]);
+ Route::post('/setting/brl_stock_add', 'setting.Stock/add')->append(['market_type' =>17])->middleware('admin_log');
+ Route::post('/setting/brl_stock_edit', 'setting.Stock/edit')->append(['market_type' =>17])->middleware('admin_log');
+ Route::post('/setting/brl_stock_select', 'setting.Stock/getTradeNameList')->append(['market_type' =>17]);
+
+ Route::post('/setting/jp_stock_index', 'setting.Stock/index')->append(['market_type' =>18]);
+ Route::post('/setting/jp_stock_add', 'setting.Stock/add')->append(['market_type' =>18])->middleware('admin_log');
+ Route::post('/setting/jp_stock_edit', 'setting.Stock/edit')->append(['market_type' =>18])->middleware('admin_log');
+ Route::post('/setting/jp_stock_select', 'setting.Stock/getTradeNameList')->append(['market_type' =>18]);
+
+ //外汇
+ Route::post('/setting/forex_index', 'setting.Forex/index');
+ Route::post('/setting/forex_add', 'setting.Forex/add');
+ Route::post('/setting/forex_edit', 'setting.Forex/edit');
+ Route::post('/setting/forex_select', 'setting.Contract/getTradeNameList');
+
+
+ // 印度期权交易对
+ Route::post('/setting/in_option_index', 'setting.Option/indexIn');
+ Route::post('/setting/in_option_add', 'setting.Option/addIn');
+ Route::post('/setting/in_option_edit', 'setting.Option/editIn');
+ Route::post('/setting/in_option_select', 'setting.Option/getTradeNameListIn');
+ Route::post('/setting/in_option_on_off', 'setting.Option/onOffIn');
+ Route::post('/setting/in_batch_edit', 'setting.Option/batchEditIn');
+
+
+ // 股票市场
+ Route::post('/setting/stock_market_index', 'setting.StockMarket/index');
+ Route::post('/setting/stock_market_add', 'setting.StockMarket/add')->middleware('admin_log');
+ Route::post('/setting/stock_market_edit', 'setting.StockMarket/edit')->middleware('admin_log');
+ Route::post('/setting/market_stock_search', 'setting.StockMarket/searchStock');
+
+ // 合约交易对
+ Route::post('/setting/contract_index', 'setting.Contract/index');
+ Route::post('/setting/contract_add', 'setting.Contract/add');
+ Route::post('/setting/contract_edit', 'setting.Contract/edit');
+ Route::post('/setting/contract_select', 'setting.Contract/getTradeNameList');
+
+
+ // 合约交易对
+ Route::post('/setting/contract_setting', 'setting.Contract/setting');
+ Route::post('/setting/contract_set_add', 'setting.Contract/set_add');
+ Route::post('/setting/contract_set_edit', 'setting.Contract/set_edit');
+ Route::post('/setting/contract_set_del', 'setting.Contract/set_del');
+
+ // 合约时间收益
+ Route::post('/setting/contract_setting', 'setting.Contract/setting');
+ Route::post('/setting/contract_setting_add', 'setting.Contract/set_add');
+ Route::post('/setting/contract_setting_edit', 'setting.Contract/set_edit');
+ Route::post('/setting/contract_setting_del', 'setting.Contract/set_del');
+
+ // 股票价格设置
+ Route::post('/setting/stock_prices_index', 'setting.StockPrice/index');
+ Route::post('/setting/stock_prices_add', 'setting.StockPrice/add')->middleware('admin_log');
+ Route::post('/setting/stock_prices_edit', 'setting.StockPrice/edit')->middleware('admin_log');
+ Route::post('/setting/stock_prices_del', 'setting.StockPrice/del')->middleware('admin_log');
+
+ // 支付通道设置
+ Route::post('/setting/payment_list', 'setting.Payment/index');
+ Route::post('/setting/payment_add', 'setting.Payment/add')->middleware('admin_log');
+ Route::post('/setting/payment_edit', 'setting.Payment/edit')->middleware('admin_log');
+ Route::post('/setting/payment_del', 'setting.Payment/del')->middleware('admin_log');
+ Route::post('/setting/payment_info', 'setting.Payment/info');
+
+ // 美股新股设置
+ Route::post('/setting/pre_us_stock_index', 'setting.PreStock/index')->append(['market_type' =>3]);
+ Route::post('/setting/pre_us_stock_add', 'setting.PreStock/add')->append(['market_type' =>3])->middleware('admin_log');
+ Route::post('/setting/pre_us_stock_edit', 'setting.PreStock/edit')->append(['market_type' =>3])->middleware('admin_log');
+ Route::post('/setting/pre_us_stock_open', 'setting.PreStock/open')->append(['market_type' =>3])->middleware('admin_log');
+ Route::post('/setting/pre_us_stock_del', 'setting.PreStock/del')->append(['market_type' =>3])->middleware('admin_log');
+ Route::post('/setting/pre_us_stock_note', 'setting.PreStock/note')->append(['market_type' =>3])->middleware('admin_log');
+ Route::post('/setting/pre_us_stock_cancel', 'setting.PreStock/cancel')->append(['market_type' =>3])->middleware('admin_log');//取消IPO
+
+ // 印尼股新股设置
+ Route::post('/setting/pre_idn_stock_index', 'setting.PreStock/index')->append(['market_type' =>4]);
+ Route::post('/setting/pre_idn_stock_add', 'setting.PreStock/add')->append(['market_type' =>4])->middleware('admin_log');
+ Route::post('/setting/pre_idn_stock_edit', 'setting.PreStock/edit')->append(['market_type' =>4])->middleware('admin_log');
+ Route::post('/setting/pre_idn_stock_open', 'setting.PreStock/open')->append(['market_type' =>4])->middleware('admin_log');
+ Route::post('/setting/pre_idn_stock_del', 'setting.PreStock/del')->append(['market_type' =>4])->middleware('admin_log');
+ Route::post('/setting/pre_idn_stock_note', 'setting.PreStock/note')->append(['market_type' =>4])->middleware('admin_log');
+ Route::post('/setting/pre_idn_stock_cancel', 'setting.PreStock/cancel')->append(['market_type' =>4])->middleware('admin_log');
+
+ // 马来股新股设置
+ Route::post('/setting/pre_mys_stock_index', 'setting.PreStock/index')->append(['market_type' =>5]);
+ Route::post('/setting/pre_mys_stock_add', 'setting.PreStock/add')->append(['market_type' =>5])->middleware('admin_log');
+ Route::post('/setting/pre_mys_stock_edit', 'setting.PreStock/edit')->append(['market_type' =>5])->middleware('admin_log');
+ Route::post('/setting/pre_mys_stock_open', 'setting.PreStock/open')->append(['market_type' =>5])->middleware('admin_log');
+ Route::post('/setting/pre_mys_stock_del', 'setting.PreStock/del')->append(['market_type' =>5])->middleware('admin_log');
+ Route::post('/setting/pre_mys_stock_note', 'setting.PreStock/note')->append(['market_type' =>5])->middleware('admin_log');
+ Route::post('/setting/pre_mys_stock_cancel', 'setting.PreStock/cancel')->append(['market_type' =>5])->middleware('admin_log');
+
+ // 泰股新股设置
+ Route::post('/setting/pre_tha_stock_index', 'setting.PreStock/index')->append(['market_type' =>6]);
+ Route::post('/setting/pre_tha_stock_add', 'setting.PreStock/add')->append(['market_type' =>6])->middleware('admin_log');
+ Route::post('/setting/pre_tha_stock_edit', 'setting.PreStock/edit')->append(['market_type' =>6])->middleware('admin_log');
+ Route::post('/setting/pre_tha_stock_open', 'setting.PreStock/open')->append(['market_type' =>6])->middleware('admin_log');
+ Route::post('/setting/pre_tha_stock_del', 'setting.PreStock/del')->append(['market_type' =>6])->middleware('admin_log');
+ Route::post('/setting/pre_tha_stock_note', 'setting.PreStock/note')->append(['market_type' =>6])->middleware('admin_log');
+ Route::post('/setting/pre_tha_stock_cancel', 'setting.PreStock/cancel')->append(['market_type' =>6])->middleware('admin_log');
+
+ // 印度股新股设置
+ Route::post('/setting/pre_in_stock_index', 'setting.PreStock/index')->append(['market_type' =>7]);
+ Route::post('/setting/pre_in_stock_add', 'setting.PreStock/add')->append(['market_type' =>7])->middleware('admin_log');
+ Route::post('/setting/pre_in_stock_edit', 'setting.PreStock/edit')->append(['market_type' =>7])->middleware('admin_log');
+ Route::post('/setting/pre_in_stock_open', 'setting.PreStock/open')->append(['market_type' =>7])->middleware('admin_log');
+ Route::post('/setting/pre_in_stock_del', 'setting.PreStock/del')->append(['market_type' =>7])->middleware('admin_log');
+ Route::post('/setting/pre_in_stock_note', 'setting.PreStock/note')->append(['market_type' =>7])->middleware('admin_log');
+ Route::post('/setting/pre_in_stock_cancel', 'setting.PreStock/cancel')->append(['market_type' =>7])->middleware('admin_log');
+
+ // 新加坡股新股设置
+ Route::post('/setting/pre_sgd_stock_index', 'setting.PreStock/index')->append(['market_type' =>9]);
+ Route::post('/setting/pre_sgd_stock_add', 'setting.PreStock/add')->append(['market_type' =>9])->middleware('admin_log');
+ Route::post('/setting/pre_sgd_stock_edit', 'setting.PreStock/edit')->append(['market_type' =>9])->middleware('admin_log');
+ Route::post('/setting/pre_sgd_stock_open', 'setting.PreStock/open')->append(['market_type' =>9])->middleware('admin_log');
+ Route::post('/setting/pre_sgd_stock_del', 'setting.PreStock/del')->append(['market_type' =>9])->middleware('admin_log');
+ Route::post('/setting/pre_sgd_stock_note', 'setting.PreStock/note')->append(['market_type' =>9])->middleware('admin_log');
+ Route::post('/setting/pre_sgd_stock_cancel', 'setting.PreStock/cancel')->append(['market_type' =>9])->middleware('admin_log');
+
+ // 香港新股设置
+ Route::post('/setting/pre_hk_stock_index', 'setting.PreStock/index')->append(['market_type' =>12]);
+ Route::post('/setting/pre_hk_stock_add', 'setting.PreStock/add')->append(['market_type' =>12])->middleware('admin_log');
+ Route::post('/setting/pre_hk_stock_edit', 'setting.PreStock/edit')->append(['market_type' =>12])->middleware('admin_log');
+ Route::post('/setting/pre_hk_stock_open', 'setting.PreStock/open')->append(['market_type' =>12])->middleware('admin_log');
+ Route::post('/setting/pre_hk_stock_del', 'setting.PreStock/del')->append(['market_type' =>12])->middleware('admin_log');
+ Route::post('/setting/pre_hk_stock_note', 'setting.PreStock/note')->append(['market_type' =>12])->middleware('admin_log');
+ Route::post('/setting/pre_hk_stock_cancel', 'setting.PreStock/cancel')->append(['market_type' =>12])->middleware('admin_log');
+
+ // 英国新股设置
+ Route::post('/setting/pre_uk_stock_index', 'setting.PreStock/index')->append(['market_type' =>14]);
+ Route::post('/setting/pre_uk_stock_add', 'setting.PreStock/add')->append(['market_type' =>14])->middleware('admin_log');
+ Route::post('/setting/pre_uk_stock_edit', 'setting.PreStock/edit')->append(['market_type' =>14])->middleware('admin_log');
+ Route::post('/setting/pre_uk_stock_open', 'setting.PreStock/open')->append(['market_type' =>14])->middleware('admin_log');
+ Route::post('/setting/pre_uk_stock_del', 'setting.PreStock/del')->append(['market_type' =>14])->middleware('admin_log');
+ Route::post('/setting/pre_uk_stock_note', 'setting.PreStock/note')->append(['market_type' =>14])->middleware('admin_log');
+ Route::post('/setting/pre_uk_stock_cancel', 'setting.PreStock/cancel')->append(['market_type' =>14])->middleware('admin_log');
+
+ Route::post('/setting/pre_fur_stock_index', 'setting.PreStock/index')->append(['market_type' =>15]);
+ Route::post('/setting/pre_fur_stock_add', 'setting.PreStock/add')->append(['market_type' =>15])->middleware('admin_log');
+ Route::post('/setting/pre_fur_stock_edit', 'setting.PreStock/edit')->append(['market_type' =>15])->middleware('admin_log');
+ Route::post('/setting/pre_fur_stock_open', 'setting.PreStock/open')->append(['market_type' =>15])->middleware('admin_log');
+ Route::post('/setting/pre_fur_stock_del', 'setting.PreStock/del')->append(['market_type' =>15])->middleware('admin_log');
+ Route::post('/setting/pre_fur_stock_note', 'setting.PreStock/note')->append(['market_type' =>15])->middleware('admin_log');
+ Route::post('/setting/pre_fur_stock_cancel', 'setting.PreStock/cancel')->append(['market_type' =>15])->middleware('admin_log');
+
+ Route::post('/setting/pre_eur_stock_index', 'setting.PreStock/index')->append(['market_type' =>16]);
+ Route::post('/setting/pre_eur_stock_add', 'setting.PreStock/add')->append(['market_type' =>16])->middleware('admin_log');
+ Route::post('/setting/pre_eur_stock_edit', 'setting.PreStock/edit')->append(['market_type' =>16])->middleware('admin_log');
+ Route::post('/setting/pre_eur_stock_open', 'setting.PreStock/open')->append(['market_type' =>16])->middleware('admin_log');
+ Route::post('/setting/pre_eur_stock_del', 'setting.PreStock/del')->append(['market_type' =>16])->middleware('admin_log');
+ Route::post('/setting/pre_eur_stock_note', 'setting.PreStock/note')->append(['market_type' =>16])->middleware('admin_log');
+ Route::post('/setting/pre_eur_stock_cancel', 'setting.PreStock/cancel')->append(['market_type' =>16])->middleware('admin_log');
+
+ Route::post('/setting/pre_brl_stock_index', 'setting.PreStock/index')->append(['market_type' =>17]);
+ Route::post('/setting/pre_brl_stock_add', 'setting.PreStock/add')->append(['market_type' =>17])->middleware('admin_log');
+ Route::post('/setting/pre_brl_stock_edit', 'setting.PreStock/edit')->append(['market_type' =>17])->middleware('admin_log');
+ Route::post('/setting/pre_brl_stock_open', 'setting.PreStock/open')->append(['market_type' =>17])->middleware('admin_log');
+ Route::post('/setting/pre_brl_stock_del', 'setting.PreStock/del')->append(['market_type' =>17])->middleware('admin_log');
+ Route::post('/setting/pre_brl_stock_note', 'setting.PreStock/note')->append(['market_type' =>17])->middleware('admin_log');
+
+ Route::post('/setting/pre_jp_stock_index', 'setting.PreStock/index')->append(['market_type' =>18]);
+ Route::post('/setting/pre_jp_stock_add', 'setting.PreStock/add')->append(['market_type' =>18])->middleware('admin_log');
+ Route::post('/setting/pre_jp_stock_edit', 'setting.PreStock/edit')->append(['market_type' =>18])->middleware('admin_log');
+ Route::post('/setting/pre_jp_stock_open', 'setting.PreStock/open')->append(['market_type' =>18])->middleware('admin_log');
+ Route::post('/setting/pre_jp_stock_del', 'setting.PreStock/del')->append(['market_type' =>18])->middleware('admin_log');
+ Route::post('/setting/pre_jp_stock_note', 'setting.PreStock/note')->append(['market_type' =>18])->middleware('admin_log');
+
+ Route::post('/setting/pre_stock_cancel', 'setting.PreStock/cancel')->middleware('admin_log');
+
+ // 基金配置
+ Route::post('/setting/pre_fund_stock_index', 'setting.PreFundStock/index');
+ Route::post('/setting/pre_fund_stock_history', 'setting.PreFundStock/history');
+ Route::post('/setting/pre_fund_stock_add', 'setting.PreFundStock/add')->middleware('admin_log');
+ Route::post('/setting/pre_fund_stock_edit', 'setting.PreFundStock/edit')->middleware('admin_log');
+ Route::post('/setting/pre_fund_stock_open', 'setting.PreFundStock/open')->middleware('admin_log');
+ Route::post('/setting/pre_fund_stock_close', 'setting.PreFundStock/close')->middleware('admin_log');
+ Route::post('/setting/pre_fund_stock_del', 'setting.PreFundStock/del');
+
+ Route::post('/setting/refer_stock_add', 'setting.PreFundStock/referStockAdd');
+ Route::post('/setting/refer_stock_del', 'setting.PreFundStock/referStockDel');
+
+ //大宗交易配置
+ Route::post('/setting/block_stock_index', 'setting.BlockStock/index');
+ Route::post('/setting/block_stock_add', 'setting.BlockStock/add');
+ Route::post('/setting/block_stock_edit', 'setting.BlockStock/edit');
+
+
+ // 股票指数
+ Route::post('/setting/stock_index_list', 'setting.StockIndex/index');
+ Route::post('/setting/stock_index_update', 'setting.StockIndex/update');
+
+
+ // 资金管理
+ Route::post('/flow/digital', 'Flow/digital');
+ Route::post('/flow/stock', 'Flow/stock');
+ Route::post('/flow/contract', 'Flow/contract');
+ Route::post('/flow/transfer', 'Flow/transfer');
+ Route::post('/flow/fee', 'Flow/fee');
+ Route::post('/flow/brokerage', 'Flow/brokerage');
+
+ Route::post('/flow/us_stock', 'Flow/StockLogs')->append(['market_type' =>3]);
+ Route::post('/flow/idn_stock', 'Flow/StockLogs')->append(['market_type' =>4]);
+ Route::post('/flow/mys_stock', 'Flow/StockLogs')->append(['market_type' =>5]);
+ Route::post('/flow/tha_stock', 'Flow/StockLogs')->append(['market_type' =>6]);
+ Route::post('/flow/in_stock', 'Flow/StockLogs')->append(['market_type' =>7]);
+ Route::post('/flow/sgd_stock', 'Flow/StockLogs')->append(['market_type' =>9]);
+ Route::post('/flow/hk_stock', 'Flow/StockLogs')->append(['market_type' =>12]);
+ Route::post('/flow/uk_stock', 'Flow/StockLogs')->append(['market_type' =>14]);
+ Route::post('/flow/fur_stock', 'Flow/StockLogs')->append(['market_type' =>15]);
+ Route::post('/flow/eur_stock', 'Flow/StockLogs')->append(['market_type' =>16]);
+ Route::post('/flow/eur_stock', 'Flow/StockLogs')->append(['market_type' =>17]);
+ Route::post('/flow/jp_stock', 'Flow/StockLogs')->append(['market_type' =>18]);
+
+
+
+ Route::post('/flow/fund_stock', 'Flow/fundStock');
+
+ Route::post('/flow/in_option_stock', 'Flow/inOptionStock');
+ Route::post('/flow/block_stock', 'Flow/blockStock');
+
+
+ // 充值订单
+ Route::post('/recharge/index', 'Recharge/index'); // 充值订单
+ Route::post('/recharge/info', 'Recharge/info');
+ Route::post('/recharge/check', 'Recharge/check')->middleware('admin_log');
+
+ Route::post('/withdraw/index', 'Withdraw/index');
+ Route::post('/withdraw/info', 'Withdraw/info');
+ Route::post('/withdraw/change_status', 'Withdraw/change_status')->middleware('admin_log');
+ Route::post('/withdraw/get_balance', 'Withdraw/get_balance');
+ Route::post('/withdraw/channel_list', 'Withdraw/channel_list');
+
+ // 文档管理
+ // 首页文章
+ Route::post('/document/doc_index', 'document.Index/index');
+ Route::post('/document/doc_add', 'document.Index/add');
+ Route::post('/document/doc_detail', 'document.Index/detail');
+ Route::post('/document/doc_edit', 'document.Index/edit');
+ Route::post('/document/doc_del', 'document.Index/del');
+ // 公告管理
+ Route::post('/document/announcement_index', 'document.Announcement/index');
+ Route::post('/document/announcement_add', 'document.Announcement/add');
+ Route::post('/document/announcement_detail', 'document.Announcement/detail');
+ Route::post('/document/announcement_edit', 'document.Announcement/edit');
+ Route::post('/document/announcement_del', 'document.Announcement/del');
+ // FAQ
+ Route::post('/document/faq_index', 'document.Faq/index');
+ Route::post('/document/faq_add', 'document.Faq/add');
+ Route::post('/document/faq_detail', 'document.Faq/detail');
+ Route::post('/document/faq_edit', 'document.Faq/edit');
+ Route::post('/document/faq_del', 'document.Faq/del');
+ // banner
+ Route::post('/document/banner_index', 'document.Banner/index');
+ Route::post('/document/banner_add', 'document.Banner/add');
+ Route::post('/document/banner_detail', 'document.Banner/detail');
+ Route::post('/document/banner_edit', 'document.Banner/edit');
+ Route::post('/document/banner_del', 'document.Banner/del');
+
+
+ //用户中心
+ Route::post('/account/update_info', 'Admin/updateInfo');
+ Route::post('/account/add', 'Admin/addUser');
+ Route::get('/account/get_user_info', 'Admin/getUserInfo');
+ Route::post('/account/update_password', 'Admin/updatePassword');
+ Route::post('/account/update_status', 'Admin/updateAccountStauts');
+ Route::post('/account/list', 'Admin/getUserList');
+ Route::post('/account/del', 'Admin/del');
+ Route::get('/account/logout', 'Admin/logout');
+ Route::post('/account/update_account', 'Admin/updateAccount');
+ Route::get('/account/get_perm_code', 'Admin/getPermCode');
+
+ //权限菜单
+ Route::post('/auth/rule/add', 'auth.AuthRule/add');
+ Route::post('/auth/rule/edit', 'auth.AuthRule/edit');
+ Route::post('/auth/rule/list', 'auth.AuthRule/list');
+ Route::post('/auth/rule/all_list', 'auth.AuthRule/allList');
+ Route::post('/auth/rule/del', 'auth.AuthRule/del');
+ Route::get('/auth/rule/get_side_menu', 'auth.AuthRule/getSideMenu');
+ //权限角色
+ Route::post('/auth/role/add', 'auth.AuthRole/add');
+ Route::post('/auth/role/edit', 'auth.AuthRole/edit');
+ Route::post('/auth/role/list', 'auth.AuthRole/list');
+ Route::post('/auth/role/update_status', 'auth.AuthRole/updateStatus');
+ Route::post('/auth/role/all_list', 'auth.AuthRole/allList');
+ Route::post('/auth/role/del', 'auth.AuthRole/del');
+
+ // 实名认证操作
+ Route::post('/user/verify_detail', 'User/verifyDetail');
+ Route::post('/user/verify_do', 'User/verifyDo');
+ Route::post('/user/lever_review', 'User/leverReview');
+ Route::post('/user/reg_code', 'User/getRegCode');
+ Route::post('/user/auto_login', 'User/autoLogin');
+
+ //设置杠杆
+ Route::post('/user/get_leverage', 'User/getLeverageNum');
+ Route::post('/user/edit_leverage', 'User/editLeverageNum')->middleware('admin_log');
+
+ // 投票
+ Route::post('/vote/index', 'Vote/index');
+ Route::post('/vote/add', 'Vote/add');
+ Route::post('/vote/edit', 'Vote/edit');
+ Route::post('/vote/del', 'Vote/del');
+
+ // 用户验证码
+ Route::post('/user/get_user_code', 'User/getUserCode');
+})->allowCrossDomain($header)
+ ->middleware('admin_auth');
+
+
+Route::post('/admin/log', 'Admin/log')->allowCrossDomain($header)->middleware('admin_auth');
+
+//登陆
+Route::post('/login/login', 'Login/login')->allowCrossDomain($header);
+// 缓存股票数据
+Route::get('/cacheIdnStock', 'Index/cacheIdnStock');
+Route::get('/cacheUsStock', 'Index/cacheUsStock');
+Route::get('/cacheMysStock', 'Index/cacheMysStock');
+Route::get('/cacheThaStock', 'Index/cacheThaStock');
+Route::get('/cacheInStock', 'Index/cacheInStock');
+Route::get('/cacheSgdStock', 'Index/cacheSgdStock');
+Route::get('/cacheHkStock', 'Index/cacheHkStock');
+Route::get('/cacheGbxStock', 'Index/cacheGbxStock');
+Route::get('/cacheFurStock', 'Index/cacheFurStock');
+Route::get('/cacheEurStock', 'Index/cacheEurStock');
+Route::get('/cacheBrlStock', 'Index/cacheBrlStock');
+Route::get('/cacheJpStock', 'Index/cacheJpStock');
+
+
+Route::get('/cacheForex', 'Index/cacheForex');
+Route::get('/cacheInOption', 'Index/cacheInOption');
+Route::get('/invite_code', 'Admin/inviteCode');
+
+//Route::get('/cache_stock', 'Index/cacheStock');
+Route::get('/cache_redis', 'Index/cacheRedis');
+Route::get('/test_send', 'Index/sendToGo');
+
+Route::get('/sign_stock', 'Index/signStock');
+Route::post('/add_stock', 'Index/autoAddStock');
+
+Route::get('/deal_stock', 'Index/dealStock');
+
+// 定时任务 基金返息
+Route::get('/setting/fund_interest', 'setting.PreFundStock/interest');
+
+Route::get('/setting/in_option_refresh', 'setting.Option/refresh');
+
+// 修改 印度股-source
+Route::post('/update_source', 'Index/updateSource');
+
diff --git a/app/admin/service/AdminBaseService.php b/app/admin/service/AdminBaseService.php
new file mode 100644
index 0000000..996d94f
--- /dev/null
+++ b/app/admin/service/AdminBaseService.php
@@ -0,0 +1,762 @@
+connect($config['host'], $config['port'], 10);
+ } catch (\Exception $exception) {
+ echo 'redis连接失败';
+ }
+ if (!empty($config['password'])) {
+ $redis->auth($config['password']);
+ }
+
+ $redis->select($config['select']);
+ return $redis;
+ }
+
+
+ /**
+ * @param string $code // 状态码
+ * @param string $msg // 提示信息
+ * @param array $result // 返回结果
+ * @return array
+ */
+ public function toData(string $code = '', string $msg = '', array $result = []): array
+ {
+ return [
+ 'code' => $code,
+ 'message' => $msg,
+ 'data' => $result
+ ];
+ }
+
+ // 根据是否是代理 以及用户id 获取where条件
+ public function getWhereByIsAgentAndUserId($adminId, $where, $userId)
+ {
+ // 判断是否是代理
+ $isAgent = AdminModel::checkUserIsAgent($adminId);
+ // 不是代理
+ if (!$isAgent) {
+ if ($userId > 0) {
+ $where[] = ['user_id', '=', $userId];
+ }
+ return $where;
+ }
+
+ // 获取管理用户
+ $userIds = AdminModel::getUserIdsByAgentId($adminId);
+ if (empty($userIds)) {
+ return false;
+ }
+
+ // 如果用户搜索
+ if ($userId > 0) {
+ $where[] = ['user_id', 'in', $userIds];
+ $where[] = ['user_id', '=', $userId];
+ return $where;
+ }
+
+ // 没有用户搜索
+ $where[] = ['user_id', 'in', $userIds];
+ return $where;
+ }
+
+ // 校验admin_id 是否可以管理 userId
+ public function checkUserIdInAgent($adminId, $userId)
+ {
+ // 判断是否是代理
+ $isAgent = AdminModel::checkUserIsAgent($adminId);
+ // 不是代理
+ if (!$isAgent) {
+ return true;
+ }
+
+ $userIds = AdminModel::getUserIdsByAgentId($adminId);
+ if (in_array($userId, $userIds)) {
+ return true;
+ }
+
+ return false;
+
+ }
+
+
+ /**
+ * @param $user_id
+ * @param $account_type
+ * @param $change_usable_num
+ * @param $change_frozen_num
+ * @param $change_type 变动类型:1-充值,2-提现,3-买入,4-卖出,5-冻结,6-解冻,7-账户转出,8-账户转入 ,9-注册返佣,10-开仓返佣 ,11-平仓返佣,12-调账加钱 13-调账减钱 19-基金返息 20-IPO订单退款
+ */
+ public function updateUserAsset($user_id, $account_type, $change_type, $change_usable_num, $change_frozen_num = 0, $order_no = "", $change_log_admin_id = 0, $rate = 0)
+ {
+ $prefix = env('database.prefix');
+ $where['user_id'] = $user_id;
+ switch ($account_type) {
+ case 1:
+ $where['digital_id'] = 'USDT';
+ $table = $prefix . 'user_digital';
+ $log_table = $prefix . 'user_digital_log';
+ $log_data['digital_id'] = 'USDT';
+ break;
+ case 2:
+ $where['contract_id'] = 'USDT';
+ $table = $prefix . 'user_contract';
+ $log_table = $prefix . 'user_contract_log';
+ $log_data['contract_id'] = 'USDT';
+ break;
+ case 3:
+ $where['stock_id'] = 'USD';
+ $table = $prefix . 'user_stock';
+ $log_table = $prefix . 'user_stock_log';
+ $log_data['stock_id'] = 'USD';
+ break;
+ case 4:
+ $where['stock_id'] = 'IDR';
+ $table = $prefix . 'user_stock_idn';
+ $log_table = $prefix . 'user_stock_idn_log';
+ $log_data['stock_id'] = 'IDR';
+ break;
+ case 5:
+ $where['stock_id'] = 'MYR';
+ $table = $prefix . 'user_stock_mys';
+ $log_table = $prefix . 'user_stock_mys_log';
+ $log_data['stock_id'] = 'MYR';
+ break;
+ case 6:
+ $where['stock_id'] = 'THB';
+ $table = $prefix . 'user_stock_tha';
+ $log_table = $prefix . 'user_stock_tha_log';
+ $log_data['stock_id'] = 'THB';
+ break;
+ case 7:
+ $where['stock_id'] = 'INR';
+ $table = $prefix . 'user_stock_in';
+ $log_table = $prefix . 'user_stock_in_log';
+ $log_data['stock_id'] = 'INR';
+ break;
+ case 8:
+ $where['contract_id'] = 'USDT';
+ $table = $prefix . 'user_contract_sec';
+ $log_table = $prefix . 'user_contract_sec_log';
+ $log_data['contract_id'] = 'USDT';
+ break;
+ case 9:
+ $where['stock_id'] = 'SGD';
+ $table = $prefix . 'user_stock_sgd';
+ $log_table = $prefix . 'user_stock_sgd_log';
+ $log_data['stock_id'] = 'SGD';
+ break;
+ case 10:
+ $where['stock_id'] = 'USD';
+ $table = $prefix . 'user_stock_fund';
+ $log_table = $prefix . 'user_stock_fund_log';
+ $log_data['stock_id'] = 'USD';
+ break;
+ case 11:
+ $where['stock_id'] = 'INR';
+ $table = $prefix . 'user_stock_option_inr';
+ $log_table = $prefix . 'user_stock_option_inr_log';
+ $log_data['stock_id'] = 'INR';
+ break;
+ case 12:
+ $where['stock_id'] = 'HKD';
+ $table = $prefix . 'user_stock_hkd';
+ $log_table = $prefix . 'user_stock_hkd_log';
+ $log_data['stock_id'] = 'HKD';
+ break;
+ case 14:
+ $where['stock_id'] = 'GBX';
+ $table = $prefix . 'user_stock_gbx';
+ $log_table = $prefix . 'user_stock_gbx_log';
+ $log_data['stock_id'] = 'GBX';
+ break;
+ case 15:
+ $where['stock_id'] = 'EUR';
+ $table = $prefix . 'user_stock_fur';
+ $log_table = $prefix . 'user_stock_fur_log';
+ $log_data['stock_id'] = 'EUR';
+ break;
+ case 16:
+ $where['stock_id'] = 'EUR';
+ $table = $prefix . 'user_stock_eur';
+ $log_table = $prefix . 'user_stock_eur_log';
+ $log_data['stock_id'] = 'EUR';
+ break;
+ case 17:
+ $where['stock_id'] = 'BRL';
+ $table = $prefix . 'user_stock_brl';
+ $log_table = $prefix . 'user_stock_brl_log';
+ $log_data['stock_id'] = 'BRL';
+ break;
+ case 18:
+ $where['stock_id'] = 'JPY';
+ $table = $prefix . 'user_stock_jp';
+ $log_table = $prefix . 'user_stock_jp_log';
+ $log_data['stock_id'] = 'JPY';
+ break;
+ case 19:
+ $where['contract_id'] = 'USD';
+ $table = $prefix . 'user_forex';
+ $log_table = $prefix . 'user_forex_log';
+ $log_data['contract_id'] = 'USD';
+ break;
+ default:
+ return [
+ 'status' => 100,
+ 'msg' => '账户类型错误'
+ ];
+ break;
+ }
+ Db::startTrans();
+ try {
+ //user_stock USD
+ $account_info = Db::table($table)->where($where)->lock(true)->find();
+ if (empty($account_info)) {
+ $insert_data = [
+ 'user_id' => $user_id,
+ 'usable_num' => 0,
+ 'frozen_num' => 0,
+ 'create_time' => date('Y-m-d H:i:s'),
+ 'update_time' => date('Y-m-d H:i:s')
+ ];
+ if (in_array($account_type, [1, 2, 8])) {
+ $insert_data['contract_id'] = $where['contract_id'];
+ } else {
+ $insert_data['stock_id'] = $where['stock_id'];
+
+ }
+ // 不存在 则新增
+ Db::table($table)->insert($insert_data);
+
+ $account_info = Db::table($table)->where($where)->lock(true)->find();
+ if (empty($account_info)) {
+ Db::rollback();
+ return [
+ 'status' => 300,
+ 'msg' => '用户资金账号不存在'
+ ];
+ }
+
+ }
+
+ $last_usable_num = bcadd($account_info['usable_num'], $change_usable_num, 18);
+ $last_frozen_num = bcadd($account_info['frozen_num'], $change_frozen_num, 18);
+ if ($last_usable_num < 0) {
+ Db::rollback();
+ return [
+ 'status' => 400,
+ 'msg' => '可用资金不能为负'
+ ];
+ }
+
+ if ($change_type == 6) {
+ if ($last_frozen_num < 0 && abs($last_frozen_num) > 0.01) {
+ Db::rollback();
+ return [
+ 'status' => 400,
+ 'msg' => '冻结资金不能为负'
+ ];
+ } elseif (abs($last_frozen_num) < 0.01) {
+ $last_frozen_num = 0;
+ }
+ } else {
+ if ($last_frozen_num < 0) {
+ Db::rollback();
+ return [
+ 'status' => 400,
+ 'msg' => '冻结资金不能为负'
+ ];
+ }
+ }
+
+
+ if (in_array($change_type, [12, 13]) && $change_log_admin_id > 0 && $rate != 0) {
+ $balance_change_log["user_id"] = $user_id;
+ $balance_change_log["type"] = $account_type;
+ $balance_change_log['before_num'] = bcdiv($account_info['usable_num'], $rate, 18);
+ $balance_change_log["change_num"] = bcdiv($change_usable_num, $rate, 18);
+ $balance_change_log["currency_rate"] = $rate;
+ $balance_change_log["admin_id"] = $change_log_admin_id;
+ $balance_change_log["create_time"] = date('Y-m-d H:i:s');
+ $balance_log_bool = Db::table('bot_user_balance_change_log')->insert($balance_change_log);
+ if (!$balance_log_bool) {
+ Db::rollback();
+ return [
+ 'status' => 100,
+ 'msg' => '上分 - 账户流水插入失败'
+ ];
+ }
+ }
+
+ Db::commit();
+ return [
+ 'status' => 200,
+ 'msg' => 'ok'
+ ];
+ } catch (ValidateException|PDOException|\Exception $e) {
+ Db::rollback();
+ return [
+ 'status' => 100,
+ 'msg' => $e->getMessage()
+ ];
+ }
+ }
+
+ // 合约插针缓存
+ public function initContractHqData()
+ {
+ $now = date('Y-m-d H:i:s');
+ $list = ContractMarketModel::where('type', 0)
+ ->whereTime('begin_time', '>', $now)
+ ->field('trade_name as selfContractCode,begin_time as BeginTime,step as Step ,end_time as EndTime,max_price as Price')
+ ->order('id', 'desc')
+ ->select();
+ $rows = [];
+ $redis = $this->getRedis();
+ if (!$list->isEmpty()) {
+ $rows = $list->toArray();
+ foreach ($rows as $key => $val) {
+ $keep_decimal = $redis->hget('CONTRACT:LIST:' . $val['selfContractCode'], 'keep_decimal');
+ $list[$key]['Digits'] = $keep_decimal;
+ }
+ }
+
+ $reds_key = "contract_hq_setting";
+ $redis->del($reds_key);
+ $redis->set($reds_key, json_encode($rows));
+ }
+
+ public function initContractSetting()
+ {
+ $list = ContractSettingModel::getSettingList();
+ $redis_key = "contract_time_setting";
+ $redis = $this->getRedis();
+ $redis->del($redis_key);
+ $redis->set($redis_key, json_encode($list, JSON_NUMERIC_CHECK));
+ }
+
+ // 合约自发行情缓存
+ public function initContractMarketData()
+ {
+
+ $now = date('Y-m-d H:i:s');
+ $list = ContractMarketModel::where('type', 1)
+ ->whereTime('begin_time', '>', $now)
+ ->field('trade_name as selfContractCode,end_time as endTime,max_price as maxPrice')
+ ->order('id', 'desc')
+ ->select();
+ $rows = [];
+ if (!$list->isEmpty()) {
+ $rows = $list->toArray();
+ }
+
+ $key = "contract_market_setting";
+ $this->redis->set($key, json_encode($rows));
+ }
+
+ public function getBrokerageKey($type)
+ {
+ switch ($type) {
+ case 1:
+ //平仓返佣
+ $brokerage_key = 'BROKERAGE:SALE:SETTING';
+ break;
+ case 2:
+ //开仓返佣
+ $brokerage_key = 'BROKERAGE:BUY:SETTING';
+ break;
+ default:
+ //注册返佣
+ $brokerage_key = 'BROKERAGE:REG:SETTING';
+ break;
+ }
+ return $brokerage_key;
+ }
+
+ public function getTradeFeeKey($market_type)
+ {
+ switch ($market_type) {
+ case 1:
+ $fee_key = 'TRADE:FEE:DIGITAL';
+ break;
+ case 2:
+ $fee_key = 'TRADE:FEE:CONTRACT';
+ break;
+ case 3:
+ $fee_key = 'TRADE:FEE:US_STOCK';
+ break;
+ case 4:
+ $fee_key = 'TRADE:FEE:IDN_STOCK';
+ break;
+ case 5:
+ $fee_key = 'TRADE:FEE:MYS_STOCK';
+ break;
+ case 6:
+ $fee_key = 'TRADE:FEE:THA_STOCK';
+ break;
+ case 7:
+ $fee_key = 'TRADE:FEE:IN_STOCK';
+ break;
+ case 8:
+ $fee_key = 'TRADE:FEE:CONTRACT_SEC';
+ break;
+ case 9:
+ $fee_key = 'TRADE:FEE:SGD_STOCK';
+ break;
+ case 12:
+ $fee_key = 'TRADE:FEE:HK_STOCK';
+ break;
+ case 14:
+ $fee_key = 'TRADE:FEE:UK_STOCK';
+ break;
+ case 15:
+ $fee_key = 'TRADE:FEE:FUR_STOCK';
+ break;
+ case 16:
+ $fee_key = 'TRADE:FEE:EUR_STOCK';
+ break;
+ case 17:
+ $fee_key = 'TRADE:FEE:BR_STOCK';
+ break;
+ case 18:
+ $fee_key = 'TRADE:FEE:JP_STOCK';
+ break;
+ case 19:
+ $fee_key = 'TRADE:FEE:FOREX';
+ break;
+ default:
+ $fee_key = '';
+ break;
+ }
+ return $fee_key;
+ }
+
+ /**
+ * @param $menus
+ * @param $pid
+ * @param $showParentName
+ * @return array|string
+ */
+ function getTreeMenu($menus, $pid = 0, $showParentName = false)
+ {
+ $arr = [];
+ if (empty($menus)) {
+ return '';
+ }
+ if ($showParentName) {
+ for ($i = 0; $i < count($menus); $i++) {
+ $parentId = $menus[$i]['pid'];
+ if ($parentId == '0') {
+ $menus[$i]['parent_name'] = "";
+ } else {
+ $parent = array_filter($menus, function ($item) use ($parentId) {
+ return $item['id'] == $parentId;
+ });
+
+ if ($parent) {
+ $parent = array_values($parent);
+ if ($parent[0]['name']) {
+ $menus[$i]['parent_name'] = $parent[0]['name'];
+ } else if ($parent[0]['title']) {
+ $menus[$i]['parent_name'] = $parent[0]['title'];
+ }
+ }
+ }
+ }
+ }
+ foreach ($menus as $key => $value) {
+ if ($value['pid'] == $pid) {
+ $children = $this->getTreeMenu($menus, $value['id']);
+ if (!empty($children)) {
+ $value['children'] = $children;
+ }
+ //pid=0为顶级菜单,前端不显示
+ if ($pid == '0') {
+ unset($value['pid']);
+ }
+ $arr[] = $value;
+ }
+ }
+
+ return $arr;
+ }
+
+ function getSortTreeMenu($menus, $sort = 'order', $pid = 0)
+ {
+ $menuList = getTreeMenu($menus, $pid = 0);
+ foreach ($menuList as $key => $value) {
+ if (!empty($value['children'])) {
+ $sort = array_column($value['children'], $sort);
+ array_multisort($sort, SORT_DESC, $value['children']);
+ }
+ }
+ return $menuList;
+ }
+
+ // 给 go 行情 发送 新增的股票
+ public function sendNewStockToGo($country, $newStockCode, $oldStockCode, $stockName, $tape, $price = 0, $isReal = 1, $intro = '', $source = 0, $numericCode = 0)
+ {
+ try {
+ switch ($country) {
+ case 'India':
+ case 'Thailand':
+ case 'US':
+ case 'HongKong':
+ $price = bcadd($price, 0, 2);
+ break;
+ case 'Indonesia':
+ $price = bcadd($price, 0, 0);
+ break;
+ case 'Malaysia':
+ $price = bcadd($price, 0, 3);
+ break;
+ default:
+ $price = bcadd($price, 0, 2);
+ }
+
+ $responseArr = [
+ 'new_ticker' => $newStockCode, //旧的股票代码 (新增的话 ,两个字段都是一样的值)
+ 'locale' => $country, //国家
+ 'yesterday_close' => $price, //价格
+ 'name' => $stockName, //股票name
+ 'primary_exchange' => $tape, //交易所
+ 'is_real' => $isReal, //1正式股票 2测试股票
+ 'intro' => $intro //股票简介
+ ];
+
+ if ($source > 0) {
+ $responseArr['source'] = $source;
+ }
+
+ if ($country == 'Malaysia') {
+ $responseArr['numeric_code'] = $numericCode . '';
+ }
+
+ $client = new Client();
+ $url = env('QUOTE.BASE_URL') . '/spots/list/new/add';
+ $response = $client->request("POST", $url, [
+ 'json' => $responseArr
+ ]);
+
+ $body = $response->getBody()->getContents();
+ $res = json_decode($body, true);
+
+ $responseArr['url'] = $url;
+ trace('---给行情推送数据---' . json_encode([$res, $responseArr]), 'error');
+
+ if (isset($res['code']) && $res['code'] == 200) {
+ return true;
+ }
+
+ trace('---给行情推送数据异常---' . json_encode([$res, $responseArr]), 'error');
+ return false;
+ } catch (\Exception $exception) {
+ trace('---给行情推送数据异常1---' . $exception->getMessage(), 'error');
+
+ } catch (GuzzleException $e) {
+ trace('---给行情推送数据异常2---' . $e->getMessage(), 'error');
+ }
+
+ return false;
+ }
+
+ // 给 go 行情 发送股票小数位数
+ public function sendDecimalToGo($country, $stockCode, int $decimal)
+ {
+ try {
+ $client = new Client();
+ $url = env('QUOTE.BASE_URL') . '/spots/update/keep';
+ $response = $client->request("POST", $url, [
+ 'json' => [
+ 'currency' => $country,
+ 'stockCode' => $stockCode,
+ 'keepDecimal' => $decimal,
+ ],
+ ]);
+
+ $body = $response->getBody()->getContents();
+ $res = json_decode($body, true);
+ if (isset($res['code']) && $res['code'] == 200) {
+ return true;
+ }
+
+ Log::error('给行情推送数据异常 ' . json_encode([$res]));
+ return false;
+ } catch (\Exception $exception) {
+ Log::error('给行情推送数据异常1 ' . $exception->getMessage());
+ } catch (GuzzleException $e) {
+ Log::error('给行情推送数据异常2 ' . $e->getMessage());
+ }
+
+ return false;
+ }
+
+ // 给 go 交易 发送股票小数位数 // $preStockId $marketType $stockCode
+ public function sendStockToGo($preStockId, $stockCode, $marketType)
+ {
+ try {
+ $marketType = $marketType + 0; // 转成数字
+ $preStockId = $preStockId . '';
+ $client = new Client();
+ $url = env('QUOTE.DEAL_BASE_URL') . '/order_sharepre/share_pre_trade';
+ $response = $client->request("POST", $url, [
+ 'json' => [
+ 'code' => $stockCode,
+ 'id' => $preStockId,
+ 'stock' => $marketType,
+ ],
+ ]);
+
+ $body = $response->getBody()->getContents();
+ $res = json_decode($body, true);
+
+ trace('---给交易推送数据---' . json_encode([$res, [
+ 'url' => $url,
+ 'code' => $stockCode,
+ 'id' => $preStockId,
+ 'stock' => $marketType,]]), 'error');
+ if (isset($res['code']) && $res['code'] == 200) {
+ return true;
+ }
+ return false;
+ } catch (\Exception $exception) {
+ trace('---通知交易异常1---' . $exception->getMessage(), 'error');
+ } catch (GuzzleException $e) {
+ trace('---通知交易异常1---' . $e->getMessage(), 'error');
+ }
+ return false;
+ }
+
+ public function sendStockToTrade($order_no, $stockCode, $marketType)
+ {
+ try {
+ $marketType = $marketType + 0; // 转成数字
+ $order_no = $order_no . '';
+ $client = new Client();
+ $url = env('QUOTE.DEAL_BASE_URL') . '/order_sharepre/share_pre_trade_by_order_no';
+ $response = $client->request("POST", $url, [
+ 'json' => [
+ 'code' => $stockCode,
+ 'id' => $order_no,
+ 'stock' => $marketType,
+ ],
+ ]);
+
+ $body = $response->getBody()->getContents();
+ $res = json_decode($body, true);
+
+ trace('---单个订单给交易推送数据---' . json_encode([$res, [
+ 'url' => $url,
+ 'code' => $stockCode,
+ 'id' => $order_no,
+ 'stock' => $marketType,]]), 'error');
+ if (isset($res['code']) && $res['code'] == 200) {
+ return true;
+ }
+ return false;
+ } catch (\Exception $exception) {
+ trace('---通知交易异常1---' . $exception->getMessage(), 'error');
+ } catch (GuzzleException $e) {
+ trace('---通知交易异常1---' . $e->getMessage(), 'error');
+ }
+ return false;
+ }
+
+ public function sendUpdateCodeGo($newCode, $oldCode, $marketType)
+ {
+ try {
+ $marketType = $marketType + 0; // 转成数字
+ $client = new Client();
+ $url = env('QUOTE.DEAL_BASE_URL') . '/order_sharepre/update_stock_id';
+ $response = $client->request("POST", $url, [
+ 'json' => [
+ 'code' => $newCode,
+ 'codeOld' => $oldCode,
+ 'stock' => $marketType,
+ ],
+ ]);
+
+ $body = $response->getBody()->getContents();
+ $res = json_decode($body, true);
+
+ if (isset($res['code']) && $res['code'] == 200) {
+ return true;
+ }
+ return false;
+ } catch (\Exception $exception) {
+ Log::error('给行情推送数据异常1 ' . $exception->getMessage());
+ } catch (GuzzleException $e) {
+ Log::error('给行情推送数据异常2 ' . $e->getMessage());
+ }
+
+ return false;
+ }
+
+ /**
+ * 给go推送股票指数代码
+ * @param $code
+ * @param $country
+ * @param $sort
+ * @param $status
+ * @return bool
+ */
+ public function sendStockIndexToGo($code, $country, $sort, $status)
+ {
+ try {
+ $client = new Client();
+ $url = env('QUOTE.BASE_URL') . '/spots/index/list/new/add';
+ $response = $client->request("POST", $url, [
+ 'json' => [
+ 'ticker' => $code,
+ 'state' => $status,
+ 'sort' => $sort,
+ ],
+ ]);
+
+ $body = $response->getBody()->getContents();
+ $res = json_decode($body, true);
+
+ Log::info('给交易推送数据 ' . json_encode([$res, [
+ 'url' => $url,
+ 'ticker' => $code,
+ 'locale' => $country,
+ 'state' => $status,
+ 'sort' => $sort,
+ ]]));
+
+
+ if (isset($res['code']) && $res['code'] == 200) {
+ return true;
+ }
+ return false;
+ } catch (\Exception $exception) {
+ Log::error('给行情推送股票指数数据异常1 ' . $exception->getMessage());
+ } catch (GuzzleException $e) {
+ Log::error('给行情推送股票指数数据异常2 ' . $e->getMessage());
+ }
+
+ return false;
+ }
+
+
+}
\ No newline at end of file
diff --git a/app/admin/service/AdminService.php b/app/admin/service/AdminService.php
new file mode 100644
index 0000000..fb726c6
--- /dev/null
+++ b/app/admin/service/AdminService.php
@@ -0,0 +1,362 @@
+scene('addUser')->check($param);
+ // 查找用户是否存在
+ $username = $param['user_name'];
+ $user = AdminModel::getByUserName($username);
+ if (!empty($user)) {
+ return $this->toData('200100', '该用户已存在', []);
+ }
+ $param['password'] = (new UnqId())->encryptPassword($param['password'], env('ENCRYPT.ADMINSALT'));
+ $param['invite_code'] = (new BaseHomeService())->getUniqInviteCode();
+
+ AdminModel::create($param);
+ return $this->toData('0', '添加成功.', []);
+ } catch (ValidateException $validateException) {
+ $message = $validateException->getError();
+ return $this->toData('100400', $message);
+ } catch (\Exception $exception) {
+ return $this->toData('100500', '系统繁忙.', [$exception->getMessage()]);
+ }
+
+ }
+
+ /**
+ * 获取用户列表
+ * @return array
+ */
+ public function getUserList($param)
+ {
+ try {
+ $adminModel = new AdminModel();
+ //查询条件
+ if (isset($param['user_name']) && !empty($param['user_name'])) {
+ $adminModel = $adminModel->where('user_name', $param['user_name']);
+ }
+ if (isset($param['nick_name']) && !empty($param['nick_name'])) {
+ $adminModel = $adminModel->where('nick_name', $param['nick_name']);
+ }
+
+ // 总数
+ $total = $adminModel->count();
+ $list = $adminModel->withoutField('password,token')->order('id', 'asc')->page($param['page'], $param['limit'])->select()->toArray();
+ $roleIds = array_column($list, "role_id");
+ $roleList = AuthRoleModel::where('id', 'in', $roleIds)->field('id,name')->select()->toArray();
+ $host = Request::host();
+ $host = str_replace('api.', '', $host);
+ if (!empty($list)) {
+ for ($i = 0; $i < count($list); $i++) {
+ $index = array_search($list[$i]['role_id'], array_column($roleList, 'id'));
+
+ if ($index !== false) {
+ $list[$i]['role_name'] = $roleList[$index]['name'];
+ }
+
+ $list[$i]['url'] = $host . '/register/index?=agent_code='.$list[$i]['invite_code'];
+ }
+ }
+ return $this->toData('0', 'SUCCESS', ['total' => $total, 'list' => $list]);
+ } catch (\Exception $exception) {
+ return $this->toData('100500', 'The system is busy.', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+
+ /**
+ * @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 = AdminModel::find($userId);
+
+ if (empty($info)) {
+ return $this->toData('100400', 'The user does not exist.', []);
+ }
+ // 返回数据
+ return $this->toData('0', 'Modification successful.', $info->toArray());
+ } catch (\Exception $exception) {
+ return $this->toData('100500', 'The system is busy.', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+
+
+ /**
+ * @desc 设置用户信息
+ * @param $userId
+ * @param $param
+ * @return array
+ */
+ public function updateInfo($userId, $param): array
+ {
+ try {
+ // 主键
+ if (empty($userId) || $userId <= 0) {
+ return $this->toData('200403', 'Please log in first.', []);
+ }
+ // 参数校验
+ validate(AdminValidate::class)->scene('updateInfo')->check($param);
+ // 查找用户信息
+ $user = AdminModel::find($userId);
+ if (empty($user)) {
+ return $this->toData('200403', 'Please log in first.', []);
+ }
+
+ $user['nick_name'] = $param['nick_name'];
+ $user['email'] = $param['email'];
+ $user['mobile'] = isset($param['mobile']) ? $param['mobile'] : null;
+ $user['desc'] = isset($param['desc']) ? $param['mobile'] : null;
+ $user->save();
+ // 返回
+ return $this->toData('0', 'Modification successful.', []);
+ } catch (ValidateException $validateException) {
+ $message = $validateException->getError();
+ return $this->toData('200400', $message);
+ } catch (\Exception $exception) {
+ return $this->toData('200500', 'The system is busy.', [$exception->getMessage()]);
+ }
+
+ }
+
+ /**
+ * 编辑账号信息
+ * @param $accountId
+ * @param $param
+ * @return array
+ */
+ public function updateAccount($accountId, $param): array
+ {
+ try {
+ // 主键
+ if (empty($accountId) || $accountId <= 0) {
+ return $this->toData('200404', 'accountId lose.', []);
+ }
+ // 参数校验
+ validate(AdminValidate::class)->scene('updateAccount')->check($param);
+ // 查找用户信息
+ $user = AdminModel::find($accountId);
+ if (empty($user)) {
+ return $this->toData('200403', '不存在该用户.', []);
+ }
+ if (isset($param['password'])) {
+ $user['password'] = (new UnqId())->encryptPassword($param['password'], env('ENCRYPT.ADMINSALT'));
+ }
+ $user['role_id'] = $param['role_id'];
+ $user['user_name'] = $param['user_name'];
+ $user['nick_name'] = $param['nick_name'];
+ $user['email'] = isset($param['email']) ? $param['email'] : null;
+ $user['remark'] = isset($param['remark']) ? $param['remark'] : null;
+ $user->save();
+ // 返回
+ return $this->toData('0', 'Modification successful.', []);
+ } catch (ValidateException $validateException) {
+ $message = $validateException->getError();
+ return $this->toData('200400', $message);
+ } catch (\Exception $exception) {
+ return $this->toData('200500', 'The system is busy.', [$exception->getMessage()]);
+ }
+
+ }
+
+ public function updateAccountStauts($accountId, $param): array
+ {
+ try {
+ // 主键
+ if (empty($accountId) || $accountId <= 0) {
+ return $this->toData('200404', 'accountId lose.', []);
+ }
+ // 参数校验
+ validate(AdminValidate::class)->scene('updateAccountStatus')->check($param);
+ // 查找用户信息
+ $user = AdminModel::find($accountId);
+ if (empty($user)) {
+ return $this->toData('200403', 'Please log in first.', []);
+ }
+ $user['status'] = $param['status'];
+ $user->save();
+ // 返回
+ return $this->toData('0', 'Modification successful.', []);
+ } catch (ValidateException $validateException) {
+ $message = $validateException->getError();
+ return $this->toData('200400', $message);
+ } catch (\Exception $exception) {
+ return $this->toData('200500', 'The system is busy.', [$exception->getMessage()]);
+ }
+
+ }
+
+
+ public function updatePassword($userId, $param): array
+ {
+ try {
+ // 主键
+ if (empty($userId) || $userId <= 0) {
+ return $this->toData('200403', 'Please log in first.', []);
+ }
+
+ // 参数校验
+ validate(AdminValidate::class)->scene('updatePassword')->check($param);
+ // 查找用户信息
+ $user = AdminModel::find($userId);
+ if (empty($user)) {
+ return $this->toData('200403', 'Please log in first.', []);
+ }
+ //检查原始密码
+ $flag = (new UnqId())->checkPassword($param['old_password'], $user['password'], env('ENCRYPT.ADMINSALT'));
+ if (!$flag) {
+ return $this->toData('200401', '原始密码错误', []);
+ }
+ //设置新密码
+ $newPassword = (new UnqId())->encryptPassword($param['new_password'], env('ENCRYPT.ADMINSALT'));
+ $user['password'] = $newPassword;
+ $user->save();
+ // 返回
+ return $this->toData('0', 'Modification successful.', []);
+ } catch (ValidateException $validateException) {
+ $message = $validateException->getError();
+ return $this->toData('200400', $message);
+ } catch (\Exception $exception) {
+ return $this->toData('200500', 'The system is busy.', [$exception->getMessage()]);
+ }
+
+ }
+
+ public function del($id): array
+ {
+ try {
+ $adminModel = AdminModel::find($id);
+ $adminModel->delete();
+ // 返回
+ return $this->toData('0', 'Modification successful.', []);
+ } catch (ValidateException $validateException) {
+ $message = $validateException->getError();
+ return $this->toData('200400', $message);
+ } catch (\Exception $exception) {
+ return $this->toData('200500', 'The system is busy.', [$exception->getMessage()]);
+ }
+
+ }
+
+ /**
+ * 查询用户权限代码
+ * @param $id
+ * @return array
+ */
+ public function getPermCode($id): array
+ {
+ try {
+ $adminModel = AdminModel::find($id);
+ //根据角色查询权限代码
+ $roleModel = AuthRoleModel::find($adminModel->role_id);
+ $rules = $roleModel->rules;
+ if ($rules) {
+ $rules = explode(",", $rules);
+ //字符串转换为数字类型
+// $rules=array_map(function ($value){
+// return (int)$value;
+// },$rules);
+ }
+ // 返回
+ return $this->toData('0', 'Modification successful.', $rules);
+ } catch (ValidateException $validateException) {
+ $message = $validateException->getError();
+ return $this->toData('200400', $message);
+ } catch (\Exception $exception) {
+ return $this->toData('200500', 'The system is busy.', [$exception->getMessage()]);
+ }
+ }
+
+
+ /**
+ * @desc 退出登陆
+ * @param $userId
+ * @return array
+ */
+ public function logout($userId)
+ {
+ try {
+ // 获取用户
+ $user = AdminModel::find($userId);
+ if (empty($user)) {
+ return $this->toData('200300', '用户不存在', []);
+ }
+ $user->token = "";
+ $user->save();
+ return $this->toData('0', 'Modification successful.');
+ } catch (\Exception $exception) {
+ return $this->toData('200500', 'The system is busy.', [$exception->getMessage()]);
+ }
+
+ }
+
+ public function logList($param)
+ {
+ try {
+ $adminLogModel = new AdminLogModel();
+ //查询条件
+ if (!empty($param['create_date'])) {
+ $adminLogModel = $adminLogModel->where('create_date', $param['create_date']);
+ }
+
+ // 总数
+ $total = $adminLogModel->count();
+ $list = $adminLogModel->order('id', 'desc')->page($param['page'], $param['limit'])->select()->toArray();
+ $accountIds = array_column($list, "admin_id");
+ $accountList = AdminModel::where('id', 'in', $accountIds)->column('user_name', 'id');
+// $menuList = AuthRuleModel::column('title', 'path');
+ if (!empty($list)) {
+ foreach ($list as &$v) {
+ $v['admin_name'] = $accountList[$v['admin_id']] ?? '-';
+ $v['path_text'] = '用户上分';
+ }
+ }
+ return $this->toData('0', 'SUCCESS', ['total' => $total, 'list' => $list]);
+ } catch (\Exception $exception) {
+ return $this->toData('100500', 'The system is busy.', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+
+ public function inviteCode()
+ {
+ try {
+ $user = AdminModel::select();
+ foreach ($user as $v){
+ $inviteCode = (new BaseHomeService())->getUniqInviteCode();
+ AdminModel::where('id',$v->id)->update(['invite_code'=>$inviteCode]);
+ }
+
+ } 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
new file mode 100644
index 0000000..eb62ba5
--- /dev/null
+++ b/app/admin/service/AgentService.php
@@ -0,0 +1,154 @@
+column('uid');
+ $roleId = 10;
+ $agentAdminUser = AdminModel::where('role_id', 'in', $roleId)->field('id,user_name,nick_name,email,mobile,status,invite_code')->select();
+ $rows = [];
+ if (!$agentAdminUser->isEmpty()) {
+ foreach ($agentAdminUser as $item) {
+ $rows[] = [
+ 'id' => $item['id'],
+ 'username' => $item['user_name'],
+ 'nickname' => $item['nick_name'],
+ 'email' => $item['email'] ?? '-',
+ 'mobile' => $item['mobile'] ?? '-',
+ 'status' => $item['status'],
+ 'invite_code' => $item['invite_code'],
+ ];
+ }
+ }
+ return $this->toData('0', 'SUCCESS', ['list' => $rows, 'total' => count($rows)]);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统异常 请稍后重试', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+
+ // 代理用户
+ public function user($param)
+ {
+ try {
+ if (empty($param['agent_id'])) {
+ return $this->toData('0', 'SUCCESS', ['list' => []]);
+ }
+
+ $userList = UserModel::where('agent_id', 'in', [0, $param['agent_id']])->where('parent_id', 0)
+ ->order('user_id', 'desc')
+ ->select();
+ $rows = [];
+ if (!$userList->isEmpty()) {
+ foreach ($userList as $item) {
+ $rows[] = [
+ 'id' => $item['user_id'],
+ 'email' => $item['email'],
+ 'user_no' => $item['user_no'],
+ 'status' => $item['agent_id'] == $param['agent_id'],
+ 'agent_id' => $param['agent_id'],
+ ];
+ }
+ }
+ return $this->toData('0', 'SUCCESS', ['list' => $rows, 'total' => count($rows)]);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统异常 请稍后重试', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+
+ public function manager($param)
+ {
+ try {
+ if (empty($param['id']) || !is_numeric($param['id'])) {
+ return $this->toData('1', '参错错误', ['list' => []]);
+ }
+
+ if (empty($param['agent_id']) || !is_numeric($param['agent_id'])) {
+ return $this->toData('1', '参错错误', ['list' => []]);
+ }
+
+ $user = UserModel::where('user_id', $param['id'])->find();
+ if (empty($user)) {
+ return $this->toData('1', '用户不存在', ['list' => []]);
+ }
+
+ if ($user['parent_id'] != 0) {
+ return $this->toData('1', '只能绑定顶层用户', ['list' => []]);
+ }
+
+ // 判断代理是否有效
+ $admin = AdminModel::where('id', $param['agent_id'])->find();
+ $roleId = 10;
+ if (empty($admin) || $admin['role_id'] != $roleId) {
+ return $this->toData('1', '代理不存在', ['list' => []]);
+ }
+
+// $agentUserId = env('AGENT.AGENT_GROUP_ID');
+// $agentAdminUserIds = AuthGroupAccessModel::where('group_id', $agentUserId)->column('uid');
+// if(!in_array($param['agent_id'], $agentAdminUserIds)){
+// return $this->toData('1', '代理不存在', ['list' => []]);
+// }
+
+ // 未绑定 直接绑定
+ if ($user->agent_id == 0) {
+ UserModel::update(['agent_id' => $param['agent_id']], ['user_id' => $param['id']]);
+ return $this->toData('0', 'SUCCESS', []);
+ }
+
+ // 取消绑定
+ if ($user->agent_id == $param['agent_id']) {
+ UserModel::update(['agent_id' => 0], ['user_id' => $param['id']]);
+ return $this->toData('0', 'SUCCESS', []);
+ }
+
+ return $this->toData('1', '该用户已被其他代理绑定, 请先取消绑定', []);
+
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统异常 请稍后重试', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+
+ public function addUser($param)
+ {
+ try {
+ if (empty($param['agent_id']) || !is_numeric($param['agent_id'])) {
+ return $this->toData('1', '参错错误');
+ }
+
+ if (empty($param['user_id']) || !is_numeric($param['user_id'])) {
+ return $this->toData('1', '参错错误');
+ }
+
+ $user = UserModel::where('user_id', $param['user_id'])->find();
+ if (empty($user)) {
+ return $this->toData('1', '用户不存在');
+ }
+
+ if ($user['parent_id'] != 0) {
+ return $this->toData('1', '只能绑定顶层用户');
+ }
+
+ // 判断代理是否有效
+ $admin = AdminModel::where('id', $param['agent_id'])->find();
+ $roleId = 10;
+ if (empty($admin) || $admin['role_id'] != $roleId) {
+ return $this->toData('1', '代理不存在');
+ }
+
+ UserModel::update(['agent_id' => $param['agent_id']], ['user_id' => $param['user_id']]);
+ return $this->toData('0', 'SUCCESS', []);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统异常 请稍后重试', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/admin/service/FlowService.php b/app/admin/service/FlowService.php
new file mode 100644
index 0000000..57d2ce4
--- /dev/null
+++ b/app/admin/service/FlowService.php
@@ -0,0 +1,1303 @@
+scene('digital')->check($param);
+
+ $where = [];
+ $userId = 0;
+ // 用户号精确搜索
+ if (!empty($param['user_no'])) {
+ $user = UserModel::where('user_no', $param['user_no'])->find();
+ if (empty($user)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => [], ]);
+ }
+ $userId = $user['user_id'];
+ }
+
+ // 判断是否是代理 如果是代理 只能看他自己管理的用户
+ $whereU = $this->getWhereByIsAgentAndUserId($adminId, $where, $userId);
+ if (!is_array($whereU)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => []]);
+ }
+
+ $changeTypeArr = UserDigitalLogModel::group('change_type')->column('change_type');
+
+ if (!empty($param['change_type']) && in_array($param['change_type'], $changeTypeArr)) $where['change_type'] = $param['change_type'];
+
+ // 交易对
+ if (!empty($param['digital_id'])) {
+ $where['digital_id'] = $param['digital_id'];
+ }
+
+ if (!empty($param['start_time']) && !empty($param['end_time'])) {
+ $where['create_time'] = ['between time', [$param['start_time'], $param['end_time']]];
+ }
+
+ // 列表
+ $list = UserDigitalLogModel::where($where)->where($whereU)->order('id', 'desc')->page($param['page'], $param['limit'])->select();
+ // 总数
+ $total = UserDigitalLogModel::where($where)->where($whereU)
+ ->count();
+
+ $rows = [];
+ if (!$list->isEmpty()) {
+ $rows = $list->toArray();
+ // 获取用户号
+ $userIdArr = [];
+ foreach ($list as $idItem) {
+ $userIdArr[] = $idItem['user_id'];
+ }
+
+ $userNoArr = UserModel::where('user_id', 'in', $userIdArr)->column('user_no', 'user_id');
+ foreach ($rows as $key => $item) {
+ $rows[$key]['user_no'] = $userNoArr[$item['user_id']] ?? '-'; // 用户号
+ }
+ }
+
+ return $this->toData('0', 'SUCCESS', ['total' => $total, 'list' => $rows, 'extend' => (new BaseHomeService())->getCapitalTypeList($changeTypeArr)]);
+
+ } catch (ValidateException $validateException) {
+ // 参数校验失败
+ $message = $validateException->getError();
+ return $this->toData('1', $message);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统异常 请稍后重试', []);
+ }
+ }
+
+ public function stock($param, $adminId)
+ {
+ try {
+ // 参数校验
+ validate(FlowValidate::class)->scene('stock')->check($param);
+
+ $where = [];
+ $userId = 0;
+ // 用户号精确搜索
+ if (!empty($param['user_no'])) {
+ $user = UserModel::where('user_no', $param['user_no'])->find();
+ if (empty($user)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => [], ]);
+ }
+ $userId = $user['user_id'];
+ }
+
+ // 判断是否是代理 如果是代理 只能看他自己管理的用户
+ $whereU = $this->getWhereByIsAgentAndUserId($adminId, $where, $userId);
+ if (!is_array($whereU)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => []]);
+ }
+
+ $changeTypeArr = UserStockLogModel::group('change_type')->column('change_type');
+
+ if (!empty($param['change_type']) && in_array($param['change_type'], $changeTypeArr)) $where['change_type'] = $param['change_type'];
+
+ // 交易对
+ if (!empty($param['stock_id'])) {
+ $where['stock_id'] = $param['stock_id'];
+ }
+
+ if (!empty($param['start_time']) && !empty($param['end_time'])) {
+ $where['create_time'] = ['between time', [$param['start_time'], $param['end_time']]];
+ }
+
+ // 列表
+ $list = UserStockLogModel::where($where)->where($whereU)->order('id', 'desc')->page($param['page'], $param['limit'])->select();
+ // 总数
+ $total = UserStockLogModel::where($where)->where($whereU)
+ ->count();
+
+ $rows = [];
+ if (!$list->isEmpty()) {
+ $rows = $list->toArray();
+ // 获取用户号
+ $userIdArr = [];
+ foreach ($list as $idItem) {
+ $userIdArr[] = $idItem['user_id'];
+ }
+
+ $userNoArr = UserModel::where('user_id', 'in', $userIdArr)->column('user_no', 'user_id');
+ foreach ($rows as $key => $item) {
+ $rows[$key]['user_no'] = $userNoArr[$item['user_id']] ?? '-'; // 用户号
+ }
+ }
+
+ return $this->toData('0', 'SUCCESS', ['total' => $total, 'list' => $rows, 'extend' => (new BaseHomeService())->getCapitalTypeList($changeTypeArr)]);
+
+ } catch (ValidateException $validateException) {
+ // 参数校验失败
+ $message = $validateException->getError();
+ return $this->toData('1', $message);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统异常 请稍后重试', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+
+ public function contract($param, $adminId)
+ {
+ try {
+ // 参数校验
+ validate(FlowValidate::class)->scene('contract')->check($param);
+
+ $where = [];
+ $userId = 0;
+ // 用户号精确搜索
+ if (!empty($param['user_no'])) {
+ $user = UserModel::where('user_no', $param['user_no'])->find();
+ if (empty($user)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => [], ]);
+ }
+ $userId = $user['user_id'];
+ }
+
+ // 判断是否是代理 如果是代理 只能看他自己管理的用户
+ $whereU = $this->getWhereByIsAgentAndUserId($adminId, $where, $userId);
+ if (!is_array($whereU)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => []]);
+ }
+
+ $changeTypeArr = UserContractLogModel::group('change_type')->column('change_type');
+
+ if (!empty($param['change_type']) && in_array($param['change_type'], $changeTypeArr)) $where['change_type'] = $param['change_type'];
+
+ // 交易对
+ if (!empty($param['contract_id'])) {
+ $where['contract_id'] = $param['contract_id'];
+ }
+
+ if (!empty($param['start_time']) && !empty($param['end_time'])) {
+ $where['create_time'] = ['between time', [$param['start_time'], $param['end_time']]];
+ }
+
+ // 列表
+ $list = UserContractLogModel::where($where)->where($whereU)->order('id', 'desc')->page($param['page'], $param['limit'])->select();
+ // 总数
+ $total = UserContractLogModel::where($where)->where($whereU)
+ ->count();
+
+ $rows = [];
+ if (!$list->isEmpty()) {
+ $rows = $list->toArray();
+ // 获取用户号
+ $userIdArr = [];
+ foreach ($list as $idItem) {
+ $userIdArr[] = $idItem['user_id'];
+ }
+
+ $userNoArr = UserModel::where('user_id', 'in', $userIdArr)->column('user_no', 'user_id');
+ foreach ($rows as $key => $item) {
+ $rows[$key]['user_no'] = $userNoArr[$item['user_id']] ?? '-'; // 用户号
+ }
+ }
+
+ return $this->toData('0', 'SUCCESS', ['total' => $total, 'list' => $rows, 'extend' => (new BaseHomeService())->getCapitalTypeList($changeTypeArr)]);
+
+ } catch (ValidateException $validateException) {
+ // 参数校验失败
+ $message = $validateException->getError();
+ return $this->toData('1', $message);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统异常 请稍后重试', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+
+ public function forex($param, $adminId)
+ {
+ try {
+ // 参数校验
+ validate(FlowValidate::class)->scene('forex')->check($param);
+
+ $where = [];
+ $userId = 0;
+ // 用户号精确搜索
+ if (!empty($param['user_no'])) {
+ $user = UserModel::where('user_no', $param['user_no'])->find();
+ if (empty($user)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => [], ]);
+ }
+ $userId = $user['user_id'];
+ }
+
+ // 判断是否是代理 如果是代理 只能看他自己管理的用户
+ $whereU = $this->getWhereByIsAgentAndUserId($adminId, $where, $userId);
+ if (!is_array($whereU)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => []]);
+ }
+
+ $changeTypeArr = UserForexLogModel::group('change_type')->column('change_type');
+
+ if (!empty($param['change_type']) && in_array($param['change_type'], $changeTypeArr)) $where['change_type'] = $param['change_type'];
+
+ // 交易对
+ if (!empty($param['contract_id'])) {
+ $where['contract_id'] = $param['contract_id'];
+ }
+
+ if (!empty($param['start_time']) && !empty($param['end_time'])) {
+ $where['create_time'] = ['between time', [$param['start_time'], $param['end_time']]];
+ }
+
+ // 列表
+ $list = UserForexLogModel::where($where)->where($whereU)->order('id', 'desc')->page($param['page'], $param['limit'])->select();
+ // 总数
+ $total = UserForexLogModel::where($where)->where($whereU)
+ ->count();
+
+ $rows = [];
+ if (!$list->isEmpty()) {
+ $rows = $list->toArray();
+ // 获取用户号
+ $userIdArr = [];
+ foreach ($list as $idItem) {
+ $userIdArr[] = $idItem['user_id'];
+ }
+
+ $userNoArr = UserModel::where('user_id', 'in', $userIdArr)->column('user_no', 'user_id');
+ foreach ($rows as $key => $item) {
+ $rows[$key]['user_no'] = $userNoArr[$item['user_id']] ?? '-'; // 用户号
+ }
+ }
+
+ return $this->toData('0', 'SUCCESS', ['total' => $total, 'list' => $rows, 'extend' => (new BaseHomeService())->getCapitalTypeList($changeTypeArr)]);
+
+ } catch (ValidateException $validateException) {
+ // 参数校验失败
+ $message = $validateException->getError();
+ return $this->toData('1', $message);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统异常 请稍后重试', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+
+ public function transfer($param, $adminId)
+ {
+ try {
+ // 参数校验
+ validate(FlowValidate::class)->scene('transfer')->check($param);
+
+ $where = [];
+ $userId = 0;
+ // 用户号精确搜索
+ if (!empty($param['user_no'])) {
+ $user = UserModel::where('user_no', $param['user_no'])->find();
+ if (empty($user)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => [], ]);
+ }
+ $userId = $user['user_id'];
+ }
+
+ // 判断是否是代理 如果是代理 只能看他自己管理的用户
+ $whereU = $this->getWhereByIsAgentAndUserId($adminId, $where, $userId);
+ if (!is_array($whereU)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => []]);
+ }
+
+ if (!empty($param['change_type'])) $where['change_type'] = $param['change_type'];
+
+
+ // 转出 转入账户
+ if (!empty($param['from_account'])) {
+ $where['from_account'] = $param['from_account'];
+ }
+
+ if (!empty($param['to_account'])) {
+ $where['to_account'] = $param['to_account'];
+ }
+
+ if (!empty($param['start_time']) && !empty($param['end_time'])) {
+ $where['create_time'] = ['between time', [$param['start_time'], $param['end_time']]];
+ }
+
+ // 列表
+ $list = UserTransferModel::where($where)->where($whereU)->order('tran_id', 'desc')->page($param['page'], $param['limit'])->select();
+ // 总数
+ $total = UserTransferModel::where($where)->where($whereU)
+ ->count();
+
+ $rows = [];
+ if (!$list->isEmpty()) {
+ $rows = $list->toArray();
+ // 获取用户号
+ $userIdArr = [];
+ foreach ($list as $idItem) {
+ $userIdArr[] = $idItem['user_id'];
+ }
+
+ $userNoArr = UserModel::where('user_id', 'in', $userIdArr)->column('user_no', 'user_id');
+ foreach ($rows as $key => $item) {
+ $rows[$key]['user_no'] = $userNoArr[$item['user_id']] ?? '-'; // 用户号
+ }
+ }
+
+ return $this->toData('0', 'SUCCESS', ['total' => $total, 'list' => $rows]);
+
+ } catch (ValidateException $validateException) {
+ // 参数校验失败
+ $message = $validateException->getError();
+ return $this->toData('1', $message);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统异常 请稍后重试', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+
+ public function fee($param, $adminId)
+ {
+ try {
+ // 参数校验
+ validate(FlowValidate::class)->scene('fee')->check($param);
+
+ $where = [];
+ $userId = 0;
+ // 用户号精确搜索
+ if (!empty($param['user_no'])) {
+ $user = UserModel::where('user_no', $param['user_no'])->find();
+ if (empty($user)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => [], ]);
+ }
+ $userId = $user['user_id'];
+ }
+
+ // 判断是否是代理 如果是代理 只能看他自己管理的用户
+ $whereU = $this->getWhereByIsAgentAndUserId($adminId, $where, $userId);
+ if (!is_array($whereU)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => []]);
+ }
+
+ if (!empty($param['change_type'])) $where['change_type'] = $param['change_type'];
+
+
+ // 账户类型
+ if (!empty($param['account_type'])) {
+ $where['account_type'] = $param['account_type'];
+ }
+
+ // 交易类型
+ if (!empty($param['trade_type'])) {
+ $where['trade_type'] = $param['trade_type'];
+ }
+
+ // 交易单号
+ if (!empty($param['trade_no'])) {
+ $where['trade_no'] = $param['trade_no'];
+ }
+
+ if (!empty($param['start_time']) && !empty($param['end_time'])) {
+ $where['create_time'] = ['between time', [$param['start_time'], $param['end_time']]];
+ }
+
+ // 列表
+ $list = TradeFeeModel::where($where)->where($whereU)->order('id', 'desc')->page($param['page'], $param['limit'])->select();
+ // 总数
+ $total = TradeFeeModel::where($where)->where($whereU)
+ ->count();
+
+ $rows = [];
+ if (!$list->isEmpty()) {
+ $rows = $list->toArray();
+ // 获取用户号
+ $userIdArr = [];
+ foreach ($list as $idItem) {
+ $userIdArr[] = $idItem['user_id'];
+ }
+
+ $userNoArr = UserModel::where('user_id', 'in', $userIdArr)->column('user_no', 'user_id');
+ foreach ($rows as $key => $item) {
+ $rows[$key]['user_no'] = $userNoArr[$item['user_id']] ?? '-'; // 用户号
+ }
+ }
+
+ return $this->toData('0', 'SUCCESS', ['total' => $total, 'list' => $rows]);
+
+ } catch (ValidateException $validateException) {
+ // 参数校验失败
+ $message = $validateException->getError();
+ return $this->toData('1', $message);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统异常 请稍后重试', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+
+ public function brokerage($param, $adminId)
+ {
+ try {
+ // 参数校验
+ validate(FlowValidate::class)->scene('brokerage')->check($param);
+
+ $where = [];
+ $userId = 0;
+ // 用户号精确搜索
+ if (!empty($param['user_no'])) {
+ $user = UserModel::where('user_no', $param['user_no'])->find();
+ if (empty($user)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => [], ]);
+ }
+ $userId = $user['user_id'];
+ }
+
+ // 判断是否是代理 如果是代理 只能看他自己管理的用户
+ $whereU = $this->getWhereByIsAgentAndUserId($adminId, $where, $userId);
+ if (!is_array($whereU)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => []]);
+ }
+
+ if (!empty($param['change_type'])) $where['change_type'] = $param['change_type'];
+
+
+ // 返佣级别
+ if (!empty($param['level_type'])) {
+ $where['level_type'] = $param['level_type'];
+ }
+
+ // 返佣类型
+ if (!empty($param['back_type'])) {
+ $where['back_type'] = $param['back_type'];
+ }
+
+
+ if (!empty($param['start_time']) && !empty($param['end_time'])) {
+ $where['create_time'] = ['between time', [$param['start_time'], $param['end_time']]];
+ }
+
+ // 列表
+ $list = UserBrokerageModel::where($where)->where($whereU)->order('id', 'desc')->page($param['page'], $param['limit'])->select();
+ // 总数
+ $total = UserBrokerageModel::where($where)->where($whereU)
+ ->count();
+
+ $rows = [];
+ if (!$list->isEmpty()) {
+ $rows = $list->toArray();
+ // 获取用户号
+ $userIdArr = [];
+ foreach ($list as $idItem) {
+ $userIdArr[] = $idItem['user_id'];
+ }
+
+ $userNoArr = UserModel::where('user_id', 'in', $userIdArr)->column('user_no', 'user_id');
+ foreach ($rows as $key => $item) {
+ $rows[$key]['user_no'] = $userNoArr[$item['user_id']] ?? '-'; // 用户号
+ }
+ }
+
+ return $this->toData('0', 'SUCCESS', ['total' => $total, 'list' => $rows]);
+
+ } catch (ValidateException $validateException) {
+ // 参数校验失败
+ $message = $validateException->getError();
+ return $this->toData('1', $message);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统异常 请稍后重试', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+
+
+ ######################################## 美股资产流水 ################################
+ // 美股
+ public function usStock($param, $adminId)
+ {
+ try {
+ // 参数校验
+ validate(FlowValidate::class)->scene('us_stock')->check($param);
+
+ $where = [];
+ $userId = 0;
+ // 用户号精确搜索
+ if (!empty($param['user_no'])) {
+ $user = UserModel::where('user_no', $param['user_no'])->find();
+ if (empty($user)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => [], ]);
+ }
+ $userId = $user['user_id'];
+ }
+
+ // 判断是否是代理 如果是代理 只能看他自己管理的用户
+ $whereU = $this->getWhereByIsAgentAndUserId($adminId, $where, $userId);
+ if (!is_array($whereU)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => []]);
+ }
+
+ $changeTypeArr = UserStockLogModel::group('change_type')->column('change_type');
+
+ if (!empty($param['change_type']) && in_array($param['change_type'], $changeTypeArr)) $where['change_type'] = $param['change_type'];
+
+ // 交易对
+ if (!empty($param['stock_id'])) {
+ $where['stock_id'] = $param['stock_id'];
+ }
+
+ if (!empty($param['start_time']) && !empty($param['end_time'])) {
+ $where['create_time'] = ['between time', [$param['start_time'], $param['end_time']]];
+ }
+
+ // 列表
+ $list = UserStockLogModel::where($where)->where($whereU)->order('id', 'desc')->page($param['page'], $param['limit'])->select();
+ // 总数
+ $total = UserStockLogModel::where($where)->where($whereU)
+ ->count();
+
+ $rows = [];
+ if (!$list->isEmpty()) {
+ $rows = $list->toArray();
+ // 获取用户号
+ $userIdArr = [];
+ foreach ($list as $idItem) {
+ $userIdArr[] = $idItem['user_id'];
+ }
+
+ $userNoArr = UserModel::where('user_id', 'in', $userIdArr)->column('user_no', 'user_id');
+ foreach ($rows as $key => $item) {
+ $rows[$key]['user_no'] = $userNoArr[$item['user_id']] ?? '-'; // 用户号
+ }
+ }
+
+ return $this->toData('0', 'SUCCESS', ['total' => $total, 'list' => $rows, 'extend' => [
+ 'change_type_list' => (new BaseHomeService())->getCapitalTypeList($changeTypeArr)
+ ]]);
+ } catch (ValidateException $validateException) {
+ // 参数校验失败
+ $message = $validateException->getError();
+ return $this->toData('1', $message);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统异常 请稍后重试', [$exception->getMessage()]);
+ }
+ }
+
+
+ // 印尼股票
+ public function idnStock($param, $adminId)
+ {
+ try {
+ // 参数校验
+ validate(FlowValidate::class)->scene('idn_stock')->check($param);
+
+ $where = [];
+ $userId = 0;
+ // 用户号精确搜索
+ if (!empty($param['user_no'])) {
+ $user = UserModel::where('user_no', $param['user_no'])->find();
+ if (empty($user)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => [], ]);
+ }
+ $userId = $user['user_id'];
+ }
+
+ // 判断是否是代理 如果是代理 只能看他自己管理的用户
+ $whereU = $this->getWhereByIsAgentAndUserId($adminId, $where, $userId);
+ if (!is_array($whereU)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => []]);
+ }
+
+ $changeTypeArr = UserStockIdnLogModel::group('change_type')->column('change_type');
+
+ if (!empty($param['change_type']) && in_array($param['change_type'], $changeTypeArr)) $where['change_type'] = $param['change_type'];
+
+ // 交易对
+ if (!empty($param['stock_id'])) {
+ $where['stock_id'] = $param['stock_id'];
+ }
+
+ if (!empty($param['start_time']) && !empty($param['end_time'])) {
+ $where['create_time'] = ['between time', [$param['start_time'], $param['end_time']]];
+ }
+
+ // 列表
+ $list = UserStockIdnLogModel::where($where)->where($whereU)->order('id', 'desc')->page($param['page'], $param['limit'])->select();
+ // 总数
+ $total = UserStockIdnLogModel::where($where)->where($whereU)
+ ->count();
+
+ $rows = [];
+ if (!$list->isEmpty()) {
+ $rows = $list->toArray();
+ // 获取用户号
+ $userIdArr = [];
+ foreach ($list as $idItem) {
+ $userIdArr[] = $idItem['user_id'];
+ }
+
+ $userNoArr = UserModel::where('user_id', 'in', $userIdArr)->column('user_no', 'user_id');
+ foreach ($rows as $key => $item) {
+ $rows[$key]['user_no'] = $userNoArr[$item['user_id']] ?? '-'; // 用户号
+ }
+ }
+
+ return $this->toData('0', 'SUCCESS', ['total' => $total, 'list' => $rows, 'extend' => [
+ 'change_type_list' => (new BaseHomeService())->getCapitalTypeList($changeTypeArr)
+ ]]);
+ } catch (ValidateException $validateException) {
+ // 参数校验失败
+ $message = $validateException->getError();
+ return $this->toData('1', $message);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统异常 请稍后重试', [$exception->getMessage()]);
+ }
+ }
+
+
+ // 马来西亚
+ public function mysStock($param, $adminId)
+ {
+ try {
+ // 参数校验
+ validate(FlowValidate::class)->scene('mys_stock')->check($param);
+
+ $where = [];
+ $userId = 0;
+ // 用户号精确搜索
+ if (!empty($param['user_no'])) {
+ $user = UserModel::where('user_no', $param['user_no'])->find();
+ if (empty($user)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => [], ]);
+ }
+ $userId = $user['user_id'];
+ }
+
+ // 判断是否是代理 如果是代理 只能看他自己管理的用户
+ $whereU = $this->getWhereByIsAgentAndUserId($adminId, $where, $userId);
+ if (!is_array($whereU)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => []]);
+ }
+
+ $changeTypeArr = UserStockMysLogModel::group('change_type')->column('change_type');
+
+ if (!empty($param['change_type']) && in_array($param['change_type'], $changeTypeArr)) $where['change_type'] = $param['change_type'];
+
+ // 交易对
+ if (!empty($param['stock_id'])) {
+ $where['stock_id'] = $param['stock_id'];
+ }
+
+ if (!empty($param['start_time']) && !empty($param['end_time'])) {
+ $where['create_time'] = ['between time', [$param['start_time'], $param['end_time']]];
+ }
+
+ // 列表
+ $list = UserStockMysLogModel::where($where)->where($whereU)->order('id', 'desc')->page($param['page'], $param['limit'])->select();
+ // 总数
+ $total = UserStockMysLogModel::where($where)->where($whereU)
+ ->count();
+
+ $rows = [];
+ if (!$list->isEmpty()) {
+ $rows = $list->toArray();
+ // 获取用户号
+ $userIdArr = [];
+ foreach ($list as $idItem) {
+ $userIdArr[] = $idItem['user_id'];
+ }
+
+ $userNoArr = UserModel::where('user_id', 'in', $userIdArr)->column('user_no', 'user_id');
+ foreach ($rows as $key => $item) {
+ $rows[$key]['user_no'] = $userNoArr[$item['user_id']] ?? '-'; // 用户号
+ }
+ }
+
+ return $this->toData('0', 'SUCCESS', ['total' => $total, 'list' => $rows, 'extend' => [
+ 'change_type_list' => (new BaseHomeService())->getCapitalTypeList($changeTypeArr)
+ ]]);
+ } catch (ValidateException $validateException) {
+ // 参数校验失败
+ $message = $validateException->getError();
+ return $this->toData('1', $message);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统异常 请稍后重试', [$exception->getMessage()]);
+ }
+ }
+
+
+ // 泰国股票
+ public function thaStock($param, $adminId)
+ {
+ try {
+ // 参数校验
+ validate(FlowValidate::class)->scene('tha_stock')->check($param);
+
+ $where = [];
+ $userId = 0;
+ // 用户号精确搜索
+ if (!empty($param['user_no'])) {
+ $user = UserModel::where('user_no', $param['user_no'])->find();
+ if (empty($user)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => [], ]);
+ }
+ $userId = $user['user_id'];
+ }
+
+ // 判断是否是代理 如果是代理 只能看他自己管理的用户
+ $whereU = $this->getWhereByIsAgentAndUserId($adminId, $where, $userId);
+ if (!is_array($whereU)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => []]);
+ }
+
+ $changeTypeArr = UserStockThaLogModel::group('change_type')->column('change_type');
+
+ if (!empty($param['change_type']) && in_array($param['change_type'], $changeTypeArr)) $where['change_type'] = $param['change_type'];
+
+ // 交易对
+ if (!empty($param['stock_id'])) {
+ $where['stock_id'] = $param['stock_id'];
+ }
+
+ if (!empty($param['start_time']) && !empty($param['end_time'])) {
+ $where['create_time'] = ['between time', [$param['start_time'], $param['end_time']]];
+ }
+
+ // 列表
+ $list = UserStockThaLogModel::where($where)->where($whereU)->order('id', 'desc')->page($param['page'], $param['limit'])->select();
+ // 总数
+ $total = UserStockThaLogModel::where($where)->where($whereU)
+ ->count();
+
+ $rows = [];
+ if (!$list->isEmpty()) {
+ $rows = $list->toArray();
+ // 获取用户号
+ $userIdArr = [];
+ foreach ($list as $idItem) {
+ $userIdArr[] = $idItem['user_id'];
+ }
+
+ $userNoArr = UserModel::where('user_id', 'in', $userIdArr)->column('user_no', 'user_id');
+ foreach ($rows as $key => $item) {
+ $rows[$key]['user_no'] = $userNoArr[$item['user_id']] ?? '-'; // 用户号
+ }
+ }
+
+ return $this->toData('0', 'SUCCESS', ['total' => $total, 'list' => $rows, 'extend' => [
+ 'change_type_list' => (new BaseHomeService())->getCapitalTypeList($changeTypeArr)
+ ]]);
+ } catch (ValidateException $validateException) {
+ // 参数校验失败
+ $message = $validateException->getError();
+ return $this->toData('1', $message);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统异常 请稍后重试', [$exception->getMessage()]);
+ }
+ }
+
+
+ // 泰国股票
+ public function inStock($param, $adminId)
+ {
+ try {
+ // 参数校验
+ validate(FlowValidate::class)->scene('in_stock')->check($param);
+
+ $where = [];
+ $userId = 0;
+ // 用户号精确搜索
+ if (!empty($param['user_no'])) {
+ $user = UserModel::where('user_no', $param['user_no'])->find();
+ if (empty($user)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => [], ]);
+ }
+ $userId = $user['user_id'];
+ }
+
+ // 判断是否是代理 如果是代理 只能看他自己管理的用户
+ $whereU = $this->getWhereByIsAgentAndUserId($adminId, $where, $userId);
+ if (!is_array($whereU)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => []]);
+ }
+
+ $changeTypeArr = UserStockInLogModel::group('change_type')->column('change_type');
+
+ if (!empty($param['change_type']) && in_array($param['change_type'], $changeTypeArr)) $where['change_type'] = $param['change_type'];
+
+ // 交易对
+ if (!empty($param['stock_id'])) {
+ $where['stock_id'] = $param['stock_id'];
+ }
+
+ if (!empty($param['start_time']) && !empty($param['end_time'])) {
+ $where['create_time'] = ['between time', [$param['start_time'], $param['end_time']]];
+ }
+
+ // 列表
+ $list = UserStockInLogModel::where($where)->where($whereU)->order('id', 'desc')->page($param['page'], $param['limit'])->select();
+ // 总数
+ $total = UserStockInLogModel::where($where)->where($whereU)
+ ->count();
+
+ $rows = [];
+ if (!$list->isEmpty()) {
+ $rows = $list->toArray();
+ // 获取用户号
+ $userIdArr = [];
+ foreach ($list as $idItem) {
+ $userIdArr[] = $idItem['user_id'];
+ }
+
+ $userNoArr = UserModel::where('user_id', 'in', $userIdArr)->column('user_no', 'user_id');
+ foreach ($rows as $key => $item) {
+ $rows[$key]['user_no'] = $userNoArr[$item['user_id']] ?? '-'; // 用户号
+ }
+ }
+
+ return $this->toData('0', 'SUCCESS', ['total' => $total, 'list' => $rows, 'extend' => [
+ 'change_type_list' => (new BaseHomeService())->getCapitalTypeList($changeTypeArr)
+ ]]);
+ } catch (ValidateException $validateException) {
+ // 参数校验失败
+ $message = $validateException->getError();
+ return $this->toData('1', $message);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统异常 请稍后重试', [$exception->getMessage()]);
+ }
+ }
+
+ // 新加坡股票流水
+ public function sgdStock($param, $adminId)
+ {
+ try {
+ // 参数校验
+ validate(FlowValidate::class)->scene('sgd_stock')->check($param);
+
+ $where = [];
+ $userId = 0;
+ // 用户号精确搜索
+ if (!empty($param['user_no'])) {
+ $user = UserModel::where('user_no', $param['user_no'])->find();
+ if (empty($user)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => [], ]);
+ }
+ $userId = $user['user_id'];
+ }
+
+ // 判断是否是代理 如果是代理 只能看他自己管理的用户
+ $whereU = $this->getWhereByIsAgentAndUserId($adminId, $where, $userId);
+ if (!is_array($whereU)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => []]);
+ }
+
+ $changeTypeArr = UserStockSgdLogModel::group('change_type')->column('change_type');
+
+ if (!empty($param['change_type']) && in_array($param['change_type'], $changeTypeArr)) $where['change_type'] = $param['change_type'];
+
+ // 交易对
+ if (!empty($param['stock_id'])) {
+ $where['stock_id'] = $param['stock_id'];
+ }
+
+ if (!empty($param['start_time']) && !empty($param['end_time'])) {
+ $where['create_time'] = ['between time', [$param['start_time'], $param['end_time']]];
+ }
+
+ // 列表
+ $list = UserStockSgdLogModel::where($where)->where($whereU)->order('id', 'desc')->page($param['page'], $param['limit'])->select();
+ // 总数
+ $total = UserStockSgdLogModel::where($where)->where($whereU)->count();
+
+ $rows = [];
+ if (!$list->isEmpty()) {
+ $rows = $list->toArray();
+ // 获取用户号
+ $userIdArr = [];
+ foreach ($list as $idItem) {
+ $userIdArr[] = $idItem['user_id'];
+ }
+
+ $userNoArr = UserModel::where('user_id', 'in', $userIdArr)->column('user_no', 'user_id');
+ foreach ($rows as $key => $item) {
+ $rows[$key]['user_no'] = $userNoArr[$item['user_id']] ?? '-'; // 用户号
+ }
+ }
+
+ return $this->toData('0', 'SUCCESS', ['total' => $total, 'list' => $rows, 'extend' => [
+ 'change_type_list' => (new BaseHomeService())->getCapitalTypeList($changeTypeArr)
+ ]]);
+ } catch (ValidateException $validateException) {
+ // 参数校验失败
+ $message = $validateException->getError();
+ return $this->toData('1', $message);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统异常 请稍后重试', [$exception->getMessage()]);
+ }
+ }
+
+ // 基金流水
+ public function fundStock($param, $adminId)
+ {
+ try {
+ // 参数校验
+ validate(FlowValidate::class)->scene('fund_stock')->check($param);
+
+ $where = [];
+ $userId = 0;
+ // 用户号精确搜索
+ if (!empty($param['user_no'])) {
+ $user = UserModel::where('user_no', $param['user_no'])->find();
+ if (empty($user)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => [], ]);
+ }
+ $userId = $user['user_id'];
+ }
+
+ // 判断是否是代理 如果是代理 只能看他自己管理的用户
+ $whereU = $this->getWhereByIsAgentAndUserId($adminId, $where, $userId);
+ if (!is_array($whereU)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => []]);
+ }
+
+ $changeTypeArr = UserStockFundLogModel::group('change_type')->column('change_type');
+
+ if (!empty($param['change_type']) && in_array($param['change_type'], $changeTypeArr)) $where['change_type'] = $param['change_type'];
+
+ // 交易对
+ if (!empty($param['stock_id'])) {
+ $where['stock_id'] = $param['stock_id'];
+ }
+
+ if (!empty($param['start_time']) && !empty($param['end_time'])) {
+ $where['create_time'] = ['between time', [$param['start_time'], $param['end_time']]];
+ }
+
+ // 列表
+ $list = UserStockFundLogModel::where($where)->where($whereU)->order('id', 'desc')->page($param['page'], $param['limit'])->select();
+ // 总数
+ $total = UserStockFundLogModel::where($where)->where($whereU)->count();
+
+ $rows = [];
+ if (!$list->isEmpty()) {
+ $rows = $list->toArray();
+ // 获取用户号
+ $userIdArr = [];
+ foreach ($list as $idItem) {
+ $userIdArr[] = $idItem['user_id'];
+ }
+
+ $userNoArr = UserModel::where('user_id', 'in', $userIdArr)->column('user_no', 'user_id');
+ foreach ($rows as $key => $item) {
+ $rows[$key]['user_no'] = $userNoArr[$item['user_id']] ?? '-'; // 用户号
+ }
+ }
+
+ return $this->toData('0', 'SUCCESS', ['total' => $total, 'list' => $rows, 'extend' => [
+ 'change_type_list' => (new BaseHomeService())->getCapitalTypeList($changeTypeArr)
+ ]]);
+ } catch (ValidateException $validateException) {
+ // 参数校验失败
+ $message = $validateException->getError();
+ return $this->toData('1', $message);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统异常 请稍后重试', [$exception->getMessage()]);
+ }
+ }
+
+ // 香港股票
+ public function hkStock($param, $adminId)
+ {
+ try {
+ // 参数校验
+ validate(FlowValidate::class)->scene('hk_stock')->check($param);
+
+ $where = [];
+ $userId = 0;
+ // 用户号精确搜索
+ if (!empty($param['user_no'])) {
+ $user = UserModel::where('user_no', $param['user_no'])->find();
+ if (empty($user)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => [], ]);
+ }
+ $userId = $user['user_id'];
+ }
+
+ // 判断是否是代理 如果是代理 只能看他自己管理的用户
+ $whereU = $this->getWhereByIsAgentAndUserId($adminId, $where, $userId);
+ if (!is_array($whereU)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => []]);
+ }
+
+ $changeTypeArr = UserStockHkdLogModel::group('change_type')->column('change_type');
+
+ if (!empty($param['change_type']) && in_array($param['change_type'], $changeTypeArr)) $where['change_type'] = $param['change_type'];
+
+ // 交易对
+ if (!empty($param['stock_id'])) {
+ $where['stock_id'] = $param['stock_id'];
+ }
+
+ if (!empty($param['start_time']) && !empty($param['end_time'])) {
+ $where['create_time'] = ['between time', [$param['start_time'], $param['end_time']]];
+ }
+
+ // 列表
+ $list = UserStockHkdLogModel::where($where)->where($whereU)->order('id', 'desc')->page($param['page'], $param['limit'])->select();
+ // 总数
+ $total = UserStockHkdLogModel::where($where)->where($whereU)
+ ->count();
+
+ $rows = [];
+ if (!$list->isEmpty()) {
+ $rows = $list->toArray();
+ // 获取用户号
+ $userIdArr = [];
+ foreach ($list as $idItem) {
+ $userIdArr[] = $idItem['user_id'];
+ }
+
+ $userNoArr = UserModel::where('user_id', 'in', $userIdArr)->column('user_no', 'user_id');
+ foreach ($rows as $key => $item) {
+ $rows[$key]['user_no'] = $userNoArr[$item['user_id']] ?? '-'; // 用户号
+ }
+ }
+
+ return $this->toData('0', 'SUCCESS', ['total' => $total, 'list' => $rows, 'extend' => [
+ 'change_type_list' => (new BaseHomeService())->getCapitalTypeList($changeTypeArr)
+ ]]);
+ } catch (ValidateException $validateException) {
+ // 参数校验失败
+ $message = $validateException->getError();
+ return $this->toData('1', $message);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统异常 请稍后重试', [$exception->getMessage()]);
+ }
+ }
+ // 香港股票
+ public function StockLogs($param, $adminId)
+ {
+ try {
+ // 参数校验
+ validate(FlowValidate::class)->scene('us_stock')->check($param);
+
+ $where = [];
+ $userId = 0;
+ // 用户号精确搜索
+ if (!empty($param['user_no'])) {
+ $user = UserModel::where('user_no', $param['user_no'])->find();
+ if (empty($user)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => [], ]);
+ }
+ $userId = $user['user_id'];
+ }
+
+ // 判断是否是代理 如果是代理 只能看他自己管理的用户
+ $whereU = $this->getWhereByIsAgentAndUserId($adminId, $where, $userId);
+ if (!is_array($whereU)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => []]);
+ }
+
+ $changeTypeArr = UserStockHkdLogModel::group('change_type')->column('change_type');
+
+ if (!empty($param['change_type']) && in_array($param['change_type'], $changeTypeArr)) $where['change_type'] = $param['change_type'];
+
+ $market_type=intval($param['market_type']);
+ $table_obj=(new IPOService())->getStockModel($market_type);
+ if (empty($table_obj)) {
+ return $this->toData('1', '数据异常');
+ }
+
+ // 交易对
+ if (!empty($param['stock_id'])) {
+ $where['stock_id'] = $param['stock_id'];
+ }
+
+ if (!empty($param['start_time']) && !empty($param['end_time'])) {
+ $where['create_time'] = ['between time', [$param['start_time'], $param['end_time']]];
+ }
+
+ // 列表
+ $list = Db::table($table_obj['log_table'])->where($where)->where($whereU)->order('id', 'desc')->page($param['page'], $param['limit'])->select();
+ // 总数
+ $total = Db::table($table_obj['log_table'])->where($where)->where($whereU)
+ ->count();
+
+ $rows = [];
+ if (!$list->isEmpty()) {
+ $rows = $list->toArray();
+ // 获取用户号
+ $userIdArr = [];
+ foreach ($list as $idItem) {
+ $userIdArr[] = $idItem['user_id'];
+ }
+
+ $userNoArr = UserModel::where('user_id', 'in', $userIdArr)->column('user_no', 'user_id');
+ foreach ($rows as $key => $item) {
+ $rows[$key]['user_no'] = $userNoArr[$item['user_id']] ?? '-'; // 用户号
+ }
+ }
+
+ return $this->toData('0', 'SUCCESS', ['total' => $total, 'list' => $rows, 'extend' => [
+ 'change_type_list' => (new BaseHomeService())->getCapitalTypeList($changeTypeArr)
+ ]]);
+ } catch (ValidateException $validateException) {
+ // 参数校验失败
+ $message = $validateException->getError();
+ return $this->toData('1', $message);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统异常 请稍后重试', [$exception->getMessage(),$exception->getTrace()]);
+ }
+ }
+
+ // 印度期权
+ public function inOptionStock($param, $adminId)
+ {
+ try {
+ // 参数校验
+ validate(FlowValidate::class)->scene('hk_stock')->check($param);
+
+ $where = [];
+ $userId = 0;
+ // 用户号精确搜索
+ if (!empty($param['user_no'])) {
+ $user = UserModel::where('user_no', $param['user_no'])->find();
+ if (empty($user)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => [], ]);
+ }
+ $userId = $user['user_id'];
+ }
+
+ // 判断是否是代理 如果是代理 只能看他自己管理的用户
+ $whereU = $this->getWhereByIsAgentAndUserId($adminId, $where, $userId);
+ if (!is_array($whereU)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => []]);
+ }
+
+ $changeTypeArr = UserStockOptionInrLogModel::group('change_type')->column('change_type');
+
+ if (!empty($param['change_type']) && in_array($param['change_type'], $changeTypeArr)) $where['change_type'] = $param['change_type'];
+
+ // 交易对
+ if (!empty($param['stock_id'])) {
+ $where['stock_id'] = $param['stock_id'];
+ }
+
+
+ if (!empty($param['start_time']) && !empty($param['end_time'])) {
+ $where['create_time'] = ['between time', [$param['start_time'], $param['end_time']]];
+ }
+
+ // 列表
+ $list = UserStockOptionInrLogModel::where($where)->where($whereU)->order('id', 'desc')->page($param['page'], $param['limit'])->select();
+ // 总数
+ $total = UserStockOptionInrLogModel::where($where)->where($whereU)
+ ->count();
+
+ $rows = [];
+ if (!$list->isEmpty()) {
+ $rows = $list->toArray();
+ // 获取用户号
+ $userIdArr = [];
+ foreach ($list as $idItem) {
+ $userIdArr[] = $idItem['user_id'];
+ }
+
+ $userNoArr = UserModel::where('user_id', 'in', $userIdArr)->column('user_no', 'user_id');
+ foreach ($rows as $key => $item) {
+ $rows[$key]['user_no'] = $userNoArr[$item['user_id']] ?? '-'; // 用户号
+ }
+ }
+
+ return $this->toData('0', 'SUCCESS', ['total' => $total, 'list' => $rows, 'extend' => [
+ 'change_type_list' => (new BaseHomeService())->getCapitalTypeList($changeTypeArr)
+ ]]);
+ } catch (ValidateException $validateException) {
+ // 参数校验失败
+ $message = $validateException->getError();
+ return $this->toData('1', $message);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统异常 请稍后重试', [$exception->getMessage()]);
+ }
+ }
+
+ // 香股
+ public function blockStock($param, $adminId)
+ {
+ try {
+ // 参数校验
+ validate(FlowValidate::class)->scene('block_stock')->check($param);
+
+ $where = [];
+ $userId = 0;
+ // 用户号精确搜索
+ if (!empty($param['user_no'])) {
+ $user = UserModel::where('user_no', $param['user_no'])->find();
+ if (empty($user)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => [], ]);
+ }
+ $userId = $user['user_id'];
+ }
+
+ // 判断是否是代理 如果是代理 只能看他自己管理的用户
+ $whereU = $this->getWhereByIsAgentAndUserId($adminId, $where, $userId);
+ if (!is_array($whereU)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => []]);
+ }
+
+ $changeTypeArr = UserStockBlockLogModel::group('change_type')->column('change_type');
+
+ if (!empty($param['change_type']) && in_array($param['change_type'], $changeTypeArr)) $where['change_type'] = $param['change_type'];
+
+ // 交易对
+ if (!empty($param['stock_id'])) {
+ $where['stock_id'] = $param['stock_id'];
+ }
+
+ if (!empty($param['start_time']) && !empty($param['end_time'])) {
+ $where['create_time'] = ['between time', [$param['start_time'], $param['end_time']]];
+ }
+
+ // 列表
+ $list = UserStockBlockLogModel::where($where)->where($whereU)->order('id', 'desc')->page($param['page'], $param['limit'])->select();
+ // 总数
+ $total = UserStockBlockLogModel::where($where)->where($whereU)
+ ->count();
+
+ $rows = [];
+ if (!$list->isEmpty()) {
+ $rows = $list->toArray();
+ // 获取用户号
+ $userIdArr = [];
+ foreach ($list as $idItem) {
+ $userIdArr[] = $idItem['user_id'];
+ }
+
+ $userNoArr = UserModel::where('user_id', 'in', $userIdArr)->column('user_no', 'user_id');
+ foreach ($rows as $key => $item) {
+ $rows[$key]['user_no'] = $userNoArr[$item['user_id']] ?? '-'; // 用户号
+ }
+ }
+
+ return $this->toData('0', 'SUCCESS', ['total' => $total, 'list' => $rows, 'extend' => [
+ 'change_type_list' => (new BaseHomeService())->getCapitalTypeList($changeTypeArr)
+ ]]);
+ } catch (ValidateException $validateException) {
+ // 参数校验失败
+ $message = $validateException->getError();
+ return $this->toData('1', $message);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统异常 请稍后重试', [$exception->getMessage()]);
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/admin/service/LoginService.php b/app/admin/service/LoginService.php
new file mode 100644
index 0000000..b540274
--- /dev/null
+++ b/app/admin/service/LoginService.php
@@ -0,0 +1,100 @@
+scene('login')->check($param);
+
+ // 获取用户
+ $info = AdminModel::getByUserName($param['user_name']);
+ if(empty($info)){
+ return $this->toData('200300', 'Incorrect account or password.1', []);
+ }
+ if($info->status!==1){
+ return $this->toData('200300', '该账户已被禁用', []);
+ }
+ //查看角色状态
+ $role=AuthRoleModel::find($info->role_id);
+ if(!$role||$role->status!==1){
+ return $this->toData('200300', '该账户所在的群组已被禁用', []);
+ }
+ // 校验密码
+ $checkPasswordBool = (new UnqId())->checkPassword($param['password'], $info->password,env('ENCRYPT.ADMINSALT'));
+
+ if(!$checkPasswordBool){
+ return $this->toData('200300', 'Incorrect account or password.3', []);
+ }
+ $token = (new Jwt())->generateToken($info->id);
+
+ if(empty($token)){
+ return $this->toData('200400', 'The system is busy. Please try again later.1', []);
+ }
+
+ //保存token
+ $info->token=$token;
+ $info->save();
+
+// $key = 'TOKEN:USER:'.$token;
+// $expired = 3600*24;
+// Cache::store('redis')->set($key, 9999999999, $expired);
+
+ $info=$info->toArray();
+ $this->setUserTokenCache($token, $info['id']);
+
+ // 返回结果以及用户信息
+ return $this->toData('0', 'Request successful.', [
+ 'id' => $info['id'],
+ 'nickname' => $info['nick_name'],
+ 'email' => $info['email'],
+ 'token' => $token,
+ ]);
+ }catch (ValidateException $validateException) {
+ // 参数校验失败 异常类
+ $message = $validateException->getError();
+ return $this->toData('100400', $message);
+ }catch (\Exception $exception){
+
+ return $this->toData('200500', 'The system is busy. Please try again later.', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+
+ public function setUserTokenCache($token, $userId)
+ {
+ // 清除之前的token 设置新的token
+ $userTokenKey = 'USER:TOKEN:'.$userId; // 根据用户id 查找token
+ $oldToken = Cache::store('redis')->get($userTokenKey);
+ if($oldToken){
+ $oldTokenKey = 'TOKEN:USER:'.$oldToken;
+ Cache::store('redis')->delete($oldTokenKey);
+ }
+
+ //trace('---设置用户登陆凭证--'.$userId.'----'.$token, 'error');
+
+ $tokenKey = 'TOKEN:USER:'.$token; // 根据token查找用户id
+ $expired = 30 * 24 * 60 * 60;
+ // 由中间件自动续期
+ Cache::store('redis')->set($tokenKey, $userId, $expired);
+ Cache::store('redis')->set($userTokenKey, $token, $expired);
+
+ }
+
+}
\ No newline at end of file
diff --git a/app/admin/service/OrderService.php b/app/admin/service/OrderService.php
new file mode 100644
index 0000000..8a91f7c
--- /dev/null
+++ b/app/admin/service/OrderService.php
@@ -0,0 +1,2897 @@
+scene('digitalPlace')->check($param);
+
+ $where = [];
+ $userId = 0;
+ // 用户号精确搜索
+ if (!empty($param['user_no'])) {
+ $user = UserModel::where('user_no', $param['user_no'])->find();
+ if (empty($user)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => [], 'extent' => ['totalMoney' => 0]]);
+ }
+ $userId = $user['user_id'];
+ }
+
+ // 判断是否是代理 如果是代理 只能看他自己管理的用户
+ $where = $this->getWhereByIsAgentAndUserId($adminId, $where, $userId);
+ if (!is_array($where)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => [], 'extent' => ['totalMoney' => 0]]);
+ }
+ if (!empty($where['user_id']) && is_numeric($where['user_id']) && $where['user_id'] == 0) {
+ return $this->toData('1', 'SUCCESS', ['total' => 0, 'list' => [], 'extent' => ['totalMoney' => 0,
+ ]]);
+ }
+
+ // 订单号
+ if (!empty($param['order_id'])) {
+ $where['order_id'] = $param['order_id'];
+ }
+
+ // 交易对
+ if (!empty($param['digital_id'])) {
+ $where['digital_id'] = $param['digital_id'];
+ }
+
+ if (!empty($param['start_time']) && !empty($param['end_time'])) {
+ $where['create_time'] = ['between time', [$param['start_time'], $param['end_time']]];
+ }
+
+ // 列表
+ $list = DigitalTradeModel::where('status', DigitalTradeModel::STATUS_PLACE)->where($where)->order('trade_id', 'desc')->page($param['page'], $param['limit'])->select();
+ // 总数
+ $total = DigitalTradeModel::where('status', DigitalTradeModel::STATUS_PLACE)
+ ->where($where)
+ ->count();
+ // 持仓总金额
+ $totalModel = DigitalTradeModel::where('status', DigitalTradeModel::STATUS_PLACE)
+ ->field('SUM(order_money) as total')
+ ->where($where)->find();
+
+ $rows = [];
+ if (!$list->isEmpty()) {
+ // 获取用户号
+ $userIdArr = [];
+ foreach ($list as $idItem) {
+ $userIdArr[] = $idItem['user_id'];
+ }
+
+ $userNoArr = UserModel::where('user_id', 'in', $userIdArr)->column('user_no', 'user_id');
+ foreach ($list as $item) {
+ $rows[] = [
+ 'user_no' => $userNoArr[$item['user_id']] ?? '-', // 用户号
+ 'order_id' => $item['order_id'], // 用户号
+ 'trade_id' => $item['trade_id'], //
+ 'trade_type' => $item['trade_type'], //
+ 'trade_type_name' => $item['trade_type'] == DigitalTradeModel::TRADE_TYPE_BUY ? '买入' : '卖出', //交易类型
+ 'create_time' => $item['create_time'], // 挂单时间
+ 'order_money' => $item['order_money'], // 订单金额
+ 'digital_id' => $item['digital_id'], // 股票代码
+ 'order_number' => $item['order_number'], // 数量
+ 'service_cost' => $item['service_cost'], // 服务费
+ 'deal_price' => $item['deal_price'], // 开仓价
+ ];
+ }
+ }
+
+ return $this->toData('0', 'SUCCESS', ['total' => $total, 'list' => $rows,
+ 'extent' => ['totalMoney' => round($totalModel['total'], 4),
+ ]]);
+
+ } catch (ValidateException $validateException) {
+ // 参数校验失败
+ $message = $validateException->getError();
+ return $this->toData('1', $message);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统异常 请稍后重试', [$exception->getMessage(), $exception->getTrace()]);
+ }
+
+ }
+
+ // 现货撤单
+ public function digitalBack($param, $adminId)
+ {
+ try {
+ // 参数校验
+ validate(OrderValidate::class)->scene('digitalBack')->check($param);
+
+ $where = [];
+ $userId = 0;
+ // 用户号精确搜索
+ if (!empty($param['user_no'])) {
+ $user = UserModel::where('user_no', $param['user_no'])->find();
+ if (empty($user)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => [], 'extent' => ['totalMoney' => 0]]);
+ }
+ $userId = $user['user_id'];
+ }
+
+ // 判断是否是代理 如果是代理 只能看他自己管理的用户
+ $whereU = $this->getWhereByIsAgentAndUserId($adminId, $where, $userId);
+ if (!is_array($whereU)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => [], 'extent' => ['totalMoney' => 0]]);
+ }
+
+ // 订单号
+ if (!empty($param['order_id'])) {
+ $where['order_id'] = $param['order_id'];
+ }
+
+ // 交易对
+ if (!empty($param['digital_id'])) {
+ $where['digital_id'] = $param['digital_id'];
+ }
+
+ if (!empty($param['start_time']) && !empty($param['end_time'])) {
+ $where['create_time'] = ['between time', [$param['start_time'], $param['end_time']]];
+ }
+
+ // 列表
+ $list = DigitalTradeModel::where('status', DigitalTradeModel::STATUS_BACk)
+ ->where($where)->where($whereU)
+ ->order('trade_id', 'desc')
+ ->page($param['page'], $param['limit'])->select();
+ // 总数
+ $total = DigitalTradeModel::where('status', DigitalTradeModel::STATUS_BACk)
+ ->where($where)->where($whereU)
+ ->count();
+ // 持仓总金额
+ $totalModel = DigitalTradeModel::where('status', DigitalTradeModel::STATUS_BACk)
+ ->field('SUM(order_money) as total')
+ ->where($where)->where($whereU)->find();
+
+ $rows = [];
+ if (!$list->isEmpty()) {
+ // 获取用户号
+ $userIdArr = [];
+ foreach ($list as $idItem) {
+ $userIdArr[] = $idItem['user_id'];
+ }
+
+ $userNoArr = UserModel::where('user_id', 'in', $userIdArr)->column('user_no', 'user_id');
+ foreach ($list as $item) {
+ $rows[] = [
+ 'trade_id' => $item['trade_id'], //
+ 'order_id' => $item['order_id'], // 用户号
+ 'user_no' => $userNoArr[$item['user_id']] ?? '-', // 用户号
+ 'trade_type' => $item['trade_type'], //
+ 'trade_type_name' => $item['trade_type'] == DigitalTradeModel::TRADE_TYPE_BUY ? '买入' : '卖出', //交易类型
+ 'create_time' => $item['create_time'], // 挂单时间
+ 'update_time' => $item['update_time'], // 撤单时间
+ 'order_money' => $item['order_money'], // 订单金额
+ 'digital_id' => $item['digital_id'], // 股票代码
+ 'order_number' => $item['order_number'], // 数量
+ 'service_cost' => $item['service_cost'], // 服务费
+ 'deal_price' => $item['deal_price'], // 开仓价
+ ];
+ }
+ }
+
+ return $this->toData('0', 'SUCCESS', ['total' => $total, 'list' => $rows,
+ 'extent' => ['totalMoney' => round($totalModel['total'], 4),
+ ]]);
+
+ } catch (ValidateException $validateException) {
+ // 参数校验失败
+ $message = $validateException->getError();
+ return $this->toData('1', $message);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统异常 请稍后重试', [$exception->getMessage(), $exception->getTrace()]);
+ }
+
+ }
+
+ // 现货订单
+ public function digitalDeal($param, $adminId)
+ {
+ try {
+ // 参数校验
+ validate(OrderValidate::class)->scene('digitalDeal')->check($param);
+
+ $where = [];
+ $userId = 0;
+ // 用户号精确搜索
+ if (!empty($param['user_no'])) {
+ $user = UserModel::where('user_no', $param['user_no'])->find();
+ if (empty($user)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => [], 'extent' => ['totalMoney' => 0]]);
+ }
+ $userId = $user['user_id'];
+ }
+
+ // 判断是否是代理 如果是代理 只能看他自己管理的用户
+ $whereU = $this->getWhereByIsAgentAndUserId($adminId, $where, $userId);
+ if (!is_array($whereU)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => [], 'extent' => ['totalMoney' => 0]]);
+ }
+
+ // 订单号
+ if (!empty($param['order_id'])) {
+ $where['order_id'] = $param['order_id'];
+ }
+
+ // 交易对
+ if (!empty($param['digital_id'])) {
+ $where['digital_id'] = $param['digital_id'];
+ }
+
+ if (!empty($param['start_time']) && !empty($param['end_time'])) {
+ $where['create_time'] = ['between time', [$param['start_time'], $param['end_time']]];
+ }
+
+ // 列表
+ $list = DigitalTradeModel::where('status', DigitalTradeModel::STATUS_SUCCESS)
+ ->where($where)->where($whereU)
+ ->order('trade_id', 'desc')
+ ->page($param['page'], $param['limit'])->select();
+ // 总数
+ $total = DigitalTradeModel::where('status', DigitalTradeModel::STATUS_SUCCESS)
+ ->where($where)->where($whereU)
+ ->count();
+ // 持仓总金额
+ $totalModel = DigitalTradeModel::where('status', DigitalTradeModel::STATUS_SUCCESS)
+ ->field('SUM(order_money) as total')
+ ->where($where)->where($whereU)->find();
+
+ $rows = [];
+ if (!$list->isEmpty()) {
+ // 获取用户号
+ $userIdArr = [];
+ foreach ($list as $idItem) {
+ $userIdArr[] = $idItem['user_id'];
+ }
+
+ $userNoArr = UserModel::where('user_id', 'in', $userIdArr)->column('user_no', 'user_id');
+ foreach ($list as $item) {
+ $rows[] = [
+ 'trade_id' => $item['trade_id'], //
+ 'order_id' => $item['order_id'], // 用户号
+ 'user_no' => $userNoArr[$item['user_id']] ?? '-', // 用户号
+ 'trade_type' => $item['trade_type'], //
+ 'trade_type_name' => $item['trade_type'] == DigitalTradeModel::TRADE_TYPE_BUY ? '买入' : '卖出', //交易类型
+ 'create_time' => $item['create_time'], // 挂单时间
+ 'closing_time' => $item['closing_time'], // 完成时间
+ 'order_money' => $item['order_money'], // 订单金额
+ 'digital_id' => $item['digital_id'], // 股票代码
+ 'order_number' => $item['order_number'], // 数量
+ 'service_cost' => $item['closing_cost'], // 服务费
+ 'deal_price' => $item['closing_price'], // 平仓价
+ ];
+ }
+ }
+
+ return $this->toData('0', 'SUCCESS', ['total' => $total, 'list' => $rows,
+ 'extent' => ['totalMoney' => round($totalModel['total'], 4),
+ ]]);
+
+ } catch (ValidateException $validateException) {
+ // 参数校验失败
+ $message = $validateException->getError();
+ return $this->toData('1', $message);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统异常 请稍后重试', [$exception->getMessage(), $exception->getTrace()]);
+ }
+
+ }
+
+
+ ######################################## 外汇交易 #######################################
+
+ // 合约持仓
+ public function forexHold($param, $adminId)
+ {
+ try {
+ // 参数校验
+ validate(OrderValidate::class)->scene('forexHold')->check($param);
+
+ $where = [];
+ $userId = 0;
+ // 用户号精确搜索
+ if (!empty($param['user_no'])) {
+ $user = UserModel::where('user_no', $param['user_no'])->find();
+ if (empty($user)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => [], 'extent' => ['totalMoney' => 0]]);
+ }
+ $userId = $user['user_id'];
+ }
+
+ // 判断是否是代理 如果是代理 只能看他自己管理的用户
+ $whereU = $this->getWhereByIsAgentAndUserId($adminId, $where, $userId);
+ if (!is_array($whereU)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => [], 'extent' => ['totalMoney' => 0]]);
+ }
+
+ // 订单号
+ if (!empty($param['order_id'])) {
+ $where['order_id'] = $param['order_id'];
+ }
+
+ // 交易对
+ if (!empty($param['contract_id'])) {
+ $where['contract_id'] = $param['contract_id'];
+ }
+
+ if (!empty($param['start_time']) && !empty($param['end_time'])) {
+ $where['open_time'] = ['between time', [$param['start_time'], $param['end_time']]];
+ }
+
+ // 列表
+ $list = ForexTradeModel::where('status', ForexTradeModel::STATUS_HOLD)->where($where)->where($whereU)->order('trade_id', 'desc')->page($param['page'], $param['limit'])->select();
+ // 总数
+ $total = ForexTradeModel::where('status', ForexTradeModel::STATUS_HOLD)
+ ->where($where)->where($whereU)
+ ->count();
+ // 持仓总金额
+ $totalModel = ForexTradeModel::where('status', ForexTradeModel::STATUS_HOLD)
+ ->field('SUM(order_money) as total')
+ ->where($where)->where($whereU)->find();
+
+ // 持仓总手续费
+ $totalServiceCost = ForexTradeModel::where('status', ForexTradeModel::STATUS_HOLD)
+ ->where($where)->where($whereU)
+ ->sum('service_cost');
+
+ $rows = [];
+ if (!$list->isEmpty()) {
+ // 获取用户号
+ $userIdArr = [];
+ foreach ($list as $idItem) {
+ $userIdArr[] = $idItem['user_id'];
+ }
+
+ $userNoArr = UserModel::where('user_id', 'in', $userIdArr)->column('user_no', 'user_id');
+ foreach ($list as $item) {
+ $rows[] = [
+ 'trade_id' => $item['trade_id'], //
+ 'user_no' => $userNoArr[$item['user_id']] ?? '-', // 用户号
+ 'order_id' => $item['order_id'], // 用户号
+ 'open_time' => $item['open_time'], // 挂单时间
+ 'trade_type' => $item['trade_type'] == 1 ? '买涨' : '买跌',
+ 'order_money' => $item['order_money'], // 订单金额
+ 'contract_id' => $item['contract_id'], // 合约代码
+ 'order_number' => $item['order_number'], // 数量
+ 'service_cost' => $item['service_cost'], // 服务费
+ 'float' => '-', // 浮动盈亏
+ 'face_value' => $item['face_value'], // 浮动盈亏
+ 'deal_price' => $item['deal_price'], // 开仓价
+ 'now_price' => '-', // 当前价
+ 'stop_loss_price' => $item['stop_loss_price'], // 止损价
+ 'stop_win_price' => $item['stop_win_price'], // 止盈价
+ 'pry_num' => $item['pry_num'], // 杠杆
+ ];
+ }
+ }
+
+ return $this->toData('0', 'SUCCESS', ['total' => $total, 'list' => $rows,
+ 'extent' => ['totalMoney' => round($totalModel['total'], 4), 'totalServiceCost' => $totalServiceCost,
+ ]]);
+
+ } catch (ValidateException $validateException) {
+ // 参数校验失败
+ $message = $validateException->getError();
+ return $this->toData('1', $message);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统异常 请稍后重试', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+
+ // 合约持仓
+ public function forexPlace($param, $adminId)
+ {
+ try {
+ // 参数校验
+ validate(OrderValidate::class)->scene('forexPlace')->check($param);
+
+ $where = [];
+ $userId = 0;
+ // 用户号精确搜索
+ if (!empty($param['user_no'])) {
+ $user = UserModel::where('user_no', $param['user_no'])->find();
+ if (empty($user)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => [], 'extent' => ['totalMoney' => 0]]);
+ }
+ $userId = $user['user_id'];
+ }
+
+ // 判断是否是代理 如果是代理 只能看他自己管理的用户
+ $whereU = $this->getWhereByIsAgentAndUserId($adminId, $where, $userId);
+ if (!is_array($whereU)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => [], 'extent' => ['totalMoney' => 0]]);
+ }
+
+ // 订单号
+ if (!empty($param['order_id'])) {
+ $where['order_id'] = $param['order_id'];
+ }
+
+ // 交易对
+ if (!empty($param['contract_id'])) {
+ $where['contract_id'] = $param['contract_id'];
+ }
+
+ if (!empty($param['start_time']) && !empty($param['end_time'])) {
+ $where['create_time'] = ['between time', [$param['start_time'], $param['end_time']]];
+ }
+
+ // 列表
+ $list = ForexTradeModel::where('status', ForexTradeModel::STATUS_PLACE)->where($where)->where($whereU)->order('trade_id', 'desc')->page($param['page'], $param['limit'])->select();
+ // 总数
+ $total = ForexTradeModel::where('status', ForexTradeModel::STATUS_PLACE)
+ ->where($where)->where($whereU)
+ ->count();
+ // 持仓总金额
+ $totalModel = ForexTradeModel::where('status', ForexTradeModel::STATUS_PLACE)
+ ->field('SUM(order_money) as total')->where($whereU)
+ ->where($where)->find();
+
+ $rows = [];
+ if (!$list->isEmpty()) {
+ // 获取用户号
+ $userIdArr = [];
+ foreach ($list as $idItem) {
+ $userIdArr[] = $idItem['user_id'];
+ }
+
+ $userNoArr = UserModel::where('user_id', 'in', $userIdArr)->column('user_no', 'user_id');
+ foreach ($list as $item) {
+ $rows[] = [
+ 'trade_id' => $item['trade_id'], //
+ 'order_id' => $item['order_id'], // 订单号
+ 'user_no' => $userNoArr[$item['user_id']] ?? '-', // 用户号
+ 'create_time' => $item['create_time'], // 挂单时间
+ 'order_money' => $item['order_money'], // 订单金额
+ 'trade_type' => $item['trade_type'] == 1 ? '买涨' : '买跌',
+ 'contract_id' => $item['contract_id'], // 合约代码
+ 'order_number' => $item['order_number'], // 数量
+ 'service_cost' => $item['service_cost'], // 服务费
+ 'deal_price' => $item['deal_price'], // 开仓价
+ 'stop_loss_price' => $item['stop_loss_price'], // 止损价
+ 'stop_win_price' => $item['stop_win_price'], // 止盈价
+ 'face_value' => $item['face_value'], // 面值
+ 'pry_num' => $item['pry_num'], // 杠杆
+ 'limit_price' => $item['limit_price'], // 杠杆
+ ];
+ }
+ }
+
+ return $this->toData('0', 'SUCCESS', ['total' => $total, 'list' => $rows,
+ 'extent' => ['totalMoney' => round($totalModel['total'], 4),
+ ]]);
+
+ } catch (ValidateException $validateException) {
+ // 参数校验失败
+ $message = $validateException->getError();
+ return $this->toData('1', $message);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统异常 请稍后重试', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+
+ // 合约撤单
+ public function forexBack($param, $adminId)
+ {
+ try {
+ // 参数校验
+ validate(OrderValidate::class)->scene('forexBack')->check($param);
+
+ $where = [];
+ $userId = 0;
+ // 用户号精确搜索
+ if (!empty($param['user_no'])) {
+ $user = UserModel::where('user_no', $param['user_no'])->find();
+ if (empty($user)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => [], 'extent' => ['totalMoney' => 0]]);
+ }
+ $userId = $user['user_id'];
+ }
+
+ // 判断是否是代理 如果是代理 只能看他自己管理的用户
+ $whereU = $this->getWhereByIsAgentAndUserId($adminId, $where, $userId);
+ if (!is_array($whereU)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => [], 'extent' => ['totalMoney' => 0]]);
+ }
+
+ // 订单号
+ if (!empty($param['order_id'])) {
+ $where['order_id'] = $param['order_id'];
+ }
+
+ // 交易对
+ if (!empty($param['contract_id'])) {
+ $where['contract_id'] = $param['contract_id'];
+ }
+
+ if (!empty($param['start_time']) && !empty($param['end_time'])) {
+ $where['update_time'] = ['between time', [$param['start_time'], $param['end_time']]];
+ }
+
+ // 列表
+ $list = ForexTradeModel::where('status', ForexTradeModel::STATUS_BACK)->where($whereU)->where($where)->order('trade_id', 'desc')->page($param['page'], $param['limit'])->select();
+ // 总数
+ $total = ForexTradeModel::where('status', ForexTradeModel::STATUS_BACK)
+ ->where($where)->where($whereU)
+ ->count();
+ // 持仓总金额
+ $totalModel = ForexTradeModel::where('status', ForexTradeModel::STATUS_BACK)
+ ->field('SUM(order_money) as total')->where($whereU)
+ ->where($where)->find();
+
+
+ $rows = [];
+ if (!$list->isEmpty()) {
+ // 获取用户号
+ $userIdArr = [];
+ foreach ($list as $idItem) {
+ $userIdArr[] = $idItem['user_id'];
+ }
+
+ $userNoArr = UserModel::where('user_id', 'in', $userIdArr)->column('user_no', 'user_id');
+ foreach ($list as $item) {
+ $rows[] = [
+ 'trade_id' => $item['trade_id'], //
+ 'user_no' => $userNoArr[$item['user_id']] ?? '-', // 用户号
+ 'order_id' => $item['order_id'], // 用户号
+ 'create_time' => $item['create_time'], // 挂单时间
+ 'update_time' => $item['update_time'], // 挂单时间
+ 'trade_type' => $item['trade_type'] == 1 ? '买涨' : '买跌',
+ 'order_money' => $item['order_money'], // 订单金额
+ 'contract_id' => $item['contract_id'], // 合约代码
+ 'order_number' => $item['order_number'], // 数量
+ 'service_cost' => $item['service_cost'], // 服务费
+ 'face_value' => $item['face_value'], // 浮动盈亏
+ 'stop_loss_price' => $item['stop_loss_price'], // 止损价
+ 'stop_win_price' => $item['stop_win_price'], // 止盈价
+ 'price' => $item['deal_type'] == 1 ? $item['limit_price'] : $item['market_price'], // 价格
+ 'pry_num' => $item['pry_num'], // 杠杆
+ ];
+ }
+ }
+
+ return $this->toData('0', 'SUCCESS', ['total' => $total, 'list' => $rows,
+ 'extent' => ['totalMoney' => round($totalModel['total'], 4),
+ ]]);
+
+ } catch (ValidateException $validateException) {
+ // 参数校验失败
+ $message = $validateException->getError();
+ return $this->toData('1', $message);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统异常 请稍后重试', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+
+ // 合约持仓
+ public function forexClear($param, $adminId)
+ {
+ try {
+ // 参数校验
+ validate(OrderValidate::class)->scene('forexClear')->check($param);
+
+ $where = [];
+ $userId = 0;
+ // 用户号精确搜索
+ if (!empty($param['user_no'])) {
+ $user = UserModel::where('user_no', $param['user_no'])->find();
+ if (empty($user)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => [], 'extent' => ['totalMoney' => 0]]);
+ }
+ $userId = $user['user_id'];
+ }
+
+ // 判断是否是代理 如果是代理 只能看他自己管理的用户
+ $whereU = $this->getWhereByIsAgentAndUserId($adminId, $where, $userId);
+ if (!is_array($whereU)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => [], 'extent' => ['totalMoney' => 0]]);
+ }
+
+ // 订单号
+ if (!empty($param['order_id'])) {
+ $where['order_id'] = $param['order_id'];
+ }
+
+ // 交易对
+ if (!empty($param['contract_id'])) {
+ $where['contract_id'] = $param['contract_id'];
+ }
+
+ if (!empty($param['start_time']) && !empty($param['end_time'])) {
+ $where['open_time'] = ['between time', [$param['start_time'], $param['end_time']]];
+ }
+
+ // 列表
+ $list = ForexTradeModel::where('status', ForexTradeModel::STATUS_CLEAR)->where($whereU)->where($where)->order('trade_id', 'desc')->page($param['page'], $param['limit'])->select();
+ // 总数
+ $total = ForexTradeModel::where('status', ForexTradeModel::STATUS_CLEAR)->where($whereU)
+ ->where($where)
+ ->count();
+
+ // 持仓总手续费
+ $totalClosingCost = ForexTradeModel::where('status', ForexTradeModel::STATUS_CLEAR)
+ ->where($whereU)
+ ->where($where)
+ ->sum('closing_cost');
+
+ $totalFloat = ForexTradeModel::where('status', ForexTradeModel::STATUS_CLEAR)
+ ->where($whereU)
+ ->where($where)
+ ->field("SUM( CASE WHEN trade_type = 1 THEN ( closing_price - deal_price )* order_number ELSE ( deal_price - closing_price )* order_number END ) AS total")->find();
+
+ $rows = [];
+ if (!$list->isEmpty()) {
+ // 获取用户号
+ $userIdArr = [];
+ foreach ($list as $idItem) {
+ $userIdArr[] = $idItem['user_id'];
+ }
+
+ $userNoArr = UserModel::where('user_id', 'in', $userIdArr)->column('user_no', 'user_id');
+ foreach ($list as $item) {
+ // 计算浮动盈亏
+ if ($item['trade_type'] == 1) {
+ $float = $item['closing_price'] - $item['deal_price'];
+ } else {
+ $float = $item['deal_price'] - $item['closing_price'];
+ }
+
+ // * 仓位
+ $float = @bcmul($float, $item['order_number'], 10);
+ // * 面值
+ $float = @bcmul($float, $item['face_value'], 6);
+
+ $rows[] = [
+ 'trade_id' => $item['trade_id'], //
+ 'user_no' => $userNoArr[$item['user_id']] ?? '-', // 用户号
+ 'order_id' => $item['order_id'], // 用户号
+ 'closing_time' => $item['closing_time'], // 平仓时间
+ 'trade_type' => $item['trade_type'] == 1 ? '买涨' : '买跌',
+ 'order_money' => $item['order_money'], // 订单金额
+ 'contract_id' => $item['contract_id'], // 合约代码
+ 'order_number' => $item['order_number'], // 数量
+ 'service_cost' => $item['service_cost'], // 服务费
+ 'closing_cost' => $item['closing_cost'], // 平仓服务费
+ 'face_value' => $item['face_value'], //
+ 'deal_price' => $item['deal_price'], // 开仓价
+ 'closing_price' => $item['closing_price'], // 平仓价格
+ 'stop_loss_price' => $item['stop_loss_price'], // 止损价
+ 'stop_win_price' => $item['stop_win_price'], // 止盈价
+ 'float' => $float, // 平仓盈亏
+ 'pry_num' => $item['pry_num'], // 杠杆
+ ];
+ }
+ }
+
+ return $this->toData('0', 'SUCCESS', ['total' => $total, 'list' => $rows,
+ 'extent' => [
+ 'totalClosingCost' => $totalClosingCost,
+ 'totalFloat' => $totalFloat['total'],
+ ]]);
+
+ } catch (ValidateException $validateException) {
+ // 参数校验失败
+ $message = $validateException->getError();
+ return $this->toData('1', $message);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统异常 请稍后重试', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+
+
+ ######################################## 合约交易 #######################################
+
+ // 合约持仓
+ public function contractHold($param, $adminId)
+ {
+ try {
+ // 参数校验
+ validate(OrderValidate::class)->scene('contractHold')->check($param);
+
+ $where = [];
+ $userId = 0;
+ // 用户号精确搜索
+ if (!empty($param['user_no'])) {
+ $user = UserModel::where('user_no', $param['user_no'])->find();
+ if (empty($user)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => [], 'extent' => ['totalMoney' => 0]]);
+ }
+ $userId = $user['user_id'];
+ }
+
+ // 判断是否是代理 如果是代理 只能看他自己管理的用户
+ $whereU = $this->getWhereByIsAgentAndUserId($adminId, $where, $userId);
+ if (!is_array($whereU)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => [], 'extent' => ['totalMoney' => 0]]);
+ }
+
+ // 订单号
+ if (!empty($param['order_id'])) {
+ $where['order_id'] = $param['order_id'];
+ }
+
+ // 交易对
+ if (!empty($param['contract_id'])) {
+ $where['contract_id'] = $param['contract_id'];
+ }
+
+ if (!empty($param['start_time']) && !empty($param['end_time'])) {
+ $where['open_time'] = ['between time', [$param['start_time'], $param['end_time']]];
+ }
+
+ // 列表
+ $list = ContractTradeModel::where('status', ContractTradeModel::STATUS_HOLD)->where($where)->where($whereU)->order('trade_id', 'desc')->page($param['page'], $param['limit'])->select();
+ // 总数
+ $total = ContractTradeModel::where('status', ContractTradeModel::STATUS_HOLD)
+ ->where($where)->where($whereU)
+ ->count();
+ // 持仓总金额
+ $totalModel = ContractTradeModel::where('status', ContractTradeModel::STATUS_HOLD)
+ ->field('SUM(order_money) as total')
+ ->where($where)->where($whereU)->find();
+
+ // 持仓总手续费
+ $totalServiceCost = ContractTradeModel::where('status', ContractTradeModel::STATUS_HOLD)
+ ->where($where)->where($whereU)
+ ->sum('service_cost');
+
+ $rows = [];
+ if (!$list->isEmpty()) {
+ // 获取用户号
+ $userIdArr = [];
+ foreach ($list as $idItem) {
+ $userIdArr[] = $idItem['user_id'];
+ }
+
+ $userNoArr = UserModel::where('user_id', 'in', $userIdArr)->column('user_no', 'user_id');
+ foreach ($list as $item) {
+ $rows[] = [
+ 'trade_id' => $item['trade_id'], //
+ 'user_no' => $userNoArr[$item['user_id']] ?? '-', // 用户号
+ 'order_id' => $item['order_id'], // 用户号
+ 'open_time' => $item['open_time'], // 挂单时间
+ 'trade_type' => $item['trade_type'] == 1 ? '买涨' : '买跌',
+ 'order_money' => $item['order_money'], // 订单金额
+ 'contract_id' => $item['contract_id'], // 合约代码
+ 'order_number' => $item['order_number'], // 数量
+ 'service_cost' => $item['service_cost'], // 服务费
+ 'float' => '-', // 浮动盈亏
+ 'face_value' => $item['face_value'], // 浮动盈亏
+ 'deal_price' => $item['deal_price'], // 开仓价
+ 'now_price' => '-', // 当前价
+ 'stop_loss_price' => $item['stop_loss_price'], // 止损价
+ 'stop_win_price' => $item['stop_win_price'], // 止盈价
+ 'pry_num' => $item['pry_num'], // 杠杆
+ ];
+ }
+ }
+
+ return $this->toData('0', 'SUCCESS', ['total' => $total, 'list' => $rows,
+ 'extent' => ['totalMoney' => round($totalModel['total'], 4), 'totalServiceCost' => $totalServiceCost,
+ ]]);
+
+ } catch (ValidateException $validateException) {
+ // 参数校验失败
+ $message = $validateException->getError();
+ return $this->toData('1', $message);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统异常 请稍后重试', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+
+ // 合约持仓
+ public function contractPlace($param, $adminId)
+ {
+ try {
+ // 参数校验
+ validate(OrderValidate::class)->scene('contractPlace')->check($param);
+
+ $where = [];
+ $userId = 0;
+ // 用户号精确搜索
+ if (!empty($param['user_no'])) {
+ $user = UserModel::where('user_no', $param['user_no'])->find();
+ if (empty($user)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => [], 'extent' => ['totalMoney' => 0]]);
+ }
+ $userId = $user['user_id'];
+ }
+
+ // 判断是否是代理 如果是代理 只能看他自己管理的用户
+ $whereU = $this->getWhereByIsAgentAndUserId($adminId, $where, $userId);
+ if (!is_array($whereU)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => [], 'extent' => ['totalMoney' => 0]]);
+ }
+
+ // 订单号
+ if (!empty($param['order_id'])) {
+ $where['order_id'] = $param['order_id'];
+ }
+
+ // 交易对
+ if (!empty($param['contract_id'])) {
+ $where['contract_id'] = $param['contract_id'];
+ }
+
+ if (!empty($param['start_time']) && !empty($param['end_time'])) {
+ $where['create_time'] = ['between time', [$param['start_time'], $param['end_time']]];
+ }
+
+ // 列表
+ $list = ContractTradeModel::where('status', ContractTradeModel::STATUS_PLACE)->where($where)->where($whereU)->order('trade_id', 'desc')->page($param['page'], $param['limit'])->select();
+ // 总数
+ $total = ContractTradeModel::where('status', ContractTradeModel::STATUS_PLACE)
+ ->where($where)->where($whereU)
+ ->count();
+ // 持仓总金额
+ $totalModel = ContractTradeModel::where('status', ContractTradeModel::STATUS_PLACE)
+ ->field('SUM(order_money) as total')->where($whereU)
+ ->where($where)->find();
+
+ $rows = [];
+ if (!$list->isEmpty()) {
+ // 获取用户号
+ $userIdArr = [];
+ foreach ($list as $idItem) {
+ $userIdArr[] = $idItem['user_id'];
+ }
+
+ $userNoArr = UserModel::where('user_id', 'in', $userIdArr)->column('user_no', 'user_id');
+ foreach ($list as $item) {
+ $rows[] = [
+ 'trade_id' => $item['trade_id'], //
+ 'order_id' => $item['order_id'], // 订单号
+ 'user_no' => $userNoArr[$item['user_id']] ?? '-', // 用户号
+ 'create_time' => $item['create_time'], // 挂单时间
+ 'order_money' => $item['order_money'], // 订单金额
+ 'trade_type' => $item['trade_type'] == 1 ? '买涨' : '买跌',
+ 'contract_id' => $item['contract_id'], // 合约代码
+ 'order_number' => $item['order_number'], // 数量
+ 'service_cost' => $item['service_cost'], // 服务费
+ 'deal_price' => $item['deal_price'], // 开仓价
+ 'stop_loss_price' => $item['stop_loss_price'], // 止损价
+ 'stop_win_price' => $item['stop_win_price'], // 止盈价
+ 'face_value' => $item['face_value'], // 面值
+ 'pry_num' => $item['pry_num'], // 杠杆
+ 'limit_price' => $item['limit_price'], // 杠杆
+ ];
+ }
+ }
+
+ return $this->toData('0', 'SUCCESS', ['total' => $total, 'list' => $rows,
+ 'extent' => ['totalMoney' => round($totalModel['total'], 4),
+ ]]);
+
+ } catch (ValidateException $validateException) {
+ // 参数校验失败
+ $message = $validateException->getError();
+ return $this->toData('1', $message);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统异常 请稍后重试', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+
+ // 合约撤单
+ public function contractBack($param, $adminId)
+ {
+ try {
+ // 参数校验
+ validate(OrderValidate::class)->scene('contractBack')->check($param);
+
+ $where = [];
+ $userId = 0;
+ // 用户号精确搜索
+ if (!empty($param['user_no'])) {
+ $user = UserModel::where('user_no', $param['user_no'])->find();
+ if (empty($user)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => [], 'extent' => ['totalMoney' => 0]]);
+ }
+ $userId = $user['user_id'];
+ }
+
+ // 判断是否是代理 如果是代理 只能看他自己管理的用户
+ $whereU = $this->getWhereByIsAgentAndUserId($adminId, $where, $userId);
+ if (!is_array($whereU)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => [], 'extent' => ['totalMoney' => 0]]);
+ }
+
+ // 订单号
+ if (!empty($param['order_id'])) {
+ $where['order_id'] = $param['order_id'];
+ }
+
+ // 交易对
+ if (!empty($param['contract_id'])) {
+ $where['contract_id'] = $param['contract_id'];
+ }
+
+ if (!empty($param['start_time']) && !empty($param['end_time'])) {
+ $where['update_time'] = ['between time', [$param['start_time'], $param['end_time']]];
+ }
+
+ // 列表
+ $list = ContractTradeModel::where('status', ContractTradeModel::STATUS_BACK)->where($whereU)->where($where)->order('trade_id', 'desc')->page($param['page'], $param['limit'])->select();
+ // 总数
+ $total = ContractTradeModel::where('status', ContractTradeModel::STATUS_BACK)
+ ->where($where)->where($whereU)
+ ->count();
+ // 持仓总金额
+ $totalModel = ContractTradeModel::where('status', ContractTradeModel::STATUS_BACK)
+ ->field('SUM(order_money) as total')->where($whereU)
+ ->where($where)->find();
+
+
+ $rows = [];
+ if (!$list->isEmpty()) {
+ // 获取用户号
+ $userIdArr = [];
+ foreach ($list as $idItem) {
+ $userIdArr[] = $idItem['user_id'];
+ }
+
+ $userNoArr = UserModel::where('user_id', 'in', $userIdArr)->column('user_no', 'user_id');
+ foreach ($list as $item) {
+ $rows[] = [
+ 'trade_id' => $item['trade_id'], //
+ 'user_no' => $userNoArr[$item['user_id']] ?? '-', // 用户号
+ 'order_id' => $item['order_id'], // 用户号
+ 'create_time' => $item['create_time'], // 挂单时间
+ 'update_time' => $item['update_time'], // 挂单时间
+ 'trade_type' => $item['trade_type'] == 1 ? '买涨' : '买跌',
+ 'order_money' => $item['order_money'], // 订单金额
+ 'contract_id' => $item['contract_id'], // 合约代码
+ 'order_number' => $item['order_number'], // 数量
+ 'service_cost' => $item['service_cost'], // 服务费
+ 'face_value' => $item['face_value'], // 浮动盈亏
+ 'stop_loss_price' => $item['stop_loss_price'], // 止损价
+ 'stop_win_price' => $item['stop_win_price'], // 止盈价
+ 'price' => $item['deal_type'] == 1 ? $item['limit_price'] : $item['market_price'], // 价格
+ 'pry_num' => $item['pry_num'], // 杠杆
+ ];
+ }
+ }
+
+ return $this->toData('0', 'SUCCESS', ['total' => $total, 'list' => $rows,
+ 'extent' => ['totalMoney' => round($totalModel['total'], 4),
+ ]]);
+
+ } catch (ValidateException $validateException) {
+ // 参数校验失败
+ $message = $validateException->getError();
+ return $this->toData('1', $message);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统异常 请稍后重试', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+
+ // 合约持仓
+ public function contractClear($param, $adminId)
+ {
+ try {
+ // 参数校验
+ validate(OrderValidate::class)->scene('contractClear')->check($param);
+
+ $where = [];
+ $userId = 0;
+ // 用户号精确搜索
+ if (!empty($param['user_no'])) {
+ $user = UserModel::where('user_no', $param['user_no'])->find();
+ if (empty($user)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => [], 'extent' => ['totalMoney' => 0]]);
+ }
+ $userId = $user['user_id'];
+ }
+
+ // 判断是否是代理 如果是代理 只能看他自己管理的用户
+ $whereU = $this->getWhereByIsAgentAndUserId($adminId, $where, $userId);
+ if (!is_array($whereU)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => [], 'extent' => ['totalMoney' => 0]]);
+ }
+
+ // 订单号
+ if (!empty($param['order_id'])) {
+ $where['order_id'] = $param['order_id'];
+ }
+
+ // 交易对
+ if (!empty($param['contract_id'])) {
+ $where['contract_id'] = $param['contract_id'];
+ }
+
+ if (!empty($param['start_time']) && !empty($param['end_time'])) {
+ $where['open_time'] = ['between time', [$param['start_time'], $param['end_time']]];
+ }
+
+ // 列表
+ $list = ContractTradeModel::where('status', ContractTradeModel::STATUS_CLEAR)->where($whereU)->where($where)->order('trade_id', 'desc')->page($param['page'], $param['limit'])->select();
+ // 总数
+ $total = ContractTradeModel::where('status', ContractTradeModel::STATUS_CLEAR)->where($whereU)
+ ->where($where)
+ ->count();
+
+ // 持仓总手续费
+ $totalClosingCost = ContractTradeModel::where('status', ContractTradeModel::STATUS_CLEAR)
+ ->where($whereU)
+ ->where($where)
+ ->sum('closing_cost');
+
+ $totalFloat = ContractTradeModel::where('status', ContractTradeModel::STATUS_CLEAR)
+ ->where($whereU)
+ ->where($where)
+ ->field("SUM( CASE WHEN trade_type = 1 THEN ( closing_price - deal_price )* order_number ELSE ( deal_price - closing_price )* order_number END ) AS total")->find();
+
+ $rows = [];
+ if (!$list->isEmpty()) {
+ // 获取用户号
+ $userIdArr = [];
+ foreach ($list as $idItem) {
+ $userIdArr[] = $idItem['user_id'];
+ }
+
+ $userNoArr = UserModel::where('user_id', 'in', $userIdArr)->column('user_no', 'user_id');
+ foreach ($list as $item) {
+ // 计算浮动盈亏
+ if ($item['trade_type'] == 1) {
+ $float = $item['closing_price'] - $item['deal_price'];
+ } else {
+ $float = $item['deal_price'] - $item['closing_price'];
+ }
+
+ // * 仓位
+ $float = @bcmul($float, $item['order_number'], 10);
+ // * 面值
+ $float = @bcmul($float, $item['face_value'], 6);
+
+ $rows[] = [
+ 'trade_id' => $item['trade_id'], //
+ 'user_no' => $userNoArr[$item['user_id']] ?? '-', // 用户号
+ 'order_id' => $item['order_id'], // 用户号
+ 'closing_time' => $item['closing_time'], // 平仓时间
+ 'trade_type' => $item['trade_type'] == 1 ? '买涨' : '买跌',
+ 'order_money' => $item['order_money'], // 订单金额
+ 'contract_id' => $item['contract_id'], // 合约代码
+ 'order_number' => $item['order_number'], // 数量
+ 'service_cost' => $item['service_cost'], // 服务费
+ 'closing_cost' => $item['closing_cost'], // 平仓服务费
+ 'face_value' => $item['face_value'], //
+ 'deal_price' => $item['deal_price'], // 开仓价
+ 'closing_price' => $item['closing_price'], // 平仓价格
+ 'stop_loss_price' => $item['stop_loss_price'], // 止损价
+ 'stop_win_price' => $item['stop_win_price'], // 止盈价
+ 'float' => $float, // 平仓盈亏
+ 'pry_num' => $item['pry_num'], // 杠杆
+ ];
+ }
+ }
+
+ return $this->toData('0', 'SUCCESS', ['total' => $total, 'list' => $rows,
+ 'extent' => [
+ 'totalClosingCost' => $totalClosingCost,
+ 'totalFloat' => $totalFloat['total'],
+ ]]);
+
+ } catch (ValidateException $validateException) {
+ // 参数校验失败
+ $message = $validateException->getError();
+ return $this->toData('1', $message);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统异常 请稍后重试', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+
+
+ ######################################## 秒合约交易 #######################################
+
+ // 合约持仓
+ public function contractSecHold($param, $adminId)
+ {
+ try {
+ // 参数校验
+ validate(OrderValidate::class)->scene('contractHold')->check($param);
+
+ $where = [];
+ $userId = 0;
+ // 用户号精确搜索
+ if (!empty($param['user_no'])) {
+ $user = UserModel::where('user_no', $param['user_no'])->find();
+ if (empty($user)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => [], 'extent' => ['totalMoney' => 0]]);
+ }
+ $userId = $user['user_id'];
+ }
+
+ // 判断是否是代理 如果是代理 只能看他自己管理的用户
+ $whereU = $this->getWhereByIsAgentAndUserId($adminId, $where, $userId);
+ if (!is_array($whereU)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => [], 'extent' => ['totalMoney' => 0]]);
+ }
+
+ // 订单号
+ if (!empty($param['order_id'])) {
+ $where['order_id'] = $param['order_id'];
+ }
+
+ // 交易对
+ if (!empty($param['contract_id'])) {
+ $where['contract_id'] = $param['contract_id'];
+ }
+
+ if (!empty($param['start_time']) && !empty($param['end_time'])) {
+ $where['open_time'] = ['between time', [$param['start_time'], $param['end_time']]];
+ }
+
+ // 列表
+ $list = ContractSecTradeModel::where('status', ContractSecTradeModel::STATUS_HOLD)->where($where)->where($whereU)->order('trade_id', 'desc')->page($param['page'], $param['limit'])->select();
+ // 总数
+ $total = ContractSecTradeModel::where('status', ContractSecTradeModel::STATUS_HOLD)
+ ->where($where)->where($whereU)
+ ->count();
+ // 持仓总金额
+ $totalModel = ContractSecTradeModel::where('status', ContractSecTradeModel::STATUS_HOLD)
+ ->field('SUM(order_money) as total')
+ ->where($where)->where($whereU)->find();
+
+ // 持仓总手续费
+ $totalServiceCost = ContractSecTradeModel::where('status', ContractSecTradeModel::STATUS_HOLD)
+ ->where($where)->where($whereU)
+ ->sum('service_cost');
+
+ $rows = [];
+ if (!$list->isEmpty()) {
+ // 获取用户号
+ $userIdArr = [];
+ foreach ($list as $idItem) {
+ $userIdArr[] = $idItem['user_id'];
+ }
+
+ $userNoArr = UserModel::where('user_id', 'in', $userIdArr)->column('user_no', 'user_id');
+ foreach ($list as $item) {
+ $rows[] = [
+ 'trade_id' => $item['trade_id'], //
+ 'user_no' => $userNoArr[$item['user_id']] ?? '-', // 用户号
+ 'order_id' => $item['order_id'], // 用户号
+ 'open_time' => $item['open_time'], // 挂单时间
+ 'trade_type' => $item['trade_type'] == 1 ? '买涨' : '买跌',
+ 'order_money' => $item['order_money'], // 订单金额
+ 'contract_id' => $item['contract_id'], // 合约代码
+ 'order_number' => $item['order_number'], // 数量
+ 'service_cost' => $item['service_cost'], // 服务费
+ 'float' => '-', // 浮动盈亏
+ 'face_value' => $item['face_value'], // 浮动盈亏
+ 'deal_price' => $item['deal_price'], // 开仓价
+ 'now_price' => '-', // 当前价
+ 'stop_loss_price' => $item['stop_loss_price'], // 止损价
+ 'stop_win_price' => $item['stop_win_price'], // 止盈价
+ 'pry_num' => $item['pry_num'], // 杠杆
+ ];
+ }
+ }
+
+ return $this->toData('0', 'SUCCESS', ['total' => $total, 'list' => $rows,
+ 'extent' => ['totalMoney' => round($totalModel['total'], 4), 'totalServiceCost' => $totalServiceCost,
+ ]]);
+
+ } catch (ValidateException $validateException) {
+ // 参数校验失败
+ $message = $validateException->getError();
+ return $this->toData('1', $message);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统异常 请稍后重试', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+
+ // 合约持仓
+ public function contractSecPlace($param, $adminId)
+ {
+ try {
+ // 参数校验
+ validate(OrderValidate::class)->scene('contractPlace')->check($param);
+
+ $where = [];
+ $userId = 0;
+ // 用户号精确搜索
+ if (!empty($param['user_no'])) {
+ $user = UserModel::where('user_no', $param['user_no'])->find();
+ if (empty($user)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => [], 'extent' => ['totalMoney' => 0]]);
+ }
+ $userId = $user['user_id'];
+ }
+
+ // 判断是否是代理 如果是代理 只能看他自己管理的用户
+ $whereU = $this->getWhereByIsAgentAndUserId($adminId, $where, $userId);
+ if (!is_array($whereU)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => [], 'extent' => ['totalMoney' => 0]]);
+ }
+
+ // 订单号
+ if (!empty($param['order_id'])) {
+ $where['order_id'] = $param['order_id'];
+ }
+
+ // 交易对
+ if (!empty($param['contract_id'])) {
+ $where['contract_id'] = $param['contract_id'];
+ }
+
+ if (!empty($param['start_time']) && !empty($param['end_time'])) {
+ $where['create_time'] = ['between time', [$param['start_time'], $param['end_time']]];
+ }
+
+ // 列表
+ $list = ContractSecTradeModel::where('status', ContractSecTradeModel::STATUS_PLACE)->where($where)->where($whereU)->order('trade_id', 'desc')->page($param['page'], $param['limit'])->select();
+ // 总数
+ $total = ContractSecTradeModel::where('status', ContractSecTradeModel::STATUS_PLACE)
+ ->where($where)->where($whereU)
+ ->count();
+ // 持仓总金额
+ $totalModel = ContractSecTradeModel::where('status', ContractSecTradeModel::STATUS_PLACE)
+ ->field('SUM(order_money) as total')->where($whereU)
+ ->where($where)->find();
+
+ $rows = [];
+ if (!$list->isEmpty()) {
+ // 获取用户号
+ $userIdArr = [];
+ foreach ($list as $idItem) {
+ $userIdArr[] = $idItem['user_id'];
+ }
+
+ $userNoArr = UserModel::where('user_id', 'in', $userIdArr)->column('user_no', 'user_id');
+ foreach ($list as $item) {
+ $rows[] = [
+ 'trade_id' => $item['trade_id'], //
+ 'order_id' => $item['order_id'], // 订单号
+ 'user_no' => $userNoArr[$item['user_id']] ?? '-', // 用户号
+ 'create_time' => $item['create_time'], // 挂单时间
+ 'order_money' => $item['order_money'], // 订单金额
+ 'trade_type' => $item['trade_type'] == 1 ? '买涨' : '买跌',
+ 'contract_id' => $item['contract_id'], // 合约代码
+ 'order_number' => $item['order_number'], // 数量
+ 'service_cost' => $item['service_cost'], // 服务费
+ 'deal_price' => $item['deal_price'], // 开仓价
+ 'stop_loss_price' => $item['stop_loss_price'], // 止损价
+ 'stop_win_price' => $item['stop_win_price'], // 止盈价
+ 'face_value' => $item['face_value'], // 面值
+ 'pry_num' => $item['pry_num'], // 杠杆
+ 'limit_price' => $item['limit_price'], // 杠杆
+ ];
+ }
+ }
+
+ return $this->toData('0', 'SUCCESS', ['total' => $total, 'list' => $rows,
+ 'extent' => ['totalMoney' => round($totalModel['total'], 4),
+ ]]);
+
+ } catch (ValidateException $validateException) {
+ // 参数校验失败
+ $message = $validateException->getError();
+ return $this->toData('1', $message);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统异常 请稍后重试', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+
+ // 合约撤单
+ public function contractSecBack($param, $adminId)
+ {
+ try {
+ // 参数校验
+ validate(OrderValidate::class)->scene('contractBack')->check($param);
+
+ $where = [];
+ $userId = 0;
+ // 用户号精确搜索
+ if (!empty($param['user_no'])) {
+ $user = UserModel::where('user_no', $param['user_no'])->find();
+ if (empty($user)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => [], 'extent' => ['totalMoney' => 0]]);
+ }
+ $userId = $user['user_id'];
+ }
+
+ // 判断是否是代理 如果是代理 只能看他自己管理的用户
+ $whereU = $this->getWhereByIsAgentAndUserId($adminId, $where, $userId);
+ if (!is_array($whereU)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => [], 'extent' => ['totalMoney' => 0]]);
+ }
+
+ // 订单号
+ if (!empty($param['order_id'])) {
+ $where['order_id'] = $param['order_id'];
+ }
+
+ // 交易对
+ if (!empty($param['contract_id'])) {
+ $where['contract_id'] = $param['contract_id'];
+ }
+
+ if (!empty($param['start_time']) && !empty($param['end_time'])) {
+ $where['update_time'] = ['between time', [$param['start_time'], $param['end_time']]];
+ }
+
+ // 列表
+ $list = ContractSecTradeModel::where('status', ContractSecTradeModel::STATUS_BACK)->where($whereU)->where($where)->order('trade_id', 'desc')->page($param['page'], $param['limit'])->select();
+ // 总数
+ $total = ContractSecTradeModel::where('status', ContractSecTradeModel::STATUS_BACK)
+ ->where($where)->where($whereU)
+ ->count();
+ // 持仓总金额
+ $totalModel = ContractSecTradeModel::where('status', ContractSecTradeModel::STATUS_BACK)
+ ->field('SUM(order_money) as total')->where($whereU)
+ ->where($where)->find();
+
+
+ $rows = [];
+ if (!$list->isEmpty()) {
+ // 获取用户号
+ $userIdArr = [];
+ foreach ($list as $idItem) {
+ $userIdArr[] = $idItem['user_id'];
+ }
+
+ $userNoArr = UserModel::where('user_id', 'in', $userIdArr)->column('user_no', 'user_id');
+ foreach ($list as $item) {
+ $rows[] = [
+ 'trade_id' => $item['trade_id'], //
+ 'user_no' => $userNoArr[$item['user_id']] ?? '-', // 用户号
+ 'order_id' => $item['order_id'], // 用户号
+ 'create_time' => $item['create_time'], // 挂单时间
+ 'update_time' => $item['update_time'], // 挂单时间
+ 'trade_type' => $item['trade_type'] == 1 ? '买涨' : '买跌',
+ 'order_money' => $item['order_money'], // 订单金额
+ 'contract_id' => $item['contract_id'], // 合约代码
+ 'order_number' => $item['order_number'], // 数量
+ 'service_cost' => $item['service_cost'], // 服务费
+ 'face_value' => $item['face_value'], // 浮动盈亏
+ 'stop_loss_price' => $item['stop_loss_price'], // 止损价
+ 'stop_win_price' => $item['stop_win_price'], // 止盈价
+ 'price' => $item['deal_type'] == 1 ? $item['limit_price'] : $item['market_price'], // 价格
+ 'pry_num' => $item['pry_num'], // 杠杆
+ ];
+ }
+ }
+
+ return $this->toData('0', 'SUCCESS', ['total' => $total, 'list' => $rows,
+ 'extent' => ['totalMoney' => round($totalModel['total'], 4),
+ ]]);
+
+ } catch (ValidateException $validateException) {
+ // 参数校验失败
+ $message = $validateException->getError();
+ return $this->toData('1', $message);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统异常 请稍后重试', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+
+ // 合约持仓
+ public function contractSecClear($param, $adminId)
+ {
+ try {
+ // 参数校验
+ validate(OrderValidate::class)->scene('contractClear')->check($param);
+
+ $where = [];
+ $userId = 0;
+ // 用户号精确搜索
+ if (!empty($param['user_no'])) {
+ $user = UserModel::where('user_no', $param['user_no'])->find();
+ if (empty($user)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => [], 'extent' => ['totalMoney' => 0]]);
+ }
+ $userId = $user['user_id'];
+ }
+
+ // 判断是否是代理 如果是代理 只能看他自己管理的用户
+ $whereU = $this->getWhereByIsAgentAndUserId($adminId, $where, $userId);
+ if (!is_array($whereU)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => [], 'extent' => ['totalMoney' => 0]]);
+ }
+
+ // 订单号
+ if (!empty($param['order_id'])) {
+ $where['order_id'] = $param['order_id'];
+ }
+
+ // 交易对
+ if (!empty($param['contract_id'])) {
+ $where['contract_id'] = $param['contract_id'];
+ }
+
+ if (!empty($param['start_time']) && !empty($param['end_time'])) {
+ $where['open_time'] = ['between time', [$param['start_time'], $param['end_time']]];
+ }
+
+ // 列表
+ $list = ContractSecTradeModel::where('status', ContractSecTradeModel::STATUS_CLEAR)->where($whereU)->where($where)->order('trade_id', 'desc')->page($param['page'], $param['limit'])->select();
+ // 总数
+ $total = ContractSecTradeModel::where('status', ContractSecTradeModel::STATUS_CLEAR)->where($whereU)
+ ->where($where)
+ ->count();
+
+ // 持仓总手续费
+ $totalClosingCost = ContractSecTradeModel::where('status', ContractSecTradeModel::STATUS_CLEAR)
+ ->where($whereU)
+ ->where($where)
+ ->sum('closing_cost');
+
+ $totalFloat = ContractSecTradeModel::where('status', ContractSecTradeModel::STATUS_CLEAR)
+ ->where($whereU)
+ ->where($where)
+ ->field("SUM( CASE WHEN trade_type = 1 THEN ( closing_price - deal_price )* order_number ELSE ( deal_price - closing_price )* order_number END ) AS total")->find();
+
+ $rows = [];
+ if (!$list->isEmpty()) {
+ // 获取用户号
+ $userIdArr = [];
+ foreach ($list as $idItem) {
+ $userIdArr[] = $idItem['user_id'];
+ }
+
+ $userNoArr = UserModel::where('user_id', 'in', $userIdArr)->column('user_no', 'user_id');
+ foreach ($list as $item) {
+ // 计算浮动盈亏
+ if ($item['trade_type'] == 1) {
+ $float = $item['closing_price'] - $item['deal_price'];
+ } else {
+ $float = $item['deal_price'] - $item['closing_price'];
+ }
+
+ // * 仓位
+ $float = @bcmul($float, $item['order_number'], 10);
+ // * 面值
+ $float = @bcmul($float, $item['face_value'], 6);
+
+ $rows[] = [
+ 'trade_id' => $item['trade_id'], //
+ 'user_no' => $userNoArr[$item['user_id']] ?? '-', // 用户号
+ 'order_id' => $item['order_id'], // 用户号
+ 'closing_time' => $item['closing_time'], // 平仓时间
+ 'trade_type' => $item['trade_type'] == 1 ? '买涨' : '买跌',
+ 'order_money' => $item['order_money'], // 订单金额
+ 'contract_id' => $item['contract_id'], // 合约代码
+ 'order_number' => $item['order_number'], // 数量
+ 'service_cost' => $item['service_cost'], // 服务费
+ 'closing_cost' => $item['closing_cost'], // 平仓服务费
+ 'face_value' => $item['face_value'], //
+ 'deal_price' => $item['deal_price'], // 开仓价
+ 'closing_price' => $item['closing_price'], // 平仓价格
+ 'stop_loss_price' => $item['stop_loss_price'], // 止损价
+ 'stop_win_price' => $item['stop_win_price'], // 止盈价
+ 'float' => $float, // 平仓盈亏
+ 'pry_num' => $item['pry_num'], // 杠杆
+ ];
+ }
+ }
+
+ return $this->toData('0', 'SUCCESS', ['total' => $total, 'list' => $rows,
+ 'extent' => [
+ 'totalClosingCost' => $totalClosingCost,
+ 'totalFloat' => $totalFloat['total'],
+ ]]);
+
+ } catch (ValidateException $validateException) {
+ // 参数校验失败
+ $message = $validateException->getError();
+ return $this->toData('1', $message);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统异常 请稍后重试', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+
+
+ ########################################## 股票交易 ###########################################
+ // 股票持仓
+ public function StockHold($param, $adminId)
+ {
+ try {
+ // 参数校验
+ validate(OrderValidate::class)->scene('stockHold')->check($param);
+
+ $where = [];
+ $userId = 0;
+ // 用户号精确搜索
+ if (!empty($param['user_no'])) {
+ $user = UserModel::where('user_no', $param['user_no'])->find();
+ if (empty($user)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => [], 'extent' => ['totalMoney' => 0]]);
+ }
+ $userId = $user['user_id'];
+ }
+
+ // 判断是否是代理 如果是代理 只能看他自己管理的用户
+ $whereU = $this->getWhereByIsAgentAndUserId($adminId, $where, $userId);
+ if (!is_array($whereU)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => [], 'extent' => ['totalMoney' => 0]]);
+ }
+ $market_type = intval($param['market_type']);
+ $table_obj = (new IPOService())->getStockModel($market_type);
+ if (empty($table_obj)) {
+ return $this->toData('1', '数据异常');
+ }
+
+ // 订单号
+ if (!empty($param['order_id'])) {
+ $where['order_id'] = $param['order_id'];
+ }
+
+ // 交易对
+ if (!empty($param['stock_id'])) {
+ $where['stock_id'] = $param['contract_id'];
+ }
+
+ if (!empty($param['start_time']) && !empty($param['end_time'])) {
+ $where['open_time'] = ['between time', [$param['start_time'], $param['end_time']]];
+ }
+
+ // 列表
+ $list = Db::table($table_obj['trade_table'])->where('status', 1)->where($whereU)->where($where)->order('trade_id', 'desc')->page($param['page'], $param['limit'])->select();
+ // 总数
+ $total = Db::table($table_obj['trade_table'])->where('status', 1)
+ ->where($whereU)
+ ->where($where)
+ ->count();
+ // 持仓总金额
+ $totalModel = Db::table($table_obj['trade_table'])->where('status', 1)
+ ->field('SUM(order_money) as total')
+ ->where($whereU)
+ ->where($where)->find();
+
+ // 持仓总手续费
+ $totalServiceCost = Db::table($table_obj['trade_table'])->where('status', 1)
+ ->where($whereU)
+ ->where($where)
+ ->sum('service_cost');
+
+ $rows = [];
+ if (!$list->isEmpty()) {
+ // 获取用户号
+ $userIdArr = [];
+ foreach ($list as $idItem) {
+ $userIdArr[] = $idItem['user_id'];
+ }
+
+ $userNoArr = UserModel::where('user_id', 'in', $userIdArr)->column('user_no', 'user_id');
+ foreach ($list as $item) {
+ $orderNumber = number_format($item['order_number'], '18', '.', '');
+ $orderPrice = number_format($item['deal_price'], '18', '.', '');
+ $orderAmount = bcmul($orderNumber, $orderPrice, 18);
+ $rows[] = [
+ 'trade_id' => $item['trade_id'], //
+ 'user_no' => $userNoArr[$item['user_id']] ?? '-', // 用户号
+ 'order_id' => $item['order_id'], // 用户号
+ 'open_time' => $item['open_time'] ?? '-', // 挂单时间
+ 'trade_type' => $item['trade_type'] == 1 ? '买涨' : '买跌',
+ 'order_money' => $orderAmount, // 订单金额
+ 'stock_id' => $item['stock_id'], // 股票代码
+ 'order_number' => $item['order_number'], // 数量
+ 'service_cost' => $item['service_cost'], // 服务费
+ 'float' => '-', // 浮动盈亏
+ 'deal_price' => $item['deal_price'], // 开仓价
+ 'now_price' => '-', // 当前价
+ 'stop_loss_price' => $item['stop_loss_price'], // 止损价
+ 'stop_win_price' => $item['stop_win_price'], // 止盈价
+ 'pry_num' => $item['pry_num'], // 杠杆
+ ];
+ }
+ }
+
+ return $this->toData('0', 'SUCCESS', ['total' => $total, 'list' => $rows,
+ 'extent' => ['totalMoney' => round($totalModel['total'], 4), 'totalServiceCost' => $totalServiceCost,
+ ]]);
+
+ } catch (ValidateException $validateException) {
+ // 参数校验失败
+ $message = $validateException->getError();
+ return $this->toData('1', $message);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统异常 请稍后重试', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+
+ // 股票挂单
+ public function StockPlace($param, $adminId)
+ {
+ try {
+ // 参数校验
+ validate(OrderValidate::class)->scene('stockPlace')->check($param);
+
+ $where = [];
+ $userId = 0;
+ // 用户号精确搜索
+ if (!empty($param['user_no'])) {
+ $user = UserModel::where('user_no', $param['user_no'])->find();
+ if (empty($user)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => [], 'extent' => ['totalMoney' => 0]]);
+ }
+ $userId = $user['user_id'];
+ }
+
+ // 判断是否是代理 如果是代理 只能看他自己管理的用户
+ $whereU = $this->getWhereByIsAgentAndUserId($adminId, $where, $userId);
+ if (!is_array($whereU)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => [], 'extent' => ['totalMoney' => 0]]);
+ }
+
+ // 订单号
+ if (!empty($param['order_id'])) {
+ $where['order_id'] = $param['order_id'];
+ }
+
+ // 交易对
+ if (!empty($param['stock_id'])) {
+ $where['stock_id'] = $param['contract_id'];
+ }
+
+ if (!empty($param['start_time']) && !empty($param['end_time'])) {
+ $where['create_time'] = ['between time', [$param['start_time'], $param['end_time']]];
+ }
+ $market_type = intval($param['market_type']);
+ $table_obj = (new IPOService())->getStockModel($market_type);
+ if (empty($table_obj)) {
+ return $this->toData('1', '数据异常');
+ }
+
+ // 列表
+ $list = Db::table($table_obj['trade_table'])->where('status', 0)->where($whereU)->where($where)->order('trade_id', 'desc')->page($param['page'], $param['limit'])->select();
+ // 总数
+ $total = Db::table($table_obj['trade_table'])->where('status', 0)
+ ->where($where)->where($whereU)
+ ->count();
+ // 持仓总金额
+ $totalModel = Db::table($table_obj['trade_table'])->where('status', 0)
+ ->field('SUM(order_money) as total')
+ ->where($where)->where($whereU)->find();
+
+ $rows = [];
+ if (!$list->isEmpty()) {
+ // 获取用户号
+ $userIdArr = [];
+ foreach ($list as $idItem) {
+ $userIdArr[] = $idItem['user_id'];
+ }
+
+ $userNoArr = UserModel::where('user_id', 'in', $userIdArr)->column('user_no', 'user_id');
+ foreach ($list as $item) {
+ // 挂单价
+ $price = $item['limit_price'];
+ if ($item['deal_type'] == 2) {
+ $price = $item['market_price'];
+ }
+
+ $orderNumber = number_format($item['order_number'], '18', '.', '');
+ $orderPrice = number_format($price, '18', '.', '');
+ $orderAmount = bcmul($orderNumber, $orderPrice, 18);
+ $rows[] = [
+ 'trade_id' => $item['trade_id'], //
+ 'order_id' => $item['order_id'], // 订单号
+ 'user_no' => $userNoArr[$item['user_id']] ?? '-', // 用户号
+ 'create_time' => $item['create_time'], // 挂单时间
+ 'order_money' => $orderAmount, // 订单金额
+ 'trade_type' => $item['trade_type'] == 1 ? '买涨' : '买跌',
+ 'stock_id' => $item['stock_id'], // 合约代码
+ 'order_number' => $item['order_number'], // 数量
+ 'service_cost' => $item['service_cost'], // 服务费
+ 'deal_price' => $price, // 委托价
+ 'stop_loss_price' => $item['stop_loss_price'], // 止损价
+ 'stop_win_price' => $item['stop_win_price'], // 止盈价
+ 'limit_price' => $item['limit_price'], // 限价
+ 'pry_num' => $item['pry_num'], // 杠杆
+ ];
+ }
+ }
+
+ return $this->toData('0', 'SUCCESS', ['total' => $total, 'list' => $rows,
+ 'extent' => ['totalMoney' => round($totalModel['total'], 4),
+ ]]);
+
+ } catch (ValidateException $validateException) {
+ // 参数校验失败
+ $message = $validateException->getError();
+ return $this->toData('1', $message);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统异常 请稍后重试', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+
+ // 股票撤单
+ public function StockBack($param, $adminId)
+ {
+ try {
+ // 参数校验
+ validate(OrderValidate::class)->scene('stockBack')->check($param);
+
+ $where = [];
+ $userId = 0;
+ // 用户号精确搜索
+ if (!empty($param['user_no'])) {
+ $user = UserModel::where('user_no', $param['user_no'])->find();
+ if (empty($user)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => [], 'extent' => ['totalMoney' => 0]]);
+ }
+ $userId = $user['user_id'];
+ }
+
+ // 判断是否是代理 如果是代理 只能看他自己管理的用户
+ $whereU = $this->getWhereByIsAgentAndUserId($adminId, $where, $userId);
+ if (!is_array($whereU)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => [], 'extent' => ['totalMoney' => 0]]);
+ }
+ $market_type = intval($param['market_type']);
+ $table_obj = (new IPOService())->getStockModel($market_type);
+ if (empty($table_obj)) {
+ return $this->toData('1', '数据异常');
+ }
+ // 订单号
+ if (!empty($param['order_id'])) {
+ $where['order_id'] = $param['order_id'];
+ }
+
+ // 交易对
+ if (!empty($param['stock_id'])) {
+ $where['stock_id'] = $param['contract_id'];
+ }
+
+ if (!empty($param['start_time']) && !empty($param['end_time'])) {
+ $where['update_time'] = ['between time', [$param['start_time'], $param['end_time']]];
+ }
+
+ // 列表
+ $list = Db::table($table_obj['trade_table'])->where('status', 2)->where($where)->where($whereU)->order('trade_id', 'desc')->page($param['page'], $param['limit'])->select();
+ // 总数
+ $total = Db::table($table_obj['trade_table'])->where('status', 2)
+ ->where($where)->where($whereU)
+ ->count();
+ // 持仓总金额
+ $totalModel = Db::table($table_obj['trade_table'])->where('status', 2)
+ ->field('SUM(order_money) as total')->where($whereU)
+ ->where($where)->find();
+
+
+ $rows = [];
+ if (!$list->isEmpty()) {
+ // 获取用户号
+ $userIdArr = [];
+ foreach ($list as $idItem) {
+ $userIdArr[] = $idItem['user_id'];
+ }
+
+ $userNoArr = UserModel::where('user_id', 'in', $userIdArr)->column('user_no', 'user_id');
+ foreach ($list as $item) {
+ // 挂单价
+ $price = $item['limit_price'];
+ if ($item['deal_type'] == 2) {
+ $price = $item['market_price'];
+ }
+ $orderNumber = number_format($item['order_number'], '18', '.', '');
+ $orderPrice = number_format($price, '18', '.', '');
+ $orderAmount = bcmul($orderNumber, $orderPrice, 18);
+ $rows[] = [
+ 'trade_id' => $item['trade_id'], //
+ 'user_no' => $userNoArr[$item['user_id']] ?? '-', // 用户号
+ 'order_id' => $item['order_id'], // 用户号
+ 'create_time' => $item['create_time'], // 挂单时间
+ 'update_time' => $item['update_time'], // 挂单时间
+ 'trade_type' => $item['trade_type'] == 1 ? '买涨' : '买跌',
+ 'order_money' => $orderAmount, // 订单金额
+ 'stock_id' => $item['stock_id'], // 合约代码
+ 'order_number' => $item['order_number'], // 数量
+ 'service_cost' => $item['service_cost'], // 服务费
+ 'deal_price' => $price, // 委托价
+ 'stop_loss_price' => $item['stop_loss_price'], // 止损价
+ 'stop_win_price' => $item['stop_win_price'], // 止盈价
+ 'pry_num' => $item['pry_num'], // 杠杆
+ ];
+ }
+ }
+
+ return $this->toData('0', 'SUCCESS', ['total' => $total, 'list' => $rows,
+ 'extent' => ['totalMoney' => round($totalModel['total'], 4),
+ ]]);
+
+ } catch (ValidateException $validateException) {
+ // 参数校验失败
+ $message = $validateException->getError();
+ return $this->toData('1', $message);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统异常 请稍后重试', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+
+ // 股票平仓
+ public function StockClear($param, $adminId)
+ {
+ try {
+ // 参数校验
+ validate(OrderValidate::class)->scene('us_stockClear')->check($param);
+
+ $where = [];
+ $userId = 0;
+ // 用户号精确搜索
+ if (!empty($param['user_no'])) {
+ $user = UserModel::where('user_no', $param['user_no'])->find();
+ if (empty($user)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => [], 'extent' => ['totalMoney' => 0]]);
+ }
+ $userId = $user['user_id'];
+ }
+
+ // 判断是否是代理 如果是代理 只能看他自己管理的用户
+ $whereU = $this->getWhereByIsAgentAndUserId($adminId, $where, $userId);
+ if (!is_array($whereU)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => [], 'extent' => ['totalMoney' => 0]]);
+ }
+
+ // 订单号
+ if (!empty($param['order_id'])) {
+ $where['order_id'] = $param['order_id'];
+ }
+
+ // 交易对
+ if (!empty($param['contract_id'])) {
+ $where['contract_id'] = $param['contract_id'];
+ }
+
+ if (!empty($param['start_time']) && !empty($param['end_time'])) {
+ $where['open_time'] = ['between time', [$param['start_time'], $param['end_time']]];
+ }
+ $market_type = intval($param['market_type']);
+ $table_obj = (new IPOService())->getStockModel($market_type);
+ if (empty($table_obj)) {
+ return $this->toData('1', '数据异常');
+ }
+
+ // 列表
+ $list = Db::table($table_obj['trade_table'])->where('status', 3)->where($whereU)->where($where)->order('trade_id', 'desc')->page($param['page'], $param['limit'])->select();
+ // 总数
+ $total = Db::table($table_obj['trade_table'])->where('status', 3)
+ ->where($where)->where($whereU)
+ ->count();
+
+ // 持仓总手续费
+ $totalClosingCost = Db::table($table_obj['trade_table'])->where('status', 3)
+ ->where($whereU)
+ ->where($where)
+ ->sum('closing_cost');
+
+ $totalFloat = Db::table($table_obj['trade_table'])->where('status', 3)
+ ->where($whereU)
+ ->where($where)
+ ->field("SUM( CASE WHEN trade_type = 1 THEN ( closing_price - deal_price )* order_number ELSE ( deal_price - closing_price )* order_number END ) AS total")->find();
+
+
+ $rows = [];
+ if (!$list->isEmpty()) {
+ // 获取用户号
+ $userIdArr = [];
+ foreach ($list as $idItem) {
+ $userIdArr[] = $idItem['user_id'];
+ }
+
+ $userNoArr = UserModel::where('user_id', 'in', $userIdArr)->column('user_no', 'user_id');
+ foreach ($list as $item) {
+ // 计算浮动盈亏
+ if ($item['trade_type'] == 1) {
+ $float = $item['closing_price'] - $item['deal_price'];
+ } else {
+ $float = $item['deal_price'] - $item['closing_price'];
+ }
+
+ $orderNumber = number_format($item['order_number'], '18', '.', '');
+ $orderPrice = number_format($item['deal_price'], '18', '.', '');
+ $float = number_format($float, '18', '.', '');
+
+ $float = bcmul($float, $item['order_number'], 18);
+ $orderAmount = bcmul($orderNumber, $orderPrice, 18);
+
+ $rows[] = [
+ 'trade_id' => $item['trade_id'], //
+ 'user_no' => $userNoArr[$item['user_id']] ?? '-', // 用户号
+ 'order_id' => $item['order_id'], // 用户号
+ 'closing_time' => $item['closing_time'], // 平仓时间
+ 'trade_type' => $item['trade_type'] == 1 ? '买涨' : '买跌',
+ 'order_money' => $orderAmount, // 订单金额
+ 'stock_id' => $item['stock_id'], // 股票代码
+ 'order_number' => $item['order_number'], // 数量
+ 'service_cost' => $item['service_cost'], // 服务费
+ 'closing_cost' => $item['closing_cost'], // 平仓服务费
+ 'deal_price' => $item['deal_price'], // 开仓价
+ 'closing_price' => $item['closing_price'], // 平仓价格
+ 'stop_loss_price' => $item['stop_loss_price'], // 止损价
+ 'stop_win_price' => $item['stop_win_price'], // 止盈价
+ 'float' => $float, // 平仓盈亏
+ 'pry_num' => $item['pry_num'], // 杠杆
+ ];
+ }
+ }
+
+ return $this->toData('0', 'SUCCESS', ['total' => $total, 'list' => $rows,
+ 'extent' => [
+ 'totalClosingCost' => $totalClosingCost,
+ 'totalFloat' => $totalFloat['total'],
+ ]]);
+
+ } catch (ValidateException $validateException) {
+ // 参数校验失败
+ $message = $validateException->getError();
+ return $this->toData('1', $message);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统异常 请稍后重试', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+
+
+ ################################################# 申购订单
+
+ // 申购订单
+ public function preStock($marketType, $param, $adminId)
+ {
+ try {
+ // 参数校验
+ validate(OrderValidate::class)->scene('pre_stock')->check($param);
+
+ $where = [];
+ $userId = 0;
+ // 用户号精确搜索
+ if (!empty($param['user_no'])) {
+ $user = UserModel::where('user_no', $param['user_no'])->find();
+ if (empty($user)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => [], 'extent' => ['totalMoney' => 0]]);
+ }
+ $userId = $user['user_id'];
+ }
+
+ // 判断是否是代理 如果是代理 只能看他自己管理的用户
+ $whereU = $this->getWhereByIsAgentAndUserId($adminId, $where, $userId);
+ if (!is_array($whereU)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => [], 'extent' => ['totalMoney' => 0]]);
+ }
+
+ // 订单号
+ if (!empty($param['order_no'])) {
+ $where['order_no'] = $param['order_no'];
+ }
+
+ $tableObj = (new IPOService)->getStockModel($marketType);
+
+ if (!empty($param['stock_code'])) {
+ $stockArr = Db::table($tableObj['stock_table'])->where('stock_code', 'like', '%' . $param['stock_code'])->column('id');
+ if (!empty($stockArr)) {
+ $where[] = ['pre_stock_id', 'in', $stockArr];
+ }
+ }
+ $list = Db::table($tableObj['order_table'])->where($where)->where($whereU)->order('id', 'desc')->page($param['page'], $param['limit'])->select();
+ $total = Db::table($tableObj['order_table'])->where($where)->where($whereU)->count();
+
+
+ $stockTape=(new IPOService)->getStockTape($marketType);
+ $tapeList = $stockTape['tape'];
+ $stockTypeList = $stockTape['type'];
+ $statusList = UserUsPreStockOrderModel::$statusList;
+
+ $rows = [];
+ if (!$list->isEmpty()) {
+ // 获取用户号
+ $userIdArr = [];
+ // stock
+ $preStockId = [];
+ foreach ($list as $idItem) {
+ $userIdArr[] = $idItem['user_id'];
+ $preStockId[] = $idItem['pre_stock_id'];
+ }
+
+ $userNoArr = UserModel::where('user_id', 'in', $userIdArr)->column('user_no', 'user_id');
+ $stockArr = Db::table($tableObj['stock_table'])->where('id', 'in', $preStockId)->column('*', 'id');
+
+ $rows = $list->toArray();
+ foreach ($rows as $key => $item) {
+ $stock = $stockArr[$item['pre_stock_id']] ?? [];
+ $rows[$key]['user_no'] = $userNoArr[$item['user_id']] ?? '-'; // 用户号
+ $rows[$key]['stock_code'] = $stock['stock_code'] ?? '-';
+ $rows[$key]['stock_name'] = $stock['stock_name'] ?? '-';
+ $rows[$key]['stock_type'] = $stock['stock_type'] ?? '-';
+ $rows[$key]['tape'] = $stock['stock_type'] ?? '-';
+ $rows[$key]['rate'] = $stock['rate'] ?? '-';
+ $rows[$key]['open_time'] = $stock['open_time'] ?? '-';
+ }
+ }
+
+ return $this->toData('0', 'SUCCESS', ['total' => $total, 'list' => $rows, 'extend' => [
+ 'tape_list' => $tapeList,
+ 'stock_type_list' => $stockTypeList,
+ 'status_list' => $statusList
+ ]]);
+
+ } catch
+ (ValidateException $validateException) {
+ // 参数校验失败
+ $message = $validateException->getError();
+ return $this->toData('1', $message);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统异常 请稍后重试', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+
+ // 申购订单 - 修改中签数
+ public function updateGetNum($marketType, $param)
+ {
+ try {
+ if (empty($param['id']) || !is_numeric($param['id'])) {
+ return $this->toData('1', 'id参数错误');
+ }
+
+ if (!is_numeric($param['get_num'])) {
+ return $this->toData('1', 'get_num参数错误');
+ }
+
+ $tableObj = (new IPOService)->getStockModel($marketType);
+ $order = Db::table($tableObj['order_table'])->where('id', $param['id'])->find();
+ if (empty($order)) return $this->toData('1', 'id参数错误');
+
+ if (in_array($order['status'], [7, 8])) return $this->toData('1', '订单已退款,不可操作');
+
+ if ($param['get_num'] > $order['num']) {
+ return $this->toData('1', '修改中签数不能大于订单申购数');
+ }
+
+ $getTime = Db::table($tableObj['stock_table'])->where('id', $order['pre_stock_id'])->value('get_time');
+ if (env('USER_ARREARS.HAS_USER_ARREARS') == 1 && $order['pay_type'] == 2 && in_array($order['status'], [5, 6])) {
+ } else {
+ if (strtotime($getTime) < time()) return $this->toData('1', 'IPO已中签,无法修改');
+ }
+
+ $bool = Db::table($tableObj['order_table'])->where('id', $param['id'])->update([
+ 'get_num' => $param['get_num'],
+ 'get_amount' => $param['get_num'] * $order['price'],
+ 'get_fee' => $order['get_amount'] * $order['fee_rate'],
+ 'update_time' => date('Y-m-d H:i:s')
+ ]);
+ if (!$bool) return $this->toData('1', '修改失败');
+
+ return $this->toData('0', 'SUCCESS', []);
+ } catch (ValidateException $validateException) {
+ // 参数校验失败
+ $message = $validateException->getError();
+ return $this->toData('1', $message);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统异常 请稍后重试', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+
+ // 申购订单退款
+ public function preRefund($marketType, $param)
+ {
+ try {
+ if (empty($param['id']) || !is_numeric($param['id'])) {
+ return $this->toData('1', 'id参数错误');
+ }
+ $tableObj = (new IPOService)->getStockModel($marketType);
+
+ $order = Db::table($tableObj['order_table'])->where('id', $param['id'])->whereIn('status',[1,2,5,6])->find();
+ if (empty($order)) return $this->toData('1', 'id参数错误');
+
+
+ $preStock = Db::table($tableObj['stock_table'])->where('id', $param['id'])->where('is_delete', 1)
+ ->where('status', 1)
+ ->where('id', $param['pre_id'])
+ // 签名状态
+ ->where('sign_status', 1)
+ ->where('open_status', 1) ->find();
+ if(empty($preStock)){
+ return $this->toData('1', 'IPO未签名或已上市不可退款');
+ }
+
+ $now = date('Y-m-d H:i:s');
+ $total_num=$order['amount']+$order['fee'];
+ //查询订单有没有欠款
+ $user_arrears=UserArrearsModel::where('order_no', $order['order_no'])->where('status',0)->where('user_id', $order['user_id'])->find();
+
+ Db::startTrans();
+ if($user_arrears){
+ $user_arrears=$user_arrears->toArray();
+ if($user_arrears['is_add']==1){
+ //扣除冻结,不加可用
+ $updateNum = Db::table($tableObj['user_table'])->where('stock_id', $tableObj['stock_id'])->where('user_id', $order['user_id'])
+ ->where('frozen_num', '>=', $total_num)
+ ->dec('frozen_num',$total_num)
+ ->update(['update_time' => $now]);
+ if(!$updateNum){
+ Db::rollback();
+ trace('IPO订单退款01-给用户ID:' . $order['user_id'] . "解冻资金异常" . $order['order_no'], 'error');
+ return $this->toData('1', '解冻资金异常');
+ }
+ }
+ $update_bool=UserArrearsModel::where('order_no', $order['order_no'])->where('user_id', $order['user_id'])
+ ->update([
+ 'update_time'=>$now,
+ 'status'=>1
+ ]);
+ if(!$update_bool){
+ Db::rollback();
+ trace('IPO订单退款02-给用户ID:' . $order['user_id'] . "更新贷款订单异常" . $order['order_no'], 'error');
+ return $this->toData('1', '更新贷款订单异常');
+ }
+
+ $status=8;
+ }else{
+ //扣除冻结 加可用
+ $updateNum = Db::table($tableObj['user_table'])->where('stock_id', $tableObj['stock_id'])->where('user_id', $order['user_id'])
+ ->where('frozen_num', '>=', $total_num)
+ ->inc('usable_num', $total_num)
+ ->dec('frozen_num',$total_num)
+ ->update(['update_time' => $now]);
+ if(!$updateNum){
+ Db::rollback();
+ trace('IPO订单退款03-给用户ID:' . $order['user_id'] . "解冻资金异常" . $order['order_no'], 'error');
+ return $this->toData('1', '解冻资金异常');
+ }
+ $status=7;
+ }
+
+ //更新状态
+ $bool_status = Db::table($tableObj['order_table'])->where('id', $order['id'])->update([
+ 'status' => $status,
+ 'update_time' => $now
+ ]);
+ if (!$bool_status) {
+ Db::rollback();
+ trace('IPO订单退款04-更新订单状态异常' . $order['order_no'], 'error');
+ return $this->toData('1', '更新订单状态异常');
+ }
+ //删除缓存订单
+ $redis = $this->getRedis();
+ $key = "USER:ARREAR:ORDER:" . $order['order_no'];
+ $redis->del($key);
+ Db::commit();
+
+ return $this->toData('0', 'SUCCESS', []);
+ } catch (ValidateException $validateException) {
+ // 参数校验失败
+ $message = $validateException->getError();
+ return $this->toData('1', $message);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统异常 请稍后重试', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+
+
+ ################################################# 基金订单
+ //基金订单
+ public function fundStock($param, $adminId)
+ {
+ try {
+ // 参数校验
+ validate(OrderValidate::class)->scene('fund_stock')->check($param);
+
+ $where = [];
+ $userId = 0;
+ // 用户号精确搜索
+ if (!empty($param['user_no'])) {
+ $user = UserModel::where('user_no', $param['user_no'])->find();
+ if (empty($user)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => [], 'extent' => ['totalMoney' => 0]]);
+ }
+ $userId = $user['user_id'];
+ }
+
+ // 判断是否是代理 如果是代理 只能看他自己管理的用户
+ $whereU = $this->getWhereByIsAgentAndUserId($adminId, $where, $userId);
+ if (!is_array($whereU)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => [], 'extent' => ['totalMoney' => 0]]);
+ }
+
+ // 订单号
+ if (!empty($param['order_no'])) $where[] = ['order_no', '=', $param['order_no']];
+
+ // 状态
+ if (!empty($param['open_status']) && in_array($param['open_status'], array_keys(PreFundStockModel::$stockTypeList))) $where[] = ['status', '=', $param['status']];
+
+ if (!empty($param['stock_code'])) {
+ $stockId = PreFundStockModel::where('stock_code', $param['stock_code'])->value('id');
+ $stockId = $stockId ?? 0;
+ $where[] = ['pre_stock_id', '=', $stockId];
+ }
+
+ $list = UserFundPreStockOrderModel::where($whereU)->where($where)->order('id', 'desc')->page($param['page'], $param['limit'])->select();
+ $total = UserFundPreStockOrderModel::where($whereU)->where($where)->count();
+
+ $rows = [];
+ if (!$list->isEmpty()) {
+ // 获取用户号
+ $userIdArr = [];
+ // stock
+ $preStockId = [];
+ foreach ($list as $idItem) {
+ $userIdArr[] = $idItem['user_id'];
+ $preStockId[] = $idItem['pre_stock_id'];
+ }
+
+ $userNoArr = UserModel::where('user_id', 'in', $userIdArr)->column('user_no', 'user_id');
+ $stockArr = PreFundStockModel::where('id', 'in', $preStockId)->column('*', 'id');
+
+ $rows = $list->toArray();
+ foreach ($rows as $key => $item) {
+ $stock = $stockArr[$item['pre_stock_id']] ?? [];
+ if (empty($stock)) continue;
+ $rows[$key]['user_no'] = $userNoArr[$item['user_id']] ?? '-'; // 用户号
+ $rows[$key]['stock_code'] = $stock['stock_code'] ?? '-';
+ $rows[$key]['stock_name'] = $stock['stock_name'] ?? '-';
+ $rows[$key]['stock_type'] = PreFundStockModel::$stockTypeList[$stock['stock_type']] ?? '-';
+ $rows[$key]['rate'] = $item['stock_rate'] . "%" ?? '-';
+ $rows[$key]['cycle'] = $item['stock_cycle'] . PreFundStockModel::$cycleTypeList[$item['stock_cycle_type']] ?? '-';
+ $rows[$key]['open_time'] = $stock['open_time'] ?? '-';
+ }
+ }
+
+ return $this->toData('0', 'SUCCESS', ['total' => $total, 'list' => $rows, 'extend' => [
+ 'tape_list' => [],
+ 'stock_type_list' => PreFundStockModel::$stockTypeList,
+ 'cycle_type_list' => PreFundStockModel::$cycleTypeList
+ ]]);
+
+ } catch (ValidateException $validateException) {
+ // 参数校验失败
+ $message = $validateException->getError();
+ return $this->toData('1', $message);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统异常 请稍后重试', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+
+ //基金订单info
+ public function fundStockInfo($param)
+ {
+ try {
+ // 参数校验
+ validate(OrderValidate::class)->scene('fund_stock_info')->check($param);
+ $list = UserStockFundInterestReceiptModel::where('order_id', $param['id'])->append(['status_text'])->select();
+ return $this->toData('0', 'SUCCESS', ['list' => $list]);
+ } catch (ValidateException $validateException) {
+ // 参数校验失败
+ $message = $validateException->getError();
+ return $this->toData('1', $message);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统异常 请稍后重试', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+
+ //基金返息单列表
+ public function fundInterestList($param, $adminId)
+ {
+ try {
+ // 参数校验
+ validate(OrderValidate::class)->scene('fund_interest_list')->check($param);
+
+ $where = [];
+ $userId = 0;
+ // 用户号精确搜索
+ if (!empty($param['user_no'])) {
+ $user = UserModel::where('user_no', $param['user_no'])->find();
+ if (empty($user)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => [], 'extent' => ['totalMoney' => 0]]);
+ }
+ $userId = $user['user_id'];
+ }
+
+ // 判断是否是代理 如果是代理 只能看他自己管理的用户
+ $whereU = $this->getWhereByIsAgentAndUserId($adminId, $where, $userId);
+ if (!is_array($whereU)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => [], 'extent' => ['totalMoney' => 0]]);
+ }
+
+ // 状态
+ if (!empty($param['status']) && in_array($param['status'], ['1', '2'])) $where[] = ['status', '=', $param['status']];
+
+ if (!empty($param['stock_code'])) {
+ $stockId = PreFundStockModel::where('stock_code', $param['stock_code'])->value('id');
+ $stockId = $stockId ?? 0;
+ $where[] = ['pre_stock_id', '=', $stockId];
+ }
+
+ $list = UserStockFundInterestReceiptModel::where($whereU)->where($where)->append(['status_text'])->order('status', 'asc')->order('return_date', 'asc')->page($param['page'], $param['limit'])->select();
+ $total = UserStockFundInterestReceiptModel::where($whereU)->where($where)->count();
+
+ $rows = [];
+ if (!$list->isEmpty()) {
+ // 获取用户号
+ $userIdArr = [];
+ // stock
+ $preStockId = [];
+ foreach ($list as $idItem) {
+ $userIdArr[] = $idItem['user_id'];
+ $orderIdArr[] = $idItem['order_id'];
+ $preStockId[] = $idItem['pre_stock_id'];
+ }
+
+ $userNoArr = UserModel::where('user_id', 'in', $userIdArr)->column('user_no', 'user_id');
+ $orderArr = UserFundPreStockOrderModel::where('id', 'in', $orderIdArr)->column('*', 'id');
+ $stockArr = PreFundStockModel::where('id', 'in', $preStockId)->column('*', 'id');
+
+ $rows = $list->toArray();
+ foreach ($rows as $key => $item) {
+ $order = $orderArr[$item['order_id']] ?? [];
+ $stock = $stockArr[$item['pre_stock_id']] ?? [];
+ if (empty($stock) || empty($order)) continue;
+ $rows[$key]['user_no'] = $userNoArr[$item['user_id']] ?? '-'; // 用户号
+ $rows[$key]['stock_code'] = $stock['stock_code'] ?? '-';
+ $rows[$key]['stock_name'] = $stock['stock_name'] ?? '-';
+ $rows[$key]['stock_type'] = PreFundStockModel::$stockTypeList[$order['interest_type']] ?? '-';
+ $rows[$key]['order_no'] = $order['order_no'] ?? '-';
+ $rows[$key]['rate'] = $order['stock_rate'] . "%" ?? '-';
+ $rows[$key]['cycle'] = $order['stock_cycle'] . PreFundStockModel::$cycleTypeList[$order['stock_cycle_type']] ?? '-';
+ $rows[$key]['open_time'] = $stock['open_time'] ?? '-';
+ }
+ }
+
+ return $this->toData('0', 'SUCCESS', ['total' => $total, 'list' => $rows, 'extend' => [
+ 'tape_list' => [],
+ 'stock_type_list' => PreFundStockModel::$stockTypeList,
+ 'cycle_type_list' => PreFundStockModel::$cycleTypeList
+ ]]);
+ } catch (ValidateException $validateException) {
+ // 参数校验失败
+ $message = $validateException->getError();
+ return $this->toData('1', $message);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统异常 请稍后重试', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+
+
+
+ ########################################## 印度期权交易 ###########################################
+ // 印度期权持仓
+ public function inOptionHold($param, $adminId)
+ {
+ try {
+ // 参数校验
+ validate(OrderValidate::class)->scene('hk_stockHold')->check($param);
+
+ $where = [];
+ $userId = 0;
+ // 用户号精确搜索
+ if (!empty($param['user_no'])) {
+ $user = UserModel::where('user_no', $param['user_no'])->find();
+ if (empty($user)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => [], 'extent' => ['totalMoney' => 0]]);
+ }
+ $userId = $user['user_id'];
+ }
+
+ // 判断是否是代理 如果是代理 只能看他自己管理的用户
+ $whereU = $this->getWhereByIsAgentAndUserId($adminId, $where, $userId);
+ if (!is_array($whereU)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => [], 'extent' => ['totalMoney' => 0]]);
+ }
+
+ // 订单号
+ if (!empty($param['order_id'])) {
+ $where['order_id'] = $param['order_id'];
+ }
+
+ // 交易对
+ if (!empty($param['stock_id'])) {
+ $where['stock_id'] = $param['contract_id'];
+ }
+
+ if (!empty($param['start_time']) && !empty($param['end_time'])) {
+ $where['open_time'] = ['between time', [$param['start_time'], $param['end_time']]];
+ }
+
+ // 列表
+ $list = StockOptionInrTradeModel::where('status', StockOptionInrTradeModel::STATUS_HOLD)->where($whereU)->where($where)->order('trade_id', 'desc')->page($param['page'], $param['limit'])->select();
+ // 总数
+ $total = StockOptionInrTradeModel::where('status', StockOptionInrTradeModel::STATUS_HOLD)
+ ->where($where)->where($whereU)
+ ->count();
+ // 持仓总金额
+ $totalModel = StockOptionInrTradeModel::where('status', StockOptionInrTradeModel::STATUS_HOLD)
+ ->field('SUM(order_money) as total')->where($whereU)
+ ->where($where)->find();
+
+ // 持仓总手续费
+ $totalServiceCost = StockOptionInrTradeModel::where('status', StockOptionInrTradeModel::STATUS_HOLD)
+ ->where($whereU)
+ ->where($where)
+ ->sum('service_cost');
+
+ $rows = [];
+ if (!$list->isEmpty()) {
+ // 获取用户号
+ $userIdArr = [];
+ foreach ($list as $idItem) {
+ $userIdArr[] = $idItem['user_id'];
+ }
+
+ $userNoArr = UserModel::where('user_id', 'in', $userIdArr)->column('user_no', 'user_id');
+ foreach ($list as $item) {
+ $orderNumber = number_format($item['order_number'], '18', '.', '');
+ $orderPrice = number_format($item['deal_price'], '18', '.', '');
+ $orderAmount = bcmul($orderNumber, $orderPrice, 18);
+ $rows[] = [
+ 'trade_id' => $item['trade_id'], //
+ 'user_no' => $userNoArr[$item['user_id']] ?? '-', // 用户号
+ 'order_id' => $item['order_id'], // 用户号
+ 'open_time' => $item['open_time'] ?? '-', // 挂单时间
+ 'trade_type' => $item['trade_type'] == 1 ? '买涨' : '买跌',
+ 'order_money' => $orderAmount, // 订单金额
+ 'stock_id' => $item['stock_id'], // 股票代码
+ 'order_number' => $item['order_number'], // 数量
+ 'service_cost' => $item['service_cost'], // 服务费
+ 'float' => '-', // 浮动盈亏
+ 'deal_price' => $item['deal_price'], // 开仓价
+ 'now_price' => '-', // 当前价
+ 'stop_loss_price' => $item['stop_loss_price'], // 止损价
+ 'stop_win_price' => $item['stop_win_price'], // 止盈价
+ 'pry_num' => $item['pry_num'], // 杠杆
+ ];
+ }
+ }
+
+ return $this->toData('0', 'SUCCESS', ['total' => $total, 'list' => $rows,
+ 'extent' => ['totalMoney' => round($totalModel['total'], 4), 'totalServiceCost' => $totalServiceCost,
+ ]]);
+
+ } catch (ValidateException $validateException) {
+ // 参数校验失败
+ $message = $validateException->getError();
+ return $this->toData('1', $message);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统异常 请稍后重试', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+
+ // 印度期权挂单
+ public function inOptionPlace($param, $adminId)
+ {
+ try {
+ // 参数校验
+ validate(OrderValidate::class)->scene('hk_stockPlace')->check($param);
+
+ $where = [];
+ $userId = 0;
+ // 用户号精确搜索
+ if (!empty($param['user_no'])) {
+ $user = UserModel::where('user_no', $param['user_no'])->find();
+ if (empty($user)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => [], 'extent' => ['totalMoney' => 0]]);
+ }
+ $userId = $user['user_id'];
+ }
+
+ // 判断是否是代理 如果是代理 只能看他自己管理的用户
+ $whereU = $this->getWhereByIsAgentAndUserId($adminId, $where, $userId);
+ if (!is_array($whereU)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => [], 'extent' => ['totalMoney' => 0]]);
+ }
+
+ // 订单号
+ if (!empty($param['order_id'])) {
+ $where['order_id'] = $param['order_id'];
+ }
+
+ // 交易对
+ if (!empty($param['stock_id'])) {
+ $where['stock_id'] = $param['contract_id'];
+ }
+
+ if (!empty($param['start_time']) && !empty($param['end_time'])) {
+ $where['create_time'] = ['between time', [$param['start_time'], $param['end_time']]];
+ }
+
+ // 列表
+ $list = StockOptionInrTradeModel::where('status', StockOptionInrTradeModel::STATUS_PLACE)->where($whereU)->where($where)->order('trade_id', 'desc')->page($param['page'], $param['limit'])->select();
+ // 总数
+ $total = StockOptionInrTradeModel::where('status', StockOptionInrTradeModel::STATUS_PLACE)
+ ->where($where)->where($whereU)
+ ->count();
+ // 持仓总金额
+ $totalModel = StockOptionInrTradeModel::where('status', StockOptionInrTradeModel::STATUS_PLACE)
+ ->field('SUM(order_money) as total')->where($whereU)
+ ->where($where)->find();
+
+ $rows = [];
+ if (!$list->isEmpty()) {
+ // 获取用户号
+ $userIdArr = [];
+ foreach ($list as $idItem) {
+ $userIdArr[] = $idItem['user_id'];
+ }
+
+ $userNoArr = UserModel::where('user_id', 'in', $userIdArr)->column('user_no', 'user_id');
+ foreach ($list as $item) {
+ // 挂单价
+ $price = $item['limit_price'];
+ if ($item['deal_type'] == 2) {
+ $price = $item['market_price'];
+ }
+
+ $orderNumber = number_format($item['order_number'], '18', '.', '');
+ $orderPrice = number_format($price, '18', '.', '');
+ $orderAmount = bcmul($orderNumber, $orderPrice, 18);
+ $rows[] = [
+ 'trade_id' => $item['trade_id'], //
+ 'order_id' => $item['order_id'], // 订单号
+ 'user_no' => $userNoArr[$item['user_id']] ?? '-', // 用户号
+ 'create_time' => $item['create_time'], // 挂单时间
+ 'order_money' => $orderAmount, // 订单金额
+ 'trade_type' => $item['trade_type'] == 1 ? '买涨' : '买跌',
+ 'stock_id' => $item['stock_id'], // 合约代码
+ 'order_number' => $item['order_number'], // 数量
+ 'service_cost' => $item['service_cost'], // 服务费
+ 'deal_price' => $price, // 委托价
+ 'stop_loss_price' => $item['stop_loss_price'], // 止损价
+ 'stop_win_price' => $item['stop_win_price'], // 止盈价
+ 'limit_price' => $item['limit_price'], // 限价
+ 'pry_num' => $item['pry_num'], // 杠杆
+ ];
+ }
+ }
+
+ return $this->toData('0', 'SUCCESS', ['total' => $total, 'list' => $rows,
+ 'extent' => ['totalMoney' => round($totalModel['total'], 4),
+ ]]);
+
+ } catch (ValidateException $validateException) {
+ // 参数校验失败
+ $message = $validateException->getError();
+ return $this->toData('1', $message);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统异常 请稍后重试', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+
+ // 印度期权撤单
+ public function inOptionBack($param, $adminId)
+ {
+ try {
+ // 参数校验
+ validate(OrderValidate::class)->scene('hk_stockBack')->check($param);
+
+ $where = [];
+ $userId = 0;
+ // 用户号精确搜索
+ if (!empty($param['user_no'])) {
+ $user = UserModel::where('user_no', $param['user_no'])->find();
+ if (empty($user)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => [], 'extent' => ['totalMoney' => 0]]);
+ }
+ $userId = $user['user_id'];
+ }
+
+ // 判断是否是代理 如果是代理 只能看他自己管理的用户
+ $whereU = $this->getWhereByIsAgentAndUserId($adminId, $where, $userId);
+ if (!is_array($whereU)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => [], 'extent' => ['totalMoney' => 0]]);
+ }
+
+ // 订单号
+ if (!empty($param['order_id'])) {
+ $where['order_id'] = $param['order_id'];
+ }
+
+ // 交易对
+ if (!empty($param['stock_id'])) {
+ $where['stock_id'] = $param['contract_id'];
+ }
+
+ if (!empty($param['start_time']) && !empty($param['end_time'])) {
+ $where['update_time'] = ['between time', [$param['start_time'], $param['end_time']]];
+ }
+
+ // 列表
+ $list = StockOptionInrTradeModel::where('status', StockOptionInrTradeModel::STATUS_BACK)->where($whereU)->where($where)->order('trade_id', 'desc')->page($param['page'], $param['limit'])->select();
+ // 总数
+ $total = StockOptionInrTradeModel::where('status', StockOptionInrTradeModel::STATUS_BACK)
+ ->where($where)->where($whereU)
+ ->count();
+ // 持仓总金额
+ $totalModel = StockOptionInrTradeModel::where('status', StockOptionInrTradeModel::STATUS_BACK)
+ ->field('SUM(order_money) as total')->where($whereU)
+ ->where($where)->find();
+
+
+ $rows = [];
+ if (!$list->isEmpty()) {
+ // 获取用户号
+ $userIdArr = [];
+ foreach ($list as $idItem) {
+ $userIdArr[] = $idItem['user_id'];
+ }
+
+ $userNoArr = UserModel::where('user_id', 'in', $userIdArr)->column('user_no', 'user_id');
+ foreach ($list as $item) {
+ // 挂单价
+ $price = $item['limit_price'];
+ if ($item['deal_type'] == 2) {
+ $price = $item['market_price'];
+ }
+
+ $orderNumber = number_format($item['order_number'], '18', '.', '');
+ $orderPrice = number_format($price, '18', '.', '');
+ $orderAmount = bcmul($orderNumber, $orderPrice, 18);
+ $rows[] = [
+ 'trade_id' => $item['trade_id'], //
+ 'user_no' => $userNoArr[$item['user_id']] ?? '-', // 用户号
+ 'order_id' => $item['order_id'], // 用户号
+ 'create_time' => $item['create_time'], // 挂单时间
+ 'update_time' => $item['update_time'], // 挂单时间
+ 'trade_type' => $item['trade_type'] == 1 ? '买涨' : '买跌',
+ 'order_money' => $orderAmount, // 订单金额
+ 'stock_id' => $item['stock_id'], // 合约代码
+ 'order_number' => $item['order_number'], // 数量
+ 'service_cost' => $item['service_cost'], // 服务费
+ 'deal_price' => $price, // 委托价
+ 'stop_loss_price' => $item['stop_loss_price'], // 止损价
+ 'stop_win_price' => $item['stop_win_price'], // 止盈价
+ 'pry_num' => $item['pry_num'], // 杠杆
+ ];
+ }
+ }
+
+ return $this->toData('0', 'SUCCESS', ['total' => $total, 'list' => $rows,
+ 'extent' => ['totalMoney' => round($totalModel['total'], 4),
+ ]]);
+
+ } catch (ValidateException $validateException) {
+ // 参数校验失败
+ $message = $validateException->getError();
+ return $this->toData('1', $message);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统异常 请稍后重试', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+
+ // 印度期权平仓
+ public function inOptionClear($param, $adminId)
+ {
+ try {
+ // 参数校验
+ validate(OrderValidate::class)->scene('hk_stockClear')->check($param);
+
+ $where = [];
+ $userId = 0;
+ // 用户号精确搜索
+ if (!empty($param['user_no'])) {
+ $user = UserModel::where('user_no', $param['user_no'])->find();
+ if (empty($user)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => [], 'extent' => ['totalMoney' => 0]]);
+ }
+ $userId = $user['user_id'];
+ }
+
+ // 判断是否是代理 如果是代理 只能看他自己管理的用户
+ $whereU = $this->getWhereByIsAgentAndUserId($adminId, $where, $userId);
+ if (!is_array($whereU)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => [], 'extent' => ['totalMoney' => 0]]);
+ }
+
+ // 订单号
+ if (!empty($param['order_id'])) {
+ $where['order_id'] = $param['order_id'];
+ }
+
+ // 交易对
+ if (!empty($param['contract_id'])) {
+ $where['contract_id'] = $param['contract_id'];
+ }
+
+ if (!empty($param['start_time']) && !empty($param['end_time'])) {
+ $where['open_time'] = ['between time', [$param['start_time'], $param['end_time']]];
+ }
+
+ // 列表
+ $list = StockOptionInrTradeModel::where('status', StockOptionInrTradeModel::STATUS_CLEAR)->where($whereU)->where($where)->order('trade_id', 'desc')->page($param['page'], $param['limit'])->select();
+ // 总数
+ $total = StockOptionInrTradeModel::where('status', StockOptionInrTradeModel::STATUS_CLEAR)
+ ->where($where)->where($whereU)
+ ->count();
+
+ // 持仓总手续费
+ $totalClosingCost = StockOptionInrTradeModel::where('status', StockOptionInrTradeModel::STATUS_CLEAR)
+ ->where($whereU)
+ ->where($where)
+ ->sum('closing_cost');
+
+ $totalFloat = StockOptionInrTradeModel::where('status', StockOptionInrTradeModel::STATUS_CLEAR)
+ ->where($whereU)
+ ->where($where)
+ ->field("SUM( CASE WHEN trade_type = 1 THEN ( closing_price - deal_price )* order_number ELSE ( deal_price - closing_price )* order_number END ) AS total")->find();
+
+
+ $rows = [];
+ if (!$list->isEmpty()) {
+ // 获取用户号
+ $userIdArr = [];
+ foreach ($list as $idItem) {
+ $userIdArr[] = $idItem['user_id'];
+ }
+
+ $userNoArr = UserModel::where('user_id', 'in', $userIdArr)->column('user_no', 'user_id');
+ foreach ($list as $item) {
+ // 计算浮动盈亏
+ if ($item['trade_type'] == 1) {
+ $float = $item['closing_price'] - $item['deal_price'];
+ } else {
+ $float = $item['deal_price'] - $item['closing_price'];
+ }
+ $float = bcmul($float, $item['order_number'], 18);
+
+ $orderNumber = number_format($item['order_number'], '18', '.', '');
+ $orderPrice = number_format($item['deal_price'], '18', '.', '');
+ $orderAmount = bcmul($orderNumber, $orderPrice, 18);
+
+ $rows[] = [
+ 'trade_id' => $item['trade_id'], //
+ 'user_no' => $userNoArr[$item['user_id']] ?? '-', // 用户号
+ 'order_id' => $item['order_id'], // 用户号
+ 'closing_time' => $item['closing_time'], // 平仓时间
+ 'trade_type' => $item['trade_type'] == 1 ? '买涨' : '买跌',
+ 'order_money' => $orderAmount, // 订单金额
+ 'stock_id' => $item['stock_id'], // 股票代码
+ 'order_number' => $item['order_number'], // 数量
+ 'service_cost' => $item['service_cost'], // 服务费
+ 'closing_cost' => $item['closing_cost'], // 平仓服务费
+ 'deal_price' => $item['deal_price'], // 开仓价
+ 'closing_price' => $item['closing_price'], // 平仓价格
+ 'stop_loss_price' => $item['stop_loss_price'], // 止损价
+ 'stop_win_price' => $item['stop_win_price'], // 止盈价
+ 'float' => $float, // 平仓盈亏
+ 'pry_num' => $item['pry_num'], // 杠杆
+ ];
+ }
+ }
+
+ return $this->toData('0', 'SUCCESS', ['total' => $total, 'list' => $rows,
+ 'extent' => [
+ 'totalClosingCost' => $totalClosingCost,
+ 'totalFloat' => $totalFloat['total'],
+ ]]);
+
+ } catch (ValidateException $validateException) {
+ // 参数校验失败
+ $message = $validateException->getError();
+ return $this->toData('1', $message);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统异常 请稍后重试', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+
+ ################################################# 大宗交易
+ //大宗交易订单
+ public function blockStock($param, $adminId)
+ {
+ try {
+ // 参数校验
+ validate(OrderValidate::class)->scene('fund_stock')->check($param);
+
+ $where = [];
+ $userId = 0;
+ // 用户号精确搜索
+ if (!empty($param['user_no'])) {
+ $user = UserModel::where('user_no', $param['user_no'])->find();
+ if (empty($user)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => [], 'extent' => ['totalMoney' => 0]]);
+ }
+ $userId = $user['user_id'];
+ }
+
+ // 判断是否是代理 如果是代理 只能看他自己管理的用户
+ $whereU = $this->getWhereByIsAgentAndUserId($adminId, $where, $userId);
+ if (!is_array($whereU)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => [], 'extent' => ['totalMoney' => 0]]);
+ }
+
+ if (!empty($param['type']) && is_numeric($param['type'])) {
+ $where['type'] = $param['type'];
+ }
+
+ $list = UserStockBlockOrderModel::where($whereU)->where($where)->order('id', 'desc')->page($param['page'], $param['limit'])->select();
+ $total = UserStockBlockOrderModel::where($whereU)->where($where)->count();
+
+ $rows = [];
+ if (!$list->isEmpty()) {
+ // 获取用户号
+ $userIdArr = [];
+ // stock
+ $preStockId = [];
+ foreach ($list as $idItem) {
+ $userIdArr[] = $idItem['user_id'];
+// $preStockId[] = $idItem['pre_stock_id'];
+ }
+
+ $userNoArr = UserModel::where('user_id', 'in', $userIdArr)->column('user_no', 'user_id');
+// $stockArr = PreFundStockModel::where('id', 'in', $preStockId)->column('*', 'id');
+
+ $rows = $list->toArray();
+ foreach ($rows as $key => $item) {
+// $stock = $stockArr[$item['pre_stock_id']] ?? [];
+// if (empty($stock)) continue;
+ $rows[$key]['user_no'] = $userNoArr[$item['user_id']] ?? '-'; // 用户号
+ $rows[$key]['stock_name'] = $item['stock_name'] ?? '-';
+ $rows[$key]['market_price'] = $item['market_price'] ?? '-';
+ $rows[$key]['deal_price'] = $item['deal_price'] ?? '-';
+ $rows[$key]['order_number'] = $item['order_number'] ?? '-';
+ $rows[$key]['market_money'] = $item['market_money'] ?? '-';
+ $rows[$key]['order_money'] = $item['order_money'] ?? '-';
+ $rows[$key]['status'] = UserStockBlockOrderModel::$statusList[$item['status']];
+ $rows[$key]['type'] = UserStockBlockOrderModel::$typeList[$item['type']];
+ $rows[$key]['create_time'] = $item['create_time'] ?? '-';
+ }
+ }
+
+ return $this->toData('0', 'SUCCESS', ['total' => $total, 'list' => $rows, 'extend' => [
+ 'status_list' => UserStockBlockOrderModel::$statusList,
+ 'type_list' => UserStockBlockOrderModel::$typeList
+ ]]);
+
+ } catch (ValidateException $validateException) {
+ // 参数校验失败
+ $message = $validateException->getError();
+ return $this->toData('1', $message);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统异常 请稍后重试', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/admin/service/RechargeService.php b/app/admin/service/RechargeService.php
new file mode 100644
index 0000000..ba5b0b6
--- /dev/null
+++ b/app/admin/service/RechargeService.php
@@ -0,0 +1,176 @@
+scene('index')->check($param);
+ $where = [];
+ $userId = 0;
+ // 用户号精确搜索
+ if (!empty($param['user_no'])) {
+ $user = UserModel::where('user_no', $param['user_no'])->find();
+ if (empty($user)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => [], ]);
+ }
+ $userId = $user['user_id'];
+ }
+ $statusList = RechargeApplyModel::$statusList;
+ // 判断是否是代理 如果是代理 只能看他自己管理的用户
+ $whereU = $this->getWhereByIsAgentAndUserId($adminId, $where, $userId);
+ if (!is_array($whereU)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => [], 'extend' => $statusList]);
+ }
+ // 订单号
+ if (!empty($param['order_id'])) {
+ $where['order_no'] = $param['order_id'];
+ }
+ if (isset($param['is_online'])) {
+ $where['is_online'] = $param['is_online'];
+ if ($param['is_online'] == 1) $statusList[0] = '用户取消';
+ }
+
+ if (isset($param['status'])) {
+ $where['status'] = $param['status'];
+ }
+
+ if (!empty($param['start_time']) && !empty($param['end_time'])) {
+ $where['update_time'] = ['between time', [$param['start_time'], $param['end_time']]];
+ }
+
+ // 列表
+ $list = RechargeApplyModel::where($where)->where($whereU)->order('id', 'desc')->page($param['page'], $param['limit'])->select();
+ // 总数
+ $total = RechargeApplyModel::where($where)->where($whereU)->count();
+ // 统计 充值成功
+ $sum = RechargeApplyModel::where($where)->where($whereU)->where('status', 1)->sum('recharge_num');
+
+ $rows = [];
+ if (!$list->isEmpty()) {
+ // 获取用户号
+ $userIdArr = [];
+ foreach ($list as $idItem) {
+ $userIdArr[] = $idItem['user_id'];
+ }
+ $userNoArr = UserModel::where('user_id', 'in', $userIdArr)->column('user_no', 'user_id');
+ $rows = $list->toArray();
+ foreach ($rows as $key => $item) {
+ $rows[$key]['status_text'] = $statusList[$item['status']];
+ $rows[$key]['user_no'] = $userNoArr[$item['user_id']] ?? '-'; // 用户号
+ $rows[$key]['order_id'] = $item['order_no'];
+ $rows[$key]['recharge_channel'] = PaymentListModel::where('id', $item['recharge_channel'])->value('channel');
+ }
+ }
+ return $this->toData('0', 'SUCCESS', ['total' => $total, 'list' => $rows, 'sum' => $sum . 'USD', 'extend' => $statusList]);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统异常 请稍后重试', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+
+ public function info($param, $adminId)
+ {
+ try {
+ // 参数校验
+ validate(RechargeValidate::class)->scene('info')->check($param);
+ $where = [
+ 'id' => $param['id']
+ ];
+
+ $userId = 0;
+ $where = $this->getWhereByIsAgentAndUserId($adminId, $where, $userId);
+ if (!is_array($where)) {
+ return $this->toData('0', 'SUCCESS', []);
+ }
+
+ $info = RechargeApplyModel::getOrderInfo($where);
+ if ($info['file_id']) {
+ $info['file_url'] = FileModel::getFilePath($info['file_id']);
+ }
+ $payment_info = PaymentListModel::getPaymentInfo([
+ 'id' => $info['recharge_channel']
+ ]);
+ if ($payment_info) {
+ $info['recharge_channel'] = !isset($payment_info['channel']) ? $payment_info['channel'] : $info['recharge_channel'];
+ $info['bank_name'] = !isset($payment_info['bank_name']) ? $payment_info['bank_name'] : '';
+ $info['bank_branch'] = !isset($payment_info['bank_branch']) ? $payment_info['bank_branch'] : '';
+ $info['bank_user'] = !isset($payment_info['bank_user']) ? $payment_info['bank_user'] : '';
+ $info['bank_account'] = !isset($payment_info['bank_account']) ? $payment_info['bank_account'] : '';
+ $info['wallet_address'] = !isset($payment_info['wallet_address']) ? $payment_info['wallet_address'] : '';
+ }
+ return $this->toData('0', 'SUCCESS', $info);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统异常 请稍后重试', [$exception->getMessage(), $exception->getTrace()]);
+ }
+
+ }
+
+ public function check($param, $adminId)
+ {
+ try {
+ // 参数校验
+ validate(RechargeValidate::class)->scene('info')->check($param);
+ $isAgent = AdminModel::checkUserIsAgent($adminId);
+ if ($isAgent) {
+ return $this->toData('10040', '代理无权限操作');
+ }
+ $where = [
+ 'id' => $param['id']
+ ];
+ $userId = 0;
+ $where = $this->getWhereByIsAgentAndUserId($adminId, $where, $userId);
+ if (!is_array($where)) {
+ return $this->toData('0', 'SUCCESS', []);
+ }
+ $info = RechargeApplyModel::getOrderInfo($where);
+ if ($info) {
+ if ($info['is_online'] == 1){
+ return $this->toData('10040', '在线充值 不可操作');
+ }
+
+ if ($info['is_check'] == 0) {
+ if ($param['check_status'] == 1) {
+ $result = $this->updateUserAsset($info['user_id'], $info['account_type'], 1, $info['market_amount'], 0, $info['order_no']);
+ if ($result['status'] == 200) {
+ RechargeApplyModel::where('id', $info['id'])->update([
+ 'is_check' => 1,
+ 'status' => 1,
+ 'deal_time' => date('Y-m-d H:i:s')
+ ]);
+ } else {
+ return $this->toData('1015', '系统异常 请稍后重试');
+ }
+ } else {
+ RechargeApplyModel::where('id', $info['id'])->update([
+ 'is_check' => 2,
+ 'status' => 2
+ ]);
+ }
+ }
+ if ($info['file_id']) {
+ $info['file_url'] = FileModel::getFilePath($info['file_id']);
+ $file = dirname(dirname(dirname(__DIR__))) . "/public" . $info['file_url'];
+ @unlink($file);
+ }
+
+ return $this->toData('0', 'SUCCESS', []);
+ } else {
+ return $this->toData('1', '参数错误', []);
+ }
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统异常 请稍后重试', [$exception->getMessage(), $exception->getTrace()]);
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/app/admin/service/UserService.php b/app/admin/service/UserService.php
new file mode 100644
index 0000000..fc3eb2a
--- /dev/null
+++ b/app/admin/service/UserService.php
@@ -0,0 +1,1003 @@
+scene('index')->check($param);
+
+ $where = [];
+ // 邮箱搜索
+ if (!empty($param['email']) && trim($param['email'])) {
+ $where['email'] = $param['email'];
+ }
+
+ // 用户审核状态筛选
+ if (!empty($param['real_status']) && is_numeric($param['real_status'])) {
+ $where['real_status'] = $param['real_status'];
+ }
+
+ // 用户号
+ if (!empty($param['user_no']) && trim($param['user_no'])) {
+ $where['user_no'] = $param['user_no'];
+ }
+
+ // 手机号搜索
+ if (!empty($param['phone']) && trim($param['phone'])) {
+ $where['phone_number'] = $param['phone'];
+ }
+
+ // 用户审核状态筛选
+ if (!empty($param['agent_id']) && is_numeric($param['agent_id'])) {
+ $where['agent_id'] = $param['agent_id'];
+ }
+
+ //邀请码
+ if (!empty($param['invite_code']) && trim($param['invite_code'])) {
+ $where['invite_code'] = $param['invite_code'];
+ }
+
+ // 杠杆申请状态
+ if (!empty($param['leve_status']) && is_numeric($param['leve_status'])) {
+ $where['leve_status'] = $param['leve_status'];
+ }
+
+ // 测试用户
+ if (!empty($param['is_test_user']) && is_numeric($param['is_test_user'])) {
+ $where['is_test_user'] = $param['is_test_user'];
+ }
+
+ // 注册时间
+ if (!empty($param['start_time']) && !empty($param['end_time'])) {
+ $where['create_time'] = ['between time', [$param['start_time'], $param['end_time']]];
+ }
+
+ $IsAgent = AdminModel::checkUserIsAgent($adminId);
+ $agentNameArr = AdminModel::where('role_id', 10)->column('user_name', 'id');
+
+ $marketRate = StockMarketModel::column('rate', 'stock_market_type');
+ $tapeList = (new StockMarketModel)->getAllTape();
+ // 父级用户号
+ if (!empty($param['parent_user_no']) && trim($param['parent_user_no'])) {
+ $parentUser = UserModel::where('user_no', $param['parent_user_no'])->find();
+ if (empty($parentUser)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => [], 'extent' => ['market_type_list' => StockMarketModel::STOCK_MARKET_TYPE, 'is_agent' => $IsAgent, 'agent_list' => $agentNameArr, 'market_rate' => $marketRate, 'market_tape_list' => $tapeList]]);
+ }
+ $where['parent_id'] = $parentUser->user_id;
+ }
+
+ if (!empty($where['user_id']) && is_numeric($where['user_id']) && $where['user_id'] == 0) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => [], 'extent' => ['market_type_list' => StockMarketModel::STOCK_MARKET_TYPE, 'is_agent' => $IsAgent, 'agent_list' => $agentNameArr, 'market_rate' => $marketRate, 'market_tape_list' => $tapeList]]);
+ }
+
+ $whereU = $this->getWhereByIsAgentAndUserId($adminId, [], 0);
+ if (!is_array($whereU)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => [], 'extent' => ['market_type_list' => StockMarketModel::STOCK_MARKET_TYPE, 'is_agent' => $IsAgent, 'agent_list' => $agentNameArr, 'market_rate' => $marketRate, 'market_tape_list' => $tapeList]]);
+ }
+
+ $userList = UserModel::where($where)->where($whereU)->page($param['page'], $param['limit'])->order('user_id', 'desc')->select();
+ $total = UserModel::where($where)->where($whereU)->count();
+
+ $rows = [];
+ if (!empty($userList)) {
+ $userIdArr = [];
+ $parentIdArr = [];
+ foreach ($userList as $value) {
+ $userIdArr[] = $value['user_id'];
+ if ($value['parent_id'] > 0) {
+ $parentIdArr[] = $value['parent_id'];
+ }
+ }
+
+ // 查询父级
+ $parentNos = UserModel::where('user_id', 'in', $parentIdArr)->column('user_no', 'user_id');
+
+ // 查询用户余额
+ $userContractList = UserContractModel::where('user_id', 'in', $userIdArr)
+ ->where('contract_id', 'USDT')
+ ->column('usable_num,frozen_num', 'user_id');
+ // 查询用户余额
+ $userContractSecList = UserContractSecModel::where('user_id', 'in', $userIdArr)
+ ->where('contract_id', 'USDT')
+ ->column('usable_num,frozen_num', 'user_id');
+ $userStockList = UserStockModel::where('user_id', 'in', $userIdArr)
+ ->where('stock_id', 'USD')
+ ->column('usable_num,frozen_num', 'user_id');
+ $userDigitalList = UserDigitalModel::where('user_id', 'in', $userIdArr)
+ ->where('digital_id', 'USDT')
+ ->column('usable_num,frozen_num', 'user_id');
+
+ // 印尼资产
+ $userStockIdrList = UserStockIdnModel::where('user_id', 'in', $userIdArr)
+ ->where('stock_id', 'IDR')
+ ->column('usable_num,frozen_num', 'user_id');
+
+ // 泰股资产
+ $userStockThaList = UserStockThaModel::where('user_id', 'in', $userIdArr)
+ ->where('stock_id', 'THB')
+ ->column('usable_num,frozen_num', 'user_id');
+
+ // 马股资产
+ $userStockMysList = UserStockMysModel::where('user_id', 'in', $userIdArr)
+ ->where('stock_id', 'MYR')
+ ->column('usable_num,frozen_num', 'user_id');
+
+ // 印度股票资产
+ $userStockInList = UserStockInModel::where('user_id', 'in', $userIdArr)
+ ->where('stock_id', 'INR')
+ ->column('usable_num,frozen_num', 'user_id');
+ //新加坡股票资产
+ $userStockSGDList = UserStockSgdModel::where('user_id', 'in', $userIdArr)
+ ->where('stock_id', 'SGD')
+ ->column('usable_num,frozen_num', 'user_id');
+ //基金资产
+ $userStockFundList = UserStockFundModel::where('user_id', 'in', $userIdArr)
+ ->where('stock_id', 'USD')
+ ->column('usable_num,frozen_num', 'user_id');
+ //印度期权
+ $userStockOptionInrList = UserStockOptionInrModel::where('user_id', 'in', $userIdArr)
+ ->where('stock_id', 'INR')
+ ->column('usable_num,frozen_num', 'user_id');
+ //港股
+ $userStockHkList = UserStockHkdModel::where('user_id', 'in', $userIdArr)
+ ->where('stock_id', 'HKD')
+ ->column('usable_num,frozen_num', 'user_id');
+ //英股
+ $userStockUkList = UserStockGBXModel::where('user_id', 'in', $userIdArr)
+ ->where('stock_id', 'GBX')
+ ->column('usable_num,frozen_num', 'user_id');
+ //法股
+ $userStockFurList = UserStockFurModel::where('user_id', 'in', $userIdArr)
+ ->where('stock_id', 'EUR')
+ ->column('usable_num,frozen_num', 'user_id');
+ //德股
+ $userStockEurList = UserStockEurModel::where('user_id', 'in', $userIdArr)
+ ->where('stock_id', 'EUR')
+ ->column('usable_num,frozen_num', 'user_id');
+ //巴西
+ $userStockBrlList = UserStockBrlModel::where('user_id', 'in', $userIdArr)
+ ->where('stock_id', 'BRL')
+ ->column('usable_num,frozen_num', 'user_id');
+
+ $userStockJpList = UserStockJpModel::where('user_id', 'in', $userIdArr)
+ ->where('stock_id', 'JPY')
+ ->column('usable_num,frozen_num', 'user_id');
+ //外汇
+ $userForexList = UserForexModel::where('user_id', 'in', $userIdArr)
+ ->where('contract_id', 'USD')
+ ->column('usable_num,frozen_num', 'user_id');
+
+
+ //最近登录IP、最近登录国家
+ $subQuery = UserLoginLog::field('user_id,MAX(login_date) AS last_login_date')
+ ->where('user_id', 'in', $userIdArr)->group('user_id')->buildSql();
+ $lastLoginLog = UserLoginLog::alias('a')->field('a.id')
+ ->join([$subQuery => 'w'], 'a.user_id=w.user_id AND a.login_date=w.last_login_date')->column(['id', 'ip', 'country', 'city'], 'a.user_id');
+
+ foreach ($userList as $item) {
+ $rows[] = [
+ 'id' => $item['user_id'],
+ 'user_no' => $item['user_no'],
+ 'nickname' => $item['nick_name'],
+ 'regTime' => $item['create_time'],
+ 'parentNo' => $parentNos[$item['parent_id']] ?? '-',
+ 'parent_id' => $item['parent_id'],
+ 'invite_code' => $item['invite_code'],
+ 'email' => $item['email'],
+ 'mobile' => $item['country_code'] . '-' . $item['phone_number'],
+
+ //余额
+ 'digital' => $userDigitalList[$item['user_id']]['usable_num'] ?? '0',
+ 'stock' => $userStockList[$item['user_id']]['usable_num'] ?? '0',
+ 'contract' => $userContractList[$item['user_id']]['usable_num'] ?? '0',
+ 'contract_sec' => $userContractSecList[$item['user_id']]['usable_num'] ?? '0',
+ 'forex' => $userForexList[$item['user_id']]['usable_num'] ?? '0',//外汇
+ 'stock_idn' => $userStockIdrList[$item['user_id']]['usable_num'] ?? '0', // 印尼股票余额
+ 'stock_tha' => $userStockThaList[$item['user_id']]['usable_num'] ?? '0', // 泰股资产
+ 'stock_mys' => $userStockMysList[$item['user_id']]['usable_num'] ?? '0', // 马股资产
+ 'stock_in' => $userStockInList[$item['user_id']]['usable_num'] ?? '0', // 印度股资产
+ 'stock_sgd' => $userStockSGDList[$item['user_id']]['usable_num'] ?? '0', // 新加坡股资产
+ 'stock_fund' => $userStockFundList[$item['user_id']]['usable_num'] ?? '0', // 基金资产
+ 'stock_option_in' => $userStockOptionInrList[$item['user_id']]['usable_num'] ?? '0', // 印度期权资产
+ 'stock_hk' => $userStockHkList[$item['user_id']]['usable_num'] ?? '0', // 香港股资产
+ 'stock_uk' => $userStockUkList[$item['user_id']]['usable_num'] ?? '0', // 英股资产
+ 'stock_fur' => $userStockFurList[$item['user_id']]['usable_num'] ?? '0', // 法股资产
+ 'stock_eur' => $userStockEurList[$item['user_id']]['usable_num'] ?? '0', // 德股资产
+ 'stock_brl' => $userStockBrlList[$item['user_id']]['usable_num'] ?? '0', // 巴西股资产
+ 'stock_jp' => $userStockJpList[$item['user_id']]['usable_num'] ?? '0', // 巴西股资产
+
+ //冻结资金
+ 'digital_frozen' => $userDigitalList[$item['user_id']]['frozen_num'] ?? '0',
+ 'stock_frozen' => $userStockList[$item['user_id']]['frozen_num'] ?? '0',
+ 'contract_frozen' => $userContractList[$item['user_id']]['frozen_num'] ?? '0',
+ 'forex_frozen' => $userForexList[$item['user_id']]['frozen_num'] ?? '0',
+ 'contract_sec_frozen' => $userContractSecList[$item['user_id']]['frozen_num'] ?? '0',
+ 'stock_idn_frozen' => $userStockIdrList[$item['user_id']]['frozen_num'] ?? '0', // 印尼股票余额
+ 'stock_tha_frozen' => $userStockThaList[$item['user_id']]['frozen_num'] ?? '0', // 泰股资产
+ 'stock_mys_frozen' => $userStockMysList[$item['user_id']]['frozen_num'] ?? '0', // 马股资产
+ 'stock_in_frozen' => $userStockInList[$item['user_id']]['frozen_num'] ?? '0', // 印度股资产
+ 'stock_sgd_frozen' => $userStockSGDList[$item['user_id']]['frozen_num'] ?? '0', // 新加坡股资产
+ 'stock_fund_frozen' => $userStockFundList[$item['user_id']]['frozen_num'] ?? '0', // 基金资产
+ 'stock_option_in_frozen' => $userStockOptionInrList[$item['user_id']]['frozen_num'] ?? '0', // 印度期权资产
+ 'stock_hk_frozen' => $userStockHkList[$item['user_id']]['frozen_num'] ?? '0', // 香港股资产
+ 'stock_uk_frozen' => $userStockUkList[$item['user_id']]['frozen_num'] ?? '0', // 英港股资产
+ 'stock_fur_frozen' => $userStockFurList[$item['user_id']]['frozen_num'] ?? '0', // 法股资产
+ 'stock_eur_frozen' => $userStockEurList[$item['user_id']]['frozen_num'] ?? '0', // 德股资产
+ 'stock_brl_frozen' => $userStockBrlList[$item['user_id']]['frozen_num'] ?? '0', // 德股资产
+ 'stock_jp_frozen' => $userStockJpList[$item['user_id']]['frozen_num'] ?? '0', // 德股资产
+
+ 'rechargeAmount' => 0,
+ 'withdrawalAmount' => 0,
+ 'regIp' => $item['reg_ip'],
+ 'status' => $item['status'],
+ 'statusName' => UserModel::$statusMap[$item['status']] ?? '-',
+ 'loginTime' => $item['last_login_time'],
+ 'is_real' => $item['is_real'],
+ 'real_status' => $item['real_status'],
+ 'lever_status' => $item['lever_status'],
+ 'is_test_user' => $item['is_test_user'],
+ 'is_test_user_text' => UserModel::$isTestUserMap[$item['is_test_user']] ?? '-',
+ 'last_ip' => $lastLoginLog[$item['user_id']]['ip'] ?? '-',
+ 'last_country' => empty($lastLoginLog[$item['user_id']]['country']) ? '-' : json_decode($lastLoginLog[$item['user_id']]['country'], true)['en'],
+ 'agent_id' => $item['agent_id'],
+ 'agent_name' => $item['agent_id'] > 0 ? $agentNameArr[$item['agent_id']] ?? '-' : '-',
+ ];
+ }
+ }
+
+ return $this->toData('0', 'SUCCESS', ['total' => $total, 'list' => $rows, 'extent' => ['market_type_list' => StockMarketModel::STOCK_MARKET_TYPE, 'is_agent' => $IsAgent, 'agent_list' => $agentNameArr, 'market_rate' => $marketRate, 'market_tape_list' => $tapeList]]);
+ } catch (ValidateException $validateException) {
+ // 参数校验失败
+ $message = $validateException->getError();
+ return $this->toData('1', $message);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统异常 请稍后重试', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+
+
+ // 修改用户状态
+ public function status($param, $adminId)
+ {
+ try {
+ // 参数校验
+ validate(UserValidate::class)->scene('status')->check($param);
+ $userId = $param['id'];
+ $status = $param['status'];
+ $user = UserModel::where('user_id', $userId)->find();
+ if (empty($user)) {
+ return $this->toData('1', '用户不存在');
+ }
+
+ $bool = $this->checkUserIdInAgent($adminId, $userId);
+ if (!$bool) {
+ return $this->toData('1', '无权操作');
+ }
+
+ UserModel::update(['status' => $status], ['user_id' => $userId]);
+ // 强制推出登录
+ if ($status != UserModel::STATUS_ON) {
+ (new BaseHomeService())->delUserTokenCache($userId);
+ }
+
+ return $this->toData('0', 'SUCCESS');
+ } catch (ValidateException $validateException) {
+ // 参数校验失败
+ $message = $validateException->getError();
+ return $this->toData('1', $message);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统异常 请稍后重试', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+
+
+ // 资产修改
+ public function change($param, $adminId)
+ {
+ try {
+ // 参数校验
+ validate(UserValidate::class)->scene('change')->check($param);
+
+ // 手动判断额度是否有效
+ if (empty($param['amount']) || !preg_match('/^[0-9]+(.[0-9]{0,18})?$/', $param['amount'])) {
+ return $this->toData('1', '调整额度格式错误');
+ }
+
+ $userId = $param['id'];
+ $type = $param['type']; // 1 现货 2 合约 3 股票
+ $amount = $param['amount']; // 调整为
+ $user = UserModel::where('user_id', $userId)->find();
+ if (empty($user)) {
+ return $this->toData('1', '用户不存在');
+ }
+ $bool = AdminModel::checkUserIsAgent($adminId);
+ if ($bool) {
+ return $this->toData('1', '无权操作');
+ }
+
+ $rate = 0;
+ $marketArr = StockMarketModel::column('rate', 'unit');
+
+ // 查询账户余额
+ switch ($param['type']) {
+ case '1': //现货
+ $originMoney = UserDigitalModel::where('user_id', $param['id'])->value('usable_num');
+
+ $rate = 1;
+ break;
+ case '2': //合约
+ $originMoney = UserContractModel::where('user_id', $param['id'])->value('usable_num');
+
+ $rate = 1;
+ break;
+ case '3': //美股
+ $originMoney = UserStockModel::where('user_id', $param['id'])
+ ->where('stock_id', 'USD')
+ ->value('usable_num');
+
+ $rate = $marketArr['USD'] ?? 0;
+ break;
+ case '4':
+ $originMoney = UserStockIdnModel::where('user_id', $param['id'])
+ ->where('stock_id', 'IDR')
+ ->value('usable_num');
+
+ $rate = $marketArr['IDR'] ?? 0;
+ break;
+ case '5':
+ $originMoney = UserStockMysModel::where('user_id', $param['id'])
+ ->where('stock_id', 'MYR')
+ ->value('usable_num');
+
+ $rate = $marketArr['MYR'] ?? 0;
+ break;
+ case '6':
+ $originMoney = UserStockThaModel::where('user_id', $param['id'])
+ ->where('stock_id', 'THB')
+ ->value('usable_num');
+
+ $rate = $marketArr['THB'] ?? 0;
+ break;
+ case '7':
+ $originMoney = UserStockInModel::where('user_id', $param['id'])
+ ->where('stock_id', 'INR')
+ ->value('usable_num');
+
+ $rate = $marketArr['INR'] ?? 0;
+ break;
+ case '8': //秒合约
+ $originMoney = UserContractSecModel::where('user_id', $param['id'])->value('usable_num');
+
+ $rate = 1;
+ break;
+ case '9':
+ $originMoney = UserStockSgdModel::where('user_id', $param['id'])
+ ->where('stock_id', 'SGD')
+ ->value('usable_num');
+
+ $rate = $marketArr['SGD'] ?? 0;
+ break;
+
+ case '10':
+ $originMoney = UserStockFundModel::where('user_id', $param['id'])
+ ->where('stock_id', 'USD')
+ ->value('usable_num');
+
+ $rate = $marketArr['USD'] ?? 0;
+ break;
+ case '11':
+ $originMoney = UserStockOptionInrModel::where('user_id', $param['id'])
+ ->where('stock_id', 'INR')
+ ->value('usable_num');
+
+ $rate = $marketArr['INR'] ?? 0;
+ break;
+ case '12':
+ $originMoney = UserStockHkdModel::where('user_id', $param['id'])
+ ->where('stock_id', 'HKD')
+ ->value('usable_num');
+
+ $rate = $marketArr['HKD'] ?? 0;
+ break;
+ case '14':
+ $originMoney = UserStockGBXModel::where('user_id', $param['id'])
+ ->where('stock_id', 'GBX')
+ ->value('usable_num');
+
+ $rate = $marketArr['GBX'] ?? 0;
+ break;
+ case '15':
+ $originMoney = UserStockFurModel::where('user_id', $param['id'])
+ ->where('stock_id', 'EUR')
+ ->value('usable_num');
+
+ $rate = $marketArr['EUR'] ?? 0;
+ break;
+ case '16':
+ $originMoney = UserStockEurModel::where('user_id', $param['id'])
+ ->where('stock_id', 'EUR')
+ ->value('usable_num');
+
+ $rate = $marketArr['EUR'] ?? 0;
+ break;
+ case '17':
+ $originMoney = UserStockBrlModel::where('user_id', $param['id'])
+ ->where('stock_id', 'BRL')
+ ->value('usable_num');
+
+ $rate = $marketArr['BRL'] ?? 0;
+ break;
+ case '18':
+ $originMoney = UserStockJpModel::where('user_id', $param['id'])
+ ->where('stock_id', 'JPY')
+ ->value('usable_num');
+
+ $rate = $marketArr['JPY'] ?? 0;
+ break;
+ case '19':
+ $originMoney = UserForexModel::where('user_id', $param['id'])
+ ->where('stock_id', 'USD')
+ ->value('usable_num');
+
+ $rate = $marketArr['USD'] ?? 0;
+ break;
+ default:
+ return $this->toData('1', '无权操作');
+ break;
+ }
+
+ $diff = bcsub($amount, $originMoney, 18);
+ // 未进行修改
+ if ($diff == 0) {
+ return $this->toData('0', 'SUCCESS');
+ }
+
+ if ($rate == 0) {
+ return $this->toData('1', '兑换汇率错误');
+ }
+
+ $operateType = '13';
+ if ($diff > 0) {
+ $operateType = '12';
+ }
+
+ //正式用户 && 给用户加钱 -> 需要写入变更日志
+ $changeLogAdminId = ($user->is_test_user == 1 && abs($diff) > 0) ? $adminId : 0;
+ // 执行修改账户额度
+ $res = $this->updateUserAsset($userId, $type, $operateType, $diff, 0, "", $changeLogAdminId, $rate);
+ if (isset($res['status']) && $res['status'] == 200) {
+ return $this->toData('0', 'SUCCESS');
+ }
+ return $this->toData('1', '操作失败', [$res]);
+ } catch (ValidateException $validateException) {
+ // 参数校验失败
+ $message = $validateException->getError();
+ return $this->toData('1', $message);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统异常 请稍后重试', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+
+
+ // 用户关系
+ public function relation($param, $adminId)
+ {
+ try {
+ // 参数校验
+ validate(UserValidate::class)->scene('relation')->check($param);
+
+ $where = [];
+ $userId = 0;
+ // 用户号精确搜索
+ if (!empty($param['user_no'])) {
+ $user = UserModel::where('user_no', $param['user_no'])->find();
+ if (empty($user)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => [],]);
+ }
+ $userId = $user['user_id'];
+ }
+
+ // 判断是否是代理 如果是代理 只能看他自己管理的用户
+ $whereU = $this->getWhereByIsAgentAndUserId($adminId, $where, $userId);
+ if (!is_array($whereU)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => []]);
+ }
+
+// // 查询列表数据
+// $userList = UserModel::where('FIND_IN_SET(:id,parent_ids)', ['id' => $userId])
+// ->order('user_id', 'desc')
+// ->page($param['page'], $param['limit'])
+// ->select();
+// // 查询总数
+// $total = UserModel::where('FIND_IN_SET(:id,parent_ids)', ['id' => $userId])
+// ->count();
+
+ // 查询列表数据
+ $userList = UserModel::where($whereU)
+ ->order('user_id', 'desc')
+ ->page($param['page'], $param['limit'])
+ ->select();
+ // 查询总数
+ $total = UserModel::where($whereU)->count();
+
+
+ $rows = [];
+ if (!empty($userList)) {
+ $userIdArr = [];
+ $parentIdArr = [];
+ foreach ($userList as $value) {
+ $userIdArr[] = $value['user_id'];
+ if ($value['parent_id'] > 0) {
+ $parentIdArr[] = $value['parent_id'];
+ }
+ }
+
+ // 查询父级
+ $parentNos = UserModel::where('user_id', 'in', $parentIdArr)->column('user_no', 'user_id');
+
+ // 查询用户余额
+ $userContractList = UserContractModel::where('user_id', 'in', $userIdArr)->column('usable_num', 'user_id');
+ $userStockList = UserStockModel::where('user_id', 'in', $userIdArr)->column('usable_num', 'user_id');
+ $userDigitalList = UserDigitalModel::where('user_id', 'in', $userIdArr)->column('usable_num', 'user_id');
+
+ foreach ($userList as $item) {
+ // 展示层级关系
+ $parentIdsArr = array_reverse(explode(',', $item['parent_ids']));
+ $level = '-';
+ for ($i = 1; $i <= count($parentIdsArr); $i++) {
+ if ($parentIdsArr[$i - 1] == $userId) {
+ $level = '下 ' . $i . ' 级';
+ }
+ }
+
+ $rows[] = [
+ 'id' => $item['user_id'],
+ 'user_no' => $item['user_no'],
+ 'regTime' => $item['create_time'],
+ 'nickname' => $item['nick_name'],
+ 'parentId' => $parentNos[$item['parent_id']] ?? '-',
+ 'parent_id' => $item['parent_id'],
+ 'email' => $item['email'],
+ 'mobile' => $item['country_code'] . '-' . $item['phone_number'],
+ 'digital' => $userDigitalList[$item['user_id']] ?? '0',
+ 'stock' => $userStockList[$item['user_id']] ?? '0',
+ 'contract' => $userContractList[$item['user_id']] ?? '0',
+ 'rechargeAmount' => 0,
+ 'withdrawalAmount' => 0,
+ 'regIp' => $item['reg_ip'],
+ 'status' => UserModel::$statusMap[$item['status']] ?? '-',
+ 'loginTime' => $item['last_login_time'],
+ 'level' => $level,
+ ];
+ }
+ }
+
+ return $this->toData('0', 'SUCCESS', ['total' => $total, 'list' => $rows]);
+ } catch (ValidateException $validateException) {
+ // 参数校验失败
+ $message = $validateException->getError();
+ return $this->toData('1', $message);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统异常 请稍后重试', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+
+ public function reg_phone($param, $adminId)
+ {
+ try {
+ // 参数校验
+ validate(UserValidate::class)->scene('add_phone')->check($param);
+ $phoneExists = UserModel::checkPhoneExists($param['phone']);
+ if ($phoneExists) {
+ return $this->toData('100400', 'The phone number has already been registered.', []);
+ }
+ // 入库
+ $userNo = (new BaseHomeService())->getUniqUserNo();
+ $salt = env('ENCRYPT.SALT');
+ $password = (new UnqId())->encryptPassword($param['password'], $salt);
+ $userInviteCode = (new BaseHomeService())->getUniqInviteCode();
+ $parentUserId = 0;
+ $ip = (new BaseHomeService())->getClientRealIp();
+ $userId = UserModel::phoneRegister($param['nation'], $param['phone'], $userNo, $userInviteCode, $parentUserId, $password, $ip, $salt, $param['is_test_user'] ?? 1, 0);
+ (new \app\home\service\UserService())->doRegInitUserInfo($userId, $parentUserId);
+ // 判断是否是代理
+ $isAgent = AdminModel::checkUserIsAgent($adminId);
+ if ($isAgent) {
+ UserModel::where('user_id', $userId)->update([
+ 'agent_id' => $adminId
+ ]);
+ }
+
+ return $this->toData('0', 'SUCCESS');
+ } catch (ValidateException $validateException) {
+ // 参数校验失败
+ $message = $validateException->getError();
+ return $this->toData('1', $message);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统异常 请稍后重试', [$exception->getMessage(), $exception->getTrace()]);
+ }
+
+ }
+
+ public function reg_email($param, $adminId)
+ {
+ try {
+ // 参数校验
+ validate(UserValidate::class)->scene('add_email')->check($param);
+ if ((new BaseHomeService())->checkForbidEmail($param['email'])) {
+ return $this->toData('100500', 'You are not allowed to register with Chinese email addresses.', []);
+ }
+ // 邮箱是否已经存在
+ $emailExists = UserModel::checkEmailExists($param['email']);
+ if ($emailExists) {
+ return $this->toData('100300', 'The email has already been registered.', []);
+ }
+
+ // 入库
+ $userNo = (new BaseHomeService())->getUniqUserNo();
+ $salt = env('ENCRYPT.SALT');
+ $password = (new UnqId())->encryptPassword($param['password'], $salt);
+ $userInviteCode = (new BaseHomeService())->getUniqInviteCode();
+ $parentUserId = 0;
+ $ip = (new BaseHomeService())->getClientRealIp();
+ $userId = UserModel::emailRegister($param['email'], $userNo, $userInviteCode, $parentUserId, $password, $ip, $salt, $param['is_test_user'] ?? 1, 0);
+ // 判断是否是代理
+ $isAgent = AdminModel::checkUserIsAgent($adminId);
+ if ($isAgent) {
+ UserModel::where('user_id', $userId)->update([
+ 'agent_id' => $adminId
+ ]);
+ }
+ (new \app\home\service\UserService())->doRegInitUserInfo($userId, $parentUserId);
+ return $this->toData('0', 'SUCCESS');
+ } catch (ValidateException $validateException) {
+ // 参数校验失败
+ $message = $validateException->getError();
+ return $this->toData('1', $message);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统异常 请稍后重试', [$exception->getMessage(), $exception->getTrace()]);
+ }
+
+ }
+
+ // 实名认证操作
+ public function verifyDetail($param)
+ {
+ try {
+ $userId = $param['user_id'] ?? '';
+ if (!is_numeric($userId)) {
+ return $this->toData('100400', 'Param error', []);
+ }
+
+ $log = UserVerifyLogModel::where('user_id', $userId)->order('id', 'desc')->find();
+ if (empty($log)) {
+ return $this->toData('0', 'success', []);
+ }
+
+ $front = FileModel::where('id', $log->front_img)->value('path');
+ $back = FileModel::where('id', $log->back_img)->value('path');
+ $country = CountryModel::where('id', $log->country)->find();
+
+ $data = [
+ 'id' => $log->id,
+ 'name' => $log->name,
+ 'code' => $log->code,
+ 'country' => $country,
+ 'front_img' => $front,
+ 'back_img' => $back,
+ 'lock_password' => $log->lock_password
+ ];
+
+ return $this->toData('0', 'success', $data);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统异常 请稍后重试', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+
+ public function verifyDo($param, $adminId)
+ {
+ try {
+ $id = $param['id'] ?? '';
+ $status = $param['status'] ?? '3';
+ if (!is_numeric($id)) {
+ return $this->toData('100400', 'Param error', []);
+ }
+
+ if (!is_numeric($status) || !in_array($status, [UserVerifyLogModel::STATUS_SUCCESS, UserVerifyLogModel::STATUS_FAIL])) {
+ return $this->toData('100400', 'Status param error', []);
+ }
+
+ $log = UserVerifyLogModel::where('id', $id)->find();
+ if (empty($log)) {
+ return $this->toData('100400', 'ID param error', []);
+ }
+
+ $agentAuth = env('AGENT_AUTH.AGENT_AUTH_VERIFY'); // 0代理不可审核 1代理可审核
+ if (empty($agentAuth)){
+ $isAgent = AdminModel::checkUserIsAgent($adminId);
+ if ($isAgent) {
+ return $this->toData('10040', '代理无权限操作');
+ }
+ }
+
+ $isReal = 0;
+ $realStatus = 4;
+ // 如果是成功 修改用户表
+ if ($status == UserVerifyLogModel::STATUS_SUCCESS) {
+ $isReal = 1;
+ $realStatus = 3;
+ }
+
+ // 更新用户
+ UserModel::where('user_id', $log->user_id)->update(['is_real' => $isReal, 'real_status' => $realStatus, 'update_time' => date('Y-m-d H:i:s')]);
+ // 更新记录
+ $log->status = $status;
+ $log->update_time = date('Y-m-d H:i:s');
+ $log->save();
+ return $this->toData('0', 'success');
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统异常 请稍后重试', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+
+ // 杠杆状态审核
+ public function leverReview($param)
+ {
+ try {
+ $userId = $param['user_id'] ?? '';
+ if (!is_numeric($userId)) {
+ return $this->toData('100400', 'Param error', []);
+ }
+
+ $lever_status = $param['lever_status'] ?? 4;
+ if (!is_numeric($lever_status)) {
+ return $this->toData('100400', 'Param error', []);
+ }
+
+ if (!in_array($lever_status, [UserModel::LEVER_STATUS_PASSED, UserModel::LEVER_STATUS_FAIL])) {
+ return $this->toData('100400', 'Param error', []);
+ }
+
+ $key = 'USER:LEVER_STATUS:' . $userId;
+ $lever_status = $lever_status + 0;
+ $this->getRedis()->set($key, $lever_status);
+ UserModel::update(['lever_status' => $lever_status, 'update_time' => date('Y-m-d H:i:s')], ['user_id' => $userId]);
+ return $this->toData('0', 'success');
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统异常 请稍后重试', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+
+
+ // 获取用户验证码
+ public function getUserCode($param)
+ {
+ try {
+ $extend = [
+ 'business' => ['1' => '已登录操作', '3' => '未登录操作'],
+ 'code_type' => ['6' => '邮箱', '9' => '短信'],
+ ];
+ if (empty($param['search']) || empty($param['business']) || empty($param['code_type'])) {
+ return $this->toData('0', 'success', ['extend' => $extend, 'get_code' => 0, 'code' => '']);
+ }
+
+ if (!is_numeric($param['business']) || !is_numeric($param['code_type']) || !is_string($param['search'])) {
+ return $this->toData('0', 'success', ['extend' => $extend, 'get_code' => 0, 'code' => '']);
+ }
+
+
+ $key_12 = "DB:USER:UNLOGIN:SMS_CODE:" . $param['search'];
+ $key_9 = "DB:USER:UNLOGIN:EMAIL_CODE:" . $param['search'];
+ $key_7 = "USER:sendEmailLoginNoTrade:" . $param['search'];
+ $key_10 = "USER:sendSmsLoginNoTrade:" . $param['search'];
+
+ $key = "key_" . ($param['business'] + $param['code_type']);
+ if (!isset($$key)) {
+ return $this->toData('0', 'success', ['extend' => $extend, 'get_code' => 0, 'code' => '']);
+ }
+
+ $redis = $this->getRedis();
+ $code = $redis->get($$key);
+ if ($code) {
+ return $this->toData('0', 'success', ['extend' => $extend, 'get_code' => 1, 'code' => $code]);
+ }
+ return $this->toData('0', 'success', ['extend' => $extend, 'get_code' => 0, 'code' => '']);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统异常 请稍后重试', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+
+
+ public function getRegCode($param)
+ {
+ $key = "USER:REG:CODE";
+ $redis = $this->getRedis();
+ $code = $redis->get($key);
+ if (empty($code)) {
+ $code = random_int(1000, 9999);
+ $time = 300;
+ $redis->setex($key, $time, $code);
+ } else {
+ $time = $redis->pttl($key);
+ }
+ return $this->toData('0', 'success', ['code' => $code, 'expiration_time' => $time]);
+ }
+
+ // 用户银行卡
+ public function bankDetail($param)
+ {
+ try {
+ $userId = $param['user_id'] ?? '';
+ if (!is_numeric($userId)) {
+ return $this->toData('100400', 'Param error', []);
+ }
+
+ $bank = UserBankModel::getUserBankInfoById(['user_id' => $userId]);
+ if (empty($bank)) {
+ return $this->toData('0', 'success', []);
+ }
+
+ return $this->toData('0', 'success', $bank);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统异常 请稍后重试', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+
+ public function editBank($param)
+ {
+ try {
+ if (empty($param['id'])) {
+ return $this->toData('100400', 'Param error', []);
+ }
+
+ $bank = UserBankModel::getUserBankInfoById(['id' => $param['id']]);
+ if (empty($bank)) {
+ return $this->toData('100400', 'Param error', []);
+ }
+
+ $updateArr = [
+ 'true_name' => $param['true_name'] ?? $bank['true_name'],
+ 'bank_name' => $param['bank_name'] ?? $bank['bank_name'],
+ 'bank_code' => $param['bank_code'] ?? $bank['bank_code'],
+ 'bank_card' => $param['bank_card'] ?? $bank['bank_card'],
+ 'bank_phone' => $param['bank_phone'] ?? $bank['bank_phone'],
+ 'bank_email' => $param['bank_email'] ?? $bank['bank_email'],
+ 'ifsc' => $param['ifsc'] ?? $bank['ifsc'],
+ 'update_time' => date('Y-m-d H:i:s')
+ ];
+ UserBankModel::where('id', $param['id'])->update($updateArr);
+ return $this->toData('0', 'SUCCESS', []);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统异常 请稍后重试', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+
+ public function editPassword($param)
+ {
+ try {
+ if (empty($param['id'])) {
+ return $this->toData('100400', 'Param error', []);
+ }
+
+ $user = UserModel::where('user_id', $param['id'])->find();
+ if (empty($user)) {
+ return $this->toData('100400', 'Param error', []);
+ }
+
+ $updateArr = [];
+// $bool = 0;
+ if (!empty($param['login_password'])) $updateArr['login_password'] = (new UnqId())->encryptPassword($param['login_password'], $user->salt);
+ if (!empty($param['trade_password'])) $updateArr['trade_password'] = (new UnqId())->encryptPassword($param['trade_password'], $user->salt);
+ if (!empty($updateArr)) UserModel::where('user_id', $param['id'])->update($updateArr);
+// if (empty($bool)) return $this->toData('1', '系统异常 请稍后重试', []);
+ return $this->toData('0', 'SUCCESS', []);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统异常 请稍后重试', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+
+ public function setAutoLogin($param)
+ {
+ try {
+ if (empty($param['id'])) {
+ return $this->toData('100400', 'Param error', []);
+ }
+ $userId = $param['id'];
+ $user = UserModel::where('user_id', $userId)->find();
+ if (empty($user)) {
+ return $this->toData('1', '用户不存在');
+ }
+ $token = md5($param['id'] . time() . date('Y-m-d H:i:s'));
+ $tokenKey = 'AUTO:TOKEN:' . $token; // 根据token查找用户id
+
+ $expired = 5 * 60;
+ // 由中间件自动续期
+ Cache::store('redis')->set($tokenKey, $userId, $expired);
+ return $this->toData('0', 'SUCCESS', [
+ 'login_token' => $token
+ ]);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统异常 请稍后重试', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+
+ public function getLeverageNum($param)
+ {
+ try {
+ if (!is_numeric($param['id'])) {
+ return $this->toData('100400', 'Param error', []);
+ }
+
+ $key = 'LEVERAGE:' . $param['id'];
+ $value = Cache::store('redis')->get($key);
+ if (empty($value)) {
+ $key = 'LEVERAGE:0';
+ $value = Cache::store('redis')->get($key);
+ }
+ return $this->toData('0', 'SUCCESS', ['leverage_num' => $value]);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统异常 请稍后重试', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+
+ public function editLeverageNum($param)
+ {
+ try {
+ if (empty($param['leverage_num'])) {
+ return $this->toData('100400', 'Param error', []);
+ }
+ if (!empty($param['id'])) {
+ $userId = $param['id'];
+ } else {
+ $userId = 0;
+ }
+
+ $key = 'LEVERAGE:' . $userId;
+ Cache::store('redis')->del($key);
+ Cache::store('redis')->set($key, $param['leverage_num']);
+ return $this->toData('0', 'SUCCESS', []);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统异常 请稍后重试', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+}
+
+
diff --git a/app/admin/service/VoteService.php b/app/admin/service/VoteService.php
new file mode 100644
index 0000000..438e5e2
--- /dev/null
+++ b/app/admin/service/VoteService.php
@@ -0,0 +1,139 @@
+order('id', 'desc');
+ $total = $vote->count();
+ $list = $vote->page($param['page'], $param['limit'])->select();
+
+ return $this->toData('0', 'SUCCESS', ['list' => $list, 'total' => $total]);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统繁忙', [$exception->getMessage()]);
+ }
+ }
+
+ public function add($param)
+ {
+ try {
+
+ if (empty($param['code'])) {
+ return $this->toData('1', 'code无效');
+ }
+
+ if (empty($param['title'])) {
+ return $this->toData('1', '标题无效');
+ }
+
+ if (empty($param['icon'])) {
+ return $this->toData('1', '图标无效');
+ }
+
+ if (empty($param['content'])) {
+ return $this->toData('1', '内容无效');
+ }
+
+ $vote = new VoteModel();
+ $vote->code = $param['code'];
+ $vote->title = $param['title'];
+ $vote->icon = $param['icon'];
+ $vote->content = $param['content'];
+ $vote->score_num = $param['score_num'] ?? 0;
+ $vote->sort = $param['sort'] ?? 0;
+ $vote->oneday_times = $param['oneday_times'] ?? 1;
+ $vote->create_time = date('Y-m-d H:i:s');
+ $vote->update_time = date('Y-m-d H:i:s');
+ $vote->save();
+
+ return $this->toData('0', 'SUCCESS');
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统繁忙', [$exception->getMessage()]);
+ }
+ }
+
+
+ public function edit($param)
+ {
+ try {
+ if (empty($param['id']) || !is_numeric($param['id'])) {
+ return $this->toData('1', '目标不存在');
+ }
+
+ $vote = VoteModel::where('id', $param['id'])
+ ->where('is_delete', VoteModel::IS_DELETE_NO)
+ ->find();
+ if (empty($doc)) {
+ return $this->toData('1', '目标不存在');
+ }
+
+ if (empty($param['code'])) {
+ return $this->toData('1', 'code无效');
+ }
+
+ if (empty($param['title'])) {
+ return $this->toData('1', '标题无效');
+ }
+
+ if (empty($param['icon'])) {
+ return $this->toData('1', '图标无效');
+ }
+
+ if (empty($param['content'])) {
+ return $this->toData('1', '内容无效');
+ }
+
+ $isHas = VoteModel::where('is_delete', VoteModel::IS_DELETE_NO)
+ ->where('id', '<>', $param['id'])
+ ->where('title', $param['title'])->find();
+ if (!empty($isHas)) {
+ return $this->toData('1', '标题在相同内容');
+ }
+
+ $vote->code = $param['code'];
+ $vote->title = $param['title'];
+ $vote->icon = $param['icon'];
+ $vote->content = $param['content'];
+ $vote->score_num = $param['score_num'] ?? 0;
+ $vote->sort = $param['sort'] ?? 0;
+ $vote->oneday_times = $param['oneday_times'] ?? 1;
+ $vote->update_time = date('Y-m-d H:i:s');
+ $vote->save();
+
+ return $this->toData('0', 'SUCCESS');
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统繁忙', [$exception->getMessage()]);
+ }
+ }
+
+ public function del($param)
+ {
+ try {
+ if (empty($param['id']) || !is_numeric($param['id'])) {
+ return $this->toData('1', '目标不存在');
+ }
+
+ $vote = VoteModel::where('id', $param['id'])
+ ->where('is_delete', VoteModel::IS_DELETE_NO)
+ ->find();
+ if (empty($vote)) {
+ return $this->toData('1', '目标不存在');
+ }
+
+ $vote->is_delete = VoteModel::IS_DELETE_YES;
+ $vote->save();
+
+ return $this->toData('0', 'SUCCESS');
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统繁忙', [$exception->getMessage()]);
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/admin/service/WithdrawService.php b/app/admin/service/WithdrawService.php
new file mode 100644
index 0000000..81e314f
--- /dev/null
+++ b/app/admin/service/WithdrawService.php
@@ -0,0 +1,346 @@
+scene('index')->check($param);
+ $where = [];
+ $userId = 0;
+ // 用户号精确搜索
+ if (!empty($param['user_no'])) {
+ $user = UserModel::where('user_no', $param['user_no'])->find();
+ if (empty($user)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => [], 'extend' => UserWithdrawalModel::$statusList]);
+ }
+ $userId = $user['user_id'];
+ }
+ // 判断是否是代理 如果是代理 只能看他自己管理的用户
+ $whereU = $this->getWhereByIsAgentAndUserId($adminId, $where, $userId);
+ if (!is_array($whereU)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => [], 'extend' => UserWithdrawalModel::$statusList]);
+ }
+ // 订单号
+ if (!empty($param['order_id'])) {
+ $where['order_no'] = $param['order_id'];
+ }
+ if (isset($param['status'])) {
+ $where['status'] = $param['status'];
+ }
+
+ if (!empty($param['start_time']) && !empty($param['end_time'])) {
+ $where['update_time'] = ['between time', [$param['start_time'], $param['end_time']]];
+ }
+
+ // 列表
+ $list = UserWithdrawalModel::where($where)->where($whereU)->order('id', 'desc')->page($param['page'], $param['limit'])->select();
+ // 总数
+ $total = UserWithdrawalModel::where($where)->where($whereU)->count();
+ // 统计 提现成功
+ $sum = UserWithdrawalModel::where($where)->where($whereU)->where('status', 4)->sum('apply_num');
+
+ $rows = [];
+ if (!$list->isEmpty()) {
+ // 获取用户号
+ $userIdArr = [];
+ foreach ($list as $idItem) {
+ $userIdArr[] = $idItem['user_id'];
+ }
+
+ $userNoArr = UserModel::where('user_id', 'in', $userIdArr)->column('user_no', 'user_id');
+ $ifscArr = UserBankModel::where('user_id', 'in', $userIdArr)->column('ifsc', 'user_id');
+
+ $rows = $list->toArray();
+ foreach ($rows as $key => $item) {
+ $rows[$key]['user_no'] = $userNoArr[$item['user_id']] ?? '-'; // 用户号.
+ $rows[$key]['ifsc'] = $ifscArr[$item['user_id']] ?? '-'; // ifsc
+ $rows[$key]['order_id'] = $item['order_no'];
+ $rows[$key]['status_text'] = UserWithdrawalModel::$statusList[$item['status']];
+ //$rows[$key]['pay_info'] = json_decode($item['pay_info'],true);
+ }
+ }
+ return $this->toData('0', 'SUCCESS', ['total' => $total, 'list' => $rows, 'sum' => $sum . 'USD', 'extend' => UserWithdrawalModel::$statusList]);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统异常 请稍后重试', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+
+ public function info($param, $adminId)
+ {
+ try {
+ // 参数校验
+ validate(WithdrawValidate::class)->scene('info')->check($param);
+ $where = [
+ 'id' => $param['id']
+ ];
+
+ $userId = 0;
+ $where = $this->getWhereByIsAgentAndUserId($adminId, $where, $userId);
+ if (!is_array($where)) {
+ return $this->toData('0', 'SUCCESS', []);
+ }
+
+ $order_info = [];
+ $info = UserWithdrawalModel::where($where)->find();
+ $ifsc = UserBankModel::where('user_id', $info->user_id)->value('ifsc');
+
+ if (!$info->isEmpty()) {
+ $order_info = $info->toArray();
+ $order_info['pay_info'] = json_decode($order_info['pay_info'], true);
+ $channel = PaymentListModel::getPaymentInfo([
+ 'id' => intval($order_info['channel_id'])
+ ]);
+ $order_info['channel_name'] = isset($channel['channel']) ? $channel['channel'] : '';
+ $order_info['ifsc'] = $ifsc ?? '-';
+ }
+ return $this->toData('0', 'SUCCESS', $order_info);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统异常 请稍后重试', [$exception->getMessage(), $exception->getTrace()]);
+ }
+
+ }
+
+ public function change_status($param, $adminId)
+ {
+ try {
+ // 参数校验
+ validate(WithdrawValidate::class)->scene('status')->check($param);
+ $isAgent = AdminModel::checkUserIsAgent($adminId);
+ if ($isAgent) {
+ return $this->toData('10040', '代理无权限操作');
+ }
+ $where = [
+ 'id' => $param['id']
+ ];
+ $userId = 0;
+ $where = $this->getWhereByIsAgentAndUserId($adminId, $where, $userId);
+ if (!is_array($where)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => []]);
+ }
+
+ $order_info = [];
+ $info = UserWithdrawalModel::where($where)->find();
+ if (empty($info)) {
+ return $this->toData('1004', '订单不存在');
+ }
+ $order_info = $info->toArray();
+ $change_flag = false;
+ if ($order_info['status'] == 0 && $param['status'] < 3) {
+ $change_flag = true;
+ }
+ if ($order_info['status'] = 1 && ($param['status'] == 3 || $param['status'] == 2)) {
+ $change_flag = true;
+ }
+ if ($order_info['status'] = 3 && $param['status'] == 4) {
+ $change_flag = true;
+ }
+ $pay_flag = false;
+ $msg = "";
+ $content = "";
+ if ($change_flag) {
+ $update_data['status'] = $param['status'];
+ $update_data['update_time'] = date('Y-m-d H:i:s');
+ //拒绝
+ if ($param['status'] == 2) {
+ $updateStatus = $this->updateUserAsset($order_info['user_id'], $order_info['account_type'], 6, $order_info['market_amount'], -$order_info['market_amount'], $order_info['order_no']);
+ }
+
+ //代付
+ if ($param['status'] == 3) {
+ //解冻资金 ,扣除提现
+ $updateOne = $this->updateUserAsset($order_info['user_id'], $order_info['account_type'], 6, $order_info['market_amount'], -$order_info['market_amount'], $order_info['order_no']);
+ if (!empty($updateOne) && $updateOne['status'] == 200) {
+ $updateStatus = $this->updateUserAsset($order_info['user_id'], $order_info['account_type'], 2, -$order_info['market_amount'], 0, $order_info['order_no']);
+ } else {
+ //提现事务回滚...
+// $updateOne = $this->updateUserAsset($order_info['user_id'], $order_info['account_type'], 5, -$order_info['market_amount'], +$order_info['market_amount'], $order_info['order_no']);
+ trace("提现失败1 - change_status - order_no=" . $order_info['order_no'] . "---user_id= " . $order_info['user_id'] . "---account_type= " . $order_info['account_type'] . "---market_amount= " . $order_info['market_amount']);
+ return $this->toData($updateOne['status'] ?? '3251', $updateOne['msg'] ?? $msg, [$content]);
+ }
+
+ if (!empty($updateStatus) && $updateStatus['status'] == 200) {
+ $channel = PaymentListModel::getPaymentInfo([
+ 'id' => $param['channel']
+ ]);
+ if ($channel) {
+ $result = $this->payToUser($order_info, $channel);
+ if ($result['code'] == 200) {
+ $update_data['order_idx'] = $result['order_idx'];
+ $update_data['channel_id'] = $param['channel'];
+ } else {
+ $update_data['status'] = 1; //代付失败
+ $pay_flag = true;
+ $content = $result['content'];
+ $msg = $result['msg'];
+ }
+ }
+ //手动支付完成
+ if ($param['channel'] == 0) {
+ $update_data['status'] = 4;
+ $update_data['channel_id'] = $param['channel'];
+ }
+ }
+ }
+
+ $update_data['beizhu'] = $param['beizhu'] ?? "";
+
+ if ($param['status'] == 1 || (!empty($updateStatus) && $updateStatus['status'] == 200)) {
+ UserWithdrawalModel::where($where)->update($update_data);
+ } else {
+ trace("提现失败2 - change_status - order_no=" . $order_info['order_no'] . "---user_id= " . $order_info['user_id'] . "---account_type= " . $order_info['account_type'] . "---market_amount= " . $order_info['market_amount']);
+ return $this->toData($updateStatus['status'] ?? '3251', $updateStatus['msg'] ?? $msg, [$content]);
+ }
+
+ if ($pay_flag) {
+ return $this->toData('3250', $msg, [$content]);
+ } else {
+ return $this->toData('0', 'SUCCESS');
+ }
+
+ } else {
+ return $this->toData('10040', '操作流程不合法');
+ }
+
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统异常 请稍后重试', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+
+ private function payToUser($order, $channel)
+ {
+ //货币单位换算
+ $order['total_amount'] = $order['apply_num'] * $channel['exchange_rate'];
+ $address_info = json_decode($order['pay_info'], true);
+
+ switch ($channel['type']) {
+ //印尼支付
+ case 2:
+ return (new IndPayService())->singleIndOrder($order);
+ break;
+ //TRC
+ case 3:
+ return (new MoPayService())->apply_pay($order['order_no'], $order['total_amount'], $address_info['bank_code'], $address_info['bank_card'], $address_info['true_name'], $address_info['bank_phone'], $address_info['ifsc']);
+ break;
+ //合泰
+ case 4:
+ return (new HTPayService())->arPay($order['order_no'], $order['total_amount'], $address_info['bank_code'], $address_info['bank_card'], $address_info['true_name']);
+ break;
+ //合泰
+ case 5:
+ return (new XdPayService())->apply_pay($order['order_no'], $order['total_amount'], $address_info['ifsc'], $address_info['bank_card'], $address_info['true_name']);
+ break;
+ //QEAE
+ case 6:
+ return (new QeaePayService())->apply_pay($order['order_no'], $order['total_amount'], $address_info['bank_card'], $address_info['true_name'], $address_info['ifsc'], $address_info['bank_code']);
+ break;
+ //合泰
+ case 7:
+ return (new NicePayService())->apply_pay($order['order_no'], $order['total_amount'], $address_info['bank_card'], $address_info['true_name'], $address_info['ifsc']);
+ break;
+ //ClickPay
+ case 8:
+ return (new ClickPayService())->apply_pay($order['order_no'], $order['total_amount'], $address_info['bank_card'], $address_info['true_name'], $address_info['ifsc'], $address_info['bank_code']);
+ break;
+ default:
+
+ break;
+ }
+ }
+
+ public function get_balance($param, $adminId)
+ {
+ $channel = PaymentListModel::getPaymentInfo([
+ 'id' => intval($param['id'])
+ ]);
+ if ($channel) {
+ switch ($channel['type']) {
+ case 1:
+ //$result=(new IndPayService())->getIndBalance();
+ $result = [
+ 'amount' => 0
+ ];
+ break;
+ case 2:
+ $result = (new TrcPayService())->getTrcBalance();
+ break;
+ case 4:
+ $result = (new HTPayService())->getHtBalance();
+ break;
+ case 5:
+ $result = (new XdPayService())->getBalance();
+ break;
+ case 6:
+ $result = (new QeaePayService())->getBalance();
+ break;
+ case 8:
+ $result = (new ClickPayService())->getBalance();
+ break;
+ default:
+ $result = [
+ 'amount' => 0
+ ];
+ break;
+ }
+
+ return $this->toData('0', '请求成功', $result);
+
+ } else {
+ return $this->toData('1', '参数错误,通道不存在', []);
+ }
+ }
+
+ public function channel_list($param, $adminId)
+ {
+ try {
+ // 参数校验
+ validate(WithdrawValidate::class)->scene('info')->check($param);
+ $where = [
+ 'id' => $param['id']
+ ];
+
+ $userId = 0;
+ $where = $this->getWhereByIsAgentAndUserId($adminId, $where, $userId);
+ if (!is_array($where)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => []]);
+ }
+
+ $order_info = UserWithdrawalModel::getUserDrawalInfo($where);
+ if ($order_info) {
+ $channel_list = PaymentListModel::getPaymentList([
+ 'is_withdrawal' => 1,
+ 'status' => 1,
+ 'channel_type' => $order_info['apply_type']
+ ]);
+ } else {
+ $channel_list = [];
+ }
+ return $this->toData('0', '请求成功', $channel_list);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统异常 请稍后重试', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+
+
+}
\ No newline at end of file
diff --git a/app/admin/service/auth/AuthRoleService.php b/app/admin/service/auth/AuthRoleService.php
new file mode 100644
index 0000000..cfef80a
--- /dev/null
+++ b/app/admin/service/auth/AuthRoleService.php
@@ -0,0 +1,148 @@
+scene('add')->check($param);
+ // 查找角色是否存在
+ $authRole=new AuthRoleModel();
+ $rule = $authRole->where('name',$param['name'])->find();
+ if(!empty($rule)){
+ return $this->toData('200100', '名称已存在', []);
+ }
+ $authRole->save($param);
+ return $this->toData('0', '添加成功.', []);
+ }catch (ValidateException $validateException){
+ $message = $validateException->getError();
+ return $this->toData('100400', $message);
+ }catch (\Exception $exception){
+ return $this->toData('100500', '系统繁忙.', [$exception->getMessage()]);
+ }
+
+ }
+
+
+ public function list($param){
+ try {
+ $authRole=new AuthRoleModel();
+ //查询条件
+ if(isset($param['name'])&&!empty($param['name'])){
+ $authRole=$authRole->where('name',$param['name']);
+ }
+ if(isset($param['satus'])&&!empty($param['status'])){
+ $authRole=$authRole->where('status',$param['status']);
+ }
+ // 总数
+ $total = $authRole->count();
+ $list=$authRole->order('sort', 'asc')->page($param['page'], $param['limit'])->select();
+ for($i=0;$itoData('0', 'SUCCESS', ['total' => $total, 'list' => $list]);
+ } catch (\Exception $exception) {
+ return $this->toData('100500', 'The system is busy.', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+
+
+ public function updateStatus($id, $param): array
+ {
+ try {
+ // 主键
+ if(empty($id) || $id <= 0){
+ return $this->toData('200403', 'id字段丢失', []);
+ }
+ // 参数校验
+ validate(AuthRoleValidate::class)->scene('updateStatus')->check($param);
+ // 查找用户信息
+ $authRole = AuthRoleModel::find($id);
+ if(empty($authRole)){
+ return $this->toData('200403', '该角色不存在.', []);
+ }
+ $authRole->status=$param['status'];
+ $authRole->save();
+ // 返回
+ return $this->toData('0', 'Modification successful.', []);
+ }catch (ValidateException $validateException){
+ $message = $validateException->getError();
+ return $this->toData('200400', $message);
+ }catch (\Exception $exception){
+ return $this->toData('200500', 'The system is busy.', [$exception->getMessage()]);
+ }
+
+ }
+ public function allList($param){
+ try {
+ $authRole=new AuthRoleModel();
+ //查询条件
+ if(isset($param['name'])&&!empty($param['name'])){
+ $authRole=$authRole->where('name',$param['name']);
+ }
+ if(isset($param['satus'])&&!empty($param['status'])){
+ $authRole=$authRole->where('status',$param['status']);
+ }
+ $list=$authRole->order('sort', 'asc')->column('name,id');
+ return $this->toData('0', 'SUCCESS', $list);
+ } catch (\Exception $exception) {
+ return $this->toData('100500', 'The system is busy.', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+
+ public function edit($id, $param): array
+ {
+ try {
+ // 主键
+ if(empty($id) || $id <= 0){
+ return $this->toData('200403', 'id字段丢失', []);
+ }
+ // 参数校验
+ validate(AuthRoleValidate::class)->scene('edit')->check($param);
+ // 查找用户信息
+ $authRole = AuthRoleModel::find($id);
+ if(empty($authRole)){
+ return $this->toData('200403', '该规则不存在.', []);
+ }
+ $authRole->withoutField('id')->save($param);
+ // 返回
+ return $this->toData('0', 'Modification successful.', []);
+ }catch (ValidateException $validateException){
+ $message = $validateException->getError();
+ return $this->toData('200400', $message);
+ }catch (\Exception $exception){
+ return $this->toData('200500', 'The system is busy.', [$exception->getMessage()]);
+ }
+
+ }
+
+ public function del($id): array
+ {
+ try {
+ $authRole = AuthRoleModel::find($id);
+ $authRole->delete();
+ // 返回
+ return $this->toData('0', 'Modification successful.', []);
+ }catch (ValidateException $validateException){
+ $message = $validateException->getError();
+ return $this->toData('200400', $message);
+ }catch (\Exception $exception){
+ return $this->toData('200500', 'The system is busy.', [$exception->getMessage()]);
+ }
+
+ }
+}
diff --git a/app/admin/service/auth/AuthRuleService.php b/app/admin/service/auth/AuthRuleService.php
new file mode 100644
index 0000000..b55b473
--- /dev/null
+++ b/app/admin/service/auth/AuthRuleService.php
@@ -0,0 +1,216 @@
+scene('add')->check($param);
+ $this->verifyRepeat($param);
+ $authRule=new AuthRuleModel();
+ $authRule->create($param);
+ return $this->toData('0', '添加成功.', []);
+ }catch (ValidateException $validateException){
+ $message = $validateException->getError();
+ return $this->toData('100400', $message);
+ }catch (\Exception $exception){
+ return $this->toData('100500', '系统繁忙.', [$exception->getMessage()]);
+ }
+
+ }
+
+ /**
+ * 查重验证
+ * @param $param
+ * @return void
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function verifyRepeat($param){
+ $authRule=new AuthRuleModel();
+ if(isset($param['id'])){ //编辑
+ $authRule=$authRule->whereNotIn('id',[$param['id']]);
+ }
+ $rule = (clone $authRule)->where('name',$param['name'])->find();
+ if(!empty($rule)){
+ throw new ValidateException('权限标识已存在');
+ }
+
+ if($param['type']=='menu'){
+ $rule = (clone $authRule)->where('path', $param['path'])->find();
+ if(!empty($rule)){
+ throw new ValidateException('路由地址已存在');
+ }
+ $rule = (clone $authRule)->where('component',$param['component'])->find();
+ if(!empty($rule)){
+ throw new ValidateException('组件已存在');
+ }
+ }
+ if($param['type']=='catelog'){
+ $rule = (clone $authRule)->where('path',$param['path'])->find();
+ if(!empty($rule)){
+ throw new ValidateException('路由地址已存在');
+ }
+ }
+
+ }
+
+ public function list($user_id,$param){
+ try {
+ $authRule=new AuthRuleModel();
+ //查询条件
+ if(isset($param['name'])&&!empty($param['name'])){
+ $authRule=$authRule->where('name',$param['name']);
+ }
+ if(isset($param['satus'])&&!empty($param['status'])){
+ $authRule=$authRule->where('status',$param['status']);
+ }
+
+ //获取用户权限id
+ $user=AdminModel::find($user_id);
+ //查询拥有权限
+ if($user->role_id=='7'){
+ //超级管理员拥有全部权限
+ $list=$authRule::order('sort', 'asc')->select()->toArray();
+ }else{
+ $role=AuthRoleModel::find($user->role_id);
+ $list=$authRule::whereIn('id',$role->rules)->order('sort', 'asc')->select()->toArray();
+ }
+
+ // 总数
+// $total = $authRule->count();
+// $list=$authRule->order('sort', 'asc')->select()->toArray();
+ $list=$this->getTreeMenu($list,0,true);
+
+
+ return $this->toData('0', 'SUCCESS', $list);
+ } catch (\Exception $exception) {
+ return $this->toData('100500', 'The system is busy.', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+ public function allList($user_id){
+ try {
+ //获取用户权限id
+ $user=AdminModel::find($user_id);
+
+ //查询拥有权限
+ if($user->role_id=='7'){
+ //超级管理员拥有全部权限
+ $list=AuthRuleModel::order('sort', 'asc')->select()->toArray();
+ }else{
+ $role=AuthRoleModel::find($user->role_id);
+ $list=AuthRuleModel::whereIn('id',$role->rules)->order('sort', 'asc')->select()->toArray();
+ }
+// $list=$authRule->order('sort', 'asc')->select()->toArray();
+ $list=$this->getTreeMenu($list,0,true);
+ return $this->toData('0', 'SUCCESS',$list);
+ } catch (\Exception $exception) {
+ return $this->toData('100500', 'The system is busy.', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+ public function edit($id, $param): array
+ {
+ try {
+ // 主键
+ if(empty($id) || $id <= 0){
+ return $this->toData('200403', 'id字段丢失', []);
+ }
+ // 参数校验
+ validate(AuthRuleValidate::class)->scene('edit')->check($param);
+ // 查找用户信息
+ $authRule = AuthRuleModel::find($id);
+ if(empty($authRule)){
+ return $this->toData('200403', 'Please log in first.', []);
+ }
+ $this->verifyRepeat($param);
+ $authRule->save($param);
+ // 返回
+ return $this->toData('0', 'Modification successful.', []);
+ }catch (ValidateException $validateException){
+ $message = $validateException->getError();
+ return $this->toData('200400', $message);
+ }catch (\Exception $exception){
+ return $this->toData('200500', 'The system is busy.', [$exception->getMessage()]);
+ }
+
+ }
+
+ public function getSideMenu($user_id){
+ try {
+ //获取用户权限id
+ $user=AdminModel::find($user_id);
+ $role=AuthRoleModel::find($user->role_id);
+ //查询拥有权限
+ if($user->role_id=='7'){
+ //超级管理员拥有全部权限
+ $authRule=AuthRuleModel::order('sort', 'asc')->select()->toArray();
+ }else{
+ $role=AuthRoleModel::find($user->role_id);
+ $authRule=AuthRuleModel::whereIn('id',$role->rules)->order('sort', 'asc')->select()->toArray();
+ }
+// $authRule=AuthRuleModel::whereIn('id',$role->rules)->order('sort', 'asc')->select()->toArray();
+// $authRule=AuthRuleModel::order('sort', 'asc')->select()->toArray();//显示全部
+ $menus=[];
+ for($i=0;$i$authRule[$i]['id'],
+ 'pid'=>$authRule[$i]['pid'],
+ 'path'=>$authRule[$i]['path'],
+ 'name'=>$authRule[$i]['name'],
+ 'component'=>$authRule[$i]['component'],
+ 'redirect'=>$authRule[$i]['redirect'],
+ 'meta'=>[
+ 'title'=>$authRule[$i]['title'],
+ 'hideMenu'=>$authRule[$i]['show']===1?false:true,
+ 'icon'=>$authRule[$i]['icon'],
+ 'ignoreKeepAlive'=>true,
+ 'isLink'=>false,
+// 'currentActiveMenu'=>"",
+ ]
+ ];
+ array_push($menus,$menuItem);
+ }
+
+ $list=$this->getTreeMenu($menus,0,true);
+
+ return $this->toData('0', 'SUCCESS',$list);
+
+ }catch (ValidateException $validateException){
+ $message = $validateException->getError();
+ return $this->toData('200400', $message);
+ }catch (\Exception $exception){
+ return $this->toData('200500', 'The system is busy.', [$exception->getMessage()]);
+ }
+ }
+
+ /**
+ * @param $id
+ * @return array
+ */
+ public function del($id): array
+ {
+ try {
+ $authRule = AuthRuleModel::find($id);
+ $authRule->delete();
+ // 返回
+ return $this->toData('0', 'Modification successful.', []);
+ }catch (ValidateException $validateException){
+ $message = $validateException->getError();
+ return $this->toData('200400', $message);
+ }catch (\Exception $exception){
+ return $this->toData('200500', 'The system is busy.', [$exception->getMessage()]);
+ }
+
+ }
+
+}
diff --git a/app/admin/service/document/AnnouncementService.php b/app/admin/service/document/AnnouncementService.php
new file mode 100644
index 0000000..93f9fda
--- /dev/null
+++ b/app/admin/service/document/AnnouncementService.php
@@ -0,0 +1,200 @@
+field('id,lang,name,title,status,weight')
+ ->order('name', 'asc')
+ ->order('weight', 'desc')->select();
+ if(!$list->isEmpty()){
+ $rows = $list->toArray();
+ $lang = LanguageSettingModel::where('id', '>', 0)->column('china_name', 'id');
+ foreach ($rows as $key=>$item){
+ $rows[$key]['lang'] = $lang[$item['lang']] ?? '-';
+ $rows[$key]['status'] = AnnouncementModel::STATUS_MAP[$item['status']] ?? '-';
+ }
+ }
+
+ return $this->toData('0', 'SUCCESS', ['list' => $rows, 'total' => count($rows)]);
+ }catch (\Exception $exception){
+ return $this->toData('1', '系统繁忙', [$exception->getMessage()]);
+ }
+ }
+
+ public function add($param)
+ {
+ try {
+ $langIds = LanguageSettingModel::column('id');
+ if(empty($param['lang']) || !in_array($param['lang'], $langIds)){
+ return $this->toData('1', '语言类型无效');
+ }
+
+ if(empty($param['name']) || !is_string($param['name'])){
+ return $this->toData('1', '名称无效');
+ }
+
+ if(empty($param['title']) || !is_string($param['title'])){
+ return $this->toData('1', '标题无效');
+ }
+
+ if(empty($param['content']) || !is_string($param['content'])){
+ return $this->toData('1', '内容无效');
+ }
+
+ if(!isset($param['weight']) || !is_numeric($param['weight']) || ceil($param['weight']) != $param['weight'] || $param['weight'] < 0){
+ return $this->toData('1', '权重无效');
+ }
+
+ if(!isset($param['status']) || !in_array($param['status'], [1,2])){
+ return $this->toData('1', '状态无效');
+ }
+//
+// if(!isset($param['is_pop_ups']) || !in_array($param['is_pop_ups'], [1,2])){
+// return $this->toData('1', 'h5弹窗状态无效');
+// }
+
+ $docExists = AnnouncementModel::where('is_delete', AnnouncementModel::IS_DELETE_NO)
+ ->where('name', $param['name'])
+ ->where('lang', $param['lang'])->find();
+ if(!empty($docExists)){
+ return $this->toData('1', '已存在相同内容');
+ }
+
+ $doc = new AnnouncementModel;
+ $doc->lang = $param['lang'];
+ $doc->title = $param['title'];
+ $doc->content = $param['content'];
+ $doc->status = $param['status'];
+ $doc->weight = $param['weight'];
+ if (!empty($param['is_pop_ups'])) $doc->is_pop_ups = $param['is_pop_ups'];
+ $doc->create_time = date('Y-m-d H:i:s');
+ $doc->update_time = date('Y-m-d H:i:s');
+ $doc->name = $param['name'];
+ $doc->save();
+
+ return $this->toData('0', 'SUCCESS');
+ }catch (\Exception $exception){
+ return $this->toData('1', '系统繁忙', [$exception->getMessage()]);
+ }
+ }
+
+ public function detail($param)
+ {
+ try {
+ if(empty($param['id']) || !is_numeric($param['id'])){
+ return $this->toData('1', '目标不存在');
+ }
+
+ $doc = AnnouncementModel::where('id', $param['id'])
+ ->where('is_delete', AnnouncementModel::IS_DELETE_NO)
+ ->find();
+ if(empty($doc)){
+ return $this->toData('1', '目标不存在');
+ }
+
+ $docArr = $doc->toArray();
+
+ return $this->toData('0', 'SUCCESS', ['row' => $docArr,]);
+
+ }catch (\Exception $exception){
+ return $this->toData('1', '系统繁忙', [$exception->getMessage()]);
+ }
+ }
+
+ public function edit($param)
+ {
+ try {
+ if(empty($param['id']) || !is_numeric($param['id'])){
+ return $this->toData('1', '目标不存在');
+ }
+
+ $doc = AnnouncementModel::where('id', $param['id'])
+ ->where('is_delete', AnnouncementModel::IS_DELETE_NO)
+ ->find();
+ if(empty($doc)){
+ return $this->toData('1', '目标不存在');
+ }
+
+
+ $langIds = LanguageSettingModel::column('id');
+ if(empty($param['lang']) || !in_array($param['lang'], $langIds)){
+ return $this->toData('1', '语言类型无效');
+ }
+
+ if(empty($param['name']) || !is_string($param['name'])){
+ return $this->toData('1', '名称无效');
+ }
+
+ if(empty($param['title']) || !is_string($param['title'])){
+ return $this->toData('1', '标题无效');
+ }
+
+ if(empty($param['content']) || !is_string($param['content'])){
+ return $this->toData('1', '内容无效');
+ }
+
+ if(!isset($param['weight']) || !is_numeric($param['weight']) || ceil($param['weight']) != $param['weight'] || $param['weight'] < 0){
+ return $this->toData('1', '权重无效');
+ }
+
+ if(!isset($param['status']) || !in_array($param['status'], [1,2])){
+ return $this->toData('1', '状态无效');
+ }
+
+// $docExists = AnnouncementModel::where('is_delete', AnnouncementModel::IS_DELETE_NO)
+// ->where('id', '<>', $param['id'])
+// ->where('name', $param['name'])
+// ->where('lang', $param['lang'])->find();
+// if(!empty($docExists)){
+// return $this->toData('1', '已存在相同内容');
+// }
+
+ $doc->lang = $param['lang'];
+ $doc->title = $param['title'];
+ $doc->content = $param['content'];
+ $doc->status = $param['status'];
+ $doc->weight = $param['weight'];
+ if (!empty($param['is_pop_ups'])) $doc->is_pop_ups = $param['is_pop_ups'];
+ $doc->update_time = date('Y-m-d H:i:s');
+ $doc->name = $param['name'];
+ $doc->save();
+
+ return $this->toData('0', 'SUCCESS');
+ }catch (\Exception $exception){
+ return $this->toData('1', '系统繁忙', [$exception->getMessage()]);
+ }
+ }
+
+ public function del($param)
+ {
+ try {
+ if(empty($param['id']) || !is_numeric($param['id'])){
+ return $this->toData('1', '目标不存在');
+ }
+
+ $doc = AnnouncementModel::where('id', $param['id'])
+ ->where('is_delete', AnnouncementModel::IS_DELETE_NO)
+ ->find();
+ if(empty($doc)){
+ return $this->toData('1', '目标不存在');
+ }
+
+ $doc->is_delete = AnnouncementModel::IS_DELETE_YES;
+ $doc->save();
+
+ return $this->toData('0', 'SUCCESS');
+ }catch (\Exception $exception){
+ return $this->toData('1', '系统繁忙', [$exception->getMessage()]);
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/admin/service/document/BannerService.php b/app/admin/service/document/BannerService.php
new file mode 100644
index 0000000..1954387
--- /dev/null
+++ b/app/admin/service/document/BannerService.php
@@ -0,0 +1,196 @@
+field('id,lang,path,name,title,status')
+ ->order('name', 'asc')
+ ->select();
+ if(!$list->isEmpty()){
+ $rows = $list->toArray();
+ $lang = LanguageSettingModel::where('id', '>', 0)->column('china_name', 'id');
+ foreach ($rows as $key=>$item){
+ $rows[$key]['lang'] = $lang[$item['lang']] ?? '-';
+ $rows[$key]['status'] = BannerModel::STATUS_MAP[$item['status']] ?? '-';
+ }
+ }
+
+ return $this->toData('0', 'SUCCESS', ['list' => $rows, 'total' => count($rows)]);
+ }catch (\Exception $exception){
+ return $this->toData('1', '系统繁忙', [$exception->getMessage()]);
+ }
+ }
+
+ public function add($param)
+ {
+ try {
+
+ $langIds = LanguageSettingModel::column('id');
+ if(empty($param['lang']) || !in_array($param['lang'], $langIds)){
+ return $this->toData('1', '语言类型无效');
+ }
+
+ if(empty($param['name']) || !is_string($param['name'])){
+ return $this->toData('1', '名称无效');
+ }
+
+ if(empty($param['title']) || !is_string($param['title'])){
+ return $this->toData('1', '标题无效');
+ }
+
+ if(empty($param['content']) || !is_string($param['content'])){
+ return $this->toData('1', '内容无效');
+ }
+
+ if(empty($param['path']) || !is_string($param['path'])){
+ return $this->toData('1', '图片路径无效');
+ }
+
+
+ if(!isset($param['status']) || !in_array($param['status'], [1,2])){
+ return $this->toData('1', '状态无效');
+ }
+
+ $docExists = BannerModel::where('is_delete', BannerModel::IS_DELETE_NO)
+ ->where('name', $param['name'])
+ ->where('lang', $param['lang'])->find();
+ if(!empty($docExists)){
+ return $this->toData('1', '已存在相同内容');
+ }
+
+ $doc = new BannerModel();
+ $doc->lang = $param['lang'];
+ $doc->path = $param['path'];
+ $doc->title = $param['title'];
+ $doc->content = $param['content'];
+ $doc->status = $param['status'];
+ $doc->create_time = date('Y-m-d H:i:s');
+ $doc->update_time = date('Y-m-d H:i:s');
+ $doc->name = $param['name'];
+ $doc->save();
+
+ return $this->toData('0', 'SUCCESS');
+ }catch (\Exception $exception){
+ return $this->toData('1', '系统繁忙', [$exception->getMessage()]);
+ }
+ }
+
+ public function detail($param)
+ {
+ try {
+ if(empty($param['id']) || !is_numeric($param['id'])){
+ return $this->toData('1', '目标不存在');
+ }
+
+ $doc = BannerModel::where('id', $param['id'])
+ ->where('is_delete', BannerModel::IS_DELETE_NO)
+ ->find();
+ if(empty($doc)){
+ return $this->toData('1', '目标不存在');
+ }
+
+ $docArr = $doc->toArray();
+
+ return $this->toData('0', 'SUCCESS', ['row' => $docArr]);
+
+ }catch (\Exception $exception){
+ return $this->toData('1', '系统繁忙', [$exception->getMessage()]);
+ }
+ }
+
+ public function edit($param)
+ {
+ try {
+ if(empty($param['id']) || !is_numeric($param['id'])){
+ return $this->toData('1', '目标不存在');
+ }
+
+ $doc = BannerModel::where('id', $param['id'])
+ ->where('is_delete', BannerModel::IS_DELETE_NO)
+ ->find();
+ if(empty($doc)){
+ return $this->toData('1', '目标不存在');
+ }
+
+ $langIds = LanguageSettingModel::column('id');
+ if(empty($param['lang']) || !in_array($param['lang'], $langIds)){
+ return $this->toData('1', '语言类型无效');
+ }
+
+ if(empty($param['name']) || !is_string($param['name'])){
+ return $this->toData('1', '名称无效');
+ }
+
+ if(empty($param['title']) || !is_string($param['title'])){
+ return $this->toData('1', '标题无效');
+ }
+
+ if(empty($param['content']) || !is_string($param['content'])){
+ return $this->toData('1', '内容无效');
+ }
+
+ if(empty($param['path']) || !is_string($param['path'])){
+ return $this->toData('1', '图片路径无效');
+ }
+
+ if(!isset($param['status']) || !in_array($param['status'], [1,2])){
+ return $this->toData('1', '状态无效');
+ }
+
+ $docExists = BannerModel::where('is_delete', BannerModel::IS_DELETE_NO)
+ ->where('id', '<>', $param['id'])
+ ->where('name', $param['name'])
+ ->where('lang', $param['lang'])->find();
+ if(!empty($docExists)){
+ return $this->toData('1', '已存在相同内容');
+ }
+
+ $doc->lang = $param['lang'];
+ $doc->title = $param['title'];
+ $doc->content = $param['content'];
+ $doc->status = $param['status'];
+ $doc->path = $param['path'];
+ $doc->update_time = date('Y-m-d H:i:s');
+ $doc->name = $param['name'];
+ $doc->save();
+
+ return $this->toData('0', 'SUCCESS');
+ }catch (\Exception $exception){
+ return $this->toData('1', '系统繁忙', [$exception->getMessage()]);
+ }
+ }
+
+ public function del($param)
+ {
+ try {
+ if(empty($param['id']) || !is_numeric($param['id'])){
+ return $this->toData('1', '目标不存在');
+ }
+
+ $doc = BannerModel::where('id', $param['id'])
+ ->where('is_delete', BannerModel::IS_DELETE_NO)
+ ->find();
+ if(empty($doc)){
+ return $this->toData('1', '目标不存在');
+ }
+
+ $doc->is_delete = BannerModel::IS_DELETE_YES;
+ $doc->save();
+
+ return $this->toData('0', 'SUCCESS');
+ }catch (\Exception $exception){
+ return $this->toData('1', '系统繁忙', [$exception->getMessage()]);
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/admin/service/document/FaqService.php b/app/admin/service/document/FaqService.php
new file mode 100644
index 0000000..8f77bb2
--- /dev/null
+++ b/app/admin/service/document/FaqService.php
@@ -0,0 +1,195 @@
+field('id,lang,name,title,status,weight')
+ ->order('name', 'asc')
+ ->order('weight', 'desc')->select();
+ if(!$list->isEmpty()){
+ $rows = $list->toArray();
+ $lang = LanguageSettingModel::where('id', '>', 0)->column('china_name', 'id');
+ foreach ($rows as $key=>$item){
+ $rows[$key]['lang'] = $lang[$item['lang']] ?? '-';
+ $rows[$key]['status'] = FaqModel::STATUS_MAP[$item['status']] ?? '-';
+ }
+ }
+
+ return $this->toData('0', 'SUCCESS', ['list' => $rows, 'total' => count($rows)]);
+ }catch (\Exception $exception){
+ return $this->toData('1', '系统繁忙', [$exception->getMessage()]);
+ }
+ }
+
+ public function add($param)
+ {
+ try {
+ $langIds = LanguageSettingModel::column('id');
+ if(empty($param['lang']) || !in_array($param['lang'], $langIds)){
+ return $this->toData('1', '语言类型无效');
+ }
+
+ if(empty($param['name']) || !is_string($param['name'])){
+ return $this->toData('1', '名称无效');
+ }
+
+ if(empty($param['title']) || !is_string($param['title'])){
+ return $this->toData('1', '标题无效');
+ }
+
+ if(empty($param['content']) || !is_string($param['content'])){
+ return $this->toData('1', '内容无效');
+ }
+
+ if(!isset($param['weight']) || !is_numeric($param['weight']) || ceil($param['weight']) != $param['weight'] || $param['weight'] < 0){
+ return $this->toData('1', '权重无效');
+ }
+
+ if(!isset($param['status']) || !in_array($param['status'], [1,2])){
+ return $this->toData('1', '状态无效');
+ }
+
+ $docExists = FaqModel::where('is_delete', FaqModel::IS_DELETE_NO)
+ ->where('name', $param['name'])
+ ->where('lang', $param['lang'])->find();
+ if(!empty($docExists)){
+ return $this->toData('1', '已存在相同内容');
+ }
+
+ $doc = new FaqModel;
+ $doc->lang = $param['lang'];
+ $doc->title = $param['title'];
+ $doc->content = $param['content'];
+ $doc->status = $param['status'];
+ $doc->weight = $param['weight'];
+ $doc->create_time = date('Y-m-d H:i:s');
+ $doc->update_time = date('Y-m-d H:i:s');
+ $doc->name = $param['name'];
+ $doc->save();
+
+ return $this->toData('0', 'SUCCESS');
+ }catch (\Exception $exception){
+ return $this->toData('1', '系统繁忙', [$exception->getMessage()]);
+ }
+ }
+
+ public function detail($param)
+ {
+ try {
+ if(empty($param['id']) || !is_numeric($param['id'])){
+ return $this->toData('1', '目标不存在');
+ }
+
+ $doc = FaqModel::where('id', $param['id'])
+ ->where('is_delete', FaqModel::IS_DELETE_NO)
+ ->find();
+ if(empty($doc)){
+ return $this->toData('1', '目标不存在');
+ }
+
+ $docArr = $doc->toArray();
+
+ return $this->toData('0', 'SUCCESS', ['row' => $docArr,]);
+
+ }catch (\Exception $exception){
+ return $this->toData('1', '系统繁忙', [$exception->getMessage()]);
+ }
+ }
+
+ public function edit($param)
+ {
+ try {
+ if(empty($param['id']) || !is_numeric($param['id'])){
+ return $this->toData('1', '目标不存在');
+ }
+
+ $doc = FaqModel::where('id', $param['id'])
+ ->where('is_delete', FaqModel::IS_DELETE_NO)
+ ->find();
+ if(empty($doc)){
+ return $this->toData('1', '目标不存在');
+ }
+
+
+ $langIds = LanguageSettingModel::column('id');
+ if(empty($param['lang']) || !in_array($param['lang'], $langIds)){
+ return $this->toData('1', '语言类型无效');
+ }
+
+ if(empty($param['name']) || !is_string($param['name'])){
+ return $this->toData('1', '名称无效');
+ }
+
+ if(empty($param['title']) || !is_string($param['title'])){
+ return $this->toData('1', '标题无效');
+ }
+
+ if(empty($param['content']) || !is_string($param['content'])){
+ return $this->toData('1', '内容无效');
+ }
+
+ if(!isset($param['weight']) || !is_numeric($param['weight']) || ceil($param['weight']) != $param['weight'] || $param['weight'] < 0){
+ return $this->toData('1', '权重无效');
+ }
+
+ if(!isset($param['status']) || !in_array($param['status'], [1,2])){
+ return $this->toData('1', '状态无效');
+ }
+
+ $docExists = FaqModel::where('is_delete', FaqModel::IS_DELETE_NO)
+ ->where('id', '<>', $param['id'])
+ ->where('name', $param['name'])
+ ->where('lang', $param['lang'])->find();
+ if(!empty($docExists)){
+ return $this->toData('1', '已存在相同内容');
+ }
+
+ $doc->lang = $param['lang'];
+ $doc->title = $param['title'];
+ $doc->content = $param['content'];
+ $doc->status = $param['status'];
+ $doc->weight = $param['weight'];
+ $doc->update_time = date('Y-m-d H:i:s');
+ $doc->name = $param['name'];
+ $doc->save();
+
+ return $this->toData('0', 'SUCCESS');
+ }catch (\Exception $exception){
+ return $this->toData('1', '系统繁忙', [$exception->getMessage()]);
+ }
+ }
+
+ public function del($param)
+ {
+ try {
+ if(empty($param['id']) || !is_numeric($param['id'])){
+ return $this->toData('1', '目标不存在');
+ }
+
+ $doc = FaqModel::where('id', $param['id'])
+ ->where('is_delete', FaqModel::IS_DELETE_NO)
+ ->find();
+ if(empty($doc)){
+ return $this->toData('1', '目标不存在');
+ }
+
+ $doc->is_delete = FaqModel::IS_DELETE_YES;
+ $doc->save();
+
+ return $this->toData('0', 'SUCCESS');
+ }catch (\Exception $exception){
+ return $this->toData('1', '系统繁忙', [$exception->getMessage()]);
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/admin/service/document/IndexService.php b/app/admin/service/document/IndexService.php
new file mode 100644
index 0000000..500ac3d
--- /dev/null
+++ b/app/admin/service/document/IndexService.php
@@ -0,0 +1,211 @@
+field('id,lang,type,name,title,status,weight')
+ ->order('type', 'asc')
+ ->order('name', 'asc')
+ ->order('weight', 'desc')->select();
+ if(!$list->isEmpty()){
+ $rows = $list->toArray();
+ $lang = LanguageSettingModel::where('id', '>', 0)->column('china_name', 'id');
+ foreach ($rows as $key=>$item){
+ $rows[$key]['type'] = DocumentModel::TYPE_MAP[$item['type']] ?? '-';
+ $rows[$key]['lang'] = $lang[$item['lang']] ?? '-';
+ $rows[$key]['status'] = DocumentModel::STATUS_MAP[$item['status']] ?? '-';
+ }
+ }
+
+ return $this->toData('0', 'SUCCESS', ['list' => $rows, 'total' => count($rows),'extend' => ['typeMap' => DocumentModel::TYPE_MAP]]);
+ }catch (\Exception $exception){
+ return $this->toData('1', '系统繁忙', [$exception->getMessage()]);
+ }
+ }
+
+ public function add($param)
+ {
+ try {
+ $typeMapKeys = array_keys(DocumentModel::TYPE_MAP);
+ if(empty($param['type']) || !in_array($param['type'],$typeMapKeys)){
+ return $this->toData('1', '文章类型无效');
+ }
+
+ $langIds = LanguageSettingModel::column('id');
+ if(empty($param['lang']) || !in_array($param['lang'], $langIds)){
+ return $this->toData('1', '语言类型无效');
+ }
+
+ if(empty($param['name']) || !is_string($param['name'])){
+ return $this->toData('1', '名称无效');
+ }
+
+ if(empty($param['title']) || !is_string($param['title'])){
+ return $this->toData('1', '标题无效');
+ }
+
+ if(empty($param['content']) || !is_string($param['content'])){
+ return $this->toData('1', '内容无效');
+ }
+
+ if(!isset($param['weight']) || !is_numeric($param['weight']) || ceil($param['weight']) != $param['weight'] || $param['weight'] < 0){
+ return $this->toData('1', '权重无效');
+ }
+
+ if(!isset($param['status']) || !in_array($param['status'], [1,2])){
+ return $this->toData('1', '状态无效');
+ }
+
+ $docExists = DocumentModel::where('type', $param['type'])
+ ->where('is_delete', DocumentModel::IS_DELETE_NO)
+ ->where('name', $param['name'])
+ ->where('lang', $param['lang'])->find();
+ if(!empty($docExists)){
+ return $this->toData('1', '已存在相同内容');
+ }
+
+ $doc = new DocumentModel;
+ $doc->lang = $param['lang'];
+ $doc->type = $param['type'];
+ $doc->title = $param['title'];
+ $doc->content = $param['content'];
+ $doc->status = $param['status'];
+ $doc->weight = $param['weight'];
+ $doc->create_time = date('Y-m-d H:i:s');
+ $doc->update_time = date('Y-m-d H:i:s');
+ $doc->name = $param['name'];
+ $doc->save();
+
+ return $this->toData('0', 'SUCCESS');
+ }catch (\Exception $exception){
+ return $this->toData('1', '系统繁忙', [$exception->getMessage()]);
+ }
+ }
+
+ public function detail($param)
+ {
+ try {
+ if(empty($param['id']) || !is_numeric($param['id'])){
+ return $this->toData('1', '目标不存在');
+ }
+
+ $doc = DocumentModel::where('id', $param['id'])
+ ->where('is_delete', DocumentModel::IS_DELETE_NO)
+ ->find();
+ if(empty($doc)){
+ return $this->toData('1', '目标不存在');
+ }
+
+ $docArr = $doc->toArray();
+
+ return $this->toData('0', 'SUCCESS', ['row' => $docArr,
+ 'extend' => ['typeMap' => DocumentModel::TYPE_MAP]]);
+
+ }catch (\Exception $exception){
+ return $this->toData('1', '系统繁忙', [$exception->getMessage()]);
+ }
+ }
+
+ public function edit($param)
+ {
+ try {
+ if(empty($param['id']) || !is_numeric($param['id'])){
+ return $this->toData('1', '目标不存在');
+ }
+
+ $doc = DocumentModel::where('id', $param['id'])
+ ->where('is_delete', DocumentModel::IS_DELETE_NO)
+ ->find();
+ if(empty($doc)){
+ return $this->toData('1', '目标不存在');
+ }
+
+ $typeMapKeys = array_keys(DocumentModel::TYPE_MAP);
+ if(empty($param['type']) || !in_array($param['type'],$typeMapKeys)){
+ return $this->toData('1', '文章类型无效');
+ }
+
+ $langIds = LanguageSettingModel::column('id');
+ if(empty($param['lang']) || !in_array($param['lang'], $langIds)){
+ return $this->toData('1', '语言类型无效');
+ }
+
+ if(empty($param['name']) || !is_string($param['name'])){
+ return $this->toData('1', '名称无效');
+ }
+
+ if(empty($param['title']) || !is_string($param['title'])){
+ return $this->toData('1', '标题无效');
+ }
+
+ if(empty($param['content']) || !is_string($param['content'])){
+ return $this->toData('1', '内容无效');
+ }
+
+ if(!isset($param['weight']) || !is_numeric($param['weight']) || ceil($param['weight']) != $param['weight'] || $param['weight'] < 0){
+ return $this->toData('1', '权重无效');
+ }
+
+ if(!isset($param['status']) || !in_array($param['status'], [1,2])){
+ return $this->toData('1', '状态无效');
+ }
+
+ $docExists = DocumentModel::where('type', $param['type'])
+ ->where('is_delete', DocumentModel::IS_DELETE_NO)
+ ->where('id', '<>', $param['id'])
+ ->where('name', $param['name'])
+ ->where('lang', $param['lang'])->find();
+ if(!empty($docExists)){
+ return $this->toData('1', '已存在相同内容');
+ }
+
+ $doc->lang = $param['lang'];
+ $doc->type = $param['type'];
+ $doc->title = $param['title'];
+ $doc->content = $param['content'];
+ $doc->status = $param['status'];
+ $doc->weight = $param['weight'];
+ $doc->update_time = date('Y-m-d H:i:s');
+ $doc->name = $param['name'];
+ $doc->save();
+
+ return $this->toData('0', 'SUCCESS');
+ }catch (\Exception $exception){
+ return $this->toData('1', '系统繁忙', [$exception->getMessage()]);
+ }
+ }
+
+ public function del($param)
+ {
+ try {
+ if(empty($param['id']) || !is_numeric($param['id'])){
+ return $this->toData('1', '目标不存在');
+ }
+
+ $doc = DocumentModel::where('id', $param['id'])
+ ->where('is_delete', DocumentModel::IS_DELETE_NO)
+ ->find();
+ if(empty($doc)){
+ return $this->toData('1', '目标不存在');
+ }
+
+ $doc->is_delete = DocumentModel::IS_DELETE_YES;
+ $doc->save();
+
+ return $this->toData('0', 'SUCCESS');
+ }catch (\Exception $exception){
+ return $this->toData('1', '系统繁忙', [$exception->getMessage()]);
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/admin/service/document/LandingPageService.php b/app/admin/service/document/LandingPageService.php
new file mode 100644
index 0000000..14e8c1b
--- /dev/null
+++ b/app/admin/service/document/LandingPageService.php
@@ -0,0 +1,148 @@
+order('id', 'desc')->select();
+ if(!$list->isEmpty()){
+ $rows = $list->toArray();
+ }
+
+ return $this->toData('0', 'SUCCESS', ['list' => $rows, 'total' => count($rows)]);
+ }catch (\Exception $exception){
+ return $this->toData('1', '系统繁忙', [$exception->getMessage()]);
+ }
+ }
+
+ public function add($param): array
+ {
+ try {
+
+ // 名称
+ if(empty($param['name']) || !is_string($param['name'])){
+ return $this->toData('1', '名称无效');
+ }
+
+ // 内容
+ if(empty($param['content']) || !is_string($param['content'])){
+ return $this->toData('1', '内容无效');
+ }
+
+ // 跳转地址
+ if(empty($param['link_url']) || !is_string($param['link_url'])){
+ $param['link_url'] = '';
+ }
+
+ if(!isset($param['status']) || !in_array($param['status'], [LandingPageModel::STATUS_ON, LandingPageModel::STATUS_OFF])){
+ return $this->toData('1', '状态无效');
+ }
+
+ $docExists = LandingPageModel::where('is_delete', LandingPageModel::IS_DELETE_NO)
+ ->where('name', $param['name'])
+ ->find();
+ if(!empty($docExists)){
+ return $this->toData('1', '已存在相同内容');
+ }
+
+ $doc = new LandingPageModel;
+ $doc->name = $param['name'];
+ $doc->content = $param['content'];
+ $doc->click_num = 0;
+ $doc->link_url = 0;
+ $doc->is_delete = 0;
+ $doc->status = 0;
+ $doc->create_time = date('Y-m-d H:i:s');
+ $doc->update_time = date('Y-m-d H:i:s');
+ $doc->save();
+
+ return $this->toData('0', 'SUCCESS');
+ }catch (\Exception $exception){
+ return $this->toData('1', '系统繁忙', [$exception->getMessage()]);
+ }
+ }
+
+ public function edit($param): array
+ {
+ try {
+ if(empty($param['id']) || !is_numeric($param['id'])){
+ return $this->toData('1', '目标不存在');
+ }
+
+ $doc = LandingPageModel::where('id', $param['id'])
+ ->where('is_delete', LandingPageModel::IS_DELETE_NO)
+ ->find();
+ if(empty($doc)){
+ return $this->toData('1', '目标不存在');
+ }
+
+ // 名称
+ if(empty($param['name']) || !is_string($param['name'])){
+ return $this->toData('1', '名称无效');
+ }
+
+ // 内容
+ if(empty($param['content']) || !is_string($param['content'])){
+ return $this->toData('1', '内容无效');
+ }
+
+ // 跳转地址
+ if(empty($param['link_url']) || !is_string($param['link_url'])){
+ $param['link_url'] = '';
+ }
+
+ if(!isset($param['status']) || !in_array($param['status'], [LandingPageModel::STATUS_ON, LandingPageModel::STATUS_OFF])){
+ return $this->toData('1', '状态无效');
+ }
+
+ $docExists = LandingPageModel::where('is_delete', LandingPageModel::IS_DELETE_NO)
+ ->where('id', '<>', $param['id'])
+ ->where('name', $param['name'])->find();
+ if(!empty($docExists)){
+ return $this->toData('1', '已存在相同内容');
+ }
+
+ $doc->name = $param['name'];
+ $doc->content = $param['content'];
+ $doc->status = $param['status'];
+ $doc->link_url = $param['link_url'];
+ $doc->update_time = date('Y-m-d H:i:s');
+ $doc->save();
+
+ return $this->toData('0', 'SUCCESS');
+ }catch (\Exception $exception){
+ return $this->toData('1', '系统繁忙', [$exception->getMessage()]);
+ }
+ }
+
+ public function del($param): array
+ {
+ try {
+ if(empty($param['id']) || !is_numeric($param['id'])){
+ return $this->toData('1', '目标不存在');
+ }
+
+ $doc = LandingPageModel::where('id', $param['id'])
+ ->where('is_delete', LandingPageModel::IS_DELETE_NO)
+ ->find();
+ if(empty($doc)){
+ return $this->toData('1', '目标不存在');
+ }
+
+ $doc->is_delete = LandingPageModel::IS_DELETE_YES;
+ $doc->save();
+
+ return $this->toData('0', 'SUCCESS');
+ }catch (\Exception $exception){
+ return $this->toData('1', '系统繁忙', [$exception->getMessage()]);
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/admin/service/setting/BlockStockService.php b/app/admin/service/setting/BlockStockService.php
new file mode 100644
index 0000000..b2db4ec
--- /dev/null
+++ b/app/admin/service/setting/BlockStockService.php
@@ -0,0 +1,372 @@
+toData('1', '分页参数错误');
+ }
+
+ $where = [];
+ // 未删除
+ $where[] = [
+ 'is_delete', '=', StockBlockListModel::IS_DELETE_NO
+ ];
+ // 股票号
+ if (!empty($param['stock_code']) && is_string($param['stock_code'])) {
+ $where[] = [
+ 'stock_code', '=', $param['stock_code']
+ ];
+ }
+
+ // 状态
+ if (!empty($param['status']) && in_array($param['status'], [StockBlockListModel::STATUS_ON, StockBlockListModel::STATUS_OFF])) {
+ $where[] = [
+ 'status', '=', $param['status']
+ ];
+ }
+
+ $query = StockBlockListModel::where($where);
+ $totalQuery = StockBlockListModel::where($where);
+ $list = $query->order('id', 'desc')->page($param['page'], $param['limit'])->select();
+ $total = $totalQuery->order('id', 'desc')->count();
+
+
+ return $this->toData('0', 'SUCCESS', ['list' => $list, 'total' => $total, 'extend' => [
+// 'tape_list' => StockBlockListModel::$tapeList,
+ 'stock_type_list' => StockBlockListModel::$typeList,
+ ]]);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统繁忙', [$exception->getMessage()]);
+ }
+ }
+
+ // 新增
+ public function add($param)
+ {
+ try {
+ // 股票代码
+ if (empty($param['stock_code']) || !is_string($param['stock_code'])) {
+ return $this->toData('1', '股票代码 无效');
+ }
+
+
+ // 股票类型
+ if (empty($param['type']) || !in_array($param['type'], array_keys(StockBlockListModel::$typeList))) {
+ return $this->toData('1', '股票市场 无效');
+ }
+
+ // 交易所类型
+// if(empty($param['tape']) || !in_array($param['tape'], array_keys(StockBlockListModel::$tapeList))){
+// return $this->toData('1', '交易所类型 无效');
+// }
+
+ switch ($param['type']) {
+ case '3':
+ $stock = StockListModel::where('stock_code', $param['stock_code'])->find();
+ if (empty($stock)) return $this->toData('1', 'stock_code 无效');
+ break;
+ case '4':
+ $stock = StockIdnListModel::where('stock_code', $param['stock_code'])->find();
+ if (empty($stock)) return $this->toData('1', 'stock_code 无效');
+ break;
+ case '5':
+ $stock = StockMysListModel::where('stock_code', $param['stock_code'])->find();
+ if (empty($stock)) return $this->toData('1', 'stock_code 无效');
+ break;
+ case '6':
+ $stock = StockThaListModel::where('stock_code', $param['stock_code'])->find();
+ if (empty($stock)) return $this->toData('1', 'stock_code 无效');
+ break;
+ case '7':
+ $stock = StockInListModel::where('stock_code', $param['stock_code'])->find();
+ if (empty($stock)) return $this->toData('1', 'stock_code 无效');
+ break;
+ case '9':
+ $stock = StockSgdListModel::where('stock_code', $param['stock_code'])->find();
+ if (empty($stock)) return $this->toData('1', 'stock_code 无效');
+ break;
+ case '12':
+ $stock = StockHkdListModel::where('stock_code', $param['stock_code'])->find();
+ if (empty($stock)) return $this->toData('1', 'stock_code 无效');
+ break;
+ default:
+ return $this->toData('1', '股票市场或股票代码 无效');
+ }
+
+
+ // 发布状态
+ if (empty($param['status']) || !in_array($param['status'], [StockBlockListModel::STATUS_ON, StockBlockListModel::STATUS_OFF])) {
+ return $this->toData('1', '发布状态 无效');
+ }
+
+ // 单股价格
+ if (empty($param['price']) || !is_numeric($param['price']) || $param['price'] <= 0) {
+ return $this->toData('1', '单股价格 无效');
+ }
+
+ // 最小申购数量
+ if (empty($param['min']) || !is_numeric($param['min']) || $param['min'] <= 0 || ceil($param['min']) != $param['min']) {
+ return $this->toData('1', '最小购买股数无效');
+ }
+
+ // 开始认购时间
+ if (empty($param['start_time']) || !is_string($param['start_time'])) {
+ return $this->toData('1', '开始认购时间 无效');
+ }
+
+ // 认购结束时间
+ if (empty($param['end_time']) || !is_string($param['end_time']) || strtotime($param['end_time']) <= strtotime($param['start_time'])) {
+ return $this->toData('1', '认购结束时间 无效');
+ }
+
+ // 可出售时间时间
+ if (empty($param['today_add']) || !is_numeric($param['today_add'])) {
+ return $this->toData('1', 'T+n 无效');
+ }
+
+ // 新增数据
+ $blockStock = new StockBlockListModel();
+ $blockStock->stock_code = $param['stock_code'];
+ $blockStock->stock_name = $param['stock_name'];
+ $blockStock->type = $param['type'];
+ $blockStock->tape = $stock->tape;
+ $blockStock->status = $param['status'];
+ $blockStock->price = $param['price'];
+ $blockStock->min = $param['min'];
+ $blockStock->start_time = $param['start_time'];
+ $blockStock->end_time = $param['end_time'];
+ $blockStock->today_add = $param['today_add'];
+ $blockStock->keep_decimal = $stock->keep_decimal;
+ $blockStock->info = $param['info'] ?? '';
+ $blockStock->forced_closure = $stock->forced_closure;
+ $blockStock->up_limit = $stock->up_limit;;
+ $blockStock->down_limit = $stock->down_limit;
+ $blockStock->create_time = date('Y-m-d H:i:s');
+ $blockStock->update_time = date('Y-m-d H:i:s');
+ $blockStock->save();
+
+ // 加入缓存
+ $list_key = StockBlockListModel::$typeListEn[$param['type']] . ":BLOCK:LIST:" . $param['stock_code'];
+ $redis = $this->getRedis();
+ $redis->del($list_key);
+ $redis->hMset($list_key, [
+ 'stock_name' => $blockStock->stock_name,
+ 'stock_code' => $blockStock->stock_code,
+ 'status' => $blockStock->status,
+ 'keep_decimal' => $blockStock->keep_decimal,
+ 'forced_closure' => $blockStock->forced_closure,
+ 'up_limit' => $blockStock->up_limit,
+ 'down_limit' => $blockStock->down_limit,
+ 'info' => $blockStock->info,
+ 'tape' => $blockStock->tape,
+ 'price' => $blockStock->price,
+ 'min' => $blockStock->min,
+ 'start_time' => $blockStock->start_time,
+ 'end_time' => $blockStock->end_time,
+ 'today_add' => $blockStock->today_add
+ ]);
+
+ return $this->toData('0', 'SUCCESS');
+ } catch (\Exception $exception) {
+ return $this->toData('0', '系统繁忙', [$exception->getMessage()]);
+ }
+ }
+
+ // 编辑
+ public function edit($param)
+ {
+ try {
+ if (empty($param['id']) || !is_numeric($param['id'])) {
+ return $this->toData('1', '主键 无效');
+ }
+
+ $blockStock = StockBlockListModel::where('id', $param['id'])->where('is_delete', StockBlockListModel::IS_DELETE_NO)->find();
+ if (empty($blockStock)) {
+ return $this->toData('1', '主键 无效');
+ }
+
+// // 已中签或者已上市不支持修改
+// if($blockStock->open_status == PreMysStockModel::OPEN_STATUS_HAD || strtotime($blockStock->get_time)<=time()){
+// return $this->toData('1', '已中签或已上市 不支持修改');
+// }
+
+ // 股票代码
+ if (empty($param['stock_code']) || !is_string($param['stock_code'])) {
+ return $this->toData('1', '股票代码 无效');
+ }
+
+ // 股票名称
+ if (empty($param['stock_name']) || !is_string($param['stock_name'])) {
+ return $this->toData('1', '股票代码 无效');
+ }
+
+ // 股票类型
+ if (empty($param['type']) || !in_array($param['type'], array_keys(StockBlockListModel::$typeList))) {
+ return $this->toData('1', '股票市场 无效');
+ }
+
+ switch ($param['type']) {
+ case '3':
+ $stock = StockListModel::where('stock_code', $param['stock_code'])->find();
+ if (empty($stock)) return $this->toData('1', 'stock_code 无效');
+ break;
+ case '4':
+ $stock = StockIdnListModel::where('stock_code', $param['stock_code'])->find();
+ if (empty($stock)) return $this->toData('1', 'stock_code 无效');
+ break;
+ case '5':
+ $stock = StockMysListModel::where('stock_code', $param['stock_code'])->find();
+ if (empty($stock)) return $this->toData('1', 'stock_code 无效');
+ break;
+ case '6':
+ $stock = StockThaListModel::where('stock_code', $param['stock_code'])->find();
+ if (empty($stock)) return $this->toData('1', 'stock_code 无效');
+ break;
+ case '7':
+ $stock = StockInListModel::where('stock_code', $param['stock_code'])->find();
+ if (empty($stock)) return $this->toData('1', 'stock_code 无效');
+ break;
+ case '9':
+ $stock = StockSgdListModel::where('stock_code', $param['stock_code'])->find();
+ if (empty($stock)) return $this->toData('1', 'stock_code 无效');
+ break;
+ case '12':
+ $stock = StockHkdListModel::where('stock_code', $param['stock_code'])->find();
+ if (empty($stock)) return $this->toData('1', 'stock_code 无效');
+ break;
+ default:
+ return $this->toData('1', '股票市场或股票代码 无效');
+ }
+
+ // 交易所类型
+// if(empty($param['tape']) || !in_array($param['tape'], array_keys(StockBlockListModel::$tapeList))){
+// return $this->toData('1', '交易所类型 无效');
+// }
+
+ // 发布状态
+ if (empty($param['status']) || !in_array($param['status'], [StockBlockListModel::STATUS_ON, StockBlockListModel::STATUS_OFF])) {
+ return $this->toData('1', '发布状态 无效');
+ }
+
+ // 单股价格
+ if (empty($param['price']) || !is_numeric($param['price']) || $param['price'] <= 0) {
+ return $this->toData('1', '单股价格 无效');
+ }
+
+ // 最小申购数量
+ if (empty($param['min']) || !is_numeric($param['min']) || $param['min'] <= 0 || ceil($param['min']) != $param['min']) {
+ return $this->toData('1', '最小购买股数无效');
+ }
+
+ // 开始认购时间
+ if (empty($param['start_time']) || !is_string($param['start_time'])) {
+ return $this->toData('1', '开始认购时间 无效');
+ }
+
+ // 认购结束时间
+ if (empty($param['end_time']) || !is_string($param['end_time']) || strtotime($param['end_time']) <= strtotime($param['start_time'])) {
+ return $this->toData('1', '认购结束时间 无效');
+ }
+
+ // 可出售时间时间
+ if (empty($param['today_add']) || !is_numeric($param['today_add'])) {
+ return $this->toData('1', 'T+n 无效');
+ }
+
+ // 新增数据
+ $blockStock->stock_code = $param['stock_code'];
+ $blockStock->stock_name = $param['stock_name'];
+ $blockStock->type = $param['type'];
+ $blockStock->tape = $stock->tape;
+ $blockStock->status = $param['status'];
+ $blockStock->price = $param['price'];
+ $blockStock->min = $param['min'];
+ $blockStock->start_time = $param['start_time'];
+ $blockStock->end_time = $param['end_time'];
+ $blockStock->today_add = $param['today_add'];
+ $blockStock->keep_decimal = $stock->keep_decimal;
+ $blockStock->info = $param['info'] ?? '';
+ $blockStock->forced_closure = $stock->forced_closure;
+ $blockStock->up_limit = $stock->up_limit;;
+ $blockStock->down_limit = $stock->down_limit;
+ $blockStock->update_time = date('Y-m-d H:i:s');
+ $blockStock->save();
+
+ // 加入缓存
+ $list_key = StockBlockListModel::$typeListEn[$param['type']] . ":BLOCK:LIST:" . $param['stock_code'];
+ $redis = $this->getRedis();
+ $redis->del($list_key);
+ $redis->hMset($list_key, [
+ 'stock_name' => $blockStock->stock_name,
+ 'stock_code' => $blockStock->stock_code,
+ 'status' => $blockStock->status,
+ 'keep_decimal' => $blockStock->keep_decimal,
+ 'forced_closure' => $blockStock->forced_closure,
+ 'up_limit' => $blockStock->up_limit,
+ 'down_limit' => $blockStock->down_limit,
+ 'info' => $blockStock->info,
+ 'tape' => $blockStock->tape,
+ 'price' => $blockStock->price,
+ 'min' => $blockStock->min,
+ 'start_time' => $blockStock->start_time,
+ 'end_time' => $blockStock->end_time,
+ 'today_add' => $blockStock->today_add
+ ]);
+
+ return $this->toData('0', 'SUCCESS');
+ } catch (\Exception $exception) {
+ return $this->toData('0', '系统繁忙', [$exception->getMessage()]);
+ }
+ }
+
+// //删除
+// public function del($param)
+// {
+// try {
+// if (empty($param['id']) || !is_numeric($param['id'])) {
+// return $this->toData('1', '主键 无效');
+// }
+//
+// $preInStock = StockBlockListModel::where('id', $param['id'])->where('is_delete', StockBlockListModel::IS_DELETE_NO)->find();
+// if (empty($preInStock)) {
+// return $this->toData('1', '主键 无效');
+// }
+//
+// $orderList = UserMysPreStockOrderModel::where('pre_stock_id', $preInStock->id)->select();
+// if (!$orderList->isEmpty()) {
+// return $this->toData('1', '已有申购订单不可删除');
+// }
+//
+// // 删除
+// $list_key = "MYS:STOCK:LIST:" . $preInStock->stock_code;
+// $redis = $this->getRedis();
+// $redis->del($list_key);
+//
+// //删除 修改状态
+// $preInStock->is_delete = PreMysStockModel::IS_DELETE_YES;
+// $preInStock->save();
+// return $this->toData('0', 'SUCCESS');
+// } catch (\Exception $exception) {
+// return $this->toData('1', '系统繁忙', [$exception->getMessage()]);
+// }
+// }
+}
\ No newline at end of file
diff --git a/app/admin/service/setting/BrokerageService.php b/app/admin/service/setting/BrokerageService.php
new file mode 100644
index 0000000..06bc2f9
--- /dev/null
+++ b/app/admin/service/setting/BrokerageService.php
@@ -0,0 +1,138 @@
+select();
+ $rows = [];
+ if(!$list->isEmpty()){
+ $rows = $list->toArray();
+ }
+ return $this->toData('0', 'SUCCESS', ['list' => $rows, 'total' => count($rows)]);
+ }catch (\Exception $exception){
+ return $this->toData('1', '系统繁忙');
+ }
+ }
+
+ public function add($param)
+ {
+ try {
+ if(!isset($param['brok_type']) || !in_array($param['brok_type'], [0,1,2])){
+ return $this->toData('1', '返佣类型无效');
+ }
+
+ if(!isset($param['pay_type']) || !in_array($param['pay_type'], [0,1])){
+ return $this->toData('1', '结算方式无效');
+ }
+
+
+ if(!isset($param['parent_fee']) || !is_numeric($param['parent_fee']) || $param['parent_fee'] < 0){
+ return $this->toData('1', '返佣比例无效1');
+ }
+
+ if(!isset($param['grandpa_fee']) || !is_numeric($param['grandpa_fee']) || $param['grandpa_fee'] < 0){
+ return $this->toData('1', '返佣比例无效2');
+ }
+
+ if(!isset($param['top_fee']) || !is_numeric($param['top_fee']) || $param['top_fee'] < 0){
+ return $this->toData('1', '返佣比例无效3');
+ }
+
+ if(isset($param['remark']) && (!is_string($param['remark']) || strlen($param['remark']) >= 15) ){
+ return $this->toData('1', '备注无效');
+ }
+
+ $remark = $param['remark']?? '';
+
+ $brok = new BrokerageSettingModel;
+ $brok->brok_type = $param['brok_type'];
+ $brok->pay_type = $param['pay_type'];
+ $brok->parent_fee = $param['parent_fee'];
+ $brok->grandpa_fee = $param['grandpa_fee'];
+ $brok->top_fee = $param['top_fee'];
+ $brok->remark = $remark;
+ $brok->save();
+
+ $fee_key=$this->getBrokerageKey($param['brok_type']);
+ $redis = $this->getRedis();
+ $redis->del($fee_key);
+ $redis->hMSet($fee_key, $param);
+
+
+ return $this->toData('0', 'SUCCESS');
+ }catch (\Exception $exception){
+ return $this->toData('1', '系统繁忙');
+ }
+
+ }
+
+ public function edit($param)
+ {
+ try {
+ if(empty($param['id']) || !is_numeric($param['id'])){
+ return $this->toData('1', '主键无效');
+ }
+
+ $brok = BrokerageSettingModel::where('id', $param['id'])->find();
+ if(empty($brok)){
+ return $this->toData('1', '主键无效');
+ }
+
+
+ if(!isset($param['brok_type']) || !in_array($param['brok_type'], [0,1,2])){
+ return $this->toData('1', '返佣类型无效');
+ }
+
+ if(!isset($param['pay_type']) || !in_array($param['pay_type'], [0,1])){
+ return $this->toData('1', '结算方式无效');
+ }
+
+ if(!isset($param['parent_fee']) || !is_numeric($param['parent_fee']) || $param['parent_fee'] < 0){
+ return $this->toData('1', '返佣比例无效');
+ }
+
+ if(!isset($param['grandpa_fee']) || !is_numeric($param['grandpa_fee']) || $param['grandpa_fee'] < 0){
+ return $this->toData('1', '返佣比例无效');
+ }
+
+ if(!isset($param['top_fee']) || !is_numeric($param['top_fee']) || $param['top_fee'] < 0){
+ return $this->toData('1', '返佣比例无效');
+ }
+
+ if(isset($param['remark']) && (!is_string($param['remark']) || strlen($param['remark']) >= 15) ){
+ return $this->toData('1', '备注无效');
+ }
+
+ $remark = $param['remark']?? '';
+
+
+ $brok->brok_type = $param['brok_type'];
+ $brok->pay_type = $param['pay_type'];
+ $brok->parent_fee = $param['parent_fee'];
+ $brok->grandpa_fee = $param['grandpa_fee'];
+ $brok->top_fee = $param['top_fee'];
+ $brok->remark = $remark;
+ $brok->save();
+
+ $fee_key=$this->getBrokerageKey($param['brok_type']);
+ $redis = $this->getRedis();
+ $redis->del($fee_key);
+ $redis->hMSet($fee_key, $param);
+
+ return $this->toData('0', 'SUCCESS');
+ }catch (\Exception $exception){
+ return $this->toData('1', '系统繁忙');
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/app/admin/service/setting/ContractService.php b/app/admin/service/setting/ContractService.php
new file mode 100644
index 0000000..88bd8d9
--- /dev/null
+++ b/app/admin/service/setting/ContractService.php
@@ -0,0 +1,348 @@
+select();
+ $rows = [];
+ if(!$list->isEmpty()){
+ $rows =$list->toArray();
+ }
+
+ return $this->toData('0', 'SUCCESS', ['list' => $rows, 'total' => count($rows)]);
+ }catch (\Exception $exception){
+ return $this->toData('1', '系统繁忙', []);
+ }
+ }
+
+ // 新增
+ public function add($param)
+ {
+ try {
+ // 交易对名称
+ if(empty($param['trade_name']) || !is_string($param['trade_name']) || strlen($param['trade_name']) > 100){
+ return $this->toData('1', '交易对名称无效', []);
+ }
+
+ // 状态
+ if(!isset($param['status']) || !in_array($param['status'], ['0', '1'])){
+ return $this->toData('1', '状态无效', []);
+ }
+
+ // 是否自发
+ if(!isset($param['is_owner']) || !in_array($param['is_owner'], ['0', '1'])){
+ return $this->toData('1', '是否自发无效', []);
+ }
+
+ // 简介
+ $info = '';
+ if(isset($param['info']) && is_string($param['info'])){
+ $info = $param['info'];
+ }
+
+ // 面值
+ if(!isset($param['face_value']) || !is_numeric($param['face_value']) || $param['face_value'] != ceil($param['face_value']) || $param['face_value'] <= 0){
+ return $this->toData('1', '面值无效', []);
+ }
+
+
+ // 排序
+ if(!isset($param['sort']) || !is_numeric($param['sort']) || $param['sort'] != ceil($param['sort']) || $param['sort'] < 0){
+ return $this->toData('1', '排序值无效', []);
+ }
+
+ // 最小杠杆
+ if(empty($param['min_pry']) || !is_numeric($param['min_pry']) || $param['min_pry'] != ceil($param['min_pry']) || $param['min_pry'] <= 0){
+ return $this->toData('1', '最小杠杆值无效', []);
+ }
+
+ // 最大杠杆
+ if(empty($param['max_pry']) || !is_numeric($param['max_pry']) || $param['max_pry'] != ceil($param['max_pry']) || $param['max_pry'] <= 0){
+ return $this->toData('1', '最大杠杆值无效', []);
+ }
+
+ // 强制平仓比例值
+ if(empty($param['compel_num']) || !is_numeric($param['compel_num']) || $param['compel_num'] <= 0){
+ return $this->toData('1', '强制平仓比例值无效', []);
+ }
+
+
+ // 小数位数
+ if(!isset($param['keep_decimal']) || !is_numeric($param['keep_decimal']) || $param['keep_decimal'] != ceil($param['keep_decimal']) || $param['keep_decimal'] < 0){
+ return $this->toData('1', '小数位数值无效', []);
+ }
+
+ // 判断名称是否已被添加
+ $count = ContractListMode::where('trade_name', $param['trade_name'])->count();
+ if($count > 0){
+ return $this->toData('1', '合约交易对名称已存在', []);
+ }
+
+ $contract = new ContractListMode;
+ $contract->trade_name = $param['trade_name'];
+ $contract->status = $param['status'];
+ $contract->is_owner = $param['is_owner'];
+ $contract->info = $info;
+ $contract->logo_link = '';
+ $contract->face_value = $param['face_value'];
+ $contract->sort = $param['sort'];
+ $contract->min_pry = $param['min_pry'];
+ $contract->max_pry = $param['max_pry'];
+ $contract->compel_num = $param['compel_num'];
+ $contract->keep_decimal = $param['keep_decimal'];
+ $contract->create_time = date('Y-m-d H:i:s');
+ $contract->update_time = date('Y-m-d H:i:s');
+ $contract->save();
+
+ $list_key="CONTRACT:LIST:".strtoupper($param['trade_name']);
+ $redis = $this->getRedis();
+ $redis->del($list_key);
+ $redis->hMset($list_key, [
+ 'name'=>strtoupper($param['trade_name']),
+ 'code'=>strtoupper($param['trade_name']),
+ 'sort'=>$param['sort'],
+ 'face_value'=>$param['face_value'],
+ 'min_pry'=>$param['min_pry'],
+ 'max_pry'=>$param['max_pry'],
+ 'compel_num'=>$param['compel_num'],
+ 'keep_decimal'=>$param['keep_decimal'],
+ 'is_owner'=>$param['is_owner'],
+ 'status'=>$param['status']
+ ]);
+
+ return $this->toData('0', '操作成功', []);
+ }catch (\Exception $exception){
+ return $this->toData('1', '系统繁忙', [$exception->getMessage()]);
+ }
+ }
+
+ public function edit($param)
+ {
+ try {
+ if(empty($param['id']) || !is_numeric($param['id'])){
+ return $this->toData('1', '目标不存在', []);
+ }
+
+ $contract = ContractListMode::where('id', $param['id'])->find();
+ $beforeStatus = $contract['status'];
+ if(empty($contract)){
+ return $this->toData('1', '目标不存在', []);
+ }
+
+ // 交易对名称
+ if(empty($param['trade_name']) || !is_string($param['trade_name']) || strlen($param['trade_name']) > 100){
+ return $this->toData('1', '交易对名称无效', []);
+ }
+
+ // 状态
+ if(!isset($param['status']) || !in_array($param['status'], ['0', '1'])){
+ return $this->toData('1', '状态无效', []);
+ }
+
+ // 是否自发
+ if(!isset($param['is_owner']) || !in_array($param['is_owner'], ['0', '1'])){
+ return $this->toData('1', '是否自发无效', []);
+ }
+
+ // 简介
+ $info = '';
+ if(isset($param['info']) && is_string($param['info'])){
+ $info = $param['info'];
+ }
+
+ // 面值
+ if(!isset($param['face_value']) || !is_numeric($param['face_value']) || $param['face_value'] != ceil($param['face_value']) || $param['face_value'] <= 0){
+ return $this->toData('1', '面值无效', []);
+ }
+
+
+ // 排序
+ if(!isset($param['sort']) || !is_numeric($param['sort']) || $param['sort'] != ceil($param['sort']) || $param['sort'] < 0){
+ return $this->toData('1', '排序值无效', []);
+ }
+
+ // 最小杠杆
+ if(empty($param['min_pry']) || !is_numeric($param['min_pry']) || $param['min_pry'] != ceil($param['min_pry']) || $param['min_pry'] <= 0){
+ return $this->toData('1', '最小杠杆值无效', []);
+ }
+
+ // 最大杠杆
+ if(empty($param['max_pry']) || !is_numeric($param['max_pry']) || $param['max_pry'] != ceil($param['max_pry']) || $param['max_pry'] <= 0){
+ return $this->toData('1', '最大杠杆值无效', []);
+ }
+
+ // 强制平仓比例值
+ if(empty($param['compel_num']) || !is_numeric($param['compel_num']) || $param['compel_num'] <= 0){
+ return $this->toData('1', '强制平仓比例值无效', []);
+ }
+
+ // 小数位数
+ if(!isset($param['keep_decimal']) || !is_numeric($param['keep_decimal']) || $param['keep_decimal'] != ceil($param['keep_decimal']) || $param['keep_decimal'] < 0){
+ return $this->toData('1', '小数位数值无效', []);
+ }
+
+ // 判断名称是否已被添加
+ $count = ContractListMode::where('trade_name', $param['trade_name'])->where('id', '<>', $param['id'])->count();
+ if($count > 0){
+ return $this->toData('1', '合约交易对名称已存在', []);
+ }
+
+ // 如果状态设置成关闭 则判断是否有正在交易的合约
+ if($beforeStatus == 1 && $param['status'] == 0){
+ $num=(new ContractTradeModel())->where([
+ 'contract_id'=>strtoupper($contract['trade_name']),
+ 'status'=>1
+ ])->count();
+ if ($num != 0) {
+ return $this->toData('1', '交易对还存在交易,不能关闭', []);
+ }
+ }
+
+ // 写入数据
+ $contract->trade_name = $param['trade_name'];
+ $contract->status = $param['status'];
+ $contract->is_owner = $param['is_owner'];
+ $contract->info = $info;
+ $contract->logo_link = '';
+ $contract->face_value = $param['face_value'];
+ $contract->sort = $param['sort'];
+ $contract->min_pry = $param['min_pry'];
+ $contract->max_pry = $param['max_pry'];
+ $contract->compel_num = $param['compel_num'];
+ $contract->keep_decimal = $param['keep_decimal'];
+ $contract->create_time = date('Y-m-d H:i:s');
+ $contract->update_time = date('Y-m-d H:i:s');
+ $contract->save();
+
+
+ $list_key="CONTRACT:LIST:".strtoupper($param['trade_name']);
+ $redis = $this->getRedis();
+ $redis->del($list_key);
+ $redis->hMset($list_key, [
+ 'name'=>strtoupper($param['trade_name']),
+ 'code'=>strtoupper($param['trade_name']),
+ 'sort'=>$param['sort'],
+ 'face_value'=>$param['face_value'],
+ 'min_pry'=>$param['min_pry'],
+ 'max_pry'=>$param['max_pry'],
+ 'compel_num'=>$param['compel_num'],
+ 'keep_decimal'=>$param['keep_decimal'],
+ 'status'=>$param['status']
+ ]);
+ return $this->toData('0', 'SUCCESS', []);
+ }catch (\Exception $exception){
+ return $this->toData('1', '系统繁忙', []);
+ }
+ }
+
+ // 获取合约交易对
+ public function getTradeNameList($param)
+ {
+ try {
+ if(isset($param['is_owner']) && in_array($param['is_owner'], [0,1])){
+ $list = ContractListMode::where('status', 1)->order('id', 'desc')
+ ->where('is_owner', $param['is_owner'])
+ ->column('trade_name', 'id');
+ } else {
+ $list = ContractListMode::where('status', 1)->order('id', 'desc')
+ ->column('trade_name', 'id');
+ }
+
+ return $this->toData('0', 'SUCCESS', ['list' => $list]);
+ }catch (\Exception $exception){
+ return $this->toData('1', '系统繁忙', []);
+ }
+ }
+ public function setting($param)
+ {
+ try {
+ $list = ContractSettingModel::order('time_step', 'asc')->select();
+ $rows = [];
+ if(!$list->isEmpty()){
+ $rows =$list->toArray();
+ }
+ return $this->toData('0', 'SUCCESS', ['list' => $rows, 'total' => count($rows)]);
+ }catch (\Exception $exception){
+ return $this->toData('1', '系统繁忙', []);
+ }
+ }
+ public function set_add($param)
+ {
+ // 状态
+ if(!isset($param['time_step'])){
+ return $this->toData('1', '时间无效', []);
+ }
+ // 是否自发
+ if(!isset($param['earnings_num'])){
+ return $this->toData('1', '收益无效', []);
+ }
+ $contract = ContractSettingModel::where('time_step', $param['time_step'])->find();
+ if(!empty($contract)){
+ return $this->toData('1', '时间已存在', []);
+ }
+ $contract = new ContractSettingModel;
+ // 写入数据
+ $contract->time_step = $param['time_step'];
+ $contract->earnings_num = $param['earnings_num'];
+ $contract->create_time = date('Y-m-d H:i:s');
+ $contract->update_time = date('Y-m-d H:i:s');
+ $contract->save();
+ $this->initContractSetting();
+ return $this->toData('0', 'SUCCESS', []);
+ }
+ public function set_edit($param)
+ {
+ // 状态
+ if(!isset($param['time_step'])){
+ return $this->toData('1', '时间无效', []);
+ }
+ // 是否自发
+ if(!isset($param['earnings_num'])){
+ return $this->toData('1', '收益无效', []);
+ }
+ // 是否自发
+ if(!isset($param['id'])){
+ return $this->toData('1', 'ID无效', []);
+ }
+ $contract = ContractSettingModel::where('id', $param['id'])->find();
+ if(empty($contract)){
+ return $this->toData('1', '目标不存在', []);
+ }
+
+ // 写入数据
+ $contract->time_step = $param['time_step'];
+ $contract->earnings_num = $param['earnings_num'];
+ $contract->create_time = date('Y-m-d H:i:s');
+ $contract->update_time = date('Y-m-d H:i:s');
+ $contract->save();
+
+ $this->initContractSetting();
+ return $this->toData('0', 'SUCCESS', []);
+ }
+ public function set_del($param)
+ {
+ if(!isset($param['id'])){
+ return $this->toData('1', 'ID无效', []);
+ }
+ $contract = ContractSettingModel::where('id', $param['id'])->find();
+ if(empty($contract)){
+ return $this->toData('1', '目标不存在', []);
+ }
+ $contract->where('id',$param['id'])->delete();
+ $this->initContractSetting();
+ return $this->toData('0', 'SUCCESS', []);
+
+ }
+}
\ No newline at end of file
diff --git a/app/admin/service/setting/DMarketService.php b/app/admin/service/setting/DMarketService.php
new file mode 100644
index 0000000..77e5833
--- /dev/null
+++ b/app/admin/service/setting/DMarketService.php
@@ -0,0 +1,161 @@
+order('id', 'desc')
+ ->select();
+ $rows = [];
+ if(!$list->isEmpty()){
+ foreach ($list as $item){
+ if(empty($rows[$item['trade_name']])){
+ $rows[$item['trade_name']] = [
+ 'trade_name' => $item['trade_name'],
+ 'begin_time' => $item['begin_time'],
+ 'end_time' => $item['end_time'],
+ 'max_price' => $item['max_price'],
+ 'step' => $item['step'],
+ ];
+ }
+ }
+ }
+
+ $rows = array_values($rows);
+ return $this->toData('0','SUCCSS',['list' => $rows, 'total' => count($rows)]);
+ }catch (\Exception $exception){
+ return $this->toData('1', '系统繁忙', []);
+ }
+ }
+
+ // 详情
+ public function detail($param)
+ {
+ try {
+ if(empty($param['trade_name']) || !is_string($param['trade_name'])){
+ return $this->toData('1', '参数错误');
+ }
+ $list = ContractMarketModel::where('type', ContractMarketModel::TYPE_DIGITAL_SELF)
+ ->where('trade_name', $param['trade_name'])
+ ->order('id', 'desc')->select();
+ $rows = [];
+ if(!$list->isEmpty()){
+ foreach ($list as $item){
+ $rows[] = [
+ 'id' => $item['id'],
+ 'trade_name' => $item['trade_name'],
+ 'begin_time' => $item['begin_time'],
+ 'end_time' => $item['end_time'],
+ 'max_price' => $item['max_price'],
+ 'step' => $item['step'],
+ ];
+ }
+ }
+ return $this->toData('0','SUCCESS',['list' => $rows]);
+ }catch (\Exception $exception){
+ return $this->toData('1', '系统繁忙', [$exception->getMessage()]);
+ }
+ }
+
+ // 新增
+ public function add($param)
+ {
+ try {
+ // 参数校验
+ validate(MarketValidate::class)->scene('add')->check($param);
+
+ // 必须大于当前时间
+ if(strtotime($param['end_time']) - time() <= 0){
+ return $this->toData('1','结束时间无效1');
+ }
+
+ if((strtotime($param['begin_time']) - time()) <= 0 || (strtotime($param['end_time']) - strtotime($param['begin_time'])) <= 0){
+ return $this->toData('1','开始时间无效2');
+ }
+
+
+ $market = new ContractMarketModel;
+ $market->trade_name = $param['trade_name'];
+ $market->begin_time = $param['begin_time'];
+ $market->end_time = $param['end_time'];
+ $market->max_price = $param['max_price'];
+ $market->type = ContractMarketModel::TYPE_DIGITAL_SELF;
+ $market->save();
+
+ return $this->toData('0','SUCCESS');
+ }catch (ValidateException $validateException){
+ return $this->toData('1', $validateException->getMessage(), []);
+ }catch (\Exception $exception){
+ return $this->toData('1', '系统繁忙', [$exception->getMessage()]);
+ }
+ }
+
+
+ // 编辑
+ public function edit($param)
+ {
+ try {
+ // 参数校验
+ validate(MarketValidate::class)->scene('edit')->check($param);
+
+ // 目标
+ $market = ContractMarketModel::where('id', $param['id'])->where('type', ContractMarketModel::TYPE_DIGITAL_SELF)->find();
+ if(empty($market)){
+ return $this->toData('1','目标不存在');
+ }
+
+
+ // 必须大于当前时间
+ if(strtotime($param['end_time']) - time() <= 0){
+ return $this->toData('1','时间无效');
+ }
+
+ if((strtotime($param['begin_time']) - time()) <= 0 || (strtotime($param['end_time']) - strtotime($param['begin_time'])) <= 0){
+ return $this->toData('1','开始时间无效');
+ }
+
+ $market->trade_name = $param['trade_name'];
+ $market->begin_time = $param['begin_time'];
+ $market->end_time = $param['end_time'];
+ $market->max_price = $param['max_price'];
+ $market->save();
+
+ return $this->toData('0','SUCCESS');
+ }catch (ValidateException $validateException){
+ return $this->toData('1', $validateException->getMessage(), []);
+ }catch (\Exception $exception){
+ return $this->toData('1', '系统繁忙', []);
+ }
+ }
+
+ // 删除
+ public function del($param)
+ {
+ try {
+ // 参数校验
+ validate(MarketValidate::class)->scene('del')->check($param);
+
+ // 目标
+ $market = ContractMarketModel::where('id', $param['id'])->where('type',ContractMarketModel::TYPE_DIGITAL_SELF)->find();
+ if(empty($market)){
+ return $this->toData('1','目标不存在');
+ }
+
+ $market->delete();
+ return $this->toData('0','SUCCESS');
+ }catch (ValidateException $validateException){
+ return $this->toData('1', $validateException->getMessage(), []);
+ }catch (\Exception $exception){
+ return $this->toData('1', '系统繁忙', []);
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/admin/service/setting/DigitalService.php b/app/admin/service/setting/DigitalService.php
new file mode 100644
index 0000000..3e66fc2
--- /dev/null
+++ b/app/admin/service/setting/DigitalService.php
@@ -0,0 +1,203 @@
+select();
+ $rows = [];
+ if(!$list->isEmpty()){
+ $rows = $list->toArray();
+ }
+ return $this->toData('0', 'SUCCESS', ['list' => $rows, 'total' => count($rows)]);
+ }catch (\Exception $exception){
+ return $this->toData('1', '系统繁忙', []);
+ }
+ }
+
+ public function add($param)
+ {
+ try {
+ if(empty($param['trade_name']) || !is_string($param['trade_name'])){
+ return $this->toData('1', '数字货币名称无效');
+ }
+
+
+ if(empty($param['exchange_name']) || !is_string($param['exchange_name'])){
+ return $this->toData('1', '数字币兑换对名称无效');
+ }
+
+ // 简介
+ if(!empty($param['info']) && !is_string($param['info'])){
+ return $this->toData('1', '简介无效');
+ }
+ $info = $param['info']?? '';
+
+ // 状态
+ if(!isset($param['status']) || !in_array($param['status'], [0,1])){
+ return $this->toData('1', '启用状态无效');
+ }
+
+ // 排序
+ if(!isset($param['sort']) || !is_numeric($param['sort']) || ceil($param['sort']) != $param['sort']){
+ return $this->toData('1', '排序无效');
+ }
+
+ // 图片链接
+ if(empty($param['logo_link']) || !is_string($param['logo_link'])){
+ return $this->toData('1', 'logo链接无效');
+ }
+
+ // 小数位数
+ if(!isset($param['keep_decimal']) || !is_numeric($param['keep_decimal']) || $param['keep_decimal'] < 0 || ceil($param['keep_decimal']) != $param['keep_decimal']){
+ return $this->toData('1', '保留小数位无效');
+ }
+
+ // 判断股票代码是否已经存在
+ $count = DigitalListModel::where('trade_name', $param['trade_name'])->where('exchange_name', $param['exchange_name'])->count();
+ if($count > 0){
+ return $this->toData('1', '现货数字币交易对已经存在');
+ }
+
+ $digitalList = new DigitalListModel;
+ $digitalList->trade_name = $param['trade_name'];
+ $digitalList->exchange_name = $param['exchange_name'];
+ $digitalList->status = $param['status'];
+ $digitalList->logo_link = $param['logo_link'];
+ $digitalList->sort = $param['sort'];
+ $digitalList->keep_decimal = $param['keep_decimal'];
+
+ $digitalList->info = $info;
+ $digitalList->create_time = date('Y-m-d H:i:s');
+ $digitalList->update_time = date('Y-m-d H:i:s');
+ $digitalList->save();
+
+ // 设置缓存
+ $fee_key="DIGITAL:LIST:".strtoupper($param['trade_name']);
+ $redis = $this->getRedis();
+ $redis->del($fee_key);
+ $redis->hMSet($fee_key,[
+ 'name'=>strtoupper($param['trade_name']),
+ 'sort'=>$param['sort'],
+ 'exchange_name'=>$param['exchange_name'],
+ 'logo_link'=>$param['logo_link'],
+ 'keep_decimal'=>$param['keep_decimal'],
+ 'status'=>$param['status'],
+ ]);
+
+ return $this->toData('0', '操作成功', []);
+ }catch (\Exception $exception){
+ return $this->toData('1', '系统繁忙', []);
+ }
+ }
+
+ public function edit($param)
+ {
+
+ try {
+ if(empty($param['id']) || !is_numeric($param['id'])){
+ return $this->toData('1', '目标不存在', []);
+ }
+
+ $digitalList = DigitalListModel::where('id', $param['id'])->find();
+ if(empty($digitalList)){
+ return $this->toData('1', '目标不存在', []);
+ }
+
+ if(empty($param['trade_name']) || !is_string($param['trade_name'])){
+ return $this->toData('1', '数字货币名称无效');
+ }
+
+
+ if(empty($param['exchange_name']) || !is_string($param['exchange_name'])){
+ return $this->toData('1', '数字币兑换对名称无效');
+ }
+
+ // 简介
+ if(!empty($param['info']) && !is_string($param['info'])){
+ return $this->toData('1', '简介无效');
+ }
+ $info = $param['info']?? '';
+
+ // 状态
+ if(!isset($param['status']) || !in_array($param['status'], [0,1])){
+ return $this->toData('1', '启用状态无效');
+ }
+
+ // 排序
+ if(!isset($param['sort']) || !is_numeric($param['sort']) || ceil($param['sort']) != $param['sort']){
+ return $this->toData('1', '排序无效');
+ }
+
+ // 图片链接
+ if(empty($param['logo_link']) || !is_string($param['logo_link'])){
+ return $this->toData('1', 'logo链接无效');
+ }
+
+ // 小数位数
+ if(!isset($param['keep_decimal']) || !is_numeric($param['keep_decimal']) || $param['keep_decimal'] < 0 || ceil($param['keep_decimal']) != $param['keep_decimal']){
+ return $this->toData('1', '保留小数位无效');
+ }
+
+ // 判断股票代码是否已经存在
+ $count = DigitalListModel::where('trade_name', $param['trade_name'])->where('exchange_name', $param['exchange_name'])
+ ->where('id','<>', $param['id'])
+ ->count();
+ if($count > 0){
+ return $this->toData('1', '现货数字币交易对已经存在');
+ }
+
+ $digitalList->trade_name = $param['trade_name'];
+ $digitalList->exchange_name = $param['exchange_name'];
+ $digitalList->status = $param['status'];
+ $digitalList->logo_link = $param['logo_link'];
+ $digitalList->sort = $param['sort'];
+ $digitalList->keep_decimal = $param['keep_decimal'];
+
+ $digitalList->info = $info;
+ $digitalList->update_time = date('Y-m-d H:i:s');
+ $digitalList->save();
+
+ // 设置缓存
+ $fee_key="DIGITAL:LIST:".strtoupper($param['trade_name']);
+ $redis = $this->getRedis();
+ $redis->del($fee_key);
+ $redis->hMSet($fee_key,[
+ 'name'=>strtoupper($param['trade_name']),
+ 'sort'=>$param['sort'],
+ 'logo_link'=>$param['logo_link'],
+ 'keep_decimal'=>$param['keep_decimal'],
+ 'status'=>$param['status'],
+ ]);
+
+ return $this->toData('0', '操作成功', []);
+ }catch (\Exception $exception){
+ return $this->toData('1', '系统繁忙', []);
+ }
+ }
+
+ public function getTradeNameList($param)
+ {
+ try {
+ if(isset($param['is_owner']) && in_array($param['is_owner'], [0,1])){
+ $list = DigitalListModel::where('status', 1)->order('id', 'desc')
+ ->where('is_owner', $param['is_owner'])
+ ->column('trade_name', 'id');
+ } else {
+ $list = DigitalListModel::where('status', 1)->order('id', 'desc')->column('trade_name', 'id');
+ }
+
+ return $this->toData('0', 'SUCCESS', ['list' => $list]);
+ }catch (\Exception $exception){
+ return $this->toData('1', '系统繁忙', []);
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/admin/service/setting/DrawalService.php b/app/admin/service/setting/DrawalService.php
new file mode 100644
index 0000000..3a7e5c6
--- /dev/null
+++ b/app/admin/service/setting/DrawalService.php
@@ -0,0 +1,68 @@
+isEmpty()){
+ $rows = $list->toArray();
+ }
+ return $this->toData('0', 'SUCCESS', ['list' => $rows, 'total' => count($rows)]);
+ }catch (\Exception $exception){
+ return $this->toData('1', '系统繁忙', []);
+ }
+ }
+
+
+ public function edit($param)
+ {
+ try {
+ if(empty($param['id']) || !is_numeric($param['id'])){
+ return $this->toData('1', '目标不存在', []);
+ }
+
+ if(empty($param['bank_drawal_fee']) || !is_numeric($param['bank_drawal_fee']) || $param['bank_drawal_fee'] < 0){
+ return $this->toData('1', '银行提现手续费无效', []);
+ }
+ if(empty($param['digital_drawal_fee']) || !is_numeric($param['digital_drawal_fee']) || $param['digital_drawal_fee'] < 0){
+ return $this->toData('1', '数字币提现手续费无效', []);
+ }
+ if(empty($param['min_recharge']) || !is_numeric($param['min_recharge']) || $param['min_recharge'] < 0){
+ return $this->toData('1', '最小充值金额无效', []);
+ }
+ if(empty($param['min_drawal']) || !is_numeric($param['min_drawal']) || $param['min_drawal'] < 0){
+ return $this->toData('1', '最小提现金额无效', []);
+ }
+
+ $drawal = DrawalSettingModel::where('id', $param['id'])->find();
+ if(empty($drawal)){
+ return $this->toData('1', '目标不存在', []);
+ }
+ $drawal->bank_drawal_fee = $param['bank_drawal_fee'];
+ $drawal->digital_drawal_fee = $param['digital_drawal_fee'];
+ $drawal->min_recharge = $param['min_recharge'];
+ $drawal->min_drawal = $param['min_drawal'];
+ $drawal->save();
+
+ $fee_key="DRAWAL:FEE:SETTING";
+ $redis = $this->getRedis();
+ $redis->del($fee_key);
+ $redis->hMSet($fee_key,$param);
+
+ return $this->toData('0','SUCCESS');
+ }catch (\Exception $exception){
+ return $this->toData('1', '系统繁忙', []);
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/admin/service/setting/FeeService.php b/app/admin/service/setting/FeeService.php
new file mode 100644
index 0000000..2b31f87
--- /dev/null
+++ b/app/admin/service/setting/FeeService.php
@@ -0,0 +1,202 @@
+select();
+ $rows = [];
+ if (!$list->isEmpty()) {
+ $rows = $list->toArray();
+ }
+ return $this->toData('0', 'SUCCESS', ['list' => $rows, 'total' => count($rows), 'extent' => [
+ 'market_type_list' => StockMarketModel::STOCK_MARKET_TYPE, 'pay_type' => FeeSettingModel::$payTypeList
+ ]]);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统繁忙', []);
+ }
+ }
+
+ public function add($param)
+ {
+ try {
+ $marketTypeIds = array_keys(StockMarketModel::STOCK_MARKET_TYPE);
+ if (empty($param['market_type']) || !in_array($param['market_type'], $marketTypeIds)) {
+ return $this->toData('1', '市场类型无效', []);
+ }
+
+ if (!is_numeric($param['buy_fee']) || $param['buy_fee'] < 0) {
+ return $this->toData('1', '买入手续费无效', []);
+ }
+
+// if(empty($param['purchase_fee']) || !is_numeric($param['purchase_fee']) || $param['purchase_fee'] < 0){
+// return $this->toData('1', '盘前申购手续费无效', []);
+// }
+
+ if (!is_numeric($param['sale_fee']) || $param['sale_fee'] < 0) {
+ return $this->toData('1', '卖出手续费无效', []);
+ }
+
+ if (in_array($param['market_type'], [3, 4, 5, 6, 7, 9, 12,14])) {
+ if (empty($param['purchase_fee']) || !is_numeric($param['purchase_fee']) || $param['purchase_fee'] < 0) {
+ return $this->toData('1', '申购手续费无效', []);
+ }
+ }
+
+
+ // 结算方式:0固定费用,1按比例结算
+ if (!isset($param['pay_type']) || !in_array($param['pay_type'], array_keys(FeeSettingModel::$payTypeList))) {
+ return $this->toData('1', '结算方式无效', []);
+ }
+
+ // 买入最小下单金额
+ if (empty($param['min_buy_num']) || !is_numeric($param['min_buy_num']) || ceil($param['min_buy_num']) != $param['min_buy_num']) {
+ return $this->toData('1', '买入最小下单金额无效', []);
+ }
+
+ //卖出最小下单金额
+ if (empty($param['min_sale_num']) || !is_numeric($param['min_sale_num']) || ceil($param['min_sale_num']) != $param['min_sale_num']) {
+ return $this->toData('1', '卖出最小下单金额无效', []);
+ }
+
+ // max_entrust_num
+ if (empty($param['max_entrust_num']) || !is_numeric($param['max_entrust_num']) || ceil($param['max_entrust_num']) != $param['max_entrust_num']) {
+ return $this->toData('1', '最大挂单数量无效', []);
+ }
+
+ // 最大持仓数量
+ if (empty($param['max_hold_num']) || !is_numeric($param['max_hold_num']) || ceil($param['max_hold_num']) != $param['max_hold_num']) {
+ return $this->toData('1', '最大持仓数量无效', []);
+ }
+
+ $count = FeeSettingModel::where('market_type', $param['market_type'])->count();
+ if ($count > 0) {
+ return $this->toData('1', '市场类型已经存在', []);
+ }
+ $feeSetting = new FeeSettingModel;
+ $feeSetting->market_type = $param['market_type'];
+ $feeSetting->buy_fee = $param['buy_fee'];
+ $feeSetting->sale_fee = $param['sale_fee'];
+ $feeSetting->pay_type = $param['pay_type'];
+ $feeSetting->purchase_fee = isset($param['purchase_fee']) ? $param['purchase_fee'] : 0;
+ $feeSetting->min_buy_num = $param['min_buy_num'];
+ $feeSetting->min_sale_num = $param['min_sale_num'];
+ $feeSetting->max_entrust_num = $param['max_entrust_num'];
+ $feeSetting->max_hold_num = $param['max_hold_num'];
+ $feeSetting->min_withdrawal_num = empty($param['min_withdrawal_num']) ? 0 :$param['min_withdrawal_num'];
+ $feeSetting->min_recharge_num = empty($param['min_recharge_num']) ? 0 :$param['min_recharge_num'];
+
+ $feeSetting->save();
+
+ // 设置缓存
+ $fee_key = $this->getTradeFeeKey($param['market_type']);
+ $redis = $this->getRedis();
+ $redis->del($fee_key);
+ $redis->hMSet($fee_key, $param);
+
+ return $this->toData('0', 'SUCCESS', []);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统繁忙', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+
+ public function edit($param)
+ {
+ try {
+ if (empty($param['id']) || !is_numeric($param['id'])) {
+ return $this->toData('1', '目标不存在', []);
+ }
+ $feeSetting = FeeSettingModel::where('id', $param['id'])->find();
+
+ if (empty($feeSetting)) {
+ return $this->toData('1', '目标不存在', []);
+ }
+
+ $marketTypeIds = array_keys(StockMarketModel::STOCK_MARKET_TYPE);
+ if (empty($param['market_type']) || !in_array($param['market_type'], $marketTypeIds)) {
+ return $this->toData('1', '市场类型无效', []);
+ }
+
+ if (!is_numeric($param['buy_fee']) || $param['buy_fee'] < 0) {
+ return $this->toData('1', '买入手续费无效', []);
+ }
+
+ if (in_array($param['market_type'], [3, 4, 5, 6, 7, 9, 12, 14])) {
+ if (empty($param['purchase_fee']) || !is_numeric($param['purchase_fee']) || $param['purchase_fee'] < 0) {
+ return $this->toData('1', '申购手续费无效', []);
+ }
+ }
+
+ if (!is_numeric($param['sale_fee']) || $param['sale_fee'] < 0) {
+ return $this->toData('1', '卖出手续费无效', []);
+ }
+
+// if(empty($param['purchase_fee']) || !is_numeric($param['purchase_fee']) || $param['purchase_fee'] < 0){
+// return $this->toData('1', '申购手续费无效', []);
+// }
+
+ // 结算方式:0固定费用,1按比例结算
+ if (!isset($param['pay_type']) || !in_array($param['pay_type'], array_keys(FeeSettingModel::$payTypeList))) {
+ return $this->toData('1', '结算方式无效', []);
+ }
+
+ // 买入最小下单金额
+ if (empty($param['min_buy_num']) || !is_numeric($param['min_buy_num']) || ceil($param['min_buy_num']) != $param['min_buy_num']) {
+ return $this->toData('1', '买入最小下单金额无效', []);
+ }
+
+ //卖出最小下单金额
+ if (empty($param['min_sale_num']) || !is_numeric($param['min_sale_num']) || ceil($param['min_sale_num']) != $param['min_sale_num']) {
+ return $this->toData('1', '卖出最小下单金额无效', []);
+ }
+
+ // max_entrust_num
+ if (empty($param['max_entrust_num']) || !is_numeric($param['max_entrust_num']) || ceil($param['max_entrust_num']) != $param['max_entrust_num']) {
+ return $this->toData('1', '最大挂单数量无效', []);
+ }
+
+ // 最大持仓数量
+ if (empty($param['max_hold_num']) || !is_numeric($param['max_hold_num']) || ceil($param['max_hold_num']) != $param['max_hold_num']) {
+ return $this->toData('1', '最大持仓数量无效', []);
+ }
+
+ $count = FeeSettingModel::where('market_type', $param['market_type'])->where('id', '<>', $feeSetting->id)->count();
+ if ($count > 0) {
+ return $this->toData('1', '市场类型已经存在', []);
+ }
+
+ $feeSetting->market_type = $param['market_type'];
+ $feeSetting->buy_fee = $param['buy_fee'];
+ $feeSetting->sale_fee = $param['sale_fee'];
+ $feeSetting->pay_type = $param['pay_type'];
+ $feeSetting->min_buy_num = $param['min_buy_num'];
+ $feeSetting->purchase_fee = $param['purchase_fee'];
+ $feeSetting->min_sale_num = $param['min_sale_num'];
+ $feeSetting->max_entrust_num = $param['max_entrust_num'];
+ $feeSetting->max_hold_num = $param['max_hold_num'];
+
+ $feeSetting->min_withdrawal_num = empty($param['min_withdrawal_num']) ? 0 :$param['min_withdrawal_num'];
+ $feeSetting->min_recharge_num = empty($param['min_recharge_num']) ? 0 :$param['min_recharge_num'];
+
+ $feeSetting->save();
+
+ // 设置缓存
+ $fee_key = $this->getTradeFeeKey($param['market_type']);
+ $redis = $this->getRedis();
+ $redis->del($fee_key);
+ $redis->hMSet($fee_key, $param);
+
+ return $this->toData('0', 'SUCCESS', []);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统繁忙', []);
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/admin/service/setting/ForexService.php b/app/admin/service/setting/ForexService.php
new file mode 100644
index 0000000..1dfc4b4
--- /dev/null
+++ b/app/admin/service/setting/ForexService.php
@@ -0,0 +1,270 @@
+select();
+ $rows = [];
+ if(!$list->isEmpty()){
+ $rows =$list->toArray();
+ }
+
+ return $this->toData('0', 'SUCCESS', ['list' => $rows, 'total' => count($rows)]);
+ }catch (\Exception $exception){
+ return $this->toData('1', '系统繁忙', []);
+ }
+ }
+
+ // 新增
+ public function add($param)
+ {
+ try {
+ // 交易对名称
+ if(empty($param['trade_name']) || !is_string($param['trade_name']) || strlen($param['trade_name']) > 100){
+ return $this->toData('1', '交易对名称无效', []);
+ }
+
+ // 状态
+ if(!isset($param['status']) || !in_array($param['status'], ['0', '1'])){
+ return $this->toData('1', '状态无效', []);
+ }
+
+ // 是否自发
+ if(!isset($param['is_owner']) || !in_array($param['is_owner'], ['0', '1'])){
+ return $this->toData('1', '是否自发无效', []);
+ }
+
+ // 简介
+ $info = '';
+ if(isset($param['info']) && is_string($param['info'])){
+ $info = $param['info'];
+ }
+
+ // 面值
+ if(!isset($param['face_value']) || !is_numeric($param['face_value']) || $param['face_value'] != ceil($param['face_value']) || $param['face_value'] <= 0){
+ return $this->toData('1', '面值无效', []);
+ }
+
+
+ // 排序
+ if(!isset($param['sort']) || !is_numeric($param['sort']) || $param['sort'] != ceil($param['sort']) || $param['sort'] < 0){
+ return $this->toData('1', '排序值无效', []);
+ }
+
+ // 最小杠杆
+ if(empty($param['min_pry']) || !is_numeric($param['min_pry']) || $param['min_pry'] != ceil($param['min_pry']) || $param['min_pry'] <= 0){
+ return $this->toData('1', '最小杠杆值无效', []);
+ }
+
+ // 最大杠杆
+ if(empty($param['max_pry']) || !is_numeric($param['max_pry']) || $param['max_pry'] != ceil($param['max_pry']) || $param['max_pry'] <= 0){
+ return $this->toData('1', '最大杠杆值无效', []);
+ }
+
+ // 强制平仓比例值
+ if(empty($param['compel_num']) || !is_numeric($param['compel_num']) || $param['compel_num'] <= 0){
+ return $this->toData('1', '强制平仓比例值无效', []);
+ }
+
+
+ // 小数位数
+ if(!isset($param['keep_decimal']) || !is_numeric($param['keep_decimal']) || $param['keep_decimal'] != ceil($param['keep_decimal']) || $param['keep_decimal'] < 0){
+ return $this->toData('1', '小数位数值无效', []);
+ }
+
+ // 判断名称是否已被添加
+ $count = ForexListModel::where('trade_name', $param['trade_name'])->count();
+ if($count > 0){
+ return $this->toData('1', '合约交易对名称已存在', []);
+ }
+
+ $contract = new ForexListModel;
+ $contract->trade_name = $param['trade_name'];
+ $contract->status = $param['status'];
+ $contract->is_owner = $param['is_owner'];
+ $contract->info = $info;
+ $contract->logo_link = '';
+ $contract->face_value = $param['face_value'];
+ $contract->sort = $param['sort'];
+ $contract->min_pry = $param['min_pry'];
+ $contract->max_pry = $param['max_pry'];
+ $contract->compel_num = $param['compel_num'];
+ $contract->keep_decimal = $param['keep_decimal'];
+ $contract->create_time = date('Y-m-d H:i:s');
+ $contract->update_time = date('Y-m-d H:i:s');
+ $contract->save();
+
+ $list_key="FOREX:LIST:".strtoupper($param['trade_name']);
+ $redis = $this->getRedis();
+ $redis->del($list_key);
+ $redis->hMset($list_key, [
+ 'name'=>strtoupper($param['trade_name']),
+ 'code'=>strtoupper($param['trade_name']),
+ 'sort'=>$param['sort'],
+ 'face_value'=>$param['face_value'],
+ 'min_pry'=>$param['min_pry'],
+ 'max_pry'=>$param['max_pry'],
+ 'compel_num'=>$param['compel_num'],
+ 'keep_decimal'=>$param['keep_decimal'],
+ 'is_owner'=>$param['is_owner'],
+ 'status'=>$param['status']
+ ]);
+
+ return $this->toData('0', '操作成功', []);
+ }catch (\Exception $exception){
+ return $this->toData('1', '系统繁忙', [$exception->getMessage()]);
+ }
+ }
+
+ public function edit($param)
+ {
+ try {
+ if(empty($param['id']) || !is_numeric($param['id'])){
+ return $this->toData('1', '目标不存在', []);
+ }
+
+ $contract = ForexListModel::where('id', $param['id'])->find();
+ $beforeStatus = $contract['status'];
+ if(empty($contract)){
+ return $this->toData('1', '目标不存在', []);
+ }
+
+ // 交易对名称
+ if(empty($param['trade_name']) || !is_string($param['trade_name']) || strlen($param['trade_name']) > 100){
+ return $this->toData('1', '交易对名称无效', []);
+ }
+
+ // 状态
+ if(!isset($param['status']) || !in_array($param['status'], ['0', '1'])){
+ return $this->toData('1', '状态无效', []);
+ }
+
+ // 是否自发
+ if(!isset($param['is_owner']) || !in_array($param['is_owner'], ['0', '1'])){
+ return $this->toData('1', '是否自发无效', []);
+ }
+
+ // 简介
+ $info = '';
+ if(isset($param['info']) && is_string($param['info'])){
+ $info = $param['info'];
+ }
+
+ // 面值
+ if(!isset($param['face_value']) || !is_numeric($param['face_value']) || $param['face_value'] != ceil($param['face_value']) || $param['face_value'] <= 0){
+ return $this->toData('1', '面值无效', []);
+ }
+
+
+ // 排序
+ if(!isset($param['sort']) || !is_numeric($param['sort']) || $param['sort'] != ceil($param['sort']) || $param['sort'] < 0){
+ return $this->toData('1', '排序值无效', []);
+ }
+
+ // 最小杠杆
+ if(empty($param['min_pry']) || !is_numeric($param['min_pry']) || $param['min_pry'] != ceil($param['min_pry']) || $param['min_pry'] <= 0){
+ return $this->toData('1', '最小杠杆值无效', []);
+ }
+
+ // 最大杠杆
+ if(empty($param['max_pry']) || !is_numeric($param['max_pry']) || $param['max_pry'] != ceil($param['max_pry']) || $param['max_pry'] <= 0){
+ return $this->toData('1', '最大杠杆值无效', []);
+ }
+
+ // 强制平仓比例值
+ if(empty($param['compel_num']) || !is_numeric($param['compel_num']) || $param['compel_num'] <= 0){
+ return $this->toData('1', '强制平仓比例值无效', []);
+ }
+
+ // 小数位数
+ if(!isset($param['keep_decimal']) || !is_numeric($param['keep_decimal']) || $param['keep_decimal'] != ceil($param['keep_decimal']) || $param['keep_decimal'] < 0){
+ return $this->toData('1', '小数位数值无效', []);
+ }
+
+ // 判断名称是否已被添加
+ $count = ForexListModel::where('trade_name', $param['trade_name'])->where('id', '<>', $param['id'])->count();
+ if($count > 0){
+ return $this->toData('1', '合约交易对名称已存在', []);
+ }
+
+ // 如果状态设置成关闭 则判断是否有正在交易的合约
+ if($beforeStatus == 1 && $param['status'] == 0){
+ $num=(new ForexListModel())->where([
+ 'contract_id'=>strtoupper($contract['trade_name']),
+ 'status'=>1
+ ])->count();
+ if ($num != 0) {
+ return $this->toData('1', '交易对还存在交易,不能关闭', []);
+ }
+ }
+
+ // 写入数据
+ $contract->trade_name = $param['trade_name'];
+ $contract->status = $param['status'];
+ $contract->is_owner = $param['is_owner'];
+ $contract->info = $info;
+ $contract->logo_link = '';
+ $contract->face_value = $param['face_value'];
+ $contract->sort = $param['sort'];
+ $contract->min_pry = $param['min_pry'];
+ $contract->max_pry = $param['max_pry'];
+ $contract->compel_num = $param['compel_num'];
+ $contract->keep_decimal = $param['keep_decimal'];
+ $contract->create_time = date('Y-m-d H:i:s');
+ $contract->update_time = date('Y-m-d H:i:s');
+ $contract->save();
+
+
+ $list_key="FOREX:LIST:".strtoupper($param['trade_name']);
+ $redis = $this->getRedis();
+ $redis->del($list_key);
+ $redis->hMset($list_key, [
+ 'name'=>strtoupper($param['trade_name']),
+ 'code'=>strtoupper($param['trade_name']),
+ 'sort'=>$param['sort'],
+ 'face_value'=>$param['face_value'],
+ 'min_pry'=>$param['min_pry'],
+ 'max_pry'=>$param['max_pry'],
+ 'compel_num'=>$param['compel_num'],
+ 'keep_decimal'=>$param['keep_decimal'],
+ 'status'=>$param['status']
+ ]);
+ return $this->toData('0', 'SUCCESS', []);
+ }catch (\Exception $exception){
+ return $this->toData('1', '系统繁忙', []);
+ }
+ }
+
+ // 获取合约交易对
+ public function getTradeNameList($param)
+ {
+ try {
+ if(isset($param['is_owner']) && in_array($param['is_owner'], [0,1])){
+ $list = ForexListModel::where('status', 1)->order('id', 'desc')
+ ->where('is_owner', $param['is_owner'])
+ ->column('trade_name', 'id');
+ } else {
+ $list = ForexListModel::where('status', 1)->order('id', 'desc')
+ ->column('trade_name', 'id');
+ }
+
+ return $this->toData('0', 'SUCCESS', ['list' => $list]);
+ }catch (\Exception $exception){
+ return $this->toData('1', '系统繁忙', []);
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/app/admin/service/setting/GiveStockService.php b/app/admin/service/setting/GiveStockService.php
new file mode 100644
index 0000000..f07069e
--- /dev/null
+++ b/app/admin/service/setting/GiveStockService.php
@@ -0,0 +1,133 @@
+toData('1', '分页参数错误');
+ }
+
+ $where = [];
+ $userId = 0;
+ // 用户号精确搜索
+ if (!empty($param['user_no'])) {
+ $user = UserModel::where('user_no', $param['user_no'])->find();
+ if (empty($user)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => [], 'extent' => StockMarketModel::STOCK_MARKET_TYPE]);
+ }
+ $userId = $user['user_id'];
+ }
+
+ // 判断是否是代理 如果是代理 只能看他自己管理的用户
+ $whereU = $this->getWhereByIsAgentAndUserId($adminId, $where, $userId);
+ if (!is_array($whereU)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => [], 'extent' => StockMarketModel::STOCK_MARKET_TYPE]);
+ }
+
+ // 股票号
+ if (!empty($param['stock_code']) && is_string($param['stock_code'])) {
+ $where[] = [
+ 'stock_code', 'like', '%' . $param['stock_code']
+ ];
+ }
+ $tableObj = (new IPOService())->getStockModel($marketType);
+
+ $query = Db::table($tableObj['give_order_table'])->where($where)->where($whereU)->with(['user' => function ($query) {
+ $query->field('user_id,user_no,nick_name,email,phone_number');
+ }])->order('id', 'desc');
+ $totalQuery = Db::table($tableObj['give_order_table'])->where($where)->where($whereU)->order('id', 'desc');
+ $list = $query->page($param['page'], $param['limit'])->select()->toArray();
+ $total = $totalQuery->count();
+ $stockCodeArr = array_column($list, 'stock_code');
+ $stockNameArr = Db::table($tableObj['list_table'])->whereIn('stock_code', $stockCodeArr)->column('stock_name', 'stock_code');
+ foreach ($list as &$v) {
+ $v['stock_name'] = $stockNameArr[$v['stock_code']];
+ }
+
+ return $this->toData('0', 'SUCCESS', ['list' => $list, 'total' => $total, 'extent' => StockMarketModel::STOCK_MARKET_TYPE]);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统繁忙', [$exception->getMessage()]);
+ }
+ }
+
+ // 新增
+ public function add($marketType, $param)
+ {
+ try {
+ // 股票代码
+ if (empty($param['stock_code']) || !is_string($param['stock_code'])) {
+ return $this->toData('1', '股票代码 无效');
+ }
+
+ if (empty($param['tape']) || !is_numeric($param['tape'])) {
+ return $this->toData('1', '交易所 无效');
+ }
+
+ $tapeList = (new StockMarketModel)->getAllTape();
+ if (strpos($param['stock_code'], ':') !== false) {
+ $param['stock_code'] = explode(':', $param['stock_code'])[1];
+ }
+
+ $tape = $tapeList[$marketType][$param['tape']];
+ if ($marketType != 3) $param['stock_code'] = $tape . ':' . $param['stock_code'];
+
+ $tableObj = (new IPOService())->getStockModel($marketType);
+ $isHas = Db::table($tableObj['list_table'])->where('stock_code', $param['stock_code'])->value('id');
+ if (empty($isHas)) return $this->toData('1', '股票 无效');
+
+ // 股票代码
+ if (empty($param['user_id']) || !is_numeric($param['user_id'])) {
+ return $this->toData('1', '用户 无效');
+ }
+
+ if (empty($param['num']) || !is_numeric($param['num']) || $param['num'] <= 0) {
+ return $this->toData('1', '送股数量 无效');
+ }
+
+ $price=!empty($param['price']) ? floatval($param['price']) : 0;
+
+ $date = date('Y-m-d H:i:s');
+ $orderNo = (new Tool())->orderNo(20);
+ $insertArr = [
+ 'user_id' => $param['user_id'],
+ 'stock_code' => $param['stock_code'],
+ 'order_no' => $orderNo,
+ 'num' => $param['num'],
+ 'price' => $price,
+ 'amount' => $price*$param['num'],
+ 'create_time' => $date,
+ 'update_time' => $date
+ ];
+ $insertBool = Db::table($tableObj['give_order_table'])->insert($insertArr);
+ if ($insertBool) {
+ // 通知交易
+ $bool = (new ClientGo())->giveawaysStock($param['stock_code'], $orderNo, $param['market_type']);
+ if (!$bool) {
+ return $this->toData('1', '给交易推送数据异常', []);
+ }
+ }
+
+ return $this->toData('0', 'SUCCESS');
+ } catch (\Exception $exception) {
+ return $this->toData('0', '系统繁忙', [$exception->getMessage()]);
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/app/admin/service/setting/HqService.php b/app/admin/service/setting/HqService.php
new file mode 100644
index 0000000..7fbed18
--- /dev/null
+++ b/app/admin/service/setting/HqService.php
@@ -0,0 +1,175 @@
+order('id', 'desc')->select();
+ $rows = [];
+ if(!$list->isEmpty()){
+ $rows = $list->toArray();
+ }
+ return $this->toData('0','SUCCSS',['list' => $rows, 'total' => count($rows)]);
+ }catch (\Exception $exception){
+ return $this->toData('1', '系统繁忙', [$exception->getMessage()]);
+ }
+ }
+
+
+ // 新增
+ public function add($param)
+ {
+ try {
+ // 参数校验
+ validate(HqValidate::class)->scene('add')->check($param);
+
+ // 已存在未执行的 不能再插入
+ $count = ContractMarketModel::where('trade_name', $param['trade_name'])
+ ->where('is_get',1)
+ ->where('type', 0)
+ ->count();
+ if($count > 0){
+ return $this->toData('1','已存在未执行');
+ }
+
+ //判断
+ $diff = strtotime($param['end_time']) - strtotime($param['begin_time']);
+ if($diff > 600 || $diff <=0){
+ return $this->toData('1','时间无效-结束时间必须在开始时间十分钟以内');
+ }
+
+ // 不能有交叉时间
+ $map1 = [
+ ['trade_name', '=',$param['trade_name']],
+ ['begin_time','between', [$param['begin_time'], $param['end_time']]]
+ ];
+ $map2 = [
+ ['trade_name', '=',$param['trade_name']],
+ ['end_time','between', [$param['begin_time'], $param['end_time']]]
+ ];
+
+ $count = ContractMarketModel::whereOr([$map1,$map2])
+ ->count();
+ if($count > 0){
+ return $this->toData('1','时间无效-时间不能有交叉');
+ }
+
+ $market = new ContractMarketModel;
+ $market->trade_name = $param['trade_name'];
+ $market->begin_time = $param['begin_time'];
+ $market->end_time = $param['end_time'];
+ $market->max_price = $param['max_price'];
+ $market->step = $param['step'];
+ $market->type = 0;
+ $market->save();
+
+ // 写入redis
+ $this->initContractHqData();
+
+ return $this->toData('0','SUCCESS');
+ }catch (ValidateException $validateException){
+ return $this->toData('1', $validateException->getMessage(), []);
+ }catch (\Exception $exception){
+ return $this->toData('1', '系统繁忙', [$exception->getMessage()]);
+ }
+ }
+
+
+ // 编辑
+ public function edit($param)
+ {
+ try {
+ // 参数校验
+ validate(HqValidate::class)->scene('edit')->check($param);
+
+ // 已存在未执行的 不能再插入
+ $count = ContractMarketModel::where('trade_name', $param['trade_name'])
+ ->where('id', '<>', $param['id'])
+ ->where('is_get',1)
+ ->where('type', 0)
+ ->count();
+
+ if($count > 0){
+ return $this->toData('1','已存在未执行');
+ }
+
+ // 目标
+ $market = ContractMarketModel::where('id', $param['id'])->where('type', 0)->find();
+ if(empty($market)){
+ return $this->toData('1','目标不存在');
+ }
+
+ //判断
+ $diff = strtotime($param['end_time']) - strtotime($param['begin_time']);
+ if($diff > 600 || $diff <=0){
+ return $this->toData('1','时间无效');
+ }
+
+ // 不能有交叉时间
+ $map1 = [
+ ['trade_name', '=',$param['trade_name']],
+ ['id', '<>',$param['id']],
+ ['begin_time','between', [$param['begin_time'], $param['end_time']]]
+ ];
+ $map2 = [
+ ['trade_name', '=',$param['trade_name']],
+ ['id', '<>',$param['id']],
+ ['end_time','between', [$param['begin_time'], $param['end_time']]]
+ ];
+
+ $count = ContractMarketModel::whereOr([$map1,$map2])
+ ->count();
+ if($count > 0){
+ return $this->toData('1','时间无效');
+ }
+
+ $market->trade_name = $param['trade_name'];
+ $market->begin_time = $param['begin_time'];
+ $market->end_time = $param['end_time'];
+ $market->max_price = $param['max_price'];
+ $market->step = $param['step'];
+ $market->save();
+
+ // redis
+ $this->initContractHqData();
+ return $this->toData('0','SUCCESS');
+ }catch (ValidateException $validateException){
+ return $this->toData('1', $validateException->getMessage(), []);
+ }catch (\Exception $exception){
+ return $this->toData('1', '系统繁忙', [$exception->getMessage(),$exception->getTrace()]);
+ }
+ }
+
+ // 删除
+ public function del($param)
+ {
+ try {
+ // 参数校验
+ validate(HqValidate::class)->scene('del')->check($param);
+
+ // 目标
+ $market = ContractMarketModel::where('id', $param['id'])->find();
+ if(empty($market)){
+ return $this->toData('1','目标不存在');
+ }
+
+ $market->delete();
+
+ $this->initContractHqData();
+ return $this->toData('0','SUCCESS');
+ }catch (ValidateException $validateException){
+ return $this->toData('12', $validateException->getMessage(), []);
+ }catch (\Exception $exception){
+ return $this->toData('11', '系统繁忙', [$exception->getMessage()]);
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/admin/service/setting/IPOService.php b/app/admin/service/setting/IPOService.php
new file mode 100644
index 0000000..410f47c
--- /dev/null
+++ b/app/admin/service/setting/IPOService.php
@@ -0,0 +1,1701 @@
+getStockModel($market_type);
+ if (empty($table_obj)) {
+ return $this->toData('1', '市场类型无效');
+ }
+ if (empty($param['page']) || !is_numeric($param['page']) || empty($param['limit']) || !is_numeric($param['limit'])) {
+ return $this->toData('1', '分页参数错误');
+ }
+
+ $userId = 0;
+ $where = [];
+ $stockTypeList = $this->getStockTape($market_type);
+ // 用户号精确搜索
+ if (!empty($param['user_no'])) {
+ $user = UserModel::where('user_no', $param['user_no'])->find();
+ if (empty($user)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => [], 'extent' => [
+ 'tape_list' => $stockTypeList['tape'],
+ 'stock_type_list' => $stockTypeList['type'],
+ 'symbol' => $table_obj['stock_id']]]);
+ }
+ $userId = $user['user_id'];
+ }
+
+ // 判断是否是代理 如果是代理 只能看他自己管理的用户
+ $whereU = $this->getWhereByIsAgentAndUserId($adminId, $where, $userId);
+ if (!is_array($whereU)) {
+ return $this->toData('0', 'SUCCESS', ['total' => 0, 'list' => [], 'extent' => [
+ 'tape_list' => $stockTypeList['tape'],
+ 'stock_type_list' => $stockTypeList['type'],
+ 'symbol' => $table_obj['stock_id']]]);
+ }
+
+ // 未删除
+ $where[] = [
+ 'is_delete', '=', 1
+ ];
+ // 股票号
+ if (!empty($param['stock_code']) && is_string($param['stock_code'])) {
+ $where[] = [
+ 'stock_code', 'like', '%' . $param['stock_code']
+ ];
+ }
+
+ // 状态
+ if (!empty($param['status']) && in_array($param['status'], [1, 2])) {
+ $where[] = [
+ 'status', '=', $param['status']
+ ];
+ }
+
+ // 上市状态 1 待申购 2 (申购中)待中签 3 (申购结束)待中签 4 待上市 5 已上市
+ $query = Db::table($table_obj['stock_table'])->where($where)->where($whereU);
+ $totalQuery = Db::table($table_obj['stock_table'])->where($where)->where($whereU);
+ if (!empty($param['open_status']) && in_array($param['open_status'], ['1', '2', '3', '4'])) {
+ switch ($param['open_status']) {
+ case '1':
+ $query = $query->whereTime('start_time', '>', date('Y-m-d H:i:s'));
+ $totalQuery = $totalQuery->whereTime('start_time', '>', date('Y-m-d H:i:s'));
+ break;
+ case '2':
+ $query = $query->whereTime('start_time', '<=', date('Y-m-d H:i:s'))->whereTime('end_time', '>=', date('Y-m-d H:i:s'));
+ $totalQuery = $totalQuery->whereTime('start_time', '<=', date('Y-m-d H:i:s'))->whereTime('end_time', '>=', date('Y-m-d H:i:s'));
+ break;
+ case '3':
+ $query = $query->whereTime('end_time', '<=', date('Y-m-d H:i:s'))->whereTime('get_time', '>', date('Y-m-d H:i:s'));
+ $totalQuery = $totalQuery->whereTime('end_time', '<=', date('Y-m-d H:i:s'))->whereTime('get_time', '>', date('Y-m-d H:i:s'));
+ break;
+ case '4':
+ $query = $query->where('open_status', 1)->whereTime('get_time', '<', date('Y-m-d H:i:s'));
+ $totalQuery = $totalQuery->where('open_status', 2);
+ break;
+ case '5':
+ $query = $query->where('open_status', 2);
+ $totalQuery = $totalQuery->where('open_status', 2);
+ break;
+ }
+ }
+
+ $list = $query->order('id', 'desc')->page($param['page'], $param['limit'])->select();
+ $total = $totalQuery->order('id', 'desc')->count();
+ $rows = [];
+ if (!$list->isEmpty()) {
+ $rows = $list->toArray();
+ foreach ($rows as $key => $item) {
+ $open_status_name = '-';
+ if (strtotime($item['start_time']) > time()) {
+ $open_status_name = '待申购';
+ $re_status = 1;
+ }
+
+ if (strtotime($item['start_time']) <= time() && strtotime($item['end_time']) >= time()) {
+ $open_status_name = '待中签(申购中)';
+ $re_status = 2;
+ }
+
+ if (strtotime($item['end_time']) < time()) {
+ $open_status_name = '待中签(申购结束)';
+ $re_status = 3;
+ }
+
+ if ($item['sign_status'] == 1) {
+ $open_status_name = '待上市(已中签)';
+ $re_status = 4;
+ }
+
+ if ($item['open_status'] == 2) {
+ $open_status_name = '已上市';
+ $re_status = 5;
+ }
+
+ $rows[$key]['open_status_name'] = $open_status_name;
+ $rows[$key]['re_status'] = $re_status;
+
+ if (strpos($item['stock_code'], ':') !== false) {
+ $rows[$key]['stock_code'] = explode(':', $item['stock_code'])[1];
+ }
+ }
+ }
+
+ return $this->toData('0', 'SUCCESS', ['list' => $rows, 'total' => $total, 'extend' => [
+ 'tape_list' => $stockTypeList['tape'],
+ 'stock_type_list' => $stockTypeList['type'],
+ 'symbol' => $table_obj['stock_id'],
+ 're_status_list' => ['1' => '待申购', '2' => '待中签(申购中)', '3' => '待中签(申购结束)', '4' => '待上市(已中签)', '5' => '已上市']
+ ]]);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统繁忙', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+
+ /**
+ * 添加IPO
+ */
+ public function addStockIPO($market_type, $param)
+ {
+ try {
+ $table_obj = $this->getStockModel($market_type);
+ if (empty($table_obj)) {
+ return $this->toData('1', '市场类型无效');
+ }
+ // 股票代码
+ if (empty($param['stock_code']) || !is_string($param['stock_code']) || !preg_match('/^[a-zA-Z0-9]+$/', $param['stock_code'])) {
+ return $this->toData('1', '股票代码 无效');
+ }
+
+ // 股票名称
+ if (empty($param['stock_name']) || !is_string($param['stock_name'])) {
+ return $this->toData('1', '股票名称 无效');
+ }
+
+ if ($market_type == 5) {
+ if (empty($param['numeric_code']) || !preg_match('/^[a-zA-Z0-9]+$/', $param['numeric_code'])) {
+ return $this->toData('1', '数字编码 无效');
+ }
+ }
+
+ $stockTypeList = $this->getStockTape($market_type);
+ // 股票类型
+ if (empty($param['stock_type']) || !in_array($param['stock_type'], array_keys($stockTypeList['type']))) {
+ return $this->toData('1', '股票类型 无效');
+ }
+
+ // 交易所类型
+ if (empty($param['tape']) || !in_array($param['tape'], array_keys($stockTypeList['tape']))) {
+ return $this->toData('1', '交易所类型 无效');
+ }
+
+ // 发布状态
+ if (empty($param['status']) || !in_array($param['status'], [1, 2])) {
+ return $this->toData('1', '发布状态 无效');
+ }
+
+ // 单股价格
+ if (empty($param['price']) || !is_numeric($param['price']) || $param['price'] <= 0) {
+ return $this->toData('1', '单股价格 无效');
+ }
+
+ // 最小申购数量
+ if (empty($param['min']) || !is_numeric($param['min']) || $param['min'] <= 0 || ceil($param['min']) != $param['min']) {
+ return $this->toData('1', '最小申购数量 无效');
+ }
+
+ // 发行总数
+ if (empty($param['total']) || !is_numeric($param['total']) || $param['total'] <= 0 || ceil($param['total']) != $param['total']) {
+ return $this->toData('1', '发行总数 无效');
+ }
+
+ // 中签率 两位小数
+ if (empty($param['rate']) || !is_numeric($param['rate']) || is_float($param['rate']) || $param['rate'] < 0 || $param['rate'] > 100) {
+ return $this->toData('1', '中签率无效;范围 0 - 100 , 必须是整数');
+ }
+
+ // 开始认购时间
+ if (empty($param['start_time']) || !is_string($param['start_time'])) {
+ return $this->toData('1', '开始认购时间 无效');
+ }
+
+ // 认购结束时间
+ if (empty($param['end_time']) || !is_string($param['end_time'])) {
+ return $this->toData('1', '认购结束时间 无效');
+ }
+
+ // 中签时间
+ if (empty($param['get_time']) || !is_string($param['get_time'])) {
+ return $this->toData('1', '中签时间 无效');
+ }
+
+ // 上市时间
+ if (empty($param['open_time']) || !is_string($param['open_time'])) {
+ return $this->toData('1', '上市时间 无效');
+ }
+
+ // 公司注册资本
+ $companyRegAmount = "";
+ if (!empty($param['company_reg_amount']) && is_string($param['company_reg_amount'])) {
+ $companyRegAmount = $param['company_reg_amount'];
+ }
+
+ // 公司上市时间
+ if (empty($param['company_open_time']) || !is_string($param['company_open_time'])) {
+ return $this->toData('1', '公司上市时间 无效');
+ }
+
+ // 公司简介
+ if (empty($param['company_info']) || !is_string($param['company_info'])) {
+ return $this->toData('1', '公司简介 无效');
+ }
+
+ // 股票logo
+ if (empty($param['logo']) || !is_string($param['logo'])) {
+ return $this->toData('1', '股票logo 无效');
+ }
+
+ // 上市时间 要大于 中签时间 中签时间要大于 认购结结束时间
+ if (strtotime($param['open_time']) <= strtotime($param['get_time']) || strtotime($param['get_time']) <= strtotime($param['end_time'])) {
+ return $this->toData('1', '上市时间 要大于 中签时间 中签时间要大于 认购结结束时间');
+ }
+
+ // 是否后支付
+ if (empty($param['is_post_pay']) || !in_array($param['is_post_pay'], [1, 2])) {
+ return $this->toData('1', '交易所类型 无效');
+ }
+
+ // 后支付截止时间 > 中签时间 && 后支付截止时间 < 上市时间
+// if ($param['is_post_pay'] == 2 && (empty($param['pay_deadline_time']) || strtotime($param['pay_deadline_time']) <= strtotime($param['get_time']) || strtotime($param['pay_deadline_time']) >= strtotime($param['open_time']))) {
+// return $this->toData('1', '后支付截止时间 要大于 中签时间 且 后支付截止时间 要小于 上市时间');
+// }
+
+ if (strpos($param['stock_code'], ':') !== false) {
+ $param['stock_code'] = explode(':', $param['stock_code'])[1];
+ }
+ //除了美股 其他的 code前拼交易所
+ if ($market_type != 3) {
+ $param['stock_code'] = $this->getStockTape($market_type)['tape'][$param['tape']] . ":" . $param['stock_code'];
+ }
+
+ // 1.0 判断股票号是否已经存在
+ $preStock = Db::table($table_obj['stock_table'])->where('stock_code', $param['stock_code'])->where('is_delete', 1)->find();
+ if (!empty($preStock)) {
+ return $this->toData('1', '股票号已经存在');
+ }
+ $stock = Db::table($table_obj['list_table'])->where('stock_code', $param['stock_code'])->find();
+ if (!empty($stock)) {
+ return $this->toData('1', '股票号已经上市');
+ }
+
+ // 新增数据
+
+ $preHkStock['stock_code'] = $param['stock_code'];
+ $preHkStock['stock_name'] = $param['stock_name'];
+ $preHkStock['stock_type'] = $param['stock_type'];
+ $preHkStock['tape'] = $param['tape'];
+ $preHkStock['status'] = $param['status'];
+ $preHkStock['price'] = $param['price'];
+ $preHkStock['min'] = $param['min'];
+ $preHkStock['max'] = $param['max'] ?? 0;
+ $preHkStock['total'] = $param['total'];
+ $preHkStock['rate'] = $param['rate'];
+ $preHkStock['start_time'] = $param['start_time'];
+ $preHkStock['end_time'] = $param['end_time'];
+ $preHkStock['get_time'] = $param['get_time'];
+ $preHkStock['open_time'] = $param['open_time'];
+ $preHkStock['is_post_pay'] = $param['is_post_pay'];
+ if (!empty($param['pay_deadline_time'])) $preHkStock['pay_deadline_time'] = $param['pay_deadline_time'];
+ $preHkStock['limit_get_num'] = $param['limit_get_num'] ?? 100;
+ $preHkStock['is_delete'] = 1;
+ $preHkStock['open_status'] = 1;
+ $preHkStock['create_time'] = date('Y-m-d H:i:s');
+ $preHkStock['update_time'] = date('Y-m-d H:i:s');
+ $preHkStock['company_reg_amount'] = $companyRegAmount;
+ $preHkStock['company_open_time'] = $param['company_open_time'];
+ $preHkStock['company_info'] = $param['company_info'];
+ $preHkStock['logo'] = $param['logo'];
+ if ($market_type == 5) $preHkStock['numeric_code'] = $param['numeric_code'] ?? '0';
+
+ $bool = Db::table($table_obj['stock_table'])->insert($preHkStock);
+ if ($bool) {
+ return $this->toData('0', 'SUCCESS');
+ } else {
+ return $this->toData('1', 'FAIL');
+ }
+ } catch (\Exception $exception) {
+ return $this->toData('0', '系统繁忙', [$exception->getMessage()]);
+ }
+ }
+
+ /**
+ * 编辑IPO
+ */
+ public function editStockIPO($market_type, $param)
+ {
+ try {
+ $table_obj = $this->getStockModel($market_type);
+ if (empty($table_obj)) {
+ return $this->toData('1', '数据异常');
+ }
+ if (empty($param['id']) || !is_numeric($param['id'])) {
+ return $this->toData('1', '主键 无效');
+ }
+
+ $preHkStock = Db::table($table_obj['stock_table'])->where('id', $param['id'])->where('is_delete', 1)->find();
+ if (empty($preHkStock)) {
+ return $this->toData('1', '主键 无效');
+ }
+ $stockTypeList = $this->getStockTape($market_type);
+ // 股票类型
+ if (empty($param['stock_type']) || !in_array($param['stock_type'], array_keys($stockTypeList['type']))) {
+ return $this->toData('1', '股票类型 无效');
+ }
+
+ // 股票代码
+ if (empty($param['stock_code']) || !is_string($param['stock_code']) || !preg_match('/^[a-zA-Z0-9]+$/', $param['stock_code'])) {
+ return $this->toData('1', '股票代码 无效');
+ }
+
+ // 股票名称
+ if (empty($param['stock_name']) || !is_string($param['stock_name'])) {
+ return $this->toData('1', '股票代码 无效');
+ }
+
+ if ($market_type == 5) {
+ if (empty($param['numeric_code']) || !preg_match('/^[a-zA-Z0-9]+$/', $param['numeric_code'])) {
+ return $this->toData('1', '数字编码 无效');
+ }
+ }
+
+ // 交易所类型
+ if (empty($param['tape']) || !in_array($param['tape'], array_keys($stockTypeList['tape']))) {
+ return $this->toData('1', '交易所类型 无效');
+ }
+
+ // 发布状态
+ if (empty($param['status']) || !in_array($param['status'], [1, 2])) {
+ return $this->toData('1', '发布状态 无效');
+ }
+
+ // 单股价格
+ if (empty($param['price']) || !is_numeric($param['price']) || $param['price'] <= 0) {
+ return $this->toData('1', '单股价格 无效');
+ }
+
+ // 开始认购时间
+ if (empty($param['start_time']) || !is_string($param['start_time'])) {
+ return $this->toData('1', '开始认购时间 无效');
+ }
+ // 最小申购数量
+ if (empty($param['min']) || !is_numeric($param['min']) || $param['min'] <= 0 || ceil($param['min']) != $param['min']) {
+ return $this->toData('1', '最小申购数量 无效');
+ }
+
+ // 发行总数
+ if (empty($param['total']) || !is_numeric($param['total']) || $param['total'] <= 0 || ceil($param['total']) != $param['total']) {
+ return $this->toData('1', '发行总数 无效');
+ }
+
+ // 中签率 两位小数
+ if (empty($param['rate']) || !is_numeric($param['rate']) || is_float($param['rate']) || $param['rate'] < 0 || $param['rate'] > 100) {
+ return $this->toData('1', '中签率无效;范围 0 - 100 , 必须是整数');
+ }
+
+ // 认购结束时间
+ if (empty($param['end_time']) || !is_string($param['end_time'])) {
+ return $this->toData('1', '认购结束时间 无效');
+ }
+
+ // 中签时间
+ if (empty($param['get_time']) || !is_string($param['get_time'])) {
+ return $this->toData('1', '中签时间 无效');
+ }
+
+ // 上市时间
+ if (empty($param['open_time']) || !is_string($param['open_time'])) {
+ return $this->toData('1', '上市时间 无效');
+ }
+
+ // 公司注册资本
+ $companyRegAmount = "";
+ if (!empty($param['company_reg_amount']) && is_string($param['company_reg_amount'])) {
+ $companyRegAmount = $param['company_reg_amount'];
+ }
+
+ // 公司上市时间
+ if (empty($param['company_open_time']) || !is_string($param['company_open_time'])) {
+ return $this->toData('1', '公司上市时间 无效');
+ }
+
+ // 公司简介
+ if (empty($param['company_info']) || !is_string($param['company_info'])) {
+ return $this->toData('1', '公司简介 无效');
+ }
+
+ // 股票logo
+ if (empty($param['logo']) || !is_string($param['logo'])) {
+ return $this->toData('1', '股票logo 无效');
+ }
+
+ // 上市时间 要大于 中签时间 中签时间要大于 认购结结束时间
+ if (strtotime($param['open_time']) <= strtotime($param['get_time']) || strtotime($param['get_time']) <= strtotime($param['end_time'])) {
+ return $this->toData('1', '上市时间 要大于 中签时间 中签时间要大于 认购结结束时间');
+ }
+
+ // 是否后支付
+ if (empty($param['is_post_pay']) || !in_array($param['is_post_pay'], [1, 2])) {
+ return $this->toData('1', '交易所类型 无效');
+ }
+
+ // 后支付截止时间 > 中签时间 && 后支付截止时间 < 上市时间
+// if ($param['is_post_pay'] == 2 && (empty($param['pay_deadline_time']) || strtotime($param['pay_deadline_time']) <= strtotime($param['get_time']) || strtotime($param['pay_deadline_time']) >= strtotime($param['open_time']))) {
+// return $this->toData('1', '后支付截止时间 要大于 中签时间 且 后支付截止时间 要小于 上市时间');
+// }
+
+ if (strpos($param['stock_code'], ':') !== false) {
+ $param['stock_code'] = explode(':', $param['stock_code'])[1];
+ }
+ //除了美股 其他的 code前拼交易所
+ if ($market_type != 3) {
+ $param['stock_code'] = $this->getStockTape($market_type)['tape'][$param['tape']] . ":" . $param['stock_code'];
+ }
+ //code变更进行通知
+ if ($preHkStock['stock_code'] != $param['stock_code'] && $preHkStock['open_status'] == 2) {
+ $source = 0;
+ if ($market_type == 7) $source = 1;
+ // 通知行情
+ $bool = $this->sendNewStockToGo($table_obj['country'], $param['stock_code'], $preHkStock['stock_code'], $param['stock_name'], $stockTypeList['tape'][$preHkStock['tape']], $preHkStock['price'], 1, $preHkStock['company_info'], $source, $param['numeric_code'] ?? 0);
+ if (!$bool) {
+ return $this->toData('1', '给行情推送数据异常', []);
+ }
+
+ // 通知交易
+ $bool = $this->sendUpdateCodeGo($param['stock_code'], $preHkStock['stock_code'], $market_type);
+ if (!$bool) {
+ return $this->toData('1', '给交易推送数据异常', []);
+ }
+
+ //修改股票code
+ $stock = Db::table($table_obj['list_table'])->where('stock_code', $preHkStock['stock_code'])->find();
+ $stock_update['stock_code'] = $param['stock_code'];
+ $stock_update['update_time'] = date('Y-m-d H:i:m');
+ $updateCodeBool = Db::table($table_obj['list_table'])->where('id', $stock['id'])->update($stock_update);
+ if (!$updateCodeBool) return $this->toData('1', '修改股票code失败');
+
+ $oldKey = $table_obj['redis_key'] . $preHkStock['stock_code'];
+ $redis = $this->getRedis();
+ $redis->del($oldKey);
+ $newKey = $table_obj['redis_key'] . $param['stock_code'];
+ $cacheArr = [
+ 'stock_name' => $stock['stock_name'],
+ 'stock_code' => $param['stock_code'],
+ 'status' => $stock['status'],
+ 'keep_decimal' => $stock['keep_decimal'],
+ 'forced_closure' => $stock['forced_closure'],
+ 'up_limit' => $stock['up_limit'],
+ 'down_limit' => $stock['down_limit'],
+ 'info' => $stock['info'],
+ 'tape' => $stock['tape'],
+ ];
+ if ($market_type == 5) $cacheArr['numeric_code'] = $param['numeric_code'] ?? '0';
+ $redis->hMset($newKey, $cacheArr);
+ }
+
+ $preHkStock['stock_code'] = $param['stock_code'];
+ $preHkStock['stock_name'] = $param['stock_name'];
+ $preHkStock['tape'] = $param['tape'];
+ $preHkStock['status'] = $param['status'];
+ $preHkStock['price'] = $param['price'];
+ $preHkStock['start_time'] = $param['start_time'];
+
+ // 新增数据
+ $preHkStock['min'] = $param['min'];
+ $preHkStock['max'] = $param['max'] ?? 0;
+ $preHkStock['total'] = $param['total'];
+ $preHkStock['rate'] = $param['rate'];
+ $preHkStock['end_time'] = $param['end_time'];
+ $preHkStock['get_time'] = $param['get_time'];
+ $preHkStock['open_time'] = $param['open_time'];
+ $preHkStock['is_post_pay'] = $param['is_post_pay'];
+ if (!empty($param['pay_deadline_time'])) $preHkStock['pay_deadline_time'] = $param['pay_deadline_time'];
+ $preHkStock['limit_get_num'] = $param['limit_get_num'] ?? 100;
+ $preHkStock['is_delete'] = 1;
+ $preHkStock['update_time'] = date('Y-m-d H:i:s');
+ $preHkStock['company_reg_amount'] = $companyRegAmount;
+ $preHkStock['company_open_time'] = $param['company_open_time'];
+ $preHkStock['company_info'] = $param['company_info'];
+ $preHkStock['logo'] = $param['logo'];
+ if ($market_type == 5) $preHkStock['numeric_code'] = $param['numeric_code'] ?? '0';
+ $bool = Db::table($table_obj['stock_table'])->where('id', $param['id'])->update($preHkStock);
+ if ($bool) {
+ return $this->toData('0', 'SUCCESS');
+ } else {
+ return $this->toData('1', 'FAIL');
+ }
+ } catch (\Exception $exception) {
+ return $this->toData('0', '系统繁忙', [$exception->getMessage()]);
+ }
+
+ }
+
+ /**
+ * 删除IPO
+ */
+ public function delStockIPO($market_type, $param)
+ {
+ try {
+ $table_obj = $this->getStockModel($market_type);
+ if (empty($table_obj)) {
+ return $this->toData('1', '数据异常');
+ }
+ if (empty($param['id']) || !is_numeric($param['id'])) {
+ return $this->toData('1', '主键 无效');
+ }
+
+ $preHkStock = Db::table($table_obj['stock_table'])->where('id', $param['id'])->where('is_delete', 1)->find();
+ if (empty($preHkStock)) {
+ return $this->toData('1', '主键 无效');
+ }
+
+
+ // 删除
+ $list_key = $table_obj['redis_key'] . $preHkStock['stock_code'];
+ $redis = $this->getRedis();
+ $redis->del($list_key);
+
+ //删除 修改状态
+ $preHkStock['is_delete'] = 2;
+ $preHkStock['update_time'] = date('Y-m-d H:i:s');
+ $bool = Db::table($table_obj['stock_table'])->where('id', $param['id'])->update($preHkStock);
+ if ($bool) {
+ return $this->toData('0', 'SUCCESS');
+ } else {
+ return $this->toData('1', 'FAIL');
+ }
+
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统繁忙', [$exception->getMessage()]);
+ }
+ }
+
+ /**
+ * IPO上市
+ */
+ public function stockIPO($market_type, $param)
+ {
+ try {
+ $table_obj = $this->getStockModel($market_type);
+ if (empty($table_obj)) {
+ return $this->toData('1', '市场类型无效');
+ }
+ if (empty($param['id']) || !is_numeric($param['id'])) {
+ return $this->toData('1', '主键 无效');
+ }
+
+ $isReal = 1;
+ if (isset($param['is_real']) && is_numeric($param['is_real']) && $param['is_real'] == '2') {
+ $isReal = 2;
+ }
+
+ $preInStock = Db::table($table_obj['stock_table'])->where('id', $param['id'])->where('is_delete', 1)->find();
+ if (empty($preInStock)) {
+ return $this->toData('1', '主键 无效');
+ }
+
+ // 判断是否签名
+ if ($preInStock['sign_status'] != 1) {
+ return $this->toData('1', '还未签名');
+ }
+
+ // 未签名 上市
+ if ($preInStock['open_status'] != 1 || strtotime($preInStock['get_time']) < date('Y-m-d H:i:s')) {
+ return $this->toData('1', '无法操作');
+ }
+
+
+ Db::startTrans();
+ // 修改股票状态
+ $num = Db::table($table_obj['stock_table'])->where('id', $preInStock['id'])->update(['open_status' => 2,
+ 'open_time' => date('Y-m-d H:i:s'),
+ 'update_time' => date('Y-m-d H:i:s')]);
+ if ($num <= 0) {
+ Db::rollback();
+ return $this->toData('1', '股票状态修改失败');
+ }
+
+ $tape_list = $this->getStockTape($market_type);
+
+ if (Db::table($table_obj['list_table'])->where('stock_code', $preInStock['stock_code'])->find()) {
+ Db::rollback();
+ return $this->toData('1', '股票列表已存在该股票');
+ }
+ // 将新股加入股票
+ $inStock['stock_name'] = $preInStock['stock_name'];
+ $inStock['stock_code'] = $preInStock['stock_code'];
+ $inStock['status'] = 1;
+ $inStock['tape'] = $preInStock['tape'];
+ $inStock['keep_decimal'] = 4;
+ $inStock['info'] = '';
+ $inStock['forced_closure'] = 30;
+ $inStock['up_limit'] = 30;
+ $inStock['down_limit'] = 30;
+ $inStock['create_time'] = date('Y-m-d H:i:s');
+ $inStock['update_time'] = date('Y-m-d H:i:s');
+ if ($market_type == 5) $inStock['numeric_code'] = $preInStock['numeric_code'];
+ $bool = Db::table($table_obj['list_table'])->insert($inStock);
+ if (!$bool) {
+ Db::rollback();
+ return $this->toData('1', '股票转移失败');
+ }
+
+ // 加入缓存
+ $list_key = $table_obj['redis_key'] . $preInStock['stock_code'];
+ $redis = $this->getRedis();
+ $redis->del($list_key);
+ $cacheArr = [
+ 'stock_name' => $inStock['stock_name'],
+ 'stock_code' => $inStock['stock_code'],
+ 'status' => $inStock['status'],
+ 'keep_decimal' => $inStock['keep_decimal'],
+ 'forced_closure' => $inStock['forced_closure'],
+ 'up_limit' => $inStock['up_limit'],
+ 'down_limit' => $inStock['down_limit'],
+ 'info' => $inStock['info'],
+ 'tape' => $inStock['tape'],
+ ];
+ if ($market_type == 5) $cacheArr['numeric_code'] = $preInStock['numeric_code'];
+
+ $redis->hMset($list_key, $cacheArr);
+
+
+ $hqArr = [
+ 'type' => 'hq',
+ 'stock_code' => $inStock['stock_code'],
+ 'stock_name' => $inStock['stock_name'],
+ 'tape' => $tape_list['tape'][$inStock['tape']],
+ 'price' => $preInStock['price'],
+ 'isReal' => $isReal,
+ 'company_info' => $preInStock['company_info'],
+ 'country' => $table_obj['country'],
+ 'id' => $preInStock['id'],
+ 'market_type' => $market_type,
+ 'source' => 0
+ ];
+ if ($market_type == 7) $hqArr['source'] = 2;
+ if ($market_type == 5) $hqArr['numeric_code'] = $preInStock['numeric_code'];
+
+
+ Db::commit();
+
+
+ return $this->toData('0', 'SUCCESS');
+ } catch (\Exception $exception) {
+ Db::rollback();
+ trace('预售股上市失败' . $exception->getMessage(), 'error');
+ return $this->toData('1', '系统繁忙', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+
+ public function updateIPOStatus($market_type, $id, $type, $status, $order_no = '')
+ {
+ $table_obj = $this->getStockModel($market_type);
+ if (empty($table_obj)) {
+ return false;
+ }
+ switch ($type) {
+ case 'trade':
+ $bool = Db::table($table_obj['stock_table'])->where('id', $id)->update([
+ 'update_time' => date('Y-m-d H:i:s'),
+ 'trade_status' => $status
+ ]);
+ if ($bool && $status == 1) {
+ Db::table($table_obj['order_table'])->where('pre_stock_id', $id)->where('status', 3)->update([
+ 'update_time' => date('Y-m-d H:i:s'),
+ 'trade_status' => 1
+ ]);
+ }
+ break;
+ case 'last_trade':
+ $bool = Db::table($table_obj['order_table'])->where('pre_stock_id', $id)->where('order_no', $order_no)->update([
+ 'update_time' => date('Y-m-d H:i:s'),
+ 'trade_status' => 1
+ ]);
+ break;
+ case 'hq':
+ $bool = Db::table($table_obj['stock_table'])->where('id', $id)->update([
+ 'update_time' => date('Y-m-d H:i:s'),
+ 'hq_status' => $status
+ ]);
+ break;
+ }
+
+ if (!$bool) {
+ trace('预售股上市修改通知状态失败-' . $id, 'error');
+ }
+ }
+
+ public function repeatNoteGo($market_type, $param)
+ {
+ $table_obj = $this->getStockModel($market_type);
+ if (empty($table_obj)) {
+ return $this->toData('1', '市场类型无效');
+ }
+ if (empty($param['id']) || !is_numeric($param['id'])) {
+ return $this->toData('1', '主键 无效');
+ }
+ if (empty($param['type'])) {
+ return $this->toData('1', '缺少参数');
+ }
+ $tape_list = $this->getStockTape($market_type);
+
+ $preInStock = Db::table($table_obj['stock_table'])->where('id', $param['id'])->where('open_status', 2)->where('is_delete', 1)->find();
+ if (empty($preInStock)) {
+ return $this->toData('1', '股票未上市');
+ }
+ if ($preInStock['hq_status'] == 2 && $param['type'] == 'hq') {
+ // 给行情发送数据
+ Queue::push('app\admin\job\SendGo', [
+ 'type' => 'hq',
+ 'stock_code' => $preInStock['stock_code'],
+ 'stock_name' => $preInStock['stock_name'],
+ 'tape' => $tape_list['tape'][$preInStock['tape']],
+ 'price' => $preInStock['price'],
+ 'isReal' => 1,
+ 'company_info' => $preInStock['company_info'],
+ 'country' => $table_obj['country'],
+ 'id' => $preInStock['id'],
+ ], 'sendGo');
+ }
+ if ($preInStock['trade_status'] == 2 && $param['type'] == 'trade') {
+ Queue::push('app\admin\job\SendGo', [
+ 'type' => 'trade',
+ 'id' => $preInStock['id'],
+ 'stock_code' => $preInStock['stock_code'],
+ 'market_type' => $market_type
+ ], 'sendGo');
+ }
+ return $this->toData('0', 'SUCCESS');
+
+ }
+
+
+ /**
+ * 处理股票IPO中签
+ */
+ public function signStockIPO($market_type)
+ {
+ try {
+ $table_obj = $this->getStockModel($market_type);
+ if (empty($table_obj)) {
+ trace('数据异常,股票市场:' . $market_type, 'info');
+ return json(["数据异常"]);
+ }
+ $now = date('Y-m-d H:i:s');
+ $preStockList = Db::table($table_obj['stock_table'])->where('is_delete', 1)
+ ->where('status', 1)
+ // 签名状态
+ ->where('sign_status', 2)
+ // 中签时间已过
+ ->whereTime('get_time', '<=', $now)
+ ->select();
+ if ($preStockList->isEmpty()) {
+ trace('没有需要处理的新股,股票市场:' . $market_type, 'info');
+ return json(["没有需要处理的新股"]);
+ }
+ foreach ($preStockList as $preStock) {
+ try {
+ // 单个股票 开始事务
+ Db::startTrans();
+ // 中签率
+ $rate = bcdiv($preStock['rate'], 100, 6);
+ $rate = number_format($rate, '6', '.', '');
+
+ // 申购的订单列表
+ $orderList = Db::table($table_obj['order_table'])->where('pre_stock_id', $preStock['id'])->whereIn('status', [1, 5])->select();
+ if (!$orderList->isEmpty()) {
+ foreach ($orderList as $order) {
+ $status = ($order['status'] == 5) ? 5 : 2; // 中签
+ $get_num = $order['get_num'] > 0 ? $order['get_num'] : ceil($order['num'] * $rate); // 计算中签 数量 * 中签率 向上取整
+ $orderPrice = number_format($order['price'], '6', '.', '');
+ $get_amount = bcmul($get_num, $orderPrice, 6);
+ $orderAmount = number_format($order['amount'], '6', '.', '');
+ $diffAmount = bcsub($orderAmount, $get_amount, 6);
+ $feeRate = number_format($order['fee_rate'], '6', '.', '');
+ $get_fee = bcmul($get_amount, $feeRate, 6);
+ $orderFee = number_format($order['fee'], '6', '.', ''); // 总手续费
+ $diff_fee = bcsub($orderFee, $get_fee, 6); // 手续费差值
+ // 修改订单数据
+ $num = Db::table($table_obj['order_table'])->where('id', $order['id'])
+ ->update([
+ 'status' => $status,
+ 'get_num' => $get_num,
+ 'get_amount' => $get_amount,
+ 'get_fee' => $get_fee,
+ 'get_time' => $now,
+ 'update_time' => $now]);
+
+ if ($num <= 0) {
+ Db::rollback();
+ trace('股票签名失败01,股票市场:' . $market_type . "股票名称:" . $preStock['stock_code'], 'info');
+ return json(["股票签名失败00"]);
+ }
+
+ //已退款订单 直接跳过
+ if ($order['status'] == 7) continue;
+
+ //后支付-未支付 直接跳过
+ if ($order['pay_type'] == 2 && $order['status'] == 5) continue;
+
+ // 回退本金
+ if ($diffAmount > 0) {
+ // 新增金额
+ $beforeAmount = Db::table($table_obj['user_table'])->where('user_id', $order['user_id'])->where('stock_id', $table_obj['stock_id'])->value('usable_num');
+ $num = Db::table($table_obj['user_table'])->where('user_id', $order['user_id'])->where('stock_id', $table_obj['stock_id'])
+ ->inc('usable_num', $diffAmount)
+ ->dec('frozen_num', $diffAmount)
+ ->update(['update_time' => $now]);
+ if ($num <= 0) {
+ Db::rollback();
+ trace('股票签名失败02,股票市场:' . $market_type . "股票名称:" . $preStock['stock_code'], 'info');
+ return json(["股票签名失败02"]);
+ }
+ // 生成日志
+ $userStockLog['user_id'] = $order['user_id'];
+ $userStockLog['change_type'] = 17;
+ $userStockLog['stock_id'] = $table_obj['stock_id'];
+ $userStockLog['before_num'] = $beforeAmount;
+ $userStockLog['change_num'] = $diffAmount;
+ $userStockLog['order_id'] = $order['order_no'];
+ $userStockLog['update_time'] = $now;
+ $userStockLog['create_time'] = $now;
+ $bool = Db::table($table_obj['log_table'])->insert($userStockLog);
+ if (!$bool) {
+ Db::rollback();
+ trace('股票签名失败03,股票市场:' . $market_type . "股票名称:" . $preStock['stock_code'], 'info');
+ return json(["股票签名失败03"]);
+ }
+ }
+
+ // 退回手续费
+ if ($diff_fee > 0) {
+ // 新增金额
+ $beforeFee = Db::table($table_obj['user_table'])->where('user_id', $order['user_id'])->where('stock_id', $table_obj['stock_id'])->value('usable_num');
+ $num = Db::table($table_obj['user_table'])->where('user_id', $order['user_id'])->where('stock_id', $table_obj['stock_id'])
+ ->inc('usable_num', $diff_fee)
+ ->dec('frozen_num', $diff_fee)
+ ->update(['update_time' => $now]);
+ if ($num <= 0) {
+ Db::rollback();
+ trace('股票签名失败04,股票市场:' . $market_type . "股票名称:" . $preStock['stock_code'], 'info');
+ return json(["股票签名失败04"]);
+ }
+
+ // 生成日志
+
+ $userStockLogFee['user_id'] = $order['user_id'];
+ $userStockLogFee['change_type'] = 18;
+ $userStockLogFee['stock_id'] = $table_obj['stock_id'];
+ $userStockLogFee['before_num'] = $beforeFee;
+ $userStockLogFee['change_num'] = $diff_fee;
+ $userStockLogFee['order_id'] = $order['order_no'];
+ $userStockLogFee['update_time'] = $now;
+ $userStockLogFee['create_time'] = $now;
+ $bool = Db::table($table_obj['log_table'])->insert($userStockLogFee);
+ if (!$bool) {
+ Db::rollback();
+ trace('股票签名失败05,股票市场:' . $market_type . "股票名称:" . $preStock['stock_code'], 'info');
+ return json(["股票签名失败05"]);
+ }
+ }
+ }
+
+ }
+ // 更新股票数据
+ $bool = Db::table($table_obj['stock_table'])->where('id', $preStock['id'])->update(['sign_status' => 1, 'update_time' => $now]);
+ if (!$bool) {
+ Db::rollback();
+ trace('股票签名失败07,股票市场:' . $market_type . "股票名称:" . $preStock['stock_code'], 'info');
+ return json(["股票签名失败07"]);
+ }
+ // 提交事务
+ Db::commit();
+
+ } catch (\Exception $exception) {
+ Db::rollback();
+ trace("股票签名失败-exception 股票市场:" . $market_type . $exception->getMessage(), 'error');
+ return json([$exception->getMessage()]);
+ }
+ }
+ return json(["SUCCESS"]);
+ } catch (\Exception $exception) {
+ trace("股票签名失败-exception 股票市场:" . $market_type . $exception->getMessage(), 'error');
+ return json([$exception->getMessage()]);
+ }
+ }
+
+ /**
+ * 股票列表
+ */
+ public function stockList($market_type, $param)
+ {
+ try {
+ $table_obj = $this->getStockModel($market_type);
+ if (empty($table_obj)) {
+ return $this->toData('1', '数据异常');
+ }
+
+ validate(StockValidate::class)->scene($table_obj['check'] . 'index')->check($param);
+ $tapeList = $this->getStockTape($market_type);
+
+ $stockCode = $param['stock_code'] ?? '';
+ $where = [];
+ $whereOr = [];
+ if (!empty($stockCode)) {
+ if ($market_type == 5) {
+ $whereOr[] = ['stock_code', 'like', '%' . $stockCode];
+ $whereOr[] = ['numeric_code', 'like', '%' . $stockCode];
+ } else {
+ $where[] = ['stock_code', 'like', '%' . $stockCode];
+ }
+ }
+
+ $list = Db::table($table_obj['list_table'])->order('id', 'desc');
+ $total = Db::table($table_obj['list_table'])->order('id', 'desc');
+
+ if (!empty($whereOr)) {
+ $list = $list->whereOr($whereOr);
+ $total = $total->whereOr($whereOr);
+ }
+
+ if (!empty($where)) {
+ $list = $list->where($where);
+ $total = $total->where($where);
+ }
+
+ $list = $list->page($param['page'], $param['limit'])->select();
+ $total = $total->count();
+
+ return $this->toData('0', 'SUCCESS', ['list' => $list, 'total' => $total, 'extend' => [
+ 'tape_list' => $tapeList['tape'],
+ 'source_list' => $tapeList['source'] ?? [],
+ ]]);
+ } catch (ValidateException $validateException) {
+ // 参数校验失败
+ $message = $validateException->getError();
+ return $this->toData('1', $message);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统繁忙', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+
+ /**
+ * 添加股票
+ */
+ public function addStock($market_type, $param)
+ {
+ try {
+ $table_obj = $this->getStockModel($market_type);
+ if (empty($table_obj)) {
+ return $this->toData('1', '数据异常');
+ }
+ validate(StockValidate::class)->scene($table_obj['check'] . 'add')->check($param);
+ $info = '';
+ if (isset($param['info']) && is_string($param['info'])) {
+ $info = $param['info'];
+ }
+ $tapeList = $this->getStockTape($market_type);
+
+ // 判断股票交易所
+ $tape = '0';
+ if (isset($param['tape']) && in_array($param['tape'], array_keys($tapeList['tape']))) {
+ $tape = $param['tape'];
+ }
+
+ if (empty($param['yesterday_close']) || !is_numeric($param['yesterday_close']) || $param['yesterday_close'] <= 0) {
+ return $this->toData('1', '昨日收盘价错误');
+ }
+ if (strpos($param['stock_code'], ':') !== false) {
+ $param['stock_code'] = explode(':', $param['stock_code'])[1];
+ }
+ if ($market_type != 3) {
+ $stock_code = $tapeList['tape'][$tape] . ":" . $param['stock_code'];
+ } else {
+ $stock_code = $param['stock_code'];
+ }
+
+ // 判断股票代码是否已经存在
+ $count = Db::table($table_obj['list_table'])->where('stock_code', $stock_code)->count();
+ if ($count > 0) {
+ return $this->toData('1', '股票代码已经存在');
+ }
+
+ $source = 0;
+ if ($market_type == 7) {
+ $stockList['source'] = $source = $param['source'] ?? 1;
+ }
+ // 给行情推送
+ $bool = $this->sendNewStockToGo($table_obj['country'], $stock_code, $stock_code, $param['stock_name'], $tapeList['tape'][$tape], $param['yesterday_close'], 1, '', $source, $param['numeric_code'] ?? '0');
+ if (!$bool) {
+ return $this->toData('1', '数据设置成功 但给行情推送数据异常', []);
+ }
+ // 新增数据
+ $stockList['stock_name'] = $param['stock_name'];
+ $stockList['stock_code'] = $stock_code;
+ $stockList['status'] = $param['status'];
+ $stockList['keep_decimal'] = $param['keep_decimal'];
+ $stockList['forced_closure'] = $param['forced_closure'];
+ $stockList['up_limit'] = $param['up_limit'];
+ $stockList['down_limit'] = $param['down_limit'];
+ $stockList['tape'] = $tape; // 交易所类型
+ $stockList['info'] = $info;
+ $stockList['yesterday_close'] = $param['yesterday_close'];
+ $stockList['create_time'] = date('Y-m-d H:i:s');
+ $stockList['update_time'] = date('Y-m-d H:i:s');
+ if ($market_type == 5) $stockList['numeric_code'] = $param['numeric_code'] ?? '0';
+
+ $bool = Db::table($table_obj['list_table'])->insert($stockList);
+ if ($bool) {
+ // 新增缓存
+ $list_key = $table_obj['redis_key'] . $stock_code;
+ $redis = $this->getRedis();
+ $redis->del($list_key);
+ $redis_arr = [
+ 'stock_name' => $param['stock_name'],
+ 'stock_code' => $stock_code,
+ 'status' => $param['status'],
+ 'keep_decimal' => $param['keep_decimal'],
+ 'forced_closure' => $param['forced_closure'],
+ 'up_limit' => $param['up_limit'],
+ 'down_limit' => $param['down_limit'],
+ 'info' => $info,
+ 'tape' => $tape,
+ ];
+ if ($market_type == 5) $redis_arr['numeric_code'] = $param['numeric_code'] ?? '0';
+ $redis->hMset($list_key, $redis_arr);
+ }
+ return $this->toData('0', 'SUCCESS', []);
+ } catch (ValidateException $validateException) {
+ $message = $validateException->getError();
+ return $this->toData('1', $message);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统繁忙', []);
+ }
+ }
+
+ /**
+ * 编辑股票
+ */
+ public function editStock($market_type, $param)
+ {
+ try {
+ $table_obj = $this->getStockModel($market_type);
+ if (empty($table_obj)) {
+ return $this->toData('1', '数据异常');
+ }
+ validate(StockValidate::class)->scene($table_obj['check'] . 'edit')->check($param);
+ $stockList = Db::table($table_obj['list_table'])->where('id', $param['id'])->find();
+ if (empty($stockList)) {
+ return $this->toData('1', '目标不存在', []);
+ }
+
+ $info = '';
+ if (isset($param['info']) && is_string($param['info'])) {
+ $info = $param['info'];
+ }
+ $tapeList = $this->getStockTape($market_type);
+ // 判断股票交易所
+ $tape = '0';
+ if (isset($param['tape']) && in_array($param['tape'], array_keys($tapeList['tape']))) {
+ $tape = $param['tape'];
+ }
+
+ if (empty($param['yesterday_close']) || !is_numeric($param['yesterday_close']) || $param['yesterday_close'] <= 0) {
+ return $this->toData('1', '昨日收盘价错误');
+ }
+
+ if (strpos($param['stock_code'], ':') !== false) {
+ $param['stock_code'] = explode(':', $param['stock_code'])[1];
+ }
+ if ($market_type != 3) {
+ $stock_code = $tapeList['tape'][$param['tape']] . ":" . $param['stock_code'];
+ } else {
+ $stock_code = $param['stock_code'];
+ }
+ $old_code = $stockList['stock_code'];
+ // 判断股票代码是否已经存在
+ $count = Db::table($table_obj['list_table'])->where('stock_code', $stock_code)->where('id', '<>', $param['id'])->count();
+ if ($count > 0) {
+ return $this->toData('1', '股票代码已经存在');
+ }
+
+ $source = 0;
+ if ($stock_code != $old_code || ($market_type == 7 && $param['source'] != $stockList['source'])) {
+ if ($market_type == 7) {
+ $stockList['source'] = $source = $param['source'] ?? 1;
+ }
+ // 给行情推送
+ $bool = $this->sendNewStockToGo($table_obj['country'], $stock_code, $old_code, $param['stock_name'], $tapeList['tape'][$tape], $param['yesterday_close'], 1, '', $source, $param['numeric_code'] ?? '0');
+ if (!$bool) {
+ return $this->toData('1', '数据设置成功 但给行情推送数据异常', []);
+ }
+ }
+
+ if ($stock_code != $old_code) {
+ // 通知交易
+ $bool = $this->sendUpdateCodeGo($stock_code, $old_code, $market_type);
+ if (!$bool) {
+ return $this->toData('1', '数据设置成功 但给交易推送数据异常', []);
+ }
+ //插针
+ $stockPrices = StockPricesSettingModel::where('market_type', $market_type)->where('stock_id', $param['id'])->find();
+ if (!empty($stockPrices)) {
+ // 添加缓存
+ $old_key = 'STOCK_PRICES:' . $stockPrices->market_type . ':' . $old_code;
+ $new_key = 'STOCK_PRICES:' . $stockPrices->market_type . ':' . $stock_code;
+ $redis = $this->getRedis();
+ $redis->del($old_key);
+ $redis->hMSet($new_key, [
+ 'market_type' => $stockPrices->market_type,
+ 'stock_id' => $stockPrices->stock_id,
+ 'stock_code' => $stock_code,
+ 'status' => $stockPrices->status,
+ 'price' => $stockPrices->price,
+ ]);
+ }
+ //IPO
+ $stockIPO = Db::table($table_obj['stock_table'])->where('stock_code', $old_code)->find();
+ if (!empty($stockIPO)) {
+ Db::table($table_obj['stock_table'])->where('stock_code', $old_code)->update(['stock_code' => $stock_code, 'update_time' => date('Y-m-d H:i:s')]);
+ }
+ }
+
+ // 修改数据
+ $stockList['stock_name'] = $param['stock_name'];
+ $stockList['stock_code'] = $stock_code;
+ $stockList['status'] = $param['status'];
+ $stockList['keep_decimal'] = $param['keep_decimal'];
+ $stockList['forced_closure'] = $param['forced_closure'];
+ $stockList['up_limit'] = $param['up_limit'];
+ $stockList['down_limit'] = $param['down_limit'];
+ $stockList['info'] = $info;
+ $stockList['tape'] = $tape;
+ $stockList['update_time'] = date('Y-m-d H:i:s');
+ $stockList['yesterday_close'] = $param['yesterday_close'];
+ if ($market_type == 5) $stockList['numeric_code'] = $param['numeric_code'] ?? '0';
+
+ $bool = Db::table($table_obj['list_table'])->where('id', $param['id'])->update($stockList);
+ if ($bool) {
+ // 新增缓存
+ $old_key = $table_obj['redis_key'] . $old_code;
+ $new_key = $table_obj['redis_key'] . $stock_code;
+ $redis = $this->getRedis();
+ $redis->del($old_key);
+ $redis_arr = [
+ 'stock_name' => $param['stock_name'],
+ 'stock_code' => $stock_code,
+ 'status' => $param['status'],
+ 'keep_decimal' => $param['keep_decimal'],
+ 'forced_closure' => $param['forced_closure'],
+ 'up_limit' => $param['up_limit'],
+ 'down_limit' => $param['down_limit'],
+ 'info' => $info,
+ 'tape' => $tape,
+ ];
+ if ($market_type == 5) $redis_arr['numeric_code'] = $param['numeric_code'] ?? '0';
+ $redis->hMset($new_key, $redis_arr);
+ }
+
+ return $this->toData('0', 'SUCCESS', []);
+ } catch (ValidateException $validateException) {
+ $message = $validateException->getError();
+ return $this->toData('1', $message);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统繁忙', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+
+ /**
+ * 自动添加股票
+ */
+ public function autoAddStock($param)
+ {
+ try {
+ $market_type = intval($param['country']);
+ $table_obj = $this->getStockModel($market_type);
+ if (empty($table_obj)) {
+ return $this->toData('1', '数据异常');
+ }
+ validate(StockValidate::class)->scene('stock_auto_add')->check($param);
+
+ $tapeList = $this->getStockTape($market_type);
+
+ $tape_arr = array_flip($tapeList['tape']);
+
+ // 判断股票交易所
+ $tape = '0';
+ if (isset($param['tape']) && in_array($param['tape'], array_keys($tape_arr))) {
+ $tape = $tape_arr[$param['tape']];
+ }
+
+ $stock_code = $param['stock_code'];
+ // 判断股票代码是否已经存在
+ $count = Db::table($table_obj['list_table'])->where('stock_code', $stock_code)->count();
+ if ($count > 0) {
+ return $this->toData('1', '股票代码已经存在');
+ }
+ // 新增数据
+ $stockList['stock_name'] = $param['stock_name'];
+ $stockList['stock_code'] = $stock_code;
+ $stockList['status'] = 1;
+ $stockList['keep_decimal'] = 4;
+ $stockList['forced_closure'] = 30;
+ $stockList['up_limit'] = 30;
+ $stockList['down_limit'] = 30;
+ $stockList['tape'] = $tape; // 交易所类型
+ $stockList['info'] = '';
+ $stockList['yesterday_close'] = 0;
+ $stockList['create_time'] = date('Y-m-d H:i:s');
+ $stockList['update_time'] = date('Y-m-d H:i:s');
+
+ $bool = Db::table($table_obj['list_table'])->insert($stockList);
+ if ($bool) {
+ // 新增缓存
+ $list_key = $table_obj['redis_key'] . $stock_code;
+ $redis = $this->getRedis();
+ $redis->del($list_key);
+ $redis->hMset($list_key, [
+ 'stock_name' => $stockList['stock_name'],
+ 'stock_code' => $stock_code,
+ 'status' => $stockList['status'],
+ 'keep_decimal' => $stockList['keep_decimal'],
+ 'forced_closure' => $stockList['forced_closure'],
+ 'up_limit' => $stockList['up_limit'],
+ 'down_limit' => $stockList['down_limit'],
+ 'info' => '',
+ 'tape' => $tape,
+ ]);
+ }
+ return $this->toData('0', 'SUCCESS', []);
+ } catch (ValidateException $validateException) {
+ $message = $validateException->getError();
+ return $this->toData('1', $message);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统繁忙', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+
+
+
+ /**
+ * 取消上市
+ */
+ public function cancelIPO($market_type,$param){
+ $table_obj = $this->getStockModel($market_type);
+ $redis = $this->getRedis();
+ if (empty($table_obj)) {
+ return false;
+ }
+ $preStock = Db::table($table_obj['stock_table'])->where('is_delete', 1)
+ ->where('status', 1)
+ ->where('id', $param['pre_id'])
+ // 签名状态
+ ->where('sign_status', 1)
+ ->where('open_status', 1)
+ ->find();
+ if(empty($preStock)){
+ return $this->toData('1', '数据异常');
+ }
+
+ //1、2已支付,5、6未支付可能存在借款
+ $order_list = Db::table($table_obj['order_table'])->where('pre_stock_id', $param['pre_id'])
+ ->whereIn('status',[1,2,5,6])
+ ->select();
+
+ $now = date('Y-m-d H:i:s');
+ foreach ($order_list as $order){
+ Db::startTrans();
+ $total_num=$order['amount']+$order['fee'];
+ //查询订单有没有欠款
+ $user_arrears=UserArrearsModel::where('order_no', $order['order_no'])->where('status',0)->where('user_id', $order['user_id'])->find();
+ if($user_arrears){
+ $user_arrears=$user_arrears->toArray();
+ if($user_arrears['is_add']==1){
+ //扣除冻结,不加可用
+ $updateNum = Db::table($table_obj['user_table'])->where('stock_id', $table_obj['stock_id'])->where('user_id', $order['user_id'])
+ ->where('frozen_num', '>=', $total_num)
+ ->dec('frozen_num',$total_num)
+ ->update(['update_time' => $now]);
+ if(!$updateNum){
+ Db::rollback();
+ trace('给用户ID:' . $order['user_id'] . "解冻资金异常" . $order['order_no'], 'error');
+ continue;
+ }
+ }
+ $update_bool=UserArrearsModel::where('order_no', $order['order_no'])->where('user_id', $order['user_id'])
+ ->update([
+ 'update_time'=>$now,
+ 'status'=>1
+ ]);
+ if(!$update_bool){
+ Db::rollback();
+ trace('给用户ID:' . $order['user_id'] . "更新贷款订单异常" . $order['order_no'], 'error');
+ continue;
+ }
+
+ $status=8;
+ }else{
+ //扣除冻结 加可用
+ $updateNum = Db::table($table_obj['user_table'])->where('stock_id', $table_obj['stock_id'])->where('user_id', $order['user_id'])
+ ->where('frozen_num', '>=', $total_num)
+ ->inc('usable_num', $total_num)
+ ->dec('frozen_num',$total_num)
+ ->update(['update_time' => $now]);
+ if(!$updateNum){
+ Db::rollback();
+ trace('给用户ID:' . $order['user_id'] . "解冻资金异常" . $order['order_no'], 'error');
+ continue;
+ }
+ $status=7;
+ }
+ //更新状态
+ $bool_status = Db::table($table_obj['order_table'])->where('id', $order['id'])->update([
+ 'status' => $status,
+ 'update_time' => $now
+ ]);
+ if (!$bool_status) {
+ Db::rollback();
+ trace('更新订单状态异常' . $order['order_no'], 'error');
+ continue;
+ }
+ //删除缓存订单
+ $key = "USER:ARREAR:ORDER:" . $order['order_no'];
+ $redis->del($key);
+ Db::commit();
+ }
+ $bool = Db::table($table_obj['stock_table'])->where('id', $param['pre_id'])->update([
+ 'is_delete'=>2,
+ 'update_time' => $now
+ ]);
+ if($bool){
+ return $this->toData('0', 'SUCCESS');
+ }else{
+ return $this->toData('1', '数据异常');
+ }
+ }
+ // 美股列表
+ public function getTradeNameList($market_type)
+ {
+ try {
+ $table_obj = $this->getStockModel($market_type);
+ if (empty($table_obj)) {
+ return $this->toData('1', '数据异常');
+ }
+ $list = Db::table($table_obj['list_table'])->where('status', 1)->order('id', 'desc')->column('stock_name', 'id');
+ return $this->toData('0', 'SUCCESS', ['list' => $list]);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统繁忙', []);
+ }
+ }
+
+ public function getStockModel($market_type)
+ {
+ //3美股、4印尼股、5马股、6泰股、7印度股、9新加坡股、12港股、14英股
+ $prefix = env('database.prefix');
+ switch ($market_type) {
+ case 3:
+ $result = [
+ 'stock_table' => $prefix . 'pre_us_stock',
+ 'order_table' => $prefix . 'user_us_pre_stock_order',
+ 'user_table' => $prefix . 'user_stock',
+ 'log_table' => $prefix . 'user_stock_log',
+ 'list_table' => $prefix . 'stock_list',
+ 'trade_table' => $prefix . 'stock_trade',
+ 'give_order_table' => $prefix . 'user_us_give_stock_order',
+ 'redis_key' => 'US:STOCK:LIST:',
+ 'stock_id' => 'USD',
+ 'country' => 'US',
+ 'check' => 'us_stock_',
+ ];
+ break;
+ case 4:
+ $result = [
+ 'stock_table' => $prefix . 'pre_idn_stock',
+ 'order_table' => $prefix . 'user_idn_pre_stock_order',
+ 'user_table' => $prefix . 'user_stock_idn',
+ 'log_table' => $prefix . 'user_stock_idn_log',
+ 'list_table' => $prefix . 'stock_idn_list',
+ 'trade_table' => $prefix . 'stock_idn_trade',
+ 'give_order_table' => $prefix . 'user_idn_give_stock_order',
+ 'redis_key' => 'IDN:STOCK:LIST:',
+ 'stock_id' => 'IDR',
+ 'country' => 'Indonesia',
+ 'check' => 'idn_stock_',
+ ];
+ break;
+ case 5:
+ $result = [
+ 'stock_table' => $prefix . 'pre_mys_stock',
+ 'order_table' => $prefix . 'user_mys_pre_stock_order',
+ 'user_table' => $prefix . 'user_stock_mys',
+ 'log_table' => $prefix . 'user_stock_mys_log',
+ 'list_table' => $prefix . 'stock_mys_list',
+ 'trade_table' => $prefix . 'stock_mys_trade',
+ 'give_order_table' => $prefix . 'user_mys_give_stock_order',
+ 'redis_key' => 'MYS:STOCK:LIST:',
+ 'stock_id' => 'MYR',
+ 'country' => 'Malaysia',
+ 'check' => 'mys_stock_',
+ ];
+ break;
+ case 6:
+ $result = [
+ 'stock_table' => $prefix . 'pre_tha_stock',
+ 'order_table' => $prefix . 'user_tha_pre_stock_order',
+ 'user_table' => $prefix . 'user_stock_tha',
+ 'log_table' => $prefix . 'user_stock_tha_log',
+ 'list_table' => $prefix . 'stock_tha_list',
+ 'trade_table' => $prefix . 'stock_tha_trade',
+ 'give_order_table' => $prefix . 'user_tha_give_stock_order',
+ 'redis_key' => 'THA:STOCK:LIST:',
+ 'stock_id' => 'THB',
+ 'country' => 'Thailand',
+ 'check' => 'tha_stock_',
+ ];
+ break;
+ case 7:
+ $result = [
+ 'stock_table' => $prefix . 'pre_in_stock',
+ 'order_table' => $prefix . 'user_in_pre_stock_order',
+ 'user_table' => $prefix . 'user_stock_in',
+ 'log_table' => $prefix . 'user_stock_in_log',
+ 'list_table' => $prefix . 'stock_in_list',
+ 'trade_table' => $prefix . 'stock_in_trade',
+ 'give_order_table' => $prefix . 'user_in_give_stock_order',
+ 'redis_key' => 'IN:STOCK:LIST:',
+ 'stock_id' => 'INR',
+ 'country' => 'India',
+ 'check' => 'idn_stock_',
+ ];
+ break;
+ case 9:
+ $result = [
+ 'stock_table' => $prefix . 'pre_sgd_stock',
+ 'order_table' => $prefix . 'user_sgd_pre_stock_order',
+ 'user_table' => $prefix . 'user_stock_sgd',
+ 'log_table' => $prefix . 'user_stock_sgd_log',
+ 'list_table' => $prefix . 'stock_sgd_list',
+ 'trade_table' => $prefix . 'stock_sgd_trade',
+ 'give_order_table' => $prefix . 'user_sgd_give_stock_order',
+ 'redis_key' => 'SGD:STOCK:LIST:',
+ 'stock_id' => 'SGD',
+ 'country' => 'Singapore',
+ 'check' => 'sgd_stock_',
+ ];
+ break;
+ case 12:
+ $result = [
+ 'stock_table' => $prefix . 'pre_hkd_stock',
+ 'order_table' => $prefix . 'user_hkd_pre_stock_order',
+ 'user_table' => $prefix . 'user_stock_hkd',
+ 'log_table' => $prefix . 'user_stock_hkd_log',
+ 'list_table' => $prefix . 'stock_hkd_list',
+ 'trade_table' => $prefix . 'stock_hkd_trade',
+ 'give_order_table' => $prefix . 'user_hkd_give_stock_order',
+ 'redis_key' => 'HKD:STOCK:LIST:',
+ 'stock_id' => 'HKD',
+ 'country' => 'HongKong',
+ 'check' => 'hk_stock_',
+ ];
+ break;
+ case 14:
+ $result = [
+ 'stock_table' => $prefix . 'pre_gbx_stock',
+ 'order_table' => $prefix . 'user_gbx_pre_stock_order',
+ 'user_table' => $prefix . 'user_stock_gbx',
+ 'log_table' => $prefix . 'user_stock_gbx_log',
+ 'list_table' => $prefix . 'stock_gbx_list',
+ 'trade_table' => $prefix . 'stock_gbx_trade',
+ 'give_order_table' => $prefix . 'user_gbx_give_stock_order',
+ 'redis_key' => 'UK:STOCK:LIST:',
+ 'stock_id' => 'GBX',
+ 'country' => 'UK',
+ 'check' => 'gbx_stock_',
+ ];
+ break;
+ case 15:
+ $result = [
+ 'stock_table' => $prefix . 'pre_fur_stock',
+ 'order_table' => $prefix . 'user_fur_pre_stock_order',
+ 'user_table' => $prefix . 'user_stock_fur',
+ 'log_table' => $prefix . 'user_stock_fur_log',
+ 'list_table' => $prefix . 'stock_fur_list',
+ 'trade_table' => $prefix . 'stock_fur_trade',
+ 'give_order_table' => $prefix . 'user_fur_give_stock_order',
+ 'redis_key' => 'FUR:STOCK:LIST:',
+ 'stock_id' => 'EUR',
+ 'country' => 'FUR',
+ 'check' => 'fur_stock_',
+ ];
+ break;
+ case 16:
+ $result = [
+ 'stock_table' => $prefix . 'pre_eur_stock',
+ 'order_table' => $prefix . 'user_eur_pre_stock_order',
+ 'user_table' => $prefix . 'user_stock_eur',
+ 'log_table' => $prefix . 'user_stock_eur_log',
+ 'list_table' => $prefix . 'stock_eur_list',
+ 'trade_table' => $prefix . 'stock_eur_trade',
+ 'give_order_table' => $prefix . 'user_eur_give_stock_order',
+ 'redis_key' => 'EUR:STOCK:LIST:',
+ 'stock_id' => 'EUR',
+ 'country' => 'EUR',
+ 'check' => 'eur_stock_',
+ ];
+ break;
+ case 17:
+ $result = [
+ 'stock_table' => $prefix . 'pre_brl_stock',
+ 'order_table' => $prefix . 'user_brl_pre_stock_order',
+ 'user_table' => $prefix . 'user_stock_brl',
+ 'log_table' => $prefix . 'user_stock_brl_log',
+ 'list_table' => $prefix . 'stock_brl_list',
+ 'trade_table' => $prefix . 'stock_brl_trade',
+ 'give_order_table' => $prefix . 'user_brl_give_stock_order',
+ 'redis_key' => 'BR:STOCK:LIST:',
+ 'stock_id' => 'BRL',
+ 'country' => 'BRL',
+ 'check' => 'brl_stock_',
+ ];
+ break;
+ case 18:
+ $result = [
+ 'stock_table' => $prefix . 'pre_jp_stock',
+ 'order_table' => $prefix . 'user_jp_pre_stock_order',
+ 'user_table' => $prefix . 'user_stock_jp',
+ 'log_table' => $prefix . 'user_stock_jp_log',
+ 'list_table' => $prefix . 'stock_jp_list',
+ 'trade_table' => $prefix . 'stock_jp_trade',
+ 'give_order_table' => $prefix . 'user_jp_give_stock_order',
+ 'redis_key' => 'JP:STOCK:LIST:',
+ 'stock_id' => 'JPY',
+ 'country' => 'Japan',
+ 'check' => 'jp_stock_',
+ ];
+ break;
+ default:
+ $result = [];
+ break;
+ }
+ return $result;
+ }
+
+ public function getStockTape($market_type)
+ {
+ //3美股、4印尼股、5马股、6泰股、7印度股、9新加坡股、12港股
+ $result = [];
+ switch ($market_type) {
+ case 3:
+ $result = [
+ 'tape' => StockListModel::$tapeList,
+ 'type' => PreUsStockModel::$stockTypeList,
+ ];
+ break;
+ case 4:
+ $result = [
+ 'tape' => StockIdnListModel::$tapeList,
+ 'type' => PreIdnStockModel::$stockTypeList,
+ ];
+ break;
+ case 5:
+ $result = [
+ 'tape' => StockMysListModel::$tapeList,
+ 'type' => PreMysStockModel::$stockTypeList,
+ ];
+ break;
+ case 6:
+ $result = [
+ 'tape' => StockThaListModel::$tapeList,
+ 'type' => PreThaStockModel::$stockTypeList,
+ ];
+ break;
+ case 7:
+ $result = [
+ 'tape' => StockInListModel::$tapeList,
+ 'type' => PreInStockModel::$stockTypeList,
+ 'source' => StockInListModel::SOURCE_LIST,
+ ];
+ break;
+ case 9:
+ $result = [
+ 'tape' => StockSgdListModel::$tapeList,
+ 'type' => PreSgdStockModel::$stockTypeList,
+ ];
+ break;
+ case 12:
+ $result = [
+ 'tape' => StockHkdListModel::$tapeList,
+ 'type' => PreHkdStockModel::$stockTypeList,
+ ];
+ break;
+ case 14:
+ $result = [
+ 'tape' => StockGBXListModel::$tapeList,
+ 'type' => PreGBXStockModel::$stockTypeList,
+ ];
+ break;
+ case 15:
+ $result = [
+ 'tape' => StockFurListModel::$tapeList,
+ 'type' => PreFurStockModel::$stockTypeList,
+ ];
+ break;
+ case 16:
+ $result = [
+ 'tape' => StockEurListModel::$tapeList,
+ 'type' => PreEurStockModel::$stockTypeList,
+ ];
+ break;
+ case 17:
+ $result = [
+ 'tape' => StockBrlListModel::$tapeList,
+ 'type' => PreBrlStockModel::$stockTypeList,
+ ];
+ break;
+ case 18:
+ $result = [
+ 'tape' => StockJpListModel::$tapeList,
+ 'type' => PreJpStockModel::$stockTypeList,
+ ];
+ break;
+ }
+ return $result;
+ }
+
+}
\ No newline at end of file
diff --git a/app/admin/service/setting/LanguageService.php b/app/admin/service/setting/LanguageService.php
new file mode 100644
index 0000000..01dca80
--- /dev/null
+++ b/app/admin/service/setting/LanguageService.php
@@ -0,0 +1,123 @@
+select();
+ $rows = [];
+ if(!$list->isEmpty()){
+ $rows = $list->toArray();
+ }
+ return $this->toData('0', 'SUCCESS', ['list' => $rows, 'total' => count($rows)]);
+ }catch (\Exception $exception){
+ return $this->toData('1', '系统繁忙', []);
+ }
+ }
+
+ public function add($param)
+ {
+
+ try {
+ if(empty($param['language_name']) || !is_string($param['language_name']) || strlen($param['language_name']) > 20){
+ return $this->toData('1','参错错误');
+ }
+ if(empty($param['language_code']) || !is_string($param['language_code']) || strlen($param['language_code']) > 20){
+ return $this->toData('1','参错错误');
+ }
+ if(empty($param['china_name']) || !is_string($param['china_name']) || strlen($param['china_name']) > 20){
+ return $this->toData('1','参错错误');
+ }
+
+ $count = LanguageSettingModel::where('language_code', $param['language_code'])->count();
+ if($count > 0){
+ return $this->toData('1','语言代码已经存在');
+ }
+
+ $lang = new LanguageSettingModel;
+ $lang->language_name = $param['language_name'];
+ $lang->language_code = $param['language_code'];
+ $lang->china_name = $param['china_name'];
+ $lang->save();
+ return $this->toData('0', 'SUCCESS', []);
+ }catch (\Exception $exception){
+ return $this->toData('1', '系统繁忙', [$exception->getMessage()]);
+ }
+ }
+
+ public function edit($param)
+ {
+ try {
+ if(empty($param['id']) || !is_numeric($param['id'])){
+ return $this->toData('1','参错错误1');
+ }
+
+ $lang = LanguageSettingModel::where('id', $param['id'])->find();
+ if(empty($lang)){
+ return $this->toData('1','目标不存在');
+ }
+
+ if(empty($param['language_name']) || !is_string($param['language_name']) || strlen($param['language_name']) > 20){
+ return $this->toData('1','参错错误2');
+ }
+ if(empty($param['language_code']) || !is_string($param['language_code']) || strlen($param['language_code']) > 20){
+ return $this->toData('1','参错错误3');
+ }
+ if(empty($param['china_name']) || !is_string($param['china_name']) || strlen($param['china_name']) > 20){
+ return $this->toData('1','参错错误4');
+ }
+
+ $count = LanguageSettingModel::where('language_code', $param['language_code'])
+ ->where('id', '<>', $param['id'])
+ ->count();
+ if($count > 0){
+ return $this->toData('1','语言代码已经存在');
+ }
+
+ $lang->language_name = $param['language_name'];
+ $lang->language_code = $param['language_code'];
+ $lang->china_name = $param['china_name'];
+ $lang->save();
+ return $this->toData('0', 'SUCCESS', []);
+ }catch (\Exception $exception){
+ return $this->toData('1', '系统繁忙', []);
+ }
+ }
+
+
+ public function del($param)
+ {
+ try {
+ if(empty($param['id']) || !is_numeric($param['id'])){
+ return $this->toData('1','参错错误');
+ }
+
+ $lang = LanguageSettingModel::where('id', $param['id'])->find();
+ if(empty($lang)){
+ return $this->toData('1','目标不存在');
+ }
+
+ $lang->delete();
+ return $this->toData('0','SUCCESS');
+ }catch (\Exception $exception){
+ return $this->toData('1', '系统繁忙', []);
+ }
+ }
+
+ public function getNameList()
+ {
+ try {
+ $list = LanguageSettingModel::order('id', 'desc')->column('language_name', 'id');
+ return $this->toData('0', 'SUCCESS', ['list' => $list]);
+ }catch (\Exception $exception){
+ return $this->toData('1', '系统繁忙', []);
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/admin/service/setting/MarketService.php b/app/admin/service/setting/MarketService.php
new file mode 100644
index 0000000..cfe4eff
--- /dev/null
+++ b/app/admin/service/setting/MarketService.php
@@ -0,0 +1,161 @@
+order('id', 'desc')
+ ->select();
+ $rows = [];
+ if(!$list->isEmpty()){
+ foreach ($list as $item){
+ if(empty($rows[$item['trade_name']])){
+ $rows[$item['trade_name']] = [
+ 'trade_name' => $item['trade_name'],
+ 'begin_time' => $item['begin_time'],
+ 'end_time' => $item['end_time'],
+ 'max_price' => $item['max_price'],
+ 'step' => $item['step'],
+ ];
+ }
+ }
+ }
+
+ $rows = array_values($rows);
+ return $this->toData('0','SUCCSS',['list' => $rows, 'total' => count($rows)]);
+ }catch (\Exception $exception){
+ return $this->toData('1', '系统繁忙', []);
+ }
+ }
+
+ // 详情
+ public function detail($param)
+ {
+ try {
+ if(empty($param['trade_name']) || !is_string($param['trade_name'])){
+ return $this->toData('1', '参数错误');
+ }
+ $list = ContractMarketModel::where('type', 1)
+ ->where('trade_name', $param['trade_name'])
+ ->order('id', 'desc')->select();
+ $rows = [];
+ if(!$list->isEmpty()){
+ foreach ($list as $item){
+ $rows[] = [
+ 'id' => $item['id'],
+ 'trade_name' => $item['trade_name'],
+ 'end_time' => $item['end_time'],
+ 'begin_time' => $item['begin_time'],
+ 'max_price' => $item['max_price'],
+ 'step' => $item['step'],
+ ];
+ }
+ }
+ return $this->toData('0','SUCCSS',['list' => $rows]);
+ }catch (\Exception $exception){
+ return $this->toData('1', '系统繁忙', [$exception->getMessage()]);
+ }
+ }
+
+ // 新增
+ public function add($param)
+ {
+ try {
+ // 参数校验
+ validate(MarketValidate::class)->scene('add')->check($param);
+
+ // 必须大于当前时间
+ if(strtotime($param['end_time']) - time() <= 0){
+ return $this->toData('1','时间无效');
+ }
+
+
+ if((strtotime($param['begin_time']) - time()) <= 0 || (strtotime($param['end_time']) - strtotime($param['begin_time'])) <= 0){
+ return $this->toData('1','开始时间无效');
+ }
+
+ $market = new ContractMarketModel;
+ $market->trade_name = $param['trade_name'];
+ $market->begin_time = $param['begin_time'];
+ $market->end_time = $param['end_time'];
+ $market->max_price = $param['max_price'];
+ $market->type = 1;
+ $market->save();
+
+ return $this->toData('0','SUCCESS');
+ }catch (ValidateException $validateException){
+ return $this->toData('1', $validateException->getMessage(), []);
+ }catch (\Exception $exception){
+ return $this->toData('1', '系统繁忙', [$exception->getMessage()]);
+ }
+ }
+
+
+ // 编辑
+ public function edit($param)
+ {
+ try {
+ // 参数校验
+ validate(MarketValidate::class)->scene('edit')->check($param);
+
+ // 目标
+ $market = ContractMarketModel::where('id', $param['id'])->where('type', 1)->find();
+ if(empty($market)){
+ return $this->toData('1','目标不存在');
+ }
+
+ // 必须大于当前时间
+ if(strtotime($param['end_time']) - time() <= 0){
+ return $this->toData('1','时间无效');
+ }
+
+ if((strtotime($param['begin_time']) - time()) <= 0 || (strtotime($param['end_time']) - strtotime($param['begin_time'])) <= 0){
+ return $this->toData('1','开始时间无效');
+ }
+
+
+ $market->trade_name = $param['trade_name'];
+ $market->begin_time = $param['begin_time'];
+ $market->end_time = $param['end_time'];
+ $market->max_price = $param['max_price'];
+ $market->save();
+
+ return $this->toData('0','SUCCESS');
+ }catch (ValidateException $validateException){
+ return $this->toData('1', $validateException->getMessage(), []);
+ }catch (\Exception $exception){
+ return $this->toData('1', '系统繁忙', []);
+ }
+ }
+
+ // 删除
+ public function del($param)
+ {
+ try {
+ // 参数校验
+ validate(MarketValidate::class)->scene('del')->check($param);
+
+ // 目标
+ $market = ContractMarketModel::where('id', $param['id'])->where('type',1)->find();
+ if(empty($market)){
+ return $this->toData('1','目标不存在');
+ }
+
+ $market->delete();
+ return $this->toData('0','SUCCESS');
+ }catch (ValidateException $validateException){
+ return $this->toData('1', $validateException->getMessage(), []);
+ }catch (\Exception $exception){
+ return $this->toData('1', '系统繁忙', []);
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/admin/service/setting/OptionInService.php b/app/admin/service/setting/OptionInService.php
new file mode 100644
index 0000000..ca77300
--- /dev/null
+++ b/app/admin/service/setting/OptionInService.php
@@ -0,0 +1,327 @@
+scene('in_option_index')->check($param);
+
+ $stockCode = $param['stock_code'] ?? '';
+ $where = [];
+ if ($stockCode) {
+ $where[] = ['stock_code', '=', $stockCode];
+ }
+ $list = StockOptionInrListModel::where($where)->page($param['page'], $param['limit'])->append(['tape_text', 'status_text'])->order('id', 'desc')->select();
+ $total = StockOptionInrListModel::order('id', 'desc')->where($where)->count();
+ $rows = [];
+ if (!$list->isEmpty()) {
+ $rows = $list->toArray();
+ }
+ return $this->toData('0', 'SUCCESS', ['list' => $rows, 'total' => $total, 'extend' => [
+ 'tape_list' => StockOptionInrListModel::$tapeListText,
+ 'status_list' => StockOptionInrListModel::$statusList
+ ]]);
+ } catch (ValidateException $validateException) {
+ // 参数校验失败
+ $message = $validateException->getError();
+ return $this->toData('1', $message);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统繁忙', []);
+ }
+ }
+
+ public function add($param)
+ {
+ try {
+ validate(StockValidate::class)->scene('in_option_add')->check($param);
+ $info = '';
+ if (isset($param['info']) && is_string($param['info'])) {
+ $info = $param['info'];
+ }
+
+ // 判断股票交易所
+ $tape = '0';
+ if (isset($param['tape']) && in_array($param['tape'], array_keys(StockOptionInrListModel::$tapeList))) {
+ $tape = $param['tape'];
+ }
+
+ // 判断股票代码是否已经存在
+ $count = StockOptionInrListModel::where('stock_code', $param['stock_code'])->count();
+ if ($count > 0) {
+ return $this->toData('1', '股票代码已经存在');
+ }
+
+ // 新增数据
+ $stockList = new StockOptionInrListModel;
+ $stockList->stock_name = $param['stock_name'];
+ $stockList->stock_code = $param['stock_code'];
+ $stockList->status = $param['status'];
+ $stockList->rate = $param['rate'] ?? 0;
+ $stockList->keep_decimal = $param['keep_decimal'] ?? 4;
+ $stockList->forced_closure = $param['forced_closure'] ?? 30;
+ $stockList->up_limit = $param['up_limit'] ?? 30;
+ $stockList->down_limit = $param['down_limit'] ?? 30;
+ $stockList->info = $info;
+ $stockList->tape = $tape;
+ $stockList->create_time = date('Y-m-d H:i:s');
+ $stockList->update_time = date('Y-m-d H:i:s');
+ $stockList->save();
+
+ // 新增缓存
+ $list_key = "IN:OPTION:LIST:" . $param['stock_code'];
+ $redis = $this->getRedis();
+ $redis->del($list_key);
+ $redis->hMset($list_key, [
+ 'stock_name' => $param['stock_name'],
+ 'stock_code' => $param['stock_code'],
+ 'status' => $param['status'],
+ 'keep_decimal' => $param['keep_decimal'] ?? 4,
+ 'forced_closure' => $param['forced_closure'] ?? 30,
+ 'up_limit' => $param['up_limit'] ?? 30,
+ 'down_limit' => $param['down_limit'] ?? 30,
+ 'rate' => $param['rate'] ?? 0,
+ 'info' => $info,
+ 'tape' => $tape,
+ ]);
+
+ // 给行情推送
+// $bool = $this->sendDecimalToGo('Indonesia', $stockList->stock_code, $stockList->keep_decimal);
+// $bool = $this->sendNewStockToGo('India', $stockList->stock_code, $stockList->stock_name, StockOptionInrListModel::$tapeList[$tape]);
+
+// if (!$bool) {
+// return $this->toData('1', '数据设置成功 但给行情推送数据异常', []);
+// }
+
+ return $this->toData('0', 'SUCCESS', []);
+
+ } catch (ValidateException $validateException) {
+ $message = $validateException->getError();
+ return $this->toData('1', $message);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统繁忙', []);
+ }
+ }
+
+
+ public function edit($param)
+ {
+ try {
+ validate(StockValidate::class)->scene('in_option_edit')->check($param);
+
+ $stockList = StockOptionInrListModel::where('id', $param['id'])->find();
+ if (empty($stockList)) {
+ return $this->toData('1', '目标不存在', []);
+ }
+
+ $info = '';
+ if (isset($param['info']) && is_string($param['info'])) {
+ $info = $param['info'];
+ }
+
+ // 判断股票交易所
+ $tape = '0';
+ if (isset($param['tape']) && in_array($param['tape'], array_keys(StockOptionInrListModel::$tapeList))) {
+ $tape = $param['tape'];
+ }
+
+ // 判断股票代码是否已经存在
+ $count = StockOptionInrListModel::where('stock_code', $param['stock_code'])->where('id', '<>', $param['id'])->count();
+ if ($count > 0) {
+ return $this->toData('1', '股票代码已经存在');
+ }
+
+ // 修改数据
+ $stockList->stock_name = $param['stock_name'];
+ $stockList->stock_code = $param['stock_code'];
+ $stockList->status = $param['status'];
+ $stockList->rate = $param['rate'] ?? 0;
+ $stockList->keep_decimal = $param['keep_decimal'] ?? 4;
+ $stockList->forced_closure = $param['forced_closure'] ?? 30;
+ $stockList->up_limit = $param['up_limit'] ?? 30;
+ $stockList->down_limit = $param['down_limit'] ?? 30;
+ $stockList->info = $info;
+ $stockList->tape = $tape;
+ $stockList->update_time = date('Y-m-d H:i:s');
+ $stockList->save();
+
+ // 新增缓存
+ $list_key = "IN:OPTION:LIST:" . $param['stock_code'];
+ $redis = $this->getRedis();
+ $redis->del($list_key);
+ $redis->hMset($list_key, [
+ 'stock_name' => $param['stock_name'],
+ 'stock_code' => $param['stock_code'],
+ 'status' => $param['status'],
+ 'keep_decimal' => $param['keep_decimal'] ?? 4,
+ 'forced_closure' => $param['forced_closure'] ?? 30,
+ 'up_limit' => $param['up_limit'] ?? 30,
+ 'down_limit' => $param['down_limit'] ?? 30,
+ 'rate' => $param['rate'] ?? 0,
+ 'info' => $info,
+ 'tape' => $tape,
+ ]);
+
+ // 给行情推送
+// $bool = $this->sendNewStockToGo('India', $stockList->stock_code, $stockList->stock_name, StockOptionInrListModel::$tapeList[$tape]);
+//
+// if (!$bool) {
+// return $this->toData('1', '数据设置成功 但给行情推送数据异常', []);
+// }
+
+ return $this->toData('0', 'SUCCESS', []);
+
+ } catch (ValidateException $validateException) {
+ $message = $validateException->getError();
+ return $this->toData('1', $message);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统繁忙', []);
+ }
+ }
+
+ // 列表
+ public function getTradeNameList()
+ {
+ try {
+ $list = StockOptionInrListModel::where('status', 1)->order('id', 'desc')->column('stock_name', 'id');
+ return $this->toData('0', 'SUCCESS', ['list' => $list]);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统繁忙', []);
+ }
+ }
+
+ public function refresh()
+ {
+ try {
+
+ $ch = curl_init();
+
+ $url = env('OPTION_REFRESH.OPTION_REFRESH_IN_URL');
+
+ curl_setopt($ch, CURLOPT_URL, $url); // Set the URL
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // Return the response as a string
+ curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); // Follow any redirects
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // This should be set to true in production, disables SSL certificate verification (only for testing)
+
+ $response = curl_exec($ch);
+ if (curl_errno($ch)) {
+ echo 'Curl error: ' . curl_error($ch);
+ }
+
+ curl_close($ch);
+
+ $data = json_decode($response, true);
+ if (empty($data) || empty($data['data']) || empty($data['code']) || (!empty($data['code']) && $data['code'] != 200)) {
+ return;
+ }
+
+ $now = date('Y-m-d H:i:s'); // 订单时间
+ $insertArr = [];
+ $responseCodeArr = array_column($data['data'], 'Code');
+ $dataCodeArr = StockOptionInrListModel::column('stock_code');
+ $result = array_diff($responseCodeArr, $dataCodeArr);
+ foreach ($data['data'] as $v) {
+ if (in_array($v['Code'], $result)) {
+ $insertArr[] = [
+ 'stock_name' => $v['Code'],
+ 'stock_code' => $v['Code'],
+ 'status' => 1,
+ 'tape' => StockOptionInrListModel::$tapeList[$v['Exchange']] ?? 1,
+ 'keep_decimal' => 4,
+ 'create_time' => $now,
+ 'update_time' => $now,
+ 'rate' => 30,
+ 'forced_closure' => 30,
+ 'up_limit' => 30,
+ 'down_limit' => 30
+ ];
+ }
+ }
+ $StockOptionInrListModel = new StockOptionInrListModel();
+ $StockOptionInrListModel::insertAll($insertArr);
+
+ $redis = $this->getRedis();
+ foreach ($insertArr as $cacheV) {
+ $list_key = "IN:OPTION:LIST:" . $cacheV['stock_code'];
+ $redis->del($list_key);
+ $redis->hMset($list_key, [
+ 'stock_name' => $cacheV['stock_name'],
+ 'stock_code' => $cacheV['stock_code'],
+ 'status' => $cacheV['status'],
+ 'keep_decimal' => $cacheV['keep_decimal'],
+ 'forced_closure' => $cacheV['forced_closure'],
+ 'up_limit' => $cacheV['up_limit'],
+ 'down_limit' => $cacheV['down_limit'],
+ 'rate' => $cacheV['rate'],
+ 'info' => '',
+ 'tape' => $cacheV['tape'],
+ ]);
+ }
+
+
+ } catch (\Exception $exception) {
+ }
+ }
+
+ public function batchEdit($param)
+ {
+ try {
+ $rate = $param['rate'];
+ $keep_decimal = $param['keep_decimal'];
+ $forced_closure = $param['forced_closure'];
+ $status = $param['status'];
+ $updateArr = ['rate' => $rate, 'keep_decimal' => $keep_decimal, 'forced_closure' => $forced_closure, 'status' => $status, 'update_time' => date('Y-m-d H:i:s')];
+ StockOptionInrListModel::where(1, '=', 1)->update($updateArr);
+
+ $dataCodeArr = StockOptionInrListModel::select()->toArray();
+ $redis = $this->getRedis();
+ foreach ($dataCodeArr as $cacheV) {
+ $list_key = "IN:OPTION:LIST:" . $cacheV['stock_code'];
+ $redis->del($list_key);
+ $redis->hMset($list_key, [
+ 'stock_name' => $cacheV['stock_name'],
+ 'stock_code' => $cacheV['stock_code'],
+ 'status' => $cacheV['status'],
+ 'keep_decimal' => $cacheV['keep_decimal'],
+ 'forced_closure' => $cacheV['forced_closure'],
+ 'up_limit' => $cacheV['up_limit'],
+ 'down_limit' => $cacheV['down_limit'],
+ 'rate' => $cacheV['rate'],
+ 'info' => $cacheV['info'],
+ 'tape' => $cacheV['tape'],
+ ]);
+ }
+
+ return $this->toData('0', 'SUCCESS');
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统繁忙', []);
+ }
+ }
+
+ public function onOff($param)
+ {
+ try {
+ $id = $param['id'];
+ $stockList = StockOptionInrListModel::where('id', $param['id'])->find();
+ if (empty($stockList)) {
+ return $this->toData('1', '目标不存在', []);
+ }
+ $status = $stockList->status == 0 ? 1 : 0;
+ $updateArr = ['status' => $status, 'update_time' => date('Y-m-d H:i:s')];
+ StockOptionInrListModel::where('id', $id)->update($updateArr);
+ return $this->toData('0', 'SUCCESS');
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统繁忙', []);
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/admin/service/setting/PaymentService.php b/app/admin/service/setting/PaymentService.php
new file mode 100644
index 0000000..1d9d60c
--- /dev/null
+++ b/app/admin/service/setting/PaymentService.php
@@ -0,0 +1,154 @@
+scene('payment_index')->check($param);
+ $list = PaymentListModel::order('id', 'desc')->page($param['page'], $param['limit'])->select();
+ $total = PaymentListModel::order('id', 'desc')->count();
+ $rows = [];
+ if (!$list->isEmpty()) {
+ $rows = $list->toArray();
+ }
+ return $this->toData('0', 'SUCCESS', ['list' => $rows, 'total' => $total, 'extend' => ['type_list' => PaymentListModel::TPYE_LIST]]);
+ } catch (ValidateException $validateException) {
+ // 参数校验失败
+ $message = $validateException->getError();
+ return $this->toData('1', $message);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统繁忙', []);
+ }
+ }
+
+ public function add($param)
+ {
+ try {
+ validate(PaymentValidate::class)->scene('payment_add')->check($param);
+ // 新增数据
+ $payment = new PaymentListModel();
+ $payment->country = $param['country'];
+ $payment->channel = $param['channel'];
+ $payment->pay_type = $param['pay_type'];
+ $payment->service_rate = $param['service_rate'];
+ $payment->type = $param['type'] ?? 1;
+ $payment->status = $param['status'];
+ $payment->channel_type = $param['channel_type'];
+// $payment->exchange_rate = $param['exchange_rate'];
+ $payment->is_recharge = $param['is_recharge'];
+ $payment->is_withdrawal = $param['is_withdrawal'];
+ $payment->is_online = $param['is_online'];
+ if (isset($param['bank_name'])) {
+ $payment->bank_name = $param['bank_name'];
+ }
+ if (isset($param['bank_branch'])) {
+ $payment->bank_branch = $param['bank_branch'];
+ }
+ if (isset($param['bank_user'])) {
+ $payment->bank_user = $param['bank_user'];
+ }
+ if (isset($param['bank_account'])) {
+ $payment->bank_account = $param['bank_account'];
+ }
+ if (isset($param['wallet_address'])) {
+ $payment->wallet_address = $param['wallet_address'];
+ }
+ if (isset($param['unit'])) {
+ $payment->unit = $param['unit'];
+ }
+ if (isset($param['account_type'])) {
+ $payment->account_type = $param['account_type'];
+ }
+ if (isset($param['ifsc'])) {
+ $payment->ifsc = $param['ifsc'];
+ }
+ if (isset($param['extra_name'])) {
+ $payment->extra_name = $param['extra_name'];
+ }
+ if (isset($param['extra_list'])) {
+ $payment->extra_list = $param['extra_list'];
+ }
+ $payment->save();
+ return $this->toData('0', 'SUCCESS', []);
+
+ } catch (ValidateException $validateException) {
+ $message = $validateException->getError();
+ return $this->toData('1', $message);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统繁忙', [$exception->getMessage()]);
+ }
+ }
+
+
+ public function edit($param)
+ {
+ try {
+ validate(PaymentValidate::class)->scene('payment_edit')->check($param);
+
+ $payment_info = PaymentListModel::where('id', $param['id'])->find();
+ if (empty($payment_info)) {
+ return $this->toData('1', '目标不存在', []);
+ }
+ $param['type'] = $param['type'] ?? 1;
+ PaymentListModel::where('id', $param['id'])->update($param);
+ return $this->toData('0', 'SUCCESS', []);
+
+ } catch (ValidateException $validateException) {
+ $message = $validateException->getError();
+ return $this->toData('1', $message);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统繁忙', [$exception->getMessage()]);
+ }
+ }
+
+ public function info($param)
+ {
+ try {
+ validate(PaymentValidate::class)->scene('payment_info')->check($param);
+ $payment_info = PaymentListModel::where('id', $param['id'])->find();
+ if (empty($payment_info)) {
+ return $this->toData('1', '目标不存在', []);
+ }
+ return $this->toData('0', 'SUCCESS', $payment_info->toArray());
+
+ } catch (ValidateException $validateException) {
+ $message = $validateException->getError();
+ return $this->toData('1', $message);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统繁忙', []);
+ }
+
+ }
+
+ public function del($param)
+ {
+ try {
+ validate(PaymentValidate::class)->scene('payment_info')->check($param);
+ $payment_info = PaymentListModel::where('id', $param['id'])->find();
+ if (empty($payment_info)) {
+ return $this->toData('1', '目标不存在', []);
+ }
+ PaymentListModel::where('id', $param['id'])->delete();
+ return $this->toData('0', 'SUCCESS', []);
+ } catch (ValidateException $validateException) {
+ $message = $validateException->getError();
+ return $this->toData('1', $message);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统繁忙', []);
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/app/admin/service/setting/PreFundStockService.php b/app/admin/service/setting/PreFundStockService.php
new file mode 100644
index 0000000..d6aa026
--- /dev/null
+++ b/app/admin/service/setting/PreFundStockService.php
@@ -0,0 +1,690 @@
+toData('1', '分页参数错误');
+ }
+ $where = [];
+ // 未删除
+ $where[] = [
+ 'is_delete', '=', PreFundStockModel::IS_DELETE_NO
+ ];
+ // 基金号
+ if (!empty($param['stock_code']) && is_string($param['stock_code'])) {
+ $where[] = [
+ 'stock_code', '=', $param['stock_code']
+ ];
+ }
+
+ $query = PreFundStockModel::where($where)->withJoin(['history' => ['stock_code', 'start_date', 'end_date', 'start_point', 'end_point']])->order('id', 'desc');
+ $totalQuery = PreFundStockModel::where($where)->order('id', 'desc');
+ if (!empty($param['open_status']) && in_array($param['open_status'], PreFundStockModel::$openStatusList)) {
+ $query = $query->where('open_status', $param['open_status']);
+ $totalQuery = $totalQuery->where('open_status', $param['open_status']);
+ }
+
+ $list = $query->append(['stock_type_text', 'open_status_text'])->order('id', 'desc')->page($param['page'], $param['limit'])->select();
+ $total = $totalQuery->order('id', 'desc')->count();
+ $rows = [];
+ if (!$list->isEmpty()) {
+ $rows = $list->toArray();
+ foreach ($rows as $key => $item) {
+ $rows[$key]['product_file'] = json_decode($item['product_file'], true);
+ $rows[$key]['current_manager'] = json_decode($item['current_manager'], true);
+ }
+ }
+
+ return $this->toData('0', 'SUCCESS', ['list' => $rows, 'total' => $total, 'extend' => [
+ 'open_status_list' => PreFundStockModel::$openStatusList,
+ 'stock_type_list' => PreFundStockModel::$stockTypeList,
+ 'interest_type_list' => PreFundStockModel::$interestTypeList,
+ 'cycle_type_list' => PreFundStockModel::$cycleTypeList,
+ 'symbol' => 'USD'
+
+ ]]);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统繁忙', [$exception->getMessage()]);
+ }
+ }
+
+ // 历史走势
+ public function history($param)
+ {
+ try {
+ if (empty($param['stock_code'])) {
+ return $this->toData('1', '基本代码 无效');
+ }
+ $history = HistoryFundStockModel::where('stock_code', $param['stock_code'])->value('history_info');
+ $history = json_decode($history, true);
+ return $this->toData('0', 'SUCCESS', ['history_info' => $history]);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统繁忙', [$exception->getMessage()]);
+ }
+ }
+
+ // 新增
+ public function add($param)
+ {
+ try {
+ // 基金代码
+ if (empty($param['stock_code']) || !is_string($param['stock_code'])) {
+ return $this->toData('1', '基金代码 无效');
+ }
+
+ // 基金名称
+ if (empty($param['stock_name']) || !is_string($param['stock_name'])) {
+ return $this->toData('1', '基金名称 无效');
+ }
+
+ // 基金类型
+ if (empty($param['stock_type']) || !in_array($param['stock_type'], array_keys(PreFundStockModel::$stockTypeList))) {
+ return $this->toData('1', '基金类型 无效');
+ }
+
+ // 返利类型
+ if (empty($param['interest_type']) || !in_array($param['interest_type'], array_keys(PreFundStockModel::$interestTypeList))) {
+ return $this->toData('1', '返利类型 无效');
+ }
+
+ // 周期单位
+ if (empty($param['cycle_type']) || !in_array($param['cycle_type'], array_keys(PreFundStockModel::$cycleTypeList))) {
+ return $this->toData('1', '返利类型 无效');
+ }
+
+ // 收益率 两位小数
+ if (empty($param['rate']) || !is_numeric($param['rate']) || $param['rate'] <= 0) {
+ return $this->toData('1', '基金收益率 无效');
+ }
+
+ // 基金周期
+ if (empty($param['cycle']) || !is_numeric($param['cycle']) || $param['cycle'] <= 0) {
+ return $this->toData('1', '基金周期 无效');
+ }
+
+ // 最低申购价格
+ if (empty($param['min_price']) || !is_numeric($param['min_price']) || $param['min_price'] <= 0) {
+ return $this->toData('1', '最低申购金额 无效');
+ }
+
+ // 开始认购时间
+ if (empty($param['start_time']) || !is_string($param['start_time'])) {
+ return $this->toData('1', '开始认购时间 无效');
+ }
+
+ // 认购结束时间
+ if (empty($param['end_time']) || !is_string($param['end_time'])) {
+ return $this->toData('1', '认购结束时间 无效');
+ }
+
+ // 基金logo
+ if (empty($param['logo']) || !is_string($param['logo'])) {
+ return $this->toData('1', '基金logo 无效');
+ }
+
+ // 基金标签
+ $tag = "";
+ if (!empty($param['tag']) && is_string($param['tag'])) {
+ $tag = $param['tag'];
+ }
+
+ // 认购结束时间要大于 认购开始时间
+ if (strtotime($param['end_time']) <= strtotime($param['start_time'])) {
+ return $this->toData('1', ' 认购结束时间 晚于 认购开始时间');
+ }
+
+ // 1.0 判断基金号是否已经存在
+ $preStock = PreFundStockModel::where('stock_code', $param['stock_code'])->find();
+ if (!empty($preStock)) {
+ return $this->toData('1', '基金号已经存在');
+ }
+
+ // 历史走势 起始日期
+ if (empty($param['start_date']) || !is_string($param['start_date'])) {
+ return $this->toData('1', '历史走势 起始日期 无效');
+ }
+
+ // 历史走势 结束日期
+ if (empty($param['end_date']) || !is_string($param['end_date'])) {
+ return $this->toData('1', '历史走势 结束日期 无效');
+ }
+
+ if (strtotime($param['end_date']) <= strtotime($param['start_date']) || strtotime($param['end_date']) - time() > 0) {
+ return $this->toData('1', '历史走势-开始日期 要大于 历史走势-结束日期 ; 历史走势-结束日期 要小于 当前时间');
+ }
+
+ // 历史走势 起始值
+ if (empty($param['start_point']) || !is_numeric($param['start_point'])) {
+ return $this->toData('1', '历史走势 起始值 无效');
+ }
+
+ // 历史走势 结束值
+ if (empty($param['end_point']) || !is_numeric($param['end_point'])) {
+ return $this->toData('1', '历史走势 结束值 无效');
+ }
+
+ Db::startTrans();
+ // 新增数据
+ $preFundStock = new PreFundStockModel();
+ $preFundStock->stock_code = $param['stock_code'];
+ $preFundStock->stock_name = $param['stock_name'];
+ $preFundStock->stock_type = $param['stock_type'];
+ $preFundStock->show_interest = $param['show_interest'] ?? 66;
+ $preFundStock->tape = $param['tape'] ?? 1;
+ $preFundStock->status = $param['status'] ?? 0;
+ $preFundStock->min_price = $param['min_price'];
+ $preFundStock->rate = $param['rate'];
+ $preFundStock->cycle = $param['cycle'];
+ $preFundStock->start_time = $param['start_time'];
+ $preFundStock->end_time = $param['end_time'];
+ $preFundStock->sort = $param['sort'] ?? 0;
+ $preFundStock->interest_type = $param['interest_type'];
+ $preFundStock->cycle_type = $param['cycle_type'];
+ $preFundStock->phase_count = $param['phase_count'] ?? 1;
+
+ $preFundStock->is_delete = PreFundStockModel::IS_DELETE_NO;
+ $preFundStock->open_status = PreFundStockModel::OPEN_STATUS_NO;
+ $preFundStock->create_time = date('Y-m-d H:i:s');
+ $preFundStock->update_time = date('Y-m-d H:i:s');
+
+ $preFundStock->stock_info = $param['stock_info'] ?? "";
+ $preFundStock->logo = $param['logo'];
+ $preFundStock->tag = $tag;
+ $preFundStock->remark = $param['remark'];
+ $preFundStock->product_file = json_encode($param['product_file']);
+ $preFundStock->current_manager = json_encode($param['current_manager']);
+ $preFundStockBool = $preFundStock->save();
+ if (!$preFundStockBool) {
+ Db::rollback();
+ return $this->toData('1', '新增基金失败');
+ }
+
+ // 基金历史走势
+ $HistoryStock = new HistoryFundStockModel();
+ $HistoryStock->stock_code = $param['stock_code'];
+ $HistoryStock->start_date = $param['start_date'];
+ $HistoryStock->end_date = $param['end_date'];
+ $HistoryStock->start_point = $param['start_point'];
+ $HistoryStock->end_point = $param['end_point'];
+ $HistoryStock->history_info = $this->autoHistory($param['start_date'], $param['end_date'], $param['start_point'], $param['end_point']);
+ $HistoryStockBool = $HistoryStock->save();
+ if (!$HistoryStockBool) {
+ Db::rollback();
+ return $this->toData('1', '新增基金走势失败');
+ }
+
+ Db::commit();
+ return $this->toData('0', 'SUCCESS');
+ } catch (\Exception $exception) {
+ Db::rollback();
+ return $this->toData('1', '系统繁忙', [$exception->getMessage()]);
+ }
+ }
+
+ // 编辑
+ public function edit($param)
+ {
+ try {
+ if (empty($param['id']) || !is_numeric($param['id'])) {
+ return $this->toData('1', '主键 无效');
+ }
+
+ $preFundStock = PreFundStockModel::where('id', $param['id'])->where('is_delete', PreFundStockModel::IS_DELETE_NO)->find();
+ if (empty($preFundStock)) {
+ return $this->toData('1', '主键 无效');
+ }
+
+ // 已中签或者已上市不支持修改
+// if ($preFundStock->open_status == PreFundStockModel::OPEN_STATUS_HAD) {
+// return $this->toData('1', '已上市 不支持修改');
+// }
+
+ // 基金类型
+ if (empty($param['stock_type']) || !in_array($param['stock_type'], array_keys(PreFundStockModel::$stockTypeList))) {
+ return $this->toData('1', '基金类型 无效');
+ }
+
+ if ($preFundStock->had_get_price == 0) {
+ // 基金代码
+ if (empty($param['stock_code']) || !is_string($param['stock_code'])) {
+ return $this->toData('1', '基金代码 无效');
+ }
+
+ // 基金名称
+ if (empty($param['stock_name']) || !is_string($param['stock_name'])) {
+ return $this->toData('1', '基金代码 无效');
+ }
+
+ // 单股价格
+ if (empty($param['min_price']) || !is_numeric($param['min_price']) || $param['min_price'] <= 0) {
+ return $this->toData('1', '最低申购金额 无效');
+ }
+
+ // 开始认购时间
+ if (empty($param['start_time']) || !is_string($param['start_time'])) {
+ return $this->toData('1', '开始认购时间 无效');
+ }
+
+ // 收益率 两位小数
+ if (empty($param['rate']) || !is_numeric($param['rate']) || $param['rate'] <= 0) {
+ return $this->toData('1', '基金收益率 无效');
+ }
+
+ // 基金周期
+ if (empty($param['cycle']) || !is_numeric($param['cycle']) || $param['cycle'] <= 0) {
+ return $this->toData('1', '基金周期 无效');
+ }
+
+ // 返利类型
+ if (empty($param['interest_type']) || !in_array($param['interest_type'], array_keys(PreFundStockModel::$interestTypeList))) {
+ return $this->toData('1', '返利类型 无效');
+ }
+
+ // 周期单位
+ if (empty($param['cycle_type']) || !in_array($param['cycle_type'], array_keys(PreFundStockModel::$cycleTypeList))) {
+ return $this->toData('1', '返利类型 无效');
+ }
+ }
+
+ // 认购结束时间
+ if (empty($param['end_time']) || !is_string($param['end_time'])) {
+ return $this->toData('1', '认购结束时间 无效');
+ }
+
+ // 基金logo
+ if (empty($param['logo']) || !is_string($param['logo'])) {
+ return $this->toData('1', '基金logo 无效');
+ }
+
+ // 基金标签
+ $tag = "";
+ if (!empty($param['tag']) && is_string($param['tag'])) {
+ $tag = $param['tag'];
+ }
+
+ // 历史走势 起始日期
+ if (empty($param['start_date']) || !is_string($param['start_date'])) {
+ return $this->toData('1', '历史走势 起始日期 无效');
+ }
+
+ // 历史走势 结束日期
+ if (empty($param['end_date']) || !is_string($param['end_date'])) {
+ return $this->toData('1', '历史走势 结束日期 无效');
+ }
+
+ // 历史走势 起始值
+ if (empty($param['start_point']) || !is_numeric($param['start_point'])) {
+ return $this->toData('1', '历史走势 起始值 无效');
+ }
+
+ // 历史走势 结束值
+ if (empty($param['end_point']) || !is_numeric($param['end_point'])) {
+ return $this->toData('1', '历史走势 结束值 无效');
+ }
+
+ // 上市时间 要大于 认购结束时间 认购结束时间要大于 认购开始时间
+ if (strtotime($param['end_time']) <= strtotime($param['start_time'])) {
+ return $this->toData('1', '认购结束时间 要晚于 认购开始时间');
+ }
+
+ // 1.0 判断基金号是否已经存在
+ $preStock = PreFundStockModel::where('stock_code', $param['stock_code'])
+ ->where('id', '<>', $param['id'])
+ ->where('is_delete', PreFundStockModel::IS_DELETE_NO)->find();
+ if (!empty($preStock)) {
+ return $this->toData('1', '基金号已经存在');
+ }
+
+ Db::startTrans();
+ // 编辑数据
+ if ($preFundStock->had_get_price == 0) {
+ $UpdatePreFundStockArr['stock_code'] = $param['stock_code'];
+ $UpdatePreFundStockArr['stock_name'] = $param['stock_name'];
+ $UpdatePreFundStockArr['status'] = $param['status'] ?? 0;
+ $UpdatePreFundStockArr['min_price'] = $param['min_price'];
+ $UpdatePreFundStockArr['start_time'] = $param['start_time'];
+ $UpdatePreFundStockArr['rate'] = $param['rate'];
+ $UpdatePreFundStockArr['cycle'] = $param['cycle'];
+ $UpdatePreFundStockArr['interest_type'] = $param['interest_type'];
+ $UpdatePreFundStockArr['cycle_type'] = $param['cycle_type'];
+ $UpdatePreFundStockArr['phase_count'] = $param['phase_count'] ?? 1;
+ $UpdatePreFundStockArr['tape'] = $param['tape'] ?? 1;
+ }
+
+ $UpdatePreFundStockArr['show_interest'] = $param['show_interest'] ?? 66;
+ $UpdatePreFundStockArr['end_time'] = $param['end_time'];
+ $UpdatePreFundStockArr['is_delete'] = PreFundStockModel::IS_DELETE_NO;
+ $UpdatePreFundStockArr['update_time'] = date('Y-m-d H:i:s');
+ $UpdatePreFundStockArr['sort'] = $param['sort'] ?? 0;
+
+ $UpdatePreFundStockArr['stock_info'] = $param['stock_info'] ?? "";
+ $UpdatePreFundStockArr['logo'] = $param['logo'];
+ $UpdatePreFundStockArr['tag'] = $tag;
+ $UpdatePreFundStockArr['remark'] = $param['remark'];
+ $UpdatePreFundStockArr['product_file'] = json_encode($param['product_file']);
+ $UpdatePreFundStockArr['current_manager'] = json_encode($param['current_manager']);
+ $UpdatePreFundStockBool = PreFundStockModel::where('id', $param['id'])->update($UpdatePreFundStockArr);
+ if (!$UpdatePreFundStockBool) {
+ Db::rollback();
+ return $this->toData('1', '编辑基金失败');
+ }
+
+ // 基金历史走势
+ $HistoryStockArr['stock_code'] = $param['stock_code'];
+ $HistoryStockArr['start_date'] = $param['start_date'];
+ $HistoryStockArr['end_date'] = $param['end_date'];
+ $HistoryStockArr['start_point'] = $param['start_point'];
+ $HistoryStockArr['end_point'] = $param['end_point'];
+ $HistoryStockArr['history_info'] = $this->autoHistory($param['start_date'], $param['end_date'], $param['start_point'], $param['end_point']);
+ $HistoryStock = HistoryFundStockModel::where('stock_code', $param['stock_code'])->find();
+ if (empty($HistoryStock)) {
+ HistoryFundStockModel::where('stock_code', $preFundStock->stock_code)->delete();
+ $HistoryStockBool = HistoryFundStockModel::create($HistoryStockArr);
+ } else {
+ $HistoryStockBool = HistoryFundStockModel::where('stock_code', $param['stock_code'])->update($HistoryStockArr);
+ }
+ if (!$HistoryStockBool) {
+ Db::rollback();
+ return $this->toData('1', '编辑基金走势失败');
+ }
+
+ Db::commit();
+ return $this->toData('0', 'SUCCESS');
+ } catch (\Exception $exception) {
+ Db::rollback();
+ return $this->toData('1', '系统繁忙', [$exception->getMessage()]);
+ }
+ }
+
+ // 上市
+ public function open($param)
+ {
+ try {
+ if (empty($param['id']) || !is_numeric($param['id'])) {
+ return $this->toData('1', '主键 无效');
+ }
+
+// $isReal = 1;
+// if (isset($param['is_real']) && is_numeric($param['is_real']) && $param['is_real'] == '2') {
+// $isReal = 2;
+// }
+
+ $preFundStock = PreFundStockModel::where('id', $param['id'])->where('is_delete', PreFundStockModel::IS_DELETE_NO)->find();
+ if (empty($preFundStock)) {
+ return $this->toData('1', '主键 无效');
+ }
+
+ // 判断是否签名
+// if ($preFundStock->sign_status != PreFundStockModel::SIGN_STATUS_DONE) {
+// return $this->toData('1', '还未签名');
+// }
+
+// if ($preFundStock->open_status != PreFundStockModel::OPEN_STATUS_NO) {
+// return $this->toData('1', '无法操作');
+// }
+
+ // 修改基金状态
+ $num = PreFundStockModel::where('id', $preFundStock->id)->update(['open_status' => PreFundStockModel::OPEN_STATUS_HAD,
+ 'open_time' => date('Y-m-d H:i:s'),
+ 'update_time' => date('Y-m-d H:i:s')]);
+
+ if ($num <= 0) {
+ return $this->toData('1', '基金状态修改失败-上市');
+ }
+
+ return $this->toData('0', 'SUCCESS');
+ } catch (\Exception $exception) {
+ Log::error("基金上市失败 " . $exception->getMessage());
+ return $this->toData('1', '系统繁忙', [$exception->getMessage()]);
+ }
+ }
+
+ // 退市
+ public function close($param)
+ {
+ try {
+ if (empty($param['id']) || !is_numeric($param['id'])) {
+ return $this->toData('1', '主键 无效');
+ }
+
+ $preFundStock = PreFundStockModel::where('id', $param['id'])->where('is_delete', PreFundStockModel::IS_DELETE_NO)->find();
+ if (empty($preFundStock)) {
+ return $this->toData('1', '主键 无效');
+ }
+
+ //
+ if ($preFundStock->open_status != PreFundStockModel::OPEN_STATUS_HAD) {
+ return $this->toData('1', '上市中 无法操作');
+ }
+
+ // 修改基金状态
+ $num = PreFundStockModel::where('id', $preFundStock->id)->update(['open_status' => PreFundStockModel::OPEN_STATUS_OUT,
+ 'close_time' => date('Y-m-d H:i:s'),
+ 'update_time' => date('Y-m-d H:i:s')]);
+
+ if ($num <= 0) {
+ return $this->toData('1', '基金状态修改失败-退市');
+ }
+
+ return $this->toData('0', 'SUCCESS');
+ } catch (\Exception $exception) {
+ Log::error("基金退市失败 " . $exception->getMessage());
+ return $this->toData('1', '系统繁忙', [$exception->getMessage()]);
+ }
+ }
+
+ // 删除
+ public function del($param)
+ {
+ try {
+ if (empty($param['id']) || !is_numeric($param['id'])) {
+ return $this->toData('1', '主键 无效');
+ }
+
+ $preFundStock = PreFundStockModel::where('id', $param['id'])->where('is_delete', PreFundStockModel::IS_DELETE_NO)->find();
+ if (empty($preFundStock)) {
+ return $this->toData('1', '主键 无效');
+ }
+
+ //
+ if ($preFundStock->open_status != PreFundStockModel::OPEN_STATUS_HAD) {
+ return $this->toData('1', '上市中 无法操作');
+ }
+
+ // 修改删除状态
+ $num = PreFundStockModel::where('id', $preFundStock->id)->update([
+ 'is_delete' => PreFundStockModel::IS_DELETE_YES,
+ 'update_time' => date('Y-m-d H:i:s')]);
+
+ if ($num <= 0) {
+ return $this->toData('1', '基金删除失败');
+ }
+
+ return $this->toData('0', 'SUCCESS');
+ } catch (\Exception $exception) {
+ Log::error("基金删除失败 " . $exception->getMessage());
+ return $this->toData('1', '系统繁忙', [$exception->getMessage()]);
+ }
+ }
+
+ private function autoHistory($startDate, $endDate, $startPoint, $endPoint)
+ {
+ $startDateOjb = new DateTime($startDate);
+ $endDateOjb = new DateTime($endDate);
+ $endDateOjb->modify('+1 day'); //DateTime 取两个日期中间日期,不含结束日期
+ $period = new DatePeriod($startDateOjb, new DateInterval('P1D'), $endDateOjb);
+ $interval = $startDateOjb->diff($endDateOjb);
+ $daysCount = $interval->format('%a');
+ $numberArr = $this->autoNumber($startPoint, $endPoint, $daysCount);
+ $start = 0;
+ foreach ($period as $k => $date) {
+ $dates[$date->format("Y-m-d")] = number_format($start += $numberArr[$k], 2, '.', '');
+ }
+
+ return json_encode($dates);
+ }
+
+ private function autoNumber($startPoint, $endPoint, $count)
+ {
+ $rand = round(($endPoint - $startPoint) / $count, 2);
+ $randomNumbers = array();
+ $randomNumbers[] = $startPoint;
+ for ($i = 0; $i < $count - 2; $i++) {
+ $temp = bcmul(rand(1, 10) > 4 ? 1 : -1, (rand(1, 10) > 5 ? rand(1, 5) : rand(4, 8)) / 100, 2);
+ // 生成随机的增减值
+ $randomChange = bcmul(rand(1, 10) > 4 ? 1 : -1, rand(1, 10) > 5 ? rand(1, 10) > 3 ? $rand * 2 : $rand * 4 : $rand * 3, 2);
+ $randomChange = bcadd($randomChange, $temp, 2);
+ // 将当前值添加到数组中
+ $randomNumbers[] = round($randomChange, 2);
+ }
+
+ $end = round($endPoint - array_sum($randomNumbers), 2);
+ if (abs($end) > 30) {
+ return $this->autoNumber($startPoint, $endPoint, $count);
+ } else {
+ $randomNumbers[] = $end;
+ return $randomNumbers;
+ }
+ }
+
+ public function interest()
+ {
+ try {
+// $interestSwitch = env();
+// if (!$interestSwitch)return;
+
+ $today = date("Y-m-d");
+ $interestList = UserStockFundInterestReceiptModel::where("return_date", $today)->where('status', UserStockFundInterestReceiptModel::STATUS_ONE)->select();
+ if (count($interestList) == 0) {
+ trace('fund_interest count=0 基金没有需要处理的返息单-完成', 'error');
+ return json(["SUCCESS"]);
+ }
+
+ foreach ($interestList as $interestV) {
+ try {
+ // 单个股票 开始事务
+ Db::startTrans();
+ $vId = $interestV->id;
+ //用户基金账户加钱
+ $beforeAmount = UserStockFundModel::where('stock_id', 'USD')->where('user_id', $interestV->user_id)->value('usable_num');
+ if (empty($beforeAmount)) {
+ Db::rollback();
+ trace("基金返息失败0 返息单ID=$vId", 'error');
+ return json(["基金返息失败0"]);
+ }
+
+ $addNum = bcadd($interestV->capital, $interestV->interest, 18);//本金+利息
+ $addBool = UserStockFundModel::where('user_id', $interestV->user_id)->where('stock_id', 'USD')->inc('usable_num', $addNum)->update(['update_time' => date('Y-m-d H:i:s')]);
+ if (!$addBool) {
+ Db::rollback();
+ trace("基金返息失败1 返息单ID=$vId", 'error');
+ return json(["基金返息失败1"]);
+ }
+
+ // 新增用户基金账户流水
+ // 生成流水
+ $userStockLog = new UserStockFundLogModel();
+ $userStockLog->user_id = $interestV->user_id;
+ $userStockLog->change_type = 19;
+ $userStockLog->stock_id = 'USD';
+ $userStockLog->before_num = $beforeAmount;
+ $userStockLog->change_num = $addNum;
+ $userStockLog->order_id = $interestV->order_no;
+ $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();
+ trace("基金返息失败2 返息单ID=$vId", 'error');
+ return json(["基金返息失败2"]);
+ }
+
+ //修改返息单状态
+ $interestReceiptUpdateBool = UserStockFundInterestReceiptModel::where('id', $interestV->id)->update(['status' => UserStockFundInterestReceiptModel::STATUS_TWO, 'update_time' => date('Y-m-d H:i:s')]);
+ if (!$interestReceiptUpdateBool) {
+ Db::rollback();
+ trace("基金返息失败3 返息单ID=$vId", 'error');
+ return json(["基金返息失败3"]);
+ }
+
+ //修改订单状态
+ $order = UserFundPreStockOrderModel::where('id', $interestV->order_id)->find();
+ if (empty($order)) {
+ Db::rollback();
+ trace("基金返息失败4 返息单ID=$vId", 'error');
+ return json(["基金返息失败4"]);
+ }
+
+ if ($order->phase_count == $interestV->phase_time) {
+ $orderStatus = UserFundPreStockOrderModel::STATUS_THREE;//已结束
+ } else {
+ $orderStatus = UserFundPreStockOrderModel::STATUS_TWO;//进行中
+ }
+ $order->status = $orderStatus;
+ $order->save();
+ // 提交事务
+ Db::commit();
+ } catch (\Exception $exception) {
+ Db::rollback();
+ trace("基金返息息失败5-exception " . $exception->getMessage(), 'error');
+ return json(["基金返息失败5-exception"]);
+ }
+ }
+
+ trace('基金返息-完成', 'error');
+ return json(["SUCCESS"]);
+ } catch (\Exception $exception) {
+ trace("基金返息失败6-exception " . $exception->getMessage(), 'error');
+ return json([$exception->getMessage()]);
+ }
+ }
+
+ public function referStockAdd($param)
+ {
+ try {
+ $bool = PreFundStockReferModel::insert(['name' => $param['name'], 'year' => $param['year'], 'rate' => $param['rate']]);
+ if (!$bool) {
+ return $this->toData('1', '基金状态修改失败-退市');
+ }
+
+ return $this->toData('0', 'SUCCESS');
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统繁忙', [$exception->getMessage()]);
+ }
+ }
+
+ public function referStockDel($param)
+ {
+ try {
+ $bool = PreFundStockReferModel::where('id', $param['id'])->delete();
+ if (!$bool) {
+ return $this->toData('1', '基金状态修改失败-退市');
+ }
+
+ return $this->toData('0', 'SUCCESS');
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统繁忙', [$exception->getMessage()]);
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/admin/service/setting/ServiceService.php b/app/admin/service/setting/ServiceService.php
new file mode 100644
index 0000000..15425c6
--- /dev/null
+++ b/app/admin/service/setting/ServiceService.php
@@ -0,0 +1,112 @@
+select();
+ if (!$list->isEmpty()) {
+ $rows = $list->toArray();
+ }
+ return $this->toData('0', 'SUCCESS', ['list' => $rows, 'total' => count($rows), 'extend' => ['type_list' => ServiceSettingModel::$typeList]]);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统繁忙', []);
+ }
+ }
+
+ public function add($param)
+ {
+ try {
+ if (empty($param['type']) || !in_array($param['type'], array_keys(ServiceSettingModel::$typeList))) {
+ return $this->toData('1', '类型 无效', []);
+ }
+
+ if (empty($param['header_photo']) || !is_string($param['header_photo'])) {
+ return $this->toData('1', '头像图片地址无效', []);
+ }
+
+ if (empty($param['server_name']) || !is_string($param['server_name'])) {
+ return $this->toData('1', '客服名称无效', []);
+ }
+
+ if (!empty($param['server_link']) && !is_string($param['server_link'])) {
+ return $this->toData('1', '类型内容 无效', []);
+ }
+
+ $service = new ServiceSettingModel;
+ $service->header_photo = $param['header_photo'];
+ $service->type = $param['type'];
+ $service->server_link = $param['server_link'] ?? '';
+ $service->server_name = $param['server_name'];
+ $service->save();
+ return $this->toData('0', 'SUCCESS');
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统繁忙', []);
+ }
+ }
+
+ public function edit($param)
+ {
+ try {
+ if (empty($param['id']) || !is_numeric($param['id'])) {
+ return $this->toData('1', '目标不存在', []);
+ }
+ $service = ServiceSettingModel::where('id', $param['id'])->find();
+ if (empty($service)) {
+ return $this->toData('1', '目标不存在', []);
+ }
+
+ if (empty($param['type']) || !in_array($param['type'], array_keys(ServiceSettingModel::$typeList))) {
+ return $this->toData('1', '类型 无效', []);
+ }
+
+ if (empty($param['header_photo']) || !is_string($param['header_photo'])) {
+ return $this->toData('1', '头像图片地址无效', []);
+ }
+
+ if (empty($param['server_name']) || !is_string($param['server_name'])) {
+ return $this->toData('1', '客服名称无效', []);
+ }
+
+ if (!empty($param['server_link']) && !is_string($param['server_link'])) {
+ return $this->toData('1', '类型内容 无效', []);
+ }
+ $service->type = $param['type'];
+ $service->header_photo = $param['header_photo'];
+ $service->server_link = $param['server_link'] ?? '';
+ $service->server_name = $param['server_name'];
+ $service->save();
+ return $this->toData('0', 'SUCCESS');
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统繁忙', []);
+ }
+ }
+
+
+ public function del($param)
+ {
+ try {
+ if (empty($param['id']) || !is_numeric($param['id'])) {
+ return $this->toData('1', '参错错误');
+ }
+
+ $lang = ServiceSettingModel::where('id', $param['id'])->find();
+ if (empty($lang)) {
+ return $this->toData('1', '目标不存在');
+ }
+
+ $lang->delete();
+ return $this->toData('0', 'SUCCESS');
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统繁忙', []);
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/admin/service/setting/StockIndexService.php b/app/admin/service/setting/StockIndexService.php
new file mode 100644
index 0000000..1e817c2
--- /dev/null
+++ b/app/admin/service/setting/StockIndexService.php
@@ -0,0 +1,65 @@
+order('id', 'desc')->select();
+ $rows = [];
+ if(!$list->isEmpty()){
+ $rows = $list->toArray();
+ }
+
+ return $this->toData('0', 'SUCCESS', ['list' => $rows, 'total' => count($rows)]);
+ }catch (\Exception $exception){
+ return $this->toData('1', '系统繁忙', []);
+ }
+
+ }
+
+ public function update($param)
+ {
+ try {
+ if(empty($param['id']) || !is_numeric($param['id'])){
+ return $this->toData('1', '参数错误1', []);
+ }
+
+ if(!isset($param['sort']) || !is_numeric($param['sort'])){
+ return $this->toData('1', '参数错误2', []);
+ }
+
+ if(empty($param['status']) || !in_array($param['status'], [1,2])){
+ return $this->toData('1', '参数错误3', []);
+ }
+
+ $stockIndex = StockIndexModel::where('id', $param['id'])->find();
+ if(empty($stockIndex)){
+ return $this->toData('1', '目标不存在', []);
+ }
+
+ $stockIndex->sort = ceil($param['sort']);
+ $stockIndex->status = ceil($param['status']);
+ $stockIndex->update_time = date('Y-m-d H:i:s');
+ $stockIndex->save();
+
+ // 通知go
+ $bool = $this->sendStockIndexToGo($stockIndex->code, $stockIndex->country, $stockIndex->sort, $stockIndex->status);
+ if(!$bool){
+ return $this->toData('1', '通知行情失败 请重新设置数据', []);
+ }
+ return $this->toData('0', 'SUCCESS');
+
+
+ }catch (\Exception $exception){
+ return $this->toData('1', '系统繁忙', [$exception->getMessage()]);
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/admin/service/setting/StockMarketService.php b/app/admin/service/setting/StockMarketService.php
new file mode 100644
index 0000000..fb34f0a
--- /dev/null
+++ b/app/admin/service/setting/StockMarketService.php
@@ -0,0 +1,518 @@
+select();
+ $rows = [];
+ if(!$list->isEmpty()){
+ $rows = $list->toArray();
+ }
+
+ return $this->toData('0','SUCCESS', ['total' => count($rows), 'list' => $rows, 'extent' => [
+ 'stock_market_type_list' => StockMarketModel::STOCK_MARKET_TYPE,
+ 'trade_day_type' => StockMarketModel::TRADE_DAY_TYPE,
+ ]]);
+ }catch (\Exception $exception){
+ return $this->toData('1', '系统繁忙', [$exception->getMessage()]);
+ }
+ }
+
+
+ // 新增
+ public function add($param)
+ {
+ try {
+ $stockMarketTypeArr = StockMarketModel::STOCK_MARKET_TYPE;
+ $tradeDayTypeArr = StockMarketModel::TRADE_DAY_TYPE;
+ $stockMarketTypeKeys = array_keys($stockMarketTypeArr);
+ $tradeDayTypeKeys = array_keys($tradeDayTypeArr);
+ if(empty($param['stock_market_type']) || !in_array($param['stock_market_type'], $stockMarketTypeKeys)){
+ return $this->toData('1', '股票市场类型无效', []);
+ }
+
+ // 判断是否已经存在
+ $stockM = StockMarketModel::where('stock_market_type', $param['stock_market_type'])->find();
+ if($stockM){
+ return $this->toData('1', '股票市场类型已经存在', []);
+ }
+
+ $amOpenTime = '00:00';
+ $amCloseTime = '00:00';
+ $pmOpenTime = '00:00';
+ $pmCloseTime = '00:00';
+ $num = 0;
+ if(isset($param['am_open_time']) && is_string($param['am_open_time'])){
+ $amOpenTimestamp = strtotime($param['am_open_time']);
+ if($amOpenTimestamp !== false && date('H:i', $amOpenTimestamp) === $param['am_open_time']){
+ $amOpenTime = $param['am_open_time'];
+ $num++;
+ }
+ }
+
+ if(isset($param['am_close_time']) && is_string($param['am_close_time'])){
+ $amCloseTimestamp = strtotime($param['am_close_time']);
+ if($amCloseTimestamp !== false && date('H:i', $amCloseTimestamp) === $param['am_close_time']){
+ $amCloseTime = $param['am_close_time'];
+ $num++;
+ }
+ }
+
+ if(isset($param['pm_open_time']) && is_string($param['pm_open_time'])){
+ $pmOpenTimestamp = strtotime($param['pm_open_time']);
+ if($pmOpenTimestamp !== false && date('H:i', $pmOpenTimestamp) === $param['pm_open_time']){
+ $pmOpenTime = $param['pm_open_time'];
+ $num++;
+ }
+ }
+
+ if(isset($param['pm_close_time']) && is_string($param['pm_close_time'])){
+ $pmCloseTimestamp = strtotime($param['pm_close_time']);
+ if($pmCloseTimestamp !== false && date('H:i', $pmCloseTimestamp) === $param['pm_close_time']){
+ $pmCloseTime = $param['pm_close_time'];
+ $num++;
+ }
+ }
+
+
+ if(empty($param['status']) || !in_array($param['status'], [StockMarketModel::STATUS_NO, StockMarketModel::STATUS_OFF])){
+ return $this->toData('1', '状态类型无效', []);
+ }
+
+ // 如果是开启状态 必须设置开盘时间
+ if($param['status'] == StockMarketModel::STATUS_NO && $num < 4){
+ return $this->toData('1', '需要设置开盘时间', []);
+ }
+
+ // 货币单位
+ if(empty($param['unit']) || !is_string($param['unit']) || strlen($param['unit']) > 10){
+ return $this->toData('1', '货币单位无效', []);
+ }
+
+ // 货币符号
+ if(empty($param['symbol']) || !is_string($param['symbol']) || strlen($param['symbol']) > 10){
+ return $this->toData('1', '货币符号无效', []);
+ }
+
+ // 兑换汇率
+ if(empty($param['rate']) || !is_numeric($param['rate']) || strlen($param['rate']) > 200){
+ return $this->toData('1', '兑换汇率无效', []);
+ }
+
+ // 如果是开启状态必须设置 交易日限制 如果是关闭状态
+ if($param['status'] == StockMarketModel::STATUS_NO){
+ if(empty($param['trade_day_type']) || !in_array($param['trade_day_type'], $tradeDayTypeKeys)){
+ return $this->toData('1', '交易日限制无效', []);
+ }
+ $tradeDayType = $param['trade_day_type'];
+ }else{
+ if(empty($param['trade_day_type']) || !in_array($param['trade_day_type'], $tradeDayTypeKeys)){
+ $tradeDayType = 0;
+ } else{
+ $tradeDayType = $param['trade_day_type'];
+ }
+ }
+
+ // 设置股票杠杆
+ $leverStatus = StockMarketModel::LEVER_STATUS_OFF;
+ $stockMin = 0;
+ $leverMin = 1;
+ $leverMax = 1;
+ if(!empty($param['lever_status']) && is_numeric($param['lever_status']) && $param['lever_status'] == StockMarketModel::LEVER_STATUS_ON){
+ $leverStatus = $param['lever_status'];
+ if(empty($param['stock_min']) || !is_numeric($param['stock_min']) || $param['stock_min'] <=0){
+ return $this->toData('1', '杠杆最小使用股数无效', []);
+ }
+
+ if(empty($param['lever_min']) || !is_numeric($param['lever_min']) || $param['lever_min'] <=0){
+ return $this->toData('1', '最小杠杆无效', []);
+ }
+
+ if(empty($param['lever_max']) || !is_numeric($param['lever_max']) || $param['lever_max'] <=0 || $param['lever_max'] < $param['lever_min']){
+ return $this->toData('1', '最大杠杆无效', []);
+ }
+
+ $stockMin = ceil($param['stock_min']);
+ $leverMin = ceil($param['lever_min']);
+ $leverMax = ceil($param['lever_max']);
+ }
+
+
+ $stockMarket = new StockMarketModel;
+ $stockMarket->stock_market_type = $param['stock_market_type'];
+ $stockMarket->status = $param['status'];
+ $stockMarket->symbol = $param['symbol'];
+ $stockMarket->unit = $param['unit'];
+ $stockMarket->rate = $param['rate'];
+ // 开盘时间
+ $stockMarket->am_open_time = $amOpenTime;
+ $stockMarket->am_close_time = $amCloseTime;
+ $stockMarket->pm_open_time = $pmOpenTime;
+ $stockMarket->pm_close_time = $pmCloseTime;
+ $stockMarket->trade_day_type = $tradeDayType;
+ $stockMarket->create_time = date('Y-m-d H:i:s');
+ $stockMarket->update_time = date('Y-m-d H:i:s');
+
+ $stockMarket->stock_min = $stockMin;
+ $stockMarket->lever_min = $leverMin;
+ $stockMarket->lever_max = $leverMax;
+ $stockMarket->lever_status = $leverStatus;
+
+ $stockMarket->save();
+
+ // 缓存
+ $list_key="STOCK_MARKET:LIST:" .$stockMarket->stock_market_type;
+ $redis = $this->getRedis();
+ $redis->del($list_key);
+ $redis->hMset($list_key, [
+ 'id'=>$stockMarket->id,
+ 'stock_market_type'=>$stockMarket->stock_market_type,
+ 'trade_day_type'=>$stockMarket->trade_day_type,
+ 'unit'=>$stockMarket->unit,
+ 'rate'=>$stockMarket->rate,
+ 'symbol'=>$stockMarket->symbol,
+ 'status'=>$stockMarket->status,
+ 'am_open_time'=>$stockMarket->am_open_time,
+ 'am_close_time'=>$stockMarket->am_close_time,
+ 'pm_open_time'=>$stockMarket->pm_open_time,
+ 'pm_close_time'=>$stockMarket->pm_close_time,
+
+ 'lever_status' => $leverStatus,
+ 'stock_min' => $stockMin,
+ 'lever_min' => $leverMin,
+ 'lever_max' => $leverMax,
+
+ ]);
+
+ return $this->toData('0','SUCCESS');
+ }catch (\Exception $exception){
+ return $this->toData('1', '系统繁忙', [$exception->getMessage(),$exception->getLine()]);
+ }
+ }
+
+ public function edit($param)
+ {
+ try {
+ if(empty($param['id']) || !is_numeric($param['id'])){
+ return $this->toData('1', '主键无效', []);
+ }
+
+ $stockMarket = StockMarketModel::where('id', $param['id'])->find();
+ if(empty($stockMarket)){
+ return $this->toData('1', '主键无效', []);
+ }
+
+ $tradeDayTypeArr = StockMarketModel::TRADE_DAY_TYPE;
+ $tradeDayTypeKeys = array_keys($tradeDayTypeArr);
+
+
+ // 状态
+ if(empty($param['status']) || !in_array($param['status'], [StockMarketModel::STATUS_NO, StockMarketModel::STATUS_OFF])){
+ return $this->toData('1', '状态类型无效', []);
+ }
+
+ $amOpenTime = '00:00';
+ $amCloseTime = '00:00';
+ $pmOpenTime = '00:00';
+ $pmCloseTime = '00:00';
+ $num = 0;
+ if(isset($param['am_open_time']) && is_string($param['am_open_time'])){
+ $amOpenTimestamp = strtotime($param['am_open_time']);
+ if($amOpenTimestamp !== false && date('H:i', $amOpenTimestamp) === $param['am_open_time']){
+ $amOpenTime = $param['am_open_time'];
+ $num++;
+ }
+ }
+
+ if(isset($param['am_close_time']) && is_string($param['am_close_time'])){
+ $amCloseTimestamp = strtotime($param['am_close_time']);
+ if($amCloseTimestamp !== false && date('H:i', $amCloseTimestamp) === $param['am_close_time']){
+ $amCloseTime = $param['am_close_time'];
+ $num++;
+ }
+ }
+
+ if(isset($param['pm_open_time']) && is_string($param['pm_open_time'])){
+ $pmOpenTimestamp = strtotime($param['pm_open_time']);
+ if($pmOpenTimestamp !== false && date('H:i', $pmOpenTimestamp) === $param['pm_open_time']){
+ $pmOpenTime = $param['pm_open_time'];
+ $num++;
+ }
+ }
+
+ if(isset($param['pm_close_time']) && is_string($param['pm_close_time'])){
+ $pmCloseTimestamp = strtotime($param['pm_close_time']);
+ if($pmCloseTimestamp !== false && date('H:i', $pmCloseTimestamp) === $param['pm_close_time']){
+ $pmCloseTime = $param['pm_close_time'];
+ $num++;
+ }
+ }
+
+ // 如果是开启状态 必须设置开盘时间
+ if($param['status'] == StockMarketModel::STATUS_NO && $num < 4){
+ return $this->toData('1', '需要设置开盘时间', []);
+ }
+
+
+ // 货币单位
+ if(empty($param['unit']) || !is_string($param['unit']) || strlen($param['unit']) > 10){
+ return $this->toData('1', '货币单位无效', []);
+ }
+
+ // 货币符号
+ if(empty($param['symbol']) || !is_string($param['symbol']) || strlen($param['symbol']) > 10){
+ return $this->toData('1', '货币符号无效', []);
+ }
+
+ // 兑换汇率
+ if(empty($param['rate']) || !is_numeric($param['rate']) || strlen($param['rate']) > 200){
+ return $this->toData('1', '兑换汇率无效', []);
+ }
+
+ $tradeDayType = $stockMarket->trade_day_type;
+
+ // 只有在没有设置过的情况下可以设置 设置之后不能修改
+ if($tradeDayType == 0){
+ if($param['status'] == StockMarketModel::STATUS_NO){
+ // 如果是开启状态 必须设置
+ if(empty($param['trade_day_type']) || !in_array($param['trade_day_type'], $tradeDayTypeKeys)){
+ return $this->toData('1', '交易日限制无效', []);
+ }
+ $tradeDayType = $param['trade_day_type'];
+ }else{
+ // 关闭状态 可以不设置
+ if(!empty($param['trade_day_type']) && in_array($param['trade_day_type'], $tradeDayTypeKeys)){
+ $tradeDayType = $param['trade_day_type'];
+ } else{
+ $tradeDayType = 0;
+ }
+ }
+ }
+
+ // 设置股票杠杆
+ $leverStatus = StockMarketModel::LEVER_STATUS_OFF;
+ $stockMin = 0;
+ $leverMin = 1;
+ $leverMax = 1;
+ if(!empty($param['lever_status']) && is_numeric($param['lever_status']) && $param['lever_status'] == StockMarketModel::LEVER_STATUS_ON){
+ $leverStatus = $param['lever_status'];
+ if(empty($param['stock_min']) || !is_numeric($param['stock_min']) || $param['stock_min'] <=0){
+ return $this->toData('1', '杠杆最小使用股数无效', []);
+ }
+
+ if(empty($param['lever_min']) || !is_numeric($param['lever_min']) || $param['lever_min'] <=0){
+ return $this->toData('1', '最小杠杆无效', []);
+ }
+
+ if(empty($param['lever_max']) || !is_numeric($param['lever_max']) || $param['lever_max'] <=0 || $param['lever_max'] < $param['lever_min']){
+ return $this->toData('1', '最大杠杆无效', []);
+ }
+
+
+
+ }
+ $stockMin = ceil($param['stock_min']);
+ $leverMin = ceil($param['lever_min']);
+ $leverMax = ceil($param['lever_max']);
+
+
+ $stockMarket->status = $param['status'];
+ $stockMarket->trade_day_type = $tradeDayType;
+ $stockMarket->symbol = $param['symbol'];
+ $stockMarket->unit = $param['unit'];
+ $stockMarket->rate = $param['rate'];
+ $stockMarket->am_open_time = $amOpenTime;
+ $stockMarket->am_close_time = $amCloseTime;
+ $stockMarket->pm_open_time = $pmOpenTime;
+ $stockMarket->pm_close_time = $pmCloseTime;
+ $stockMarket->trade_day_type = $tradeDayType;
+ $stockMarket->update_time = date('Y-m-d H:i:s');
+
+ $stockMarket->stock_min = $stockMin;
+ $stockMarket->lever_min = $leverMin;
+ $stockMarket->lever_max = $leverMax;
+ $stockMarket->lever_status = $leverStatus;
+
+ $stockMarket->save();
+
+ // 缓存
+ $list_key="STOCK_MARKET:LIST:" .$stockMarket->stock_market_type;
+ $redis = $this->getRedis();
+ $redis->del($list_key);
+ $redis->hMset($list_key, [
+ 'id'=>$stockMarket->id,
+ 'stock_market_type'=>$stockMarket->stock_market_type,
+ 'trade_day_type'=>$stockMarket->trade_day_type,
+ 'status'=>$stockMarket->status,
+ 'symbol'=>$stockMarket->symbol,
+ 'unit'=>$stockMarket->unit,
+ 'rate'=>$stockMarket->rate,
+ 'am_open_time'=>$stockMarket->am_open_time,
+ 'am_close_time'=>$stockMarket->am_close_time,
+ 'pm_open_time'=>$stockMarket->pm_open_time,
+ 'pm_close_time'=>$stockMarket->pm_close_time,
+
+ 'lever_status' => $leverStatus,
+ 'stock_min' => $stockMin,
+ 'lever_min' => $leverMin,
+ 'lever_max' => $leverMax,
+ ]);
+ $arr=$redis->hGetAll($list_key);
+
+ return $this->toData('0','SUCCESS',$arr);
+ }catch (\Exception $exception){
+ return $this->toData('1', '系统繁忙', [$exception->getMessage()]);
+ }
+ }
+
+
+ // 股票筛选 根据股票号 股票市场 模糊搜索股票数据
+ public function searchStock($param)
+ {
+ try {
+ $marketTypeList = StockMarketModel::STOCK_MARKET_TYPE;
+ if(empty($param['market_type']) || !in_array($param['market_type'], array_keys($marketTypeList))){
+ return $this->toData('1', '股票市场无效', []);
+ }
+
+ $where = [];
+ if(empty($param['page']) || !is_numeric($param['page']) || ceil($param['page']) != $param['page'] || $param['page'] <= 0){
+ return $this->toData('1', '分页参数无效', []);
+ }
+
+ if(empty($param['limit']) || !is_numeric($param['limit']) || ceil($param['limit']) != $param['limit'] || $param['limit'] <= 0){
+ return $this->toData('1', '分页参数无效', []);
+ }
+
+ if(!empty($param['stock_code']) && is_string($param['stock_code'])){
+ $where[] = ['stock_code', 'like', '%'.$param['stock_code']];
+ }
+
+ switch ($param['market_type'])
+ {
+ // 美股
+ case StockMarketModel::STOCK_MARKET_USA:
+ $stockList = StockListModel::where($where)->page($param['page'], $param['limit'])->select();
+ $total = StockListModel::where($where)->count();
+ break;
+ case StockMarketModel::STOCK_MARKET_YNG:
+ $stockList = StockIdnListModel::where($where)->page($param['page'], $param['limit'])->select();
+ $total = StockIdnListModel::where($where)->count();
+ break;
+ case StockMarketModel::STOCK_MARKET_MG:
+ $stockList = StockMysListModel::where($where)->page($param['page'], $param['limit'])->select();
+ $total = StockMysListModel::where($where)->count();
+ break;
+ case StockMarketModel::STOCK_MARKET_TG:
+ $stockList = StockThaListModel::where($where)->page($param['page'], $param['limit'])->select();
+ $total = StockThaListModel::where($where)->count();
+ break;
+ case StockMarketModel::STOCK_MARKET_IN:
+ $stockList = StockInListModel::where($where)->page($param['page'], $param['limit'])->select();
+ $total = StockInListModel::where($where)->count();
+ break;
+ case StockMarketModel::STOCK_MARKET_HK:
+ $stockList = StockHkdListModel::where($where)->page($param['page'], $param['limit'])->select();
+ $total = StockHkdListModel::where($where)->count();
+ break;
+ case StockMarketModel::STOCK_MARKET_UK:
+ $stockList = StockGBXListModel::where($where)->page($param['page'], $param['limit'])->select();
+ $total = StockGBXListModel::where($where)->count();
+ break;
+ case StockMarketModel::STOCK_MARKET_FUR:
+ $stockList = StockFurListModel::where($where)->page($param['page'], $param['limit'])->select();
+ $total = StockFurListModel::where($where)->count();
+ break;
+ case StockMarketModel::STOCK_MARKET_EUR:
+ $stockList = StockEurListModel::where($where)->page($param['page'], $param['limit'])->select();
+ $total = StockEurListModel::where($where)->count();
+ break;
+ default:
+ return $this->toData('1', '股票市场无效', []);
+ }
+
+ $rows = [];
+ if(!$stockList->isEmpty()){
+ $rows = $stockList->toArray();
+ }
+
+ return $this->toData('0','SUCCESS', ['total' => $total, 'list' => $rows, 'extent' => [
+ 'stock_market_type_list' => StockMarketModel::STOCK_MARKET_TYPE,
+ 'trade_day_type' => StockMarketModel::TRADE_DAY_TYPE,
+ ]]);
+ }catch (\Exception $exception){
+ return $this->toData('1', '系统繁忙', [$exception->getMessage()]);
+ }
+ }
+
+ // 根据股票市场 股票主键 查询股票
+ public function searchStockById($param)
+ {
+ $marketTypeList = StockMarketModel::STOCK_MARKET_TYPE;
+ if(empty($param['market_type']) || !in_array($param['market_type'], array_keys($marketTypeList))){
+ return [];
+ }
+
+ if(empty($param['stock_id']) || !is_numeric($param['stock_id'])){
+ return [];
+ }
+
+
+ switch ($param['market_type'])
+ {
+ // 美股
+ case StockMarketModel::STOCK_MARKET_USA:
+ $stock = StockListModel::where('id', $param['stock_id'])->find();
+ break;
+ case StockMarketModel::STOCK_MARKET_YNG:
+ $stock = StockIdnListModel::where('id', $param['stock_id'])->find();
+ break;
+ case StockMarketModel::STOCK_MARKET_MG:
+ $stock = StockMysListModel::where('id', $param['stock_id'])->find();
+ break;
+ case StockMarketModel::STOCK_MARKET_TG:
+ $stock = StockThaListModel::where('id', $param['stock_id'])->find();
+ break;
+ case StockMarketModel::STOCK_MARKET_IN:
+ $stock = StockInListModel::where('id', $param['stock_id'])->find();
+ break;
+ case StockMarketModel::STOCK_MARKET_HK:
+ $stock = StockHkdListModel::where('id', $param['stock_id'])->find();
+ break;
+ case StockMarketModel::STOCK_MARKET_UK:
+ $stock = StockGBXListModel::where('id', $param['stock_id'])->find();
+ break;
+ case StockMarketModel::STOCK_MARKET_FUR:
+ $stock = StockFurListModel::where('id', $param['stock_id'])->find();
+ break;
+ case StockMarketModel::STOCK_MARKET_EUR:
+ $stock = StockEurListModel::where('id', $param['stock_id'])->find();
+ break;
+ default:
+ return [];
+ }
+
+ if(empty($stock)){
+ return [];
+ }
+ return $stock->toArray();
+ }
+}
\ No newline at end of file
diff --git a/app/admin/service/setting/StockPriceSettingService.php b/app/admin/service/setting/StockPriceSettingService.php
new file mode 100644
index 0000000..376bd26
--- /dev/null
+++ b/app/admin/service/setting/StockPriceSettingService.php
@@ -0,0 +1,227 @@
+toData('1', '分页参数无效', []);
+ }
+
+ if (empty($param['limit']) || !is_numeric($param['limit']) || ceil($param['limit']) != $param['limit'] || $param['limit'] <= 0) {
+ return $this->toData('1', '分页参数无效', []);
+ }
+
+ $list = StockPricesSettingModel::order('id', 'desc')->page($param['page'], $param['limit'])->select();
+ $total = StockPricesSettingModel::where('id', '>', 0)->count();
+
+
+ $rows = [];
+ // 股票市场货币符号
+ $marketSymbol = StockMarketModel::where('id', '>', 0)->column('symbol', 'stock_market_type');
+ if (!$list->isEmpty()) {
+ $rows = $list->toArray();
+ foreach ($list as $key => $item) {
+ $stock = (new StockMarketService)->searchStockById(['market_type' => $item->market_type, 'stock_id' => $item->stock_id]);
+ $rows[$key]['stock_code'] = $stock['stock_code'] ?? '-';
+ $rows[$key]['stock_name'] = $stock['stock_name'] ?? '-';
+ $rows[$key]['symbol'] = $marketSymbol[$item->market_type] ?? '-';
+ $rows[$key]['price'] = rtrim(rtrim($item['price'], '0'), '.');
+ }
+ }
+
+
+ return $this->toData('0', 'SUCCESS', ['list' => $rows, 'total' => $total, 'extent' => [
+ 'market_type_list' => StockMarketModel::STOCK_MARKET_TYPE,
+ 'market_symbol' => $marketSymbol
+ ]]);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统繁忙', [$exception->getMessage()]);
+ }
+ }
+
+ // 新增
+ public function add($param)
+ {
+ try {
+ $marketTypeList = StockMarketModel::STOCK_MARKET_TYPE;
+ // 股票市场
+ if (empty($param['market_type']) || !in_array($param['market_type'], array_keys($marketTypeList))) {
+ return $this->toData('1', '市场类型无效', []);
+ }
+
+ // 股票主键
+ if (empty($param['stock_id']) || !is_numeric($param['stock_id'])) {
+ return $this->toData('1', '股票无效', []);
+ }
+
+ $stock = (new StockMarketService)->searchStockById(['market_type' => $param['market_type'], 'stock_id' => $param['stock_id']]);
+ if (empty($stock)) {
+ return $this->toData('1', '股票无效', []);
+ }
+
+ // 盘前状态
+ if (empty($param['status']) || !in_array($param['status'], [StockPricesSettingModel::STATUS_ON, StockPricesSettingModel::STATUS_OFF])) {
+ return $this->toData('1', '状态无效', []);
+ }
+
+ if (empty($param['price']) || !is_numeric($param['price'])) {
+ return $this->toData('1', '价格无效', []);
+ }
+
+ // 判断市场是否已经存在
+ $count = StockPricesSettingModel::where('market_type', $param['market_type'])->where('stock_id', $param['stock_id'])->count();
+ if ($count > 0) {
+ return $this->toData('1', '已存在相同配置', []);
+ }
+
+ // 添加缓存
+ $key = 'STOCK_PRICES:' . $param['market_type'] . ':' . $stock['stock_code'];
+ $redis = $this->getRedis();
+ $redis->del($key);
+ $bool = $redis->hMSet($key, [
+ 'market_type' => $param['market_type'],
+ 'stock_id' => $param['stock_id'],
+ 'stock_code' => $stock['stock_code'],
+ 'status' => $param['status'],
+ 'price' => $param['price'],
+ ]);
+
+ if ($bool) {
+ $stockPriceSetting = new StockPricesSettingModel;
+ $stockPriceSetting->market_type = $param['market_type'];
+ $stockPriceSetting->stock_id = $param['stock_id'];
+ $stockPriceSetting->status = $param['status'];
+ $stockPriceSetting->price = $param['price'];
+ $stockPriceSetting->create_time = date('Y-m-d H:i:s');
+ $stockPriceSetting->update_time = date('Y-m-d H:i:s');
+ $stockPriceSetting->save();
+ }
+
+ return $this->toData('0', 'SUCCESS', []);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统繁忙', [$exception->getMessage()]);
+ }
+ }
+
+ // 编辑
+ public function edit($param)
+ {
+ try {
+ $marketTypeList = StockMarketModel::STOCK_MARKET_TYPE;
+ // 目标
+ if (empty($param['id']) || !is_numeric($param['id'])) {
+ return $this->toData('1', '目标不存在', []);
+ }
+
+ $stockPriceSetting = StockPricesSettingModel::where('id', $param['id'])->find();
+ if (empty($stockPriceSetting)) {
+ return $this->toData('1', '目标不存在', []);
+ }
+
+ // 股票市场
+ if (empty($param['market_type']) || !in_array($param['market_type'], array_keys($marketTypeList))) {
+ return $this->toData('1', '市场类型无效', []);
+ }
+
+ // 股票主键
+ if (empty($param['stock_id']) || !is_numeric($param['stock_id'])) {
+ return $this->toData('1', '股票无效', []);
+ }
+
+ $stock = (new StockMarketService)->searchStockById(['market_type' => $param['market_type'], 'stock_id' => $param['stock_id']]);
+ if (empty($stock)) {
+ return $this->toData('1', '股票无效', []);
+ }
+
+ // 盘前状态
+ if (empty($param['status']) || !in_array($param['status'], [StockPricesSettingModel::STATUS_ON, StockPricesSettingModel::STATUS_OFF])) {
+ return $this->toData('1', '盘前状态无效', []);
+ }
+
+ if (empty($param['price']) || !is_numeric($param['price'])) {
+ return $this->toData('1', '价格无效', []);
+ }
+
+ // 判断市场是否已经存在
+ $count = StockPricesSettingModel::where('market_type', $param['market_type'])->where('stock_id', $param['stock_id'])
+ ->where('id', '<>', $param['id'])
+ ->count();
+
+ if ($count > 0) {
+ return $this->toData('1', '已存在相同配置', []);
+ }
+
+ // 添加缓存
+ $key = 'STOCK_PRICES:' . $param['market_type'] . ':' . $stock['stock_code'];
+ $redis = $this->getRedis();
+ $redis->del($key);
+ $bool = $redis->hMSet($key, [
+ 'market_type' => $param['market_type'],
+ 'stock_id' => $param['stock_id'],
+ 'stock_code' => $stock['stock_code'],
+ 'status' => $param['status'],
+ 'price' => $param['price'],
+ ]);
+
+ if ($bool) {
+ $stockPriceSetting->market_type = $param['market_type'];
+ $stockPriceSetting->stock_id = $param['stock_id'];
+ $stockPriceSetting->status = $param['status'];
+ $stockPriceSetting->price = $param['price'];
+ $stockPriceSetting->update_time = date('Y-m-d H:i:s');
+ $stockPriceSetting->save();
+ }
+
+ return $this->toData('0', 'SUCCESS', [$stockPriceSetting->price]);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统繁忙', [$exception->getMessage()]);
+ }
+ }
+
+ // 删除
+ public function del($param)
+ {
+ try {
+ // 目标
+ if (empty($param['id']) || !is_numeric($param['id'])) {
+ return $this->toData('1', '目标不存在', []);
+ }
+
+ $stockPriceSetting = StockPricesSettingModel::where('id', $param['id'])->find();
+ if (empty($stockPriceSetting)) {
+ return $this->toData('1', '目标不存在', []);
+ }
+
+ if ($stockPriceSetting->status == StockPricesSettingModel::STATUS_ON) {
+ return $this->toData('1', '配置开启中 不可删除', []);
+ }
+
+ $stock = (new StockMarketService)->searchStockById(['market_type' => $stockPriceSetting->market_type, 'stock_id' => $stockPriceSetting->stock_id]);
+ if (empty($stock)) {
+ return $this->toData('1', '股票无效', []);
+ }
+
+ $key = 'STOCK_PRICES:' . $stockPriceSetting->market_type . ':' . $stock['stock_code'];
+ $redis = $this->getRedis();
+ $num = $redis->del($key);
+ if ($num > 0) {
+ $stockPriceSetting->delete();
+ }
+
+ return $this->toData('0', 'SUCCESS');
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统繁忙', [$exception->getMessage()]);
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/app/admin/service/setting/StockService.php b/app/admin/service/setting/StockService.php
new file mode 100644
index 0000000..010ca2a
--- /dev/null
+++ b/app/admin/service/setting/StockService.php
@@ -0,0 +1,43 @@
+stockList(3,$param);
+ }
+
+ public function add($param)
+ {
+ return (new IPOService())->addStock(3,$param);
+ }
+
+
+ public function edit($param)
+ {
+ return (new IPOService())->editStock(3,$param);
+ }
+
+ // 美股列表
+ public function getTradeNameList($param)
+ {
+ try {
+ $list = StockListModel::where('status', 1)->order('id', 'desc')->column('stock_name', 'id');
+ return $this->toData('0', 'SUCCESS', ['list' => $list]);
+ } catch (\Exception $exception) {
+ return $this->toData('1', '系统繁忙', []);
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/admin/validate/AdminBaseValidate.php b/app/admin/validate/AdminBaseValidate.php
new file mode 100644
index 0000000..8b50591
--- /dev/null
+++ b/app/admin/validate/AdminBaseValidate.php
@@ -0,0 +1,93 @@
+ 'require|alphaNum',
+ 'password' => 'require|length:5,40',
+ 'new_password' => 'require|length:5,40',
+ 'old_password' => 'require|length:5,40',
+ 'nick_name' => 'require|alphaNum',
+
+ ];
+
+ protected $message = [
+ 'user_name.alphaNum' => '用户名必须包含字母和数字',
+ 'nick_name.alphaNum' => '昵称必须包含字母和数字',
+ 'password.require' => '请填写密码',
+// 'password.isString' => '密码格式不正确.',
+ 'password.length' => '密码必须大于5个字符.',
+ 'new_password.require' => '请填写新密码',
+// 'password.isString' => '密码格式不正确.',
+ 'new_password.length' => '密码必须大于5个字符.',
+ 'old_password.require' => '请填写原始密码',
+// 'password.isString' => '密码格式不正确.',
+ 'old_password.length' => '密码必须大于5个字符.',
+
+ ];
+
+
+ protected $scene = [
+ 'addUser' => ['user_name','password','nick_name'],
+ 'updateInfo' => ['nick_name','email'],
+ 'updateAccount' => ['user_name','nick_name'],
+ 'updatePassword'=>['new_password','old_password'],
+ 'updateAccountStatus'=>['id','status']
+ ];
+}
\ No newline at end of file
diff --git a/app/admin/validate/FlowValidate.php b/app/admin/validate/FlowValidate.php
new file mode 100644
index 0000000..d067098
--- /dev/null
+++ b/app/admin/validate/FlowValidate.php
@@ -0,0 +1,77 @@
+ 'require|integer',
+ 'limit' => 'require|integer',
+ 'order_id' => 'alphaNum',
+ 'user_no' => 'alphaNum',
+ 'chang_type' => 'in:1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20',
+ 'digital_id' => 'upper',
+ 'contract_id' => 'alphaDash',
+ 'stock_id' => 'alphaDash',
+ 'start_time' => 'date|dateFormat:Y-m-d H:i:s',
+ 'end_time' => 'date|dateFormat:Y-m-d H:i:s',
+ 'from_account' => 'in:1,2,3',
+ 'to_account' => 'in:1,2,3',
+ 'account_type' => 'in:1,2,3',
+ 'trade_type' => 'in:1,2',
+ 'trade_no' => 'alphaNum',
+ 'level_type' => 'in:1,2,3',
+ 'back_type' => 'in:0,1,2,3',
+ ];
+
+ protected $message = [
+ 'page.require' => '分页参数无效',
+ 'page.integer' => '分页参数无效',
+ 'limit.require' => '分页参数无效',
+ 'limit.integer' => '分页参数无效',
+ 'chang_type.in' => '变动类型无效',
+ 'order_id.alphaNum' => '订单号无效',
+ 'user_no.alphaNum' => '用户号无效',
+ 'digital_id.upper' => '交易对无效',
+ 'contract_id.upper' => '合约代码无效',
+ 'stock_id.upper' => '股票代码无效',
+ 'start_time.date' => '搜索日期无效',
+ 'start_time.dateFormat' => '搜索日期无效',
+ 'end_time.date' => '搜索日期无效',
+ 'end_time.dateFormat' => '搜索日期无效',
+ 'from_account.in' => '转出资金账号无效',
+ 'to_account.in' => '转入资金账号无效',
+ 'account_type.in' => '账户类型无效',
+ 'trade_type.in' => '交易类型无效',
+ 'trade_no.in' => '交易单号无效',
+ 'level_type.in' => '返佣级别无效',
+ 'back_type.in' => '返佣类型无效',
+ ];
+
+ protected $scene = [
+ 'digital' => ['page','limit', 'user_no', 'digital_id', 'chang_type','start_time', 'end_time'],
+ 'stock' => ['page','limit', 'user_no', 'stock_id', 'chang_type','start_time', 'end_time'],
+ 'contract' => ['page','limit', 'user_no', 'contract_id', 'chang_type','start_time', 'end_time'],
+ 'forex' => ['page','limit', 'user_no', 'contract_id', 'chang_type','start_time', 'end_time'],
+ 'transfer' => ['page','limit', 'user_no', 'from_account', 'to_account','start_time', 'end_time'],
+ 'fee' => ['page','limit', 'user_no', 'account_type', 'trade_type','trade_no','start_time', 'end_time'],
+ 'brokerage' => ['page','limit', 'user_no', 'level_type', 'back_type','start_time', 'end_time'],
+
+ // 美股资产流水
+ 'us_stock' => ['page','limit', 'user_no', 'stock_id', 'chang_type','start_time', 'end_time'],
+ // 印尼股票
+ 'idn_stock' => ['page','limit', 'user_no', 'stock_id', 'chang_type','start_time', 'end_time'],
+ // 马来西亚资产流水
+ 'mys_stock' => ['page','limit', 'user_no', 'stock_id', 'chang_type','start_time', 'end_time'],
+ // 泰国股票
+ 'tha_stock' => ['page','limit', 'user_no', 'stock_id', 'chang_type','start_time', 'end_time'],
+ // 印度股票
+ 'in_stock' => ['page','limit', 'user_no', 'stock_id', 'chang_type','start_time', 'end_time'],
+ 'sgd_stock' => ['page','limit', 'user_no', 'stock_id', 'chang_type','start_time', 'end_time'],
+ 'hk_stock' => ['page','limit', 'user_no', 'stock_id', 'chang_type','start_time', 'end_time'],
+
+ 'fund_stock' => ['page','limit', 'user_no', 'stock_id', 'chang_type','start_time', 'end_time'],
+ 'block_stock' => ['page','limit', 'user_no', 'stock_id', 'chang_type','start_time', 'end_time'],
+
+ ];
+}
\ No newline at end of file
diff --git a/app/admin/validate/LoginValidate.php b/app/admin/validate/LoginValidate.php
new file mode 100644
index 0000000..bf33bc4
--- /dev/null
+++ b/app/admin/validate/LoginValidate.php
@@ -0,0 +1,20 @@
+ 'require|alphaNum',
+ 'password' => 'require|length:5,40',
+ ];
+ protected $message = [
+ 'user_name.require' => '请填写用户名',
+ 'user_name.alphaNum' => '用户名必须包含字母和数字',
+ 'password.require' => '请填写密码',
+ 'password.length' => '密码必须大于5个字符.',
+ ];
+ protected $scene = [
+ 'login' => ['user_name','password'],
+ ];
+}
\ No newline at end of file
diff --git a/app/admin/validate/OrderValidate.php b/app/admin/validate/OrderValidate.php
new file mode 100644
index 0000000..a060b1a
--- /dev/null
+++ b/app/admin/validate/OrderValidate.php
@@ -0,0 +1,109 @@
+ 'require|integer',
+ 'limit' => 'require|integer',
+ 'order_id' => 'alphaNum',
+ 'order_no' => 'alphaNum',
+ 'user_no' => 'alphaNum',
+ 'digital_id' => 'upper',
+ 'contract_id' => 'alphaDash',
+ 'stock_id' => 'alphaDash',
+ 'stock_code' => 'alphaDash',
+ 'status' => 'integer',
+ 'start_time' => 'date|dateFormat:Y-m-d H:i:s',
+ 'end_time' => 'date|dateFormat:Y-m-d H:i:s',
+ ];
+
+ protected $message = [
+ 'page.require' => '分页参数无效',
+ 'page.integer' => '分页参数无效',
+ 'limit.require' => '分页参数无效',
+ 'limit.integer' => '分页参数无效',
+ 'order_id.alphaNum' => '订单号无效',
+ 'user_no.alphaNum' => '用户号无效',
+ 'digital_id.upper' => '交易对无效',
+ 'contract_id.upper' => '合约代码无效',
+ 'stock_id.upper' => '股票代码无效',
+ 'start_time.date' => '搜索日期无效',
+ 'start_time.dateFormat' => '搜索日期无效',
+ 'end_time.date' => '搜索日期无效',
+ 'end_time.dateFormat' => '搜索日期无效',
+ ];
+
+ protected $scene = [
+ // 现货
+ 'digitalPlace' => ['page', 'limit', 'order_id', 'user_no', 'digital_id', 'start_time', 'end_time'],
+ 'digitalBack' => ['page', 'limit', 'order_id', 'user_no', 'digital_id', 'start_time', 'end_time'],
+ 'digitalDeal' => ['page', 'limit', 'order_id', 'user_no', 'digital_id', 'start_time', 'end_time'],
+
+ // 合约
+ 'contractHold' => ['page', 'limit', 'order_id', 'user_no', 'contract_id', 'start_time', 'end_time'],
+ 'contractPlace' => ['page', 'limit', 'order_id', 'user_no', 'contract_id', 'start_time', 'end_time'],
+ 'contractBack' => ['page', 'limit', 'order_id', 'user_no', 'contract_id', 'start_time', 'end_time'],
+ 'contractClear' => ['page', 'limit', 'order_id', 'user_no', 'contract_id', 'start_time', 'end_time'],
+ // 合约
+ 'forexHold' => ['page', 'limit', 'order_id', 'user_no', 'contract_id', 'start_time', 'end_time'],
+ 'forexPlace' => ['page', 'limit', 'order_id', 'user_no', 'contract_id', 'start_time', 'end_time'],
+ 'forexBack' => ['page', 'limit', 'order_id', 'user_no', 'contract_id', 'start_time', 'end_time'],
+ 'forexClear' => ['page', 'limit', 'order_id', 'user_no', 'contract_id', 'start_time', 'end_time'],
+
+ // 股票
+ 'stockHold' => ['page', 'limit', 'order_id', 'user_no', 'stock_id', 'start_time', 'end_time'],
+ 'stockPlace' => ['page', 'limit', 'order_id', 'user_no', 'stock_id', 'start_time', 'end_time'],
+ 'stockBack' => ['page', 'limit', 'order_id', 'user_no', 'stock_id', 'start_time', 'end_time'],
+ 'stockClear' => ['page', 'limit', 'order_id', 'user_no', 'stock_id', 'start_time', 'end_time'],
+
+ // 美股股票
+ 'us_stockHold' => ['page', 'limit', 'order_id', 'user_no', 'stock_id', 'start_time', 'end_time'],
+ 'us_stockPlace' => ['page', 'limit', 'order_id', 'user_no', 'stock_id', 'start_time', 'end_time'],
+ 'us_stockBack' => ['page', 'limit', 'order_id', 'user_no', 'stock_id', 'start_time', 'end_time'],
+ 'us_stockClear' => ['page', 'limit', 'order_id', 'user_no', 'stock_id', 'start_time', 'end_time'],
+
+ // 印尼股票
+ 'idn_stockHold' => ['page', 'limit', 'order_id', 'user_no', 'stock_id', 'start_time', 'end_time'],
+ 'idn_stockPlace' => ['page', 'limit', 'order_id', 'user_no', 'stock_id', 'start_time', 'end_time'],
+ 'idn_stockBack' => ['page', 'limit', 'order_id', 'user_no', 'stock_id', 'start_time', 'end_time'],
+ 'idn_stockClear' => ['page', 'limit', 'order_id', 'user_no', 'stock_id', 'start_time', 'end_time'],
+
+ // 马来西亚股票
+ 'mys_stockHold' => ['page', 'limit', 'order_id', 'user_no', 'stock_id', 'start_time', 'end_time'],
+ 'mys_stockPlace' => ['page', 'limit', 'order_id', 'user_no', 'stock_id', 'start_time', 'end_time'],
+ 'mys_stockBack' => ['page', 'limit', 'order_id', 'user_no', 'stock_id', 'start_time', 'end_time'],
+ 'mys_stockClear' => ['page', 'limit', 'order_id', 'user_no', 'stock_id', 'start_time', 'end_time'],
+
+ // 泰国股票
+ 'tha_stockHold' => ['page', 'limit', 'order_id', 'user_no', 'stock_id', 'start_time', 'end_time'],
+ 'tha_stockPlace' => ['page', 'limit', 'order_id', 'user_no', 'stock_id', 'start_time', 'end_time'],
+ 'tha_stockBack' => ['page', 'limit', 'order_id', 'user_no', 'stock_id', 'start_time', 'end_time'],
+ 'tha_stockClear' => ['page', 'limit', 'order_id', 'user_no', 'stock_id', 'start_time', 'end_time'],
+
+ // 印度股票
+ 'in_stockHold' => ['page', 'limit', 'order_id', 'user_no', 'stock_id', 'start_time', 'end_time'],
+ 'in_stockPlace' => ['page', 'limit', 'order_id', 'user_no', 'stock_id', 'start_time', 'end_time'],
+ 'in_stockBack' => ['page', 'limit', 'order_id', 'user_no', 'stock_id', 'start_time', 'end_time'],
+ 'in_stockClear' => ['page', 'limit', 'order_id', 'user_no', 'stock_id', 'start_time', 'end_time'],
+
+ // 申购订单
+ 'pre_stock' => ['page', 'limit', 'order_no', 'user_no', 'market_type'],
+
+ // 基金订单
+ 'fund_stock' => ['page', 'limit', 'order_no', 'user_no', 'start_time', 'end_time'],
+ 'fund_stock_info' => ['id'],
+ 'fund_interest_list' => ['page', 'limit', 'user_no', 'start_time', 'end_time'],
+
+ // 香港股票
+ 'hk_stockHold' => ['page', 'limit', 'order_id', 'user_no', 'stock_id', 'start_time', 'end_time'],
+ 'hk_stockPlace' => ['page', 'limit', 'order_id', 'user_no', 'stock_id', 'start_time', 'end_time'],
+ 'hk_stockBack' => ['page', 'limit', 'order_id', 'user_no', 'stock_id', 'start_time', 'end_time'],
+ 'hk_stockClear' => ['page', 'limit', 'order_id', 'user_no', 'stock_id', 'start_time', 'end_time'],
+
+ // 大宗交易
+ 'block_stock' => ['page', 'limit', 'user_no'],
+ ];
+}
\ No newline at end of file
diff --git a/app/admin/validate/RechargeValidate.php b/app/admin/validate/RechargeValidate.php
new file mode 100644
index 0000000..17962ea
--- /dev/null
+++ b/app/admin/validate/RechargeValidate.php
@@ -0,0 +1,44 @@
+ 'require|integer',
+ 'limit' => 'require|integer',
+ 'check_status' => 'require|integer',
+ 'is_online' => 'require|integer',
+ 'id' => 'require|integer',
+ 'order_id' => 'alphaNum',
+ 'user_no' => 'alphaNum',
+ 'start_time' => 'date|dateFormat:Y-m-d H:i:s',
+ 'end_time' => 'date|dateFormat:Y-m-d H:i:s',
+ ];
+
+ protected $message = [
+ 'is_online.require' => '支付类型无效',
+ 'is_online.integer' => '支付类型无效',
+ 'id.require' => 'ID参数无效',
+ 'id.integer' => 'ID参数无效',
+ 'check_status.require' => '审核状态无效',
+ 'check_status.integer' => '审核无效',
+ 'page.require' => '分页参数无效',
+ 'page.integer' => '分页参数无效',
+ 'limit.require' => '分页参数无效',
+ 'limit.integer' => '分页参数无效',
+ 'order_id.alphaNum' => '订单号无效',
+ 'user_no.alphaNum' => '用户号无效',
+ 'start_time.date' => '搜索日期无效',
+ 'start_time.dateFormat' => '搜索日期无效',
+ 'end_time.date' => '搜索日期无效',
+ 'end_time.dateFormat' => '搜索日期无效',
+ ];
+
+ protected $scene = [
+ // 现货
+ 'index' => ['page','limit','order_id', 'user_no', 'start_time', 'end_time','is_online'],
+ 'info' => ['id'],
+ 'check' => ['id','check_status'],
+ ];
+}
\ No newline at end of file
diff --git a/app/admin/validate/UserValidate.php b/app/admin/validate/UserValidate.php
new file mode 100644
index 0000000..5215039
--- /dev/null
+++ b/app/admin/validate/UserValidate.php
@@ -0,0 +1,55 @@
+ 'require|integer',
+ 'limit' => 'require|integer',
+ 'start_time' => 'date|dateFormat:Y-m-d H:i:s',
+ 'end_time' => 'date|dateFormat:Y-m-d H:i:s',
+ 'phone' => 'alphaNum',
+ 'user_no' => 'alphaNum',
+ 'email' => 'email',
+ 'status' => 'require|in:1,2,3',
+ 'nation'=>'require',
+ 'password'=>'require',
+ 'id' =>'require|integer',
+ 'is_test_user' => 'require|in:1,2',
+ ];
+
+ protected $message = [
+ 'page.require' => '分页参数无效',
+ 'page.integer' => '分页参数无效',
+ 'limit.require' => '分页参数无效',
+ 'limit.integer' => '分页参数无效',
+ 'user_no.alphaNum' => '用户号无效',
+ 'start_time.date' => '搜索日期无效',
+ 'start_time.dateFormat' => '搜索日期无效',
+ 'end_time.date' => '搜索日期无效',
+ 'end_time.dateFormat' => '搜索日期无效',
+ 'phone.alphaNum' => '手机号无效',
+ 'email.email' => '邮箱无效',
+ 'id.require' => '主键无效',
+ 'id.alphaNum' => '主键无效',
+ 'status.require' => '状态无效',
+ 'nation.require' => '国家代码无效',
+ 'password.require' => '登录密码无效',
+ 'status.in' => '主键无效',
+ 'type.require' => '类型无效',
+ 'type.in' => '类型无效',
+ 'is_test_user.in' => '未选择用户类型',
+ ];
+
+
+ protected $scene = [
+ 'index' => ['page','limit','user_no', 'email', 'phone', 'start_time', 'end_time'],
+ 'status' => ['id','status'],
+ 'change' => ['id','amount'],
+ 'relation' => ['page','limit','user_no'],
+ 'add_phone' =>['nation','phone','password'],
+ 'add_email' =>['email','password'],
+ ];
+}
\ No newline at end of file
diff --git a/app/admin/validate/WithdrawValidate.php b/app/admin/validate/WithdrawValidate.php
new file mode 100644
index 0000000..edce6de
--- /dev/null
+++ b/app/admin/validate/WithdrawValidate.php
@@ -0,0 +1,41 @@
+ 'require|integer',
+ 'id' => 'require|integer',
+ 'status' => 'require|integer',
+ 'limit' => 'require|integer',
+ 'order_id' => 'alphaNum',
+ 'user_no' => 'alphaNum',
+ 'start_time' => 'date|dateFormat:Y-m-d H:i:s',
+ 'end_time' => 'date|dateFormat:Y-m-d H:i:s',
+ ];
+
+ protected $message = [
+ 'id.require' => '订单ID无效',
+ 'id.integer' => '订单ID无效',
+ 'status.require' => '状态无效',
+ 'status.integer' => '状态无效',
+ 'page.require' => '分页参数无效',
+ 'page.integer' => '分页参数无效',
+ 'limit.require' => '分页参数无效',
+ 'limit.integer' => '分页参数无效',
+ 'order_id.alphaNum' => '订单号无效',
+ 'user_no.alphaNum' => '用户号无效',
+ 'start_time.date' => '搜索日期无效',
+ 'start_time.dateFormat' => '搜索日期无效',
+ 'end_time.date' => '搜索日期无效',
+ 'end_time.dateFormat' => '搜索日期无效',
+ ];
+
+ protected $scene = [
+ // 现货
+ 'index' => ['page','limit','order_id', 'user_no', 'start_time', 'end_time'],
+ 'info' => ['id'],
+ 'status' => ['id','status'],
+ ];
+}
\ No newline at end of file
diff --git a/app/admin/validate/auth/AuthRoleValidate.php b/app/admin/validate/auth/AuthRoleValidate.php
new file mode 100644
index 0000000..2ceffe5
--- /dev/null
+++ b/app/admin/validate/auth/AuthRoleValidate.php
@@ -0,0 +1,30 @@
+ 'require|integer',
+ 'limit' => 'require|integer',
+ 'id'=>'require|integer',
+ 'name' => 'require',
+ 'rules' => 'require',
+ 'status' => 'require',
+
+ ];
+
+ protected $message = [
+
+
+ ];
+
+
+ protected $scene = [
+ 'add' => ['name'],
+ 'edit'=> ['id','name'],
+ 'list'=>[],
+ 'updateStatus'=>['id','status'],
+ ];
+}
\ No newline at end of file
diff --git a/app/admin/validate/auth/AuthRuleValidate.php b/app/admin/validate/auth/AuthRuleValidate.php
new file mode 100644
index 0000000..d6b461e
--- /dev/null
+++ b/app/admin/validate/auth/AuthRuleValidate.php
@@ -0,0 +1,40 @@
+ 'require|integer',
+ 'limit' => 'require|integer',
+ 'id' => 'require|integer',
+ 'type' => 'require',
+ 'pid' => 'require|integer',
+ 'name' => 'require',
+ 'title' => 'require',
+ 'icon'=>'require',
+ 'route_path'=>'require',
+ 'remark'=>'require',
+ 'sort'=>'require',
+ 'status'=>'require',
+ 'permission'=>'require',
+ 'path'=>'require',
+ 'show'=>'require',
+ 'component_path'=>'require'
+
+
+ ];
+
+ protected $message = [
+
+
+ ];
+
+
+ protected $scene = [
+ 'add' => ['type','name',],
+ 'edit' => ['id','type','name'],
+ 'list'=>[]
+ ];
+}
\ No newline at end of file
diff --git a/app/admin/validate/setting/ContractValidate.php b/app/admin/validate/setting/ContractValidate.php
new file mode 100644
index 0000000..b65a781
--- /dev/null
+++ b/app/admin/validate/setting/ContractValidate.php
@@ -0,0 +1,58 @@
+ 'require|alphaDash',
+ 'status' => 'require|in:0,1',
+ 'is_owner' => 'require|in:0,1',
+ 'limit' => 'require|alphaNum',
+ 'order_id' => 'alphaNum',
+ 'user_no' => 'alphaNum',
+ 'digital_id' => 'upper',
+ 'contract_id' => 'alphaDash',
+ 'stock_id' => 'alphaDash',
+ 'start_time' => 'date|dateFormat:Y-m-d H:i:s',
+ 'end_time' => 'date|dateFormat:Y-m-d H:i:s',
+ ];
+
+ protected $message = [
+ 'page.require' => '分页参数无效',
+ 'page.alphaNum' => '分页参数无效',
+ 'limit.require' => '分页参数无效',
+ 'limit.alphaNum' => '分页参数无效',
+ 'order_id.alphaNum' => '订单号无效',
+ 'user_no.alphaNum' => '用户号无效',
+ 'digital_id.upper' => '交易对无效',
+ 'contract_id.upper' => '合约代码无效',
+ 'stock_id.upper' => '股票代码无效',
+ 'start_time.date' => '搜索日期无效',
+ 'start_time.dateFormat' => '搜索日期无效',
+ 'end_time.date' => '搜索日期无效',
+ 'end_time.dateFormat' => '搜索日期无效',
+ ];
+
+ protected $scene = [
+ // 现货
+ 'digitalPlace' => ['page','limit','order_id', 'user_no', 'digital_id', 'start_time', 'end_time'],
+ 'digitalBack' => ['page','limit','order_id', 'user_no', 'digital_id', 'start_time', 'end_time'],
+ 'digitalDeal' => ['page','limit','order_id', 'user_no', 'digital_id', 'start_time', 'end_time'],
+
+ // 合约
+ 'contractHold' => ['page','limit','order_id', 'user_no', 'contract_id', 'start_time', 'end_time'],
+ 'contractPlace' => ['page','limit','order_id', 'user_no', 'contract_id', 'start_time', 'end_time'],
+ 'contractBack' => ['page','limit','order_id', 'user_no', 'contract_id', 'start_time', 'end_time'],
+ 'contractClear' => ['page','limit','order_id', 'user_no', 'contract_id', 'start_time', 'end_time'],
+
+ // 股票
+ 'stockHold' => ['page','limit','order_id', 'user_no', 'stock_id', 'start_time', 'end_time'],
+ 'stockPlace' => ['page','limit','order_id', 'user_no', 'stock_id', 'start_time', 'end_time'],
+ 'stockBack' => ['page','limit','order_id', 'user_no', 'stock_id', 'start_time', 'end_time'],
+ 'stockClear' => ['page','limit','order_id', 'user_no', 'stock_id', 'start_time', 'end_time'],
+ ];
+}
\ No newline at end of file
diff --git a/app/admin/validate/setting/HqValidate.php b/app/admin/validate/setting/HqValidate.php
new file mode 100644
index 0000000..10273c9
--- /dev/null
+++ b/app/admin/validate/setting/HqValidate.php
@@ -0,0 +1,35 @@
+ 'require|alphaDash',
+ 'begin_time' => 'date',
+ 'end_time' => 'date',
+ 'step' => 'require|integer',
+ 'max_price' => 'require|float',
+ 'id' => 'require|integer',
+ ];
+
+ protected $message = [
+ 'trade_name.require' => '交易对无效',
+ 'trade_name.alphaDash' => '交易对无效',
+ 'begin_time.date' => '开始时间无效',
+ 'end_time.date' => '结束时间无效',
+ 'step.require' => '步长无效',
+ 'step.integer' => '步长无效',
+ 'max_price.require' => '价格无效',
+ 'max_price.float' => '价格无效',
+ ];
+
+ protected $scene = [
+ 'add' => ['trade_name','begin_time','end_time', 'step', 'max_price'],
+ 'edit' => ['trade_name','begin_time','end_time', 'step', 'max_price', 'id'],
+ 'del' => ['id'],
+ ];
+}
\ No newline at end of file
diff --git a/app/admin/validate/setting/MarketValidate.php b/app/admin/validate/setting/MarketValidate.php
new file mode 100644
index 0000000..8c9798f
--- /dev/null
+++ b/app/admin/validate/setting/MarketValidate.php
@@ -0,0 +1,31 @@
+ 'require|alphaDash',
+ 'end_time' => 'date|dateFormat:Y-m-d H:i',
+ 'max_price' => 'require|float',
+ 'id' => 'require|integer',
+ ];
+
+ protected $message = [
+ 'trade_name.require' => '交易对无效',
+ 'trade_name.alphaDash' => '交易对无效',
+ 'end_time.dateFormat' => '结束时间无效3',
+ 'end_time.date' => '结束时间无效4',
+ 'max_price.require' => '价格无效',
+ 'max_price.float' => '价格无效',
+ ];
+
+ protected $scene = [
+ 'add' => ['trade_name','end_time', 'max_price'],
+ 'edit' => ['trade_name','end_time', 'max_price', 'id'],
+ 'del' => ['id'],
+ 'detail' => ['trade_name'],
+ ];
+}
\ No newline at end of file
diff --git a/app/admin/validate/setting/PaymentValidate.php b/app/admin/validate/setting/PaymentValidate.php
new file mode 100644
index 0000000..648b8f9
--- /dev/null
+++ b/app/admin/validate/setting/PaymentValidate.php
@@ -0,0 +1,62 @@
+ 'require|integer',
+ 'limit' => 'require|integer',
+ 'country' => 'require|checkIsString',
+ 'channel' => 'require',
+ 'service_rate' => 'require|float',
+ //'channel_type' => 'checkInRequire|in:Bank,TRC-20,ERC-20,BRC-20',
+ 'channel_type' => 'require',
+ 'status' => 'checkStatusRequire|in:0,1',
+ 'pay_type' => 'checkStatusRequire|in:0,1',
+ 'is_recharge' => 'checkStatusRequire|in:0,1',
+ 'is_withdrawal' => 'checkStatusRequire|in:0,1',
+
+ 'id' => 'require|checkNumberIntBg',
+ ];
+
+ protected $message = [
+ 'page.require' => '分页参数无效',
+ 'page.integer' => '分页参数无效',
+ 'limit.require' => '分页参数无效',
+ 'limit.integer' => '分页参数无效',
+ 'channel.require' => '渠道名称不能为空',
+ 'country.require' => '国家代码无效',
+ 'service_rate.require' => '手续费率不能为空',
+ 'service_rate.float' => '手续费率无效',
+
+ 'country.checkIsString' => '国家代码无效',
+
+ 'status.checkStatusRequire' => '状态无效',
+ 'status.in' => '状态无效',
+ 'pay_type.checkStatusRequire' => '结算方式无效',
+ 'pay_type.in' => '结算方式无效',
+ 'is_recharge.checkStatusRequire' => '充值渠道状态无效',
+ 'is_recharge.in' => '充值渠道状态无效',
+ 'is_withdrawal.checkStatusRequire' => '提现渠道状态无效',
+ 'is_withdrawal.in' => '提现渠道状态无效',
+ 'channel_type.checkInRequire' => '渠道类型无效1',
+ 'channel_type.in' => '渠道类型无效',
+ 'channel_type.require' => '渠道类型无效',
+
+ 'id.require' => '主键无效',
+ 'id.checkNumberIntBg' => '主键无效',
+
+ ];
+
+
+ protected $scene = [
+ // 美股
+ 'payment_index' => ['page','limit'],
+ 'payment_add' => ['country','channel', 'status', 'pay_type', 'service_rate', 'channel_type', 'exchange_rate','is_recharge','is_withdrawal'],
+ 'payment_edit' => ['id','country','channel', 'status', 'pay_type', 'service_rate', 'channel_type', 'exchange_rate','is_recharge','is_withdrawal'],
+ 'payment_info'=>['id'],
+ ];
+}
\ No newline at end of file
diff --git a/app/admin/validate/setting/StockValidate.php b/app/admin/validate/setting/StockValidate.php
new file mode 100644
index 0000000..eed067c
--- /dev/null
+++ b/app/admin/validate/setting/StockValidate.php
@@ -0,0 +1,112 @@
+ 'require|integer',
+ 'limit' => 'require|integer',
+ 'stock_name' => 'require|checkIsString',
+ 'stock_code' => 'require|checkIsString',
+ 'status' => 'checkStatusRequire|in:0,1',
+ 'keep_decimal' => 'checkNumberIntAt',
+ 'forced_closure' => 'require|checkNumberFloatBg',
+ 'up_limit' => 'require|checkNumberFloatBg',
+ 'down_limit' => 'require|checkNumberFloatBg',
+ 'id' => 'require|checkNumberIntBg',
+ ];
+
+ protected $message = [
+ 'page.require' => '分页参数无效',
+ 'page.integer' => '分页参数无效',
+ 'limit.require' => '分页参数无效',
+ 'limit.integer' => '分页参数无效',
+ 'stock_name.require' => '股票名称无效',
+ 'stock_name.checkIsString' => '股票名称无效',
+
+ 'stock_code.require' => '股票代码无效',
+ 'stock_code.checkIsString' => '股票代码无效',
+
+ 'status.checkStatusRequire' => '状态无效',
+ 'status.in' => '状态无效',
+
+ 'keep_decimal.require' => '保留小数位无效',
+ 'keep_decimal.checkNumberIntBg' => '保留小数位无效',
+
+ 'forced_closure.require' => '强制平仓阈值无效',
+ 'forced_closure.checkNumberFloatBg' => '强制平仓阈值无效',
+
+ 'up_limit.require' => '涨停限制无效',
+ 'up_limit.checkNumberFloatBg' => '涨停限制无效',
+
+ 'down_limit.require' => '跌停限制无效',
+ 'down_limit.checkNumberFloatBg' => '跌停限制无效',
+
+ 'id.require' => '主键无效',
+ 'id.checkNumberIntBg' => '主键无效',
+
+ ];
+
+
+ protected $scene = [
+ // 美股
+ 'us_stock_index' => ['page', 'limit'],
+ 'us_stock_add' => ['stock_name', 'stock_code', 'status', 'keep_decimal', 'forced_closure', 'up_limit', 'down_limit'],
+ 'us_stock_edit' => ['id', 'stock_name', 'stock_code', 'status', 'keep_decimal', 'forced_closure', 'up_limit', 'down_limit'],
+
+ // 印尼股
+ 'idn_stock_index' => ['page', 'limit'],
+ 'idn_stock_add' => ['stock_name', 'stock_code', 'status', 'keep_decimal', 'forced_closure', 'up_limit', 'down_limit'],
+ 'idn_stock_edit' => ['id', 'stock_name', 'stock_code', 'status', 'keep_decimal', 'forced_closure', 'up_limit', 'down_limit'],
+
+ // 马股
+ 'mys_stock_index' => ['page', 'limit'],
+ 'mys_stock_add' => ['stock_name', 'stock_code', 'status', 'keep_decimal', 'forced_closure', 'up_limit', 'down_limit'],
+ 'mys_stock_edit' => ['id', 'stock_name', 'stock_code', 'status', 'keep_decimal', 'forced_closure', 'up_limit', 'down_limit'],
+
+ // 印度
+ 'in_stock_index' => ['page', 'limit'],
+ 'in_stock_add' => ['stock_name', 'stock_code', 'status', 'keep_decimal', 'forced_closure', 'up_limit', 'down_limit'],
+ 'in_stock_edit' => ['id', 'stock_name', 'stock_code', 'status', 'keep_decimal', 'forced_closure', 'up_limit', 'down_limit'],
+
+ // 泰股
+ 'tha_stock_index' => ['page', 'limit'],
+ 'tha_stock_add' => ['stock_name', 'stock_code', 'status', 'keep_decimal', 'forced_closure', 'up_limit', 'down_limit'],
+ 'tha_stock_edit' => ['id', 'stock_name', 'stock_code', 'status', 'keep_decimal', 'forced_closure', 'up_limit', 'down_limit'],
+ // 新加坡
+ 'sgd_stock_index' => ['page', 'limit'],
+ 'sgd_stock_add' => ['stock_name', 'stock_code', 'status', 'keep_decimal', 'forced_closure', 'up_limit', 'down_limit'],
+ 'sgd_stock_edit' => ['id', 'stock_name', 'stock_code', 'status', 'keep_decimal', 'forced_closure', 'up_limit', 'down_limit'],
+ // 香港
+ 'hk_stock_index' => ['page', 'limit'],
+ 'hk_stock_add' => ['stock_name', 'stock_code', 'status', 'keep_decimal', 'forced_closure', 'up_limit', 'down_limit'],
+ 'hk_stock_edit' => ['id', 'stock_name', 'stock_code', 'status', 'keep_decimal', 'forced_closure', 'up_limit', 'down_limit'],
+ // 英国
+ 'gbx_stock_index' => ['page', 'limit'],
+ 'gbx_stock_add' => ['stock_name', 'stock_code', 'status', 'keep_decimal', 'forced_closure', 'up_limit', 'down_limit'],
+ 'gbx_stock_edit' => ['id', 'stock_name', 'stock_code', 'status', 'keep_decimal', 'forced_closure', 'up_limit', 'down_limit'],
+ // 法国
+ 'fur_stock_index' => ['page', 'limit'],
+ 'fur_stock_add' => ['stock_name', 'stock_code', 'status', 'keep_decimal', 'forced_closure', 'up_limit', 'down_limit'],
+ 'fur_stock_edit' => ['id', 'stock_name', 'stock_code', 'status', 'keep_decimal', 'forced_closure', 'up_limit', 'down_limit'],
+ // 德国
+ 'eur_stock_index' => ['page', 'limit'],
+ 'eur_stock_add' => ['stock_name', 'stock_code', 'status', 'keep_decimal', 'forced_closure', 'up_limit', 'down_limit'],
+ 'eur_stock_edit' => ['id', 'stock_name', 'stock_code', 'status', 'keep_decimal', 'forced_closure', 'up_limit', 'down_limit'],
+ // 德国
+ 'jp_stock_index' => ['page', 'limit'],
+ 'jp_stock_add' => ['stock_name', 'stock_code', 'status', 'keep_decimal', 'forced_closure', 'up_limit', 'down_limit'],
+ 'jp_stock_edit' => ['id', 'stock_name', 'stock_code', 'status', 'keep_decimal', 'forced_closure', 'up_limit', 'down_limit'],
+
+ // 印度期权
+ 'in_option_index' => ['page', 'limit'],
+ 'in_option_add' => ['stock_name', 'stock_code', 'status', 'keep_decimal', 'forced_closure'],
+ 'in_option_edit' => ['id', 'stock_name', 'stock_code', 'status', 'keep_decimal', 'forced_closure'],
+
+ //自动添加股票
+ 'stock_auto_add' => ['stock_name', 'stock_code', 'tape', 'country'],
+ ];
+}
\ No newline at end of file
diff --git a/app/common.php b/app/common.php
new file mode 100644
index 0000000..57cb6d8
--- /dev/null
+++ b/app/common.php
@@ -0,0 +1,2 @@
+ [
+ ],
+
+ 'listen' => [
+ 'AppInit' => [],
+ 'HttpRun' => [],
+ 'HttpEnd' => [],
+ 'LogLevel' => [],
+ 'LogWrite' => [],
+ ],
+
+ 'subscribe' => [
+ ],
+];
diff --git a/app/home/controller/Announcement.php b/app/home/controller/Announcement.php
new file mode 100644
index 0000000..a893fb3
--- /dev/null
+++ b/app/home/controller/Announcement.php
@@ -0,0 +1,122 @@
+request->header('Language');
+ if(empty($lang)){
+ $lang = 'zh-cn';
+ }
+ $langId = 1;
+ $langModel = LanguageSettingModel::where('language_code', $lang)->find();
+ if(!empty($langModel)){
+ $langId = $langModel->id;
+ }
+
+ $is_pop_ups = $this->request->post()['is_pop_ups'] ?? 0;
+ $announcement = AnnouncementModel::where('status', AnnouncementModel::STATUS_ON);
+ if ($is_pop_ups) $announcement = $announcement->where('is_pop_ups', $is_pop_ups);
+ $list = $announcement->where('is_delete', AnnouncementModel::IS_DELETE_NO)
+ ->where('lang', $langId)
+ ->order('weight', 'desc')
+ ->select();
+
+ $res = [];
+ if(!$list->isEmpty()){
+ foreach ($list as $item){
+ $res[] = [
+ 'id' => $item['id'],
+ 'title' => $item['title'],
+ 'create_time' => $item['update_time'],
+ ];
+ }
+ }
+
+ return json([
+ 'code'=>'0',
+ 'message' => 'Request successful.',
+ 'data' => $res,
+ ]);
+ }
+
+ public function detail()
+ {
+ $id = $this->request->param('id');
+ if(empty($id)){
+ return json([
+ 'code'=>'0',
+ 'message' => 'Request successful.',
+ 'data' => ['content' => '','title'=>'','create_time'=>date('Y-m-d H:i:s')],
+ ]);
+ }
+
+ $announcement = AnnouncementModel::where('id', $id)->where('status', DocumentModel::STATUS_ON)->find();
+ if(empty($announcement)){
+ return json([
+ 'code'=>'0',
+ 'message' => 'Request successful.',
+ 'data' => ['content' => '','title'=>'', 'create_time' => date('Y-m-d H:i:s')],
+ ]);
+ }
+
+
+ // 判断是否修改了语言
+ $lang = $this->request->header('Language');
+ if(empty($lang)){
+ return json([
+ 'code'=>'0',
+ 'message' => 'Request successful.',
+ 'data' => ['content' => $announcement['content'],'title'=>$announcement['title'], 'create_time' =>$announcement['update_time']],
+ ]);
+ }
+
+ // 无效语言
+ $langModel = LanguageSettingModel::where('language_code', $lang)->find();
+ if(empty($langModel)){
+ return json([
+ 'code'=>'0',
+ 'message' => 'Request successful.',
+ 'data' => ['content' => $announcement['content'],'title'=>$announcement['title'],'create_time' =>$announcement['update_time']],
+ ]);
+ }
+
+ // 语言相同
+ if($langModel['id'] == $announcement['lang']){
+ return json([
+ 'code'=>'0',
+ 'message' => 'Request successful.',
+ 'data' => ['content' => $announcement['content'],'title'=>$announcement['title'],'create_time' =>$announcement['update_time']],
+ ]);
+ }
+
+ // 查询同名 其他语言文件
+ $announcementChange = AnnouncementModel::where('name', $announcement['name'])
+ ->where('status', DocumentModel::STATUS_ON)
+ ->where('lang', $langModel['id'])
+ ->find();
+ if(empty($announcementChange)){
+ return json([
+ 'code'=>'0',
+ 'message' => 'Request successful.',
+ 'data' => ['content' => $announcement['content'],'title'=>$announcement['title'],'create_time' =>$announcement['update_time']],
+ ]);
+ }
+
+ // 返回原数据
+ return json([
+ 'code'=>'0',
+ 'message' => 'Request successful.',
+ 'data' => ['content' => $announcementChange['content'],'title'=>$announcementChange['title'],'create_time' =>$announcementChange['update_time']],
+ ]);
+
+ }
+}
\ No newline at end of file
diff --git a/app/home/controller/Block.php b/app/home/controller/Block.php
new file mode 100644
index 0000000..b6ddcb1
--- /dev/null
+++ b/app/home/controller/Block.php
@@ -0,0 +1,26 @@
+index($this->request->param());
+ return json($result);
+ }
+
+ // 大宗交易订单列表列表
+ public function list()
+ {
+ $service = new BlockStockService();
+ $result = $service->list($this->request->param(), $this->request->userId);
+ return json($result);
+ }
+}
\ No newline at end of file
diff --git a/app/home/controller/Carousel.php b/app/home/controller/Carousel.php
new file mode 100644
index 0000000..d480678
--- /dev/null
+++ b/app/home/controller/Carousel.php
@@ -0,0 +1,136 @@
+getCarousel();
+ return json($result);
+ }
+
+ // 广告图
+ public function index()
+ {
+ // 语言筛选
+ $lang = $this->request->header('Language');
+ if(empty($lang)){
+ $lang = 'zh-cn';
+ }
+
+ $langId = 1;
+ $langModel = LanguageSettingModel::where('language_code', $lang)->find();
+ if(!empty($langModel)){
+ $langId = $langModel->id;
+ }
+
+ $banner = BannerModel::where('status', BannerModel::STATUS_ON)
+ ->where('is_delete', BannerModel::IS_DELETE_NO)
+ ->where('lang', $langId)
+ ->select();
+
+ $res = [];
+ if(!$banner->isEmpty()){
+ foreach ($banner as $item){
+ $res[] = [
+ 'id' => $item['id'],
+ 'title' => $item['title'],
+ 'content' => $item['content'],
+ 'image' => $item['path'],
+ 'redirect_url' => '',
+ 'type'=> '1'
+ ];
+ }
+ }
+
+ return json([
+ 'code'=>'0',
+ 'message' => 'Request successful.',
+ 'data' => $res,
+ ]);
+ }
+
+ // 广告图详情
+ public function detail()
+ {
+ $id = $this->request->param('id');
+ if(empty($id)){
+ return json([
+ 'code'=>'0',
+ 'message' => 'Request successful.',
+ 'data' => ['content' => '','title'=>''],
+ ]);
+ }
+
+ $banner = BannerModel::where('id', $id)->where('status', BannerModel::STATUS_ON)->find();
+ if(empty($banner)){
+ return json([
+ 'code'=>'0',
+ 'message' => 'Request successful.',
+ 'data' => ['content' => '','title'=>''],
+ ]);
+ }
+
+
+ // 判断是否修改了语言
+ $lang = $this->request->header('Language');
+ if(empty($lang)){
+ return json([
+ 'code'=>'0',
+ 'message' => 'Request successful.',
+ 'data' => ['content' => $banner['content'],'title'=>$banner['title']],
+ ]);
+ }
+
+ // 无效语言
+ $langModel = LanguageSettingModel::where('language_code', $lang)->find();
+ if(empty($langModel)){
+ return json([
+ 'code'=>'0',
+ 'message' => 'Request successful.',
+ 'data' => ['content' => $banner['content'],'title'=>$banner['title']],
+ ]);
+ }
+
+ // 语言相同
+ if($langModel['id'] == $banner['lang']){
+ return json([
+ 'code'=>'0',
+ 'message' => 'Request successful.',
+ 'data' => ['content' => $banner['content'],'title'=>$banner['title']],
+ ]);
+ }
+
+ // 查询同名 其他语言文件
+ $bannerChange = BannerModel::where('name', $banner['name'])
+ ->where('status', BannerModel::STATUS_ON)
+ ->where('lang', $langModel['id'])
+ ->find();
+ if(empty($bannerChange)){
+ return json([
+ 'code'=>'0',
+ 'message' => 'Request successful.',
+ 'data' => ['content' => $banner['content'],'title'=>$banner['title']],
+ ]);
+ }
+
+ // 返回原数据
+ return json([
+ 'code'=>'0',
+ 'message' => 'Request successful.',
+ 'data' => ['content' => $bannerChange['content'],'title'=>$bannerChange['title']],
+ ]);
+
+ }
+}
\ No newline at end of file
diff --git a/app/home/controller/Country.php b/app/home/controller/Country.php
new file mode 100644
index 0000000..ff125ee
--- /dev/null
+++ b/app/home/controller/Country.php
@@ -0,0 +1,44 @@
+isEmpty()){
+ $deny = explode(',', env('NATION.DENY_NATION'));
+ foreach ($res as $item) {
+ $active = 1;
+ if(in_array($item['code'],$deny )){
+ $active = 0;
+ }
+ $returnData[] = [
+ 'id' => $item['id'],
+ 'nameCn' => $item['name_cn'],
+ 'nameEn' => $item['name_en'],
+ 'nation' => $item['code'],
+ 'active' => $active,
+ ];
+ }
+ }
+ return json(['code' => '0', 'message' => 'Request successful.','data' => $returnData]);
+ }catch (\Exception $exception){
+ return json(['code' => '100500', 'message' => 'System error','data' => [$exception->getMessage()]]);
+ }
+
+ }
+
+
+}
\ No newline at end of file
diff --git a/app/home/controller/Device.php b/app/home/controller/Device.php
new file mode 100644
index 0000000..90e47d2
--- /dev/null
+++ b/app/home/controller/Device.php
@@ -0,0 +1,13 @@
+request->header('Language');
+ if(empty($lang)){
+ $lang = 'zh-cn';
+ }
+
+ $langId = 1;
+ $langModel = LanguageSettingModel::where('language_code', $lang)->find();
+ if(!empty($langModel)){
+ $langId = $langModel->id;
+ }
+
+ $res = [
+ 'other'=>[]
+ ];
+ $map = DocumentModel::TYPE_FOOTER_PC;
+ $docList = DocumentModel::where('type', 'in', array_keys($map))
+ ->where('status', DocumentModel::STATUS_ON)
+ ->where('is_delete', DocumentModel::IS_DELETE_NO)
+ ->where('lang', $langId)
+ ->order('type', 'asc')
+ ->order('weight', 'desc')
+ ->select();
+
+ if(!$docList->isEmpty()){
+ foreach ($docList as $item){
+ $res['other'][] = [
+ 'title' => $item['title'],
+ 'content' => $item['content'],
+ 'id' => $item['id'],
+ ];
+ }
+ }
+
+ return json([
+ 'code'=>'0',
+ 'message' => 'Request successful.',
+ 'data' => $res,
+ ]);
+ }
+
+ // h5 平台管理
+ public function getPlatform()
+ {
+ // 语言筛选
+ $lang = $this->request->header('Language');
+ if(empty($lang)){
+ $lang = 'zh-cn';
+ }
+
+ $langId = 1;
+ $langModel = LanguageSettingModel::where('language_code', $lang)->find();
+ if(!empty($langModel)){
+ $langId = $langModel->id;
+ }
+
+ $doc = DocumentModel::where('lang', $langId)->where('status', DocumentModel::STATUS_ON)
+ ->where('is_delete', DocumentModel::IS_DELETE_NO)
+ ->where('type', '5')->order('id', 'desc')->find();
+ $res = ['content' => ''];
+ if(!empty($doc)){
+ $res['content'] = $doc['content'];
+ }
+
+ return json([
+ 'code'=>'0',
+ 'message' => 'Request successful.',
+ 'data' => $res,
+ ]);
+ }
+
+ // pc 页脚 文档
+ public function getDocPc()
+ {
+ // 语言筛选
+ $lang = $this->request->header('Language');
+ if(empty($lang)){
+ $lang = 'zh-cn';
+ }
+
+ $langId = 1;
+ $langModel = LanguageSettingModel::where('language_code', $lang)->find();
+ if(!empty($langModel)){
+ $langId = $langModel->id;
+ }
+
+ // 支持的类型
+ $map = DocumentModel::TYPE_FOOTER_PC;
+ $docList = DocumentModel::where('type', 'in', array_keys($map))
+ ->where('status', DocumentModel::STATUS_ON)
+ ->where('is_delete', DocumentModel::IS_DELETE_NO)
+ ->where('lang', $langId)
+ ->order('type', 'asc')->order('weight', 'desc')
+ ->select();
+
+ $res = [];
+ foreach ($map as $key=>$value){
+ $res[$key] = [
+ 'name' => $value,
+ 'child' => []
+ ];
+ }
+ if(!$docList->isEmpty()){
+ foreach ($docList as $item) {
+ $res[$item['type']]['child'][] = [
+ 'title' => $item['title'],
+ 'content' => $item['content'],
+ 'id' => $item['id'],
+ ];
+ }
+ }
+
+ return json([
+ 'code'=>'0',
+ 'message' => 'Request successful.',
+ 'data' => $res,
+ ]);
+ }
+
+ // 详情
+ public function detail()
+ {
+ $id = $this->request->param('id');
+ if(empty($id)){
+ return json([
+ 'code'=>'0',
+ 'message' => 'Request successful.',
+ 'data' => ['content' => '','title'=>''],
+ ]);
+ }
+
+ $doc = DocumentModel::where('id', $id)
+ ->where('is_delete', DocumentModel::IS_DELETE_NO)
+ ->where('status', DocumentModel::STATUS_ON)->find();
+ if(empty($doc)){
+ return json([
+ 'code'=>'0',
+ 'message' => 'Request successful.',
+ 'data' => ['content' => '','title'=>''],
+ ]);
+ }
+
+ // 判断是否修改了语言
+ $lang = $this->request->header('Language');
+ if(empty($lang)){
+ return json([
+ 'code'=>'0',
+ 'message' => 'Request successful.',
+ 'data' => ['content' => $doc['content'],'title'=>$doc['title']],
+ ]);
+ }
+
+ // 无效语言
+ $langModel = LanguageSettingModel::where('language_code', $lang)->find();
+ if(empty($langModel)){
+ return json([
+ 'code'=>'0',
+ 'message' => 'Request successful.',
+ 'data' => ['content' => $doc['content'],'title'=>$doc['title']],
+ ]);
+ }
+
+ // 语言相同
+ if($langModel['id'] == $doc['lang']){
+ return json([
+ 'code'=>'0',
+ 'message' => 'Request successful.',
+ 'data' => ['content' => $doc['content'],'title'=>$doc['title']],
+ ]);
+ }
+
+ // 查询同名 其他语言文件
+ $docChange = DocumentModel::where('name', $doc['name'])
+ ->where('status', DocumentModel::STATUS_ON)
+ ->where('is_delete', DocumentModel::IS_DELETE_NO)
+ ->where('lang', $langModel['id'])
+ ->find();
+ if(empty($docChange)){
+ return json([
+ 'code'=>'0',
+ 'message' => 'Request successful.',
+ 'data' => ['content' => $doc['content'],'title'=>$doc['title']],
+ ]);
+ }
+
+ // 返回原数据
+ return json([
+ 'code'=>'0',
+ 'message' => 'Request successful.',
+ 'data' => ['content' => $docChange['content'],'title'=>$docChange['title']],
+ ]);
+ }
+}
\ No newline at end of file
diff --git a/app/home/controller/Faq.php b/app/home/controller/Faq.php
new file mode 100644
index 0000000..4a121c0
--- /dev/null
+++ b/app/home/controller/Faq.php
@@ -0,0 +1,120 @@
+request->header('Language');
+ if(empty($lang)){
+ $lang = 'zh-cn';
+ }
+
+ $langId = 1;
+ $langModel = LanguageSettingModel::where('language_code', $lang)->find();
+ if(!empty($langModel)){
+ $langId = $langModel->id;
+ }
+
+ $faq = FaqModel::where('status', FaqModel::STATUS_ON)
+ ->where('is_delete', FaqModel::IS_DELETE_NO)
+ ->where('lang', $langId)
+ ->order('weight', 'desc')
+ ->select();
+
+ $res = [];
+ if(!$faq->isEmpty()){
+ foreach ($faq as $item){
+ $res[] = [
+ 'id' => $item['id'],
+ 'title' => $item['title'],
+ 'content' => $item['content'],
+ ];
+ }
+ }
+
+ return json([
+ 'code'=>'0',
+ 'message' => 'Request successful.',
+ 'data' => $res,
+ ]);
+ }
+
+ public function detail()
+ {
+ $id = $this->request->param('id');
+ if(empty($id)){
+ return json([
+ 'code'=>'0',
+ 'message' => 'Request successful.',
+ 'data' => ['content' => '','title'=>''],
+ ]);
+ }
+
+ $faq = FaqModel::where('id', $id)->where('status', FaqModel::STATUS_ON)->find();
+ if(empty($faq)){
+ return json([
+ 'code'=>'0',
+ 'message' => 'Request successful.',
+ 'data' => ['content' => '','title'=>''],
+ ]);
+ }
+
+
+ // 判断是否修改了语言
+ $lang = $this->request->header('Language');
+ if(empty($lang)){
+ return json([
+ 'code'=>'0',
+ 'message' => 'Request successful.',
+ 'data' => ['content' => $faq['content'],'title'=>$faq['title']],
+ ]);
+ }
+
+ // 无效语言
+ $langModel = LanguageSettingModel::where('language_code', $lang)->find();
+ if(empty($langModel)){
+ return json([
+ 'code'=>'0',
+ 'message' => 'Request successful.',
+ 'data' => ['content' => $faq['content'],'title'=>$faq['title']],
+ ]);
+ }
+
+ // 语言相同
+ if($langModel['id'] == $faq['lang']){
+ return json([
+ 'code'=>'0',
+ 'message' => 'Request successful.',
+ 'data' => ['content' => $faq['content'],'title'=>$faq['title']],
+ ]);
+ }
+
+ // 查询同名 其他语言文件
+ $faqChange = FaqModel::where('name', $faq['name'])
+ ->where('status', FaqModel::STATUS_ON)
+ ->where('lang', $langModel['id'])
+ ->find();
+ if(empty($faqChange)){
+ return json([
+ 'code'=>'0',
+ 'message' => 'Request successful.',
+ 'data' => ['content' => $faq['content'],'title'=>$faq['title']],
+ ]);
+ }
+
+ // 返回原数据
+ return json([
+ 'code'=>'0',
+ 'message' => 'Request successful.',
+ 'data' => ['content' => $faqChange['content'],'title'=>$faqChange['title']],
+ ]);
+
+ }
+}
\ No newline at end of file
diff --git a/app/home/controller/Fund.php b/app/home/controller/Fund.php
new file mode 100644
index 0000000..beec1d9
--- /dev/null
+++ b/app/home/controller/Fund.php
@@ -0,0 +1,53 @@
+index($this->request->param());
+ return json($result);
+ }
+
+ // 基金详情
+ public function detail(): Json
+ {
+ $result = (new FundService())->detail($this->request->param());
+ return json($result);
+ }
+
+ //历史走势
+ public function history(): Json
+ {
+ $result = (new FundService())->history($this->request->param());
+ return json($result);
+ }
+
+ // 申购下单
+ public function order(): Json
+ {
+ $result = (new FundService())->order($this->request->param(), $this->request->userId);
+ return json($result);
+ }
+
+ // 用户基金持仓
+ public function userFund(): Json
+ {
+ $result = (new FundService())->userFund($this->request->param(), $this->request->userId);
+ return json($result);
+ }
+
+ // 用户基金 - 资产流水
+ public function userFundAssets(): Json
+ {
+ $result = (new FundService())->userFundAssets($this->request->param());
+ return json($result);
+ }
+}
\ No newline at end of file
diff --git a/app/home/controller/HomeBaseController.php b/app/home/controller/HomeBaseController.php
new file mode 100644
index 0000000..d87e994
--- /dev/null
+++ b/app/home/controller/HomeBaseController.php
@@ -0,0 +1,10 @@
+getLangList();
+ return json($result);
+ }
+ public function serviceList(Request $request): Json
+ {
+ $result = (new LanguageService())->getServiceList();
+ return json($result);
+ }
+ public function initRedisData(Request $request): Json
+ {
+ $result = (new BaseHomeService())->initSetting();
+ return json($result);
+ }
+
+}
\ No newline at end of file
diff --git a/app/home/controller/Login.php b/app/home/controller/Login.php
new file mode 100644
index 0000000..3f54593
--- /dev/null
+++ b/app/home/controller/Login.php
@@ -0,0 +1,126 @@
+sendEmail($this->request->post());
+ return json($returnData);
+ }
+
+ /**
+ * @desc 邮箱注册
+ * @return Json
+ * @throws \Psr\SimpleCache\InvalidArgumentException
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function registerEmail(): Json
+ {
+ $returnData = (new LoginService())->registerEmail($this->request->post());
+ return json($returnData);
+ }
+
+ /**
+ * @desc 登陆接口
+ * @return Json
+ */
+ public function loginEmail(): Json
+ {
+ $returnData = (new LoginService())->loginEmail($this->request->post());
+ return json($returnData);
+ }
+
+ /**
+ * #desc 发送短信验证码
+ * @return Json
+ */
+ public function sendSms(): Json
+ {
+ $returnData = (new LoginService())->sendSms($this->request->post());
+ return json($returnData);
+ }
+
+
+ /**
+ * @desc @desc 短信注册
+ * @return Json
+ * @throws \Psr\SimpleCache\InvalidArgumentException
+ */
+ public function registerSms(): Json
+ {
+ $returnData = (new LoginService())->registerSms($this->request->post());
+ return json($returnData);
+ }
+
+ /**
+ * @desc 短信验证码登陆
+ * @return Json
+ * @throws \Psr\SimpleCache\InvalidArgumentException
+ */
+ public function loginSms(): Json
+ {
+ $returnData = (new LoginService())->loginSms($this->request->post());
+ return json($returnData);
+ }
+
+ /**
+ * @desc 忘记密码 根据邮箱设置密码
+ * @return Json
+ * @throws \Psr\SimpleCache\InvalidArgumentException
+ */
+ public function resetPasswordByEmail(): Json
+ {
+ $returnData = (new LoginService())->resetPasswordByEmail($this->request->post());
+ return json($returnData);
+ }
+
+ /**
+ * @desc 忘记密码 根据短信设置密码
+ * @return Json
+ */
+ public function resetPasswordBySms(): Json
+ {
+ $returnData = (new LoginService())->resetPasswordBySms($this->request->post());
+ return json($returnData);
+ }
+
+ /**
+ * @desc 手机号登陆
+ * @return Json
+ */
+ public function phoneLogin(): Json
+ {
+ $returnData = (new LoginService())->phoneLogin($this->request->post());
+ return json($returnData);
+ }
+
+ /**
+ * 免密码登录
+ * @return Json
+ */
+ public function autoLogin():Json
+ {
+ $returnData = (new LoginService())->autoLogin($this->request->post());
+ return json($returnData);
+ }
+ public function getIP():Json
+ {
+ $returnData = (new LoginService())->getIP();
+ return json($returnData);
+
+ }
+
+}
\ No newline at end of file
diff --git a/app/home/controller/Market.php b/app/home/controller/Market.php
new file mode 100644
index 0000000..03a63bf
--- /dev/null
+++ b/app/home/controller/Market.php
@@ -0,0 +1,130 @@
+post('market_type');
+ $data['trade_name'] = $request->post('trade_name');
+ $data['page'] = $request->post('page',1);
+ $data['page_size'] = $request->post('page_size',10);
+ $result = (new MarketService())->getMarketList($data);
+ return json($result);
+ }
+
+ /**
+ * 获取用户自选行情
+ * @param Request $request
+ * @return Json
+ */
+ public function userMarket(Request $request): Json
+ {
+ $data['market_type']= $request->post('market_type');
+ $data['user_id'] = $request->userId;
+ $data['trade_name'] = $request->post('trade_name');
+ $data['page'] = $request->post('page',1);
+ $data['page_size'] = $request->post('page_size',10);
+ $result = (new MarketService())->getUserMarket($data);
+ return json($result);
+ }
+
+ /**
+ * 添加自选数据
+ * @param Request $request
+ * @return Json
+ */
+ public function addMarket(Request $request): Json
+ {
+ $data['market_type'] = $request->post('market_type');
+ $data['user_id'] = $request->userId;
+ $data['trade_name'] = $request->post('trade_name');
+ $data['trade_numeric_code'] = $request->post('trade_numeric_code') ?? 0;
+ $data['market_name'] = $request->post('market_name');
+ $result = (new MarketService())->addUserMarket($data);
+ return json($result);
+ }
+
+ /**
+ * 删除自选数据
+ * @param Request $request
+ * @return Json
+ */
+ public function delMarket(Request $request): Json
+ {
+ $data['market_type'] = $request->post('market_type');
+ $data['user_id'] = $request->userId;
+ $data['trade_name'] = $request->post('trade_name');
+ $result = (new MarketService())->delUserMarket($data);
+ return json($result);
+ }
+ public function MarketCollect(Request $request): Json
+ {
+ $data['market_type'] = $request->post('market_type');
+ $data['user_id'] = $request->userId;
+ $data['trade_name'] = $request->post('trade_name');
+ $result = (new MarketService())->getUserIsCollect($data);
+ return json($result);
+
+ }
+ /**
+ * 获取交易手续费用
+ */
+ public function tradeFee(Request $request): Json
+ {
+ $data['market_type'] = $request->post('market_type');
+ $result = (new MarketService())->getTradeFee($data);
+ return json($result);
+ }
+ public function marketTradeList(Request $request): Json
+ {
+ $data['market_type'] = $request->post('market_type');
+ $data['trade_name'] = $request->post('trade_name');
+ $data['num'] = $request->post('num',100);
+ $result = (new MarketService())->getMarketTradeList($data);
+ return json($result);
+
+ }
+ public function TradeTypeList(Request $request): Json
+ {
+ $result = (new MarketService())->getTradeTypeList();
+ return json($result);
+ }
+ public function ForexFaceList(Request $request): Json
+ {
+ $data['trade_name'] = $request->post('trade_name');
+ $result = (new MarketService())->getForexFace($data);
+ return json($result);
+ }
+ public function ContractFaceList(Request $request): Json
+ {
+ $result = (new MarketService())->getContractFace();
+ return json($result);
+ }
+ public function ContractSetting(Request $request): Json
+ {
+ $result = (new MarketService())->getContractSetting();
+ return json($result);
+ }
+ public function marketRate(Request $request): Json
+ {
+ $result = (new MarketService())->getMarketRate();
+ return json($result);
+ }
+
+
+}
\ No newline at end of file
diff --git a/app/home/controller/Pay.php b/app/home/controller/Pay.php
new file mode 100644
index 0000000..3a69061
--- /dev/null
+++ b/app/home/controller/Pay.php
@@ -0,0 +1,320 @@
+post('is_online', 1);
+ $result = (new PayService())->getPaymentList($data);
+ return json($result);
+ }
+
+ public function BankList(Request $request): Json
+ {
+ $result = (new IndPayService())->getBankList();
+ return json($result);
+ }
+
+ /**
+ * 用户充值接口
+ * @return Json
+ */
+ public function rechargeApply(Request $request): Json
+ {
+ $data['user_id'] = $request->userId;
+ $data['account_type'] = $request->post('account_type');
+ $data['country'] = $request->post('country');
+ $data['recharge_channel'] = $request->post('recharge_channel');
+ $data['recharge_num'] = $request->post('recharge_num');
+ $data['is_online'] = $request->post('is_online', 1);
+ $data['file_id'] = $request->post('file_id', 0);
+ $data['product'] = $request->post('product', '');
+ $data['extra'] = $request->post('extra', '');
+ $result = (new PayService())->insertRechargeApply($data);
+ return json($result);
+ }
+ public function getTRC20BuyList(Request $request): Json
+ {
+ $result=(new StarPayService())->getTRC20BuyList();
+ return json($result);
+ }
+ public function starPayNotify(Request $request)
+ {
+ Log::info('starPay支付异步回调:' . json_encode($_REQUEST));
+
+ $data['merchant_no'] = $request->post('merchant_no');
+ $data['timestamp'] = $request->post('timestamp');
+ $data['sign_type'] = $request->post('sign_type');
+ $data['sign'] = $request->post('sign');
+ //$data['params'] = json_decode($request->post('params'),true);
+ $data['params'] = $request->post('params');
+ Log::info('starPay支付异步回调:' . json_encode($data));
+ $result = (new StarPayService())->starPayNotify($data);
+ return $result;
+ }
+ public function indPayNotify(Request $request)
+ {
+ Log::info('支付异步回调:' . json_encode($_REQUEST));
+ $data['busi_code'] = $request->post('busi_code');
+ $data['err_code'] = $request->post('err_code');
+ $data['err_msg'] = $request->post('err_msg');
+ $data['mer_no'] = $request->post('mer_no');
+ $data['mer_order_no'] = $request->post('mer_order_no');
+ $data['order_amount'] = $request->post('order_amount');
+ $data['order_no'] = $request->post('order_no');
+ $data['order_time'] = $request->post('order_time');
+ $data['pay_amount'] = $request->post('pay_amount');
+ $data['pay_time'] = $request->post('pay_time');
+ $data['status'] = $request->post('status');
+ $data['sign'] = $request->post('sign');
+ Log::info('支付异步回调:' . json_encode($data));
+ $result = (new IndPayService())->indPayNotify($data);
+ return $result['msg'];
+ }
+
+ public function indPayQuery(Request $request)
+ {
+ Log::info('支付同步回调:' . json_encode($_REQUEST));
+ $data['busi_code'] = $request->post('busi_code');
+ $data['err_code'] = $request->post('err_code');
+ $data['err_msg'] = $request->post('err_msg');
+ $data['mer_no'] = $request->post('mer_no');
+ $data['mer_order_no'] = $request->post('mer_order_no');
+ $data['order_amount'] = $request->post('order_amount');
+ $data['order_no'] = $request->post('order_no');
+ $data['order_time'] = $request->post('order_time');
+ $data['pay_amount'] = $request->post('pay_amount');
+ $data['pay_time'] = $request->post('pay_time');
+ $data['status'] = $request->post('status');
+ $data['sign'] = $request->post('sign');
+ Log::info('支付同步回调:' . json_encode($data));
+ return 'SUCCESS';
+ }
+
+ public function singleNotify(Request $request)
+ {
+ Log::info('代付回调:' . json_encode($_REQUEST));
+ $data['err_code'] = $request->post('err_code');
+ $data['err_msg'] = $request->post('err_msg');
+ $data['mer_no'] = $request->post('mer_no');
+ $data['mer_order_no'] = $request->post('mer_order_no');
+ $data['order_amount'] = $request->post('order_amount');
+ $data['ccy_no'] = $request->post('ccy_no');
+ $data['order_no'] = $request->post('order_no');
+ $data['create_time'] = $request->post('create_time');
+ $data['pay_time'] = $request->post('pay_time');
+ $data['status'] = $request->post('status');
+ $data['sign'] = $request->post('sign');
+ Log::info('代付回调:' . json_encode($data));
+ $result = (new IndPayService())->singleIndNotify($data);
+ return $result['msg'];
+ }
+
+ public function payNotify(Request $request)
+ {
+ $data = $request->post('data');
+ $result = (new TrcPayService())->TrcpayNotify($data);
+ return $result;
+ }
+
+ public function OrderConfirm(Request $request)
+ {
+ $data = $request->post('data');
+ $result = (new TrcPayService())->dealOrderConfirm($data);
+ return $result;
+ }
+
+ public function wallet(Request $request)
+ {
+ (new TrcPayService())->WalletAddress();
+ }
+
+ public function htPayNotify(Request $request)
+ {
+ Log::info('合泰回调:' . json_encode($_REQUEST));
+ $data['amount'] = $request->post('amount');
+ $data['mchId'] = $request->post('mchId');
+ $data['mchOrderNo'] = $request->post('mchOrderNo');
+ $data['merRetMsg'] = $request->post('merRetMsg');
+ $data['signType'] = $request->post('signType');
+ $data['tradeResult'] = $request->post('tradeResult');
+ $data['sign'] = $request->post('sign');
+ $result = (new HTPayService())->qrNotify($data);
+ return 'success';
+ }
+
+ public function arPayNotify(Request $request)
+ {
+ Log::info('合泰代付回调:' . json_encode($_REQUEST));
+ $data['amount'] = $request->post('amount');
+ $data['mchId'] = $request->post('mchId');
+ $data['mchOrderNo'] = $request->post('mchOrderNo');
+ $data['signType'] = $request->post('signType');
+ $data['tradeResult'] = $request->post('tradeResult');
+ $data['sign'] = $request->post('sign');
+ $result = (new HTPayService())->arNotify($data);
+ return 'success';
+ }
+
+ public function XdPayNotify(Request $request)
+ {
+ Log::info('Xdpay代收回调:' . json_encode($_REQUEST));
+ $data['platOrderId'] = $request->post('platOrderId');
+ $data['orderId'] = $request->post('orderId');
+ $data['amount'] = $request->post('amount');
+ $data['status'] = $request->post('status');
+ $data['reverse'] = $request->post('reverse');
+ $data['remark'] = $request->post('remark');
+ $data['sign'] = $request->post('sign');
+ $result = (new XdPayService())->xdpayNotify($data);
+ return 'success';
+ }
+
+ public function XdPayAppNotify(Request $request)
+ {
+ Log::info('Xdpay代付回调:' . json_encode($_REQUEST));
+ $data['platOrderId'] = $request->post('platOrderId');
+ $data['orderId'] = $request->post('orderId');
+ $data['amount'] = $request->post('amount');
+ $data['status'] = $request->post('status');
+ $data['reverse'] = $request->post('reverse');
+ $data['remark'] = $request->post('remark');
+ $data['sign'] = $request->post('sign');
+ $result = (new XdPayService())->xdpayApplyNotify($data);
+ return 'success';
+ }
+
+ public function NicePayNotify(Request $request)
+ {
+ Log::info('NicePay代收回调:' . json_encode($_REQUEST));
+ $data['amount'] = $request->post('amount');
+ $data['order'] = $request->post('order');
+ $data['status'] = $request->post('status');
+ $data['sign'] = $request->post('sign');
+ $result = (new NicePayService())->NicePayNotify($data);
+ return 'success';
+ }
+
+ public function NicePayApplyNotify(Request $request)
+ {
+ Log::info('NicePay代付回调:' . json_encode($_REQUEST));
+ $data['amount'] = $request->post('amount');
+ $data['order'] = $request->post('order');
+ $data['status'] = $request->post('status');
+ $data['sign'] = $request->post('sign');
+ $result = (new NicePayService())->NicePayApplyNotify($data);
+ return 'success';
+ }
+
+ public function MoPayNotify(Request $request)
+ {
+ Log::info('MoPay代收回调:' . json_encode($_REQUEST));
+ $data['memberid'] = $request->post('memberid');
+ $data['orderid'] = $request->post('orderid');
+ $data['transaction_id'] = $request->post('transaction_id');
+ $data['amount'] = $request->post('amount');
+ $data['datetime'] = $request->post('datetime');
+ $data['returncode'] = $request->post('returncode');
+ $data['attach'] = $request->post('attach');
+ $data['sign'] = $request->post('sign');
+ $result = (new MoPayService())->moPayNotify($data);
+ return 'ok';
+ }
+
+ public function moPayAppNotify(Request $request)
+ {
+ Log::info('Mopay代付回调:' . json_encode($_REQUEST));
+ $data['memberid'] = $request->post('memberid');
+ $data['orderid'] = $request->post('orderid');
+ $data['transaction_id'] = $request->post('transaction_id');
+ $data['amount'] = $request->post('amount');
+ $data['datetime'] = $request->post('datetime');
+ $data['returncode'] = $request->post('returncode');
+ $data['attach'] = $request->post('attach');
+ $data['sign'] = $request->post('sign');
+ $result = (new MoPayService())->moPayApplyNotify($data);
+ return 'ok';
+ }
+
+ // QEAE支付回调
+ public function QeaePayNotify(Request $request)
+ {
+ Log::info('Qeaepay支付回调:' . json_encode($_REQUEST));
+ $data['tradeResult'] = $request->post('tradeResult');
+ $data['orderNo'] = $request->post('orderNo');
+ $data['mchId'] = $request->post('mchId');
+ $data['mchOrderNo'] = $request->post('mchOrderNo');
+ $data['oriAmount'] = $request->post('oriAmount');
+ $data['amount'] = $request->post('oriAmount');
+ $data['orderDate'] = $request->post('orderDate');
+ $data['sign_type'] = $request->post('signType');
+ $data['sign'] = $request->post('sign');
+ $result = (new QeaePayService())->qeaePayNotify($data);
+ return 'success';
+ }
+
+ // QEAE代付回调
+ public function QeaePayAppNotify(Request $request)
+ {
+ Log::info('Qeae代付回调:' . json_encode($_REQUEST));
+ $data['tradeResult'] = $request->post('tradeResult');
+ $data['merTransferId'] = $request->post('merTransferId'); // 商家转账订单号
+ $data['merNo'] = $request->post('merNo');
+ $data['tradeNo'] = $request->post('tradeNo');
+ $data['transferAmount'] = $request->post('transferAmount');
+ $data['applyDate'] = $request->post('applyDate');
+ $data['version'] = $request->post('version');
+ $data['respCode'] = $request->post('respCode');
+ $data['sign'] = $request->post('sign');
+ $data['sign_type'] = $request->post('signType');
+ $result = (new QeaePayService())->qeaePayApplyNotify($data);
+ return 'success';
+ }
+
+ public function test(Request $request)
+ {
+// $amount=1000;
+// $order_no='ht'.rand(10000,99999);
+// (new HTPayService())->arPay($order_no,$amount,'101','65243451224','test');
+ (new TrcPayService())->getTrcBalance();
+
+ }
+
+ // Click 代收(充值)回调
+ public function ClickPayNotify()
+ {
+ $res = $this->request->param();
+ Log::info('Clickpay 代收(充值)回调000:' . json_encode($res));
+ $result = (new ClickPayService())->clickPayNotify($res);
+ return json($result);
+ }
+
+ // Click 代付回调
+ public function ClickPayApplyNotify(Request $request)
+ {
+ $res = $this->request->param();
+ Log::info('Clickpay 代付回调000:' . json_encode($res));
+ $result = (new ClickPayService())->clickPayApplyNotify($res);
+ return json($result);
+ }
+
+}
\ No newline at end of file
diff --git a/app/home/controller/PreStock.php b/app/home/controller/PreStock.php
new file mode 100644
index 0000000..bb3431c
--- /dev/null
+++ b/app/home/controller/PreStock.php
@@ -0,0 +1,58 @@
+index($this->request->param());
+ return json($result);
+ }
+
+ // 新股列表
+ public function stockDetail()
+ {
+ $service = new PreStockService();
+ $result = $service->stockDetail($this->request->param());
+ return json($result);
+ }
+
+ // 申购下单
+ public function order()
+ {
+ $service = new PreStockService();
+ $result = $service->order($this->request->param(), $this->request->userId);
+ return json($result);
+ }
+
+ // 申购记录
+ public function list()
+ {
+ $service = new PreStockService();
+ $result = $service->list($this->request->param(), $this->request->userId);
+ return json($result);
+ }
+
+ // 申购记录详情
+ public function detail()
+ {
+ $service = new PreStockService();
+ $result = $service->detail($this->request->param(), $this->request->userId);
+ return json($result);
+ }
+
+ // 后支付-付款
+ public function postPay()
+ {
+ $service = new PreStockService();
+ $result = $service->postPay($this->request->param(), $this->request->userId);
+ return json($result);
+ }
+}
\ No newline at end of file
diff --git a/app/home/controller/Stock.php b/app/home/controller/Stock.php
new file mode 100644
index 0000000..a0c3e91
--- /dev/null
+++ b/app/home/controller/Stock.php
@@ -0,0 +1,17 @@
+checkMarketStatus($this->request->param());
+ return json($result);
+ }
+}
\ No newline at end of file
diff --git a/app/home/controller/Team.php b/app/home/controller/Team.php
new file mode 100644
index 0000000..10f8840
--- /dev/null
+++ b/app/home/controller/Team.php
@@ -0,0 +1,38 @@
+userId;
+ $result = (new TeamService())->getUserTeamCollect($user_id);
+ return json($result);
+ }
+ public function userTeamBack(Request $request): Json
+ {
+ $data['user_id']=$request->userId;
+ $data['level_type']=$request->post('level_type');
+ $data['page']=$request->post('page');
+ $data['page_size']=$request->post('page_size');
+ $result = (new TeamService())->getUserTeamBack($data);
+ return json($result);
+ }
+ public function userTeamList(Request $request): Json
+ {
+ $data['user_id']=$request->userId;
+ $data['level_type']=$request->post('level_type');
+ $data['page']=$request->post('page');
+ $data['page_size']=$request->post('page_size');
+ $result = (new TeamService())->getUserTeamList($data);
+ return json($result);
+ }
+
+}
\ No newline at end of file
diff --git a/app/home/controller/Upload.php b/app/home/controller/Upload.php
new file mode 100644
index 0000000..96b5ec2
--- /dev/null
+++ b/app/home/controller/Upload.php
@@ -0,0 +1,76 @@
+request->file('file');
+ // 参数校验
+ validate(UploadValidate::class)->scene('uploadImage')->check(['image' => $file]);
+ // 将文件存储在本地
+ $name = Filesystem::disk('local')->putFile('', $file);
+ $path = '/bs/image/'.$name;
+ // 入库
+ $id = FileModel::insertFile($path, 2);
+ return json(['code' => '0', 'message' => 'Request successful.','data' => ['id' => $id]]);
+ }catch (ValidateException $validateException){
+ // 参数校验失败 异常类
+ $message = $validateException->getError();
+ return json(['code' => '1004001', 'message' => $message]);
+ }catch (\Exception $exception){
+ return json(['code' => '100500', 'message' => 'System error','data' => [$exception->getMessage(), $exception->getTrace(), $exception->getFile(),$filess]]);
+ }
+ }
+ public function uploadRechargeImage(): Json
+ {
+ try {
+ // 获取文件
+ $file = $this->request->file('file');
+ // 参数校验
+ validate(UploadValidate::class)->scene('uploadImage')->check(['image' => $file]);
+
+ // 将文件存储在本地
+ $name = Filesystem::disk('local')->putFile('', $file);
+ $path = '/bs/image/'.$name;
+
+ // 入库
+ $id = FileModel::insertFile($path, 2);
+ return json(['code' => '0', 'message' => 'Request successful.','data' => ['id' => $id]]);
+ }catch (\Exception $exception){
+ return json(['code' => '100500', 'message' => 'System error','data' => [$exception->getMessage()]]);
+ }
+ }
+
+ public function getConfig(): Json
+ {
+ try {
+ $param = $this->request->param();
+ if (empty($param['name'])) return json(['code' => '1', 'message' => '参数错误', 'data' => []]);
+ $name = $param['name'];
+ $value = ConfigModel::where('name', $name)->value('value');
+
+ return json(['code' => '0', 'message' => 'Request successful.', 'data' => ['value' => $value]]);
+ } catch (\Exception $exception) {
+ return json(['code' => '100500', 'message' => 'System error', 'data' => [$exception->getMessage()]]);
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/home/controller/User.php b/app/home/controller/User.php
new file mode 100644
index 0000000..e2686bb
--- /dev/null
+++ b/app/home/controller/User.php
@@ -0,0 +1,259 @@
+getUserInfo($this->request->userId);
+ return json($returnData);
+ }
+
+ /**
+ * @desc 设置用户国家
+ * @return Json
+ */
+ public function setCountry(): Json
+ {
+ $returnData = (new UserService())->setCountry($this->request->userId, $this->request->post());
+ return json($returnData);
+ }
+
+ /**
+ * @desc 更新用户头像
+ * @return Json
+ */
+ public function updateHeadImg(): Json
+ {
+ $returnData = (new UserService())->updateHeadImg($this->request->userId, $this->request->post());
+ return json($returnData);
+ }
+
+ /**
+ * @desc 设置 昵称 姓名 性别
+ * @return Json
+ */
+ public function updateInfo(): Json
+ {
+ $returnData = (new UserService())->updateInfo($this->request->userId, $this->request->post());
+ return json($returnData);
+ }
+
+ /**
+ * @desc 登陆状态获取邮件
+ * @return Json
+ */
+ public function sendEmail(): Json
+ {
+ $returnData = (new UserService())->sendEmail($this->request->userId, $this->request->post());
+ return json($returnData);
+ }
+
+ /**
+ * @desc 登陆后发送短信
+ * @return Json
+ */
+ public function sendSms(): Json
+ {
+ $returnData = (new UserService())->sendSms($this->request->userId, $this->request->post());
+ return json($returnData);
+ }
+
+ /**
+ * @desc 通过邮箱 设置取款密码
+ * @return Json
+ */
+ public function setPayPasswordByEmail(): Json
+ {
+ $returnData = (new UserService())->setPayPasswordByEmail($this->request->userId, $this->request->post());
+ return json($returnData);
+ }
+
+ /**
+ * @desc 通过短信 设置取款密码
+ * @return Json
+ */
+ public function setPayPasswordBySms(): Json
+ {
+ $returnData = (new UserService())->setPayPasswordBySms($this->request->userId, $this->request->post());
+ return json($returnData);
+ }
+
+ /**
+ * @desc 通过短信修改交易密码
+ * @return Json
+ */
+ public function updatePayPasswordBySms()
+ {
+ $returnData = (new UserService())->updatePayPasswordBySms($this->request->userId, $this->request->post());
+ return json($returnData);
+ }
+
+ /**
+ * @desc 通过邮箱修改交易密码
+ * @return Json
+ */
+ public function updatePayPasswordByEmail()
+ {
+ $returnData = (new UserService())->updatePayPasswordByEmail($this->request->userId, $this->request->post());
+ return json($returnData);
+ }
+
+ /**
+ * @desc 短信重新设置交易密码
+ * @return Json
+ * @throws InvalidArgumentException
+ */
+ public function resetPayPasswordBySms()
+ {
+ $returnData = (new UserService())->resetPayPasswordBySms($this->request->userId, $this->request->post());
+ return json($returnData);
+ }
+
+ /**
+ * @desc 通过邮箱重新设置交易密码
+ * @return Json
+ * @throws InvalidArgumentException
+ */
+ public function resetPayPasswordByEmail()
+ {
+ $returnData = (new UserService())->resetPayPasswordByEmail($this->request->userId, $this->request->post());
+ return json($returnData);
+ }
+
+ /**
+ * @desc 短信修改登陆密码
+ * @return Json
+ */
+ public function updatePasswordBySms()
+ {
+ $returnData = (new UserService())->updatePasswordBySms($this->request->userId, $this->request->post());
+ return json($returnData);
+ }
+
+ /**
+ * @desc 邮箱修改登陆密码
+ * @return Json
+ * @throws InvalidArgumentException
+ */
+ public function updatePasswordByEmail()
+ {
+ $returnData = (new UserService())->updatePasswordByEmail($this->request->userId, $this->request->post());
+ return json($returnData);
+ }
+
+ /**
+ * @desc 短信重新设置登陆密码
+ * @return Json
+ */
+ public function resetPasswordBySms()
+ {
+ $returnData = (new UserService())->resetPasswordBySms($this->request->userId, $this->request->post());
+ return json($returnData);
+ }
+
+ /**
+ * @desc 邮箱设置登陆密码
+ * @return Json
+ */
+ public function resetPasswordByEmail()
+ {
+ $returnData = (new UserService())->resetPasswordByEmail($this->request->userId, $this->request->post());
+ return json($returnData);
+ }
+
+
+ /**
+ * @desc 绑定邮箱
+ * @return Json
+ */
+ public function bindEmail(): Json
+ {
+ $returnData = (new UserService())->bindEmail($this->request->userId, $this->request->post());
+ return json($returnData);
+ }
+
+ /**
+ * @desc 修改已经绑定的邮箱
+ * @return Json
+ * @throws InvalidArgumentException
+ */
+ public function updateEmail(): Json
+ {
+ $returnData = (new UserService())->updateEmail($this->request->userId, $this->request->post());
+ return json($returnData);
+ }
+
+
+ /**
+ * @desc 绑定手机号
+ * @return Json
+ */
+ public function bindPhone(): Json
+ {
+ $returnData = (new UserService())->bindPhone($this->request->userId, $this->request->post());
+ return json($returnData);
+ }
+
+ /**
+ * @desc
+ * @return Json
+ * @throws InvalidArgumentException
+ */
+ public function updatePhone(): Json
+ {
+ $returnData = (new UserService())->updatePhone($this->request->userId, $this->request->post());
+ return json($returnData);
+ }
+
+ /**
+ * @desc 退出登陆
+ * @return Json
+ */
+ public function logout(): Json
+ {
+ $returnData = (new UserService())->logout($this->request->userId);
+ return json($returnData);
+ }
+
+ /**
+ * @desc 获取登陆信息
+ * @return Json
+ */
+ public function loginLog(): Json
+ {
+ $returnData = (new UserService())->loginLog($this->request->userId);
+ return json($returnData);
+ }
+
+ /**
+ * 获取时间
+ * @return Json
+ */
+ public function getTime()
+ {
+ return json(['code' => '0',
+ 'message' => 'SUCCESS',
+ 'data' => ['time' => 259200]]);
+ }
+
+ /**
+ * @desc 杠杆状态
+ * @return Json
+ */
+ public function leverApply(): Json
+ {
+ $returnData = (new UserService())->leverApply($this->request->userId);
+ return json($returnData);
+ }
+}
\ No newline at end of file
diff --git a/app/home/controller/UserVerify.php b/app/home/controller/UserVerify.php
new file mode 100644
index 0000000..444661c
--- /dev/null
+++ b/app/home/controller/UserVerify.php
@@ -0,0 +1,24 @@
+add($this->request->post(),$this->request->userId);
+ return json($returnData);
+ }
+
+
+ // 实名认证详细信息
+ public function detail()
+ {
+ $returnData = (new UserVerifyService())->detail($this->request->userId);
+ return json($returnData);
+ }
+}
\ No newline at end of file
diff --git a/app/home/controller/Vote.php b/app/home/controller/Vote.php
new file mode 100644
index 0000000..4260b72
--- /dev/null
+++ b/app/home/controller/Vote.php
@@ -0,0 +1,76 @@
+order('sort', 'asc')
+ ->select();
+
+ return json([
+ 'code' => '0',
+ 'message' => 'Request successful.',
+ 'data' => $list,
+ ]);
+ }
+
+ public function cheer(Request $request): Json
+ {
+ $param = $this->request->param();
+ if (empty($param['id']) || empty($this->request->userId)) {
+ return json([
+ 'code' => '1',
+ 'message' => 'Error',
+ 'data' => [],
+ ]);
+ }
+
+ $vote = VoteModel::find($param['id']);
+ if (empty($vote)) {
+ return json([
+ 'code' => '1',
+ 'message' => 'Error',
+ 'data' => [],
+ ]);
+ }
+ $onedayTimes = $vote->oneday_times;
+ $todayStart = date('Y-m-d 00:00:00');
+ $todayEnd = date('Y-m-d 23:59:59');
+
+ $times = UserVoteModel::where('vote_id', $param['id'])->where('user_id', $this->request->userId)->where('create_time', '<=', $todayEnd)->where('create_time', '>=', $todayStart)->count();
+ if ($times >= $onedayTimes) {
+ return json([
+ 'code' => '1',
+ 'message' => 'You have already cast your vote today',
+ 'data' => [],
+ ]);
+ }
+
+ $vote->score_num = $vote->score_num + 1;
+ $vote->save();
+
+ UserVoteModel::insert(
+ [
+ 'vote_id' => $param['id'],
+ 'user_id' => $this->request->userId,
+ 'create_time' => date('Y-m-d H:i:s')
+ ]
+ );
+
+ return json([
+ 'code' => '0',
+ 'message' => 'Request successful.',
+ 'data' => [],
+ ]);
+ }
+}
\ No newline at end of file
diff --git a/app/home/controller/Wallet.php b/app/home/controller/Wallet.php
new file mode 100644
index 0000000..67c3dcb
--- /dev/null
+++ b/app/home/controller/Wallet.php
@@ -0,0 +1,297 @@
+userId;
+ $account_type=$request->post('account_type',0);
+ $result = (new WalletService())->getUserAssets($user_id,$account_type);
+ return json($result);
+ }
+
+
+ public function userRechargeList(Request $request): Json
+ {
+ $data['user_id']=$request->userId;
+ $data['account_type']=$request->post('account_type');
+ $data['page']=$request->post('page');
+ $data['page_size']=$request->post('page_size');
+ $result = (new WalletService())->getUserRechargeList($data);
+ return json($result);
+ }
+
+ /**
+ * 用户添加钱包地址
+ * @param Request $request
+ * @return Json
+ */
+ public function addWalletAddress(Request $request): Json
+ {
+ $data['user_id']=$request->userId;
+ $data['wallet_type']=$request->post('wallet_type');
+ $data['wallet_address']=$request->post('wallet_address');
+ $data['remark']=$request->post('remark');
+ $data['adr_id']=$request->post('address_id');
+ $data['is_default']=$request->post('is_default');
+
+ $result=(new WalletService())->insertWalletAdress($data);
+ return json($result);
+ }
+
+ /**
+ * 获取用户钱包地址列表
+ * @param Request $request
+ * @return Json
+ */
+ public function getWalletAddress(Request $request): Json
+ {
+ $data['user_id']=$request->userId;
+ $data['page']=$request->post('page');
+ $data['page_size']=$request->post('page_size');
+ $data['wallet_type']=$request->post('wallet_type');
+ $result=(new WalletService())->getUserWalletAddress($data);
+ return json($result);
+ }
+
+ /**
+ * 获取用户钱包地址详情
+ * @param Request $request
+ * @return Json
+ */
+ public function getWalletAddressInfo(Request $request): Json
+ {
+ $data['user_id']=$request->userId;
+ $data['adr_id']=$request->post('address_id',0);
+ $result=(new WalletService())->getUserWalletAddressInfo($data);
+ return json($result);
+ }
+
+ /**
+ * 删除用户钱包地址
+ * @param Request $request
+ * @return Json
+ * @throws \think\db\exception\DbException
+ */
+ public function delWalletAddress(Request $request): Json
+ {
+ $data['user_id']=$request->userId;
+ $data['adr_id']=$request->post('address_id');
+ $result=(new WalletService())->delUserWalletAddress($data);
+ return json($result);
+ }
+
+ /**
+ * 获取银行卡列表
+ * @param Request $request
+ * @return Json
+ */
+ public function getUserBank(Request $request): Json
+ {
+ $data['user_id']=$request->userId;
+ $data['page']=$request->post('page');
+ $data['page_size']=$request->post('page_size');
+ $result=(new WalletService())->getUserBank($data);
+ return json($result);
+ }
+
+ /**
+ *
+ * @param Request $request
+ * @return Json
+ */
+ public function getUserBankInfo(Request $request): Json
+ {
+ $data['user_id']=$request->userId;
+ $data['id']=$request->post('id');
+ $result=(new WalletService())->getUserBankInfo($data);
+ return json($result);
+ }
+ /**
+ * 添加编辑银行卡
+ * @param Request $request
+ * @return Json
+ */
+ public function addUserBank(Request $request): Json
+ {
+ $data['user_id']=$request->userId;
+ $data['id']=$request->post('id');
+ $data['true_name']=$request->post('true_name');
+ $data['identity_card']=$request->post('identity_card');
+ $data['bank_card']=$request->post('bank_card');
+ $data['bank_name']=$request->post('bank_name');
+ $data['bank_email']=$request->post('bank_email');
+ $data['bank_phone']=$request->post('bank_phone');
+ $data['bank_code']=$request->post('bank_code');
+ $data['is_default']=$request->post('is_default');
+ $data['ifsc']=$request->post('ifsc');
+ $data['bank_address']=$request->post('bank_address');
+ $data['user_address']=$request->post('user_address');
+ $data['bank_country']=$request->post('bank_country');
+ $result=(new WalletService())->insertUserBank($data);
+ return json($result);
+ }
+
+ /**
+ * 删除银行卡
+ * @param Request $request
+ * @return Json
+ */
+ public function delUserBank(Request $request): Json
+ {
+ $data['user_id']=$request->userId;
+ $data['id']=$request->post('id');
+ $result=(new WalletService())->delUserBank($data);
+ return json($result);
+ }
+
+ /**
+ * 获取用户账户可用余额
+ * @param Request $request
+ * @return Json
+ */
+ public function getUserBalance(Request $request): Json
+ {
+ $data['user_id']=$request->userId;
+ $data['account_type']=$request->post('account_type');
+ $data['trade_name']=$request->post('trade_name');
+ $result=(new WalletService())->getUserBalance($data);
+ return json($result);
+ }
+
+ public function drawalFee(Request $request): Json
+ {
+ $account_type=$request->post('account_type',0,'intval');
+ $result=(new WalletService())->getDrawalFee($account_type);
+ return json($result);
+ }
+
+ /**
+ * 用户提款申请
+ * @param Request $request
+ * @return Json
+ */
+ public function drawalApply(Request $request): Json
+ {
+ $data['user_id']=$request->userId;
+ $data['account_type']=$request->post('account_type');
+ $data['apply_num']=$request->post('apply_num');
+ $data['apply_type']=$request->post('apply_type');
+ $data['bank_id']=$request->post('bank_id');
+ $data['address_id']=$request->post('address_id');
+ $data['wallet_address']=$request->post('wallet_address');
+ $data['drawal_type']=$request->post('drawal_type');
+ $data['trade_pwd']=$request->post('trade_pwd');
+ $data['country']=$request->post('country');
+
+ $result=(new WalletService())->dealDrawalApply($data);
+ return json($result);
+ } /**
+ * 用户提款申请
+ * @param Request $request
+ * @return Json
+ */
+ public function canncelDrawalApply(Request $request): Json
+ {
+ $data['user_id']=$request->userId;
+ $data['order_no']=$request->post('order_no');
+ $result=(new WalletService())->canncelDrawalApply($data);
+ return json($result);
+ }
+ public function userDrawalList(Request $request): Json
+ {
+ $data['user_id']=$request->userId;
+ $data['account_type']=$request->post('account_type');
+ $data['page']=$request->post('page');
+ $data['page_size']=$request->post('page_size');
+ $result=(new WalletService())->getDrawalList($data);
+ return json($result);
+ }
+
+ /**
+ * 获取用户资金明细数据
+ * @param Request $request
+ * @return Json
+ */
+ public function UserBalanceRecord(Request $request): Json
+ {
+ $data['user_id']=$request->userId;
+ $data['account_type']=$request->post('account_type');
+ $data['page']=$request->post('page');
+ $data['page_size']=$request->post('page_size');
+ $result=(new WalletService())->getUserBalanceRecord($data);
+ return json($result);
+ }
+
+ /**
+ * 处理用户资金账户相互划转接口
+ * @param Request $request
+ * @return Json
+ */
+ public function userTransfer(Request $request): Json
+ {
+ $data['user_id']=$request->userId;
+ $data['from_account']=$request->post('from_account');
+ $data['to_account']=$request->post('to_account');
+ $data['change_num']=$request->post('change_num');
+ $result=(new WalletService())->doUserTransfer($data);
+ return json($result);
+ }
+ public function userRechargeWallet(Request $request): Json
+ {
+ $data['user_id']=$request->userId;
+ $data['wallet_type']=$request->post('wallet_type');
+ $result=(new WalletService())->getUserRechargeWallet($data);
+ return json($result);
+ }
+
+ /**
+ * 获取用户划转资金明细
+ * @param Request $request
+ * @return Json
+ */
+ public function userTransferRecord(Request $request): Json
+ {
+ $data['user_id']=$request->userId;
+ $data['page']=$request->post('page');
+ $data['page_size']=$request->post('page_size');
+ $result=(new WalletService())->getUserTransfer($data);
+ return json($result);
+ }
+ public function userHasNotPay(Request $request):Json
+ {
+ $data['user_id']=$request->userId;
+ $data['market_type']=$request->post('market_type');
+ $result=(new WalletService())->userHasNotPay($data);
+ return json($result);
+ }
+ public function dealUnPayIPO(Request $request):Json
+ {
+ $data['user_id']=$request->userId;
+ $data['market_type']=$request->post('market_type');
+ $result=(new WalletService())->dealUnPayIPO($data);
+ return json($result);
+ }
+
+
+ // 获取用户账户之间划转的费率 支持计算具体值
+ public function getRateToTransfer()
+ {
+ $result=(new WalletService())->getRateToTransfer($this->request->param());
+ return json($result);
+ }
+
+}
\ No newline at end of file
diff --git a/app/home/job/LoginDone.php b/app/home/job/LoginDone.php
new file mode 100644
index 0000000..cb6065e
--- /dev/null
+++ b/app/home/job/LoginDone.php
@@ -0,0 +1,68 @@
+ $lastLoginTime], $userId);
+ }catch (\Exception $exception){
+ trace('---用户登陆记录写入异常---'.$exception->getMessage(), 'error');
+ }
+
+ try {
+ $countryNameStr = '';
+ $cityNameStr = '';
+
+ try {
+ $countryDb = base_path().'GeoLite2-Country.mmdb';
+ $cityDb = base_path().'GeoLite2-City.mmdb';
+ $countryReader = new Reader($countryDb);
+ $cityReader = new Reader($cityDb);
+ $countryNames = $countryReader->country($ip)->country->names;
+ $cityNames = $cityReader->city($ip)->city->names;
+
+ $countryNameStr = json_encode([
+ 'cn' => $countryNames['zh-CN']?? '',
+ 'en' => $countryNames['en']?? '',
+ ]);
+
+ $cityNameStr = json_encode([
+ 'cn' => $cityNames['zh-CN'] ?? '',
+ 'en' => $cityNames['en'] ?? '',
+ ]);
+
+ }catch (\Exception $exception){
+ trace('---用户登陆ip记录解析异常---data--'.json_encode([$data]).'-------'.$exception->getMessage(), 'error');
+ }
+
+ UserLoginLog::addData($userId,$device,$ip,$countryNameStr,$cityNameStr,$lastLoginTime);
+
+ }catch (\Exception $exception){
+ trace('---用户登陆ip记录写入异常---data--'.json_encode([$data]).'-------'.$exception->getMessage(), 'error');
+ }
+
+ $job->delete();
+ }
+}
\ No newline at end of file
diff --git a/app/home/job/SendEmail.php b/app/home/job/SendEmail.php
new file mode 100644
index 0000000..36f60a5
--- /dev/null
+++ b/app/home/job/SendEmail.php
@@ -0,0 +1,47 @@
+sendEmail($data['email'], $data['title'], $data['subject']);
+ if ($bool) {
+ $success = true;
+ break;
+ }
+
+ trace($job->getJobId().'---重试-----'.$times, 'info');
+ }
+
+ // 任务失败
+ if (!$success) {
+ trace($job->getJobId().'---失败-------'.json_encode($data), 'info');
+ }
+
+ // 删除任务
+ $job->delete();
+ }
+
+ public function failed($data)
+ {
+ // 失败任务
+ $dataStr = json_encode($data);
+ trace('queue job 任务失败---'.$dataStr, 'error');
+ }
+}
\ No newline at end of file
diff --git a/app/home/job/SendSms.php b/app/home/job/SendSms.php
new file mode 100644
index 0000000..b12c01d
--- /dev/null
+++ b/app/home/job/SendSms.php
@@ -0,0 +1,71 @@
+ $conArr[0],
+ 'secret' => $conArr[1]
+ ];
+ }
+ return $config;
+ }
+
+ /**
+ * @desc 发送短信验证码
+ * @param Job $job
+ * @param $data
+ * @return void
+ * @throws \Psr\SimpleCache\InvalidArgumentException
+ */
+ public function fire(Job $job, $data)
+ {
+ trace($job->getJobId().'---执行短信任务--------'.json_encode($data), 'info');
+
+ $config = $this->getConfig();
+ if(empty($config)){
+ trace('------- sms config empty -------', 'error');
+ return;
+ }
+
+ $key = "SMS:SEND:LAST_ACCESS_KEY";
+ $lastUse = Cache::store('redis')->get($key);
+ $count = count($config);
+ if(empty($lastUse) || $lastUse >= ($count -1)){
+ $nowKey = 0;
+ } else {
+ $nowKey = $lastUse++;
+ }
+ $to = $data['mobile'];
+ $message = $data['subject'];
+ $accessKey = $config[$nowKey]['access_key'];
+ $secret = $config[$nowKey]['secret'];
+ Cache::store('redis')->set($key, $nowKey);
+
+ (new \app\utility\SendSms())->send($to, $message, $accessKey, $secret);
+ // 删除任务
+ $job->delete();
+ }
+
+ public function failed($data)
+ {
+ }
+}
\ No newline at end of file
diff --git a/app/home/job/Wallet.php b/app/home/job/Wallet.php
new file mode 100644
index 0000000..72d917a
--- /dev/null
+++ b/app/home/job/Wallet.php
@@ -0,0 +1,33 @@
+WalletAddress();
+ if(!empty($result)){
+ break;
+ }
+ trace($job->getJobId().'---获取钱包任务-----'.$times, 'info');
+ }
+ // 删除任务
+ $job->delete();
+ }
+
+ public function failed($data)
+ {
+ // 失败任务
+ $dataStr = json_encode($data);
+ trace('queue job 获取钱包任务失败---'.$dataStr, 'error');
+ }
+}
\ No newline at end of file
diff --git a/app/home/middleware/AuthMiddleware.php b/app/home/middleware/AuthMiddleware.php
new file mode 100644
index 0000000..b5a0b21
--- /dev/null
+++ b/app/home/middleware/AuthMiddleware.php
@@ -0,0 +1,67 @@
+method(true) === 'OPTIONS') {
+ return response()->send();
+ }
+ $header = $request->header();
+ if(!isset($header['language'])){
+ $request->lang=Config::get('lang.default_lang');
+ }else{
+ $lang_list=Config::get('lang.allow_lang_list');
+ $lang=strtolower($header['language']);
+ if(in_array($lang,$lang_list)){
+ $request->lang=$lang;
+ }else{
+ $request->lang=Config::get('lang.default_lang');
+ }
+ }
+ if(empty($header['token'])){
+ return json(['code' => '100403', 'message' => 'login please','data' => []]);
+ }
+ if(!is_string($header['token'])){
+ return json(['code' => '100403', 'message' => 'login please','data' => []]);
+ }
+
+ $tokenUserKey = 'TOKEN:USER:'.$header['token'];
+ $userId = Cache::store('redis')->get($tokenUserKey);
+ if(empty($userId) || $userId <= 0){
+ return json(['code' => '100403', 'message' => 'login please','data' => []]);
+ }
+
+ // 查找用户信息
+ $user = UserModel::getFieldsByUserId('status,user_id', $userId);
+ if(empty($user)){
+ return json(['code' => '100403', 'message' => 'no user','data' => []]);
+ }
+
+ if($user['status'] != UserModel::STATUS_ON){
+ return json(['code' => '100403', 'message' => 'no auth','data' => []]);
+ }
+
+ $request->userId = $userId;
+ $userTokenKey = 'USER:TOKEN:'.$request->userId;
+
+ $expire = 30 * 24 * 60 * 60;
+ Cache::store('redis')->set($userTokenKey, $header['token'], $expire);
+ Cache::store('redis')->set($tokenUserKey, $request->userId, $expire);
+ return $next($request);
+
+ }
+}
\ No newline at end of file
diff --git a/app/home/middleware/CorsMiddleware.php b/app/home/middleware/CorsMiddleware.php
new file mode 100644
index 0000000..a228899
--- /dev/null
+++ b/app/home/middleware/CorsMiddleware.php
@@ -0,0 +1,26 @@
+ 'true',
+ 'Access-Control-Max-Age' => 1800,
+ 'Access-Control-Allow-Methods' => 'GET, POST, PATCH, PUT, DELETE, OPTIONS',
+ 'Access-Control-Allow-Headers' => 'Authorization, Content-Type, If-Match, If-Modified-Since, If-None-Match, If-Unmodified-Since, X-CSRF-TOKEN, X-Requested-With,Token,Language',
+ ];
+ public function handle($request, Closure $next, ?array $header = [])
+ {
+ header('Access-Control-Allow-Origin: *' );
+ header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, PATCH, OPTIONS');
+ header('Access-Control-Allow-Headers: Content-Type, Authorization,Accpet,Token,Language');
+ header('Access-Control-Max-Age: 86400');
+ header('Access-Control-Allow-Credentials: true');
+ return parent::handle($request, $next, $header); // TODO: Change the autogenerated stub
+ }
+
+}
+
diff --git a/app/home/middleware/RepeatOperateMiddleware.php b/app/home/middleware/RepeatOperateMiddleware.php
new file mode 100644
index 0000000..6528879
--- /dev/null
+++ b/app/home/middleware/RepeatOperateMiddleware.php
@@ -0,0 +1,48 @@
+method(true) === 'OPTIONS') {
+ return response()->send();
+ }
+
+ $header = $request->header();
+ if(!isset($header['language'])){
+ $request->lang=Config::get('lang.default_lang');
+ }else{
+ $lang_list=Config::get('lang.allow_lang_list');
+ $lang=strtolower($header['language']);
+ if(in_array($lang,$lang_list)){
+ $request->lang=$lang;
+ }else{
+ $request->lang=Config::get('lang.default_lang');
+ }
+ }
+ //echo $request->lang;
+ $ip = (new BaseHomeService())->getClientRealIp();
+ $url = $request->url();
+ $key = 'REPEAT_OPERATE_'.$url.'_'.$ip;
+ if(Cache::store('redis')->has($key)){
+ return json(['code' => '100403', 'message' => 'repeated','data' => []]);
+ }
+
+ //Cache::store('redis')->set($key, 1, 2);
+ return $next($request);
+
+ }
+}
\ No newline at end of file
diff --git a/app/home/route/app.php b/app/home/route/app.php
new file mode 100644
index 0000000..3ff2077
--- /dev/null
+++ b/app/home/route/app.php
@@ -0,0 +1,273 @@
+
+// +----------------------------------------------------------------------
+use think\facade\Route;
+
+$header = [
+ 'Access-Control-Allow-Credentials' => 'true',
+ 'Access-Control-Max-Age' => 1800,
+ 'Access-Control-Allow-Methods' => 'GET, POST, PATCH, PUT, DELETE, OPTIONS',
+ 'Access-Control-Allow-Headers' => 'Authorization, Content-Type, If-Match, If-Modified-Since, If-None-Match, If-Unmodified-Since, X-CSRF-TOKEN, X-Requested-With,Token,Language,X-token',
+];
+
+/**
+ * 不需要登陆的路由
+ */
+Route::group('/',function (){
+ Route::group('/',function (){
+ // 邮箱 登录
+ Route::post('/email_login', 'Login/loginEmail');
+ // 发送邮件
+ Route::post('/email', 'Login/sendEmail');
+ // 邮箱注册
+ Route::post('/email_reg', 'Login/registerEmail');
+ // 发送短信
+ Route::post('/sms', 'Login/sendSms');
+ //短信注册
+ Route::post('/sms_reg', 'Login/registerSms');
+ //短信登陆
+ Route::post('/sms_login', 'Login/loginSms');
+ //通过邮箱重新设置密码
+ Route::post('/forget_email', 'Login/resetPasswordByEmail');
+ //通过短信重新设置密码
+ Route::post('/forget_sms', 'Login/resetPasswordBySms');
+ // 手机号密码登陆
+ Route::post('/phone_login', 'Login/phoneLogin');
+
+ // 获取配置
+ Route::post('/get_config', 'Upload/getConfig');
+
+ })->middleware(\app\home\middleware\RepeatOperateMiddleware::class);
+ // 获取帮助中心文档
+ Route::post('/faq_index', 'Faq/index');
+ Route::post('/faq_detail', 'Faq/detail');
+ Route::post('/banner_index', 'Carousel/index');
+ Route::post('/banner_detail', 'Carousel/detail');
+ Route::post('/announcement_index', 'Announcement/index');
+ Route::post('/announcement_detail', 'Announcement/detail');
+
+ Route::post('/doc_platform', 'Document/getPlatform');
+ Route::post('/doc_pc', 'Document/getDocPc');
+ Route::post('/doc_detail', 'Document/detail');
+ Route::post('/doc', 'Document/getDoc');
+
+ // 国家和地区
+ Route::post('/country', 'Country/getAll');
+ // 获取首页广告图
+ Route::post('/carousal', 'Carousel/getCarousel');
+ Route::post('/market', 'Market/marketList');
+ Route::post('/market_rate', 'Market/marketRate');
+ Route::post('/market_trade', 'Market/marketTradeList');
+ Route::post('/trade_type', 'Market/TradeTypeList');
+ Route::post('/face_list', 'Market/ContractFaceList');
+ Route::post('/face_forex', 'Market/ForexFaceList');
+
+ Route::post('/lang', 'Language/langList');
+ Route::post('/service', 'Language/serviceList');
+ Route::post('/init_data', 'Language/initRedisData');
+
+ // 获取股票市场状态
+ Route::post('/stock/check_status', 'Stock/checkMarketStatus');
+
+
+ //Route::post('payment_test', 'Pay/test'); //获取充值渠道
+ Route::post('indpay_notify', 'Pay/indPayNotify')->name('indpay_notify'); //支付异步通知地址
+ Route::post('indpay_query', 'Pay/indPayQuery')->name('indpay_query'); //支付同步通知地址
+ Route::post('single_notify', 'Pay/singleNotify')->name('single_notify');
+
+ //数字币充值
+ Route::post('pay_notify', 'Pay/payNotify')->name('pay_notify'); //充值通知接口
+ Route::post('order_confirm', 'Pay/OrderConfirm')->name('order_confirm'); //充值通知接口
+ Route::get('get_wallet', 'Pay/wallet')->name('get_wallet');//获取钱包地址
+ Route::post('htpay_notify', 'Pay/htPayNotify')->name('htpay_notify'); //充值通知接口
+ Route::post('arpay_notify', 'Pay/arPayNotify')->name('arpay_notify'); //充值通知接口
+
+ Route::post('xdpay_notify', 'Pay/XdPayNotify')->name('xdpay_notify'); //充值通知接口
+ Route::post('xdpay_anotify', 'Pay/XdPayAppNotify')->name('xdpay_anotify'); //充值通知接口
+
+ Route::post('qeaepay_notify', 'Pay/QeaePayNotify')->name('qeaepay_notify'); //充值通知接口
+ Route::post('qeaepay_appNotify', 'Pay/QeaePayAppNotify')->name('qeaepay_appNotify'); //充值通知接口
+
+ Route::post('xdpay_notify', 'Pay/XdPayNotify')->name('xdpay_notify'); //充值通知接口
+ Route::post('xdpay_anotify', 'Pay/XdPayAppNotify')->name('xdpay_anotify'); //充值通知接口
+
+ Route::post('mopay_notify', 'Pay/MoPayNotify')->name('mopay_notify'); //充值通知接口
+ Route::post('mopay_anotify', 'Pay/MoPayAppNotify')->name('mopay_anotify'); //充值通知接口
+
+ Route::post('nicepay_notify', 'Pay/NicePayNotify')->name('nicepay_notify');
+ Route::post('nicepay_anotify', 'Pay/NicePayApplyNotify')->name('nicepay_anotify');
+
+ Route::post('clickpay_notify', 'Pay/ClickPayNotify')->name('clickpay_notify'); //充值通知接口
+ Route::post('clickpay_ApplyNotify', 'Pay/ClickPayApplyNotify')->name('clickpay_appNotify'); //充值通知接口
+
+ Route::post('starpay_notify', 'Pay/starPayNotify')->name('starpay_notify'); //充值通知接口
+ Route::post('starpay_ApplyNotify', 'Pay/ClickPayApplyNotify')->name('starpay_appNotify'); //充值通知接口
+
+
+ Route::post('payment_test', 'Pay/test');
+
+ Route::post('bank_list', 'Pay/BankList');
+
+ // 需要登陆的操作
+ Route::group('/',function (){
+ // 上传用户头像
+ Route::post('upload_header', 'Upload/uploadHeaderImage');
+ // 需要防止重复操作的路由
+ Route::group('', function () {
+ // 设置国家码
+ Route::post('user/set_country', 'User/setCountry');
+
+ // 设置用户头像
+ Route::post('head_update', 'User/updateHeadImg');
+ // 登陆状态获取邮箱验证码
+ Route::post('user/email_send', 'User/sendEmail');
+ // 登陆状态获取邮箱验证码
+ Route::post('user/sms_send', 'User/sendSms');
+ // 设置用户信息
+ Route::post('user/update_info', 'User/updateInfo');
+
+
+ // 邮箱修改支付密码
+ Route::post('user/update_pay_password_email', 'User/updatePayPasswordByEmail');
+ // 短信修改支付密码
+ Route::post('user/update_pay_password_sms', 'User/updatePayPasswordBySms');
+ // 邮箱修改支付密码-忘记密码
+ Route::post('user/reset_pay_password_email', 'User/resetPayPasswordByEmail');
+ // 短信修改支付密码-忘记密码
+ Route::post('user/reset_pay_password_sms', 'User/resetPayPasswordBySms');
+
+ // 邮箱修改密码
+ Route::post('user/update_password_email', 'User/updatePasswordByEmail');
+ // 短信修改密码
+ Route::post('user/update_password_sms', 'User/updatePasswordBySms');
+ // 邮箱修改密码-忘记密码
+ Route::post('user/reset_password_email', 'User/resetPasswordByEmail');
+ // 短信修改密码-忘记密码
+ Route::post('user/reset_password_sms', 'User/resetPasswordBySms');
+
+ // 邮件 设置支付密码
+ Route::post('user/pay_password_email_set', 'User/setPayPasswordByEmail');
+ // 短信 设置支付密码
+ Route::post('user/pay_password_sms_set', 'User/setPayPasswordBySms');
+
+ // 绑定邮箱
+ Route::post('user/bind_email', 'User/bindEmail');
+ Route::post('user/update_email', 'User/updateEmail');
+ // 绑定手机号
+ Route::post('user/bind_phone', 'User/bindPhone');
+ Route::post('user/update_phone', 'User/updatePhone');
+
+ // 新增实名认证
+ Route::post('user_verify/add', 'UserVerify/add');
+
+
+ })->middleware(\app\home\middleware\RepeatOperateMiddleware::class);
+
+ // 新增实名认证
+ Route::post('user_verify/detail', 'UserVerify/detail');
+
+ // 获取时间
+ Route::post('user/get_time', 'User/getTime');
+ // 获取用户基础信息
+ Route::post('user/info', 'User/getUserInfo');
+ // 获取登陆记录
+ Route::post('user/login_log', 'User/loginLog');
+ // 退出登陆
+ Route::post('user/log_out', 'User/logout');
+
+
+ Route::post('payment_list', 'Pay/payChannel'); //获取充值渠道
+ Route::post('user_recharge', 'Pay/rechargeApply')->middleware(\app\home\middleware\RepeatOperateMiddleware::class); // 用户申请充值接口 防止重复操作
+
+ Route::post('user_assets', 'Wallet/getAllAssets'); // 获取用户所有资产列表数据
+ Route::post('user_balance', 'Wallet/getUserBalance'); // 获取用户所有资产列表数据
+ Route::post('balance_record', 'Wallet/UserBalanceRecord'); // 获取用户资金明细数据
+
+ Route::post('recharge_list', 'Wallet/userRechargeList');
+ Route::post('recharge_wallet', 'Wallet/userRechargeWallet');
+ Route::post('upload_recharge', 'Upload/uploadRechargeImage');
+
+ Route::post('transfer', 'Wallet/userTransfer')->middleware(\app\home\middleware\RepeatOperateMiddleware::class); // 用户资金划转接口
+ Route::post('transfer_list', 'Wallet/userTransferRecord'); // 用户资金划转接口
+
+ Route::post('user_drawal', 'Wallet/drawalApply')->middleware(\app\home\middleware\RepeatOperateMiddleware::class); // 用户申请提现接口
+ Route::post('canncel_drawal', 'Wallet/canncelDrawalApply')->middleware(\app\home\middleware\RepeatOperateMiddleware::class); // 用户申请提现接口
+ Route::post('drawal_fee', 'Wallet/drawalFee'); // 用户提现手续费接口
+ Route::post('drawal_list', 'Wallet/userDrawalList'); // 用户提现手续费接口
+
+ Route::post('trc20_list', 'Pay/getTRC20BuyList'); // TRC20
+
+ Route::post('add_bank', 'Wallet/addUserBank'); // 用户添加银行卡
+ Route::post('user_bank', 'Wallet/getUserBank'); // 获取用户银行卡列表
+ Route::post('bank_info', 'Wallet/getUserBankInfo'); // 获取用户银行卡详情
+ Route::post('del_bank', 'Wallet/delUserBank'); // 删除用户银行卡
+ Route::post('add_wallet_address', 'Wallet/addWalletAddress'); // 用户添加钱包地址
+ Route::post('wallet_address', 'Wallet/getWalletAddress'); // 获取用户钱包地址列表
+ Route::post('del_wallet_address', 'Wallet/delWalletAddress'); // 删除用户钱包地址
+ Route::post('get_wallet_address', 'Wallet/getWalletAddressInfo'); // 获取用户钱包地址详情
+
+ Route::post('get_transfer_rate', 'Wallet/getRateToTransfer'); // 获取用户账户之间划转的费率 支持计算具体值
+
+ Route::post('user_market', 'Market/userMarket'); // 获取用户自选数据
+ Route::post('add_market', 'Market/addMarket'); // 添加用户自选数据
+ Route::post('del_market', 'Market/delMarket'); // 删除用户自选数据
+ Route::post('is_collect', 'Market/MarketCollect'); // 删除用户自选数据
+ Route::post('trade_fee', 'Market/tradeFee');
+ Route::post('contract_setting', 'Market/ContractSetting');
+
+ Route::post('team_collect', 'Team/userTeamCollect');// 获取团队汇总
+ Route::post('team_back', 'Team/userTeamBack'); // 获取团队人数
+ Route::post('team_list', 'Team/userTeamList'); // 获取团队人数
+ // 根据邮箱重新设置密码
+ Route::post('user/reset_pwd_email', 'User/resetPasswordByEmail');
+ Route::post('user/lever_apply', 'User/leverApply');
+
+
+ // 股票申购
+ Route::post('pre_stock/order', 'PreStock/order')->middleware(\app\home\middleware\RepeatOperateMiddleware::class); // 新股下单 防止重复操作
+ Route::post('pre_stock/post_pay', 'PreStock/postPay')->middleware(\app\home\middleware\RepeatOperateMiddleware::class); // 新股下单后支付 - 订单支付
+ Route::post('pre_stock/list', 'PreStock/list');
+ Route::post('pre_stock/detail', 'PreStock/detail');
+
+ // 基金订单
+ Route::post('fund/order', 'Fund/order')->middleware(\app\home\middleware\RepeatOperateMiddleware::class);
+ Route::post('fund/user_fund', 'Fund/userFund');
+ Route::post('fund/detail', 'Fund/detail');
+ Route::post('fund/history', 'Fund/history');
+
+ Route::post('has_pay', 'Wallet/userHasNotPay');
+ Route::post('pay_ipo', 'Wallet/dealUnPayIPO');
+
+ //大宗交易
+ Route::post('block/index', 'Block/index'); //大宗交易商品列表
+ Route::post('block/list', 'Block/list'); //大宗交易订单
+
+ //投票
+ Route::post('vote/index', 'Vote/index');
+ Route::post('vote/cheer', 'Vote/cheer');
+
+ })->middleware(\app\home\middleware\AuthMiddleware::class);
+ // 美股申购列表 不需要登陆
+ Route::post('pre_stock/index', 'PreStock/index');
+ Route::post('pre_stock/stock_detail', 'PreStock/stockDetail');
+
+ //基金
+ Route::post('fund/index', 'Fund/index');
+ Route::post('auto_login', 'Login/autoLogin');
+ Route::post('get_ip', 'Login/getIP');
+
+
+})->allowCrossDomain($header);
+
+
+
+
+
+
diff --git a/app/home/service/BaseHomeService.php b/app/home/service/BaseHomeService.php
new file mode 100644
index 0000000..0a5f3dc
--- /dev/null
+++ b/app/home/service/BaseHomeService.php
@@ -0,0 +1,957 @@
+ $code,
+ 'message' => $msg,
+ 'data' => $result
+ ];
+ }
+ public function __construct()
+ {
+ $this->redis=$this->getRedis();
+ //$this->getTrcWalletAddress();
+ }
+
+ /**
+ *
+ */
+ private function getTrcWalletAddress()
+ {
+ $redis_key="TRCWallet";
+ $num=WalletListModel::where([
+ 'user_id'=>0,
+ 'wallet_type'=>'TRC-20'
+ ])->count();
+ $flag=$this->redis->exists($redis_key);
+ if($num<50 && empty($flag)){
+ $this->redis->setex($redis_key,120,2);
+ $queuename = 'app\home\job\Wallet';
+ Queue::push($queuename, "test", 'Wallet');
+ }
+ }
+
+ /**
+ * @desc 获取发送的短信内容
+ * @param int $type
+ * @return array
+ * @throws \Exception
+ */
+ public function getSmsContent(int $type = 1): array
+ {
+ $code = random_int(1000,9999);
+ $subject = "your code is [$code], valid for 5 minutes";
+ return ['subject' => $subject, 'code' => $code];
+ }
+
+ /**
+ * @desc 根据类型获取要发送的邮件内容
+ * @param int $type
+ * @return array
+ * @throws \Exception
+ */
+ public function getEmailContent(int $type = 1): array
+ {
+ $code = random_int(1000,9999);
+ $title = 'Verification Code';
+ $subject = "your code is [$code], valid for 5 minutes, please do not reply to this email";
+ return ['title' => $title, 'subject' => $subject, 'code' => $code];
+ }
+
+ /**
+ * 生成13位用户号
+ * @return string
+ * @throws InvalidArgumentException
+ */
+ public function getUniqUserNo(): string
+ {
+ $code = 's';
+ $code .= date('ymd'); // s230629
+ while (true)
+ {
+ $code .= rand(100000, 999999);
+ // redis 去重
+ $exist = Cache::store('redis')->get($code);
+ // 存储有效期为距离明天还要多久
+ $expire = strtotime('tomorrow') - time();
+ if (!$exist) {
+ Cache::store('redis')->set($code, 1, $expire);
+ break;
+ }
+ }
+ return $code;
+ }
+
+ /**
+ * 生成12位随机邀请码
+ * @param $length
+ * @return string
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ function getUniqInviteCode($length = 6) {
+ $characters = '1234567890abcdefghijklmnpqrstwxyzABCDEFGHIJKLMNPQRSTWXYZ';
+ $inviteCode = '';
+ while (true)
+ {
+ for ($i = 0; $i < $length; $i++) {
+ $index = rand(0, strlen($characters) - 1);
+ $inviteCode .= $characters[$index];
+ }
+
+ // 查询去重
+ $user = UserModel::where('invite_code', $inviteCode)->value('user_id');
+ if(empty($user)){
+ break;
+ }
+ // 查询去重
+ $agent = AdminModel::where('invite_code', $inviteCode)->value('id');
+ if(empty($agent)){
+ break;
+ }
+ }
+ return $inviteCode;
+ }
+
+ /**
+ * 生成12位随机邀请码
+ * @return string
+ * @throws InvalidArgumentException
+ */
+ public function getUniqInviteCodeBack(): string
+ {
+ $code = '';
+ $arr = [
+ '9','t','6', 'k', 'h', '8', '5','f', 'm', 'd', 's', '6'
+ ];
+ // redis 去重
+ while (true)
+ {
+ $rand_num = time().rand(10,99);
+ for($i = 0; $iget($code);
+ if (!$exist) {
+ Cache::store('redis')->set($code, 1, 5);
+ break;
+ }
+ }
+
+ return $code;
+ }
+
+ /**
+ * @desc 获取客户端ip
+ * @return mixed|string
+ */
+ public function getClientRealIp()
+ {
+ $ip = '';
+ if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
+ $ip = $_SERVER['HTTP_CLIENT_IP'];
+ } elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
+ $ipArray = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
+ $ip = trim($ipArray[0]);
+ } elseif (!empty($_SERVER['HTTP_X_FORWARDED'])) {
+ $ip = $_SERVER['HTTP_X_FORWARDED'];
+ } elseif (!empty($_SERVER['HTTP_FORWARDED_FOR'])) {
+ $ip = $_SERVER['HTTP_FORWARDED_FOR'];
+ } elseif (!empty($_SERVER['HTTP_FORWARDED'])) {
+ $ip = $_SERVER['HTTP_FORWARDED'];
+ } elseif (!empty($_SERVER['REMOTE_ADDR'])) {
+ $ip = $_SERVER['REMOTE_ADDR'];
+ }
+
+ return $ip;
+ }
+
+ /**
+ * @desc 判断是否为禁止邮箱
+ * @param $email
+ * @return bool
+ */
+ public function checkForbidEmail($email): bool
+ {
+ $emailType = explode('@', $email);
+ $denyEmailType = explode(',', env('EMAIL.DENY_EMAIL_TYPE'));
+ if (in_array($emailType[1], $denyEmailType)) {
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * @desc 判断是否为禁止的国家码
+ * @param $nation
+ * @return bool
+ */
+ public function checkForbidNation($nation)
+ {
+ $denyNation = explode(',', env('NATION.DENY_NATION'));
+ if (in_array($nation, $denyNation)) {
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * @desc 判断获取验证码是否已经达到上限
+ * @param $key
+ * @return bool
+ * @throws InvalidArgumentException
+ */
+ public function checkGetNoTradeCodeNum($key): bool
+ {
+ $num = env('LOGIN.PER_IP_GET_CODE_NUM');
+ if(!Cache::store('redis')->has($key)){
+ return false;
+ }
+ $hadNum = Cache::store('redis')->get($key);
+ if($hadNum >= $num ){
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * @desc 判断获取验证码是否已经达到上限
+ * @param $key
+ * @return bool
+ * @throws InvalidArgumentException
+ */
+ public function checkGetNoTradeCodeNumPhone($key): bool
+ {
+ $num = env('LOGIN.PER_PHONE_GET_CODE_NUM');
+ if(!Cache::store('redis')->has($key)){
+ return false;
+ }
+ $hadNum = Cache::store('redis')->get($key);
+ if($hadNum >= $num ){
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * @desc 更新已经获取的key的次数 存在就累加 1 不存在就新增 并设置有效期
+ * @param $key
+ * @return void
+ * @throws InvalidArgumentException
+ */
+ public function updateHadGetCodeNumCache($key)
+ {
+ if(!Cache::store('redis')->has($key)){
+ $expire = 24 * 60 * 60;
+ Cache::store('redis')->set($key, 1, $expire);
+ }else{
+ Cache::store('redis')->inc($key, 1);
+ }
+ }
+
+ /**
+ * @desc 将验证码存进redis 并设置有效期
+ * @param $key
+ * @param $code
+ * @param $seconds
+ * @return void
+ * @throws InvalidArgumentException
+ */
+ public function insertCodeToCache($key, $code, $seconds)
+ {
+ Cache::store('redis')->set($key, $code, $seconds);
+ }
+
+ /**
+ * @desc 验证验证码
+ * @param $key
+ * @param $code
+ * @return bool
+ * @throws InvalidArgumentException
+ */
+ public function checkCode($key, $code)
+ {
+ $cacheCode = Cache::store('redis')->get($key);
+ if(empty($cacheCode)){
+ return false;
+ }
+
+ return $cacheCode == $code;
+ }
+ /**
+ * @desc 验证是否已经达到每日注册上限
+ * @param $key
+ * @return bool
+ * @throws InvalidArgumentException
+ */
+ public function checkRegisterLimit($key)
+ {
+ $setCanRegisterNumPerDayPerIp = env('LOGIN.PER_IP_REGISTER_NUM_EVERY_DAY');
+ if(!Cache::store('redis')->has($key)){
+ return false;
+ }
+
+ $hadNum = Cache::store('redis')->get($key);
+ return $hadNum >= $setCanRegisterNumPerDayPerIp;
+ }
+
+ /**
+ * @desc 更新已经注册的数量
+ * @param $key
+ * @return void
+ * @throws InvalidArgumentException
+ */
+ public function updateHadRegisterNumCache($key)
+ {
+ if(!Cache::store('redis')->has($key)){
+ $expire = 24 * 60 * 60;
+ Cache::store('redis')->set($key, 1, $expire);
+ }
+ Cache::store('redis')->inc($key, 1);
+ }
+
+ /**
+ * @desc 根据邀请码获取邀请人的id
+ * @param $inviteCode
+ * @return int|mixed
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getParentIdByInviteCode($inviteCode)
+ {
+ $parentUser = UserModel::getUserByInviteCode($inviteCode);
+ if(empty($parentUser)){
+ return 0;
+ }
+ return $parentUser['user_id'];
+ }
+
+ /**
+ * @desc 删除指定key
+ * @param $key
+ * @return void
+ * @throws InvalidArgumentException
+ */
+ public function delCache($key)
+ {
+ Cache::store('redis')->delete($key);
+ }
+
+ public function setUserTokenCache($token, $userId)
+ {
+ // 清除之前的token 设置新的token
+ $userTokenKey = 'USER:TOKEN:'.$userId; // 根据用户id 查找token
+ $oldToken = Cache::store('redis')->get($userTokenKey);
+ if($oldToken){
+ $oldTokenKey = 'TOKEN:USER:'.$oldToken;
+ Cache::store('redis')->delete($oldTokenKey);
+ }
+ $tokenKey = 'TOKEN:USER:'.$token; // 根据token查找用户id
+ $expired = 30 * 24 * 60 * 60;
+ // 由中间件自动续期
+ Cache::store('redis')->set($tokenKey, $userId, $expired);
+ Cache::store('redis')->set($userTokenKey, $token, $expired);
+
+ }
+ public function delUserTokenCache($userId)
+ {
+ // user -> token
+ $userTokenKey = 'USER:TOKEN:'.$userId; // 根据用户id 查找token
+ $token = Cache::store('redis')->get($userTokenKey);
+ Cache::store('redis')->delete($token);
+ // token -> user
+ $tokenUser = 'TOKEN:USER:'.$token;
+ Cache::store('redis')->delete($tokenUser);
+ }
+
+ public function setUserLevel($userId,$level_info)
+ {
+ $key='USER:LEVEL:'.$userId;
+ // 由中间件自动续期
+ Cache::store('redis')->set($key, $level_info);
+ }
+
+ public function initSetting(){
+ $this->initTradeFeeSetting();
+ $this->initBrokerageRegSetting();
+ $this->initUserLevelSetting();
+ $this->initContractSetting();
+ $this->initDigitalList();
+ $this->initDrawalSetting(1);
+ return $this->toData(0,'ok');
+ }
+ public function initDigitalList(){
+ $result=DigitalListModel::getMarketList([
+ 'page'=>1,
+ 'page_size'=>2000
+ ]);
+ foreach ($result['list'] as $val){
+ $key="DIGITAL:LIST:".$val['name'];
+ $this->redis->del($key);
+ $this->redis->hMSet($key,$val);
+ }
+ return $result['list'];
+ }
+ public function getDigitalList(){
+ $data=$this->redis->keys('DIGITAL:LIST:*');
+ $list=[];
+ foreach ($data as $val){
+ $list[]=$this->redis->hGetAll($val);
+ }
+ return [
+ 'total'=>count($data),
+ 'list'=>$list,
+ ];
+ }
+ public function initDrawalSetting($type=0)
+ {
+ $key="DRAWAL:FEE:SETTING";
+ if($type==1){
+ $info=DrawalSettingModel::getDrawalFee();
+ $this->redis->hMset($key,$info);
+ }else{
+ return $this->redis->hGetAll($key);
+ }
+ }
+ public function initContractSetting()
+ {
+ $list=ContractListMode::getMarketFaceList();
+ foreach ($list as $val){
+ $key="CONTRACT:LIST:".$val['name'];
+ $this->redis->del($key);
+ $this->redis->hMSet($key,$val);
+ }
+ return $list;
+ }
+ public function getContractFaceList($type=0)
+ {
+
+ $list=$this->redis->keys('CONTRACT:LIST:*');
+ //var_dump($list);
+ if(empty($list)){
+ $list=$this->initContractSetting();
+ if($type){
+ return $list;
+ }else{
+ return [
+ 'total'=>count($list),
+ 'list'=>$list
+ ];
+ }
+ }else{
+ $data=[];
+ foreach ($list as $val){
+ $data[]=$this->redis->hGetAll($val);
+ }
+ if($type){
+ return $data;
+ }else{
+ return [
+ 'total'=>count($data),
+ 'list'=>$data
+ ];
+ }
+ }
+ }
+ public function initBrokerageRegSetting()
+ {
+ //注册返佣
+ $brokerage_reg_key='BROKERAGE:REG:SETTING';
+ //开仓返佣
+ $brokerage_buy_key='BROKERAGE:BUY:SETTING';
+ //平仓返佣
+ $brokerage_sale_key='BROKERAGE:SALE:SETTING';
+ $list=BrokerageSettingModel::getBrokerageSetting();
+ foreach ($list as $val){
+ switch ($val['brok_type']){
+ case 1:
+ $this->redis->hMset($brokerage_buy_key,$val);
+ break;
+ case 2:
+ $this->redis->hMset($brokerage_sale_key,$val);
+ break;
+ default:
+ $this->redis->hMset($brokerage_reg_key,$val);
+ break;
+ }
+ }
+ }
+ /**
+ * 获取返佣配置
+ * @return void
+ */
+ public function getBrokerageRegSetting()
+ {
+ //注册返佣
+ $brokerage_reg_key='BROKERAGE:REG:SETTING';
+ $res= $this->redis->hGetAll($brokerage_reg_key);
+ if(empty($res)){
+ $this->initBrokerageRegSetting();
+ $res= $this->redis->hGetAll($brokerage_reg_key);
+ }
+ return $res;
+
+ }
+ public function initUserLevelSetting()
+ {
+ $list=UserLevelModel::getUserLevelList();
+ foreach ($list as $item){
+ $key='USER:LEVEL:'.$item['user_id'];
+ $this->redis->hMset($key,$item);
+ }
+ }
+ public function initTradeFeeSetting($market_type=0)
+ {
+ $digital_fee_key='TRADE:FEE:DIGITAL';
+ $contract_fee_key='TRADE:FEE:CONTRACT';
+ $us_stock_fee_key='TRADE:FEE:US_STOCK';
+ $idn_stock_fee_key='TRADE:FEE:IDN_STOCK';
+ $mys_stock_fee_key='TRADE:FEE:MYS_STOCK';
+ $tha_stock_fee_key='TRADE:FEE:THA_STOCK';
+ $in_stock_fee_key='TRADE:FEE:IN_STOCK';
+ $SGD_stock_fee_key='TRADE:FEE:SGD_STOCK';
+ $hk_stock_fee_key='TRADE:FEE:HK_STOCK';
+ $uk_stock_fee_key='TRADE:FEE:UK_STOCK';
+ $fur_stock_fee_key='TRADE:FEE:FUR_STOCK';
+ $eur_stock_fee_key='TRADE:FEE:EUR_STOCK';
+ $brl_stock_fee_key='TRADE:FEE:BR_STOCK';
+ $jp_stock_fee_key='TRADE:FEE:JP_STOCK';
+ $forex_fee_key='TRADE:FEE:FOREX';
+
+
+ if($market_type==0){
+ $trade_fee_list=FeeSettingModel::getTradeFeeById(0);
+ foreach ($trade_fee_list as $item){
+ switch ($item['market_type']){
+ case 1:
+ $this->redis->del($digital_fee_key);
+ $this->redis->hMset($digital_fee_key,$item);
+ break;
+ case 2:
+ $this->redis->del($contract_fee_key);
+ $this->redis->hMset($contract_fee_key,$item);
+ break;
+ case 3:
+ $this->redis->del($us_stock_fee_key);
+ $this->redis->hMset($us_stock_fee_key,$item);
+ break;
+ case 4:
+ $this->redis->del($idn_stock_fee_key);
+ $this->redis->hMset($idn_stock_fee_key,$item);
+ break;
+ case 5:
+ $this->redis->del($mys_stock_fee_key);
+ $this->redis->hMset($mys_stock_fee_key,$item);
+ break;
+ case 6:
+ $this->redis->del($tha_stock_fee_key);
+ $this->redis->hMset($tha_stock_fee_key,$item);
+ break;
+ case 7:
+ $this->redis->del($in_stock_fee_key);
+ $this->redis->hMset($in_stock_fee_key,$item);
+ break;
+ case 9:
+ $this->redis->del($SGD_stock_fee_key);
+ $this->redis->hMset($SGD_stock_fee_key,$item);
+ break;
+ case 12:
+ $this->redis->del($hk_stock_fee_key);
+ $this->redis->hMset($hk_stock_fee_key,$item);
+ break;
+ case 14:
+ $this->redis->del($uk_stock_fee_key);
+ $this->redis->hMset($uk_stock_fee_key,$item);
+ break;
+ case 15:
+ $this->redis->del($fur_stock_fee_key);
+ $this->redis->hMset($fur_stock_fee_key,$item);
+ break;
+ case 16:
+ $this->redis->del($eur_stock_fee_key);
+ $this->redis->hMset($eur_stock_fee_key,$item);
+ break;
+ case 17:
+ $this->redis->del($brl_stock_fee_key);
+ $this->redis->hMset($brl_stock_fee_key,$item);
+ break;
+ case 18:
+ $this->redis->del($jp_stock_fee_key);
+ $this->redis->hMset($jp_stock_fee_key,$item);
+ break;
+ case 19:
+ $this->redis->del($forex_fee_key);
+ $this->redis->hMset($forex_fee_key,$item);
+ break;
+ }
+ }
+ return $trade_fee_list;
+ }else{
+ $res=[];
+ switch ($market_type){
+ case 1:
+ $res= $this->redis->hGetAll($digital_fee_key);
+ break;
+ case 2:
+ $res=$this->redis->hGetAll($contract_fee_key);
+ break;
+ case 3:
+ $res=$this->redis->hGetAll($us_stock_fee_key);
+ break;
+ case 4:
+ $res=$this->redis->hGetAll($idn_stock_fee_key);
+ break;
+ case 5:
+ $res=$this->redis->hGetAll($mys_stock_fee_key);
+ break;
+ case 6:
+ $res=$this->redis->hGetAll($tha_stock_fee_key);
+ break;
+ case 7:
+ $res=$this->redis->hGetAll($in_stock_fee_key);
+ break;
+ case 9:
+ $res=$this->redis->hGetAll($SGD_stock_fee_key);
+ break;
+ case 12:
+ $res=$this->redis->hGetAll($hk_stock_fee_key);
+ break;
+ case 14:
+ $res=$this->redis->hGetAll($uk_stock_fee_key);
+ break;
+ case 15:
+ $res=$this->redis->hGetAll($fur_stock_fee_key);
+ break;
+ case 16:
+ $res=$this->redis->hGetAll($eur_stock_fee_key);
+ break;
+ case 17:
+ $res=$this->redis->hGetAll($brl_stock_fee_key);
+ break;
+ case 18:
+ $res=$this->redis->hGetAll($jp_stock_fee_key);
+ break;
+ case 19:
+ $res=$this->redis->hGetAll($forex_fee_key);
+ break;
+ }
+ return $res;
+ }
+
+ }
+ private function checkEmpty($value1, $value2, $value3) :bool
+ {
+ $count = 0; // 用于计数非空值的个数
+ if (!empty($value1)) {
+ $count++;
+ }
+ if (!empty($value2)) {
+ $count++;
+ }
+ if (!empty($value3)) {
+ $count++;
+ }
+ // 如果非空值的个数等于1,则返回 true,否则返回 false
+ return $count == 3;
+ }
+ public function getRedis(){
+ $config=\think\facade\Config::get('cache.stores.redis');
+ $redis=new \Redis();
+
+ try{
+ $redis->connect($config['host'], $config['port'],10);
+ }catch (\Exception $exception){
+ echo 'redis连接失败';
+ }
+ if(!empty($config['password'])){
+ $redis->auth($config['password']);
+ }
+
+ $redis->select($config['select']);
+ return $redis;
+ }
+ /**
+ * 生成随机订单号
+ * @param int $length
+ * @return false|string
+ */
+ public function generateOrderNumber(int $length=20) {
+ $prefix = date('ymd'); // 可选的订单号前缀,如需要可以在这里设置
+ $timestamp = time();
+ $randomNum = mt_rand(10000, 99999); // 使用 mt_rand() 生成一个四位的随机数
+ // 将时间戳和随机数组合起来作为订单号的一部分
+ $orderNumber = $prefix . $timestamp . $randomNum;
+ // 如果订单号的长度超过指定的长度,则截取前面指定长度的部分
+ if (strlen($orderNumber) > $length) {
+ $orderNumber = substr($orderNumber, 0, $length);
+ }
+ return $orderNumber;
+ }
+
+ public function getCapitalTypeList($type_arr = [])
+ {
+ $type_list = [
+ 1 => [
+ 'zh-cn' => '充值',
+ 'zh-zh' => '充值',
+ 'zh-us' => 'Deposit',
+ 'zh-cs' => 'Vklad',
+ 'zh-sp' => 'Recarga',
+ 'zh-eu' => 'Recarga',
+ 'zh-th' => 'เติมเงิน',
+ 'zh-in' => 'लबालब भरना',
+ 'zh-jp' => 'チャージ',
+ ],
+ 2 => [
+ 'zh-cn' => '提現',
+ 'zh-zh' => '提现',
+ 'zh-us' => 'Withdrawal',
+ 'zh-cs' => 'Výběr',
+ 'zh-sp' => 'Retiro',
+ 'zh-eu' => 'Retirada',
+ 'zh-th' => 'ถอน',
+ 'zh-in' => 'निकालना',
+ 'zh-jp' => '引き出し',
+ ],
+ 3 => [
+ 'zh-cn' => '買入',
+ 'zh-zh' => '买入',
+ 'zh-us' => 'Buy',
+ 'zh-cs' => 'Nákup',
+ 'zh-sp' => 'Compra',
+ 'zh-eu' => 'Compra',
+ 'zh-th' => 'ซื้อ',
+ 'zh-in' => 'खरीदना',
+ 'zh-jp' => '買い入れ',
+ ],
+ 4 => [
+ "zh-cn" => "賣出",
+ 'zh-zh' => '卖出',
+ 'zh-us' => 'Sell',
+ 'zh-cs' => 'Prodej',
+ 'zh-sp' => 'Venta',
+ 'zh-eu' => 'Venda',
+ 'zh-th' => 'ขาย',
+ 'zh-in' => 'बेचना',
+ 'zh-jp' => '売り出し',
+ ],
+ 5 => [
+ "zh-cn" => "凍結",
+ 'zh-zh' => '冻结',
+ 'zh-us' => 'Freeze',
+ 'zh-cs' => 'Zamknout',
+ 'zh-sp' => 'Congelar',
+ 'zh-eu' => 'Congelar',
+ 'zh-th' => 'แช่แข็ง',
+ 'zh-in' => 'जमाना',
+ 'zh-jp' => '凍結',
+ ],
+ 6 => [
+ "zh-cn" => "解冻",
+ 'zh-zh' => '解冻',
+ 'zh-us' => 'Unfreeze',
+ 'zh-cs' => 'Odemknout',
+ 'zh-sp' => 'Descongelar',
+ 'zh-eu' => 'Descongelar',
+ 'zh-th' => 'ละลาย',
+ 'zh-in' => 'पिघलना',
+ 'zh-jp' => '解凍',
+ ],
+ 7 => [
+ "zh-cn" => "帳戶轉出",
+ 'zh-zh' => '账户转出',
+ 'zh-us' => 'Transfer Out',
+ 'zh-cs' => 'Převod ven',
+ 'zh-sp' => 'Transferencia Saliente',
+ 'zh-eu' => 'Transferência para Fora',
+ 'zh-th' => 'บัญชีโอนออก',
+ 'zh-in' => 'खाता स्थानांतरण',
+ 'zh-jp' => '振り出し',
+ ],
+ 8 => [
+ "zh-cn" => "帳戶轉入",
+ 'zh-zh' => '账户转入',
+ 'zh-us' => 'Transfer In',
+ 'zh-cs' => 'Převod dovnitř',
+ 'zh-sp' => 'Transferencia Entrante',
+ 'zh-eu' => 'Transferência para Dentro',
+ 'zh-th' => 'การโอนบัญชี',
+ 'zh-in' => 'खाता स्थानांतरण',
+ 'zh-jp' => '振り込み',
+ ],
+ 9 => [
+ "zh-cn" => "註冊返佣",
+ 'zh-zh' => '注册返佣',
+ 'zh-us' => 'Registration Rebate',
+ 'zh-cs' => 'Registrační sleva',
+ 'zh-sp' => 'Reembolso de Registro',
+ 'zh-eu' => 'Reembolso de Registro',
+ 'zh-th' => 'ส่วนลดการลงทะเบียน',
+ 'zh-in' => 'पंजीकरण में छूट',
+ 'zh-jp' => '登録ボーナス',
+ ],
+ 10 => [
+ "zh-cn" => "開倉返佣",
+ 'zh-zh' => '开仓返佣',
+ 'zh-us' => 'Open Position Rebate',
+ 'zh-cs' => 'Sleva na otevřenou pozici',
+ 'zh-sp' => 'Reembolso de Apertura',
+ 'zh-eu' => 'Reembolso de Apertura',
+ 'zh-th' => 'ส่วนลดค่าคอมมิชชั่นสำหรับการเปิดตำแหน่ง',
+ 'zh-in' => 'पद खोलने के लिए कमीशन में छूट',
+ 'zh-jp' => '取引ボーナス',
+ ],
+ 11 => [
+ "zh-cn" => "平倉返佣",
+ 'zh-zh' => '平仓返佣',
+ 'zh-us' => 'Close Position Rebate',
+ 'zh-cs' => 'Sleva na uzavřenou pozici',
+ 'zh-sp' => 'Reembolso de Cierre',
+ 'zh-eu' => 'Reembolso de Fechamento',
+ 'zh-th' => 'ส่วนลดค่าคอมมิชชั่นสำหรับการปิดสถานะ',
+ 'zh-in' => 'समापन स्थिति के लिए कमीशन छूट',
+ 'zh-jp' => '決済ボーナス',
+ ],
+ 12 => [
+ "zh-cn" => "調賬加錢",
+ 'zh-zh' => '调账加钱',
+ 'zh-us' => 'Adjustment - Add Funds',
+ 'zh-cs' => 'Úprava - Přidat peníze',
+ 'zh-sp' => 'Ajuste - Agregar Fondos',
+ 'zh-eu' => 'Ajuste - Adicionar Fundos',
+ 'zh-th' => 'ปรับบัญชีและเพิ่มเงิน',
+ 'zh-in' => 'खाता समायोजित करें और पैसे जोड़ें',
+ 'zh-jp' => '調整入金',
+ ],
+ 13 => [
+ "zh-cn" => "調賬減錢",
+ 'zh-zh' => '调账减钱',
+ 'zh-us' => 'Adjustment - Decrease Funds',
+ 'zh-cs' => 'Úprava - Odečíst peníze',
+ 'zh-sp' => 'Ajuste - Restar Fondos',
+ 'zh-eu' => 'Ajuste - Deduzir Fundos',
+ 'zh-th' => 'ปรับบัญชีและลดเงิน',
+ 'zh-in' => 'खाता समायोजित करें और पैसे कम करें',
+ 'zh-jp' => '調整出金',
+ ],
+ 14 => [
+ "zh-cn" => "扣手续费",
+ "zh-zh" => "扣手续费",
+ 'zh-us' => 'Deduct Commission',
+ 'zh-cs' => 'Odečíst provizi',
+ 'zh-sp' => 'Deducir Comisión',
+ 'zh-eu' => 'Deduzir Comissão',
+ 'zh-th' => 'การหักค่าธรรมเนียมการจัดการ',
+ 'zh-in' => 'कटौती प्रक्रियाएँ',
+ 'zh-jp' => '手数料を差し引く',
+ ],
+ 15 => [
+ "zh-cn" => "申购扣费",
+ "zh-zh" => "申購扣費",
+ 'zh-us' => 'Subscription deduction fee',
+ 'zh-cs' => 'Poplatek za předplatbu',
+ 'zh-sp' => 'Tarifa de deducción de suscripción',
+ 'zh-eu' => 'Taxa de dedução de subscrição',
+ 'zh-th' => 'การหักค่าสมัครสมาชิก',
+ 'zh-in' => 'सदस्यता कटौती',
+ 'zh-jp' => '申し込み手数料を差し引く',
+ ],
+ 16 => [
+ "zh-cn" => "申购手续费",
+ "zh-zh" => "申購手續費",
+ 'zh-us' => 'Subscription handling fee',
+ 'zh-cs' => 'Poplatek za zpracování předplatby',
+ 'zh-sp' => 'Tarifa de gestión de suscripción',
+ 'zh-eu' => 'Taxa de processamento de subscrição',
+ 'zh-th' => 'การหักค่าสมัครสมาชิก',
+ 'zh-in' => 'सदस्यता प्रबंधन शुल्क',
+ 'zh-jp' => '申込手数料',
+ ],
+ 17 => [
+ "zh-cn" => "申购退费",
+ "zh-zh" => "申購退費",
+ 'zh-us' => 'Refund of subscription',
+ 'zh-cs' => 'Vrácení předplatby',
+ 'zh-sp' => 'Reembolso de la suscripción',
+ 'zh-eu' => 'Reembolso da subscrição',
+ 'zh-th' => 'การคืนเงินค่าสมัครสมาชิก',
+ 'zh-in' => 'सदस्यता वापसी',
+ 'zh-jp' => '申し込み返金',
+ ],
+ 18 => [
+ "zh-cn" => "申购退手续费",
+ "zh-zh" => "申購退手續費",
+ 'zh-us' => 'Refund of subscription handling fee',
+ 'zh-cs' => 'Vrácení poplatku za zpracování předplatby',
+ 'zh-sp' => 'Reembolso de la tarifa de gestión de suscripción',
+ 'zh-eu' => 'Reembolso da taxa de processamento de subscrição',
+ 'zh-th' => 'ค่าธรรมเนียมการดำเนินการคืนเงินการสมัครสมาชิก',
+ 'zh-in' => 'सदस्यता वापसी प्रबंधन शुल्क',
+ 'zh-jp' => '申し込み手数料の返金',
+ ],
+ 19 => [
+ "zh-cn" => "基金返利",
+ "zh-zh" => "基金返利",
+ 'zh-us' => 'Fund rebates',
+ 'zh-cs' => 'Slevy z fondu',
+ 'zh-sp' => 'Deducción de fondos',
+ 'zh-eu' => 'Descontos de fundos',
+ 'zh-th' => 'เงินคืน',
+ 'zh-in' => 'फोन्ड फिनु बेट',
+ 'zh-jp' => 'ファンドリベート',
+ ],
+ ];
+
+ if (empty($type_arr)) {
+ return $type_list;
+ } else {
+ $result = [];
+ foreach ($type_arr as $v) {
+ $result[$v] = $type_list[$v];
+ }
+ return $result;
+ }
+ }
+
+
+}
\ No newline at end of file
diff --git a/app/home/service/BlockStockService.php b/app/home/service/BlockStockService.php
new file mode 100644
index 0000000..ae29ebe
--- /dev/null
+++ b/app/home/service/BlockStockService.php
@@ -0,0 +1,70 @@
+toData('1', 'Params error');
+ }
+
+ $list = StockBlockListModel::where('type', $param['type'])->page($param['page'], $param['limit'])->select();
+ $total = StockBlockListModel::where('type', $param['type'])->count();
+
+ $redisKeyArr = [3 => 'US', 4 => 'Indonesia', 5 => 'Malaysia', 6 => 'Thailand', 7 => 'India', 9 => 'Singapore', 12 => 'HongKong'];
+ $redis = $this->getRedis();
+
+ foreach ($list as &$v) {
+ $key = "Stock:" . $redisKeyArr[$v->type];
+ $v->current_price = $redis->hget($key . ":ClosePrice", $v->stock_code) ?? $redis->hget($key . ":CloseNewPrice", $v->stock_code);
+ }
+ return $this->toData('0', 'SUCCESS', ['list' => $list, 'total' => $total,]);
+ } catch (\Exception $exception) {
+ return $this->toData('0', 'The system is busy. Please try again later.', [$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'] = 10;
+ }
+
+ $where[] = ['user_id', '=', $userId];
+ // stock_type 3 美股 4 印尼 5 马股 6 泰股 9 新加坡股票
+ if (!empty($param['type']) && ($param['type'] >2 && $param['type']< 19)) {
+ $where[] = [
+ 'type', '=', $param['type']
+ ];
+ }
+
+ $list = UserStockBlockOrderModel::where($where)->page($param['page'], $param['limit'])->select();
+ $total = StockBlockListModel::where($where)->count();
+
+ return $this->toData('0', 'SUCCESS', ['list' => $list, 'total' => $total,]);
+ } catch (\Exception $exception) {
+ return $this->toData('0', 'The system is busy. Please try again later.', [$exception->getMessage()]);
+ }
+ }
+
+
+}
\ No newline at end of file
diff --git a/app/home/service/CarouselService.php b/app/home/service/CarouselService.php
new file mode 100644
index 0000000..c89694d
--- /dev/null
+++ b/app/home/service/CarouselService.php
@@ -0,0 +1,42 @@
+toData(
+ '0',
+ 'Request successful.',
+ [
+ [
+ 'title' => '测试数据',
+ 'content' => '这是斜体1
这是加粗
这是娃哈哈
这是斜体
这是加粗
这是娃哈哈
',
+ 'img_url' => '/logo/1.png',
+ 'redirect_url' => '',
+ 'type'=> '1'
+ ],
+ [
+ 'title' => '测试数据2',
+ 'content' => '这是斜体2
这是加粗
这是娃哈哈
这是斜体
这是加粗
这是娃哈哈
',
+ 'img_url' => '/logo/2.png',
+ 'redirect_url' => '',
+ 'type'=> '1'
+ ],
+ ]
+ );
+ }catch (\Exception $exception){
+ return $this->toData(
+ '1',
+ 'Request failed.',
+ []
+ );
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/home/service/ClickPayService.php b/app/home/service/ClickPayService.php
new file mode 100644
index 0000000..a1680b0
--- /dev/null
+++ b/app/home/service/ClickPayService.php
@@ -0,0 +1,314 @@
+merchant; //商户在平台开通的商户号 string(32)
+ $post_data['method'] = 'UPI'; //付款方式 string(10)
+ $post_data['orderNum'] = $orderId; //商户系统唯一订单号 string(32)
+ $post_data['payMoney'] = floor($amount); //订单付款金额 double(15,2)
+ $post_data['productDetail'] = $orderId; //产品描述 string(32)
+ $post_data['name'] = 'Neo'; //银行付款确认页面上显示的名称 string(32)
+ $post_data['email'] = 'neo@gmial.com'; //客户的电子邮件地址 string(64)
+ $post_data['currency'] = 'INR'; //货币 string(64)
+ $post_data['notifyUrl'] = $this->notify_url; //异步通知地址 string(100)
+ $post_data['redirectUrl'] = 'https://abglobalfund.com/topUp'; //同步重定向地址 string(100)
+ $post_data['phone'] = '082112345678'; //客户的手机号码 string(16)
+ $post_data['expiryPeriod'] = 10; //订单到期时间(分钟) int(5)
+ $post_data['dateTime'] = date("YmdHis", time());; //日期和时间 (yyyyMMddHHmmss) string(14)
+ ksort($post_data);
+
+ Log::info('clickPay post-: ' . json_encode($post_data));
+
+ $params_str = '';
+ foreach ($post_data as $postVal) {
+ $params_str = $params_str . $postVal;
+ }
+ $sign = $this->pivate_key_encrypt($params_str, $this->pr_key);
+ $post_data['sign'] = $sign;
+ $header = array("Content-Type:application/json");
+ $res = json_decode($this->curlPost($this->payable_url, $post_data, 10, $header, 'json'), true);
+
+ Log::info('clickPay notify-: ' . json_encode($res));
+ if (!empty($res['status'])) {
+ $res['platRespMessage'] = '11';
+ $res['platRespCode'] = 'error';
+ return $res;
+ }
+ if (!empty($res['platSign'])) unset($res['platSign']);
+ // $platSign = $res['platSign'];
+// $decryptSign = $this->public_key_decrypt($platSign, $this->de_pu_key);
+// $params = $res;
+// ksort($params);
+// $params_str = '';
+// foreach ($params as $resVal) {
+// $params_str .= $resVal;
+// }
+// if ($params_str == $decryptSign && !empty($res['payData'])) {
+ return $res;
+// } else {
+// $res['platRespMessage'] = '11';
+// $res['platRespCode'] = 'error';
+// return $res;
+// }
+ }
+
+ // 代收 异步回调处理
+ public function clickPayNotify($data)
+ {
+ $platSign = $data['platSign'];
+ unset($data['platSign']);
+
+ $sign = $this->public_key_decrypt($platSign, $this->de_pu_key);
+ $params = $data;
+ ksort($params);
+ $params_str = '';
+ foreach ($params as $val) {
+ $params_str .= $val;
+ }
+ if ($params_str == $sign) {
+ // Check if payment was successful
+ if ($data['code'] == '00' && $data['msg'] == 'SUCCESS') {
+ $order_info = RechargeApplyModel::getOrderByNo([
+ 'order_no' => $data['orderNum']
+ ]);
+ if ($order_info && $data['payMoney'] == $order_info['total_amount']) {
+ if ($order_info['status'] == 0) {
+ $res = (new PayService())->dealPayNotify($order_info);
+ if ($res['code'] == 200) {
+ Log::info('clickpay代收 成功111:' . json_encode($data));
+ return 'SUCCESS';
+ }
+ }
+ }
+ Log::info('clickpay代收 成功222:' . json_encode($data));
+ return 'SUCCESS';
+ } else {
+ Log::info('clickpay代收 失败111:' . json_encode($data));
+ return 'FAIL';
+ }
+ } else {
+ Log::info('clickpay代收 失败222:' . json_encode($data));
+ return 'FAIL';
+ }
+ }
+
+ // 代付
+ public function apply_pay($orderId, $amount, $bank_account, $nike_name, $ifsc, $bank_code)
+ {
+ $post_data['merchantCode'] = $this->merchant; //商户在平台开通的商户号 string(32)
+ $post_data['orderNum'] = $orderId; //商户系统唯一订单号 string(32)
+ $post_data['money'] = floor($amount); //转账金额 double(15,2)
+ $post_data['feeType'] = '0'; //费用类型(0-从转账金额中扣除,1-从商户余额中扣除) string(10)
+ $post_data['dateTime'] = date("YmdHis", time());; //日期和时间 (yyyyMMddHHmmss) string(14)
+ $post_data['name'] = ' MUHAMAD JUMAEDI'; //持卡人姓名 string(32)
+ $post_data['number'] = $bank_account; //帐号或 UPI 号码 string(32)
+ $post_data['bankLinked'] = $ifsc; //联合服务中心 string(32)
+ $post_data['bankCode'] = 'IFSC'; //联合服务中心 string(32)
+ $post_data['bankName'] = $nike_name; //银行名 string(32)
+ $post_data['accountEmail'] = 'test@test.com'; //帐户的电子邮件 string(64)
+ $post_data['accountMobile'] = '082112345678'; //帐号手机号码 string(16)
+ $post_data['description'] = 'INR'; //转让说明 string(100)
+ $post_data['currency'] = 'INR'; //货币 string(64)
+ $post_data['notifyUrl'] = $this->notify_apply_url; //异步通知地址 string(100)
+ ksort($post_data);
+
+ Log::info('clickPay-daifu- post-: ' . json_encode($post_data));
+ $params_str = '';
+ foreach ($post_data as $postVal) {
+ $params_str = $params_str . $postVal;
+ }
+ $sign = $this->pivate_key_encrypt($params_str, $this->pr_key);
+ $post_data['sign'] = $sign;
+ $header = array("Content-Type:application/json");
+ $res = json_decode($this->curlPost($this->pay_url, $post_data, 10, $header, 'json'), true);
+ Log::info('clickPay-daifu notify-: ' . json_encode($res));
+
+ if (!empty($res['platSign'])) unset($res['platSign']);
+
+ if (strtoupper($res['platRespCode']) == 'SUCCESS') {
+ return [
+ 'code' => 200,
+ 'msg' => 'ok',
+ 'order_idx' => $res['orderNum'],
+ 'content' => $res
+ ];
+ } else {
+ return [
+ 'code' => 300,
+ 'msg' => $res['platRespMessage'],
+ 'order_idx' => '',
+ 'content' => $res
+ ];
+ }
+
+
+ }
+
+ public function clickPayApplyNotify($data)
+ {
+ $platSign = $data['platSign'];
+ unset($data['platSign']);
+
+ $sign = $this->public_key_decrypt($platSign, $this->de_pu_key);
+ $params = $data;
+ ksort($params);
+ $params_str = '';
+ foreach ($params as $val) {
+ $params_str .= $val;
+ }
+ if ($params_str == $sign) {
+ // Check if payment was successful
+ if ($data['code'] == '00' && $data['msg'] == 'SUCCESS') {
+ $order_info = UserWithdrawalModel::getUserDrawalInfo([
+ 'order_no' => $data['orderNum']
+ ]);
+ if ($order_info && $order_info['status'] == 3) {
+ UserWithdrawalModel::where([
+ 'id' => $order_info['id']
+ ])->update([
+ 'status' => 4,
+ 'deal_time' => date('Y-m-d H:i:s')
+ ]);
+ Log::info('clickpay代付 成功111:' . json_encode($data));
+ return 'SUCCESS';
+ }
+ Log::info('clickpay代付 成功222:' . json_encode($data));
+ return 'SUCCESS';
+ } else {
+ Log::info('clickpay代付 失败111:' . json_encode($data));
+ return 'FAIL';
+ }
+ } else {
+ Log::info('clickpay代付 失败222:' . json_encode($data));
+ return 'FAIL';
+ }
+ }
+
+ public function getBalance()
+ {
+ $post_data['merchantCode'] = $this->merchant;
+ $post_data['dateTime'] = date("YmdHis", time());; //日期和时间 (yyyyMMddHHmmss) string(14)
+ ksort($post_data);
+ Log::info('clickPay-getBalance-post-: ' . json_encode($post_data));
+
+ $params_str = '';
+ foreach ($post_data as $val) {
+ $params_str .= $val;
+ }
+
+ $sign = $this->pivate_key_encrypt($params_str, $this->pr_key);
+ $post_data['sign'] = $sign;
+ $header = array("Content-Type:application/json");
+ $res = json_decode($this->curlPost($this->get_account, $post_data, 10, $header, 'json'), true);
+ Log::info('clickPay-getBalance-res-: ' . json_encode($res));
+ if (strtoupper($res['platRespCode']) == 'SUCCESS') {
+ return [
+ 'amount' => $res['balance']
+ ];
+ } else {
+ return [
+ 'amount' => 0
+ ];
+ }
+ }
+
+ private function curlPost($url, $post_data = array(), $timeout = 5, $header = "", $data_type = "")
+ {
+ $header = empty($header) ? '' : $header;
+ //支持json数据数据提交
+ if ($data_type == 'json') {
+ $post_string = json_encode($post_data);
+ } elseif ($data_type == 'array') {
+ $post_string = $post_data;
+ } elseif (is_array($post_data)) {
+ $post_string = http_build_query($post_data, '', '&');
+ }
+
+ $ch = curl_init(); // 启动一个CURL会话
+ curl_setopt($ch, CURLOPT_URL, $url); // 要访问的地址
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 对认证证书来源的检查 // https请求 不验证证书和hosts
+ curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); // 从证书中检查SSL加密算法是否存在
+ curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']); // 模拟用户使用的浏览器
+ //curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1); // 使用自动跳转
+ //curl_setopt($curl, CURLOPT_AUTOREFERER, 1); // 自动设置Referer
+ curl_setopt($ch, CURLOPT_POST, true); // 发送一个常规的Post请求
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $post_string); // Post提交的数据包
+ curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout); // 设置超时限制防止死循环
+ curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
+ //curl_setopt($curl, CURLOPT_HEADER, 0); // 显示返回的Header区域内容
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // 获取的信息以文件流的形式返回
+ curl_setopt($ch, CURLOPT_HTTPHEADER, $header); //模拟的header头
+ $result = curl_exec($ch);
+ curl_close($ch);
+ return $result;
+ }
+
+ private function pivate_key_encrypt($data, $key)
+ {
+ $pivate_key = '-----BEGIN PRIVATE KEY-----' . "\n" . $key . "\n" . '-----END PRIVATE KEY-----';
+ $pi_key = openssl_pkey_get_private($pivate_key);
+ $crypto = '';
+ foreach (str_split($data, 117) as $chunk) {
+ openssl_private_encrypt($chunk, $encryptData, $pi_key);
+ $crypto .= $encryptData;
+ }
+
+ return base64_encode($crypto);
+ }
+
+ private function public_key_decrypt($data, $key)
+ {
+ $public_key = '-----BEGIN PUBLIC KEY-----' . "\n" . $key . "\n" . '-----END PUBLIC KEY-----';
+ $data = base64_decode($data);
+ $pu_key = openssl_pkey_get_public($public_key);
+ $crypto = '';
+ foreach (str_split($data, 128) as $chunk) {
+ openssl_public_decrypt($chunk, $decryptData, $pu_key);
+ $crypto .= $decryptData;
+ }
+
+ return $crypto;
+ }
+
+
+}
\ No newline at end of file
diff --git a/app/home/service/FundService.php b/app/home/service/FundService.php
new file mode 100644
index 0000000..6cd1215
--- /dev/null
+++ b/app/home/service/FundService.php
@@ -0,0 +1,353 @@
+field('id,stock_code,min_price,stock_type,stock_name,tag,cycle,rate,stock_info,open_status')->append(['stock_type_text', 'open_status_text', 'stock_type_en_text', 'open_status_en_text'])->orderRaw($orderString)->order('sort', 'asc')->page($param['page'], $param['limit'])->select();
+ $total = PreFundStockModel::where($where)->count();
+
+ return $this->toData('0', 'SUCCESS', ['list' => $rows, 'total' => $total]);
+ } catch (\Exception $exception) {
+ return $this->toData('400', 'System error', [$exception->getMessage()]);
+ }
+ }
+
+ // 基金详情
+ public function detail($param): array
+ {
+ try {
+ if (empty($param['id']) || !is_numeric($param['id'])) {
+ return $this->toData('1', 'Params error', []);
+ }
+
+ $fund = PreFundStockModel::where('id', $param['id'])->where('is_delete', PreFundStockModel::IS_DELETE_NO)->find();
+ if (empty($fund)) {
+ return $this->toData('1', 'Params error', []);
+ }
+ $fund->product_file = json_decode($fund->product_file, true);
+ $fund->current_manager = json_decode($fund->current_manager, true);
+
+ return $this->toData('0', 'SUCCESS', ['data' => $fund, 'interest' => $fund->show_interest]);
+ } catch (\Exception $exception) {
+ return $this->toData('400', 'System error', [$exception->getMessage()]);
+ }
+ }
+
+ // 基金历史走势
+ public function history(array $param): array
+ {
+ try {
+ if (empty($param['stock_code']) || !is_string($param['stock_code'])) {
+ return $this->toData('1', 'Params error', []);
+ }
+
+ if (empty($param['type']) || !in_array($param['type'], [1, 2, 3])) {
+ $param['type'] = 1;
+ }
+
+ $historyData = HistoryFundStockModel::where('stock_code', $param['stock_code'])->find();
+ if (empty($historyData)) {
+ return $this->toData('1', 'Params error', []);
+ }
+
+ $history = [];
+ $historyInfo = json_decode($historyData->history_info, true);
+ $start = new DateTime($historyData->start_date);
+ $end = new DateTime($historyData->end_date);
+ switch ($param['type']) {
+ case 1: //日
+ $history = $historyInfo;
+ break;
+ case 2: //月
+ // 创建 DateInterval 对象,表示一个月的时间间隔
+ $interval = new DateInterval('P1M');
+ // 创建 DatePeriod 对象,表示两个日期之间的月份
+ $period = new DatePeriod($start, $interval, $end);
+ foreach ($period as $date) {
+ $month = $date->format('Y-m');
+ $firstDay = new DateTime("$month-01");
+ $nextMonth = clone $firstDay;
+ $nextMonth->modify('+1 month');
+ $lastDay = $nextMonth->modify('-1 day');
+ $monthlastDay = $lastDay->format('Y-m-d');
+ if ($lastDay > $end) {
+ $monthlastDay = $end->format('Y-m-d');
+ }
+ $history[$month] = $historyInfo[$monthlastDay];
+ }
+ break;
+ case 3: //年
+ $currentDate = clone $start;
+ $startYear = $currentDate->format('Y');
+ $currentYear = new DateTime("$startYear-01-01");
+ while ($currentYear <= $end) {
+ $lastDayOfYear = new DateTime($currentYear->format('Y') . "-12-31");
+ $lastDayOfYearStr = $lastDayOfYear->format('Y-m-d');
+ if ($lastDayOfYear > $end) {
+ $lastDayOfYearStr = $end->format('Y-m-d');
+ }
+ $history[$currentYear->format('Y')] = $historyInfo[$lastDayOfYearStr];
+ $currentYear->modify('+1 year');
+ }
+ break;
+ }
+ $year = [];
+ if ($param['type'] == 3) {
+ $year = $history;
+ } else {
+ $currentDate = clone $start;
+ $startYear = $currentDate->format('Y');
+ $currentYear = new DateTime("$startYear-01-01");
+ while ($currentYear <= $end) {
+ $lastDayOfYear = new DateTime($currentYear->format('Y') . "-12-31");
+ $lastDayOfYearStr = $lastDayOfYear->format('Y-m-d');
+ if ($lastDayOfYear > $end) {
+ $lastDayOfYearStr = $end->format('Y-m-d');
+ }
+ $year[$currentYear->format('Y')] = $historyInfo[$lastDayOfYearStr];
+ $currentYear->modify('+1 year');
+ }
+ }
+ $refer = PreFundStockReferModel::select();
+ $referResult = [];
+ foreach ($refer as $v) {
+ $referResult[$v['name']][$v['year']] = $v['rate'];
+ }
+
+ return $this->toData('0', 'SUCCESS', ['data' => $history, 'year' => $year, 'refer' => $referResult]);
+ } catch (\Exception $exception) {
+ return $this->toData('400', 'System error', [$exception->getMessage()]);
+ }
+ }
+
+ // 下单
+ public function order($param, $userId)
+ {
+ try {
+ // 需要完成实名认证之后才能下单
+ $user = UserModel::where('user_id', $userId)->find();
+ if (empty($user) || $user->is_real != 1) {
+ return $this->toData('405', 'Only after completing real-name authentication can you place an order.');
+ }
+
+ if (empty($userId)) {
+ return $this->toData('1', 'Login fail');
+ }
+
+ if (empty($param['id']) || !is_numeric($param['id'])) {
+ return $this->toData('1', 'Params error2', []);
+ }
+
+ $fund = PreFundStockModel::where('id', $param['id'])
+ ->where('open_status', PreFundStockModel::OPEN_STATUS_HAD)
+ ->where('is_delete', PreFundStockModel::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($fund)) {
+ return $this->toData('1', 'Params error3', []);
+ }
+
+ // 下单参数
+ if (empty($param['amount']) || !is_numeric($param['amount']) || ceil($param['amount']) != $param['amount'] || $param['amount'] <= 0) {
+ return $this->toData('1', 'Params error', []);
+ }
+
+ if ($param['amount'] < $fund->min_price) {
+ return $this->toData('1', 'Params num error4', []);
+ }
+
+ $amount = $param['amount'];
+ // 计算手续费
+ $purchaseFee = FeeSettingModel::where('market_type', StockMarketModel::STOCK_MARKET_FUND)->value('purchase_fee');
+ if (empty($purchaseFee)) {
+ $purchaseFee = 0;
+ $fee = 0;
+ } else {
+ $purchaseFee = number_format($purchaseFee, 18, '.', '');
+ $fee = bcmul($amount, $purchaseFee, 18);
+ }
+
+ Db::startTrans();
+
+ // 生成订单
+ $orderNo = $this->generateOrderNumber(20);
+ $order = new UserFundPreStockOrderModel;
+ $order->user_id = $userId;
+ $order->pre_stock_id = $fund->id;
+ $order->status = UserFundPreStockOrderModel::STATUS_ONE;
+ $order->order_no = $orderNo;
+ $order->amount = $amount;
+ $order->phase_count = $fund->phase_count;
+ $order->stock_rate = $fund->rate;
+ $order->stock_cycle_type = $fund->cycle_type;
+ $order->stock_cycle = $fund->cycle;
+ $order->fee = $fee;
+ $order->fee_rate = $purchaseFee; // 手续费比率
+ $bool = $order->save();
+ if (!$bool) {
+ Db::rollback();
+ return $this->toData('1', 'create fund order error', []);
+ }
+
+ // 扣除用户资产
+ $userStockName = (new UserStockFundModel())->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)
+ ->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 UserStockFundLogModel();
+ $userStockLog->user_id = $userId;
+ $userStockLog->change_type = 3;
+ $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 UserStockFundLogModel;
+ $userStockLog->user_id = $userId;
+ $userStockLog->change_type = 14; //扣手续费
+ $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', []);
+ }
+ }
+
+ // 生成基金返款记录
+ $userStockFundInterestReceipt = new UserStockFundInterestReceiptModel;
+ $userStockFundInterestReceipt->user_id = $userId;
+ $userStockFundInterestReceipt->order_id = $order->id;
+ $userStockFundInterestReceipt->pre_stock_id = $fund->id;
+ $userStockFundInterestReceipt->order_no = $this->generateOrderNumber(20);
+ $userStockFundInterestReceipt->capital = $amount;
+ $userStockFundInterestReceipt->interest = bcmul($amount, $fund->rate / 100, 18);
+ $userStockFundInterestReceipt->phase_time = 1;
+ $userStockFundInterestReceipt->unit = 'USD';
+ $currentDate = new DateTime();
+ $addDay = $fund->cycle + 1;
+ $currentDate->modify("+$addDay days");
+ $userStockFundInterestReceipt->return_date = $currentDate->format('Y-m-d');
+ $userStockFundInterestReceiptBool = $userStockFundInterestReceipt->save();
+ if (!$userStockFundInterestReceiptBool) {
+ Db::rollback();
+ return $this->toData('1', 'update fund interest error', []);
+ }
+
+ //更新基金 已购买金额
+ $fundHadNum = PreFundStockModel::where('id', $fund->id)->inc('had_get_price', $amount)->update(['update_time' => date('Y-m-d H:i:s')]);
+ if ($fundHadNum <= 0) {
+ Db::rollback();
+ return $this->toData('1', 'Update fund had_get_price error', []);
+ }
+
+ Db::commit();
+ return $this->toData('0', 'SUCCESS', []);
+
+ } catch (\Exception $exception) {
+ return $this->toData('0', 'The system is busy. Please try again later.', [$exception->getMessage()]);
+ }
+ }
+
+ public function userFund($param, $userId)
+ {
+ try {
+ if (empty($param['page']) || !is_numeric($param['page']) || empty($param['limit']) || !is_numeric($param['limit'])) {
+ $param['page'] = 1;
+ $param['limit'] = 10;
+ }
+ $oderTableName = (new UserFundPreStockOrderModel())->getName();
+ $oderTableName = 'bot_' . $oderTableName;
+
+ $total = UserFundPreStockOrderModel::where("user_id", $userId)->count();
+ $rows = UserFundPreStockOrderModel::where($oderTableName . ".user_id", $userId)->with('interest_arr')->withJoin(['fund' => ['stock_name', 'cycle', 'rate', 'stock_info', 'stock_type']])->append(['status_en_text'])->order('status', 'asc')->order('id', 'desc')->page($param['page'], $param['limit'])->select()->toArray();
+ foreach ($rows as &$v) {
+ $capitalArr = array_column($v['interest_arr'], 'capital');
+ $interestArr = array_column($v['interest_arr'], 'interest');
+ $v['capital'] = array_sum($capitalArr);
+ $v['interest'] = array_sum($interestArr);
+ $v['fund']['stock_type_en_text'] = PreFundStockModel::$stockTypeEnList[$v['fund']['stock_type']];
+ }
+ return $this->toData('0', 'SUCCESS', ['list' => $rows, 'total' => $total]);
+ } catch (\Exception $exception) {
+ return $this->toData('400', 'System error', [$exception->getMessage()]);
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/home/service/HTPayService.php b/app/home/service/HTPayService.php
new file mode 100644
index 0000000..99c8c71
--- /dev/null
+++ b/app/home/service/HTPayService.php
@@ -0,0 +1,229 @@
+getPayConfig($key);
+ $this->mch_id=$config['mch_id'];
+ $this->sign_key=$config['sign_key'];
+ }
+ public function qrNotify($data)
+ {
+ Log::info('收到合泰异步回调:'.json_encode($data));
+ $sign=$this->generateQueryString($data,$this->sign_key);
+ if($sign==strtoupper($data['sign'])){
+ if($data['tradeResult']==1){
+ $order_info=RechargeApplyModel::getOrderByNo([
+ 'order_no'=>$data['mchOrderNo']
+ ]);
+ if($order_info && $data['amount']==$order_info['total_amount']){
+ if($order_info['status']==0){
+ return (new PayService())->dealPayNotify($order_info);
+ }
+ }else{
+ Log::info('合泰支付订单不存在:'.json_encode($data));
+ }
+ }else{
+ Log::info('合泰支付订单支付失败:'.json_encode($data));
+ }
+ }else{
+ Log::info('合泰签名校验失败:'.json_encode($data));
+ }
+ }
+ //代付通知
+ public function arNotify($data){
+ Log::info('收到合泰代付异步回调:'.json_encode($data));
+ $sign=$this->generateQueryString($data,$this->sign_key);
+ if($sign==strtoupper($data['sign'])){
+ if($data['tradeResult']==1){
+ $order_info=UserWithdrawalModel::getUserDrawalInfo([
+ 'order_no'=>$data['mchOrderNo']
+ ]);
+ if($order_info && $order_info['status']==3){
+ UserWithdrawalModel::where([
+ 'id'=>$order_info['id']
+ ])->update([
+ 'status'=>4,
+ 'deal_time'=>date('Y-m-d H:i:s')
+ ]);
+ Log::info('合泰代付支付成功:'.json_encode($data));
+ }else{
+ Log::info('合泰代付订单不存在:'.json_encode($data));
+ }
+ }else{
+ UserWithdrawalModel::where([
+ 'order_no'=>$data['mchOrderNo']
+ ])->update([
+ 'status'=>1,
+ ]);
+ Log::info('合泰代付失败:'.json_encode($data));
+ }
+ }else{
+ Log::info('合泰代付签名校验失败:'.json_encode($data));
+ }
+
+ }
+ public function qrPay($order_no,$order_amount){
+ $notify_url=env('PAY.NOTIFY_URL');
+ $data['version']='3.0';
+ $data['mch_id']=$this->mch_id;
+ $data['notify_url']=$notify_url.url('htpay_notify');
+ $data['mch_order_no']=$order_no;
+ $data['trade_amount']=$order_amount;
+ $data['order_date']=date('Y-m-d H:i:s');
+ $data['point']=2;
+ $data['pay_css']=rand(1,2);
+ $data['mch_return_msg']=$order_amount;
+ $data['sign_type']='md5';
+ $data['sign']=$this->generateQueryString($data,$this->sign_key);
+ $header = array("Content-Type:application/x-www-form-urlencoded");
+ $http_url="https://api.hetaivip.com/pay/qr";
+ $res=$this->curlPost($http_url,$data,10,$header);
+ $result=json_decode($res,true);
+ return $result;
+ }
+ //代付
+ public function arPay($order_no,$order_amount,$bank_code,$bank_account,$nike_name){
+ $notify_url=env('PAY.NOTIFY_URL');
+ $data['sign_type']='md5';
+ $data['mch_id']=$this->mch_id;
+ $data['back_url']=$notify_url.url('arpay_notify');
+ $data['resultid']=$order_no;
+ $data['money']=$order_amount;
+ $data['apply_date']=date('Y-m-d H:i:s');
+ $data['nikename']=$nike_name;
+ $data['banktype']=$bank_code;
+ $data['account']=$bank_account;
+ $data['sign']=$this->generateQueryString($data,$this->sign_key);
+ $header = array("Content-Type:application/x-www-form-urlencoded");
+ $http_url="https://api.hetaivip.com/pay/ar";
+ $res=$this->curlPost($http_url,$data,10,$header);
+ $result=json_decode($res,true);
+ if($result['status']==1){
+ return [
+ 'code'=>200,
+ 'msg'=>'ok',
+ 'order_idx'=>$result['orderNo'],
+ 'content'=>$res
+ ];
+ }else{
+ return [
+ 'code'=>300,
+ 'msg'=>$result['message'],
+ 'order_idx'=>'',
+ 'content'=>$res
+ ];
+ }
+ }
+ public function getHtBalance(){
+ $data['sign_type']='md5';
+ $data['mch_id']=$this->mch_id;
+ $data['sign']=$this->generateQueryString($data,$this->sign_key);
+ $header = array("Content-Type:application/x-www-form-urlencoded");
+ $http_url="https://api.hetaivip.com/query/balance";
+ $res=$this->curlPost($http_url,$data,10,$header);
+ $result=json_decode($res,true);
+ if($result['status']==1){
+ return [
+ 'amount'=>$result['availableAmount']
+ ];
+ }else{
+ return [
+ 'amount'=>0
+ ];
+ }
+ }
+
+ /**
+ * 传入数组进行HTTP POST请求
+ */
+ public function curlPost($url, $post_data = array(), $timeout = 5, $header = "", $data_type = "") {
+ $header = empty($header) ? '' : $header;
+ //支持json数据数据提交
+ if($data_type == 'json'){
+ $post_string = json_encode($post_data);
+ }elseif($data_type == 'array') {
+ $post_string = $post_data;
+ }elseif(is_array($post_data)){
+ $post_string = http_build_query($post_data, '', '&');
+ }
+
+ $ch = curl_init(); // 启动一个CURL会话
+ curl_setopt($ch, CURLOPT_URL, $url); // 要访问的地址
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 对认证证书来源的检查 // https请求 不验证证书和hosts
+ curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); // 从证书中检查SSL加密算法是否存在
+ curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']); // 模拟用户使用的浏览器
+ //curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1); // 使用自动跳转
+ //curl_setopt($curl, CURLOPT_AUTOREFERER, 1); // 自动设置Referer
+ curl_setopt($ch, CURLOPT_POST, true); // 发送一个常规的Post请求
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $post_string); // Post提交的数据包
+ curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout); // 设置超时限制防止死循环
+ curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
+ //curl_setopt($curl, CURLOPT_HEADER, 0); // 显示返回的Header区域内容
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // 获取的信息以文件流的形式返回
+ curl_setopt($ch, CURLOPT_HTTPHEADER, $header); //模拟的header头
+ $result = curl_exec($ch);
+ curl_close($ch);
+ return $result;
+ }
+ private function generateQueryString($fields, $privateKey) {
+ // 按ASCII顺序对字段名进行自然排序
+ ksort($fields);
+
+ // 将字段按 k=v 格式拼接成字符串
+ $query = '';
+ foreach($fields as $key => $value) {
+ if($key!='sign'){
+ $query .= $key . '=' . $value . '&';
+ }
+ }
+ // 去除末尾的 '&'
+ $query = rtrim($query, '&');
+ // 在字符串末尾拼接私钥
+ $query .= '&key=' . $privateKey;
+ $sign=strtoupper(md5($query));
+ return $sign;
+ }
+
+ private function getPayConfig($key)
+ {
+ $config=[
+ 'test'=>[
+ 'mch_id'=>'79385824',
+ 'sign_key'=>'3c3c71a4722e04d31e9e938dd0a927d0',
+ ],
+ 'stock'=>[
+ 'mch_id'=>'79385824',
+ 'sign_key'=>'3c3c71a4722e04d31e9e938dd0a927d0',
+ ],
+
+ ];
+ return $config[$key];
+ }
+
+
+
+}
\ No newline at end of file
diff --git a/app/home/service/IPOService.php b/app/home/service/IPOService.php
new file mode 100644
index 0000000..c72caf6
--- /dev/null
+++ b/app/home/service/IPOService.php
@@ -0,0 +1,870 @@
+getStockModel($marketType);
+ $nowDate = date('Y-m-d H:i:s');
+
+ $where = [];
+ $where[] = ['is_delete', '=', 1];
+ $where[] = ['status', '=', 1];
+
+ $query = Db::table($tableObj['stock_table'])->where($where);
+ $totalQuery = Db::table($tableObj['stock_table'])->where($where);
+ // 申购状态筛选 1 可申购 2 带中签 3 待上市 4 已上市
+ if (isset($param['open_status']) && in_array($param['open_status'], ['1', '2', '3', '4'])) {
+ switch ($param['open_status']) {
+ case '1':
+ $query = $query->whereTime('end_time', '>', $nowDate);
+ $totalQuery = $totalQuery->whereTime('end_time', '>', $nowDate);
+ break;
+ case '2':
+ $query = $query->whereTime('end_time', '<', $nowDate)->where('sign_status', '=', 2);
+ $totalQuery = $totalQuery->whereTime('end_time', '<', $nowDate)->where('sign_status', '=', 2);
+ break;
+ case '3':
+ $query = $query->where('sign_status', '=', 1)->where('open_status', 1);
+ $totalQuery = $totalQuery->where('sign_status', '=', 1)->where('open_status', 1);
+ break;
+ case '4':
+ $query = $query->where('open_status', 2);
+ $totalQuery = $totalQuery->where('open_status', 2);
+ 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'] < $nowDate && $item['open_status'] == 1) {
+ $is_defer = '1';
+ }
+
+ $is_start = '0';
+ if ($item['start_time'] <= $nowDate && $item['end_time'] >= $nowDate) {
+ $is_start = '1';
+ }
+
+ $progressStatus = 1;
+ if (time() >= $item['end_time']) $progressStatus = 2;
+ if ($item['sign_status'] == 1) $progressStatus = 3;
+ if ($item['is_post_pay'] == 2 && $item['pay_deadline_time'] < $nowDate) $progressStatus = 4;
+ if ($item['open_status'] == 2) $progressStatus = $item['is_post_pay'] == 2 ? 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,
+ ];
+ }
+ }
+
+ $extend = (new adminIPOService)->getStockTape($marketType);
+ return $this->toData('0', 'SUCCESS', ['list' => $rows, 'total' => $total, 'extend' => [
+ 'tape_list' => $extend['tape'],
+ 'stock_type_list' => $extend['type'],
+ ]]);
+ } catch (\Exception $exception) {
+ return $this->toData('1', 'System error', [$exception->getMessage(),$exception->getTrace()]);
+ }
+ }
+
+ // 股票详情
+ public function stockDetail($marketType, $param)
+ {
+ try {
+ if (empty($param['id']) || !is_numeric($param['id'])) {
+ return $this->toData('1', 'Params error', []);
+ }
+
+ $tableObj = (new adminIPOService)->getStockModel($marketType);
+ $nowDate = date('Y-m-d H:i:s');
+
+ $preStock = Db::table($tableObj['stock_table'])->where('id', $param['id'])->where('is_delete', 1)->where('status', 1)->find();
+ if (empty($preStock)) {
+ return $this->toData('1', 'Params error', []);
+ }
+
+ $is_defer = '0';
+ if ($preStock['open_time'] < $nowDate && $preStock['open_status'] == 1) {
+ $is_defer = '1';
+ }
+
+ $is_start = '0';
+ if ($preStock['start_time'] <= $nowDate && $preStock['end_time'] >= $nowDate) {
+ $is_start = '1';
+ }
+
+ $progressStatus = 1;
+ if (time() >= $preStock['end_time']) $progressStatus = 2;
+ if ($preStock['sign_status'] == 1) $progressStatus = 3;
+ if ($preStock['is_post_pay'] == 2 && $preStock['pay_deadline_time'] < $nowDate) $progressStatus = 4;
+ if ($preStock['open_status'] == 2) $progressStatus = $preStock['is_post_pay'] == 2 ? 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,
+ ];
+
+ $extend = (new adminIPOService)->getStockTape($marketType);
+ return $this->toData('0', 'SUCCESS', ['data' => $data, 'extend' => [
+ 'tape_list' => $extend['tape'],
+ 'stock_type_list' => $extend['type'],
+ ]]);
+ } catch (\Exception $exception) {
+ return $this->toData('1', 'System error', []);
+ }
+ }
+
+ // 申购操作
+ public function order($marketType, $param, $userId)
+ {
+ try {
+ if (empty($param['id']) || !is_numeric($param['id'])) {
+ return $this->toData('1', 'Params error', []);
+ }
+
+ $tableObj = (new adminIPOService)->getStockModel($marketType);
+ $nowDate = date('Y-m-d H:i:s');
+
+ $preStock = Db::table($tableObj['stock_table'])->where('id', $param['id'])
+ ->where('status', 1)
+ ->where('is_delete', 1)
+ ->whereTime('start_time', '<=', $nowDate)
+ ->whereTime('end_time', '>=', $nowDate)
+ ->find();
+ if (empty($preStock)) {
+ return $this->toData('1', 'Params error', []);
+ }
+
+ $hasOrder = Db::table($tableObj['order_table'])->where('user_id', $userId)->where('pre_stock_id', $param['id'])->count();
+ if ($preStock['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'] < $preStock['min']) {
+ return $this->toData('1', 'Order quantity less than the minimum', []);
+ }
+
+ if ($preStock['max'] > 0 && $param['num'] > $preStock['max']) {
+ return $this->toData('1', 'Order quantity greater than maximum', []);
+ }
+
+ if ($preStock['price'] <= 0) {
+ return $this->toData('1', 'Price error', []);
+ }
+
+ // 支付类型
+ if (empty($param['pay_type']) || !is_numeric($param['pay_type']) || !in_array($param['pay_type'], [1, 2])) {
+ return $this->toData('1', 'Params error', []);
+ }
+
+ // 计算金额
+ $amount = bcmul($param['num'], $preStock['price'], 18);
+ // 计算手续费
+ $purchaseFee = FeeSettingModel::where('market_type', $marketType)->value('purchase_fee');
+ if($purchaseFee == null){
+ return $this->toData('1', 'Setting error', []);
+ }
+
+ if ($purchaseFee <= 0) {
+ $fee = 0;
+ } else {
+ $fee = bcmul($amount, $purchaseFee, 18);
+ }
+
+ Db::startTrans();
+ $orderNo = $this->generateOrderNumber(20);
+ $insertOrderArr = [
+ 'user_id' => $userId,
+ 'pre_stock_id' => $preStock['id'],
+ 'status' => $param['pay_type'] == 1 ? 1 : 5,
+ 'pay_type' => $param['pay_type'],
+ 'order_no' => $orderNo,
+ 'num' => $param['num'],
+ 'get_num' => 0,
+ 'price' => $preStock['price'],
+ 'amount' => $amount,
+ 'get_amount' => 0,
+ 'fee' => $fee,
+ 'get_fee' => 0,
+ 'fee_rate' => $purchaseFee,
+ 'get_time' => $preStock['get_time'],
+ 'create_time' => date('Y-m-d H:i:s'),
+ 'update_time' => date('Y-m-d H:i:s'),
+ 'trade_status' => 0
+ ];
+ $insertOrderNum = Db::table($tableObj['order_table'])->insert($insertOrderArr);
+ if ($insertOrderNum <= 0) {
+ Db::rollback();
+ return $this->toData('1', 'create order error', []);
+ }
+
+ if ($param['pay_type'] == 2) {
+ Db::commit();
+ return $this->toData('0', 'SUCCESS', []);
+ }
+
+ // 扣除用户资产
+ $beforeAmount = Db::table($tableObj['user_table'])->where('stock_id', $tableObj['stock_id'])->where('user_id', $userId)->value('usable_num');
+ if ($beforeAmount < $amount) {
+ Db::rollback();
+ return $this->toData('1', 'assert not enough', []);
+ }
+
+ $updateNum = Db::table($tableObj['user_table'])->where('stock_id', $tableObj['stock_id'])->where('user_id', $userId)
+ ->where('usable_num', '>=', $amount)->dec('usable_num', $amount)
+ ->inc('frozen_num', $amount)
+ ->update(['update_time' => $nowDate]);
+ if ($updateNum <= 0) {
+ Db::rollback();
+ return $this->toData('1', 'Update user amount error', []);
+ }
+
+ // 生成流水
+ $insertStockLogArr = [
+ 'user_id' => $userId,
+ 'change_type' => 15, // 新股申购扣减费用
+ 'stock_id' => $tableObj['stock_id'],
+ 'before_num' => $beforeAmount,
+ 'change_num' => '-' . $amount,
+ 'order_id' => $orderNo,
+ 'create_time' => $nowDate,
+ 'update_time' => $nowDate
+ ];
+ $insertStockLogNum = Db::table($tableObj['log_table'])->insert($insertStockLogArr);
+ if ($insertStockLogNum <= 0) {
+ Db::rollback();
+ return $this->toData('1', 'create user log error', []);
+ }
+
+ // 扣除手续费
+ if ($fee > 0) {
+ $beforeFee = Db::table($tableObj['user_table'])->where('stock_id', $tableObj['stock_id'])->where('user_id', $userId)->value('usable_num');
+ if ($beforeFee < $fee) {
+ Db::rollback();
+ return $this->toData('1', 'assert not enough', []);
+ }
+
+ $updateNumFee = Db::table($tableObj['user_table'])->where('stock_id', $tableObj['stock_id'])->where('user_id', $userId)
+ ->where('usable_num', '>=', $fee)->dec('usable_num', $fee)
+ ->inc('frozen_num', $fee)
+ ->update(['update_time' => $nowDate]);
+ if ($updateNumFee <= 0) {
+ Db::rollback();
+ return $this->toData('1', 'Update user amount error', []);
+ }
+
+ // 生成流水
+ $insertStockLogArrFee = [
+ 'user_id' => $userId,
+ 'change_type' => 16, // 新股申购扣减费用
+ 'stock_id' => $tableObj['stock_id'],
+ 'before_num' => $beforeFee,
+ 'change_num' => '-' . $fee,
+ 'order_id' => $orderNo,
+ 'create_time' => $nowDate,
+ 'update_time' => $nowDate
+ ];
+ $insertStockLogNumFee = Db::table($tableObj['log_table'])->insert($insertStockLogArrFee);
+ if ($insertStockLogNumFee <= 0) {
+ Db::rollback();
+ return $this->toData('1', 'create user log error', []);
+ }
+ }
+
+ Db::commit();
+ return $this->toData('0', 'SUCCESS', []);
+ } catch (\Exception $exception) {
+ Db::rollback();
+ return $this->toData('1', 'System error', [$exception->getMessage(),$exception->getTrace()]);
+ }
+ }
+
+ // 后支付 - 支付
+ public function postPay1($marketType, $param, $userId)
+ {
+ try {
+ if (empty($param['id']) || empty($param['stock_code']) || !is_numeric($param['id'])) {
+ return $this->toData('1', 'Params error2', []);
+ }
+
+ $tableObj = (new adminIPOService)->getStockModel($marketType);
+ $nowDate = date('Y-m-d H:i:s');
+
+ $preStock = Db::table($tableObj['stock_table'])->where('stock_code', $param['stock_code'])
+ ->where('status', 1)
+ ->where('is_delete', 1)
+ ->where('is_post_pay', 2)
+// ->whereTime('pay_deadline_time', '>=', $nowDate)
+ ->find();
+ if (empty($preStock)) {
+ return $this->toData('1', 'Payment deadline exceeded', []);
+ }
+
+ $hasOrder = Db::table($tableObj['order_table'])->where('user_id', $userId)->where('id', $param['id'])->where('pay_type', 2)->where('status', 5)->find();
+ if (empty($hasOrder)) {
+ return $this->toData('1', 'Params error3', []);
+ }
+
+ $orderNo = $hasOrder['order_no'];
+ Db::startTrans();
+ if ($preStock['sign_status'] == 1) {
+ //已签名
+ $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 = Db::table($tableObj['user_table'])->where('stock_id', $tableObj['stock_id'])->where('user_id', $userId)->value('usable_num');
+ if ($beforeAmount < $amount) {
+ Db::rollback();
+ return $this->toData('1', 'assert not enough', []);
+ }
+
+ $updateNum = Db::table($tableObj['user_table'])->where('stock_id', $tableObj['stock_id'])->where('user_id', $userId)
+ ->where('usable_num', '>=', $amount)->dec('usable_num', $amount)
+ ->inc('frozen_num', $amount)
+ ->update(['update_time' => $nowDate]);
+ if ($updateNum <= 0) {
+ Db::rollback();
+ return $this->toData('1', 'Update user amount error', []);
+ }
+
+ // 生成流水
+ $insertStockLogArr = [
+ 'user_id' => $userId,
+ 'change_type' => 15, // 新股申购扣减费用
+ 'stock_id' => $tableObj['stock_id'],
+ 'before_num' => $beforeAmount,
+ 'change_num' => '-' . $amount,
+ 'order_id' => $orderNo,
+ 'create_time' => $nowDate,
+ 'update_time' => $nowDate
+ ];
+ $insertStockLogNum = Db::table($tableObj['log_table'])->insert($insertStockLogArr);
+ if ($insertStockLogNum <= 0) {
+ Db::rollback();
+ return $this->toData('1', 'create user log error', []);
+ }
+
+ // 扣除手续费
+ if ($fee > 0) {
+ $beforeFee = Db::table($tableObj['user_table'])->where('stock_id', $tableObj['stock_id'])->where('user_id', $userId)->value('usable_num');
+ if ($beforeFee < $fee) {
+ Db::rollback();
+ return $this->toData('1', 'assert not enough', []);
+ }
+
+ $updateNum = Db::table($tableObj['user_table'])->where('stock_id', $tableObj['stock_id'])->where('user_id', $userId)
+ ->where('usable_num', '>=', $fee)->dec('usable_num', $fee)
+ ->inc('frozen_num', $fee)
+ ->update(['update_time' => $nowDate]);
+ if ($updateNum <= 0) {
+ Db::rollback();
+ return $this->toData('1', 'Update user amount error', []);
+ }
+
+ // 生成流水
+ $insertStockLogArrFee = [
+ 'user_id' => $userId,
+ 'change_type' => 16, // 新股申购扣减费用
+ 'stock_id' => $tableObj['stock_id'],
+ 'before_num' => $beforeFee,
+ 'change_num' => '-' . $fee,
+ 'order_id' => $orderNo,
+ 'create_time' => $nowDate,
+ 'update_time' => $nowDate
+ ];
+ $insertStockLogNumFee = Db::table($tableObj['log_table'])->insert($insertStockLogArrFee);
+ if ($insertStockLogNumFee <= 0) {
+ Db::rollback();
+ return $this->toData('1', 'create user log error', []);
+ }
+ }
+
+ if ($preStock['open_status'] == 1) {
+ //未上市
+ $bool = Db::table($tableObj['order_table'])->where('id', $param['id'])->update(['status' => 2, 'update_time' => $nowDate]);
+ if (!$bool) {
+ Db::rollback();
+ return $this->toData('1', 'update order error', []);
+ }
+
+ } elseif ($preStock['open_status'] == 2) {
+ //已上市
+ $bool = Db::table($tableObj['order_table'])->where('id', $param['id'])->update(['status' => 3, 'update_time' => $nowDate]);
+ if (!$bool) {
+ Db::rollback();
+ return $this->toData('1', 'update order error', []);
+ }
+
+ // 已上市 扣除手续费 冻结资金
+ $num = Db::table($tableObj['user_table'])->where('user_id', $userId)->where('stock_id', $tableObj['stock_id'])
+ ->dec('frozen_num', $hasOrder['get_fee'])
+ ->update(['update_time' => $nowDate]);
+ if ($num <= 0) {
+ Db::rollback();
+ trace('股票:' . $preStock['stock_code'] . ',扣除手续费失败,用户ID:' . $userId, 'error');
+ }
+ // 手续费流水
+ $tradeFee = new TradeFeeModel;
+ $tradeFee['user_id'] = $userId;
+ $tradeFee['account_type'] = $marketType;
+ $tradeFee['service_fee'] = $hasOrder['get_fee'];
+ $tradeFee['trade_type'] = 1;
+ $tradeFee['trade_no'] = $orderNo;
+ $tradeFee['create_time'] = date('Y-m-d H:i:s');
+ $bool = $tradeFee->save();
+ if (!$bool) {
+ Db::rollback();
+ trace('股票:' . $preStock['stock_code'] . ',生成手续费失败,用户ID:' . $userId, 'error');
+ }
+ }
+ } elseif ($preStock['sign_status'] == 2) {
+ //未签名
+ $amount = $hasOrder['amount'];
+ $fee = $hasOrder['fee'];
+ // 扣除用户资产
+ $beforeAmount = Db::table($tableObj['user_table'])->where('stock_id', $tableObj['stock_id'])->where('user_id', $userId)->value('usable_num');
+ if ($beforeAmount < $amount) {
+ Db::rollback();
+ return $this->toData('1', 'assert not enough', []);
+ }
+
+ $updateNum = Db::table($tableObj['user_table'])->where('stock_id', $tableObj['stock_id'])->where('user_id', $userId)
+ ->where('usable_num', '>=', $amount)->dec('usable_num', $amount)
+ ->inc('frozen_num', $amount)
+ ->update(['update_time' => $nowDate]);
+ if ($updateNum <= 0) {
+ Db::rollback();
+ return $this->toData('1', 'Update user amount error', []);
+ }
+
+ // 生成流水
+ $insertStockLogArr = [
+ 'user_id' => $userId,
+ 'change_type' => 15, // 新股申购扣减费用
+ 'stock_id' => $tableObj['stock_id'],
+ 'before_num' => $beforeAmount,
+ 'change_num' => '-' . $amount,
+ 'order_id' => $orderNo,
+ 'create_time' => $nowDate,
+ 'update_time' => $nowDate
+ ];
+ $insertStockLogNum = Db::table($tableObj['log_table'])->insert($insertStockLogArr);
+ if ($insertStockLogNum <= 0) {
+ Db::rollback();
+ return $this->toData('1', 'create user log error', []);
+ }
+
+ // 扣除手续费
+ if ($fee > 0) {
+ $beforeFee = Db::table($tableObj['user_table'])->where('stock_id', $tableObj['stock_id'])->where('user_id', $userId)->value('usable_num');
+ if ($beforeFee < $fee) {
+ Db::rollback();
+ return $this->toData('1', 'assert not enough', []);
+ }
+
+ $updateNumFee = Db::table($tableObj['user_table'])->where('stock_id', $tableObj['stock_id'])->where('user_id', $userId)
+ ->where('usable_num', '>=', $fee)->dec('usable_num', $fee)
+ ->inc('frozen_num', $fee)
+ ->update(['update_time' => $nowDate]);
+ if ($updateNumFee <= 0) {
+ Db::rollback();
+ return $this->toData('1', 'Update user amount error', []);
+ }
+
+ // 生成流水
+ $insertStockLogArrFee = [
+ 'user_id' => $userId,
+ 'change_type' => 16, // 新股申购扣减费用
+ 'stock_id' => $tableObj['stock_id'],
+ 'before_num' => $beforeFee,
+ 'change_num' => '-' . $fee,
+ 'order_id' => $orderNo,
+ 'create_time' => $nowDate,
+ 'update_time' => $nowDate
+ ];
+ $insertStockLogNumFee = Db::table($tableObj['log_table'])->insert($insertStockLogArrFee);
+ if ($insertStockLogNumFee <= 0) {
+ Db::rollback();
+ return $this->toData('1', 'create user log error', []);
+ }
+ }
+ $bool = Db::table($tableObj['order_table'])->where('id', $param['id'])->update(['status' => 1, 'update_time' => $nowDate]);
+ if (!$bool) {
+ Db::rollback();
+ return $this->toData('1', 'update order error', []);
+ }
+
+ } else {
+ Db::rollback();
+ return $this->toData('1', 'Params error4', []);
+ }
+ Db::commit();
+
+ //已上市IPO 订单通知交易 转持仓
+ if ($preStock->open_status == 2){
+ Queue::push('app\admin\job\SendGo', [
+ 'type' => 'last_trade',
+ 'id' => $preStock['id'],
+ 'stock_code' => $preStock['stock_code'],
+ 'order_no' => $orderNo,
+ 'market_type' => $marketType,
+ ], 'sendGo');
+ }
+
+ return $this->toData('0', 'SUCCESS', []);
+ } catch (\Exception $exception) {
+ Db::rollback();
+ return $this->toData('1', 'System error110', [$exception->getMessage(),$exception->getTrace()]);
+ }
+ }
+ public function postPay($marketType, $param, $userId){
+ try {
+ if (empty($param['id']) || empty($param['stock_code']) || !is_numeric($param['id'])) {
+ return $this->toData('1', 'Params error2', []);
+ }
+
+ $tableObj = (new adminIPOService)->getStockModel($marketType);
+ $nowDate = date('Y-m-d H:i:s');
+
+ $preStock = Db::table($tableObj['stock_table'])->where('stock_code', $param['stock_code'])
+ ->where('status', 1)
+ ->where('is_delete', 1)
+ ->where('is_post_pay', 2)
+// ->whereTime('pay_deadline_time', '>=', $nowDate)
+ ->find();
+ if (empty($preStock)) {
+ return $this->toData('1', 'Payment deadline exceeded', []);
+ }
+ if(strtotime($preStock['pay_deadline_time']) < time()){
+ return $this->toData('1', 'The order has passed the payment deadline', []);
+ }
+
+ $hasOrder = Db::table($tableObj['order_table'])->where('user_id', $userId)->where('id', $param['id'])->where('pay_type', 2)->whereIn('status', [5,6])->find();
+ if (empty($hasOrder)) {
+ return $this->toData('1', 'Params error3', []);
+ }
+
+ $orderNo = $hasOrder['order_no'];
+ Db::startTrans();
+
+ if ($preStock['sign_status'] == 1) {
+ //已签名
+ $amount = $hasOrder['get_amount'];
+ $fee = $hasOrder['get_fee'];
+ $getNum = $hasOrder['get_num'];
+ }else{
+ //未签名
+ $amount = $hasOrder['amount'];
+ $fee = $hasOrder['fee'];
+ $getNum = $hasOrder['num'];
+ }
+ if ($getNum <= 0) {
+ Db::rollback();
+ return $this->toData('1', 'get num error', []);
+ }
+
+
+ $updateNum = Db::table($tableObj['user_table'])->where('stock_id', $tableObj['stock_id'])->where('user_id', $userId)
+ ->where('usable_num', '>=', $amount)->dec('usable_num', $amount)
+ ->inc('frozen_num', $amount)
+ ->update(['update_time' => $nowDate]);
+ if ($updateNum <= 0) {
+ Db::rollback();
+ return $this->toData('1', 'Update user amount error', []);
+ }
+ // 生成流水
+ $insertStockLogArr = [
+ 'user_id' => $userId,
+ 'change_type' => 15, // 新股申购扣减费用
+ 'stock_id' => $tableObj['stock_id'],
+ 'change_num' => '-' . $amount,
+ 'order_id' => $orderNo,
+ 'create_time' => $nowDate,
+ 'update_time' => $nowDate
+ ];
+ $insertStockLogNum = Db::table($tableObj['log_table'])->insert($insertStockLogArr);
+ if ($insertStockLogNum <= 0) {
+ Db::rollback();
+ return $this->toData('1', 'create user log error', []);
+ }
+
+ if ($fee > 0) {
+ $beforeFee = Db::table($tableObj['user_table'])->where('stock_id', $tableObj['stock_id'])->where('user_id', $userId)->value('usable_num');
+ if ($beforeFee < $fee) {
+ Db::rollback();
+ return $this->toData('1', 'assert not enough', []);
+ }
+
+ $updateNum = Db::table($tableObj['user_table'])->where('stock_id', $tableObj['stock_id'])->where('user_id', $userId)
+ ->where('usable_num', '>=', $fee)->dec('usable_num', $fee)
+ ->inc('frozen_num', $fee)
+ ->update(['update_time' => $nowDate]);
+ if ($updateNum <= 0) {
+ Db::rollback();
+ return $this->toData('1', 'Update user amount error', []);
+ }
+
+ }
+
+ if ($preStock['open_status'] == 1 && $preStock['sign_status'] == 1) {
+ //未上市
+ $bool = Db::table($tableObj['order_table'])->where('id', $param['id'])->update(['status' =>5, 'update_time' => $nowDate]);
+ if (!$bool) {
+ Db::rollback();
+ return $this->toData('1', 'update order error', []);
+ }
+ } elseif ($preStock['open_status'] == 2 && $preStock['sign_status'] == 1) {
+ // 手续费流水
+ $tradeFee = new TradeFeeModel;
+ $tradeFee['user_id'] = $userId;
+ $tradeFee['account_type'] = $marketType;
+ $tradeFee['service_fee'] = $hasOrder['get_fee'];
+ $tradeFee['trade_type'] = 1;
+ $tradeFee['trade_no'] = $orderNo;
+ $tradeFee['create_time'] = date('Y-m-d H:i:s');
+ $bool = $tradeFee->save();
+ if (!$bool) {
+ Db::rollback();
+ trace('股票:' . $preStock['stock_code'] . ',生成手续费失败,用户ID:' . $userId, 'error');
+ }
+ }
+
+ if ($preStock['sign_status'] == 2){
+ $bool = Db::table($tableObj['order_table'])->where('id', $param['id'])->update(['status' => 1, 'update_time' => $nowDate]);
+ if (!$bool) {
+ Db::rollback();
+ return $this->toData('1', 'update order error', []);
+ }
+ }
+
+
+ Db::commit();
+ return $this->toData('0', 'SUCCESS', []);
+ } catch (\Exception $exception) {
+ Db::rollback();
+ return $this->toData('1', 'System error', [$exception->getMessage(),$exception->getTrace()]);
+ }
+ }
+
+ // 申购记录
+ public function list($marketType, $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');
+ }
+
+ $tableObj = (new adminIPOService)->getStockModel($marketType);
+ $nowDate = date('Y-m-d H:i:s');
+
+ $statusArr = explode(",", $param['status']);
+ $list = Db::table($tableObj['order_table'])->whereIn('status', $statusArr)->where('user_id', $userId)->order('update_time', 'desc')->page($param['page'], $param['limit'])->select();
+ $total = Db::table($tableObj['order_table'])->whereIn('status', $statusArr)->where('user_id', $userId)->count();
+ $rows = [];
+ if (!$list->isEmpty()) {
+ $stockIdList = [];
+ foreach ($list as $item) {
+ $stockIdList[] = $item['pre_stock_id'];
+ }
+
+ $stockList = Db::table($tableObj['stock_table'])->where('id', 'in', $stockIdList)->column(['*'], 'id');
+
+ // 计算手续费
+ $purchaseFee = FeeSettingModel::where('market_type', $marketType)->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 < $nowDate && $openStatus == 1) {
+ $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'] == 2 && $item['status'] == 5 && 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;
+ }
+ }
+
+ $extend = (new adminIPOService)->getStockTape($marketType);
+ return $this->toData('0', 'SUCCESS', ['list' => $rows, 'total' => $total, 'extend' => [
+ 'tape_list' => $extend['tape'],
+ 'stock_type_list' => $extend['type'],
+ ]]);
+ } catch (\Exception $exception) {
+ return $this->toData('1', 'System error', []);
+ }
+ }
+
+ // 申购订单详情
+ public function detail($marketType, $param, $userId)
+ {
+ try {
+ if (empty($param['id']) || !is_numeric($param['id'])) {
+ return $this->toData('1', 'Params error', []);
+ }
+
+ $tableObj = (new adminIPOService)->getStockModel($marketType);
+ $order = Db::table($tableObj['order_table'])->where('user_id', $userId)->where('id', $param['id'])->find();
+ if (empty($order)) {
+ return $this->toData('1', 'Params error', []);
+ }
+
+ $stock = Db::table($tableObj['stock_table'])->where('id', $order['pre_stock_id'])->find();
+ if (empty($stock)) {
+ return $this->toData('1', 'Params error', []);
+ }
+
+ $is_defer = '0';
+ if ($stock['open_status'] == 1) {
+ $is_defer = '1';
+ }
+
+ $data = [
+ 'logo' => $stock['logo'],
+ 'stock_code' => $stock['stock_code'],
+ 'stock_name' => $stock['stock_name'],
+ 'stock_type' => $stock['stock_type'],
+ 'sign_status' => $stock['sign_status'],
+ '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']
+ ];
+
+ $extend = (new adminIPOService)->getStockTape($marketType);
+ return $this->toData('0', 'SUCCESS', ['data' => $data, 'extend' => [
+ 'tape_list' => $extend['tape'],
+ 'stock_type_list' => $extend['type'],
+ ]]);
+ } catch (\Exception $exception) {
+ return $this->toData('1', 'System error', [$exception->getMessage(),$exception->getTrace()]);
+ }
+ }
+
+
+}
\ No newline at end of file
diff --git a/app/home/service/IndPayService.php b/app/home/service/IndPayService.php
new file mode 100644
index 0000000..ef3571d
--- /dev/null
+++ b/app/home/service/IndPayService.php
@@ -0,0 +1,407 @@
+makeMd5Sign($sign_data);
+ if($sign==$data['sign'] && $data['status']=='SUCCESS'){
+ Log::info('回调签名检验成功:'.$sign.'-----'.$data['sign']);
+ $order_info=RechargeApplyModel::getOrderByNo([
+ 'order_no'=>$data['mer_order_no'],
+ 'order_idx'=>$data['order_no'],
+ ]);
+ if(empty($order_info)){
+ Log::info('回调检验订单失败:'.$data['mer_order_no']);
+ return [
+ 'code'=>100130,
+ 'msg'=>'FAIL'
+ ];
+ }
+ if($order_info['status']==0){
+ return (new PayService())->dealPayNotify($order_info);
+ }else{
+ return [
+ 'code'=>200,
+ 'msg'=>'SUCCESS'
+ ];
+ }
+ }else{
+ Log::info('回调签名检验失败:'.$sign.'-----'.$data['sign']);
+ return [
+ 'code'=>100120,
+ 'msg'=>'FAIL'
+ ];
+ }
+ }
+
+ public function indPay($out_trade_no,$order_amount)
+ {
+ $url=env('PAY.NOTIFY_URL');
+ $notifyUrl=$url.url('indpay_notify');
+ $pageUrl=$url.url('indpay_query');
+ $data['mer_no']=$this->mch_id;
+ $data['mer_order_no']=$out_trade_no;
+ $data['pname']='test';
+ $data['pemail']='test@mail.com';
+ $data['phone']="9852146882";//限制只能为数字号码
+ $data['order_amount']=$order_amount;
+ //$data['order_amount']=100000;
+ $data['ccy_no']="IDR";
+ $data['busi_code']="100401";##支付编码
+ $data['notifyUrl']=$notifyUrl;##回调地址
+ $data['pageUrl']=$pageUrl;##跳转地址
+ Log::info('支付post数据:'.json_encode($data));
+ $data=$this->encrypt($data);
+ $data=json_encode($data, JSON_UNESCAPED_UNICODE);
+ $url='https://cqdft.dyb360.com/ty/orderPay';
+ $ret=$this->globalpay_http_post_res_json($url,$data);
+ Log::info('支付返回数据:'.json_encode($ret));
+ return $ret;
+ }
+ public function singleIndOrder($order)
+ {
+ //$order=UserWithdrawalModel::where('id',1)->find()->toArray();
+ $url=env('PAY.NOTIFY_URL');
+ $notifyUrl=$url.url('single_notify');
+
+ $pay_info=json_decode($order['pay_info'],true);
+
+ $data['mer_no']=$this->mch_id;
+ $data['mer_order_no']=$order['order_no'];
+ $data['acc_no']=$pay_info['bank_card'];
+ $data['acc_name']=$pay_info['true_name'];
+ $data['bank_code']=$pay_info['bank_code'];##'=>'银行编码
+ $data['ccy_no']='IDR';
+ $data['order_amount']=round($order['total_amount'],2);
+ $data['mobile_no']=$pay_info['bank_phone'];//限制只能为数字号码
+ $data['summary']='summary';##备注
+ $data['notifyUrl']=$notifyUrl;//回调地址 代付成功失败都走回调
+
+ $data=$this->encrypt($data);
+
+ $data=json_encode($data, JSON_UNESCAPED_UNICODE);
+ $url='https://sbgdt.dyb360.com/withdraw/singleOrder';
+ $ret=$this->globalpay_http_post_res_json($url,$data);
+ $code=300;
+ $order_idx='';
+ if($ret['status']=='SUCCESS'){
+ $code=200;
+ $order_idx=$ret['order_no'];
+ }
+ return [
+ 'code'=>$code,
+ 'msg'=>$ret['status'],
+ 'order_idx'=>$order_idx
+ ];
+ }
+ public function getIndBalance(){
+ $data['mer_no']=$this->mch_id;
+ $data['request_no']=$this->generateOrderNumber();
+ $data['request_time']=date('YmdHis');
+ $data=$this->encrypt($data);
+ $data=json_encode($data, JSON_UNESCAPED_UNICODE);
+ $url='https://sbgdt.dyb360.com/withdraw/balanceQuery';
+ $ret=$this->globalpay_http_post_res_json($url,$data);
+ //var_dump($ret);
+
+ }
+
+ public function singleIndNotify(array $data)
+ {
+ $sign_data=$data;
+ unset($sign_data['sign']);
+ $sign=$this->makeMd5Sign($sign_data);
+ if($sign==$data['sign'] && $data['status']=='SUCCESS'){
+ Log::info('代付回调签名检验成功:'.$sign.'-----'.$data['sign']);
+ $order=UserWithdrawalModel::where([
+ 'order_no'=>$data['mer_order_no'],
+ 'order_idx'=>$data['order_no']
+ ])->find();
+ if(empty($order)){
+ return [
+ 'code'=>400,
+ 'msg'=>'FAIL'
+ ];
+ }
+ $order_info=$order->toArray();
+ if($order_info['status']==3){
+ UserWithdrawalModel::where('id',$order_info['id'])->update([
+ 'deal_time'=>date('Y-m-d H:i:s'),
+ 'status'=>4
+ ]);
+ }
+ return [
+ 'code'=>200,
+ 'msg'=>'SUCCESS'
+ ];
+ }else{
+ Log::info('代付回调签名检验失败:'.$sign.'-----'.$data['sign']);
+ return [
+ 'code'=>100120,
+ 'msg'=>'FAIL'
+ ];
+ }
+ }
+ private function decrypt($data){
+ $mch_public_key=$this->public_key;
+ ksort($data);
+ $toSign ='';
+ foreach($data as $key=>$value){
+ if(strcmp($key, 'sign')!= 0 && $value!=''){
+ $toSign .= $key.'='.$value.'&';
+ }
+ }
+ $str = rtrim($toSign,'&');
+ $encrypted = '';
+ //替换自己的公钥
+ $pem = chunk_split( $mch_public_key,64, "\n");
+ $pem = "-----BEGIN PUBLIC KEY-----\n" . $pem . "-----END PUBLIC KEY-----\n";
+ $publickey = openssl_pkey_get_public($pem);
+
+ $base64=str_replace(array('-', '_'), array('+', '/'), $data['sign']);
+
+ $crypto = '';
+ foreach(str_split(base64_decode($base64), 128) as $chunk) {
+ openssl_public_decrypt($chunk,$decrypted,$publickey);
+ $crypto .= $decrypted;
+ }
+ if($str != $crypto){
+ exit('sign fail11');
+ }
+ }
+
+//支付加密
+ private function encrypt($data){
+ $mch_private_key=$this->private_key;
+ ksort($data);
+ $str = '';
+ foreach ($data as $k => $v){
+ if(!empty($v)){
+ $str .=(string) $k.'='.$v.'&';
+ }
+ }
+ $str = rtrim($str,'&');
+ $encrypted = '';
+ //替换成自己的私钥
+ $pem = chunk_split($mch_private_key, 64, "\n");
+ $pem = "-----BEGIN PRIVATE KEY-----\n" . $pem . "-----END PRIVATE KEY-----\n";
+ $private_key = openssl_pkey_get_private($pem);
+ $crypto = '';
+ foreach (str_split($str, 117) as $chunk) {
+ openssl_private_encrypt($chunk, $encryptData, $private_key);
+ $crypto .= $encryptData;
+ }
+ $encrypted = base64_encode($crypto);
+ $encrypted = str_replace(array('+','/','='),array('-','_',''),$encrypted);
+
+ $data['sign']=$encrypted;
+ return $data;
+ }
+
+//请求
+ private function globalpay_http_post_res_json($url, $postData)
+ {
+ $curl = curl_init();
+ curl_setopt($curl, CURLOPT_URL, $url);
+ curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
+ curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
+ curl_setopt($curl, CURLOPT_POST, 1);
+ curl_setopt($curl, CURLOPT_POSTFIELDS, $postData);
+ curl_setopt($curl, CURLOPT_HEADER, 0);
+ curl_setopt($curl, CURLOPT_HTTPHEADER, array(
+ 'Content-Type: application/json; charset=utf-8',
+ 'Content-Length:' . strlen($postData) ,
+ 'Cache-Control: no-cache',
+ 'Pragma: no-cache'
+ ));
+ curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
+ $res = curl_exec($curl);
+ $errorno = curl_errno($curl);
+ curl_close($curl);
+ $result=json_decode($res,true);
+ //var_dump($res,$errorno);
+ //echo $postData;
+ return $result;
+ }
+
+//生成查询签名
+ private function makeMd5Sign($data){
+ $md5_key=$this->md5_key;
+ ksort($data);
+ $str = '';
+ foreach ($data as $k => $v){
+ if(!empty($v)){
+ $str .=(string) $k.'='.$v.'&';
+ }
+ }
+ $str = rtrim($str,'&');
+ $str .='&key='.$md5_key;
+
+ //加密
+ $sign = md5($str);
+ return $sign;
+ }
+ public function getBankList()
+ {
+ $back_list=[
+ 'COMMONWEALTH'=>'Bank Commonwealth',
+ 'CHINATRUST'=>'Bank CTBC (China Trust) Indonesia',
+ 'BANK_OCBC'=>'Bank OCBC – Indonesia',
+ 'BANK_MAYBANK'=>'Bank Maybank Indocorp',
+ 'BANK_MERIN'=>'Bank Merincorp',
+ 'BANK_AGRIS'=>'Bank Agris',
+ 'LINK_AJA'=>'Link Aja',
+ 'DOMPETKU'=>'Indosat Dompetku',
+ 'BPR_KS'=>'BPR KS',
+ 'HARDA_INTERNASIONAL'=>'Bank Harda',
+ 'BANK_VICTORIA'=>'Bank Victoria International',
+ 'MANDIRI_TASPEN'=>'Bank Mandiri Taspen Pos',
+ 'FAMA'=>'Bank Fama Internasional',
+ 'CENTRATAMA'=>'Centratama Nasional Bank',
+ 'INDEX_SELINDO'=>'Bank Index Selindo',
+ 'MAYORA'=>'Bank Mayora Indonesia',
+ 'MULTI_ARTA_SENTOSA'=>'Bank Multi Arta Sentosa',
+ 'BTPN_SYARIAH'=>'Bank Purba Danarta',
+ 'ARTOS'=>'Bank Artos IND',
+ 'BCA_SYR'=>'Bank BCA Syariah',
+ 'BANK_KESEJAHTERAAN_EKONOMI'=>'Bank Kesejahteraan Ekonomi',
+ 'BANK_ANGLOMAS'=>'Anglomas Internasional Bank',
+ 'BANK_LIMAN'=>'Liman International Bank',
+ 'BANK_AKITA'=>'Bank Akita',
+ 'OCBC'=>'Bank Dipo International (Bank Sahabat Sampoerna)',
+ 'BANK_PERSY'=>'Bank Persyarikatan Indonesia',
+ 'PRIMA_MASTER'=>'Prima Master Bank',
+ 'BANK_HARFA'=>'Bank Harfa',
+ 'BANK_INA'=>'Bank Ina Perdana',
+ 'MEGA_SYR'=>'Bank Syariah Mega',
+ 'NATIONALNOBU'=>'Bank Alfindo (Bank National Nobu)',
+ 'ROYAL'=>'Bank Royal Indonesia',
+ 'BANK_INDOMONEX'=>'ank Indomonex (Bank SBI Indonesia)',
+ 'AGRONIAGA'=>'Bank BRI Agro',
+ 'BANK_YUDHA'=>'Bank Yudha Bhakti',
+ 'BANK_BUMIPUTERA'=>'Bank MNC / Bank Bumiputera',
+ 'BANK_BINTANG'=>'Bank Bintang Manunggal',
+ 'JASA_JAKARTA'=>'Bank Jasa Jakarta',
+ 'BANK_SRI_PARTHA'=>'Bank Sri Partha',
+ 'BISNIS_INTERNASION'=>'Bank Bisnis Internasional',
+ 'MANDIRI_SYR'=>'Bank Syariah Mandiri(BSI)',
+ 'BUKOPIN'=>'Bank Bukopin',
+ 'BNI_SYR'=>'Bank BNI Syariah',
+ 'MEGA'=>'Bank Mega',
+ 'BJB_SYR'=>'Bank BJB Syariah',
+ 'BANK_SWAGUNA'=>'Bank Swaguna',
+ 'TABUNGAN_PENSIUNAN_NASIONAL'=>'Bank Tabungan Pensiunan Nasional (BTPN)',
+ 'JENIUS'=>'JENIUS',
+ 'BANK_HIM'=>'Bank Himpunan Saudara 1906',
+ 'BTN'=>'Bank Tabungan Negara (BTN)',
+ 'QNB_INDONESIA'=>'Bank QNB Kesawan (Bank QNB Indonesia)',
+ 'BANK_HARM'=>'Bank Harmoni International',
+ 'ICBC Halim Indonesia'=>'Bank (Bank ICBC Indonesia)',
+ 'CCB'=>'Bank Windu Kentjana',
+ 'GANESHA'=>'Bank Ganesha',
+ 'BANK_HAGAKITA'=>'Bank Hagakita',
+ 'MASPION'=>'Bank Maspion Indonesia',
+ 'SINARMAS_UUS'=>'Bank Sinarmas',
+ 'SHINHAN'=>'Bank Metro Express (Bank Shinhan Indonesia)',
+ 'MESTIKA_DHARMA'=>'Bank Mestika Dharma',
+ 'MUAMALAT'=>'Bank Muamalat',
+ 'BANK_OF_INDIA'=>'Bank of India Indonesia',
+ 'NUSANTARA_PARAHYANGAN'=>'Bank Nusantara Parahyangan',
+ 'BANK_SULTRA'=>'Bank Sultra',
+ 'SULAWESI'=>'Bank Sulawesi Tengah',
+ 'BENGKULU'=>'Bank Bengkulu',
+ 'PAPUA'=>'Bank Papua',
+ 'MALUKU'=>'Bank Maluku Malut',
+ 'BANK_NTT'=>'Bank NTT',
+ 'BALI BPD'=>'Bali',
+ 'BPD_NTB'=>'Bank NTB, NTB Syariah',
+ 'SUMSEL_DAN_BABEL_SULUT'=>'Bank Sulut Gorontalo',
+ 'SULSELBAR'=>'Bank Sulsel dan Barat',
+ 'BPD_KALTENG'=>'Bank Kalteng',
+ 'BPD_KAITIM'=>'Bank Kalimantan Timur dan Utara',
+ 'KALIMANTAN_BARAT'=>'Bank Kalimantan Barat',
+ 'BPD_KALSEL'=>'Bank Kalsel',
+ 'LAMPUNG'=>'Bank Lampung',
+ 'SUMSEL_DAN_BABEL'=>'Bank Sumsel Babel',
+ 'RIAU_DAN_KEPRI'=>'Bank Riau',
+ 'BANK_NAGARI'=>'Bank Nagari',
+ 'SUMUT'=>'Bank Sumut',
+ 'ACEH BPD Aceh'=>'BPD Aceh Syariah',
+ 'JAMBI'=>'BPD Jambi',
+ 'BANK_JATIM'=>'Bank Jatim',
+ 'BANK_JATENG'=>'Bank Jateng',
+ 'DAERAH_ISTIMEWA'=>'BPD DIY',
+ 'DKI'=>'Bank DKI',
+ 'BANK_JABAR'=>'Bank Jabar dan Banten (BJB)',
+ 'MAYAPADA'=>'Bank Mayapada',
+ 'JTRUST'=>'Bank JTRUST',
+ 'BANK_IFI'=>'Bank IFI',
+ 'BANK_HAGA'=>'Bank Haga',
+ 'BANK_ANTAR'=>'Bank Antardaerah',
+ 'BANK_EKONOMI'=>'Bank Ekonomi',
+ 'BUMI_ARTA'=>'Bank Bumi Arta',
+ 'BOC'=>'Bank OF China',
+ 'BANK_WOOR'=>'Bank Woori Indonesia',
+ 'DEUTSCHE'=>'Deutsche Bank AG.',
+ 'BANK_ANZ'=>'Bank ANZ Indonesia',
+ 'BANK_DANAMON'=>'Korea Exchange Bank Danamon',
+ 'BNP_PARIBAS'=>'Bank BNP Paribas Indonesia',
+ 'CAPITAL'=>'Bank Capital Indonesia',
+ 'BANK_KEPPEL'=>'Bank Keppel Tatlee Buana',
+ 'BANK_A'=>'Bank ABN Amro',
+ 'STANDARD_CHARTERED'=>'Standard Chartered Bank',
+ 'MIZUHO'=>'Bank Mizuho Indonesia',
+ 'RESONA'=>'Bank Resona Perdania',
+ 'DBS'=>'Bank DBS Indonesia',
+ 'MITSUI'=>'Bank Sumitomo Mitsui Indonesia',
+ 'BANK_TOKYO'=>'The Bank of Tokyo Mitsubishi UFJ LTD',
+ 'HSBC'=>'The Hongkong & Shanghai B.C. (Bank HSBC)',
+ 'BANK_COMP'=>'The Bangkok Bank Comp. LTD',
+ 'BANK_C_AGR'=>'Credit Agricole Indosuez',
+ 'ARTHA'=>'Bank Artha Graha Internasional',
+ 'BANK_ING'=>'ING Indonesia Bank',
+ 'BAML'=>'Bank of America, N.A',
+ 'JPMORGAN'=>'JP. Morgan Chase Bank, N.A',
+ 'CITIBANK'=>'Citibank',
+ 'BANK_LTD'=>'American Express Bank LTD',
+ 'NISP'=>'Bank OCBC NISP',
+ 'BANK_LIPPO'=>'Bank Lippo',
+ 'CIMB'=>'Bank CIMB Niaga',
+ 'ARTA_NIAGA_KENCANA'=>'Bank Arta Niaga Kencana',
+ 'PANIN'=>'Bank Panin',
+ 'MAYBANK'=>'Bank BII Maybank',
+ 'BCA'=>'Bank BCA',
+ 'PERMATA'=>'Permata Bank',
+ 'DANAMON'=>'Bank Danamon',
+ 'BNI'=>'Bank BNI',
+ 'MANDIRI'=>'Bank Mandiri',
+ 'EXIMBANK'=>'Bank Ekspor Indonesia',
+ 'BRI'=>'Bank BRI',
+ 'BANK_BUANA'=>'Bank UOB Indonesia',
+ 'BNC'=>'BNC'
+ ];
+ return $this->toData(0,'Request successful.',$back_list);
+ }
+
+
+}
\ No newline at end of file
diff --git a/app/home/service/LanguageService.php b/app/home/service/LanguageService.php
new file mode 100644
index 0000000..d712c07
--- /dev/null
+++ b/app/home/service/LanguageService.php
@@ -0,0 +1,23 @@
+toData(0,'Request successful.',$list);
+ }
+ public function getServiceList() : array
+ {
+ $list=ServiceSettingModel::getServiceList();
+ return $this->toData(0,'Request successful.',$list);
+ }
+
+}
\ No newline at end of file
diff --git a/app/home/service/LoginService.php b/app/home/service/LoginService.php
new file mode 100644
index 0000000..27d71fa
--- /dev/null
+++ b/app/home/service/LoginService.php
@@ -0,0 +1,727 @@
+getClientRealIp();
+
+ // 参数校验
+ validate(LoginValidate::class)->scene('sendEmail')->check($param);
+
+ $param['email'] = trim($param['email']);
+ // 邮箱类型校验 去除国内邮箱
+ if ($this->checkForbidEmail($param['email'])) {
+ return $this->toData('100300', 'The email is not supported.', []);
+ }
+
+ // 每天获取code 次数限制
+ $sendCodeKey = 'USER:SEND_CODE_NUM:' . $ip;
+ if ($this->checkGetNoTradeCodeNum($sendCodeKey)) {
+ return $this->toData('100300', 'The maximum number of attempts for today has been exceeded. Please try again tomorrow.', []);
+ }
+
+ // 获取发送的邮件内容
+ $content = $this->getEmailContent();
+ $content['email'] = $param['email'];
+
+ // 将发送邮件任务添加到异步队列
+ $queuename = 'app\home\job\SendEmail';
+ Queue::push($queuename, $content, 'sendEmail');
+
+ // 邮件code存到缓存(未登录操作共用)
+ $key = 'DB:USER:UNLOGIN:EMAIL_CODE:' . $param['email'];
+ $this->insertCodeToCache($key, $content['code'], 300);
+
+ // 记录已经发送的code次数
+ $this->updateHadGetCodeNumCache($sendCodeKey);
+
+ // 返回结果
+ return $this->toData('0', 'Email sent successfully. Please check your inbox.', []);
+
+ } 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 $param
+ * @return array
+ * @throws InvalidArgumentException
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function registerEmail($param): array
+ {
+ try {
+ // 获取客户端ip
+ $ip = $this->getClientRealIp();
+
+ $param['invite_code'] = $param['invite_code'] ?? '';
+ $param['agent_code'] = $param['agent_code'] ?? '';
+
+ // 邮件注册参数校验
+ validate(LoginValidate::class)->scene('emailRegister')->check($param);
+
+ // 判断注册数量 ip每天可注册数量
+ $ipCanRegisterNumPerIpPerDay = 'USER:REGISTER:' . $ip;
+ if ($this->checkRegisterLimit($ipCanRegisterNumPerIpPerDay)) {
+ return $this->toData('100300', 'The maximum number of attempts for today has been exceeded. Please try again tomorrow.', []);
+ }
+
+ // 验证验证码
+ $emailKey = 'DB:USER:UNLOGIN:EMAIL_CODE:' . $param['email'];
+ if (!$this->checkCode($emailKey, $param['email_code'])) {
+ //注册验证码
+ $reg_key = "USER:REG:CODE";
+ if (!$this->checkCode($reg_key, $param['email_code'])) {
+ return $this->toData('100300', 'The verification code is incorrect.', []);
+ } else {
+ $code = random_int(1000, 9999);
+ $this->insertCodeToCache($reg_key, $code, 300);
+ }
+ }
+
+ $email = $param['email'];
+ $inviteCode = trim($param['invite_code']);
+ $agentCode = trim($param['agent_code']);
+
+ // 邮箱是否已经存在
+ $emailExists = UserModel::checkEmailExists($email);
+ if ($emailExists) {
+ return $this->toData('100300', 'The email has already been registered.', []);
+ }
+
+ // 判断邀请人是否存在
+ $agentId = 0;
+ $parentUserId = 0;
+ if (!empty($inviteCode)) {
+ $agentId = AdminModel::getIdByInviteCode($inviteCode);
+ if ($agentId <= 0) {
+ $parentUserId = $this->getParentIdByInviteCode($inviteCode);
+ if ($parentUserId <= 0) {
+ return $this->toData('100400', 'The invitation code is invalid.', []);
+ }
+ }
+ }
+
+ // 判断代理人是否存在
+ if (!empty($agentCode) || $agentId > 0) {
+ if ($agentId == 0) {
+ $agentId = AdminModel::getIdByInviteCode($agentCode);
+ if ($agentId <= 0) {
+ return $this->toData('100400', 'The invitation code is invalid.', []);
+ }
+ }
+ } else {
+ // 是否必须填写有效的邀请码
+ $inviteCodeIsRequired = env("REG_USER.INVITE_CODE_REQUIRED");
+ if ($parentUserId <= 0 && $inviteCodeIsRequired >= 1) {
+ return $this->toData('100400', 'The invitation code is invalid.', []);
+ }
+ }
+
+ // 入库
+ $userNo = $this->getUniqUserNo();
+ $salt = env('ENCRYPT.SALT');
+ $password = (new UnqId())->encryptPassword($param['password'], $salt);
+ $userInviteCode = $this->getUniqInviteCode();
+ // 需要开启事务
+ \think\facade\Db::transaction(function () use ($email, $userNo, $userInviteCode, $parentUserId, $password, $ip, $salt, $agentId) {
+ // 生成用户数据
+ $userId = UserModel::emailRegister($email, $userNo, $userInviteCode, $parentUserId, $password, $ip, $salt, 1, $agentId);
+ // 生成钱包地址
+ (new UserService())->doRegInitUserInfo($userId, $parentUserId);
+ });
+ // 删除缓存
+ $this->delCache($emailKey);
+ // 累加已经注册的个数
+ $this->updateHadRegisterNumCache($ipCanRegisterNumPerIpPerDay);
+ return $this->toData('0', 'Registration Successful.', []);
+ } catch (ValidateException $validateException) {
+ // 参数校验失败 异常类
+ $message = $validateException->getError();
+ return $this->toData('100400', $message);
+ } catch (\Exception $exception) {
+ trace('【注册错误】提交数据:'.json_encode($param), 'error');
+ trace('【注册错误】'.$exception->getMessage(), 'error');
+ return $this->toData('100500', 'The system is busy.', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+
+ /**
+ * @desc 登陆业务处理接口
+ * @param array $param
+ * @return array
+ */
+ public function loginEmail(array $param): array
+ {
+ try {
+ // 参数校验 邮箱 密码
+ validate(LoginValidate::class)->scene('emailLogin')->check($param);
+
+ $param['email'] = trim($param['email']);
+ // 查找邮箱
+ $userId = UserModel::getUserIdByEmail($param['email']);
+ if ($userId <= 0) {
+ return $this->toData('100300', 'The user does not exist.', []);
+ }
+
+ // 查找用户信息
+ $user = UserModel::getFieldsByUserId('invite_code,user_id,user_no,nick_name,is_real,login_password,salt', $userId);
+ if (empty($user)) {
+ return $this->toData('100300', 'Incorrect account or password.', []);
+ }
+
+ // 校验密码
+ $checkPasswordBool = (new UnqId())->checkPassword($param['password'], $user['login_password'], $user['salt']);
+ if (!$checkPasswordBool) {
+ return $this->toData('100300', 'Incorrect account or password.', []);
+ }
+
+ // 生成token
+ $token = (new Jwt())->getToken($userId, env('ENCRYPT.SALT'));
+ if (empty($token)) {
+ return $this->toData('100300', 'The system is busy.', []);
+ }
+
+ // 用户登陆之后需要进行的操作 异步完成
+ Queue::push('app\home\job\LoginDone', ['userId' => $userId,
+ 'fields' => [
+ 'last_login_time' => date('Y-m-d H:i:s'),
+ 'ip' => $this->getClientRealIp(),
+ 'device' => $param['device'],
+
+ ]
+ ], 'loginDone');
+
+ // 将token存致缓存 覆盖新的缓存 实现单设备登陆
+ $this->setUserTokenCache($token, $userId);
+
+ // 用户登记关系
+ (new UserService())->getUserLevel($userId);
+
+ // 返回结果以及用户信息
+ return $this->toData('0', 'Request successful.', [
+ 'userId' => $userId,
+ 'userNo' => $user['user_no'],
+ 'nickName' => $user['nick_name'],
+ 'inviteCode' => $user['invite_code'],
+ 'isReal' => $user['is_real'],
+ 'logo' => env('USER.DEFAULT_HEAD_IMG_PATH'),
+ 'token' => $token,
+ ]);
+ } catch (ValidateException $validateException) {
+ // 参数校验失败 异常类
+ $message = $validateException->getError();
+ return $this->toData('100400', $message);
+ } catch (InvalidArgumentException $invalidArgumentException) {
+ return $this->toData('100400', 'The system is busy. Please try again later.', []);
+ } catch (\Exception $exception) {
+ return $this->toData('100500', 'The system is busy.', []);
+ }
+ }
+
+ /**
+ * @desc未登陆获取短信验证码
+ * @param array $param
+ * @return array
+ * @throws InvalidArgumentException
+ */
+ public function sendSms(array $param): array
+ {
+ try {
+ // 防止重复操作 单个ip 3秒钟内只能请求一次
+ $ip = $this->getClientRealIp();
+
+ // 参数校验
+ validate(LoginValidate::class)->scene('sendSms')->check($param);
+
+ $param['nation'] = trim($param['nation']);
+ $param['phone'] = trim($param['phone']);
+ // 去除国内手机号
+ if ($this->checkForbidNation($param['nation'])) {
+ return $this->toData('100300', 'Unsupported country or region.', []);
+ }
+
+ // 判断国家码是否有效
+ $nationExists = CountryModel::checkCodeExists($param['nation']);
+ if (!$nationExists) {
+ return $this->toData('100300', 'Unsupported country or region.', []);
+ }
+
+ // 发送次数校验 - 号码
+ $phoneSendCodeKey = 'USER:PHONE_SEND_CODE_NUM:' . $param['nation'].':'.$param['phone'];
+ if ($this->checkGetNoTradeCodeNumPhone($phoneSendCodeKey)) {
+ return $this->toData('100300', 'No worries. Please feel free to reach out again tomorrow.', []);
+ }
+
+ // 发送次数校验 - ip
+ $ipSendCodeKey = 'USER:IP_SEND_CODE_NUM:' . $ip;
+ if ($this->checkGetNoTradeCodeNum($ipSendCodeKey)) {
+ return $this->toData('100300', 'No worries. Please feel free to reach out again tomorrow.', []);
+ }
+
+ // 获取发送内容
+ $content = $this->getSmsContent();
+ $mobile = $param['nation'] . $param['phone'];
+ $content['mobile'] = $mobile;
+
+ // 异步发送
+ $queuename = 'app\home\job\SendSms';
+ Queue::push($queuename, $content, 'sendSms');
+
+ // 短信code存到缓存(未登录操作共用)
+ $key = 'DB:USER:UNLOGIN:SMS_CODE:' . $mobile;
+ $this->insertCodeToCache($key, $content['code'], 300);
+
+ // 累加已经获取的次数
+ $this->updateHadGetCodeNumCache($phoneSendCodeKey);
+ $this->updateHadGetCodeNumCache($ipSendCodeKey);
+
+ // 返回结果
+ return $this->toData('0', 'The message has been sent. Please check your inbox.', []);
+ } catch (ValidateException $validateException) {
+ // 参数校验失败 异常类
+ $message = $validateException->getError();
+ return $this->toData('100400', $message);
+ } catch (\Exception $exception) {
+ trace('【注册错误】提交数据:'.json_encode($param), 'error');
+ trace('【注册错误】'.$exception->getMessage(), 'error');
+ return $this->toData('100500', 'The system is busy.', [$exception->getMessage()]);
+ }
+ }
+
+ /**
+ * @desc 短信注册
+ * @param array $param
+ * @return array
+ * @throws InvalidArgumentException
+ */
+ public function registerSms(array $param): array
+ {
+ try {
+ // 防止重复操作
+ $ip = $this->getClientRealIp();
+
+ $param['invite_code'] = $param['invite_code'] ?? '';
+ $param['agent_code'] = $param['agent_code'] ?? '';
+
+ // 短信注册参数校验
+ validate(LoginValidate::class)->scene('smsRegister')->check($param);
+
+ // 判断注册数量 ip每天可注册数量
+ $ipCanRegisterNumPerIpPerDay = 'USER:REGISTER:' . $ip;
+ $this->checkRegisterLimit($ipCanRegisterNumPerIpPerDay);
+
+ // 校验验证码
+ $mobile = $param['nation'] . $param['phone'];
+ $smsKey = 'DB:USER:UNLOGIN:SMS_CODE:' . $mobile;
+ if (!$this->checkCode($smsKey, $param['sms_code'])) {
+ $reg_key = "USER:REG:CODE";
+ //注册验证码
+ if (!$this->checkCode($reg_key, $param['sms_code'])) {
+ return $this->toData('100300', 'The verification code is incorrect.', []);
+ } else {
+ $code = random_int(1000, 9999);
+ $this->insertCodeToCache($reg_key, $code, 300);
+ }
+ }
+
+ // 手机号是否已经存在
+ $phoneExists = UserModel::checkPhoneExists($param['phone']);
+ if ($phoneExists) {
+ return $this->toData('100300', 'The phone number has already been registered.', []);
+ }
+
+ // 邀请人
+ $inviteCode = trim($param['invite_code']);
+ $agentCode = trim($param['agent_code']);
+ $parentUserId = 0;
+ $agentId = 0;
+ if (!empty($inviteCode)) {
+ $agentId = AdminModel::getIdByInviteCode($inviteCode);
+ if ($agentId <= 0) {
+ $parentUserId = $this->getParentIdByInviteCode($inviteCode);
+ if ($parentUserId <= 0) {
+ return $this->toData('100400', 'The invitation code is invalid.', []);
+ }
+ }
+ }
+
+ // 判断代理人是否存在
+ if (!empty($agentCode) || $agentId > 0) {
+ if ($agentId == 0) {
+ $agentId = AdminModel::getIdByInviteCode($agentCode);
+ if ($agentId <= 0) {
+ return $this->toData('100400', 'The invitation code is invalid.', []);
+ }
+ }
+ } else {
+ // 是否必须填写有效的邀请码
+ $inviteCodeIsRequired = env("REG_USER.INVITE_CODE_REQUIRED");
+ if ($parentUserId <= 0 && $inviteCodeIsRequired >= 1) {
+ return $this->toData('100400', 'The invitation code is invalid.', []);
+ }
+ }
+
+ // 入库
+ $userNo = $this->getUniqUserNo();
+ $salt = env('ENCRYPT.SALT');
+ $password = (new UnqId())->encryptPassword($param['password'], $salt);
+ $userInviteCode = $this->getUniqInviteCode();
+
+ // 需要开启事务
+ \think\facade\Db::transaction(function () use ($param, $userNo, $userInviteCode, $parentUserId, $password, $ip, $salt, $agentId) {
+ // 生成用户数据
+ $userId = UserModel::phoneRegister($param['nation'], $param['phone'], $userNo, $userInviteCode, $parentUserId, $password, $ip, $salt, 1, $agentId);
+ // 生成钱包地址
+ (new UserService())->doRegInitUserInfo($userId, $parentUserId);
+ });
+
+ // 删除缓存
+ $this->delCache($smsKey);
+
+ // 更新注册个数
+ $this->updateHadRegisterNumCache($ipCanRegisterNumPerIpPerDay);
+
+ return $this->toData('0', 'Registration 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(), $exception->getTrace()]);
+ }
+ }
+
+ /**
+ * @desc 短信验证码登陆
+ * @param array $param
+ * @return array
+ * @throws InvalidArgumentException
+ */
+ public function loginSms(array $param): array
+ {
+ try {
+ // 邮件注册参数校验
+ validate(LoginValidate::class)->scene('smsLogin')->check($param);
+
+ $param['nation'] = trim($param['nation']);
+ $param['phone'] = trim($param['phone']);
+
+ // 验证短信验证码
+ $mobile = $param['nation'] . $param['phone'];
+ $smsKey = 'DB:USER:UNLOGIN:SMS_CODE:' . $mobile;
+ if (!$this->checkCode($smsKey, $param['sms_code'])) {
+ return $this->toData('100300', 'The verification code is incorrect.', []);
+ };
+
+ // 查找手机号
+ $userId = UserModel::getUserIdByNationAndPhone($param['nation'], $param['phone']);
+ if ($userId <= 0) {
+ return $this->toData('100300', 'The user does not exist.', []);
+ }
+
+ // 查找用户信息
+ $user = UserModel::getFieldsByUserId('invite_code,user_id,user_no,nick_name,is_real,login_password,salt', $userId);
+ if (empty($user)) {
+ return $this->toData('100300', 'Incorrect account or password.', []);
+ }
+
+ // 生成token
+ $token = (new Jwt())->getToken($userId, env('ENCRYPT.SALT'));
+ if (empty($token)) {
+ return $this->toData('100300', 'The system is busy. Please try again later.', []);
+ }
+
+ // 用户登陆之后需要进行的操作 异步完成
+ Queue::push('app\home\job\LoginDone', ['userId' => $userId,
+ 'fields' => [
+ 'last_login_time' => date('Y-m-d H:i:s'),
+ 'ip' => $this->getClientRealIp(),
+ 'device' => $param['device'],
+ ]
+ ], 'loginDone');
+
+ // 将token存致缓存 覆盖新的缓存 实现单设备登陆
+ $this->setUserTokenCache($token, $userId);
+
+ // 用户登记关系
+ (new UserService())->getUserLevel($userId);
+
+ // 返回结果以及用户信息
+ return $this->toData('0', 'Request successful.', [
+ 'userId' => $userId,
+ 'userNo' => $user['user_no'],
+ 'nickName' => $user['nick_name'],
+ 'isReal' => $user['is_real'],
+ 'inviteCode' => $user['invite_code'],
+ 'logo' => env('USER.DEFAULT_HEAD_IMG_PATH'),
+ 'token' => $token,
+ ]);
+ } catch (ValidateException $validateException) {
+ // 参数校验失败 异常类
+ $message = $validateException->getError();
+ return $this->toData('100400', $message);
+ } catch (\Exception $exception) {
+ return $this->toData('100500', 'The system is busy. Please try again later.', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+
+ /**
+ * @desc 忘记密码 根据邮箱设置密码
+ * @param array $param
+ * @return array
+ * @throws InvalidArgumentException
+ */
+ public function resetPasswordByEmail(array $param): array
+ {
+ try {
+ // 邮件注册参数校验
+ validate(LoginValidate::class)->scene('emailForget')->check($param);
+
+ // 验证码
+ $emailKey = 'DB:USER:UNLOGIN:EMAIL_CODE:' . $param['email'];
+ if (!$this->checkCode($emailKey, $param['email_code'])) {
+ return $this->toData('100300', 'The verification code is incorrect', []);
+ }
+
+ // 查找邮箱
+ $userId = UserModel::getUserIdByEmail($param['email']);
+ if ($userId <= 0) {
+ return $this->toData('100300', 'The user does not exist.', []);
+ }
+
+ // 修改密码
+ $salt = env('ENCRYPT.SALT');
+ $password = (new UnqId())->encryptPassword($param['password'], $salt);
+ UserModel::updatePassword($password, $salt, $userId);
+
+ // 删除缓存
+ $this->delCache($emailKey);
+
+ 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. Please try again later.', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+
+ /**
+ * @desc 忘记密码 根据短信设置密码
+ * @param array $param
+ * @return array
+ * @throws InvalidArgumentException
+ */
+ public function resetPasswordBySms(array $param): array
+ {
+ try {
+ // 邮件注册参数校验
+ validate(LoginValidate::class)->scene('smsForget')->check($param);
+
+ // 判断验证码
+ $mobile = $param['nation'] . $param['phone'];
+ $smsKey = 'DB:USER:UNLOGIN:SMS_CODE:' . $mobile;
+ if (!$this->checkCode($smsKey, $param['sms_code'])) {
+ return $this->toData('100300', 'The verification code is incorrect', []);
+ }
+
+ // 查找用户
+ $userId = UserModel::getUserIdByNationAndPhone($param['nation'], $param['phone']);
+ if ($userId <= 0) {
+ return $this->toData('100300', 'The user does not exist.', []);
+ }
+
+ // 修改密码
+ $salt = env('ENCRYPT.SALT');
+ $password = (new UnqId())->encryptPassword($param['password'], $salt);
+ UserModel::updatePassword($password, $salt, $userId);
+
+ // 删除缓存
+ $this->delCache($smsKey);
+
+ 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. Please try again later.', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+
+
+ /**
+ * @desc 手机号 密码登陆
+ * @param $param
+ * @return array
+ */
+ public function phoneLogin($param): array
+ {
+ try {
+ // 参数校验
+ validate(LoginValidate::class)->scene('smsPasswordLogin')->check($param);
+
+ // 获取用户
+ $userId = UserModel::getUserIdByNationAndPhone($param['nation'], $param['phone']);
+ if ($userId <= 0) {
+ return $this->toData('100300', 'Incorrect account or password.1', []);
+ }
+
+ $info = UserModel::getFieldsByUserId('invite_code,is_real,nick_name,user_no,user_id,login_password,salt', $userId);
+ if (empty($info)) {
+ return $this->toData('100300', 'Incorrect account or password.2', []);
+ }
+
+ // 校验密码
+ $checkPasswordBool = (new UnqId())->checkPassword($param['password'], $info['login_password'], $info['salt']);
+ if (!$checkPasswordBool) {
+ return $this->toData('100300', 'Incorrect account or password.3', []);
+ }
+
+ // 生成token
+ $token = (new Jwt())->getToken($userId, env('ENCRYPT.SALT'));
+ if (empty($token)) {
+ return $this->toData('100400', 'The system is busy. Please try again later.', []);
+ }
+
+ // 用户登陆之后需要进行的操作 异步完成
+ Queue::push('app\home\job\LoginDone', ['userId' => $userId,
+ 'fields' => [
+ 'last_login_time' => date('Y-m-d H:i:s'),
+ 'ip' => $this->getClientRealIp(),
+ 'device' => $param['device'],
+ ]
+ ], 'loginDone');
+
+ // 将token存致缓存 覆盖新的缓存 实现单设备登陆
+ $this->setUserTokenCache($token, $userId);
+
+ // 用户登记关系
+ (new UserService())->getUserLevel($userId);
+
+ // 返回结果以及用户信息
+ return $this->toData('0', 'Request successful.', [
+ 'userId' => $userId,
+ 'userNo' => $info['user_no'],
+ 'nickName' => $info['nick_name'],
+ 'isReal' => $info['is_real'],
+ 'inviteCode' => $info['invite_code'],
+ 'logo' => env('USER.DEFAULT_HEAD_IMG_PATH'),
+ 'token' => $token,
+ ]);
+ } catch (ValidateException $validateException) {
+ // 参数校验失败 异常类
+ $message = $validateException->getError();
+ return $this->toData('100400', $message);
+ } catch (\Exception $exception) {
+ return $this->toData('100500', 'The system is busy. Please try again later.', []);
+ }
+ }
+
+ public function autoLogin($param): array
+ {
+ try {
+ $login_token=$param['login_token'];
+ $tokenUserKey = 'AUTO:TOKEN:'.$login_token;
+ $userId = Cache::store('redis')->get($tokenUserKey);
+ if(empty($userId) || $userId <= 0){
+ return $this->toData('100300', 'Incorrect token', []);
+ }
+ $info = UserModel::getFieldsByUserId('invite_code,is_real,nick_name,user_no,user_id,login_password,salt', $userId);
+ if (empty($info)) {
+ return $this->toData('100300', 'Incorrect account or password.2', []);
+ }
+ // 生成token
+ $token = (new Jwt())->getToken($userId, env('ENCRYPT.SALT'));
+ if (empty($token)) {
+ return $this->toData('100400', 'The system is busy. Please try again later.', []);
+ }
+
+ // 将token存致缓存 覆盖新的缓存 实现单设备登陆
+ $this->setUserTokenCache($token, $userId);
+
+ // 用户登记关系
+ (new UserService())->getUserLevel($userId);
+
+ // 返回结果以及用户信息
+ return $this->toData('0', 'Request successful.', [
+ 'userId' => $userId,
+ 'userNo' => $info['user_no'],
+ 'nickName' => $info['nick_name'],
+ 'isReal' => $info['is_real'],
+ 'inviteCode' => $info['invite_code'],
+ 'logo' => env('USER.DEFAULT_HEAD_IMG_PATH'),
+ 'token' => $token,
+ ]);
+ } catch (ValidateException $validateException) {
+ // 参数校验失败 异常类
+ $message = $validateException->getError();
+ return $this->toData('100400', $message);
+ } catch (\Exception $exception) {
+ return $this->toData('100500', 'The system is busy. Please try again later.', []);
+ }
+
+ }
+ public function getIP(): array
+ {
+ $ip=$this->getClientRealIp();
+ $countryDb = base_path().'GeoLite2-Country.mmdb';
+ $cityDb = base_path().'GeoLite2-City.mmdb';
+ $countryReader = new Reader($countryDb);
+ $cityReader = new Reader($cityDb);
+ try{
+ $countryNames = $countryReader->country($ip)->country->names;
+ $cityNames = $cityReader->city($ip)->city->names;
+ return $this->toData('0', 'Request successful.', [
+ 'country' => $countryNames['zh-CN'],
+ 'city' => $cityNames['zh-CN'],
+ 'ip'=>$ip
+ ]);
+ }catch (\Exception $exception){
+ return $this->toData('0', 'Request successful.', [
+ 'country' => '未知',
+ 'city' =>'未知',
+ 'ip'=>$ip
+ ]);
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/home/service/MarketService.php b/app/home/service/MarketService.php
new file mode 100644
index 0000000..9009fe3
--- /dev/null
+++ b/app/home/service/MarketService.php
@@ -0,0 +1,237 @@
+scene('getMarketList')->check($data);
+ //1现货,2合约,3美股
+ switch ($data['market_type']){
+ case 1:
+ $result = $this->getDigitalList();
+ break;
+ case 2:
+ $result = $this->getContractFaceList();
+ break;
+ case 3:
+ $result = StockListModel::getMarketList($data);
+ break;
+ default:
+ $result = $this->getDigitalList();
+ break;
+ }
+ return $this->toData(0,'Request successful.',$result);
+ }catch (ValidateException $validateException){
+ $message = $validateException->getMessage();
+ return $this->toData('1', $message, []);
+ }catch (\Exception $exception){
+ return $this->toData('100500', 'The system is busy. Please try again later.', [$exception->getMessage(),$exception->getTrace()]);
+ }
+ }
+
+ /**
+ * 获取用户自选数据
+ * @param int $user_id
+ * @param int $market_type
+ * @return array
+ */
+ public function getUserMarket(array $data): array
+ {
+ try{
+ validate(MarketValidate::class)->scene('getMarket')->check($data);
+ $result=UserMarketModel::getUserMarket($data);
+ return $this->toData(0,'Request successful.',$result);
+ }catch (ValidateException $validateException){
+ $message = $validateException->getMessage();
+ return $this->toData('1', $message, []);
+ }catch (\Exception $exception){
+ return $this->toData('100500', 'The system is busy. Please try again later.', [$exception->getMessage(),$exception->getTrace()]);
+ }
+ }
+
+ /**
+ * 添加用户自选
+ * @param array $data
+ * @return array
+ */
+
+ public function addUserMarket(array $data):array
+ {
+ try{
+ validate(MarketValidate::class)->scene('setMarket')->check($data);
+ // 不做大写处理
+// $data['trade_name']=strtoupper($data['trade_name']);
+// $data['market_name']=strtoupper($data['market_name']);
+
+ $id= UserMarketModel::checkExistMarket($data);
+ if(!$id){
+ UserMarketModel::insertUserMarket($data);
+ }
+ $this->pushUserMarket($data);
+ return $this->toData(0,'Request successful.');
+ }catch (ValidateException $validateException){
+ $message = $validateException->getMessage();
+ return $this->toData('1', $message, []);
+ }catch (\Exception $exception){
+ return $this->toData('100500', 'The system is busy. Please try again later.', [$exception->getMessage(),$exception->getTrace()]);
+ }
+
+
+ }
+ public function getUserIsCollect(array $data): array
+ {
+ $id = UserMarketModel::checkExistMarket($data);
+ return $this->toData(0, 'Request successful.',[
+ 'is_collet'=>($id > 0)
+ ]);
+ }
+
+ /**
+ * 删除用户自选
+ * @param array $data
+ * @return array
+ */
+ public function delUserMarket(array $data):array
+ {
+ try{
+ validate(MarketValidate::class)->scene('delMarket')->check($data);
+ $id= UserMarketModel::checkExistMarket($data);
+ if($id){
+ UserMarketModel::delUserMarket($id);
+ }
+ $this->pushUserMarket($data);
+ return $this->toData(0,'Request successful.');
+ }catch (ValidateException $validateException){
+ $message = $validateException->getMessage();
+ return $this->toData('1', $message, []);
+ }catch (\Exception $exception){
+ return $this->toData('100500', 'The system is busy. Please try again later.', [$exception->getMessage(),$exception->getTrace()]);
+ }
+ }
+ private function pushUserMarket($data){
+ $list=UserMarketModel::getUserMarket(['page'=>1,'page_size'=>1000,'user_id'=>$data['user_id']]);
+ $tokenUserKey="USER:MARKET:".$data['user_id'];
+ $redis=$this->getRedis();
+ $redis->set($tokenUserKey,json_encode($list['list']));
+ }
+ private function checkMarket($market_type,$trade_name):bool
+ {
+ switch ($market_type){
+ case 1:
+ return DigitalListModel::existMarket($trade_name);
+ break;
+ case 2:
+ return ContractListMode::existMarket($trade_name);
+ break;
+ case 3:
+ return StockListModel::existMarket($trade_name);
+ break;
+ default:
+ return DigitalListModel::existMarket($trade_name);
+ break;
+ }
+ }
+
+ public function getTradeFee(array $data): array
+ {
+ try{
+ validate(MarketValidate::class)->scene('getTradeFee')->check($data);
+ $fee_info=$this->initTradeFeeSetting($data['market_type']);
+ //$fee_info=FeeSettingModel::getTradeFeeById($data['market_type']);
+ return $this->toData(0,'Request successful.',$fee_info);
+ }catch (ValidateException $validateException){
+ $message = $validateException->getMessage();
+ return $this->toData('1', $message, []);
+ }catch (\Exception $exception){
+ return $this->toData('100500', 'The system is busy. Please try again later.', [$exception->getMessage(),$exception->getTrace()]);
+ }
+ }
+ public function getMarketTradeList(array $data):array
+ {
+ try{
+ validate(MarketValidate::class)->scene('getTrade')->check($data);
+ switch ($data['market_type']){
+ case 2:
+ $list=ContractTradeModel::getTradeList($data['trade_name'],intval($data['num']));
+ break;
+ case 3:
+ $list=StockTradeModel::getTradeList($data['trade_name'],intval($data['num']));
+ break;
+ default:
+ $list=DigitalTradeModel::getTradeList($data['trade_name'],intval($data['num']));
+ break;
+
+ }
+ return $this->toData(0,'Request successful.',$list);
+ }catch (ValidateException $validateException){
+ $message = $validateException->getMessage();
+ return $this->toData('1', $message, []);
+ }catch (\Exception $exception){
+ return $this->toData('100500', 'The system is busy. Please try again later.', [$exception->getMessage(),$exception->getTrace()]);
+ }
+ }
+ public function getTradeTypeList():array
+ {
+ $list=$this->getCapitalTypeList();
+ return $this->toData(0,'Request successful.',$list);
+ }
+ public function getContractFace():array
+ {
+ $list=$this->getContractFaceList(1);
+ return $this->toData(0,'Request successful.',$list);
+ }
+ public function getForexFace($data):array
+ {
+ $info=ForexListModel::where('trade_name',$data['trade_name'])->find();
+ if(!empty($info)){
+ $arr=$info->toArray();
+ }else{
+ $arr=[];
+ }
+ return $this->toData(0,'Request successful.',$arr);
+ }
+ public function getContractSetting():array
+ {
+ $list=ContractSettingModel::getSettingList();
+ return $this->toData(0,'Request successful.',$list);
+ }
+ public function getMarketRate():array
+ {
+ $list=StockMarketModel::where('status',1)->field('stock_market_type as market_type,unit,symbol,rate')->select();
+ if(!empty($list)){
+ $list_arr=$list->toArray();
+ }else{
+ $list_arr=[];
+ }
+ return $this->toData(0,'Request successful.',$list_arr);
+ }
+
+
+
+
+}
\ No newline at end of file
diff --git a/app/home/service/MoPayService.php b/app/home/service/MoPayService.php
new file mode 100644
index 0000000..5f54b56
--- /dev/null
+++ b/app/home/service/MoPayService.php
@@ -0,0 +1,203 @@
+merchant;
+ $post_data['pay_orderid']=$orderId;
+ $post_data['pay_applydate']=date('Y-m-d H:i:s');
+ $post_data['pay_notifyurl']=$notify_url.url('mopay_notify');
+ $post_data['pay_callbackurl']=$notify_url.url('mopay_notify');
+ $post_data['pay_amount']=$amount;
+ $post_data['pay_bankcode']=$this->bankcode;
+
+ $sign=$this->createSign($this->key,$post_data);
+ $post_data['pay_md5sign']=$sign;
+ $header = array("Content-Type:application/x-www-form-urlencoded");
+ $res=$this->curlPost($this->pay_url,$post_data,10,$header);
+ $result=json_decode($res,true);
+ return $result;
+ }
+ public function moPayNotify($data){
+ Log::info('收到mopay异步回调:'.json_encode($data));
+ $sign=$this->createSign($this->key,$data);
+ Log::info('收到mopay代付异步回调sign:'.$sign.'====='.$data['sign']);
+ if($sign==strtoupper($data['sign'])){
+ if($data['returncode']=='00'){
+ $order_info=RechargeApplyModel::getOrderByNo([
+ 'order_no'=>$data['orderid']
+ ]);
+ if($order_info && $data['amount']==$order_info['total_amount']){
+ if($order_info['status']==0){
+ return (new PayService())->dealPayNotify($order_info);
+ }
+ }else{
+ Log::info('mopay支付订单不存在:'.json_encode($data));
+ }
+ }else{
+ Log::info('mopay支付订单支付失败:'.json_encode($data));
+ }
+ }else{
+ Log::info('mopay签名校验失败:'.$sign.json_encode($data));
+ }
+ }
+ public function apply_pay($orderId,$amount,$bank_code,$bank_account,$nike_name,$moblie,$ifsc)
+ {
+ $notify_url=env('PAY.NOTIFY_URL');
+ $post_data['mchid']=$this->merchant;
+ $post_data['out_trade_no']=$orderId;
+ $post_data['money']=round($amount,2);
+ $post_data['bank_code']=$bank_code;
+ $post_data['bank_account']=$nike_name;
+ $post_data['bank_card_no']=$bank_account;
+ $post_data['mobile']=$moblie;
+ $post_data['ifsc']=$ifsc;
+ $post_data['notifyurl']=$notify_url.'/bs/mopay_anotify';
+
+ $sign=$this->createSign($this->key,$post_data);
+ $post_data['pay_md5sign']=$sign;
+ Log::info('mopay post:'.json_encode($post_data));
+ $header = array("Content-Type:application/x-www-form-urlencoded");
+ $res=$this->curlPost($this->app_url,$post_data,10,$header);
+ $result=json_decode($res,true);
+ Log::info('mopay post结果:'.$res);
+ if(strtolower($result['status'])=='success'){
+ return [
+ 'code'=>200,
+ 'msg'=>'ok',
+ 'order_idx'=>$result['transaction_id'],
+ 'content'=>$res
+ ];
+ }else{
+ return [
+ 'code'=>300,
+ 'msg'=>$result['msg'],
+ 'order_idx'=>'',
+ 'content'=>$res
+ ];
+ }
+ }
+ public function moPayApplyNotify($data){
+ Log::info('收到mopay代付异步回调:'.json_encode($data));
+
+ $sign=$this->createSign($this->key,$data);
+
+ if($sign==strtoupper($data['sign'])){
+ if($data['returncode']=='00'){
+ $order_info=UserWithdrawalModel::getUserDrawalInfo([
+ 'order_no'=>$data['orderid']
+ ]);
+ if($order_info && $order_info['status']==3){
+ UserWithdrawalModel::where([
+ 'id'=>$order_info['id']
+ ])->update([
+ 'order_idx'=>$data['transaction_id'],
+ 'status'=>4,
+ 'deal_time'=>date('Y-m-d H:i:s')
+ ]);
+ Log::info('mopay代付支付成功:'.json_encode($data));
+ }else{
+ Log::info('mopay代付订单不存在:'.json_encode($data));
+ }
+ }else{
+ UserWithdrawalModel::where([
+ 'order_no'=>$data['orderid']
+ ])->update([
+ 'status'=>1,
+ ]);
+ Log::info('mopay代付失败:'.json_encode($data));
+ }
+ }else{
+ Log::info('mopay代付签名校验失败:'.json_encode($data));
+ }
+ }
+ public function getBalance()
+ {
+ $post_data['merchant']=$this->merchant;
+ $sign=$this->generateQueryString($post_data,$this->key);
+ $post_data['sign']=$sign;
+ $header = array("Content-Type:application/x-www-form-urlencoded");
+ $res=$this->curlPost($this->bla_url,$post_data,10,$header);
+ $result=json_decode($res,true);
+ if($result['code']==200){
+ return [
+ 'amount'=>$result['data']['balanceUsable']
+ ];
+ }else{
+ return [
+ 'amount'=>0
+ ];
+ }
+ }
+
+ private function curlPost($url, $post_data = array(), $timeout = 5, $header = "", $data_type = "") {
+ $header = empty($header) ? '' : $header;
+ //支持json数据数据提交
+ if($data_type == 'json'){
+ $post_string = json_encode($post_data);
+ }elseif($data_type == 'array') {
+ $post_string = $post_data;
+ }elseif(is_array($post_data)){
+ $post_string = http_build_query($post_data, '', '&');
+ }
+
+ $ch = curl_init(); // 启动一个CURL会话
+ curl_setopt($ch, CURLOPT_URL, $url); // 要访问的地址
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 对认证证书来源的检查 // https请求 不验证证书和hosts
+ curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); // 从证书中检查SSL加密算法是否存在
+ curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']); // 模拟用户使用的浏览器
+ //curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1); // 使用自动跳转
+ //curl_setopt($curl, CURLOPT_AUTOREFERER, 1); // 自动设置Referer
+ curl_setopt($ch, CURLOPT_POST, true); // 发送一个常规的Post请求
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $post_string); // Post提交的数据包
+ curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout); // 设置超时限制防止死循环
+ curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
+ //curl_setopt($curl, CURLOPT_HEADER, 0); // 显示返回的Header区域内容
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // 获取的信息以文件流的形式返回
+ curl_setopt($ch, CURLOPT_HTTPHEADER, $header); //模拟的header头
+ $result = curl_exec($ch);
+ curl_close($ch);
+ return $result;
+ }
+ /**
+ * 创建签名
+ * @param $Md5key
+ * @param $list
+ * @return string
+ */
+ protected function createSign($Md5key, $list)
+ {
+ ksort($list);
+ $md5str = "";
+ foreach ($list as $key => $val) {
+ if (!empty($val) && !in_array($key,['sign','pay_md5sign'])) {
+ $md5str = $md5str . $key . "=" . $val . "&";
+ }
+ }
+ // 去除末尾的 '&'
+ $sign_str=$md5str . "key=" . $Md5key;
+ Log::info('mopay代付签名串:'.$sign_str);
+ $sign = strtoupper(md5($sign_str));
+ return $sign;
+ }
+
+
+
+}
\ No newline at end of file
diff --git a/app/home/service/NicePayService.php b/app/home/service/NicePayService.php
new file mode 100644
index 0000000..ce6de0f
--- /dev/null
+++ b/app/home/service/NicePayService.php
@@ -0,0 +1,242 @@
+app_key;
+ $post_data['balance']=$amount;
+ $post_data['ord_id']=$orderId;
+ $post_data['notify_url']=$notify_url.url('nicepay_notify');
+ $randomKey = array_rand($this->p_type);
+ $post_data['p_type']=$this->p_type[$randomKey];
+ $sign=$this->createSign($this->key,$post_data);
+ $post_data['sign']=$sign;
+ //$header = array("Content-Type:application/json;");
+ //$res=$this->curlPost($this->pay_url,$post_data,10,$header);
+ $res=$this->fetch_page_json($this->pay_url,$post_data);
+ Log::info('收到nicepay响应:'.$res."----".json_encode($post_data));
+ $result=json_decode($res,true);
+ return $result;
+ }
+ public function NicePayNotify($data){
+ Log::info('收到nicepay异步回调:'.json_encode($data));
+ if($this->check_sign($data,$this->key)){
+ if($data['status']==1){
+ $order_info=RechargeApplyModel::getOrderByNo([
+ 'order_no'=>$data['order']
+ ]);
+ if($order_info && $data['amount']==$order_info['total_amount']){
+ if($order_info['status']==0){
+ return (new PayService())->dealPayNotify($order_info);
+ }
+ }else{
+ Log::info('nicepay支付订单不存在:'.json_encode($data));
+ }
+ }else{
+ Log::info('nicepay支付订单支付失败:'.json_encode($data));
+ }
+ }else{
+ Log::info('nicepay签名校验失败:'.json_encode($data));
+ }
+ }
+ public function apply_pay($orderId,$amount,$bank_account,$nike_name,$ifsc)
+ {
+ $notify_url=env('PAY.NOTIFY_URL');
+ $post_data['app_key']=$this->app_key;
+ $post_data['balance']=round($amount,2);
+ $post_data['ord_id']=$orderId;
+ $post_data['card']=$bank_account;
+ $post_data['name']=$nike_name;
+
+ $randomKey = array_rand($this->p_type);
+ $post_data['p_type']=$this->p_type[$randomKey];
+ $post_data['ifsc']=$ifsc;
+ $post_data['notify_url']=$notify_url.'/bs/nicepay_anotify';
+
+ $sign=$this->createSign($this->key,$post_data);
+ $post_data['sign']=$sign;
+ Log::info('nicepay post:'.json_encode($post_data));
+
+ $header = array("Content-Type:application/json;charset=UTF-8");
+ //$res=$this->curlPost($this->app_url,$post_data,10,$header);
+ $res=$this->fetch_page_json($this->app_url,$post_data);
+ $result=json_decode($res,true);
+ Log::info('nicepay post结果:'.$res);
+ if($result['err']==0 && !empty($result)){
+ return [
+ 'code'=>200,
+ 'msg'=>'ok',
+ 'order_idx'=>'',
+ 'content'=>$res
+ ];
+ }else{
+ return [
+ 'code'=>300,
+ 'msg'=>$res,
+ 'order_idx'=>'',
+ 'content'=>$res
+ ];
+ }
+ }
+ public function NicePayApplyNotify($data){
+ Log::info('收到nicepay代付异步回调:'.json_encode($data));
+
+ if($this->check_sign($data,$this->key)){
+ if($data['status']==1){
+ $order_info=UserWithdrawalModel::getUserDrawalInfo([
+ 'order_no'=>$data['order']
+ ]);
+ if($order_info && $order_info['status']==3){
+ UserWithdrawalModel::where([
+ 'id'=>$order_info['id']
+ ])->update([
+ 'status'=>4,
+ 'deal_time'=>date('Y-m-d H:i:s')
+ ]);
+ Log::info('nicepay代付支付成功:'.json_encode($data));
+ }else{
+ Log::info('nicepay代付订单不存在:'.json_encode($data));
+ }
+ }else{
+ UserWithdrawalModel::where([
+ 'order_no'=>$data['order']
+ ])->update([
+ 'status'=>1,
+ ]);
+ Log::info('nicepay代付失败:'.json_encode($data));
+ }
+ }else{
+ Log::info('nicepay代付签名校验失败:'.json_encode($data));
+ }
+ }
+ public function getBalance()
+ {
+ $post_data['app_key']=$this->app_key;
+ $sign=$this->createSign($this->key,$post_data);
+ $post_data['sign']=$sign;
+// $header = array("Content-Type:application/json;charset=UTF-8");
+// $res=$this->curlPost($this->bla_url,$post_data,10,$header);
+ $res=$this->fetch_page_json($this->app_url,$post_data);
+ $result=json_decode($res,true);
+ if($result['err']==0 && !empty($result)){
+ return [
+ 'amount'=>$result['balance']
+ ];
+ }else{
+ return [
+ 'amount'=>0
+ ];
+ }
+ }
+ function fetch_page_json ($url, $params = null)
+ {
+ $ch = curl_init();
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($ch, CURLOPT_POST, true);
+ curl_setopt($ch, CURLOPT_HTTPHEADER, ["Content-Type:application/json;charset=UTF-8"]);
+ curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($params));
+ curl_setopt($ch, CURLOPT_URL, $url);
+
+ $result = curl_exec($ch);
+ $errno = curl_errno($ch);
+ $errmsg = curl_error($ch);
+ if ($errno != 0)
+ {
+ throw new Exception($errmsg, $errno);
+ }
+ curl_close($ch);
+ return $result;
+ }
+ private function check_sign($param,$salt){
+ $data = $param;
+ $sign = $data['sign'];
+ if(!$sign){
+ return false;
+ }
+ unset($data['sign']);
+ ksort($data);
+
+ $str="";
+ foreach ($data as $key => $value)
+ {
+ $str=$str.$value;
+ }
+ $str = $str."".$salt;
+ $check_sign = md5($str);
+
+ if($sign != $check_sign){
+ return false;
+ }else{
+ return true;
+ }
+ }
+ private function curlPost($url, $post_data = array(), $timeout = 5, $header = "", $data_type = "") {
+ $header = empty($header) ? '' : $header;
+ //支持json数据数据提交
+ if($data_type == 'json'){
+ $post_string = json_encode($post_data);
+ }elseif($data_type == 'array') {
+ $post_string = $post_data;
+ }elseif(is_array($post_data)){
+ $post_string = http_build_query($post_data, '', '&');
+ }
+
+ $ch = curl_init(); // 启动一个CURL会话
+ curl_setopt($ch, CURLOPT_URL, $url); // 要访问的地址
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 对认证证书来源的检查 // https请求 不验证证书和hosts
+ curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); // 从证书中检查SSL加密算法是否存在
+ curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']); // 模拟用户使用的浏览器
+ //curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1); // 使用自动跳转
+ //curl_setopt($curl, CURLOPT_AUTOREFERER, 1); // 自动设置Referer
+ curl_setopt($ch, CURLOPT_POST, true); // 发送一个常规的Post请求
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $post_string); // Post提交的数据包
+ curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout); // 设置超时限制防止死循环
+ curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
+ //curl_setopt($curl, CURLOPT_HEADER, 0); // 显示返回的Header区域内容
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // 获取的信息以文件流的形式返回
+ curl_setopt($ch, CURLOPT_HTTPHEADER, $header); //模拟的header头
+ $result = curl_exec($ch);
+ curl_close($ch);
+ return $result;
+ }
+ /**
+ * 创建签名
+ * @param $Md5key
+ * @param $list
+ * @return string
+ */
+ protected function createSign($salt, $param)
+ {
+ $data = $param;
+ ksort($data);
+
+ $str="";
+ foreach ($data as $key => $value)
+ {
+ $str=$str.$value;
+ }
+ $str = $str.$salt;
+ return md5($str);
+ }
+
+
+
+}
\ No newline at end of file
diff --git a/app/home/service/PayService.php b/app/home/service/PayService.php
new file mode 100644
index 0000000..5c0795f
--- /dev/null
+++ b/app/home/service/PayService.php
@@ -0,0 +1,305 @@
+ 1,
+ 'is_recharge' => 1,
+ 'is_online' => $data['is_online']
+ ])->order('id', 'desc')->select()->toArray();
+
+ return $this->toData(0, 'Request successful.', $list);
+ }
+
+ /**
+ * 用户充值申请入库1
+ * @param array $data
+ * @return array
+ */
+ public function insertRechargeApply(array $data): array
+ {
+ $channel = PaymentListModel::getPaymentInfo([
+ 'id' => $data['recharge_channel']
+ ]);
+
+ if (empty($channel)) {
+ return $this->toData('100110', 'The system is busy. Please try again later.1', []);
+ }
+ if (empty($data['country'])) {
+ return $this->toData('100120', 'The system is busy. Please try again later.2', []);
+ }
+ if (empty($data['recharge_num']) || $data['recharge_num'] <= 0) {
+ return $this->toData('100130', 'The system is busy. Please try again later.3', []);
+ }
+ if($channel['type']==9){
+ //1USD=1USDT
+ $currency_rate = 1;
+ if($data['product']=='TRC20Buy'){
+ switch ($data['extra']){
+ case 'GBP':
+ $gpx_rate=StockMarketModel::where('stock_market_type',14)->value('rate');
+ $currency_rate=$gpx_rate/100;
+ break;
+ case "EUR":
+ $eur_rate=StockMarketModel::where('stock_market_type',15)->value('rate');
+ $currency_rate=$eur_rate*1;
+ break;
+ }
+ }
+ }else{
+ $currency_rate = $channel['exchange_rate'];
+ }
+ //$currency_rate=(new StockMarketModel)->getRate(4);
+ if ($data['account_type'] > 2 && ($data['account_type'] != 8)) {
+ $market_rate = (new StockMarketModel)->getRate($data['account_type']);
+ } else {
+ $market_rate = 1;
+ }
+ $market_amount = $data['recharge_num'] * $market_rate;
+ $market_amount = round($market_amount, 2);
+
+ if ($channel['pay_type'] == 1) {
+ $fee = $data['recharge_num'] * $currency_rate * $channel['service_rate'];
+ $server_fee = $market_amount * $channel['service_rate'];
+ } else {
+ $fee = $currency_rate * $channel['service_rate'];
+ $server_fee = $market_rate * $channel['service_rate'];
+ }
+ $total_amount = $data['recharge_num'] * $currency_rate + $fee;
+ $total_amount = round($total_amount, 2);
+
+ if ($data['is_online'] == 1 && $total_amount > 100000) {
+ return $this->toData('101900', 'Online payment scope: 100 - 100000');
+ }
+ $data['service_fee'] = $server_fee;//手续费用
+ $data['market_amount'] = $market_amount; //换算的市场金额
+ $data['total_amount'] = $total_amount; //要支付的渠道货币金额
+ $data['currency_rate'] = $currency_rate;
+ if ($channel['channel_type'] == 'Bank') {
+ $data['recharge_type'] = 2;
+ } else {
+ $data['recharge_type'] = 1;
+ }
+
+ $data['order_no'] = $this->generateOrderNumber();
+
+ $order_id = RechargeApplyModel::InsertUserRecharge($data);
+ if ($order_id) {
+ switch ($channel['type']) {
+ case 2:
+ $result = (new IndPayService())->indPay($data['order_no'], $data['total_amount']);
+ if ($result['status'] == 'SUCCESS') {
+ RechargeApplyModel::where('order_no', $data['order_no'])->update([
+ 'order_idx' => $result['order_no'],
+ 'pay_url' => $result['order_data'],
+ ]);
+ return $this->toData(0, 'Request successful.', [
+ 'type' => 'bank_pay',
+ 'pay_url' => $result['order_data'],
+ 'order_no' => $result['mer_order_no'],
+ ]);
+ } else {
+ return $this->toData('100900', 'The system is busy. Please try again later.4', [$result['err_msg'], $result['err_code']]);
+ }
+ break;
+ case 3:
+ $result = (new MoPayService())->create_order($data['order_no'], $data['total_amount']);
+ if ($result['status'] == 'SUCCESS') {
+ RechargeApplyModel::where('order_no', $data['order_no'])->update([
+ 'pay_url' => $result['data']['pay_url'],
+ ]);
+ return $this->toData(0, 'Request successful.', [
+ 'type' => 'bank_pay',
+ 'pay_url' => $result['data']['pay_url'],
+ 'order_no' => $data['order_no'],
+ ]);
+ } else {
+ return $this->toData('100600', 'The system is busy. Please try again later.5', [$result['err_msg'], $result['err_code']]);
+ }
+ break;
+ case 4:
+ $result = (new HTPayService())->qrPay($data['order_no'], round($data['total_amount']));
+ if ($result['status'] == 1) {
+ RechargeApplyModel::where('order_no', $data['order_no'])->update([
+ 'order_idx' => $result['orderNo'],
+ 'pay_url' => $result['payUrl'],
+ 'total_amount' => $result['oriAmount']
+ ]);
+ return $this->toData(0, 'Request successful.', [
+ 'type' => 'bank_pay',
+ 'pay_url' => $result['payUrl'],
+ 'order_no' => $data['order_no'],
+ ]);
+
+ } else {
+ return $this->toData('101900', 'The system is busy. Please try again later.6', [$result['status'], $result['message']]);
+ }
+ break;
+ case 5:
+ $result = (new XdPayService())->create_order($data['order_no'], $data['total_amount']);
+ if ($result['code'] == 200) {
+ RechargeApplyModel::where('order_no', $data['order_no'])->update([
+ 'pay_url' => $result['data']['url'],
+ ]);
+ return $this->toData(0, 'Request successful.', [
+ 'type' => 'bank_pay',
+ 'pay_url' => $result['data']['url'],
+ 'order_no' => $data['order_no'],
+ ]);
+ } else {
+ return $this->toData('101900', 'The system is busy. Please try again later.7', [$result['code'], $result['msg']]);
+ }
+ break;
+ case 6:
+ $result = (new QeaePayService())->create_order($data['order_no'], $data['total_amount']);
+ if ($result['respCode'] == 'SUCCESS') {
+ RechargeApplyModel::where('order_no', $data['order_no'])->update([
+ 'pay_url' => $result['payInfo'],
+ ]);
+ return $this->toData(0, 'Request successful.', [
+ 'type' => 'bank_pay',
+ 'pay_url' => $result['payInfo'],
+ 'order_no' => $data['order_no'],
+ ]);
+ } else {
+ return $this->toData('101900', 'The system is busy. Please try again later.8', [$result['respCode'], $result['tradeMsg']]);
+ }
+ break;
+ case 7:
+ $result = (new NicePayService())->create_order($data['order_no'], $data['total_amount']);
+ if ($result['err'] == 0 && !empty($result)) {
+ RechargeApplyModel::where('order_no', $data['order_no'])->update([
+ 'pay_url' => $result['url'],
+ ]);
+ return $this->toData(0, 'Request successful.', [
+ 'type' => 'bank_pay',
+ 'pay_url' => $result['url'],
+ 'order_no' => $data['order_no'],
+ ]);
+ } else {
+ return $this->toData('101900', 'The system is busy. Please try again later.9', [$result['err'], $result['err_msg']]);
+ }
+ break;
+ case 8:
+ $result = (new ClickPayService())->create_order($data['order_no'], $data['total_amount']);
+ if (strtoupper($result['platRespCode']) == 'SUCCESS') {
+ RechargeApplyModel::where('order_no', $data['order_no'])->update([
+ 'order_idx' => $result['platOrderNum'],
+ ]);
+ return $this->toData(0, 'Request successful.', [
+ 'type' => 'bank_pay',
+ 'pay_url' => $result['payData'],
+ 'order_no' => $data['order_no'],
+ ]);
+ } else {
+ return $this->toData('101900', 'The system is busy. Please try again later.10');
+ }
+ break;
+ case 9:
+ if(in_array(trim($data['product']),['TRC20H5','TRC20Buy'])){
+ $result = (new StarPayService())->create_order($data['order_no'], $data['total_amount'],$data['product'],$data['extra']);
+ if ($result['code'] == 200) {
+ $respon=json_decode($result['params'],true);
+ RechargeApplyModel::where('order_no', $data['order_no'])->update([
+ 'pay_url' => $respon['payurl'],
+ ]);
+ return $this->toData(0, 'Request successful.', [
+ 'type' => 'bank_pay',
+ 'pay_url' => $respon['payurl'],
+ 'order_no' => $data['order_no'],
+ ]);
+ } else {
+ return $this->toData('100600', 'The system is busy. Please try again later.5', $result);
+ }
+ }else{
+ return $this->toData('102000', 'The system is busy. Please try again later.20');
+ }
+ break;
+ default:
+ return $this->toData(0, 'Request successful.', []);
+ break;
+ }
+
+ } else {
+ return $this->toData(100140, 'The system is busy. Please try again later.10', []);
+ }
+ }
+
+ public function dealPayNotify($order_info)
+ {
+ $wallet = new WalletService();
+ // 启动事务
+ Db::startTrans();
+ try {
+ //查询划转资金账户信息
+ $account = $wallet->lockUserBalance($order_info['account_type'], $order_info['user_id']);
+ if (empty($account)) {
+ Db::rollback();
+ return [
+ 'code' => 100,
+ 'msg' => 'FAIL'
+ ];
+ }
+ // 新增转入 特别需要注意的是,股票账户需要进行汇率转换 现货\合约\美股都是USD
+ $update_data['usable_num'] = $account['usable_num'] + $order_info['market_amount'];
+ $res = $wallet->updateUserBalance($order_info['account_type'], $update_data, $order_info['user_id']);
+ if (empty($res)) {
+ Db::rollback();
+ return [
+ 'code' => 300,
+ 'msg' => 'FAIL'
+ ];
+ }
+ //插入资金变动日志
+ $logs['user_id'] = $order_info['user_id'];
+ $logs['change_type'] = 1;
+ $logs['change_num'] = $order_info['market_amount'];
+ $logs['before_num'] = $account['usable_num'];
+ $logs['order_id'] = $order_info['order_no'];
+ $log_res = $wallet->addUserBalanceLog($order_info['account_type'], $logs);
+ if (empty($log_res)) {
+ Db::rollback();
+ return [
+ 'code' => 400,
+ 'msg' => 'FAIL'
+ ];
+ }
+ //修改订单状态
+ RechargeApplyModel::where('id', $order_info['id'])->update([
+ 'status' => 1,
+ 'deal_time' => date('Y-m-d H:i:s'),
+ ]);
+ // 提交事务
+ Db::commit();
+ return [
+ 'code' => 200,
+ 'msg' => 'SUCCESS'
+ ];
+ } catch (\Exception $e) {
+ // 出现异常,回滚事务
+ Db::rollback();
+ return [
+ 'code' => 500,
+ 'msg' => $e->getMessage()
+ ];
+ }
+ }
+
+
+}
\ No newline at end of file
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/PreStockService.php b/app/home/service/PreStockService.php
new file mode 100644
index 0000000..72ef06e
--- /dev/null
+++ b/app/home/service/PreStockService.php
@@ -0,0 +1,145 @@
+toData('1', 'Params error');
+ }
+
+ $server = new IPOService();
+ return $server->index($param['market_type'], $param);
+ } catch (\Exception $exception) {
+ return $this->toData('0', 'The system is busy. Please try again later.', [$exception->getMessage(),$exception->getTrace()]);
+ }
+ }
+
+ // 列表
+ public function stockDetail($param)
+ {
+ try {
+ // stock_type 3 美股 4 印尼 5 马股 6 泰股
+ if (empty($param['market_type'])) {
+ return $this->toData('1', 'Params error');
+ }
+
+ $server = new IPOService();
+ return $server->stockDetail($param['market_type'], $param);
+ } catch (\Exception $exception) {
+ return $this->toData('0', 'The system is busy. Please try again later.', [$exception->getMessage()]);
+ }
+ }
+
+ // 下单
+ public function order($param, $userId)
+ {
+ try {
+ if (empty($userId)) {
+ return $this->toData('1', 'Login fail');
+ }
+
+ // 需要完成实名认证之后才能下单
+ $user = UserModel::where('user_id', $userId)->find();
+ if (empty($user) || $user->is_real != 1) {
+ return $this->toData('405', 'Only after completing real-name authentication can you place an order.');
+ }
+
+ // stock_type 3 美股 4 印尼 5 马股 6 泰股
+ if (empty($param['market_type'])) {
+ return $this->toData('1', 'Params error');
+ }
+
+ $server = new IPOService();
+ return $server->order($param['market_type'], $param, $userId);
+ } catch (\Exception $exception) {
+ return $this->toData('0', 'The system is busy. Please try again later.', [$exception->getMessage()]);
+ }
+ }
+
+ // 后支付-付款
+ /*
+
+ 支付金额(先支付)= 申购数量*申购价格+手续费
+ 申购开始时间-公布中签时间
+ 支付金额(后支付)=申购数量*申购价格+手续费
+ 公布中签时间-申购截止时间
+ 支付金额(后支付)=分配数量*申购价格+手续费
+
+ */
+ public function postPay($param, $userId)
+ {
+ try {
+ if (empty($userId)) {
+ return $this->toData('1', 'Login fail');
+ }
+
+ // 需要完成实名认证之后才能下单
+ $user = UserModel::where('user_id', $userId)->find();
+ if (empty($user) || $user->is_real != 1) {
+ return $this->toData('405', 'Only after completing real-name authentication can you place an order.');
+ }
+
+ // stock_type 3 美股 4 印尼 5 马股 6 泰股
+ if (empty($param['market_type'])) {
+ return $this->toData('1', 'Params error');
+ }
+
+
+ $server = new IPOService();
+ return $server->postPay($param['market_type'], $param, $userId);
+ } catch (\Exception $exception) {
+ return $this->toData('0', 'The system is busy. Please try again later.', [$exception->getMessage()]);
+ }
+ }
+
+ // 申购记录
+ public function list($param, $userId)
+ {
+ try {
+ // stock_type 3 美股 4 印尼 5 马股 6 泰股
+ if (empty($param['market_type'])) {
+ return $this->toData('1', 'Params error');
+ }
+
+ if (empty($userId)) {
+ return $this->toData('1', 'Login fail');
+ }
+
+ $server = new IPOService();
+ return $server->list($param['market_type'], $param, $userId);
+ } catch (\Exception $exception) {
+ return $this->toData('0', 'The system is busy. Please try again later.', [$exception->getMessage()]);
+ }
+ }
+
+ // 申购订单详情
+ public function detail($param, $userId)
+ {
+ try {
+ // stock_type 3 美股 4 印尼 5 马股 6 泰股
+ if (empty($param['market_type'])) {
+ return $this->toData('1', 'Params error');
+ }
+
+ if (empty($userId)) {
+ return $this->toData('1', 'Login fail');
+ }
+
+ $server = new IPOService();
+ return $server->detail($param['market_type'], $param, $userId);
+ } catch (\Exception $exception) {
+ return $this->toData('0', 'The system is busy. Please try again later.', [$exception->getMessage()]);
+ }
+ }
+}
\ 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/QeaePayService.php b/app/home/service/QeaePayService.php
new file mode 100644
index 0000000..4233728
--- /dev/null
+++ b/app/home/service/QeaePayService.php
@@ -0,0 +1,228 @@
+key = env('QEAE_PAY.KEY');
+ $this->df_key = env('QEAE_PAY.DF_KEY');
+ $this->merchant = env('QEAE_PAY.MERCHANT');
+ }
+
+
+ /**
+ * @param $orderId // 订单id
+ * @param $amount
+ * @return mixed
+ */
+ public function create_order($orderId,$amount)
+ {
+ // order_no
+ $notify_url = env('PAY.NOTIFY_URL');
+ $post_data['goods_name'] = $orderId; // 商品名称必传参数 不超过50字节
+ $post_data['mch_id'] = $this->merchant; //商户号
+ $post_data['mch_order_no'] = $orderId; //商家订单号
+ $post_data['order_date'] = date('Y-m-d H:i:s'); // 订单时间
+ $post_data['pay_type'] = $this->pay_type; // 支付类型
+ $post_data['trade_amount'] = $amount; //交易金额 当地货币 精确到元
+ $post_data['version'] = '1.0'; //版本号
+ $post_data['notify_url'] = $notify_url.url('qeaepay_notify');
+
+ $sign = $this->generateQueryString($post_data,$this->key);
+ $post_data['sign'] = $sign;
+ $post_data['sign_type'] = 'MD5'; // 签名方式固定MD5
+ $header = array("Content-Type:application/x-www-form-urlencoded");
+ $res = $this->curlPost($this->pay_url,$post_data,10,$header);
+ $result = json_decode($res,true);
+
+ return $result;
+ }
+ // 异步回调处理
+ public function qeaePayNotify($data){
+ Log::info('收到QeaePay异步回调:'.json_encode($data));
+
+ $sign=$this->generateQueryString($data,$this->key);
+
+ if($sign==strtolower($data['sign'])){
+
+ if($data['tradeResult']==1){
+ $order_info=RechargeApplyModel::getOrderByNo([
+ 'order_no'=>$data['mchOrderNo']
+ ]);
+ if($order_info && $data['amount']==$order_info['total_amount']){
+ if($order_info['status']==0){
+ return (new PayService())->dealPayNotify($order_info);
+ }
+ }else{
+ Log::info('QeaePay支付订单不存在:'.json_encode($data));
+ }
+ }else{
+ Log::info('QeaePay支付订单支付失败:'.json_encode($data));
+ }
+ }else{
+ Log::info('QeaePay签名校验失败:'.json_encode($data));
+ }
+
+ }
+ // 代付
+ public function apply_pay($orderId,$amount,$bank_account,$nike_name,$ifsc,$bank_code)
+ {
+ $notify_url=env('PAY.NOTIFY_URL');
+
+ $post_data['sign_type'] = 'MD5'; // 加密方式
+ $post_data['mch_id'] = $this->merchant; //商家编号
+ $post_data['mch_transferId'] = $orderId; //商家转账订单号
+ $post_data['transfer_amount'] = floor($amount); //转账金额
+ $post_data['apply_date'] = date('Y-m-d H:i:s'); // 订单时间;
+ $post_data['bank_code'] = $bank_code; // 收款银行代码
+ $post_data['receive_name'] = $nike_name; // 收款银行户名
+ $post_data['receive_account'] = $bank_account; // 收款银行账号
+ $post_data['back_url'] = $notify_url.'/bs/qeaepay_appNotify';
+
+ $post_data['remark'] = $ifsc;
+ $sign=$this->generateQueryString($post_data,$this->df_key);
+ $post_data['sign']=$sign;
+ $header = array("Content-Type:application/x-www-form-urlencoded");
+ $res=$this->curlPost($this->app_url,$post_data,10,$header);
+ $result=json_decode($res,true);
+
+ if($result['respCode']=='SUCCESS'){
+ return [
+ 'code'=>200,
+ 'msg'=>'ok',
+ 'order_idx'=>$result['tradeNo'],
+ 'content'=>$res
+ ];
+ }else{
+ return [
+ 'code'=>300,
+ 'msg'=>$result['errorMsg'],
+ 'order_idx'=>'',
+ 'content'=>$res
+ ];
+ }
+ }
+ public function qeaePayApplyNotify($data){
+ Log::info('收到qeaepay代付异步回调:'.json_encode($data));
+// $data['reverse']=$data['reverse'] ? 'true':'false';
+
+ $sign=$this->generateQueryString($data,$this->df_key);
+ if($sign==strtolower($data['sign'])){
+ if($data['tradeResult']==1){
+ $order_info=UserWithdrawalModel::getUserDrawalInfo([
+ 'order_no'=>$data['merTransferId']
+ ]);
+ if($order_info && $order_info['status']==3){
+ UserWithdrawalModel::where([
+ 'id'=>$order_info['id']
+ ])->update([
+ 'status'=>4,
+ 'deal_time'=>date('Y-m-d H:i:s')
+ ]);
+ Log::info('qeaepay代付支付成功:'.json_encode($data));
+ }else{
+ Log::info('qeaepay代付订单不存在:'.json_encode($data));
+ }
+ }else{
+ UserWithdrawalModel::where([
+ 'order_no'=>$data['orderId']
+ ])->update([
+ 'status'=>1,
+ ]);
+ Log::info('xdpay代付失败:'.json_encode($data));
+ }
+ }else{
+ Log::info('xdpay代付签名校验失败:'.json_encode($data));
+ }
+ }
+ public function getBalance()
+ {
+ $post_data['mch_id']=$this->merchant;
+ $sign=$this->generateQueryString($post_data,$this->key);
+ $post_data['sign']=$sign;
+ $post_data['sign_type']='MD5';
+ $header = array("Content-Type:application/x-www-form-urlencoded");
+ $res=$this->curlPost($this->bla_url,$post_data,10,$header);
+ $result=json_decode($res,true);
+ if($result['respCode']=='SUCCESS'){
+ return [
+ 'amount'=>$result['availableAmount']
+ ];
+ }else{
+ return [
+ 'amount'=>0
+ ];
+ }
+ }
+ private function curlPost($url, $post_data = array(), $timeout = 5, $header = "", $data_type = "") {
+ $header = empty($header) ? '' : $header;
+ //支持json数据数据提交
+ if($data_type == 'json'){
+ $post_string = json_encode($post_data);
+ }elseif($data_type == 'array') {
+ $post_string = $post_data;
+ }elseif(is_array($post_data)){
+ $post_string = http_build_query($post_data, '', '&');
+ }
+
+ $ch = curl_init(); // 启动一个CURL会话
+ curl_setopt($ch, CURLOPT_URL, $url); // 要访问的地址
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 对认证证书来源的检查 // https请求 不验证证书和hosts
+ curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); // 从证书中检查SSL加密算法是否存在
+ curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']); // 模拟用户使用的浏览器
+ //curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1); // 使用自动跳转
+ //curl_setopt($curl, CURLOPT_AUTOREFERER, 1); // 自动设置Referer
+ curl_setopt($ch, CURLOPT_POST, true); // 发送一个常规的Post请求
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $post_string); // Post提交的数据包
+ curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout); // 设置超时限制防止死循环
+ curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
+ //curl_setopt($curl, CURLOPT_HEADER, 0); // 显示返回的Header区域内容
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // 获取的信息以文件流的形式返回
+ curl_setopt($ch, CURLOPT_HTTPHEADER, $header); //模拟的header头
+ $result = curl_exec($ch);
+ curl_close($ch);
+ return $result;
+ }
+ private function generateQueryString($fields, $privateKey) {
+ // 按ASCII顺序对字段名进行自然排序
+ ksort($fields);
+
+ // 将字段按 k=v 格式拼接成字符串
+ $query = '';
+ foreach($fields as $key => $value) {
+ // sign 和signType 不参与签名
+ if($key!='sign' && $key != 'sign_type'){
+ $query .= $key . '=' . strval($value) . '&';
+ }
+ }
+ // 去除末尾的 '&'
+ $query = rtrim($query, '&');
+ // 在字符串末尾拼接私钥
+ $query .= '&key=' . $privateKey;
+ $sign=md5($query);
+ return $sign;
+ }
+
+
+}
\ No newline at end of file
diff --git a/app/home/service/StarPayService.php b/app/home/service/StarPayService.php
new file mode 100644
index 0000000..780643d
--- /dev/null
+++ b/app/home/service/StarPayService.php
@@ -0,0 +1,149 @@
+merchant_no;
+ $post_data['timestamp'] = time();
+ $post_data['sign_type'] = 'MD5';
+
+ $params['merchant_ref']=$orderId;
+ $params['product']=$product;
+ $params['amount']=$amount;
+ $params['extra']=(object) [];
+ if($product=='TRC20Buy'){
+ $params['extra']->fiat_currency=$fiat_currency;
+ }
+ $post_data['params'] = json_encode($params);
+
+
+ $post_data['sign'] =$this->sign_data($post_data);
+
+ Log::info('starPay post-: ' . json_encode($post_data));
+ $header = array("Content-Type:application/x-www-form-urlencoded");
+ $res=$this->curlPost($this->pay_url,$post_data,10,$header);
+ Log::info('starPay 返回-: ' . $res);
+ $result=json_decode($res,true);
+ return $result;
+ }
+ public function starPayNotify($data){
+ Log::info('收到star_pay异步回调:'.json_encode($data));
+ $sign=$this->sign_data($data);
+ if($sign==$data['sign']){
+ Log::info('star_pay签名校验成功:'.json_encode($data));
+ $result=json_decode($data['params'],true);
+ if($result['status']==1){
+ $order_info=RechargeApplyModel::getOrderByNo([
+ 'order_no'=>$result['merchant_ref']
+ ]);
+ if($order_info && $result['amount']==$order_info['total_amount']){
+ if($order_info['status']==0){
+ return (new PayService())->dealPayNotify($order_info);
+ }
+ }else{
+ Log::info('star_pay支付订单不存在:'.json_encode($data));
+ }
+ }else{
+ Log::info('star_pay支付订单支付失败:'.json_encode($data));
+ }
+ }else{
+ Log::info('star_pay签名校验失败:'.json_encode($data));
+ }
+ return [
+ 'code'=>300,
+ 'msg'=>'FAIL'
+ ];
+
+ }
+ private function sign_data($post_data){
+ if(is_array($post_data['params'])){
+ $sign_str=$this->merchant_no.json_encode($post_data['params']).$post_data['sign_type'].$post_data['timestamp'].$this->sign_key;
+ }else{
+ $sign_str=$this->merchant_no.$post_data['params'].$post_data['sign_type'].$post_data['timestamp'].$this->sign_key;
+ }
+
+ Log::info('star_pay签名:'.json_encode($sign_str));
+ return md5($sign_str);
+ }
+ public function getTRC20BuyList()
+ {
+ $gpx_rate=StockMarketModel::where('stock_market_type',14)->value('rate');
+ $eur_rate=StockMarketModel::where('stock_market_type',15)->value('rate');
+ $json=[
+ [
+ "bank_name"=>"GBP",
+ "bank_code"=> "GBP",
+ "exchange_rate"=>$gpx_rate/100,
+ "unit"=>'GBP',
+ "min_num"=>10,
+ "max_num"=>30000,
+ ],
+ [
+ "bank_name"=> "USD",
+ "bank_code"=> "USD",
+ "exchange_rate"=>1,
+ "unit"=>'USD',
+ "min_num"=>10,
+ "max_num"=>100000,
+ ],
+ [
+ "bank_name"=> "EUR",
+ "bank_code"=> "EUR",
+ "exchange_rate"=>$eur_rate,
+ "unit"=>'EUR',
+ "min_num"=>10,
+ "max_num"=>92945,
+ ],
+ ];
+ return $this->toData('0', 'SUCCESS', $json);
+ }
+ private function curlPost($url, $post_data = array(), $timeout = 5, $header = "", $data_type = "")
+ {
+ $header = empty($header) ? '' : $header;
+ //支持json数据数据提交
+ if ($data_type == 'json') {
+ $post_string = json_encode($post_data);
+ } elseif ($data_type == 'array') {
+ $post_string = $post_data;
+ } elseif (is_array($post_data)) {
+ $post_string = http_build_query($post_data, '', '&');
+ }
+
+ $ch = curl_init(); // 启动一个CURL会话
+ curl_setopt($ch, CURLOPT_URL, $url); // 要访问的地址
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 对认证证书来源的检查 // https请求 不验证证书和hosts
+ curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); // 从证书中检查SSL加密算法是否存在
+ curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']); // 模拟用户使用的浏览器
+ //curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1); // 使用自动跳转
+ //curl_setopt($curl, CURLOPT_AUTOREFERER, 1); // 自动设置Referer
+ curl_setopt($ch, CURLOPT_POST, true); // 发送一个常规的Post请求
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $post_string); // Post提交的数据包
+ curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout); // 设置超时限制防止死循环
+ curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
+ //curl_setopt($curl, CURLOPT_HEADER, 0); // 显示返回的Header区域内容
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // 获取的信息以文件流的形式返回
+ curl_setopt($ch, CURLOPT_HTTPHEADER, $header); //模拟的header头
+ $result = curl_exec($ch);
+ curl_close($ch);
+ return $result;
+ }
+
+
+
+}
\ No newline at end of file
diff --git a/app/home/service/StockService.php b/app/home/service/StockService.php
new file mode 100644
index 0000000..6c69e8d
--- /dev/null
+++ b/app/home/service/StockService.php
@@ -0,0 +1,67 @@
+toData('0', 'SUCCESS', ['status' => '2']);
+ }
+
+ // 1 开启 2 关闭
+ $market = StockMarketModel::where('stock_market_type', $param['type'])->find();
+ if(empty($market)){
+ return $this->toData('0', 'SUCCESS', ['status' => '2']);
+ }
+
+ if($market->status == StockMarketModel::STATUS_OFF){
+ return $this->toData('0', 'SUCCESS', ['status' => '2', 'market' => $market->toArray()]);
+ }
+
+ // 如果是开启 则判断是否在开盘时间段
+ $date = date('H:i');
+ $dateTime = \DateTime::createFromFormat('H:i', $date);
+ $amOpenTime = \DateTime::createFromFormat('H:i', $market->am_open_time);
+ $pmOpenTime = \DateTime::createFromFormat('H:i', $market->pm_open_time);
+ $amCloseTime = \DateTime::createFromFormat('H:i', $market->am_close_time);
+ $pmCloseTime = \DateTime::createFromFormat('H:i', $market->pm_close_time);
+
+ // 判断 上午盘
+ if($amOpenTime > $amCloseTime){
+ // 开盘时间 大于 闭盘时间 跨天
+ if($dateTime >= $amOpenTime || $dateTime <= $amCloseTime){
+ return $this->toData('0', 'SUCCESS', ['status' => '1','market' => $market->toArray(),$dateTime,$amOpenTime,$amCloseTime,1]);
+ }
+ } else {
+ if($dateTime >= $amOpenTime && $dateTime <= $amCloseTime){
+ return $this->toData('0', 'SUCCESS', ['status' => '1','market' => $market->toArray(),$dateTime,$amOpenTime,$amCloseTime,2]);
+ }
+ }
+
+ // 下午盘
+ if($pmOpenTime > $pmCloseTime){
+ // 开盘时间 大于 闭盘时间 跨天
+ if($dateTime >= $pmOpenTime || $dateTime <= $pmCloseTime){
+ return $this->toData('0', 'SUCCESS', ['status' => '1','market' => $market->toArray(),$dateTime,$pmOpenTime,$pmCloseTime,3]);
+ }
+ } else {
+ if($dateTime >= $pmOpenTime && $dateTime <= $pmCloseTime){
+ return $this->toData('0', 'SUCCESS', ['status' => '1','market' => $market->toArray(),$dateTime,$pmOpenTime,$pmCloseTime,4]);
+ }
+ }
+
+ return $this->toData('0', 'SUCCESS', ['status' => '2','market' => $market->toArray()]);
+ }catch (\Exception $exception){
+ return $this->toData('400','System error',[$exception->getMessage()]);
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/app/home/service/TeamService.php b/app/home/service/TeamService.php
new file mode 100644
index 0000000..e173ab6
--- /dev/null
+++ b/app/home/service/TeamService.php
@@ -0,0 +1,197 @@
+$user_id
+ ]);
+ $level2_num=UserLevelModel::getUserLevelCount([
+ 'grandpa_id'=>$user_id
+ ]);
+ $level3_num=UserLevelModel::getUserLevelCount([
+ 'top_id'=>$user_id
+ ]);
+
+ //总人数
+ $total_num=$level_num+$level2_num+$level3_num;
+
+ $users_level=UserLevelModel::getUsers([
+ 'parent_id'=>$user_id
+ ]);
+ if(!empty($users_level)){
+ $users_level_arr=array_column($users_level,'user_id');
+ $pay_level=RechargeApplyModel::getUserPayNum($users_level_arr);
+ }else{
+ $pay_level=0;
+ }
+ $users_level2=UserLevelModel::getUsers([
+ 'grandpa_id'=>$user_id
+ ]);
+ if(!empty($users_level2)){
+ $users_level2_arr=array_column($users_level2,'user_id');
+ $pay_level2=RechargeApplyModel::getUserPayNum($users_level2_arr);
+ }else{
+ $pay_level2=0;
+ }
+ $users_level3=UserLevelModel::getUsers([
+ 'top_id'=>$user_id
+ ]);
+ if(!empty($users_level3)){
+ $users_level3_arr=array_column($users_level3,'user_id');
+ $pay_level3=RechargeApplyModel::getUserPayNum($users_level3_arr);
+ }else{
+ $pay_level3=0;
+ }
+
+ $total_pay=$pay_level+$pay_level2+$pay_level3;
+
+
+
+ //总收入
+ $level_back_num=UserBrokerageModel::getUserBrokerageNum([
+ 'user_id'=>$user_id,
+ 'level_type'=>1
+ ],'brokerage_num');
+ $level2_back_num=UserBrokerageModel::getUserBrokerageNum([
+ 'user_id'=>$user_id,
+ 'level_type'=>2
+ ],'brokerage_num');
+ $level3_back_num=UserBrokerageModel::getUserBrokerageNum([
+ 'user_id'=>$user_id,
+ 'level_type'=>3
+ ],'brokerage_num');
+
+ $total_back_num=$level_back_num+$level2_back_num+$level3_back_num;
+
+ //今日收入
+ $today=date('Y-m-d 00:00:00');
+ $level_today_num=UserBrokerageModel::getUserBrokerageNum([
+ ['user_id','=',$user_id],
+ ['level_type','=',1],
+ ['create_time','>=',$today],
+ ],'brokerage_num');
+ $level2_today_num=UserBrokerageModel::getUserBrokerageNum([
+ ['user_id','=',$user_id],
+ ['level_type','=',2],
+ ['create_time','>=',$today],
+ ],'brokerage_num');
+ $level3_today_num=UserBrokerageModel::getUserBrokerageNum([
+ ['user_id','=',$user_id],
+ ['level_type','=',3],
+ ['create_time','>=',$today],
+ ],'brokerage_num');
+
+
+ $today_back_num=$level_today_num+$level2_today_num+$level3_today_num;
+
+ $result=[
+ 'total_num'=>[
+ 'reg_num'=>$total_num,
+ 'recharge_num'=>$total_pay,
+ 'back_num'=>$total_back_num,
+ 'today_back_num'=>$today_back_num
+ ],
+ 'level1'=>[
+ 'reg_num'=>$level_num,
+ 'recharge_num'=>$pay_level,
+ 'back_num'=>$level_back_num,
+ 'today_back_num'=>$level2_today_num
+ ],
+ 'level2'=>[
+ 'reg_num'=>$level2_num,
+ 'recharge_num'=>$pay_level2,
+ 'back_num'=>$level2_back_num,
+ 'today_back_num'=>$level2_today_num
+ ],
+ 'level3'=>[
+ 'reg_num'=>$level3_num,
+ 'recharge_num'=>$pay_level3,
+ 'back_num'=>$level3_back_num,
+ 'today_back_num'=>$level3_today_num
+ ]
+
+ ];
+
+ return $this->toData(0,'Request successful.',$result);
+ }
+
+ public function getUserTeamBack(array $data) : array
+ {
+ $list=UserBrokerageModel::getUserBrokerageList($data);
+ return $this->toData(0,'Request successful.',$list);
+ }
+ public function getUserTeamList(array $data):array
+ {
+ $list=UserLevelModel::getUserTeamList($data);
+ return $this->toData(0,'Request successful.',$list);
+ }
+
+ //注册返佣
+ public function regBrokerage(int $parent_id,int $grandpa_id,int $top_id)
+ {
+ $reg_brokerage_stting=$this->getBrokerageRegSetting();
+ $reg_parent_brokerage=$reg_brokerage_stting['parent_fee'];
+ $reg_grandpa_brokerage=$reg_brokerage_stting['grandpa_fee'];
+ $reg_top_brokerage=$reg_brokerage_stting['top_fee'];
+ if($reg_parent_brokerage>0 && $parent_id>0){
+ $this->addUserBrokerage([
+ 'user_id'=>$parent_id,
+ 'level_type'=>1,
+ 'back_type'=>0,
+ 'brokerage_num'=>$reg_parent_brokerage,
+ 'service_fee'=>0,
+ 'create_time'=>date('Y-m-d H:i:s'),
+ ]);
+ }
+ if($reg_grandpa_brokerage>0 && $grandpa_id>0){
+ $this->addUserBrokerage([
+ 'user_id'=>$grandpa_id,
+ 'level_type'=>2,
+ 'back_type'=>0,
+ 'brokerage_num'=>$reg_parent_brokerage,
+ 'service_fee'=>0,
+ 'create_time'=>date('Y-m-d H:i:s'),
+ ]);
+ }
+ if($reg_top_brokerage>0 && $top_id>0){
+ $this->addUserBrokerage([
+ 'user_id'=>$top_id,
+ 'level_type'=>3,
+ 'back_type'=>0,
+ 'brokerage_num'=>$reg_parent_brokerage,
+ 'service_fee'=>0,
+ 'create_time'=>date('Y-m-d H:i:s'),
+ ]);
+ }
+ }
+ private function addUserBrokerage($data)
+ {
+ UserBrokerageModel::InsertUserBrokerage($data);
+ //查询提现资金账户信息
+ $from_account=(new WalletService())->lockUserBalance(1,$data['user_id']);
+ if(!empty($from_account)){
+ $from_update['usable_num']=$from_account['usable_num']+$data['brokerage_num'];
+ (new WalletService())->updateUserBalance(1,$from_update,$data['user_id']);
+ $to_log['user_id']=$data['user_id'];
+ $to_log['change_type']=9;
+ $to_log['change_num']=$data['brokerage_num'];
+ $to_log['before_num']=$from_update['usable_num'];
+ (new WalletService())->addUserBalanceLog(1,$to_log);
+ }
+ }
+
+
+}
\ No newline at end of file
diff --git a/app/home/service/TrcPayService.php b/app/home/service/TrcPayService.php
new file mode 100644
index 0000000..ea36dac
--- /dev/null
+++ b/app/home/service/TrcPayService.php
@@ -0,0 +1,384 @@
+getPayConfig($key);
+ $this->http_url=env('WALLET.HTTP_URL');
+ $this->app_id=$config['app_id'];
+ $this->private_key=$config['private_key'];
+ $this->public_key=$config['public_key'];
+ }
+
+ public function WalletAddress()
+ {
+ $num=WalletListModel::where([
+ 'user_id'=>0,
+ 'wallet_type'=>'TRC-20'
+ ])->count();
+ if($num>100){
+ return false;
+ }
+ $url=$this->http_url."/wallet/get_address";
+ $data['version']="V3";
+ $data['time']=time();
+ $data['chain_name']='TRON';
+ $encrypt_str=json_encode($data);
+ $str=RsaUtility::Encrypt($encrypt_str,$this->private_key);
+ $post_data['app_id']=$this->app_id;
+ $post_data['data']=$str;
+ $res=$this->http_post_res($url,$post_data);
+ $result=json_decode(RsaUtility::Decrypt($res['data'],$this->public_key),true);
+ if($result['code']==0 && $result['message']=='SUCCESS'){
+ WalletListModel::InsertUserWalletAddress([
+ 'user_id'=>0,
+ 'wallet_type'=>'TRC-20',
+ 'wallet_address'=>$result['data']['address']
+ ]);
+ return true;
+ }else{
+ Log::error('钱包服务器返回数据异常 '.json_encode($result));
+ return false;
+ }
+ }
+ public function TrcpayNotify($data)
+ {
+ $result=json_decode(RsaUtility::Decrypt($data,$this->public_key),true);
+ //var_dump($result);
+ //充值
+ if($result['type']==1){
+ $user_id=WalletListModel::getUidByWallet([
+ 'wallet_address'=>$result['to_address']
+ ]);
+ if($user_id){
+ $channel=PaymentListModel::getPaymentInfo([
+ 'channel_type'=>'TRC-20'
+ ]);
+ //var_dump($channel);
+ if($result['symbol']=='USDT(TRC20)'){
+ $account_type=1;//默认充值到现货账户
+ return $this->dealRechangePay($user_id,$account_type,$channel,$result['amount'],$result['tx_hash']);
+ }
+ }
+ }else{
+
+ }
+ return 'SUCCESS';
+ }
+ public function dealOrderConfirm($data)
+ {
+ $result=json_decode(RsaUtility::Decrypt($data,$this->public_key),true);
+ $result_data['check_sum']=0;
+ //$result_data['check_sum']=$result['check_sum'];
+ if(!empty($result)){
+ $info=UserWithdrawalModel::getUserDrawalInfo([
+ 'order_no'=>$result['request_id']
+ ]);
+ if(!empty($info) && $info['apply_num']==$result['amount']){
+ $result_data['check_sum']= $result['check_sum'];
+ }
+ }
+ $result_data['check_sum']= $result['check_sum'];
+ $encrypt_str=json_encode($result_data);
+ $str=RsaUtility::Encrypt($encrypt_str,$this->private_key);
+ return [
+ 'data'=>$str
+ ];
+ }
+ public function TrcAgnetPay($amount,$wallet_address,$order_no)
+ {
+ $url=$this->http_url."/wallet/transfer";
+ $data['version']="V3";
+ $data['time']=time();
+ $data['to_address']=$wallet_address;
+ $data['amount']=$amount;
+ $data['symbol']='USDT(TRC20)';
+ $data['request_id']=$order_no;
+ $encrypt_str=json_encode($data);
+ //echo $encrypt_str;
+ $str=RsaUtility::Encrypt($encrypt_str,$this->private_key);
+ $post_data['app_id']=$this->app_id;
+ $post_data['data']=$str;
+ $res=$this->http_post_res($url,$post_data);
+ $result=json_decode(RsaUtility::Decrypt($res['data'],$this->public_key),true);
+ if($result['code']==0){
+ return [
+ 'code'=>200,
+ 'msg'=>'ok',
+ 'order_idx'=>$result['data']['order_no'],
+ 'content'=>json_encode($result)
+ ];
+ }else{
+ return [
+ 'code'=>300,
+ 'msg'=>$result['message'],
+ 'order_idx'=>'',
+ 'content'=>json_encode($result)
+ ];
+ }
+ }
+ public function getTrcBalance(){
+ $url=$this->http_url."/wallet/balance";
+ $data['version']="V3";
+ $data['symbol']='USDT(TRC20)';
+ $data['time']=time();
+ $encrypt_str=json_encode($data);
+ //echo $encrypt_str;
+ $str=RsaUtility::Encrypt($encrypt_str,$this->private_key);
+ $post_data['app_id']=$this->app_id;
+ $post_data['data']=$str;
+ $res=$this->http_post_res($url,$post_data);
+ $result=json_decode(RsaUtility::Decrypt($res['data'],$this->public_key),true);
+ if($result['code']==0){
+ return [
+ 'amount'=>$result['data']['amount']
+ ];
+ }else{
+ return [
+ 'amount'=>0
+ ];
+ }
+ }
+ private function dealRechangePay($user_id,$account_type,$channel,$amount,$tx_hash)
+ {
+ $ex_res=RechargeApplyModel::getOrderInfo([
+ 'order_idx'=>$tx_hash
+ ]);
+ if($ex_res){
+ return 'SUCCESS';
+ }
+ if($channel['pay_type']==1){
+ $fee= $amount * $channel['service_rate'] ;
+ }else{
+ $fee= $channel['service_rate'];
+ }
+ $total_amount=$amount;
+ $market_amount=$amount-$fee;
+ //var_dump($market_amount);
+ if($market_amount>0){
+ $rechange_data['user_id']=$user_id;
+ $rechange_data['account_type']=$account_type;
+ $rechange_data['recharge_type']=1;
+ $rechange_data['recharge_channel']=0;
+ $rechange_data['order_no']=$this->generateOrderNumber();
+ $rechange_data['order_idx']=$tx_hash;
+ $rechange_data['deal_time']=date('Y-m-d H:i:s');
+ $rechange_data['recharge_num']=$market_amount;
+ $rechange_data['currency_rate']=1;
+ $rechange_data['status']=1;
+ $rechange_data['market_amount']=$market_amount;
+ $rechange_data['service_fee']=$fee;
+ $rechange_data['total_amount']=$total_amount;
+
+ $res=RechargeApplyModel::AddUserRecharge($rechange_data);
+ //var_dump($res);
+ if($res){
+ Db::startTrans();
+ try {
+ $wallet_obj=new WalletService();
+ //查询提现资金账户信息
+ $account_info=$wallet_obj->lockUserBalance($account_type,$user_id);
+ if(empty($account_info)){
+ Db::rollback();
+ return 'FAIL';
+ }
+ $acc_update['usable_num']=$account_info['usable_num']+$market_amount;
+ $res=$wallet_obj->updateUserBalance($account_type,$acc_update,$user_id);
+ if(empty($res)){
+ Db::rollback();
+ return 'FAIL';
+ }
+ $log_data['user_id']=$user_id;
+ $log_data['change_type']=1; //充值
+ $log_data['change_num']=$market_amount;
+ $log_data['before_num']=$account_info['usable_num'];
+ $log_data['order_id']=$rechange_data['order_no'];
+ $res=$wallet_obj->addUserBalanceLog($account_type,$log_data);
+ if(empty($res)) Db::rollback();
+ Db::commit();
+ return 'SUCCESS';
+ } catch (\Exception $exception) {
+ // 回滚事务
+ Db::rollback();
+ return 'FAIL';
+ }
+ }else{
+ return 'FAIL';
+ }
+
+ }else{
+ return 'SUCCESS';
+ }
+ }
+
+ private function http_post_res($url, $postData)
+ {
+ try {
+ $client = new Client();
+ $response = $client->request("POST", $url,[
+ 'json' => $postData,
+ ]);
+ $body = $response->getBody()->getContents();
+ $res = json_decode($body, true);
+ return $res;
+ }catch (\Exception $exception){
+ Log::error('给钱包服务器发送数据异常1 '.$exception->getMessage());
+ } catch (GuzzleException $e) {
+ Log::error('给钱包服务器发送数据异常2 '.$e->getMessage());
+ }
+ }
+
+ private function getPayConfig($key){
+ $config=[
+ 'test'=>[
+ 'app_id'=>'MQ6fGxVZX1SbnYFxk1qH',
+ 'private_key'=>'-----BEGIN PRIVATE KEY-----
+MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDOc+ILpnKhurA+
+Rz1etWSC8bzbsyUzNFC7lSkpACRr3LlCoWbBXeRpgpWMwSW7B80QzvTTbZSr/Kk8
+sTJeotKCBCu1O0NpmSlsVe+BVfKoluSzdOmDQa7fViX0tNU+shLuef5oX5jTE3FA
+wCsLMrCYAYKvwUrylrHC4EX6IznL1MD5anHLUNqrUHonNsHx4ZYX16Wpwlst4f2s
+XgVnrnesX7iPoupIUgWhcLdKFhIQI0XAY/aoALKy+YGREimxlpm/FxQcCWC1tZBe
+cPGWjLicHbGmyOcFUXxc/4D0XmdS+Xcr9pFWHyHV5iRtM6WFoWHKLPaz5+fPrIaW
+6hXRSPeJAgMBAAECggEABmkcxMXXW2RDorttkWpKg7Jj7eKDLjLaquh3zbkeaGcD
+Lal7WlfDBu+yGxvIQyV73aC/g20sp6aBzsulx8CAjt74SHldn4LNAXsto7N6hHej
+BFuGALhiaLbxGMcgtACti9An8S++vBcndh5Bd+iMCTxKxZBX9m5teKKkKZ88ZTLY
+uopvvtP51rc2Wo3h9dF0h4DIjJeguChDNKdxgT+PCukZ2DZsn8qL+1xAqPj7MKg9
+dukXLAmaa3nfcyKmc62cuIW/pRdZ6ZwI6rJ1p4/UwLLx93M9BXAMIJ+e37D0XtV+
+KJ+dAMRbwezK4isaQJjC0Z8hhtzbC0VN5Ih1SwBSAQKBgQDzA8n/xB5pXiMO1o0r
+h7GnkSQSvwFCa8y2Okbm/SnJue3iaIhJGatVIJoWwRb6LFMNzRf+uKl9c3MJGS0G
+CzT4Azswp1vuNcKq2FtKpAhq3X3CZ50sAmIH5dyht/yT0Zna0zJ9HB7XpEZlEZJQ
+GwJNGt2gMDwEdzY3JoCeoSzqwQKBgQDZe/VzAFAsRuGN0DFCa0Rkp/+s6PiI3yUV
+g57V3n8blZZZUjgWRgc0mnjHYOlvfbyUJEnRzUcMWoj+8iieg4bxmVTChEbrxkbd
+IQVhQJOcjbokiR1UhsN67CkZcPzNXirGuek8j190DJHvCl26F9gkHCHHu9ryzYlp
+P47ZgSwmyQKBgQDKG4efIJOOXE1Z5NRJtLPqwco3kQVSIWeC0prvNvPPIsQWPYvD
+CAc3aELe073xWHXGj6D6JshHXoH4uih40089SSqr/zR0u99nyUK7pAqgHg+eZCAS
+XvT6zpAdK3Bz26lSlb1y0bVQ8P3exqth1eSnDcXumM8Bg8fiPDJSO4eowQKBgGv5
+T+W1fRhOZIL8nsgj60Ox6IzW6TVC2+1veDckDKUMQiW8XR4pzEAAhQAvjBWPLkW6
+MnAX4zMt65/vZ90y3ZcrEdq0w2Ug/mOglkQvRFnQP18ON+KUOY7YmpsH7mqjWsdo
+23P2lmROLVGpKtlOJz/eO6MnD8/F3XfEV06DBAGJAoGAQSC0XLlqqgwr7kYQwjQN
+HNulo7QRhU36Y13MRMoGQ0FdOzjwbOxnt3Ozu0qjnraaUsBUaeyNam3kqamL63UF
+4559oHwShlqNUEj/X769827MMpRpgO2ZuRZ0Vbi41aSRPC/bPnVKxk1+rOcJ1ofO
+0Zmj0Gz7P2v5BLO7m1dlhhw=
+-----END PRIVATE KEY-----',
+ 'public_key'=>'-----BEGIN PUBLIC KEY-----
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2MdaHtMSUnIJzmyhtHkQ
+oR2ddffyU8UCATVnoKgcgzst55TvKmY2zCbjcf6cfJVIkYIEf5Wny3yhZbSEVRNg
+GeEpB2N2QVYd3qdMVEa0Wq+rcrXzdzNy8uq0FzJMw114LPzF+OGKO8gKcmPnYKFm
+4dbFxfIYhWQ+DaRJxgSZ6OaK5hFBXBlvUDLagn98ckdHvENhwuWaQ3Z2MpOhvO6z
+qQLLj0VQU/LEkfnAcKpyy31iIfJxbMRop6DAJH+GXbhn5eARH8GDJLz32WkkqC8+
+vIkQhZyQI7fjpqtQoMXr7C31lME0QGLEQcWZtt8PfzFzMeW9MEcBWuxF41Ghf8jC
+SwIDAQAB
+-----END PUBLIC KEY-----'
+ ],
+ 'bourse'=>[
+ 'app_id'=>'bVzIS6lChCNXk6w',
+ 'private_key'=>'-----BEGIN PRIVATE KEY-----
+MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCabCMxKsktrZQn
+NkVYcu+UOI75uF4Jq6HoABNuTEXf7ff5SGTkJkLzk2lsPQwJQymX201uQV3FJqKg
+HMMZwcFvfmNn2dapBgmyoO3fnWHxULVV04m+wFF7ol77c7llbvKTXnWZU3CEm42v
+Bu0rIZrYmsWOvQN97LLfQmpfFGgbFP+fV8cQ2OaGC8r+BrBU2nzTVexlstBkaxEg
+j15hlc5OC1sQvzpwnjmbydrL1LKEgMlwAAFLeEYhudb+ulaXGWG0Hm9YUEW0GAmD
+eMaC6zgCI0rppLhGVTFrYnDCo0G3zoj+lqxVTgx3+u7dGKU63BLPuMEkzIdDizYQ
+OJJ8YygbAgMBAAECggEAZscgaSIEAh3sZGjPoL3mzS0TpAtcs20DdqlORXQIcbEu
+AUF4vQzmNL3hRcQf1a5Y6ZRxpbdl1MkRJiXeiK8XssBZIw6uu5KkM7q+d72FKZrB
+Bl2j6UyRLwtz0kJEm8lLNGCDPsh1NB1gIKUohzN3n0DrykPtJgu7RbMrnxqy64p2
+qKYVh3hwbOkxTjde5E0AvPxH7iO4gRvOBZ9NmtKiDAVDkdyNI9lxYokya95Ag4cm
+FJeDUoF1N8Wiw9lcjIVVEXeL+pI+rAX0zM/3jln0MWdE8FnaKp3o9YZkZsPpv3yu
+EuJC0xf8iDJI28t+jEVmfw64XkvAOrN+8inEyfUy2QKBgQDHr1DzRVxLxqFBLRoj
+O+wflwA9LcZain/DPCG+zTeChcf5NPB5l+yDIkAubx6MvFlBbnJ7nSu+i0KiJ/Bg
+BZncadaivUA3oAsx5VG0th8Zv1jrBwIFPpzS90avpbEYy6ru+YMT+uYXpgpmYDSh
+8HqcO2xcoUz7nO+LvtIlCHjcxwKBgQDF+QB7XQVDymA2p+POQ0nPE6gS8StFwvs1
+X/4F4CLBebRtcXvsj/NKqUva9682zCE08A9JTOp3UsqCA3gJEXFs/OBfgZKD/yoh
+LmP81ANiJsNpcriEanE1tVifSID6oBkHPRgdsF1V6/C5/I6X6CPJh3Grh0t1/dW0
+uEeOj7p+DQKBgGeq9PPXRptwe7dCmxc/vM6Jrm4Una3TyZCqXzqXgAIbQj525YG7
+BebumTOCLPITtqLpnDXg2x0JX4agBYNUZRSxPeUvK2+1fxpgW5LeGjdbx+X8tWfT
+ocdE6UW3V8HvusZmc06kK2CLq0qLF8ga+QyzLQbKFxVp3FNItgDT7StxAoGAcg75
+xhlbtSjdsd+ckfOWjKWoifFEmxaxIJlDgyMVIx75YqylVy/AXd2YBHn7Crkk0JkW
+VYbo9wJOBgX1nFPeY4p1wtCmF0JlhWRy2vFTWbM3loMv56pjuyvV+T8OgFbI1LDQ
+OhqoS555vM3TYZWvOKa+SLLUORCblVkucOZB7ekCgYArqqbE+tjNaVJ25KVtgmf1
+OswFLizTSmbzsyDvTT4BawgLbK/rOJB9fERujTNd0ZtM/uJ/MTgIWOaXxlA7SjX3
+yeScRql1I+9mvUZh/BvFCsir0ElfnMiGuZ/k6jqq0nl/h0a2nScISjvNwZwg0elF
+Zwuv1gWW/tQFCSdfF8ewBQ==
+-----END PRIVATE KEY-----',
+ 'public_key'=>'-----BEGIN PUBLIC KEY-----
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvhOR8XKjt5TH8wNpel26
+vDvWgC428q+QGyY0tQcYqAna7fTB1ta5DB1a8MyWIkV9kqwzBJbND/rSVZLyW//e
+K7DliUvcNCCksC5RTvVW2A+cpUTemNz9Oc/lFcsszac3XQXlvieTWg20ii4s89N9
+vwr0fWi72umEtkDkpDcU/aGJWv5yxBl3OMeIPUqPiM+9quiWr5ZUqo6zlvtzWz1H
+57IPdOxgGoRgCccaINt2PJVDFJ0d3L+ZQsKEKJY4OkhLAjKbuEDxuj0BcLVwnPr1
+x52/dTSyUZca3nJOeaSRBEzOx5oqbbRfyUbzQhFu2UD/ZeDS4dIRmxPeDcF+5aJF
+IQIDAQAB
+-----END PUBLIC KEY-----'
+ ],
+ 'stock'=>[
+ 'app_id'=>'mCy0zbuRRRstYGq',
+ 'private_key'=>'-----BEGIN PRIVATE KEY-----
+MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDTu2XAYZ+hQkrl
+mUP0xpSwg1wMxmTfXKeOQmmwfSgi2k5g/NlTblwoK+pVDaav1UXIEI5cThZWu+HT
+ljPxZHSQlldSy/N34yE33ioTl1Bq7W10Yq6iOjJMybjqmARbbbdbNB5ktnb3DmmQ
+ZxexV2Pj7XUrVDtagngH7JF1lEaK6zkbP8koxBOo/sBmvIsd6ps+B+5nMOnpYMNd
+0dn1N6YJmjWKVbkRbNDM5BasJwTQ8kbYQ/XN0YhCdjixcrhpADDypkqQJ/AA2Ys+
+8uEtnB1yZV+hbCMbbUDpZlsOagLmF3C7FywHxzXlkuzdTP/Til7tjnky0B1E4fv1
+e3Ff5eTZAgMBAAECggEBAMkMSqQQjtk6749wpzyIS6wIL6HZyPLnMhs9KMpzLWda
+z838ighU5KEoggxdOAgChY5hWix/4WpeYSLen1f5wU2B1E1EaF1QiLxZ8q5DohLG
+fIZlJdnZVOXhLftkec6vMcoihTGwqOoS/14k5jR4/NrzIa0RAIMDHCK6Ga0CLLG+
+yxR/D1kh/mzJ3g+l/smrfwSJKcglSAJA79sqCOirY26cTv8xabM1MqECClhhS1p2
+o2BICiy1AyOR0pXS8Z5IvC3IEMJBs4XmkYHc1118w8Y97o+2EyY2LNLe5z3GvPgS
+n2vFN+Wr9z1C4fUKnoW8W60VXacP+FTN14ydj4jRBHkCgYEA85ZhjLID0V9j/eIH
+2mvAOzK/HULNYExNuLb461tda4fIHbcU93gCFvmf+BTbxRwsOJsYQ+Cd1NZe7OH4
+JrXFrEUNh5oGz+UANTbIkWHFEUeyihe0dcbS2n4/7siY9gUU897zgdKIt3H5T9rP
+9fuXTt0F2u7nGMYdOJPPO5czI08CgYEA3oV1vSI1HdYWsBUbcTSUQsU1r8YpoagH
+kmwYTvm8KiizdI9VOQLj6xMRZCDidsYqrduT9fcce756R/QE7QEb6wsHFzfoHiCp
+ZYfjYp6YouyU8snQzwVmO7JkvOZcWQedcoZGJ/ZadKOoGNWlXQn8WqQuTSw/1kta
+nkPkhM7Xi1cCgYBopH+/q3HMbkhMdt+cy5FHXSOQ9HO6HM1+vsvsf9GAMlKbwVz2
+es2bBR3du0g2Q0YUAzzHXCUxm+4noWOzbX8/5GJNkLPAd8ZBFgnPusqoA78FZ+2U
+cxd92aKpd++OMNyxb2P4r3MgK4xI691O9QgpTvYG+X65u9ItzgHGvcuwLQKBgBBe
+dvPL0WZ5ej/HvbYNLR7gTPu6MxPOPYha5Urh+iKLze+0H4vLF6MSSwQ3mxErsLYL
+Yg4E+JZtw6cJX1dj7n7S19mwZiXZNzzdyy9VBVtu1eIqUG76MbQQgnKW65ItCjsD
+f6Ou7qaH53S0Oq7mbibozvMkXynPb0IXMndGk/qPAoGACYz1oExg/3zGNezrC2PY
+fFkgZY69iGjr6y9G6giy15ocBHR+1lLVSKkzzrCuO9tw+sGQCXiFGxx2Ne3k/htu
+mzqXoTsMRyGk5Pi7I/zRyvKXiIm/adz46m/Y8l6aDgexFuW9Y+23L3IwPWaZzR+z
+VjXIC2JkJA2RpBAV0HIXEgQ=
+-----END PRIVATE KEY-----',
+ 'public_key'=>'-----BEGIN PUBLIC KEY-----
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyQtS6llJRABJkVE/cuVE
+5lvur0kPYSN/tBgwwye/O2jHl5M0fZGFpx3KLeq8PQxqobGXFYe4CzxX5/RNP7OT
+/AGR1UqkSK0ZGYGcz0kanIq+Oq1xCZQQyEAcZ9elZzUG3hBi1TR8Dn2MvIuRvKVz
+EFVyyWoAjL+dBV5yn26cXXNkDVkrD4qtFUihUe76xXTxf5TWXCYzmIX4yeu1w47w
+f/K2rWENe/Uo2fUaAfN41hsrIZMo8LZLGi94G4hVlXqfE9F/KSGJh0YNF5o0Lod7
+cS/uZZvDSYc2CqBoT5OGsdz6l93kd9QBupAmwQL/u4CmeOePyuZ3rA1yHxQBpEzF
+ZwIDAQAB
+-----END PUBLIC KEY-----'
+ ]
+ ];
+ return isset($config[$key]) ? $config[$key]: $config['test'];
+ }
+
+
+
+}
\ No newline at end of file
diff --git a/app/home/service/UserService.php b/app/home/service/UserService.php
new file mode 100644
index 0000000..d80fd11
--- /dev/null
+++ b/app/home/service/UserService.php
@@ -0,0 +1,1330 @@
+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('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', $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;
+
+ // 返回数据
+ 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'],
+ '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
+ ]);
+ } 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()]);
+ }
+ }
+
+ /**
+ * @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])) {
+ UserModel::update(['lever_status' => UserModel::LEVER_STATUS_APPLY, '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.', []);
+ }
+ }
+}
diff --git a/app/home/service/UserVerifyService.php b/app/home/service/UserVerifyService.php
new file mode 100644
index 0000000..fdf1242
--- /dev/null
+++ b/app/home/service/UserVerifyService.php
@@ -0,0 +1,133 @@
+toData('100400','Invalid name');
+ }
+
+ if(empty($params['code']) || !is_string($params['code'])){
+ return $this->toData('100400','Invalid ID number');
+ }
+
+ if(empty($params['country']) || !is_numeric($params['country'])){
+ return $this->toData('100400','Invalid country');
+ }
+
+ if(empty($params['front_img']) || !is_numeric($params['front_img'])){
+ return $this->toData('100400','Invalid front_img');
+ }
+
+ if(empty($params['back_img']) || !is_numeric($params['back_img'])){
+ return $this->toData('100400','Invalid back_img');
+ }
+
+ // 判断用户状态
+ $user = UserModel::where('user_id', $userId)->find();
+ if(empty($user)){
+ return $this->toData('100400','param error');
+ }
+
+ // 判断是是否已经认证
+ if($user->is_real == 1){
+ return $this->toData('100400','Already real-name authenticated');
+ }
+
+ // 是否是未认证或者认证失败状态
+ if($user->real_status == 2 || $user->real_status == 3){
+ return $this->toData('100400','status error');
+ }
+
+ $country = CountryModel::where('id',$params['country'])->find();
+ if(empty($country)){
+ return $this->toData('100400','country error');
+ }
+
+ // 图片记录
+ $front = FileModel::where('id',$params['front_img'])->find();
+ if(empty($front)){
+ return $this->toData('100400','front_img error');
+ }
+
+ $back = FileModel::where('id',$params['back_img'])->find();
+ if(empty($back)){
+ return $this->toData('100400','back_img error');
+ }
+
+ //锁屏密码
+ $lockPassword = '';
+ if (!empty($params['lock_password'])) {
+ $lockPassword = $params['lock_password'];
+// $salt = env('ENCRYPT.SALT');
+// $enLockPassword = (new UnqId())->encryptPassword($lockPassword, $salt);
+ }
+
+
+ // 写入数据库
+ $userVerify = new UserVerifyLogModel;
+ $userVerify->user_id = $userId;
+ $userVerify->country = $params['country'];
+ $userVerify->code = $params['code'];
+ $userVerify->name = $params['name'];
+ $userVerify->front_img = $params['front_img'];
+ $userVerify->back_img = $params['back_img'];
+ if (!empty($lockPassword)) $userVerify->lock_password = $lockPassword;
+ $userVerify->create_time = date('Y-m-d H:i:s');
+ $userVerify->update_time = date('Y-m-d H:i:s');
+ $userVerify->save();
+
+ // 更改用户状态
+ $user->real_status = 2;
+ $user->save();
+
+ return $this->toData('0','SUCCESS');
+
+ }catch (\Exception $exception){
+ return $this->toData('100500','The system is busy.');
+ }
+ }
+
+ public function detail($userId)
+ {
+ try {
+ $user = UserModel::where('user_id', $userId)->find();
+ if(empty($user)){
+ return $this->toData('100400','param error');
+ }
+
+ $log = UserVerifyLogModel::where('user_id', $userId)->order('id', 'desc')->find();
+
+ $data = [];
+ if(!empty($log)){
+ $front = FileModel::where('id', $log->front_img)->value('path');
+ $back = FileModel::where('id', $log->back_img)->value('path');
+ $country = CountryModel::where('id', $log->country)->find();
+ $data = [
+ 'name' => $log->name,
+ 'code' => $log->code,
+ 'country_data' => $country,
+ 'front_img' => $front,
+ 'back_img' => $back,
+ 'status' => $log->status,
+ ];
+ }
+
+ return $this->toData('0', 'SUCCESS', $data);
+ }catch (\Exception $exception){
+ return $this->toData('100500','The system is busy.');
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/home/service/WalletService.php b/app/home/service/WalletService.php
new file mode 100644
index 0000000..2fa2ffb
--- /dev/null
+++ b/app/home/service/WalletService.php
@@ -0,0 +1,1800 @@
+ $this->getUserDigital([
+ 'user_id' => $user_id,
+ 'account_type' => $account_type
+ ])
+ ];
+ break;
+ case 2:
+ $result = [
+ 'contract' => $this->getUserContract([
+ 'user_id' => $user_id,
+ 'account_type' => $account_type
+ ])
+ ];
+ break;
+ // 美股
+ case 3:
+ $result = [
+ 'contract' => $this->getUserUsStock([
+ 'user_id' => $user_id,
+ 'account_type' => $account_type
+ ])
+ ];
+ break;
+ // 印尼股票
+ case 4:
+ $result = [
+ 'contract' => $this->getUserIdnStock([
+ 'user_id' => $user_id,
+ 'account_type' => $account_type
+ ])
+ ];
+ break;
+ // 马来西亚股票
+ case 5:
+ $result = [
+ 'contract' => $this->getUserMysStock([
+ 'user_id' => $user_id,
+ 'account_type' => $account_type
+ ])
+ ];
+ break;
+ // 泰股股票
+ case 6:
+ $result = [
+ 'contract' => $this->getUserThaStock([
+ 'user_id' => $user_id,
+ 'account_type' => $account_type
+ ])
+ ];
+ break;
+
+ case 7:
+ $result = [
+ 'contract' => $this->getUserInStock([
+ 'user_id' => $user_id,
+ 'account_type' => $account_type
+ ])
+ ];
+ break;
+ // 秒合约
+ case 8:
+ $result = [
+ 'contract' => $this->getUserContractSec([
+ 'user_id' => $user_id,
+ 'account_type' => $account_type
+ ])
+ ];
+ break;
+ //新加坡
+ case 9:
+ $result = [
+ 'contract' => $this->getUserSgdStock([
+ 'user_id' => $user_id,
+ 'account_type' => $account_type
+ ])
+ ];
+ break;
+ //基金
+ case 10:
+ $result = [
+ 'contract' => $this->getUserFundStock([
+ 'user_id' => $user_id,
+ 'account_type' => $account_type
+ ])
+ ];
+ break;
+ //印度期权
+ case 11:
+ $result = [
+ 'contract' => $this->getUserInOption([
+ 'user_id' => $user_id,
+ 'account_type' => $account_type
+ ])
+ ];
+ break;
+ //港股
+ case 12:
+ $result = [
+ 'contract' => $this->getUserHkStock([
+ 'user_id' => $user_id,
+ 'account_type' => $account_type
+ ])
+ ];
+ break;
+ case 14:
+ $result = [
+ 'contract' => $this->getUserUkStock([
+ 'user_id' => $user_id,
+ 'account_type' => $account_type
+ ])
+ ];
+ break;
+ case 15:
+ $result = [
+ 'contract' => $this->getUserFurStock([
+ 'user_id' => $user_id,
+ 'account_type' => $account_type
+ ])
+ ];
+ break;
+ case 16:
+ $result = [
+ 'contract' => $this->getUserEurStock([
+ 'user_id' => $user_id,
+ 'account_type' => $account_type
+ ])
+ ];
+ break;
+ case 17:
+ $result = [
+ 'contract' => $this->getUserBrlStock([
+ 'user_id' => $user_id,
+ 'account_type' => $account_type
+ ])
+ ];
+ break;
+ case 18:
+ $result = [
+ 'contract' => $this->getUserJpStock([
+ 'user_id' => $user_id,
+ 'account_type' => $account_type
+ ])
+ ];
+ break;
+ case 19:
+ $result = [
+ 'contract' => $this->getUserForex([
+ 'user_id' => $user_id,
+ 'account_type' => $account_type
+ ])
+ ];
+ break;
+ default:
+ $result = [
+ 'digital' => $this->getUserDigital([
+ 'user_id' => $user_id,
+ 'account_type' => $account_type
+ ]),
+ 'contract' => $this->getUserContract([
+ 'user_id' => $user_id,
+ 'account_type' => $account_type
+ ]),
+ 'forex' => $this->getUserForex([
+ 'user_id' => $user_id,
+ 'account_type' => $account_type
+ ]),
+ 'contract_sec' => $this->getUserContractSec([
+ 'user_id' => $user_id,
+ 'account_type' => $account_type
+ ]),
+ 'us_stock' => $this->getUserUsStock([
+ 'user_id' => $user_id,
+ 'account_type' => $account_type
+ ]),
+ 'idn_stock' => $this->getUserIdnStock([
+ 'user_id' => $user_id,
+ 'account_type' => $account_type
+ ]),
+ 'mys_stock' => $this->getUserMysStock([
+ 'user_id' => $user_id,
+ 'account_type' => $account_type
+ ]),
+ 'tha_stock' => $this->getUserThaStock([
+ 'user_id' => $user_id,
+ 'account_type' => $account_type
+ ]),
+ 'in_stock' => $this->getUserInStock([
+ 'user_id' => $user_id,
+ 'account_type' => $account_type
+ ]),
+ 'sgd_stock' => $this->getUserSgdStock([
+ 'user_id' => $user_id,
+ 'account_type' => $account_type
+ ]),
+ 'fund_stock' => $this->getUserFundStock([
+ 'user_id' => $user_id,
+ 'account_type' => $account_type
+ ]),
+ 'option_in_stock' => $this->getUserInOption([
+ 'user_id' => $user_id,
+ 'account_type' => $account_type
+ ]),
+ 'hk_stock' => $this->getUserHkStock([
+ 'user_id' => $user_id,
+ 'account_type' => $account_type
+ ]),
+ 'uk_stock' => $this->getUserUkStock([
+ 'user_id' => $user_id,
+ 'account_type' => $account_type
+ ]),
+ 'fur_stock' => $this->getUserFurStock([
+ 'user_id' => $user_id,
+ 'account_type' => $account_type
+ ]),
+ 'eur_stock' => $this->getUserEurStock([
+ 'user_id' => $user_id,
+ 'account_type' => $account_type
+ ]),
+ 'brl_stock' => $this->getUserBrlStock([
+ 'user_id' => $user_id,
+ 'account_type' => $account_type
+ ]),
+ 'jp_stock' => $this->getUserJpStock([
+ 'user_id' => $user_id,
+ 'account_type' => $account_type
+ ]),
+ ];
+ break;
+ }
+ return $this->toData(0, 'Request successful.', $result);
+ }
+
+ /**
+ * 获取用户现货资产
+ * @param $user_id
+ * @param int $type 0全部资产,1只获取usdt资产
+ * @return array
+ */
+ private function getUserDigital(array $data, int $type = 0): array
+ {
+ try {
+ validate(WalletValidate::class)->scene('getUserBalance')->check($data);
+ if ($type == 0) {
+ return UserDigitalModel::getUserDigitalList($data['user_id']);
+ } else {
+ return UserDigitalModel::getUserDigitalByUserId($data);
+ }
+ } catch (ValidateException $validateException) {
+ $message = $validateException->getMessage();
+ return $this->toData('1', $message, []);
+ } catch (\Exception $exception) {
+ return $this->toData('100500', 'The system is busy. Please try again later.', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+
+ /**
+ * 获取用户合约资产
+ * @param $data
+ * @return array
+ */
+ private function getUserContract($data, int $type = 0): array
+ {
+ try {
+ validate(WalletValidate::class)->scene('getUserBalance')->check($data);
+ if ($type == 0) {
+ return UserContractModel::getUserContractList($data['user_id']);
+ } else {
+ return UserContractModel::getUserContractByUserId($data);
+ }
+ } catch (ValidateException $validateException) {
+ $message = $validateException->getMessage();
+ return $this->toData('1', $message, []);
+ } catch (\Exception $exception) {
+ return $this->toData('100500', 'The system is busy. Please try again later.', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+ /**
+ * 获取用户外汇资产
+ * @param $data
+ * @return array
+ */
+ private function getUserForex($data, int $type = 0): array
+ {
+ try {
+ validate(WalletValidate::class)->scene('getUserBalance')->check($data);
+ if ($type == 0) {
+ return UserForexModel::getUserForexList($data['user_id']);
+ } else {
+ return UserForexModel::getUserForexByUserId($data);
+ }
+ } catch (ValidateException $validateException) {
+ $message = $validateException->getMessage();
+ return $this->toData('1', $message, []);
+ } catch (\Exception $exception) {
+ return $this->toData('100500', 'The system is busy. Please try again later.', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+
+ /**
+ * 获取用户秒合约资产
+ * @param $data
+ * @return array
+ */
+ private function getUserContractSec($data, int $type = 0): array
+ {
+ try {
+ validate(WalletValidate::class)->scene('getUserBalance')->check($data);
+ if ($type == 0) {
+ return UserContractSecModel::getUserContractList($data['user_id']);
+ } else {
+ return UserContractSecModel::getUserContractByUserId($data);
+ }
+ } catch (ValidateException $validateException) {
+ $message = $validateException->getMessage();
+ return $this->toData('1', $message, []);
+ } catch (\Exception $exception) {
+ return $this->toData('100500', 'The system is busy. Please try again later.', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+
+ /**
+ * 获取用户美股资产
+ * @param $user_id
+ * @return array
+ */
+ private function getUserStock($data, int $type = 0): array
+ {
+ try {
+ validate(WalletValidate::class)->scene('getUserBalance')->check($data);
+ if ($type == 0) {
+ return UserStockModel::getUserStockList($data['user_id']);
+ } else {
+ return UserStockModel::getUserStockByUserId($data);
+ }
+ } catch (ValidateException $validateException) {
+ $message = $validateException->getMessage();
+ return $this->toData('1', $message, []);
+ } catch (\Exception $exception) {
+ return $this->toData('100500', 'The system is busy. Please try again later.', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+
+ /**
+ * 获取用户美股资产
+ * @param $user_id
+ * @return array
+ */
+ private function getUserUsStock($data, int $type = 0): array
+ {
+ try {
+ validate(WalletValidate::class)->scene('getUserBalance')->check($data);
+ if ($type == 0) {
+ return UserStockModel::getUserStockList($data['user_id']);
+ } else {
+ return UserStockModel::getUserStockByUserId($data);
+ }
+ } catch (ValidateException $validateException) {
+ $message = $validateException->getMessage();
+ return $this->toData('1', $message, []);
+ } catch (\Exception $exception) {
+ return $this->toData('100500', 'The system is busy. Please try again later.', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+
+ /**
+ * 获取用户印尼股票 资产
+ * @param $user_id
+ * @return array
+ */
+ private function getUserIdnStock($data, int $type = 0): array
+ {
+ try {
+ validate(WalletValidate::class)->scene('getUserBalance')->check($data);
+ if ($type == 0) {
+ return UserStockIdnModel::getUserStockList($data['user_id']);
+ } else {
+ return UserStockIdnModel::getUserStockByUserId($data);
+ }
+ } catch (ValidateException $validateException) {
+ $message = $validateException->getMessage();
+ return $this->toData('1', $message, []);
+ } catch (\Exception $exception) {
+ return $this->toData('100500', 'The system is busy. Please try again later.', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+
+ private function getUserSgdStock($data, int $type = 0): array
+ {
+ try {
+ validate(WalletValidate::class)->scene('getUserBalance')->check($data);
+ if ($type == 0) {
+ return UserStockSgdModel::getUserStockList($data['user_id']);
+ } else {
+ return UserStockSgdModel::getUserStockByUserId($data);
+ }
+ } catch (ValidateException $validateException) {
+ $message = $validateException->getMessage();
+ return $this->toData('1', $message, []);
+ } catch (\Exception $exception) {
+ return $this->toData('100500', 'The system is busy. Please try again later.', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+
+ private function getUserFundStock($data, int $type = 0): array
+ {
+ try {
+ validate(WalletValidate::class)->scene('getUserBalance')->check($data);
+ if ($type == 0) {
+ return UserStockFundModel::getUserStockList($data['user_id']);
+ } else {
+ return UserStockFundModel::getUserStockByUserId($data);
+ }
+ } catch (ValidateException $validateException) {
+ $message = $validateException->getMessage();
+ return $this->toData('1', $message, []);
+ } catch (\Exception $exception) {
+ return $this->toData('100500', 'The system is busy. Please try again later.', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+
+ /**
+ * 获取用户马来西亚股票 资产
+ * @param $user_id
+ * @return array
+ */
+ private function getUserMysStock($data, int $type = 0): array
+ {
+ try {
+ validate(WalletValidate::class)->scene('getUserBalance')->check($data);
+ if ($type == 0) {
+ return UserStockMysModel::getUserStockList($data['user_id']);
+ } else {
+ return UserStockMysModel::getUserStockByUserId($data);
+ }
+ } catch (ValidateException $validateException) {
+ $message = $validateException->getMessage();
+ return $this->toData('1', $message, []);
+ } catch (\Exception $exception) {
+ return $this->toData('100500', 'The system is busy. Please try again later.', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+
+ /**
+ * 获取用户马股股票 资产
+ * @param $user_id
+ * @return array
+ */
+ private function getUserThaStock($data, int $type = 0): array
+ {
+ try {
+ validate(WalletValidate::class)->scene('getUserBalance')->check($data);
+ if ($type == 0) {
+ return UserStockThaModel::getUserStockList($data['user_id']);
+ } else {
+ return UserStockThaModel::getUserStockByUserId($data);
+ }
+ } catch (ValidateException $validateException) {
+ $message = $validateException->getMessage();
+ return $this->toData('1', $message, []);
+ } catch (\Exception $exception) {
+ return $this->toData('100500', 'The system is busy. Please try again later.', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+
+ /**
+ * 获取用户印度股票 资产
+ * @param $user_id
+ * @return array
+ */
+ private function getUserInStock($data, int $type = 0): array
+ {
+ try {
+ validate(WalletValidate::class)->scene('getUserBalance')->check($data);
+ if ($type == 0) {
+ return UserStockInModel::getUserStockList($data['user_id']);
+ } else {
+ return UserStockInModel::getUserStockByUserId($data);
+ }
+ } catch (ValidateException $validateException) {
+ $message = $validateException->getMessage();
+ return $this->toData('1', $message, []);
+ } catch (\Exception $exception) {
+ return $this->toData('100500', 'The system is busy. Please try again later.', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+
+ /**
+ * 获取用户印度股票 资产
+ * @param $user_id
+ * @return array
+ */
+ private function getUserHkStock($data, int $type = 0): array
+ {
+ try {
+ validate(WalletValidate::class)->scene('getUserBalance')->check($data);
+ if ($type == 0) {
+ return UserStockHkdModel::getUserStockList($data['user_id']);
+ } else {
+ return UserStockHkdModel::getUserStockByUserId($data);
+ }
+ } catch (ValidateException $validateException) {
+ $message = $validateException->getMessage();
+ return $this->toData('1', $message, []);
+ } catch (\Exception $exception) {
+ return $this->toData('100500', 'The system is busy. Please try again later.', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+ /**
+ * 获取用户印度股票 资产
+ * @param $user_id
+ * @return array
+ */
+ private function getUserUkStock($data, int $type = 0): array
+ {
+ try {
+ validate(WalletValidate::class)->scene('getUserBalance')->check($data);
+ if ($type == 0) {
+ return UserStockGBXModel::getUserStockList($data['user_id']);
+ } else {
+ return UserStockGBXModel::getUserStockByUserId($data);
+ }
+ } catch (ValidateException $validateException) {
+ $message = $validateException->getMessage();
+ return $this->toData('1', $message, []);
+ } catch (\Exception $exception) {
+ return $this->toData('100500', 'The system is busy. Please try again later.', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+ private function getUserFurStock($data, int $type = 0): array
+ {
+ try {
+ validate(WalletValidate::class)->scene('getUserBalance')->check($data);
+ if ($type == 0) {
+ return UserStockFurModel::getUserStockList($data['user_id']);
+ } else {
+ return UserStockFurModel::getUserStockByUserId($data);
+ }
+ } catch (ValidateException $validateException) {
+ $message = $validateException->getMessage();
+ return $this->toData('1', $message, []);
+ } catch (\Exception $exception) {
+ return $this->toData('100500', 'The system is busy. Please try again later.', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+ private function getUserEurStock($data, int $type = 0): array
+ {
+ try {
+ validate(WalletValidate::class)->scene('getUserBalance')->check($data);
+ if ($type == 0) {
+ return UserStockEurModel::getUserStockList($data['user_id']);
+ } else {
+ return UserStockEurModel::getUserStockByUserId($data);
+ }
+ } catch (ValidateException $validateException) {
+ $message = $validateException->getMessage();
+ return $this->toData('1', $message, []);
+ } catch (\Exception $exception) {
+ return $this->toData('100500', 'The system is busy. Please try again later.', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+ private function getUserBrlStock($data, int $type = 0): array
+ {
+ try {
+ validate(WalletValidate::class)->scene('getUserBalance')->check($data);
+ if ($type == 0) {
+ return UserStockBrlModel::getUserStockList($data['user_id']);
+ } else {
+ return UserStockBrlModel::getUserStockByUserId($data);
+ }
+ } catch (ValidateException $validateException) {
+ $message = $validateException->getMessage();
+ return $this->toData('1', $message, []);
+ } catch (\Exception $exception) {
+ return $this->toData('100500', 'The system is busy. Please try again later.', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+ private function getUserJpStock($data, int $type = 0): array
+ {
+ try {
+ validate(WalletValidate::class)->scene('getUserBalance')->check($data);
+ if ($type == 0) {
+ return UserStockJpModel::getUserStockList($data['user_id']);
+ } else {
+ return UserStockJpModel::getUserStockByUserId($data);
+ }
+ } catch (ValidateException $validateException) {
+ $message = $validateException->getMessage();
+ return $this->toData('1', $message, []);
+ } catch (\Exception $exception) {
+ return $this->toData('100500', 'The system is busy. Please try again later.', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+
+ /**
+ * 获取用户印度期权资产
+ * @param $user_id
+ * @return array
+ */
+ private function getUserInOption($data, int $type = 0): array
+ {
+ try {
+ validate(WalletValidate::class)->scene('getUserBalance')->check($data);
+ if ($type == 0) {
+ return UserStockOptionInrModel::getUserStockList($data['user_id']);
+ } else {
+ return UserStockOptionInrModel::getUserStockByUserId($data);
+ }
+ } catch (ValidateException $validateException) {
+ $message = $validateException->getMessage();
+ return $this->toData('1', $message, []);
+ } catch (\Exception $exception) {
+ return $this->toData('100500', 'The system is busy. Please try again later.', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+
+ /**
+ * 获取用户充值列表
+ * @param array $data
+ * @return array
+ */
+ public function getUserRechargeList(array $data): array
+ {
+ try {
+ validate(WalletValidate::class)->scene('getDrawalList')->check($data);
+ $list = RechargeApplyModel::getUserRecharge($data);
+ return $this->toData(0, 'Request successful.', $list);
+ } catch (ValidateException $validateException) {
+ $message = $validateException->getMessage();
+ return $this->toData('1', $message, []);
+ } catch (\Exception $exception) {
+ return $this->toData('100500', 'The system is busy. Please try again later.', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+
+ public function getUserRechargeWallet(array $data): array
+ {
+ $list = WalletListModel::getUserWalletList([
+ 'wallet_type' => $data['wallet_type']
+ ]);
+ return $this->toData(0, 'Request successful.', $list);
+ }
+
+ /**
+ * 用户添加钱包地址
+ * @param array $data
+ * @return array
+ */
+ public function insertWalletAdress(array $data): array
+ {
+ try {
+ validate(BankValidate::class)->scene('setWalletAddress')->check($data);
+ UserWalletaddressModel::InsertUserWallet($data);
+ return $this->toData(0, 'Request successful.');
+ } catch (ValidateException $validateException) {
+ $message = $validateException->getMessage();
+ return $this->toData('1', $message, []);
+ } catch (\Exception $exception) {
+ return $this->toData('100500', 'The system is busy. Please try again later.', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+
+ /**
+ * 获取用户钱包地址列表
+ * @param array $data
+ * @return array
+ */
+ public function getUserWalletAddress(array $data): array
+ {
+ try {
+ validate(BankValidate::class)->scene('getWalletAddressList')->check($data);
+ $address_list = UserWalletaddressModel::getUserWalletList($data);
+ return $this->toData(0, 'Request successful.', $address_list);
+ } catch (ValidateException $validateException) {
+ $message = $validateException->getMessage();
+ return $this->toData('1', $message, []);
+ } catch (\Exception $exception) {
+ return $this->toData('100500', 'The system is busy. Please try again later.', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+
+ /**
+ * 获取用户钱包地址详情
+ * @param array $data
+ * @param int $type
+ * @return array
+ *
+ */
+ public function getUserWalletAddressInfo(array $data, int $type = 0): array
+ {
+ try {
+ validate(BankValidate::class)->scene('getWalletAddressInfo')->check($data);
+ $address_info = UserWalletaddressModel::getUserWalletInfoById($data);
+ if ($type) {
+ return $address_info;
+ } else {
+ return $this->toData(0, 'Request successful.', $address_info);
+ }
+ } catch (ValidateException $validateException) {
+ $message = $validateException->getMessage();
+ return $this->toData('1', $message, []);
+ } catch (\Exception $exception) {
+ return $this->toData('100500', 'The system is busy. Please try again later.', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+
+ /**
+ * 删除用户钱包地址
+ * @param array $data
+ * @return array
+ */
+ public function delUserWalletAddress(array $data): array
+ {
+ try {
+ validate(BankValidate::class)->scene('getWalletAddressInfo')->check($data);
+ UserWalletaddressModel::delUserWalletById($data);
+ return $this->toData(0, 'Request successful.');
+ } catch (ValidateException $validateException) {
+ $message = $validateException->getMessage();
+ return $this->toData('1', $message, []);
+ } catch (\Exception $exception) {
+ return $this->toData('100500', 'The system is busy. Please try again later.', [$exception->getMessage(), $exception->getTrace()]);
+ }
+
+ }
+
+ /**
+ * 添加编辑银行卡
+ * @param array $data
+ * @return array
+ */
+ public function insertUserBank(array $data): array
+ {
+ try {
+ validate(BankValidate::class)->scene('setBank')->check($data);
+ UserBankModel::InsertUserBank($data);
+ return $this->toData(0, 'Request successful.');
+ } catch (ValidateException $validateException) {
+ $message = $validateException->getMessage();
+ return $this->toData('1', $message, []);
+ } catch (\Exception $exception) {
+ return $this->toData('100500', 'The system is busy. Please try again later.', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+
+ /**
+ * 获取银行卡列表
+ * @param array $data
+ * @return array
+ */
+ public function getUserBank(array $data): array
+ {
+ try {
+ validate(BankValidate::class)->scene('getBankList')->check($data);
+ $bank_list = UserBankModel::getUserBankList($data);
+ return $this->toData(0, 'Request successful.', $bank_list);
+ } catch (ValidateException $validateException) {
+ $message = $validateException->getMessage();
+ return $this->toData('1', $message, []);
+ } catch (\Exception $exception) {
+ return $this->toData('100500', 'The system is busy. Please try again later.', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+
+ /**
+ * 获取银行卡详情
+ * @param array $data
+ * @return array
+ */
+ public function getUserBankInfo(array $data, int $type = 0): array
+ {
+ try {
+ validate(BankValidate::class)->scene('getBankInfo')->check($data);
+ $bank_info = UserBankModel::getUserBankInfoById($data);
+ if ($type) {
+ return $bank_info;
+ } else {
+ return $this->toData(0, 'Request successful.', $bank_info);
+ }
+ } catch (ValidateException $validateException) {
+ $message = $validateException->getMessage();
+ return $this->toData('1', $message, []);
+ } catch (\Exception $exception) {
+ return $this->toData('100500', 'The system is busy. Please try again later.', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+
+ /**
+ * 删除银行卡
+ * @param array $data
+ * @return array
+ */
+ public function delUserBank(array $data): array
+ {
+ try {
+ validate(BankValidate::class)->scene('getBankInfo')->check($data);
+ UserBankModel::delUserBankById($data);
+ return $this->toData(0, 'Request successful.');
+ } catch (ValidateException $validateException) {
+ $message = $validateException->getMessage();
+ return $this->toData('1', $message, []);
+ } catch (\Exception $exception) {
+ return $this->toData('100500', 'The system is busy. Please try again later.', [$exception->getMessage(), $exception->getTrace()]);
+ }
+
+ }
+
+ /**
+ * 获取用户账户可用余额
+ * @param array $data
+ * @return array
+ */
+ public function getUserBalance(array $data): array
+ {
+ //账户类型:1现货,2合约,3美股 4 印尼股票 5 马来西呀 6 泰股 7印度股 8秒合约 9新加坡股 10基金 11印度期权 12港股
+ switch ($data['account_type']) {
+ case 2:
+ $usdt_info = $this->getUserContract($data, 1);
+ break;
+ case 3:
+ $usdt_info = $this->getUserUsStock($data, 1);
+ break;
+ case 4:
+ $usdt_info = $this->getUserIdnStock($data, 1);
+ break;
+ case 5:
+ $usdt_info = $this->getUserMysStock($data, 1);
+ break;
+ case 6:
+ $usdt_info = $this->getUserThaStock($data, 1);
+ break;
+ case 7:
+ $usdt_info = $this->getUserInStock($data, 1);
+ break;
+ case 8:
+ $usdt_info = $this->getUserContractSec($data, 1);
+ break;
+ case 9:
+ $usdt_info = $this->getUserSgdStock($data, 1);
+ break;
+ case 10:
+ $usdt_info = $this->getUserFundStock($data, 1);
+ break;
+ case 11:
+ $usdt_info = $this->getUserInOption($data, 1);
+ break;
+ case 12:
+ $usdt_info = $this->getUserHkStock($data, 1);
+ break;
+ case 14:
+ $usdt_info = $this->getUserUkStock($data, 1);
+ break;
+ case 15:
+ $usdt_info = $this->getUserFurStock($data, 1);
+ break;
+ case 16:
+ $usdt_info = $this->getUserEurStock($data, 1);
+ break;
+ case 17:
+ $usdt_info = $this->getUserBrlStock($data, 1);
+ break;
+ case 18:
+ $usdt_info = $this->getUserJpStock($data, 1);
+ break;
+ case 19:
+ $usdt_info = $this->getUserForex($data, 1);
+ break;
+ default:
+ $usdt_info = $this->getUserDigital($data, 1);
+ break;
+ }
+ return $this->toData(0, "ok", $usdt_info);
+ }
+
+ /**
+ * 获取手续费用
+ * @return array
+ */
+ public function getDrawalFee(int $account_type = 0): array
+ {
+ $fee_info = DrawalSettingModel::getDrawalFee();
+ $info = FeeSettingModel::where('market_type', $account_type)->field('min_withdrawal_num,min_recharge_num')->find();
+ if(!empty($info)){
+ $info =$info->toArray();
+ $fee_info['min_drawal']=$info['min_withdrawal_num']>0 ? $info['min_withdrawal_num']: $fee_info['min_drawal'];
+ $fee_info['min_recharge']=$info['min_recharge_num']>0 ? $info['min_recharge_num']: $fee_info['min_recharge'];
+ }
+ return $this->toData(0, "ok",$fee_info);
+ }
+
+ /**
+ * 处理提款;处理流程: 1.提交提款申请 ->检查余额->将可用余额扣除提款金额及手续费,转入冻结余额
+ * @param array $data
+ * @return array
+ */
+ public function dealDrawalApply(array $data): array
+ {
+ //校验交易密码
+ $salt = env('ENCRYPT.SALT');
+ $name = env('WALLET.NAME');
+ $user_info = UserModel::getFieldsByUserId('trade_password,is_real', $data['user_id']);
+ if (empty($user_info['trade_password'])) {
+ return $this->toData(3, "Please set a transaction password first.");
+ }
+ if ($user_info['is_real'] == 0 && $name == 'STOCK') {
+ return $this->toData('20150', 'Please authenticate with real name first', []);
+ }
+ $check_pwd = (new UnqId())->checkPassword($data['trade_pwd'], $user_info['trade_password'], $salt);
+ if (!$check_pwd) {
+ return $this->toData(2, "Transaction password is incorrect.");
+ }
+ $flag = $this->checkOnlyOneNotEmpty($data['bank_id'], $data['address_id'], $data['wallet_address']);
+ if ($flag) {
+ //手续费
+ $fee = $this->getUserDrawalFee($data['apply_num'], $data['drawal_type']);
+ $pay_info = [];
+ if ($data['bank_id'] > 0) {
+ $pay_info = $this->getUserBankInfo(['user_id' => $data['user_id'], 'id' => $data['bank_id']], 1);
+ }
+ if ($data['address_id'] > 0) {
+ $pay_info = $this->getUserWalletAddressInfo(['user_id' => $data['user_id'], 'adr_id' => $data['address_id']], 1);
+ }
+ if (!empty($data['wallet_address'])) {
+ $pay_info['wallet_address'] = $data['wallet_address'];
+ }
+ if (empty($pay_info)) {
+ return $this->toData(1, 'The withdrawal information is incorrect.');
+ }
+ if ($data['account_type'] > 2 && ($data['account_type'] != 8)) {
+ $market_rate = (new StockMarketModel())->getRate($data['account_type']);
+ } else {
+ $market_rate = 1;
+ }
+ //提现金额
+ $apply_num = ($data['apply_num'] - $fee);
+
+ $apply_usd_num = round($apply_num / $market_rate, 4);
+
+ //印尼通道
+ $currency_rate = (new StockMarketModel())->getRate(4);
+
+ //扣手续费
+ $total_amount = round($apply_usd_num * $currency_rate, 4);
+
+ //事务开启, 查询用户资金
+ Db::startTrans();
+ try {
+ //查询提现资金账户信息
+ $from_account = $this->lockUserBalance($data['account_type'], $data['user_id']);
+ if (empty($from_account)) Db::rollback();
+ //换算汇率
+ //$change_num=$apply_num*$market_rate;
+ $change_num = $apply_num;
+ $cha_num = bcsub($from_account['usable_num'], $data['apply_num'], 18); //$from_account['usable_num']-$data['apply_num'];
+ if ($cha_num < 0) {
+ Db::rollback();
+ return $this->toData(1, 'Insufficient balance.');
+ }
+
+ //插入提款记录表
+ $drawal_data['user_id'] = $data['user_id'];
+ $drawal_data['order_no'] = $this->generateOrderNumber(20);
+ $drawal_data['account_type'] = $data['account_type'];
+ $drawal_data['apply_type'] = $data['apply_type'];
+ $drawal_data['apply_num'] = $apply_usd_num;
+ $drawal_data['service_fee'] = $fee;
+ $drawal_data['currency_rate'] = $currency_rate;
+ $drawal_data['pay_info'] = json_encode($pay_info);
+ $drawal_data['status'] = 0;
+ $drawal_data['country'] = $data['country'];
+ $drawal_data['drawal_type'] = $data['drawal_type'];
+ $drawal_data['market_amount'] = $data['apply_num'];
+ $drawal_data['total_amount'] = $apply_num;
+ UserWithdrawalModel::InsertUserDrawalLog($drawal_data);
+
+ $log_data['user_id'] = $data['user_id'];
+ $log_data['change_type'] = 5; //冻结
+ $log_data['change_num'] = -$data['apply_num'];
+ $log_data['before_num'] = $from_account['usable_num'];
+ $log_data['order_id'] = $drawal_data['order_no'];
+ $res = $this->addUserBalanceLog($data['account_type'], $log_data);
+ if (empty($res)) Db::rollback();
+ Db::commit();
+ return $this->toData(0, 'Request successful.');
+ } catch (\Exception $exception) {
+ // 回滚事务
+ Db::rollback();
+ return $this->toData('100500', 'The system is busy. Please try again later.', [$exception->getMessage(), $exception->getTrace()]);
+ }
+
+ } else {
+ return $this->toData(1, "Please fill in the parameters according to the requirements.");
+ }
+
+ }
+ public function canncelDrawalApply(array $data): array
+ {
+ $order_info = UserWithdrawalModel::getUserDrawalInfo($data);
+ if ($order_info['status'] == 0) {
+ $obj = new AdminBaseService();
+ $updateStatus = $obj->updateUserAsset($order_info['user_id'], $order_info['account_type'], 6, $order_info['market_amount'], -$order_info['market_amount'], $order_info['order_no']);
+ if (!empty($updateStatus) && $updateStatus['status'] == 200) {
+ return $this->toData(0, 'Request successful.');
+ }else{
+ return $this->toData(500, "System error.");
+ }
+ } else {
+ return $this->toData(300, "Withdrawal orders cannot be cancelled.");
+ }
+ }
+ private function checkOnlyOneNotEmpty($value1, $value2, $value3): bool
+ {
+ $count = 0; // 用于计数非空值的个数
+ if (!empty($value1)) {
+ $count++;
+ }
+ if (!empty($value2)) {
+ $count++;
+ }
+ if (!empty($value3)) {
+ $count++;
+ }
+ // 如果非空值的个数等于1,则返回 true,否则返回 false
+ return $count == 1;
+ }
+
+ public function getDrawalList(array $data): array
+ {
+ try {
+ validate(WalletValidate::class)->scene('getDrawalList')->check($data);
+ $list = UserWithdrawalModel::getUserDrawalList($data);
+ return $this->toData(0, 'Request successful.', $list);
+ } catch (ValidateException $validateException) {
+ $message = $validateException->getMessage();
+ return $this->toData('1', $message, []);
+ } catch (\Exception $exception) {
+ return $this->toData('100500', 'The system is busy. Please try again later.', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+
+ /**
+ * 计算用户提现手续费用
+ * @param $money
+ * @param $type 1数字币,2银行卡
+ * @return float|int|mixed
+ */
+ private function getUserDrawalFee($money, $type = 0)
+ {
+ $fee_info = DrawalSettingModel::getDrawalFee();
+ if ($type == 2) {
+ return $fee_info['bank_drawal_fee'] * $money;
+ } else {
+ return $fee_info['digital_drawal_fee'];
+ }
+ }
+
+ public function getUserBalanceRecord(array $data): array
+ {
+ $record_list = [];
+ //账户类型:1现货,2合约,3美股
+ switch ($data['account_type']) {
+ case 1:
+ $record_list = UserDigitalLogModel::getUserBalanceLog($data);
+ break;
+ case 2:
+ $record_list = UserContractLogModel::getUserBalanceLog($data);
+ break;
+ case 3:
+ $record_list = UserStockLogModel::getUserBalanceLog($data);
+ break;
+ case 4:
+ // 印尼股票
+ $record_list = UserStockIdnLogModel::getUserBalanceLog($data);
+ break;
+ case 5:
+ // 马来股票
+ $record_list = UserStockMysLogModel::getUserBalanceLog($data);
+ break;
+ case 6:
+ // 泰国股票
+ $record_list = UserStockThaLogModel::getUserBalanceLog($data);
+ break;
+ case 7:
+ // 印度股票
+ $record_list = UserStockInLogModel::getUserBalanceLog($data);
+ break;
+ case 8:
+ // 秒合约
+ $record_list = UserContractSecLogModel::getUserBalanceLog($data);
+ break;
+ case 9:
+ // 新加坡
+ $record_list = UserStockSgdLogModel::getUserBalanceLog($data);
+ break;
+ case 10:
+ // 基金
+ $record_list = UserStockFundLogModel::getUserBalanceLog($data);
+ break;
+ case 11:
+ // 印度期权
+ $record_list = UserStockOptionInrLogModel::getUserBalanceLog($data);
+ break;
+ case 12:
+ // 香港
+ $record_list = UserStockHkdLogModel::getUserBalanceLog($data);
+ break;
+ case 14:
+ // 德国
+ $record_list = UserStockGBXLogModel::getUserBalanceLog($data);
+ break;
+ case 15:
+ // 法国
+ $record_list = UserStockFurLogModel::getUserBalanceLog($data);
+ break;
+ case 16:
+ // 英国
+ $record_list = UserStockEurLogModel::getUserBalanceLog($data);
+ break;
+ case 17:
+ // 巴西
+ $record_list = UserStockBrlLogModel::getUserBalanceLog($data);
+ break;
+ case 18:
+ // 巴西
+ $record_list = UserStockJpLogModel::getUserBalanceLog($data);
+ break;
+ case 19:
+ // 巴西
+ $record_list =UserForexLogModel::getUserBalanceLog($data);
+ break;
+ default:
+ return $this->toData(1, "Please fill in the parameters according to the requirements.");
+ break;
+ }
+ return $this->toData(0, "ok", $record_list);
+ }
+
+ /**
+ * 处理用户各资金账户相互划转
+ * @param array $data
+ * @return array
+ */
+ public function doUserTransfer(array $data): array
+ {
+ try {
+ validate(WalletValidate::class)->scene('transfer')->check($data);
+ if ($data['from_account'] == $data['to_account']) {
+ return $this->toData('2', 'The transfer out and transfer in accounts cannot be the same account.');
+ }
+ //事务开启, 查询用户资金
+ Db::startTrans();
+ try {
+ //查询划转资金账户信息
+ $from_account = $this->lockUserBalance($data['from_account'], $data['user_id']);
+ if (empty($from_account)) {
+ Db::rollback();
+ return $this->toData('2', 'error');
+ }
+
+ //print_r($from_account);
+
+ $cha_num = $from_account['usable_num'] - $data['change_num'];
+ if ($cha_num < 0) {
+ Db::rollback();
+ return $this->toData(1, 'Insufficient balance.');
+ }
+
+ $to_num = $this->getRateToTransfer([
+ 'from_account' => $data['from_account'],
+ 'to_account' => $data['to_account'],
+ 'change_num' => $data['change_num']
+ ]);
+
+ $to_num_data = $to_num['data'];
+ if (!isset($to_num_data['to_change_num']) || !is_numeric($to_num_data['to_change_num']) || $to_num_data['to_change_num'] <= 0) {
+ return $to_num;
+ }
+
+ //查询转入资金账户信息
+ $to_account = $this->lockUserBalance($data['to_account'], $data['user_id']);
+ if (empty($to_account)) {
+ Db::rollback();
+ return $this->toData('2', 'error to_account ');
+ }
+
+
+ //插入账户资金划转表
+ $transfer_data['user_id'] = $data['user_id'];
+ $transfer_data['from_account'] = $data['from_account'];
+ $transfer_data['to_account'] = $data['to_account'];
+ $transfer_data['from_num'] = $data['change_num']; // 转出数量
+ $transfer_data['to_num'] = $to_num_data['to_change_num']; // 转入数量
+ $transfer_data['from_account_rate'] = $to_num_data['from_usd']; // 转出费率
+ $transfer_data['to_account_rate'] = $to_num_data['usd_to']; // 转入费率
+ $transfer_data['status'] = 1;
+ $transfer_data['order_sn'] = $this->generateOrderNumber(20);
+ UserTransferModel::InsertUserStock($transfer_data);
+
+ //更新划转资金账户余额
+ $from_update['usable_num'] = $cha_num;
+ $res = $this->updateUserBalance($data['from_account'], $from_update, $data['user_id']);
+ if (empty($res)) {
+ Db::rollback();
+ return $this->toData('2', 'error from_account transfer');
+ }
+
+ // 新增转入
+ $to_update['usable_num'] = $to_account['usable_num'] + $to_num_data['to_change_num'];
+ $res = $this->updateUserBalance($data['to_account'], $to_update, $data['user_id']);
+ if (empty($res)) {
+ Db::rollback();
+ return $this->toData('2', 'error to_account transfer ');
+ }
+
+ //变动类型:1-充值,2-提现,3-买入,4-卖出,5-冻结,6-解冻,7账户转出,8账户转入
+ //插入资金变动日志
+
+ $from_log['user_id'] = $data['user_id'];
+ $from_log['change_type'] = 7;
+ $from_log['change_num'] = -$data['change_num'];
+ $from_log['before_num'] = $from_account['usable_num'];
+ $from_log['order_id'] = $transfer_data['order_sn'];
+ $res = $this->addUserBalanceLog($data['from_account'], $from_log);
+ if (empty($res)) {
+ Db::rollback();
+ return $this->toData('2', 'error from_log transfer');
+ }
+
+
+ $to_log['user_id'] = $data['user_id'];
+ $to_log['change_type'] = 8;
+ $to_log['change_num'] = $to_num_data['to_change_num'];
+ $to_log['before_num'] = $to_account['usable_num'];
+ $to_log['order_id'] = $transfer_data['order_sn'];
+ $res = $this->addUserBalanceLog($data['to_account'], $to_log);
+ if (empty($res)) {
+ Db::rollback();
+ return $this->toData('2', 'error to_log transfer');
+ }
+
+ Db::commit();
+
+ return $this->toData(0, 'Request successful.');
+ } catch (\Exception $exception) {
+ // 回滚事务
+ Db::rollback();
+ return $this->toData('100500', 'The system is busy. Please try again later.', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ } catch (ValidateException $validateException) {
+ $message = $validateException->getMessage();
+ return $this->toData('1', $message, []);
+ } catch (\Exception $exception) {
+ return $this->toData('100500', 'The system is busy. Please try again later.', [$exception->getMessage(), $exception->getTrace()]);
+ }
+
+ }
+
+ public function lockUserBalance(int $account_type, int $user_id): array
+ {
+ switch ($account_type) {
+ case 1:
+ return UserDigitalModel::getUserDigitalLock($user_id);
+ break;
+ case 2:
+ return UserContractModel::getUserContractLock($user_id);
+ break;
+ case 3:
+ // 美股
+ return UserStockModel::getUserStockLock($user_id);
+ break;
+ case 4:
+ // 印尼 股
+ return UserStockIdnModel::getUserStockLock($user_id);
+ break;
+ case 5:
+ // 马来西亚 股
+ return UserStockMysModel::getUserStockLock($user_id);
+ break;
+ case 6:
+ // 泰 股
+ return UserStockThaModel::getUserStockLock($user_id);
+ break;
+ case 7:
+ // 印度 股
+ return UserStockInModel::getUserStockLock($user_id);
+ break;
+ case 8:
+ // 秒合约
+ return UserContractSecModel::getUserContractLock($user_id);
+ break;
+ case 9:
+ // 新加坡
+ return UserStockSgdModel::getUserStockLock($user_id);
+ break;
+ case 10:
+ // 基金
+ return UserStockFundModel::getUserStockLock($user_id);
+ break;
+ case 11:
+ // 印度期权
+ return UserStockOptionInrModel::getUserStockLock($user_id);
+ break;
+ case 12:
+ // 香港
+ return UserStockHkdModel::getUserStockLock($user_id);
+ break;
+ case 14:
+ // 英国
+ return UserStockGBXModel::getUserStockLock($user_id);
+ break;
+ case 15:
+ // 英国
+ return UserStockFurModel::getUserStockLock($user_id);
+ break;
+ case 16:
+ // 英国
+ return UserStockEurModel::getUserStockLock($user_id);
+ break;
+ case 17:
+ // 巴西
+ return UserStockBrlModel::getUserStockLock($user_id);
+ break;
+ case 18:
+ // 巴西
+ return UserStockJpModel::getUserStockLock($user_id);
+ break;
+ case 19:
+ // 巴西
+ return UserForexModel::getUserForexLock($user_id);
+ break;
+ default:
+ return [];
+ break;
+ }
+ }
+
+ public function updateUserBalance(int $account_type, array $update_data, int $user_id): bool
+ {
+ switch ($account_type) {
+ case 1:
+ return UserDigitalModel::updateUserDigital($update_data, [
+ 'user_id' => $user_id,
+ 'digital_id' => 'USDT'
+ ]);
+ break;
+ case 2:
+ return UserContractModel::updateUserContract($update_data, [
+ 'user_id' => $user_id,
+ 'contract_id' => 'USDT'
+ ]);
+ break;
+ case 3:
+ return UserStockModel::updateUserStock($update_data, [
+ 'user_id' => $user_id,
+ 'stock_id' => 'USD'
+ ]);
+ break;
+ case 4:
+ return UserStockIdnModel::updateUserStock($update_data, [
+ 'user_id' => $user_id,
+ 'stock_id' => 'IDR'
+ ]);
+ break;
+ case 5:
+ return UserStockMysModel::updateUserStock($update_data, [
+ 'user_id' => $user_id,
+ 'stock_id' => 'MYR'
+ ]);
+ break;
+ case 6:
+ return UserStockThaModel::updateUserStock($update_data, [
+ 'user_id' => $user_id,
+ 'stock_id' => 'THB'
+ ]);
+ break;
+ case 7:
+ return UserStockInModel::updateUserStock($update_data, [
+ 'user_id' => $user_id,
+ 'stock_id' => 'INR'
+ ]);
+ break;
+ case 8:
+ return UserContractSecModel::updateUserContract($update_data, [
+ 'user_id' => $user_id,
+ 'contract_id' => 'USDT'
+ ]);
+ break;
+ case 9:
+ return UserStockSgdModel::updateUserStock($update_data, [
+ 'user_id' => $user_id,
+ 'stock_id' => 'SGD'
+ ]);
+ break;
+ case 10:
+ return UserStockFundModel::updateUserStock($update_data, [
+ 'user_id' => $user_id,
+ 'stock_id' => 'USD'
+ ]);
+ break;
+ case 11:
+ return UserStockOptionInrModel::updateUserStock($update_data, [
+ 'user_id' => $user_id,
+ 'stock_id' => 'INR'
+ ]);
+ break;
+ case 12:
+ return UserStockHkdModel::updateUserStock($update_data, [
+ 'user_id' => $user_id,
+ 'stock_id' => 'HKD'
+ ]);
+ break;
+ case 14:
+ return UserStockGBXModel::updateUserStock($update_data, [
+ 'user_id' => $user_id,
+ 'stock_id' => 'GBX'
+ ]);
+ break;
+ case 15:
+ return UserStockFurModel::updateUserStock($update_data, [
+ 'user_id' => $user_id,
+ 'stock_id' => 'EUR'
+ ]);
+ break;
+ case 16:
+ return UserStockEurModel::updateUserStock($update_data, [
+ 'user_id' => $user_id,
+ 'stock_id' => 'EUR'
+ ]);
+ break;
+ case 17:
+ return UserStockBrlModel::updateUserStock($update_data, [
+ 'user_id' => $user_id,
+ 'stock_id' => 'BRL'
+ ]);
+ break;
+ case 18:
+ return UserStockJpModel::updateUserStock($update_data, [
+ 'user_id' => $user_id,
+ 'stock_id' => 'JPY'
+ ]);
+ break;
+ case 19:
+ return UserForexModel::updateUserForex($update_data, [
+ 'user_id' => $user_id,
+ 'contract_id' => 'USD'
+ ]);
+ break;
+ default:
+ return false;
+ break;
+ }
+ }
+
+ public function addUserBalanceLog(int $account_type, array $log_data): bool
+ {
+ switch ($account_type) {
+ case 1:
+ $log_data['digital_id'] = 'USDT';
+ return UserDigitalLogModel::InsertUserBalanceLog($log_data);
+ break;
+ case 2:
+ $log_data['contract_id'] = 'USDT';
+ return UserContractLogModel::InsertUserBalanceLog($log_data);
+ break;
+ case 3:
+ $log_data['stock_id'] = 'USD';
+ return UserStockLogModel::InsertUserBalanceLog($log_data);
+ break;
+ case 4:
+ $log_data['stock_id'] = 'IDR';
+ return UserStockIdnLogModel::InsertUserBalanceLog($log_data);
+ break;
+ case 5:
+ $log_data['stock_id'] = 'MYR';
+ return UserStockMysLogModel::InsertUserBalanceLog($log_data);
+ break;
+ case 6:
+ $log_data['stock_id'] = 'THB';
+ return UserStockThaLogModel::InsertUserBalanceLog($log_data);
+ break;
+ case 7:
+ $log_data['stock_id'] = 'INR';
+ return UserStockInLogModel::InsertUserBalanceLog($log_data);
+ break;
+ case 8:
+ $log_data['contract_id'] = 'USDT';
+ return UserContractSecLogModel::InsertUserBalanceLog($log_data);
+ break;
+ case 9:
+ $log_data['stock_id'] = 'SGD';
+ return UserStockSgdLogModel::InsertUserBalanceLog($log_data);
+ break;
+ case 10:
+ $log_data['stock_id'] = 'USD';
+ return UserStockFundLogModel::InsertUserBalanceLog($log_data);
+ break;
+ case 11:
+ $log_data['stock_id'] = 'INR';
+ return UserStockOptionInrLogModel::InsertUserBalanceLog($log_data);
+ break;
+ case 12:
+ $log_data['stock_id'] = 'HKD';
+ return UserStockHkdLogModel::InsertUserBalanceLog($log_data);
+ break;
+ case 14:
+ $log_data['stock_id'] = 'GBX';
+ return UserStockGBXLogModel::InsertUserBalanceLog($log_data);
+ break;
+ case 15:
+ $log_data['stock_id'] = 'EUR';
+ return UserStockFurLogModel::InsertUserBalanceLog($log_data);
+ break;
+ case 16:
+ $log_data['stock_id'] = 'EUR';
+ return UserStockEurLogModel::InsertUserBalanceLog($log_data);
+ break;
+ case 17:
+ $log_data['stock_id'] = 'BRL';
+ return UserStockBrlLogModel::InsertUserBalanceLog($log_data);
+ break;
+ case 18:
+ $log_data['stock_id'] = 'JPY';
+ return UserStockJpLogModel::InsertUserBalanceLog($log_data);
+ break;
+ case 19:
+ $log_data['contract_id'] = 'USD';
+ return UserForexLogModel::InsertUserBalanceLog($log_data);
+ break;
+ default:
+ return false;
+ break;
+ }
+ }
+
+ /**
+ * 获取用户资金划转明细
+ * @param array $data
+ * @return array
+ */
+ public function getUserTransfer(array $data): array
+ {
+ try {
+ validate(WalletValidate::class)->scene('getRechargeList')->check($data);
+ $list = UserTransferModel::getUserTransferList($data);
+ return $this->toData(0, 'Request successful.', $list);
+ } catch (ValidateException $validateException) {
+ $message = $validateException->getMessage();
+ return $this->toData('1', $message, []);
+ } catch (\Exception $exception) {
+ return $this->toData('100500', 'The system is busy. Please try again later.', [$exception->getMessage(), $exception->getTrace()]);
+ }
+ }
+ public function userHasNotPay(array $data):array
+ {
+ if (!empty($data['market_type'])) {
+ $table_obj = (new \app\admin\service\setting\IPOService())->getStockModel($data['market_type']);
+ if (empty($table_obj)) {
+ return $this->toData(1, 'system error.');
+ }
+ $list = UserArrearsModel::where('user_id', $data['user_id'])->where('status', 0)->where('account_type', $data['market_type'])->select();
+ } else {
+ $list = UserArrearsModel::where('user_id', $data['user_id'])->where('status', 0)->select();
+ }
+ if (empty($list)) {
+ $list = [];
+ } else {
+ $list = $list->toArray();
+ foreach ($list as $key => $val) {
+ $table_obj = (new \app\admin\service\setting\IPOService())->getStockModel($val['account_type']);
+ $order = Db::table($table_obj['order_table'])->where('order_no', $val['order_no'])->find();
+ if ($order) {
+ $list[$key]['get_num'] = $order['get_num'];
+ $list[$key]['get_amount'] = $order['get_amount'];
+ $list[$key]['get_fee'] = $order['get_fee'];
+ $list[$key]['stock_code'] = Db::table($table_obj['stock_table'])->where('id', $order['pre_stock_id'])->value('stock_code');
+ }
+
+ }
+ }
+ return $this->toData(0, 'Request successful.', $list);
+ }
+
+
+ public function dealUnPayIPO(array $data):array
+ {
+ $total=UserArrearsModel::where('user_id',$data['user_id'])->where('account_type',$data['market_type'])->where('status',0)->sum('num');
+ $table_obj=(new \app\admin\service\setting\IPOService())->getStockModel($data['market_type']);
+ $res=Db::table($table_obj['user_table'])->where('user_id',$data['user_id'])->where('stock_id',$table_obj['stock_id'])
+ ->where('usable_num','>=',$total)
+ ->find();
+ if(empty($res)){
+ return $this->toData(1, 'The balance is not enough.');
+ }
+
+
+
+ $order_list=UserArrearsModel::where('user_id',$data['user_id'])->where('account_type',$data['market_type'])->select();
+ $nowDate=date('Y-m-d H:i:s');
+ Db::startTrans();
+ //扣钱
+ $update_bool = Db::table($table_obj['user_table'])->where('stock_id', $table_obj['stock_id'])->where('user_id', $data['user_id'])
+ ->dec('usable_num', $total)
+ ->update(['update_time' => $nowDate]);
+ if(!$update_bool){
+ Db::rollback();
+ return $this->toData('1', 'system error0', []);
+ }
+
+ foreach ($order_list as $order){
+ //生成支付流水
+ $insertStockLogArr = [
+ 'user_id' => $order['user_id'],
+ 'change_type' => 15, // 新股申购扣减费用
+ 'stock_id' => $table_obj['stock_id'],
+ 'before_num' => 0,
+ 'change_num' => '-' . Db::table($table_obj['order_table'])->where('order_no',$order['order_no'])->value('get_amount'),
+ 'order_id' => $order['order_no'],
+ 'create_time' => $nowDate,
+ 'update_time' => $nowDate
+ ];
+ $log_bool = Db::table($table_obj['log_table'])->insert($insertStockLogArr);
+ if(!$log_bool){
+ Db::rollback();
+ return $this->toData('1', 'system error1', []);
+ }
+ // 生成扣手续流水
+ $insertStockLogArrFee = [
+ 'user_id' => $order['user_id'],
+ 'change_type' => 16, // 新股申购扣减费用
+ 'stock_id' => $table_obj['stock_id'],
+ 'before_num' => 0,
+ 'change_num' => '-' . Db::table($table_obj['order_table'])->where('order_no',$order['order_no'])->value('get_fee'),
+ 'order_id' => $order['order_no'],
+ 'create_time' => $nowDate,
+ 'update_time' => $nowDate
+ ];
+ $fee_bool = Db::table($table_obj['log_table'])->insert($insertStockLogArrFee);
+ if (!$fee_bool) {
+ Db::rollback();
+ return $this->toData('1', 'system error2', []);
+ }
+ //更新状态
+ $status_bool=UserArrearsModel::where('user_id',$order['user_id'])->where('order_no',$order['order_no'])->update([
+ 'status'=>1,
+ 'update_time'=>$nowDate
+ ]);
+ if (!$status_bool) {
+ Db::rollback();
+ return $this->toData('1', 'system error2', []);
+ }
+ //更新订单状态
+ if(env('USER_ARREARS.HAS_USER_ARREARS')==3){
+ $sign_status=Db::table($table_obj['stock_table'])->where('id',$order['pre_stock_id'])->value('sign_status');
+ $order_bool=Db::table($table_obj['order_table'])->where('order_no',$order['order_no'])->where('user_id',$order['user_id'])
+ ->update([
+ 'status'=> $sign_status==1 ? 2:3,
+ 'update_time'=>$nowDate
+ ]);
+ if (!$order_bool) {
+ Db::rollback();
+ return $this->toData('1', 'system error3'.Db::table($table_obj['order_table'])->getLastSql(), []);
+ }
+ }
+
+ //删除缓存订单
+ $key="USER:ARREAR:ORDER:".$order['order_no'];
+ Cache::store('redis')->delete($key);
+ }
+
+ Db::commit();
+
+ return $this->toData(0, 'Request successful.',[]);
+ }
+ // 获取账户之间划转手续费
+ public function getRateToTransfer($data)
+ {
+ try {
+ // 1 现货 2 合约 3 美股 4 印尼股 5 马股 6 泰股 7 印度
+ $fromAccount = $data['from_account'];
+ $toAccount = $data['to_account'];
+
+ if($fromAccount <1 || $fromAccount > 20){
+ return $this->toData('2', 'Transfer out account type is incorrect.');
+ }
+ if($toAccount <1 || $toAccount > 20){
+ return $this->toData('2', 'Transfer out account type is incorrect.');
+ }
+
+ if ($fromAccount == $toAccount) {
+ return $this->toData('2', 'The transfer out and transfer in accounts cannot be the same account.');
+ }
+
+ // 转出地址对美元的汇率
+ $fromRate = (new StockMarketModel())->getRate($fromAccount);
+ $toRate = (new StockMarketModel())->getRate($toAccount);
+
+ if ($fromRate <= 0) {
+ return $this->toData('2', 'Transfer out account type is incorrect.');
+ }
+
+ if ($toRate <= 0) {
+ return $this->toData('2', 'Transfer in account type is incorrect.');
+ }
+
+ // 是否传递转账数量
+ $toChangeNum = '-';
+ if (!empty($data['change_num']) && is_numeric($data['change_num']) && $data['change_num'] > 0) {
+ // 转出数量计算 change_num / from_rate * to_rate
+ $toChangeNum = bcmul(bcdiv($data['change_num'], $fromRate, 6), $toRate, 6);
+ }
+ return $this->toData('0', 'SUCCESS', [
+ 'from_usd' => $fromRate,
+ 'usd_to' => $toRate,
+ 'to_change_num' => $toChangeNum
+ ]);
+ } catch (\Exception $exception) {
+ return $this->toData('100500', 'The system is busy. Please try again later.', [$exception->getMessage(), $exception->getTrace()]);
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/app/home/service/XdPayService.php b/app/home/service/XdPayService.php
new file mode 100644
index 0000000..0a6f1bf
--- /dev/null
+++ b/app/home/service/XdPayService.php
@@ -0,0 +1,192 @@
+merchant;
+ $post_data['payCode']=$this->payCode;
+ $post_data['amount']=$amount;
+ $post_data['orderId']=$orderId;
+ $post_data['notifyUrl']=$notify_url.url('xdpay_notify');
+ $sign=$this->generateQueryString($post_data,$this->key);
+ $post_data['sign']=$sign;
+ $header = array("Content-Type:application/x-www-form-urlencoded");
+ $res=$this->curlPost($this->pay_url,$post_data,10,$header);
+ $result=json_decode($res,true);
+ return $result;
+ }
+ public function xdpayNotify($data){
+ Log::info('收到xdpay异步回调:'.json_encode($data));
+ $data['reverse']=$data['reverse'] ? 'true':'false';
+ $sign=$this->generateQueryString($data,$this->key);
+ if($sign==strtolower($data['sign'])){
+ if($data['status']==1){
+ $order_info=RechargeApplyModel::getOrderByNo([
+ 'order_no'=>$data['orderId']
+ ]);
+ if($order_info && $data['amount']==$order_info['total_amount']){
+ if($order_info['status']==0){
+ return (new PayService())->dealPayNotify($order_info);
+ }
+ }else{
+ Log::info('xdpay支付订单不存在:'.json_encode($data));
+ }
+ }else{
+ Log::info('xdpay支付订单支付失败:'.json_encode($data));
+ }
+ }else{
+ Log::info('xdpay签名校验失败:'.json_encode($data));
+ }
+ }
+ public function apply_pay($orderId,$amount,$ifsc,$bank_account,$nike_name)
+ {
+ $notify_url=env('PAY.NOTIFY_URL');
+ $post_data['merchant']=$this->merchant;
+ $post_data['payCode']=$this->payAppCode;
+ $post_data['amount']=$amount;
+ $post_data['orderId']=$orderId;
+ $post_data['notifyUrl']=$notify_url.'/bs/xdpay_anotify';
+ $post_data['bankAccount']=$bank_account;
+ $post_data['customName']=$nike_name;
+ $post_data['remark']=$ifsc;
+ $sign=$this->generateQueryString($post_data,$this->key);
+ $post_data['sign']=$sign;
+ $header = array("Content-Type:application/x-www-form-urlencoded");
+ $res=$this->curlPost($this->app_url,$post_data,10,$header);
+ $result=json_decode($res,true);
+ if($result['code']==200){
+ return [
+ 'code'=>200,
+ 'msg'=>'ok',
+ 'order_idx'=>$result['data']['platOrderId'],
+ 'content'=>$res
+ ];
+ }else{
+ return [
+ 'code'=>300,
+ 'msg'=>$res,
+ 'order_idx'=>'',
+ 'content'=>$res
+ ];
+ }
+ }
+ public function xdpayApplyNotify($data){
+ Log::info('收到xdpay代付异步回调:'.json_encode($data));
+ $data['reverse']=$data['reverse'] ? 'true':'false';
+ $sign=$this->generateQueryString($data,$this->key);
+ if($sign==strtolower($data['sign'])){
+ if($data['status']==1){
+ $order_info=UserWithdrawalModel::getUserDrawalInfo([
+ 'order_no'=>$data['orderId']
+ ]);
+ if($order_info && $order_info['status']==3){
+ UserWithdrawalModel::where([
+ 'id'=>$order_info['id']
+ ])->update([
+ 'status'=>4,
+ 'deal_time'=>date('Y-m-d H:i:s')
+ ]);
+ Log::info('xdpay代付支付成功:'.json_encode($data));
+ }else{
+ Log::info('xdpay代付订单不存在:'.json_encode($data));
+ }
+ }else{
+ UserWithdrawalModel::where([
+ 'order_no'=>$data['orderId']
+ ])->update([
+ 'status'=>1,
+ ]);
+ Log::info('xdpay代付失败:'.json_encode($data));
+ }
+ }else{
+ Log::info('xdpay代付签名校验失败:'.json_encode($data));
+ }
+ }
+ public function getBalance()
+ {
+ $post_data['merchant']=$this->merchant;
+ $sign=$this->generateQueryString($post_data,$this->key);
+ $post_data['sign']=$sign;
+ $header = array("Content-Type:application/x-www-form-urlencoded");
+ $res=$this->curlPost($this->bla_url,$post_data,10,$header);
+ $result=json_decode($res,true);
+ if($result['code']==200){
+ return [
+ 'amount'=>$result['data']['balanceUsable']
+ ];
+ }else{
+ return [
+ 'amount'=>0
+ ];
+ }
+ }
+ private function curlPost($url, $post_data = array(), $timeout = 5, $header = "", $data_type = "") {
+ $header = empty($header) ? '' : $header;
+ //支持json数据数据提交
+ if($data_type == 'json'){
+ $post_string = json_encode($post_data);
+ }elseif($data_type == 'array') {
+ $post_string = $post_data;
+ }elseif(is_array($post_data)){
+ $post_string = http_build_query($post_data, '', '&');
+ }
+
+ $ch = curl_init(); // 启动一个CURL会话
+ curl_setopt($ch, CURLOPT_URL, $url); // 要访问的地址
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 对认证证书来源的检查 // https请求 不验证证书和hosts
+ curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); // 从证书中检查SSL加密算法是否存在
+ curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']); // 模拟用户使用的浏览器
+ //curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1); // 使用自动跳转
+ //curl_setopt($curl, CURLOPT_AUTOREFERER, 1); // 自动设置Referer
+ curl_setopt($ch, CURLOPT_POST, true); // 发送一个常规的Post请求
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $post_string); // Post提交的数据包
+ curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout); // 设置超时限制防止死循环
+ curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
+ //curl_setopt($curl, CURLOPT_HEADER, 0); // 显示返回的Header区域内容
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // 获取的信息以文件流的形式返回
+ curl_setopt($ch, CURLOPT_HTTPHEADER, $header); //模拟的header头
+ $result = curl_exec($ch);
+ curl_close($ch);
+ return $result;
+ }
+ private function generateQueryString($fields, $privateKey) {
+ // 按ASCII顺序对字段名进行自然排序
+ ksort($fields);
+
+ // 将字段按 k=v 格式拼接成字符串
+ $query = '';
+ foreach($fields as $key => $value) {
+ if($key!='sign'){
+ $query .= $key . '=' . strval($value) . '&';
+ }
+ }
+ // 去除末尾的 '&'
+ $query = rtrim($query, '&');
+ // 在字符串末尾拼接私钥
+ $query .= '&key=' . $privateKey;
+ $sign=md5($query);
+ return $sign;
+ }
+
+
+}
\ No newline at end of file
diff --git a/app/home/validate/BankValidate.php b/app/home/validate/BankValidate.php
new file mode 100644
index 0000000..3c44878
--- /dev/null
+++ b/app/home/validate/BankValidate.php
@@ -0,0 +1,57 @@
+ 'require|number',
+ 'adr_id' => 'require|number',
+ 'user_id' => 'require|number',
+ 'true_name' => 'require|isString',
+ 'identity_card' => 'require|isString',
+ 'bank_name' => 'require|isString',
+ 'bank_card' => 'require|isString',
+ 'bank_phone' => 'require|isString',
+ 'bank_email' => 'require|email',
+
+ 'wallet_type' => 'require',
+ 'wallet_address' => 'require',
+ 'remark' => 'require',
+
+ 'is_default' => 'require|in:0,1',
+ 'page' => 'require|number',
+ 'page_size' => 'require|number',
+ ];
+
+ protected $message = [
+ 'id.require' => 'Please fill in the ID.',
+ 'adr_id.require' => 'Please fill in the ID.',
+ 'user_id.require' => 'Please fill in the user ID.',
+ 'true_name.require' => 'Please fill in the account name',
+ 'identity_card.require' => 'Please fill in the ID card number.',
+ 'bank_name.require' => 'Please fill in the bank name.',
+ 'bank_card.require' => 'Please fill in the bank card number.',
+ 'bank_phone.require' => 'Please fill in the phone number.',
+ 'bank_email.require' => 'Please fill in the email address.',
+ 'wallet_type.require' => 'Please fill in the wallet type.',
+ 'wallet_address.require' => 'Please fill in the wallet address.',
+ 'remark.require' => 'Please fill in the wallet remark.',
+ 'is_default.require' => 'Is it set as the default',
+ 'is_default.in' => 'data is error',
+ 'page.number' => 'Please enter the page number.',
+ 'page_size.number' => 'Please enter the page size number.',
+ ];
+
+ protected $scene = [
+ //'setBank' => ['id','user_id','true_name','identity_card','bank_name','bank_card','bank_phone','bank_email','is_default'],
+ 'setBank' => ['id','user_id','true_name','bank_name','bank_card','is_default'],
+ 'getBankList' => ['user_id','page','page_size'],
+ 'getBankInfo' => ['user_id','id'],
+
+ 'setWalletAddress'=>['adr_id','user_id','wallet_type','wallet_address','is_default'],
+ 'getWalletAddressList' => ['user_id','page','page_size'],
+ 'getWalletAddressInfo' => ['user_id','adr_id'],
+ 'delWalletAddress' => ['user_id','adr_id'],
+ ];
+}
diff --git a/app/home/validate/BaseHomeValidate.php b/app/home/validate/BaseHomeValidate.php
new file mode 100644
index 0000000..9f077e9
--- /dev/null
+++ b/app/home/validate/BaseHomeValidate.php
@@ -0,0 +1,21 @@
+ 'require|email|length:5,40',
+ 'email_code' => 'require|number',
+ 'password' => 'require|isString|length:5,40',
+ 'invite_code' => 'alphaDash',
+ 'phone' => 'require|isString|length:5,40',
+ 'nation' => 'require|isString',
+ 'sms_code' => 'require|isString',
+ 'device' => 'require|isString|length:2,100',
+ ];
+
+ protected $message = [
+ 'email.require' => 'The email is required.',
+ 'email.email' => 'The email format is incorrect.',
+ 'email.length' => 'The email length must be between 5 and 40 characters.',
+ 'email_code.require' => 'The email verification code is required.',
+ 'email_code.number' => 'The email verification code format is incorrect.',
+ 'password.require' => 'The password is required.',
+ 'password.isString' => 'The password is invalid.',
+ 'password.length' => 'The password length is invalid.',
+ 'invite_code.alphaDash' => 'The invitation code is invalid.',
+ 'phone.require' => 'The phone number is required.',
+ 'phone.number' => 'The phone number is invalid.',
+ 'phone.length' => 'The phone number length must be between 5 and 40 characters.',
+ 'nation.require' => 'The country code is required.',
+ 'nation.number' => 'The country code is invalid.',
+ 'sms_code.require' => 'The SMS verification code is required.',
+ 'sms_code.number' => 'The SMS verification code format is incorrect.',
+ 'device.require' => 'The device type is required.',
+ 'device.isString' => 'The device type format is incorrect.',
+ 'device.length' => 'The device type parameter is incorrect.',
+ ];
+
+ protected $scene = [
+ 'sendEmail' => ['email'],
+ 'emailRegister' => ['email', 'email_code', 'password', 'invite_code'],
+ 'emailLogin' => ['email', 'password','device'],
+ 'sendSms' => ['phone', 'nation'],
+ 'smsRegister' => ['phone', 'nation','sms_code', 'password', 'invite_code'],
+ 'smsLogin' => ['phone', 'nation','sms_code','device'],
+ 'emailForget' => ['email', 'email_code', 'password'],
+ 'smsForget' => ['phone', 'nation','sms_code', 'password'],
+ 'smsPasswordLogin' => ['phone', 'nation','password','device'],
+ ];
+}
\ No newline at end of file
diff --git a/app/home/validate/MarketValidate.php b/app/home/validate/MarketValidate.php
new file mode 100644
index 0000000..eee76a6
--- /dev/null
+++ b/app/home/validate/MarketValidate.php
@@ -0,0 +1,36 @@
+ 'require|number',
+ 'trade_name' => 'require|isString',
+ 'market_name' => 'require|isString',
+ 'page' => 'number',
+ 'page_size' => 'number',
+ ];
+
+ protected $message = [
+ 'user_id.require' => 'Please fill in the user ID.',
+ 'market_type.require' => 'Please fill in the market type.',
+ 'trade_name.require' => 'Please fill in the trading pair.',
+ 'market_name.require' => 'Please fill in the name of the trading pair.',
+ 'trade_name.isString' => 'The trading pair format is incorrect.',
+ 'market_type.in' => 'The market type is incorrect.',
+ 'page.number' => 'Please enter the page number.',
+ 'page_size.number' => 'Please enter the page size number.',
+ ];
+
+ protected $scene = [
+ 'setMarket' => ['user_id','market_type','trade_name','market_name','trade_numeric_code'],
+ 'delMarket' => ['user_id','market_type','trade_name'],
+ 'getMarket' => ['user_id','market_type','page','page_size'],
+ 'getMarketList' => ['market_type'],
+ 'getTradeFee' => ['market_type'],
+ 'getTrade' => ['market_type','trade_name'],
+ ];
+}
diff --git a/app/home/validate/UploadValidate.php b/app/home/validate/UploadValidate.php
new file mode 100644
index 0000000..85153f3
--- /dev/null
+++ b/app/home/validate/UploadValidate.php
@@ -0,0 +1,20 @@
+ 'require|fileSize:10485760|fileExt:jpg,jpeg,png',
+ ];
+
+ protected $message = [
+ 'image.require' => 'Please select a file.',
+ 'image.fileSize' => 'Please ensure that the file size is within 10 MB.',
+ 'image.fileExt' => 'Please upload the image in jpg, jpeg, or png format.',
+ ];
+
+ protected $scene = [
+ 'uploadImage' => ['image'],
+ ];
+}
\ No newline at end of file
diff --git a/app/home/validate/UserValidate.php b/app/home/validate/UserValidate.php
new file mode 100644
index 0000000..f194013
--- /dev/null
+++ b/app/home/validate/UserValidate.php
@@ -0,0 +1,119 @@
+ 'require|isString',
+ 'file_id' => 'require|integer',
+ 'email_code' => 'require|isString',
+ 'sms_code' => 'require|isString',
+ 'email_type' => 'require|in:1,2', // 1 给已经绑定的号发 2 给未绑定的号发
+ 'email' => 'requireIf:email_type,2|email|length:5,40',
+ 'business' => 'require|in:1,2', // 1 非交易业务 2交易业务
+ 'nation' => 'requireIf:phone_type,2|isString',
+ 'phone' => 'requireIf:phone_type,2|isString|length:5,40',
+ 'phone_type' => 'require|in:1,2',// 1 给已经绑定的号发 2 给未绑定的号发
+ 'pay_password' => 'require|isString',
+ 'pay_password_new' => 'require|isString|length:6,150',
+ 'password' => 'require|isString',
+ 'password_new' => 'require|isString|length:6,150',
+ 'nick_name' => 'require|isString|length:2,100',
+ 'first_name' => 'isString|length:2,100',
+ 'last_name' => 'isString|length:2,100',
+ 'gender' => 'isString|in:0,1,2',
+ ];
+
+ protected $message = [
+ 'country_id.require' => 'The country code is required.',
+ 'country_id.isString' => 'The country code format is incorrect.',
+ 'file_id.isString' => 'The file is required.',
+ 'file_id.integer' => 'The file is missing.',
+ 'email_type.require' => 'The email sending type is required.',
+ 'email_type.in' => 'The email sending type format is incorrect.',
+ 'email.requireIf' => 'The email is required.',
+ 'email.email' => 'The email format is incorrect.',
+ 'email.length' => 'The email should be between 5 and 40 characters.',
+ 'business.require' => 'The business type is required.',
+ 'business.in' => 'The business type is incorrect.',
+ 'nation.requireIf' => 'The country code is required.',
+ 'phone.requireIf' => 'The phone number is required.',
+ 'phone.isString' => 'The phone number format is incorrect.',
+ 'phone.length' => 'The phone number should be between 5 and 40 characters.',
+ 'nation.isString' => 'The country code format is incorrect.',
+ 'phone_type.require' => 'The phone message sending type is required.',
+ 'phone_type.in' => 'The phone message sending type is incorrect.',
+ 'email_code.require' => 'The email verification code is required.',
+ 'email_code.isString' => 'The email verification code format is incorrect.',
+ 'pay_password.isString' => 'The collection password format is incorrect.',
+ 'pay_password.require' => 'The collection password is required.',
+ 'pay_password_new.require' => 'The new collection password is required.',
+ 'pay_password_new.isString' => 'The new collection password format is incorrect.',
+ 'pay_password_new.length' => 'The new collection password length format is incorrect.',
+ 'password.isString' => 'The login password format is incorrect.',
+ 'password.require' => 'The login password is required.',
+ 'password_new.isString' => 'The new login password format is incorrect.',
+ 'password_new.require' => 'The new login password is required',
+ 'password_new.length' => 'The new login length format is incorrect.',
+ 'sms_code.require' => 'The SMS verification code is required.',
+ 'sms_code.isString' => 'The SMS verification code format is incorrect.',
+ 'nick_name.require' => 'Nickname is required.',
+ 'nick_name.isString' => 'The name format is incorrect.',
+ 'nick_name.length' => 'The name should be between 2 and 100 characters.',
+ 'first_name.isString' => 'The name format is incorrect.',
+ 'first_name.length' => 'The name should be between 2 and 100 characters.',
+ 'last_name.isString' => 'The name format is incorrect.',
+ 'last_name.length' => 'The name should be between 2 and 100 characters.',
+ 'gender.isString' => 'The gender format is incorrect.',
+ 'gender.in' => 'The gender format is incorrect.',
+ ];
+
+ protected $scene = [
+ 'setCountry' => ['country_id'],
+ 'updateHeadImg' => ['file_id'],
+ 'sendEmail' => ['email_type', 'email', 'business'],
+ 'sendSms' => ['phone_type', 'phone', 'business', 'nation'],
+// 'setPayPasswordByEmail' => ['email_code', 'pay_password'],
+// 'setPayPasswordBySms' => ['sms_code', 'phone', 'pay_password', 'nation'],
+ 'setPayPasswordByEmail' => ['pay_password'],
+ 'setPayPasswordBySms' => ['phone', 'pay_password', 'nation'],
+
+ 'updateInfo' => ['nick_name', 'first_name', 'last_name', 'gender'],
+
+// 'updatePayPasswordBySms' => ['sms_code','pay_password', 'pay_password_new'],
+ 'updatePayPasswordBySms' => ['pay_password', 'pay_password_new'],
+
+// 'updatePayPasswordByEmail' => ['email_code','pay_password','pay_password_new'],
+ 'updatePayPasswordByEmail' => ['pay_password', 'pay_password_new'],
+
+// 'resetPayPasswordBySms' => ['sms_code', 'pay_password_new'],
+// 'resetPayPasswordByEmail' => ['email_code', 'pay_password_new'],
+ 'resetPayPasswordBySms' => ['pay_password_new'],
+ 'resetPayPasswordByEmail' => ['pay_password_new'],
+
+// 'updatePasswordBySms' => ['sms_code', 'password', 'password_new'],
+// 'updatePasswordByEmail' => ['email_code', 'password', 'password_new'],
+// 'resetPasswordBySms' => ['sms_code', 'password_new'],
+// 'resetPasswordByEmail' => ['email_code', 'password_new'],
+ 'updatePasswordBySms' => ['password', 'password_new'],
+ 'updatePasswordByEmail' => ['password', 'password_new'],
+ 'resetPasswordBySms' => ['password_new'],
+ 'resetPasswordByEmail' => ['password_new'],
+
+
+// 'bindEmail' => ['email', 'email_code'], // 绑定邮箱
+ 'bindEmail' => ['email'], // 绑定邮箱
+
+// 'updateEmail' => ['email', 'email_code', 'password'], // 修改绑定邮箱
+ 'updateEmail' => ['email', 'password'], // 修改绑定邮箱
+
+
+// 'bindPhone' => ['phone', 'nation','sms_code'], // 绑定手机号
+ 'bindPhone' => ['phone', 'nation'], // 绑定手机号
+
+// 'updatePhone' => ['phone', 'nation','sms_code','password'], // 修改绑定手机号
+ 'updatePhone' => ['phone', 'nation', 'password'], // 修改绑定手机号
+
+ ];
+}
\ No newline at end of file
diff --git a/app/home/validate/WalletValidate.php b/app/home/validate/WalletValidate.php
new file mode 100644
index 0000000..ff94074
--- /dev/null
+++ b/app/home/validate/WalletValidate.php
@@ -0,0 +1,45 @@
+ 'require|number',
+ 'recharge_type' => 'require|in:1,2',
+ 'recharge_channel' => 'require|isString',
+ 'recharge_num' => 'require|number',
+ 'change_num' => 'require|gt:0',
+ 'page' => 'number',
+ 'page_size' => 'number',
+ ];
+
+ protected $message = [
+ 'user_id.require' => 'Please fill in the user ID.',
+ 'account_type.require' => 'Please fill in the market type.',
+ 'from_account.require' => 'Please select the transfer out account.',
+ 'to_account.require' => 'Please select the transfer in account.',
+ 'account_type.in' => 'Account type is incorrect.',
+ 'from_account.in' => 'Transfer out account type is incorrect.',
+ 'to_account.in' => 'Transfer in account type is incorrect.',
+ 'recharge_type.require' => 'Please fill in the recharge method.',
+ 'recharge_type.in' => 'The recharge method is incorrect.',
+ 'recharge_channel.require' => 'Please fill in the recharge channel.',
+ 'recharge_num.require' => 'Please fill in the recharge amount.',
+ 'change_num.gt' => 'The quantity must be greater than 0.',
+ 'page.number' => 'Please enter the page number.',
+ 'page_size.number' => 'Please enter the page size number.',
+ ];
+
+ protected $scene = [
+ 'recharge' => ['user_id','account_type','recharge_type','recharge_channel','recharge_num'],
+ 'transfer' => ['user_id','from_account','to_account','change_num'],
+
+ 'getRechargeList'=>['user_id','page','page_size'],
+ 'getDrawalList'=>['user_id','account_type','page','page_size'],
+ 'getUserBalance'=>['user_id','account_type'],
+
+
+
+ ];
+}
diff --git a/app/middleware.php b/app/middleware.php
new file mode 100644
index 0000000..d2c3fda
--- /dev/null
+++ b/app/middleware.php
@@ -0,0 +1,10 @@
+column('user_id');
+ if(empty($firstUserIds)){
+ return [];
+ }
+
+ // 查询父级下面的用户
+ $userIds = UserModel::where('origin_user_id','in',$firstUserIds)->column('user_id');
+ return array_merge($firstUserIds, $userIds);
+// return UserModel::where('origin_user_id','in',$firstUserIds)->column('user_id');
+ }
+
+ // 判断操作用户是否是代理商
+ public static function checkUserIsAgent($adminId)
+ {
+ // 代理角色
+ $roleId = 10;
+ $admin = self::where('id', $adminId)->find();
+ if($admin && $admin['role_id'] == $roleId){
+ return true;
+ }
+
+ return false;
+// $agentGroupId = env('AGENT.AGENT_GROUP_ID');
+// $authGroupAccess = AuthGroupAccessModel::where('uid', $adminId)->find();
+// if($authGroupAccess && $authGroupAccess['group_id'] == $agentGroupId){
+// return true;
+// }
+// return false;
+ }
+
+ /**
+ * @desc 根据用户id 查询指定字段
+ * @param $fields
+ * @param $userId
+ * @return array
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public static function getFieldsByUserId($fields, $userId): array
+ {
+ $self = self::where('id', $userId)->field($fields)->find();
+ if(empty($self)){
+ return [];
+ }
+ return $self->toArray();
+ }
+
+ /**
+ * @desc 获取邀请码用户
+ * @param $inviteCode
+ * @return array
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public static function getIdByInviteCode($inviteCode): int
+ {
+ $self = self::where('invite_code', $inviteCode)->value('id');
+
+ if(empty($self)){
+ return 0;
+ }
+ return $self;
+ }}
\ No newline at end of file
diff --git a/app/model/AnnouncementModel.php b/app/model/AnnouncementModel.php
new file mode 100644
index 0000000..7a88a4e
--- /dev/null
+++ b/app/model/AnnouncementModel.php
@@ -0,0 +1,19 @@
+ '上架',
+ self::STATUS_OFF => '下架',
+ ];
+
+ const IS_DELETE_NO = 1;
+ const IS_DELETE_YES = 2;
+}
\ No newline at end of file
diff --git a/app/model/AuthGroupAccessModel.php b/app/model/AuthGroupAccessModel.php
new file mode 100644
index 0000000..644ec13
--- /dev/null
+++ b/app/model/AuthGroupAccessModel.php
@@ -0,0 +1,9 @@
+field($fields)->find();
+ if(empty($self)){
+ return [];
+ }
+ return $self->toArray();
+ }
+}
\ No newline at end of file
diff --git a/app/model/AuthRuleModel.php b/app/model/AuthRuleModel.php
new file mode 100644
index 0000000..ec44dc0
--- /dev/null
+++ b/app/model/AuthRuleModel.php
@@ -0,0 +1,31 @@
+field($fields)->find();
+ if(empty($self)){
+ return [];
+ }
+ return $self->toArray();
+ }
+}
\ No newline at end of file
diff --git a/app/model/BannerModel.php b/app/model/BannerModel.php
new file mode 100644
index 0000000..0d3c0b6
--- /dev/null
+++ b/app/model/BannerModel.php
@@ -0,0 +1,18 @@
+ '上架',
+ self::STATUS_OFF => '下架',
+ ];
+
+ const IS_DELETE_NO = 1;
+ const IS_DELETE_YES = 2;
+}
\ No newline at end of file
diff --git a/app/model/BaseModel.php b/app/model/BaseModel.php
new file mode 100644
index 0000000..0680985
--- /dev/null
+++ b/app/model/BaseModel.php
@@ -0,0 +1,10 @@
+field('brok_type,parent_fee,grandpa_fee,top_fee,pay_type,remark')->select();
+ return $list->toArray();
+ }
+
+
+
+}
\ No newline at end of file
diff --git a/app/model/ConfigModel.php b/app/model/ConfigModel.php
new file mode 100644
index 0000000..076bc4f
--- /dev/null
+++ b/app/model/ConfigModel.php
@@ -0,0 +1,15 @@
+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/ContractMarketModel.php b/app/model/ContractMarketModel.php
new file mode 100644
index 0000000..948c6bf
--- /dev/null
+++ b/app/model/ContractMarketModel.php
@@ -0,0 +1,11 @@
+$user_id,
+ 'status'=>1,
+ 'contract_id'=>$contract_id,
+ 'trade_type'=>$trade_type
+ ])->field('order_number,deal_price,service_cost')->select();
+ $con_list=ContractListMode::getMarketFaceList(1);
+ if(!empty($list)) {
+ $list_arr=$list->toArray();
+ foreach ($list_arr as $val){
+ $order_num=$val['order_number']*$val['deal_price'] ;//+ $val['service_cost'];
+ $money+=$order_num;
+ $num+=$val['order_number'];
+ }
+ }
+ return [
+ 'buy_num'=>$num,
+ 'face_value'=>isset($con_list[$contract_id]) ? $con_list[$contract_id]:0,
+ 'buy_money'=>$money
+ ];
+ }
+ public static function getUserEarnestMmoney(int $user_id)
+ {
+ $num=self::where([
+ 'user_id'=>$user_id,
+ 'status'=>1
+ ])->sum('earnest_money');
+ return $num >0 ? $num:0;
+ }
+ public static function getUserTradeNum(int $user_id)
+ {
+ //查询持仓订单总成本
+ $count=self::where([
+ ['user_id','=',$user_id],
+ ['status','>',0]
+ ])->count();
+ return $count>0;
+ }
+
+ /**
+ * 获取累计盈亏
+ */
+ public static function getTradeOrderDailyNum(int $user_id)
+ {
+ $num=0;
+ //查询持仓订单总成本
+ $list=self::where([
+ 'user_id'=>$user_id,
+ 'status'=>3
+ ])->field('order_number,closing_price,deal_price,closing_cost,service_cost,trade_type,contract_id,face_value')->select();
+
+ //$con_list=ContractListMode::getMarketFaceList(1);
+ if(!empty($list)) {
+ $list_arr=$list->toArray();
+ foreach ($list_arr as $val){
+ if(empty($val['face_value'])){
+ $face_value=1;
+ }else{
+ $face_value=$val['face_value'];
+ }
+ if($val['trade_type']==1){
+ //$order_num=$val['order_number']*($val['closing_price']-$val['deal_price'])-$val['closing_cost']-$val['service_cost'];
+ $order_num=$val['order_number']*($val['closing_price']-$val['deal_price'])*$face_value;
+ }else{
+ //$order_num=$val['order_number']*($val['deal_price']-$val['closing_price'])-$val['closing_cost']-$val['service_cost'];
+ $order_num=$val['order_number']*($val['deal_price']-$val['closing_price'])*$face_value;
+ }
+ $num+=$order_num;
+ }
+ }
+ return $num;
+ }
+ public static function getTradeOrderFee(int $user_id)
+ {
+ $info=self::where([
+ ['user_id','=',$user_id],
+ ['status','in',[1,3]]
+ ])->field('sum(service_cost+closing_cost) as fee')->find();
+ if(empty($info)){
+ return 0;
+ }else{
+ $info=$info->toArray();
+ return empty($info['fee']) ? 0 : $info['fee'];
+ }
+ }
+ public static function getTradeList($trade_name,$num)
+ {
+ $trade_list=[];
+ $list=self::where([
+ ['status','in','1,3'],
+ ['contract_id','=',strtoupper($trade_name)]
+ ])->field('deal_price,order_number,closing_price,open_time,closing_time,status')->order('trade_id desc')->limit($num)->select();
+ if(!empty($list)) {
+ $list_arr=$list->toArray();
+ foreach ($list_arr as $val){
+ if($val['status']==1){
+ $trade_data['order_number']=$val['order_number'];
+ $trade_data['deal_price']=$val['deal_price'];
+ $trade_data['order_time']=strtotime($val['open_time'])*1000;
+ $trade_data['trade_type']=1;
+ array_push($trade_list,$trade_data);
+ }
+ if($val['status']==3){
+ $trade_data['order_number']=$val['order_number'];
+ $trade_data['deal_price']=$val['deal_price'];
+ $trade_data['order_time']=strtotime($val['open_time'])*1000;
+ $trade_data['trade_type']=1;
+ array_push($trade_list,$trade_data);
+
+ $sale_data['order_number']=$val['order_number'];
+ $sale_data['deal_price']=$val['closing_price'];
+ $sale_data['order_time']=strtotime($val['closing_time'])*1000;
+ $sale_data['trade_type']=2;
+ array_push($trade_list,$sale_data);
+
+ }
+ }
+ }
+ return $trade_list;
+ }
+
+
+
+}
\ No newline at end of file
diff --git a/app/model/ContractSettingModel.php b/app/model/ContractSettingModel.php
new file mode 100644
index 0000000..f62cb9b
--- /dev/null
+++ b/app/model/ContractSettingModel.php
@@ -0,0 +1,13 @@
+', 0)->field('time_step,earnings_num')->order('time_step', 'asc')->select()->toArray();
+ }
+}
\ No newline at end of file
diff --git a/app/model/ContractTradeModel.php b/app/model/ContractTradeModel.php
new file mode 100644
index 0000000..91d75be
--- /dev/null
+++ b/app/model/ContractTradeModel.php
@@ -0,0 +1,168 @@
+$user_id,
+ 'status'=>1,
+ 'contract_id'=>$contract_id,
+ 'trade_type'=>$trade_type
+ ])->field('order_number,deal_price,service_cost')->select();
+ $con_list=ContractListMode::getMarketFaceList(1);
+ if(!empty($list)) {
+ $list_arr=$list->toArray();
+ foreach ($list_arr as $val){
+ $order_num=$val['order_number']*$val['deal_price'] ;//+ $val['service_cost'];
+ $money+=$order_num;
+ $num+=$val['order_number'];
+ }
+ }
+ return [
+ 'buy_num'=>$num,
+ 'face_value'=>isset($con_list[$contract_id]) ? $con_list[$contract_id]:0,
+ 'buy_money'=>$money
+ ];
+ }
+ public static function getUserEarnestMmoney(int $user_id)
+ {
+ $num=self::where([
+ 'user_id'=>$user_id,
+ 'status'=>1
+ ])->sum('earnest_money');
+ return $num >0 ? $num:0;
+ }
+ public static function getUserTradeNum(int $user_id)
+ {
+ //查询持仓订单总成本
+ $count=self::where([
+ ['user_id','=',$user_id],
+ ['status','>',0]
+ ])->count();
+ return $count>0;
+ }
+
+ /**
+ * 获取累计盈亏
+ */
+ public static function getTradeOrderDailyNum(int $user_id)
+ {
+ $num=0;
+ //查询持仓订单总成本
+ $list=self::where([
+ 'user_id'=>$user_id,
+ 'status'=>3
+ ])->field('order_number,closing_price,deal_price,closing_cost,service_cost,trade_type,contract_id,face_value')->select();
+
+ //$con_list=ContractListMode::getMarketFaceList(1);
+ if(!empty($list)) {
+ $list_arr=$list->toArray();
+ foreach ($list_arr as $val){
+ if(empty($val['face_value'])){
+ $face_value=1;
+ }else{
+ $face_value=$val['face_value'];
+ }
+ if($val['trade_type']==1){
+ //$order_num=$val['order_number']*($val['closing_price']-$val['deal_price'])-$val['closing_cost']-$val['service_cost'];
+ $order_num=$val['order_number']*($val['closing_price']-$val['deal_price'])*$face_value;
+ }else{
+ //$order_num=$val['order_number']*($val['deal_price']-$val['closing_price'])-$val['closing_cost']-$val['service_cost'];
+ $order_num=$val['order_number']*($val['deal_price']-$val['closing_price'])*$face_value;
+ }
+ $num+=$order_num;
+ }
+ }
+ return $num;
+ }
+ public static function getTradeOrderFee(int $user_id)
+ {
+ $info=self::where([
+ ['user_id','=',$user_id],
+ ['status','in',[1,3]]
+ ])->field('sum(service_cost+closing_cost) as fee')->find();
+ if(empty($info)){
+ return 0;
+ }else{
+ $info=$info->toArray();
+ return empty($info['fee']) ? 0 : $info['fee'];
+ }
+ }
+ public static function getTradeList($trade_name,$num)
+ {
+ $trade_list=[];
+ $list=self::where([
+ ['status','in','1,3'],
+ ['contract_id','=',strtoupper($trade_name)]
+ ])->field('deal_price,order_number,closing_price,open_time,closing_time,status')->order('trade_id desc')->limit($num)->select();
+ if(!empty($list)) {
+ $list_arr=$list->toArray();
+ foreach ($list_arr as $val){
+ if($val['status']==1){
+ $trade_data['order_number']=$val['order_number'];
+ $trade_data['deal_price']=$val['deal_price'];
+ $trade_data['order_time']=strtotime($val['open_time'])*1000;
+ $trade_data['trade_type']=1;
+ array_push($trade_list,$trade_data);
+ }
+ if($val['status']==3){
+ $trade_data['order_number']=$val['order_number'];
+ $trade_data['deal_price']=$val['deal_price'];
+ $trade_data['order_time']=strtotime($val['open_time'])*1000;
+ $trade_data['trade_type']=1;
+ array_push($trade_list,$trade_data);
+
+ $sale_data['order_number']=$val['order_number'];
+ $sale_data['deal_price']=$val['closing_price'];
+ $sale_data['order_time']=strtotime($val['closing_time'])*1000;
+ $sale_data['trade_type']=2;
+ array_push($trade_list,$sale_data);
+
+ }
+ }
+ }
+ return $trade_list;
+ }
+
+
+
+}
\ No newline at end of file
diff --git a/app/model/CountryModel.php b/app/model/CountryModel.php
new file mode 100644
index 0000000..88488a3
--- /dev/null
+++ b/app/model/CountryModel.php
@@ -0,0 +1,64 @@
+find();
+ if(empty($self)){
+ return [];
+ }
+ return $self->toArray();
+ }
+
+ public static function getAll()
+ {
+ return self::where('id', '>', 0)->order('sort', 'desc')->select();
+ }
+
+ /**
+ * @desc 判断国家码是否存在
+ * @param $code
+ * @return bool
+ * @throws \think\db\exception\DbException
+ */
+ public static function checkCodeExists($code): bool
+ {
+ $count = self::where('code', $code)->count();
+ return $count > 0;
+ }
+ public static function getNameById($id, $lang = 'en')
+ {
+ $self = self::where('id', $id)->find();
+ if(empty($self)){
+ return '';
+ }
+ if($lang == 'cn'){
+ return $self->name_cn;
+ }
+
+ return $self->name_en;
+ }
+}
\ No newline at end of file
diff --git a/app/model/DigitalListModel.php b/app/model/DigitalListModel.php
new file mode 100644
index 0000000..cba846e
--- /dev/null
+++ b/app/model/DigitalListModel.php
@@ -0,0 +1,67 @@
+count();
+ $list = self::where($where)->field('trade_name as name,exchange_name as code,logo_link,sort')->page($data['page'],$data['page_size'])->select();
+ if(empty($list)){
+ return [];
+ }
+ $list=$list->toArray();
+
+ foreach ($list as $key=>$val){
+ $list[$key]['code']=$val['name'].'-'.$val['code'];
+ }
+
+ return [
+ 'total'=>$count,
+ 'list'=>$list,
+ ];
+ }
+ public static function existMarket($trade_name):bool
+ {
+ $id=self::where('trade_name',$trade_name)->value('id');
+ return $id >0;
+ }
+
+
+}
\ No newline at end of file
diff --git a/app/model/DigitalTradeModel.php b/app/model/DigitalTradeModel.php
new file mode 100644
index 0000000..b7046d2
--- /dev/null
+++ b/app/model/DigitalTradeModel.php
@@ -0,0 +1,162 @@
+$user_id,
+ 'status'=>1
+ ])->field('order_number,deal_price,service_cost')->select();
+ if(!empty($list)) {
+ $list_arr=$list->toArray();
+ foreach ($list_arr as $val){
+ $order_num=$val['order_number']*$val['deal_price'] + $val['service_cost'];
+ $num+=$order_num;
+ }
+ }
+ return $num;
+ }
+
+ /**
+ * 买入成本
+ */
+ public static function getTradeOrderPrice(int $user_id,string $digital_id,int $trade_type)
+ {
+ $num=0;
+ $buy_num=0;
+ //查询持仓订单总成本
+ $list=self::where([
+ 'user_id'=>$user_id,
+ 'status'=>3,
+ 'digital_id'=>$digital_id,
+ 'trade_type'=>$trade_type
+ ])->field('order_number,closing_price,service_cost,closing_cost')->select();
+ if(!empty($list)) {
+ $list_arr=$list->toArray();
+ foreach ($list_arr as $val){
+ $order_num=$val['order_number']*$val['closing_price'] + $val['service_cost'];
+ $num+=$order_num;
+ $buy_num+=$val['order_number'];
+ }
+ }
+ return [
+ 'order_money'=>$num, //订单总额
+ 'order_num'=>$buy_num //订单数量
+ ];
+ }
+ public static function getTradeOrderFee(int $user_id)
+ {
+ $info=self::where([
+ ['user_id','=',$user_id],
+ ['status','in',[1,3]]
+ ])->sum('closing_cost');
+ return $info;
+ }
+ public static function getUserTradeNum(int $user_id)
+ {
+ //查询持仓订单总成本
+ $count=self::where([
+ ['user_id','=',$user_id],
+ ['status','>',0]
+ ])->count();
+ return $count>0;
+ }
+
+ /**
+ * 获取累计盈亏
+ */
+ public static function getTradeOrderDailyNum(int $user_id)
+ {
+ $num=0;
+ //查询持仓订单总成本
+ $list=self::where([
+ 'user_id'=>$user_id,
+ 'status'=>3
+ ])->field('order_number,closing_price,deal_price,closing_cost,service_cost')->select();
+ if(!empty($list)) {
+ $list_arr=$list->toArray();
+ foreach ($list_arr as $val){
+ $order_num=$val['order_number']*($val['closing_price']-$val['deal_price'])-$val['closing_cost']-$val['service_cost'];
+ $num+=$order_num;
+ }
+ }
+ return $num;
+ }
+ public static function getTradeList($trade_name,$num)
+ {
+ $trade_list=[];
+ $list=self::where([
+ ['status','in','1,3'],
+ ['digital_id','=',strtoupper($trade_name)]
+ ])->field('deal_price,order_number,closing_price,open_time,closing_time,status')->order('trade_id desc')->limit($num)->select();
+ if(!empty($list)) {
+ $list_arr=$list->toArray();
+ foreach ($list_arr as $val){
+ if($val['status']==1){
+ $trade_data['order_number']=$val['order_number'];
+ $trade_data['deal_price']=$val['closing_price'];
+ $trade_data['order_time']=strtotime($val['open_time'])*1000;
+ $trade_data['trade_type']=1;
+ array_push($trade_list,$trade_data);
+ }
+ if($val['status']==3){
+ $trade_data['order_number']=$val['order_number'];
+ $trade_data['deal_price']=$val['closing_price'];
+ $trade_data['order_time']=strtotime($val['closing_time'])*1000;
+ $trade_data['trade_type']=1;
+ array_push($trade_list,$trade_data);
+
+ $sale_data['order_number']=$val['order_number'];
+ $sale_data['deal_price']=$val['closing_price'];
+ $sale_data['order_time']=strtotime($val['closing_time'])*1000;
+ $sale_data['trade_type']=2;
+ array_push($trade_list,$sale_data);
+
+ }
+ }
+ }
+ return $trade_list;
+ }
+
+
+
+}
\ No newline at end of file
diff --git a/app/model/DocumentModel.php b/app/model/DocumentModel.php
new file mode 100644
index 0000000..50141e5
--- /dev/null
+++ b/app/model/DocumentModel.php
@@ -0,0 +1,39 @@
+ '平台介绍',
+ '2' => '功能介绍',
+ '3' => '资金风控',
+ '4' => '关于我们',
+ '5' => 'H5首页文章',
+ '6' => '投资理念',
+ '7' => '管理团队'
+ ];
+
+ // pc 页脚展示的文章
+ const TYPE_FOOTER_PC = [
+ '1' => '平台介绍',
+ '2' => '功能介绍',
+ '3' => '资金风控',
+ '4' => '关于我们',
+// '5' => 'H5首页文章',
+ '6' => '投资理念',
+ '7' => '管理团队'
+ ];
+
+ const STATUS_ON = '1';
+ const STATUS_OFF = '2';
+ const STATUS_MAP = [
+ self::STATUS_ON => '上架',
+ self::STATUS_OFF => '下架',
+ ];
+
+
+ const IS_DELETE_NO = 1;
+ const IS_DELETE_YES = 2;
+}
\ No newline at end of file
diff --git a/app/model/DrawalSettingModel.php b/app/model/DrawalSettingModel.php
new file mode 100644
index 0000000..010fd5f
--- /dev/null
+++ b/app/model/DrawalSettingModel.php
@@ -0,0 +1,26 @@
+field('bank_drawal_fee,digital_drawal_fee,min_recharge,min_drawal')->find();
+ if(empty($info)){
+ return [];
+ }
+ return $info->toArray();
+ }
+
+
+
+}
\ No newline at end of file
diff --git a/app/model/FaqModel.php b/app/model/FaqModel.php
new file mode 100644
index 0000000..5ba1dfc
--- /dev/null
+++ b/app/model/FaqModel.php
@@ -0,0 +1,18 @@
+ '上架',
+ self::STATUS_OFF => '下架',
+ ];
+
+ const IS_DELETE_NO = 1;
+ const IS_DELETE_YES = 2;
+}
\ No newline at end of file
diff --git a/app/model/FeeSettingModel.php b/app/model/FeeSettingModel.php
new file mode 100644
index 0000000..a61add7
--- /dev/null
+++ b/app/model/FeeSettingModel.php
@@ -0,0 +1,61 @@
+ '现货',
+ '2' => '合约',
+ '3' => '美股',
+ '4' => '印尼股票', // 5 马股 6 泰股
+ '5' => '马股',
+ '6' => '泰股',
+ '7' => '印度股票',
+ '8' => '秒合约',
+ '9' => '新加坡股票',
+ '10' => '基金',
+ '11' => '印度期权',
+ '12' => '港股',
+ '14' => '英股'
+ ];
+
+ public static $payTypeList = [
+ '0' => '固定费用',
+ '1' => '按比例结算',
+ '2' => '按张结算',
+ ];
+
+ public static function getTradeFeeById($market_type):array
+ {
+ if($market_type>0){
+ $info = self::where('market_type', $market_type)->field('market_type,buy_fee,sale_fee,pay_type,min_buy_num,min_sale_num,purchase_fee')->find();
+ if(empty($info)){
+ return [];
+ }
+ return $info->toArray();
+ }else{
+ $info = self::where(1)->field('market_type,buy_fee,sale_fee,pay_type,min_buy_num,min_sale_num,purchase_fee')->select();
+ if(empty($info)){
+ return [];
+ }
+ return $info->toArray();
+ }
+ }
+
+
+
+}
\ No newline at end of file
diff --git a/app/model/FileModel.php b/app/model/FileModel.php
new file mode 100644
index 0000000..ef645c6
--- /dev/null
+++ b/app/model/FileModel.php
@@ -0,0 +1,67 @@
+find();
+ if(empty($self)){
+ return [];
+ }
+ return $self->toArray();
+ }
+
+ /**
+ * @desc 获取文件路径
+ * @param $id
+ * @return mixed|string
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public static function getFilePath($id)
+ {
+ $self = self::where('id', $id)->find();
+ if(!empty($self)){
+ return $self->path;
+ }
+
+ return '';
+ }
+ /**
+ * @desc 将文件入库
+ * @param $path
+ * @param int $type
+ * @return int
+ */
+ public static function insertFile($path, int $type = 1)
+ {
+ $self = new self;
+ $self->type = $type;
+ $self->path = $path;
+ $self->create_time = date('Y-m-d H:i:s');
+ $self->save();
+ return $self->id;
+ }
+}
\ No newline at end of file
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/ForexListModel.php b/app/model/ForexListModel.php
new file mode 100644
index 0000000..efaf677
--- /dev/null
+++ b/app/model/ForexListModel.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/ForexTradeModel.php b/app/model/ForexTradeModel.php
new file mode 100644
index 0000000..51a9a0d
--- /dev/null
+++ b/app/model/ForexTradeModel.php
@@ -0,0 +1,168 @@
+$user_id,
+ 'status'=>1,
+ 'contract_id'=>$contract_id,
+ 'trade_type'=>$trade_type
+ ])->field('order_number,deal_price,service_cost')->select();
+ $con_list=ContractListMode::getMarketFaceList(1);
+ if(!empty($list)) {
+ $list_arr=$list->toArray();
+ foreach ($list_arr as $val){
+ $order_num=$val['order_number']*$val['deal_price'] ;//+ $val['service_cost'];
+ $money+=$order_num;
+ $num+=$val['order_number'];
+ }
+ }
+ return [
+ 'buy_num'=>$num,
+ 'face_value'=>isset($con_list[$contract_id]) ? $con_list[$contract_id]:0,
+ 'buy_money'=>$money
+ ];
+ }
+ public static function getUserEarnestMmoney(int $user_id)
+ {
+ $num=self::where([
+ 'user_id'=>$user_id,
+ 'status'=>1
+ ])->sum('earnest_money');
+ return $num >0 ? $num:0;
+ }
+ public static function getUserTradeNum(int $user_id)
+ {
+ //查询持仓订单总成本
+ $count=self::where([
+ ['user_id','=',$user_id],
+ ['status','>',0]
+ ])->count();
+ return $count>0;
+ }
+
+ /**
+ * 获取累计盈亏
+ */
+ public static function getTradeOrderDailyNum(int $user_id)
+ {
+ $num=0;
+ //查询持仓订单总成本
+ $list=self::where([
+ 'user_id'=>$user_id,
+ 'status'=>3
+ ])->field('order_number,closing_price,deal_price,closing_cost,service_cost,trade_type,contract_id,face_value')->select();
+
+ //$con_list=ContractListMode::getMarketFaceList(1);
+ if(!empty($list)) {
+ $list_arr=$list->toArray();
+ foreach ($list_arr as $val){
+ if(empty($val['face_value'])){
+ $face_value=1;
+ }else{
+ $face_value=$val['face_value'];
+ }
+ if($val['trade_type']==1){
+ //$order_num=$val['order_number']*($val['closing_price']-$val['deal_price'])-$val['closing_cost']-$val['service_cost'];
+ $order_num=$val['order_number']*($val['closing_price']-$val['deal_price'])*$face_value;
+ }else{
+ //$order_num=$val['order_number']*($val['deal_price']-$val['closing_price'])-$val['closing_cost']-$val['service_cost'];
+ $order_num=$val['order_number']*($val['deal_price']-$val['closing_price'])*$face_value;
+ }
+ $num+=$order_num;
+ }
+ }
+ return $num;
+ }
+ public static function getTradeOrderFee(int $user_id)
+ {
+ $info=self::where([
+ ['user_id','=',$user_id],
+ ['status','in',[1,3]]
+ ])->field('sum(service_cost+closing_cost) as fee')->find();
+ if(empty($info)){
+ return 0;
+ }else{
+ $info=$info->toArray();
+ return empty($info['fee']) ? 0 : $info['fee'];
+ }
+ }
+ public static function getTradeList($trade_name,$num)
+ {
+ $trade_list=[];
+ $list=self::where([
+ ['status','in','1,3'],
+ ['contract_id','=',strtoupper($trade_name)]
+ ])->field('deal_price,order_number,closing_price,open_time,closing_time,status')->order('trade_id desc')->limit($num)->select();
+ if(!empty($list)) {
+ $list_arr=$list->toArray();
+ foreach ($list_arr as $val){
+ if($val['status']==1){
+ $trade_data['order_number']=$val['order_number'];
+ $trade_data['deal_price']=$val['deal_price'];
+ $trade_data['order_time']=strtotime($val['open_time'])*1000;
+ $trade_data['trade_type']=1;
+ array_push($trade_list,$trade_data);
+ }
+ if($val['status']==3){
+ $trade_data['order_number']=$val['order_number'];
+ $trade_data['deal_price']=$val['deal_price'];
+ $trade_data['order_time']=strtotime($val['open_time'])*1000;
+ $trade_data['trade_type']=1;
+ array_push($trade_list,$trade_data);
+
+ $sale_data['order_number']=$val['order_number'];
+ $sale_data['deal_price']=$val['closing_price'];
+ $sale_data['order_time']=strtotime($val['closing_time'])*1000;
+ $sale_data['trade_type']=2;
+ array_push($trade_list,$sale_data);
+
+ }
+ }
+ }
+ return $trade_list;
+ }
+
+
+
+}
\ No newline at end of file
diff --git a/app/model/HistoryFundStockModel.php b/app/model/HistoryFundStockModel.php
new file mode 100644
index 0000000..2fb2b21
--- /dev/null
+++ b/app/model/HistoryFundStockModel.php
@@ -0,0 +1,17 @@
+field('language_name,language_code')->select();
+ if(empty($list)){
+ return [];
+ }
+ return $list->toArray();
+ }
+
+
+
+}
\ No newline at end of file
diff --git a/app/model/PaymentListModel.php b/app/model/PaymentListModel.php
new file mode 100644
index 0000000..b8b9f2d
--- /dev/null
+++ b/app/model/PaymentListModel.php
@@ -0,0 +1,56 @@
+select();
+ if ($list) {
+ return $list->toArray();
+ } else {
+ return [];
+ }
+ }
+
+ public static function getPaymentInfo($where): array
+ {
+ $list = self::where($where)->find();
+ if ($list) {
+ return $list->toArray();
+ } else {
+ return [];
+ }
+ }
+
+ const BANK = 1;
+ const IND_PAY = 2;
+ const MO_PAY = 3;
+ const HT_PAY = 4;
+ const XD_PAY = 5;
+ const QEAE_PAY = 6;
+ const NICE_PAY = 7;
+ const CLICK_PAY = 8;
+ const STAR_PAY = 9;
+ const TPYE_LIST = [
+ self::IND_PAY => 'IND PAY',
+ self::MO_PAY => 'MO PAY',
+ self::HT_PAY => 'HT PAY',
+ self::XD_PAY => 'XD PAY',
+ self::QEAE_PAY => 'QEAE PAY',
+ self::NICE_PAY => 'NICE PAY',
+ self::CLICK_PAY => 'CLICK PAY',
+ self::STAR_PAY => 'STAR PAY',
+ ];
+
+}
\ No newline at end of file
diff --git a/app/model/PreBrlStockModel.php b/app/model/PreBrlStockModel.php
new file mode 100644
index 0000000..f6051dc
--- /dev/null
+++ b/app/model/PreBrlStockModel.php
@@ -0,0 +1,67 @@
+ 'Common Stock',
+ self::STOCK_TYPE_PREFERRED => 'Preferred Stock',
+ ];
+}
\ No newline at end of file
diff --git a/app/model/PreEurStockModel.php b/app/model/PreEurStockModel.php
new file mode 100644
index 0000000..624866d
--- /dev/null
+++ b/app/model/PreEurStockModel.php
@@ -0,0 +1,67 @@
+ 'Common Stock',
+ self::STOCK_TYPE_PREFERRED => 'Preferred Stock',
+ ];
+}
\ No newline at end of file
diff --git a/app/model/PreFundStockModel.php b/app/model/PreFundStockModel.php
new file mode 100644
index 0000000..ba71e95
--- /dev/null
+++ b/app/model/PreFundStockModel.php
@@ -0,0 +1,118 @@
+ '固定收益',
+ ];
+
+ public static $stockTypeEnList = [
+ self::STOCK_TYPE_ONE => 'FIXED INCOME', //固定收益
+ ];
+
+ public static $openStatusList = [
+ self::OPEN_STATUS_NO => '未上市',
+ self::OPEN_STATUS_HAD => '已上市',
+ self::OPEN_STATUS_OUT => '退市',
+ ];
+
+ public static $openStatusEnList = [
+ self::OPEN_STATUS_NO => 'Unlisted',
+ self::OPEN_STATUS_HAD => 'BE LISTED',
+ self::OPEN_STATUS_OUT => 'BE DELISTED',
+ ];
+
+ public static $cycleTypeList = [
+ self::DAY => '天',
+// self::MONTH => '月',
+// self::YEAR => '年',
+ ];
+
+ public static $interestTypeList = [
+ self::ONE_TIME_PRINCIPAL_INTEREST => '一次性本息',
+ ];
+
+ public function getStockTypeTextAttr($value, $data)
+ {
+ $status = PreFundStockModel::$stockTypeList[$data['stock_type']];
+ return $status;
+ }
+
+ public function getStockTypeEnTextAttr($value, $data)
+ {
+ $status = PreFundStockModel::$stockTypeEnList[$data['stock_type']];
+ return $status;
+ }
+
+ public function getOpenStatusTextAttr($value, $data)
+ {
+ $status = PreFundStockModel::$openStatusList[$data['open_status']];
+ return $status;
+ }
+
+ public function getOpenStatusEnTextAttr($value, $data)
+ {
+ $status = PreFundStockModel::$openStatusEnList[$data['open_status']];
+ return $status;
+ }
+
+ public function history()
+ {
+ return $this->belongsTo(HistoryFundStockModel::class, 'stock_code', 'stock_code');
+ }
+}
\ No newline at end of file
diff --git a/app/model/PreFundStockReferModel.php b/app/model/PreFundStockReferModel.php
new file mode 100644
index 0000000..aa15dee
--- /dev/null
+++ b/app/model/PreFundStockReferModel.php
@@ -0,0 +1,11 @@
+ 'Common Stock',
+ self::STOCK_TYPE_PREFERRED => 'Preferred Stock',
+ ];
+}
\ No newline at end of file
diff --git a/app/model/PreGBXStockModel.php b/app/model/PreGBXStockModel.php
new file mode 100644
index 0000000..74baebc
--- /dev/null
+++ b/app/model/PreGBXStockModel.php
@@ -0,0 +1,67 @@
+ 'Common Stock',
+ self::STOCK_TYPE_PREFERRED => 'Preferred Stock',
+ ];
+}
\ No newline at end of file
diff --git a/app/model/PreHkdStockModel.php b/app/model/PreHkdStockModel.php
new file mode 100644
index 0000000..5224e9e
--- /dev/null
+++ b/app/model/PreHkdStockModel.php
@@ -0,0 +1,67 @@
+ 'Common Stock',
+ self::STOCK_TYPE_PREFERRED => 'Preferred Stock',
+ ];
+}
\ No newline at end of file
diff --git a/app/model/PreIdnStockModel.php b/app/model/PreIdnStockModel.php
new file mode 100644
index 0000000..daa1616
--- /dev/null
+++ b/app/model/PreIdnStockModel.php
@@ -0,0 +1,67 @@
+ 'Common Stock',
+ self::STOCK_TYPE_PREFERRED => 'Preferred Stock',
+ ];
+}
\ No newline at end of file
diff --git a/app/model/PreInStockModel.php b/app/model/PreInStockModel.php
new file mode 100644
index 0000000..d710d05
--- /dev/null
+++ b/app/model/PreInStockModel.php
@@ -0,0 +1,67 @@
+ 'Common Stock',
+ self::STOCK_TYPE_PREFERRED => 'Preferred Stock',
+ ];
+}
\ No newline at end of file
diff --git a/app/model/PreJpStockModel.php b/app/model/PreJpStockModel.php
new file mode 100644
index 0000000..24c932b
--- /dev/null
+++ b/app/model/PreJpStockModel.php
@@ -0,0 +1,67 @@
+ 'Common Stock',
+ self::STOCK_TYPE_PREFERRED => 'Preferred Stock',
+ ];
+}
\ No newline at end of file
diff --git a/app/model/PreMysStockModel.php b/app/model/PreMysStockModel.php
new file mode 100644
index 0000000..26d7433
--- /dev/null
+++ b/app/model/PreMysStockModel.php
@@ -0,0 +1,67 @@
+ 'Common Stock',
+ self::STOCK_TYPE_PREFERRED => 'Preferred Stock',
+ ];
+}
\ No newline at end of file
diff --git a/app/model/PreSgdStockModel.php b/app/model/PreSgdStockModel.php
new file mode 100644
index 0000000..a67c7bf
--- /dev/null
+++ b/app/model/PreSgdStockModel.php
@@ -0,0 +1,67 @@
+ 'Common Stock',
+ self::STOCK_TYPE_PREFERRED => 'Preferred Stock',
+ ];
+}
\ No newline at end of file
diff --git a/app/model/PreThaStockModel.php b/app/model/PreThaStockModel.php
new file mode 100644
index 0000000..19668ff
--- /dev/null
+++ b/app/model/PreThaStockModel.php
@@ -0,0 +1,67 @@
+ 'Common Stock',
+ self::STOCK_TYPE_PREFERRED => 'Preferred Stock',
+ ];
+}
\ No newline at end of file
diff --git a/app/model/PreUsStockModel.php b/app/model/PreUsStockModel.php
new file mode 100644
index 0000000..6a907b7
--- /dev/null
+++ b/app/model/PreUsStockModel.php
@@ -0,0 +1,67 @@
+ 'Common Stock',
+ self::STOCK_TYPE_PREFERRED => 'Preferred Stock',
+ ];
+}
\ No newline at end of file
diff --git a/app/model/RechargeApplyModel.php b/app/model/RechargeApplyModel.php
new file mode 100644
index 0000000..fe17790
--- /dev/null
+++ b/app/model/RechargeApplyModel.php
@@ -0,0 +1,121 @@
+ '处理中(待审核)',
+ self::STATUS_ONE => '充值成功',
+ self::STATUS_TWO => '充值失败',
+ ];
+
+ public static function getUserRecharge(array $data)
+ {
+ $where['user_id']=$data['user_id'];
+ if($data['account_type']>0){
+ $where['account_type']=$data['account_type'];
+ }
+ if($data['page']<1){
+ $data['page']=1;
+ }
+ if($data['page_size']<1){
+ $data['page_size']=10;
+ }
+ $count= self::where($where)->count();
+ $list = self::where($where)->field('account_type,market_amount as recharge_num,status,order_no,recharge_type,recharge_channel,service_fee,create_time')
+ ->order('id desc')->page($data['page'],$data['page_size'])->select();
+ if(empty($list)){
+ return [];
+ }else{
+ return [
+ 'total'=>$count,
+ 'list'=>$list->toArray()
+ ];
+ }
+ }
+ public static function getUserIsRecharge(array $data)
+ {
+ $count= self::where([
+ 'user_id'=>$data['user_id'],
+ 'status'=>1
+ ])->count();
+ return $count > 0;
+ }
+ public static function getUserPayNum(array $data)
+ {
+ $count= self::where([
+ ['user_id','in',$data],
+ ['status','=',1]
+ ])->count('DISTINCT user_id');
+ return $count;
+ }
+ public static function InsertUserRecharge(array $data)
+ {
+ $self = new self;
+ $self->user_id = $data['user_id'];
+ $self->account_type = $data['account_type'];
+ $self->recharge_type = $data['recharge_type'];
+ $self->recharge_channel = $data['recharge_channel'];
+ $self->recharge_num = $data['recharge_num'];
+ $self->status = 0;
+ $self->is_check = 0;
+ $self->country = $data['country'];
+ $self->order_no = $data['order_no'];
+ $self->currency_rate = $data['currency_rate'];
+ $self->market_amount = $data['market_amount'];
+ $self->service_fee = $data['service_fee'];
+ $self->total_amount = $data['total_amount'];
+ $self->is_online=$data['is_online'];
+ $self->file_id=$data['file_id'];
+
+ $self->create_time = date('Y-m-d H:i:s');
+ $self->update_time = date('Y-m-d H:i:s');
+ return $self->save();
+ }
+ public static function getOrderByNo(array $where)
+ {
+ $order_info=self::where($where)->find();
+ if($order_info){
+ return $order_info->toArray();
+ }else{
+ return [];
+ }
+ }
+ public static function AddUserRecharge(array $data)
+ {
+ $self = new self;
+ return $self->save($data);
+ }
+ public static function getOrderInfo($where)
+ {
+ $order_info=self::where($where)->find();
+ if($order_info){
+ return $order_info->toArray();
+ }else{
+ return [];
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/app/model/ServiceSettingModel.php b/app/model/ServiceSettingModel.php
new file mode 100644
index 0000000..3f3c8ac
--- /dev/null
+++ b/app/model/ServiceSettingModel.php
@@ -0,0 +1,33 @@
+ '邮箱',
+ self::TYPE_TWO => '跳转地址',
+ ];
+
+ public static function getServiceList():array
+ {
+ $list = self::where(1)->field('server_name,header_photo,server_link,type')->select();
+ if(empty($list)){
+ return [];
+ }
+ return $list->toArray();
+ }
+
+
+
+}
\ No newline at end of file
diff --git a/app/model/StockBlockListModel.php b/app/model/StockBlockListModel.php
new file mode 100644
index 0000000..7cc1ce4
--- /dev/null
+++ b/app/model/StockBlockListModel.php
@@ -0,0 +1,68 @@
+ [self::TAPE_NYSE => 'NYSE',
+ self::TAPE_NYSE_ARCA => 'NYSE ARCA',
+ self::TAPE_NASDAQ => 'NASDAQ',],
+ 4 => [1 => 'IDX'],
+ 5 => [1 => 'MYX'],
+ 6 => [1 => 'SET'],
+ 7 => [
+ self::TAPE_BSE => 'BSE',
+ self::TAPE_NSE => 'NSE',
+ ],
+ 9 => [1 => 'SGD'],
+ 12 => []
+ ];
+
+
+ public static $typeList = [
+ 3 => '美股',
+ 4 => '印尼股',
+ 5 => '马股',
+ 6 => '泰股',
+ 7 => '印度股',
+ 9 => '新加坡股',
+ 12 => '港股',
+ 14 => '英股',
+ 15 => '法股',
+ 16 => '德股',
+
+ ];
+ public static $typeListEn = [
+ 3 => 'US',
+ 4 => 'IDN',
+ 5 => 'MYS',
+ 6 => 'THA',
+ 7 => 'IN',
+ 9 => 'SGD',
+ 12 => 'HKD',
+ 14 => 'UK',
+ 15 => 'FUR',
+ 16 => 'EUR',
+ ];
+
+}
\ No newline at end of file
diff --git a/app/model/StockBrlListModel.php b/app/model/StockBrlListModel.php
new file mode 100644
index 0000000..72ae643
--- /dev/null
+++ b/app/model/StockBrlListModel.php
@@ -0,0 +1,41 @@
+ 'BMFBOVESPA',
+ // self::TAPE_NSE => 'NSE',
+ ];
+
+ const SOURCE_TV='1';
+ const SOURCE_ECONOMICTIMES='2';
+ const SOURCE_LIST = [
+ self::SOURCE_TV => 'TV',
+ self::SOURCE_ECONOMICTIMES => '交易所',
+ ];
+}
\ No newline at end of file
diff --git a/app/model/StockBrlTradeModel.php b/app/model/StockBrlTradeModel.php
new file mode 100644
index 0000000..777ea88
--- /dev/null
+++ b/app/model/StockBrlTradeModel.php
@@ -0,0 +1,168 @@
+$user_id,
+ 'status'=>1,
+ 'stock_id'=>$stock_id,
+ 'trade_type'=>$trade_type
+ ])->field('order_number,deal_price,service_cost')->select();
+ if(!empty($list)) {
+ $list_arr=$list->toArray();
+ foreach ($list_arr as $val){
+ $order_num=$val['order_number']*$val['deal_price'] ;//+ $val['service_cost'];
+ $money+=$order_num;
+ $num+=$val['order_number'];
+ }
+ }
+ return [
+ 'buy_num'=>$num,
+ 'buy_money'=>$money
+ ];
+ }
+ public static function getUserEarnestMmoney(int $user_id)
+ {
+ $num=self::where([
+ 'user_id'=>$user_id,
+ 'status'=>1
+ ])->sum('earnest_money');
+ return $num >0 ? $num:0;
+ }
+ public static function getUserTradeNum(int $user_id)
+ {
+ //查询持仓订单总成本
+ $count=self::where([
+ ['user_id','=',$user_id],
+ ['status','>',0]
+ ])->count();
+ return $count>0;
+ }
+ public static function getTradeOrderFee(int $user_id)
+ {
+ $info=self::where([
+ ['user_id','=',$user_id],
+ ['status','in',[1,3]]
+ ])->field('sum(service_cost+closing_cost) as fee')->find();
+ if(empty($info)){
+ return 0;
+ }else{
+ $info=$info->toArray();
+ return empty($info['fee']) ? 0 : $info['fee'];
+ }
+ }
+ /**
+ * 获取累计盈亏
+ */
+ public static function getTradeOrderDailyNum(int $user_id)
+ {
+ $num=0;
+ //查询持仓订单总成本
+ $list=self::where([
+ 'user_id'=>$user_id,
+ 'status'=>3
+ ])->field('order_number,closing_price,deal_price,closing_cost,service_cost,trade_type')->select();
+ if(!empty($list)) {
+ $list_arr=$list->toArray();
+ foreach ($list_arr as $val){
+ if($val['trade_type']==1){
+ $order_num=$val['order_number']*($val['closing_price']-$val['deal_price']);
+ }else{
+ $order_num=$val['order_number']*($val['deal_price']-$val['closing_price']);
+ }
+ $num+=$order_num;
+ }
+ }
+ return $num;
+ }
+ public static function getTradeList($trade_name,$num)
+ {
+ $trade_list=[];
+ $list=self::where([
+ ['status','in','1,3'],
+ ['stock_id','=',strtoupper($trade_name)]
+ ])->field('deal_price,order_number,closing_price,open_time,closing_time,status')->order('trade_id desc')->limit($num)->select();
+ if(!empty($list)) {
+ $list_arr=$list->toArray();
+ foreach ($list_arr as $val){
+ if($val['status']==1){
+ $trade_data['order_number']=$val['order_number'];
+ $trade_data['deal_price']=$val['deal_price'];
+ $trade_data['order_time']=strtotime($val['open_time'])*1000;
+ $trade_data['trade_type']=1;
+ array_push($trade_list,$trade_data);
+ }
+ if($val['status']==3){
+ $trade_data['order_number']=$val['order_number'];
+ $trade_data['deal_price']=$val['deal_price'];
+ $trade_data['order_time']=strtotime($val['open_time'])*1000;
+ $trade_data['trade_type']=1;
+ array_push($trade_list,$trade_data);
+
+ $sale_data['order_number']=$val['order_number'];
+ $sale_data['deal_price']=$val['closing_price'];
+ $sale_data['order_time']=strtotime($val['closing_time'])*1000;
+ $sale_data['trade_type']=2;
+ array_push($trade_list,$sale_data);
+
+ }
+ }
+ }
+ return $trade_list;
+ }
+
+ // 获取 挂单 持仓的订单金额 股票价格 * 股数 之和 也就是 market_money 的和
+ public static function getAmountForMargin($user_id)
+ {
+ $trade = self::where('status', '=', '1')->where('user_id', $user_id)->field('sum(deal_price * order_number) as amount')->find();
+ if(empty($trade)){
+ return 0;
+ }
+
+ $trade = $trade->toArray();
+ return $trade['amount']?? 0;
+ }
+
+
+
+}
\ No newline at end of file
diff --git a/app/model/StockEurListModel.php b/app/model/StockEurListModel.php
new file mode 100644
index 0000000..3063637
--- /dev/null
+++ b/app/model/StockEurListModel.php
@@ -0,0 +1,41 @@
+ 'FWB',
+ // self::TAPE_NSE => 'NSE',
+ ];
+
+ const SOURCE_TV='1';
+ const SOURCE_ECONOMICTIMES='2';
+ const SOURCE_LIST = [
+ self::SOURCE_TV => 'TV',
+ self::SOURCE_ECONOMICTIMES => '交易所',
+ ];
+}
\ No newline at end of file
diff --git a/app/model/StockEurTradeModel.php b/app/model/StockEurTradeModel.php
new file mode 100644
index 0000000..7f87491
--- /dev/null
+++ b/app/model/StockEurTradeModel.php
@@ -0,0 +1,168 @@
+$user_id,
+ 'status'=>1,
+ 'stock_id'=>$stock_id,
+ 'trade_type'=>$trade_type
+ ])->field('order_number,deal_price,service_cost')->select();
+ if(!empty($list)) {
+ $list_arr=$list->toArray();
+ foreach ($list_arr as $val){
+ $order_num=$val['order_number']*$val['deal_price'] ;//+ $val['service_cost'];
+ $money+=$order_num;
+ $num+=$val['order_number'];
+ }
+ }
+ return [
+ 'buy_num'=>$num,
+ 'buy_money'=>$money
+ ];
+ }
+ public static function getUserEarnestMmoney(int $user_id)
+ {
+ $num=self::where([
+ 'user_id'=>$user_id,
+ 'status'=>1
+ ])->sum('earnest_money');
+ return $num >0 ? $num:0;
+ }
+ public static function getUserTradeNum(int $user_id)
+ {
+ //查询持仓订单总成本
+ $count=self::where([
+ ['user_id','=',$user_id],
+ ['status','>',0]
+ ])->count();
+ return $count>0;
+ }
+ public static function getTradeOrderFee(int $user_id)
+ {
+ $info=self::where([
+ ['user_id','=',$user_id],
+ ['status','in',[1,3]]
+ ])->field('sum(service_cost+closing_cost) as fee')->find();
+ if(empty($info)){
+ return 0;
+ }else{
+ $info=$info->toArray();
+ return empty($info['fee']) ? 0 : $info['fee'];
+ }
+ }
+ /**
+ * 获取累计盈亏
+ */
+ public static function getTradeOrderDailyNum(int $user_id)
+ {
+ $num=0;
+ //查询持仓订单总成本
+ $list=self::where([
+ 'user_id'=>$user_id,
+ 'status'=>3
+ ])->field('order_number,closing_price,deal_price,closing_cost,service_cost,trade_type')->select();
+ if(!empty($list)) {
+ $list_arr=$list->toArray();
+ foreach ($list_arr as $val){
+ if($val['trade_type']==1){
+ $order_num=$val['order_number']*($val['closing_price']-$val['deal_price']);
+ }else{
+ $order_num=$val['order_number']*($val['deal_price']-$val['closing_price']);
+ }
+ $num+=$order_num;
+ }
+ }
+ return $num;
+ }
+ public static function getTradeList($trade_name,$num)
+ {
+ $trade_list=[];
+ $list=self::where([
+ ['status','in','1,3'],
+ ['stock_id','=',strtoupper($trade_name)]
+ ])->field('deal_price,order_number,closing_price,open_time,closing_time,status')->order('trade_id desc')->limit($num)->select();
+ if(!empty($list)) {
+ $list_arr=$list->toArray();
+ foreach ($list_arr as $val){
+ if($val['status']==1){
+ $trade_data['order_number']=$val['order_number'];
+ $trade_data['deal_price']=$val['deal_price'];
+ $trade_data['order_time']=strtotime($val['open_time'])*1000;
+ $trade_data['trade_type']=1;
+ array_push($trade_list,$trade_data);
+ }
+ if($val['status']==3){
+ $trade_data['order_number']=$val['order_number'];
+ $trade_data['deal_price']=$val['deal_price'];
+ $trade_data['order_time']=strtotime($val['open_time'])*1000;
+ $trade_data['trade_type']=1;
+ array_push($trade_list,$trade_data);
+
+ $sale_data['order_number']=$val['order_number'];
+ $sale_data['deal_price']=$val['closing_price'];
+ $sale_data['order_time']=strtotime($val['closing_time'])*1000;
+ $sale_data['trade_type']=2;
+ array_push($trade_list,$sale_data);
+
+ }
+ }
+ }
+ return $trade_list;
+ }
+
+ // 获取 挂单 持仓的订单金额 股票价格 * 股数 之和 也就是 market_money 的和
+ public static function getAmountForMargin($user_id)
+ {
+ $trade = self::where('status', '=', '1')->where('user_id', $user_id)->field('sum(deal_price * order_number) as amount')->find();
+ if(empty($trade)){
+ return 0;
+ }
+
+ $trade = $trade->toArray();
+ return $trade['amount']?? 0;
+ }
+
+
+
+}
\ No newline at end of file
diff --git a/app/model/StockFurListModel.php b/app/model/StockFurListModel.php
new file mode 100644
index 0000000..04d08bd
--- /dev/null
+++ b/app/model/StockFurListModel.php
@@ -0,0 +1,41 @@
+ 'EURONEXT',
+ //self::TAPE_NSE => 'NSE',
+ ];
+
+ const SOURCE_TV='1';
+ const SOURCE_ECONOMICTIMES='2';
+ const SOURCE_LIST = [
+ self::SOURCE_TV => 'TV',
+ self::SOURCE_ECONOMICTIMES => '交易所',
+ ];
+}
\ No newline at end of file
diff --git a/app/model/StockFurTradeModel.php b/app/model/StockFurTradeModel.php
new file mode 100644
index 0000000..458839a
--- /dev/null
+++ b/app/model/StockFurTradeModel.php
@@ -0,0 +1,168 @@
+$user_id,
+ 'status'=>1,
+ 'stock_id'=>$stock_id,
+ 'trade_type'=>$trade_type
+ ])->field('order_number,deal_price,service_cost')->select();
+ if(!empty($list)) {
+ $list_arr=$list->toArray();
+ foreach ($list_arr as $val){
+ $order_num=$val['order_number']*$val['deal_price'] ;//+ $val['service_cost'];
+ $money+=$order_num;
+ $num+=$val['order_number'];
+ }
+ }
+ return [
+ 'buy_num'=>$num,
+ 'buy_money'=>$money
+ ];
+ }
+ public static function getUserEarnestMmoney(int $user_id)
+ {
+ $num=self::where([
+ 'user_id'=>$user_id,
+ 'status'=>1
+ ])->sum('earnest_money');
+ return $num >0 ? $num:0;
+ }
+ public static function getUserTradeNum(int $user_id)
+ {
+ //查询持仓订单总成本
+ $count=self::where([
+ ['user_id','=',$user_id],
+ ['status','>',0]
+ ])->count();
+ return $count>0;
+ }
+ public static function getTradeOrderFee(int $user_id)
+ {
+ $info=self::where([
+ ['user_id','=',$user_id],
+ ['status','in',[1,3]]
+ ])->field('sum(service_cost+closing_cost) as fee')->find();
+ if(empty($info)){
+ return 0;
+ }else{
+ $info=$info->toArray();
+ return empty($info['fee']) ? 0 : $info['fee'];
+ }
+ }
+ /**
+ * 获取累计盈亏
+ */
+ public static function getTradeOrderDailyNum(int $user_id)
+ {
+ $num=0;
+ //查询持仓订单总成本
+ $list=self::where([
+ 'user_id'=>$user_id,
+ 'status'=>3
+ ])->field('order_number,closing_price,deal_price,closing_cost,service_cost,trade_type')->select();
+ if(!empty($list)) {
+ $list_arr=$list->toArray();
+ foreach ($list_arr as $val){
+ if($val['trade_type']==1){
+ $order_num=$val['order_number']*($val['closing_price']-$val['deal_price']);
+ }else{
+ $order_num=$val['order_number']*($val['deal_price']-$val['closing_price']);
+ }
+ $num+=$order_num;
+ }
+ }
+ return $num;
+ }
+ public static function getTradeList($trade_name,$num)
+ {
+ $trade_list=[];
+ $list=self::where([
+ ['status','in','1,3'],
+ ['stock_id','=',strtoupper($trade_name)]
+ ])->field('deal_price,order_number,closing_price,open_time,closing_time,status')->order('trade_id desc')->limit($num)->select();
+ if(!empty($list)) {
+ $list_arr=$list->toArray();
+ foreach ($list_arr as $val){
+ if($val['status']==1){
+ $trade_data['order_number']=$val['order_number'];
+ $trade_data['deal_price']=$val['deal_price'];
+ $trade_data['order_time']=strtotime($val['open_time'])*1000;
+ $trade_data['trade_type']=1;
+ array_push($trade_list,$trade_data);
+ }
+ if($val['status']==3){
+ $trade_data['order_number']=$val['order_number'];
+ $trade_data['deal_price']=$val['deal_price'];
+ $trade_data['order_time']=strtotime($val['open_time'])*1000;
+ $trade_data['trade_type']=1;
+ array_push($trade_list,$trade_data);
+
+ $sale_data['order_number']=$val['order_number'];
+ $sale_data['deal_price']=$val['closing_price'];
+ $sale_data['order_time']=strtotime($val['closing_time'])*1000;
+ $sale_data['trade_type']=2;
+ array_push($trade_list,$sale_data);
+
+ }
+ }
+ }
+ return $trade_list;
+ }
+
+ // 获取 挂单 持仓的订单金额 股票价格 * 股数 之和 也就是 market_money 的和
+ public static function getAmountForMargin($user_id)
+ {
+ $trade = self::where('status', '=', '1')->where('user_id', $user_id)->field('sum(deal_price * order_number) as amount')->find();
+ if(empty($trade)){
+ return 0;
+ }
+
+ $trade = $trade->toArray();
+ return $trade['amount']?? 0;
+ }
+
+
+
+}
\ No newline at end of file
diff --git a/app/model/StockGBXListModel.php b/app/model/StockGBXListModel.php
new file mode 100644
index 0000000..c4eaa8c
--- /dev/null
+++ b/app/model/StockGBXListModel.php
@@ -0,0 +1,41 @@
+ 'LSE',
+// self::TAPE_NSE => 'NSE',
+ ];
+
+ const SOURCE_TV='1';
+ const SOURCE_ECONOMICTIMES='2';
+ const SOURCE_LIST = [
+ self::SOURCE_TV => 'TV',
+ self::SOURCE_ECONOMICTIMES => '交易所',
+ ];
+}
\ No newline at end of file
diff --git a/app/model/StockGBXTradeModel.php b/app/model/StockGBXTradeModel.php
new file mode 100644
index 0000000..f0d0e45
--- /dev/null
+++ b/app/model/StockGBXTradeModel.php
@@ -0,0 +1,168 @@
+$user_id,
+ 'status'=>1,
+ 'stock_id'=>$stock_id,
+ 'trade_type'=>$trade_type
+ ])->field('order_number,deal_price,service_cost')->select();
+ if(!empty($list)) {
+ $list_arr=$list->toArray();
+ foreach ($list_arr as $val){
+ $order_num=$val['order_number']*$val['deal_price'] ;//+ $val['service_cost'];
+ $money+=$order_num;
+ $num+=$val['order_number'];
+ }
+ }
+ return [
+ 'buy_num'=>$num,
+ 'buy_money'=>$money
+ ];
+ }
+ public static function getUserEarnestMmoney(int $user_id)
+ {
+ $num=self::where([
+ 'user_id'=>$user_id,
+ 'status'=>1
+ ])->sum('earnest_money');
+ return $num >0 ? $num:0;
+ }
+ public static function getUserTradeNum(int $user_id)
+ {
+ //查询持仓订单总成本
+ $count=self::where([
+ ['user_id','=',$user_id],
+ ['status','>',0]
+ ])->count();
+ return $count>0;
+ }
+ public static function getTradeOrderFee(int $user_id)
+ {
+ $info=self::where([
+ ['user_id','=',$user_id],
+ ['status','in',[1,3]]
+ ])->field('sum(service_cost+closing_cost) as fee')->find();
+ if(empty($info)){
+ return 0;
+ }else{
+ $info=$info->toArray();
+ return empty($info['fee']) ? 0 : $info['fee'];
+ }
+ }
+ /**
+ * 获取累计盈亏
+ */
+ public static function getTradeOrderDailyNum(int $user_id)
+ {
+ $num=0;
+ //查询持仓订单总成本
+ $list=self::where([
+ 'user_id'=>$user_id,
+ 'status'=>3
+ ])->field('order_number,closing_price,deal_price,closing_cost,service_cost,trade_type')->select();
+ if(!empty($list)) {
+ $list_arr=$list->toArray();
+ foreach ($list_arr as $val){
+ if($val['trade_type']==1){
+ $order_num=$val['order_number']*($val['closing_price']-$val['deal_price']);
+ }else{
+ $order_num=$val['order_number']*($val['deal_price']-$val['closing_price']);
+ }
+ $num+=$order_num;
+ }
+ }
+ return $num;
+ }
+ public static function getTradeList($trade_name,$num)
+ {
+ $trade_list=[];
+ $list=self::where([
+ ['status','in','1,3'],
+ ['stock_id','=',strtoupper($trade_name)]
+ ])->field('deal_price,order_number,closing_price,open_time,closing_time,status')->order('trade_id desc')->limit($num)->select();
+ if(!empty($list)) {
+ $list_arr=$list->toArray();
+ foreach ($list_arr as $val){
+ if($val['status']==1){
+ $trade_data['order_number']=$val['order_number'];
+ $trade_data['deal_price']=$val['deal_price'];
+ $trade_data['order_time']=strtotime($val['open_time'])*1000;
+ $trade_data['trade_type']=1;
+ array_push($trade_list,$trade_data);
+ }
+ if($val['status']==3){
+ $trade_data['order_number']=$val['order_number'];
+ $trade_data['deal_price']=$val['deal_price'];
+ $trade_data['order_time']=strtotime($val['open_time'])*1000;
+ $trade_data['trade_type']=1;
+ array_push($trade_list,$trade_data);
+
+ $sale_data['order_number']=$val['order_number'];
+ $sale_data['deal_price']=$val['closing_price'];
+ $sale_data['order_time']=strtotime($val['closing_time'])*1000;
+ $sale_data['trade_type']=2;
+ array_push($trade_list,$sale_data);
+
+ }
+ }
+ }
+ return $trade_list;
+ }
+
+ // 获取 挂单 持仓的订单金额 股票价格 * 股数 之和 也就是 market_money 的和
+ public static function getAmountForMargin($user_id)
+ {
+ $trade = self::where('status', '=', '1')->where('user_id', $user_id)->field('sum(deal_price * order_number) as amount')->find();
+ if(empty($trade)){
+ return 0;
+ }
+
+ $trade = $trade->toArray();
+ return $trade['amount']?? 0;
+ }
+
+
+
+}
\ No newline at end of file
diff --git a/app/model/StockHkdListModel.php b/app/model/StockHkdListModel.php
new file mode 100644
index 0000000..1d7c030
--- /dev/null
+++ b/app/model/StockHkdListModel.php
@@ -0,0 +1,33 @@
+ 'HKEX',
+ ];
+}
\ No newline at end of file
diff --git a/app/model/StockHkdTradeModel.php b/app/model/StockHkdTradeModel.php
new file mode 100644
index 0000000..2bedfcd
--- /dev/null
+++ b/app/model/StockHkdTradeModel.php
@@ -0,0 +1,168 @@
+$user_id,
+ 'status'=>1,
+ 'stock_id'=>$stock_id,
+ 'trade_type'=>$trade_type
+ ])->field('order_number,deal_price,service_cost')->select();
+ if(!empty($list)) {
+ $list_arr=$list->toArray();
+ foreach ($list_arr as $val){
+ $order_num=$val['order_number']*$val['deal_price'] ;//+ $val['service_cost'];
+ $money+=$order_num;
+ $num+=$val['order_number'];
+ }
+ }
+ return [
+ 'buy_num'=>$num,
+ 'buy_money'=>$money
+ ];
+ }
+ public static function getUserEarnestMmoney(int $user_id)
+ {
+ $num=self::where([
+ 'user_id'=>$user_id,
+ 'status'=>1
+ ])->sum('earnest_money');
+ return $num >0 ? $num:0;
+ }
+ public static function getUserTradeNum(int $user_id)
+ {
+ //查询持仓订单总成本
+ $count=self::where([
+ ['user_id','=',$user_id],
+ ['status','>',0]
+ ])->count();
+ return $count>0;
+ }
+ public static function getTradeOrderFee(int $user_id)
+ {
+ $info=self::where([
+ ['user_id','=',$user_id],
+ ['status','in',[1,3]]
+ ])->field('sum(service_cost+closing_cost) as fee')->find();
+ if(empty($info)){
+ return 0;
+ }else{
+ $info=$info->toArray();
+ return empty($info['fee']) ? 0 : $info['fee'];
+ }
+ }
+ /**
+ * 获取累计盈亏
+ */
+ public static function getTradeOrderDailyNum(int $user_id)
+ {
+ $num=0;
+ //查询持仓订单总成本
+ $list=self::where([
+ 'user_id'=>$user_id,
+ 'status'=>3
+ ])->field('order_number,closing_price,deal_price,closing_cost,service_cost,trade_type')->select();
+ if(!empty($list)) {
+ $list_arr=$list->toArray();
+ foreach ($list_arr as $val){
+ if($val['trade_type']==1){
+ $order_num=$val['order_number']*($val['closing_price']-$val['deal_price']);
+ }else{
+ $order_num=$val['order_number']*($val['deal_price']-$val['closing_price']);
+ }
+ $num+=$order_num;
+ }
+ }
+ return $num;
+ }
+ public static function getTradeList($trade_name,$num)
+ {
+ $trade_list=[];
+ $list=self::where([
+ ['status','in','1,3'],
+ ['stock_id','=',strtoupper($trade_name)]
+ ])->field('deal_price,order_number,closing_price,open_time,closing_time,status')->order('trade_id desc')->limit($num)->select();
+ if(!empty($list)) {
+ $list_arr=$list->toArray();
+ foreach ($list_arr as $val){
+ if($val['status']==1){
+ $trade_data['order_number']=$val['order_number'];
+ $trade_data['deal_price']=$val['deal_price'];
+ $trade_data['order_time']=strtotime($val['open_time'])*1000;
+ $trade_data['trade_type']=1;
+ array_push($trade_list,$trade_data);
+ }
+ if($val['status']==3){
+ $trade_data['order_number']=$val['order_number'];
+ $trade_data['deal_price']=$val['deal_price'];
+ $trade_data['order_time']=strtotime($val['open_time'])*1000;
+ $trade_data['trade_type']=1;
+ array_push($trade_list,$trade_data);
+
+ $sale_data['order_number']=$val['order_number'];
+ $sale_data['deal_price']=$val['closing_price'];
+ $sale_data['order_time']=strtotime($val['closing_time'])*1000;
+ $sale_data['trade_type']=2;
+ array_push($trade_list,$sale_data);
+
+ }
+ }
+ }
+ return $trade_list;
+ }
+
+ // 获取 挂单 持仓的订单金额 股票价格 * 股数 之和 也就是 market_money 的和
+ public static function getAmountForMargin($user_id)
+ {
+ $trade = self::where('status', '=', '1')->where('user_id', $user_id)->field('sum(deal_price * order_number) as amount')->find();
+ if(empty($trade)){
+ return 0;
+ }
+
+ $trade = $trade->toArray();
+ return $trade['amount']?? 0;
+ }
+
+
+
+}
\ No newline at end of file
diff --git a/app/model/StockIdnListModel.php b/app/model/StockIdnListModel.php
new file mode 100644
index 0000000..05ac08e
--- /dev/null
+++ b/app/model/StockIdnListModel.php
@@ -0,0 +1,33 @@
+ 'IDX',
+ ];
+}
\ No newline at end of file
diff --git a/app/model/StockIdnTradeModel.php b/app/model/StockIdnTradeModel.php
new file mode 100644
index 0000000..ea72224
--- /dev/null
+++ b/app/model/StockIdnTradeModel.php
@@ -0,0 +1,143 @@
+$user_id,
+ 'status'=>1,
+ 'stock_id'=>$stock_id,
+ 'trade_type'=>$trade_type
+ ])->field('order_number,deal_price,service_cost')->select();
+ if(!empty($list)) {
+ $list_arr=$list->toArray();
+ foreach ($list_arr as $val){
+ $order_num=$val['order_number']*$val['deal_price'] ;//+ $val['service_cost'];
+ $money+=$order_num;
+ $num+=$val['order_number'];
+ }
+ }
+ return [
+ 'buy_num'=>$num,
+ 'buy_money'=>$money
+ ];
+ }
+ public static function getUserEarnestMmoney(int $user_id)
+ {
+ $num=self::where([
+ 'user_id'=>$user_id,
+ 'status'=>1
+ ])->sum('earnest_money');
+ return $num >0 ? $num:0;
+ }
+ public static function getUserTradeNum(int $user_id)
+ {
+ //查询持仓订单总成本
+ $count=self::where([
+ ['user_id','=',$user_id],
+ ['status','>',0]
+ ])->count();
+ return $count>0;
+ }
+ public static function getTradeOrderFee(int $user_id)
+ {
+ $info=self::where([
+ ['user_id','=',$user_id],
+ ['status','in',[1,3]]
+ ])->field('sum(service_cost+closing_cost) as fee')->find();
+ if(empty($info)){
+ return 0;
+ }else{
+ $info=$info->toArray();
+ return empty($info['fee']) ? 0 : $info['fee'];
+ }
+ }
+ /**
+ * 获取累计盈亏
+ */
+ public static function getTradeOrderDailyNum(int $user_id)
+ {
+ $num=0;
+ //查询持仓订单总成本
+ $list=self::where([
+ 'user_id'=>$user_id,
+ 'status'=>3
+ ])->field('order_number,closing_price,deal_price,closing_cost,service_cost,trade_type')->select();
+ if(!empty($list)) {
+ $list_arr=$list->toArray();
+ foreach ($list_arr as $val){
+ if($val['trade_type']==1){
+ $order_num=$val['order_number']*($val['closing_price']-$val['deal_price']);
+ }else{
+ $order_num=$val['order_number']*($val['deal_price']-$val['closing_price']);
+ }
+ $num+=$order_num;
+ }
+ }
+ return $num;
+ }
+ public static function getTradeList($trade_name,$num)
+ {
+ $trade_list=[];
+ $list=self::where([
+ ['status','in','1,3'],
+ ['stock_id','=',strtoupper($trade_name)]
+ ])->field('deal_price,order_number,closing_price,open_time,closing_time,status')->order('trade_id desc')->limit($num)->select();
+ if(!empty($list)) {
+ $list_arr=$list->toArray();
+ foreach ($list_arr as $val){
+ if($val['status']==1){
+ $trade_data['order_number']=$val['order_number'];
+ $trade_data['deal_price']=$val['deal_price'];
+ $trade_data['order_time']=strtotime($val['open_time'])*1000;
+ $trade_data['trade_type']=1;
+ array_push($trade_list,$trade_data);
+ }
+ if($val['status']==3){
+ $trade_data['order_number']=$val['order_number'];
+ $trade_data['deal_price']=$val['deal_price'];
+ $trade_data['order_time']=strtotime($val['open_time'])*1000;
+ $trade_data['trade_type']=1;
+ array_push($trade_list,$trade_data);
+
+ $sale_data['order_number']=$val['order_number'];
+ $sale_data['deal_price']=$val['closing_price'];
+ $sale_data['order_time']=strtotime($val['closing_time'])*1000;
+ $sale_data['trade_type']=2;
+ array_push($trade_list,$sale_data);
+
+ }
+ }
+ }
+ return $trade_list;
+ }
+
+ // 获取 挂单 持仓的订单金额 股票价格 * 股数 之和 也就是 market_money 的和
+ public static function getAmountForMargin($user_id)
+ {
+ $trade = self::where('status', '=', '1')->where('user_id', $user_id)->field('sum(deal_price * order_number) as amount')->find();
+ if(empty($trade)){
+ return 0;
+ }
+
+ $trade = $trade->toArray();
+ return $trade['amount']?? 0;
+ }
+}
\ No newline at end of file
diff --git a/app/model/StockInListModel.php b/app/model/StockInListModel.php
new file mode 100644
index 0000000..b15a0fa
--- /dev/null
+++ b/app/model/StockInListModel.php
@@ -0,0 +1,42 @@
+ 'BSE',
+ self::TAPE_NSE => 'NSE',
+ ];
+
+ const SOURCE_TV='1';
+ const SOURCE_ECONOMICTIMES='2';
+ const SOURCE_LIST = [
+ self::SOURCE_TV => 'TV',
+// self::SOURCE_ECONOMICTIMES => 'ECONOMICTIMES',
+ self::SOURCE_ECONOMICTIMES => '交易所',
+ ];
+}
\ No newline at end of file
diff --git a/app/model/StockInTradeModel.php b/app/model/StockInTradeModel.php
new file mode 100644
index 0000000..6d87092
--- /dev/null
+++ b/app/model/StockInTradeModel.php
@@ -0,0 +1,168 @@
+$user_id,
+ 'status'=>1,
+ 'stock_id'=>$stock_id,
+ 'trade_type'=>$trade_type
+ ])->field('order_number,deal_price,service_cost')->select();
+ if(!empty($list)) {
+ $list_arr=$list->toArray();
+ foreach ($list_arr as $val){
+ $order_num=$val['order_number']*$val['deal_price'] ;//+ $val['service_cost'];
+ $money+=$order_num;
+ $num+=$val['order_number'];
+ }
+ }
+ return [
+ 'buy_num'=>$num,
+ 'buy_money'=>$money
+ ];
+ }
+ public static function getUserEarnestMmoney(int $user_id)
+ {
+ $num=self::where([
+ 'user_id'=>$user_id,
+ 'status'=>1
+ ])->sum('earnest_money');
+ return $num >0 ? $num:0;
+ }
+ public static function getUserTradeNum(int $user_id)
+ {
+ //查询持仓订单总成本
+ $count=self::where([
+ ['user_id','=',$user_id],
+ ['status','>',0]
+ ])->count();
+ return $count>0;
+ }
+ public static function getTradeOrderFee(int $user_id)
+ {
+ $info=self::where([
+ ['user_id','=',$user_id],
+ ['status','in',[1,3]]
+ ])->field('sum(service_cost+closing_cost) as fee')->find();
+ if(empty($info)){
+ return 0;
+ }else{
+ $info=$info->toArray();
+ return empty($info['fee']) ? 0 : $info['fee'];
+ }
+ }
+ /**
+ * 获取累计盈亏
+ */
+ public static function getTradeOrderDailyNum(int $user_id)
+ {
+ $num=0;
+ //查询持仓订单总成本
+ $list=self::where([
+ 'user_id'=>$user_id,
+ 'status'=>3
+ ])->field('order_number,closing_price,deal_price,closing_cost,service_cost,trade_type')->select();
+ if(!empty($list)) {
+ $list_arr=$list->toArray();
+ foreach ($list_arr as $val){
+ if($val['trade_type']==1){
+ $order_num=$val['order_number']*($val['closing_price']-$val['deal_price']);
+ }else{
+ $order_num=$val['order_number']*($val['deal_price']-$val['closing_price']);
+ }
+ $num+=$order_num;
+ }
+ }
+ return $num;
+ }
+ public static function getTradeList($trade_name,$num)
+ {
+ $trade_list=[];
+ $list=self::where([
+ ['status','in','1,3'],
+ ['stock_id','=',strtoupper($trade_name)]
+ ])->field('deal_price,order_number,closing_price,open_time,closing_time,status')->order('trade_id desc')->limit($num)->select();
+ if(!empty($list)) {
+ $list_arr=$list->toArray();
+ foreach ($list_arr as $val){
+ if($val['status']==1){
+ $trade_data['order_number']=$val['order_number'];
+ $trade_data['deal_price']=$val['deal_price'];
+ $trade_data['order_time']=strtotime($val['open_time'])*1000;
+ $trade_data['trade_type']=1;
+ array_push($trade_list,$trade_data);
+ }
+ if($val['status']==3){
+ $trade_data['order_number']=$val['order_number'];
+ $trade_data['deal_price']=$val['deal_price'];
+ $trade_data['order_time']=strtotime($val['open_time'])*1000;
+ $trade_data['trade_type']=1;
+ array_push($trade_list,$trade_data);
+
+ $sale_data['order_number']=$val['order_number'];
+ $sale_data['deal_price']=$val['closing_price'];
+ $sale_data['order_time']=strtotime($val['closing_time'])*1000;
+ $sale_data['trade_type']=2;
+ array_push($trade_list,$sale_data);
+
+ }
+ }
+ }
+ return $trade_list;
+ }
+
+ // 获取 挂单 持仓的订单金额 股票价格 * 股数 之和 也就是 market_money 的和
+ public static function getAmountForMargin($user_id)
+ {
+ $trade = self::where('status', '=', '1')->where('user_id', $user_id)->field('sum(deal_price * order_number) as amount')->find();
+ if(empty($trade)){
+ return 0;
+ }
+
+ $trade = $trade->toArray();
+ return $trade['amount']?? 0;
+ }
+
+
+
+}
\ No newline at end of file
diff --git a/app/model/StockIndexModel.php b/app/model/StockIndexModel.php
new file mode 100644
index 0000000..f5c79f9
--- /dev/null
+++ b/app/model/StockIndexModel.php
@@ -0,0 +1,24 @@
+ 'TSE',
+ ];
+}
\ No newline at end of file
diff --git a/app/model/StockJpTradeModel.php b/app/model/StockJpTradeModel.php
new file mode 100644
index 0000000..696e00f
--- /dev/null
+++ b/app/model/StockJpTradeModel.php
@@ -0,0 +1,172 @@
+$user_id,
+ 'status'=>1,
+ 'stock_id'=>$stock_id,
+ 'trade_type'=>$trade_type
+ ])->field('order_number,deal_price,service_cost')->select();
+ if(!empty($list)) {
+ $list_arr=$list->toArray();
+ foreach ($list_arr as $val){
+ $order_num=$val['order_number']*$val['deal_price'] ;//+ $val['service_cost'];
+ $money+=$order_num;
+ $num+=$val['order_number'];
+ }
+ }
+ return [
+ 'buy_num'=>$num,
+ 'buy_money'=>$money
+ ];
+ }
+ public static function getUserEarnestMmoney(int $user_id)
+ {
+ $num=self::where([
+ 'user_id'=>$user_id,
+ 'status'=>1
+ ])->sum('earnest_money');
+ return $num >0 ? $num:0;
+ }
+ public static function getUserTradeNum(int $user_id)
+ {
+ //查询持仓订单总成本
+ $count=self::where([
+ ['user_id','=',$user_id],
+ ['status','>',0]
+ ])->count();
+ return $count>0;
+ }
+
+ /**
+ * 获取累计交易手续费
+ */
+ public static function getTradeOrderFee(int $user_id)
+ {
+ $info=self::where([
+ ['user_id','=',$user_id],
+ ['status','in',[1,3]]
+ ])->field('sum(service_cost+closing_cost) as fee')->find();
+ if(empty($info)){
+ return 0;
+ }else{
+ $info=$info->toArray();
+ return empty($info['fee']) ? 0 : $info['fee'];
+ }
+ }
+ /**
+ * 获取累计盈亏
+ */
+ public static function getTradeOrderDailyNum(int $user_id)
+ {
+ $num=0;
+ //查询持仓订单总成本
+ $list=self::where([
+ 'user_id'=>$user_id,
+ 'status'=>3
+ ])->field('order_number,closing_price,deal_price,closing_cost,service_cost,trade_type')->select();
+ if(!empty($list)) {
+ $list_arr=$list->toArray();
+ foreach ($list_arr as $val){
+ if($val['trade_type']==1){
+ $order_num=$val['order_number']*($val['closing_price']-$val['deal_price']);
+ }else{
+ $order_num=$val['order_number']*($val['deal_price']-$val['closing_price']);
+ }
+ $num+=$order_num;
+ }
+ }
+ return $num;
+ }
+ public static function getTradeList($trade_name,$num)
+ {
+ $trade_list=[];
+ $list=self::where([
+ ['status','in','1,3'],
+ ['stock_id','=',strtoupper($trade_name)]
+ ])->field('deal_price,order_number,closing_price,open_time,closing_time,status')->order('trade_id desc')->limit($num)->select();
+ if(!empty($list)) {
+ $list_arr=$list->toArray();
+ foreach ($list_arr as $val){
+ if($val['status']==1){
+ $trade_data['order_number']=$val['order_number'];
+ $trade_data['deal_price']=$val['deal_price'];
+ $trade_data['order_time']=strtotime($val['open_time'])*1000;
+ $trade_data['trade_type']=1;
+ array_push($trade_list,$trade_data);
+ }
+ if($val['status']==3){
+ $trade_data['order_number']=$val['order_number'];
+ $trade_data['deal_price']=$val['deal_price'];
+ $trade_data['order_time']=strtotime($val['open_time'])*1000;
+ $trade_data['trade_type']=1;
+ array_push($trade_list,$trade_data);
+
+ $sale_data['order_number']=$val['order_number'];
+ $sale_data['deal_price']=$val['closing_price'];
+ $sale_data['order_time']=strtotime($val['closing_time'])*1000;
+ $sale_data['trade_type']=2;
+ array_push($trade_list,$sale_data);
+
+ }
+ }
+ }
+ return $trade_list;
+ }
+
+ // 获取 挂单 持仓的订单金额 股票价格 * 股数 之和 也就是 market_money 的和
+ public static function getAmountForMargin($user_id)
+ {
+ $trade = self::where('status', '=', '1')->where('user_id', $user_id)->field('sum(deal_price * order_number) as amount')->find();
+ if(empty($trade)){
+ return 0;
+ }
+
+ $trade = $trade->toArray();
+ return $trade['amount']?? 0;
+ }
+
+
+
+}
\ No newline at end of file
diff --git a/app/model/StockListModel.php b/app/model/StockListModel.php
new file mode 100644
index 0000000..99c40c4
--- /dev/null
+++ b/app/model/StockListModel.php
@@ -0,0 +1,69 @@
+ 'NYSE',
+ self::TAPE_NYSE_ARCA => 'NYSEARCA',
+ self::TAPE_NASDAQ => 'NASDAQ',
+ ];
+
+
+ public static function getMarketList($data): array
+ {
+ $where='status=1';
+ if(!empty($data['trade_name'])){
+ $where.=" and (trade_name like '".strtoupper($data['trade_name'])."%' or stock_code like '".strtoupper($data['trade_name'])."%')";
+ }
+ if($data['page']<1){
+ $data['page']=1;
+ }
+ if($data['page_size']<1){
+ $data['page_size']=10;
+ }
+
+ $count=self::where($where)->count();
+
+ $list = self::where($where)->field('trade_name as name,stock_code 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('stock_code',$trade_name)->value('id');
+ return $id >0;
+ }
+
+}
\ No newline at end of file
diff --git a/app/model/StockMarketModel.php b/app/model/StockMarketModel.php
new file mode 100644
index 0000000..2bbffe1
--- /dev/null
+++ b/app/model/StockMarketModel.php
@@ -0,0 +1,222 @@
+ '现货',
+ self::CONTRACT_MARKET => '合约',
+ self::STOCK_MARKET_USA => '美股',
+ self::STOCK_MARKET_MG => '马股',
+ self::STOCK_MARKET_TG => '泰股',
+ self::STOCK_MARKET_YNG => '印尼股',
+ self::STOCK_MARKET_IN => '印度股',
+ self::STOCK_MARKET_HY => '秒合约',
+ self::STOCK_MARKET_SGD => '新加坡股',
+ self::STOCK_MARKET_FUND => '基金',
+ self::STOCK_MARKET_OPTION_IN => '印度期权',
+ self::STOCK_MARKET_HK => '港股',
+ self::STOCK_MARKET_UK => '英股',
+ self::STOCK_MARKET_FUR => '法股',
+ self::STOCK_MARKET_EUR => '德股',
+ self::STOCK_MARKET_BRL => '巴西股',
+ self::STOCK_MARKET_JP => '日股',
+ self::FOREX_MARKET => '外汇',
+ ];
+
+ // 状态
+ const STATUS_NO = 1;
+ const STATUS_OFF = 2;
+
+ // 交易日限制
+ const TRADE_DAY_TYPE = [
+ '1' => 'T+0',
+ '2' => 'T+1',
+ '3' => 'T+2',
+ '4' => 'T+3',
+ ];
+
+ const LEVER_STATUS_ON = 1; // 杠杆状态 开启
+ const LEVER_STATUS_OFF = 2; // 杠杆状态 关闭
+
+
+ // 获取费率
+ public function getRate($accountType)
+ {
+ switch ($accountType)
+ {
+ case '3':
+ // 美股
+ $rate = StockMarketModel::where('stock_market_type', StockMarketModel::STOCK_MARKET_USA)->value('rate');
+ if(empty($rate) || $rate <= 0){
+ $rate = 0;
+ }
+ break;
+ case '4':
+ // 印尼股
+ $rate = StockMarketModel::where('stock_market_type', StockMarketModel::STOCK_MARKET_YNG)->value('rate');
+ if(empty($rate) || $rate <= 0){
+ $rate = 0;
+ }
+ break;
+ case '5':
+ // 马来股
+ $rate = StockMarketModel::where('stock_market_type', StockMarketModel::STOCK_MARKET_MG)->value('rate');
+ if(empty($rate) || $rate <= 0){
+ $rate = 0;
+ }
+ break;
+ case '6':
+ // 泰股
+ $rate = StockMarketModel::where('stock_market_type', StockMarketModel::STOCK_MARKET_TG)->value('rate');
+ if(empty($rate) || $rate <= 0){
+ $rate = 0;
+ }
+ break;
+ case '7':
+ // 印度股
+ $rate = StockMarketModel::where('stock_market_type', StockMarketModel::STOCK_MARKET_IN)->value('rate');
+ if(empty($rate) || $rate <= 0){
+ $rate = 0;
+ }
+ break;
+ case '9':
+ // 新加坡
+ $rate = StockMarketModel::where('stock_market_type', StockMarketModel::STOCK_MARKET_SGD)->value('rate');
+ if(empty($rate) || $rate <= 0){
+ $rate = 0;
+ }
+ break;
+ case '10':
+ // 基金
+ $rate = StockMarketModel::where('stock_market_type', StockMarketModel::STOCK_MARKET_FUND)->value('rate');
+ if(empty($rate) || $rate <= 0){
+ $rate = 0;
+ }
+ break;
+ case '11':
+ // 印度期权
+ $rate = StockMarketModel::where('stock_market_type', StockMarketModel::STOCK_MARKET_OPTION_IN)->value('rate');
+ if(empty($rate) || $rate <= 0){
+ $rate = 0;
+ }
+ break;
+ case '12':
+ // 港股
+ $rate = StockMarketModel::where('stock_market_type', StockMarketModel::STOCK_MARKET_HK)->value('rate');
+ if(empty($rate) || $rate <= 0){
+ $rate = 0;
+ }
+ break;
+ case '14':
+ // 港股
+ $rate = StockMarketModel::where('stock_market_type', StockMarketModel::STOCK_MARKET_UK)->value('rate');
+ if(empty($rate) || $rate <= 0){
+ $rate = 0;
+ }
+ break;
+ case '15':
+ // 港股
+ $rate = StockMarketModel::where('stock_market_type', StockMarketModel::STOCK_MARKET_FUR)->value('rate');
+ if(empty($rate) || $rate <= 0){
+ $rate = 0;
+ }
+ break;
+ case '16':
+ // 港股
+ $rate = StockMarketModel::where('stock_market_type', StockMarketModel::STOCK_MARKET_EUR)->value('rate');
+ if(empty($rate) || $rate <= 0){
+ $rate = 0;
+ }
+ break;
+ case '17':
+ // 巴西股
+ $rate = StockMarketModel::where('stock_market_type', StockMarketModel::STOCK_MARKET_BRL)->value('rate');
+ if(empty($rate) || $rate <= 0){
+ $rate = 0;
+ }
+ break;
+ case '18':
+ // 巴西股
+ $rate = StockMarketModel::where('stock_market_type', StockMarketModel::STOCK_MARKET_JP)->value('rate');
+ if(empty($rate) || $rate <= 0){
+ $rate = 0;
+ }
+ break;
+ case '19':
+ // 巴西股
+ $rate = StockMarketModel::where('stock_market_type', StockMarketModel::FOREX_MARKET)->value('rate');
+ if(empty($rate) || $rate <= 0){
+ $rate = 0;
+ }
+ break;
+ default:
+ $rate = 1;
+ break;
+ }
+
+ return $rate;
+ }
+
+ //
+ public function getAllTape(){
+ return [
+ self::STOCK_MARKET_USA => StockListModel::$tapeList,
+ self::STOCK_MARKET_MG => StockMysListModel::$tapeList,
+ self::STOCK_MARKET_TG => StockThaListModel::$tapeList,
+ self::STOCK_MARKET_YNG => StockIdnListModel::$tapeList,
+ self::STOCK_MARKET_IN => StockInListModel::$tapeList,
+ self::STOCK_MARKET_SGD => StockSgdListModel::$tapeList,
+ self::STOCK_MARKET_HK => StockHkdListModel::$tapeList,
+ self::STOCK_MARKET_EUR => StockEurListModel::$tapeList,
+ self::STOCK_MARKET_FUR => StockFurListModel::$tapeList,
+ self::STOCK_MARKET_BRL => StockBrlListModel::$tapeList,
+ self::STOCK_MARKET_JP => StockJpListModel::$tapeList,
+ ];
+ }
+}
\ No newline at end of file
diff --git a/app/model/StockMysListModel.php b/app/model/StockMysListModel.php
new file mode 100644
index 0000000..54eb730
--- /dev/null
+++ b/app/model/StockMysListModel.php
@@ -0,0 +1,32 @@
+ 'MYX',
+ ];
+}
\ No newline at end of file
diff --git a/app/model/StockMysTradeModel.php b/app/model/StockMysTradeModel.php
new file mode 100644
index 0000000..99f4960
--- /dev/null
+++ b/app/model/StockMysTradeModel.php
@@ -0,0 +1,168 @@
+$user_id,
+ 'status'=>1,
+ 'stock_id'=>$stock_id,
+ 'trade_type'=>$trade_type
+ ])->field('order_number,deal_price,service_cost')->select();
+ if(!empty($list)) {
+ $list_arr=$list->toArray();
+ foreach ($list_arr as $val){
+ $order_num=$val['order_number']*$val['deal_price'] ;//+ $val['service_cost'];
+ $money+=$order_num;
+ $num+=$val['order_number'];
+ }
+ }
+ return [
+ 'buy_num'=>$num,
+ 'buy_money'=>$money
+ ];
+ }
+ public static function getUserEarnestMmoney(int $user_id)
+ {
+ $num=self::where([
+ 'user_id'=>$user_id,
+ 'status'=>1
+ ])->sum('earnest_money');
+ return $num >0 ? $num:0;
+ }
+ public static function getUserTradeNum(int $user_id)
+ {
+ //查询持仓订单总成本
+ $count=self::where([
+ ['user_id','=',$user_id],
+ ['status','>',0]
+ ])->count();
+ return $count>0;
+ }
+ public static function getTradeOrderFee(int $user_id)
+ {
+ $info=self::where([
+ ['user_id','=',$user_id],
+ ['status','in',[1,3]]
+ ])->field('sum(service_cost+closing_cost) as fee')->find();
+ if(empty($info)){
+ return 0;
+ }else{
+ $info=$info->toArray();
+ return empty($info['fee']) ? 0 : $info['fee'];
+ }
+ }
+ /**
+ * 获取累计盈亏
+ */
+ public static function getTradeOrderDailyNum(int $user_id)
+ {
+ $num=0;
+ //查询持仓订单总成本
+ $list=self::where([
+ 'user_id'=>$user_id,
+ 'status'=>3
+ ])->field('order_number,closing_price,deal_price,closing_cost,service_cost,trade_type')->select();
+ if(!empty($list)) {
+ $list_arr=$list->toArray();
+ foreach ($list_arr as $val){
+ if($val['trade_type']==1){
+ $order_num=$val['order_number']*($val['closing_price']-$val['deal_price']);
+ }else{
+ $order_num=$val['order_number']*($val['deal_price']-$val['closing_price']);
+ }
+ $num+=$order_num;
+ }
+ }
+ return $num;
+ }
+ public static function getTradeList($trade_name,$num)
+ {
+ $trade_list=[];
+ $list=self::where([
+ ['status','in','1,3'],
+ ['stock_id','=',strtoupper($trade_name)]
+ ])->field('deal_price,order_number,closing_price,open_time,closing_time,status')->order('trade_id desc')->limit($num)->select();
+ if(!empty($list)) {
+ $list_arr=$list->toArray();
+ foreach ($list_arr as $val){
+ if($val['status']==1){
+ $trade_data['order_number']=$val['order_number'];
+ $trade_data['deal_price']=$val['deal_price'];
+ $trade_data['order_time']=strtotime($val['open_time'])*1000;
+ $trade_data['trade_type']=1;
+ array_push($trade_list,$trade_data);
+ }
+ if($val['status']==3){
+ $trade_data['order_number']=$val['order_number'];
+ $trade_data['deal_price']=$val['deal_price'];
+ $trade_data['order_time']=strtotime($val['open_time'])*1000;
+ $trade_data['trade_type']=1;
+ array_push($trade_list,$trade_data);
+
+ $sale_data['order_number']=$val['order_number'];
+ $sale_data['deal_price']=$val['closing_price'];
+ $sale_data['order_time']=strtotime($val['closing_time'])*1000;
+ $sale_data['trade_type']=2;
+ array_push($trade_list,$sale_data);
+
+ }
+ }
+ }
+ return $trade_list;
+ }
+
+ // 获取 挂单 持仓的订单金额 股票价格 * 股数 之和 也就是 market_money 的和
+ public static function getAmountForMargin($user_id)
+ {
+ $trade = self::where('status', '=', '1')->where('user_id', $user_id)->field('sum(deal_price * order_number) as amount')->find();
+ if(empty($trade)){
+ return 0;
+ }
+
+ $trade = $trade->toArray();
+ return $trade['amount']?? 0;
+ }
+
+
+
+}
\ No newline at end of file
diff --git a/app/model/StockOptionInrListModel.php b/app/model/StockOptionInrListModel.php
new file mode 100644
index 0000000..b4544b1
--- /dev/null
+++ b/app/model/StockOptionInrListModel.php
@@ -0,0 +1,62 @@
+ '未启用',
+ self::STATUS_ON => '已启用',
+ ];
+
+
+ // 交易所类型
+ const BSE = 'BSE';
+ const NSE = 'NSE';
+ public static $tapeList = [
+ self::BSE => 1,
+ self::NSE => 2,
+ ];
+
+ public static $tapeListText = [
+ 1 => self::BSE,
+ 2 => self::NSE,
+ ];
+
+ public function getStatusTextAttr($value, $data)
+ {
+ $result = StockOptionInrListModel::$statusList[$data['status']]??'';
+ return $result;
+ }
+
+ public function getTapeTextAttr($value, $data)
+ {
+ $result = StockOptionInrListModel::$tapeListText[$data['tape']]??'BSE';
+ return $result;
+ }
+}
\ No newline at end of file
diff --git a/app/model/StockOptionInrTradeModel.php b/app/model/StockOptionInrTradeModel.php
new file mode 100644
index 0000000..a521856
--- /dev/null
+++ b/app/model/StockOptionInrTradeModel.php
@@ -0,0 +1,171 @@
+$user_id,
+ 'status'=>1,
+ 'stock_id'=>$stock_id,
+ 'trade_type'=>$trade_type
+ ])->field('order_number,deal_price,service_cost')->select();
+ if(!empty($list)) {
+ $list_arr=$list->toArray();
+ foreach ($list_arr as $val){
+ $order_num=$val['order_number']*$val['deal_price'] ;//+ $val['service_cost'];
+ $money+=$order_num;
+ $num+=$val['order_number'];
+ }
+ }
+ return [
+ 'buy_num'=>$num,
+ 'buy_money'=>$money
+ ];
+ }
+ public static function getUserEarnestMmoney(int $user_id)
+ {
+ $num=self::where([
+ 'user_id'=>$user_id,
+ 'status'=>1
+ ])->sum('earnest_money');
+ return $num >0 ? $num:0;
+ }
+ public static function getUserTradeNum(int $user_id)
+ {
+ //查询持仓订单总成本
+ $count=self::where([
+ ['user_id','=',$user_id],
+ ['status','>',0]
+ ])->count();
+ return $count>0;
+ }
+ public static function getTradeOrderFee(int $user_id)
+ {
+ $info=self::where([
+ ['user_id','=',$user_id],
+ ['status','in',[1,3]]
+ ])->field('sum(service_cost+closing_cost) as fee')->find();
+ if(empty($info)){
+ return 0;
+ }else{
+ $info=$info->toArray();
+ return empty($info['fee']) ? 0 : $info['fee'];
+ }
+ }
+ /**
+ * 获取累计盈亏
+ */
+ public static function getTradeOrderDailyNum(int $user_id)
+ {
+ $num=0;
+ //查询持仓订单总成本
+ $list=self::where([
+ 'user_id'=>$user_id,
+ 'status'=>3
+ ])->field('order_number,closing_price,deal_price,closing_cost,service_cost,trade_type')->select();
+ if(!empty($list)) {
+ $list_arr=$list->toArray();
+ foreach ($list_arr as $val){
+ if($val['trade_type']==1){
+ $order_num=$val['order_number']*($val['closing_price']-$val['deal_price']);
+ }else{
+ $order_num=$val['order_number']*($val['deal_price']-$val['closing_price']);
+ }
+ $num+=$order_num;
+ }
+ }
+ return $num;
+ }
+ public static function getTradeList($trade_name,$num)
+ {
+ $trade_list=[];
+ $list=self::where([
+ ['status','in','1,3'],
+ ['stock_id','=',strtoupper($trade_name)]
+ ])->field('deal_price,order_number,closing_price,open_time,closing_time,status')->order('trade_id desc')->limit($num)->select();
+ if(!empty($list)) {
+ $list_arr=$list->toArray();
+ foreach ($list_arr as $val){
+ if($val['status']==1){
+ $trade_data['order_number']=$val['order_number'];
+ $trade_data['deal_price']=$val['deal_price'];
+ $trade_data['order_time']=strtotime($val['open_time'])*1000;
+ $trade_data['trade_type']=1;
+ array_push($trade_list,$trade_data);
+ }
+ if($val['status']==3){
+ $trade_data['order_number']=$val['order_number'];
+ $trade_data['deal_price']=$val['deal_price'];
+ $trade_data['order_time']=strtotime($val['open_time'])*1000;
+ $trade_data['trade_type']=1;
+ array_push($trade_list,$trade_data);
+
+ $sale_data['order_number']=$val['order_number'];
+ $sale_data['deal_price']=$val['closing_price'];
+ $sale_data['order_time']=strtotime($val['closing_time'])*1000;
+ $sale_data['trade_type']=2;
+ array_push($trade_list,$sale_data);
+
+ }
+ }
+ }
+ return $trade_list;
+ }
+
+ // 获取 挂单 持仓的订单金额 股票价格 * 股数 之和 也就是 market_money 的和
+ public static function getAmountForMargin($user_id)
+ {
+ $trade = self::where('status', '=', '1')->where('user_id', $user_id)->field('sum(deal_price * order_number) as amount')->find();
+ if(empty($trade)){
+ return 0;
+ }
+
+ $trade = $trade->toArray();
+ return $trade['amount']?? 0;
+ }
+
+ public static function getRealFee($userId)
+ {
+ return self::where('user_id', $userId)->sum('service_cost');
+ }
+
+}
\ No newline at end of file
diff --git a/app/model/StockPricesSettingModel.php b/app/model/StockPricesSettingModel.php
new file mode 100644
index 0000000..29a4df3
--- /dev/null
+++ b/app/model/StockPricesSettingModel.php
@@ -0,0 +1,24 @@
+ 'SGX',
+ ];
+}
\ No newline at end of file
diff --git a/app/model/StockSgdTradeModel.php b/app/model/StockSgdTradeModel.php
new file mode 100644
index 0000000..492a365
--- /dev/null
+++ b/app/model/StockSgdTradeModel.php
@@ -0,0 +1,172 @@
+$user_id,
+ 'status'=>1,
+ 'stock_id'=>$stock_id,
+ 'trade_type'=>$trade_type
+ ])->field('order_number,deal_price,service_cost')->select();
+ if(!empty($list)) {
+ $list_arr=$list->toArray();
+ foreach ($list_arr as $val){
+ $order_num=$val['order_number']*$val['deal_price'] ;//+ $val['service_cost'];
+ $money+=$order_num;
+ $num+=$val['order_number'];
+ }
+ }
+ return [
+ 'buy_num'=>$num,
+ 'buy_money'=>$money
+ ];
+ }
+ public static function getUserEarnestMmoney(int $user_id)
+ {
+ $num=self::where([
+ 'user_id'=>$user_id,
+ 'status'=>1
+ ])->sum('earnest_money');
+ return $num >0 ? $num:0;
+ }
+ public static function getUserTradeNum(int $user_id)
+ {
+ //查询持仓订单总成本
+ $count=self::where([
+ ['user_id','=',$user_id],
+ ['status','>',0]
+ ])->count();
+ return $count>0;
+ }
+
+ /**
+ * 获取累计交易手续费
+ */
+ public static function getTradeOrderFee(int $user_id)
+ {
+ $info=self::where([
+ ['user_id','=',$user_id],
+ ['status','in',[1,3]]
+ ])->field('sum(service_cost+closing_cost) as fee')->find();
+ if(empty($info)){
+ return 0;
+ }else{
+ $info=$info->toArray();
+ return empty($info['fee']) ? 0 : $info['fee'];
+ }
+ }
+ /**
+ * 获取累计盈亏
+ */
+ public static function getTradeOrderDailyNum(int $user_id)
+ {
+ $num=0;
+ //查询持仓订单总成本
+ $list=self::where([
+ 'user_id'=>$user_id,
+ 'status'=>3
+ ])->field('order_number,closing_price,deal_price,closing_cost,service_cost,trade_type')->select();
+ if(!empty($list)) {
+ $list_arr=$list->toArray();
+ foreach ($list_arr as $val){
+ if($val['trade_type']==1){
+ $order_num=$val['order_number']*($val['closing_price']-$val['deal_price']);
+ }else{
+ $order_num=$val['order_number']*($val['deal_price']-$val['closing_price']);
+ }
+ $num+=$order_num;
+ }
+ }
+ return $num;
+ }
+ public static function getTradeList($trade_name,$num)
+ {
+ $trade_list=[];
+ $list=self::where([
+ ['status','in','1,3'],
+ ['stock_id','=',strtoupper($trade_name)]
+ ])->field('deal_price,order_number,closing_price,open_time,closing_time,status')->order('trade_id desc')->limit($num)->select();
+ if(!empty($list)) {
+ $list_arr=$list->toArray();
+ foreach ($list_arr as $val){
+ if($val['status']==1){
+ $trade_data['order_number']=$val['order_number'];
+ $trade_data['deal_price']=$val['deal_price'];
+ $trade_data['order_time']=strtotime($val['open_time'])*1000;
+ $trade_data['trade_type']=1;
+ array_push($trade_list,$trade_data);
+ }
+ if($val['status']==3){
+ $trade_data['order_number']=$val['order_number'];
+ $trade_data['deal_price']=$val['deal_price'];
+ $trade_data['order_time']=strtotime($val['open_time'])*1000;
+ $trade_data['trade_type']=1;
+ array_push($trade_list,$trade_data);
+
+ $sale_data['order_number']=$val['order_number'];
+ $sale_data['deal_price']=$val['closing_price'];
+ $sale_data['order_time']=strtotime($val['closing_time'])*1000;
+ $sale_data['trade_type']=2;
+ array_push($trade_list,$sale_data);
+
+ }
+ }
+ }
+ return $trade_list;
+ }
+
+ // 获取 挂单 持仓的订单金额 股票价格 * 股数 之和 也就是 market_money 的和
+ public static function getAmountForMargin($user_id)
+ {
+ $trade = self::where('status', '=', '1')->where('user_id', $user_id)->field('sum(deal_price * order_number) as amount')->find();
+ if(empty($trade)){
+ return 0;
+ }
+
+ $trade = $trade->toArray();
+ return $trade['amount']?? 0;
+ }
+
+
+
+}
\ No newline at end of file
diff --git a/app/model/StockThaListModel.php b/app/model/StockThaListModel.php
new file mode 100644
index 0000000..a932adb
--- /dev/null
+++ b/app/model/StockThaListModel.php
@@ -0,0 +1,33 @@
+ 'SET',
+ ];
+}
\ No newline at end of file
diff --git a/app/model/StockThaTradeModel.php b/app/model/StockThaTradeModel.php
new file mode 100644
index 0000000..fb8d8e7
--- /dev/null
+++ b/app/model/StockThaTradeModel.php
@@ -0,0 +1,168 @@
+$user_id,
+ 'status'=>1,
+ 'stock_id'=>$stock_id,
+ 'trade_type'=>$trade_type
+ ])->field('order_number,deal_price,service_cost')->select();
+ if(!empty($list)) {
+ $list_arr=$list->toArray();
+ foreach ($list_arr as $val){
+ $order_num=$val['order_number']*$val['deal_price'] ;//+ $val['service_cost'];
+ $money+=$order_num;
+ $num+=$val['order_number'];
+ }
+ }
+ return [
+ 'buy_num'=>$num,
+ 'buy_money'=>$money
+ ];
+ }
+ public static function getUserEarnestMmoney(int $user_id)
+ {
+ $num=self::where([
+ 'user_id'=>$user_id,
+ 'status'=>1
+ ])->sum('earnest_money');
+ return $num >0 ? $num:0;
+ }
+ public static function getUserTradeNum(int $user_id)
+ {
+ //查询持仓订单总成本
+ $count=self::where([
+ ['user_id','=',$user_id],
+ ['status','>',0]
+ ])->count();
+ return $count>0;
+ }
+ public static function getTradeOrderFee(int $user_id)
+ {
+ $info=self::where([
+ ['user_id','=',$user_id],
+ ['status','in',[1,3]]
+ ])->field('sum(service_cost+closing_cost) as fee')->find();
+ if(empty($info)){
+ return 0;
+ }else{
+ $info=$info->toArray();
+ return empty($info['fee']) ? 0 : $info['fee'];
+ }
+ }
+ /**
+ * 获取累计盈亏
+ */
+ public static function getTradeOrderDailyNum(int $user_id)
+ {
+ $num=0;
+ //查询持仓订单总成本
+ $list=self::where([
+ 'user_id'=>$user_id,
+ 'status'=>3
+ ])->field('order_number,closing_price,deal_price,closing_cost,service_cost,trade_type')->select();
+ if(!empty($list)) {
+ $list_arr=$list->toArray();
+ foreach ($list_arr as $val){
+ if($val['trade_type']==1){
+ $order_num=$val['order_number']*($val['closing_price']-$val['deal_price']);
+ }else{
+ $order_num=$val['order_number']*($val['deal_price']-$val['closing_price']);
+ }
+ $num+=$order_num;
+ }
+ }
+ return $num;
+ }
+ public static function getTradeList($trade_name,$num)
+ {
+ $trade_list=[];
+ $list=self::where([
+ ['status','in','1,3'],
+ ['stock_id','=',strtoupper($trade_name)]
+ ])->field('deal_price,order_number,closing_price,open_time,closing_time,status')->order('trade_id desc')->limit($num)->select();
+ if(!empty($list)) {
+ $list_arr=$list->toArray();
+ foreach ($list_arr as $val){
+ if($val['status']==1){
+ $trade_data['order_number']=$val['order_number'];
+ $trade_data['deal_price']=$val['deal_price'];
+ $trade_data['order_time']=strtotime($val['open_time'])*1000;
+ $trade_data['trade_type']=1;
+ array_push($trade_list,$trade_data);
+ }
+ if($val['status']==3){
+ $trade_data['order_number']=$val['order_number'];
+ $trade_data['deal_price']=$val['deal_price'];
+ $trade_data['order_time']=strtotime($val['open_time'])*1000;
+ $trade_data['trade_type']=1;
+ array_push($trade_list,$trade_data);
+
+ $sale_data['order_number']=$val['order_number'];
+ $sale_data['deal_price']=$val['closing_price'];
+ $sale_data['order_time']=strtotime($val['closing_time'])*1000;
+ $sale_data['trade_type']=2;
+ array_push($trade_list,$sale_data);
+
+ }
+ }
+ }
+ return $trade_list;
+ }
+
+ // 获取 挂单 持仓的订单金额 股票价格 * 股数 之和 也就是 market_money 的和
+ public static function getAmountForMargin($user_id)
+ {
+ $trade = self::where('status', '=', '1')->where('user_id', $user_id)->field('sum(deal_price * order_number) as amount')->find();
+ if(empty($trade)){
+ return 0;
+ }
+
+ $trade = $trade->toArray();
+ return $trade['amount']?? 0;
+ }
+
+
+
+}
\ No newline at end of file
diff --git a/app/model/StockTradeModel.php b/app/model/StockTradeModel.php
new file mode 100644
index 0000000..69be1a5
--- /dev/null
+++ b/app/model/StockTradeModel.php
@@ -0,0 +1,168 @@
+$user_id,
+ 'status'=>1,
+ 'stock_id'=>$stock_id,
+ 'trade_type'=>$trade_type
+ ])->field('order_number,deal_price,service_cost')->select();
+ if(!empty($list)) {
+ $list_arr=$list->toArray();
+ foreach ($list_arr as $val){
+ $order_num=$val['order_number']*$val['deal_price'] ;//+ $val['service_cost'];
+ $money+=$order_num;
+ $num+=$val['order_number'];
+ }
+ }
+ return [
+ 'buy_num'=>$num,
+ 'buy_money'=>$money
+ ];
+ }
+ public static function getUserEarnestMmoney(int $user_id)
+ {
+ $num=self::where([
+ 'user_id'=>$user_id,
+ 'status'=>1
+ ])->sum('earnest_money');
+ return $num >0 ? $num:0;
+ }
+ public static function getUserTradeNum(int $user_id)
+ {
+ //查询持仓订单总成本
+ $count=self::where([
+ ['user_id','=',$user_id],
+ ['status','>',0]
+ ])->count();
+ return $count>0;
+ }
+ public static function getTradeOrderFee(int $user_id)
+ {
+ $info=self::where([
+ ['user_id','=',$user_id],
+ ['status','in',[1,3]]
+ ])->field('sum(service_cost+closing_cost) as fee')->find();
+ if(empty($info)){
+ return 0;
+ }else{
+ $info=$info->toArray();
+ return empty($info['fee']) ? 0 : $info['fee'];
+ }
+ }
+ /**
+ * 获取累计盈亏
+ */
+ public static function getTradeOrderDailyNum(int $user_id)
+ {
+ $num=0;
+ //查询持仓订单总成本
+ $list=self::where([
+ 'user_id'=>$user_id,
+ 'status'=>3
+ ])->field('order_number,closing_price,deal_price,closing_cost,service_cost,trade_type')->select();
+ if(!empty($list)) {
+ $list_arr=$list->toArray();
+ foreach ($list_arr as $val){
+ if($val['trade_type']==1){
+ $order_num=$val['order_number']*($val['closing_price']-$val['deal_price']);
+ }else{
+ $order_num=$val['order_number']*($val['deal_price']-$val['closing_price']);
+ }
+ $num+=$order_num;
+ }
+ }
+ return $num;
+ }
+ public static function getTradeList($trade_name,$num)
+ {
+ $trade_list=[];
+ $list=self::where([
+ ['status','in','1,3'],
+ ['stock_id','=',strtoupper($trade_name)]
+ ])->field('deal_price,order_number,closing_price,open_time,closing_time,status')->order('trade_id desc')->limit($num)->select();
+ if(!empty($list)) {
+ $list_arr=$list->toArray();
+ foreach ($list_arr as $val){
+ if($val['status']==1){
+ $trade_data['order_number']=$val['order_number'];
+ $trade_data['deal_price']=$val['deal_price'];
+ $trade_data['order_time']=strtotime($val['open_time'])*1000;
+ $trade_data['trade_type']=1;
+ array_push($trade_list,$trade_data);
+ }
+ if($val['status']==3){
+ $trade_data['order_number']=$val['order_number'];
+ $trade_data['deal_price']=$val['deal_price'];
+ $trade_data['order_time']=strtotime($val['open_time'])*1000;
+ $trade_data['trade_type']=1;
+ array_push($trade_list,$trade_data);
+
+ $sale_data['order_number']=$val['order_number'];
+ $sale_data['deal_price']=$val['closing_price'];
+ $sale_data['order_time']=strtotime($val['closing_time'])*1000;
+ $sale_data['trade_type']=2;
+ array_push($trade_list,$sale_data);
+
+ }
+ }
+ }
+ return $trade_list;
+ }
+
+ // 获取 挂单 持仓的订单金额 股票价格 * 股数 之和 也就是 market_money 的和
+ public static function getAmountForMargin($user_id)
+ {
+ $trade = self::where('status', '=', '1')->where('user_id', $user_id)->field('sum(deal_price * order_number) as amount')->find();
+ if(empty($trade)){
+ return 0;
+ }
+
+ $trade = $trade->toArray();
+ return $trade['amount']?? 0;
+ }
+
+
+
+}
\ No newline at end of file
diff --git a/app/model/TradeFeeModel.php b/app/model/TradeFeeModel.php
new file mode 100644
index 0000000..90a094e
--- /dev/null
+++ b/app/model/TradeFeeModel.php
@@ -0,0 +1,9 @@
+count();
+ $list = self::where('user_id', $data['user_id'])->field("id,true_name,bank_name,bank_card,bank_phone,bank_email,is_default,identity_card,ifsc")
+ ->page($data['page'],$data['page_size'])->select();
+ if(empty($list)){
+ return [];
+ }else{
+ return [
+ 'total'=>$count,
+ 'list'=>$list->toArray()
+ ];
+ }
+ }
+ public static function getUserBankInfoById(array $data,$file='*'):array
+ {
+ $info=self::where($data)->find();
+ if(empty($info)){
+ return [];
+ }else{
+ return $info->toArray();
+ }
+ }
+ public static function delUserBankById(array $data)
+ {
+ self::where([
+ 'id'=>$data['id'],
+ 'user_id'=>$data['user_id'],
+ ])->delete();
+ }
+ public static function InsertUserBank(array $data)
+ {
+ $self = new self;
+
+ if($data['is_default']==1){
+ $self::updateDefault($data['user_id']);
+ }
+ if($data['id']>0){
+ $self::where([
+ 'id'=>$data['id'],
+ 'user_id'=>$data['user_id'],
+ ])->save([
+ 'true_name'=>$data['true_name'],
+ 'identity_card'=>isset($data['identity_card']) ? $data['identity_card']:'',
+ 'bank_card'=>$data['bank_card'],
+ 'bank_name'=>$data['bank_name'],
+ 'bank_email'=>isset($data['bank_email']) ? $data['bank_email']:'',
+ 'bank_phone'=>isset($data['bank_phone']) ? $data['bank_phone']:'',
+ 'user_address'=>isset($data['user_address']) ? $data['user_address']:'',
+ 'bank_address'=>isset($data['bank_address']) ? $data['bank_address']:'',
+ 'ifsc'=>isset($data['ifsc']) ? $data['ifsc']:'',
+ 'bank_code'=>$data['bank_code'],
+ 'bank_country'=>$data['bank_country'],
+ 'is_default'=>$data['is_default'],
+ 'update_time'=>date('Y-m-d H:i:s')
+ ]);
+ }else{
+ $self->user_id = $data['user_id'];
+ $self->true_name = $data['true_name'];
+ $self->bank_card = $data['bank_card'];
+ $self->bank_name = $data['bank_name'];
+ if(isset($data['bank_email'])){
+ $self->bank_email = $data['bank_email'];
+ }
+ if(isset($data['identity_card'])){
+ $self->identity_card = $data['identity_card'];
+ }
+ if(isset($data['bank_phone'])){
+ $self->bank_phone = $data['bank_phone'];
+ }
+ if(isset($data['ifsc'])){
+ $self->ifsc = $data['ifsc'];
+ }
+ if(isset($data['bank_address'])){
+ $self->bank_address = $data['bank_address'];
+ }
+ if(isset($data['user_address'])){
+ $self->user_address = $data['user_address'];
+ }
+ $self->bank_code = $data['bank_code'];
+ $self->bank_country = $data['bank_country'];
+ $self->is_default = $data['is_default'];
+ $self->create_time = date('Y-m-d H:i:s');
+ $self->update_time = date('Y-m-d H:i:s');
+ $self->save();
+ }
+ }
+ public static function updateDefault(int $user_id){
+ self::where([
+ 'user_id'=>$user_id
+ ])->save([
+ 'is_default'=>0,
+ 'update_time'=>date('Y-m-d H:i:s')
+ ]);
+ }
+
+
+}
\ No newline at end of file
diff --git a/app/model/UserBrlGiveStockOrderModel.php b/app/model/UserBrlGiveStockOrderModel.php
new file mode 100644
index 0000000..3510198
--- /dev/null
+++ b/app/model/UserBrlGiveStockOrderModel.php
@@ -0,0 +1,26 @@
+ '申购中',
+ self::STATUS_SIGNING => '中签',//'已签名',
+ self::STATUS_SIGNED => '已上市',
+ self::STATUS_UNSIGNED => '未中签',
+ self::STATUS_POST_PAY => '申购中(待支付)',
+ self::STATUS_POST_PAY_BACK => '已上市(未支付)',
+ self::STATUS_REFUND => '订单退款',
+ self::STATUS_CLOSED => '订单关闭',
+ ];
+
+ const PAY_TYPE_ONE = 1;//正常支付
+ const PAY_TYPE_TWO = 2;//后支付
+
+ public static function getRealFee($userId)
+ {
+ return self::where('user_id', $userId)->sum('get_fee');
+ }
+}
\ No newline at end of file
diff --git a/app/model/UserBrokerageModel.php b/app/model/UserBrokerageModel.php
new file mode 100644
index 0000000..f804481
--- /dev/null
+++ b/app/model/UserBrokerageModel.php
@@ -0,0 +1,63 @@
+count();
+ if($data['page']<1){
+ $data['page']=1;
+ }
+ if($data['page_size']<1){
+ $data['page_size']=10;
+ }
+ $list = self::where($where)->field('user_id,back_type,brokerage_num,service_fee,create_time')->order('id desc')->page($data['page'],$data['page_size'])->select();
+ if(empty($list)){
+ return [];
+ }
+ $order_list=$list->toArray() ;
+
+ foreach ($order_list as $key=>$val){
+ $res=UserModel::where('user_id',$val['user_id'])->find()->toArray();
+ $order_list[$key]['user_no']=$res['user_no'];
+ }
+ return [
+ 'total'=>$count,
+ 'list'=>$order_list,
+ ];
+
+ }
+ public static function getUserBrokerageNum(array $where,string $field)
+ {
+ $num=self::where($where)->sum($field);
+ return $num;
+ }
+ public static function InsertUserBrokerage(array $data)
+ {
+ $self = new self;
+ $self->user_id = $data['user_id'];
+ $self->level_type = $data['level_type'];
+ $self->back_type = $data['back_type'];
+ $self->brokerage_num = $data['brokerage_num'];
+ $self->service_fee = $data['service_fee'];
+ $self->create_time = $data['create_time'];
+ return $self->save();
+ }
+
+
+}
\ No newline at end of file
diff --git a/app/model/UserContractLogModel.php b/app/model/UserContractLogModel.php
new file mode 100644
index 0000000..2bfd969
--- /dev/null
+++ b/app/model/UserContractLogModel.php
@@ -0,0 +1,55 @@
+count();
+ if($data['page']<1){
+ $data['page']=1;
+ }
+ if($data['page_size']<1){
+ $data['page_size']=10;
+ }
+ $list = self::where($where)->field('change_type,contract_id as name,change_num,create_time')->order('id desc')->page($data['page'],$data['page_size'])->select();
+ if(empty($list)){
+ return [];
+ }
+ return [
+ 'total'=>$count,
+ 'list'=>$list->toArray(),
+ ];
+ }
+ public static function InsertUserBalanceLog(array $data)
+ {
+ $self = new self;
+ $self->user_id = $data['user_id'];
+ $self->contract_id = $data['contract_id'];
+ $self->change_type = $data['change_type'];
+ $self->change_num = $data['change_num'];
+ if(isset($data['order_id'])){
+ $self->order_id = $data['order_id'];
+ }
+ $self->before_num = $data['before_num'];
+ $self->create_time = date('Y-m-d H:i:s');
+ $self->update_time = date('Y-m-d H:i:s');
+ return $self->save();
+ }
+
+
+
+
+}
\ No newline at end of file
diff --git a/app/model/UserContractModel.php b/app/model/UserContractModel.php
new file mode 100644
index 0000000..da075b5
--- /dev/null
+++ b/app/model/UserContractModel.php
@@ -0,0 +1,116 @@
+$data['user_id'],
+ 'contract_id'=>$contract_id
+ ])->field('usable_num,frozen_num,contract_id as name')->find();
+ if(empty($info)){
+ return [
+ 'usable_num'=>0,
+ 'frozen_num'=>0,
+ 'name'=>$contract_id
+ ];
+ }
+ return $info->toArray();
+ }
+ public static function getUserContractLock(int $user_id,string $contract_id='USDT'):array
+ {
+ $info = self::where([
+ 'user_id'=>$user_id,
+ 'contract_id'=>$contract_id
+ ])->lock(true)->find();
+ if(empty($info)){
+ $info = new self;
+ $info->user_id = $user_id;
+ $info->contract_id = $contract_id;
+ $info->usable_num = 0;
+ $info->frozen_num = 0;
+ $info->create_time = date('Y-m-d H:i:s');
+ $info->update_time = date('Y-m-d H:i:s');
+ $info->save();
+ }
+ return $info->toArray();
+ }
+ public static function getUserContractList(int $user_id):array
+ {
+ $list = self::where([
+ 'user_id'=>$user_id,
+ ])->field('usable_num,frozen_num,contract_id as name')->select();
+ if(empty($list)){
+ return [];
+ }
+ foreach ($list as $key=>$val){
+ if($val['name']=='USDT'){
+ $list[$key]['buy_up']=[
+ 'buy_num'=>0,
+ 'buy_money'=>0
+ ];
+ $list[$key]['buy_down']=[
+ 'buy_num'=>0,
+ 'buy_money'=>0
+ ];
+ }else{
+ //获取持仓成本
+ $list[$key]['buy_up']=ContractTradeModel::getTradeOrderBuyNum($user_id,$val['name'],1);
+ $list[$key]['buy_down']=ContractTradeModel::getTradeOrderBuyNum($user_id,$val['name'],2);
+ }
+
+ }
+
+ //获取平仓累计盈亏
+ $daily_num=ContractTradeModel::getTradeOrderDailyNum($user_id);
+ $earnest_money=ContractTradeModel::getUserEarnestMmoney($user_id);
+ $fee_num=ContractTradeModel::getTradeOrderFee($user_id);
+ return [
+ 'earnest_money'=>$earnest_money,//保证金
+ 'daily_num'=>$daily_num,//累计盈亏
+ 'fee_num'=>$fee_num,//累计盈亏
+ 'list'=>$list->toArray()
+ ];
+
+ }
+
+
+ public static function InsertUserContract(array $data)
+ {
+ $self = new self;
+ $self->user_id = $data['user_id'];
+ $self->contract_id = $data['contract_id'];
+ $self->usable_num = $data['usable_num'];
+ $self->frozen_num = $data['frozen_num'];
+ $self->create_time = date('Y-m-d H:i:s');
+ $self->save();
+ }
+ public static function updateUserContract(array $update_data,array $where)
+ {
+ $update_data['update_time']=date('Y-m-d H:i:s');
+ $res=self::where($where)->save($update_data);
+ //echo self::where($where)->getLastSql();
+ return $res;
+ }
+
+
+
+
+}
\ No newline at end of file
diff --git a/app/model/UserContractSecLogModel.php b/app/model/UserContractSecLogModel.php
new file mode 100644
index 0000000..4d8c1b1
--- /dev/null
+++ b/app/model/UserContractSecLogModel.php
@@ -0,0 +1,55 @@
+count();
+ if($data['page']<1){
+ $data['page']=1;
+ }
+ if($data['page_size']<1){
+ $data['page_size']=10;
+ }
+ $list = self::where($where)->field('change_type,contract_id as name,change_num,create_time')->order('id desc')->page($data['page'],$data['page_size'])->select();
+ if(empty($list)){
+ return [];
+ }
+ return [
+ 'total'=>$count,
+ 'list'=>$list->toArray(),
+ ];
+ }
+ public static function InsertUserBalanceLog(array $data)
+ {
+ $self = new self;
+ $self->user_id = $data['user_id'];
+ $self->contract_id = $data['contract_id'];
+ $self->change_type = $data['change_type'];
+ $self->change_num = $data['change_num'];
+ if(isset($data['order_id'])){
+ $self->order_id = $data['order_id'];
+ }
+ $self->before_num = $data['before_num'];
+ $self->create_time = date('Y-m-d H:i:s');
+ $self->update_time = date('Y-m-d H:i:s');
+ return $self->save();
+ }
+
+
+
+
+}
\ No newline at end of file
diff --git a/app/model/UserContractSecModel.php b/app/model/UserContractSecModel.php
new file mode 100644
index 0000000..544ef1c
--- /dev/null
+++ b/app/model/UserContractSecModel.php
@@ -0,0 +1,132 @@
+$data['user_id'],
+ 'contract_id'=>$contract_id
+ ])->field('usable_num,frozen_num,contract_id as name')->find();
+ if(empty($info)){
+ // 如果没有则创建
+ $info = new self;
+ $info->user_id = $data['user_id'];
+ $info->contract_id = $contract_id;
+ $info->usable_num = 0;
+ $info->frozen_num = 0;
+ $info->create_time = date('Y-m-d H:i:s');
+ $info->update_time = date('Y-m-d H:i:s');
+ $info->save();
+ }
+ return $info->toArray();
+ }
+ public static function getUserContractLock(int $user_id,string $contract_id='USDT'):array
+ {
+ $info = self::where([
+ 'user_id'=>$user_id,
+ 'contract_id'=>$contract_id
+ ])->lock(true)->find();
+ if(empty($info)){
+ $info = new self;
+ $info->user_id = $user_id;
+ $info->contract_id = $contract_id;
+ $info->usable_num = 0;
+ $info->frozen_num = 0;
+ $info->create_time = date('Y-m-d H:i:s');
+ $info->update_time = date('Y-m-d H:i:s');
+ $info->save();
+ }
+ return $info->toArray();
+ }
+ public static function getUserContractList(int $user_id):array
+ {
+
+ $list = self::where([
+ 'user_id'=>$user_id,
+ ])->field('usable_num,frozen_num,contract_id as name')->select();
+ if($list->isEmpty()){
+ $self = new self;
+ $self->user_id = $user_id;
+ $self->contract_id = 'USDT';
+ $self->usable_num = '0';
+ $self->frozen_num = '0';
+ $self->create_time = date('Y-m-d H:i:s');
+ $self->update_time = date('Y-m-d H:i:s');
+ $self->save();
+ $list = self::where([
+ 'user_id'=>$user_id,
+ ])->field('usable_num,frozen_num,stock_id as name')->select();
+ }
+
+ foreach ($list as $key=>$val){
+ if($val['name']=='USDT'){
+ $list[$key]['buy_up']=[
+ 'buy_num'=>0,
+ 'buy_money'=>0
+ ];
+ $list[$key]['buy_down']=[
+ 'buy_num'=>0,
+ 'buy_money'=>0
+ ];
+ }else{
+ //获取持仓成本
+ $list[$key]['buy_up']=ContractSecTradeModel::getTradeOrderBuyNum($user_id,$val['name'],1);
+ $list[$key]['buy_down']=ContractSecTradeModel::getTradeOrderBuyNum($user_id,$val['name'],2);
+ }
+
+ }
+ //获取平仓累计盈亏
+ $daily_num=ContractSecTradeModel::getTradeOrderDailyNum($user_id);
+ $earnest_money=ContractSecTradeModel::getUserEarnestMmoney($user_id);
+ $fee_num=ContractSecTradeModel::getTradeOrderFee($user_id);
+ return [
+ 'earnest_money'=>$earnest_money,//保证金
+ 'daily_num'=>$daily_num,//累计盈亏
+ 'fee_num'=>$fee_num,//累计盈亏
+ 'list'=>$list->toArray()
+ ];
+
+ }
+
+
+ public static function InsertUserContract(array $data)
+ {
+ $self = new self;
+ $self->user_id = $data['user_id'];
+ $self->contract_id = $data['contract_id'];
+ $self->usable_num = $data['usable_num'];
+ $self->frozen_num = $data['frozen_num'];
+ $self->create_time = date('Y-m-d H:i:s');
+ $self->save();
+ }
+ public static function updateUserContract(array $update_data,array $where)
+ {
+ $update_data['update_time']=date('Y-m-d H:i:s');
+ $res=self::where($where)->save($update_data);
+ //echo self::where($where)->getLastSql();
+ return $res;
+ }
+
+
+
+
+}
\ No newline at end of file
diff --git a/app/model/UserDigitalLogModel.php b/app/model/UserDigitalLogModel.php
new file mode 100644
index 0000000..23625d5
--- /dev/null
+++ b/app/model/UserDigitalLogModel.php
@@ -0,0 +1,56 @@
+count();
+ if($data['page']<1){
+ $data['page']=1;
+ }
+ if($data['page_size']<1){
+ $data['page_size']=10;
+ }
+ $list = self::where($where)->field('change_type,digital_id as name,change_num,create_time')->order('id desc')->page($data['page'],$data['page_size'])->select();
+ if(empty($list)){
+ return [];
+ }
+ return [
+ 'total'=>$count,
+ 'list'=>$list->toArray(),
+ ];
+ }
+ public static function InsertUserBalanceLog(array $data)
+ {
+ $self = new self;
+ $self->user_id = $data['user_id'];
+ $self->digital_id = $data['digital_id'];
+ $self->change_type = $data['change_type'];
+ $self->change_num = $data['change_num'];
+ if(isset($data['order_id'])){
+ $self->order_id = $data['order_id'];
+ }
+ $self->before_num = $data['before_num'];
+ $self->create_time = date('Y-m-d H:i:s');
+ $self->update_time = date('Y-m-d H:i:s');
+ return $self->save();
+ }
+
+
+
+
+}
\ No newline at end of file
diff --git a/app/model/UserDigitalModel.php b/app/model/UserDigitalModel.php
new file mode 100644
index 0000000..d87967f
--- /dev/null
+++ b/app/model/UserDigitalModel.php
@@ -0,0 +1,126 @@
+$data['user_id'],
+ 'digital_id'=>$digital_id
+ ])->field('usable_num,frozen_num,digital_id as name')->find();
+ if(empty($info)){
+ return [
+ 'usable_num'=>0,
+ 'frozen_num'=>0,
+ 'name'=>$digital_id
+ ];
+ }
+ return $info->toArray();
+ }
+ public static function getUserDigitalLock(int $user_id,string $digital_id='USDT'):array
+ {
+ $info = self::where([
+ 'user_id'=>$user_id,
+ 'digital_id'=>$digital_id
+ ])->lock(true)->find();
+ if(empty($info)){
+ $info = new self;
+ $info->user_id = $user_id;
+ $info->digital_id = $digital_id;
+ $info->usable_num = 0;
+ $info->frozen_num = 0;
+ $info->create_time = date('Y-m-d H:i:s');
+ $info->update_time = date('Y-m-d H:i:s');
+ $info->save();
+ }
+ return $info->toArray();
+ }
+ public static function getUserDigitalList(int $user_id):array
+ {
+ $list = self::where([
+ 'user_id'=>$user_id,
+ ])->field('usable_num,frozen_num,digital_id as name')->select();
+ if(empty($list)){
+ return [];
+ }
+ $digital_list=DigitalListModel::getMarketList(['page'=>1,'page_size'=>100],$type=1);
+ //print_r($digital_list);
+ foreach ($list as $key=>$val){
+ foreach ($digital_list['list'] as $item){
+ if($item['name']==$val['name']){
+ $list[$key]['logo_link']=$item['logo_link'];
+ }
+ }
+ if($val['name']!='USDT'){
+ //买入成本
+ $buy_info=DigitalTradeModel::getTradeOrderPrice($user_id,$val['name'],1);
+ if($buy_info['order_num']>0){
+ $buy_price=($buy_info['order_money']/$buy_info['order_num']);//平均买入价
+ $list[$key]['buy_price']=$buy_price;
+ }else{
+ $list[$key]['buy_price']=0;
+ }
+ //累计盈亏
+ $sale_info=DigitalTradeModel::getTradeOrderPrice($user_id,$val['name'],2);
+ if($sale_info['order_num']>0){
+ $sale_price=$sale_info['order_money']/$sale_info['order_num'];
+ $list[$key]['daily_num']=($sale_price-$buy_price)*$sale_info['order_num'];
+ }else{
+ $list[$key]['daily_num']=0;
+ }
+ }else{
+ $list[$key]['buy_price']=0;
+ $list[$key]['daily_num']=0;
+ }
+ }
+
+ //获取持仓成本
+ //$buy_num=DigitalTradeModel::getTradeOrderBuyNum($user_id);
+ //获取平仓累计盈亏
+ //$daily_num=DigitalTradeModel::getTradeOrderDailyNum($user_id);
+ $fee_num=DigitalTradeModel::getTradeOrderFee($user_id);
+ return [
+ 'fee_num'=>$fee_num,//手续费
+ 'list'=>$list->toArray()
+ ];
+ }
+
+
+ public static function InsertUserDigital(array $data)
+ {
+ $self = new self;
+ $self->user_id = $data['user_id'];
+ $self->digital_id = $data['digital_id'];
+ $self->usable_num = $data['usable_num'];
+ $self->frozen_num = $data['frozen_num'];
+ $self->create_time = date('Y-m-d H:i:s');
+ $self->save();
+ }
+ public static function updateUserDigital(array $update_data,array $where)
+ {
+ $update_data['update_time']=date('Y-m-d H:i:s');
+ $res=self::where($where)->save($update_data);
+ //echo self::where($where)->getLastSql();
+ return $res;
+ }
+
+
+
+}
\ No newline at end of file
diff --git a/app/model/UserEurGiveStockOrderModel.php b/app/model/UserEurGiveStockOrderModel.php
new file mode 100644
index 0000000..8463ff6
--- /dev/null
+++ b/app/model/UserEurGiveStockOrderModel.php
@@ -0,0 +1,26 @@
+ '申购中',
+ self::STATUS_SIGNING => '中签',//'已签名',
+ self::STATUS_SIGNED => '已上市',
+ self::STATUS_UNSIGNED => '未中签',
+ self::STATUS_POST_PAY => '申购中(待支付)',
+ self::STATUS_POST_PAY_BACK => '已上市(未支付)',
+ self::STATUS_REFUND => '订单退款',
+ self::STATUS_CLOSED => '订单关闭',
+ ];
+
+ const PAY_TYPE_ONE = 1;//正常支付
+ const PAY_TYPE_TWO = 2;//后支付
+
+ public static function getRealFee($userId)
+ {
+ return self::where('user_id', $userId)->sum('get_fee');
+ }
+}
\ No newline at end of file
diff --git a/app/model/UserForexLogModel.php b/app/model/UserForexLogModel.php
new file mode 100644
index 0000000..ac5b6ca
--- /dev/null
+++ b/app/model/UserForexLogModel.php
@@ -0,0 +1,55 @@
+count();
+ if($data['page']<1){
+ $data['page']=1;
+ }
+ if($data['page_size']<1){
+ $data['page_size']=10;
+ }
+ $list = self::where($where)->field('change_type,contract_id as name,change_num,create_time')->order('id desc')->page($data['page'],$data['page_size'])->select();
+ if(empty($list)){
+ return [];
+ }
+ return [
+ 'total'=>$count,
+ 'list'=>$list->toArray(),
+ ];
+ }
+ public static function InsertUserBalanceLog(array $data)
+ {
+ $self = new self;
+ $self->user_id = $data['user_id'];
+ $self->contract_id = $data['contract_id'];
+ $self->change_type = $data['change_type'];
+ $self->change_num = $data['change_num'];
+ if(isset($data['order_id'])){
+ $self->order_id = $data['order_id'];
+ }
+ $self->before_num = $data['before_num'];
+ $self->create_time = date('Y-m-d H:i:s');
+ $self->update_time = date('Y-m-d H:i:s');
+ return $self->save();
+ }
+
+
+
+
+}
\ No newline at end of file
diff --git a/app/model/UserForexModel.php b/app/model/UserForexModel.php
new file mode 100644
index 0000000..98b179e
--- /dev/null
+++ b/app/model/UserForexModel.php
@@ -0,0 +1,116 @@
+$data['user_id'],
+ 'contract_id'=>$contract_id
+ ])->field('usable_num,frozen_num,contract_id as name')->find();
+ if(empty($info)){
+ return [
+ 'usable_num'=>0,
+ 'frozen_num'=>0,
+ 'name'=>$contract_id
+ ];
+ }
+ return $info->toArray();
+ }
+ public static function getUserForexLock(int $user_id,string $contract_id='USD'):array
+ {
+ $info = self::where([
+ 'user_id'=>$user_id,
+ 'contract_id'=>$contract_id
+ ])->lock(true)->find();
+ if(empty($info)){
+ $info = new self;
+ $info->user_id = $user_id;
+ $info->contract_id = $contract_id;
+ $info->usable_num = 0;
+ $info->frozen_num = 0;
+ $info->create_time = date('Y-m-d H:i:s');
+ $info->update_time = date('Y-m-d H:i:s');
+ $info->save();
+ }
+ return $info->toArray();
+ }
+ public static function getUserForexList(int $user_id):array
+ {
+ $list = self::where([
+ 'user_id'=>$user_id,
+ ])->field('usable_num,frozen_num,contract_id as name')->select();
+ if(empty($list)){
+ return [];
+ }
+ foreach ($list as $key=>$val){
+ if($val['name']=='USD'){
+ $list[$key]['buy_up']=[
+ 'buy_num'=>0,
+ 'buy_money'=>0
+ ];
+ $list[$key]['buy_down']=[
+ 'buy_num'=>0,
+ 'buy_money'=>0
+ ];
+ }else{
+ //获取持仓成本
+ $list[$key]['buy_up']=ContractTradeModel::getTradeOrderBuyNum($user_id,$val['name'],1);
+ $list[$key]['buy_down']=ContractTradeModel::getTradeOrderBuyNum($user_id,$val['name'],2);
+ }
+
+ }
+
+ //获取平仓累计盈亏
+ $daily_num=ContractTradeModel::getTradeOrderDailyNum($user_id);
+ $earnest_money=ContractTradeModel::getUserEarnestMmoney($user_id);
+ $fee_num=ContractTradeModel::getTradeOrderFee($user_id);
+ return [
+ 'earnest_money'=>$earnest_money,//保证金
+ 'daily_num'=>$daily_num,//累计盈亏
+ 'fee_num'=>$fee_num,//累计盈亏
+ 'list'=>$list->toArray()
+ ];
+
+ }
+
+
+ public static function InsertUserForex(array $data)
+ {
+ $self = new self;
+ $self->user_id = $data['user_id'];
+ $self->contract_id = $data['contract_id'];
+ $self->usable_num = $data['usable_num'];
+ $self->frozen_num = $data['frozen_num'];
+ $self->create_time = date('Y-m-d H:i:s');
+ $self->save();
+ }
+ public static function updateUserForex(array $update_data,array $where)
+ {
+ $update_data['update_time']=date('Y-m-d H:i:s');
+ $res=self::where($where)->save($update_data);
+ //echo self::where($where)->getLastSql();
+ return $res;
+ }
+
+
+
+
+}
\ No newline at end of file
diff --git a/app/model/UserFundPreStockOrderModel.php b/app/model/UserFundPreStockOrderModel.php
new file mode 100644
index 0000000..f10f6bf
--- /dev/null
+++ b/app/model/UserFundPreStockOrderModel.php
@@ -0,0 +1,53 @@
+ 'Having',
+ self::STATUS_TWO => 'Returning',
+ self::STATUS_THREE => 'Over',
+ ];
+
+ public function getStatusEnTextAttr($value, $data)
+ {
+ $status = UserFundPreStockOrderModel::$statusEnList[$data['status']];
+ return $status;
+ }
+
+ public function fund()
+ {
+ return $this->hasOne(PreFundStockModel::class, 'id', 'pre_stock_id');
+ }
+
+ public function interestArr()
+ {
+ return $this->hasMany(UserStockFundInterestReceiptModel::class, 'order_id','id');
+ }
+}
\ No newline at end of file
diff --git a/app/model/UserFurGiveStockOrderModel.php b/app/model/UserFurGiveStockOrderModel.php
new file mode 100644
index 0000000..f3e78fa
--- /dev/null
+++ b/app/model/UserFurGiveStockOrderModel.php
@@ -0,0 +1,26 @@
+ '申购中',
+ self::STATUS_SIGNING => '中签',//'已签名',
+ self::STATUS_SIGNED => '已上市',
+ self::STATUS_UNSIGNED => '未中签',
+ self::STATUS_POST_PAY => '申购中(待支付)',
+ self::STATUS_POST_PAY_BACK => '已上市(未支付)',
+ self::STATUS_REFUND => '订单退款',
+ self::STATUS_CLOSED => '订单关闭',
+ ];
+
+ const PAY_TYPE_ONE = 1;//正常支付
+ const PAY_TYPE_TWO = 2;//后支付
+
+ public static function getRealFee($userId)
+ {
+ return self::where('user_id', $userId)->sum('get_fee');
+ }
+}
\ No newline at end of file
diff --git a/app/model/UserGBXGiveStockOrderModel.php b/app/model/UserGBXGiveStockOrderModel.php
new file mode 100644
index 0000000..eee6e8c
--- /dev/null
+++ b/app/model/UserGBXGiveStockOrderModel.php
@@ -0,0 +1,26 @@
+ '申购中',
+ self::STATUS_SIGNING => '中签',//'已签名',
+ self::STATUS_SIGNED => '已上市',
+ self::STATUS_UNSIGNED => '未中签',
+ self::STATUS_POST_PAY => '申购中(待支付)',
+ self::STATUS_POST_PAY_BACK => '已上市(未支付)',
+ self::STATUS_REFUND => '订单退款',
+ self::STATUS_CLOSED => '订单关闭',
+ ];
+
+ const PAY_TYPE_ONE = 1;//正常支付
+ const PAY_TYPE_TWO = 2;//后支付
+
+ public static function getRealFee($userId)
+ {
+ return self::where('user_id', $userId)->sum('get_fee');
+ }
+}
\ No newline at end of file
diff --git a/app/model/UserHkdGiveStockOrderModel.php b/app/model/UserHkdGiveStockOrderModel.php
new file mode 100644
index 0000000..76fdde9
--- /dev/null
+++ b/app/model/UserHkdGiveStockOrderModel.php
@@ -0,0 +1,26 @@
+ '申购中',
+ self::STATUS_SIGNING => '中签',//'已签名',
+ self::STATUS_SIGNED => '已上市',
+ self::STATUS_UNSIGNED => '未中签',
+ self::STATUS_POST_PAY => '申购中(待支付)',
+ self::STATUS_POST_PAY_BACK => '已上市(未支付)',
+ self::STATUS_REFUND => '订单退款',
+ self::STATUS_CLOSED => '订单关闭',
+ ];
+
+ const PAY_TYPE_ONE = 1;//正常支付
+ const PAY_TYPE_TWO = 2;//后支付
+
+ public static function getRealFee($userId)
+ {
+ return self::where('user_id', $userId)->sum('get_fee');
+ }
+}
\ No newline at end of file
diff --git a/app/model/UserIdnGiveStockOrderModel.php b/app/model/UserIdnGiveStockOrderModel.php
new file mode 100644
index 0000000..1bc63b3
--- /dev/null
+++ b/app/model/UserIdnGiveStockOrderModel.php
@@ -0,0 +1,26 @@
+ '申购中',
+ self::STATUS_SIGNING => '中签',//'已签名',
+ self::STATUS_SIGNED => '已上市',
+ self::STATUS_UNSIGNED => '未中签',
+ self::STATUS_POST_PAY => '申购中(待支付)',
+ self::STATUS_POST_PAY_BACK => '已上市(未支付)',
+ self::STATUS_REFUND => '订单退款',
+ self::STATUS_CLOSED => '订单关闭',
+ ];
+
+ const PAY_TYPE_ONE = 1;//正常支付
+ const PAY_TYPE_TWO = 2;//后支付
+
+ public static function getRealFee($userId)
+ {
+ return self::where('user_id', $userId)->sum('get_fee');
+ }
+}
\ No newline at end of file
diff --git a/app/model/UserInGiveStockOrderModel.php b/app/model/UserInGiveStockOrderModel.php
new file mode 100644
index 0000000..7ac248e
--- /dev/null
+++ b/app/model/UserInGiveStockOrderModel.php
@@ -0,0 +1,26 @@
+ '申购中',
+ self::STATUS_SIGNING => '中签',//'已签名',
+ self::STATUS_SIGNED => '已上市',
+ self::STATUS_UNSIGNED => '未中签',
+ self::STATUS_POST_PAY => '申购中(待支付)',
+ self::STATUS_POST_PAY_BACK => '已上市(未支付)',
+ self::STATUS_REFUND => '订单退款',
+ self::STATUS_CLOSED => '订单关闭',
+
+ ];
+
+ const PAY_TYPE_ONE = 1;//正常支付
+ const PAY_TYPE_TWO = 2;//后支付
+
+ public static function getRealFee($userId)
+ {
+ return self::where('user_id', $userId)->sum('get_fee');
+ }
+}
\ No newline at end of file
diff --git a/app/model/UserJpGiveStockOrderModel.php b/app/model/UserJpGiveStockOrderModel.php
new file mode 100644
index 0000000..d3c2153
--- /dev/null
+++ b/app/model/UserJpGiveStockOrderModel.php
@@ -0,0 +1,26 @@
+ '申购中',
+ self::STATUS_SIGNING => '中签',//'已签名',
+ self::STATUS_SIGNED => '已上市',
+ self::STATUS_UNSIGNED => '未中签',
+ self::STATUS_POST_PAY => '申购中(待支付)',
+ self::STATUS_POST_PAY_BACK => '已上市(未支付)',
+ self::STATUS_REFUND => '订单退款',
+ self::STATUS_CLOSED => '订单关闭',
+ ];
+
+ const PAY_TYPE_ONE = 1;//正常支付
+ const PAY_TYPE_TWO = 2;//后支付
+
+ /**
+ * 获取新股申购手续费用
+ */
+ public static function getRealFee($userId)
+ {
+ return self::where('user_id', $userId)->sum('get_fee');
+ }
+}
\ No newline at end of file
diff --git a/app/model/UserLevelModel.php b/app/model/UserLevelModel.php
new file mode 100644
index 0000000..1120798
--- /dev/null
+++ b/app/model/UserLevelModel.php
@@ -0,0 +1,115 @@
+find();
+ if(empty($info)){
+ return [];
+ }
+ return $info->toArray();
+ }
+ public static function getUserLevelList():array
+ {
+
+ $list = self::where(1)->select();
+ if(empty($list)){
+ return [];
+ }
+ return $list->toArray();
+ }
+ public static function getUserTeamList($data):array
+ {
+ if($data['page']<1){
+ $data['page']=1;
+ }
+ if($data['page_size']<1){
+ $data['page_size']=10;
+ }
+ $where=[];
+ switch ($data['level_type']){
+ case 1:
+ $where['l.parent_id']=$data['user_id'];
+ break;
+ case 2:
+ $where['l.grandpa_id']=$data['user_id'];
+ break;
+ case 3:
+ $where['l.top_id']=$data['user_id'];
+ break;
+ }
+
+ $list=Db::table('bot_user_level l')->field('l.user_id,u.user_no,u.create_time as reg_time')
+ ->leftjoin('bot_users u','u.user_id=l.user_id')
+ ->where($where)->select();
+ $count=Db::table('bot_user_level l')->field('l.user_id,u.user_no,u.create_time as reg_time')
+ ->leftjoin('bot_users u','u.user_id=l.user_id')
+ ->where($where)->count();
+ if(!empty($list)){
+ $list=$list->toArray();
+ foreach ($list as $key=>$val){
+ $list[$key]['is_pay']=RechargeApplyModel::getUserIsRecharge($val);
+ $list[$key]['is_trade']=self::getUserIsTrade($val['user_id']);
+ }
+ return [
+ 'total'=>$count,
+ 'list'=>$list,
+ ];
+ }else{
+ return [];
+ }
+ }
+ public static function getUserLevelCount(array $where){
+ $count=self::where($where)->count();
+ return $count;
+ }
+ public static function InsertUserLevel(array $data)
+ {
+ $self = new self;
+ $self->user_id = $data['user_id'];
+ $self->parent_id = $data['parent_id'];
+ $self->grandpa_id = $data['grandpa_id'];
+ $self->top_id = $data['top_id'];
+ return $self->save();
+ }
+ public static function getUserIsTrade($user_id){
+ $dig_res=DigitalTradeModel::getUserTradeNum($user_id);
+ if($dig_res){
+ return true;
+ }
+ $sto_res=StockTradeModel::getUserTradeNum($user_id);
+ if($sto_res){
+ return true;
+ }
+ $con_res=ContractTradeModel::getUserTradeNum($user_id);
+ if($con_res){
+ return true;
+ }
+ return false;
+ }
+ public static function getUsers($data)
+ {
+ $list=self::where($data)->field('user_id')->select();
+ if(!empty($list)){
+ return $list->toArray();
+ }else{
+ return [];
+ }
+
+ }
+
+
+}
\ No newline at end of file
diff --git a/app/model/UserLoginLog.php b/app/model/UserLoginLog.php
new file mode 100644
index 0000000..edb9c40
--- /dev/null
+++ b/app/model/UserLoginLog.php
@@ -0,0 +1,40 @@
+user_id = $userId;
+ $self->device = $device;
+ $self->ip = $ip;
+ $self->country = $country;
+ $self->city = $city;
+ $self->login_date = $loginDate;
+ $self->save();
+ }
+
+ public static function getLog($userId, $limit=10)
+ {
+ $list = self::where('user_id', $userId)->limit($limit)->order('id', 'desc')->select();
+ if($list->isEmpty()){
+ return [];
+ }
+ return $list->toArray();
+ }
+}
\ No newline at end of file
diff --git a/app/model/UserMarketModel.php b/app/model/UserMarketModel.php
new file mode 100644
index 0000000..1f8d9a3
--- /dev/null
+++ b/app/model/UserMarketModel.php
@@ -0,0 +1,78 @@
+0){
+ $where[]=['market_type','=',$data['market_type']];
+ }
+ if(!empty($data['trade_name'])){
+ $where[]=['trade_name','like',$data['trade_name'].'%'];
+ }
+ $count=self::where($where)->count();
+ $list = self::where($where)->field('trade_name as code,market_name as name,market_type,trade_numeric_code')->page($data['page'],$data['page_size'])->order('id desc')->select();
+ if(empty($list)){
+ return [];
+ }
+ return [
+ 'total'=>$count,
+ 'list'=>$list->toArray(),
+ ];
+ }
+ public static function checkExistMarket(array $data) : int
+ {
+ $id = self::where([
+ 'user_id'=>$data['user_id'],
+ 'market_type'=>$data['market_type'],
+ 'trade_name'=>$data['trade_name']
+ ])->value('id');
+
+ if(empty($id)){
+ return 0;
+ }else{
+ return $id;
+ }
+ }
+ public static function insertUserMarket(array $data)
+ {
+ $self = new self;
+ $self->user_id = $data['user_id'];
+ $self->trade_name = $data['trade_name'];
+ $self->trade_numeric_code = $data['trade_numeric_code'];
+ $self->market_name = $data['market_name'];
+ $self->market_type = $data['market_type'];
+ $self->create_time = date('Y-m-d H:i:s');
+ $self->save();
+ return $self->id;
+ }
+ public static function delUserMarket(int $id){
+ self::where("id",$id)->delete();
+ }
+
+
+
+}
\ No newline at end of file
diff --git a/app/model/UserModel.php b/app/model/UserModel.php
new file mode 100644
index 0000000..da9f6fb
--- /dev/null
+++ b/app/model/UserModel.php
@@ -0,0 +1,291 @@
+ '正常',
+ self::STATUS_FORBID => '禁止登录',
+ self::STATUS_BLACK => '黑名单',
+ ];
+
+ const IS_TEST_USER_NO = 1; // 正常用户
+ const IS_TEST_USER_YES = 2; // 测试用户
+
+ public static $isTestUserMap = [
+ self::IS_TEST_USER_NO => '正常用户',
+ self::IS_TEST_USER_YES => '测试用户'
+ ];
+
+ const LEVER_STATUS_NO = 1; // 未申请
+ const LEVER_STATUS_APPLY = 2; // 申请中
+ const LEVER_STATUS_PASSED = 3; // 通过
+ const LEVER_STATUS_FAIL = 4; // 拒绝
+
+ /**
+ * @desc 邮箱是否已经被注册
+ * @param $email
+ * @return bool
+ * @throws \think\db\exception\DbException
+ */
+ public static function checkEmailExists($email): bool
+ {
+ $count = self::where('email', $email)->count();
+ return $count > 0;
+ }
+
+ /**
+ * @desc 判断手机号是否已经被注册
+ * @param $phone
+ * @return bool
+ * @throws \think\db\exception\DbException
+ */
+ public static function checkPhoneExists($phone): bool
+ {
+ $count = self::where('phone_number', $phone)->count();
+ return $count > 0;
+ }
+
+ /**
+ * @desc 根据邮箱获取用户id
+ * @param $email
+ * @return int|mixed
+ */
+ public static function getUserIdByEmail($email)
+ {
+ $userId = self::where('email', $email)->value('user_id');
+ return $userId ?? 0;
+ }
+
+ /**
+ * @desc 根据用户id获取登陆密码
+ * @param $id
+ * @return mixed
+ */
+ public static function getPasswordById($id)
+ {
+ return self::where('user_id', $id)->value('login_password');
+ }
+
+ /**
+ * @desc 根据用户id获取邮箱
+ * @param $id
+ * @return mixed
+ */
+ public static function getEmailById($id)
+ {
+ return self::where('user_id', $id)->value('email');
+ }
+
+ /**
+ * @desc 根据国家码和手机号获取用户id
+ * @param $nation
+ * @param $phone
+ * @return int|mixed
+ */
+ public static function getUserIdByNationAndPhone($nation, $phone)
+ {
+ $userId = self::where('country_code', $nation)
+ ->where('phone_number', $phone)
+ ->value('user_id');
+ return $userId ?? 0;
+ }
+ /**
+ * @desc 根据用户id 查询指定字段
+ * @param $fields
+ * @param $userId
+ * @return array
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public static function getFieldsByUserId($fields, $userId): array
+ {
+ $self = self::where('user_id', $userId)->field($fields)->find();
+ if(empty($self)){
+ return [];
+ }
+ return $self->toArray();
+ }
+ /**
+ * @desc 获取邀请码用户
+ * @param $inviteCode
+ * @return array
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public static function getUserByInviteCode($inviteCode): array
+ {
+ $self = self::where('invite_code', $inviteCode)->field('user_id')->find();
+
+ if(empty($self)){
+ return [];
+ }
+ return $self->toArray();
+ }
+
+ public static function updateFieldsByUserId($fields, $userId)
+ {
+ $self = self::where('user_id', $userId)->find();
+ foreach ($fields as $key=>$value) {
+ $self->$key = $value;
+ }
+ $self->update_time = date('Y-m-d H:i:s');
+ $self->save();
+ }
+
+ /**
+ * @desc 更新登陆密码
+ * @param $password
+ * @param $userId
+ * @return void
+ */
+ public static function updatePassword($password, $salt, $userId)
+ {
+ self::update(['login_password' => $password, 'salt' => $salt], ['user_id' => $userId]);
+ }
+
+ /**
+ * @desc 邮箱用户注册
+ *
+ * @param $email
+ * @param $userNo
+ * @param $inviteCode
+ * @param $parentId
+ * @param $password
+ * @param $ip
+ * @return int
+ */
+ public static function emailRegister($email, $userNo, $inviteCode, $parentId, $password, $ip, $salt, $isTestUser, $agentId): int
+ {
+ $self = new self;
+ $self->email = $email;
+ $self->user_no = $userNo;
+ $self->invite_code = $inviteCode;
+ $self->parent_id = $parentId;
+ $self->agent_id = $agentId;
+ $self->login_password = $password;
+ $self->salt = $salt;
+ $self->reg_ip = $ip;
+ $self->is_test_user = $isTestUser;
+
+ $self->nick_name = 'user_'.explode('@', $email)[0];
+ $self->create_time = date('Y-m-d H:i:s');
+ $self->update_time = date('Y-m-d H:i:s');
+
+ // 查询父级
+ $parentIds = '';
+ $originUserId = 0;
+ if($parentId > 0){
+ $parentUser = self::where('user_id', $parentId)->findOrEmpty();
+ if($parentUser){
+ $parentIds = $parentUser['parent_ids']? $parentUser['parent_ids'].','.$parentId : $parentId;
+ // 如果祖先id = 0 说明这个父级就是祖先id
+ $originUserId = $parentUser['origin_user_id'] == 0? $parentId : $parentUser['origin_user_id'];
+ }
+ }
+
+ $self->origin_user_id = $originUserId;
+ $self->parent_ids = $parentIds;
+
+ $self->save();
+ return $self->user_id;
+ }
+
+ /**
+ * @desc 手机号注册
+ * @param $nation
+ * @param $phone
+ * @param $userNo
+ * @param $inviteCode
+ * @param $parentId
+ * @param $password
+ * @param $ip
+ * @param $salt
+ * @return int
+ */
+ public static function phoneRegister($nation, $phone, $userNo, $inviteCode, $parentId, $password, $ip, $salt, $isTestUser, $agentId): int
+ {
+ $self = new self;
+ $self->country_code = $nation;
+ $self->phone_number = $phone;
+ $self->user_no = $userNo;
+ $self->invite_code = $inviteCode;
+ $self->parent_id = $parentId;
+ $self->agent_id = $agentId;
+ $self->login_password = $password;
+ $self->salt = $salt;
+ $self->reg_ip = $ip;
+ $self->is_test_user = $isTestUser;
+
+ $name = 'user_'.substr($phone, -4);
+ $self->nick_name = $name;
+ $self->create_time = date('Y-m-d H:i:s');
+ $self->update_time = date('Y-m-d H:i:s');
+
+ // 查询父级
+ $parentIds = '';
+ $originUserId = 0;
+ if($parentId > 0){
+ $parentUser = self::where('user_id', $parentId)->findOrEmpty();
+ if($parentUser){
+ $parentIds = $parentUser['parent_ids']? $parentUser['parent_ids'].','.$parentId : $parentId;
+ // 如果祖先id = 0 说明这个父级就是祖先id
+ $originUserId = $parentUser['origin_user_id'] == 0? $parentId : $parentUser['origin_user_id'];
+ }
+ }
+
+ $self->origin_user_id = $originUserId;
+ $self->parent_ids = $parentIds;
+
+
+ $self->save();
+ return $self->user_id;
+ }
+
+ /**
+ * @desc 设置交易密码
+ * @param $password
+ * @param $salt
+ * @param $userId
+ * @return void
+ */
+ public static function setPayPassword($password, $salt, $userId)
+ {
+ self::update(['trade_password' => $password, 'salt' => $salt], ['user_id' => $userId]);
+ }
+}
\ No newline at end of file
diff --git a/app/model/UserMysGiveStockOrderModel.php b/app/model/UserMysGiveStockOrderModel.php
new file mode 100644
index 0000000..0047171
--- /dev/null
+++ b/app/model/UserMysGiveStockOrderModel.php
@@ -0,0 +1,26 @@
+ '申购中',
+ self::STATUS_SIGNING => '中签',//'已签名',
+ self::STATUS_SIGNED => '已上市',
+ self::STATUS_UNSIGNED => '未中签',
+ self::STATUS_POST_PAY => '申购中(待支付)',
+ self::STATUS_POST_PAY_BACK => '已上市(未支付)',
+ self::STATUS_REFUND => '订单退款',
+ self::STATUS_CLOSED => '订单关闭',
+ ];
+
+ const PAY_TYPE_ONE = 1;//正常支付
+ const PAY_TYPE_TWO = 2;//后支付
+
+ public static function getRealFee($userId)
+ {
+ return self::where('user_id', $userId)->sum('get_fee');
+ }
+}
\ No newline at end of file
diff --git a/app/model/UserSgdGiveStockOrderModel.php b/app/model/UserSgdGiveStockOrderModel.php
new file mode 100644
index 0000000..bdfc2bf
--- /dev/null
+++ b/app/model/UserSgdGiveStockOrderModel.php
@@ -0,0 +1,26 @@
+ '申购中',
+ self::STATUS_SIGNING => '中签',//'已签名',
+ self::STATUS_SIGNED => '已上市',
+ self::STATUS_UNSIGNED => '未中签',
+ self::STATUS_POST_PAY => '申购中(待支付)',
+ self::STATUS_POST_PAY_BACK => '已上市(未支付)',
+ self::STATUS_REFUND => '订单退款',
+ self::STATUS_CLOSED => '订单关闭',
+ ];
+
+ const PAY_TYPE_ONE = 1;//正常支付
+ const PAY_TYPE_TWO = 2;//后支付
+
+ /**
+ * 获取新股申购手续费用
+ */
+ public static function getRealFee($userId)
+ {
+ return self::where('user_id', $userId)->sum('get_fee');
+ }
+}
\ No newline at end of file
diff --git a/app/model/UserStockBlockLogModel.php b/app/model/UserStockBlockLogModel.php
new file mode 100644
index 0000000..a2e8c7a
--- /dev/null
+++ b/app/model/UserStockBlockLogModel.php
@@ -0,0 +1,54 @@
+count();
+// if($data['page']<1){
+// $data['page']=1;
+// }
+// if($data['page_size']<1){
+// $data['page_size']=10;
+// }
+// $list = self::where($where)->field('change_type,stock_id as name,change_num,create_time,order_id')->order('id desc')->page($data['page'],$data['page_size'])->select();
+// if(empty($list)){
+// return [];
+// }
+// return [
+// 'total'=>$count,
+// 'list'=>$list->toArray(),
+// ];
+// }
+ public static function InsertUserBalanceLog(array $data)
+ {
+ $self = new self;
+ $self->user_id = $data['user_id'];
+ $self->stock_id = $data['stock_id'];
+ $self->change_type = $data['change_type'];
+ $self->change_num = $data['change_num'];
+ if(isset($data['order_id'])){
+ $self->order_id = $data['order_id'];
+ }
+ $self->before_num = $data['before_num'];
+ $self->create_time = date('Y-m-d H:i:s');
+ $self->update_time = date('Y-m-d H:i:s');
+ return $self->save();
+ }
+
+}
\ No newline at end of file
diff --git a/app/model/UserStockBlockOrderModel.php b/app/model/UserStockBlockOrderModel.php
new file mode 100644
index 0000000..ba184c6
--- /dev/null
+++ b/app/model/UserStockBlockOrderModel.php
@@ -0,0 +1,52 @@
+ '挂单(委托)',
+ self::STATUS_ONE => '持仓订单',
+ self::STATUS_TWO => '已撤单',
+ self::STATUS_THREE => '完成订单',
+ ];
+
+ public static $typeList = [
+ 3 => '美股',
+ 4 => '印尼股',
+ 5 => '马股',
+ 6 => '泰股',
+ 7 => '印度股',
+ 9 => '新加坡股',
+ 12 => '港股',
+ 14 => '英股',
+ 15 => '法股',
+ 16 => '德股',
+ ];
+
+}
\ No newline at end of file
diff --git a/app/model/UserStockBrlLogModel.php b/app/model/UserStockBrlLogModel.php
new file mode 100644
index 0000000..e20395d
--- /dev/null
+++ b/app/model/UserStockBrlLogModel.php
@@ -0,0 +1,55 @@
+count();
+ if($data['page']<1){
+ $data['page']=1;
+ }
+ if($data['page_size']<1){
+ $data['page_size']=10;
+ }
+ $list = self::where($where)->field('change_type,stock_id as name,change_num,create_time,order_id')->order('id desc')->page($data['page'],$data['page_size'])->select();
+ if(empty($list)){
+ return [];
+ }
+ return [
+ 'total'=>$count,
+ 'list'=>$list->toArray(),
+ ];
+ }
+ public static function InsertUserBalanceLog(array $data)
+ {
+ $self = new self;
+ $self->user_id = $data['user_id'];
+ $self->stock_id = $data['stock_id'];
+ if(isset($data['order_id'])){
+ $self->order_id = $data['order_id'];
+ }
+ $self->change_type = $data['change_type'];
+ $self->change_num = $data['change_num'];
+ $self->before_num = $data['before_num'];
+ $self->create_time = date('Y-m-d H:i:s');
+ $self->update_time = date('Y-m-d H:i:s');
+ return $self->save();
+ }
+}
\ No newline at end of file
diff --git a/app/model/UserStockBrlModel.php b/app/model/UserStockBrlModel.php
new file mode 100644
index 0000000..377b628
--- /dev/null
+++ b/app/model/UserStockBrlModel.php
@@ -0,0 +1,135 @@
+$data['user_id'],
+ 'stock_id'=>$stock_id
+ ])->field('usable_num,frozen_num,stock_id as name')->find();
+ if(empty($info)){
+ $info = new self;
+ $info->user_id = $data['user_id'];
+ $info->stock_id = $stock_id;
+ $info->usable_num = 0;
+ $info->frozen_num = 0;
+ $info->create_time = date('Y-m-d H:i:s');
+ $info->update_time = date('Y-m-d H:i:s');
+ $info->save();
+ }
+ return $info->toArray();
+ }
+ public static function getUserStockLock(int $user_id,string $stock_id='BRL'):array
+ {
+ $info = self::where([
+ 'user_id'=>$user_id,
+ 'stock_id'=>$stock_id
+ ])->lock(true)->find();
+ if(empty($info)){
+ // 如果没有则创建
+ $info = new self;
+ $info->user_id = $user_id;
+ $info->stock_id = $stock_id;
+ $info->usable_num = 0;
+ $info->frozen_num = 0;
+ $info->create_time = date('Y-m-d H:i:s');
+ $info->update_time = date('Y-m-d H:i:s');
+ $info->save();
+ }
+ return $info->toArray();
+ }
+ public static function getUserStockList(int $user_id):array
+ {
+ $list = self::where([
+ 'user_id'=>$user_id,
+ ])->field('usable_num,frozen_num,stock_id as name')->select();
+ if($list->isEmpty()){
+ $self = new self;
+ $self->user_id = $user_id;
+ $self->stock_id = 'BRL';
+ $self->usable_num = '0';
+ $self->frozen_num = '0';
+ $self->create_time = date('Y-m-d H:i:s');
+ $self->update_time = date('Y-m-d H:i:s');
+ $self->save();
+
+ $list = self::where([
+ 'user_id'=>$user_id,
+ ])->field('usable_num,frozen_num,stock_id as name')->select();
+ }
+ foreach ($list as $key=>$val){
+ if($val['name']=='BRL'){
+ $list[$key]['buy_up']=[
+ 'buy_num'=>0,
+ 'buy_money'=>0
+ ];
+ $list[$key]['buy_down']=[
+ 'buy_num'=>0,
+ 'buy_money'=>0
+ ];
+ }else{
+ //获取持仓成本
+ $list[$key]['buy_up']=StockMysTradeModel::getTradeOrderBuyNum($user_id,$val['name'],1);
+ $list[$key]['buy_down']=StockMysTradeModel::getTradeOrderBuyNum($user_id,$val['name'],2);
+ }
+
+ }
+ //获取平仓累计盈亏
+ $daily_num=StockMysTradeModel::getTradeOrderDailyNum($user_id);
+ //$earnest_money=StockTradeModel::getUserEarnestMmoney($user_id);
+ // 保证金 挂单 和 持仓的订单金额
+// $earnest_money=StockMysTradeModel::getAmountForMargin($user_id);
+ $earnest_money=0;
+ $fee_num=StockMysTradeModel::getTradeOrderFee($user_id);
+ // 获取新股申购的手续费
+ $pre_fee = UserMysPreStockOrderModel::getRealFee($user_id);
+ return [
+ 'earnest_money'=>(float)$earnest_money,//保证金
+ 'daily_num'=>$daily_num,//累计盈亏
+ 'fee_num'=>$fee_num,//累计盈亏
+ 'pre_fee' => $pre_fee, // 新股手续费
+ 'sum_fee' => bcadd($fee_num, $pre_fee, 4),
+ 'list'=>$list->toArray()
+ ];
+ }
+
+ public static function InsertUserStock(array $data)
+ {
+ $self = new self;
+ $self->user_id = $data['user_id'];
+ $self->stock_id = $data['stock_id'];
+ $self->usable_num = $data['usable_num'];
+ $self->frozen_num = $data['frozen_num'];
+ $self->create_time = date('Y-m-d H:i:s');
+ $self->save();
+ }
+ public static function updateUserStock(array $update_data,array $where)
+ {
+ $update_data['update_time']=date('Y-m-d H:i:s');
+ $res=self::where($where)->save($update_data);
+ //echo self::where($where)->getLastSql();
+ return $res;
+ }
+
+
+
+
+}
\ No newline at end of file
diff --git a/app/model/UserStockEurLogModel.php b/app/model/UserStockEurLogModel.php
new file mode 100644
index 0000000..b4d7b61
--- /dev/null
+++ b/app/model/UserStockEurLogModel.php
@@ -0,0 +1,55 @@
+count();
+ if($data['page']<1){
+ $data['page']=1;
+ }
+ if($data['page_size']<1){
+ $data['page_size']=10;
+ }
+ $list = self::where($where)->field('change_type,stock_id as name,change_num,create_time,order_id')->order('id desc')->page($data['page'],$data['page_size'])->select();
+ if(empty($list)){
+ return [];
+ }
+ return [
+ 'total'=>$count,
+ 'list'=>$list->toArray(),
+ ];
+ }
+ public static function InsertUserBalanceLog(array $data)
+ {
+ $self = new self;
+ $self->user_id = $data['user_id'];
+ $self->stock_id = $data['stock_id'];
+ if(isset($data['order_id'])){
+ $self->order_id = $data['order_id'];
+ }
+ $self->change_type = $data['change_type'];
+ $self->change_num = $data['change_num'];
+ $self->before_num = $data['before_num'];
+ $self->create_time = date('Y-m-d H:i:s');
+ $self->update_time = date('Y-m-d H:i:s');
+ return $self->save();
+ }
+}
\ No newline at end of file
diff --git a/app/model/UserStockEurModel.php b/app/model/UserStockEurModel.php
new file mode 100644
index 0000000..7f40450
--- /dev/null
+++ b/app/model/UserStockEurModel.php
@@ -0,0 +1,135 @@
+$data['user_id'],
+ 'stock_id'=>$stock_id
+ ])->field('usable_num,frozen_num,stock_id as name')->find();
+ if(empty($info)){
+ $info = new self;
+ $info->user_id = $data['user_id'];
+ $info->stock_id = $stock_id;
+ $info->usable_num = 0;
+ $info->frozen_num = 0;
+ $info->create_time = date('Y-m-d H:i:s');
+ $info->update_time = date('Y-m-d H:i:s');
+ $info->save();
+ }
+ return $info->toArray();
+ }
+ public static function getUserStockLock(int $user_id,string $stock_id='EUR'):array
+ {
+ $info = self::where([
+ 'user_id'=>$user_id,
+ 'stock_id'=>$stock_id
+ ])->lock(true)->find();
+ if(empty($info)){
+ // 如果没有则创建
+ $info = new self;
+ $info->user_id = $user_id;
+ $info->stock_id = $stock_id;
+ $info->usable_num = 0;
+ $info->frozen_num = 0;
+ $info->create_time = date('Y-m-d H:i:s');
+ $info->update_time = date('Y-m-d H:i:s');
+ $info->save();
+ }
+ return $info->toArray();
+ }
+ public static function getUserStockList(int $user_id):array
+ {
+ $list = self::where([
+ 'user_id'=>$user_id,
+ ])->field('usable_num,frozen_num,stock_id as name')->select();
+ if($list->isEmpty()){
+ $self = new self;
+ $self->user_id = $user_id;
+ $self->stock_id = 'EUR';
+ $self->usable_num = '0';
+ $self->frozen_num = '0';
+ $self->create_time = date('Y-m-d H:i:s');
+ $self->update_time = date('Y-m-d H:i:s');
+ $self->save();
+
+ $list = self::where([
+ 'user_id'=>$user_id,
+ ])->field('usable_num,frozen_num,stock_id as name')->select();
+ }
+ foreach ($list as $key=>$val){
+ if($val['name']=='EUR'){
+ $list[$key]['buy_up']=[
+ 'buy_num'=>0,
+ 'buy_money'=>0
+ ];
+ $list[$key]['buy_down']=[
+ 'buy_num'=>0,
+ 'buy_money'=>0
+ ];
+ }else{
+ //获取持仓成本
+ $list[$key]['buy_up']=StockMysTradeModel::getTradeOrderBuyNum($user_id,$val['name'],1);
+ $list[$key]['buy_down']=StockMysTradeModel::getTradeOrderBuyNum($user_id,$val['name'],2);
+ }
+
+ }
+ //获取平仓累计盈亏
+ $daily_num=StockMysTradeModel::getTradeOrderDailyNum($user_id);
+ //$earnest_money=StockTradeModel::getUserEarnestMmoney($user_id);
+ // 保证金 挂单 和 持仓的订单金额
+// $earnest_money=StockMysTradeModel::getAmountForMargin($user_id);
+ $earnest_money=0;
+ $fee_num=StockMysTradeModel::getTradeOrderFee($user_id);
+ // 获取新股申购的手续费
+ $pre_fee = UserMysPreStockOrderModel::getRealFee($user_id);
+ return [
+ 'earnest_money'=>(float)$earnest_money,//保证金
+ 'daily_num'=>$daily_num,//累计盈亏
+ 'fee_num'=>$fee_num,//累计盈亏
+ 'pre_fee' => $pre_fee, // 新股手续费
+ 'sum_fee' => bcadd($fee_num, $pre_fee, 4),
+ 'list'=>$list->toArray()
+ ];
+ }
+
+ public static function InsertUserStock(array $data)
+ {
+ $self = new self;
+ $self->user_id = $data['user_id'];
+ $self->stock_id = $data['stock_id'];
+ $self->usable_num = $data['usable_num'];
+ $self->frozen_num = $data['frozen_num'];
+ $self->create_time = date('Y-m-d H:i:s');
+ $self->save();
+ }
+ public static function updateUserStock(array $update_data,array $where)
+ {
+ $update_data['update_time']=date('Y-m-d H:i:s');
+ $res=self::where($where)->save($update_data);
+ //echo self::where($where)->getLastSql();
+ return $res;
+ }
+
+
+
+
+}
\ No newline at end of file
diff --git a/app/model/UserStockFundInterestReceiptModel.php b/app/model/UserStockFundInterestReceiptModel.php
new file mode 100644
index 0000000..9ed49a4
--- /dev/null
+++ b/app/model/UserStockFundInterestReceiptModel.php
@@ -0,0 +1,24 @@
+ '待返息',
+ self::STATUS_TWO => '已结束',
+ ];
+
+ public function getStatusTextAttr($value, $data)
+ {
+ $status = UserStockFundInterestReceiptModel::$statusList[$data['status']];
+ return $status;
+ }
+}
diff --git a/app/model/UserStockFundLogModel.php b/app/model/UserStockFundLogModel.php
new file mode 100644
index 0000000..7bcca21
--- /dev/null
+++ b/app/model/UserStockFundLogModel.php
@@ -0,0 +1,56 @@
+count();
+ if($data['page']<1){
+ $data['page']=1;
+ }
+ if($data['page_size']<1){
+ $data['page_size']=10;
+ }
+ $list = self::where($where)->field('change_type,stock_id as name,change_num,create_time,order_id')->order('id desc')->page($data['page'],$data['page_size'])->select();
+
+ if(empty($list)){
+ return [];
+ }
+ return [
+ 'total'=>$count,
+ 'list'=>$list->toArray(),
+ ];
+ }
+ public static function InsertUserBalanceLog(array $data)
+ {
+ $self = new self;
+ $self->user_id = $data['user_id'];
+ $self->stock_id = $data['stock_id'];
+ $self->change_type = $data['change_type'];
+ $self->change_num = $data['change_num'];
+ if(isset($data['order_id'])){
+ $self->order_id = $data['order_id'];
+ }
+ $self->before_num = $data['before_num'];
+ $self->create_time = date('Y-m-d H:i:s');
+ $self->update_time = date('Y-m-d H:i:s');
+ return $self->save();
+ }
+
+
+
+
+}
\ No newline at end of file
diff --git a/app/model/UserStockFundModel.php b/app/model/UserStockFundModel.php
new file mode 100644
index 0000000..d81cd8f
--- /dev/null
+++ b/app/model/UserStockFundModel.php
@@ -0,0 +1,133 @@
+$data['user_id'],
+ 'stock_id'=>$stock_id
+ ])->field('usable_num,frozen_num,stock_id as name')->find();
+ if(empty($info)){
+ $info = new self;
+ $info->user_id = $data['user_id'];
+ $info->stock_id = $stock_id;
+ $info->usable_num = 0;
+ $info->frozen_num = 0;
+ $info->create_time = date('Y-m-d H:i:s');
+ $info->update_time = date('Y-m-d H:i:s');
+ $info->save();
+ }
+ return $info->toArray();
+ }
+ public static function getUserStockLock(int $user_id,string $stock_id='USD'):array
+ {
+ $info = self::where([
+ 'user_id'=>$user_id,
+ 'stock_id'=>$stock_id
+ ])->lock(true)->find();
+ if(empty($info)){
+ // 如果没有则创建
+ $info = new self;
+ $info->user_id = $user_id;
+ $info->stock_id = $stock_id;
+ $info->usable_num = 0;
+ $info->frozen_num = 0;
+ $info->create_time = date('Y-m-d H:i:s');
+ $info->update_time = date('Y-m-d H:i:s');
+ $info->save();
+ }
+ return $info->toArray();
+ }
+ public static function getUserStockList(int $user_id):array
+ {
+ $list = self::where([
+ 'user_id'=>$user_id,
+ ])->field('usable_num,frozen_num,stock_id as name')->select();
+ if($list->isEmpty()){
+ $self = new self;
+ $self->user_id = $user_id;
+ $self->stock_id = 'USD';
+ $self->usable_num = '0';
+ $self->frozen_num = '0';
+ $self->create_time = date('Y-m-d H:i:s');
+ $self->update_time = date('Y-m-d H:i:s');
+ $self->save();
+
+ $list = self::where([
+ 'user_id'=>$user_id,
+ ])->field('usable_num,frozen_num,stock_id as name')->select();
+ }
+ foreach ($list as $key=>$val){
+ if($val['name']=='USD'){
+ $list[$key]['buy_up']=[
+ 'buy_num'=>0,
+ 'buy_money'=>0
+ ];
+ $list[$key]['buy_down']=[
+ 'buy_num'=>0,
+ 'buy_money'=>0
+ ];
+ }
+
+ }
+ //获取平仓累计盈亏
+ $daily_num=0;//StockThaTradeModel::getTradeOrderDailyNum($user_id);
+ //$earnest_money=StockTradeModel::getUserEarnestMmoney($user_id);
+ // 保证金 挂单 和 持仓的订单金额
+// $earnest_money=StockThaTradeModel::getAmountForMargin($user_id);
+ $earnest_money=0;
+ $fee_num=0;//StockThaTradeModel::getTradeOrderFee($user_id);
+ // 获取新股申购的手续费
+ $pre_fee = 0;//UserThaPreStockOrderModel::getRealFee($user_id);
+ return [
+ 'earnest_money'=>(float)$earnest_money,//保证金
+ 'daily_num'=>$daily_num,//累计盈亏
+ 'fee_num'=>$fee_num,//累计盈亏
+ 'pre_fee' => $pre_fee, // 新股手续费
+ 'sum_fee' => bcadd($fee_num, $pre_fee, 4),
+ 'list'=>$list->toArray()
+ ];
+ }
+
+ public static function InsertUserStock(array $data)
+ {
+ $self = new self;
+ $self->user_id = $data['user_id'];
+ $self->stock_id = $data['stock_id'];
+ $self->usable_num = $data['usable_num'];
+ $self->frozen_num = $data['frozen_num'];
+ $self->create_time = date('Y-m-d H:i:s');
+ $self->save();
+ }
+ public static function updateUserStock(array $update_data,array $where)
+ {
+ $update_data['update_time']=date('Y-m-d H:i:s');
+ $res=self::where($where)->save($update_data);
+ //echo self::where($where)->getLastSql();
+ return $res;
+ }
+
+
+
+
+}
\ No newline at end of file
diff --git a/app/model/UserStockFurLogModel.php b/app/model/UserStockFurLogModel.php
new file mode 100644
index 0000000..80c311d
--- /dev/null
+++ b/app/model/UserStockFurLogModel.php
@@ -0,0 +1,55 @@
+count();
+ if($data['page']<1){
+ $data['page']=1;
+ }
+ if($data['page_size']<1){
+ $data['page_size']=10;
+ }
+ $list = self::where($where)->field('change_type,stock_id as name,change_num,create_time,order_id')->order('id desc')->page($data['page'],$data['page_size'])->select();
+ if(empty($list)){
+ return [];
+ }
+ return [
+ 'total'=>$count,
+ 'list'=>$list->toArray(),
+ ];
+ }
+ public static function InsertUserBalanceLog(array $data)
+ {
+ $self = new self;
+ $self->user_id = $data['user_id'];
+ $self->stock_id = $data['stock_id'];
+ if(isset($data['order_id'])){
+ $self->order_id = $data['order_id'];
+ }
+ $self->change_type = $data['change_type'];
+ $self->change_num = $data['change_num'];
+ $self->before_num = $data['before_num'];
+ $self->create_time = date('Y-m-d H:i:s');
+ $self->update_time = date('Y-m-d H:i:s');
+ return $self->save();
+ }
+}
\ No newline at end of file
diff --git a/app/model/UserStockFurModel.php b/app/model/UserStockFurModel.php
new file mode 100644
index 0000000..f3474f9
--- /dev/null
+++ b/app/model/UserStockFurModel.php
@@ -0,0 +1,135 @@
+$data['user_id'],
+ 'stock_id'=>$stock_id
+ ])->field('usable_num,frozen_num,stock_id as name')->find();
+ if(empty($info)){
+ $info = new self;
+ $info->user_id = $data['user_id'];
+ $info->stock_id = $stock_id;
+ $info->usable_num = 0;
+ $info->frozen_num = 0;
+ $info->create_time = date('Y-m-d H:i:s');
+ $info->update_time = date('Y-m-d H:i:s');
+ $info->save();
+ }
+ return $info->toArray();
+ }
+ public static function getUserStockLock(int $user_id,string $stock_id='EUR'):array
+ {
+ $info = self::where([
+ 'user_id'=>$user_id,
+ 'stock_id'=>$stock_id
+ ])->lock(true)->find();
+ if(empty($info)){
+ // 如果没有则创建
+ $info = new self;
+ $info->user_id = $user_id;
+ $info->stock_id = $stock_id;
+ $info->usable_num = 0;
+ $info->frozen_num = 0;
+ $info->create_time = date('Y-m-d H:i:s');
+ $info->update_time = date('Y-m-d H:i:s');
+ $info->save();
+ }
+ return $info->toArray();
+ }
+ public static function getUserStockList(int $user_id):array
+ {
+ $list = self::where([
+ 'user_id'=>$user_id,
+ ])->field('usable_num,frozen_num,stock_id as name')->select();
+ if($list->isEmpty()){
+ $self = new self;
+ $self->user_id = $user_id;
+ $self->stock_id = 'EUR';
+ $self->usable_num = '0';
+ $self->frozen_num = '0';
+ $self->create_time = date('Y-m-d H:i:s');
+ $self->update_time = date('Y-m-d H:i:s');
+ $self->save();
+
+ $list = self::where([
+ 'user_id'=>$user_id,
+ ])->field('usable_num,frozen_num,stock_id as name')->select();
+ }
+ foreach ($list as $key=>$val){
+ if($val['name']=='EUR'){
+ $list[$key]['buy_up']=[
+ 'buy_num'=>0,
+ 'buy_money'=>0
+ ];
+ $list[$key]['buy_down']=[
+ 'buy_num'=>0,
+ 'buy_money'=>0
+ ];
+ }else{
+ //获取持仓成本
+ $list[$key]['buy_up']=StockMysTradeModel::getTradeOrderBuyNum($user_id,$val['name'],1);
+ $list[$key]['buy_down']=StockMysTradeModel::getTradeOrderBuyNum($user_id,$val['name'],2);
+ }
+
+ }
+ //获取平仓累计盈亏
+ $daily_num=StockMysTradeModel::getTradeOrderDailyNum($user_id);
+ //$earnest_money=StockTradeModel::getUserEarnestMmoney($user_id);
+ // 保证金 挂单 和 持仓的订单金额
+// $earnest_money=StockMysTradeModel::getAmountForMargin($user_id);
+ $earnest_money=0;
+ $fee_num=StockMysTradeModel::getTradeOrderFee($user_id);
+ // 获取新股申购的手续费
+ $pre_fee = UserMysPreStockOrderModel::getRealFee($user_id);
+ return [
+ 'earnest_money'=>(float)$earnest_money,//保证金
+ 'daily_num'=>$daily_num,//累计盈亏
+ 'fee_num'=>$fee_num,//累计盈亏
+ 'pre_fee' => $pre_fee, // 新股手续费
+ 'sum_fee' => bcadd($fee_num, $pre_fee, 4),
+ 'list'=>$list->toArray()
+ ];
+ }
+
+ public static function InsertUserStock(array $data)
+ {
+ $self = new self;
+ $self->user_id = $data['user_id'];
+ $self->stock_id = $data['stock_id'];
+ $self->usable_num = $data['usable_num'];
+ $self->frozen_num = $data['frozen_num'];
+ $self->create_time = date('Y-m-d H:i:s');
+ $self->save();
+ }
+ public static function updateUserStock(array $update_data,array $where)
+ {
+ $update_data['update_time']=date('Y-m-d H:i:s');
+ $res=self::where($where)->save($update_data);
+ //echo self::where($where)->getLastSql();
+ return $res;
+ }
+
+
+
+
+}
\ No newline at end of file
diff --git a/app/model/UserStockGBXLogModel.php b/app/model/UserStockGBXLogModel.php
new file mode 100644
index 0000000..965e448
--- /dev/null
+++ b/app/model/UserStockGBXLogModel.php
@@ -0,0 +1,55 @@
+count();
+ if($data['page']<1){
+ $data['page']=1;
+ }
+ if($data['page_size']<1){
+ $data['page_size']=10;
+ }
+ $list = self::where($where)->field('change_type,stock_id as name,change_num,create_time,order_id')->order('id desc')->page($data['page'],$data['page_size'])->select();
+ if(empty($list)){
+ return [];
+ }
+ return [
+ 'total'=>$count,
+ 'list'=>$list->toArray(),
+ ];
+ }
+ public static function InsertUserBalanceLog(array $data)
+ {
+ $self = new self;
+ $self->user_id = $data['user_id'];
+ $self->stock_id = $data['stock_id'];
+ if(isset($data['order_id'])){
+ $self->order_id = $data['order_id'];
+ }
+ $self->change_type = $data['change_type'];
+ $self->change_num = $data['change_num'];
+ $self->before_num = $data['before_num'];
+ $self->create_time = date('Y-m-d H:i:s');
+ $self->update_time = date('Y-m-d H:i:s');
+ return $self->save();
+ }
+}
\ No newline at end of file
diff --git a/app/model/UserStockGBXModel.php b/app/model/UserStockGBXModel.php
new file mode 100644
index 0000000..d46acaa
--- /dev/null
+++ b/app/model/UserStockGBXModel.php
@@ -0,0 +1,135 @@
+$data['user_id'],
+ 'stock_id'=>$stock_id
+ ])->field('usable_num,frozen_num,stock_id as name')->find();
+ if(empty($info)){
+ $info = new self;
+ $info->user_id = $data['user_id'];
+ $info->stock_id = $stock_id;
+ $info->usable_num = 0;
+ $info->frozen_num = 0;
+ $info->create_time = date('Y-m-d H:i:s');
+ $info->update_time = date('Y-m-d H:i:s');
+ $info->save();
+ }
+ return $info->toArray();
+ }
+ public static function getUserStockLock(int $user_id,string $stock_id='GBX'):array
+ {
+ $info = self::where([
+ 'user_id'=>$user_id,
+ 'stock_id'=>$stock_id
+ ])->lock(true)->find();
+ if(empty($info)){
+ // 如果没有则创建
+ $info = new self;
+ $info->user_id = $user_id;
+ $info->stock_id = $stock_id;
+ $info->usable_num = 0;
+ $info->frozen_num = 0;
+ $info->create_time = date('Y-m-d H:i:s');
+ $info->update_time = date('Y-m-d H:i:s');
+ $info->save();
+ }
+ return $info->toArray();
+ }
+ public static function getUserStockList(int $user_id):array
+ {
+ $list = self::where([
+ 'user_id'=>$user_id,
+ ])->field('usable_num,frozen_num,stock_id as name')->select();
+ if($list->isEmpty()){
+ $self = new self;
+ $self->user_id = $user_id;
+ $self->stock_id = 'GBX';
+ $self->usable_num = '0';
+ $self->frozen_num = '0';
+ $self->create_time = date('Y-m-d H:i:s');
+ $self->update_time = date('Y-m-d H:i:s');
+ $self->save();
+
+ $list = self::where([
+ 'user_id'=>$user_id,
+ ])->field('usable_num,frozen_num,stock_id as name')->select();
+ }
+ foreach ($list as $key=>$val){
+ if($val['name']=='GBX'){
+ $list[$key]['buy_up']=[
+ 'buy_num'=>0,
+ 'buy_money'=>0
+ ];
+ $list[$key]['buy_down']=[
+ 'buy_num'=>0,
+ 'buy_money'=>0
+ ];
+ }else{
+ //获取持仓成本
+ $list[$key]['buy_up']=StockMysTradeModel::getTradeOrderBuyNum($user_id,$val['name'],1);
+ $list[$key]['buy_down']=StockMysTradeModel::getTradeOrderBuyNum($user_id,$val['name'],2);
+ }
+
+ }
+ //获取平仓累计盈亏
+ $daily_num=StockMysTradeModel::getTradeOrderDailyNum($user_id);
+ //$earnest_money=StockTradeModel::getUserEarnestMmoney($user_id);
+ // 保证金 挂单 和 持仓的订单金额
+// $earnest_money=StockMysTradeModel::getAmountForMargin($user_id);
+ $earnest_money=0;
+ $fee_num=StockMysTradeModel::getTradeOrderFee($user_id);
+ // 获取新股申购的手续费
+ $pre_fee = UserMysPreStockOrderModel::getRealFee($user_id);
+ return [
+ 'earnest_money'=>(float)$earnest_money,//保证金
+ 'daily_num'=>$daily_num,//累计盈亏
+ 'fee_num'=>$fee_num,//累计盈亏
+ 'pre_fee' => $pre_fee, // 新股手续费
+ 'sum_fee' => bcadd($fee_num, $pre_fee, 4),
+ 'list'=>$list->toArray()
+ ];
+ }
+
+ public static function InsertUserStock(array $data)
+ {
+ $self = new self;
+ $self->user_id = $data['user_id'];
+ $self->stock_id = $data['stock_id'];
+ $self->usable_num = $data['usable_num'];
+ $self->frozen_num = $data['frozen_num'];
+ $self->create_time = date('Y-m-d H:i:s');
+ $self->save();
+ }
+ public static function updateUserStock(array $update_data,array $where)
+ {
+ $update_data['update_time']=date('Y-m-d H:i:s');
+ $res=self::where($where)->save($update_data);
+ //echo self::where($where)->getLastSql();
+ return $res;
+ }
+
+
+
+
+}
\ No newline at end of file
diff --git a/app/model/UserStockHkdLogModel.php b/app/model/UserStockHkdLogModel.php
new file mode 100644
index 0000000..cb8c033
--- /dev/null
+++ b/app/model/UserStockHkdLogModel.php
@@ -0,0 +1,54 @@
+count();
+ if($data['page']<1){
+ $data['page']=1;
+ }
+ if($data['page_size']<1){
+ $data['page_size']=10;
+ }
+ $list = self::where($where)->field('change_type,stock_id as name,change_num,create_time,order_id')->order('id desc')->page($data['page'],$data['page_size'])->select();
+ if(empty($list)){
+ return [];
+ }
+ return [
+ 'total'=>$count,
+ 'list'=>$list->toArray(),
+ ];
+ }
+ public static function InsertUserBalanceLog(array $data)
+ {
+ $self = new self;
+ $self->user_id = $data['user_id'];
+ $self->stock_id = $data['stock_id'];
+ $self->change_type = $data['change_type'];
+ $self->change_num = $data['change_num'];
+ if(isset($data['order_id'])){
+ $self->order_id = $data['order_id'];
+ }
+ $self->before_num = $data['before_num'];
+ $self->create_time = date('Y-m-d H:i:s');
+ $self->update_time = date('Y-m-d H:i:s');
+ return $self->save();
+ }
+
+}
\ No newline at end of file
diff --git a/app/model/UserStockHkdModel.php b/app/model/UserStockHkdModel.php
new file mode 100644
index 0000000..aa5b2cd
--- /dev/null
+++ b/app/model/UserStockHkdModel.php
@@ -0,0 +1,137 @@
+$data['user_id'],
+ 'stock_id'=>$stock_id
+ ])->field('usable_num,frozen_num,stock_id as name')->find();
+ if(empty($info)){
+ $info = new self;
+ $info->user_id = $data['user_id'];
+ $info->stock_id = $stock_id;
+ $info->usable_num = 0;
+ $info->frozen_num = 0;
+ $info->create_time = date('Y-m-d H:i:s');
+ $info->update_time = date('Y-m-d H:i:s');
+ $info->save();
+ }
+ return $info->toArray();
+ }
+ public static function getUserStockLock(int $user_id,string $stock_id='HKD'):array
+ {
+ $info = self::where([
+ 'user_id'=>$user_id,
+ 'stock_id'=>$stock_id
+ ])->lock(true)->find();
+ if(empty($info)){
+ // 如果没有则创建
+ $info = new self;
+ $info->user_id = $user_id;
+ $info->stock_id = $stock_id;
+ $info->usable_num = 0;
+ $info->frozen_num = 0;
+ $info->create_time = date('Y-m-d H:i:s');
+ $info->update_time = date('Y-m-d H:i:s');
+ $info->save();
+ }
+ return $info->toArray();
+ }
+ public static function getUserStockList(int $user_id):array
+ {
+ $list = self::where([
+ 'user_id'=>$user_id,
+ ])->field('usable_num,frozen_num,stock_id as name')->select();
+ if($list->isEmpty()){
+ $self = new self;
+ $self->user_id = $user_id;
+ $self->stock_id = 'HKD';
+ $self->usable_num = '0';
+ $self->frozen_num = '0';
+ $self->create_time = date('Y-m-d H:i:s');
+ $self->update_time = date('Y-m-d H:i:s');
+ $self->save();
+
+ $list = self::where([
+ 'user_id'=>$user_id,
+ ])->field('usable_num,frozen_num,stock_id as name')->select();
+ }
+ foreach ($list as $key=>$val){
+ if($val['name']=='SGD'){
+ $list[$key]['buy_up']=[
+ 'buy_num'=>0,
+ 'buy_money'=>0
+ ];
+ $list[$key]['buy_down']=[
+ 'buy_num'=>0,
+ 'buy_money'=>0
+ ];
+ }else{
+ //获取持仓成本
+ $list[$key]['buy_up']=StockHkdTradeModel::getTradeOrderBuyNum($user_id,$val['name'],1);
+ $list[$key]['buy_down']=StockHkdTradeModel::getTradeOrderBuyNum($user_id,$val['name'],2);
+ }
+
+ }
+ //获取平仓累计盈亏
+ $daily_num=StockHkdTradeModel::getTradeOrderDailyNum($user_id);
+ //$earnest_money=StockIdnTradeModel::getUserEarnestMmoney($user_id);
+// $earnest_money=StockIdnTradeModel::getAmountForMargin($user_id);
+ $earnest_money=0;
+
+ $fee_num=StockHkdTradeModel::getTradeOrderFee($user_id);
+ // 获取新股申购的手续费
+ $pre_fee = UserHkdPreStockOrderModel::getRealFee($user_id);
+ return [
+ 'earnest_money'=>(float)$earnest_money,//保证金
+ 'daily_num'=>$daily_num,//累计盈亏
+ 'fee_num'=>$fee_num,//累计盈亏
+ 'pre_fee' => $pre_fee, // 新股手续费
+ 'sum_fee' => bcadd($fee_num, $pre_fee, 4),
+ 'list'=>$list->toArray()
+ ];
+ }
+
+ public static function InsertUserStock(array $data)
+ {
+ $self = new self;
+ $self->user_id = $data['user_id'];
+ $self->stock_id = $data['stock_id'];
+ $self->usable_num = $data['usable_num'];
+ $self->frozen_num = $data['frozen_num'];
+ $self->create_time = date('Y-m-d H:i:s');
+ $self->save();
+ }
+ public static function updateUserStock(array $update_data,array $where)
+ {
+ $update_data['update_time']=date('Y-m-d H:i:s');
+ $res=self::where($where)->save($update_data);
+ //echo self::where($where)->getLastSql();
+ return $res;
+ }
+
+
+
+
+}
\ No newline at end of file
diff --git a/app/model/UserStockIdnLogModel.php b/app/model/UserStockIdnLogModel.php
new file mode 100644
index 0000000..028b7dd
--- /dev/null
+++ b/app/model/UserStockIdnLogModel.php
@@ -0,0 +1,55 @@
+count();
+ if($data['page']<1){
+ $data['page']=1;
+ }
+ if($data['page_size']<1){
+ $data['page_size']=10;
+ }
+ $list = self::where($where)->field('change_type,stock_id as name,change_num,create_time,order_id')->order('id desc')->page($data['page'],$data['page_size'])->select();
+ if(empty($list)){
+ return [];
+ }
+ return [
+ 'total'=>$count,
+ 'list'=>$list->toArray(),
+ ];
+ }
+ public static function InsertUserBalanceLog(array $data)
+ {
+ $self = new self;
+ $self->user_id = $data['user_id'];
+ $self->stock_id = $data['stock_id'];
+ if(isset($data['order_id'])){
+ $self->order_id = $data['order_id'];
+ }
+ $self->change_type = $data['change_type'];
+ $self->change_num = $data['change_num'];
+ $self->before_num = $data['before_num'];
+ $self->create_time = date('Y-m-d H:i:s');
+ $self->update_time = date('Y-m-d H:i:s');
+ return $self->save();
+ }
+}
\ No newline at end of file
diff --git a/app/model/UserStockIdnModel.php b/app/model/UserStockIdnModel.php
new file mode 100644
index 0000000..3fcbf4e
--- /dev/null
+++ b/app/model/UserStockIdnModel.php
@@ -0,0 +1,138 @@
+$data['user_id'],
+ 'stock_id'=>$stock_id
+ ])->field('usable_num,frozen_num,stock_id as name')->find();
+ if(empty($info)){
+ // 如果没有则创建
+ $info = new self;
+ $info->user_id = $data['user_id'];
+ $info->stock_id = $stock_id;
+ $info->usable_num = 0;
+ $info->frozen_num = 0;
+ $info->create_time = date('Y-m-d H:i:s');
+ $info->update_time = date('Y-m-d H:i:s');
+ $info->save();
+ }
+ return $info->toArray();
+ }
+
+ // 印尼股票
+ public static function getUserStockLock(int $user_id,string $stock_id='IDR'):array
+ {
+ $info = self::where([
+ 'user_id'=>$user_id,
+ 'stock_id'=>$stock_id
+ ])->lock(true)->find();
+ if(empty($info)){
+ // 如果没有则创建
+ $info = new self;
+ $info->user_id = $user_id;
+ $info->stock_id = $stock_id;
+ $info->usable_num = 0;
+ $info->frozen_num = 0;
+ $info->create_time = date('Y-m-d H:i:s');
+ $info->update_time = date('Y-m-d H:i:s');
+ $info->save();
+ }
+ return $info->toArray();
+ }
+
+ public static function getUserStockList(int $user_id):array
+ {
+ $list = self::where([
+ 'user_id'=>$user_id,
+ ])->field('usable_num,frozen_num,stock_id as name')->select();
+ if($list->isEmpty()){
+ $self = new self;
+ $self->user_id = $user_id;
+ $self->stock_id = 'IDR';
+ $self->usable_num = '0';
+ $self->frozen_num = '0';
+ $self->create_time = date('Y-m-d H:i:s');
+ $self->update_time = date('Y-m-d H:i:s');
+
+ $self->save();
+
+ $list = self::where([
+ 'user_id'=>$user_id,
+ ])->field('usable_num,frozen_num,stock_id as name')->select();
+ }
+ foreach ($list as $key=>$val){
+ if($val['name']=='IDR'){
+ $list[$key]['buy_up']=[
+ 'buy_num'=>0,
+ 'buy_money'=>0
+ ];
+ $list[$key]['buy_down']=[
+ 'buy_num'=>0,
+ 'buy_money'=>0
+ ];
+ }else{
+ //获取持仓成本
+ $list[$key]['buy_up']=StockIdnTradeModel::getTradeOrderBuyNum($user_id,$val['name'],1);
+ $list[$key]['buy_down']=StockIdnTradeModel::getTradeOrderBuyNum($user_id,$val['name'],2);
+ }
+
+ }
+ //获取平仓累计盈亏
+ $daily_num=StockIdnTradeModel::getTradeOrderDailyNum($user_id);
+ //$earnest_money=StockIdnTradeModel::getUserEarnestMmoney($user_id);
+// $earnest_money=StockIdnTradeModel::getAmountForMargin($user_id);
+ $earnest_money=0;
+
+ $fee_num=StockIdnTradeModel::getTradeOrderFee($user_id);
+ // 获取新股申购的手续费
+ $pre_fee = UserIdnPreStockOrderModel::getRealFee($user_id);
+ return [
+ 'earnest_money'=>(float)$earnest_money,//保证金
+ 'daily_num'=>$daily_num,//累计盈亏
+ 'fee_num'=>$fee_num,//累计盈亏
+ 'pre_fee' => $pre_fee, // 新股手续费
+ 'sum_fee' => bcadd($fee_num, $pre_fee, 4),
+ 'list'=>$list->toArray()
+ ];
+ }
+
+ public static function InsertUserStock(array $data)
+ {
+ $self = new self;
+ $self->user_id = $data['user_id'];
+ $self->stock_id = $data['stock_id'];
+ $self->usable_num = $data['usable_num'];
+ $self->frozen_num = $data['frozen_num'];
+ $self->create_time = date('Y-m-d H:i:s');
+ $self->save();
+ }
+ public static function updateUserStock(array $update_data,array $where)
+ {
+ $update_data['update_time']=date('Y-m-d H:i:s');
+ $res=self::where($where)->save($update_data);
+ //echo self::where($where)->getLastSql();
+ return $res;
+ }
+}
\ No newline at end of file
diff --git a/app/model/UserStockInLogModel.php b/app/model/UserStockInLogModel.php
new file mode 100644
index 0000000..0902a8c
--- /dev/null
+++ b/app/model/UserStockInLogModel.php
@@ -0,0 +1,57 @@
+count();
+ if($data['page']<1){
+ $data['page']=1;
+ }
+ if($data['page_size']<1){
+ $data['page_size']=10;
+ }
+ $list = self::where($where)->field('change_type,stock_id as name,change_num,create_time,order_id')->order('id desc')->page($data['page'],$data['page_size'])->select();
+ if(empty($list)){
+ return [];
+ }
+ return [
+ 'total'=>$count,
+ 'list'=>$list->toArray(),
+ ];
+ }
+ public static function InsertUserBalanceLog(array $data)
+ {
+ $self = new self;
+ $self->user_id = $data['user_id'];
+ $self->stock_id = $data['stock_id'];
+ $self->change_type = $data['change_type'];
+ $self->change_num = $data['change_num'];
+ if(isset($data['order_id'])){
+ $self->order_id = $data['order_id'];
+ }
+ $self->before_num = $data['before_num'];
+ $self->create_time = date('Y-m-d H:i:s');
+ $self->update_time = date('Y-m-d H:i:s');
+ return $self->save();
+ }
+
+
+
+
+}
\ No newline at end of file
diff --git a/app/model/UserStockInModel.php b/app/model/UserStockInModel.php
new file mode 100644
index 0000000..13fd460
--- /dev/null
+++ b/app/model/UserStockInModel.php
@@ -0,0 +1,135 @@
+$data['user_id'],
+ 'stock_id'=>$stock_id
+ ])->field('usable_num,frozen_num,stock_id as name')->find();
+ if(empty($info)){
+ $info = new self;
+ $info->user_id = $data['user_id'];
+ $info->stock_id = $stock_id;
+ $info->usable_num = 0;
+ $info->frozen_num = 0;
+ $info->create_time = date('Y-m-d H:i:s');
+ $info->update_time = date('Y-m-d H:i:s');
+ $info->save();
+ }
+ return $info->toArray();
+ }
+ public static function getUserStockLock(int $user_id,string $stock_id='INR'):array
+ {
+ $info = self::where([
+ 'user_id'=>$user_id,
+ 'stock_id'=>$stock_id
+ ])->lock(true)->find();
+ if(empty($info)){
+ // 如果没有则创建
+ $info = new self;
+ $info->user_id = $user_id;
+ $info->stock_id = $stock_id;
+ $info->usable_num = 0;
+ $info->frozen_num = 0;
+ $info->create_time = date('Y-m-d H:i:s');
+ $info->update_time = date('Y-m-d H:i:s');
+ $info->save();
+ }
+ return $info->toArray();
+ }
+ public static function getUserStockList(int $user_id):array
+ {
+ $list = self::where([
+ 'user_id'=>$user_id,
+ ])->field('usable_num,frozen_num,stock_id as name')->select();
+ if($list->isEmpty()){
+ $self = new self;
+ $self->user_id = $user_id;
+ $self->stock_id = 'INR';
+ $self->usable_num = '0';
+ $self->frozen_num = '0';
+ $self->create_time = date('Y-m-d H:i:s');
+ $self->update_time = date('Y-m-d H:i:s');
+ $self->save();
+
+ $list = self::where([
+ 'user_id'=>$user_id,
+ ])->field('usable_num,frozen_num,stock_id as name')->select();
+ }
+ foreach ($list as $key=>$val){
+ if($val['name']=='INR'){
+ $list[$key]['buy_up']=[
+ 'buy_num'=>0,
+ 'buy_money'=>0
+ ];
+ $list[$key]['buy_down']=[
+ 'buy_num'=>0,
+ 'buy_money'=>0
+ ];
+ }else{
+ //获取持仓成本
+ $list[$key]['buy_up']=StockInTradeModel::getTradeOrderBuyNum($user_id,$val['name'],1);
+ $list[$key]['buy_down']=StockInTradeModel::getTradeOrderBuyNum($user_id,$val['name'],2);
+ }
+
+ }
+ //获取平仓累计盈亏
+ $daily_num=StockInTradeModel::getTradeOrderDailyNum($user_id);
+ //$earnest_money=StockTradeModel::getUserEarnestMmoney($user_id);
+ // 保证金 挂单 和 持仓的订单金额
+// $earnest_money=StockMysTradeModel::getAmountForMargin($user_id);
+ $earnest_money=0;
+ $fee_num=StockInTradeModel::getTradeOrderFee($user_id);
+ // 获取新股申购的手续费
+ $pre_fee = UserInPreStockOrderModel::getRealFee($user_id);
+ return [
+ 'earnest_money'=>(float)$earnest_money,//保证金
+ 'daily_num'=>$daily_num,//累计盈亏
+ 'fee_num'=>$fee_num,//累计盈亏
+ 'pre_fee' => $pre_fee, // 新股手续费
+ 'sum_fee' => bcadd($fee_num, $pre_fee, 4),
+ 'list'=>$list->toArray()
+ ];
+ }
+
+ public static function InsertUserStock(array $data)
+ {
+ $self = new self;
+ $self->user_id = $data['user_id'];
+ $self->stock_id = $data['stock_id'];
+ $self->usable_num = $data['usable_num'];
+ $self->frozen_num = $data['frozen_num'];
+ $self->create_time = date('Y-m-d H:i:s');
+ $self->save();
+ }
+ public static function updateUserStock(array $update_data,array $where)
+ {
+ $update_data['update_time']=date('Y-m-d H:i:s');
+ $res=self::where($where)->save($update_data);
+ //echo self::where($where)->getLastSql();
+ return $res;
+ }
+
+
+
+
+}
\ No newline at end of file
diff --git a/app/model/UserStockJpLogModel.php b/app/model/UserStockJpLogModel.php
new file mode 100644
index 0000000..11a67c4
--- /dev/null
+++ b/app/model/UserStockJpLogModel.php
@@ -0,0 +1,56 @@
+count();
+ if($data['page']<1){
+ $data['page']=1;
+ }
+ if($data['page_size']<1){
+ $data['page_size']=10;
+ }
+ $list = self::where($where)->field('change_type,stock_id as name,change_num,create_time,order_id')->order('id desc')->page($data['page'],$data['page_size'])->select();
+
+ if(empty($list)){
+ return [];
+ }
+ return [
+ 'total'=>$count,
+ 'list'=>$list->toArray(),
+ ];
+ }
+ public static function InsertUserBalanceLog(array $data)
+ {
+ $self = new self;
+ $self->user_id = $data['user_id'];
+ $self->stock_id = $data['stock_id'];
+ $self->change_type = $data['change_type'];
+ $self->change_num = $data['change_num'];
+ if(isset($data['order_id'])){
+ $self->order_id = $data['order_id'];
+ }
+ $self->before_num = $data['before_num'];
+ $self->create_time = date('Y-m-d H:i:s');
+ $self->update_time = date('Y-m-d H:i:s');
+ return $self->save();
+ }
+
+
+
+
+}
\ No newline at end of file
diff --git a/app/model/UserStockJpModel.php b/app/model/UserStockJpModel.php
new file mode 100644
index 0000000..e144991
--- /dev/null
+++ b/app/model/UserStockJpModel.php
@@ -0,0 +1,138 @@
+$data['user_id'],
+ 'stock_id'=>$stock_id
+ ])->field('usable_num,frozen_num,stock_id as name')->find();
+ if(empty($info)){
+ // 如果没有则创建
+ $info = new self;
+ $info->user_id = $data['user_id'];
+ $info->stock_id = $stock_id;
+ $info->usable_num = 0;
+ $info->frozen_num = 0;
+ $info->create_time = date('Y-m-d H:i:s');
+ $info->update_time = date('Y-m-d H:i:s');
+ $info->save();
+ }
+ return $info->toArray();
+ }
+
+ // 印尼股票
+ public static function getUserStockLock(int $user_id,string $stock_id='JPY'):array
+ {
+ $info = self::where([
+ 'user_id'=>$user_id,
+ 'stock_id'=>$stock_id
+ ])->lock(true)->find();
+ if(empty($info)){
+ // 如果没有则创建
+ $info = new self;
+ $info->user_id = $user_id;
+ $info->stock_id = $stock_id;
+ $info->usable_num = 0;
+ $info->frozen_num = 0;
+ $info->create_time = date('Y-m-d H:i:s');
+ $info->update_time = date('Y-m-d H:i:s');
+ $info->save();
+ }
+ return $info->toArray();
+ }
+
+ public static function getUserStockList(int $user_id):array
+ {
+ $list = self::where([
+ 'user_id'=>$user_id,
+ ])->field('usable_num,frozen_num,stock_id as name')->select();
+ if($list->isEmpty()){
+ $self = new self;
+ $self->user_id = $user_id;
+ $self->stock_id = 'JPY';
+ $self->usable_num = '0';
+ $self->frozen_num = '0';
+ $self->create_time = date('Y-m-d H:i:s');
+ $self->update_time = date('Y-m-d H:i:s');
+
+ $self->save();
+
+ $list = self::where([
+ 'user_id'=>$user_id,
+ ])->field('usable_num,frozen_num,stock_id as name')->select();
+ }
+ foreach ($list as $key=>$val){
+ if($val['name']=='JOY'){
+ $list[$key]['buy_up']=[
+ 'buy_num'=>0,
+ 'buy_money'=>0
+ ];
+ $list[$key]['buy_down']=[
+ 'buy_num'=>0,
+ 'buy_money'=>0
+ ];
+ }else{
+ //获取持仓成本
+ $list[$key]['buy_up']=StockJpTradeModel::getTradeOrderBuyNum($user_id,$val['name'],1);
+ $list[$key]['buy_down']=StockJpTradeModel::getTradeOrderBuyNum($user_id,$val['name'],2);
+ }
+
+ }
+ //获取平仓累计盈亏
+ $daily_num=StockJpTradeModel::getTradeOrderDailyNum($user_id);
+ //$earnest_money=StockIdnTradeModel::getUserEarnestMmoney($user_id);
+// $earnest_money=StockIdnTradeModel::getAmountForMargin($user_id);
+ $earnest_money=0;
+
+ $fee_num=StockJpTradeModel::getTradeOrderFee($user_id);
+ // 获取新股申购的手续费
+ $pre_fee = UserJpPreStockOrderModel::getRealFee($user_id);
+ return [
+ 'earnest_money'=>(float)$earnest_money,//保证金
+ 'daily_num'=>$daily_num,//累计盈亏
+ 'fee_num'=>$fee_num,//累计盈亏
+ 'pre_fee' => $pre_fee, // 新股手续费
+ 'sum_fee' => bcadd($fee_num, $pre_fee, 4),
+ 'list'=>$list->toArray()
+ ];
+ }
+
+ public static function InsertUserStock(array $data)
+ {
+ $self = new self;
+ $self->user_id = $data['user_id'];
+ $self->stock_id = $data['stock_id'];
+ $self->usable_num = $data['usable_num'];
+ $self->frozen_num = $data['frozen_num'];
+ $self->create_time = date('Y-m-d H:i:s');
+ $self->save();
+ }
+ public static function updateUserStock(array $update_data,array $where)
+ {
+ $update_data['update_time']=date('Y-m-d H:i:s');
+ $res=self::where($where)->save($update_data);
+ //echo self::where($where)->getLastSql();
+ return $res;
+ }
+}
\ No newline at end of file
diff --git a/app/model/UserStockLogModel.php b/app/model/UserStockLogModel.php
new file mode 100644
index 0000000..04ddb6a
--- /dev/null
+++ b/app/model/UserStockLogModel.php
@@ -0,0 +1,57 @@
+count();
+ if($data['page']<1){
+ $data['page']=1;
+ }
+ if($data['page_size']<1){
+ $data['page_size']=10;
+ }
+ $list = self::where($where)->field('change_type,stock_id as name,change_num,create_time,order_id')->order('id desc')->page($data['page'],$data['page_size'])->select();
+ if(empty($list)){
+ return [];
+ }
+ return [
+ 'total'=>$count,
+ 'list'=>$list->toArray(),
+ ];
+ }
+ public static function InsertUserBalanceLog(array $data)
+ {
+ $self = new self;
+ $self->user_id = $data['user_id'];
+ $self->stock_id = $data['stock_id'];
+ $self->change_type = $data['change_type'];
+ $self->change_num = $data['change_num'];
+ if(isset($data['order_id'])){
+ $self->order_id = $data['order_id'];
+ }
+ $self->before_num = $data['before_num'];
+ $self->create_time = date('Y-m-d H:i:s');
+ $self->update_time = date('Y-m-d H:i:s');
+ return $self->save();
+ }
+
+
+
+
+}
\ No newline at end of file
diff --git a/app/model/UserStockModel.php b/app/model/UserStockModel.php
new file mode 100644
index 0000000..34e577f
--- /dev/null
+++ b/app/model/UserStockModel.php
@@ -0,0 +1,116 @@
+$data['user_id'],
+ 'stock_id'=>$stock_id
+ ])->field('usable_num,frozen_num,stock_id as name')->find();
+ if(empty($info)){
+ return [];
+ }
+ return $info->toArray();
+ }
+ public static function getUserStockLock(int $user_id,string $stock_id='USD'):array
+ {
+ $info = self::where([
+ 'user_id'=>$user_id,
+ 'stock_id'=>$stock_id
+ ])->lock(true)->find();
+ if(empty($info)){
+ $info = new self;
+ $info->user_id = $user_id;
+ $info->stock_id = $stock_id;
+ $info->usable_num = 0;
+ $info->frozen_num = 0;
+ $info->create_time = date('Y-m-d H:i:s');
+ $info->update_time = date('Y-m-d H:i:s');
+ $info->save();
+ }
+ return $info->toArray();
+ }
+ public static function getUserStockList(int $user_id):array
+ {
+ $list = self::where([
+ 'user_id'=>$user_id,
+ ])->field('usable_num,frozen_num,stock_id as name')->select();
+ if(empty($list)){
+ return [];
+ }
+ foreach ($list as $key=>$val){
+ if($val['name']=='USD'){
+ $list[$key]['buy_up']=[
+ 'buy_num'=>0,
+ 'buy_money'=>0
+ ];
+ $list[$key]['buy_down']=[
+ 'buy_num'=>0,
+ 'buy_money'=>0
+ ];
+ }else{
+ //获取持仓成本
+ $list[$key]['buy_up']=StockTradeModel::getTradeOrderBuyNum($user_id,$val['name'],1);
+ $list[$key]['buy_down']=StockTradeModel::getTradeOrderBuyNum($user_id,$val['name'],2);
+ }
+
+ }
+ //获取平仓累计盈亏
+ $daily_num=StockTradeModel::getTradeOrderDailyNum($user_id);
+ //$earnest_money=StockTradeModel::getUserEarnestMmoney($user_id);
+ // 保证金 挂单 和 持仓的订单金额
+// $earnest_money=StockTradeModel::getAmountForMargin($user_id);
+ $earnest_money=0;
+ $fee_num=StockTradeModel::getTradeOrderFee($user_id);
+ // 获取新股申购的手续费
+ $pre_fee = UserUsPreStockOrderModel::getRealFee($user_id);
+ return [
+ 'earnest_money'=>(float)$earnest_money,//保证金
+ 'daily_num'=>$daily_num,//累计盈亏
+ 'fee_num'=>$fee_num,//累计盈亏
+ 'pre_fee' => $pre_fee, // 新股手续费
+ 'sum_fee' => bcadd($fee_num, $pre_fee, 4),
+ 'list'=>$list->toArray()
+ ];
+ }
+
+ public static function InsertUserStock(array $data)
+ {
+ $self = new self;
+ $self->user_id = $data['user_id'];
+ $self->stock_id = $data['stock_id'];
+ $self->usable_num = $data['usable_num'];
+ $self->frozen_num = $data['frozen_num'];
+ $self->create_time = date('Y-m-d H:i:s');
+ $self->save();
+ }
+ public static function updateUserStock(array $update_data,array $where)
+ {
+ $update_data['update_time']=date('Y-m-d H:i:s');
+ $res=self::where($where)->save($update_data);
+ //echo self::where($where)->getLastSql();
+ return $res;
+ }
+
+
+
+
+}
\ No newline at end of file
diff --git a/app/model/UserStockMysLogModel.php b/app/model/UserStockMysLogModel.php
new file mode 100644
index 0000000..cb044f2
--- /dev/null
+++ b/app/model/UserStockMysLogModel.php
@@ -0,0 +1,57 @@
+count();
+ if($data['page']<1){
+ $data['page']=1;
+ }
+ if($data['page_size']<1){
+ $data['page_size']=10;
+ }
+ $list = self::where($where)->field('change_type,stock_id as name,change_num,create_time,order_id')->order('id desc')->page($data['page'],$data['page_size'])->select();
+ if(empty($list)){
+ return [];
+ }
+ return [
+ 'total'=>$count,
+ 'list'=>$list->toArray(),
+ ];
+ }
+ public static function InsertUserBalanceLog(array $data)
+ {
+ $self = new self;
+ $self->user_id = $data['user_id'];
+ $self->stock_id = $data['stock_id'];
+ $self->change_type = $data['change_type'];
+ $self->change_num = $data['change_num'];
+ if(isset($data['order_id'])){
+ $self->order_id = $data['order_id'];
+ }
+ $self->before_num = $data['before_num'];
+ $self->create_time = date('Y-m-d H:i:s');
+ $self->update_time = date('Y-m-d H:i:s');
+ return $self->save();
+ }
+
+
+
+
+}
\ No newline at end of file
diff --git a/app/model/UserStockMysModel.php b/app/model/UserStockMysModel.php
new file mode 100644
index 0000000..d8b269c
--- /dev/null
+++ b/app/model/UserStockMysModel.php
@@ -0,0 +1,137 @@
+$data['user_id'],
+ 'stock_id'=>$stock_id
+ ])->field('usable_num,frozen_num,stock_id as name')->find();
+ if(empty($info)){
+ $info = new self;
+ $info->user_id = $data['user_id'];
+ $info->stock_id = $stock_id;
+ $info->usable_num = 0;
+ $info->frozen_num = 0;
+ $info->create_time = date('Y-m-d H:i:s');
+ $info->update_time = date('Y-m-d H:i:s');
+ $info->save();
+ }
+ return $info->toArray();
+ }
+ public static function getUserStockLock(int $user_id,string $stock_id='MYR'):array
+ {
+ $info = self::where([
+ 'user_id'=>$user_id,
+ 'stock_id'=>$stock_id
+ ])->lock(true)->find();
+ if(empty($info)){
+ // 如果没有则创建
+ $info = new self;
+ $info->user_id = $user_id;
+ $info->stock_id = $stock_id;
+ $info->usable_num = 0;
+ $info->frozen_num = 0;
+ $info->create_time = date('Y-m-d H:i:s');
+ $info->update_time = date('Y-m-d H:i:s');
+ $info->save();
+ }
+ return $info->toArray();
+ }
+ public static function getUserStockList(int $user_id):array
+ {
+ $list = self::where([
+ 'user_id'=>$user_id,
+ ])->field('usable_num,frozen_num,stock_id as name')->select();
+ if($list->isEmpty()){
+ $self = new self;
+ $self->user_id = $user_id;
+ $self->stock_id = 'MYR';
+ $self->usable_num = '0';
+ $self->frozen_num = '0';
+ $self->create_time = date('Y-m-d H:i:s');
+ $self->update_time = date('Y-m-d H:i:s');
+ $self->save();
+
+ $list = self::where([
+ 'user_id'=>$user_id,
+ ])->field('usable_num,frozen_num,stock_id as name')->select();
+ }
+ foreach ($list as $key=>$val){
+ if($val['name']=='MYR'){
+ $list[$key]['buy_up']=[
+ 'buy_num'=>0,
+ 'buy_money'=>0
+ ];
+ $list[$key]['buy_down']=[
+ 'buy_num'=>0,
+ 'buy_money'=>0
+ ];
+ }else{
+ //获取持仓成本
+ $list[$key]['buy_up']=StockMysTradeModel::getTradeOrderBuyNum($user_id,$val['name'],1);
+ $list[$key]['buy_down']=StockMysTradeModel::getTradeOrderBuyNum($user_id,$val['name'],2);
+ }
+ $numeric_code=StockMysListModel::where('stock_code',$val['name'])->value('numeric_code');
+ $list[$key]['numeric_code']=empty($numeric_code) ? 0: $numeric_code;
+
+ }
+ //获取平仓累计盈亏
+ $daily_num=StockMysTradeModel::getTradeOrderDailyNum($user_id);
+ //$earnest_money=StockTradeModel::getUserEarnestMmoney($user_id);
+ // 保证金 挂单 和 持仓的订单金额
+// $earnest_money=StockMysTradeModel::getAmountForMargin($user_id);
+ $earnest_money=0;
+ $fee_num=StockMysTradeModel::getTradeOrderFee($user_id);
+ // 获取新股申购的手续费
+ $pre_fee = UserMysPreStockOrderModel::getRealFee($user_id);
+ return [
+ 'earnest_money'=>(float)$earnest_money,//保证金
+ 'daily_num'=>$daily_num,//累计盈亏
+ 'fee_num'=>$fee_num,//累计盈亏
+ 'pre_fee' => $pre_fee, // 新股手续费
+ 'sum_fee' => bcadd($fee_num, $pre_fee, 4),
+ 'list'=>$list->toArray()
+ ];
+ }
+
+ public static function InsertUserStock(array $data)
+ {
+ $self = new self;
+ $self->user_id = $data['user_id'];
+ $self->stock_id = $data['stock_id'];
+ $self->usable_num = $data['usable_num'];
+ $self->frozen_num = $data['frozen_num'];
+ $self->create_time = date('Y-m-d H:i:s');
+ $self->save();
+ }
+ public static function updateUserStock(array $update_data,array $where)
+ {
+ $update_data['update_time']=date('Y-m-d H:i:s');
+ $res=self::where($where)->save($update_data);
+ //echo self::where($where)->getLastSql();
+ return $res;
+ }
+
+
+
+
+}
\ No newline at end of file
diff --git a/app/model/UserStockOptionInrLogModel.php b/app/model/UserStockOptionInrLogModel.php
new file mode 100644
index 0000000..d113ce4
--- /dev/null
+++ b/app/model/UserStockOptionInrLogModel.php
@@ -0,0 +1,56 @@
+count();
+ if($data['page']<1){
+ $data['page']=1;
+ }
+ if($data['page_size']<1){
+ $data['page_size']=10;
+ }
+ $list = self::where($where)->field('change_type,stock_id as name,change_num,create_time,order_id')->order('id desc')->page($data['page'],$data['page_size'])->select();
+
+ if(empty($list)){
+ return [];
+ }
+ return [
+ 'total'=>$count,
+ 'list'=>$list->toArray(),
+ ];
+ }
+ public static function InsertUserBalanceLog(array $data)
+ {
+ $self = new self;
+ $self->user_id = $data['user_id'];
+ $self->stock_id = $data['stock_id'];
+ $self->change_type = $data['change_type'];
+ $self->change_num = $data['change_num'];
+ if(isset($data['order_id'])){
+ $self->order_id = $data['order_id'];
+ }
+ $self->before_num = $data['before_num'];
+ $self->create_time = date('Y-m-d H:i:s');
+ $self->update_time = date('Y-m-d H:i:s');
+ return $self->save();
+ }
+
+
+
+
+}
\ No newline at end of file
diff --git a/app/model/UserStockOptionInrModel.php b/app/model/UserStockOptionInrModel.php
new file mode 100644
index 0000000..5bd79be
--- /dev/null
+++ b/app/model/UserStockOptionInrModel.php
@@ -0,0 +1,138 @@
+$data['user_id'],
+ 'stock_id'=>$stock_id
+ ])->field('usable_num,frozen_num,stock_id as name')->find();
+ if(empty($info)){
+ $info = new self;
+ $info->user_id = $data['user_id'];
+ $info->stock_id = $stock_id;
+ $info->usable_num = 0;
+ $info->frozen_num = 0;
+ $info->create_time = date('Y-m-d H:i:s');
+ $info->update_time = date('Y-m-d H:i:s');
+ $info->save();
+ }
+ return $info->toArray();
+ }
+ public static function getUserStockLock(int $user_id,string $stock_id='INR'):array
+ {
+ $info = self::where([
+ 'user_id'=>$user_id,
+ 'stock_id'=>$stock_id
+ ])->lock(true)->find();
+ if(empty($info)){
+ // 如果没有则创建
+ $info = new self;
+ $info->user_id = $user_id;
+ $info->stock_id = $stock_id;
+ $info->usable_num = 0;
+ $info->frozen_num = 0;
+ $info->create_time = date('Y-m-d H:i:s');
+ $info->update_time = date('Y-m-d H:i:s');
+ $info->save();
+ }
+ return $info->toArray();
+ }
+ public static function getUserStockList(int $user_id):array
+ {
+ $list = self::where([
+ 'user_id'=>$user_id,
+ ])->field('usable_num,frozen_num,stock_id as name')->select();
+ if($list->isEmpty()){
+ $self = new self;
+ $self->user_id = $user_id;
+ $self->stock_id = 'INR';
+ $self->usable_num = '0';
+ $self->frozen_num = '0';
+ $self->create_time = date('Y-m-d H:i:s');
+ $self->update_time = date('Y-m-d H:i:s');
+ $self->save();
+
+ $list = self::where([
+ 'user_id'=>$user_id,
+ ])->field('usable_num,frozen_num,stock_id as name')->select();
+ }
+ foreach ($list as $key=>$val){
+ if($val['name']=='INR'){
+ $list[$key]['buy_up']=[
+ 'buy_num'=>0,
+ 'buy_money'=>0
+ ];
+ $list[$key]['buy_down']=[
+ 'buy_num'=>0,
+ 'buy_money'=>0
+ ];
+ }else{
+ //获取持仓成本
+ $list[$key]['buy_up']=StockOptionInrTradeModel::getTradeOrderBuyNum($user_id,$val['name'],1);
+ $list[$key]['buy_down']=StockOptionInrTradeModel::getTradeOrderBuyNum($user_id,$val['name'],2);
+ }
+
+ }
+ //获取平仓累计盈亏
+ $daily_num=StockOptionInrTradeModel::getTradeOrderDailyNum($user_id);
+ //$earnest_money=StockTradeModel::getUserEarnestMmoney($user_id);
+ // 保证金 挂单 和 持仓的订单金额
+// $earnest_money=StockThaTradeModel::getAmountForMargin($user_id);
+ $earnest_money=0;
+ // 获取新股申购的手续费
+ $fee_num=StockOptionInrTradeModel::getTradeOrderFee($user_id);
+ // 获取新股申购的手续费
+ $pre_fee = StockOptionInrTradeModel::getRealFee($user_id);
+ return [
+ 'earnest_money'=>(float)$earnest_money,//保证金
+ 'daily_num'=>$daily_num,//累计盈亏
+ 'fee_num'=>$fee_num,//累计盈亏
+ 'pre_fee' => $pre_fee, // 新股手续费
+ 'sum_fee' => bcadd($fee_num, $pre_fee, 4),
+ 'list'=>$list->toArray()
+ ];
+ }
+
+ public static function InsertUserStock(array $data)
+ {
+ $self = new self;
+ $self->user_id = $data['user_id'];
+ $self->stock_id = $data['stock_id'];
+ $self->usable_num = $data['usable_num'];
+ $self->frozen_num = $data['frozen_num'];
+ $self->create_time = date('Y-m-d H:i:s');
+ $self->save();
+ }
+ public static function updateUserStock(array $update_data,array $where)
+ {
+ $update_data['update_time']=date('Y-m-d H:i:s');
+ $res=self::where($where)->save($update_data);
+ //echo self::where($where)->getLastSql();
+ return $res;
+ }
+
+
+
+
+}
\ No newline at end of file
diff --git a/app/model/UserStockSgdLogModel.php b/app/model/UserStockSgdLogModel.php
new file mode 100644
index 0000000..44bd676
--- /dev/null
+++ b/app/model/UserStockSgdLogModel.php
@@ -0,0 +1,56 @@
+count();
+ if($data['page']<1){
+ $data['page']=1;
+ }
+ if($data['page_size']<1){
+ $data['page_size']=10;
+ }
+ $list = self::where($where)->field('change_type,stock_id as name,change_num,create_time,order_id')->order('id desc')->page($data['page'],$data['page_size'])->select();
+
+ if(empty($list)){
+ return [];
+ }
+ return [
+ 'total'=>$count,
+ 'list'=>$list->toArray(),
+ ];
+ }
+ public static function InsertUserBalanceLog(array $data)
+ {
+ $self = new self;
+ $self->user_id = $data['user_id'];
+ $self->stock_id = $data['stock_id'];
+ $self->change_type = $data['change_type'];
+ $self->change_num = $data['change_num'];
+ if(isset($data['order_id'])){
+ $self->order_id = $data['order_id'];
+ }
+ $self->before_num = $data['before_num'];
+ $self->create_time = date('Y-m-d H:i:s');
+ $self->update_time = date('Y-m-d H:i:s');
+ return $self->save();
+ }
+
+
+
+
+}
\ No newline at end of file
diff --git a/app/model/UserStockSgdModel.php b/app/model/UserStockSgdModel.php
new file mode 100644
index 0000000..7a354f8
--- /dev/null
+++ b/app/model/UserStockSgdModel.php
@@ -0,0 +1,138 @@
+$data['user_id'],
+ 'stock_id'=>$stock_id
+ ])->field('usable_num,frozen_num,stock_id as name')->find();
+ if(empty($info)){
+ // 如果没有则创建
+ $info = new self;
+ $info->user_id = $data['user_id'];
+ $info->stock_id = $stock_id;
+ $info->usable_num = 0;
+ $info->frozen_num = 0;
+ $info->create_time = date('Y-m-d H:i:s');
+ $info->update_time = date('Y-m-d H:i:s');
+ $info->save();
+ }
+ return $info->toArray();
+ }
+
+ // 印尼股票
+ public static function getUserStockLock(int $user_id,string $stock_id='SGD'):array
+ {
+ $info = self::where([
+ 'user_id'=>$user_id,
+ 'stock_id'=>$stock_id
+ ])->lock(true)->find();
+ if(empty($info)){
+ // 如果没有则创建
+ $info = new self;
+ $info->user_id = $user_id;
+ $info->stock_id = $stock_id;
+ $info->usable_num = 0;
+ $info->frozen_num = 0;
+ $info->create_time = date('Y-m-d H:i:s');
+ $info->update_time = date('Y-m-d H:i:s');
+ $info->save();
+ }
+ return $info->toArray();
+ }
+
+ public static function getUserStockList(int $user_id):array
+ {
+ $list = self::where([
+ 'user_id'=>$user_id,
+ ])->field('usable_num,frozen_num,stock_id as name')->select();
+ if($list->isEmpty()){
+ $self = new self;
+ $self->user_id = $user_id;
+ $self->stock_id = 'SGD';
+ $self->usable_num = '0';
+ $self->frozen_num = '0';
+ $self->create_time = date('Y-m-d H:i:s');
+ $self->update_time = date('Y-m-d H:i:s');
+
+ $self->save();
+
+ $list = self::where([
+ 'user_id'=>$user_id,
+ ])->field('usable_num,frozen_num,stock_id as name')->select();
+ }
+ foreach ($list as $key=>$val){
+ if($val['name']=='SGD'){
+ $list[$key]['buy_up']=[
+ 'buy_num'=>0,
+ 'buy_money'=>0
+ ];
+ $list[$key]['buy_down']=[
+ 'buy_num'=>0,
+ 'buy_money'=>0
+ ];
+ }else{
+ //获取持仓成本
+ $list[$key]['buy_up']=StockSgdTradeModel::getTradeOrderBuyNum($user_id,$val['name'],1);
+ $list[$key]['buy_down']=StockSgdTradeModel::getTradeOrderBuyNum($user_id,$val['name'],2);
+ }
+
+ }
+ //获取平仓累计盈亏
+ $daily_num=StockSgdTradeModel::getTradeOrderDailyNum($user_id);
+ //$earnest_money=StockIdnTradeModel::getUserEarnestMmoney($user_id);
+// $earnest_money=StockIdnTradeModel::getAmountForMargin($user_id);
+ $earnest_money=0;
+
+ $fee_num=StockSgdTradeModel::getTradeOrderFee($user_id);
+ // 获取新股申购的手续费
+ $pre_fee = UserSgdPreStockOrderModel::getRealFee($user_id);
+ return [
+ 'earnest_money'=>(float)$earnest_money,//保证金
+ 'daily_num'=>$daily_num,//累计盈亏
+ 'fee_num'=>$fee_num,//累计盈亏
+ 'pre_fee' => $pre_fee, // 新股手续费
+ 'sum_fee' => bcadd($fee_num, $pre_fee, 4),
+ 'list'=>$list->toArray()
+ ];
+ }
+
+ public static function InsertUserStock(array $data)
+ {
+ $self = new self;
+ $self->user_id = $data['user_id'];
+ $self->stock_id = $data['stock_id'];
+ $self->usable_num = $data['usable_num'];
+ $self->frozen_num = $data['frozen_num'];
+ $self->create_time = date('Y-m-d H:i:s');
+ $self->save();
+ }
+ public static function updateUserStock(array $update_data,array $where)
+ {
+ $update_data['update_time']=date('Y-m-d H:i:s');
+ $res=self::where($where)->save($update_data);
+ //echo self::where($where)->getLastSql();
+ return $res;
+ }
+}
\ No newline at end of file
diff --git a/app/model/UserStockThaLogModel.php b/app/model/UserStockThaLogModel.php
new file mode 100644
index 0000000..5cdcd2d
--- /dev/null
+++ b/app/model/UserStockThaLogModel.php
@@ -0,0 +1,56 @@
+count();
+ if($data['page']<1){
+ $data['page']=1;
+ }
+ if($data['page_size']<1){
+ $data['page_size']=10;
+ }
+ $list = self::where($where)->field('change_type,stock_id as name,change_num,create_time,order_id')->order('id desc')->page($data['page'],$data['page_size'])->select();
+
+ if(empty($list)){
+ return [];
+ }
+ return [
+ 'total'=>$count,
+ 'list'=>$list->toArray(),
+ ];
+ }
+ public static function InsertUserBalanceLog(array $data)
+ {
+ $self = new self;
+ $self->user_id = $data['user_id'];
+ $self->stock_id = $data['stock_id'];
+ $self->change_type = $data['change_type'];
+ $self->change_num = $data['change_num'];
+ if(isset($data['order_id'])){
+ $self->order_id = $data['order_id'];
+ }
+ $self->before_num = $data['before_num'];
+ $self->create_time = date('Y-m-d H:i:s');
+ $self->update_time = date('Y-m-d H:i:s');
+ return $self->save();
+ }
+
+
+
+
+}
\ No newline at end of file
diff --git a/app/model/UserStockThaModel.php b/app/model/UserStockThaModel.php
new file mode 100644
index 0000000..3063ae8
--- /dev/null
+++ b/app/model/UserStockThaModel.php
@@ -0,0 +1,137 @@
+$data['user_id'],
+ 'stock_id'=>$stock_id
+ ])->field('usable_num,frozen_num,stock_id as name')->find();
+ if(empty($info)){
+ $info = new self;
+ $info->user_id = $data['user_id'];
+ $info->stock_id = $stock_id;
+ $info->usable_num = 0;
+ $info->frozen_num = 0;
+ $info->create_time = date('Y-m-d H:i:s');
+ $info->update_time = date('Y-m-d H:i:s');
+ $info->save();
+ }
+ return $info->toArray();
+ }
+ public static function getUserStockLock(int $user_id,string $stock_id='THB'):array
+ {
+ $info = self::where([
+ 'user_id'=>$user_id,
+ 'stock_id'=>$stock_id
+ ])->lock(true)->find();
+ if(empty($info)){
+ // 如果没有则创建
+ $info = new self;
+ $info->user_id = $user_id;
+ $info->stock_id = $stock_id;
+ $info->usable_num = 0;
+ $info->frozen_num = 0;
+ $info->create_time = date('Y-m-d H:i:s');
+ $info->update_time = date('Y-m-d H:i:s');
+ $info->save();
+ }
+ return $info->toArray();
+ }
+ public static function getUserStockList(int $user_id):array
+ {
+ $list = self::where([
+ 'user_id'=>$user_id,
+ ])->field('usable_num,frozen_num,stock_id as name')->select();
+ if($list->isEmpty()){
+ $self = new self;
+ $self->user_id = $user_id;
+ $self->stock_id = 'THB';
+ $self->usable_num = '0';
+ $self->frozen_num = '0';
+ $self->create_time = date('Y-m-d H:i:s');
+ $self->update_time = date('Y-m-d H:i:s');
+ $self->save();
+
+ $list = self::where([
+ 'user_id'=>$user_id,
+ ])->field('usable_num,frozen_num,stock_id as name')->select();
+ }
+ foreach ($list as $key=>$val){
+ if($val['name']=='THB'){
+ $list[$key]['buy_up']=[
+ 'buy_num'=>0,
+ 'buy_money'=>0
+ ];
+ $list[$key]['buy_down']=[
+ 'buy_num'=>0,
+ 'buy_money'=>0
+ ];
+ }else{
+ //获取持仓成本
+ $list[$key]['buy_up']=StockThaTradeModel::getTradeOrderBuyNum($user_id,$val['name'],1);
+ $list[$key]['buy_down']=StockThaTradeModel::getTradeOrderBuyNum($user_id,$val['name'],2);
+ }
+
+ }
+ //获取平仓累计盈亏
+ $daily_num=StockThaTradeModel::getTradeOrderDailyNum($user_id);
+ //$earnest_money=StockTradeModel::getUserEarnestMmoney($user_id);
+ // 保证金 挂单 和 持仓的订单金额
+// $earnest_money=StockThaTradeModel::getAmountForMargin($user_id);
+ $earnest_money=0;
+ $fee_num=StockThaTradeModel::getTradeOrderFee($user_id);
+ // 获取新股申购的手续费
+ $pre_fee = UserThaPreStockOrderModel::getRealFee($user_id);
+ return [
+ 'earnest_money'=>(float)$earnest_money,//保证金
+ 'daily_num'=>$daily_num,//累计盈亏
+ 'fee_num'=>$fee_num,//累计盈亏
+ 'pre_fee' => $pre_fee, // 新股手续费
+ 'sum_fee' => bcadd($fee_num, $pre_fee, 4),
+ 'list'=>$list->toArray()
+ ];
+ }
+
+ public static function InsertUserStock(array $data)
+ {
+ $self = new self;
+ $self->user_id = $data['user_id'];
+ $self->stock_id = $data['stock_id'];
+ $self->usable_num = $data['usable_num'];
+ $self->frozen_num = $data['frozen_num'];
+ $self->create_time = date('Y-m-d H:i:s');
+ $self->save();
+ }
+ public static function updateUserStock(array $update_data,array $where)
+ {
+ $update_data['update_time']=date('Y-m-d H:i:s');
+ $res=self::where($where)->save($update_data);
+ //echo self::where($where)->getLastSql();
+ return $res;
+ }
+
+
+
+
+}
\ No newline at end of file
diff --git a/app/model/UserThaGiveStockOrderModel.php b/app/model/UserThaGiveStockOrderModel.php
new file mode 100644
index 0000000..5d41dc6
--- /dev/null
+++ b/app/model/UserThaGiveStockOrderModel.php
@@ -0,0 +1,26 @@
+ '申购中',
+ self::STATUS_SIGNING => '中签',//'已签名',
+ self::STATUS_SIGNED => '已上市',
+ self::STATUS_UNSIGNED => '未中签',
+ self::STATUS_POST_PAY => '申购中(待支付)',
+ self::STATUS_POST_PAY_BACK => '已上市(未支付)',
+ self::STATUS_REFUND => '订单退款',
+ self::STATUS_CLOSED => '订单关闭',
+ ];
+
+ const PAY_TYPE_ONE = 1;//正常支付
+ const PAY_TYPE_TWO = 2;//后支付
+
+ public static function getRealFee($userId)
+ {
+ return self::where('user_id', $userId)->sum('get_fee');
+ }
+}
\ No newline at end of file
diff --git a/app/model/UserTransferModel.php b/app/model/UserTransferModel.php
new file mode 100644
index 0000000..3205f40
--- /dev/null
+++ b/app/model/UserTransferModel.php
@@ -0,0 +1,60 @@
+count();
+ if($data['page']<1){
+ $data['page']=1;
+ }
+ if($data['page_size']<1){
+ $data['page_size']=10;
+ }
+
+ $list = self::where($where)->order('tran_id desc')->page($data['page'],$data['page_size'])->select();
+ if(empty($list)){
+ return [];
+ }
+ return [
+ 'total'=>$count,
+ 'list'=>$list->toArray(),
+ ];
+ }
+ public static function InsertUserStock(array $data)
+ {
+ $self = new self;
+ $self->user_id = $data['user_id'];
+ $self->from_account = $data['from_account'];
+ $self->to_account = $data['to_account'];
+ $self->from_num = $data['from_num'];
+ $self->to_num = $data['to_num'];
+ $self->from_account_rate = $data['from_account_rate'];
+ $self->to_account_rate = $data['to_account_rate'];
+ $self->status = $data['status'];
+ $self->order_sn = $data['order_sn'];
+ $self->create_time = date('Y-m-d H:i:s');
+ $self->update_time = date('Y-m-d H:i:s');
+ $self->save();
+ }
+
+
+
+
+}
\ No newline at end of file
diff --git a/app/model/UserUsGiveStockOrderModel.php b/app/model/UserUsGiveStockOrderModel.php
new file mode 100644
index 0000000..2979f36
--- /dev/null
+++ b/app/model/UserUsGiveStockOrderModel.php
@@ -0,0 +1,32 @@
+hasOne(UserModel::class,'user_id','user_id');
+ }
+}
\ No newline at end of file
diff --git a/app/model/UserUsPreStockOrderModel.php b/app/model/UserUsPreStockOrderModel.php
new file mode 100644
index 0000000..d4befa4
--- /dev/null
+++ b/app/model/UserUsPreStockOrderModel.php
@@ -0,0 +1,55 @@
+ '申购中',
+ self::STATUS_SIGNING => '中签',//'已签名',
+ self::STATUS_SIGNED => '已上市',
+ self::STATUS_UNSIGNED => '未中签',
+ self::STATUS_POST_PAY => '申购中(待支付)',
+ self::STATUS_POST_PAY_BACK => '已上市(未支付)',
+ self::STATUS_REFUND => '订单退款',
+ self::STATUS_CLOSED => '订单关闭',
+ ];
+
+ const PAY_TYPE_ONE = 1;//正常支付
+ const PAY_TYPE_TWO = 2;//后支付
+
+ public static function getRealFee($userId)
+ {
+ return self::where('user_id', $userId)->sum('get_fee');
+ }
+}
\ No newline at end of file
diff --git a/app/model/UserVerifyLogModel.php b/app/model/UserVerifyLogModel.php
new file mode 100644
index 0000000..6a77446
--- /dev/null
+++ b/app/model/UserVerifyLogModel.php
@@ -0,0 +1,26 @@
+count();
+ $list = self::where($where)->field("adr_id as id,user_id,wallet_type,wallet_address,is_default,remark")
+ ->page($data['page'],$data['page_size'])->select();
+ if(empty($list)){
+ return [];
+ }else{
+ return [
+ 'total'=>$count,
+ 'list'=>$list->toArray()
+ ];
+ }
+ }
+ public static function getUserWalletInfoById(array $data):array
+ {
+ $info=self::where($data)->field("adr_id as id,user_id,wallet_type,wallet_address,is_default,remark")->find();
+ if(empty($info)){
+ return [];
+ }else{
+ return $info->toArray();
+ }
+ }
+ public static function delUserWalletById(array $data)
+ {
+ self::where([
+ 'adr_id'=>$data['adr_id'],
+ 'user_id'=>$data['user_id'],
+ ])->delete();
+ }
+ public static function InsertUserWallet(array $data)
+ {
+ $self = new self;
+ if($data['adr_id']>0){
+ $self::where([
+ 'adr_id'=>$data['adr_id'],
+ 'user_id'=>$data['user_id'],
+ ])->save([
+ 'wallet_type'=>$data['wallet_type'],
+ 'wallet_address'=>$data['wallet_address'],
+ 'remark'=>$data['remark'],
+ 'is_default'=>$data['is_default'],
+ 'update_time'=>date('Y-m-d H:i:s')
+ ]);
+ }else{
+ $self->user_id = $data['user_id'];
+ $self->wallet_type = $data['wallet_type'];
+ $self->wallet_address = $data['wallet_address'];
+ $self->remark = $data['remark'];
+ $self->is_default = $data['is_default'];
+ $self->create_time = date('Y-m-d H:i:s');
+ $self->update_time = date('Y-m-d H:i:s');
+ $self->save();
+ }
+ }
+ public static function updateDefault(int $user_id){
+ self::where([
+ 'user_id'=>$user_id
+ ])->save([
+ 'is_default'=>0,
+ 'update_time'=>date('Y-m-d H:i:s')
+ ]);
+ }
+
+}
\ No newline at end of file
diff --git a/app/model/UserWithdrawalModel.php b/app/model/UserWithdrawalModel.php
new file mode 100644
index 0000000..d0796b2
--- /dev/null
+++ b/app/model/UserWithdrawalModel.php
@@ -0,0 +1,100 @@
+ '处理中',
+ self::STATUS_ONE => '已审核',
+ self::STATUS_TWO => '已拒绝',
+ self::STATUS_THREE => '支付中',
+ self::STATUS_FOUR => '支付成功',
+ self::STATUS_FIVE => '用户取消',
+ ];
+
+ public static function getUserDrawalList(array $data)
+ {
+ $where['user_id'] = $data['user_id'];
+ if ($data['account_type'] > 0) {
+ $where['account_type'] = $data['account_type'];
+ }
+ if ($data['page'] < 1) {
+ $data['page'] = 1;
+ }
+ if ($data['page_size'] < 1) {
+ $data['page_size'] = 10;
+ }
+ $count = self::where($where)->count();
+ $list = self::where($where)->field('account_type,order_no,service_fee,total_amount as apply_num,apply_type,pay_info,status,beizhu,create_time')
+ ->page($data['page'], $data['page_size'])->order('id', 'desc')->select();
+
+ if (empty($list)) {
+ return [];
+ } else {
+ return [
+ 'total' => $count,
+ 'list' => $list->toArray()
+ ];
+ }
+
+ }
+
+ public static function InsertUserDrawalLog(array $data)
+ {
+ $self = new self;
+ $self->user_id = $data['user_id'];
+ $self->order_no = $data['order_no'];
+ $self->account_type = $data['account_type'];
+ $self->service_fee = $data['service_fee'];
+ $self->apply_num = $data['apply_num'];
+ $self->apply_type = $data['apply_type'];
+ $self->pay_info = $data['pay_info'];
+ $self->status = 0;
+ $self->drawal_type = $data['drawal_type'];
+ $self->country = $data['country'];
+ $self->currency_rate = $data['currency_rate'];
+ $self->total_amount = $data['total_amount'];
+ $self->market_amount = $data['market_amount'];
+ $self->deal_admin_id = 0;
+ $self->create_time = date('Y-m-d H:i:s');
+ $self->update_time = date('Y-m-d H:i:s');
+ return $self->save();
+ }
+
+ public static function getUserDrawalInfo(array $where)
+ {
+ $info = self::where($where)->find();
+ if ($info) {
+ return $info->toArray();
+ } else {
+ return [];
+ }
+ }
+
+
+}
\ No newline at end of file
diff --git a/app/model/VoteModel.php b/app/model/VoteModel.php
new file mode 100644
index 0000000..64d2f6c
--- /dev/null
+++ b/app/model/VoteModel.php
@@ -0,0 +1,11 @@
+field('wallet_address,wallet_type')->find();
+ if(empty($list)){
+ $wallet_info=self::where([
+ 'user_id'=>0,
+ 'wallet_type'=>$data['wallet_type']
+ ])->order('id','asc')->find();
+ if($wallet_info){
+ $wallet_info=$wallet_info->toArray();
+ self::where('id',$wallet_info['id'])->update([
+ 'user_id'=>$data['user_id']
+ ]);
+ }
+ $list=$wallet_info;
+ }else{
+ $list=$list->toArray();
+ }
+ return $list;
+ }
+ public static function getUidByWallet(array $data)
+ {
+ $info=self::where($data)->find();
+ if(!empty($info)){
+ $wallet_info=$info->toArray();
+ return $wallet_info['user_id'];
+ }else{
+ return '';
+ }
+ }
+ public static function getUserWalletAddress(array $data)
+ {
+ $info=self::where($data)->find();
+ if(!empty($info)){
+ $wallet_info=$info->toArray();
+ return $wallet_info['wallet_address'];
+ }else{
+ return '';
+ }
+ }
+ public static function InsertUserWalletAddress(array $data)
+ {
+ $self = new self;
+ $self->user_id = $data['user_id'];
+ $self->wallet_address = $data['wallet_address'];
+ $self->wallet_type = $data['wallet_type'];
+ $self->create_time = date('Y-m-d H:i:s');
+ $self->save();
+ }
+
+
+
+
+}
\ No newline at end of file
diff --git a/app/provider.php b/app/provider.php
new file mode 100644
index 0000000..73d99fa
--- /dev/null
+++ b/app/provider.php
@@ -0,0 +1,9 @@
+ Request::class,
+ 'think\exception\Handle' => ExceptionHandle::class,
+];
diff --git a/app/service.php b/app/service.php
new file mode 100644
index 0000000..db1ee6a
--- /dev/null
+++ b/app/service.php
@@ -0,0 +1,9 @@
+
+
+
+
+ sorry
+
+
+There have been some issues with the service. If you need to use it, please contact customer service.
+
+
\ No newline at end of file
diff --git a/app/utility/Base64Utility.php b/app/utility/Base64Utility.php
new file mode 100644
index 0000000..4a614c3
--- /dev/null
+++ b/app/utility/Base64Utility.php
@@ -0,0 +1,36 @@
+ '+'
+ * '_' -> '/'
+ * The remainder of the string length %4, supplemented with '='
+ * @param base64 $string
+ */
+ public static function Decode($string) {
+ $data = str_replace(array('-','_'),array('+','/'),$string);
+ $mod4 = strlen($data) % 4;
+ if ($mod4) {
+ $data .= substr('====', $mod4);
+ }
+ return base64_decode($data);
+ }
+
+ /**
+ * URL base64 encoding
+ * '+' -> '-'
+ * '/' -> '_'
+ * '=' -> ''
+ * @param raw $string
+ */
+ public static function Encode($string) {
+ $data = base64_encode($string);
+ $data = str_replace(array('+','/','='),array('-','_',''),$data);
+ return $data;
+ }
+}
\ No newline at end of file
diff --git a/app/utility/BusinessLog.php b/app/utility/BusinessLog.php
new file mode 100644
index 0000000..06bca26
--- /dev/null
+++ b/app/utility/BusinessLog.php
@@ -0,0 +1,12 @@
+request("POST", $url, [
+ 'json' => [
+ 'code' => $code,
+ 'id' => $id,
+ 'stock' => $marketType,
+ ],
+ ]);
+
+ $body = $response->getBody()->getContents();
+ $res = json_decode($body, true);
+
+ Log::info('给交易推送数据 ' . json_encode([$res, [
+ 'code' => $code,
+ 'id' => $id,
+ 'stock' => $marketType,
+ ]]));
+
+ if (isset($res['code']) && $res['code'] == 200) {
+ return true;
+ }
+ return false;
+ } catch (\Exception $exception) {
+ Log::error('给交易推送数据异常1 ' . $exception->getMessage());
+ } catch (GuzzleException $e) {
+ Log::error('给交易推送数据异常2 ' . $e->getMessage());
+ }
+
+ return false;
+ }
+
+ // 给 go 行情 发送 source
+ public function updateIndiaSource($country, $stockCode, $source = 0)
+ {
+ try {
+
+ $responseArr = [
+ 'new_ticker' => $stockCode, //新的股票代码
+ 'locale' => $country,
+ 'source' => $source,
+ 'token' => 'asdfsnl123jlknl3nksdf32345ln98sdfsfs8891232nsdfsdfsdfsdxcfvbhnfgh',
+ ];
+
+ $client = new Client();
+ $url = env('QUOTE.BASE_URL') . '/spots/php/update';
+ $response = $client->request("POST", $url, [
+ 'json' => $responseArr
+ ]);
+
+ $body = $response->getBody()->getContents();
+ $res = json_decode($body, true);
+
+ $responseArr['url'] = $url;
+ trace('---给行情推送数据---' . json_encode([$res, $responseArr]), 'error');
+
+ if (isset($res['code']) && $res['code'] == 200) {
+ return true;
+ }
+
+ trace('---给行情推送数据异常---' . json_encode([$res, $responseArr]), 'error');
+ return false;
+ } catch (\Exception $exception) {
+ trace('---给行情推送数据异常1---' . $exception->getMessage(), 'error');
+
+ } catch (GuzzleException $e) {
+ trace('---给行情推送数据异常2---' . $e->getMessage(), 'error');
+ }
+
+ return false;
+ }
+
+}
\ No newline at end of file
diff --git a/app/utility/DesEn.php b/app/utility/DesEn.php
new file mode 100644
index 0000000..29c404c
--- /dev/null
+++ b/app/utility/DesEn.php
@@ -0,0 +1,125 @@
+key = $key;
+ $this->method = $method;
+ $this->output = $output;
+ $this->iv = $iv;
+ $this->options = $options;
+ }
+
+ /**
+ * 加密
+ *
+ * @param $str
+ * @return string
+ */
+ public function encrypt($str)
+ {
+ $str = $this->padding($str, 8);
+ $sign = openssl_encrypt($str, $this->method, $this->key, $this->options, $this->iv);
+ if ($this->output == self::OUTPUT_BASE64) {
+ $sign = base64_encode($sign);
+ } else if ($this->output == self::OUTPUT_HEX) {
+ $sign = bin2hex($sign);
+ }
+
+ return $sign;
+ }
+
+ /**
+ * 填充
+ *
+ * @param $str
+ * @param $blockSize
+ * @return string
+ * @internal param $blocksize
+ */
+ private function padding($str, $blockSize)
+ {
+ $pad = $blockSize - (strlen($str) % $blockSize);
+ return $str . str_repeat(chr($pad), $pad);
+ }
+
+ /**
+ * 解密
+ *
+ * @param $encrypted
+ * @return string
+ */
+ public function decrypt($encrypted)
+ {
+ if ($this->output == self::OUTPUT_BASE64) {
+ $encrypted = base64_decode($encrypted);
+ } else if ($this->output == self::OUTPUT_HEX) {
+ $encrypted = hex2bin($encrypted);
+ }
+ $sign = @openssl_decrypt($encrypted, $this->method, $this->key, $this->options, $this->iv);
+ $sign = $this->unPadding($sign);
+ $sign = rtrim($sign);
+ return $sign;
+ }
+
+ /**
+ * 去填充
+ *
+ * @param $str
+ * @return string
+ */
+ private function unPadding($str)
+ {
+ $pad = ord($str[strlen($str) - 1]);
+ if ($pad > strlen($str)) {
+ return false;
+ }
+ return substr($str, 0, -1 * $pad);
+ }
+
+}
\ No newline at end of file
diff --git a/app/utility/Jwt.php b/app/utility/Jwt.php
new file mode 100644
index 0000000..6b5829f
--- /dev/null
+++ b/app/utility/Jwt.php
@@ -0,0 +1,99 @@
+ [
+ 'userId' =>$userId
+ ],
+ 'iss' => 'qwueiqnyuqjezchiw', // 随机
+ 'aud' => '',
+ 'iat' =>time()
+ ];
+
+ return 'Bear' . \Firebase\JWT\JWT::encode($payload, $key, 'HS256');
+ }
+
+ /**
+ * 后端生成token
+ * @param $userId // 用户id
+ * @return string
+ */
+ function generateToken($userId)
+ {
+ //获取当前时间戳
+ $currentTime = time();
+ $data = array(
+ "iss" => 'coinwerqwerasdf', //签发者 可以为空
+ "aud" => '', //面象的用户,可以为空
+ "iat" => $currentTime, //签发时间
+ "nbf" => $currentTime, //立马生效
+ "exp" => $currentTime + 3600*24, //token 过期时间 1天
+ "data" => [ //记录的userid的信息
+ 'user_id' => $userId,
+ ]
+ );
+ //生成token
+ $token = \Firebase\JWT\JWT::encode($data, env('ENCRYPT.ADMINSALT'), "HS256");
+
+ return 'Bear'.$token;
+ }
+
+ /**
+ * 检查token有效性
+ * @param $token
+ * @return array|int[]
+ */
+ public function chekToken($token)
+ {
+ $status=array("code"=>2);
+ if(!$token){
+ $status['msg']="token缺失";
+ return $status;
+ }
+
+ $len=4;
+ $bear=substr($token,0,6);
+ if($bear=='Bearer'){
+ $len=6;
+ }
+ $token = trim(substr_replace($token,'',0,$len)," ");
+ try {
+ \Firebase\JWT\JWT::$leeway = 60;//当前时间减去60
+ $decoded = \Firebase\JWT\JWT::decode($token, new \Firebase\JWT\Key(env('ENCRYPT.ADMINSALT'), 'HS256'));
+ $arr = (array)$decoded;
+ $res['code']=1;
+ $res['data']=$arr['data'];
+ return $res;
+
+ } catch(\Firebase\JWT\SignatureInvalidException $e) { //签名不正确
+ $status['msg']="token签名不正确";
+ return $status;
+ }catch(\Firebase\JWT\BeforeValidException $e) { // 签名在某个时间点之后才能用
+ $status['msg']="token失效";
+ return $status;
+ }catch(\Firebase\JWT\ExpiredException $e) { // token过期
+ $status['msg']="token失效";
+
+ return $status;
+ }catch(\Exception $e) { //其他错误
+ $status['msg']="未知错误";
+ return $status;
+ }
+ }
+
+
+
+
+}
\ No newline at end of file
diff --git a/app/utility/RsaUtility.php b/app/utility/RsaUtility.php
new file mode 100644
index 0000000..04916f5
--- /dev/null
+++ b/app/utility/RsaUtility.php
@@ -0,0 +1,74 @@
+pub_key);
+ return $decrypted;
+ }
+}
\ No newline at end of file
diff --git a/app/utility/SendEmail.php b/app/utility/SendEmail.php
new file mode 100644
index 0000000..8bead96
--- /dev/null
+++ b/app/utility/SendEmail.php
@@ -0,0 +1,53 @@
+phpEmail = new PHPMailer();
+ $this->phpEmail->SMTPDebug = 0; // 关闭调试功能
+ $this->phpEmail->CharSet = 'UTF-8';
+ $this->phpEmail->isSMTP(); // 设定使用SMTP服务
+ //$this->phpEmail->Host = 'smtpdm-ap-southeast-1.aliyun.com';
+ $this->phpEmail->Host = empty( env('EMAIL.Host')) ? 'smtpdm-ap-southeast-1.aliyun.com': env('EMAIL.Host');
+ $this->phpEmail->Port = 465; // SMTP服务器的端口号
+ $this->phpEmail->SMTPAuth = true;
+ $this->phpEmail->Username = env('EMAIL.Username'); // 发件地址
+ $this->phpEmail->Password = env('EMAIL.Password'); // SMTP密码
+ $this->phpEmail->SMTPSecure = 'ssl';
+ $this->phpEmail->From = env('EMAIL.From');
+ }
+
+ /**
+ * @desc 发送邮箱服务
+ * @param $toAddress // 收件地址
+ * @param $title // 标题
+ * @param $content // 内容
+ * @return bool
+ */
+ public function sendEmail($toAddress, $title, $content): bool
+ {
+ try {
+ $this->phpEmail->addAddress($toAddress);
+ $this->phpEmail->Subject = $title;
+ $this->phpEmail->Body = $content;
+ $status = $this->phpEmail->send();
+ if ($status) {
+ return true;
+ }
+ trace('---异常-----'.$this->phpEmail->ErrorInfo, 'info');
+
+ return false;
+ }catch (\Exception $exception) {
+ trace('---异常-----'.$exception->getMessage(), 'info');
+ return false;
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/app/utility/SendSms.php b/app/utility/SendSms.php
new file mode 100644
index 0000000..313dea0
--- /dev/null
+++ b/app/utility/SendSms.php
@@ -0,0 +1,55 @@
+regionId('ap-southeast-1')
+ ->asDefaultClient();
+
+ $result = AlibabaCloud::rpcRequest()
+ ->product('Dysmsapi')
+ ->host('dysmsapi.ap-southeast-1.aliyuncs.com')
+ ->version('2018-05-01')
+ ->action('SendMessageToGlobe')
+ ->method('POST')
+ ->options([
+ 'query' => [
+ "To" => $toNum,
+ "Message" => $content,
+ ],
+ ])
+ ->request();
+
+ $res = $result->toArray();
+
+ Log::error("----sms_send-----".json_encode([$res]));
+ if(!isset($res['ResponseCode']) || $res['ResponseCode'] != 'OK'){
+ trace('短信发送失败00_'.json_encode([$res]), 'error');
+ }
+ return true;
+
+ }catch (ClientException $clientException) {
+ trace('短信发送失败01_'.$clientException->getMessage(), 'error');
+ }catch (ServerException $serverException) {
+ trace('短信发送失败02_'.$serverException->getMessage(), 'error');
+ }catch (\Exception $exception) {
+ trace('短信发送失败03_'.$exception->getMessage(), 'error');
+ }
+
+ return false;
+ }
+}
\ No newline at end of file
diff --git a/app/utility/Tool.php b/app/utility/Tool.php
new file mode 100644
index 0000000..83365b1
--- /dev/null
+++ b/app/utility/Tool.php
@@ -0,0 +1,21 @@
+ $length) {
+ $orderNumber = substr($orderNumber, 0, $length);
+ }
+ return $orderNumber;
+ }
+}
\ No newline at end of file
diff --git a/app/utility/UnqId.php b/app/utility/UnqId.php
new file mode 100644
index 0000000..6f9e1b2
--- /dev/null
+++ b/app/utility/UnqId.php
@@ -0,0 +1,38 @@
+encryptPassword($string, $salt);
+ return $encryptPassword == $password;
+ }
+}
\ No newline at end of file
diff --git a/config/app.php b/config/app.php
new file mode 100644
index 0000000..6588fe9
--- /dev/null
+++ b/config/app.php
@@ -0,0 +1,43 @@
+ env('app.host', ''),
+ // 应用的命名空间
+ 'app_namespace' => '',
+ // 是否启用路由
+ 'with_route' => true,
+ // 默认应用
+ 'default_app' => 'index',
+ // 默认时区
+ 'default_timezone' => 'Asia/Singapore',
+
+ // 应用映射(自动多应用模式有效)
+ 'app_map' => [
+ 'bs' => 'home',
+ 'XwkjlLbDcG' => 'admin',
+ ],
+ 'cross_origin' => true, //允许跨域
+ // 域名绑定(自动多应用模式有效)
+ 'domain_bind' => [],
+ // 禁止URL访问的应用列表(自动多应用模式有效)
+ 'deny_app_list' => [],
+
+ // 异常页面的模板文件
+ //'exception_tmpl' => app()->getThinkPath() . 'tpl/think_exception.tpl',
+ 'exception_tmpl' => base_path().'sorry.html',
+
+ // 错误显示信息,非调试模式有效
+ 'error_message' => '页面错误!请稍后再试~',
+ // 显示错误信息
+ 'show_error_msg' => false,
+ 'fields_cache'=>true,
+ 'http_exception_template' => [
+ // '404' => base_path().'404.html',
+ ],
+ //多语言
+ 'lang_switch_on'=>true,
+];
diff --git a/config/cache.php b/config/cache.php
new file mode 100644
index 0000000..7485d47
--- /dev/null
+++ b/config/cache.php
@@ -0,0 +1,37 @@
+ env('cache.driver', 'file'),
+
+ // 缓存连接方式配置
+ 'stores' => [
+ 'file' => [
+ // 驱动方式
+ 'type' => 'File',
+ // 缓存保存目录
+ 'path' => '',
+ // 缓存前缀
+ 'prefix' => '',
+ // 缓存有效期 0表示永久缓存
+ 'expire' => 0,
+ // 缓存标签前缀
+ 'tag_prefix' => 'tag:',
+ // 序列化机制 例如 ['serialize', 'unserialize']
+ 'serialize' => [],
+ ],
+ // 更多的缓存连接
+ 'redis' => [
+ 'type' => 'redis',
+ 'host' => env('REDIS.HOST', '172.31.120.245'),
+ 'port' => env('REDIS.PORT', '6378'),
+ 'select' => env('REDIS.SELECT', '0'),
+ 'password' => env('REDIS.PASSWORD', 'rfvtyujnbhg56'),
+ ],
+ ],
+
+];
diff --git a/config/console.php b/config/console.php
new file mode 100644
index 0000000..a818a98
--- /dev/null
+++ b/config/console.php
@@ -0,0 +1,9 @@
+ [
+ ],
+];
diff --git a/config/cookie.php b/config/cookie.php
new file mode 100644
index 0000000..d3b3aab
--- /dev/null
+++ b/config/cookie.php
@@ -0,0 +1,20 @@
+ 0,
+ // cookie 保存路径
+ 'path' => '/',
+ // cookie 有效域名
+ 'domain' => '',
+ // cookie 启用安全传输
+ 'secure' => false,
+ // httponly设置
+ 'httponly' => false,
+ // 是否使用 setcookie
+ 'setcookie' => true,
+ // samesite 设置,支持 'strict' 'lax'
+ 'samesite' => '',
+];
diff --git a/config/database.php b/config/database.php
new file mode 100644
index 0000000..1b6e9f6
--- /dev/null
+++ b/config/database.php
@@ -0,0 +1,63 @@
+ env('database.driver', 'mysql'),
+
+ // 自定义时间查询规则
+ 'time_query_rule' => [],
+
+ // 自动写入时间戳字段
+ // true为自动识别类型 false关闭
+ // 字符串则明确指定时间字段类型 支持 int timestamp datetime date
+ 'auto_timestamp' => true,
+
+ // 时间字段取出后的默认时间格式
+ 'datetime_format' => 'Y-m-d H:i:s',
+
+ // 时间字段配置 配置格式:create_time,update_time
+ 'datetime_field' => '',
+
+ // 数据库连接配置信息
+ 'connections' => [
+ 'mysql' => [
+ // 数据库类型
+ 'type' => env('database.type', 'mysql'),
+ // 服务器地址
+ 'hostname' => env('database.hostname', 'dbtest.crsocbk1nt38.ap-southeast-1.rds.amazonaws.com'),
+ // 数据库名
+ 'database' => env('database.database', 'bourse'),
+ // 用户名
+ 'username' => env('database.username', 'admin'),
+ // 密码
+ 'password' => env('database.password', '123456'),
+ // 端口
+ 'hostport' => env('database.hostport', '3306'),
+ // 数据库连接参数
+ 'params' => [],
+ // 数据库编码默认采用utf8
+ 'charset' => env('database.charset', 'utf8'),
+ // 数据库表前缀
+ 'prefix' => env('database.prefix', 'bot_'),
+
+ // 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器)
+ 'deploy' => 0,
+ // 数据库读写是否分离 主从式有效
+ 'rw_separate' => false,
+ // 读写分离后 主服务器数量
+ 'master_num' => 1,
+ // 指定从服务器序号
+ 'slave_no' => '',
+ // 是否严格检查字段是否存在
+ 'fields_strict' => true,
+ // 是否需要断线重连
+ 'break_reconnect' => false,
+ // 监听SQL
+ 'trigger_sql' => env('app_debug', true),
+ // 开启字段缓存
+ 'fields_cache' => false,
+ ],
+
+ // 更多的数据库配置信息
+ ],
+];
diff --git a/config/filesystem.php b/config/filesystem.php
new file mode 100644
index 0000000..9f1d5ac
--- /dev/null
+++ b/config/filesystem.php
@@ -0,0 +1,25 @@
+ env('filesystem.driver', 'local'),
+ // 磁盘列表
+ 'disks' => [
+ 'local' => [
+ 'type' => 'local',
+ //'root' => app()->getRuntimePath() . 'storage',
+ 'root' => app()->getRootPath() . 'public/bs/image'
+ ],
+ 'public' => [
+ // 磁盘类型
+ 'type' => 'local',
+ // 磁盘路径
+ 'root' => app()->getRootPath() . 'public/storage',
+ // 磁盘路径对应的外部URL路径
+ 'url' => '/storage',
+ // 可见性
+ 'visibility' => 'public',
+ ],
+ // 更多的磁盘配置信息
+ ],
+];
diff --git a/config/lang.php b/config/lang.php
new file mode 100644
index 0000000..eaf2fdb
--- /dev/null
+++ b/config/lang.php
@@ -0,0 +1,31 @@
+ env('lang.default_lang', 'zh-cn'),
+ // 允许的语言列表
+ 'allow_lang_list' => [
+ 'zh-cn',
+ 'en-us',
+ ],
+ // 多语言自动侦测变量名
+ 'detect_var' => 'lang',
+ // 是否使用Cookie记录
+ 'use_cookie' => true,
+ // 多语言cookie变量
+ 'cookie_var' => 'think_lang',
+ // 多语言header变量
+ 'header_var' => 'think-lang',
+ // 扩展语言包
+ 'extend_list' => [],
+ // Accept-Language转义为对应语言包名称
+ 'accept_language' => [
+ 'zh-hans-cn' => 'zh-cn',
+ ],
+ // 是否支持语言分组
+ 'allow_group' => false,
+
+];
diff --git a/config/log.php b/config/log.php
new file mode 100644
index 0000000..634d42d
--- /dev/null
+++ b/config/log.php
@@ -0,0 +1,45 @@
+ env('log.channel', 'file'),
+ // 日志记录级别
+ 'level' => ['error','info'],
+ // 日志类型记录的通道 ['error'=>'email',...]
+ 'type_channel' => [],
+ // 关闭全局日志写入
+ 'close' => false,
+ // 全局日志处理 支持闭包
+ 'processor' => null,
+
+ // 日志通道列表
+ 'channels' => [
+ 'file' => [
+ // 日志记录方式
+ 'type' => 'File',
+ // 日志保存目录
+ 'path' => '',
+ // 单文件日志写入
+ 'single' => false,
+ // 独立日志级别
+ 'apart_level' => [],
+ // 最大日志文件数量
+ 'max_files' => 0,
+ // 使用JSON格式记录
+ 'json' => false,
+ // 日志处理
+ 'processor' => null,
+ // 关闭通道日志写入
+ 'close' => false,
+ // 日志输出格式化
+ 'format' => '[%s][%s] %s',
+ // 是否实时写入
+ 'realtime_write' => false,
+ ],
+ // 其它日志通道配置
+ ],
+
+];
diff --git a/config/middleware.php b/config/middleware.php
new file mode 100644
index 0000000..633fb51
--- /dev/null
+++ b/config/middleware.php
@@ -0,0 +1,18 @@
+ [
+ 'admin_auth' => app\admin\middleware\Check::class,
+ 'admin_log'=> app\admin\middleware\AdminLog::class,
+
+ 'bs_auth' => app\home\middleware\AuthMiddleware::class,
+ 'bs_repeat' => app\home\middleware\RepeatOperateMiddleware::class,
+ 'bs_cors' => app\home\middleware\CorsMiddleware::class,
+ ],
+ // 优先级设置,此数组中的中间件会按照数组中的顺序优先执行
+ 'priority' => [
+ \think\middleware\AllowCrossDomain::class,
+ ],
+
+];
diff --git a/config/model_help.php b/config/model_help.php
new file mode 100644
index 0000000..2c823b4
--- /dev/null
+++ b/config/model_help.php
@@ -0,0 +1,53 @@
+ true,
+
+ /*
+ * 开启模型字段schema的写入,开启后无需更新字段缓存
+ * https://www.kancloud.cn/manual/thinkphp6_0/1037581
+ */
+ 'write_schema' => true,
+
+ /*
+ * 开启模型查询方法的辅助注释
+ * 包括 find findOrEmpty select
+ */
+ 'write_select_help' => true,
+
+ /*
+ * 开启关联模型查询方法的辅助注释
+ */
+ 'write_relation_model' => true,
+
+ /*
+ * 是否允许覆盖
+ * 注意,这里仅检查原有模型是否含有该字段,并不检测字段是否需要更新
+ * 开启后每次都会更新并写入模型,即使没有字段变更,git也可能会刷新版本
+ */
+
+ 'over_write_phpdoc' => false,
+ 'over_write_schema' => false,
+
+ /*
+ * 设置读取模型的目录
+ * 例如:
+ * ‘model’ 读取的是 base_path('model') 即 app 目录下的 model 目录
+ * 或者直接使用绝对路径
+ */
+ 'load_dir' => [
+ 'model'
+ ],
+
+ /*
+ * 忽略更新的模型
+ * 例如
+ * \think\Model::class
+ */
+ 'ignore_model' => [
+
+ ],
+];
\ No newline at end of file
diff --git a/config/queue.php b/config/queue.php
new file mode 100644
index 0000000..b9c8433
--- /dev/null
+++ b/config/queue.php
@@ -0,0 +1,29 @@
+
+// +----------------------------------------------------------------------
+
+return [
+ 'default' => 'redis',
+ 'connections' => [
+ 'sync' => [
+ 'type' => 'sync',
+ ],
+ 'redis' => [
+ 'type' => 'redis',
+ 'queue' => 'default',
+ 'host' => env('REDIS.HOST', '127.0.0.1'),
+ 'port' => env('REDIS.PORT', '6379'),
+ 'password' => env('REDIS.PASSWORD', ''),
+ 'select' => env('REDIS.SELECT', '0'),
+ 'timeout' => 0,
+ 'persistent' => false,
+ ],
+ ],
+];
diff --git a/config/redis.php b/config/redis.php
new file mode 100644
index 0000000..0c10ef8
--- /dev/null
+++ b/config/redis.php
@@ -0,0 +1,15 @@
+ [
+ 'type' => 'redis',
+ 'host' => env('REDIS.HOST', '13.251.125.27'),
+ 'port' => env('REDIS.PORT', '6378'),
+ 'select' => env('REDIS.SELECT', '0'),
+ 'password' => env('REDIS.PASSWORD', 'rfvtyujnbhg56'),
+ ],
+
+];
diff --git a/config/route.php b/config/route.php
new file mode 100644
index 0000000..2f4cd12
--- /dev/null
+++ b/config/route.php
@@ -0,0 +1,45 @@
+ '/',
+ // URL伪静态后缀
+ 'url_html_suffix' => 'html',
+ // URL普通方式参数 用于自动生成
+ 'url_common_param' => true,
+ // 是否开启路由延迟解析
+ 'url_lazy_route' => false,
+ // 是否强制使用路由
+ 'url_route_must' => false,
+ // 合并路由规则
+ 'route_rule_merge' => false,
+ // 路由是否完全匹配
+ 'route_complete_match' => false,
+ // 访问控制器层名称
+ 'controller_layer' => 'controller',
+ // 空控制器名
+ 'empty_controller' => 'Error',
+ // 是否使用控制器后缀
+ 'controller_suffix' => false,
+ // 默认的路由变量规则
+ 'default_route_pattern' => '[\w\.]+',
+ // 是否开启请求缓存 true自动缓存 支持设置请求缓存规则
+ 'request_cache_key' => false,
+ // 请求缓存有效期
+ 'request_cache_expire' => null,
+ // 全局请求缓存排除规则
+ 'request_cache_except' => [],
+ // 默认控制器名
+ 'default_controller' => 'Index',
+ // 默认操作名
+ 'default_action' => 'index',
+ // 操作方法后缀
+ 'action_suffix' => '',
+ // 默认JSONP格式返回的处理方法
+ 'default_jsonp_handler' => 'jsonpReturn',
+ // 默认JSONP处理方法
+ 'var_jsonp_handler' => 'callback',
+];
diff --git a/config/session.php b/config/session.php
new file mode 100644
index 0000000..c1ef6e1
--- /dev/null
+++ b/config/session.php
@@ -0,0 +1,19 @@
+ 'PHPSESSID',
+ // SESSION_ID的提交变量,解决flash上传跨域
+ 'var_session_id' => '',
+ // 驱动方式 支持file cache
+ 'type' => 'file',
+ // 存储连接标识 当type使用cache的时候有效
+ 'store' => null,
+ // 过期时间
+ 'expire' => 1440,
+ // 前缀
+ 'prefix' => '',
+];
diff --git a/config/trace.php b/config/trace.php
new file mode 100644
index 0000000..fad2392
--- /dev/null
+++ b/config/trace.php
@@ -0,0 +1,10 @@
+ 'Html',
+ // 读取的日志通道名
+ 'channel' => '',
+];
diff --git a/config/view.php b/config/view.php
new file mode 100644
index 0000000..01259a0
--- /dev/null
+++ b/config/view.php
@@ -0,0 +1,25 @@
+ 'Think',
+ // 默认模板渲染规则 1 解析为小写+下划线 2 全部转换小写 3 保持操作方法
+ 'auto_rule' => 1,
+ // 模板目录名
+ 'view_dir_name' => 'view',
+ // 模板后缀
+ 'view_suffix' => 'html',
+ // 模板文件名分隔符
+ 'view_depr' => DIRECTORY_SEPARATOR,
+ // 模板引擎普通标签开始标记
+ 'tpl_begin' => '{',
+ // 模板引擎普通标签结束标记
+ 'tpl_end' => '}',
+ // 标签库标签开始标记
+ 'taglib_begin' => '{',
+ // 标签库标签结束标记
+ 'taglib_end' => '}',
+];
diff --git a/extend/.gitignore b/extend/.gitignore
new file mode 100644
index 0000000..c96a04f
--- /dev/null
+++ b/extend/.gitignore
@@ -0,0 +1,2 @@
+*
+!.gitignore
\ No newline at end of file
diff --git a/public/.htaccess b/public/.htaccess
new file mode 100644
index 0000000..e69de29
diff --git a/public/Ubsfim.apk b/public/Ubsfim.apk
new file mode 100644
index 0000000..4ce7ce6
Binary files /dev/null and b/public/Ubsfim.apk differ
diff --git a/public/bs/.gitignore b/public/bs/.gitignore
new file mode 100644
index 0000000..c96a04f
--- /dev/null
+++ b/public/bs/.gitignore
@@ -0,0 +1,2 @@
+*
+!.gitignore
\ No newline at end of file
diff --git a/public/favicon.ico b/public/favicon.ico
new file mode 100644
index 0000000..e71815a
Binary files /dev/null and b/public/favicon.ico differ
diff --git a/public/index.php b/public/index.php
new file mode 100644
index 0000000..e3c0fe9
--- /dev/null
+++ b/public/index.php
@@ -0,0 +1,24 @@
+
+// +----------------------------------------------------------------------
+
+// [ 应用入口文件 ]
+namespace think;
+
+require __DIR__ . '/../vendor/autoload.php';
+
+// 执行HTTP应用并响应
+$http = (new App())->http;
+
+$response = $http->run();
+
+$response->send();
+
+$http->end($response);
diff --git a/public/logo/1.png b/public/logo/1.png
new file mode 100644
index 0000000..4a06e39
Binary files /dev/null and b/public/logo/1.png differ
diff --git a/public/logo/2.png b/public/logo/2.png
new file mode 100644
index 0000000..90c925b
Binary files /dev/null and b/public/logo/2.png differ
diff --git a/public/logo/ada.png b/public/logo/ada.png
new file mode 100644
index 0000000..08e3e79
Binary files /dev/null and b/public/logo/ada.png differ
diff --git a/public/logo/avax.png b/public/logo/avax.png
new file mode 100644
index 0000000..b65486b
Binary files /dev/null and b/public/logo/avax.png differ
diff --git a/public/logo/bch.png b/public/logo/bch.png
new file mode 100644
index 0000000..3824c5a
Binary files /dev/null and b/public/logo/bch.png differ
diff --git a/public/logo/bnb.png b/public/logo/bnb.png
new file mode 100644
index 0000000..5bfc3e2
Binary files /dev/null and b/public/logo/bnb.png differ
diff --git a/public/logo/btc.png b/public/logo/btc.png
new file mode 100644
index 0000000..80272c8
Binary files /dev/null and b/public/logo/btc.png differ
diff --git a/public/logo/busd.png b/public/logo/busd.png
new file mode 100644
index 0000000..e4b950e
Binary files /dev/null and b/public/logo/busd.png differ
diff --git a/public/logo/dai.png b/public/logo/dai.png
new file mode 100644
index 0000000..7a1afb7
Binary files /dev/null and b/public/logo/dai.png differ
diff --git a/public/logo/doge.png b/public/logo/doge.png
new file mode 100644
index 0000000..10c0d72
Binary files /dev/null and b/public/logo/doge.png differ
diff --git a/public/logo/dot.png b/public/logo/dot.png
new file mode 100644
index 0000000..70f1459
Binary files /dev/null and b/public/logo/dot.png differ
diff --git a/public/logo/eos.png b/public/logo/eos.png
new file mode 100644
index 0000000..34caf0f
Binary files /dev/null and b/public/logo/eos.png differ
diff --git a/public/logo/eth.png b/public/logo/eth.png
new file mode 100644
index 0000000..317228b
Binary files /dev/null and b/public/logo/eth.png differ
diff --git a/public/logo/ltc.png b/public/logo/ltc.png
new file mode 100644
index 0000000..51c4aca
Binary files /dev/null and b/public/logo/ltc.png differ
diff --git a/public/logo/matic.png b/public/logo/matic.png
new file mode 100644
index 0000000..ad93fdb
Binary files /dev/null and b/public/logo/matic.png differ
diff --git a/public/logo/shib.png b/public/logo/shib.png
new file mode 100644
index 0000000..22c2e93
Binary files /dev/null and b/public/logo/shib.png differ
diff --git a/public/logo/sol.png b/public/logo/sol.png
new file mode 100644
index 0000000..4c5dc47
Binary files /dev/null and b/public/logo/sol.png differ
diff --git a/public/logo/tg.png b/public/logo/tg.png
new file mode 100644
index 0000000..539175e
Binary files /dev/null and b/public/logo/tg.png differ
diff --git a/public/logo/ton.png b/public/logo/ton.png
new file mode 100644
index 0000000..9a517e8
Binary files /dev/null and b/public/logo/ton.png differ
diff --git a/public/logo/trx.png b/public/logo/trx.png
new file mode 100644
index 0000000..575be70
Binary files /dev/null and b/public/logo/trx.png differ
diff --git a/public/logo/usdc.png b/public/logo/usdc.png
new file mode 100644
index 0000000..2bad29e
Binary files /dev/null and b/public/logo/usdc.png differ
diff --git a/public/logo/usdt.png b/public/logo/usdt.png
new file mode 100644
index 0000000..07d8323
Binary files /dev/null and b/public/logo/usdt.png differ
diff --git a/public/logo/wbtc.png b/public/logo/wbtc.png
new file mode 100644
index 0000000..96e4448
Binary files /dev/null and b/public/logo/wbtc.png differ
diff --git a/public/logo/ws.png b/public/logo/ws.png
new file mode 100644
index 0000000..a3f9df0
Binary files /dev/null and b/public/logo/ws.png differ
diff --git a/public/logo/xrp.png b/public/logo/xrp.png
new file mode 100644
index 0000000..4f31676
Binary files /dev/null and b/public/logo/xrp.png differ
diff --git a/public/nginx.htaccess b/public/nginx.htaccess
new file mode 100644
index 0000000..5f3f014
--- /dev/null
+++ b/public/nginx.htaccess
@@ -0,0 +1,5 @@
+location / {
+ if (!-e $request_filename){
+ rewrite ^(.*)$ /index.php?s=/$1 last;
+ }
+}
\ No newline at end of file
diff --git a/public/robots.txt b/public/robots.txt
new file mode 100644
index 0000000..eb05362
--- /dev/null
+++ b/public/robots.txt
@@ -0,0 +1,2 @@
+User-agent: *
+Disallow:
diff --git a/public/router.php b/public/router.php
new file mode 100644
index 0000000..9b39a62
--- /dev/null
+++ b/public/router.php
@@ -0,0 +1,19 @@
+
+// +----------------------------------------------------------------------
+// $Id$
+
+if (is_file($_SERVER["DOCUMENT_ROOT"] . $_SERVER["SCRIPT_NAME"])) {
+ return false;
+} else {
+ $_SERVER["SCRIPT_FILENAME"] = __DIR__ . '/index.php';
+
+ require __DIR__ . "/index.php";
+}
diff --git a/public/static/.gitignore b/public/static/.gitignore
new file mode 100644
index 0000000..c96a04f
--- /dev/null
+++ b/public/static/.gitignore
@@ -0,0 +1,2 @@
+*
+!.gitignore
\ No newline at end of file
diff --git a/route/app.php b/route/app.php
new file mode 100644
index 0000000..41c876d
--- /dev/null
+++ b/route/app.php
@@ -0,0 +1,3 @@
+console->run();
\ No newline at end of file
diff --git a/view/README.md b/view/README.md
new file mode 100644
index 0000000..360eb24
--- /dev/null
+++ b/view/README.md
@@ -0,0 +1 @@
+如果不使用模板,可以删除该目录
\ No newline at end of file