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