Files
ntonpower/app/library/SSOApi.php
2026-10-14 14:00:29 +08:00

459 lines
14 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace app\library;
use think\facade\Cache;
use think\facade\Env;
use think\facade\Session;
/**
* 单点请求类
*/
trait SSOApi
{
/**
* 应用请求token
* @var array
*/
protected $appToken = [];
/**
* 单点配置信息
* @var array
*/
protected $ssoApiConfig = [];
/**
* 接口列表
*/
protected $apis = [
'getAuthorizeToken' => '/authorize/token',/*获取应用授权接口*/
'getDeptList' => '/dept/list',/*部门分页数据*/
'getDeptDetail' => '/dept/detail',/*根据ID部门详细*/
'getDeptDetailDeptCode' => '/dept/detail/dept_code',/*根据编码部门详细*/
'getDeptHead' => '/dept/head',/*根据编码获取部门主管*/
'getDeptChainId' => '/dept/chain/id/{id}',/*根据部门ID获取部门上下级*/
'getDeptChainCode' => '/dept/chain/code/{code}',/*根据部门编码获取部门上下级*/
'getStaffList' => '/staff/list',/*员工分页数据*/
'getStaffListDept' => '/staff/list/dept',/*根据部门编码获取员工数据*/
'getUserDetailUid' => '/user/detail/uid',/*根据用户ID获取用户详细*/
'getUserDetailStaffCode' => '/user/detail/staff_code',/*根据用户(员工)编码获取用户(员工)详情*/
'getUserDepts' => '/user/depts',/*根据用户ID获取用户所属部门*/
'getUserDeptsStaffCode' => '/user/depts/staff_code',/*根据用户编码获取用户所属部门*/
'getUserDetailMobile' => '/user/detail/mobile',/*根据手机号获取用户详细*/
'getRoleDetailId' => '/role/detail/id/{id}',/*根据ID获取角色详细*/
'getRoleDetailCode' => '/role/detail/code/{code}',/*根据编码获取角色详细*/
'getMenuListApp' => '/menu/list/app',/*获取应用的菜单*/
'getMenuListUserCode' => '/menu/list/user/{code}',/*获取用户权限菜单*/
];
/**
* 初始化配置,需要手动去.env文件里面填写以下配置项
*
* [SSO]
* UC_URL='https://uc.test'
* UC_CACHE_KEY='crm_dev'
* APPID='cfcd05b1f3576e90cf53dc8a3d221ff7'
* APPSECRET='271491c88ef42303da0251034aee3e5c'
* UC_API_VERSION=v1
* PUB_KEY='-----BEGIN PUBLIC KEY-----
* -----END PUBLIC KEY-----'
* PRI_KEY='-----BEGIN PRIVATE KEY-----
* -----END PRIVATE KEY-----'
*
* UC_URL: 单点域名
* UC_CACHE_KEY:单点应用 token 缓存key值,用于标识是哪个应用的,比如crm系统,线上使用orico_crm,测试使用 dev_crm,
* APPID : 应用ID
* APPSECRET:应用密钥
*/
private function initSSOConfig(): array
{
if (Cache::has('app_get_auth') && Cache::get('app_get_auth') == 1) {
return $this->ssoApiConfig = [
'appId' => Cache::get('app')['app_id'],/*应用的APPID*/
'appSecret' => Cache::get('app')['app_secret'],/*应用密钥*/
'ssoApiUrl' => Env::get('SSO.UC_URL'),/*单点请求链接*/
'cacheKey' => Cache::get('app')['uc_cache_key'].'_app_token',/*应用token缓存key*/
'apiVersion' => '/api/'.Env::get('SSO.UC_API_VERSION')/*接口版本*/
];
} else {
return $this->ssoApiConfig = [
'appId' => Session::get('app')['app_id'],/*应用的APPID*/
'appSecret' => Session::get('app')['app_secret'],/*应用密钥*/
'ssoApiUrl' => Env::get('SSO.UC_URL'),/*单点请求链接*/
'cacheKey' => Session::get('app')['uc_cache_key'].'_app_token',/*应用token缓存key*/
'apiVersion' => '/api/'.Env::get('SSO.UC_API_VERSION')/*接口版本*/
];
}
}
/**
* 生成请求接口
* @param array $data 请求数据
* @param string $funcName 请求方法名
* @param bool $isPost 请求类型,true = post| false = get
* @param array $options 请求头
* @return array
*/
public function setRequestURI(array $data, string $funcName, bool $isPost = false,array $options = []):array
{
// if (empty($this->ssoApiConfig)) {
$this->initSSOConfig();
// }
//设置接口token
if (empty($this->appToken) && $funcName != 'getAuthorizeToken') {
$this->getAuthorizeToken();
}
$arrToken = [];
if ($funcName != 'getAuthorizeToken') {
$arrToken['access_token'] = $this->appToken['access_token'];
$data['access_token'] = $this->appToken['access_token'];
}
$params = null;
if (false === $isPost) {
//get请求
if ($funcName == 'getStaffListDept') {
$params = '?' . http_build_query($data);
} else {
$params = '?' . http_build_query($arrToken);
}
}
//拼接请求链接
$url = $this->ssoApiConfig['ssoApiUrl'].$this->ssoApiConfig['apiVersion'].$this->apis[$funcName];/*post 请求*/
if (!is_null($params)) {
//get 请求
if (false === strpos($this->apis[$funcName],'{')) {
$url = $this->ssoApiConfig['ssoApiUrl'].$this->ssoApiConfig['apiVersion'].$this->apis[$funcName].$params;
} else {
//解析出参数,restful 接口。 id/{:id}
$arr = explode('/{',$this->apis[$funcName]);
if (2 === count($arr)) {
$param = rtrim($arr[1],'}');
$newUrl = $arr[0];
$url = $this->ssoApiConfig['ssoApiUrl'].$this->ssoApiConfig['apiVersion'].$newUrl.DIRECTORY_SEPARATOR.$data[$param].$params;
}
}
}
//执行请求
$result = $this->http($url,$data,$isPost,$options);
// \think\facade\Log::record($url);
// \think\facade\Log::record(json_encode($result));
if (isset($result['status']) && $result['status'] == 200) {
return $result['data'];
}
return [];
}
/**
* 获取应用token
*/
public function getAuthorizeToken():array
{
// if (empty($this->ssoApiConfig)) {
$this->initSSOConfig();
// }
$data = [
'appid' => $this->ssoApiConfig['appId'],
'app_secret'=> $this->ssoApiConfig['appSecret']
];
$this->appToken = Cache::get($this->ssoApiConfig['cacheKey']);
if (is_null($this->appToken) || $this->appToken['expires_time'] - time() <= 600) {
$data = $this->setRequestURI($data,__FUNCTION__,true);
if (!empty($data)) {
$data['expires_time'] = time() + $data['expires_in'];
Cache::set($this->ssoApiConfig['cacheKey'], $data, $data['expires_in']-1000);
$this->appToken = $data;
return $data;
}
}
return $this->appToken;
}
/**
* 部门分页数据
* @param int $page 页码
* @param int $size 每页条数
* @param array $filter 查询条件,{"keywords":"dept_name=欧洲团"}
* @return array
*/
public function getDeptList(int $page = 0,int $size = 0,array $filter = []):array
{
$data = [];
if ($page != 0) {
$data['page'] = $page;
}
if ($size != 0) {
$data['size'] = $size;
}
if (!empty($filter)) {
$data['filter'] = $filter;
}
return $this->setRequestURI($data,__FUNCTION__,true);
}
/**
* 根据ID部门详细
* @param int $deptId 部门ID
* @return array
*/
public function getDeptDetail(int $deptId):array
{
$data = [
'id' => $deptId
];
return $this->setRequestURI($data,__FUNCTION__,true);
}
/**
* 根据ID部门详细
* @param string $deptCode 部门dept_code
* @return array
*/
public function getDeptDetailDeptCode(string $deptCode):array
{
$data = [
'dept_code' => $deptCode
];
return $this->setRequestURI($data,__FUNCTION__,true);
}
/**
* 根据编码获取部门主管
* @param string $deptCode 部门dept_codes
* @return array
*/
public function getDeptHead(string $deptCode):array
{
$data = [
'dept_code' => $deptCode
];
return $this->setRequestURI($data,__FUNCTION__);
}
/**
* 根据部门ID获取部门上下级
* @param int $deptId 部门ID
* @return array
*/
public function getDeptChainId(int $deptId):array
{
$data = [
'id' => $deptId
];
return $this->setRequestURI($data,__FUNCTION__);
}
/**
* 根据部门code获取部门上下级
* @param string $deptCode 部门dept_code
* @return array
*/
public function getDeptChainCode(string $deptCode):array
{
$data = [
'code' => $deptCode
];
return $this->setRequestURI($data,__FUNCTION__);
}
/**
* 员工分页数据
* @param int $page 页码
* @param int $size 每页条数
* @return array
*/
public function getStaffList(int $page = 0,int $size = 0):array
{
$data = [];
if ($page != 0) {
$data['page'] = $page;
}
if ($size != 0) {
$data['size'] = $size;
}
return $this->setRequestURI($data,__FUNCTION__,true);
}
/**
* 根据部门编码获取员工数据
* @param string $deptCode 部门dept_code
* @return array
*/
public function getStaffListDept(string $deptCode):array
{
$data = [
'dept_code' => $deptCode
];
return $this->setRequestURI($data,__FUNCTION__);
}
/**
* 根据用户ID获取用户详细
* @param int $uid 部门ID
* @return array
*/
public function getUserDetailUid(int $uid):array
{
$data = [
'uid' => $uid
];
return $this->setRequestURI($data,__FUNCTION__,true);
}
/**
* 根据用户(员工)编码获取用户(员工)详情
* @param string $staffCode 员工staff_code
* @return array
*/
public function getUserDetailStaffCode(string $staffCode):array
{
$data = [
'staff_code' => $staffCode
];
return $this->setRequestURI($data,__FUNCTION__,true);
}
/**
* 根据用户ID获取用户所属部门
* @param int $uid 部门ID
* @return array
*/
public function getUserDepts(int $uid):array
{
$data = [
'uid' => $uid
];
return $this->setRequestURI($data,__FUNCTION__,true);
}
/**
* 根据用户编码获取用户所属部门
* @param string $staffCode 员工staff_code
* @return array
*/
public function getUserDeptsStaffCode(string $staffCode):array
{
$data = [
'staff_code' => $staffCode
];
return $this->setRequestURI($data,__FUNCTION__,true);
}
/**
* 根据手机号获取用户详细
* @param string $mobile 手机号
* @return array
*/
public function getUserDetailMobile(string $mobile):array
{
$data = [
'mobile' => $mobile
];
return $this->setRequestURI($data,__FUNCTION__,true);
}
/**
* 根据ID获取角色详细
* @param int $roleId 角色role_id
* @return array
*/
public function getRoleDetailId(int $roleId):array
{
$data = [
'id' => $roleId
];
return $this->setRequestURI($data,__FUNCTION__);
}
/**
* 根据编码获取角色详细
* @param string $roleCode 角色role_code
* @return array
*/
public function getRoleDetailCode(string $roleCode):array
{
$data = [
'code' => $roleCode
];
return $this->setRequestURI($data,__FUNCTION__);
}
/**
* 获取应用的菜单
* @return array
*/
public function getMenuListApp():array
{
return $this->setRequestURI([],__FUNCTION__);
}
/**
* 获取用户权限菜单
* @param string $staffCode 用户staff_code
* @return array
*/
public function getMenuListUserCode(string $staffCode):array
{
// 是否是用于检测有没有权限
$this->appToken = [];
$data = [
'code' => $staffCode
];
return $this->setRequestURI($data,__FUNCTION__);
}
/**
* curl请求
* @param $url string 请求的url链接
* @param $data string|array|mixed 请求的数据
* @param bool $is_post 是否是post请求,默认false
* @param array $options 是否附带请求头
* @return array|mixed
*/
private function http(string $url, array $data, bool $is_post=false, array $options=[]):array
{
$data = json_encode($data);
$headerArray = [
'Content-type: application/json;charset=utf-8',
'Accept: application/json'
];
$curl = curl_init();
$arr = [];
array_push($arr,$url);
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST,FALSE);
if ($is_post) {
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
}
curl_setopt($curl,CURLOPT_HTTPHEADER,$headerArray);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
if (!empty($options['cookie'])) {
curl_setopt($curl, CURLOPT_COOKIE, $options['cookie']);
}
$output = curl_exec($curl);
$http_status = curl_errno($curl);
$http_msg = curl_error($curl);
curl_close($curl);
if ($http_status == 0) {
return json_decode($output, true);
} else {
return ['status' => $http_status, 'message' => $http_msg, 'data' => []];
}
}
}