新版数智员工

This commit is contained in:
wong
2026-03-24 10:39:16 +08:00
parent 1853934d85
commit 7fb61b77a4
123 changed files with 38491 additions and 1018 deletions

View File

@@ -0,0 +1,114 @@
<?php
namespace app\common\controller;
use think\Controller;
use think\facade\Log;
use app\common\service\UserApiKeyService;
use app\common\util\JwtUtil;
/**
* 对外开放接口 — 鉴权控制器
*
* 第三方系统先用 apiKey + sign 换取 JWT Token
* 后续所有 /v1/open/* 业务接口只需在 Header 中携带:
* Authorization: Bearer <token>
* 即可调用,与存客宝内部接口完全兼容。
*/
class OpenAuthController extends Controller
{
/**
* 获取 JWT Token
* POST /v1/open/auth/token
*
* 请求参数:
* apiKey - 账号专属 API Keyck_users.apiKey
* account - 登录账号ck_users.account参与签名
* timestamp - 秒级时间戳
* sign - 签名值,算法见签名文档
*
* 成功响应:
* { code: 200, message: "success", data: { token: "xxx", expires_in: 7200 } }
*/
public function getToken()
{
try {
$params = $this->request->param();
// ── 1. 必填参数校验 ─────────────────────────────────────────
if (empty($params['apiKey'])) {
return $this->fail('apiKey不能为空', 400);
}
if (empty($params['account'])) {
return $this->fail('account不能为空', 400);
}
if (empty($params['sign'])) {
return $this->fail('sign不能为空', 400);
}
if (empty($params['timestamp'])) {
return $this->fail('timestamp不能为空', 400);
}
// ── 2. 时间戳时效校验±5 分钟)──────────────────────────────
if (abs(time() - intval($params['timestamp'])) > 300) {
return $this->fail('请求已过期', 400);
}
// ── 3. 用 apiKey 找账号,并校验 account 一致性 ───────────────
$user = UserApiKeyService::findUserByKey($params['apiKey']);
if (!$user) {
return $this->fail('无效的apiKey', 401);
}
if ($user['account'] !== $params['account']) {
return $this->fail('无效的apiKey', 401);
}
// ── 4. 验签account + timestamp + apiKey────────────────────
if (!UserApiKeyService::validateSign(
$params['account'],
(string)$params['timestamp'],
$params['apiKey'],
$params['sign']
)) {
return $this->fail('签名验证失败', 401);
}
// ── 5. 签发 JWT2 小时有效期)────────────────────────────────
$expireSeconds = 7200;
$token = JwtUtil::createToken([
'id' => (int)$user['id'],
'account' => $user['account'] ?? '',
'username' => $user['username'] ?? '',
'phone' => $user['phone'] ?? '',
'companyId' => (int)$user['companyId'],
'typeId' => (int)$user['typeId'],
'isAdmin' => (int)($user['isAdmin'] ?? 0),
'via' => 'open_api', // 标记来源,方便日志区分
], $expireSeconds);
Log::info('[OpenAuth] 对外接口登录成功', [
'userId' => $user['id'],
'account' => $user['account'],
'ip' => $this->request->ip(),
]);
return json([
'code' => 200,
'message' => 'success',
'data' => [
'token' => $token,
'expires_in' => $expireSeconds,
],
]);
} catch (\Exception $e) {
Log::error('[OpenAuth] getToken 异常:' . $e->getMessage());
return $this->fail('系统错误: ' . $e->getMessage(), 500);
}
}
private function fail(string $message, int $code = 400)
{
return json(['code' => $code, 'message' => $message, 'data' => null]);
}
}