DingtalkService.php 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. <?php
  2. namespace app\common\service;
  3. use app\common\constant\CommonConstant;
  4. use app\common\model\Department;
  5. use app\common\model\User;
  6. use app\extend\Dingtalk\Sample;
  7. use think\Db;
  8. use think\Exception;
  9. /**
  10. * 钉钉服务类
  11. */
  12. class DingtalkService
  13. {
  14. public static function get_obj()
  15. {
  16. require_once env('root_path') . '/vendor/dingapi/TopSdk.php';
  17. date_default_timezone_set('Asia/Shanghai');
  18. $c = new \DingTalkClient(\DingTalkConstant::$CALL_TYPE_OAPI, \DingTalkConstant::$METHOD_POST, \DingTalkConstant::$FORMAT_JSON);
  19. return $c;
  20. }
  21. /**
  22. * 通过免登码获取用户信息
  23. *
  24. * @param string $code 免登授权码
  25. * @return mixed
  26. */
  27. public static function get_user_info($code)
  28. {
  29. $accessToken = Sample::accessToken()['accessToken'];
  30. $c = self::get_obj();
  31. $req = new \OapiV2UserGetuserinfoRequest;
  32. $req->setCode($code);
  33. $resp = $c->execute($req, $accessToken, "https://oapi.dingtalk.com/topapi/v2/user/getuserinfo");
  34. if ($resp->errcode == 0 && $resp->errmsg == 'ok') {
  35. $result = $resp->result;
  36. return $result;
  37. }
  38. except($resp->errcode . ' ' . $resp->errmsg);
  39. }
  40. /**
  41. * 设置企业内部应用H5微应用鉴权
  42. *
  43. * @param string $url 应用URL,例如:https://your-domain.com/path/to/your/app.html
  44. * @return mixed
  45. **/
  46. public static function generateAuthSignature($url)
  47. {
  48. // 获取jsapiTicket
  49. $jsapiTicket = Sample::jsapiTickets()['jsapiTicket'];
  50. // 生成鉴权签名
  51. $nonceStr = randCode(16); // 随机字符串,用于保证签名不可预测性,长度为16个字符的随机字符串
  52. $timeStamp = time(); // 时间戳,格式为13位数字,如:1602756290
  53. $stringA = "jsapi_ticket=$jsapiTicket&noncestr=$nonceStr&timestamp=$timeStamp&url=$url";
  54. $signature = sha1($stringA); // 签名值
  55. // agentId值
  56. // corpId值
  57. $config = config('app.dingtalk');
  58. $agentId = $config['agentId'];
  59. $corpId = $config['corpId'];
  60. return compact("agentId", "corpId", "nonceStr", "timeStamp", "signature", "url");
  61. }
  62. /**
  63. * 更新员工和部门
  64. *
  65. * @return bool
  66. * [{"dept_id":438337214,"name":"BOSS","parent_id":1},{"dept_id":438145402,"name":"项目管理中心","parent_id":1},{"dept_id":501674219,"name":"技术部","parent_id":438145402},{"dept_id":500773946,"name":"项目一组","parent_id":501674219},{"dept_id":501193520,"name":"项目二组","parent_id":501674219},{"dept_id":731200005,"name":"Ui测试组","parent_id":501674219},{"dept_id":501415496,"name":"销售部","parent_id":438145402},{"dept_id":859178110,"name":"运营部","parent_id":438145402},{"dept_id":724339668,"name":"职能支持中心","parent_id":1},{"dept_id":438218445,"name":"人力资源部","parent_id":724339668},{"dept_id":702458745,"name":"财务部","parent_id":724339668}]
  67. **/
  68. public static function renew()
  69. {
  70. $save_department_data = [];
  71. $add_department_data = [];
  72. $del_department_data = [];
  73. $department_user_data = [];
  74. $user_data = [];
  75. $save_user_data = [];
  76. $add_user_data = [];
  77. $del_user_data = [];
  78. $department_data = self::get_tree(1);
  79. $department_data_key = array_column($department_data, null, 'dept_id');
  80. $department_list = Department::field('is_deleted', true)
  81. ->where('is_deleted', CommonConstant::IS_DELETED_0)
  82. ->select();
  83. $department_key = array_column($department_list->toArray(), null, 'dept_id');
  84. foreach ($department_data as $value) {
  85. if (array_key_exists($value['dept_id'], $department_key)) {
  86. $save_department_data[] = $value;
  87. } else {
  88. $add_department_data[] = $value;
  89. }
  90. $user_list = self::user_list($value['dept_id']);
  91. if ($user_list->list) {
  92. $department_user_data[$value['dept_id']] = $user_list->list;
  93. }
  94. }
  95. foreach ($department_user_data as $value) {
  96. foreach ($value as $val) {
  97. $user_data[] = (array)$val;
  98. }
  99. }
  100. $user_data_key = array_column($user_data, null, 'userid');
  101. $user_list = User::field('is_deleted', true)
  102. ->where('is_deleted', CommonConstant::IS_DELETED_0)
  103. ->select();
  104. $user_key = array_column($user_list->toArray(), null, 'userid');
  105. Db::startTrans();
  106. try {
  107. // 更新部门
  108. foreach ($department_list as $val) {
  109. if (array_key_exists($val['dept_id'], $department_data_key)) {
  110. $department_data_info = $department_data_key[$val['dept_id']];
  111. $val->save($department_data_info);
  112. } else {
  113. $del_department_data[] = $val['id'];
  114. }
  115. }
  116. if ($add_department_data) {
  117. Department::insertAll($add_department_data);
  118. }
  119. if ($del_department_data) {
  120. Department::where('id', 'in', $del_department_data)->update(['is_deleted' => CommonConstant::IS_DELETED_1]);
  121. }
  122. // 更新员工
  123. foreach ($user_data as $value) {
  124. if (array_key_exists($value['userid'], $user_key)) {
  125. $save_user_data[] = $value;
  126. } else {
  127. $data = [
  128. 'userid' => $value['userid'],
  129. 'unionid' => $value['unionid'],
  130. 'name' => $value['name'],
  131. 'avatar' => $value['avatar'],
  132. 'mobile' => isset($value['mobile']) ? $value['mobile'] : '',
  133. 'title' => isset($value['title']) ? $value['title'] : '',
  134. 'manager_userid' => isset($value['manager_userid']) ? $value['manager_userid'] : '',
  135. 'department' => implode(',', $value['dept_id_list']),
  136. ];
  137. $add_user_data[] = $data;
  138. }
  139. }
  140. foreach ($user_list as $val) {
  141. if (array_key_exists($val['userid'], $user_data_key)) {
  142. $user_data_info = $user_data_key[$val['userid']];
  143. $data = [
  144. 'userid' => $user_data_info['userid'],
  145. 'unionid' => $user_data_info['unionid'],
  146. 'department' => implode(',', $user_data_info['dept_id_list']),
  147. ];
  148. $val->save($data);
  149. } else {
  150. $del_user_data[] = $val['id'];
  151. }
  152. }
  153. if ($add_user_data) {
  154. User::insertAll($add_user_data);
  155. }
  156. if ($del_user_data) {
  157. User::where('id', 'in', $del_user_data)->update(['is_deleted' => CommonConstant::IS_DELETED_1]);
  158. }
  159. Db::commit();
  160. } catch (Exception $e) {
  161. Db::rollback();
  162. except('出现错误:' . $e->getMessage() .'|'. $e->getFile() .'|'. $e->getLine());
  163. }
  164. return true;
  165. }
  166. /**
  167. * 递归
  168. **/
  169. public static function get_tree($dept_id, &$tree = [])
  170. {
  171. $resp = self::department_listsub($dept_id);
  172. foreach ($resp as $value) {
  173. $tree[] = [
  174. 'dept_id' => $value->dept_id,
  175. 'name' => $value->name,
  176. 'parent_id' => $value->parent_id,
  177. ];
  178. self::get_tree($value->dept_id, $tree);
  179. }
  180. return $tree;
  181. }
  182. /**
  183. * 获取部门列表
  184. *
  185. * @param string $dept_id 父部门ID
  186. * @return mixed
  187. */
  188. public static function department_listsub($dept_id)
  189. {
  190. $accessToken = Sample::accessToken()['accessToken'];
  191. $c = self::get_obj();
  192. $req = new \OapiV2DepartmentListsubRequest;
  193. $req->setDeptId($dept_id);
  194. $resp = $c->execute($req, $accessToken, "https://oapi.dingtalk.com/topapi/v2/department/listsub");
  195. if ($resp->errcode == 0 && $resp->errmsg == 'ok') {
  196. $result = $resp->result;
  197. return $result;
  198. }
  199. except($resp->errcode . ' ' . $resp->errmsg);
  200. }
  201. /**
  202. * 获取部门详情
  203. *
  204. * @param string $dept_id 部门ID
  205. * @return mixed
  206. */
  207. public static function department_get($dept_id)
  208. {
  209. $accessToken = Sample::accessToken()['accessToken'];
  210. $c = self::get_obj();
  211. $req = new \OapiV2DepartmentListsubRequest;
  212. $req->setDeptId($dept_id);
  213. $resp = $c->execute($req, $accessToken, "https://oapi.dingtalk.com/topapi/v2/department/get");
  214. if ($resp->errcode == 0 && $resp->errmsg == 'ok') {
  215. $result = $resp->result;
  216. return $result;
  217. }
  218. except($resp->errcode . ' ' . $resp->errmsg);
  219. }
  220. /**
  221. * 获取部门用户详情
  222. *
  223. * @param string $dept_id 部门ID
  224. * @return mixed
  225. */
  226. public static function user_list($dept_id)
  227. {
  228. $accessToken = Sample::accessToken()['accessToken'];
  229. $c = self::get_obj();
  230. $req = new \OapiV2UserListRequest;
  231. $req->setDeptId($dept_id);
  232. $req->setCursor("0");
  233. $req->setSize("100");
  234. $resp = $c->execute($req, $accessToken, "https://oapi.dingtalk.com/topapi/v2/user/list");
  235. if ($resp->errcode == 0 && $resp->errmsg == 'ok') {
  236. $result = $resp->result;
  237. return $result;
  238. }
  239. except($resp->errcode . ' ' . $resp->errmsg);
  240. }
  241. /**
  242. * 查询用户详情
  243. *
  244. * @param string $userid 用户的userId
  245. * @return mixed
  246. */
  247. public static function user_get($userid)
  248. {
  249. $accessToken = Sample::accessToken()['accessToken'];
  250. $c = self::get_obj();
  251. $req = new \OapiV2UserGetRequest;
  252. $req->setUserid($userid);
  253. $resp = $c->execute($req, $accessToken, "https://oapi.dingtalk.com/topapi/v2/user/get");
  254. if ($resp->errcode == 0 && $resp->errmsg == 'ok') {
  255. $result = $resp->result;
  256. return $result;
  257. }
  258. except($resp->errcode . ' ' . $resp->errmsg);
  259. }
  260. }