DingtalkService.php 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  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. if ($save_department_data) {
  109. foreach ($department_list as $val) {
  110. if (array_key_exists($val['dept_id'], $department_data_key)) {
  111. $department_data_info = $department_data_key[$val['dept_id']];
  112. $val->save($department_data_info);
  113. } else {
  114. $del_department_data[] = $val['id'];
  115. }
  116. }
  117. }
  118. if ($add_department_data) {
  119. Department::insertAll($add_department_data);
  120. }
  121. if ($del_department_data) {
  122. Department::where('id', 'in', $del_department_data)->update(['is_deleted' => CommonConstant::IS_DELETED_1]);
  123. }
  124. // 更新员工
  125. foreach ($user_data as $value) {
  126. if (array_key_exists($value['userid'], $user_key)) {
  127. $save_user_data[] = $value;
  128. } else {
  129. $data = [
  130. 'userid' => $value['userid'],
  131. 'unionid' => $value['unionid'],
  132. 'name' => $value['name'],
  133. 'avatar' => $value['avatar'],
  134. 'mobile' => isset($value['mobile']) ? $value['mobile'] : '',
  135. 'title' => isset($value['title']) ? $value['title'] : '',
  136. 'manager_userid' => isset($value['manager_userid']) ? $value['manager_userid'] : '',
  137. 'department' => implode(',', $value['dept_id_list']),
  138. ];
  139. $add_user_data[] = $data;
  140. }
  141. }
  142. if ($save_user_data) {
  143. foreach ($user_list as $val) {
  144. if (array_key_exists($val['userid'], $user_data_key)) {
  145. $user_data_info = $user_data_key[$val['userid']];
  146. $data = [
  147. 'userid' => $user_data_info['userid'],
  148. 'unionid' => $user_data_info['unionid'],
  149. 'department' => implode(',', $user_data_info['dept_id_list']),
  150. ];
  151. $val->save($data);
  152. } else {
  153. $del_user_data[] = $val['id'];
  154. }
  155. }
  156. }
  157. if ($add_user_data) {
  158. User::insertAll($add_user_data);
  159. }
  160. if ($del_user_data) {
  161. User::where('id', 'in', $del_user_data)->update(['is_deleted' => CommonConstant::IS_DELETED_1]);
  162. }
  163. Db::commit();
  164. } catch (Exception $e) {
  165. Db::rollback();
  166. except('出现错误:' . $e->getMessage() .'|'. $e->getFile() .'|'. $e->getLine());
  167. }
  168. return true;
  169. }
  170. /**
  171. * 递归
  172. **/
  173. public static function get_tree($dept_id, &$tree = [])
  174. {
  175. $resp = self::department_listsub($dept_id);
  176. foreach ($resp as $value) {
  177. $tree[] = [
  178. 'dept_id' => $value->dept_id,
  179. 'name' => $value->name,
  180. 'parent_id' => $value->parent_id,
  181. ];
  182. self::get_tree($value->dept_id, $tree);
  183. }
  184. return $tree;
  185. }
  186. /**
  187. * 获取部门列表
  188. *
  189. * @param string $dept_id 父部门ID
  190. * @return mixed
  191. */
  192. public static function department_listsub($dept_id)
  193. {
  194. $accessToken = Sample::accessToken()['accessToken'];
  195. $c = self::get_obj();
  196. $req = new \OapiV2DepartmentListsubRequest;
  197. $req->setDeptId($dept_id);
  198. $resp = $c->execute($req, $accessToken, "https://oapi.dingtalk.com/topapi/v2/department/listsub");
  199. if ($resp->errcode == 0 && $resp->errmsg == 'ok') {
  200. $result = $resp->result;
  201. return $result;
  202. }
  203. except($resp->errcode . ' ' . $resp->errmsg);
  204. }
  205. /**
  206. * 获取部门详情
  207. *
  208. * @param string $dept_id 部门ID
  209. * @return mixed
  210. */
  211. public static function department_get($dept_id)
  212. {
  213. $accessToken = Sample::accessToken()['accessToken'];
  214. $c = self::get_obj();
  215. $req = new \OapiV2DepartmentListsubRequest;
  216. $req->setDeptId($dept_id);
  217. $resp = $c->execute($req, $accessToken, "https://oapi.dingtalk.com/topapi/v2/department/get");
  218. if ($resp->errcode == 0 && $resp->errmsg == 'ok') {
  219. $result = $resp->result;
  220. return $result;
  221. }
  222. except($resp->errcode . ' ' . $resp->errmsg);
  223. }
  224. /**
  225. * 获取部门用户详情
  226. *
  227. * @param string $dept_id 部门ID
  228. * @return mixed
  229. */
  230. public static function user_list($dept_id)
  231. {
  232. $accessToken = Sample::accessToken()['accessToken'];
  233. $c = self::get_obj();
  234. $req = new \OapiV2UserListRequest;
  235. $req->setDeptId($dept_id);
  236. $req->setCursor("0");
  237. $req->setSize("100");
  238. $resp = $c->execute($req, $accessToken, "https://oapi.dingtalk.com/topapi/v2/user/list");
  239. if ($resp->errcode == 0 && $resp->errmsg == 'ok') {
  240. $result = $resp->result;
  241. return $result;
  242. }
  243. except($resp->errcode . ' ' . $resp->errmsg);
  244. }
  245. /**
  246. * 查询用户详情
  247. *
  248. * @param string $userid 用户的userId
  249. * @return mixed
  250. */
  251. public static function user_get($userid)
  252. {
  253. $accessToken = Sample::accessToken()['accessToken'];
  254. $c = self::get_obj();
  255. $req = new \OapiV2UserGetRequest;
  256. $req->setUserid($userid);
  257. $resp = $c->execute($req, $accessToken, "https://oapi.dingtalk.com/topapi/v2/user/get");
  258. if ($resp->errcode == 0 && $resp->errmsg == 'ok') {
  259. $result = $resp->result;
  260. return $result;
  261. }
  262. except($resp->errcode . ' ' . $resp->errmsg);
  263. }
  264. }