chore: 入库生产基线(2026-10-26 与 shop.douba.top 一致)

- 11 个已跟踪文件的在途改动此前只存在于工作区,生产已在运行
- 补入两个从未入库的文件:InternalController.php(app_03/box_app 内部接口)、
  config/internal.php(内部通信 key,值从 .env 读取,不含硬编码密钥)
- 逐文件 md5 比对过生产,内容一致

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-10-26 17:08:55 +08:00
parent c7f85ffbda
commit fc353899a9
13 changed files with 331 additions and 37 deletions

View File

@@ -0,0 +1,134 @@
<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\controller\api\v1;
use app\Request;
use app\services\user\UserServices;
use app\services\wechat\RoutineServices;
use app\services\wechat\WechatUserServices;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\exception\ValidateException;
use think\Response;
/**
* 内部服务接口(不经过用户认证)
* 用于 H5 / app_03 后端通过 openid 自动补齐用户信息
*/
class InternalController
{
/**
* 验证内部 API Key
* @param Request $request
* @return bool true=通过,false=拒绝
*/
private function checkInternalKey(Request $request): bool
{
$apiKey = $request->header('X-Internal-Key');
// 注意:在 Swoole 沙箱里 env()/getenv() 经常读不到 .env
// 用 config() 兜底,确保两种部署(PHP-FPM / Swoole)都生效
$configKey = (string)(config('internal.api_key') ?: env('INTERNAL_API_KEY', ''));
return $apiKey && $configKey && $apiKey === $configKey;
}
/**
* 根据 openid 获取用户信息
* @param Request $request
* @param WechatUserServices $wechatUserServices
* @return Response
*/
public function userInfo(Request $request, WechatUserServices $wechatUserServices): Response
{
if (!$this->checkInternalKey($request)) {
return Response::create(['code' => 403, 'msg' => 'Forbidden'], 'json');
}
$openid = $request->param('openid', '');
if (!$openid) {
return Response::create(['code' => 400, 'msg' => 'openid is required'], 'json');
}
try {
$wechatUser = $wechatUserServices->getWechatUserInfo(['openid' => $openid]);
} catch (DataNotFoundException | ModelNotFoundException | DbException $e) {
return Response::create(['code' => 500, 'msg' => '查询失败'], 'json');
}
if (!$wechatUser) {
return Response::create(['code' => 404, 'msg' => 'user not found'], 'json');
}
$uid = (int)$wechatUser['uid'];
$userServices = app()->make(UserServices::class);
try {
$user = $userServices->getUserInfo($uid);
} catch (DataNotFoundException | ModelNotFoundException | DbException $e) {
$user = null;
}
return Response::create([
'code' => 200,
'data' => [
'uid' => $uid,
'nickname' => $user['nickname'] ?? $wechatUser['nickname'] ?? '',
'phone' => $user['phone'] ?? $wechatUser['phone'] ?? '',
'avatar' => $user['avatar'] ?? $wechatUser['headimgurl'] ?? '',
],
], 'json');
}
/**
* 通过微信 code 换 openid(绕过 store_user_mobile 限制)
*
* 设计目的:H5/app_03 在新用户场景下(CRMEB 强制绑手机号=true),
* 原 silenceAuth 返回 {auth_login:1, key:...},前端拿不到 openid 会被
* 引导到授权页。本端点只调微信 code2session 拿 openid/unionid,不查
* store_user_mobile、不建用户、不发 token,前端拿到 openid 后走自己的
* openid-login 即可自助登录。
*
* @param Request $request
* @param RoutineServices $routineServices
* @return Response
*/
public function getOpenidByCode(Request $request, RoutineServices $routineServices): Response
{
if (!$this->checkInternalKey($request)) {
return Response::create(['code' => 403, 'msg' => 'Forbidden'], 'json');
}
$code = $request->param('code', '');
if (!$code) {
return Response::create(['code' => 400, 'msg' => 'code is required'], 'json');
}
try {
$wechatInfo = $routineServices->getUserInfoByCode((string)$code);
} catch (ValidateException $e) {
return Response::create(['code' => 400, 'msg' => $e->getMessage()], 'json');
} catch (\Throwable $e) {
return Response::create(['code' => 500, 'msg' => 'code2session 失败: ' . $e->getMessage()], 'json');
}
$openid = $wechatInfo['openid'] ?? '';
if (!$openid) {
return Response::create(['code' => 500, 'msg' => 'openid 缺失'], 'json');
}
return Response::create([
'code' => 200,
'data' => [
'openid' => $openid,
'unionid' => $wechatInfo['unionid'] ?? '',
],
], 'json');
}
}