* Finish task#57901.
This commit is contained in:
@@ -150,30 +150,24 @@ class feishuapi
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getDeptTree()
|
||||
public function getChildDeptTree($departmentID)
|
||||
{
|
||||
$depts = array('result' => 'success', 'data' => array());
|
||||
|
||||
/* Gets the enterprise name. */
|
||||
$response = $this->queryAPI($this->apiUrl . "tenant/v2/tenant/query", '', array(CURLOPT_CUSTOMREQUEST => "GET"));
|
||||
$company = array('id' => '1', 'pId' => '0', 'name' => $response->data->tenant->name, 'open' => 1);
|
||||
$data = array($company);
|
||||
|
||||
/* Get depts by parent dept. */
|
||||
$depts = array();
|
||||
$pageToken = '';
|
||||
$index = 0;
|
||||
while(true)
|
||||
{
|
||||
$response = $this->queryAPI($this->apiUrl . "contact/v3/departments?parent_department_id=0" . ($pageToken ? "&page_token={$pageToken}" : '') . "&fetch_child=true&page_size=50", '', array(CURLOPT_CUSTOMREQUEST => "GET"));
|
||||
$response = $this->queryAPI($this->apiUrl . "contact/v3/departments?parent_department_id={$departmentID}" . ($pageToken ? "&page_token={$pageToken}" : '') . "&fetch_child=true&page_size=50", '', array(CURLOPT_CUSTOMREQUEST => "GET"));
|
||||
if(isset($response->data->items))
|
||||
{
|
||||
foreach($response->data->items as $key => $dept)
|
||||
{
|
||||
$depts[$index]['id'] = $dept->open_department_id;
|
||||
$depts[$index]['pId'] = empty($dept->parent_department_id) ? 1 : $dept->parent_department_id;
|
||||
$depts[$index]['name'] = $dept->name;
|
||||
$depts[$index]['open'] = 1;
|
||||
$index++;
|
||||
$data[$index]['id'] = $dept->open_department_id;
|
||||
$data[$index]['pId'] = empty($dept->parent_department_id) ? 1 : $dept->parent_department_id;
|
||||
$data[$index]['name'] = $dept->name;
|
||||
$data[$index]['open'] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -181,10 +175,129 @@ class feishuapi
|
||||
$pageToken = $response->data->page_token;
|
||||
}
|
||||
|
||||
$depts['data'] = $data;
|
||||
return $depts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the first tier department.
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getDeptTree()
|
||||
{
|
||||
$depts = array('data' => array());
|
||||
|
||||
/* Gets the enterprise name. */
|
||||
$response = $this->queryAPI($this->apiUrl . "tenant/v2/tenant/query", '', array(CURLOPT_CUSTOMREQUEST => "GET"));
|
||||
$company = array('id' => '1', 'pId' => '0', 'name' => $response->data->tenant->name, 'open' => 1);
|
||||
$depts = array($company);
|
||||
|
||||
$departmentIdList = $this->getScopes();
|
||||
|
||||
$urls = array();
|
||||
foreach($departmentIdList as $departmentID) $urls[] = $this->apiUrl . "contact/v3/departments/{$departmentID}";
|
||||
$datas = $this->multiRequest($urls);
|
||||
|
||||
foreach($datas as $index => $dept)
|
||||
{
|
||||
$index += 1;
|
||||
$dept = json_decode($dept);
|
||||
|
||||
$memberCount = $dept->data->department->member_count;
|
||||
$status = $dept->data->department->status->is_deleted;
|
||||
|
||||
$depts[$index]['id'] = $dept->data->department->open_department_id;
|
||||
$depts[$index]['pId'] = empty($dept->data->department->parent_department_id) ? 1 : $dept->data->department->parent_department_id;
|
||||
$depts[$index]['name'] = $dept->data->department->name;
|
||||
$depts[$index]['open'] = 1;
|
||||
}
|
||||
|
||||
return $depts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the visible range of the application.
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getScopes()
|
||||
{
|
||||
$pageToken = '';
|
||||
$departmentIdList = array();
|
||||
|
||||
while(true)
|
||||
{
|
||||
$response = $this->queryAPI($this->apiUrl . "contact/v3/scopes" . "?user_id_type=open_id&department_id_type=open_department_id&page_token={$pageToken}&page_size=100", '', array(CURLOPT_CUSTOMREQUEST => "GET"));
|
||||
$departmentIds = isset($response->data->department_ids) ? $response->data->department_ids : array();
|
||||
foreach($departmentIds as $id) $departmentIdList[] = $id;
|
||||
|
||||
if(!isset($response->data->page_token)) break;
|
||||
$pageToken = $response->data->page_token;
|
||||
}
|
||||
|
||||
return $departmentIdList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the concurrency of requests.
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function multiRequest($urls)
|
||||
{
|
||||
$curl = curl_multi_init();
|
||||
$urlHandlers = array();
|
||||
$urlData = array();
|
||||
|
||||
/* Set request header information. */
|
||||
$headers = array();
|
||||
$headers[] = "Content-Type: application/json";
|
||||
if($this->token) $headers[] = "Authorization:Bearer {$this->token}";
|
||||
|
||||
/* Initialize multiple request handles to one. */
|
||||
foreach($urls as $url)
|
||||
{
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
|
||||
|
||||
$urlHandlers[] = $ch;
|
||||
curl_multi_add_handle($curl, $ch);
|
||||
}
|
||||
|
||||
$active = null;
|
||||
do
|
||||
{
|
||||
$mrc = curl_multi_exec($curl, $active);
|
||||
}
|
||||
while($mrc == CURLM_CALL_MULTI_PERFORM);
|
||||
|
||||
while($active && $mrc == CURLM_OK)
|
||||
{
|
||||
usleep(50000);
|
||||
if(curl_multi_select($curl) != -1)
|
||||
{
|
||||
do
|
||||
{
|
||||
$mrc = curl_multi_exec($curl, $active);
|
||||
}
|
||||
while($mrc == CURLM_CALL_MULTI_PERFORM);
|
||||
}
|
||||
}
|
||||
|
||||
foreach($urlHandlers as $index => $ch)
|
||||
{
|
||||
$urlData[$index] = curl_multi_getcontent($ch);
|
||||
curl_multi_remove_handle($curl, $ch);
|
||||
}
|
||||
curl_multi_close($curl);
|
||||
return $urlData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send message
|
||||
*
|
||||
|
||||
@@ -291,12 +291,7 @@ class webhook extends control
|
||||
$response = $dingapi->getDeptTree();
|
||||
}
|
||||
|
||||
if($webhook->type == 'feishuuser')
|
||||
{
|
||||
$this->app->loadClass('feishuapi', true);
|
||||
$feishuApi = new feishuapi($webhook->secret->appId, $webhook->secret->appSecret);
|
||||
$response = $feishuApi->getDeptTree();
|
||||
}
|
||||
if($webhook->type == 'feishuuser') $response = array('result' => 'success', 'data' => array());
|
||||
|
||||
if($response['result'] == 'fail')
|
||||
{
|
||||
@@ -315,11 +310,34 @@ class webhook extends control
|
||||
$this->view->title = $this->lang->webhook->chooseDept;
|
||||
$this->view->position[] = $this->lang->webhook->chooseDept;
|
||||
|
||||
$this->view->deptTree = $response['data'];
|
||||
$this->view->webhookID = $id;
|
||||
$this->view->webhookType = $webhook->type;
|
||||
$this->view->deptTree = $response['data'];
|
||||
$this->view->webhookID = $id;
|
||||
$this->display();
|
||||
}
|
||||
|
||||
public function ajaxGetFeishuDeptList($webhookID)
|
||||
{
|
||||
$webhook = $this->webhook->getById($webhookID);
|
||||
$webhook->secret = json_decode($webhook->secret);
|
||||
|
||||
if($_POST)
|
||||
{
|
||||
$this->app->loadClass('feishuapi', true);
|
||||
$feishuApi = new feishuapi($webhook->secret->appId, $webhook->secret->appSecret);
|
||||
$departmentID = $_POST['departmentID'] ? $_POST['departmentID'] : '';
|
||||
$depts = $feishuApi->getChildDeptTree($departmentID);
|
||||
echo json_encode($depts, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->app->loadClass('feishuapi', true);
|
||||
$feishuApi = new feishuapi($webhook->secret->appId, $webhook->secret->appSecret);
|
||||
$depts = $feishuApi->getDeptTree();
|
||||
echo json_encode($depts, true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Send data by async.
|
||||
*
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
#notice {margin-bottom: 0px;}
|
||||
#deptList {padding: 15px 0px;}
|
||||
@@ -104,6 +104,7 @@ $lang->webhook->note->typeList['dingding'] = 'Add a customized bot in dingding
|
||||
$lang->webhook->note->typeList['weixin'] = 'Add a customized bot in WeChat and get the webhook url.';
|
||||
$lang->webhook->note->typeList['default'] = 'Get a webhook url from others';
|
||||
|
||||
$lang->webhook->error = new stdclass();
|
||||
$lang->webhook->error->curl = 'Load php-curl in php.ini.';
|
||||
$lang->webhook->error->noDept = 'There is no department selected. Please choose department first.';
|
||||
$lang->webhook->error = new stdclass();
|
||||
$lang->webhook->error->curl = 'Load php-curl in php.ini.';
|
||||
$lang->webhook->error->noDept = 'There is no department selected. Please choose department first.';
|
||||
$lang->webhook->error->requestError = 'Request error!';
|
||||
|
||||
@@ -87,6 +87,7 @@ $lang->webhook->paramsList['comment'] = '备注';
|
||||
$lang->webhook->paramsList['text'] = '操作内容';
|
||||
|
||||
$lang->webhook->confirmDelete = '您确认要删除该webhook吗?';
|
||||
$lang->webhook->loadPrompt = '友情提示:当部门数据较多时,数据加载可能需要较多时间;本列表优先展示一级部门数据,您可以通过点击一级部门标题,自动加载出该部门下的子部门数。';
|
||||
|
||||
$lang->webhook->trimWords = '了';
|
||||
|
||||
@@ -104,6 +105,7 @@ $lang->webhook->note->typeList['dingding'] = '请在钉钉中添加一个自定
|
||||
$lang->webhook->note->typeList['weixin'] = '请在企业微信中添加一个自定义机器人,并将其webhook填写到此处。';
|
||||
$lang->webhook->note->typeList['default'] = '从第三方系统获取webhook并填写到此处。';
|
||||
|
||||
$lang->webhook->error = new stdclass();
|
||||
$lang->webhook->error->curl = '需要加载php-curl扩展。';
|
||||
$lang->webhook->error->noDept = '没有选择部门,请先选择同步部门。';
|
||||
$lang->webhook->error = new stdclass();
|
||||
$lang->webhook->error->curl = '需要加载php-curl扩展。';
|
||||
$lang->webhook->error->noDept = '没有选择部门,请先选择同步部门。';
|
||||
$lang->webhook->error->requestError = '请求错误!';
|
||||
|
||||
@@ -17,6 +17,11 @@
|
||||
<div class='main-header'>
|
||||
<h2><?php echo $lang->webhook->chooseDept?></h2>
|
||||
</div>
|
||||
<?php if($webhookType == 'feishuuser'):?>
|
||||
<div id="notice" class="alert alert-info">
|
||||
<div class="content"><i class="icon-exclamation-sign"></i> <?php echo $lang->webhook->loadPrompt;?></div>
|
||||
</div>
|
||||
<?php endif;?>
|
||||
<ul id='deptList' class="ztree"></ul>
|
||||
<div class='actions'>
|
||||
<?php echo html::commonButton($lang->save, '', 'btn btn-primary save');?>
|
||||
@@ -25,27 +30,143 @@
|
||||
</div>
|
||||
</div>
|
||||
<?php js::set('deptTree', $deptTree);?>
|
||||
<?php js::set('webhookType', $webhookType);?>
|
||||
<?php js::set('webhookID', $webhookID);?>
|
||||
<?php js::set('requestError', $lang->webhook->error->requestError);?>
|
||||
<?php js::set('feishuUrl', $this->createLink('webhook', 'ajaxGetFeishuDeptList', array('webhookID' => $webhookID)));?>
|
||||
<script>
|
||||
$(function()
|
||||
{
|
||||
var ztreeSettings =
|
||||
if(webhookType == 'feishuuser')
|
||||
{
|
||||
view:
|
||||
var setting =
|
||||
{
|
||||
showIcon: false
|
||||
},
|
||||
check:
|
||||
view:
|
||||
{
|
||||
showIcon: false,
|
||||
dblClickExpand: false,
|
||||
},
|
||||
check:
|
||||
{
|
||||
enable: true,
|
||||
chkStyle: "checkbox",
|
||||
chkboxType: {"Y" : "s", "N" : "s"}
|
||||
},
|
||||
data:
|
||||
{
|
||||
simpleData: {enable: true}
|
||||
},
|
||||
async:
|
||||
{
|
||||
enable: true,
|
||||
url: feishuUrl,
|
||||
autoParam:["id", "name=name"],
|
||||
type: 'get',
|
||||
dataFilter: filter
|
||||
},
|
||||
callback:
|
||||
{
|
||||
beforeClick: beforeClick,
|
||||
beforeAsync: beforeAsync,
|
||||
onClick: ztreeOnAsyncSuccess
|
||||
}
|
||||
};
|
||||
|
||||
function filter(treeId, parentNode, childNodes)
|
||||
{
|
||||
enable: true,
|
||||
chkStyle: "checkbox",
|
||||
chkboxType: {"Y":"s", "N":"s"}
|
||||
},
|
||||
data:
|
||||
{
|
||||
simpleData: {enable: true}
|
||||
if(!childNodes) return null;
|
||||
for(var i = 0, l = childNodes.length; i < l; i++)
|
||||
{
|
||||
childNodes[i].name = childNodes[i].name.replace(/\.n/g, '.');
|
||||
}
|
||||
return childNodes;
|
||||
}
|
||||
};
|
||||
ztreeObj = $.fn.zTree.init($("#deptList"), ztreeSettings, deptTree);
|
||||
|
||||
function beforeClick(treeId, treeNode)
|
||||
{
|
||||
if(treeNode.isParent)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
function beforeAsync(treeId, treeNode)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
function ztreeOnAsyncSuccess(event, treeId, treeNode)
|
||||
{
|
||||
if(treeNode == undefined)
|
||||
{
|
||||
departmentID = "0";
|
||||
}
|
||||
else
|
||||
{
|
||||
departmentID = treeNode.id;
|
||||
}
|
||||
var url = createLink('webhook', 'ajaxGetFeishuDeptList', 'webhookID=' + webhookID);
|
||||
|
||||
$.ajax(
|
||||
{
|
||||
type: "post",
|
||||
url: url,
|
||||
data: {departmentID: departmentID},
|
||||
dataType: "json",
|
||||
async: true,
|
||||
success: function(jsonData)
|
||||
{
|
||||
if(jsonData != null)
|
||||
{
|
||||
var data = jsonData;
|
||||
if(data != null && data.length != 0)
|
||||
{
|
||||
if(treeNode == undefined)
|
||||
{
|
||||
ztreeObj.addNodes(null, data, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
ztreeObj.addNodes(treeNode, data, true);
|
||||
}
|
||||
}
|
||||
ztreeObj.expandNode(treeNode, true, false, false);
|
||||
}
|
||||
},
|
||||
error: function()
|
||||
{
|
||||
alert(requestError);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
var ztreeObj = $.fn.zTree.init($("#deptList"), setting);
|
||||
}
|
||||
else
|
||||
{
|
||||
var ztreeSettings =
|
||||
{
|
||||
view:
|
||||
{
|
||||
showIcon: false
|
||||
},
|
||||
check:
|
||||
{
|
||||
enable: true,
|
||||
chkStyle: "checkbox",
|
||||
chkboxType: {"Y":"s", "N":"s"}
|
||||
},
|
||||
data:
|
||||
{
|
||||
simpleData: {enable: true}
|
||||
}
|
||||
};
|
||||
ztreeObj = $.fn.zTree.init($("#deptList"), ztreeSettings, deptTree);
|
||||
}
|
||||
|
||||
$('.actions .save').click(function()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user