chuan 3 months ago
parent
commit
1754ad7591
  1. 10
      app/admin/controller/Test.php
  2. 172
      app/admin/controller/Upload.php
  3. 13
      app/admin/controller/User.php
  4. 28
      app/admin/controller/setting/Forex.php
  5. 4
      app/admin/route/app.php
  6. 26
      app/admin/service/AdminBaseService.php
  7. 29
      app/admin/service/AgentService.php
  8. 110
      app/admin/service/UserService.php
  9. 162
      app/admin/service/setting/ForexService.php
  10. 15
      app/admin/service/setting/IPOService.php
  11. 6
      app/home/job/SendEmail.php
  12. 30
      app/home/job/SendSms.php
  13. 42
      app/home/service/LoginService.php
  14. 3
      app/home/service/StockService.php
  15. 8
      app/home/service/UserService.php
  16. 6
      app/model/AdminModel.php
  17. 11
      app/model/ForexMarketModel.php
  18. 3
      composer.json

10
app/admin/controller/Test.php

@ -8,13 +8,21 @@ class Test extends AdminBaseController
public function index()
{
$appRootPath = app()->getRootPath();
$appAppPath = app()->getAppPath();
$memoryLimit = ini_get('memory_limit');
$uploadMax = ini_get('upload_max_filesize');
$postMax = ini_get('post_max_size');
$max_execution_time = ini_get('max_execution_time'); //最大执行时间(秒)
$max_input_time = ini_get('max_input_time'); // 输入解析时间限制
return json(['code' => '0', 'msg' => 'SUCCESS', 'data' => [
'memory_limit' => $memoryLimit,
'upload_max' => $uploadMax,
'post_max' => $postMax
'post_max' => $postMax,
'max_execution_time' => $max_execution_time,
'max_input_time' => $max_input_time,
'app_root_path' => $appRootPath,
'app_path' => $appAppPath,
]]);
}
}

172
app/admin/controller/Upload.php

@ -7,6 +7,7 @@ use app\model\FileModel;
use Aws\S3\S3Client;
use think\facade\Filesystem;
use think\facade\Config;
use think\facade\Log;
class Upload extends AdminBaseController
{
@ -20,11 +21,16 @@ class Upload extends AdminBaseController
if (!$file) {
return json(['code' => 400, 'message' => 'No file uploaded']);
}
// 验证文件类型和大小
$maxSize = 15 * 1024 * 1024; //限制M
// 验证文件类型和大小, 限制20M
$maxSize = 20 * 1024 * 1024;
if ($file->getSize() > $maxSize) {
return json(['code' => 400, 'message' => 'Upload file is too large']);
}
// 打开文件
$openFile = fopen($file->getRealPath(), 'r');
if (!$openFile) {
return json(['code' => 400, 'message' => 'Failed to open the file']);
}
// 验证上传文件类型
if (!in_array($file->getOriginalMime(), ['image/jpeg','image/png','image/webp','image/bm'])) {
return json(['code' => 400, 'message' => 'Upload file type error']);
@ -45,10 +51,10 @@ class Upload extends AdminBaseController
$result = $s3Client->putObject([
'Bucket' => $s3Config['aws_bucket'],
'Key' => 'bourse-avatar/' . $fileName, // s3中的存储路径
'Body' => fopen($file->getRealPath(), 'r'),
'Body' => $openFile,
'ContentType' => $file->getOriginalMime(), // 设置文件的MIME, 不然s3会以流式存储
]);
if (empty($result) || empty($result['ObjectURL'])) {
])->toArray();
if (empty($result['ObjectURL'])) {
return json(['code' => 400, 'message' => '上传s3失败']);
}
// 记录上传的文件
@ -59,10 +65,13 @@ class Upload extends AdminBaseController
'mime' => $file->getOriginalMime(),
'ext' => $file->getOriginalExtension(),
]);
fclose($openFile);
// 返回路径
return json(['code' => '0', 'message' => '上传成功', 'data' => ['path' => $resData->s3_url]]);
} catch (\Exception $exception) {
if (isset($openFile)) {
fclose($openFile);
}
return json(['code' => '100500', 'message' => '系统繁忙', 'data' => [$exception->getMessage()]]);
}
}
@ -77,11 +86,16 @@ class Upload extends AdminBaseController
if (!$file) {
return json(['code' => 400, 'message' => 'No file uploaded']);
}
// 验证文件类型和大小
$maxSize = 1024 * 1024 * 1024; //限制1G
// 验证文件类型和大小 限制100M
$maxSize = 100 * 1024 * 1024;
if ($file->getSize() > $maxSize) {
return json(['code' => 400, 'message' => 'The file size cannot exceed 1 GB']);
}
// 打开文件
$openFile = fopen($file->getRealPath(), 'r');
if (!$openFile) {
return json(['code' => 400, 'message' => 'Failed to open the file']);
}
// 生成唯一的文件名
$fileName = bin2hex(random_bytes(16)) . '.' . $file->getOriginalExtension();
// 初始化s3客户端
@ -99,12 +113,14 @@ class Upload extends AdminBaseController
$result = $s3Client->putObject([
'Bucket' => $s3Config['aws_bucket'],
'Key' => 'bourse-video-node/' . $fileName, // s3中的存储路径
'Body' => fopen($file->getRealPath(), 'r'),
'Body' => $openFile,
'ContentType' => $file->getOriginalMime(), // 设置文件的MIME, 不然s3会以流式存储
// 'ACL' => 'public-read', // 设置文件为公开可读
]);
if (empty($result) || empty($result['ObjectURL'])) {
return json(['code' => 400, 'message' => '上传s3失败']);
])->toArray();
fclose($openFile);
Log::info("上传s3结果:". json_encode($result));
if (empty($result['ObjectURL'])) {
return json(['code' => 400, 'message' => '上传失败']);
}
// 记录上传的文件
$resData = AwsS3Model::create([
@ -124,30 +140,44 @@ class Upload extends AdminBaseController
'ext'=> $file->getOriginalExtension(),
]]);
} catch (\Exception $exception) {
if (isset($openFile)) {
fclose($openFile);
}
return json(['code' => '100500', 'message' => '系统繁忙', 'data' => [$exception->getMessage()]]);
}
}
// 初始化分片上传
// 上传文件至服务器本地
public function uploadToServer()
{
$file = $this->request->file('file');
if (!$file) {
return json(['code' => 400, 'message' => 'No file uploaded233']);
}
if ($file->getSize() > 100 * 1024 * 1024) {
return json(['code' => 400, 'message' => 'Upload file is too large']);
}
$name = Filesystem::disk('local')->putFile('topic', $file);
$path = '/bs/image/'.$name;
return json(['code'=>0, 'message'=>'ok', 'data'=>['path'=>$path]]);
}
// 创建分段上传,初始化一个新的上传任务,生成一个上传的唯一标识符
public function initiateUpload(){
try {
$param = $this->request->param();
if (empty($param['file_type'])) {
return json(['code' => '100500', 'message' => '缺少参数 file_type', 'data' => []]);
}
// 允许的视频类型
$allowed_types = [
'video/mp4',
'video/quicktime',
'video/x-msvideo',
'video/x-ms-wmv',
'video/x-matroska',
];
if (!in_array($param['file_type'], $allowed_types)) {
return json(['code' => '100500', 'message' => '上传的文件类型不在允许范围内', 'data' => []]);
$param = $this->request->post();
if (empty($param['mime'])) {
return json(['code' => 400, 'message' => '缺少参数mime']);
}
$getMime = trim($param['mime']);
// 获取文件扩展名
$mimeArr = explode('/', $getMime);
$getExt = end($mimeArr);
if (empty($getExt)) {
return json(['code' => 400, 'message' => '提取文件扩展名错误']);
}
// 生成唯一的文件名
$fileName = bin2hex(random_bytes(16));
$fileName = bin2hex(random_bytes(16)) . '.' . $getExt;
// 初始化s3客户端
$s3Config = Config::get('common.aws_s3');
$s3Client = new S3Client([
@ -158,24 +188,38 @@ class Upload extends AdminBaseController
'secret' => $s3Config['aws_secret'],
],
]);
// 初始化Multipart Upload
// 初始化分段上传,获取上传Id
$result = $s3Client->createMultipartUpload([
'Bucket' => $s3Config['aws_bucket'],
'Key' => 'bourse-video-node/' . $fileName,
'ContentType' => $getMime,
])->toArray();
Log::info("初始化分段上传结果:".json_encode($result));
if (empty($result['UploadId'])) {
return json(['code' => 500, 'message' => '初始化分片上传失败','data'=>$result]);
}
AwsS3Model::create([
'upload_id' => $result['UploadId'],
'key' => 'bourse-video-node/' . $fileName,
'name' => $fileName,
'mime' => $getMime,
'ext' => $getExt,
]);
return json([
'code' => 0,
'message' => 'success',
'data' => [
'uploadId' => $result['UploadId'],
'key' => $result['Key']
]
]);
} catch (\Exception $exception) {
return json(['code' => '100500', 'message' => '初始化上传失败', 'data' => [$exception->getMessage()]]);
return json(['code' => '500', 'message' => '初始化分段上传失败', 'data' => [$exception->getMessage()]]);
}
}
// 上传分片
// 上传每个分段
public function uploadPart(){
try {
$param = $this->request->param();
@ -186,6 +230,15 @@ class Upload extends AdminBaseController
if (!$file) {
return json(['code' => 400, 'message' => 'No file uploaded']);
}
// 每个分段大小限制 最大50M
if ($file->getSize() > 100 * 1024 * 1024) {
return json(['code' => 400, 'message' => 'File size is too large for multipart upload']);
}
// 打开文件
$openFile = fopen($file->getRealPath(), 'r');
if (!$openFile) {
return json(['code' => 400, 'message' => 'Failed to open file']);
}
// 初始化s3客户端
$s3Config = Config::get('common.aws_s3');
$s3Client = new S3Client([
@ -201,28 +254,43 @@ class Upload extends AdminBaseController
'Key' => $param['key'],
'PartNumber' => $param['partNumber'],
'UploadId' => $param['uploadId'],
'Body' => fopen($file->getRealPath(), 'r'),
]);
'Body' => $openFile,
])->toArray();
fclose($openFile);
Log::info("上传分段结果:".json_encode($result));
return json([
'code' => 200,
'message' => 'success',
'data' => [
'ETag' => $result['ETag'],
'PartNumber' => $param['partNumber']
'ETag' => $result['ETag'], // 每个分段的ETag
'PartNumber' => $param['partNumber'],
'key' => $param['key'], // 存储在s3桶中的key
]
]);
} catch (\Exception $exception) {
if (isset($openFile)) {
fclose($openFile);
}
return json(['code' => '100500', 'message' => '上传失败', 'data' => [$exception->getMessage()]]);
}
}
// 完成上传
// 完成分段上传
public function completeUpload(){
try {
$param = $this->request->param();
if (empty($param['uploadId']) || empty($param['key']) || empty($param['parts'])) {
if (empty($param['uploadId']) || empty($param['key'])) {
return json(['code' => 400, 'message' => '缺少参数']);
}
if (empty($param['parts']) || !is_array($param['parts'])) {
return json(['code' => 400, 'message' => 'parts参数错误']);
}
// 注意:$parts 是一个数组,里面需要有每个分段编号,以及每个分段对应的ETag
// $parts = [
// ['PartNumber' => 1, 'ETag' => 'etag-for-part-1'],
// ['PartNumber' => 2, 'ETag' => 'etag-for-part-2'],
// ];
// 初始化s3客户端
$s3Config = Config::get('common.aws_s3');
$s3Client = new S3Client([
@ -233,22 +301,38 @@ class Upload extends AdminBaseController
'secret' => $s3Config['aws_secret'],
],
]);
$s3Client->completeMultipartUpload([
$result = $s3Client->completeMultipartUpload([
'Bucket' => $s3Config['aws_bucket'],
'Key' => $param['key'],
'UploadId' => $param['uploadId'],
'MultipartUpload' => [
'Parts' => $param['parts']
],
]);
])->toArray();
Log::info("完成分段上传结果:".json_encode($result));
return json(['code' => 200, 'message' => '上传成功']);
// 更新分片上传记录
$awsS3 = AwsS3Model::where(['upload_id'=>$param['uploadId']])->find();
if (empty($awsS3)) {
return json(['code' => 500, 'message' => '数据记录错误']);
}
$awsS3->is_complete = 1;
$awsS3->parts = json_encode($param['parts']);
$awsS3->s3_url = $result['Location'];
$awsS3->save();
return json(['code' => 200, 'message' => '上传成功', 'data'=>[
'id' => $awsS3->id,
'uploadId' => $param['uploadId'],
'key' => $param['key'],
'location' => $result['Location'],
]]);
} catch (\Exception $exception) {
return json(['code' => '100500', 'message' => '完成上传失败', 'data' => [$exception->getMessage()]]);
}
}
// 取消上传
// 中止分段上传
public function abortUpload(){
try {
$param = $this->request->param();
@ -265,12 +349,12 @@ class Upload extends AdminBaseController
'secret' => $s3Config['aws_secret'],
],
]);
$s3Client->abortMultipartUpload([
$result = $s3Client->abortMultipartUpload([
'Bucket' => $s3Config['aws_bucket'],
'Key' => $param['key'],
'UploadId' => $param['uploadId'],
]);
Log::info('终止分段上传结果:'.json_encode($result));
return json(['code' => 200, 'message' => '上传已取消']);
} catch (\Exception $exception) {
return json(['code' => '100500', 'message' => '取消上传失败', 'data' => [$exception->getMessage()]]);

13
app/admin/controller/User.php

@ -72,6 +72,19 @@ class User extends AdminBaseController
return json($result);
}
public function get_loan()
{
$service = new UserService();
$result = $service->getUserLoan($this->request->param(),$this->getAdminId());
return json($result);
}
public function deal_loan()
{
$service = new UserService();
$result = $service->dealUserLoan($this->request->param(),$this->getAdminId());
return json($result);
}
##################### 查看验证码
public function getUserCode()
{

28
app/admin/controller/setting/Forex.php

@ -44,6 +44,34 @@ class Forex extends AdminBaseController
return json($result);
}
public function hq_index()
{
$service = new ForexService();
$result = $service->hq_index();
return json($result);
}
public function hq_add()
{
$service = new ForexService();
$result = $service->hq_add($this->request->param());
return json($result);
}
public function hq_edit()
{
$service = new ForexService();
$result = $service->hq_edit($this->request->param());
return json($result);
}
public function hq_del()
{
$service = new ForexService();
$result = $service->hq_del($this->request->param());
return json($result);
}
public function set_add()
{
$service = new ForexService();

4
app/admin/route/app.php

@ -14,7 +14,7 @@ $header = [
//Route::get('/test', 'Test/index');
Route::post('/test', 'Test/index');
Route::post('/test_upload', 'Upload/uploadVideo');
Route::post('test_api', 'Admin/sendEmailOrSms');
Route::post('test_api', 'Agent/customerUserList');
Route::group('/', function () {
// 上传图片
Route::post('/upload', 'Upload/upload');
@ -179,7 +179,7 @@ Route::group('/', function () {
Route::post('/agent/user', 'Agent/user');
Route::post('/agent/manager', 'Agent/manager');
Route::post('/agent/customer_list', 'Agent/customerList'); //客服列表,支持搜索某个代理下的客服
Route::post('/agent/customer_user_list', 'Agent/customerUserList'); //获取客服下所有用户
Route::post('agent/customer_user_list', 'Agent/customerUserList'); //获取客服下所有用户
Route::post('/agent/change_user_customer', 'Agent/changeUserCustomer')->middleware('admin_log'); //变更用户绑定的客服
Route::post('/agent/aws_ivs_list', 'Agent/awsIvsList'); //直播推流列表
Route::post('/agent/aws_ivs_add', 'Agent/awsIvsAdd')->middleware('admin_log'); //直播推流配置添加

26
app/admin/service/AdminBaseService.php

@ -5,6 +5,7 @@ namespace app\admin\service;
use app\model\AdminModel;
use app\model\ContractMarketModel;
use app\model\ContractSettingModel;
use app\model\ForexMarketModel;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\GuzzleException;
use think\db\exception\PDOException;
@ -380,6 +381,31 @@ class AdminBaseService
$redis->set($reds_key, json_encode($rows));
}
// 外汇插针缓存
public function initForexHqData()
{
$now = date('Y-m-d H:i:s');
$list = ForexMarketModel::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('FOREX:LIST:' . $val['selfContractCode'], 'keep_decimal');
$list[$key]['Digits'] = $keep_decimal;
}
}
$reds_key = "forex_hq_setting";
$redis->del($reds_key);
$redis->set($reds_key, json_encode($rows));
}
public function initContractSetting()
{
$list = ContractSettingModel::getSettingList();

29
app/admin/service/AgentService.php

@ -4,10 +4,8 @@ namespace app\admin\service;
use app\model\AdminModel;
use app\model\AgentChannelListModel;
use app\model\AuthGroupAccessModel;
use app\model\AuthRoleModel;
use app\model\AwsIvsModel;
use app\model\CustomerRelationalModel;
use app\model\ForexTradeModel;
use app\model\PurchaseVipModel;
use app\model\RechargeApplyModel;
@ -212,24 +210,17 @@ class AgentService extends AdminBaseService
if (empty($param['customer_id']) || !is_numeric($param['customer_id'])) {
return $this->toData('400', '参错错误');
}
if (empty($param['page']) || !is_numeric($param['page'])) {
if (empty($param['page']) || empty($param['limit'])) {
return $this->toData('400', '参错错误');
}
// 查询当前客服下的用户
$list = CustomerRelationalModel::where('customer_id', $param['customer_id'])->order('id', 'desc')->paginate([
$list = UserModel::where('customer_id', $param['customer_id'])->order('user_id', 'desc')->paginate([
'list_rows' => $param['limit'],
'page' => $param['page'], // 使用前端传递的页码
]);
$userIds = array_column($list->items(), 'user_id'); // 获取当前页的用户id
// 根据user_id查询用户列表
$userDetails = [];
if ($userIds) {
$userDetails = UserModel::whereIn('user_id', $userIds)->select()->toArray();
}
return $this->toData('0', 'success', [
'list' => $list->items(), // 当前页的数据
'user_details' => $userDetails,
'page' => $list->currentPage(), // 当前页码
'total' => $list->total(), // 总记录数
'last_page' => $list->lastPage(), // 最后一页页码
@ -246,21 +237,21 @@ class AgentService extends AdminBaseService
return $this->toData('400', '参数错误');
}
$cstRlt = CustomerRelationalModel::where(['user_id'=>$param['user_id'], 'customer_id'=>$param['old_customer_id']])->find();
if (empty($cstRlt)) {
return $this->toData('500', '操作的数据不存在');
$user = UserModel::where(['user_id'=>$param['user_id']])->find();
if (empty($user)) {
return $this->toData('500', '用户数据为空');
}
// 变更的客服必须是同一个代理
$newCustomer = AdminModel::where(['id'=>$param['new_customer_id']])->find();
if (empty($newCustomer)) {
return $this->toData('500', '要变更的客服不存在');
return $this->toData('500', '客服数据错误');
}
if ($newCustomer->parent_id != $cstRlt->agent_id) {
return $this->toData('500', '客服不属于同一个代理');
if ($newCustomer->parent_id != $user->agent_id) {
return $this->toData('500', '变更的客服不属于同一个代理');
}
// 变更客服绑定关系
$cstRlt->customer_id = $param['new_customer_id'];
$cstRlt->save();
$user->customer_id = $param['new_customer_id'];
$user->save();
// 将用户与新客服的聊天账号加好友
$userChatInfo = UserChatLinkModel::where(['user_id'=>$param['user_id'], 'user_type'=>UserChatLinkModel::USER_CHAT_LINK_USER_TYPE_PC])->find();

110
app/admin/service/UserService.php

@ -6,10 +6,9 @@ use app\admin\validate\UserValidate;
use app\home\service\BaseHomeService;
use app\model\AccountFrozenModel;
use app\model\AdminModel;
use app\model\AuthRoleModel;
use app\model\AwsS3Model;
use app\model\CountryModel;
use app\model\CustomerRelationalModel;
use app\model\FileModel;
use app\model\StockMarketModel;
use app\model\UserBankModel;
use app\model\UserChatLinkModel;
@ -17,6 +16,7 @@ use app\model\UserContractModel;
use app\model\UserContractSecModel;
use app\model\UserDigitalModel;
use app\model\UserForexModel;
use app\model\UserLoanModel;
use app\model\UserLoginLog;
use app\model\UserModel;
use app\model\UserStageStateModel;
@ -38,7 +38,6 @@ use app\model\UserStockFundModel;
use think\exception\ValidateException;
use app\utility\UnqId;
use think\facade\Cache;
use think\facade\Log;
class UserService extends AdminBaseService
{
@ -51,6 +50,27 @@ class UserService extends AdminBaseService
validate(UserValidate::class)->scene('index')->check($param);
$where = [];
// 角色数据权限过滤: 管理员登录可查看所有用户数据;代理登录查看代理下用户数据;客服登录查看客服关联用户的数据
$account = AdminModel::where(['id'=>$adminId])->find();
if (empty($account)) {
return $this->toData('500', '当前账号数据错误');
}
$role = AuthRoleModel::where(['id'=>$account->role_id])->find();
if (empty($role)) {
return $this->toData('500', '当前角色数据错误');
}
// 如果是代理,过滤代理下的用户
if ($role->name == AuthRoleModel::NAME_AGENT) {
$where['agent_id'] = $adminId;
}
// 如果是客服,过滤客服下的用户
if ($role->name == AuthRoleModel::NAME_CUSTOMER) {
$where['customer_id'] = $adminId;
}
// base_label过滤
if (!empty($param['base_label'])) {
$where['base_label'] = trim($param['base_label']);
@ -134,11 +154,15 @@ class UserService extends AdminBaseService
$rows = [];
$userIdArr = [];
$parentIdArr = [];
$customerRelationList = [];
foreach ($userList as $value) {
$userIdArr[] = $value['user_id'];
if ($value['parent_id'] > 0) {
$parentIdArr[] = $value['parent_id'];
}
if (!empty($value['customer_id'])) {
$customerRelationList[$value['user_id']] = $value['customer_id'];
}
}
// 查询父级
@ -219,8 +243,6 @@ class UserService extends AdminBaseService
->where('contract_id', 'USD')
->column('usable_num,frozen_num', 'user_id');
// 用户关联的客服id
$customerRelationList = CustomerRelationalModel::where('user_id', 'in', $userIdArr)->column('customer_id', 'user_id');
// 获取每个客服的名称
$customerNames = [];
if ($customerRelationList) {
@ -879,6 +901,84 @@ class UserService extends AdminBaseService
}
}
public function getUserLoan($param,$adminId)
{
try {
$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(isset($param['status'])){
$where['status']=intval($param['status']);
}
$data['where']=$where;
$data['page']=isset($param['page']) ? intval($param['page']) : 1;
$data['size']=isset($param['size']) ? intval($param['size']) : 10;
$list = UserLoanModel::getUserLoanList($data);
if(!empty($list['list'])){
foreach ($list['list'] as $key=>$item){
$user= UserModel::where('user_id', $item['user_id'])->find();
$list['list'][$key]['nick_name']=$user->nick_name;
}
}
return $this->toData('0', 'SUCCESS', $list);
} catch (\Exception $exception) {
return $this->toData('1', '系统繁忙', [$exception->getMessage(),$exception->getTrace()]);
}
}
public function dealUserLoan($param,$adminId)
{
try {
$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);
$where['id']=intval($param['id']);
$info=UserLoanModel::where($where)->find();
if(empty($info)){
return $this->toData('1', '数据不存在');
}
if($info['status']!=0){
return $this->toData('1', '数据已审核');
}
UserLoanModel::where($where)->update([
'status'=>intval($param['status']),
'update_time'=>date('Y-m-d H:i:s')
]);
return $this->toData('0', 'SUCCESS', []);
} catch (\Exception $exception) {
return $this->toData('1', '系统繁忙', [$exception->getMessage()]);
}
}
// 获取用户验证码
public function getUserCode($param)

162
app/admin/service/setting/ForexService.php

@ -3,11 +3,14 @@
namespace app\admin\service\setting;
use app\admin\service\AdminBaseService;
use app\admin\validate\setting\HqValidate;
use app\home\service\BaseHomeService;
use app\model\ContractListMode;
use app\model\ContractSettingModel;
use app\model\ContractTradeModel;
use app\model\ForexListModel;
use app\model\ForexMarketModel;
use think\exception\ValidateException;
use think\facade\Cache;
class ForexService extends AdminBaseService
@ -267,4 +270,163 @@ class ForexService extends AdminBaseService
}
}
public function hq_index()
{
try {
$list = ForexMarketModel::where('type', 0)->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 hq_add($param)
{
try {
// 参数校验
validate(HqValidate::class)->scene('add')->check($param);
// 已存在未执行的 不能再插入
$count = ForexMarketModel::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 = ForexMarketModel::whereOr([$map1,$map2])
->count();
if($count > 0){
return $this->toData('1','时间无效-时间不能有交叉');
}
$market = new ForexMarketModel;
$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->initForexHqData();
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 hq_edit($param)
{
try {
// 参数校验
validate(HqValidate::class)->scene('edit')->check($param);
// 已存在未执行的 不能再插入
$count = ForexMarketModel::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 = ForexMarketModel::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 = ForexMarketModel::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->is_get = 1;
$market->step = $param['step'];
$market->save();
// redis
$this->initForexHqData();
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 hq_del($param)
{
try {
// 参数校验
validate(HqValidate::class)->scene('del')->check($param);
// 目标
$market = ForexMarketModel::where('id', $param['id'])->find();
if(empty($market)){
return $this->toData('1','目标不存在');
}
$market->delete();
$this->initForexHqData();
return $this->toData('0','SUCCESS');
}catch (ValidateException $validateException){
return $this->toData('12', $validateException->getMessage(), []);
}catch (\Exception $exception){
return $this->toData('11', '系统繁忙', [$exception->getMessage()]);
}
}
}

15
app/admin/service/setting/IPOService.php

@ -1609,6 +1609,21 @@ class IPOService extends AdminBaseService
'check' => 'jp_stock_',
];
break;
case 19:
$result = [
// 'stock_table' => $prefix . 'pre_jp_stock',
// 'order_table' => $prefix . 'user_jp_pre_stock_order',
'user_table' => $prefix . 'user_forex',
'log_table' => $prefix . 'user_forex_log',
'list_table' => $prefix . 'forex_list',
'trade_table' => $prefix . 'forex_trade',
// 'give_order_table' => $prefix . 'user_jp_give_stock_order',
'redis_key' => 'FOREX:STOCK:LIST:',
'stock_id' => 'FOREX',
// 'country' => 'Japan',
'check' => 'forex_stock_',
];
break;
default:
$result = [];
break;

6
app/home/job/SendEmail.php

@ -16,7 +16,7 @@ class SendEmail
*/
public function fire(Job $job, $data)
{
trace('新任务', 'info');
trace('发送邮件任务开始', 'info');
$phpEmail = new \app\utility\SendEmail();
$success = false;
for($times = 1; $times <= 3; $times++) {
@ -25,13 +25,11 @@ class SendEmail
$success = true;
break;
}
trace($job->getJobId().'---重试-----'.$times, 'info');
}
// 任务失败
if (!$success) {
trace($job->getJobId().'---失败-------'.json_encode($data), 'info');
trace($job->getJobId().'---发送邮件任务失败-------'.json_encode($data), 'info');
}
// 删除任务

30
app/home/job/SendSms.php

@ -38,29 +38,17 @@ class SendSms
*/
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++;
}
trace($job->getJobId().'---发送短信任务开始--------'.json_encode($data), 'info');
$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);
$from = 'Bourse';
$accessKey = env('SMS.ACCESS_KEY_ID');
$secret = env('SMS.ACCESS_KEY_SECRET');
if (empty($accessKey) || empty($secret)) {
trace('------- 短信账号配置错误 -------', 'error');
return;
}
(new \app\utility\SendSms())->sendMessageToGlobe($to, $message, $from, $accessKey, $secret);
// 删除任务
$job->delete();
}

42
app/home/service/LoginService.php

@ -2,24 +2,19 @@
namespace app\home\service;
use app\home\controller\User;
use app\home\validate\LoginValidate;
use app\model\AdminModel;
use app\model\CountryModel;
use app\model\CustomerRelationalModel;
use app\model\EmailTemplateModel;
use app\model\UserChatGroupModel;
use app\model\UserChatLinkModel;
use app\model\UserModel;
use app\utility\Jwt;
use app\utility\SendSms;
use app\utility\UnqId;
use Psr\SimpleCache\InvalidArgumentException;
use think\exception\ValidateException;
use think\facade\Cache;
use think\facade\Log;
use think\facade\Queue;
use think\queue\Job;
use GeoIp2\Database\Reader;
class LoginService extends BaseHomeService
@ -97,10 +92,10 @@ class LoginService extends BaseHomeService
// 获取客户端ip
$ip = $this->getClientRealIp();
$param['invite_code'] = $param['invite_code'] ?? '';
$param['agent_code'] = $param['agent_code'] ?? '';
$param['invite_code'] = $param['invite_code'] ?? ''; // 邀请码,可以是管理端的非代理账号,也可以是user表的用户
$param['agent_code'] = $param['agent_code'] ?? ''; // 代理
$chCode = $param['ch_code'] ?? ''; // 注册渠道标识码
$phone = $param['phone']; //p3定制需求-邮箱注册必须传手机号
$phone = $param['phone']; //p2定制需求-邮箱注册必须传手机号
// 邮件注册参数校验
validate(LoginValidate::class)->scene('emailRegister')->check($param);
@ -231,31 +226,24 @@ class LoginService extends BaseHomeService
// 如果有代理,绑定到代理下一个客服(轮询客服绑定)
if ($agentId > 0 ) {
$customerIds = AdminModel::getCustomerIdsByAgentId($agentId); // 获取代理下的所有客服ID
Log::info("邮箱注册 - 代理下客服ids=".json_encode($customerIds));
if (empty($customerIds)) {
return $this->toData('100400', 'There is no customer service account under the current agent', []);
return $this->toData('500', 'There is no customer service account under the current agent');
}
$counterKey = 'counter_bind_customer:'.$agentId;
$counterKey = 'counter_of_bind_customer:'.$agentId;
$counterIndex = Cache::store('redis')->get($counterKey); //客服绑定计数器索引
if (empty($counterIndex)) {
$counterIndex = 0;
Cache::store('redis')->set($counterKey, $counterIndex);
Cache::store('redis')->set($counterKey, 1);
$tagCustomerId = $customerIds[0];
} else {
Cache::store('redis')->inc($counterKey); //更新计数器索引
$tagIndex = $counterIndex % count($customerIds);
$tagCustomerId = $customerIds[$tagIndex];
}
Log::info("邮箱注册 - 要绑定的客服id=".$tagCustomerId);
if ($tagCustomerId > 0) {
CustomerRelationalModel::create([
'user_id' => $userId,
'customer_id' => $tagCustomerId,
'agent_id' => $agentId,
]);
$regUser->customer_id = $tagCustomerId;
$regUser->save();
}
// 将注册账号的chat_id与绑定客服的chat_id加为好友
Log::info("邮箱注册 - 获取去客服聊天账号信息, $tagCustomerId=".$tagCustomerId);
$customerChatInfo = UserChatLinkModel::where(['user_id'=>$tagCustomerId, 'user_type'=>UserChatLinkModel::USER_CHAT_LINK_USER_TYPE_ADMIN])->find(); //查询客服的聊天账号uuid
if (empty($customerChatInfo)) {
return $this->toData('100400', 'The customer uuid is error.', []);
@ -577,13 +565,12 @@ class LoginService extends BaseHomeService
if ($agentId > 0 ) {
$customerIds = AdminModel::getCustomerIdsByAgentId($agentId); // 获取代理下的所有客服ID
if (empty($customerIds)) {
return $this->toData('100400', 'There is no customer service account under the current agent', []);
return $this->toData('500', 'There is no customer service account under the current agent', []);
}
$counterKey = 'counter_bind_customer:'.$agentId;
$counterKey = 'counter_of_bind_customer:'.$agentId;
$counterIndex = Cache::store('redis')->get($counterKey); //客服绑定计数器索引
if (empty($counterIndex)) {
$counterIndex = 0;
Cache::store('redis')->set($counterKey, $counterIndex);
Cache::store('redis')->set($counterKey, 1);
$tagCustomerId = $customerIds[0];
} else {
Cache::store('redis')->inc($counterKey); //更新计数器索引
@ -591,11 +578,8 @@ class LoginService extends BaseHomeService
$tagCustomerId = $customerIds[$tagIndex];
}
if ($tagCustomerId > 0) {
CustomerRelationalModel::create([
'user_id' => $userId,
'customer_id' => $tagCustomerId,
'agent_id' => $agentId,
]);
$regUser->customer_id = $tagCustomerId;
$regUser->save();
}
// 将注册账号的chat_id与绑定客服的chat_id加为好友
$customerChatInfo = UserChatLinkModel::where(['user_id'=>$tagCustomerId,'user_type'=>UserChatLinkModel::USER_CHAT_LINK_USER_TYPE_ADMIN])->find(); //查询客服的聊天账号uuid

3
app/home/service/StockService.php

@ -79,6 +79,8 @@ class StockService extends BaseHomeService
return $this->toData('400','缺少参数');
}
// p4项目无限制调用股票分析接口
if (!isset($param['project']) || $param['project'] != 'p4') {
// 检测用户调用该接口次数,普通用户只能调用5次,vip用户可以无限次调用
$apiCalledNum = ApiCalledNumModel::where(['user_id'=>$userId])->find();
if (!empty($apiCalledNum) && $apiCalledNum->stock_api >= ApiCalledNumModel::API_CALLED_LIMIT) {
@ -91,6 +93,7 @@ class StockService extends BaseHomeService
}
}
}
}
$replaceData = [
'{stock_code}' => $param['stock_code']

8
app/home/service/UserService.php

@ -7,7 +7,6 @@ use app\model\ApiCalledNumModel;
use app\model\AwsIvsModel;
use app\model\AwsS3Model;
use app\model\CountryModel;
use app\model\CustomerRelationalModel;
use app\model\FileModel;
use app\model\PurchaseVipLogModel;
use app\model\PurchaseVipModel;
@ -143,7 +142,7 @@ class UserService extends BaseHomeService
return $this->toData('100403', 'Please log in first', []);
}
$info = UserModel::getFieldsByUserId('trade_password,lever_status,gender,last_name,first_name,real_status,country_id,user_no,nick_name,email,phone_number,country_code,agent_id,is_real,head_img_id,invite_code,is_test_user,customer_remark,label', $userId);
$info = UserModel::getFieldsByUserId('trade_password,lever_status,gender,last_name,first_name,real_status,country_id,user_no,nick_name,email,phone_number,country_code,agent_id,customer_id,is_real,head_img_id,invite_code,is_test_user,customer_remark,label', $userId);
if (empty($info)) {
return $this->toData('100400', 'The user does not exist.', []);
}
@ -184,9 +183,8 @@ class UserService extends BaseHomeService
// 查询用户绑定的客服chat_uuid
$customerChatUuid = "";
$customerChatName = "";
$customerRelationInfo = CustomerRelationalModel::where('user_id', $userId)->find(); //查询用户关联的客服账号信息
if ($customerRelationInfo) {
$customerChatInfo = UserChatLinkModel::where(['user_id'=>$customerRelationInfo->customer_id, 'user_type'=>UserChatLinkModel::USER_CHAT_LINK_USER_TYPE_ADMIN])->find(); //查询客服的chat账号
if (!empty($info['customer_id'])) {
$customerChatInfo = UserChatLinkModel::where(['user_id'=>$info['customer_id'], 'user_type'=>UserChatLinkModel::USER_CHAT_LINK_USER_TYPE_ADMIN])->find();
if ($customerChatInfo) {
$customerChatUuid = $customerChatInfo->chat_uuid;
$customerChatName = $customerChatInfo->chat_name;

6
app/model/AdminModel.php

@ -82,6 +82,10 @@ class AdminModel extends BaseModel
public static function getCustomerIdsByAgentId($agentId): array
{
return self::where('parent_id', $agentId)->column('id');
$role = AuthRoleModel::where(['name'=>'客服'])->find();
if (empty($role)) {
return [];
}
return self::where(['role_id'=>$role->id,'parent_id'=>$agentId])->column('id');
}
}

11
app/model/ForexMarketModel.php

@ -0,0 +1,11 @@
<?php
namespace app\model;
class ForexMarketModel extends BaseModel
{
protected $name = 'forex_market';
const TYPE_DIGITAL_SELF = 2; // 自发行情现货
}

3
composer.json

@ -33,7 +33,8 @@
"geoip2/geoip2": "2.13",
"guzzlehttp/guzzle": "^7.7",
"lcobucci/jwt": "^4.0",
"phpoffice/phpspreadsheet": "^1.29"
"phpoffice/phpspreadsheet": "^1.29",
"ext-json": "*",
},
"require-dev": {
"symfony/var-dumper": "^4.2",

Loading…
Cancel
Save