UserService.java 53 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221
  1. package com.izouma.nineth.service;
  2. import cn.binarywang.wx.miniapp.api.WxMaService;
  3. import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
  4. import cn.binarywang.wx.miniapp.bean.WxMaUserInfo;
  5. import cn.hutool.core.convert.Convert;
  6. import com.alibaba.fastjson.JSON;
  7. import cn.hutool.core.collection.CollUtil;
  8. import com.alibaba.fastjson.JSONObject;
  9. import com.alipay.api.AlipayApiException;
  10. import com.alipay.api.AlipayClient;
  11. import com.alipay.api.DefaultAlipayClient;
  12. import com.alipay.api.request.AlipayUserCertifyOpenCertifyRequest;
  13. import com.alipay.api.request.AlipayUserCertifyOpenInitializeRequest;
  14. import com.alipay.api.request.AlipayUserCertifyOpenQueryRequest;
  15. import com.alipay.api.response.AlipayUserCertifyOpenCertifyResponse;
  16. import com.alipay.api.response.AlipayUserCertifyOpenInitializeResponse;
  17. import com.alipay.api.response.AlipayUserCertifyOpenQueryResponse;
  18. import com.github.kevinsawicki.http.HttpRequest;
  19. import com.huifu.adapay.core.exception.BaseAdaPayException;
  20. import com.izouma.nineth.TokenHistory;
  21. import com.izouma.nineth.config.AlipayProperties;
  22. import com.izouma.nineth.config.Constants;
  23. import com.izouma.nineth.config.GeneralProperties;
  24. import com.izouma.nineth.config.RedisKeys;
  25. import com.izouma.nineth.domain.Collection;
  26. import com.izouma.nineth.domain.*;
  27. import com.izouma.nineth.dto.*;
  28. import com.izouma.nineth.dto.oasis.OasisLoginDTO;
  29. import com.izouma.nineth.enums.AssetStatus;
  30. import com.izouma.nineth.enums.AuthStatus;
  31. import com.izouma.nineth.enums.AuthorityName;
  32. import com.izouma.nineth.enums.HeatType;
  33. import com.izouma.nineth.event.RegisterEvent;
  34. import com.izouma.nineth.exception.BusinessException;
  35. import com.izouma.nineth.repo.*;
  36. import com.izouma.nineth.security.Authority;
  37. import com.izouma.nineth.security.JwtTokenUtil;
  38. import com.izouma.nineth.security.JwtUserFactory;
  39. import com.izouma.nineth.service.sms.SmsService;
  40. import com.izouma.nineth.service.storage.StorageService;
  41. import com.izouma.nineth.utils.*;
  42. import lombok.AllArgsConstructor;
  43. import lombok.extern.slf4j.Slf4j;
  44. import me.chanjar.weixin.common.error.WxErrorException;
  45. import me.chanjar.weixin.mp.api.WxMpService;
  46. import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken;
  47. import me.chanjar.weixin.mp.bean.result.WxMpUser;
  48. import org.apache.commons.lang3.ObjectUtils;
  49. import org.apache.commons.lang3.RandomStringUtils;
  50. import org.apache.commons.lang3.StringUtils;
  51. import org.apache.rocketmq.spring.core.RocketMQTemplate;
  52. import org.springframework.beans.BeanUtils;
  53. import org.springframework.cache.annotation.CacheEvict;
  54. import org.springframework.cache.annotation.Cacheable;
  55. import org.springframework.data.domain.Page;
  56. import org.springframework.data.domain.PageImpl;
  57. import org.springframework.data.domain.PageRequest;
  58. import org.springframework.data.domain.Sort;
  59. import org.springframework.data.jpa.domain.Specification;
  60. import org.springframework.data.redis.core.RedisTemplate;
  61. import org.springframework.scheduling.annotation.Async;
  62. import org.springframework.scheduling.annotation.Scheduled;
  63. import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
  64. import org.springframework.security.crypto.password.PasswordEncoder;
  65. import org.springframework.stereotype.Service;
  66. import javax.management.openmbean.OpenMBeanAttributeInfoSupport;
  67. import javax.persistence.criteria.CriteriaBuilder;
  68. import javax.persistence.criteria.CriteriaQuery;
  69. import javax.persistence.criteria.Predicate;
  70. import java.math.BigDecimal;
  71. import java.math.BigInteger;
  72. import java.net.URLEncoder;
  73. import java.nio.charset.StandardCharsets;
  74. import java.text.SimpleDateFormat;
  75. import java.time.Duration;
  76. import java.util.*;
  77. import java.util.concurrent.atomic.AtomicInteger;
  78. import java.util.regex.Pattern;
  79. import java.util.stream.Collectors;
  80. @Service
  81. @Slf4j
  82. @AllArgsConstructor
  83. public class UserService {
  84. private UserRepo userRepo;
  85. private WxMaService wxMaService;
  86. private WxMpService wxMpService;
  87. private SmsService smsService;
  88. private StorageService storageService;
  89. private JwtTokenUtil jwtTokenUtil;
  90. private FollowService followService;
  91. private FollowRepo followRepo;
  92. private IdentityAuthRepo identityAuthRepo;
  93. private SysConfigService sysConfigService;
  94. private UserBankCardRepo userBankCardRepo;
  95. private InviteRepo inviteRepo;
  96. private CacheService cacheService;
  97. private TokenHistoryRepo tokenHistoryRepo;
  98. private CollectionRepo collectionRepo;
  99. private AdapayMerchantService adapayMerchantService;
  100. private RocketMQTemplate rocketMQTemplate;
  101. private GeneralProperties generalProperties;
  102. private RedisTemplate<String, Object> redisTemplate;
  103. private PasswordEncoder passwordEncoder;
  104. private WeakPassRepo weakPassRepo;
  105. private UserBalanceRepo userBalanceRepo;
  106. private ContentAuditService contentAuditService;
  107. private HeatInfoRepo heatInfoRepo;
  108. private ShowroomRepo showroomRepo;
  109. private TradingAccountRepo tradingAccountRepo;
  110. private AlipayClient alipayClient;
  111. private SnowflakeIdWorker snowflakeIdWorker;
  112. private FaceAuthRepo faceAuthRepo;
  113. private AuctionPassRecordRepo auctionPassRecordRepo;
  114. private AssetRepo assetRepo;
  115. private ShowCollectionRepo showCollectionRepo;
  116. private ShowroomService showroomService;
  117. private NewsLikeRepo newsLikeRepo;
  118. private UserPropertyRepo userPropertyRepo;
  119. public User update(User user) {
  120. if (!SecurityUtils.hasRole(AuthorityName.ROLE_ADMIN)) {
  121. if (!SecurityUtils.getAuthenticatedUser().getId().equals(user.getId())) {
  122. throw new BusinessException("无权限");
  123. }
  124. }
  125. User orig = userRepo.findById(user.getId()).orElseThrow(new BusinessException("无记录"));
  126. ObjUtils.merge(orig, user);
  127. orig = save(orig);
  128. userRepo.updateAssetMinter(orig.getId());
  129. userRepo.updateAssetOwner(orig.getId());
  130. userRepo.updateCollectionMinter(orig.getId());
  131. userRepo.updateCollectionOwner(orig.getId());
  132. userRepo.updateOrderMinter(orig.getId());
  133. userRepo.updateHistoryFromUser(orig.getId());
  134. userRepo.updateHistoryToUser(orig.getId());
  135. userRepo.updateShowroomToUser(orig.getId());
  136. cacheService.clearCollection();
  137. return orig;
  138. }
  139. public User save(User user) {
  140. if (user.getId() != null) {
  141. cacheService.clearUserMy(user.getId());
  142. cacheService.clearUser(user.getId());
  143. }
  144. return userRepo.save(user);
  145. }
  146. public User update(Long userId, String nickname, String avatar, String sex, String bg, String intro,
  147. Boolean useCollectionPic, Boolean riskWarning, Integer level) {
  148. User user = userRepo.findById(userId).orElseThrow(new BusinessException("用户不存在"));
  149. if (StringUtils.isNotBlank(nickname)) {
  150. if (!nickname.equals(user.getNickname())) {
  151. if (!contentAuditService.auditText(nickname)) {
  152. throw new BusinessException("昵称包含非法内容");
  153. }
  154. }
  155. user.setNickname(nickname);
  156. }
  157. if (StringUtils.isNotBlank(avatar)) {
  158. user.setAvatar(avatar);
  159. }
  160. if (StringUtils.isNotBlank(sex)) {
  161. user.setSex(sex);
  162. }
  163. if (StringUtils.isNotBlank(bg)) {
  164. user.setBg(bg);
  165. }
  166. if (StringUtils.isNotBlank(intro)) {
  167. if (!intro.equals(user.getIntro())) {
  168. if (!contentAuditService.auditText(nickname)) {
  169. throw new BusinessException("简介包含非法内容");
  170. }
  171. }
  172. user.setIntro(intro);
  173. }
  174. if (useCollectionPic != null) {
  175. user.setUseCollectionPic(useCollectionPic);
  176. }
  177. if (riskWarning != null) {
  178. user.setRiskWarning(riskWarning);
  179. }
  180. if (level != null) {
  181. user.setLevel(level);
  182. }
  183. user = save(user);
  184. userRepo.updateAssetMinter(userId);
  185. userRepo.updateAssetOwner(userId);
  186. userRepo.updateCollectionMinter(userId);
  187. userRepo.updateCollectionOwner(userId);
  188. userRepo.updateOrderMinter(userId);
  189. userRepo.updateHistoryFromUser(userId);
  190. userRepo.updateHistoryToUser(userId);
  191. userRepo.updateShowroomToUser(userId);
  192. return user;
  193. }
  194. @Cacheable(value = "userList", key = "#pageQuery.hashCode()")
  195. public PageWrapper<User> all(PageQuery pageQuery) {
  196. Specification<User> specification = JpaUtils.toSpecification(pageQuery, User.class);
  197. specification = specification.and((Specification<User>) (root, criteriaQuery, criteriaBuilder) -> {
  198. List<Predicate> and = new ArrayList<>();
  199. and.add(criteriaBuilder.equal(root.get("del"), false));
  200. if (!pageQuery.getQuery().containsKey("admin")) {
  201. and.add(criteriaBuilder.equal(root.get("admin"), false));
  202. }
  203. if (pageQuery.getQuery().containsKey("hasRole")) {
  204. String roleName = (String) pageQuery.getQuery().get("hasRole");
  205. if (roleName.equals("ROLE_MINTER")) {
  206. and.add(criteriaBuilder.equal(root.get("minter"), true));
  207. } else {
  208. and.add(criteriaBuilder
  209. .isMember(Authority.get(AuthorityName.valueOf(roleName)), root.get("authorities")));
  210. }
  211. }
  212. if (pageQuery.getQuery().containsKey("vip")) {
  213. boolean vip = (boolean) pageQuery.getQuery().get("vip");
  214. if (vip) {
  215. and.add(criteriaBuilder.greaterThan(root.get("vipPurchase"), 0));
  216. } else {
  217. and.add(criteriaBuilder.lessThanOrEqualTo(root.get("vipPurchase"), 0));
  218. }
  219. }
  220. return criteriaBuilder.and(and.toArray(new Predicate[0]));
  221. });
  222. Page<User> page = userRepo.findAll(specification, JpaUtils.toPageRequest(pageQuery));
  223. return PageWrapper.of(page);
  224. }
  225. public User create(UserRegister userRegister) {
  226. User user = new User();
  227. BeanUtils.copyProperties(userRegister, user);
  228. user.setShareRatio(sysConfigService.getBigDecimal("share_ratio"));
  229. user.setAuthStatus(AuthStatus.NOT_AUTH);
  230. if (StringUtils.isNotBlank(userRegister.getPassword())) {
  231. checkPasswordStrength(userRegister.getPassword());
  232. user.setPassword(passwordEncoder.encode(userRegister.getPassword()));
  233. }
  234. return save(user);
  235. }
  236. public User phoneRegister(String phone, String code, String password, String inviteCode, Long invitor,
  237. Long collectionId, Long showroomId) {
  238. String name = "0x" + RandomStringUtils.randomAlphabetic(8);
  239. Invite invite = null;
  240. if (StringUtils.isNotBlank(inviteCode)) {
  241. invite = inviteRepo.findFirstByCode(inviteCode).orElse(null);
  242. }
  243. smsService.verify(phone, code);
  244. Collection collection;
  245. if (collectionId != null) {
  246. collection = collectionRepo.findById(collectionId).orElseThrow(new BusinessException("无藏品"));
  247. // if (!collection.isOnShelf() || !collection.isSalable()) {
  248. // collectionId = null;
  249. // } else if (collection.isScheduleSale()) {
  250. // if (collection.getStartTime().isAfter(LocalDateTime.now())) {
  251. // collectionId = null;
  252. // }
  253. // }
  254. // 只看是否开去分享
  255. if (ObjectUtils.isEmpty(collection.getOpenQuota()) || !collection.getOpenQuota()) {
  256. collectionId = null;
  257. }
  258. }
  259. User user = create(UserRegister.builder()
  260. .username(name)
  261. .nickname(name)
  262. .password(password)
  263. .avatar(Constants.DEFAULT_AVATAR)
  264. .phone(phone)
  265. .invitorPhone(Optional.ofNullable(invite).map(Invite::getPhone).orElse(null))
  266. .invitorName(Optional.ofNullable(invite).map(Invite::getName).orElse(null))
  267. .inviteCode(Optional.ofNullable(invite).map(Invite::getCode).orElse(null))
  268. .collectionInvitor(invitor)
  269. .collectionId(collectionId)
  270. .build());
  271. if (invite != null) {
  272. inviteRepo.increaseNum(invite.getId());
  273. }
  274. if (ObjectUtils.isNotEmpty(showroomId)) {
  275. //通过展厅的注册数量
  276. int weight = sysConfigService.getInt("heat_register_weight");
  277. heatInfoRepo.save(HeatInfo.builder()
  278. .showroomId(showroomId)
  279. .userId(user.getId())
  280. .type(HeatType.REGISTER)
  281. .value(weight)
  282. .build());
  283. showroomRepo.addHeatAndRegister(showroomId, weight, 1);
  284. }
  285. return user;
  286. }
  287. public String mqRegister(String phone, String code, String password, String inviteCode, Long invitor,
  288. Long collectionId, Long showroomId) {
  289. rocketMQTemplate.convertAndSend(generalProperties.getRegisterTopic(),
  290. new RegisterEvent(phone, code, password, inviteCode, invitor, collectionId, showroomId));
  291. return phone;
  292. }
  293. public Object getRegisterResult(String phone) {
  294. return redisTemplate.opsForValue().get("register::" + phone);
  295. }
  296. public void del(Long id) {
  297. User user = userRepo.findById(id).orElseThrow(new BusinessException("用户不存在"));
  298. user.setDel(true);
  299. if (StringUtils.isNoneEmpty(user.getOpenId())) {
  300. user.setOpenId(user.getOpenId() + "###" + RandomStringUtils.randomAlphabetic(8));
  301. }
  302. if (StringUtils.isNoneEmpty(user.getPhone())) {
  303. user.setPhone(user.getPhone() + "###" + RandomStringUtils.randomAlphabetic(8));
  304. }
  305. save(user);
  306. //删除实名认证
  307. identityAuthRepo.softDeleteByUserId(id);
  308. }
  309. public User loginByPhone(String phone, String code) {
  310. User user = userRepo.findByPhoneAndDelFalse(phone).orElse(null);
  311. smsService.verify(phone, code);
  312. if (user == null) {
  313. String name = "0x" + RandomStringUtils.randomAlphabetic(8);
  314. user = create(UserRegister.builder()
  315. .authorities(Collections.singleton(Authority.get(AuthorityName.ROLE_USER)))
  316. .username(name)
  317. .nickname(name)
  318. .avatar(Constants.DEFAULT_AVATAR)
  319. .phone(phone)
  320. .build());
  321. }
  322. return user;
  323. }
  324. public User loginByPhonePwd(String phone, String password) {
  325. if (StringUtils.isEmpty(phone)) {
  326. throw new BusinessException("手机号错误");
  327. }
  328. User user = userRepo.findByPhoneAndDelFalse(phone).orElseThrow(new BusinessException("账号或密码错误"));
  329. if (StringUtils.isEmpty(user.getPassword())) {
  330. throw new BusinessException("账号或密码错误");
  331. }
  332. if (StringUtils.isNoneEmpty(user.getPassword()) &&
  333. !passwordEncoder.matches(password, user.getPassword())) {
  334. throw new BusinessException("账号或密码错误");
  335. }
  336. return user;
  337. }
  338. public User loginByUsernamePwd(String username, String password) {
  339. if (StringUtils.isEmpty(username)) {
  340. throw new BusinessException("用户名错误");
  341. }
  342. User user = userRepo.findByUsernameAndDelFalse(username).orElseThrow(new BusinessException("账号或密码错误"));
  343. if (StringUtils.isEmpty(user.getPassword())
  344. || !passwordEncoder.matches(password, user.getPassword())) {
  345. throw new BusinessException("账号或密码错误");
  346. }
  347. return user;
  348. }
  349. public User loginMp(String code) throws WxErrorException {
  350. WxMpOAuth2AccessToken accessToken = wxMpService.oauth2getAccessToken(code);
  351. WxMpUser wxMpUser = wxMpService.oauth2getUserInfo(accessToken, null);
  352. User user = userRepo.findByOpenIdAndDelFalse(wxMpUser.getOpenId()).orElse(null);
  353. if (user == null) {
  354. String name = "0x" + RandomStringUtils.randomAlphabetic(8);
  355. user = User.builder()
  356. .username(name)
  357. .nickname(name)
  358. .avatar(wxMpUser.getHeadImgUrl())
  359. .sex(wxMpUser.getSexDesc())
  360. .country(wxMpUser.getCountry())
  361. .province(wxMpUser.getProvince())
  362. .city(wxMpUser.getCity())
  363. .openId(wxMpUser.getOpenId())
  364. .language(wxMpUser.getLanguage())
  365. .authorities(Collections.singleton(Authority.get(AuthorityName.ROLE_USER)))
  366. .authStatus(AuthStatus.NOT_AUTH)
  367. .build();
  368. save(user);
  369. }
  370. return user;
  371. }
  372. public String code2openId(String code) throws WxErrorException {
  373. WxMpOAuth2AccessToken accessToken = wxMpService.oauth2getAccessToken(code);
  374. return wxMpService.oauth2getUserInfo(accessToken, null).getOpenId();
  375. }
  376. public User loginMa(String code) {
  377. try {
  378. WxMaJscode2SessionResult result = wxMaService.jsCode2SessionInfo(code);
  379. String openId = result.getOpenid();
  380. String sessionKey = result.getSessionKey();
  381. User userInfo = userRepo.findByOpenIdAndDelFalse(openId).orElse(null);
  382. ;
  383. if (userInfo != null) {
  384. return userInfo;
  385. }
  386. String name = "0x" + RandomStringUtils.randomAlphabetic(8);
  387. userInfo = User.builder()
  388. .username(name)
  389. .nickname(name)
  390. .openId(openId)
  391. .avatar(Constants.DEFAULT_AVATAR)
  392. .authorities(Collections.singleton(Authority.get(AuthorityName.ROLE_USER)))
  393. .authStatus(AuthStatus.NOT_AUTH)
  394. .build();
  395. userInfo = save(userInfo);
  396. return userInfo;
  397. } catch (WxErrorException e) {
  398. e.printStackTrace();
  399. }
  400. throw new BusinessException("登录失败");
  401. }
  402. public User getMaUserInfo(String sessionKey, String rawData, String signature,
  403. String encryptedData, String iv) {
  404. // 用户信息校验
  405. if (!wxMaService.getUserService().checkUserInfo(sessionKey, rawData, signature)) {
  406. throw new BusinessException("获取用户信息失败");
  407. }
  408. // 解密用户信息
  409. WxMaUserInfo wxUserInfo = wxMaService.getUserService().getUserInfo(sessionKey, encryptedData, iv);
  410. User user = userRepo.findByOpenIdAndDelFalse(wxUserInfo.getOpenId()).orElse(null);
  411. String avatarUrl = Constants.DEFAULT_AVATAR;
  412. try {
  413. String path = "image/avatar/" +
  414. new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss").format(new Date()) +
  415. RandomStringUtils.randomAlphabetic(8) +
  416. ".jpg";
  417. avatarUrl = storageService.uploadFromUrl(wxUserInfo.getAvatarUrl(), path);
  418. } catch (Exception e) {
  419. log.error("获取头像失败", e);
  420. }
  421. if (user == null) {
  422. user = User.builder()
  423. .username(UUID.randomUUID().toString())
  424. .nickname(wxUserInfo.getNickName())
  425. .openId(wxUserInfo.getOpenId())
  426. .avatar(avatarUrl)
  427. .sex(wxUserInfo.getGender())
  428. .country(wxUserInfo.getCountry())
  429. .province(wxUserInfo.getProvince())
  430. .city(wxUserInfo.getCity())
  431. .authorities(Collections.singleton(Authority.builder().name("ROLE_USER").build()))
  432. .build();
  433. user = save(user);
  434. } else {
  435. user.setAvatar(avatarUrl);
  436. user.setNickname(wxUserInfo.getNickName());
  437. user.setSex(wxUserInfo.getGender());
  438. user.setCountry(wxUserInfo.getCountry());
  439. user.setProvince(wxUserInfo.getProvince());
  440. user.setCity(wxUserInfo.getCity());
  441. user = save(user);
  442. }
  443. return user;
  444. }
  445. public String setPassword(Long userId, String password) {
  446. checkPasswordStrength(password);
  447. User user = userRepo.findById(userId).orElseThrow(new BusinessException("用户不存在"));
  448. user.setPassword(passwordEncoder.encode(password));
  449. user = save(user);
  450. return jwtTokenUtil.generateToken(JwtUserFactory.create(user));
  451. }
  452. public String setPassword(Long userId, String code, String password) {
  453. checkPasswordStrength(password);
  454. User user = userRepo.findById(userId).orElseThrow(new BusinessException("用户不存在"));
  455. smsService.verify(user.getPhone(), code);
  456. return setPassword(userId, password);
  457. }
  458. public String forgotPassword(String phone, String password, String code) {
  459. checkPasswordStrength(password);
  460. User user = userRepo.findByPhoneAndDelFalse(phone).orElseThrow(new BusinessException("手机号未注册"));
  461. smsService.verify(user.getPhone(), code);
  462. return setPassword(user.getId(), password);
  463. }
  464. public static void checkPasswordStrength(String password) {
  465. if (StringUtils.isBlank(password)) throw new BusinessException("密码不能为空");
  466. if (!Pattern.matches("^[a-zA-Z0-9!@#$%^&*]+$", password)) throw new BusinessException("密码含非法字符");
  467. int upper = 0;
  468. int lower = 0;
  469. int digit = 0;
  470. int special = 0;
  471. char ch;
  472. for (int i = 0; i < password.length(); i++) {
  473. ch = password.charAt(i);
  474. if (Character.isUpperCase(ch))
  475. upper++;
  476. else if (Character.isLowerCase(ch))
  477. lower++;
  478. else if (Character.isDigit(ch))
  479. digit++;
  480. else {
  481. if (ch == '<' || ch == '>') {
  482. throw new BusinessException("密码包含非法字符");
  483. } else
  484. special++;
  485. }
  486. }
  487. if (upper > 0 && lower > 0 && digit > 0 && password.length() >= 8) {
  488. return;
  489. }
  490. throw new BusinessException("密码长度至少为8位,且必须包含大小写字母和数字");
  491. }
  492. public void bindPhone(Long userId, String phone) {
  493. User user = userRepo.findByIdAndDelFalse(userId).orElseThrow(new BusinessException("用户不存在"));
  494. if (StringUtils.isNoneEmpty(user.getPhone())) {
  495. throw new BusinessException("该账号已绑定手机");
  496. }
  497. userRepo.findByPhoneAndDelFalse(phone).ifPresent(user1 -> {
  498. if (!user1.getId().equals(userId)) {
  499. throw new BusinessException("该手机号已绑定其他账号");
  500. }
  501. });
  502. user.setPhone(phone);
  503. save(user);
  504. }
  505. public UserDTO toDTO(User user) {
  506. return toDTO(user, true);
  507. }
  508. public UserDTO toDTO(User user, boolean join) {
  509. UserDTO userDTO = new UserDTO();
  510. BeanUtils.copyProperties(user, userDTO);
  511. if (user.getAuthorities() != null) {
  512. userDTO.setAuthorities(new HashSet<>(user.getAuthorities()));
  513. }
  514. if (join) {
  515. if (SecurityUtils.getAuthenticatedUser() != null) {
  516. userDTO.setFollow(followService.isFollow(SecurityUtils.getAuthenticatedUser().getId(), user.getId()));
  517. }
  518. }
  519. return userDTO;
  520. }
  521. public List<UserDTO> toDTO(List<User> users) {
  522. List<Follow> follows = new ArrayList<>();
  523. if (SecurityUtils.getAuthenticatedUser() != null) {
  524. follows.addAll(followRepo.findByUserId(SecurityUtils.getAuthenticatedUser().getId()));
  525. }
  526. return users.stream().parallel().map(user -> {
  527. UserDTO dto = toDTO(user, false);
  528. if (!follows.isEmpty()) {
  529. dto.setFollow(follows.stream().anyMatch(f -> f.getFollowUserId().equals(user.getId())));
  530. }
  531. return dto;
  532. }).collect(Collectors.toList());
  533. }
  534. public Page<UserDTO> toDTO(Page<User> users) {
  535. List<UserDTO> userDTOS = toDTO(users.getContent());
  536. return new PageImpl<>(userDTOS, users.getPageable(), users.getTotalElements());
  537. }
  538. @CacheEvict(value = "user", allEntries = true)
  539. public void setTradeCode(Long userId, String token, String tradeCode) {
  540. String phone = smsService.verifyToken(token);
  541. User user = userRepo.findById(userId).orElseThrow(new BusinessException("用户不存在"));
  542. if (!StringUtils.equals(phone, user.getPhone())) {
  543. throw new BusinessException("验证码无效");
  544. }
  545. user.setTradeCode(passwordEncoder.encode(tradeCode));
  546. save(user);
  547. }
  548. public void verifyTradeCode(Long userId, String tradeCode) {
  549. User user = userRepo.findById(userId).orElseThrow(new BusinessException("用户不存在"));
  550. if (!passwordEncoder.matches(tradeCode, user.getTradeCode())) {
  551. throw new BusinessException("交易密码错误");
  552. }
  553. }
  554. public Map<String, Object> searchByPhone(String phone) {
  555. if (AuthStatus.SUCCESS != SecurityUtils.getAuthenticatedUser().getAuthStatus()) {
  556. throw new BusinessException("实名认证后才能赠送");
  557. }
  558. User user = userRepo.findByPhoneAndDelFalse(phone).orElseThrow(new BusinessException("用户不存在或未认证"));
  559. if (AuthStatus.SUCCESS != user.getAuthStatus()) {
  560. throw new BusinessException("用户不存在或未认证");
  561. }
  562. String realName = identityAuthRepo.findFirstByUserIdAndStatusAndDelFalseOrderByCreatedAtDesc(
  563. user.getId(), AuthStatus.SUCCESS)
  564. .map(IdentityAuth::getRealName).orElse("").replaceAll(".*(?=.)", "**");
  565. Map<String, Object> map = new HashMap<>();
  566. map.put("id", user.getId());
  567. map.put("avatar", user.getAvatar());
  568. map.put("phone", user.getPhone().replaceAll("(?<=.{3}).*(?=.{4})", "**"));
  569. map.put("realName", realName);
  570. return map;
  571. }
  572. public Map<String, Object> searchByPhoneAdmin(String phoneStr) {
  573. List<String> phone = Arrays.stream(phoneStr.replaceAll("\n", " ")
  574. .replaceAll("\r\n", " ")
  575. .split(" "))
  576. .map(String::trim)
  577. .filter(s -> !StringUtils.isEmpty(s))
  578. .collect(Collectors.toList());
  579. List<User> users = userRepo.findByPhoneInAndDelFalse(phone);
  580. Map<String, Object> map = new HashMap<>();
  581. map.put("users", users);
  582. List<String> notFound = phone.stream().filter(p -> users.stream().noneMatch(u -> p.equals(u.getPhone())))
  583. .collect(Collectors.toList());
  584. map.put("notFound", notFound);
  585. return map;
  586. }
  587. public void addBankCard(Long userId, String bankNo, String phone, String code) throws BaseAdaPayException {
  588. User user = userRepo.findById(userId).orElseThrow(new BusinessException("用户不存在"));
  589. IdentityAuth identityAuth = identityAuthRepo
  590. .findFirstByUserIdAndStatusAndDelFalseOrderByCreatedAtDesc(userId, AuthStatus.SUCCESS)
  591. .orElseThrow(new BusinessException("用户未认证"));
  592. if (identityAuth.isOrg()) {
  593. //throw new BusinessException("企业认证用户请绑定对公账户");
  594. }
  595. if (!StringUtils.isBlank(user.getSettleAccountId())) {
  596. throw new BusinessException("此账号已绑定");
  597. }
  598. BankValidate bankValidate = BankUtils.validate(bankNo);
  599. if (!bankValidate.isValidated()) {
  600. throw new BusinessException("暂不支持此卡");
  601. }
  602. smsService.verify(phone, code);
  603. // adapayMerchantService.createMemberForAll(userId.toString(), user.getPhone(), identityAuth.getRealName(), identityAuth.getIdNo());
  604. // user.setMemberId(user.getId().toString());
  605. // save(user);
  606. //
  607. // String accountId = adapayMerchantService.createSettleAccountForAll
  608. // (user.getMemberId(), identityAuth.getRealName(),
  609. // identityAuth.getIdNo(), phone, bankNo);
  610. // user.setSettleAccountId(Optional.ofNullable(accountId).orElse("1"));
  611. // save(user);
  612. user.setMemberId(user.getId().toString());
  613. user.setSettleAccountId("1");
  614. save(user);
  615. userBankCardRepo.save(UserBankCard.builder()
  616. .bank(bankValidate.getBank())
  617. .bankName(bankValidate.getBankName())
  618. .bankNo(bankNo)
  619. .cardType(bankValidate.getCardType())
  620. .cardTypeDesc(bankValidate.getCardTypeDesc())
  621. .userId(userId)
  622. .phone(phone)
  623. .realName(identityAuth.getRealName())
  624. .idNo(identityAuth.getIdNo())
  625. .build());
  626. userBalanceRepo.unlock(userId);
  627. }
  628. public void removeBankCard(Long userId) throws BaseAdaPayException {
  629. User user = userRepo.findById(userId).orElseThrow(new BusinessException("用户不存在"));
  630. // if (StringUtils.isNotBlank(user.getSettleAccountId()) && StringUtils.isNotBlank(user.getMemberId())) {
  631. // adapayMerchantService.delSettleAccountForAll(user.getMemberId());
  632. // user.setSettleAccountId(null);
  633. // save(user);
  634. // userBankCardRepo.deleteByUserId(userId);
  635. // cacheService.clearUserMy(userId);
  636. // } else {
  637. // throw new BusinessException("未绑定");
  638. // }
  639. user.setSettleAccountId(null);
  640. save(user);
  641. userBankCardRepo.deleteByUserId(userId);
  642. cacheService.clearUserMy(userId);
  643. }
  644. public void removeAuth(Long userId) {
  645. User user = userRepo.findById(userId).orElseThrow(new BusinessException("用户不存在"));
  646. if (user.getAuthStatus() == AuthStatus.SUCCESS) {
  647. user.setAuthStatus(AuthStatus.NOT_AUTH);
  648. save(user);
  649. identityAuthRepo.deleteAll(identityAuthRepo.findByUserIdAndDelFalse(userId));
  650. cacheService.clearUserMy(userId);
  651. }
  652. }
  653. public Map<String, Object> batchRegister(String phones, String defaultPassword) {
  654. List<String> exist = new ArrayList<>();
  655. List<String> err = new ArrayList<>();
  656. List<String> success = new ArrayList<>();
  657. Arrays.stream(phones.replaceAll(",", " ")
  658. .replaceAll(",", " ")
  659. .replaceAll("\n", " ")
  660. .replaceAll("\r\n", " ")
  661. .split(" ")).forEach(phone -> {
  662. if (userRepo.findByPhoneAndDelFalse(phone).isPresent()) {
  663. exist.add(phone);
  664. } else {
  665. if (!Pattern.matches("^1[3-9]\\d{9}$", phone)) {
  666. err.add(phone);
  667. } else {
  668. try {
  669. String name = "0x" + RandomStringUtils.randomAlphabetic(8);
  670. User user = create(UserRegister.builder()
  671. .authorities(Collections.singleton(Authority.get(AuthorityName.ROLE_USER)))
  672. .username(name)
  673. .nickname(name)
  674. .password(defaultPassword)
  675. .avatar(Constants.DEFAULT_AVATAR)
  676. .phone(phone)
  677. .build());
  678. success.add(phone);
  679. } catch (Exception e) {
  680. log.error("注册失败", e);
  681. err.add(phone);
  682. }
  683. }
  684. }
  685. });
  686. Map<String, Object> map = new HashMap<>();
  687. map.put("exist", exist);
  688. map.put("error", err);
  689. map.put("success", success);
  690. return map;
  691. }
  692. public Map<String, Object> invite(PageQuery pageQuery) {
  693. Page<User> all = this.all(pageQuery).toPage();
  694. List<Long> userIds = all.map(User::getId).getContent();
  695. List<TokenHistory> page = tokenHistoryRepo.userBuy(userIds);
  696. Map<Long, BigDecimal> buy = page.stream()
  697. .collect(Collectors.groupingBy(TokenHistory::getToUserId,
  698. Collectors.mapping(TokenHistory::getPrice,
  699. Collectors.reducing(BigDecimal.ZERO, BigDecimal::add))));
  700. Page<InvitePhoneDTO> users = all.map(user -> {
  701. InvitePhoneDTO dto = new InvitePhoneDTO(user);
  702. dto.setTotal(buy.get(user.getId()) == null ? BigDecimal.ZERO : buy.get(user.getId()));
  703. return dto;
  704. });
  705. BigDecimal total = buy.values().stream().reduce(BigDecimal.ZERO, BigDecimal::add);
  706. Map<String, Object> map = new HashMap<>();
  707. map.put("user", users);
  708. map.put("total", total);
  709. return map;
  710. }
  711. @Async
  712. public void checkSettleAccountAsync() {
  713. checkSettleAccount();
  714. }
  715. public void checkSettleAccount() {
  716. List<User> list = userRepo.findBySettleAccountIdIsNotNull();
  717. AtomicInteger count = new AtomicInteger();
  718. list.forEach(user -> {
  719. try {
  720. Thread.sleep(500);
  721. IdentityAuth identityAuth = identityAuthRepo
  722. .findFirstByUserIdAndStatusAndDelFalseOrderByCreatedAtDesc(user.getId(), AuthStatus.SUCCESS)
  723. .orElseThrow(new BusinessException("用户未认证"));
  724. UserBankCard userBankCard = userBankCardRepo.findByUserId(user.getId()).stream().findAny()
  725. .orElseThrow(new BusinessException("未绑卡"));
  726. adapayMerchantService.createMemberForAll(
  727. user.getId().toString(), Optional.ofNullable(userBankCard.getPhone()).orElse(user.getPhone()),
  728. identityAuth.getRealName(), identityAuth.getIdNo());
  729. adapayMerchantService.createSettleAccountForAll(
  730. user.getId().toString(), identityAuth.getRealName(),
  731. identityAuth.getIdNo(), Optional.ofNullable(userBankCard.getPhone()).orElse(user.getPhone()),
  732. userBankCard.getBankNo());
  733. userBankCard.setPhone(Optional.ofNullable(userBankCard.getPhone()).orElse(user.getPhone()));
  734. userBankCardRepo.save(userBankCard);
  735. } catch (Exception e) {
  736. user.setSettleAccountId(null);
  737. save(user);
  738. userBankCardRepo.deleteByUserId(user.getId());
  739. }
  740. count.getAndIncrement();
  741. log.info("checkSettleAccount {}/{}", count.get(), list.size());
  742. });
  743. }
  744. @Cacheable(value = "myUserInfo", key = "#id")
  745. public User my(Long id) {
  746. User user = userRepo.findById(id).orElseThrow(new BusinessException("用户不存在"));
  747. user.setPassword(null);
  748. user.setTradeCode(null);
  749. return user;
  750. }
  751. public Page<Minter> toMinterDTO(Page<User> users) {
  752. List<User> origins = users.getContent();
  753. List<Minter> minters = new ArrayList<>();
  754. origins.forEach(user -> {
  755. Minter minter = Minter.builder()
  756. .id(user.getId())
  757. .name(user.getNickname())
  758. .avatar(user.getAvatar())
  759. .build();
  760. minters.add(minter);
  761. });
  762. return new PageImpl<>(minters, users.getPageable(), users.getTotalElements());
  763. }
  764. @Async
  765. public List<User> scanWeakPassword() {
  766. String[] weakPass = new String[]{
  767. "000000", "111111", "11111111", "112233", "123123", "123321", "123456", "12345678", "654321", "666666",
  768. "888888", "abcdef", "abcabc", "abc123", "a1b2c3", "aaa111", "123qwe", "qwerty", "qweasd", "admin",
  769. "password", "p@ssword", "passwd", "iloveyou", "5201314", "asdfghjkl", "66666666", "88888888"};
  770. boolean hasNext = true;
  771. int pageNum = 0;
  772. List<User> list = new ArrayList<>();
  773. while (hasNext) {
  774. Page<User> page = userRepo.findAll((Specification<User>) (root, query, criteriaBuilder) ->
  775. criteriaBuilder.isNotNull(root.get("password")), PageRequest.of(pageNum++, 200, Sort.by("id")));
  776. page.getContent().parallelStream().forEach(user -> {
  777. BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
  778. boolean match = false;
  779. for (String pass : weakPass) {
  780. if (encoder.matches(pass, user.getPassword())) {
  781. match = true;
  782. log.info("检测到弱密码userId={}, pass={}", user.getId(), pass);
  783. weakPassRepo.save(new WeakPass(user.getId(), pass));
  784. user.setPassword(null);
  785. save(user);
  786. redisTemplate.opsForValue().set(RedisKeys.JWT_TOKEN + user.getId(), "1");
  787. break;
  788. }
  789. }
  790. if (match) {
  791. list.add(user);
  792. }
  793. });
  794. hasNext = page.hasNext();
  795. }
  796. return list;
  797. }
  798. public List<InvitorDTO> findInviteOrderByCount(Long collectionId) {
  799. redisTemplate.opsForValue().get(RedisKeys.INVITOR_LIST + collectionId);
  800. List<InvitorDTO> dtos;
  801. dtos = JSONObject.parseArray((String) redisTemplate.opsForValue()
  802. .get(RedisKeys.INVITOR_LIST + collectionId), InvitorDTO.class);
  803. if (dtos == null) {
  804. dtos = new ArrayList<>();
  805. List<Object[]> objects = userRepo.customSearch(collectionId);
  806. for (Object[] object : objects) {
  807. InvitorDTO invitorDTO = new InvitorDTO((BigInteger) object[0], (String) object[1], (BigInteger) object[2]);
  808. dtos.add(invitorDTO);
  809. }
  810. redisTemplate.opsForValue()
  811. .set(RedisKeys.INVITOR_LIST + collectionId, JSONObject.toJSONString(dtos), Duration
  812. .ofSeconds(60 * 10));
  813. }
  814. return dtos;
  815. }
  816. public InvitorDetailDTO findMyInviteRecord(Long userId, Long collectionId) {
  817. InvitorDetailDTO result = new InvitorDetailDTO();
  818. // if (!SecurityUtils.getAuthenticatedUser().getId().equals(userId)) {
  819. // throw new BusinessException("无法查询他人邀请记录");
  820. // }
  821. List<InvitorDTO> invitorDTOS = findInviteOrderByCount(collectionId);
  822. InvitorDTO dto = invitorDTOS.stream()
  823. .filter(invitorDTO -> invitorDTO.getUserId().equals(BigInteger.valueOf(userId)))
  824. .findFirst().orElse(null);
  825. if (dto != null) {
  826. result.setIndex(invitorDTOS.indexOf(dto) + 1);
  827. result.setUserId(BigInteger.valueOf(userId));
  828. result.setNickName(dto.getNickName());
  829. if (result.getIndex() != 1) {
  830. result.setLastCount(invitorDTOS.get(invitorDTOS.indexOf(dto) - 1).getCount());
  831. }
  832. } else {
  833. result.setUserId(BigInteger.valueOf(userId));
  834. result.setNickName(SecurityUtils.getAuthenticatedUser().getNickname());
  835. }
  836. List<InvitedUserDTO> invitedUserDTOS = userRepo.findInvitedDTO(collectionId, userId);
  837. result.setInvitedUserDTOS(invitedUserDTOS);
  838. result.setCount(BigInteger.valueOf(invitedUserDTOS.size()));
  839. return result;
  840. }
  841. public void enableWallet(Long userId) {
  842. User user = userRepo.findById(userId).orElseThrow(new BusinessException("用户不存在"));
  843. if (user.isWalletEnabled()) {
  844. return;
  845. }
  846. if (!sysConfigService.getBoolean("enable_wallet")) {
  847. throw new BusinessException("绿魔卡功能暂未开启");
  848. }
  849. IdentityAuth identityAuth = identityAuthRepo.findByUserId(userId).stream().findFirst().orElse(null);
  850. if (identityAuth == null) {
  851. throw new BusinessException("请先完成实名认证");
  852. }
  853. // long age = ChronoUnit.YEARS.between(LocalDate.parse(identityAuth.getIdNo().substring(6, 14),
  854. // DateTimeFormatter.ofPattern("yyyyMMdd")), LocalDate.now());
  855. // if (!((age >= 22 && age <= 55))) {
  856. // throw new BusinessException("仅22至55周岁藏家可申请绿魔卡");
  857. // }
  858. // BigDecimal amount = sysConfigService.getBigDecimal("wallet_enable_amount");
  859. // if (Optional.ofNullable(orderRepo.sumUserPrice(userId)).orElse(BigDecimal.ZERO).compareTo(amount) < 0) {
  860. // throw new BusinessException("申请绿魔卡需满" + amount + "绿洲石");
  861. // }
  862. user.setWalletEnabled(true);
  863. save(user);
  864. }
  865. public Page<CompanyDTO> companyList(PageQuery pageQuery) {
  866. Page<User> users = this.all(pageQuery).toPage();
  867. List<Map<String, Object>> companyNums = showroomRepo.countNum("COMPANY");
  868. Map<Long, Integer> showroomNum = new HashMap<>();
  869. companyNums.forEach(value -> showroomNum.put(Convert.convert(Long.class, value.get("user_id")),
  870. Convert.convert(Integer.class, value.get("num"))));
  871. List<Map<String, Object>> companyBoxNums = showroomRepo.countNum("COMPANY_BOX");
  872. Map<Long, Integer> boxNum = new HashMap<>();
  873. companyBoxNums.forEach(value -> boxNum.put(Convert.convert(Long.class, value.get("user_id")),
  874. Convert.convert(Integer.class, value.get("num"))));
  875. return users.map(user -> {
  876. CompanyDTO dto = new CompanyDTO(user);
  877. dto.setShowroomNum(showroomNum.get(user.getId()) == null ? 0 : showroomNum.get(user.getId()));
  878. dto.setBoxShowroomNum(boxNum.get(user.getId()) == null ? 0 : boxNum.get(user.getId()));
  879. return dto;
  880. });
  881. }
  882. public Object loginTrading(String phone, String password, String tradeCode) {
  883. if (StringUtils.isEmpty(phone)) {
  884. throw new BusinessException("手机号错误");
  885. }
  886. User user = userRepo.findByPhoneAndDelFalse(phone).orElseThrow(new BusinessException("账号或密码错误"));
  887. TradingAccount tradingAccount = tradingAccountRepo.findById(user.getId())
  888. .orElseThrow(new BusinessException("账号或密码错误"));
  889. if (StringUtils.isEmpty(user.getPassword())) {
  890. throw new BusinessException("账号或密码错误");
  891. }
  892. if (StringUtils.isNoneEmpty(user.getPassword()) &&
  893. !passwordEncoder.matches(password, user.getPassword())) {
  894. throw new BusinessException("账号或密码错误");
  895. }
  896. if (StringUtils.isNoneEmpty(user.getPassword()) &&
  897. !passwordEncoder.matches(tradeCode, user.getTradeCode())) {
  898. throw new BusinessException("支付密码错误");
  899. }
  900. Map<String, Object> map = new HashMap<>();
  901. map.put("user", user);
  902. map.put("token", jwtTokenUtil.generateToken(JwtUserFactory.create(user)));
  903. map.put("account", tradingAccount);
  904. return map;
  905. }
  906. public Object myTrading(Long id) {
  907. User user = userRepo.findById(id).orElseThrow(new BusinessException("账号或密码错误"));
  908. TradingAccount tradingAccount = tradingAccountRepo.findById(user.getId())
  909. .orElseThrow(new BusinessException("账号或密码错误"));
  910. Map<String, Object> map = new HashMap<>();
  911. map.put("user", user);
  912. map.put("account", tradingAccount);
  913. return map;
  914. }
  915. public String prepareAliAuth(String type, Long userId, String name, String no) throws AlipayApiException {
  916. Long id = snowflakeIdWorker.nextId();
  917. AlipayUserCertifyOpenInitializeRequest request = new AlipayUserCertifyOpenInitializeRequest();
  918. JSONObject biz = new JSONObject();
  919. biz.put("outer_order_no", id + "");
  920. biz.put("biz_code", "FACE");
  921. JSONObject identity_param = new JSONObject();
  922. identity_param.put("identity_type", "CERT_INFO");
  923. identity_param.put("cert_type", type);
  924. identity_param.put("cert_name", name);
  925. identity_param.put("cert_no", no);
  926. biz.put("identity_param", identity_param);
  927. JSONObject merchant_config = new JSONObject();
  928. merchant_config.put("return_url", "alipays://platformapi/startapp?appId=20000067&url=" +
  929. URLEncoder.encode(generalProperties.getHost() + "/user/faceAuthNotify/" + id, StandardCharsets.UTF_8));
  930. biz.put("merchant_config", merchant_config);
  931. log.info(JSON.toJSONString(biz, true));
  932. request.setBizContent(biz.toJSONString());
  933. AlipayUserCertifyOpenInitializeResponse response = alipayClient.execute(request);
  934. if (response.isSuccess()) {
  935. String certifyId = response.getCertifyId();
  936. faceAuthRepo.save(FaceAuth.builder()
  937. .id(id)
  938. .userId(userId)
  939. .name(name)
  940. .idNo(no)
  941. .certifyId(certifyId)
  942. .build());
  943. return certifyId;
  944. }
  945. throw new BusinessException(response.getMsg());
  946. }
  947. public String getAliAuthUrl(String certify_id) throws AlipayApiException {
  948. AlipayUserCertifyOpenCertifyRequest request = new AlipayUserCertifyOpenCertifyRequest();
  949. JSONObject bizContentObj = new JSONObject();
  950. bizContentObj.put("certify_id", certify_id);
  951. request.setBizContent(bizContentObj.toString());
  952. AlipayUserCertifyOpenCertifyResponse response = alipayClient.pageExecute(request, "GET");
  953. if (response.isSuccess()) {
  954. return response.getBody();
  955. }
  956. throw new BusinessException(response.getMsg());
  957. }
  958. public User oneKeyLogin(String umengKey, String token) {
  959. String phone = UmengUtils.getMobile(umengKey, token);
  960. if (StringUtils.isBlank(phone)) {
  961. throw new BusinessException("登录失败,请尝试其他方式");
  962. }
  963. User user = userRepo.findByPhoneAndDelFalse(phone).orElse(null);
  964. if (user == null) {
  965. String name = "0x" + RandomStringUtils.randomAlphabetic(8);
  966. user = create(UserRegister.builder()
  967. .authorities(Collections.singleton(Authority.get(AuthorityName.ROLE_USER)))
  968. .username(name)
  969. .nickname(name)
  970. .avatar(Constants.DEFAULT_AVATAR)
  971. .phone(phone)
  972. .build());
  973. }
  974. return user;
  975. }
  976. public Map<String, Object> checkFaceAuth(String certifyId) throws AlipayApiException {
  977. AlipayUserCertifyOpenQueryRequest request = new AlipayUserCertifyOpenQueryRequest();
  978. JSONObject biz = new JSONObject();
  979. biz.put("certify_id", certifyId);
  980. request.setBizContent(biz.toJSONString());
  981. AlipayUserCertifyOpenQueryResponse response = alipayClient.execute(request);
  982. Map<String, Object> map = new HashMap<>();
  983. if (response.isSuccess()) {
  984. System.out.println("调用成功");
  985. } else {
  986. System.out.println("调用失败");
  987. }
  988. return map;
  989. }
  990. public void faceAuthNotify(Long id) {
  991. faceAuthRepo.findById(id).ifPresent(faceAuth -> {
  992. try {
  993. AlipayUserCertifyOpenQueryRequest request = new AlipayUserCertifyOpenQueryRequest();
  994. JSONObject biz = new JSONObject();
  995. biz.put("certify_id", faceAuth.getCertifyId());
  996. request.setBizContent(biz.toJSONString());
  997. AlipayUserCertifyOpenQueryResponse response = alipayClient.execute(request);
  998. if (response.isSuccess()) {
  999. JSONObject res = JSONObject.parseObject(response.getBody());
  1000. JSONObject data = res.getJSONObject("alipay_user_certify_open_query_response");
  1001. if (StringUtils.equals(data.getString("passed"), "T")) {
  1002. User user = userRepo.findById(faceAuth.getUserId()).orElse(null);
  1003. if (user != null) {
  1004. IdentityAuth identityAuth = identityAuthRepo.save(IdentityAuth.builder()
  1005. .userId(user.getId())
  1006. .idNo(faceAuth.getIdNo())
  1007. .realName(faceAuth.getName())
  1008. .status(AuthStatus.SUCCESS)
  1009. .build());
  1010. identityAuthRepo.deleteDuplicated(user.getId(), identityAuth.getId());
  1011. user.setAuthStatus(AuthStatus.SUCCESS);
  1012. user.setAuthId(identityAuth.getId());
  1013. save(user);
  1014. }
  1015. }
  1016. }
  1017. } catch (AlipayApiException e) {
  1018. throw new RuntimeException(e);
  1019. }
  1020. });
  1021. }
  1022. public Map<String, Object> oasisInfo(Long userId) {
  1023. Map<String, Object> map = new HashMap<>();
  1024. User user = userRepo.findById(userId).orElseThrow(new BusinessException("未找到用户信息"));
  1025. map.put("nickName", user.getNickname());
  1026. List<Asset> assets = assetRepo.findAllByOwnerIdAndStatusAndOasisIdNotNull(userId, AssetStatus.NORMAL);
  1027. List<OasisLoginDTO> oasisLoginDTOS = new ArrayList<>();
  1028. assets.forEach(asset -> {
  1029. OasisLoginDTO oasisLoginDTO = new OasisLoginDTO();
  1030. oasisLoginDTO.setOasisId(asset.getOasisId());
  1031. oasisLoginDTO.setAssetId(asset.getId());
  1032. oasisLoginDTO.setSource(asset.getStatus().getDescription());
  1033. Collection collection = collectionRepo.findFirstByOnShelfAndAssetId(true, asset.getId());
  1034. if (collection != null) {
  1035. oasisLoginDTO.setUrl(generalProperties.getHost() + "/9th/productDetail/" + collection
  1036. .getId() + "?id=" + collection.getId());
  1037. } else {
  1038. oasisLoginDTO.setUrl("未公开展示");
  1039. }
  1040. Showroom showroom = showroomRepo.findByOasisId(oasisLoginDTO.getOasisId())
  1041. .orElseThrow(new BusinessException("无记录 "));
  1042. List<ShowCollection> origin = showCollectionRepo.findAllByShowroomIdOrderBySort(showroom.getId());
  1043. List<ShowCollection> neo = new ArrayList<>();
  1044. if (origin != null) {
  1045. origin.forEach(orig -> collectionRepo.findById(orig.getCollectionId())
  1046. .ifPresent(collection1 -> {
  1047. orig.setStatus(showroomService.getStatus(collection1));
  1048. orig.setPrice(collection1.getPrice());
  1049. neo.add(orig);
  1050. }));
  1051. }
  1052. showroom.setCollections(neo);
  1053. User showRoomUser = SecurityUtils.getAuthenticatedUser();
  1054. if (showRoomUser != null && !showRoomUser.isAdmin()) {
  1055. List<NewsLike> likes = newsLikeRepo.findByUserIdAndShowroomId(showRoomUser
  1056. .getId(), showroom.getId());
  1057. showroom.setLiked(CollUtil.isNotEmpty(likes));
  1058. }
  1059. oasisLoginDTO.setShowroom(showroom);
  1060. oasisLoginDTOS.add(oasisLoginDTO);
  1061. });
  1062. map.put("oasisInfo", oasisLoginDTOS);
  1063. map.put("avatar", SecurityUtils.getAuthenticatedUser().getAvatar());
  1064. return map;
  1065. }
  1066. /**
  1067. * 流拍5次直接删号处罚
  1068. */
  1069. @Scheduled(cron = "0 0/10 * * * ?")
  1070. public void delUser() {
  1071. List<Long> userIds = auctionPassRecordRepo.checkUserId();
  1072. if (CollUtil.isNotEmpty(userIds)) {
  1073. log.info("流拍处罚:{}", userIds);
  1074. userRepo.softDeleteIn(userIds);
  1075. //清缓存
  1076. userIds.forEach(id -> {
  1077. cacheService.clearUserMy(id);
  1078. cacheService.clearUser(id);
  1079. });
  1080. }
  1081. }
  1082. public void savePoint(User user) {
  1083. //给积分
  1084. Long invitor = user.getCollectionInvitor();
  1085. if (ObjectUtils.isEmpty(user.getCollectionId()) || ObjectUtils.isEmpty(invitor)) {
  1086. return;
  1087. }
  1088. Collection collection = collectionRepo.findById(user.getCollectionId()).orElse(null);
  1089. if (collection == null) {
  1090. return;
  1091. }
  1092. if (user.getVipPoint() < 1) {
  1093. //有效新用户1个限购
  1094. user.setVipPoint(100);
  1095. userRepo.save(user);
  1096. cacheService.clearUserMy(user.getId());
  1097. cacheService.clearUser(user.getId());
  1098. }
  1099. //指标数量
  1100. int assignment = collection.getAssignment();
  1101. if (assignment < 1) {
  1102. return;
  1103. }
  1104. int inviteNum = userRepo.countAllByCollectionIdAndCollectionInvitorAndSettleAccountIdIsNotNull(
  1105. user.getCollectionId(), invitor);
  1106. int point = inviteNum / assignment;
  1107. if (point < 1) {
  1108. return;
  1109. }
  1110. User parent = userRepo.findById(invitor).orElse(null);
  1111. if (parent == null) {
  1112. return;
  1113. }
  1114. if (parent.getVipPoint() < 1) {
  1115. //老用户可有一个限购
  1116. parent.setVipPoint(100);
  1117. userRepo.save(parent);
  1118. cacheService.clearUserMy(user.getId());
  1119. cacheService.clearUser(user.getId());
  1120. }
  1121. UserProperty userProperty = userPropertyRepo.findById(invitor).orElse(new UserProperty(invitor, 0));
  1122. if (userProperty.getMaxCount() < 10 && userProperty.getMaxCount() != point) {
  1123. userProperty.setMaxCount(point);
  1124. userPropertyRepo.save(userProperty);
  1125. }
  1126. }
  1127. }