存客宝应用接口初始化

This commit is contained in:
Ghost
2026-01-05 10:25:32 +08:00
parent fa37227954
commit 02797ba50a
414 changed files with 85530 additions and 75 deletions

View File

@@ -0,0 +1,748 @@
<?php
namespace app\api\controller;
use app\api\model\CompanyAccountModel;
use app\api\model\CompanyModel;
use Library\S2\Logics\AccountLogic;
use think\Db;
use think\facade\Request;
/**
* 账号管理控制器
* 包含账号管理和部门管理的相关功能
*/
class AccountController extends BaseController
{
/************************ 账号管理相关接口 ************************/
/**
* 获取公司账号列表
* @param string $pageIndex 页码
* @param string $pageSize 每页数量
* @param bool $isInner 是否为定时任务调用
* @return \think\response\Json
*/
public function getlist($data = [], $isInner = false)
{
$pageIndex = !empty($data['pageIndex']) ? $data['pageIndex'] : 0;
$pageSize = !empty($data['pageSize']) ? $data['pageSize'] : 20;
$showNormalAccount = !empty($data['showNormalAccount']) ? $data['showNormalAccount'] : '';
$keyword = !empty($data['keyword']) ? $data['keyword'] : '';
$departmentId = !empty($data['departmentId']) ? $data['departmentId'] : '';
// 获取授权token
$authorization = trim($this->request->header('authorization', $this->authorization));
if (empty($authorization)) {
if ($isInner) {
return json_encode(['code' => 500, 'msg' => '缺少授权信息']);
} else {
return errorJson('缺少授权信息');
}
}
try {
// 构建请求参数
$params = [
'showNormalAccount' => $showNormalAccount,
'keyword' => $keyword,
'departmentId' => $departmentId,
'pageIndex' => $pageIndex,
'pageSize' => $pageSize
];
// 设置请求头
$headerData = ['client:system'];
$header = setHeader($headerData, $authorization, 'plain');
// 发送请求获取公司账号列表
$result = requestCurl($this->baseUrl . 'api/Account/myTenantPageAccounts', $params, 'GET', $header);
$response = handleApiResponse($result);
// 保存数据到数据库
if (!empty($response['results'])) {
foreach ($response['results'] as $item) {
$this->saveAccount($item);
}
}
if ($isInner) {
return json_encode(['code' => 200, 'msg' => '获取公司账号列表成功', 'data' => $response]);
} else {
return successJson($response);
}
} catch (\Exception $e) {
if ($isInner) {
return json_encode(['code' => 500, 'msg' => '获取公司账号列表失败:' . $e->getMessage()]);
} else {
return errorJson('获取公司账号列表失败:' . $e->getMessage());
}
}
}
/**
* 创建新账号
* @return \think\response\Json
*/
public function createAccount()
{
// 获取授权token
$authorization = trim($this->request->header('authorization', $this->authorization));
if (empty($authorization)) {
return errorJson('缺少授权信息');
}
try {
// 获取并验证请求参数
$userName = $this->request->param('userName', '');
$password = $this->request->param('password', '');
$realName = $this->request->param('realName', '');
$nickname = $this->request->param('nickname', '');
$memo = $this->request->param('memo', '');
$departmentId = $this->request->param('departmentId', 0);
// 参数验证
if (empty($userName)) {
return errorJson('用户名不能为空');
}
// if (!preg_match('/^[a-zA-Z][a-zA-Z0-9]{5,9}$/', $userName)) {
// return errorJson('用户名必须以字母开头只能包含字母和数字长度6-10位');
// }
if (empty($password)) {
return errorJson('密码不能为空');
}
if (empty($realName)) {
return errorJson('真实姓名不能为空');
}
if (empty($departmentId)) {
return errorJson('公司ID不能为空');
}
// 检查账号是否已存在
$existingAccount = CompanyAccountModel::where('userName', $userName)->find();
if (!empty($existingAccount)) {
return errorJson('账号已存在');
}
// 构建请求参数
$params = [
'userName' => $userName,
'password' => $password,
'realName' => $realName,
'nickname' => $nickname,
'memo' => $memo,
'departmentId' => $departmentId,
'departmentIdArr' => empty($departmentId) ? [914] : [914, $departmentId]
];
// 设置请求头
$headerData = ['client:system'];
$header = setHeader($headerData, $authorization, 'json');
// 发送请求创建账号
$result = requestCurl($this->baseUrl . 'api/account/newAccount', $params, 'POST', $header, 'json');
if (is_numeric($result)) {
$res = CompanyAccountModel::create([
'id' => $result,
'tenantId' => 242,
'userName' => $userName,
'realName' => $realName,
'nickname' => $nickname,
'passwordMd5' => md5($password),
'passwordLocal' => localEncrypt($password),
'memo' => $memo,
'accountType' => 11,
'departmentId' => $departmentId,
'createTime' => time(),
'privilegeIds' => json_encode([])
]);
$this->setPrivileges(['id' => $result]);
return successJson($res);
} else {
return errorJson($result);
}
} catch (\Exception $e) {
return errorJson('创建账号失败:' . $e->getMessage());
}
}
/**
* 创建新账号(包含创建部门)
* @return \think\response\Json
*/
public function createNewAccount()
{
// 获取授权token
$authorization = trim($this->request->header('authorization', $this->authorization));
if (empty($authorization)) {
return errorJson('缺少授权信息');
}
DB::startTrans();
try {
// 获取参数
$departmentName = $this->request->param('departmentName', '');
$departmentMemo = $this->request->param('departmentMemo', '');
$accountName = $this->request->param('accountName', '');
$accountPassword = $this->request->param('accountPassword', '');
$accountRealName = $this->request->param('accountRealName', '');
$accountNickname = $this->request->param('accountNickname', '');
$accountMemo = $this->request->param('accountMemo', '');
// 验证参数
if (empty($departmentName)) {
return errorJson('部门名称不能为空');
}
if (empty($accountName)) {
return errorJson('账号名称不能为空');
}
if (empty($accountPassword)) {
return errorJson('账号密码不能为空');
}
// 检查部门是否已存在
$existingDepartment = CompanyModel::where('name', $departmentName)->find();
if (!empty($existingDepartment)) {
return errorJson('部门以存在');
}
// 检查账号是否已存在
$existingAccount = CompanyAccountModel::where('userName', $accountName)->find();
if (!empty($existingAccount)) {
return errorJson('账号已存在');
}
$headerData = ['client:system'];
$header = setHeader($headerData, $authorization, 'json');
// 1. 创建部门
$departmentParams = [
'name' => $departmentName,
'memo' => $departmentMemo,
'departmentIdArr' => [914],
'parentId' => 914
];
$departmentResult = requestCurl($this->baseUrl . 'api/Department/createDepartment', $departmentParams, 'POST', $header, 'json');
if (is_numeric($departmentResult)) {
// 保存部门到数据库
CompanyModel::create([
'id' => $departmentResult,
'name' => $departmentName,
'memo' => $departmentMemo,
'tenantId' => 242,
'isTop' => 0,
'level' => 1,
'parentId' => 914,
'privileges' => '',
'createTime' => time(),
'lastUpdateTime' => 0
]);
$this->setPrivileges(['id' => $departmentResult]);
} else {
DB::rollback();
return errorJson('创建部门失败:' . $departmentResult);
}
// 2. 创建账号
$accountParams = [
'userName' => $accountName,
'password' => $accountPassword,
'realName' => $accountRealName,
'nickname' => $accountNickname,
'memo' => $accountMemo,
'departmentId' => $departmentResult,
'departmentIdArr' => [914, $departmentResult]
];
$accountResult = requestCurl($this->baseUrl . 'api/Account/newAccount', $accountParams, 'POST', $header, 'json');
if (is_numeric($accountResult)) {
$res = CompanyAccountModel::create([
'id' => $accountResult,
'tenantId' => 242,
'userName' => $accountName,
'realName' => $accountRealName,
'nickname' => $accountNickname,
'passwordMd5' => md5($accountPassword),
'passwordLocal' => localEncrypt($accountPassword),
'memo' => $accountMemo,
'accountType' => 11,
'departmentId' => $departmentResult,
'createTime' => time(),
'privilegeIds' => json_encode([])
]);
DB::commit();
return successJson($res, '账号创建成功');
} else {
// 如果创建账号失败,删除已创建的部门
$this->deleteDepartment($accountResult);
DB::rollback();
return errorJson('创建账号失败:' . $accountResult);
}
} catch (\Exception $e) {
DB::rollback();
return errorJson('创建账号失败:' . $e->getMessage());
}
}
/************************ 部门管理相关接口 ************************/
/**
* 获取部门列表
* @return \think\response\Json
*/
public function getDepartmentList($isInner = false)
{
// 获取授权token
$authorization = trim($this->request->header('authorization', $this->authorization));
if (empty($authorization)) {
if ($isInner) {
return json_encode(['code' => 500, 'msg' => '缺少授权信息']);
} else {
return errorJson('缺少授权信息');
}
}
try {
// 设置请求头
$headerData = ['client:system'];
$header = setHeader($headerData, $authorization, 'json');
// 发送请求获取部门列表
$url = $this->baseUrl . 'api/Department/fetchMyAndSubordinateDepartment';
$result = requestCurl($url, [], 'GET', $header, 'json');
// 处理返回结果
$response = handleApiResponse($result);
// 保存数据到数据库
if (!empty($response)) {
CompanyModel::where('1=1')->delete();
$this->processDepartments($response);
}
if ($isInner) {
return json_encode(['code' => 200, 'msg' => '获取部门列表成功', 'data' => $response]);
} else {
return successJson($response, '获取部门列表成功');
}
} catch (\Exception $e) {
if ($isInner) {
return json_encode(['code' => 500, 'msg' => '获取部门列表失败:' . $e->getMessage()]);
} else {
return errorJson('获取部门列表失败:' . $e->getMessage());
}
}
}
/**
* 创建部门
* @return \think\response\Json
*/
public function createDepartment()
{
// 获取授权token
$authorization = trim($this->request->header('authorization', $this->authorization));
if (empty($authorization)) {
return errorJson('缺少授权信息');
}
try {
// 获取并验证请求参数
$name = $this->request->param('name', '');
$memo = $this->request->param('memo', '');
if (empty($name)) {
return errorJson('请输入公司名称');
}
// 检查部门名称是否已存在
$departmentId = CompanyModel::where('name', $name)->find();
if (!empty($departmentId)) {
return errorJson('部门已存在');
}
// 构建请求参数
$params = [
'name' => $name,
'memo' => $memo,
'departmentIdArr' => [914],
'parentId' => 914
];
// 设置请求头
$headerData = ['client:system'];
$header = setHeader($headerData, $authorization, 'json');
// 发送请求创建部门
$result = requestCurl($this->baseUrl . 'api/Department/createDepartment', $params, 'POST', $header, 'json');
// 处理返回结果
if (is_numeric($result)) {
$res = CompanyModel::create([
'id' => $result,
'name' => $name,
'memo' => $memo,
'tenantId' => 242,
'isTop' => 0,
'level' => 1,
'parentId' => 914,
'privileges' => '',
'createTime' => time(),
'lastUpdateTime' => 0
]);
return successJson($res);
} else {
return errorJson($result);
}
} catch (\Exception $e) {
return errorJson('创建部门失败:' . $e->getMessage());
}
}
/**
* 修改部门信息
* @return \think\response\Json
*/
public function updateDepartment()
{
// 获取授权token
$authorization = trim($this->request->header('authorization', $this->authorization));
if (empty($authorization)) {
return errorJson('缺少授权信息');
}
try {
// 获取并验证请求参数
$id = $this->request->param('id', 0);
$name = $this->request->param('name', '');
$memo = $this->request->param('memo', '');
if (empty($id)) {
return errorJson('部门ID不能为空');
}
if (empty($name)) {
return errorJson('部门名称不能为空');
}
// 验证部门是否存在
$department = CompanyModel::where('id', $id)->find();
if (empty($department)) {
return errorJson('部门不存在');
}
// 构建请求参数
$departmentIdArr = $department->parentId == 914 ? [914] : [914, $department->parentId];
$params = [
'id' => $id,
'name' => $name,
'memo' => $memo,
'departmentIdArr' => $departmentIdArr,
'tenantId' => 242,
'createTime' => $department->createTime,
'isTop' => $department->isTop,
'level' => $department->level,
'parentId' => $department->parentId,
'lastUpdateTime' => $department->lastUpdateTime,
'privileges' => $department->privileges
];
// 设置请求头
$headerData = ['client:system'];
$header = setHeader($headerData, $authorization, 'json');
// 发送请求修改部门
$result = requestCurl($this->baseUrl . 'api/Department/department', $params, 'PUT', $header, 'json');
$response = handleApiResponse($result);
// 更新本地数据库
$department->name = $name;
$department->memo = $memo;
$department->save();
return successJson([], '部门修改成功');
} catch (\Exception $e) {
return errorJson('修改部门失败:' . $e->getMessage());
}
}
/**
* 删除部门
* @return \think\response\Json
*/
public function deleteDepartment($id = '')
{
// 获取授权token
$authorization = trim($this->request->header('authorization', $this->authorization));
if (empty($authorization)) {
return errorJson('缺少授权信息');
}
try {
// 获取并验证部门ID
$id = !empty($id) ? $id : $this->request->param('id', '');
if (empty($id)) {
return errorJson('部门ID不能为空');
}
// 验证部门是否存在
$department = CompanyModel::where('id', $id)->find();
if (empty($department)) {
return errorJson('部门不存在');
}
// 设置请求头
$headerData = ['client:system'];
$header = setHeader($headerData, $authorization, 'json');
// 发送删除请求
$result = requestCurl($this->baseUrl . 'api/Department/del/' . $id, [], 'DELETE', $header);
if ($result) {
return errorJson($result);
} else {
// 删除本地数据库记录
$department->delete();
return successJson([], '部门删除成功');
}
} catch (\Exception $e) {
return errorJson('删除部门失败:' . $e->getMessage());
}
}
/**
* 修改部门权限
* @return \think\response\Json
*/
public function setPrivileges($data = [])
{
// 获取授权token
$authorization = trim($this->request->header('authorization', $this->authorization));
if (empty($authorization)) {
return errorJson('缺少授权信息');
}
try {
// 获取并验证请求参数
$id = !empty($data['id']) ? $data['id'] : $this->request->param('id', 0);
if (empty($id)) {
return errorJson('部门ID不能为空');
}
$privilegeIds = !empty($data['privilegeIds']) ? $data['privilegeIds'] : '1001,1002,1004,1023,1406,20003,20021,20022,20023,20032,20041,20049,20054,20055,20060,20100,20102,20107';
$privilegeIds = explode(',',$privilegeIds);
// 验证部门是否存在
$department = CompanyModel::where('id', $id)->find();
if (empty($department)) {
return errorJson('部门不存在');
}
// 构建请求参数
$params = [
'departmentId' => $id,
'privilegeIds' => $privilegeIds,
'syncPrivilege' => true
];
// 设置请求头
$headerData = ['client:system'];
$header = setHeader($headerData, $authorization, 'json');
// 发送请求修改部门
$result = requestCurl($this->baseUrl . 'api/Department/privileges', $params, 'PUT', $header, 'json');
$response = handleApiResponse($result);
return successJson([], '部门权限修改成功');
} catch (\Exception $e) {
return errorJson('修改部门权限失败:' . $e->getMessage());
}
}
public function accountModify($data = [])
{
// 获取授权token
$authorization = $this->authorization;
if (empty($authorization)) {
return errorJson('缺少授权信息');
}
$id = !empty($data['id']) ? $data['id'] : '';
if (empty($id)) {
return errorJson('账号ID不能为空');
}
$account = CompanyAccountModel::where('id', $id)->find();
if (empty($account)) {
return errorJson('账号不存在');
}
$privilegeIds = json_decode($account->privilegeIds,true);
$privilegeIds = !empty($privilegeIds) ? $privilegeIds : [1001,1002,1004,1023,1406,20003,20021,20022,20023,20032,20041,20049,20054,20055,20060,20100,20102,20107,20055];
// 构建请求参数
$params = [
'accountType' => !empty($data['accountType']) ? $data['accountType'] : $account->accountType,
'alive' => !empty($data['alive']) ? $data['alive'] : $account->alive,
'avatar' => !empty($data['avatar']) ? $data['avatar'] : $account->avatar,
'createTime' => !empty($data['createTime']) ? $data['createTime'] : $account->createTime,
'creator' => !empty($data['creator']) ? $data['creator'] : $account->creator,
'creatorRealName' => !empty($data['creatorRealName']) ? $data['creatorRealName'] : $account->creatorRealName,
'creatorUserName' => !empty($data['creatorUserName']) ? $data['creatorUserName'] : $account->creatorUserName,
'departmentId' => !empty($data['departmentId']) ? $data['departmentId'] : $account->departmentId,
'departmentIdArr' => !empty($data['departmentIdArr']) ? $data['departmentIdArr'] : [914,$account->departmentId],
'departmentName' => !empty($data['departmentName']) ? $data['departmentName'] : $account->departmentName,
'hasXiakeAccount' => !empty($data['hasXiakeAccount']) ? $data['hasXiakeAccount'] : false,
'id' => !empty($data['id']) ? $data['id'] : $account->id,
'memo' => !empty($data['memo']) ? $data['memo'] : $account->memo,
'nickname' => !empty($data['nickname']) ? $data['nickname'] : $account->nickname,
'privilegeIds' => !empty($data['privilegeIds']) ? $data['privilegeIds'] : $privilegeIds,
'realName' => !empty($data['realName']) ? $data['realName'] : $account->realName,
'status' => !empty($data['status']) ? $data['status'] : $account->status,
'tenantId' => !empty($data['tenantId']) ? $data['tenantId'] : $account->tenantId,
'userName' => !empty($data['userName']) ? $data['userName'] : $account->userName,
];
// 设置请求头
$headerData = ['client:system'];
$header = setHeader($headerData, $authorization, 'json');
// 发送请求修改部门
$result = requestCurl($this->baseUrl . 'api/account/modify', $params, 'PUT', $header, 'json');
$response = handleApiResponse($result);
if(empty($response)){
$newData = [
'nickname' => $params['nickname'],
'avatar' => $params['avatar'],
];
CompanyAccountModel::where('id', $id)->update($newData);
return json_encode(['code' => 200, 'msg' => '账号修改成功']);
}else{
return json_encode(['code' => 500, 'msg' => $response]);
}
}
/************************ 私有辅助方法 ************************/
/**
* 递归处理部门列表
* @param array $departments 部门数据
*/
private function processDepartments($departments)
{
if (empty($departments) || !is_array($departments)) {
return;
}
foreach ($departments as $item) {
// 保存当前部门
$this->saveDepartment($item);
// 递归处理子部门
if (!empty($item['children']) && is_array($item['children'])) {
$this->processDepartments($item['children']);
}
}
}
/**
* 保存部门数据到数据库
* @param array $item 部门数据
*/
private function saveDepartment($item)
{
$data = [
'id' => isset($item['id']) ? $item['id'] : 0,
'name' => isset($item['name']) ? $item['name'] : '',
'memo' => isset($item['memo']) ? $item['memo'] : '',
'level' => isset($item['level']) ? $item['level'] : 0,
'isTop' => isset($item['isTop']) ? $item['isTop'] : false,
'parentId' => isset($item['parentId']) ? $item['parentId'] : 0,
'tenantId' => isset($item['tenantId']) ? $item['tenantId'] : 0,
'privileges' => isset($item['privileges']) ? (is_array($item['privileges']) ? json_encode($item['privileges']) : $item['privileges']) : '',
'createTime' => isset($item['createTime']) ? strtotime($item['createTime']) : 0,
'lastUpdateTime' => isset($item['lastUpdateTime']) ? ($item['lastUpdateTime'] == '0001-01-01T00:00:00' ? 0 : strtotime($item['lastUpdateTime'])) : 0
];
// 使用id作为唯一性判断
$department = CompanyModel::where('id', $item['id'])->find();
if ($department) {
$department->save($data);
} else {
CompanyModel::create($data);
}
}
/**
* 保存账号数据到数据库
* @param array $item 账号数据
*/
private function saveAccount($item)
{
// 将日期时间字符串转换为时间戳
$createTime = isset($item['createTime']) ? strtotime($item['createTime']) : null;
$deleteTime = isset($item['deleteTime']) ? strtotime($item['deleteTime']) : null;
$data = [
'id' => $item['id'],
'accountType' => isset($item['accountType']) ? $item['accountType'] : 0,
'status' => isset($item['status']) ? $item['status'] : 0,
'tenantId' => isset($item['tenantId']) ? $item['tenantId'] : 0,
'userName' => isset($item['userName']) ? $item['userName'] : '',
'realName' => isset($item['realName']) ? $item['realName'] : '',
'nickname' => isset($item['nickname']) ? $item['nickname'] : '',
'avatar' => isset($item['avatar']) ? $item['avatar'] : '',
'phone' => isset($item['phone']) ? $item['phone'] : '',
'memo' => isset($item['memo']) ? $item['memo'] : '',
'createTime' => $createTime,
'creator' => isset($item['creator']) ? $item['creator'] : 0,
'creatorUserName' => isset($item['creatorUserName']) ? $item['creatorUserName'] : '',
'creatorRealName' => isset($item['creatorRealName']) ? $item['creatorRealName'] : '',
'departmentId' => isset($item['departmentId']) ? $item['departmentId'] : 0,
'departmentName' => isset($item['departmentName']) ? $item['departmentName'] : '',
'privilegeIds' => isset($item['privilegeIds']) ? json_encode($item['privilegeIds']) : json_encode([]),
'alive' => isset($item['alive']) ? $item['alive'] : false,
'hasXiakeAccount' => isset($item['hasXiakeAccount']) ? $item['hasXiakeAccount'] : false,
'isDeleted' => isset($item['isDeleted']) ? $item['isDeleted'] : false,
'deleteTime' => $deleteTime
];
// 使用tenantId作为唯一性判断
$account = CompanyAccountModel::where('id', $item['id'])->find();
if ($account) {
$account->save($data);
} else {
CompanyAccountModel::create($data);
}
}
}

View File

@@ -0,0 +1,362 @@
<?php
namespace app\api\controller;
use app\api\model\CompanyAccountModel;
use app\api\model\AllotRuleModel;
use app\api\model\WechatAccountModel;
use think\Queue;
use app\job\AllotRuleListJob;
use think\Db;
class AllotRuleController extends BaseController
{
/************************************
* 分配规则列表和数据同步相关方法
************************************/
/**
* 获取所有分配规则
* @param bool $isInner 是否为内部调用
* @return \think\response\Json
*/
public function getAllRules($data = [], $isInner = false)
{
// 获取授权token
$authorization = trim($this->request->header('authorization', $this->authorization));
if (empty($authorization)) {
if ($isInner) {
return json_encode(['code' => 500, 'msg' => '缺少授权信息']);
} else {
return errorJson('缺少授权信息');
}
}
try {
// 设置请求头
$headerData = ['client:system'];
$header = setHeader($headerData, $authorization, 'plain');
// 发送请求获取所有分配规则
$result = requestCurl($this->baseUrl . 'api/AllotRule/all', [], 'GET', $header);
$response = handleApiResponse($result);
// 保存数据到数据库
if (!empty($response)) {
AllotRuleModel::where('1=1')->update(['isDel' => 1]);
foreach ($response as $item) {
$this->saveAllotRule($item);
}
}
if ($isInner) {
return json_encode(['code' => 200, 'msg' => 'success', 'data' => $response]);
} else {
return successJson($response);
}
} catch (\Exception $e) {
if ($isInner) {
return json_encode(['code' => 500, 'msg' => '获取分配规则失败:' . $e->getMessage()]);
} else {
return errorJson('获取分配规则失败:' . $e->getMessage());
}
}
}
/**
* 手动触发分配规则同步任务
* @return \think\response\Json
*/
public function startJob()
{
try {
$data = [
'time' => time()
];
// 添加到队列,设置任务名为 allotrule_list
$isSuccess = Queue::push(AllotRuleListJob::class, $data, 'allotrule_list');
if ($isSuccess !== false) {
return successJson([], '分配规则同步任务已添加到队列');
} else {
return errorJson('添加分配规则同步任务到队列失败');
}
} catch (\Exception $e) {
return errorJson('触发分配规则同步任务失败:' . $e->getMessage());
}
}
/************************************
* 分配规则CRUD操作方法
************************************/
/**
* 创建分配规则
* @param array $data 请求数据
* @param bool $isInner 是否为内部调用
* @return \think\response\Json
*/
public function createRule($data = [], $isInner = false)
{
// 获取授权token
$authorization = trim($this->request->header('authorization', $this->authorization));
if (empty($authorization)) {
if ($isInner) {
return json_encode(['code' => 500, 'msg' => '缺少授权信息']);
} else {
return errorJson('缺少授权信息');
}
}
try {
$wechatData = input('wechatData', '[]') ?: [];
$priorityStrategy = input('priorityStrategy', '[]') ?: [];
// 构建请求数据
$params = [
'allotType' => input('allotType', 1),
'kefuRange' => input('kefuRange', 5),
'wechatRange' => input('wechatRange',3),
'kefuData' => input('kefuData', '[]') ?: [],
'wechatData' => $wechatData,
'labels' => input('labels', '[]') ?: [],
'priorityStrategy' => json_encode($priorityStrategy,256)
];
// 设置请求头
$headerData = ['client:system'];
$header = setHeader($headerData, $authorization, 'json');
// 发送请求到微信接口
$result = requestCurl($this->baseUrl . 'api/AllotRule/new', $params, 'POST', $header, 'json');
if (empty($result)) {
// 异步更新所有规则列表
AllotRuleModel::where('1=1')->update(['isDel' => 1]);
$this->getAllRules();
$res = AllotRuleModel::where('isDel',0)->order('id','DESC')->find();
$res->departmentId = !empty($data['departmentId']) ? $data['departmentId'] : 0;
$res->save();
return successJson($res, '创建分配规则成功');
} else {
return errorJson($result);
}
} catch (\Exception $e) {
return errorJson('创建分配规则失败:' . $e->getMessage());
}
}
/**
* 更新分配规则
* @param array $data 请求数据
* @param bool $isInner 是否为内部调用
* @return \think\response\Json
*/
public function updateRule($data = [], $isInner = false)
{
// 获取授权token
$authorization = trim($this->request->header('authorization', $this->authorization));
if (empty($authorization)) {
return errorJson('缺少授权信息');
}
try {
// 获取请求参数
$id = !empty($data['id']) ? $data['id'] : input('id',0);
if (empty($id)) {
return errorJson('规则ID不能为空');
}
$rule = AllotRuleModel::where('id', $id)->find();
if (empty($rule)) {
return errorJson('规则不存在');
}
// 构建请求数据
$params = [
'id' => $id,
'tenantId' => $rule['tenantId'],
'allotType' => !empty($data['allotType']) ? $data['allotType'] : input('allotType',1),
'allotOnline' => !empty($data['allotOnline']) ? $data['allotOnline'] : input('allotOnline',false),
'kefuRange' => !empty($data['kefuRange']) ? $data['kefuRange'] : input('kefuRange',5),
'wechatRange' => !empty($data['wechatRange']) ? $data['wechatRange'] : input('wechatRange',3),
'kefuData' => !empty($data['kefuData']) ? $data['kefuData'] : input('kefuData',[]),
'wechatData' => !empty($data['wechatData']) ? $data['wechatData'] : input('wechatData',[]),
'labels' => !empty($data['labels']) ? $data['labels'] : input('labels',[]),
'priorityStrategy' => json_encode(!empty($data['priorityStrategy']) ? $data['priorityStrategy'] : input('priorityStrategy',[]),256),
];
// 设置请求头
$headerData = ['client:system'];
$header = setHeader($headerData, $authorization, 'json');
// 发送请求到微信接口
$result = requestCurl($this->baseUrl . 'api/AllotRule/update', $params, 'PUT', $header, 'json');
if (empty($result)) {
$this->getAllRules();
return successJson([], '更新分配规则成功');
} else {
return errorJson($result);
}
} catch (\Exception $e) {
return errorJson('更新分配规则失败:' . $e->getMessage());
}
}
/**
* 删除分配规则
* @param array $data 请求数据
* @param bool $isInner 是否为内部调用
* @return \think\response\Json
*/
public function deleteRule($data = [], $isInner = false)
{
// 获取授权token
$authorization = trim($this->request->header('authorization', $this->authorization));
if (empty($authorization)) {
if ($isInner) {
return json_encode(['code' => 500, 'msg' => '缺少授权信息']);
} else {
return errorJson('缺少授权信息');
}
}
try {
// 获取请求参数
$id = !empty($data['id']) ? $data['id'] : input('id', 0);
if (empty($id)) {
return errorJson('规则ID不能为空');
}
// 检查规则是否存在
$rule = AllotRuleModel::where('id', $id)->find();
if (empty($rule)) {
return errorJson('规则不存在');
}
// 设置请求头
$headerData = ['client:system'];
$header = setHeader($headerData, $authorization, 'plain');
// 发送请求到微信接口
$result = requestCurl($this->baseUrl . 'api/AllotRule/delete?id=' . $id, [], 'DELETE', $header);
$response = handleApiResponse($result);
if (empty($response)) {
// 删除成功,同步本地数据库
AllotRuleModel::where('id', $id)->update(['isDel' => 1]);
return successJson([], '删除分配规则成功');
} else {
return errorJson($response);
}
} catch (\Exception $e) {
return errorJson('删除分配规则失败:' . $e->getMessage());
}
}
/************************************
* 数据查询相关方法
************************************/
/**
* 自动创建分配规则
* 根据今日新增微信账号自动创建或更新分配规则
* @param array $data 请求数据
* @param bool $isInner 是否为内部调用
* @return \think\response\Json|string
*/
public function autoCreateAllotRules($data = [], $isInner = false)
{
try {
// 获取今天的开始时间和结束时间
$todayStart = strtotime(date('Y-m-d 00:00:00'));
$todayEnd = strtotime(date('Y-m-d 23:59:59'));
// 查询今天新增的微信账号
$newAccounts = Db::table('s2_wechat_account')
->alias('wa')
->join(['s2_company_account' => 'ca'], 'wa.deviceAccountId = ca.id', 'LEFT')
->field([
'wa.id',
'wa.wechatId',
'wa.nickname',
'wa.deviceAccountId',
'wa.alias',
'wa.createTime',
'ca.departmentId',
])
->where('wa.createTime', 'BETWEEN', [$todayStart, $todayEnd])
->where('wa.isDeleted', 0)
->order('wa.createTime', 'DESC')
->select();
// 没有今日新增微信账号,直接返回
if (empty($newAccounts)) {
$result = ['code' => 200, 'msg' => '没有今日新增微信账号,无需创建分配规则', 'data' => []];
return $isInner ? json_encode($result) : successJson([], '没有今日新增微信账号,无需创建分配规则');
}
// 获取所有分配规则
foreach ($newAccounts as $key => $value) {
$rules = AllotRuleModel::where(['departmentId' => $value['departmentId'],'isDel' => 0])->order('id','DESC')->find();
if (!empty($rules)) {
$wechatData = json_decode($rules['wechatData'], true);
if (!in_array($value['id'], $wechatData)) {
$wechatData[] = $value['id'];
$kefuData = [$value['deviceAccountId']];
$this->updateRule(['id' => $rules['id'],'wechatData' => $wechatData,'kefuData' => $kefuData],true);
}
}else{
$wechatData =[$value['id']];
$kefuData = [$value['deviceAccountId']];
$this->createRule(['wechatData' => $wechatData,'kefuData' => $kefuData,'departmentId' => $value['departmentId']],true);
}
}
$result = ['code' => 200, 'msg' => '自动分配规则成功', 'data' => []];
return $isInner ? json_encode($result) : successJson([], '自动分配规则成功');
} catch (\Exception $e) {
$error = '自动分配规则失败: ' . $e->getMessage();
$result = ['code' => 500, 'msg' => $error];
return $isInner ? json_encode($result) : errorJson($error);
}
}
/************************************
* 辅助方法
************************************/
/**
* 保存分配规则数据到数据库
* @param array $item 分配规则数据
*/
private function saveAllotRule($item)
{
$data = [
'id' => isset($item['id']) ? $item['id'] : '',
'tenantId' => isset($item['tenantId']) ? $item['tenantId'] : 0,
'allotType' => isset($item['allotType']) ? $item['allotType'] : 0,
'allotOnline' => isset($item['allotOnline']) ? $item['allotOnline'] : false,
'kefuRange' => isset($item['kefuRange']) ? $item['kefuRange'] : 0,
'wechatRange' => isset($item['wechatRange']) ? $item['wechatRange'] : 0,
'kefuData' => isset($item['kefuData']) ? json_encode($item['kefuData']) : json_encode([]),
'wechatData' => isset($item['wechatData']) ? json_encode($item['wechatData']) : json_encode([]),
'labels' => isset($item['labels']) ? json_encode($item['labels']) : json_encode([]),
'priorityStrategy' => isset($item['priorityStrategy']) ? json_encode($item['priorityStrategy']) : json_encode([]),
'sortIndex' => isset($item['sortIndex']) ? $item['sortIndex'] : 0,
'creatorAccountId' => isset($item['creatorAccountId']) ? $item['creatorAccountId'] : 0,
'createTime' => isset($item['createTime']) ? (strtotime($item['createTime']) ?: 0) : 0,
'ruleName' => isset($item['ruleName']) ? $item['ruleName'] : '',
'isDel' => 0,
];
// 使用ID作为唯一性判断
$rule = AllotRuleModel::where('id', $item['id'])->find();
if ($rule) {
$rule->save($data);
} else {
AllotRuleModel::create($data);
}
}
}

View File

@@ -0,0 +1,346 @@
<?php
namespace app\api\controller;
use app\api\model\CompanyAccountModel;
use app\api\model\CompanyModel;
use Library\S2\Logics\AccountLogic;
use think\Db;
use think\facade\Request;
/**
* 账号管理控制器
* 包含账号管理和部门管理的相关功能
*/
class AutomaticAssign extends BaseController
{
/**
* 自动分配微信好友
* @return \think\response\Json
*/
public function autoAllotWechatFriend($data = [],$isInner = false)
{
// 获取授权token
$authorization = trim($this->request->header('authorization', $this->authorization));
if (empty($authorization)) {
if($isInner){
return json_encode(['code'=>500,'msg'=>'缺少授权信息']);
}else{
return errorJson('缺少授权信息');
}
}
try {
// 获取请求参数
$toAccountId = !empty($data['toAccountId']) ? $data['toAccountId'] : input('toAccountId', '');
$wechatAccountKeyword = !empty($data['wechatAccountKeyword']) ? $data['wechatAccountKeyword'] : input('wechatAccountKeyword', '');
$isDeleted = !empty($data['isDeleted']) ? $data['isDeleted'] : input('isDeleted', false);
if (empty($toAccountId)) {
if($isInner){
return json_encode(['code'=>500,'msg'=>'目标账号ID不能为空']);
}else{
return errorJson('目标账号ID不能为空');
}
}
$params = [
'accountKeyword' => !empty($data['accountKeyword']) ? $data['accountKeyword'] : '',
'addFrom' => !empty($data['addFrom']) ? $data['addFrom'] : [],
'allotAccountId' => !empty($data['allotAccountId']) ? $data['allotAccountId'] : '',
'containAllLabel' => !empty($data['containAllLabel']) ? $data['containAllLabel'] : false,
'containSubDepartment' => !empty($data['containSubDepartment']) ? $data['containSubDepartment'] : false,
'departmentId' => !empty($data['departmentId']) ? $data['departmentId'] : '',
'extendFields' => !empty($data['extendFields']) ? $data['extendFields'] : [],
'friendKeyword' => !empty($data['friendKeyword']) ? $data['friendKeyword'] : '',
'friendPhoneKeyword' => !empty($data['friendPhoneKeyword']) ? $data['friendPhoneKeyword'] : '',
'friendPinYinKeyword' => !empty($data['friendPinYinKeyword']) ? $data['friendPinYinKeyword'] : '',
'friendRegionKeyword' => !empty($data['friendRegionKeyword']) ? $data['friendRegionKeyword'] : '',
'friendRemarkKeyword' => !empty($data['friendRemarkKeyword']) ? $data['friendRemarkKeyword'] : '',
'gender' => !empty($data['gender']) ? $data['gender'] : '',
'groupId' => !empty($data['groupId']) ? $data['groupId'] : null,
'isByRule' => !empty($data['isByRule']) ? $data['isByRule'] : false,
'isDeleted' => $isDeleted,
'isPass' => !empty($data['isPass']) ? $data['isPass'] : true,
'keyword' => !empty($data['keyword']) ? $data['keyword'] : '',
'labels' => !empty($data['labels']) ? $data['labels'] : [],
'pageIndex' => !empty($data['pageIndex']) ? $data['pageIndex'] : 0,
'pageSize' => !empty($data['pageSize']) ? $data['pageSize'] : 100,
'preFriendId' => !empty($data['preFriendId']) ? $data['preFriendId'] : '',
'toAccountId' => $toAccountId,
'wechatAccountKeyword' => $wechatAccountKeyword
];
// 设置请求头
$headerData = ['client:system'];
$header = setHeader($headerData, $authorization, 'json');
// 发送请求
$result = requestCurl($this->baseUrl . 'api/WechatFriend/allotSearchResult', $params, 'PUT', $header,'json');
$response = handleApiResponse($result);
if($response){
if($isInner){
return json_encode(['code'=>200,'msg'=>'微信好友自动分配成功']);
}else{
return successJson([],'微信好友自动分配成功');
}
}else{
if($isInner){
return json_encode(['code'=>500,'msg'=>$response]);
}else{
return errorJson($response);
}
}
} catch (\Exception $e) {
if($isInner){
return json_encode(['code'=>500,'msg'=>'微信好友自动分配失败:' . $e->getMessage()]);
}else{
return errorJson('微信好友自动分配失败:' . $e->getMessage());
}
}
}
/**
* 自动分配微信群聊
* @param string $toAccountId 目标账号ID
* @param string $wechatAccountKeyword 微信账号关键字
* @param bool $isDeleted 是否已删除
* @return \think\response\Json
*/
public function autoAllotWechatChatroom($data = [])
{
// 获取授权token
$authorization = trim($this->request->header('authorization', $this->authorization));
if (empty($authorization)) {
return errorJson('缺少授权信息');
}
try {
// 获取请求参数
$toAccountId = !empty($data['toAccountId']) ? $data['toAccountId'] : input('toAccountId', '');
$wechatAccountKeyword = !empty($data['wechatAccountKeyword']) ? $data['wechatAccountKeyword'] : input('wechatAccountKeyword', '');
$isDeleted = !empty($data['isDeleted']) ? $data['isDeleted'] : input('isDeleted', false);
if (empty($toAccountId)) {
return errorJson('目标账号ID不能为空');
}
$params = [
'AllotBySearch' => true,
'byRule' => false,
'comment' => '',
'groupId' => null,
'isDeleted' => $isDeleted,
'keyword' => '',
'memberKeyword' => '',
'notifyReceiver' => false,
'toAccountId' => $toAccountId,
'wechatAccountKeyword' => $wechatAccountKeyword,
'wechatChatroomId' => 0,
'wechatChatroomIds' => []
];
// 设置请求头
$headerData = ['client:system'];
$header = setHeader($headerData, $authorization, 'json');
// 发送请求
$result = requestCurl($this->baseUrl . 'api/WechatChatroom/allotChatroom', $params, 'PUT', $header, 'json');
$response = handleApiResponse($result);
if($response){
return successJson([], '微信群聊自动分配成功');
}else{
return errorJson($response);
}
} catch (\Exception $e) {
return errorJson('微信群聊自动分配失败:' . $e->getMessage());
}
}
/**
* 指定微信好友分配到指定账号
* @param int $wechatFriendId 微信好友ID
* @param int $toAccountId 目标账号ID
* @param string $comment 评论/备注
* @param bool $notifyReceiver 是否通知接收者
* @param int $optFrom 操作来源
* @return \think\response\Json
*/
public function allotWechatFriend($data = [],$isInner = false,$errorNum = 0)
{
// 获取授权token
$authorization = $this->authorization;
if (empty($authorization)) {
if($isInner){
return json_encode(['code'=>500,'msg'=>'缺少授权信息']);
}else{
return errorJson('缺少授权信息');
}
}
try {
// 获取请求参数
$wechatFriendId = !empty($data['wechatFriendId']) ? $data['wechatFriendId'] : input('wechatFriendId', 0);
$toAccountId = !empty($data['toAccountId']) ? $data['toAccountId'] : input('toAccountId', 0);
$comment = !empty($data['comment']) ? $data['comment'] : input('comment', '');
$notifyReceiver = !empty($data['notifyReceiver']) ? $data['notifyReceiver'] : input('notifyReceiver', 'false');
$optFrom = !empty($data['optFrom']) ? $data['optFrom'] : input('optFrom', 4); // 默认操作来源为4
// 参数验证
if (empty($wechatFriendId)) {
return json_encode(['code'=>500,'msg'=>'微信好友ID不能为空']);
}
if (empty($toAccountId)) {
return json_encode(['code'=>500,'msg'=>'目标账号ID不能为空']);
}
// 设置请求头
$headerData = ['client:system'];
$header = setHeader($headerData, $authorization, 'json');
// 发送请求
$url = $this->baseUrl . 'api/WechatFriend/allot?wechatFriendId='.$wechatFriendId.'&notifyReceiver='.$notifyReceiver.'&comment='.$comment.'&toAccountId='.$toAccountId.'&optFrom='.$optFrom;
$result = requestCurl($url, [], 'PUT', $header, 'json');
$response = handleApiResponse($result);
if (empty($response)) {
if($isInner){
return json_encode(['code'=>200,'msg'=>'微信好友分配成功']);
}else{
return successJson([], '微信好友分配成功');
}
} else {
if($isInner){
return json_encode(['code'=>500,'msg'=>$result]);
}else{
return errorJson($result);
}
}
} catch (\Exception $e) {
if($isInner){
return json_encode(['code'=>500,'msg'=>'微信好友分配失败:' . $e->getMessage()]);
}else{
Cache::rm('system_authorization_token');
Cache::rm('system_refresh_token');
$errorNum ++;
if ($errorNum <= 3) {
$this->allotWechatFriend($data,$isInner,$errorNum);
}
return json_encode(['code'=>500,'msg'=> $result]);
return errorJson('微信好友分配失败:' . $e->getMessage());
}
}
}
public function multiAllotFriendToAccount($data = [],$errorNum = 0){
// 获取授权token
$authorization = $this->authorization;
if (empty($authorization)) {
return json_encode(['code'=>500,'msg'=>'缺少授权信息']);
}
$wechatFriendIds = !empty($data['wechatFriendIds']) ? $data['wechatFriendIds'] : input('wechatFriendIds', []);
$toAccountId = !empty($data['toAccountId']) ? $data['toAccountId'] : input('toAccountId', 0);
$notifyReceiver = !empty($data['notifyReceiver']) ? $data['notifyReceiver'] : input('notifyReceiver', 'false');
// 参数验证
if (empty($wechatFriendIds)) {
return json_encode(['code'=>500,'msg'=>'微信好友ID不能为空']);
}
if (empty($toAccountId)) {
return json_encode(['code'=>500,'msg'=>'目标账号ID不能为空']);
}
// 设置请求头
$headerData = ['client:system'];
$header = setHeader($headerData, $authorization, 'json');
// 发送请求
$url = $this->baseUrl . 'api/WechatFriend/multiAllotFriendToAccount?wechatFriendIds='.$wechatFriendIds.'&toAccountId='.$toAccountId.'&notifyReceiver='.$notifyReceiver;
$result = requestCurl($url, [], 'PUT', $header, 'json');
if (empty($result)) {
return json_encode(['code'=>200,'msg'=>'微信好友分配成功']);
} else {
Cache::rm('system_authorization_token');
Cache::rm('system_refresh_token');
$errorNum ++;
if ($errorNum <= 3) {
$this->multiAllotFriendToAccount($data,$errorNum);
}
return json_encode(['code'=>500,'msg'=> $result]);
}
}
/**
* 分配搜索结果
* @param array $data 请求参数
* @return \think\response\Json
*/
public function allotSearchResult($data = [])
{
// 获取授权token
$authorization = trim($this->request->header('authorization', $this->authorization));
if (empty($authorization)) {
return json_encode(['code'=>500,'msg'=>'缺少授权信息']);
}
try {
$params = [
'accountKeyword' => !empty($data['accountKeyword']) ? $data['accountKeyword'] : '',
'addFrom' => !empty($data['addFrom']) ? $data['addFrom'] : [],
'allotAccountId' => !empty($data['allotAccountId']) ? $data['allotAccountId'] : '',
'containAllLabel' => !empty($data['containAllLabel']) ? $data['containAllLabel'] : false,
'containSubDepartment' => !empty($data['containSubDepartment']) ? $data['containSubDepartment'] : false,
'departmentId' => !empty($data['departmentId']) ? $data['departmentId'] : '',
'extendFields' => !empty($data['extendFields']) ? json_encode($data['extendFields']) : json_encode([]),
'friendKeyword' => !empty($data['friendKeyword']) ? $data['friendKeyword'] : '',
'friendPhoneKeyword' => !empty($data['friendPhoneKeyword']) ? $data['friendPhoneKeyword'] : '',
'friendPinYinKeyword' => !empty($data['friendPinYinKeyword']) ? $data['friendPinYinKeyword'] : '',
'friendRegionKeyword' => !empty($data['friendRegionKeyword']) ? $data['friendRegionKeyword'] : '',
'friendRemarkKeyword' => !empty($data['friendRemarkKeyword']) ? $data['friendRemarkKeyword'] : '',
'gender' => !empty($data['gender']) ? $data['gender'] : '',
'groupId' => !empty($data['groupId']) ? $data['groupId'] : null,
'isByRule' => !empty($data['isByRule']) ? $data['isByRule'] : false,
'isDeleted' => !empty($data['isDeleted']) ? $data['isDeleted'] : false,
'isPass' => !empty($data['isPass']) ? $data['isPass'] : true,
'keyword' => !empty($data['keyword']) ? $data['keyword'] : '',
'labels' => !empty($data['labels']) ? $data['labels'] : [],
'pageIndex' => !empty($data['pageIndex']) ? $data['pageIndex'] : 0,
'pageSize' => !empty($data['pageSize']) ? $data['pageSize'] : 20,
'preFriendId' => !empty($data['preFriendId']) ? $data['preFriendId'] : '',
'toAccountId' => !empty($data['toAccountId']) ? $data['toAccountId'] : '',
'wechatAccountKeyword' => !empty($data['wechatAccountKeyword']) ? $data['wechatAccountKeyword'] : ''
];
// 设置请求头
$headerData = ['client:system'];
$header = setHeader($headerData, $authorization, 'json');
// 发送请求
$result = requestCurl($this->baseUrl . 'api/WechatFriend/allotSearchResult', $params, 'POST', $header, 'json');
$response = handleApiResponse($result);
if($response){
return json_encode(['code'=>200,'msg'=>'分配成功']);
}else{
return json_encode(['code'=>500,'msg'=>$response]);
}
} catch (\Exception $e) {
return json_encode(['code'=>500,'msg'=>'微信好友分配失败:' . $e->getMessage()]);
}
}
}

View File

@@ -0,0 +1,26 @@
<?php
namespace app\api\controller;
use think\Controller;
use think\facade\Env;
use app\common\service\AuthService;
class BaseController extends Controller
{
/**
* 令牌
*
* @var string
*/
protected $token = '';
protected $baseUrl;
protected $authorization = '';
public function __construct()
{
parent::__construct();
$this->baseUrl = Env::get('api.wechat_url');
$this->authorization = AuthService::getSystemAuthorization();
}
}

View File

@@ -0,0 +1,142 @@
<?php
namespace app\api\controller;
use app\api\model\CompanyAccountModel;
use app\api\model\CompanyModel;
use app\api\model\CallRecordingModel;
use Library\S2\Logics\AccountLogic;
use think\Db;
use think\facade\Request;
/**
* 通话记录控制器
* 包含通话记录管理的相关功能
*/
class CallRecordingController extends BaseController
{
/**
* 获取通话记录列表
* @param array $data 请求参数
* @param bool $isInner 是否为定时任务调用
* @return \think\response\Json
*/
public function getlist($data = [], $isInner = false)
{
// 获取请求参数
$keyword = !empty($data['keyword']) ? $data['keyword'] : '';
$isCallOut = !empty($data['isCallOut']) ? $data['isCallOut'] : '';
$secondMin = !empty($data['secondMin']) ? $data['secondMin'] : 0;
$secondMax = !empty($data['secondMax']) ? $data['secondMax'] : 99999;
$departmentIds = !empty($data['departmentIds']) ? $data['departmentIds'] : '';
$pageIndex = !empty($data['pageIndex']) ? $data['pageIndex'] : 0;
$pageSize = !empty($data['pageSize']) ? $data['pageSize'] : 100;
$from = !empty($data['from']) ? $data['from'] : '2016-01-01 00:00:00';
$to = !empty($data['to']) ? $data['to'] : '2025-08-31 00:00:00';
$departmentId = !empty($data['departmentId']) ? $data['departmentId'] : '';
// 获取授权token
$authorization = trim($this->request->header('authorization', $this->authorization));
if (empty($authorization)) {
if ($isInner) {
return json_encode(['code' => 500, 'msg' => '缺少授权信息']);
} else {
return errorJson('缺少授权信息');
}
}
try {
// 构建请求参数
$params = [
'keyword' => $keyword,
'isCallOut' => $isCallOut,
'secondMin' => $secondMin,
'secondMax' => $secondMax,
'departmentIds' => $departmentIds,
'pageIndex' => $pageIndex,
'pageSize' => $pageSize,
'from' => $from,
'to' => $to,
'departmentId' => $departmentId
];
// 设置请求头
$headerData = ['client:system'];
$header = setHeader($headerData, $authorization, 'plain');
// 发送请求获取通话记录列表
$result = requestCurl($this->baseUrl . 'api/CallRecording/list', $params, 'GET', $header);
$response = handleApiResponse($result);
// 保存数据到数据库
if (!empty($response['results'])) {
foreach ($response['results'] as $item) {
$this->saveCallRecording($item);
}
}
if ($isInner) {
return json_encode(['code' => 200, 'msg' => '获取通话记录列表成功', 'data' => $response]);
} else {
return successJson($response, '获取通话记录列表成功');
}
} catch (\Exception $e) {
if ($isInner) {
return json_encode(['code' => 500, 'msg' => '获取通话记录列表失败:' . $e->getMessage()]);
} else {
return errorJson('获取通话记录列表失败:' . $e->getMessage());
}
}
}
/**
* 保存通话记录数据到数据库
* @param array $item 通话记录数据
*/
private function saveCallRecording($item)
{
// 将时间戳转换为秒级时间戳API返回的是毫秒级
$beginTime = isset($item['beginTime']) ? intval($item['beginTime'] / 1000) : 0;
$endTime = isset($item['endTime']) ? intval($item['endTime'] / 1000) : 0;
$callBeginTime = isset($item['callBeginTime']) ? intval($item['callBeginTime'] / 1000) : 0;
// 将日期时间字符串转换为时间戳
$createTime = isset($item['createTime']) ? strtotime($item['createTime']) : 0;
$lastUpdateTime = isset($item['lastUpdateTime']) ? strtotime($item['lastUpdateTime']) : 0;
$data = [
'id' => isset($item['id']) ? $item['id'] : 0,
'tenantId' => isset($item['tenantId']) ? $item['tenantId'] : 0,
'deviceOwnerId' => isset($item['deviceOwnerId']) ? $item['deviceOwnerId'] : 0,
'userName' => isset($item['userName']) ? $item['userName'] : '',
'nickname' => isset($item['nickname']) ? $item['nickname'] : '',
'realName' => isset($item['realName']) ? $item['realName'] : '',
'deviceMemo' => isset($item['deviceMemo']) ? $item['deviceMemo'] : '',
'fileName' => isset($item['fileName']) ? $item['fileName'] : '',
'imei' => isset($item['imei']) ? $item['imei'] : '',
'phone' => isset($item['phone']) ? $item['phone'] : '',
'isCallOut' => isset($item['isCallOut']) ? $item['isCallOut'] : false,
'beginTime' => $beginTime,
'endTime' => $endTime,
'audioUrl' => isset($item['audioUrl']) ? $item['audioUrl'] : '',
'mp3AudioUrl' => isset($item['mp3AudioUrl']) ? $item['mp3AudioUrl'] : '',
'callBeginTime' => $callBeginTime,
'callLogId' => isset($item['callLogId']) ? $item['callLogId'] : 0,
'callType' => isset($item['callType']) ? $item['callType'] : 0,
'duration' => isset($item['duration']) ? $item['duration'] : 0,
'skipReason' => isset($item['skipReason']) ? $item['skipReason'] : '',
'skipUpload' => isset($item['skipUpload']) ? $item['skipUpload'] : false,
'isDeleted' => isset($item['isDeleted']) ? $item['isDeleted'] : false,
'createTime' => $createTime,
'lastUpdateTime' => $lastUpdateTime
];
// 使用id作为唯一性判断
$callRecording = CallRecordingModel::where('id', $item['id'])->find();
if ($callRecording) {
$callRecording->save($data);
} else {
CallRecordingModel::create($data);
}
}
}

View File

@@ -0,0 +1,769 @@
<?php
namespace app\api\controller;
use app\api\model\DeviceModel;
use app\api\model\DeviceGroupModel;
use think\Db;
use think\facade\Request;
use think\facade\Env;
use Endroid\QrCode\QrCode;
use Endroid\QrCode\ErrorCorrectionLevel;
class DeviceController extends BaseController
{
/************************ 设备管理相关接口 ************************/
/**
* 获取设备列表
* @param string $pageIndex 页码
* @param string $pageSize 每页数量
* @param bool $isInner 是否为内部调用
* @return \think\response\Json
*/
public function getlist($data = [],$isInner = false,$isDel = 0)
{
// 获取授权token
$authorization = $this->authorization;
if (empty($authorization)) {
if($isInner){
return json_encode(['code'=>500,'msg'=>'缺少授权信息']);
}else{
return errorJson('缺少授权信息');
}
}
try {
// 根据isDel设置对应的deleteType值
$deleteType = 'unDeleted'; // 默认值
if ($isDel == 1) {
$deleteType = 'deleted';
} elseif ($isDel == 2) {
$deleteType = 'deletedAndStop';
}
// 构建请求参数
$params = [
'accountId' => !empty($data['accountId']) ? $data['accountId'] : $this->request->param('accountId', ''),
'keyword' => $this->request->param('keyword', ''),
'imei' => $this->request->param('imei', ''),
'groupId' => $this->request->param('groupId', ''),
'brand' => $this->request->param('brand', ''),
'model' => $this->request->param('model', ''),
'deleteType' => $this->request->param('deleteType', $deleteType),
'operatingSystem' => $this->request->param('operatingSystem', ''),
'softwareVersion' => $this->request->param('softwareVersion', ''),
'phoneAppVersion' => $this->request->param('phoneAppVersion', ''),
'recorderVersion' => $this->request->param('recorderVersion', ''),
'contactsVersion' => $this->request->param('contactsVersion', ''),
'rooted' => $this->request->param('rooted', ''),
'xPosed' => $this->request->param('xPosed', ''),
'alive' => $this->request->param('alive', ''),
'hasWechat' => $this->request->param('hasWechat', ''),
'departmentId' => $this->request->param('departmentId', ''),
'pageIndex' => !empty($data['pageIndex']) ? $data['pageIndex'] : $this->request->param('pageIndex', 0),
'pageSize' => !empty($data['pageSize']) ? $data['pageSize'] : $this->request->param('pageSize', 20)
];
// 设置请求头
$headerData = ['client:system'];
$header = setHeader($headerData, $authorization, 'plain');
// 发送请求获取设备列表
$result = requestCurl($this->baseUrl . 'api/device/pageResult', $params, 'GET', $header);
$response = handleApiResponse($result);
// 保存数据到数据库
if (!empty($response['results'])) {
foreach ($response['results'] as $item) {
$this->saveDevice($item);
}
}
if($isInner){
return json_encode(['code'=>200,'msg'=>'success','data'=>$response]);
}else{
return successJson($response);
}
} catch (\Exception $e) {
if($isInner){
return json_encode(['code'=>500,'msg'=>'获取设备列表失败:' . $e->getMessage()]);
}else{
return errorJson('获取设备列表失败:' . $e->getMessage());
}
}
}
/**
* 生成设备二维码
* @param int $accountId 账号ID
* @return \think\response\Json
*/
public function addDevice($accountId = 0,$isInner = false)
{
if (empty($accountId)) {
$accountId = $this->request->param('accountId', '');
}
if (empty($accountId)) {
if($isInner){
return json_encode(['code'=>500,'msg'=>'账号ID不能为空']);
}else{
return errorJson('账号ID不能为空');
}
}
try {
// 获取环境配置
$tenantGuid = Env::get('api.guid', '');
$deviceSocketHost = Env::get('api.deviceSocketHost', '');
if (empty($tenantGuid) || empty($deviceSocketHost)) {
if($isInner){
return json_encode(['code'=>500,'msg'=>'环境配置不完整请检查api.guid和api.deviceSocketHost配置']);
}else{
return errorJson('环境配置不完整请检查api.guid和api.deviceSocketHost配置');
}
}
// 构建设备配置数据
$data = [
'tenantGuid' => $tenantGuid,
'deviceSocketHost' => $deviceSocketHost,
'checkVersionUrl' => '',
'accountId' => intval($accountId)
];
// 将数据转换为JSON
$jsonData = json_encode($data);
// 生成二维码图片
$qrCode = $this->generateQrCodeImage($jsonData);
return successJson([
'qrCode' => $qrCode,
'config' => $data
]);
} catch (\Exception $e) {
if($isInner){
return json_encode(['code'=>500,'msg'=>'生成设备二维码失败:' . $e->getMessage()]);
}else{
return errorJson('生成设备二维码失败:' . $e->getMessage());
}
}
}
/**
* 更新设备账号
* @return \think\response\Json
*/
public function updateaccount($data = [],$isInner = false)
{
// 获取授权token
$authorization = trim($this->request->header('authorization', $this->authorization));
if (empty($authorization)) {
if($isInner){
return json_encode(['code'=>500,'msg'=>'缺少授权信息']);
}else{
return errorJson('缺少授权信息');
}
}
try {
// 获取参数
$id = !empty($data['id']) ? $data['id'] : $this->request->param('id', '');
$accountId = !empty($data['accountId']) ? $data['accountId'] : $this->request->param('accountId', '');
if (empty($id)) {
if($isInner){
return json_encode(['code'=>500,'msg'=>'设备ID不能为空']);
}else{
return errorJson('设备ID不能为空');
}
}
if (empty($accountId)) {
if($isInner){
return json_encode(['code'=>500,'msg'=>'账号id不能为空']);
}else{
return errorJson('账号id不能为空');
}
}
// 设置请求头
$headerData = ['client:system'];
$header = setHeader($headerData, $authorization, 'plain');
// 发送请求
$result = requestCurl($this->baseUrl . 'api/device/updateaccount?accountId=' . $accountId . '&deviceId=' . $id, [], 'PUT', $header);
$response = handleApiResponse($result);
if(empty($response)){
return successJson([],'操作成功');
}else{
return errorJson([],$response);
}
} catch (\Exception $e) {
if($isInner){
return json_encode(['code'=>500,'msg'=>'更新设备账号失败:' . $e->getMessage()]);
}else{
return errorJson('更新设备账号失败:' . $e->getMessage());
}
}
}
/**
* 更新设备所属分组
* @param int $id 设备ID
* @param int $groupId 分组ID
* @return \think\response\Json
*/
public function updateDeviceToGroup($data = [])
{
// 获取授权token
$authorization = trim($this->request->header('authorization', $this->authorization));
if (empty($authorization)) {
return errorJson('缺少授权信息');
}
try {
// 获取参数
$id = !empty($data['id']) ? $data['id'] : $this->request->param('id', '');
$groupId = !empty($data['groupId']) ? $data['groupId'] : $this->request->param('groupId', '');
if (empty($id)) {
return errorJson('设备ID不能为空');
}
if (empty($groupId)) {
return errorJson('分组ID不能为空');
}
// 验证设备是否存在
$device = DeviceModel::where('id', $id)->find();
if (empty($device)) {
return errorJson('设备不存在');
}
// 验证分组是否存在
$group = DeviceGroupModel::where('id', $groupId)->find();
if (empty($group)) {
return errorJson('分组不存在');
}
// 设置请求头
$headerData = ['client:system'];
$header = setHeader($headerData, $authorization, 'plain');
// 发送请求到微信接口
$result = requestCurl($this->baseUrl . 'api/device/updateDeviceGroup?id=' . $id . '&groupId=' . $groupId, [], 'PUT', $header);
$response = handleApiResponse($result);
if (empty($response)) {
// 更新成功,更新本地数据库
$device->groupId = $groupId;
$device->groupName = $group->groupName;
$device->save();
return successJson([], '设备分组更新成功');
} else {
return errorJson([], $response);
}
} catch (\Exception $e) {
return errorJson('更新设备分组失败:' . $e->getMessage());
}
}
/**
* 删除设备
*
* @param $deviceId
* @return false|string
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function delDevice($deviceId = '')
{
$authorization = $this->authorization;
if (empty($authorization)) {
return json_encode(['code'=>500,'msg'=>'缺少授权信息']);
}
if (empty($deviceId)) {
return json_encode(['code'=>500,'msg'=>'删除的设备不能为空']);
}
$device = Db::table('s2_device')->where('id', $deviceId)->find();
if (empty($device)) {
return json_encode(['code'=>500,'msg'=>'设备不存在']);
}
try {
// 设置请求头
$headerData = ['client:system'];
$header = setHeader($headerData, $authorization, 'json');
// 发送请求
$result = requestCurl($this->baseUrl . 'api/device/del/'.$deviceId, [], 'DELETE', $header,'json');
if (empty($result)) {
Db::table('s2_device')->where('id', $deviceId)->update([
'isDeleted' => 1,
'deleteTime' => time()
]);
return json_encode(['code'=>200,'msg'=>'删除成功']);
}else{
return json_encode(['code'=>200,'msg'=>'删除失败']);
}
} catch (\Exception $e) {
return json_encode(['code'=>500,'msg'=>'获取设备分组列表失败:' . $e->getMessage()]);
}
}
/**
* 更新设备联系人
* @param int $id 设备ID
* @param int $groupId 分组ID
* @return \think\response\Json
*/
public function importContact($data = [],$isInner = false)
{
// 获取授权token
$authorization = $this->authorization;
if (empty($authorization)) {
if($isInner){
return json_encode(['code'=>500,'msg'=>'缺少授权信息']);
}else{
return errorJson('缺少授权信息');
}
}
try {
// 获取参数
$deviceId = !empty($data['deviceId']) ? $data['deviceId'] : $this->request->param('deviceId', '');
$rawContactJson = !empty($data['contactJson']) ? $data['contactJson'] : $this->request->param('contactJson', '');
$clearContact = !empty($data['clearContact']) ? $data['clearContact'] : $this->request->param('clearContact', false);
if (empty($deviceId)) {
if($isInner){
return json_encode(['code'=>500,'msg'=>'设备ID不能为空']);
}else{
return errorJson('设备ID不能为空');
}
}
$contacts = [];
if (!empty($rawContactJson)) {
if (is_string($rawContactJson)) {
$decodedContacts = json_decode($rawContactJson, true);
if (json_last_error() === JSON_ERROR_NONE) {
// It's a valid JSON string
$contacts = $decodedContacts;
} else {
// It's not a JSON string, treat as multi-line text
$lines = explode("\n", str_replace("\r\n", "\n", $rawContactJson));
foreach ($lines as $line) {
$line = trim($line);
if (empty($line)) continue;
$parts = explode(',', $line);
if (count($parts) == 2) {
$contacts[] = ['name' => trim($parts[0]), 'phone' => trim($parts[1])];
}
}
}
} elseif (is_array($rawContactJson)) {
// It's already an array
$contacts = $rawContactJson;
}
}
if (empty($contacts)){
if($isInner){
return json_encode(['code'=>500,'msg'=>'更新设备联系人失败:通讯录不能为空' ]);
}else{
return errorJson('更新设备联系人失败:通讯录不能为空' );
}
}
// Trim whitespace from name and phone in all cases
if (!empty($contacts)) {
foreach ($contacts as &$contact) {
if (isset($contact['name'])) {
$contact['name'] = trim($contact['name']);
}
if (isset($contact['phone'])) {
$contact['phone'] = trim($contact['phone']);
}
}
unset($contact); // Unset reference to the last element
}
$contactJsonForApi = json_encode($contacts);
// 构建请求参数
$params = [
'deviceId' => $deviceId,
'contactJson' => $contactJsonForApi,
'clearContact' => $clearContact
];
// 设置请求头
$headerData = ['client:system'];
$header = setHeader($headerData, $authorization, 'json');
// 发送请求
$result = requestCurl($this->baseUrl . 'api/device/importContact', $params, 'POST', $header,'json');
$response = handleApiResponse($result);
if(empty($response)){
if($isInner){
return json_encode(['code'=>200,'msg'=>'更新设备联系人成功' ]);
}else{
return successJson([],'更新设备联系人失败:通讯录不能为空' );
}
}else{
if($isInner){
return json_encode(['code'=>200,'msg'=> $response ]);
}else{
return successJson([],$response );
}
}
} catch (\Exception $e) {
if($isInner){
return json_encode(['code'=>500,'msg'=>'更新设备联系人失败:' . $e->getMessage()]);
}else{
return errorJson('更新设备联系人失败:' . $e->getMessage());
}
}
}
/************************ 设备分组相关接口 ************************/
/**
* 获取设备分组列表
* @return \think\response\Json
*/
public function getGroupList($data = [],$isInner = false)
{
// 获取授权token
$authorization = trim($this->request->header('authorization', $this->authorization));
if (empty($authorization)) {
if($isInner){
return json_encode(['code'=>500,'msg'=>'缺少授权信息']);
}else{
return errorJson('缺少授权信息');
}
}
try {
// 设置请求头
$headerData = ['client:system'];
$header = setHeader($headerData, $authorization, 'json');
// 发送请求
$result = requestCurl($this->baseUrl . 'api/DeviceGroup/list', [], 'GET', $header,'json');
$response = handleApiResponse($result);
// 保存数据到数据库
if (!empty($response)) {
foreach ($response as $item) {
$this->saveDeviceGroup($item);
}
}
if($isInner){
return json_encode(['code'=>200,'msg'=>'success','data'=>$response]);
}else{
return successJson($response);
}
} catch (\Exception $e) {
if($isInner){
return json_encode(['code'=>500,'msg'=>'获取设备分组列表失败:' . $e->getMessage()]);
}else{
return errorJson('获取设备分组列表失败:' . $e->getMessage());
}
}
}
/**
* 创建设备分组
* @return \think\response\Json
*/
public function createGroup($data = [],$isInner = false)
{
// 获取授权token
$authorization = trim($this->request->header('authorization', $this->authorization));
if (empty($authorization)) {
if($isInner){
return json_encode(['code'=>500,'msg'=>'缺少授权信息']);
}else{
return errorJson('缺少授权信息');
}
}
try {
// 获取参数
$groupName = !empty($data['groupName']) ? $data['groupName'] : $this->request->param('groupName', '');
$groupMemo = !empty($data['groupMemo']) ? $data['groupMemo'] : $this->request->param('groupMemo', '');
if (empty($groupName)) {
if($isInner){
return json_encode(['code'=>500,'msg'=>'分组名称不能为空']);
}else{
return errorJson('分组名称不能为空');
}
}
// 构建请求参数
$params = [
'groupName' => $groupName,
'groupMemo' => $groupMemo
];
// 设置请求头
$headerData = ['client:system'];
$header = setHeader($headerData, $authorization, 'json');
// 发送请求
$result = requestCurl($this->baseUrl . 'api/DeviceGroup/new', $params, 'POST', $header,'json');
if(empty($result)){
// $res = $this->getGroupList([],true);
// $res = json_decode($res,true);
// if(!empty($res['data'])){
// $data = $res['data'][0];
// }
$data = [];
if($isInner){
return json_encode(['code'=>200,'msg'=>'success','data'=>$data]);
}else{
return successJson($data,'操作成功');
}
}else{
if($isInner){
return json_encode(['code'=>500,'msg'=> $result]);
}else{
return errorJson($result);
}
}
} catch (\Exception $e) {
if($isInner){
return json_encode(['code'=>500,'msg'=>'创建设备分组失败:' . $e->getMessage()]);
}else{
return errorJson('创建设备分组失败:' . $e->getMessage());
}
}
}
/**
* 更新设备分组
* @return \think\response\Json
*/
public function updateDeviceGroup($data = [],$isInner = false)
{
// 获取授权token
$authorization = trim($this->request->header('authorization', $this->authorization));
if (empty($authorization)) {
if($isInner){
return json_encode(['code'=>500,'msg'=>'缺少授权信息']);
}else{
return errorJson('缺少授权信息');
}
}
try {
// 获取参数
$id = !empty($data['id']) ? $data['id'] : $this->request->param('id', '');
$groupName = !empty($data['groupName']) ? $data['groupName'] : $this->request->param('groupName', '');
$groupMemo = !empty($data['groupMemo']) ? $data['groupMemo'] : $this->request->param('groupMemo', '');
if (empty($id)) {
if($isInner){
return json_encode(['code'=>500,'msg'=>'分组ID不能为空']);
}else{
return errorJson('分组ID不能为空');
}
}
if (empty($groupName)) {
if($isInner){
return json_encode(['code'=>500,'msg'=>'分组名称不能为空']);
}else{
return errorJson('分组名称不能为空');
}
}
$group = DeviceGroupModel::where('id', $id)->find();
if(empty($group)){
if($isInner){
return json_encode(['code'=>500,'msg'=>'分组不存在']);
}else{
return errorJson('分组不存在');
}
}
$isGroupName = DeviceGroupModel::where('groupName', $groupName)->find();
if(!empty($isGroupName)){
if($isInner){
return json_encode(['code'=>500,'msg'=>'分组名称已存在']);
}else{
return errorJson('分组名称已存在');
}
}
// 设置请求头
$headerData = ['client:system'];
$header = setHeader($headerData, $authorization, 'json');
// 从数据库获取对象后创建一个正确格式的数组用于API请求
$requestData = [
'id' => $group->id,
'tenantId' => $group->tenantId,
'groupName' => $groupName,
'groupMemo' => $groupMemo
];
// 发送请求
$result = requestCurl($this->baseUrl . 'api/DeviceGroup/update', $requestData, 'PUT', $header, 'json');
if(empty($result)){
$group->groupName = $groupName;
$group->groupMemo = $groupMemo;
$group->save();
if($isInner){
return json_encode(['code'=>200,'msg'=>'success','data'=>$group]);
}else{
return successJson($group,'操作成功');
}
}else{
if($isInner){
return json_encode(['code'=>500,'msg'=> $result]);
}else{
return errorJson($result);
}
}
} catch (\Exception $e) {
if($isInner){
return json_encode(['code'=>500,'msg'=>'更新设备分组失败:' . $e->getMessage()]);
}else{
return errorJson('更新设备分组失败:' . $e->getMessage());
}
}
}
/************************ 私有辅助方法 ************************/
/**
* 保存设备数据到数据库
* @param array $item 设备数据
*/
private function saveDevice($item)
{
$data = [
'id' => isset($item['id']) ? $item['id'] : '',
'userName' => isset($item['userName']) ? $item['userName'] : '',
'nickname' => isset($item['nickname']) ? $item['nickname'] : '',
'realName' => isset($item['realName']) ? $item['realName'] : '',
'groupName' => isset($item['groupName']) ? $item['groupName'] : '',
'wechatAccounts' => isset($item['wechatAccounts']) ? json_encode($item['wechatAccounts']) : json_encode([]),
'alive' => isset($item['alive']) ? $item['alive'] : false,
'lastAliveTime' => isset($item['lastAliveTime']) ? $item['lastAliveTime'] : null,
'tenantId' => isset($item['tenantId']) ? $item['tenantId'] : 0,
'groupId' => isset($item['groupId']) ? $item['groupId'] : 0,
'currentAccountId' => isset($item['currentAccountId']) ? $item['currentAccountId'] : 0,
'imei' => $item['imei'],
'memo' => isset($item['memo']) ? $item['memo'] : '',
'createTime' => isset($item['createTime']) ? strtotime($item['createTime']) : 0,
'isDeleted' => isset($item['isDeleted']) ? $item['isDeleted'] : false,
'deletedAndStop' => isset($item['deletedAndStop']) ? $item['deletedAndStop'] : false,
'deleteTime' => empty($item['isDeleted']) ? 0 : strtotime($item['deleteTime']),
'rooted' => isset($item['rooted']) ? $item['rooted'] : false,
'xPosed' => isset($item['xPosed']) ? $item['xPosed'] : false,
'brand' => isset($item['brand']) ? $item['brand'] : '',
'model' => isset($item['model']) ? $item['model'] : '',
'operatingSystem' => isset($item['operatingSystem']) ? $item['operatingSystem'] : '',
'softwareVersion' => isset($item['softwareVersion']) ? $item['softwareVersion'] : '',
'extra' => isset($item['extra']) ? json_encode($item['extra']) : json_encode([]),
'phone' => isset($item['phone']) ? $item['phone'] : '',
'lastUpdateTime' => isset($item['lastUpdateTime']) ? ($item['lastUpdateTime'] == '0001-01-01T00:00:00' ? 0 : strtotime($item['lastUpdateTime'])) : 0
];
if (!empty($data['alive'])){
$data['aliveTime'] = time();
}
// 使用imei作为唯一性判断
$device = DeviceModel::where('id', $item['id'])->find();
if ($device) {
$device->save($data);
} else {
// autoLike自动点赞
// momentsSync朋友圈同步
// autoCustomerDev自动开发客户
// groupMessageDeliver群消息推送
// autoGroup自动建群
$data['taskConfig'] = json_encode([
'autoLike' => true,
'momentsSync' => true,
'autoCustomerDev' => true,
'groupMessageDeliver' => true,
'autoGroup' => true,
]);
DeviceModel::create($data);
}
}
/**
* 保存设备分组数据到数据库
* @param array $item 设备分组数据
*/
private function saveDeviceGroup($item)
{
$data = [
'id' => $item['id'],
'tenantId' => $item['tenantId'],
'groupName' => $item['groupName'],
'groupMemo' => $item['groupMemo'],
'count' => isset($item['count']) ? $item['count'] : 0,
'createTime' => $item['createTime'] == '0001-01-01T00:00:00' ? 0 : strtotime($item['createTime'])
];
// 使用ID作为唯一性判断
$group = DeviceGroupModel::where('id', $item['id'])->find();
if ($group) {
$group->save($data);
} else {
DeviceGroupModel::create($data);
}
}
/**
* 生成二维码图片base64格式
* @param string $data 二维码数据
* @return string base64编码的图片
*/
private function generateQrCodeImage($data)
{
// 使用endroid/qr-code 2.5版本生成二维码
$qrCode = new QrCode($data);
$qrCode->setSize(300);
$qrCode->setMargin(10);
$qrCode->setWriterByName('png');
$qrCode->setEncoding('UTF-8');
// 使用枚举常量而不是字符串
$qrCode->setErrorCorrectionLevel(ErrorCorrectionLevel::HIGH);
// 直接获取base64内容
$base64 = 'data:image/png;base64,' . base64_encode($qrCode->writeString());
return $base64;
}
}

View File

@@ -0,0 +1,192 @@
<?php
namespace app\api\controller;
use app\api\model\FriendTaskModel;
use app\common\model\WechatRestricts;
use think\facade\Request;
class FriendTaskController extends BaseController
{
/************************ 好友任务管理相关接口 ************************/
/**
* 获取添加好友记录列表
* @param int $pageIndex 页码
* @param int $pageSize 每页数量
* @param bool $isInner 是否为定时任务调用
* @return \think\response\Json
*/
public function getlist($pageIndex, $pageSize, $isInner = false)
{
// 获取授权token
$authorization = $this->authorization;
if (empty($authorization)) {
if($isInner){
return json_encode(['code'=>500,'msg'=>'缺少授权信息']);
}else{
return errorJson('缺少授权信息');
}
}
try {
// 构建请求参数
$params = [
'keyword' => $this->request->param('keyword', ''),
'status' => $this->request->param('status', ''),
'pageIndex' => !empty($pageIndex) ? $pageIndex : $this->request->param('pageIndex', 0),
'pageSize' => !empty($pageSize) ? $pageSize : $this->request->param('pageSize', 20),
];
// 设置请求头
$headerData = ['client:system'];
$header = setHeader($headerData, $authorization, 'json');
// 发送请求获取添加好友记录列表
$result = requestCurl($this->baseUrl . 'api/AddFriendByPhoneTask/list', $params, 'GET', $header,'json');
$response = handleApiResponse($result);
// 保存数据到数据库
if (!empty($response['results'])) {
foreach ($response['results'] as $item) {
$this->saveFriendTask($item);
}
}
if($isInner){
return json_encode(['code'=>200,'msg'=>'获取添加好友记录列表成功','data'=>$response]);
}else{
return successJson($response);
}
} catch (\Exception $e) {
if($isInner){
return json_encode(['code'=>500,'msg'=>'获取添加好友记录列表失败:' . $e->getMessage()]);
}else{
return errorJson('获取添加好友记录列表失败:' . $e->getMessage());
}
}
}
/**
* 添加好友任务
* @return \think\response\Json
*/
public function addFriendTask($data = [])
{
// 获取授权token
$authorization =$this->authorization;
if (empty($authorization)) {
return json_encode(['code'=>500,'msg'=>'缺少授权信息']);
}
try {
// 获取请求参数
$phone = !empty($data['phone']) ? $data['phone'] : '';
$message = !empty($data['message']) ? $data['message'] : '';
$remark = !empty($data['remark']) ? $data['remark'] : '';
$labels = !empty($data['labels']) ? $data['labels'] : '';
$wechatAccountId = !empty($data['wechatAccountId']) ? $data['wechatAccountId'] : '';
// 参数验证
if (empty($phone)) {
return json_encode(['code'=>500,'msg'=>'手机号不能为空']);
}
if (empty($wechatAccountId)) {
return json_encode(['code'=>500,'msg'=>'微信号不能为空']);
}
// 构建请求参数
$params = [
'phone' => $phone,
'message' => $message,
'remark' => $remark,
'labels' => is_array($labels) ? $labels : [$labels],
'wechatAccountId' => (int)$wechatAccountId
];
// 设置请求头
$headerData = ['client:system'];
$header = setHeader($headerData, $authorization, 'json');
// 发送请求添加好友任务
$result = requestCurl($this->baseUrl . 'api/AddFriendByPhoneTask/add', $params, 'POST', $header, 'json');
// 处理响应
return json_encode(['code'=>200,'msg'=>'添加好友任务创建成功']);
} catch (\Exception $e) {
return json_encode(['code'=>500,'msg'=> '添加好友任务失败:' . $e->getMessage()]);
}
}
/************************ 私有辅助方法 ************************/
/**
* 保存添加好友记录到数据库
* @param array $item 添加好友记录数据
*/
private function saveFriendTask($item)
{
// 将日期时间字符串转换为时间戳
$createTime = isset($item['createTime']) ? strtotime($item['createTime']) : null;
$data = [
'id' => $item['id'],
'tenantId' => $item['tenantId'],
'operatorAccountId' => $item['operatorAccountId'],
'status' => $item['status'],
'phone' => $item['phone'],
'msgContent' => $item['msgContent'],
'wechatAccountId' => $item['wechatAccountId'],
'createTime' => $createTime,
'remark' => $item['remark'],
'extra' => $item['extra'],
'labels' => $item['labels'],
'from' => $item['from'],
'alias' => $item['alias'],
'wechatId' => $item['wechatId'],
'wechatAvatar' => $item['wechatAvatar'],
'wechatNickname' => $item['wechatNickname'],
'accountNickname' => $item['accountNickname'],
'accountRealName' => $item['accountRealName'],
'accountUsername' => $item['accountUsername']
];
// 使用taskId作为唯一性判断
$task = FriendTaskModel::where('id', $item['id'])->find();
if ($task) {
$task->save($data);
} else {
FriendTaskModel::create($data);
}
//创建非法记录
if ($item['status'] == 2){
$data = [
'level' => 2,
'taskId' => $item['id'],
'reason' => '',
'memo' => '',
'wechatId' => $item['wechatId'],
'companyId' => '',
'restrictTime' => time(),
'recoveryTime' => time() + 3600 * 72,
];
if (strpos('操作过于频繁', $item['extra']) !== false){
$data['reason'] = '频繁添加好友';
$data['memo'] = '操作过于频繁,请稍后再试';
}
if (strpos('当前账号存在安全风险', $item['extra']) !== false){
$data['reason'] = '账号风险';
$data['memo'] = '当前账号存在安全风险,需先到「微信团队」进行安全验证后才能继续使用当前功能';
}
$res = WechatRestricts::where('taskId', $item['id'])->find();
if (empty($res)) {
WechatRestricts::create($data);
}
}
}
}

View File

@@ -0,0 +1,584 @@
<?php
namespace app\api\controller;
use app\api\model\WechatMessageModel;
use think\Db;
use think\facade\Request;
class MessageController extends BaseController
{
/************************ 好友消息相关接口 ************************/
/**
* 获取微信好友列表
* @return \think\response\Json
*/
public function getFriendsList($pageIndex = '',$pageSize = '',$isInner = false)
{
// 获取授权token
$authorization = trim($this->request->header('authorization', $this->authorization));
if (empty($authorization)) {
if($isInner){
return json_encode(['code'=>500,'msg'=>'缺少授权信息']);
}else{
return errorJson('缺少授权信息');
}
}
$fromTime = $this->request->param('fromTime', date('Y-m-d 00:00:00', strtotime('-1 days')));
$toTime = $this->request->param('toTime', date('Y-m-d 23:59:59'));
try {
// 构建请求参数
$params = [
'chatroomKeyword' => $this->request->param('chatroomKeyword', ''),
'friendKeyword' => $this->request->param('friendKeyword', ''),
'friendPhoneKeyword' => $this->request->param('friendPhoneKeyword', ''),
'friendPinYinKeyword' => $this->request->param('friendPinYinKeyword', ''),
'friendRegionKeyword' => $this->request->param('friendRegionKeyword', ''),
'friendRemarkKeyword' => $this->request->param('friendRemarkKeyword', ''),
'groupId' => $this->request->param('groupId', null),
'kefuId' => $this->request->param('kefuId', null),
'labels' => $this->request->param('labels', []),
'msgFrom' => $fromTime,
'msgKeyword' => $this->request->param('msgKeyword', ''),
'msgTo' => $toTime,
'msgType' => $this->request->param('msgType', ''),
'pageIndex' => !empty($pageIndex) ? $pageIndex : input('pageIndex', 0),
'pageSize' => !empty($pageSize) ? $pageSize : input('pageSize', 20),
'reverse' => $this->request->param('reverse', false),
'type' => $this->request->param('type', 'friend'),
'wechatAccountIds' => $this->request->param('wechatAccountIds', [])
];
// 设置请求头
$headerData = ['client:system'];
$header = setHeader($headerData, $authorization, 'json');
// 发送请求获取好友列表
$result = requestCurl($this->baseUrl . 'api/WechatFriend/listWechatFriendForMsgPagination', $params, 'POST', $header, 'json');
$response = handleApiResponse($result);
// 获取同步消息标志
$syncMessages = $this->request->param('syncMessages', true);
// 如果需要同步消息,则获取每个好友的消息
if ($syncMessages && !empty($response['results'])) {
$from = strtotime($fromTime) * 1000;
$to = strtotime($toTime) * 1000;
foreach ($response['results'] as &$friend) {
// 构建获取消息的参数
$messageParams = [
'keyword' => '',
'msgType' => '',
'accountId' => '',
'count' => 20,
'messageId' => '',
'olderData' => true,
'wechatAccountId' => $friend['wechatAccountId'],
'wechatFriendId' => $friend['wechatFriendId'],
'from' => $from,
'to' => $to,
'searchFrom' => 'admin'
];
// 调用获取消息的接口
$messageResult = requestCurl($this->baseUrl . 'api/FriendMessage/searchMessage', $messageParams, 'GET', $header, 'json');
$messageResponse = handleApiResponse($messageResult);
// 保存消息到数据库
if (!empty($messageResponse)) {
foreach ($messageResponse as $item) {
$this->saveMessage($item);
}
}
// 将消息列表添加到好友数据中
$friend['messages'] = $messageResponse ?? [];
}
unset($friend);
}
if($isInner){
return json_encode(['code'=>200,'msg'=>'获取好友列表成功','data'=>$response]);
}else{
return successJson($response);
}
} catch (\Exception $e) {
if($isInner){
return json_encode(['code'=>500,'msg'=>'获取好友列表失败:' . $e->getMessage()]);
}else{
return errorJson('获取好友列表失败:' . $e->getMessage());
}
}
}
/**
* 用户聊天记录
* @return \think\response\Json
*/
public function getMessageList()
{
// 获取授权token
$authorization = trim($this->request->header('authorization', $this->authorization));
if (empty($authorization)) {
return errorJson('缺少授权信息');
}
try {
// 构建请求参数
$params = [
'keyword' => $this->request->param('keyword', ''),
'msgType' => $this->request->param('msgType', ''),
'accountId' => $this->request->param('accountId', ''),
'count' => $this->request->param('count', 100),
'messageId' => $this->request->param('messageId', ''),
'olderData' => $this->request->param('olderData', true),
'wechatAccountId' => $this->request->param('wechatAccountId', ''),
'wechatFriendId' => $this->request->param('wechatFriendId', ''),
'from' => $this->request->param('from', ''),
'to' => $this->request->param('to', ''),
'searchFrom' => $this->request->param('searchFrom', 'admin')
];
// 参数验证
if (empty($params['wechatAccountId'])) {
return errorJson('微信账号ID不能为空');
}
if (empty($params['wechatFriendId'])) {
return errorJson('好友ID不能为空');
}
// 设置请求头
$headerData = ['client:system'];
$header = setHeader($headerData, $authorization, 'json');
// 发送请求获取聊天记录
$result = requestCurl($this->baseUrl . 'api/FriendMessage/searchMessage', $params, 'GET', $header, 'json');
$response = handleApiResponse($result);
// 保存数据到数据库
if (!empty($response)) {
foreach ($response as $item) {
$this->saveMessage($item);
}
}
return successJson($response);
} catch (\Exception $e) {
return errorJson('获取聊天记录失败:' . $e->getMessage());
}
}
/************************ 群聊消息相关接口 ************************/
/**
* 获取微信群聊列表
* @return \think\response\Json
*/
public function getChatroomList($pageIndex = '',$pageSize = '',$isInner = false)
{
// 获取授权token
$authorization = trim($this->request->header('authorization', $this->authorization));
if (empty($authorization)) {
if($isInner){
return json_encode(['code'=>500,'msg'=>'缺少授权信息']);
}else{
return errorJson('缺少授权信息');
}
}
$fromTime = $this->request->param('fromTime', date('Y-m-d 00:00:00', strtotime('-1 days')));
$toTime = $this->request->param('toTime', date('Y-m-d 23:59:59'));
try {
// 构建请求参数
$params = [
'chatroomKeyword' => $this->request->param('chatroomKeyword', ''),
'friendKeyword' => $this->request->param('friendKeyword', ''),
'friendInKeyword' => $this->request->param('friendInKeyword', ''),
'friendInTimeKeyword' => $this->request->param('friendInTimeKeyword', ''),
'friendOutKeyword' => $this->request->param('friendOutKeyword', ''),
'friendRemarkKeyword' => $this->request->param('friendRemarkKeyword', ''),
'groupId' => $this->request->param('groupId', null),
'kefuId' => $this->request->param('kefuId', null),
'labels' => $this->request->param('labels', []),
'msgFrom' => $fromTime,
'msgKeyword' => $this->request->param('msgKeyword', ''),
'msgTo' => $toTime,
'msgType' => $this->request->param('msgType', ''),
'pageIndex' => $this->request->param('pageIndex', 0),
'pageSize' => $this->request->param('pageSize', 100),
'reverse' => $this->request->param('reverse', false),
'type' => $this->request->param('type', 'chatroom'),
'wechatAccountIds' => $this->request->param('wechatAccountIds', [])
];
// 设置请求头
$headerData = ['client:system'];
$header = setHeader($headerData, $authorization, 'json');
// 发送请求获取群聊列表
$result = requestCurl($this->baseUrl . 'api/WechatChatroom/listWechatChatroomForMsgPagination', $params, 'POST', $header, 'json');
$response = handleApiResponse($result);
// 获取同步消息标志
$syncMessages = $this->request->param('syncMessages', true);
// 如果需要同步消息,则获取每个群的消息
if ($syncMessages && !empty($response)) {
$from = strtotime($fromTime) * 1000;
$to = strtotime($toTime) * 1000;
foreach ($response['results'] as &$chatroom) {
// 构建获取消息的参数
$messageParams = [
'keyword' => '',
'msgType' =>'',
'accountId' => '',
'count' => 20,
'messageId' => '',
'olderData' => true,
'wechatId' => '',
'wechatAccountId' => $chatroom['wechatAccountId'],
'wechatChatroomId' => $chatroom['wechatChatroomId'],
'from' => $from,
'to' => $to,
'searchFrom' => 'admin'
];
// 调用获取消息的接口
$messageResult = requestCurl($this->baseUrl . 'api/ChatroomMessage/searchMessage', $messageParams, 'GET', $header, 'json');
$messageResponse = handleApiResponse($messageResult);
// 保存消息到数据库
if (!empty($messageResponse)) {
foreach ($messageResponse as $item) {
$this->saveChatroomMessage($item);
}
}
// 将消息列表添加到群聊数据中
$chatroom['messages'] = $messageResponse ?? [];
}
unset($chatroom);
}
if($isInner){
return json_encode(['code'=>200,'msg'=>'获取群聊列表成功','data'=>$response]);
}else{
return successJson($response);
}
} catch (\Exception $e) {
if($isInner){
return json_encode(['code'=>500,'msg'=>'获取群聊列表失败:' . $e->getMessage()]);
}else{
return errorJson('获取群聊列表失败:' . $e->getMessage());
}
}
}
/**
* 获取群聊消息列表
* @return \think\response\Json
*/
public function getChatroomMessages()
{
// 获取授权token
$authorization = trim($this->request->header('authorization', $this->authorization));
if (empty($authorization)) {
return errorJson('缺少授权信息');
}
try {
// 构建请求参数
$params = [
'keyword' => $this->request->param('keyword', ''),
'msgType' => $this->request->param('msgType', ''),
'accountId' => $this->request->param('accountId', ''),
'count' => $this->request->param('count', 100),
'messageId' => $this->request->param('messageId', ''),
'olderData' => $this->request->param('olderData', true),
'wechatId' => $this->request->param('wechatId', ''),
'wechatAccountId' => $this->request->param('wechatAccountId', ''),
'wechatChatroomId' => $this->request->param('wechatChatroomId', ''),
'from' => $this->request->param('from', strtotime(date('Y-m-d 00:00:00', strtotime('-1 days')))),
'to' => $this->request->param('to', strtotime(date('Y-m-d 00:00:00'))),
'searchFrom' => $this->request->param('searchFrom', 'admin')
];
// 参数验证
if (empty($params['wechatAccountId'])) {
return errorJson('微信账号ID不能为空');
}
if (empty($params['wechatChatroomId'])) {
return errorJson('群聊ID不能为空');
}
// 设置请求头
$headerData = ['client:system'];
$header = setHeader($headerData, $authorization, 'json');
// 发送请求获取群聊消息
$result = requestCurl($this->baseUrl . 'api/ChatroomMessage/searchMessage', $params, 'GET', $header, 'json');
$response = handleApiResponse($result);
// 保存数据到数据库
if (!empty($response)) {
foreach ($response as $item) {
$res = $this->saveChatroomMessage($item);
if(!$res){
return errorJson('保存群聊消息失败');
}
}
}
return successJson($response);
} catch (\Exception $e) {
return errorJson('获取群聊消息失败:' . $e->getMessage());
}
}
/************************ 私有辅助方法 ************************/
/**
* 保存消息记录到数据库
* @param array $item 消息记录数据
*/
public function saveMessage($item)
{
// 检查消息是否已存在
$exists = WechatMessageModel::where('id', $item['id']) ->find();
if (!empty($exists) && $exists['sendStatus'] == 0){
return true;
}
// 将毫秒时间戳转换为秒级时间戳
$createTime = isset($item['createTime']) ? strtotime($item['createTime']) : null;
$deleteTime = !empty($item['isDeleted']) ? strtotime($item['deleteTime']) : null;
$wechatTime = isset($item['wechatTime']) ? floor($item['wechatTime'] / 1000) : null;
$data = [
'id' => $item['id'],
'type' => 1,
'accountId' => $item['accountId'],
'content' => $item['content'],
'createTime' => $createTime,
'deleteTime' => $deleteTime,
'isDeleted' => $item['isDeleted'] ?? false,
'isSend' => $item['isSend'] ?? true,
'msgId' => $item['msgId'],
'msgSubType' => $item['msgSubType'] ?? 0,
'msgSvrId' => $item['msgSvrId'] ?? '',
'msgType' => $item['msgType'],
'origin' => $item['origin'] ?? 0,
'recallId' => $item['recallId'] ?? false,
'sendStatus' => $item['sendStatus'] ?? 0,
'synergyAccountId' => $item['synergyAccountId'] ?? 0,
'tenantId' => $item['tenantId'],
'wechatAccountId' => $item['wechatAccountId'],
'wechatFriendId' => $item['wechatFriendId'],
'wechatTime' => $wechatTime
];
//已被删除
if ($item['msgType'] == 10000 && strpos($item['content'],'开启了朋友验证') !== false) {
Db::table('s2_wechat_friend')->where('id',$item['wechatFriendId'])->update(['isDeleted'=> 1,'deleteTime' => $wechatTime]);
}else{
//优先分配在线客服
$friend = Db::table('s2_wechat_friend')->where('id',$item['wechatFriendId'])->find();
if (!empty($friend)){
$accountId = $item['accountId'];
$accountData = Db::table('s2_company_account')->where('id',$accountId)->find();
if (!empty($accountData)){
$account = new AccountController();
$account->getlist(['pageIndex' => 0,'pageSize' => 100,'departmentId' => $accountData['departmentId']]);
$accountIds = Db::table('s2_company_account')->where(['departmentId' => $accountData['departmentId'],'alive' => 1])->column('id');
if (!empty($accountIds)){
if (!in_array($friend['accountId'],$accountIds)){
// 执行切换好友命令
$randomKey = array_rand($accountIds, 1);
$toAccountId = $accountIds[$randomKey];
$toAccountData = Db::table('s2_company_account')->where('id',$toAccountId)->find();
$automaticAssign = new AutomaticAssign();
$automaticAssign->allotWechatFriend([
'wechatFriendId' => $friend['id'],
'toAccountId' => $toAccountId
], true);
Db::table('s2_wechat_friend')
->where('id',$friend['id'])
->update([
'accountId' => $toAccountId,
'accountUserName' => $toAccountData['userName'],
'accountRealName' => $toAccountData['realName'],
'accountNickname' => $toAccountData['nickname'],
]);
}
}
}
}
}
$id = '';
if (empty($exists)){
// 创建新记录
$res = WechatMessageModel::create($data);
$id= $res['id'];
}else{
$id = $data['id'];
unset($data['id']);
$res = $exists->save($data);
}
// 1 文字 3图片 47动态图片 34语言 43视频 42名片 40/20链接 49文件
if (!empty($res) && empty($item['isSend']) && in_array($item['msgType'],[1,3,20,34,40,42,43,47,49])){
$friend = Db::name('wechat_friendship')->where('id',$item['wechatFriendId'])->find();
if (!empty($friend)){
$trafficPoolId = Db::name('traffic_pool')->where('identifier',$friend['wechatId'])->value('id');
if (!empty($trafficPoolId)){
$data = [
'type' => 4,
'companyId' => $friend['companyId'],
'trafficPoolId' => $trafficPoolId,
'source' => 0,
'uniqueId' => $id,
'sourceData' => json_encode([]),
'remark' => '用户发送了消息',
'createTime' => time(),
'updateTime' => time()
];
Db::name('user_portrait')->insert($data);
}
}
}
return true;
}
/**
* 保存群聊消息记录到数据库
* @param array $item 消息记录数据
* @return bool 是否保存成功
*/
public function saveChatroomMessage($item)
{
// 检查消息是否已存在
$exists = WechatMessageModel::where('id', $item['id'])->find();
if (!empty($exists) && $exists['sendStatus'] == 0){
return true;
}
// 处理发送者信息
$sender = $item['sender'] ?? [];
// 处理消息内容提取发送者ID和消息内容
$originalContent = $item['content'] ?? '';
$processedResult = $this->processMessageContent($originalContent);
$senderId = $processedResult['senderId'];
$processedContent = $processedResult['content'];
// 将毫秒时间戳转换为秒级时间戳
$createTime = isset($item['createTime']) ? strtotime($item['createTime']) : null;
$deleteTime = !empty($item['isDeleted']) ? strtotime($item['deleteTime']) : null;
$wechatTime = isset($item['wechatTime']) ? floor($item['wechatTime'] / 1000) : null;
$data = [
'id' => $item['id'],
'type' => 2,
'wechatChatroomId' => $item['wechatChatroomId'],
// sender信息添加sender前缀
'senderNickname' => $sender['nickname'] ?? '',
'senderWechatId' => $sender['wechatId'] ?? $senderId, // 使用提取的发送者ID作为备选
'senderIsAdmin' => $sender['isAdmin'] ?? false,
'senderIsDeleted' => $sender['isDeleted'] ?? false,
'senderChatroomNickname' => $sender['chatroomNickname'] ?? '',
'senderWechatAccountId' => $sender['wechatAccountId'] ?? '',
// 其他字段
'wechatAccountId' => $item['wechatAccountId'],
'tenantId' => $item['tenantId'],
'accountId' => $item['accountId'],
'synergyAccountId' => $item['synergyAccountId'] ?? 0,
'content' => $processedContent, // 使用处理后的内容
'originalContent' => $originalContent, // 保存原始内容
'msgType' => $item['msgType'],
'msgSubType' => $item['msgSubType'] ?? 0,
'msgSvrId' => $item['msgSvrId'] ?? '',
'isSend' => $item['isSend'] ?? true,
'createTime' => $createTime,
'isDeleted' => $item['isDeleted'] ?? false,
'deleteTime' => $deleteTime,
'sendStatus' => $item['sendStatus'] ?? 0,
'wechatTime' => $wechatTime,
'origin' => $item['origin'] ?? 0,
'msgId' => $item['msgId'],
'recallId' => $item['recallId'] ?? false
];
// 创建新记录
try {
if(empty($exists)){
WechatMessageModel::create($data);
}else{
unset($data['id']);
$exists->save($data);
}
return true;
} catch (\Exception $e) {
return false;
}
}
/**
* 处理消息内容提取发送者ID和消息内容
* @param string $content 原始消息内容
* @return array 包含senderId和content的数组
*/
private function processMessageContent($content)
{
if (empty($content)) {
return [
'senderId' => '',
'content' => ''
];
}
// 处理消息格式wxid_vr2qafb1vg0d22:\n安德玛儿童
if (preg_match('/^([^:]+):\n(.+)$/s', $content, $matches)) {
$senderId = trim($matches[1]);
$messageContent = trim($matches[2]);
// 检查消息内容是否为JSON格式
if (substr($messageContent, 0, 1) === '{' && substr($messageContent, -1) === '}') {
try {
// 尝试解析JSON
$jsonData = json_decode($messageContent, true);
if (json_last_error() == JSON_ERROR_NONE && isset($jsonData['text'])) {
// 如果是合法的JSON且包含text字段则提取text字段作为内容
$messageContent = $jsonData['text'];
}
} catch (\Exception $e) {
// JSON解析出错保持原内容不变
}
}
return [
'senderId' => $senderId,
'content' => $messageContent
];
}
// 如果没有匹配到格式,则返回原始内容
return [
'senderId' => '',
'content' => $content
];
}
}

View File

@@ -0,0 +1,153 @@
<?php
namespace app\api\controller;
use think\facade\Request;
class MomentsController extends BaseController
{
/************************ 朋友圈发布相关接口 ************************/
/**
* 发布朋友圈
* @return \think\response\Json
*/
public function addJob($data = [])
{
// 获取授权token
$authorization = $this->authorization;
if (empty($authorization)) {
return json_encode(['msg' => '缺少授权信息','code' => 400]);
}
try {
// 获取请求参数
$text = $data['text'] ?? ''; // 朋友圈文本内容
$picUrlList = $data['picUrlList'] ?? []; // 图片URL列表
$videoUrl = $data['videoUrl'] ?? ''; // 视频URL
$immediately = $data['immediately'] ?? true; // 是否立即发布
$timingTime = $data['timingTime'] ?? ''; // 定时发布时间
$beginTime = $data['beginTime'] ?? ''; // 开始时间
$endTime = $data['endTime'] ?? ''; // 结束时间
$isUseLocation = $data['isUseLocation'] ?? false; // 是否使用位置信息
$poiName = $data['poiName'] ?? ''; // 位置名称
$poiAddress = $data['poiAddress'] ?? ''; // 位置地址
$lat = $data['lat'] ?? 0; // 纬度
$lng = $data['lng'] ?? 0; // 经度
$momentContentType = $data['momentContentType'] ?? 1; // 朋友圈内容类型
$publicMode = $data['publicMode'] ?? 0; // 发布模式
$altList = $data['altList'] ?? ''; // 替代列表
$link = $data['link'] ?? []; // 链接信息
$jobPublishWechatMomentsItems = $data['jobPublishWechatMomentsItems'] ?? []; // 发布账号和评论信息
// 必填参数验证
if (empty($jobPublishWechatMomentsItems) || !is_array($jobPublishWechatMomentsItems)) {
return json_encode(['msg' => '至少需要选择一个发布账号','code' => 400]);
}
// 根据朋友圈类型验证必填字段
if ($momentContentType == 1 && empty($text)) { // 纯文本
return json_encode(['msg' => '朋友圈内容不能为空','code' => 400]);
} else if ($momentContentType == 2 && (empty($picUrlList) || empty($text))) { // 图片+文字
return json_encode(['msg' => '朋友圈内容和图片不能为空','code' => 400]);
} else if ($momentContentType == 3 && (empty($videoUrl) || empty($text))) { // 视频+文字
return json_encode(['msg' => '朋友圈内容和视频不能为空','code' => 400]);
} else if ($momentContentType == 4 && (empty($link) || empty($text))) { // 链接+文字
return json_encode(['msg' => '朋友圈内容和链接不能为空','code' => 400]);
}
// 构建请求参数
$params = [
'text' => $text,
'picUrlList' => $picUrlList,
'videoUrl' => $videoUrl,
'immediately' => $immediately,
'timingTime' => $timingTime,
'beginTime' => $beginTime,
'endTime' => $endTime,
'isUseLocation' => $isUseLocation,
'poiName' => $poiName,
'poiAddress' => $poiAddress,
'lat' => $lat,
'lng' => $lng,
'momentContentType' => (int)$momentContentType,
'publicMode' => (int)$publicMode,
'altList' => $altList,
'link' => $link,
'jobPublishWechatMomentsItems' => $jobPublishWechatMomentsItems
];
// 设置请求头
$headerData = ['client:system'];
$header = setHeader($headerData, $authorization, 'json');
// 发送请求发布朋友圈
$result = requestCurl($this->baseUrl . 'api/JobPublishWechatMoments/addJob', $params, 'POST', $header, 'json');
// 处理响应
if (empty($result)) {
return json_encode(['msg' => '朋友圈任务创建成功','code' => 200]);
} else {
// 如果返回的是错误信息
return json_encode(['msg' => $result,'code' => 400]);
}
} catch (\Exception $e) {
return json_encode(['msg' => '发布朋友圈失败','code' => 400]);
}
}
/************************ 朋友圈任务管理相关接口 ************************/
/**
* 获取朋友圈任务列表
* @return \think\response\Json
*/
public function getList()
{
// 获取授权token
$authorization = trim($this->request->header('authorization', $this->authorization));
if (empty($authorization)) {
return errorJson('缺少授权信息');
}
try {
// 获取请求参数
$keyword = $this->request->param('keyword', ''); // 关键词搜索
$jobStatus = $this->request->param('jobStatus', ''); // 任务状态筛选
$contentType = $this->request->param('contentType', ''); // 内容类型筛选
$only = $this->request->param('only', 'false'); // 是否只查看自己的
$pageIndex = $this->request->param('pageIndex', 0); // 当前页码
$pageSize = $this->request->param('pageSize', 10); // 每页数量
$from = $this->request->param('from', ''); // 开始日期
$to = $this->request->param('to', ''); // 结束日期
// 构建请求参数
$params = [
'keyword' => $keyword,
'jobStatus' => $jobStatus,
'contentType' => $contentType,
'only' => $only,
'pageIndex' => (int)$pageIndex,
'pageSize' => (int)$pageSize
];
// 添加日期筛选条件(如果有)
if (!empty($from)) {
$params['from'] = $from;
}
if (!empty($to)) {
$params['to'] = $to;
}
// 设置请求头
$headerData = ['client:system'];
$header = setHeader($headerData, $authorization, 'json');
// 发送请求获取朋友圈任务列表
$result = requestCurl($this->baseUrl . 'api/JobPublishWechatMoments/listPagination', $params, 'GET', $header, 'json');
$response = handleApiResponse($result);
return successJson($response);
} catch (\Exception $e) {
return errorJson('获取朋友圈任务列表失败:' . $e->getMessage());
}
}
}

View File

@@ -0,0 +1,75 @@
<?php
namespace app\api\controller;
/**
* 统计控制器
* Class StatsController
* @package app\frontend\controller
*/
class StatsController extends BaseController
{
/**
* API客户端类型
*/
const CLIENT_TYPE = 'system';
/**
* 账号基本信息
* @return \think\response\Json
*/
public function basicData()
{
$authorization = trim($this->request->header('authorization', $this->authorization));
if (empty($authorization)) {
return errorJson('缺少授权信息');
}
$headerData = ['client:' . self::CLIENT_TYPE];
$header = setHeader($headerData, $authorization, 'plain');
try {
$result = requestCurl($this->baseUrl . '/api/DashBoard/ListHomePageStatistics', ['refresh' => 10000], 'GET', $header);
return successJson($result);
} catch (\Exception $e) {
return errorJson('获取基础数据失败:' . $e->getMessage());
}
}
/**
* 好友统计
* @return \think\response\Json
*/
public function FansStatistics(){
/* 参数说明
lidu 数据搜索类型 0 小时 1 天 2月
from to 时间 当lidu为 0时2025-03-12 09:54:42 当lidu为 1时2025-03-12 当lidu为 2时2025-03
*/
$authorization = trim($this->request->header('authorization', $this->authorization));
$lidu = trim($this->request->param('lidu', ''));
$from = trim($this->request->param('from', ''));
$to = trim($this->request->param('to', ''));
if (empty($authorization)) {
return errorJson('缺少授权信息');
}
$params = [
'lidu' => $lidu,
'from' => $from,
'to' => $to,
];
$headerData = ['client:' . self::CLIENT_TYPE];
$header = setHeader($headerData, $authorization, 'plain');
try {
$result = requestCurl($this->baseUrl . 'api/DashBoard/listStatisticsCountDTOByCreateTimeAsync', $params, 'GET', $header);
return successJson($result);
} catch (\Exception $e) {
return errorJson('获取粉丝统计数据失败:' . $e->getMessage());
}
}
}

View File

@@ -0,0 +1,365 @@
<?php
namespace app\api\controller;
use app\api\model\CompanyAccountModel;
use think\facade\Env;
use think\Response;
/**
* 用户控制器
* Class UserController
* @package app\frontend\controller
*/
class UserController extends BaseController
{
/**
* API客户端类型
*/
const CLIENT_TYPE = 'system';
/**
* 构造函数
*/
public function __construct()
{
parent::__construct();
}
/**
* 登录
* @return \think\response\Json
*/
public function login()
{
// 获取并验证参数
$params = $this->validateLoginParams();
if (!is_array($params)) {
return $params;
}
// 验证账号是否存在
$existingAccount = CompanyAccountModel::where('userName', $params['username'])->find();
if (empty($existingAccount)) {
// 记录登录失败日志
recordUserLog(0, $params['username'], 'LOGIN', '账号不存在', $params, 500, '账号不存在');
return errorJson('账号不存在');
}
// 获取验证码会话ID和用户输入的验证码
$verifySessionId = $this->request->param('verifySessionId', '');
$verifyCode = $this->request->param('verifyCode', '');
// 设置请求头
$headerData = ['client:' . self::CLIENT_TYPE];
// 如果存在验证码信息,添加到请求头
if (!empty($verifySessionId) && !empty($verifyCode)) {
$headerData[] = 'verifysessionid:' . $verifySessionId;
$headerData[] = 'verifycode:' . $verifyCode;
}
$header = setHeader($headerData, '', 'plain');
try {
// 请求登录接口
$result = requestCurl($this->baseUrl . 'token', $params, 'POST', $header);
$result_array = handleApiResponse($result);
if (is_array($result_array) && isset($result_array['error'])) {
// 记录登录失败日志
recordUserLog(0, $params['username'], 'LOGIN', '登录失败', $params, 500, $result_array['error_description']);
return errorJson($result_array['error_description']);
}
// 获取客户端IP地址
$ip = $this->request->ip();
// 登录成功,更新密码信息和登录信息
$updateData = [
'passwordMd5' => md5($params['password']),
'passwordLocal' => localEncrypt($params['password']),
'lastLoginIp' => $ip,
'lastLoginTime' => time()
];
// 更新密码信息
CompanyAccountModel::where('userName', $params['username'])->update($updateData);
// 记录登录成功日志
recordUserLog($existingAccount['id'], $params['username'], 'LOGIN', '登录成功', [], 200, '登录成功');
return successJson($result_array);
} catch (\Exception $e) {
// 记录登录异常日志
recordUserLog(0, $params['username'], 'LOGIN', '登录请求失败', $params, 500, $e->getMessage());
return errorJson('登录请求失败:' . $e->getMessage());
}
}
/**
* 获取新的token
* @return \think\response\Json
*/
public function getNewToken()
{
$grant_type = $this->request->param('grant_type', 'refresh_token');
$refresh_token = $this->request->param('refresh_token', '');
$authorization = $this->request->header('authorization', $this->authorization);
if (empty($grant_type) || empty($authorization)) {
return errorJson('参数错误');
}
$params = [
'grant_type' => $grant_type,
'refresh_token' => $refresh_token,
];
$headerData = ['client:' . self::CLIENT_TYPE];
$header = setHeader($headerData, $authorization, 'system');
try {
$result = requestCurl($this->baseUrl . 'token', $params, 'POST', $header);
$result_array = handleApiResponse($result);
if (is_array($result_array) && isset($result_array['error'])) {
recordUserLog(0, '', 'REFRESH_TOKEN', '刷新token失败', $params, 500, $result_array['error_description']);
return errorJson($result_array['error_description']);
}
recordUserLog(0, '', 'REFRESH_TOKEN', '刷新token成功', $params, 200, '刷新成功');
return successJson($result_array);
} catch (\Exception $e) {
recordUserLog(0, '', 'REFRESH_TOKEN', '刷新token异常', $params, 500, $e->getMessage());
return errorJson('获取新token失败' . $e->getMessage());
}
}
/**
* 获取商户基本信息
* @return \think\response\Json
*/
public function getAccountInfo()
{
$authorization = trim($this->request->header('authorization', $this->authorization));
if (empty($authorization)) {
return errorJson('缺少授权信息');
}
$headerData = ['client:' . self::CLIENT_TYPE];
$header = setHeader($headerData, $authorization, 'json');
try {
$result = requestCurl($this->baseUrl . 'api/Account/self', [], 'GET', $header,'json');
$response = handleApiResponse($result);
if (!empty($response['account'])) {
$accountData = $response['account'];
// 准备数据库字段映射,保持驼峰命名
$dbData = [
'tenantId' => $accountData['id'],
'realName' => $accountData['realName'],
'nickname' => $accountData['nickname'],
'memo' => $accountData['memo'],
'avatar' => $accountData['avatar'],
'userName' => $accountData['userName'],
'secret' => $accountData['secret'],
'accountType' => $accountData['accountType'],
'companyId' => $accountData['departmentId'],
'useGoogleSecretKey' => $accountData['useGoogleSecretKey'],
'hasVerifyGoogleSecret' => $accountData['hasVerifyGoogleSecret'],
'updateTime' => time()
];
// 查找是否存在该账户
$existingAccount = CompanyAccountModel::where('userName', $accountData['userName'])->find();
if ($existingAccount) {
// 更新现有记录
CompanyAccountModel::where('userName', $accountData['userName'])->update($dbData);
} else {
// 创建新记录
$dbData['createTime'] = time();
CompanyAccountModel::create($dbData);
}
return successJson($response['account']);
}else{
return successJson($response);
}
} catch (\Exception $e) {
recordUserLog(0, '', 'GET_ACCOUNT_INFO', '获取账户信息异常', [], 500, $e->getMessage());
return errorJson('获取账户信息失败:' . $e->getMessage());
}
}
/**
* 修改密码
* @return \think\response\Json
*/
public function modifyPwd($data = [])
{
if (empty($data)) {
return json_encode(['code' => 400,'msg' => '参数缺失']);
}
if (!isset($data['id']) || !isset($data['pwd'])) {
return json_encode(['code' => 401,'msg' => '参数缺失']);
}
$authorization = $this->authorization;
if (empty($authorization)) {
return json_encode(['code' => 400,'msg' => '缺少授权信息']);
}
$headerData = ['client:system'];
$header = setHeader($headerData, $authorization, 'json');
$params = [
'id' => $data['id'],
'newPw' => $data['pwd'],
];
try {
$result = requestCurl($this->baseUrl . 'api/Account/modifypw', $params, 'PUT', $header,'json');
$response = handleApiResponse($result);
if (empty($response)) {
return json_encode(['code' => 200,'msg' => '修改成功']);
}
return json_encode(['code' => 400,'msg' => $response]);
} catch (\Exception $e) {
return json_encode(['code' => 400,'msg' => '修改密码失败:' . $e->getMessage()]);
}
}
/**
* 登出
* @return \think\response\Json
*/
public function logout()
{
$authorization = trim($this->request->header('authorization', $this->authorization));
if (empty($authorization)) {
return errorJson('缺少授权信息');
}
$headerData = ['client:' . self::CLIENT_TYPE];
$header = setHeader($headerData, $authorization, 'system');
try {
// 调用外部退出登录接口
$result = requestCurl($this->baseUrl . 'api/Account/SignOut', [], 'GET', $header);
return successJson([] , '退出成功');
} catch (\Exception $e) {
recordUserLog(0, '', 'LOGOUT', '退出登录异常', [], 500, $e->getMessage());
return errorJson('退出登录失败:' . $e->getMessage());
}
}
/**
* 获取验证码
* @return \think\response\Json
*/
public function getVerifyCode($isJson = false)
{
$headerData = ['client:' . self::CLIENT_TYPE];
$header = setHeader($headerData, '', 'plain');
try {
$result = requestCurl($this->baseUrl . 'api/Account/getVerifyCode', [], 'GET', $header);
$response = handleApiResponse($result);
// 检查返回的数据格式
if (is_array($response)) {
// 如果verifyCodeImage和verifySessionId都不为null返回它们
if (!empty($response['verifyCodeImage']) && !empty($response['verifySessionId'])) {
$returnData = [
'verifyCodeImage' => $response['verifyCodeImage'],
'verifySessionId' => $response['verifySessionId']
];
return !empty($isJson) ? json_encode(['code' => 200,'data' => $returnData]) : successJson($returnData);
}
}
// 如果不是预期的格式,返回原始数据
return !empty($isJson) ? json_encode(['code' => 200,'msg' => '无需验证码','data' => ['verifyCodeImage' => '', 'verifySessionId' => '']]) : successJson(['verifyCodeImage' => '', 'verifySessionId' => ''],'无需验证码');
} catch (\Exception $e) {
$msg = '获取验证码失败'. $e->getMessage();
return !empty($isJson) ? json_encode(['code' => 400,'msg' => $msg]) : errorJson($msg);
}
}
/**
* 验证登录参数
* @return array|\think\response\Json
*/
private function validateLoginParams()
{
$username = trim($this->request->param('username', ''));
$password = trim($this->request->param('password', ''));
$verifyCode = trim($this->request->param('verifyCode', ''));
$verifySessionId = trim($this->request->param('verifySessionId', ''));
if (empty($username) || empty($password)) {
return errorJson('用户名和密码不能为空');
}
// 验证密码格式
$passwordValidation = validateString($password, 'password',['max_length' => 20]);
if (!$passwordValidation['status']) {
return errorJson($passwordValidation['message']);
}
// 如果提供了验证码,验证格式
if (!empty($verifyCode)) {
if (empty($verifySessionId)) {
return errorJson('验证码会话ID不能为空');
}
// 验证码格式验证假设是4位数字
if (!preg_match('/^\d{4}$/', $verifyCode)) {
return errorJson('验证码格式不正确');
}
}
return [
'grant_type' => 'password',
'username' => $username,
'password' => $password,
];
}
/**
* 验证修改密码参数
* @return array|\think\response\Json
*/
private function validateModifyPwdParams()
{
$cPw = trim($this->request->param('cPw', ''));
$newPw = trim($this->request->param('newPw', ''));
$oldPw = trim($this->request->param('oldPw', ''));
if (empty($cPw) || empty($newPw) || empty($oldPw)) {
return errorJson('密码参数不完整');
}
if ($newPw !== $cPw) {
return errorJson('两次输入的新密码不一致');
}
// 验证新密码格式
$passwordValidation = validateString($newPw, 'password');
if (!$passwordValidation['status']) {
return errorJson($passwordValidation['message']);
}
return [
'cPw' => $cPw,
'newPw' => $newPw,
'oldPw' => $oldPw,
];
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,559 @@
<?php
namespace app\api\controller;
use think\cache\driver\Redis;
use think\Db;
use think\Log;
use WebSocket\Client;
use think\facade\Env;
class WebSocketControllerCopy extends BaseController
{
protected $authorized;
protected $accountId;
protected $client;
/************************************
* 初始化相关功能
************************************/
/**
* 构造函数 - 初始化WebSocket连接
* @param array $userData 用户数据
*/
public function __construct($userData = [])
{
parent::__construct();
if(!empty($userData) && count($userData)){
if (empty($userData['userName']) || empty($userData['password'])) {
return json_encode(['code'=>400,'msg'=>'参数缺失']);
}
$params = [
'grant_type' => 'password',
'username' => $userData['userName'],
'password' => $userData['password']
];
// 调用登录接口获取token
// 设置请求头
$headerData = ['client:kefu-client'];
$header = setHeader($headerData, '', 'plain');
$result = requestCurl('https://s2.siyuguanli.com:9991/token', $params, 'POST',$header);
$result_array = handleApiResponse($result);
if (isset($result_array['access_token']) && !empty($result_array['access_token'])) {
$authorization = $result_array['access_token'];
$this->authorized = $authorization;
$this->accountId = $userData['accountId'];
} else {
return json_encode(['code'=>400,'msg'=>'获取系统授权信息失败']);
}
}else{
$this->authorized = $this->request->header('authorization', '');
$this->accountId = $this->request->param('accountId', '');
}
if (empty($this->authorized) || empty($this->accountId)) {
$data['authorized'] = $this->authorized;
$data['accountId'] = $this->accountId;
return json_encode(['code'=>400,'msg'=>'缺失关键参数']);
}
//证书
$context = stream_context_create();
stream_context_set_option($context, 'ssl', 'verify_peer', false);
stream_context_set_option($context, 'ssl', 'verify_peer_name', false);
//开启WS链接
$result = [
"accessToken" => $this->authorized,
"accountId" => $this->accountId,
"client" => "kefu-client",
"cmdType" => "CmdSignIn",
"seq" => 1,
];
$content = json_encode($result);
$this->client = new Client("wss://s2.siyuguanli.com:9993",
[
'filter' => ['text', 'binary', 'ping', 'pong', 'close','receive', 'send'],
'context' => $context,
'headers' => [
'Sec-WebSocket-Protocol' => 'soap',
'origin' => 'localhost',
],
'timeout' => 86400,
]
);
$this->client->send($content);
}
/************************************
* 朋友圈相关功能
************************************/
/**
* 获取指定账号朋友圈信息
* @param array $data 请求参数
* @return \think\response\Json
*/
public function getMoments($data = [])
{
$count = !empty($data['count']) ? $data['count'] : 10;
$wechatAccountId = !empty($data['wechatAccountId']) ? $data['wechatAccountId'] : '';
$wechatFriendId = !empty($data['id']) ? $data['id'] : '';
//过滤消息
if (empty($wechatAccountId)) {
return json_encode(['code'=>400,'msg'=>'指定账号不能为空']);
}
if (empty($wechatFriendId)) {
return json_encode(['code'=>400,'msg'=>'指定好友不能为空']);
}
$msg = '获取朋友圈信息成功';
$message = [];
try {
$params = [
"cmdType" => "CmdFetchMoment",
"count" => $count,
"createTimeSec" => time(),
"isTimeline" => false,
"prevSnsId" => 0,
"wechatAccountId" => $wechatAccountId,
"wechatFriendId" => $wechatFriendId,
"seq" => time(),
];
$params = json_encode($params);
//Log::write('WS获取朋友圈信息参数' . json_encode($params, 256));
$this->client->send($params);
$message = $this->client->receive();
//Log::write('WS获取朋友圈信息成功结果' . $message);
$message = json_decode($message, 1);
// 存储朋友圈数据到数据库
if (isset($message['result']) && !empty($message['result'])) {
$this->saveMomentsToDatabase($message['result'], $wechatAccountId, $wechatFriendId);
}
//关闭WS链接
$this->client->close();
} catch (\Exception $e) {
$msg = $e->getMessage();
}
return json_encode(['code'=>200,'msg'=>$msg,'data'=>$message]);
}
/**
* 朋友圈点赞
* @return \think\response\Json
*/
public function momentInteract()
{
if ($this->request->isPost()) {
$data = $this->request->param();
if (empty($data)) {
return json_encode(['code'=>400,'msg'=>'参数缺失']);
}
$dataArray = $data;
if (!is_array($dataArray)) {
return json_encode(['code'=>400,'msg'=>'数据格式错误']);
}
//过滤消息
if (empty($dataArray['snsId'])) {
return json_encode(['code'=>400,'msg'=>'snsId不能为空']);
}
if (empty($dataArray['wechatAccountId'])) {
return json_encode(['code'=>400,'msg'=>'微信id不能为空']);
}
$result = [
"cmdType" => "CmdMomentInteract",
"momentInteractType" => 1,
"seq" => time(),
"snsId" => $dataArray['snsId'],
"wechatAccountId" => $dataArray['wechatAccountId'],
"wechatFriendId" => 0,
];
$result = json_encode($result);
$this->client->send($result);
$message = $this->client->receive();
$message = json_decode($message, 1);
//关闭WS链接
$this->client->close();
//Log::write('WS个人消息发送');
return json_encode(['code'=>200,'msg'=>'点赞成功','data'=>$message]);
} else {
return json_encode(['code'=>400,'msg'=>'非法请求']);
}
}
/**
* 朋友圈取消点赞
* @return \think\response\Json
*/
public function momentCancelInteract()
{
if ($this->request->isPost()) {
$data = $this->request->param();
if (empty($data)) {
return json_encode(['code'=>400,'msg'=>'参数缺失']);
}
$dataArray = $data;
if (!is_array($dataArray)) {
return json_encode(['code'=>400,'msg'=>'数据格式错误']);
}
//过滤消息
if (empty($dataArray['snsId'])) {
return json_encode(['code'=>400,'msg'=>'snsId不能为空']);
}
if (empty($dataArray['wechatAccountId'])) {
return json_encode(['code'=>400,'msg'=>'微信id不能为空']);
}
$result = [
"CommentId2" => '',
"CommentTime" => 0,
"cmdType" => "CmdMomentCancelInteract",
"optType" => 1,
"seq" => time(),
"snsId" => $dataArray['snsId'],
"wechatAccountId" => $dataArray['wechatAccountId'],
"wechatFriendId" => 0,
];
$result = json_encode($result);
$this->client->send($result);
$message = $this->client->receive();
$message = json_decode($message, 1);
//关闭WS链接
$this->client->close();
//Log::write('WS个人消息发送');
return json_encode(['code'=>200,'msg'=>'取消点赞成功','data'=>$message]);
} else {
return json_encode(['code'=>400,'msg'=>'非法请求']);
}
}
/**
* 获取指定账号朋友圈图片地址
* @return \think\response\Json
*/
public function getMomentSourceRealUrl()
{
if ($this->request->isPost()) {
$data = $this->request->param();
if (empty($data)) {
return json_encode(['code'=>400,'msg'=>'参数缺失']);
}
$dataArray = $data;
if (!is_array($dataArray)) {
return json_encode(['code'=>400,'msg'=>'数据格式错误']);
}
//获取数据条数
// $count = isset($dataArray['count']) ? $dataArray['count'] : 10;
//过滤消息
if (empty($dataArray['wechatAccountId'])) {
return json_encode(['code'=>400,'msg'=>'指定账号不能为空']);
}
if (empty($dataArray['snsId'])) {
return json_encode(['code'=>400,'msg'=>'指定消息ID不能为空']);
}
if (empty($dataArray['snsUrls'])) {
return json_encode(['code'=>400,'msg'=>'资源信息不能为空']);
}
$msg = '获取朋友圈资源链接成功';
$message = [];
try {
$params = [
"cmdType" => $dataArray['type'],
"snsId" => $dataArray['snsId'],
"urls" => $dataArray['snsUrls'],
"wechatAccountId" => $dataArray['wechatAccountId'],
"seq" => time(),
];
$params = json_encode($params);
$this->client->send($params);
$message = $this->client->receive();
//Log::write('WS获取朋友圈图片/视频链接成功,结果:' . json_encode($message, 256));
//关闭WS链接
$this->client->close();
} catch (\Exception $e) {
$msg = $e->getMessage();
}
return json_encode(['code'=>200,'msg'=>$msg,'data'=>$message]);
} else {
return json_encode(['code'=>400,'msg'=>'非法请求']);
}
}
/**
* 保存朋友圈数据到数据库
* @param array $momentList 朋友圈数据列表
* @param int $wechatAccountId 微信账号ID
* @param string $wechatFriendId 微信好友ID
* @return bool
*/
protected function saveMomentsToDatabase($momentList, $wechatAccountId, $wechatFriendId)
{
if (empty($momentList) || !is_array($momentList)) {
return false;
}
try {
foreach ($momentList as $moment) {
// 提取momentEntity中的数据
$momentEntity = $moment['momentEntity'] ?? [];
// 检查朋友圈数据是否已存在
$momentId = Db::table('s2_wechat_moments')
->where('snsId', $moment['snsId'])
->where('wechatAccountId', $wechatAccountId)
->value('id');
$dataToSave = [
'commentList' => json_encode($moment['commentList'] ?? [], 256),
'createTime' => $moment['createTime'] ?? 0,
'likeList' => json_encode($moment['likeList'] ?? [], 256),
'content' => $momentEntity['content'] ?? '',
'lat' => $momentEntity['lat'] ?? 0,
'lng' => $momentEntity['lng'] ?? 0,
'location' => $momentEntity['location'] ?? '',
'picSize' => $momentEntity['picSize'] ?? 0,
'resUrls' => json_encode($momentEntity['resUrls'] ?? [], 256),
'userName' => $momentEntity['userName'] ?? '',
'snsId' => $moment['snsId'] ?? '',
'type' => $moment['type'] ?? 0,
'title' => $moment['title'] ?? '',
'coverImage' => $moment['coverImage'] ?? '',
'update_time' => time()
];
if ($momentId) {
// 如果已存在,则更新数据
Db::table('s2_wechat_moments')->where('id', $momentId)->update($dataToSave);
} else {
if(empty($wechatFriendId)){
$wechatFriendId = WechatFriend::where('wechatAccountId', $wechatAccountId)->where('wechatId', $momentEntity['userName'])->value('id');
}
// 如果不存在,则插入新数据
$dataToSave['wechatAccountId'] = $wechatAccountId;
$dataToSave['wechatFriendId'] = $wechatFriendId;
$dataToSave['create_time'] = time();
Db::table('s2_wechat_moments')->insert($dataToSave);
}
}
//Log::write('朋友圈数据已存入数据库,共' . count($momentList) . '条');
return true;
} catch (\Exception $e) {
//Log::write('保存朋友圈数据失败:' . $e->getMessage(), 'error');
return false;
}
}
/************************************
* 消息发送相关功能
************************************/
/**
* 个人消息发送
* @return \think\response\Json
*/
public function sendPersonal()
{
if ($this->request->isPost()) {
$data = $this->request->param();
if (empty($data)) {
return json_encode(['code'=>400,'msg'=>'参数缺失']);
}
$dataArray = $data;
if (!is_array($dataArray)) {
return json_encode(['code'=>400,'msg'=>'数据格式错误']);
}
//过滤消息
if (empty($dataArray['content'])) {
return json_encode(['code'=>400,'msg'=>'内容缺失']);
}
if (empty($dataArray['wechatAccountId'])) {
return json_encode(['code'=>400,'msg'=>'微信id不能为空']);
}
if (empty($dataArray['wechatFriendId'])) {
return json_encode(['code'=>400,'msg'=>'接收人不能为空']);
}
if (empty($dataArray['msgType'])) {
return json_encode(['code'=>400,'msg'=>'类型缺失']);
}
//消息拼接 msgType(1:文本 3:图片 43:视频 47:动图表情包 49:小程序)
$result = [
"cmdType" => "CmdSendMessage",
"content" => $dataArray['content'],
"msgSubType" => 0,
"msgType" => $dataArray['msgType'],
"seq" => time(),
"wechatAccountId" => $dataArray['wechatAccountId'],
"wechatChatroomId" => 0,
"wechatFriendId" => $dataArray['wechatFriendId'],
];
$result = json_encode($result);
$this->client->send($result);
$message = $this->client->receive();
$message = json_decode($message, 1);
//关闭WS链接
$this->client->close();
//Log::write('WS个人消息发送');
return json_encode(['code'=>200,'msg'=>'消息成功发送','data'=>$message]);
//return successJson($message, '消息成功发送');
} else {
return json_encode(['code'=>400,'msg'=>'非法请求']);
//return errorJson('非法请求');
}
}
/**
* 发送群消息
* @return \think\response\Json
*/
public function sendCommunity()
{
if ($this->request->isPost()) {
$data = $this->request->post();
if (empty($data)) {
return json_encode(['code'=>400,'msg'=>'参数缺失']);
}
$dataArray = $data;
if (!is_array($dataArray)) {
return json_encode(['code'=>400,'msg'=>'数据格式错误']);
}
//过滤消息
if (empty($dataArray['content'])) {
return json_encode(['code'=>400,'msg'=>'内容缺失']);
}
if (empty($dataArray['wechatAccountId'])) {
return json_encode(['code'=>400,'msg'=>'微信id不能为空']);
}
if (empty($dataArray['msgType'])) {
return json_encode(['code'=>400,'msg'=>'类型缺失']);
}
if (empty($dataArray['wechatChatroomId'])) {
return json_encode(['code'=>400,'msg'=>'群id不能为空']);
}
$msg = '消息成功发送';
$message = [];
try {
//消息拼接 msgType(1:文本 3:图片 43:视频 47:动图表情包 49:小程序)
$result = [
"cmdType" => "CmdSendMessage",
"content" => htmlspecialchars_decode($dataArray['content']),
"msgSubType" => 0,
"msgType" => $dataArray['msgType'],
"seq" => time(),
"wechatAccountId" => $dataArray['wechatAccountId'],
"wechatChatroomId" => $dataArray['wechatChatroomId'],
"wechatFriendId" => 0,
];
$result = json_encode($result);
$this->client->send($result);
$message = $this->client->receive();
//关闭WS链接
$this->client->close();
//Log::write('WS群消息发送');
//Log::write($message);
$message = json_decode($message, 1);
} catch (\Exception $e) {
$msg = $e->getMessage();
}
return json_encode(['code'=>200,'msg'=>$msg,'data'=>$message]);
} else {
return json_encode(['code'=>400,'msg'=>'非法请求']);
//return errorJson('非法请求');
}
}
/**
* 发送群消息(内部调用版)
* @param array $data 消息数据
* @return \think\response\Json
*/
public function sendCommunitys($data = [])
{
if (empty($data)) {
return json_encode(['code'=>400,'msg'=>'参数缺失']);
}
$dataArray = $data;
if (!is_array($dataArray)) {
return json_encode(['code'=>400,'msg'=>'数据格式错误']);
}
//过滤消息
if (empty($dataArray['content'])) {
return json_encode(['code'=>400,'msg'=>'内容缺失']);
}
if (empty($dataArray['wechatAccountId'])) {
return json_encode(['code'=>400,'msg'=>'微信id不能为空']);
}
if (empty($dataArray['msgType'])) {
return json_encode(['code'=>400,'msg'=>'类型缺失']);
}
if (empty($dataArray['wechatChatroomId'])) {
return json_encode(['code'=>400,'msg'=>'群id不能为空']);
}
$msg = '消息成功发送';
$message = [];
try {
//消息拼接 msgType(1:文本 3:图片 43:视频 47:动图表情包 49:小程序)
$result = [
"cmdType" => "CmdSendMessage",
"content" => $dataArray['content'],
"msgSubType" => 0,
"msgType" => $dataArray['msgType'],
"seq" => time(),
"wechatAccountId" => $dataArray['wechatAccountId'],
"wechatChatroomId" => $dataArray['wechatChatroomId'],
"wechatFriendId" => 0,
];
$result = json_encode($result);
$this->client->send($result);
$message = $this->client->receive();
//关闭WS链接
$this->client->close();
//Log::write('WS群消息发送');
//Log::write($message);
$message = json_decode($message, 1);
} catch (\Exception $e) {
$msg = $e->getMessage();
}
return json_encode(['code'=>200,'msg'=>$msg,'data'=>$message]);
}
}

View File

@@ -0,0 +1,255 @@
<?php
namespace app\api\controller;
use app\api\model\WechatChatroomModel;
use app\api\model\WechatChatroomMemberModel;
use app\job\WechatChatroomJob;
use think\facade\Request;
class WechatChatroomController extends BaseController
{
/**
* 获取微信群聊列表
* @return \think\response\Json
*/
public function getlist($data = [],$isInner = false, $isDel = '')
{
// 获取授权token
$authorization = $this->authorization;
if (empty($authorization)) {
return json_encode(['code'=>500,'msg'=>'缺少授权信息']);
}
try {
// 根据isDel设置对应的isDeleted值
$isDeleted = '';
if ($isDel === '0' || $isDel === 0) {
$isDeleted = false;
} elseif ($isDel === '1' || $isDel === 1) {
$isDeleted = true;
}
// 构建请求参数
$params = [
'keyword' => $data['keyword'] ?? '',
'wechatAccountKeyword' => $data['wechatAccountKeyword'] ?? '',
'isDeleted' => $data['isDeleted'] ?? $isDeleted ,
'allotAccountId' => $data['allotAccountId'] ?? '',
'groupId' => $data['groupId'] ?? '',
'wechatChatroomId' => $data['wechatChatroomId'] ?? '',
'memberKeyword' => $data['memberKeyword'] ?? '',
'pageIndex' => $data['pageIndex'] ?? 0,
'pageSize' => $data['pageSize'] ?? 20
];
// 设置请求头
$headerData = ['client:system'];
$header = setHeader($headerData, $authorization, 'json');
// 发送请求获取群聊列表
$result = requestCurl($this->baseUrl . 'api/WechatChatroom/pagelist', $params, 'GET', $header,'json');
$response = handleApiResponse($result);
// 保存数据到数据库
if (!empty($response['results'])) {
$isUpdate = false;
foreach ($response['results'] as $item) {
$updated = $this->saveChatroom($item);
if($updated && $isDel == 0){
$isUpdate = true;
}
}
}
if($isInner){
return json_encode(['code'=>200,'msg'=>'success','data'=>$response,'isUpdate'=>$isUpdate]);
}else{
return successJson($response);
}
} catch (\Exception $e) {
if($isInner){
return json_encode(['code'=>200,'msg'=>'获取微信群聊列表失败' . $e->getMessage()]);
}else{
return errorJson('获取微信群聊列表失败:' . $e->getMessage());
}
}
}
/**
* 保存群聊数据到数据库
* @param array $item 群聊数据
*/
private function saveChatroom($item)
{
$data = [
'id' => $item['id'],
'wechatAccountId' => $item['wechatAccountId'],
'wechatAccountAlias' => $item['wechatAccountAlias'],
'wechatAccountWechatId' => $item['wechatAccountWechatId'],
'wechatAccountAvatar' => $item['wechatAccountAvatar'],
'wechatAccountNickname' => $item['wechatAccountNickname'],
'chatroomId' => $item['chatroomId'],
'hasMe' => $item['hasMe'],
'chatroomOwnerNickname' => isset($item['chatroomOwnerNickname']) ? $item['chatroomOwnerNickname'] : '',
'chatroomOwnerAvatar' => isset($item['chatroomOwnerAvatar']) ? $item['chatroomOwnerAvatar'] : '',
'conRemark' => isset($item['conRemark']) ? $item['conRemark'] : '',
'nickname' => isset($item['nickname']) ? $item['nickname'] : '',
'pyInitial' => isset($item['pyInitial']) ? $item['pyInitial'] : '',
'quanPin' => isset($item['quanPin']) ? $item['quanPin'] : '',
'chatroomAvatar' => isset($item['chatroomAvatar']) ? $item['chatroomAvatar'] : '',
'members' => is_array($item['members']) ? json_encode($item['members']) : json_encode([]),
'isDeleted' => isset($item['isDeleted']) ? $item['isDeleted'] : 0,
'deleteTime' => !empty($item['isDeleted']) ? strtotime($item['deleteTime']) : 0,
'createTime' => isset($item['createTime']) ? strtotime($item['createTime']) : 0,
'accountId' => isset($item['accountId']) ? $item['accountId'] : 0,
'accountUserName' => isset($item['accountUserName']) ? $item['accountUserName'] : '',
'accountRealName' => isset($item['accountRealName']) ? $item['accountRealName'] : '',
'accountNickname' => isset($item['accountNickname']) ? $item['accountNickname'] : '',
'groupId' => isset($item['groupId']) ? $item['groupId'] : 0,
'updateTime' => time()
];
// 使用chatroomId和wechatAccountId的组合作为唯一性判断
$chatroom = WechatChatroomModel::where('id',$item['id'])->find();
if ($chatroom) {
$chatroom->save($data);
return true;
} else {
WechatChatroomModel::create($data);
return false;
}
// // 同时保存群成员数据
// if (!empty($item['members'])) {
// foreach ($item['members'] as $member) {
// $this->saveChatroomMember($member, $item['chatroomId']);
// }
// }
}
/**
* 获取群成员列表
* @param string $wechatChatroomId 微信群ID
* @return \think\response\Json
*/
public function listChatroomMember($wechatChatroomId = '',$chatroomId = '',$isInner = false)
{
// 获取授权token
$authorization = trim($this->request->header('authorization', $this->authorization));
$wechatChatroomId = !empty($wechatChatroomId) ? $wechatChatroomId : $this->request->param('id', '');
$chatroomId = !empty($chatroomId) ? $chatroomId : $this->request->param('chatroomId', '');
if (empty($authorization)) {
if($isInner){
return json_encode(['code'=>500,'msg'=>'缺少授权信息']);
}else{
return errorJson('缺少授权信息');
}
}
if (empty($wechatChatroomId)) {
if($isInner){
return json_encode(['code'=>500,'msg'=>'群ID不能为空']);
}else{
return errorJson('群ID不能为空');
}
}
try {
// 构建请求参数
$params = [
'wechatChatroomId' => $wechatChatroomId
];
// 设置请求头
$headerData = ['client:system'];
$header = setHeader($headerData, $authorization, 'plain');
// 发送请求获取群成员列表
$result = requestCurl($this->baseUrl . 'api/WechatChatroom/listChatroomMember', $params, 'GET', $header);
$response = handleApiResponse($result);
// 保存数据到数据库
if (!empty($response)) {
foreach ($response as $item) {
$this->saveChatroomMember($item, $chatroomId);
}
}
if($isInner){
return json_encode(['code'=>200,'msg'=>'success','data'=>$response]);
}else{
return successJson($response);
}
} catch (\Exception $e) {
if($isInner){
return json_encode(['code'=>500,'msg'=>'获取群成员列表失败:' . $e->getMessage()]);
}else{
return errorJson('获取群成员列表失败:' . $e->getMessage());
}
}
}
/**
* 保存群成员数据到数据库
* @param array $item 群成员数据
* @param string $wechatChatroomId 微信群ID
*/
private function saveChatroomMember($item, $wechatChatroomId)
{
$data = [
'chatroomId' => $wechatChatroomId,
'wechatId' => isset($item['wechatId']) ? $item['wechatId'] : '',
'nickname' => isset($item['nickname']) ? $item['nickname'] : '',
'avatar' => isset($item['avatar']) ? $item['avatar'] : '',
'conRemark' => isset($item['conRemark']) ? $item['conRemark'] : '',
'alias' => isset($item['alias']) ? $item['alias'] : '',
'friendType' => isset($item['friendType']) ? $item['friendType'] : false,
'updateTime' => time()
];
// 使用chatroomId和wechatId的组合作为唯一性判断
$member = WechatChatroomMemberModel::where([
['chatroomId', '=', $wechatChatroomId],
['wechatId', '=', $item['wechatId']]
])->find();
if ($member) {
$member->savea($data);
} else {
$data['createTime'] = time();
WechatChatroomMemberModel::create($data);
}
}
/**
* 同步微信群聊数据
* 此方法用于手动触发微信群聊数据同步任务
* @return \think\response\Json
*/
public function syncChatrooms()
{
try {
// 获取请求参数
$pageIndex = $this->request->param('pageIndex', 0);
$pageSize = $this->request->param('pageSize', 100);
$keyword = $this->request->param('keyword', '');
$wechatAccountKeyword = $this->request->param('wechatAccountKeyword', '');
$isDeleted = $this->request->param('isDeleted', '');
// 添加同步任务到队列
$result = WechatChatroomJob::addSyncTask($pageIndex, $pageSize, $keyword, $wechatAccountKeyword, $isDeleted);
if ($result) {
return successJson([], '微信群聊同步任务已添加到队列');
} else {
return errorJson('添加同步任务失败');
}
} catch (\Exception $e) {
return errorJson('添加同步任务异常:' . $e->getMessage());
}
}
}

View File

@@ -0,0 +1,295 @@
<?php
namespace app\api\controller;
use app\api\model\WechatAccountModel;
use think\Db;
/**
* 微信账号管理控制器
*/
class WechatController extends BaseController
{
/**
* 获取微信账号列表(主方法)
*
* @param string $pageIndex 页码
* @param string $pageSize 每页大小
* @param bool $isInner 是否为任务调用
* @return \think\response\Json
*/
public function getList($pageIndex = '', $pageSize = '', $isInner = false)
{
// 获取授权token
$authorization = trim($this->request->header('authorization', $this->authorization));
if (empty($authorization)) {
if ($isInner) {
return json_encode(['code' => 500, 'msg' => '缺少授权信息']);
} else {
return errorJson('缺少授权信息');
}
}
try {
// 构建请求参数
$params = [
'wechatAlive' => $this->request->param('wechatAlive', ''),
'keyword' => $this->request->param('keyword', ''),
'groupId' => $this->request->param('groupId', ''),
'departmentId' => $this->request->param('departmentId', ''),
'hasDevice' => $this->request->param('hasDevice', ''),
'deviceGroupId' => $this->request->param('deviceGroupId', ''),
'containSubDepartment' => $this->request->param('containSubDepartment', 'false'),
'pageIndex' => !empty($pageIndex) ? $pageIndex : $this->request->param('pageIndex', 0),
'pageSize' => !empty($pageSize) ? $pageSize : $this->request->param('pageSize', 10)
];
// 设置请求头
$headerData = ['client:system'];
$header = setHeader($headerData, $authorization, 'plain');
// 发送请求获取基本信息
$result = requestCurl($this->baseUrl . 'api/WechatAccount/list', $params, 'GET', $header);
$response = handleApiResponse($result);
// 保存基本数据到数据库
if (!empty($response['results'])) {
foreach ($response['results'] as $item) {
$this->saveWechatAccount($item);
}
// 获取并更新微信账号状态信息
$this->getListTenantWechatPartial($authorization);
}
if ($isInner) {
return json_encode(['code' => 200, 'msg' => '获取微信账号列表成功', 'data' => $response]);
} else {
return successJson($response);
}
} catch (\Exception $e) {
if ($isInner) {
return json_encode(['code' => 500, 'msg' => '获取微信账号列表失败:' . $e->getMessage()]);
} else {
return errorJson('获取微信账号列表失败:' . $e->getMessage());
}
}
}
/**
* 获取微信账号状态信息
*
* @param string $authorization 授权token
* @param int $pageIndex 页码默认为1
* @param int $pageSize 每页数量默认为40
* @return \think\response\Json|void
*/
public function getListTenantWechatPartial($authorization = '', $pageIndex = 1, $pageSize = 40)
{
// 获取授权token如果未传入
if (empty($authorization)) {
$authorization = trim($this->request->header('authorization', $this->authorization));
if (empty($authorization)) {
return errorJson('缺少授权信息');
}
}
try {
// 从数据库获取微信账号和设备信息
$wechatList = Db::table('s2_wechat_account')
->where('imei', 'not null')
->page($pageIndex, $pageSize)
->select();
if (empty($wechatList)) {
return;
}
// 构造请求参数
$wechatAccountIds = [];
$deviceIds = [];
$accountIds = [];
foreach ($wechatList as $item) {
$wechatAccountIds[] = $item['id'];
$deviceIds[] = $item['currentDeviceId'] ?: 0;
$accountIds[] = $item['deviceAccountId'] ?: 0;
}
// 设置请求头
$headerData = ['client:system'];
$header = setHeader($headerData, $authorization, 'json');
$params = [
'wechatAccountIdsStr' => json_encode($wechatAccountIds),
'deviceIdsStr' => json_encode($deviceIds),
'accountIdsStr' => json_encode($accountIds),
'groupId' => ''
];
// 发送请求获取状态信息
$result = requestCurl($this->baseUrl . 'api/WechatAccount/listTenantWechatPartial', $params, 'GET', $header,'json');
$response = handleApiResponse($result);
// 如果请求成功并返回数据,则更新数据库
if (!empty($response)) {
$this->batchUpdateWechatAccounts($response);
}
// 递归调用获取下一页数据
$this->getListTenantWechatPartial($authorization, $pageIndex + 1, $pageSize);
} catch (\Exception $e) {
if (empty($authorization)) { // 只有作为独立API调用时才返回
return json(['code' => 500, 'msg' => '获取失败:' . $e->getMessage()]);
}
}
}
/**
* 批量更新微信账号数据
*
* @param array $data 接口返回的数据
*/
private function batchUpdateWechatAccounts($data)
{
// 更新微信账号信息
if (!empty($data['totalFriend'])) {
// 遍历所有微信账号ID
$wechatIds = array_keys($data['totalFriend']);
foreach ($wechatIds as $wechatId) {
// 构建更新数据
$updateData = [
'maleFriend' => $data['maleFriend'][$wechatId] ?? 0,
'femaleFriend' => $data['femaleFriend'][$wechatId] ?? 0,
'unknowFriend' => $data['unknowFriend'][$wechatId] ?? 0,
'totalFriend' => $data['totalFriend'][$wechatId] ?? 0,
'yesterdayMsgCount' => $data['yesterdayMsgCount'][$wechatId] ?? 0,
'sevenDayMsgCount' => $data['sevenDayMsgCount'][$wechatId] ?? 0,
'thirtyDayMsgCount' => $data['thirtyDayMsgCount'][$wechatId] ?? 0,
'wechatAlive' => isset($data['wechatAlive'][$wechatId]) ? (int)$data['wechatAlive'][$wechatId] : 0,
'updateTime' => time()
];
if (!empty($updateData['wechatAlive'])) {
$updateData['wechatAliveTime'] = time();
}
// 更新数据库
Db::table('s2_wechat_account')
->where('id', $wechatId)
->update($updateData);
}
}
// 更新设备状态
if (!empty($data['deviceAlive'])) {
foreach ($data['deviceAlive'] as $deviceId => $isAlive) {
// 更新微信账号的设备状态
Db::table('s2_wechat_account')
->where('currentDeviceId', $deviceId)
->update([
'deviceAlive' => (int)$isAlive,
'updateTime' => time()
]);
// 更新设备表的状态
Db::table('s2_device')
->where('id', $deviceId)
->update([
'alive' => (int)$isAlive,
'updateTime' => time()
]);
}
}
}
/**
* 保存微信账号基本数据到数据库
*
* @param array $item 微信账号数据
*/
private function saveWechatAccount($item)
{
// 处理时间字段
$createTime = isset($item['createTime']) ? strtotime($item['createTime']) : 0;
$deleteTime = !empty($item['isDeleted']) ? strtotime($item['deleteTime']) : 0;
// 构建数据
$data = [
'id' => $item['id'],
'wechatId' => $item['wechatId'] ?? '',
'deviceAccountId' => $item['deviceAccountId'] ?? 0,
'imei' => $item['imei'] ?? '',
'deviceMemo' => $item['deviceMemo'] ?? '',
'accountUserName' => $item['accountUserName'] ?? '',
'accountRealName' => $item['accountRealName'] ?? '',
'accountNickname' => $item['accountNickname'] ?? '',
'wechatGroupName' => $item['wechatGroupName'] ?? '',
'alias' => $item['alias'] ?? '',
'tenantId' => $item['tenantId'] ?? 0,
'nickname' => $item['nickname'] ?? '',
'avatar' => $item['avatar'] ?? '',
'gender' => $item['gender'] ?? 0,
'region' => $item['region'] ?? '',
'signature' => $item['signature'] ?? '',
'bindQQ' => $item['bindQQ'] ?? '',
'bindEmail' => $item['bindEmail'] ?? '',
'bindMobile' => $item['bindMobile'] ?? '',
'currentDeviceId' => $item['currentDeviceId'] ?? 0,
'isDeleted' => $item['isDeleted'] ?? 0,
'groupId' => $item['groupId'] ?? 0,
'memo' => $item['memo'] ?? '',
'wechatVersion' => $item['wechatVersion'] ?? '',
'labels' => !empty($item['labels']) ? json_encode($item['labels']) : json_encode([]),
'createTime' => $createTime,
'deleteTime' => $deleteTime,
'updateTime' => time()
];
// 保存或更新数据
$account = WechatAccountModel::where('id', $item['id'])->find();
if ($account) {
$account->save($data);
} else {
WechatAccountModel::create($data);
}
}
public function chatroomCreate($data = [])
{
$authorization = $this->authorization;
if (empty($authorization)) {
return json_encode(['code' => 500, 'msg' => '缺少授权信息']);
}
try {
// 设置请求头
$headerData = ['Client:system'];
$header = setHeader($headerData, $authorization,'json');
$params = [
"chatroomOperateType" => 7,
"extra" => "{chatroomName:{$data['chatroomName']}}",
"wechatAccountId" => $data['wechatAccountId'],
"wechatChatroomId" => 0,
"wechatFriendIds" => $data['wechatFriendIds']
];
// 发送请求获取状态信息
$result = requestCurl($this->baseUrl . 'api/WechatChatroom/chatroomOperate', $params, 'POST', $header,'json');
$response = handleApiResponse($result);
if (!empty($response)) {
return json_encode(['code' => 500, 'msg' =>$response]);
}else{
return json_encode(['code' => 200, 'msg' =>'成功']);
}
} catch (\Exception $e) {
if (empty($authorization)) { // 只有作为独立API调用时才返回
return json_encode(['code' => 500, 'msg' => '获取失败:' . $e->getMessage()]);
}
}
}
}

View File

@@ -0,0 +1,165 @@
<?php
namespace app\api\controller;
use app\api\model\WechatFriendModel;
use think\facade\Request;
use think\facade\Log;
class WechatFriendController extends BaseController
{
/**
* 获取微信好友列表数据
* @param string $pageIndex 页码
* @param string $pageSize 每页大小
* @param string $preFriendId 上一个好友ID
* @param bool $isInner 是否为任务调用
* @return \think\response\Json
*/
public function getlist($data = [], $isInner = false,$isDel = '')
{
// 获取授权token
$authorization = trim($this->request->header('authorization', $this->authorization));
if (empty($authorization)) {
if ($isInner) {
return json_encode(['code' => 500, 'msg' => '缺少授权信息']);
} else {
return errorJson('缺少授权信息');
}
}
$pageIndex = !empty($data['pageIndex']) ? $data['pageIndex'] : '';
$pageSize = !empty($data['pageSize']) ? $data['pageSize'] : '';
$preFriendId = !empty($data['preFriendId']) ? $data['preFriendId'] : '';
$friendKeyword = !empty($data['friendKeyword']) ? $data['friendKeyword'] : '';
$wechatAccountKeyword = !empty($data['wechatAccountKeyword']) ? $data['wechatAccountKeyword'] : '';
try {
// 初始化isUpdate标志为false
$isUpdate = false;
// 根据isDel设置对应的isDeleted值
$isDeleted = null; // 默认值
if ($isDel == '0' || $isDel == 0) {
$isDeleted = false;
} elseif ($isDel == '1' || $isDel == 1) {
$isDeleted = true;
}
// 构建请求参数
$params = [
'accountKeyword' => '',
'addFrom' => '[]',
'allotAccountId' => input('allotAccountId', ''),
'containSubDepartment' => false,
'departmentId' => '',
'extendFields' => '{}',
'gender' => '',
'groupId' => null,
'isDeleted' => $isDeleted,
'isPass' => null,
'keyword' => input('keyword', ''),
'labels' => '[]',
'pageIndex' => !empty($pageIndex) ? $pageIndex : input('pageIndex', 0),
'pageSize' => !empty($pageSize) ? $pageSize : input('pageSize', 20),
'preFriendId' => !empty($preFriendId) ? $preFriendId : input('preFriendId', ''),
'friendKeyword' => !empty($friendKeyword) ? $friendKeyword : input('friendKeyword', ''),
'wechatAccountKeyword' => !empty($wechatAccountKeyword) ? $wechatAccountKeyword : input('wechatAccountKeyword', '')
];
// 设置请求头
$headerData = ['client:system'];
$header = setHeader($headerData, $authorization);
// 发送请求获取好友列表
$result = requestCurl($this->baseUrl . 'api/WechatFriend/friendlistData', $params, 'POST', $header, 'json');
$response = handleApiResponse($result);
// 保存数据到数据库
if (is_array($response)) {
$isUpdate = false;
foreach ($response as $item) {
$updated = $this->saveFriend($item);
if($updated && $isDel == 0){
$isUpdate = true;
}
}
}
if ($isInner) {
return json_encode(['code' => 200, 'msg' => 'success', 'data' => $response, 'isUpdate' => $isUpdate]);
} else {
return successJson($response);
}
} catch (\Exception $e) {
if ($isInner) {
return json_encode(['code' => 500, 'msg' => '获取微信好友列表失败:' . $e->getMessage()]);
} else {
return errorJson('获取微信好友列表失败:' . $e->getMessage());
}
}
}
/**
* 保存微信好友数据到数据库
* @param array $item 微信好友数据
* @return bool 是否创建或更新了记录
*/
private function saveFriend($item)
{
$data = [
'id' => $item['id'],
'wechatAccountId' => $item['wechatAccountId'],
'alias' => $item['alias'],
'wechatId' => $item['wechatId'],
'conRemark' => $item['conRemark'],
'nickname' => $item['nickname'],
'pyInitial' => $item['pyInitial'],
'quanPin' => $item['quanPin'],
'avatar' => $item['avatar'],
'gender' => $item['gender'],
'region' => $item['region'],
'addFrom' => $item['addFrom'],
'labels' => is_array($item['labels']) ? json_encode($item['labels']) : json_encode([]),
'siteLabels' => json_encode([]),
'signature' => $item['signature'],
'isDeleted' => $item['isDeleted'],
'isPassed' => $item['isPassed'],
'deleteTime' => !empty($item['isDeleted']) ? strtotime($item['deleteTime']) : 0,
'accountId' => $item['accountId'],
'extendFields' => is_array($item['extendFields']) ? json_encode($item['extendFields']) : json_encode([]),
'accountUserName' => $item['accountUserName'],
'accountRealName' => $item['accountRealName'],
'accountNickname' => $item['accountNickname'],
'ownerAlias' => $item['ownerAlias'],
'ownerWechatId' => $item['ownerWechatId'],
'ownerNickname' => $item['ownerNickname'],
'ownerAvatar' => $item['ownerAvatar'],
'phone' => $item['phone'],
'thirdParty' => is_array($item['thirdParty']) ? json_encode($item['thirdParty']) : json_encode([]),
'groupId' => $item['groupId'],
'passTime' => !empty($item['isPassed']) && $item['passTime'] != '0001-01-01T00:00:00' ? strtotime($item['passTime']) : 0,
'additionalPicture' => $item['additionalPicture'],
'desc' => $item['desc'],
'country' => $item['country'],
'privince' => isset($item['privince']) ? $item['privince'] : '',
'city' => isset($item['city']) ? $item['city'] : '',
'createTime' => isset($item['createTime']) ? strtotime($item['createTime']) : 0,
'updateTime' => time()
];
// 使用ID作为唯一性判断
$friend = WechatFriendModel::where('id', $item['id'])->find();
if ($friend) {
unset($data['siteLabels']);
$friend->save($data);
return true;
} else {
WechatFriendModel::create($data);
return false;
}
}
}