MiniAppController.java 21KB

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