MiniAppController.java 21KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564
  1. package com.huiju.estateagents.controller;
  2. import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
  3. import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;
  4. import cn.binarywang.wx.miniapp.bean.WxMaUserInfo;
  5. import com.alibaba.fastjson.JSON;
  6. import com.alibaba.fastjson.JSONObject;
  7. import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
  8. import com.huiju.estateagents.base.BaseController;
  9. import com.huiju.estateagents.base.ResponseBean;
  10. import com.huiju.estateagents.center.sysUser.service.ISysTokenService;
  11. import com.huiju.estateagents.center.taUser.entity.TaUser;
  12. import com.huiju.estateagents.center.taUser.service.ITaUserService;
  13. import com.huiju.estateagents.common.CommConstant;
  14. import com.huiju.estateagents.common.JWTUtils;
  15. import com.huiju.estateagents.common.StringUtils;
  16. import com.huiju.estateagents.drainage.entity.TaDrainage;
  17. import com.huiju.estateagents.drainage.service.ITaDrainageService;
  18. import com.huiju.estateagents.entity.*;
  19. import com.huiju.estateagents.event.EventBus;
  20. import com.huiju.estateagents.mapper.TaOrgCityMapper;
  21. import com.huiju.estateagents.mapper.TaSalesBatchMapper;
  22. import com.huiju.estateagents.property.model.TaUserVerify;
  23. import com.huiju.estateagents.property.service.ITaUserVerifyService;
  24. import com.huiju.estateagents.redpack.service.ITaMpMiniappService;
  25. import com.huiju.estateagents.service.*;
  26. import com.huiju.estateagents.third.service.ITaThirdPartyMiniappConfigService;
  27. import io.swagger.annotations.Api;
  28. import io.swagger.annotations.ApiOperation;
  29. import me.chanjar.weixin.common.error.WxErrorException;
  30. import org.apache.commons.collections.CollectionUtils;
  31. import org.apache.http.HttpStatus;
  32. import org.checkerframework.checker.units.qual.A;
  33. import org.slf4j.Logger;
  34. import org.slf4j.LoggerFactory;
  35. import org.springframework.beans.factory.annotation.Autowired;
  36. import org.springframework.context.ApplicationContext;
  37. import org.springframework.web.bind.annotation.*;
  38. import javax.annotation.Resource;
  39. import javax.servlet.http.HttpServletRequest;
  40. import java.lang.reflect.Array;
  41. import java.time.LocalDateTime;
  42. import java.util.HashMap;
  43. import java.util.List;
  44. import java.util.Map;
  45. import java.util.concurrent.ExecutorService;
  46. import java.util.concurrent.Executors;
  47. import java.util.stream.Collector;
  48. import java.util.stream.Collectors;
  49. import static com.sun.jmx.snmp.ThreadContext.contains;
  50. @RestController
  51. @RequestMapping("/api/wx")
  52. @Api(value = "微信登录相关", tags = "微信登录相关")
  53. public class MiniAppController extends BaseController {
  54. private Logger logger = LoggerFactory.getLogger(MiniAppController.class);
  55. @Autowired
  56. private ITaPersonService taPersonService;
  57. @Autowired
  58. private IMiniAppService miniAppService;
  59. @Autowired
  60. private ITaRecommendCustomerService taRecommendCustomerService;
  61. @Resource
  62. private ApplicationContext applicationContext;
  63. @Autowired
  64. private ITaOrgService taOrgService;
  65. @Autowired
  66. private ISysTokenService sysTokenService;
  67. @Autowired
  68. private ITaMiniappService taMiniappService;
  69. @Autowired
  70. private ITaSharePersonFromService taSharePersonFromService;
  71. @Autowired
  72. private ITaBuildingDynamicService buildingDynamicService;
  73. @Autowired
  74. private ITaNewsService newsService;
  75. @Autowired
  76. private ITaUserService userService;
  77. @Autowired
  78. private ITaPersonBuildingService personBuildingService;
  79. @Autowired
  80. public ITaThirdPartyMiniappConfigService iTaThirdPartyMiniappConfigService;
  81. @Autowired
  82. private ITaCustomImgService iTaCustomImgService;
  83. @Autowired
  84. public ITdPointsRulesService iTdPointsRulesService;
  85. @Autowired
  86. public ITaMiniappService iTaMiniappService;
  87. @Autowired
  88. public TaOrgCityMapper taOrgCityMapper;
  89. @Autowired
  90. public ITdCityService iTdCityService;
  91. @Autowired
  92. private IHelpActivityService helpActivityService;
  93. @Autowired
  94. private ITaShareActivityService taShareActivityService;
  95. @Autowired
  96. private ITaLiveActivityService taLiveActivityService;
  97. @Autowired
  98. private ITaDrainageService taDrainageService;
  99. @Autowired
  100. private TaSalesBatchMapper taSalesBatchMapper;
  101. @Autowired
  102. private ITaUserVerifyService taUserVerifyService;
  103. @Autowired
  104. private ITaMpMiniappService iTaMpMiniappService;
  105. /**
  106. * 验证接入
  107. */
  108. @GetMapping(value = "/", produces = "text/plain;charset=utf-8")
  109. public String access(@RequestParam(name = "signature", required = false) String signature,
  110. @RequestParam(name = "timestamp", required = false) String timestamp,
  111. @RequestParam(name = "nonce", required = false) String nonce,
  112. @RequestParam(name = "echostr", required = false) String echostr) {
  113. return echostr;
  114. }
  115. /**
  116. * 小程序数据预拉取 https://developers.weixin.qq.com/miniprogram/dev/framework/ability/pre-fetch.html
  117. *
  118. * @param appid
  119. * @param timestamp
  120. * @param token
  121. * @param code
  122. * @param path
  123. * @param query
  124. * @param scene
  125. * @return
  126. */
  127. @GetMapping("/preload")
  128. public ResponseBean getPreloadData(
  129. @RequestParam(name = "appid") String appid,
  130. @RequestParam(name = "timestamp") Long timestamp,
  131. String token,
  132. String code,
  133. String path,
  134. String query,
  135. Integer scene
  136. ) {
  137. Map<String, Object> resp = new HashMap<>();
  138. // 获取小程序信息
  139. TaMiniapp taMiniapp = iTaMiniappService.getInfoWithTpls(appid);
  140. resp.put("miniapp", taMiniapp);
  141. if (null == taMiniapp) {
  142. return ResponseBean.error("当前 appid 未在系统内注册", ResponseBean.ERROR_ILLEGAL_PARAMS);
  143. }
  144. // 获取组织信息
  145. TaOrg taOrg = taOrgService.getById(taMiniapp.getOrgId());
  146. resp.put("org", taOrg);
  147. if (null == taOrg) {
  148. return ResponseBean.error("当前 appid 未设置对应组织", ResponseBean.ERROR_UNAVAILABLE);
  149. }
  150. //把積分規則返回給小程序
  151. QueryWrapper<TdPointsRules> tdPointsRulesQueryWrapper = new QueryWrapper<>();
  152. tdPointsRulesQueryWrapper.eq("org_id", taOrg.getOrgId());
  153. List<TdPointsRules> rulesPointList = iTdPointsRulesService.list(tdPointsRulesQueryWrapper);
  154. resp.put("pointRuleList", rulesPointList);
  155. return ResponseBean.success(resp);
  156. }
  157. /**
  158. * 登陆接口
  159. */
  160. @ApiOperation(value = "小程序登录", notes = "小程序登录")
  161. @PostMapping("/login")
  162. public ResponseBean login(
  163. String code,
  164. @RequestParam(required = false) String from,
  165. @RequestParam(required = false) String recommender,
  166. @RequestParam(required = false) String mpOpenId,
  167. @RequestParam(required = false) String targetId,
  168. @RequestParam(required = false) Integer scene,
  169. HttpServletRequest request) {
  170. String appid = request.getHeader("appid");
  171. if (StringUtils.isEmpty(code)) {
  172. return ResponseBean.error("参数 code 不能为空", ResponseBean.ERROR_ILLEGAL_PARAMS);
  173. }
  174. if (StringUtils.isEmpty(appid)) {
  175. return ResponseBean.error("Header 参数 appid 不能为空", ResponseBean.ERROR_ILLEGAL_PARAMS);
  176. }
  177. // 校验服务过期日期等
  178. ResponseBean checkResp = checkMiniappStatus(appid);
  179. if (checkResp != null) {
  180. return checkResp;
  181. }
  182. try {
  183. TaMiniapp miniapp = taMiniappService.getById(appid);
  184. WxMaJscode2SessionResult session = miniAppService.getSessionInfo(code, appid);
  185. Integer orgId = miniapp.getOrgId();
  186. // 如果是扫码进来的
  187. Map<String, String> sceneParams = null;
  188. if (null != scene) {
  189. TaMiniappQrcode qrcode = miniAppService.getQrCodeBySerialNo(scene);
  190. if (null != qrcode) {
  191. String paramStr = qrcode.getQrParams();
  192. JSONObject params = JSON.parseObject(paramStr);
  193. sceneParams = StringUtils.parseQuery(params.getString("scene"));
  194. from = sceneParams.get("from");
  195. recommender = sceneParams.get("recommender");
  196. targetId = sceneParams.get("id");
  197. }
  198. }
  199. TaPerson taPerson = taPersonService.newPersonByOpenid(session.getOpenid(), miniapp, from, recommender);
  200. if (null == taPerson) {
  201. return ResponseBean.error("发生未知错误", ResponseBean.ERROR_UNAVAILABLE);
  202. }
  203. taPerson.setPassword(null);
  204. // 变换person的身份
  205. QueryWrapper<TaUser> taUserQueryWrapper = new QueryWrapper<>();
  206. taUserQueryWrapper.eq("phone",taPerson.getPhone());
  207. List<TaUser> userList = userService.list(taUserQueryWrapper);
  208. if (userList.size() > 0){
  209. TaUser taUser = userList.get(0);
  210. taPerson.setPersonType(taUser.getType());
  211. }
  212. taPersonService.updateById(taPerson);
  213. if (StringUtils.isEmpty(mpOpenId)) {
  214. iTaMpMiniappService.mpPerson(taPerson, mpOpenId);
  215. }
  216. Map<Object, Object> map = new HashMap<>();
  217. map.put("openId", session.getOpenid());
  218. map.put("orgId", orgId);
  219. map.put("personId", taPerson.getPersonId());
  220. String token = JWTUtils.newTokenByMap(map);
  221. sysTokenService.saveToken(token);
  222. if (!StringUtils.isEmpty(from) && !StringUtils.isEmpty(recommender) && !StringUtils.isEmpty(targetId)) {
  223. taSharePersonFromService.createBy(taPerson, from, recommender, targetId);
  224. }
  225. // 获取用户认证状态
  226. taPerson.setVerifyStatus(getVerifyStatus(taPerson));
  227. Map<String, Object> result = new HashMap<>();
  228. result.put("person", taPerson);
  229. result.put("sessionKey", session.getSessionKey());
  230. result.put("token", token);
  231. if (null != sceneParams) {
  232. result.put("scene", sceneParams);
  233. }
  234. return ResponseBean.success(result);
  235. } catch (WxErrorException e) {
  236. System.err.println(e.getError());
  237. return ResponseBean.error("解析小程序 code 失败", ResponseBean.ERROR_UNAVAILABLE);
  238. }
  239. }
  240. // @PostMapping("/share-person")
  241. // public ResponseBean sharePerson(@RequestParam(required = false) String from,
  242. // @RequestParam(required = false) String recommender,
  243. // @RequestParam(required = false) String targetId,
  244. // @RequestParam(required = false) Integer scene,
  245. // HttpServletRequest request) {
  246. // String openid = getOpenId(request);
  247. // List<TaPerson> persons = taPersonService.getPersonsByOpenId(openid);
  248. // if (null == persons || persons.size() < 1) {
  249. // return ResponseBean.error("校验人员信息出错", ResponseBean.ERROR_UNAVAILABLE);
  250. // }
  251. //
  252. // // 如果是扫码进来的
  253. // Map<String, String> sceneParams = null;
  254. // if (null != scene) {
  255. // TaMiniappQrcode qrcode = miniAppService.getQrCodeBySerialNo(scene);
  256. // if (null != qrcode) {
  257. // String paramStr = qrcode.getQrParams();
  258. // JSONObject params = JSON.parseObject(paramStr);
  259. // sceneParams = StringUtils.parseQuery(params.getString("scene"));
  260. //
  261. // from = sceneParams.get("from");
  262. // recommender = sceneParams.get("recommender");
  263. // targetId = sceneParams.get("id");
  264. // }
  265. // }
  266. //
  267. // taSharePersonFromService.createBy(persons.get(0), from, recommender, targetId);
  268. //
  269. // return ResponseBean.success("success");
  270. // }
  271. private ResponseBean checkMiniappStatus(String appid) {
  272. TaUser taUser = userService.getAdminByAppID(appid);
  273. if (null == taUser) {
  274. return ResponseBean.error("系统尚未添加管理员, 请联系相关人员", ResponseBean.ERROR_UNAVAILABLE);
  275. }
  276. if (null == taUser.getExpDate() || LocalDateTime.now().isAfter(taUser.getExpDate())) {
  277. return ResponseBean.error("系统服务已到期或者尚未设置到期日期", ResponseBean.ERROR_UNAVAILABLE);
  278. }
  279. if (null == taUser.getStatus() || CommConstant.STATUS_NORMAL != taUser.getStatus()) {
  280. return ResponseBean.error("系统服务被停止或者出现异常", ResponseBean.ERROR_UNAVAILABLE);
  281. }
  282. return null;
  283. }
  284. private boolean checkSharePersonFrom(String from, String personId, String targetId, Integer orgId) {
  285. QueryWrapper<TaSharePersonFrom> queryWrapper = new QueryWrapper<>();
  286. queryWrapper.eq("target_type", from);
  287. queryWrapper.eq("person_id", personId);
  288. queryWrapper.eq("target_id", targetId);
  289. queryWrapper.eq("org_id", orgId);
  290. List<TaSharePersonFrom> list = taSharePersonFromService.list(queryWrapper);
  291. if (list.size() > 0) {
  292. return false;
  293. }
  294. return true;
  295. }
  296. /**
  297. * 登陆接口
  298. */
  299. @PostMapping("/logout")
  300. public ResponseBean logout(HttpServletRequest request) {
  301. String openid = getOpenId(request);
  302. List<TaPerson> persons = taPersonService.getPersonsByOpenId(openid);
  303. if (null == persons || persons.size() == 0) {
  304. return ResponseBean.success("");
  305. }
  306. return ResponseBean.success("");
  307. }
  308. /**
  309. * 获取用户信息, 并写入内部人员表
  310. */
  311. @PostMapping("/signup")
  312. public ResponseBean info(@RequestBody String paramStr, HttpServletRequest request) {
  313. String appid = request.getHeader("appid");
  314. TaPerson person = null;
  315. TaMiniapp miniapp = taMiniappService.getById(appid);
  316. if (null == paramStr || "".equals(paramStr.trim()) || "{}".equals(paramStr.trim())) {
  317. String openid = getOpenId(request);
  318. List<TaPerson> taPersons = taPersonService.getPersonsByOpenId(openid);
  319. if (null == taPersons || taPersons.size() != 1) {
  320. return ResponseBean.error("验证人员信息失败", ResponseBean.ERROR_UNAVAILABLE);
  321. }
  322. person = taPersons.get(0);
  323. } else {
  324. JSONObject params = JSONObject.parseObject(paramStr);
  325. if (null == params) {
  326. return ResponseBean.error("校验参数失败", ResponseBean.ERROR_ILLEGAL_PARAMS);
  327. }
  328. String sessionKey = params.getString("sessionKey");
  329. String signature = params.getString("signature");
  330. String rawData = params.getString("rawData");
  331. String encryptedData = params.getString("encryptedData");
  332. String iv = params.getString("iv");
  333. // 用户信息校验
  334. if (!miniAppService.checkUserInfo(sessionKey, rawData, signature, appid)) {
  335. return ResponseBean.error("校验参数失败", ResponseBean.ERROR_ILLEGAL_PARAMS);
  336. }
  337. // 解密用户信息
  338. WxMaUserInfo userInfo = miniAppService.getUserInfo(sessionKey, encryptedData, iv, appid);
  339. // 更新或保存用户信息
  340. person = taPersonService.mergePersonWxInfo(userInfo);
  341. if (null == person) {
  342. return ResponseBean.error("发生未知错误", ResponseBean.ERROR_UNAVAILABLE);
  343. }
  344. taPersonService.upDatePersonCityToId(person.getPersonId());
  345. }
  346. // 获取其余信息
  347. Map<String, Object> extraInfo = taPersonService.getExtraInfo(person.getPersonId());
  348. person.setPassword(null);
  349. // 获取用户认证状态
  350. person.setVerifyStatus(getVerifyStatus(person));
  351. Map<String, Object> result = new HashMap<>();
  352. result.put("person", person);
  353. result.put("extraInfo", extraInfo);
  354. result.put("miniApp", miniapp);
  355. return ResponseBean.success(result);
  356. }
  357. private String getVerifyStatus(TaPerson person) {
  358. QueryWrapper<TaUserVerify> taUserVerifyQueryWrapper = new QueryWrapper<>();
  359. taUserVerifyQueryWrapper.eq("person_id",person.getPersonId());
  360. List<TaUserVerify> taUserVerifies = taUserVerifyService.list(taUserVerifyQueryWrapper);
  361. // 未认证
  362. String verifyStatus = "not_certified";
  363. List<String> verifyList = taUserVerifies.stream().map(TaUserVerify::getVerifyStatus).collect(Collectors.toList());
  364. if (verifyList.contains("1")){
  365. // 已认证
  366. verifyStatus = "certified";
  367. }else if (verifyList.contains("2")){
  368. // 认证未通过
  369. verifyStatus = "certification_failed";
  370. }else if (verifyList.contains("0")){
  371. // 认证中
  372. verifyStatus = "certification_in_progress";
  373. }
  374. return verifyStatus;
  375. }
  376. /**
  377. * 获取用户绑定手机号信息
  378. */
  379. @ApiOperation(value = "小程序授权手机号", notes = "小程序授权手机号")
  380. @PostMapping("/userPhone")
  381. public ResponseBean phone(@RequestBody String paramStr, HttpServletRequest request) {
  382. String appid = request.getHeader("appid");
  383. JSONObject params = JSONObject.parseObject(paramStr);
  384. if (null == params) {
  385. return ResponseBean.error("校验参数失败", ResponseBean.ERROR_ILLEGAL_PARAMS);
  386. }
  387. // 手机号解码
  388. String sessionKey = params.getString("sessionKey");
  389. String encryptedData = params.getString("encryptedData");
  390. String iv = params.getString("iv");
  391. // 楼盘ID
  392. String buildingId = params.getString("buildingId");
  393. // 场景ID
  394. String sceneId = params.getString("sceneId");
  395. // 访问目标
  396. String targetType = params.getString("targetType");
  397. // 目标ID
  398. String targetId = params.getString("targetId");
  399. // 目标名称
  400. String targetName = params.getString("targetName");
  401. // 推广用户 - 分享人
  402. String promoter = params.getString("recommender");
  403. // 置业顾问
  404. String consultantPersonId = request.getHeader("x-consultant");
  405. // 渠道ID
  406. String channelId = params.getString("channelId");
  407. // 推广码ID
  408. String qrCodeId = params.getString("qrCodeId");
  409. // 解密
  410. WxMaPhoneNumberInfo phoneNoInfo = miniAppService.getPhoneNoInfo(sessionKey, encryptedData, iv, appid);
  411. if (null == phoneNoInfo || StringUtils.isEmpty(phoneNoInfo.getPhoneNumber())) {
  412. ResponseBean.error("解析用户手机号码出错", ResponseBean.ERROR_UNAVAILABLE);
  413. }
  414. String openid = getOpenId(request);
  415. Integer orgId = getOrgId(request);
  416. String phone = phoneNoInfo.getPhoneNumber();
  417. TaCustomerFrom customerFrom = new TaCustomerFrom();
  418. customerFrom.setTargetType(targetType);
  419. customerFrom.setTargetId(targetId);
  420. customerFrom.setTargetName(targetName);
  421. customerFrom.setOrgId(orgId);
  422. customerFrom.setSceneId(sceneId);
  423. if (!StringUtils.isEmpty(channelId)) {
  424. customerFrom.setChannelId(Integer.valueOf(channelId));
  425. }
  426. if (!StringUtils.isEmpty(qrCodeId)) {
  427. customerFrom.setQrCodeId(Integer.valueOf(qrCodeId));
  428. }
  429. try {
  430. taPersonService.authPhone(
  431. orgId,
  432. openid,
  433. phone,
  434. buildingId,
  435. promoter,
  436. consultantPersonId,
  437. customerFrom);
  438. return ResponseBean.success(phoneNoInfo);
  439. } catch (Exception e) {
  440. e.printStackTrace();
  441. return ResponseBean.error("授权手机失败: " + e.getMessage(), ResponseBean.ERROR_UNAVAILABLE);
  442. }
  443. }
  444. /**
  445. * 生成二维码
  446. *
  447. * @return
  448. */
  449. @PostMapping("/qrcode")
  450. public ResponseBean qrcode(@RequestBody String paramsStr, HttpServletRequest request) {
  451. String appid = request.getHeader("appid");
  452. return miniAppService.getQrCode(paramsStr, appid);
  453. }
  454. /**
  455. * 获取二维码参数
  456. *
  457. * @param serialNo
  458. * @return
  459. */
  460. @GetMapping("/qrcode/scene/{serialNo}")
  461. public ResponseBean getScene(@PathVariable String serialNo) {
  462. try {
  463. Integer id = Integer.valueOf(serialNo);
  464. TaMiniappQrcode qrcode = miniAppService.getQrCodeBySerialNo(id);
  465. if (null == qrcode) {
  466. return ResponseBean.error("不存在的二维码参数", HttpStatus.SC_BAD_REQUEST);
  467. }
  468. return ResponseBean.success(qrcode.getQrParams());
  469. } catch (Exception e) {
  470. e.printStackTrace();
  471. return ResponseBean.error("获取二维码参数失败: " + e.getMessage(), HttpStatus.SC_INTERNAL_SERVER_ERROR);
  472. }
  473. }
  474. public Integer getOrgId(HttpServletRequest request) {
  475. Map map = JWTUtils.getUserIdAndOrgId(request);
  476. if (null != map && null != map.get("orgId")) {
  477. return Integer.valueOf(map.get("orgId").toString());
  478. }
  479. return null;
  480. }
  481. }