-
{user?.username || "用户"}
+
{userInfo?.username || "用户"}
账号:
- {user?.account || Math.floor(10000000 + Math.random() * 90000000).toString()}
+ {userInfo?.account || Math.floor(10000000 + Math.random() * 90000000).toString()}
diff --git a/Cunkebao/app/workspace/group-sync/new/page.tsx b/Cunkebao/app/workspace/group-sync/new/page.tsx
index 862e0858..fd644590 100644
--- a/Cunkebao/app/workspace/group-sync/new/page.tsx
+++ b/Cunkebao/app/workspace/group-sync/new/page.tsx
@@ -9,6 +9,7 @@ import { BasicSettings } from "../components/basic-settings"
import { GroupSelector } from "../components/group-selector"
import { ContentSelector } from "../components/content-selector"
import type { WechatGroup, ContentLibrary } from "@/types/group-sync"
+import { toast } from "@/components/ui/use-toast"
const steps = [
{ id: 1, title: "步骤 1", subtitle: "基础设置" },
@@ -46,11 +47,39 @@ export default function NewGroupSyncPage() {
setFormData((prev) => ({ ...prev, contentLibraries }))
}
- const handleSave = () => {
- // 这里可以添加保存逻辑,例如API调用
- console.log("保存表单数据:", formData)
- router.push("/workspace/group-sync")
- }
+ const handleSubmit = async (formData: any) => {
+ try {
+ const response = await fetch(`${process.env.NEXT_PUBLIC_API_BASE_URL}/v1/api/group-sync`, {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ 'Authorization': `Bearer ${localStorage.getItem('token')}`
+ },
+ body: JSON.stringify(formData)
+ });
+
+ const data = await response.json();
+ if (data.code === 200) {
+ toast({
+ title: "创建成功",
+ description: "群同步计划已创建",
+ });
+ router.push('/workspace/group-sync');
+ } else {
+ toast({
+ title: "创建失败",
+ description: data.msg || "请稍后重试",
+ variant: "destructive",
+ });
+ }
+ } catch (error) {
+ toast({
+ title: "创建失败",
+ description: "网络错误,请稍后重试",
+ variant: "destructive",
+ });
+ }
+ };
const handleCancel = () => {
router.push("/workspace/group-sync")
@@ -81,7 +110,7 @@ export default function NewGroupSyncPage() {
isEnabled: formData.isEnabled,
}}
onNext={handleBasicSettingsNext}
- onSave={handleSave}
+ onSave={handleSubmit}
onCancel={handleCancel}
/>
)}
@@ -92,7 +121,7 @@ export default function NewGroupSyncPage() {
onGroupsChange={handleGroupsChange}
onPrevious={() => setCurrentStep(1)}
onNext={() => setCurrentStep(3)}
- onSave={handleSave}
+ onSave={handleSubmit}
onCancel={handleCancel}
/>
)}
@@ -103,7 +132,7 @@ export default function NewGroupSyncPage() {
onLibrariesChange={handleLibrariesChange}
onPrevious={() => setCurrentStep(2)}
onNext={() => setCurrentStep(4)}
- onSave={handleSave}
+ onSave={handleSubmit}
onCancel={handleCancel}
/>
)}
@@ -118,7 +147,7 @@ export default function NewGroupSyncPage() {
-
diff --git a/Server/application/common/config/route.php b/Server/application/common/config/route.php
index c7f823d8..8b133a1a 100644
--- a/Server/application/common/config/route.php
+++ b/Server/application/common/config/route.php
@@ -6,17 +6,17 @@ use think\facade\Route;
// 定义RESTful风格的API路由 - 认证相关
Route::group('v1/auth', function () {
// 无需认证的接口
- Route::post('login', 'app\\common\\controller\\Auth@login'); // 账号密码登录
- Route::post('mobile-login', 'app\\common\\controller\\Auth@mobileLogin'); // 手机号验证码登录
- Route::post('code', 'app\\common\\controller\\Auth@sendCode'); // 发送验证码
+ Route::post('login', 'app\common\controller\PasswordLoginController@index'); // 账号密码登录
+ Route::post('mobile-login', 'app\common\controller\Auth@mobileLogin'); // 手机号验证码登录
+ Route::post('code', 'app\common\controller\Auth@SendCodeController'); // 发送验证码
// 需要JWT认证的接口
- Route::get('info', 'app\\common\\controller\\Auth@info')->middleware(['jwt']); // 获取用户信息
- Route::post('refresh', 'app\\common\\controller\\Auth@refresh')->middleware(['jwt']); // 刷新令牌
+ Route::get('info', 'app\common\controller\Auth@info')->middleware(['jwt']); // 获取用户信息
+ Route::post('refresh', 'app\common\controller\Auth@refresh')->middleware(['jwt']); // 刷新令牌
});
// 附件上传相关路由
Route::group('v1/', function () {
- Route::post('attachment/upload', 'app\\common\\controller\\Attachment@upload'); // 上传附件
- Route::get('attachment/:id', 'app\\common\\controller\\Attachment@info'); // 获取附件信息
+ Route::post('attachment/upload', 'app\common\controller\Attachment@upload'); // 上传附件
+ Route::get('attachment/:id', 'app\common\controller\Attachment@info'); // 获取附件信息
})->middleware(['jwt']);
\ No newline at end of file
diff --git a/Server/application/common/controller/BaseController.php b/Server/application/common/controller/BaseController.php
new file mode 100644
index 00000000..81dcf83c
--- /dev/null
+++ b/Server/application/common/controller/BaseController.php
@@ -0,0 +1,12 @@
+where('phone', $account)->whereOr('account', $account);
+ }
+ )
+ ->where(
+ function ($query) use ($typeId) {
+ $query->where('status', 1)->where('typeId', $typeId);
+ }
+ )->find();
+
+ return $user;
+ }
+
+ /**
+ * 获取用户信息
+ *
+ * @param string $account 账号(手机号)
+ * @param string $password 密码(可能是加密后的)
+ * @param int $typeId 身份信息
+ * @return array|null
+ */
+ protected function getUser(string $account, string $password, int $typeId): array
+ {
+ $user = $this->getUserProfileWithAccountAndType($account, $typeId);
+
+ if (!$user) {
+ throw new \Exception('用户不存在或已禁用', 403);
+ }
+
+ if ($user->passwordMd5 !== md5($password)) {
+ throw new \Exception('账号或密码错误', 403);
+ }
+
+ return array_merge($user->toArray(), [
+ 'lastLoginIp' => $this->request->ip(),
+ 'lastLoginTime' => time()
+ ]);
+ }
+
+ /**
+ * 数据验证
+ *
+ * @param array $params
+ * @return $this
+ * @throws \Exception
+ */
+ protected function dataValidate(array $params): self
+ {
+ $validate = Validate::make([
+ 'account' => 'require',
+ 'password' => 'require|length:6,64',
+ 'typeId' => 'require|in:1,2',
+ ], [
+ 'account.require' => '账号不能为空',
+ 'password.require' => '密码不能为空',
+ 'password.length' => '密码长度必须在6-64个字符之间',
+ 'typeId.require' => '用户类型不能为空',
+ 'typeId.in' => '用户类型错误',
+ ]);
+
+ if (!$validate->check($params)) {
+ throw new \Exception($validate->getError(), 400);
+ }
+
+ return $this;
+ }
+
+ /**
+ * 用户登录
+ *
+ * @param string $account 账号(手机号)
+ * @param string $password 密码(可能是加密后的)
+ * @param string $typeId 登录IP
+ * @return array
+ * @throws \Exception
+ */
+ protected function doLogin(string $account, string $password, int $typeId): array
+ {
+ // 获取用户信息
+ $member = $this->getUser($account, $password, $typeId);
+
+ // 生成JWT令牌
+ $token = JwtUtil::createToken($member, 86400);
+ $token_expired = time() + 86400;
+
+ return compact('member', 'token', 'token_expired');
+ }
+
+ /**
+ * 用户登录
+ *
+ * @return \think\response\Json
+ */
+ public function index()
+ {
+ $params = $this->request->only(['account', 'password', 'typeId']);
+
+ try {
+ $result = $this->dataValidate($params)->doLogin(
+ $params['account'],
+ $params['password'],
+ $params['typeId']
+ );
+
+ return ResponseHelper::success($result, '登录成功');
+ } catch (Exception $e) {
+ return ResponseHelper::error($e->getMessage(), $e->getCode());
+ }
+ }
+}
\ No newline at end of file
diff --git a/Server/application/common/controller/SendCodeController.php b/Server/application/common/controller/SendCodeController.php
new file mode 100644
index 00000000..7dc58d23
--- /dev/null
+++ b/Server/application/common/controller/SendCodeController.php
@@ -0,0 +1,39 @@
+request->only(['account', 'type']);
+
+ // 参数验证
+ $validate = validate('common/Auth');
+ if (!$validate->scene('send_code')->check($params)) {
+ return ResponseHelper::error($validate->getError());
+ }
+
+ try {
+ // 调用发送验证码服务
+ $result = $this->authService->sendLoginCode(
+ $params['account'],
+ $params['type']
+ );
+ return ResponseHelper::success($result, '验证码发送成功');
+ } catch (\Exception $e) {
+ return ResponseHelper::error($e->getMessage());
+ }
+ }
+}
\ No newline at end of file
diff --git a/Server/application/common/model/User.php b/Server/application/common/model/User.php
index bd37c17f..c3535d5c 100644
--- a/Server/application/common/model/User.php
+++ b/Server/application/common/model/User.php
@@ -1,4 +1,5 @@
'integer',
- 'isAdmin' => 'integer',
- 'companyId' => 'integer',
- 'typeId' => 'integer',
- 'lastLoginTime' => 'integer',
- 'status' => 'integer',
- 'createTime' => 'integer',
- 'updateTime' => 'integer',
- 'deleteTime' => 'integer'
- ];
-
- /**
- * 通过手机号获取用户信息
- * @param string $account 手机号
- * @return array|null
- */
- public static function getUserByMobile($account)
- {
- // 查询用户
- $user = self::where('account', $account)
- ->where('status', 1)
- ->find();
-
- if (!$user) {
- return null;
- }
-
- // 用手机号当做默认用户名(如果没有设置用户名)
- $username = $user->username ?: $user->account;
- // 默认头像地址
- $avatar = $user->avatar ?: '';
-
- return [
- 'id' => $user->id,
- 'username' => $username,
- 'account' => $user->account,
- 'avatar' => $avatar,
- 'isAdmin' => $user->isAdmin,
- 'companyId' => $user->companyId,
- 'typeId' => $user->typeId,
- 'lastLoginIp' => $user->lastLoginIp,
- 'lastLoginTime' => $user->lastLoginTime
- ];
- }
}
\ No newline at end of file
diff --git a/Server/application/common/service/AuthService.php b/Server/application/common/service/AuthService.php
index b94c57cc..a2eac90e 100644
--- a/Server/application/common/service/AuthService.php
+++ b/Server/application/common/service/AuthService.php
@@ -1,85 +1,59 @@
where('phone', $account)->whereOr('account', $account);
+ })
+ ->where(function ($query) use ($typeId) {
+ $query->where('status', 1)->where('typeId', $typeId);
+ })->find();
+
+ return $user;
+ }
+
/**
* 获取用户信息
+ *
* @param string $account 账号(手机号)
* @param string $password 密码(可能是加密后的)
* @param int $typeId 身份信息
* @return array|null
*/
- protected function getUser($account, $password, $typeId)
+ protected function getUser(string $account, string $password, int $typeId): array
{
- // 查询用户
- $user = User::where('account', $account)
- ->where('typeId', $typeId)
- ->where('status', 1)
- ->find();
+ $user = $this->getUserProfileWithAccountAndType($account, $typeId);
if (!$user) {
- // 记录日志
- \think\facade\Log::info('用户不存在或已禁用', ['account' => $account]);
- return null;
+ throw new \Exception('用户不存在或已禁用', 403);
}
- // 记录密码验证信息
- \think\facade\Log::info('密码验证', [
- 'account' => $account,
- 'input_password' => $password,
- 'stored_hash' => $user->passwordMd5,
- ]);
-
- // 验证密码
- $isValid = ($user->passwordMd5 == md5($password));
-
- \think\facade\Log::info('密码验证结果', [
- 'account' => $account,
- 'is_valid' => $isValid,
- ]);
-
- if (!$isValid) {
- return null;
+ if ($user->passwordMd5 !== md5($password)) {
+ throw new \Exception('账号或密码错误', 403);
}
- // 更新登录信息
- $user->lastLoginIp = request()->ip();
- $user->lastLoginTime = time();
- $user->save();
-
- // 用手机号当做默认用户名(如果没有设置用户名)
- $username = $user->username ?: $user->account;
-
- return [
- 'id' => $user->id,
- 'username' => $username,
- 'account' => $user->account,
- 'avatar' => $user->avatar,
- 'isAdmin' => $user->isAdmin,
- 'companyId' => $user->companyId,
- 'typeId' => $user->typeId,
- 'lastLoginIp' => $user->lastLoginIp,
- 'lastLoginTime' => $user->lastLoginTime
- ];
+ return $user->toArray();
}
/**
@@ -92,39 +66,28 @@ class AuthService
/**
* 用户登录
+ *
* @param string $account 账号(手机号)
* @param string $password 密码(可能是加密后的)
* @param string $ip 登录IP
* @return array
* @throws \Exception
*/
- public function login($account, $password, $typeId, $ip)
+ public function login(string $account, string $password, int $typeId, string $ip)
{
// 获取用户信息
- $user = $this->getUser($account, $password, $typeId);
+ $member = $this->getUser($account, $password, $typeId);
- if (empty($user)) {
- // 记录登录失败
- Log::info('登录失败', ['account' => $account, 'ip' => $ip, 'is_encrypted' => true]);
- throw new \Exception('账号或密码错误');
- }
-
// 生成JWT令牌
$token = JwtUtil::createToken($user, self::TOKEN_EXPIRE);
- $expireTime = time() + self::TOKEN_EXPIRE;
-
- // 记录登录成功
- Log::info('登录成功', ['account' => $account, 'ip' => $ip]);
-
- return [
- 'token' => $token,
- 'token_expired' => $expireTime,
- 'member' => $user
- ];
+ $token_expired = time() + self::TOKEN_EXPIRE;
+
+ return compact('member', 'token', 'token_expired');
}
/**
* 手机号验证码登录
+ *
* @param string $account 手机号
* @param string $code 验证码(可能是加密后的)
* @param string $ip 登录IP
@@ -137,14 +100,14 @@ class AuthService
// 验证验证码
if (!$this->smsService->verifyCode($account, $code, 'login', $isEncrypted)) {
Log::info('验证码验证失败', ['account' => $account, 'ip' => $ip, 'is_encrypted' => $isEncrypted]);
- throw new \Exception('验证码错误或已过期');
+ throw new \Exception('验证码错误或已过期', 404);
}
// 获取用户信息
$user = User::getUserByMobile($account);
if (empty($user)) {
Log::info('用户不存在', ['account' => $account, 'ip' => $ip]);
- throw new \Exception('用户不存在');
+ throw new \Exception('用户不存在', 404);
}
// 生成JWT令牌
@@ -163,6 +126,7 @@ class AuthService
/**
* 发送登录验证码
+ *
* @param string $account 手机号
* @param string $type 验证码类型
* @return array
@@ -175,6 +139,7 @@ class AuthService
/**
* 获取用户信息
+ *
* @param array $userInfo JWT中的用户信息
* @return array
* @throws \Exception
@@ -184,16 +149,17 @@ class AuthService
if (empty($userInfo)) {
throw new \Exception('获取用户信息失败');
}
-
+
// 移除不需要返回的字段
unset($userInfo['exp']);
unset($userInfo['iat']);
-
+
return $userInfo;
}
/**
* 刷新令牌
+ *
* @param array $userInfo JWT中的用户信息
* @return array
* @throws \Exception
@@ -203,15 +169,15 @@ class AuthService
if (empty($userInfo)) {
throw new \Exception('刷新令牌失败');
}
-
+
// 移除过期时间信息
unset($userInfo['exp']);
unset($userInfo['iat']);
-
+
// 生成新令牌
$token = JwtUtil::createToken($userInfo, self::TOKEN_EXPIRE);
$expireTime = time() + self::TOKEN_EXPIRE;
-
+
return [
'token' => $token,
'token_expired' => $expireTime
@@ -220,52 +186,53 @@ class AuthService
/**
* 获取系统授权信息,使用缓存存储10分钟
+ *
* @return string
*/
public static function getSystemAuthorization()
{
// 定义缓存键名
$cacheKey = 'system_authorization_token';
-
+
// 尝试从缓存获取授权信息
$authorization = Cache::get($cacheKey);
//$authorization = 'mYpVVhPY7PxctvYw1pn1VCTS2ck0yZG8q11gAiJrRN_D3q7KXXBPAfXoAmqs7kKHeaAx-h4GB7DiqVIQJ09HiXVhaQT6PtgLX3w8YV16erThC-lG1fyJB4DJxu-QxA3Q8ogSs1WFOa8aAXD1QQUZ7Kbjkw_VMLL4lrfe0Yjaqy3DnO7aL1xGnNjjX8P5uqCAZgHKlN8NjuDEGyYvXygW1YyoK9pNpwvq-6DYKjLWdmbHvFaAybHf-hU1XyrFavZqcZYxIoVXjfJ5ASp4XxeCWqMCzwtSoz9RAvwLAlNxGweowtuyX9389ZaXI-zbqb2T0S8llg';
- // 如果缓存中没有或已过期,则重新获取
+ // 如果缓存中没有或已过期,则重新获取
if (empty($authorization)) {
try {
// 从环境变量中获取API用户名和密码
$username = Env::get('api.username', '');
$password = Env::get('api.password', '');
-
+
if (empty($username) || empty($password)) {
Log::error('缺少API用户名或密码配置');
return '';
}
-
+
// 构建登录参数
$params = [
'grant_type' => 'password',
'username' => $username,
'password' => $password
];
-
+
// 获取API基础URL
$baseUrl = Env::get('api.wechat_url', '');
if (empty($baseUrl)) {
Log::error('缺少API基础URL配置');
return '';
}
-
+
// 调用登录接口获取token
// 设置请求头
$headerData = ['client:system'];
$header = setHeader($headerData, '', 'plain');
- $result = requestCurl($baseUrl . 'token', $params, 'POST',$header);
+ $result = requestCurl($baseUrl . 'token', $params, 'POST', $header);
$result_array = handleApiResponse($result);
if (isset($result_array['access_token']) && !empty($result_array['access_token'])) {
$authorization = $result_array['access_token'];
-
+
// 存入缓存,有效期10分钟(600秒)
Cache::set($cacheKey, $authorization, 600);
Cache::set('system_refresh_token', $result_array['refresh_token'], 600);
@@ -281,7 +248,7 @@ class AuthService
return '';
}
}
-
+
return $authorization;
}
}
\ No newline at end of file
diff --git a/Server/application/common/service/SmsService.php b/Server/application/common/service/SmsService.php
index 91d08773..e0552f11 100644
--- a/Server/application/common/service/SmsService.php
+++ b/Server/application/common/service/SmsService.php
@@ -1,4 +1,5 @@
checkSendLimit($mobile, $type);
-
+
// 生成验证码
$code = $this->generateCode();
-
+
// 缓存验证码
$this->saveCode($mobile, $code, $type);
-
+
// 发送验证码(实际项目中对接短信平台)
$this->doSend($mobile, $code, $type);
-
+
// 记录日志
Log::info('发送验证码', [
'mobile' => $mobile,
'type' => $type,
'code' => $code
]);
-
+
return [
'mobile' => $mobile,
'expire' => self::CODE_EXPIRE,
@@ -54,7 +55,7 @@ class SmsService
'code' => $code
];
}
-
+
/**
* 验证验证码
* @param string $mobile 手机号
@@ -67,7 +68,7 @@ class SmsService
{
$cacheKey = $this->getCodeCacheKey($mobile, $type);
$cacheCode = Cache::get($cacheKey);
-
+
if (!$cacheCode) {
Log::info('验证码不存在或已过期', [
'mobile' => $mobile,
@@ -75,15 +76,15 @@ class SmsService
]);
return false;
}
-
+
// 验证码是否匹配
$isValid = false;
-
+
if ($isEncrypted) {
// 前端已加密,需要对缓存中的验证码进行相同的加密处理
$encryptedCacheCode = $this->encryptCode($cacheCode);
$isValid = hash_equals($encryptedCacheCode, $code);
-
+
// 记录日志
Log::info('加密验证码验证', [
'mobile' => $mobile,
@@ -95,7 +96,7 @@ class SmsService
} else {
// 未加密,直接比较
$isValid = ($cacheCode === $code);
-
+
// 记录日志
Log::info('明文验证码验证', [
'mobile' => $mobile,
@@ -104,15 +105,15 @@ class SmsService
'is_valid' => $isValid
]);
}
-
+
// 验证成功后删除缓存
if ($isValid) {
Cache::rm($cacheKey);
}
-
+
return $isValid;
}
-
+
/**
* 检查发送频率限制
* @param string $mobile 手机号
@@ -122,24 +123,24 @@ class SmsService
protected function checkSendLimit($mobile, $type)
{
$cacheKey = $this->getCodeCacheKey($mobile, $type);
-
+
// 检查是否存在未过期的验证码
if (Cache::has($cacheKey)) {
throw new \Exception('验证码已发送,请稍后再试');
}
-
+
// 检查当日发送次数限制
$limitKey = "sms_limit:{$mobile}:" . date('Ymd');
$sendCount = Cache::get($limitKey, 0);
-
+
if ($sendCount >= 10) {
throw new \Exception('今日发送次数已达上限');
}
-
+
// 更新发送次数
Cache::set($limitKey, $sendCount + 1, 86400);
}
-
+
/**
* 生成随机验证码
* @return string
@@ -149,7 +150,7 @@ class SmsService
// 生成4位数字验证码
return sprintf("%0" . self::CODE_LENGTH . "d", mt_rand(0, pow(10, self::CODE_LENGTH) - 1));
}
-
+
/**
* 保存验证码到缓存
* @param string $mobile 手机号
@@ -161,7 +162,7 @@ class SmsService
$cacheKey = $this->getCodeCacheKey($mobile, $type);
Cache::set($cacheKey, $code, self::CODE_EXPIRE);
}
-
+
/**
* 执行发送验证码
* @param string $mobile 手机号
@@ -175,7 +176,7 @@ class SmsService
// 这里仅做模拟,返回成功
return true;
}
-
+
/**
* 获取验证码缓存键名
* @param string $mobile 手机号
@@ -186,7 +187,7 @@ class SmsService
{
return "sms_code:{$mobile}:{$type}";
}
-
+
/**
* 加密验证码
* 使用与前端相同的加密算法
diff --git a/Server/application/cunkebao/config/route.php b/Server/application/cunkebao/config/route.php
index 6a14bb07..309a6dfd 100644
--- a/Server/application/cunkebao/config/route.php
+++ b/Server/application/cunkebao/config/route.php
@@ -10,72 +10,73 @@ Route::group('v1/', function () {
// 设备管理相关
Route::group('devices', function () {
- Route::get(':id/related-accounts', 'app\\cunkebao\\controller\\device\\GetRelatedAccountsV1Controller@index'); // 设备关联微信账号路由
- Route::get(':id/handle-logs', 'app\\cunkebao\\controller\\device\\GetDeviceHandleLogsV1Controller@index'); // 获取设备操作记录
- Route::get('', 'app\\cunkebao\\controller\\device\\GetDeviceListV1Controller@index'); // 获取设备列表
- Route::get(':id', 'app\\cunkebao\\controller\\device\\GetDeviceDetailV1Controller@index'); // 获取设备详情
- Route::post('', 'app\\cunkebao\\controller\\device\\PostAddDeviceV1Controller@index'); // 添加设备
- Route::put('refresh', 'app\\cunkebao\\controller\\device\\RefreshDeviceDetailV1Controller@index'); // 刷新设备状态
- Route::delete(':id', 'app\\cunkebao\\controller\\Device@delete'); // 删除设备
- Route::post('task-config', 'app\\cunkebao\\controller\\device\\UpdateDeviceTaskConfigV1Controller@index'); // 更新设备任务配置
+ Route::get(':id/related-accounts', 'app\cunkebao\controller\device\GetRelatedAccountsV1Controller@index'); // 设备关联微信账号路由
+ Route::get(':id/handle-logs', 'app\cunkebao\controller\device\GetDeviceHandleLogsV1Controller@index'); // 获取设备操作记录
+ Route::get('', 'app\cunkebao\controller\device\GetDeviceListV1Controller@index'); // 获取设备列表
+ Route::get(':id', 'app\cunkebao\controller\device\GetDeviceDetailV1Controller@index'); // 获取设备详情
+ Route::post('', 'app\cunkebao\controller\device\PostAddDeviceV1Controller@index'); // 添加设备
+ Route::put('refresh', 'app\cunkebao\controller\device\RefreshDeviceDetailV1Controller@index'); // 刷新设备状态
+ Route::delete(':id', 'app\cunkebao\controller\Device@delete'); // 删除设备
+ Route::post('task-config', 'app\cunkebao\controller\device\UpdateDeviceTaskConfigV1Controller@index');
+ Route::get('add-results', 'app\cunkebao\controller\device\GetAddResultedDevicesController@index'); // 更新设备任务配置
});
// 设备微信相关
Route::group('device/wechats', function () {
- Route::get('friends', 'app\\cunkebao\\controller\\DeviceWechat@getFriends'); // 获取微信好友列表
- Route::get('count', 'app\\cunkebao\\controller\\DeviceWechat@count'); // 获取在线微信账号数量
- Route::get('device-count', 'app\\cunkebao\\controller\\DeviceWechat@deviceCount'); // 获取有登录微信的设备数量
- Route::get('', 'app\\cunkebao\\controller\\DeviceWechat@index'); // 获取在线微信账号列表
- Route::get(':id', 'app\\cunkebao\\controller\\DeviceWechat@detail'); // 获取微信号详情
- Route::put('refresh', 'app\\cunkebao\\controller\\DeviceWechat@refresh'); // 刷新设备微信状态
- Route::post('transfer-friends', 'app\\cunkebao\\controller\\DeviceWechat@transferFriends'); // 微信好友转移
+ Route::get('friends', 'app\cunkebao\controller\DeviceWechat@getFriends'); // 获取微信好友列表
+ Route::get('count', 'app\cunkebao\controller\DeviceWechat@count'); // 获取在线微信账号数量
+ Route::get('device-count', 'app\cunkebao\controller\DeviceWechat@deviceCount'); // 获取有登录微信的设备数量
+ Route::get('', 'app\cunkebao\controller\DeviceWechat@index'); // 获取在线微信账号列表
+ Route::get(':id', 'app\cunkebao\controller\DeviceWechat@detail'); // 获取微信号详情
+ Route::put('refresh', 'app\cunkebao\controller\DeviceWechat@refresh'); // 刷新设备微信状态
+ Route::post('transfer-friends', 'app\cunkebao\controller\DeviceWechat@transferFriends'); // 微信好友转移
});
// 获客场景相关
Route::group('plan/scenes', function () {
- Route::get('', 'app\\cunkebao\\controller\\Scene@index'); // 获取场景列表
+ Route::get('', 'app\cunkebao\controller\Scene@index'); // 获取场景列表
});
// 流量标签相关
Route::group('traffic/tags', function () {
- Route::get('', 'app\\cunkebao\\controller\\TrafficTag@index'); // 获取标签列表
+ Route::get('', 'app\cunkebao\controller\TrafficTag@index'); // 获取标签列表
});
// 流量池相关
Route::group('traffic/pool', function () {
- Route::post('import', 'app\\cunkebao\\controller\\TrafficPool@importOrders'); // 导入订单标签
+ Route::post('import', 'app\cunkebao\controller\TrafficPool@importOrders'); // 导入订单标签
});
// 工作台相关
Route::group('workbench', function () {
- Route::post('create', 'app\\cunkebao\\controller\\WorkbenchController@create'); // 创建工作台
- Route::get('list', 'app\\cunkebao\\controller\\WorkbenchController@getList'); // 获取工作台列表
- Route::post('update-status', 'app\\cunkebao\\controller\\WorkbenchController@updateStatus'); // 更新工作台状态
- Route::delete('delete', 'app\\cunkebao\\controller\\WorkbenchController@delete'); // 删除工作台
- Route::post('copy', 'app\\cunkebao\\controller\\WorkbenchController@copy'); // 拷贝工作台
- Route::get('detail', 'app\\cunkebao\\controller\\WorkbenchController@detail'); // 获取工作台详情
- Route::post('update', 'app\\cunkebao\\controller\\WorkbenchController@update'); // 更新工作台
+ Route::post('create', 'app\cunkebao\controller\WorkbenchController@create'); // 创建工作台
+ Route::get('list', 'app\cunkebao\controller\WorkbenchController@getList'); // 获取工作台列表
+ Route::post('update-status', 'app\cunkebao\controller\WorkbenchController@updateStatus'); // 更新工作台状态
+ Route::delete('delete', 'app\cunkebao\controller\WorkbenchController@delete'); // 删除工作台
+ Route::post('copy', 'app\cunkebao\controller\WorkbenchController@copy'); // 拷贝工作台
+ Route::get('detail', 'app\cunkebao\controller\WorkbenchController@detail'); // 获取工作台详情
+ Route::post('update', 'app\cunkebao\controller\WorkbenchController@update'); // 更新工作台
});
// 内容库相关
Route::group('content/library', function () {
- Route::post('create', 'app\\cunkebao\\controller\\ContentLibraryController@create'); // 创建内容库
- Route::get('list', 'app\\cunkebao\\controller\\ContentLibraryController@getList'); // 获取内容库列表
- Route::post('update', 'app\\cunkebao\\controller\\ContentLibraryController@update'); // 更新内容库
- Route::delete('delete', 'app\\cunkebao\\controller\\ContentLibraryController@delete'); // 删除内容库
- Route::get('detail', 'app\\cunkebao\\controller\\ContentLibraryController@detail'); // 获取内容库详情
- Route::get('collectMoments', 'app\\cunkebao\\controller\\ContentLibraryController@collectMoments'); // 采集朋友圈
+ Route::post('create', 'app\cunkebao\controller\ContentLibraryController@create'); // 创建内容库
+ Route::get('list', 'app\cunkebao\controller\ContentLibraryController@getList'); // 获取内容库列表
+ Route::post('update', 'app\cunkebao\controller\ContentLibraryController@update'); // 更新内容库
+ Route::delete('delete', 'app\cunkebao\controller\ContentLibraryController@delete'); // 删除内容库
+ Route::get('detail', 'app\cunkebao\controller\ContentLibraryController@detail'); // 获取内容库详情
+ Route::get('collectMoments', 'app\cunkebao\controller\ContentLibraryController@collectMoments'); // 采集朋友圈
});
// 好友相关
Route::group('friend', function () {
- Route::get('', 'app\\cunkebao\\controller\\friend\\GetFriendListV1Controller@index'); // 获取好友列表
+ Route::get('', 'app\cunkebao\controller\friend\GetFriendListV1Controller@index'); // 获取好友列表
});
//群相关
Route::group('chatroom', function () {
- Route::get('', 'app\\cunkebao\\controller\\chatroom\\GetChatroomListV1Controller@index'); // 获取群列表
- Route::get('getMemberList', 'app\\cunkebao\\controller\\chatroom\\GetChatroomListV1Controller@getMemberList'); // 获取群详情
+ Route::get('', 'app\cunkebao\controller\chatroom\GetChatroomListV1Controller@index'); // 获取群列表
+ Route::get('getMemberList', 'app\cunkebao\controller\chatroom\GetChatroomListV1Controller@getMemberList'); // 获取群详情
});
diff --git a/Server/application/cunkebao/controller/BaseController.php b/Server/application/cunkebao/controller/BaseController.php
index 1189cafa..852858f9 100644
--- a/Server/application/cunkebao/controller/BaseController.php
+++ b/Server/application/cunkebao/controller/BaseController.php
@@ -32,7 +32,7 @@ class BaseController extends Controller
* @return mixed
* @throws \Exception
*/
- protected function getUserInfo(string $column = '')
+ protected function getUserInfo(?string $column = null)
{
$user = $this->request->userInfo;
diff --git a/Server/application/cunkebao/controller/device/GetAddResultedDevicesController.php b/Server/application/cunkebao/controller/device/GetAddResultedDevicesController.php
new file mode 100644
index 00000000..6a5e23a9
--- /dev/null
+++ b/Server/application/cunkebao/controller/device/GetAddResultedDevicesController.php
@@ -0,0 +1,120 @@
+value('companyId');
+ }
+
+ /**
+ * 获取项目下的所有设备。
+ *
+ * @param int $companyId
+ * @return array
+ */
+ protected function getAllDevicesIdWithInCompany(int $companyId): array
+ {
+ return DeviceModel::where('companyId', $companyId)->column('id') ?: [0];
+ }
+
+ /**
+ * 执行数据迁移。
+ *
+ * @param int $accountId
+ * @return void
+ */
+ protected function migrateData(int $accountId): void
+ {
+ $companyId = $this->getCompanyIdByAccountId($accountId);
+ $deviceIds = $this->getAllDevicesIdWithInCompany($companyId) ?: [0];
+
+ // 从 s2_device 导入数据。
+ $this->getNewDeviceFromS2_device($deviceIds, $companyId);
+ }
+
+ /**
+ * 从 s2_device 导入数据。
+ *
+ * @param array $ids
+ * @param int $companyId
+ * @return void
+ */
+ protected function getNewDeviceFromS2_device(array $ids, int $companyId): void
+ {
+ $ids = implode(',', $ids);
+
+ $sql = "insert into ck_device(`id`, `imei`, `model`, phone, operatingSystem,memo,alive,brand,rooted,xPosed,softwareVersion,extra,createTime,updateTime,deleteTime,companyId)
+ select
+ d.id,d.imei,d.model,d.phone,d.operatingSystem,d.memo,d.alive,d.brand,d.rooted,d.xPosed,d.softwareVersion,d.extra,d.createTime,d.lastUpdateTime,d.deleteTime,a.departmentId companyId
+ from s2_device d
+ join s2_company_account a on d.currentAccountId = a.id
+ where isDeleted = 0 and deletedAndStop = 0 and d.id not in ({$ids}) and a.departmentId = {$companyId}
+ ";
+
+ Db::query($sql);
+ }
+
+ /**
+ * 获取添加的关联设备结果。
+ *
+ * @param int $accountId
+ * @return bool
+ */
+ protected function getAddResulted(int $accountId): bool
+ {
+ $result = (new ApiDeviceController())->getlist(
+ [
+ 'accountId' => $accountId,
+ 'pageIndex' => 0,
+ 'pageSize' => 1
+ ],
+ true
+ );
+
+ $result = json_decode($result, true);
+ $result = $result['data']['results'][0] ?? false;
+
+ return $result ? (
+ // 125是前端延迟5秒 + 轮询120次 1次/s
+ time() - strtotime($result['lastUpdateTime']) <= 65
+ ) : false;
+ }
+
+ /**
+ * 获取基础统计信息
+ *
+ * @return \think\response\Json
+ */
+ public function index()
+ {
+ $accountId = $this->request->param('accountId/d');
+
+ $isAdded = $this->getAddResulted($accountId);
+ $isAdded && $this->migrateData($accountId);
+
+ return ResponseHelper::success(
+ [
+ 'added' => $isAdded
+ ]
+ );
+ }
+}
\ No newline at end of file