|
|
@ -2,36 +2,54 @@ |
|
|
|
|
|
|
|
namespace app\admin\service; |
|
|
|
|
|
|
|
use app\admin\middleware\AdminLog; |
|
|
|
use app\admin\validate\AdminValidate; |
|
|
|
use app\home\service\BaseHomeService; |
|
|
|
use app\model\AdminLogModel; |
|
|
|
use app\model\AdminModel; |
|
|
|
use app\model\AuthRoleModel; |
|
|
|
use app\model\EmailTemplateModel; |
|
|
|
use app\model\GroupLeaderWithUserModel; |
|
|
|
use app\model\PurchaseVipLogModel; |
|
|
|
use app\model\PurchaseVipModel; |
|
|
|
use app\model\SmsTemplateModel; |
|
|
|
use app\model\SellerWithUserModel; |
|
|
|
use app\model\TranslatorCustomerModel; |
|
|
|
use app\model\UserAccessLogModel; |
|
|
|
use app\model\UserChatGroupModel; |
|
|
|
use app\model\UserChatLinkModel; |
|
|
|
use app\model\UserModel; |
|
|
|
use app\model\UserStockLogModel; |
|
|
|
use app\model\UserStockModel; |
|
|
|
use phpDocumentor\Reflection\Type; |
|
|
|
use think\facade\Cache; |
|
|
|
use think\exception\ValidateException; |
|
|
|
use app\utility\UnqId; |
|
|
|
use think\facade\Config; |
|
|
|
use think\facade\Db; |
|
|
|
use think\facade\Log; |
|
|
|
use think\facade\Queue; |
|
|
|
use function Sodium\compare; |
|
|
|
use think\facade\Request; |
|
|
|
|
|
|
|
|
|
|
|
class AdminService extends AdminBaseService |
|
|
|
{ |
|
|
|
const BATCH_SMS_LIST_KEY = "BATCH_SMS_LIST_KEY"; // 批量发送短信redis Key |
|
|
|
const BATCH_SMS_CONTENT_KEY = "BATCH_SMS_CONTENT_KEY"; // 批量发送短信内容Key |
|
|
|
const BATCH_EMAIL_LIST_KEY = "BATCH_EMAIL_LIST_KEY"; // 批量发送邮件redis Key |
|
|
|
const BATCH_EMAIL_CONTENT_KEY = "BATCH_EMAIL_CONTENT_KEY"; // 邮件内容redis key |
|
|
|
|
|
|
|
// 根据角色获取账号列表 |
|
|
|
public function getUsersByRole($param) |
|
|
|
{ |
|
|
|
try { |
|
|
|
if (!isset($param['role_name'])) { |
|
|
|
return $this->toData('400', '缺少参数'); |
|
|
|
} |
|
|
|
$role = AuthRoleModel::where(['name'=>$param['role_name']])->find(); |
|
|
|
if (empty($role)) { |
|
|
|
return $this->toData('500', '没有目标角色信息'); |
|
|
|
} |
|
|
|
// 根据角色查询账号列表 |
|
|
|
$users = AdminModel::where(['role_id'=>$role->id])->select()->toArray(); |
|
|
|
return $this->toData('0', 'ok', $users); |
|
|
|
} catch (\Exception $e) { |
|
|
|
return $this->toData('500', '系统错误', [$e->getMessage(), $e->getTrace()]); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
public function addUser($param): array |
|
|
|
{ |
|
|
@ -242,8 +260,9 @@ class AdminService extends AdminBaseService |
|
|
|
$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['email'] = $param['email'] ?? null; |
|
|
|
$user['remark'] = $param['remark'] ?? null; |
|
|
|
$user['parent_id'] = $param['parent_id'] ?? 0; |
|
|
|
$user->save(); |
|
|
|
// 返回 |
|
|
|
return $this->toData('0', 'Modification successful.', []); |
|
|
@ -532,6 +551,84 @@ class AdminService extends AdminBaseService |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// 组长与用户添加chat好友 |
|
|
|
public function groupLeaderWithUser($param) |
|
|
|
{ |
|
|
|
try { |
|
|
|
if (empty($param['group_leader_id']) || empty($param['user_id'])) { |
|
|
|
return $this->toData('400', '缺少参数'); |
|
|
|
} |
|
|
|
|
|
|
|
$relation = GroupLeaderWithUserModel::where(['user_id'=>$param['user_id']])->find(); |
|
|
|
if (empty($relation)) { |
|
|
|
$res = GroupLeaderWithUserModel::create([ |
|
|
|
'user_id' => $param['user_id'], |
|
|
|
'group_leader_id' => $param['group_leader_id'] |
|
|
|
]); |
|
|
|
if (empty($res->id)) { |
|
|
|
return $this->toData('0', '操作失败'); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
$adminUserChat = UserChatLinkModel::where(['user_id'=>$param['group_leader_id'], 'user_type'=>UserChatLinkModel::USER_CHAT_LINK_USER_TYPE_ADMIN])->find(); |
|
|
|
if (empty($adminUserChat)) { |
|
|
|
return $this->toData('400', '管理端账号缺少chat信息'); |
|
|
|
} |
|
|
|
$frontUserChat = UserChatLinkModel::where(['user_id'=>$param['user_id'], 'user_type'=>UserChatLinkModel::USER_CHAT_LINK_USER_TYPE_PC])->find(); |
|
|
|
if (empty($frontUserChat)) { |
|
|
|
return $this->toData('400', '用户账号缺少chat信息'); |
|
|
|
} |
|
|
|
$chatFriendsData = [ |
|
|
|
'UserUuid' => $frontUserChat->chat_uuid, |
|
|
|
'CustomerUuid' => $adminUserChat->chat_uuid, |
|
|
|
]; |
|
|
|
$chatFriendsUrl = env('CHAT_SERVER.BASE_URL') . '/api/eachOtherFriends'; |
|
|
|
$chatFriendsRes = (new \app\utility\RequestChatServer())->ReqChatServer($chatFriendsUrl, $chatFriendsData); |
|
|
|
return $this->toData('0', 'ok', $chatFriendsRes); |
|
|
|
} catch (\Exception $e) { |
|
|
|
return $this->toData('500', '系统错误', [$e->getMessage(), $e->getTrace()]); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// 电销与用户添加chat好友 |
|
|
|
public function sellerWithUser($param) |
|
|
|
{ |
|
|
|
try { |
|
|
|
if (empty($param['seller_id']) || empty($param['user_id'])) { |
|
|
|
return $this->toData('400', '缺少参数'); |
|
|
|
} |
|
|
|
|
|
|
|
$relation = SellerWithUserModel::where(['user_id'=>$param['user_id']])->find(); |
|
|
|
if (empty($relation)) { |
|
|
|
$res = SellerWithUserModel::create([ |
|
|
|
'user_id' => $param['user_id'], |
|
|
|
'seller_id' => $param['seller_id'] |
|
|
|
]); |
|
|
|
if (empty($res->id)) { |
|
|
|
return $this->toData('0', '操作失败'); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
$adminUserChat = UserChatLinkModel::where(['user_id'=>$param['seller_id'], 'user_type'=>UserChatLinkModel::USER_CHAT_LINK_USER_TYPE_ADMIN])->find(); |
|
|
|
if (empty($adminUserChat)) { |
|
|
|
return $this->toData('400', '管理端账号缺少chat信息'); |
|
|
|
} |
|
|
|
$frontUserChat = UserChatLinkModel::where(['user_id'=>$param['user_id'], 'user_type'=>UserChatLinkModel::USER_CHAT_LINK_USER_TYPE_PC])->find(); |
|
|
|
if (empty($frontUserChat)) { |
|
|
|
return $this->toData('400', '用户账号缺少chat信息'); |
|
|
|
} |
|
|
|
$chatFriendsData = [ |
|
|
|
'UserUuid' => $frontUserChat->chat_uuid, |
|
|
|
'CustomerUuid' => $adminUserChat->chat_uuid, |
|
|
|
]; |
|
|
|
$chatFriendsUrl = env('CHAT_SERVER.BASE_URL') . '/api/eachOtherFriends'; |
|
|
|
$chatFriendsRes = (new \app\utility\RequestChatServer())->ReqChatServer($chatFriendsUrl, $chatFriendsData); |
|
|
|
return $this->toData('0', 'ok', $chatFriendsRes); |
|
|
|
} catch (\Exception $e) { |
|
|
|
return $this->toData('500', '系统错误', [$e->getMessage(), $e->getTrace()]); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// 用户访问页面的记录 |
|
|
|
public function getUserAccessLog($param) |
|
|
|
{ |
|
|
@ -698,4 +795,151 @@ class AdminService extends AdminBaseService |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// 批量发送短信或邮件 |
|
|
|
public function batchSendEmailOrSms($param) |
|
|
|
{ |
|
|
|
try { |
|
|
|
// type: 1-短信,2-邮件 |
|
|
|
if (!in_array($param['type'], [1,2])) { |
|
|
|
return $this->toData('400', '发送类型不在支持范围内'); |
|
|
|
} |
|
|
|
// content: 发送的消息内容 |
|
|
|
if (empty($param['content'])) { |
|
|
|
return $this->toData('400', '消息内容不能为空'); |
|
|
|
} |
|
|
|
// user_ids: 要发送的用户ID, 数组格式 |
|
|
|
if (empty($param['user_ids']) || !is_array($param['user_ids'])) { |
|
|
|
return $this->toData('400', '用户ID错误'); |
|
|
|
} |
|
|
|
|
|
|
|
switch ($param['type']) { |
|
|
|
case 1: // 发送短信 |
|
|
|
$userList = UserModel::where('user_id', 'in', $param['user_ids'])->column('phone_number', 'user_id'); |
|
|
|
if (empty($userList)) { |
|
|
|
return $this->toData('500', '用户列表为空'); |
|
|
|
} |
|
|
|
// 将短信内容存储在redis中 |
|
|
|
Cache::store('redis')->set(self::BATCH_SMS_CONTENT_KEY, $param['content']); |
|
|
|
// 将用户手机号存储到redis list中 |
|
|
|
foreach ($userList as $phone) { |
|
|
|
if (empty($phone)) { |
|
|
|
continue; |
|
|
|
} |
|
|
|
Cache::store('redis')->lpush(self::BATCH_SMS_LIST_KEY, $phone); |
|
|
|
} |
|
|
|
break; |
|
|
|
case 2: // 发送邮件 |
|
|
|
if (empty($param['title'])) { |
|
|
|
return $this->toData('400', '邮件标题不能为空'); |
|
|
|
} |
|
|
|
$userList = UserModel::where('user_id', 'in', $param['user_ids'])->column('email', 'user_id'); |
|
|
|
if (empty($userList)) { |
|
|
|
return $this->toData('500', '用户列表为空'); |
|
|
|
} |
|
|
|
// 将邮件内容存储在redis中 |
|
|
|
$buildContent = $param['title']."@".$param['content']; |
|
|
|
Cache::store('redis')->set(self::BATCH_EMAIL_CONTENT_KEY, $buildContent); |
|
|
|
// 将用邮箱存储到redis list中 |
|
|
|
foreach ($userList as $email) { |
|
|
|
if (empty($email)) { |
|
|
|
continue; |
|
|
|
} |
|
|
|
Cache::store('redis')->lpush(self::BATCH_EMAIL_LIST_KEY, $email); |
|
|
|
} |
|
|
|
break; |
|
|
|
default: |
|
|
|
return $this->toData('500', '操作类型错误', []); |
|
|
|
} |
|
|
|
|
|
|
|
return $this->toData('0', 'ok'); |
|
|
|
} catch (\Exception $e) { |
|
|
|
return $this->toData('500', 'The system is busy', [$e->getMessage(), $e->getTrace()]); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// 定时任务处理匹批量发送短信 |
|
|
|
public function execBatchSendSms() |
|
|
|
{ |
|
|
|
try { |
|
|
|
// 每次处理2000个用户 |
|
|
|
$maxNum = 2000; |
|
|
|
$smsLen = Cache::store('redis')->llen(self::BATCH_SMS_LIST_KEY); |
|
|
|
if ($smsLen <= 0) { |
|
|
|
return; |
|
|
|
} |
|
|
|
if ($smsLen < $maxNum) { |
|
|
|
$maxNum = $smsLen; |
|
|
|
} |
|
|
|
$accessKey = env('SMS.ACCESS_KEY_ID'); |
|
|
|
$secret = env('SMS.ACCESS_KEY_SECRET'); |
|
|
|
if (empty($accessKey) || empty($secret)) { |
|
|
|
Log::info("批量短信发送 - 短信配置数据未找到"); |
|
|
|
return; |
|
|
|
} |
|
|
|
$content = Cache::store('redis')->get(self::BATCH_SMS_CONTENT_KEY); |
|
|
|
if (empty($content)) { |
|
|
|
Log::info("批量短信发送 - 短信内容不能为空"); |
|
|
|
return; |
|
|
|
} |
|
|
|
$smsObj = new \app\utility\SendSms(); |
|
|
|
for ($i=1; $i<=$maxNum; $i++) { |
|
|
|
$phone = Cache::store('redis')->rpop(self::BATCH_SMS_LIST_KEY); |
|
|
|
if (empty($phone)) { |
|
|
|
continue; |
|
|
|
} |
|
|
|
$from = 'Auto'; |
|
|
|
$bool = $smsObj->sendMessageToGlobe($phone, $content, $from, $accessKey, $secret); |
|
|
|
if (!$bool) { |
|
|
|
Log::info("批量短信发送 - 当前用户发送失败, phone=".$phone); |
|
|
|
} |
|
|
|
} |
|
|
|
return $this->toData('0', 'ok'); |
|
|
|
} catch (\Exception $e) { |
|
|
|
Log::info("批量短信发送异常:err==". $e->getMessage()." trace==".$e->getTraceAsString()); |
|
|
|
return $this->toData('500', 'The system is busy', [$e->getMessage(), $e->getTrace()]); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// 定时任务执行批量发送邮件任务 |
|
|
|
public function execBatchSendEmail(){ |
|
|
|
try { |
|
|
|
// 每次处理2000个用户 |
|
|
|
$maxNum = 2000; |
|
|
|
$emailLen = Cache::store('redis')->llen(self::BATCH_EMAIL_LIST_KEY); |
|
|
|
if ($emailLen <= 0) { |
|
|
|
return; |
|
|
|
} |
|
|
|
if ($emailLen < $maxNum) { |
|
|
|
$maxNum = $emailLen; |
|
|
|
} |
|
|
|
$content = Cache::store('redis')->get(self::BATCH_EMAIL_CONTENT_KEY); |
|
|
|
if (empty($content)) { |
|
|
|
Log::info("批量邮件发送 - 邮件内容不能为空"); |
|
|
|
return; |
|
|
|
} |
|
|
|
// 邮件内容需要以@符号分割,然后获取到title 和 content |
|
|
|
$splStr = explode('@', $content); |
|
|
|
$title = $splStr[0]; |
|
|
|
$msg = $splStr[1]; |
|
|
|
$phpEmail = new \app\utility\SendEmail(); |
|
|
|
for ($i=1; $i<=$maxNum; $i++) { |
|
|
|
$email = Cache::store('redis')->rpop(self::BATCH_EMAIL_LIST_KEY); |
|
|
|
if (empty($email)) { |
|
|
|
continue; |
|
|
|
} |
|
|
|
$emailTemplate['email'] = $email; |
|
|
|
$title = trim($title); |
|
|
|
$content = trim($msg); |
|
|
|
$bool = $phpEmail->sendEmail($emailTemplate['email'], $title, $content); |
|
|
|
if (!$bool) { |
|
|
|
Log::info("批量发送邮件 - 当前用户发送失败, email=".$email); |
|
|
|
} |
|
|
|
} |
|
|
|
return $this->toData('0', 'ok'); |
|
|
|
} catch (\Exception $e) { |
|
|
|
Log::info("批量短信发送异常:err==". $e->getMessage()." trace==".$e->getTraceAsString()); |
|
|
|
return $this->toData('500', 'The system is busy', [$e->getMessage(), $e->getTrace()]); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|