Users.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  1. <?php
  2. namespace app\api\controller;
  3. use app\event\Msg;
  4. use app\logics\EmployeeLogic;
  5. use app\logics\OrgLogic;
  6. use app\model\Company;
  7. use app\model\CustomerClue;
  8. use app\model\Employee;
  9. use app\model\Miniprogram;
  10. use app\model\User as ModelUser;
  11. use app\model\Wechat;
  12. use Firebase\JWT\JWT;
  13. use openssl\Aes;
  14. use wx\miniprogram\User as MiniprogramUser;
  15. class Users extends Base
  16. {
  17. /**
  18. * 用户登陆
  19. * @return json [code:状态,token:jwt_token, exist:是否已注册]
  20. */
  21. public function code2session($code)
  22. {
  23. // 小程序类型获取
  24. $miniType = $this->request->param('client_type');
  25. // 查找小程序根部门
  26. if (!empty($miniType)) {
  27. $miniprogram = Miniprogram::where([['notify', '=', $miniType]])->findOrEmpty();
  28. $rootOrg = $miniprogram->root_id;
  29. $miniprogramId = Company::where('root_id', $rootOrg)->value('mini');
  30. $miniprogram = Wechat::findOrEmpty($miniprogramId);
  31. } else {
  32. $defaultRootOrg = Miniprogram::where([['notify', '=', config('app.cgi')]])->value('root_id');
  33. if (empty($client)) {
  34. $miniprogram = Wechat::findOrEmpty(1);
  35. } else {
  36. $miniprogram = Wechat::where('appid', $client)->findOrEmpty();
  37. }
  38. }
  39. if ($miniprogram->isEmpty()) return json(['code' => self::error_msg, 'msg' => '未授权的小程序']);
  40. // code获取用户信息
  41. $rs = (new MiniprogramUser())->code2session($miniprogram->appid, $miniprogram->secret, $code);
  42. if (isset($rs['errcode']) && $rs['errcode'] != 0) {
  43. return json(['code' => self::error_debug_msg, 'msg' => $rs['errmsg']]);
  44. }
  45. // 初始token
  46. $token = [
  47. 'openid' => $rs['openid'],
  48. 'session_key' => $rs['session_key'],
  49. 'client_type' => $miniType,
  50. 'isEmployee' => false,
  51. 'mini' => $miniprogram->id
  52. ];
  53. $multi = ModelUser::whereOr([['unionid', '=', $rs['unionid']], ['mini_openid', '=', $rs['openid']]])->count(); // 查询用户数量
  54. if ($multi == 1) {
  55. $user = ModelUser::whereOr([['unionid', '=', $rs['unionid']], ['mini_openid', '=', $rs['openid']]])->find();
  56. if (!empty($rootOrg) && $user->root_id != $rootOrg) $user = null;
  57. } elseif ($multi > 1) {
  58. if (!empty($rootOrg)) {
  59. $user = ModelUser::whereOr([[['unionid', '=', $rs['unionid']], ['root_id', '=', $rootOrg]], [['mini_openid', '=', $rs['openid']], ['root_id', '=', $rootOrg]]])->find();
  60. } else {
  61. // 查询用户最后进入记录
  62. $user = ModelUser::whereOr([['unionid', '=', $rs['unionid']], ['mini_openid', '=', $rs['openid']]])->order('updatetime desc')->find();
  63. }
  64. }
  65. if (empty($user)) {
  66. $data = [
  67. 'mini_openid' => $rs['openid'],
  68. 'unionid' => $rs['unionid'],
  69. 'root_id' => $rootOrg ?? $defaultRootOrg,
  70. 'updatetime' => date('Y-m-d H:i:s')
  71. ];
  72. $user = ModelUser::create($data);
  73. } else {
  74. $user->updatetime = date('Y-m-d H:i:s');
  75. if (empty($user->unionid)) $user->unionid = $rs['unionid'];
  76. $user->mini_openid = $rs['openid'];
  77. $user->save();
  78. }
  79. $rootOrg = $user->root_id;
  80. $token['root_org'] = $rootOrg;
  81. $token['client_type'] = Miniprogram::where(['root_id' => $rootOrg])->value('notify');
  82. $token['uid'] = $user->id;
  83. $userData = $user->visible(['id', 'nickname', 'headimgurl', 'sex', 'subscribe', 'phone'])->toArray();
  84. $employee = Employee::where([['uid', '=', $user->id], ['state', 'in', ['在职', '待审核']]])->find();
  85. if ($employee) {
  86. $employee->save(['updatetime' => date('Y-m-d H:i:s')]);
  87. if ($employee->disable == 0) {
  88. $userData['binded'] = [
  89. 'id' => $employee->id,
  90. 'name' => $employee->name,
  91. 'org_name' => $employee->org->name,
  92. 'org_id' => $employee->org_id,
  93. 'isManager' => $employee->is_manager,
  94. 'isNewbie' => $employee->is_newbie,
  95. 'state' => $employee->state,
  96. 'qrcode' => $employee->qrcode
  97. ];
  98. }
  99. $token['isEmployee'] = true;
  100. $token['employee_id'] = $employee->id;
  101. $token['org_id'] = $employee->org_id;
  102. }
  103. $shareuser = null;
  104. $share = $this->request->param('share');
  105. $share_agent_id = $this->request->param('share_agent_id'); //通过经纪人分享打开的
  106. $share_agent_id = isset($share_agent_id)&&!empty($share_agent_id) ? $share_agent_id : 0;
  107. if ($share && !$token['isEmployee']) {
  108. $shareuser = ModelUser::where(['id' => $share, 'root_id' => $rootOrg])->field('id,nickname,headimgurl,phone')->find();
  109. if ($shareuser) {
  110. $shareBind = Employee::where(['uid' => $shareuser->id])->find();
  111. if ($shareBind && $shareBind['state'] == '离职' && $shareBind['left_to_empid']) { // 如果分享人已离职
  112. $shareBind = Employee::where(['id' => $shareBind['left_to_empid']])->find();
  113. $shareuser = ModelUser::where('id', $shareBind->uid)->field('id,nickname,headimgurl,phone')->find();
  114. }
  115. $token['share'] = $shareuser->id;
  116. if ($shareBind && $shareBind['state'] == '在职') {
  117. $token['share_employee'] = $shareBind->id;
  118. $token['share_org'] = $shareBind->org_id;
  119. $token['share_agent_id'] = $share_agent_id; //经纪人分享的
  120. $shareuser['qrcode'] = $shareBind->qrcode;
  121. }
  122. if (!$token['isEmployee'] && !empty($user->nickname) && !empty($user->headimgurl)) {
  123. $this->addClue([
  124. 'uid' => $userData['id'],
  125. 'employee_id' => $token['share_employee'] ?? 0,
  126. 'org_id' => $token['share_org'] ?? $token['root_org'],
  127. 'agent_id' => $share_agent_id
  128. ], $token['root_org']);
  129. }
  130. }
  131. }
  132. $company = Company::where('root_id', $rootOrg)->find()->toArray();
  133. $company['client_type'] = $token['client_type'];
  134. // 信息加密
  135. $data = http_build_query($token);
  136. $aes = new Aes(config('app.jwt_key'));
  137. $key = $aes->encrypt($data);
  138. // token数据设置
  139. $payload = array(
  140. "iss" => "https://" . $this->request->domain(),
  141. "aud" => 'mini',
  142. "iat" => time(),
  143. "nbf" => time(),
  144. "data" => $key
  145. );
  146. // 自定义登陆状态
  147. $token = JWT::encode($payload, config('app.jwt_key'));
  148. $returnData = ['code' => self::success, 'token' => $token, 'user' => $userData, 'company' => $company['company_name'], 'company_data' => $company];
  149. empty($shareuser) ?: $returnData['share'] = $shareuser;
  150. return json($returnData);
  151. }
  152. private function addClue($data, $root_id)
  153. {
  154. // 如果线索是员工(包含运维,已离职,待审核)
  155. $isEmployee = Employee::where([['uid', '=', $data['uid']], ['root_id', '=', $root_id], ['state', 'in', ['在职', '待审核']]])->find();
  156. if ($isEmployee) return false;
  157. // 如果线索已经获取过,更新时间
  158. if ($data['employee_id'] == 0) { // 判断是否有员工已获取
  159. CustomerClue::where([['uid', '=', $data['uid']]])->update(['updatetime' => date('Y-m-d H:i:s')]);
  160. } else { // 判读是否重复获取
  161. $rs = CustomerClue::where([['uid', '=', $data['uid']], ['employee_id', '=', $data['employee_id']]])->update(['updatetime' => date('Y-m-d H:i:s')]);
  162. // 没有更新过,创建线索
  163. if (!$rs && $data['employee_id'] !== 0) {
  164. CustomerClue::create($data);
  165. }
  166. }
  167. }
  168. /**
  169. * 授权获取用户信息(客户小程序调用)
  170. */
  171. public function setUserInfo($encryptedData, $iv, $signature, $rawData)
  172. {
  173. $request = request();
  174. $token = $request->token;
  175. // 计算签名是否正确
  176. $sign = sha1($rawData . $token['session_key']);
  177. if ($sign != $signature) {
  178. return json(['code' => self::error_debug_msg, 'msg' => '签名验证失败']);
  179. }
  180. $miniprogram = Wechat::where([['id', '=', $token['mini']]])->find();
  181. // 解析获取用户数据
  182. $mini = new MiniprogramUser();
  183. $data = $mini->getInfo($miniprogram->appid, $token['session_key'], $encryptedData, $iv);
  184. $user = ModelUser::where([['mini_openid', '=', $request->token['openid']], ['root_id', '=', $token['root_org']]])->find();
  185. // 保存用户信息
  186. $user->save([
  187. 'city' => $data['city'],
  188. 'province' => $data['province'],
  189. 'country' => $data['country'],
  190. 'sex' => $data['gender'],
  191. 'nickname' => $data['nickName'],
  192. 'headimgurl' => $data['avatarUrl']
  193. ]);
  194. // 更新token
  195. if (!$token['isEmployee']) {
  196. // 添加客户线索
  197. $this->addClue([
  198. 'uid' => $token['uid'],
  199. 'employee_id' => $token['share_employee'] ?? 0,
  200. 'org_id' => $token['share_org'] ?? $token['root_org'],
  201. 'agent_id' => $token['share_agent_id'] ?? 0
  202. ], $token['root_org']);
  203. }
  204. return json(['code' => self::success, 'msg' => '信息保存成功']);
  205. }
  206. /**
  207. * 授权获取并保存用户手机号
  208. */
  209. public function setUserMobile($encryptedData, $iv)
  210. {
  211. $request = request();
  212. $miniprogram = Wechat::where([['id', '=', $request->token['mini']]])->find();
  213. $mini = new MiniprogramUser();
  214. $data = $mini->getInfo($miniprogram->appid, $request->token['session_key'], $encryptedData, $iv);
  215. $user = ModelUser::where([['mini_openid', '=', $request->token['openid']], ['root_id', '=', $request->token['root_org']]])->find();
  216. $user->save(['phone' => $data['phoneNumber']]);
  217. // 线索更新手机号
  218. if (!$request->token['isEmployee'] && !empty($request->token['share_employee'])) {
  219. CustomerClue::where([
  220. 'uid' => $request->token['uid'],
  221. 'employee_id' => $request->token['share_employee']
  222. ])->update(['phone' => $data['phoneNumber']]);
  223. }
  224. return json(['code' => self::success, 'msg' => '信息保存成功', 'mobile' => $data['phoneNumber']]);
  225. }
  226. /**
  227. * 员工注册
  228. */
  229. public function register()
  230. {
  231. $params = request()->param(['is_manager', 'name', 'orgid']);
  232. $result = EmployeeLogic::addemployee($params, $msg);
  233. if ($result) {
  234. $leader = Employee::where(['org_id' => $params['orgid'], 'is_manager' => 1])->column('id');
  235. event(new Msg($leader, '您接收到一条新审批,请点击前往审阅', 'register'));
  236. return json(['code' => 0, 'msg' => '成功提交', 'data' => $result]);
  237. } else {
  238. return json(['code' => 1, 'msg' => $msg]);
  239. }
  240. }
  241. /**
  242. * 组织结构
  243. */
  244. public function org()
  245. {
  246. $token = request()->token;
  247. $data = OrgLogic::struc($token['root_org']);
  248. return json(['code' => 0, 'data' => $data]);
  249. }
  250. }