UsersService.java 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638
  1. package com.qxgmat.service;
  2. import com.github.pagehelper.Page;
  3. import com.nuliji.tools.AbstractService;
  4. import com.nuliji.tools.CipherHelp;
  5. import com.nuliji.tools.Tools;
  6. import com.nuliji.tools.Transform;
  7. import com.nuliji.tools.exception.AuthException;
  8. import com.nuliji.tools.exception.ParameterException;
  9. import com.nuliji.tools.exception.SystemException;
  10. import com.nuliji.tools.mybatis.Example;
  11. import com.nuliji.tools.mybatis.NativeJsonHandler;
  12. import com.nuliji.tools.third.OauthData;
  13. import com.qxgmat.data.constants.enums.status.DirectionStatus;
  14. import com.qxgmat.data.constants.enums.user.PrepareExaminationTime;
  15. import com.qxgmat.data.dao.UserMapper;
  16. import com.qxgmat.data.dao.entity.User;
  17. import com.qxgmat.data.dao.entity.UserOrder;
  18. import com.qxgmat.data.inline.UserToken;
  19. import com.qxgmat.data.relation.UserRelationMapper;
  20. import com.qxgmat.data.relation.entity.UserPrepareRelation;
  21. import com.qxgmat.help.WechatHelp;
  22. import com.qxgmat.service.extend.MessageExtendService;
  23. import com.qxgmat.service.extend.OrderFlowService;
  24. import com.qxgmat.service.inline.UserCourseService;
  25. import com.qxgmat.service.inline.UserMessageService;
  26. import com.qxgmat.service.inline.UserOrderService;
  27. import org.hibernate.criterion.Order;
  28. import org.springframework.beans.factory.annotation.Value;
  29. import org.springframework.stereotype.Service;
  30. import org.springframework.transaction.annotation.Transactional;
  31. import javax.annotation.Resource;
  32. import java.math.BigDecimal;
  33. import java.util.*;
  34. /**
  35. * Created by GaoJie on 2017/11/1.
  36. */
  37. @Service
  38. public class UsersService extends AbstractService {
  39. final public String PLATORM_WECHAT_NATIVE = "wechatOpenidWechat";
  40. final public String PLATORM_WECHAT_PC = "wechatOpenidPc";
  41. final public String PLATORM_WECHAT = "wechatUnionid";
  42. @Value("${self.secret}")
  43. private String secret;
  44. private NativeJsonHandler<UserToken> tokenHandler = new NativeJsonHandler<UserToken>(UserToken.class);
  45. @Resource
  46. private UserMapper userMapper;
  47. @Resource
  48. private WechatHelp wechatHelp;
  49. @Resource
  50. private UserRelationMapper userRelationMapper;
  51. @Resource
  52. private OrderFlowService orderFlowService;
  53. @Resource
  54. private MessageExtendService messageExtendService;
  55. /**
  56. * 生成有效期token
  57. * @param user
  58. * @return
  59. */
  60. public String getTokenByUser(User user){
  61. UserToken ut = new UserToken();
  62. ut.setId(user.getId());
  63. Date expire = new Date(new Date().getTime() + 86400);
  64. ut.setExpire(expire);
  65. String info = tokenHandler.toJson(ut);
  66. return CipherHelp.encrypt(info, CipherHelp.DES, secret);
  67. }
  68. /**
  69. * 解析有效期token
  70. * @param token
  71. * @return
  72. */
  73. public User getUserByToken(String token){
  74. // 默认测试token
  75. if (token.equals("1234567890")){
  76. return get(1);
  77. }else{
  78. String info = CipherHelp.decrypt(token, CipherHelp.DES, secret);
  79. UserToken ut = tokenHandler.toObject(info);
  80. Date expire = ut.getExpire();
  81. if (expire.before(new Date())){
  82. throw new AuthException("token错误");
  83. }
  84. return get(ut.getId());
  85. }
  86. }
  87. /**
  88. * 绑定第三方账号信息
  89. * @param user 当前登录用户
  90. * @param code
  91. * @param platform
  92. * @return
  93. */
  94. @Transactional
  95. public User Oauth(User user, String code, String platform, boolean userInfo){
  96. OauthData data;
  97. switch(platform){
  98. case "wechat_pc":
  99. data = wechatHelp.oauthPc(code, userInfo);
  100. break;
  101. case "wechat_native":
  102. data = wechatHelp.oauthNative(code, userInfo);
  103. break;
  104. default:
  105. throw new ParameterException("第三方平台"+platform+"不支持");
  106. }
  107. User openUser = getByOpen(data.getOpenId(), data.getUnionId(), platform);
  108. // 获取已关联的账号
  109. if (user != null && user.getId() != null){
  110. // 检验是否已经绑定
  111. if(openUser != null && !openUser.getId().equals(user.getId())){
  112. // // 自动合并账号
  113. // // 更新消息
  114. // userMessageService.mergeUser(openUser.getId(), user.getId());
  115. // // 更新消费记录
  116. // userOrderService.mergeUser(openUser.getId(), user.getId());
  117. // // 更新课程信息
  118. // userCourseService.mergeUser(openUser.getId(), user.getId());
  119. // // 更新服务信息
  120. // userServiceService.mergeUser(openUser.getId(), user.getId());
  121. //
  122. // // 更新实名认证
  123. // if (openUser.getRealStatus() > 0){
  124. // user.setRealAddress(openUser.getRealAddress());
  125. // user.setRealIdentity(openUser.getRealIdentity());
  126. // user.setRealName(openUser.getRealName());
  127. // user.setRealPhotoFront(openUser.getRealPhotoFront());
  128. // user.setRealPhotoBack(openUser.getRealPhotoBack());
  129. // user.setRealStatus(openUser.getRealStatus());
  130. // }
  131. //
  132. // // 删除旧账号
  133. // delete(openUser.getId());
  134. throw new ParameterException("该微信账户已绑定其他手机号,您可直接使用微信登录");
  135. }
  136. }
  137. User mm = User.builder().build();
  138. if (openUser ==null || openUser.getAvatar() == null || openUser.getAvatar().isEmpty()) {
  139. mm.setAvatar(data.getAvatar());
  140. if(openUser != null){
  141. openUser.setAvatar(data.getAvatar());
  142. }
  143. }
  144. if (openUser == null || openUser.getNickname() == null|| openUser.getNickname().isEmpty() || openUser.getNickname().equals("qx"+openUser.getMobile())){
  145. mm.setNickname(data.getNickName());
  146. if(openUser != null){
  147. openUser.setNickname(data.getNickName());
  148. }
  149. }
  150. switch(platform){
  151. case "wechat_pc":
  152. mm.setWechatOpenidPc(data.getOpenId());
  153. mm.setWechatUnionid(data.getUnionId());
  154. break;
  155. case "wechat_native":
  156. mm.setWechatOpenidWechat(data.getOpenId());
  157. mm.setWechatUnionid(data.getUnionId());
  158. mm.setWechatAccessToken(data.getAccessToken());
  159. mm.setWechatRefreshToken(data.getRefreshToken());
  160. mm.setWechatExpireTime(data.getExpiresTime());
  161. break;
  162. }
  163. if (openUser != null && openUser.getId() != null){
  164. // 直接更新数据
  165. mm.setId(openUser.getId());
  166. edit(mm);
  167. return openUser;
  168. }
  169. return mm;
  170. }
  171. /**
  172. * 通过手机号注册
  173. * @param mobile
  174. * @param inviteCode
  175. * @param openUser
  176. * @return
  177. */
  178. @Transactional
  179. public User register(String area, String mobile, String inviteCode, String email, User openUser, String registerIp, String[] registerInfo){
  180. boolean n = false;
  181. User user = getByMobile(area, mobile);
  182. if (user != null){
  183. if (openUser == null) {
  184. // 直接手机登录,异常抛出,根据情况忽略
  185. throw new ParameterException("手机号已注册");
  186. }else if(user.getWechatUnionid() != null && !user.getWechatUnionid().equals("")){
  187. // openUser不为空,则用于绑定微信
  188. throw new ParameterException("该手机已绑定其他账号,请更换手机号码");
  189. }
  190. user = User.builder().id(user.getId()).build();
  191. if (user.getRegisterIp() == null || user.getRegisterIp().isEmpty()){
  192. user.setRegisterIp(registerIp);
  193. user.setRegisterCity(registerInfo != null ? String.join(",",registerInfo) : "");
  194. user.setLatestLoginIp(registerIp);
  195. }
  196. }else{
  197. // 注册,并且绑定邀请者
  198. user = User.builder().area(area).mobile(mobile).email(email).build();
  199. n = true;
  200. if (inviteCode != null && !inviteCode.isEmpty()){
  201. User origin = getByInviteCode(inviteCode);
  202. user.setOriginId(origin.getId());
  203. edit(User.builder().id(origin.getId()).inviteNumber(origin.getInviteNumber() + 1).inviteLatestTime(new Date()).build());
  204. // 邀请奖励
  205. orderFlowService.giveInvite(origin);
  206. }
  207. // 生成邀请码: 10位字符串
  208. user.setInviteCode(Tools.getRandomString(10));
  209. user.setRegisterIp(registerIp);
  210. user.setRegisterCity(registerInfo != null ? String.join(",",registerInfo) : "");
  211. user.setLatestLoginIp(registerIp);
  212. user.setNickname("qx"+user.getMobile());
  213. }
  214. // 绑定第三方登录信息
  215. if (openUser != null){
  216. this.bind(user, openUser);
  217. }
  218. if (n){
  219. user = add(user);
  220. messageExtendService.sendRegister(user);
  221. }else{
  222. user = edit(user);
  223. }
  224. if(user == null)
  225. throw new SystemException("注册失败");
  226. return user;
  227. }
  228. public User bind(User user, User openUser){
  229. // 绑定第三方登录信息
  230. if(openUser.getWechatOpenidPc() != null) user.setWechatOpenidPc(openUser.getWechatOpenidPc());
  231. if(openUser.getWechatOpenidWechat() != null) user.setWechatOpenidWechat(openUser.getWechatOpenidWechat());
  232. if(openUser.getWechatExpireTime() != null) user.setWechatExpireTime(openUser.getWechatExpireTime());
  233. if(openUser.getWechatUnionid() != null) user.setWechatUnionid(openUser.getWechatUnionid());
  234. if(openUser.getWechatAccessToken() != null) user.setWechatAccessToken(openUser.getWechatAccessToken());
  235. if(openUser.getWechatRefreshToken() != null) user.setWechatRefreshToken(openUser.getWechatRefreshToken());
  236. if(openUser.getNickname() != null && (user.getNickname() == null || user.getNickname().isEmpty() || user.getNickname().equals("qx" + user.getMobile()))) user.setNickname(openUser.getNickname());
  237. if(openUser.getAvatar() != null && (user.getAvatar() == null || user.getAvatar().isEmpty())) user.setAvatar(openUser.getAvatar());
  238. return user;
  239. }
  240. // 获取微信快到期账号
  241. public Page<User> listByWechatExpire(int page, int size, Date expire){
  242. Example example = new Example(User.class);
  243. example.and(
  244. example.createCriteria()
  245. .andLessThan("wechatExpireTime", expire)
  246. );
  247. return page(()->select(userMapper, example), page, size);
  248. }
  249. // 通过手机号获取用户
  250. public User getByMobile(String area, String mobile){
  251. User user = User.builder().area(area).mobile(mobile).build();
  252. return one(userMapper, user);
  253. }
  254. // 通过邮箱获取用户
  255. public User getByEmail(String email){
  256. User user = User.builder().email(email).build();
  257. return one(userMapper, user);
  258. }
  259. // 通过身份证获取用户
  260. public User getByIdentity(String identity){
  261. User user = User.builder().realIdentity(identity).build();
  262. return one(userMapper, user);
  263. }
  264. // 通过openid获取用户
  265. public User getByOpen(String openId, String unionId, String platform){
  266. String platformField;
  267. String unionField;
  268. switch(platform){
  269. case "wechat_pc":
  270. platformField = PLATORM_WECHAT_PC;
  271. unionField = PLATORM_WECHAT;
  272. break;
  273. case "wechat_native":
  274. platformField = PLATORM_WECHAT_NATIVE;
  275. unionField = PLATORM_WECHAT;
  276. break;
  277. default:
  278. throw new ParameterException("第三方平台"+platform+"不支持");
  279. }
  280. Example example = new Example(User.class);
  281. example.or(
  282. example.createCriteria()
  283. .andEqualTo(platformField, openId)
  284. );
  285. if (unionId != null && !unionId.isEmpty()){
  286. example.or(
  287. example.createCriteria()
  288. .andEqualTo(unionField, unionId)
  289. );
  290. }
  291. return one(userMapper, example);
  292. }
  293. /**
  294. * 通过邀请码或者手机好获取邀请人
  295. * @param inviteCode
  296. * @return
  297. */
  298. public User getByInviteCode(String inviteCode){
  299. User user = new User();
  300. Example example = new Example(User.class);
  301. // 查找手机或邀请码
  302. example.and(
  303. example.createCriteria()
  304. .orEqualTo("inviteCode", inviteCode)
  305. .orEqualTo("mobile", inviteCode)
  306. );
  307. return one(userMapper, example);
  308. }
  309. /**
  310. * 获取备考统计:身份
  311. * @return
  312. */
  313. public List<UserPrepareRelation> statPrepareStatus(){
  314. return userRelationMapper.groupPrepareString("prepare_status");
  315. }
  316. /**
  317. * 获取备考统计:目标分数
  318. * @return
  319. */
  320. public List<UserPrepareRelation> statPrepareGoal(){
  321. List<UserPrepareRelation> relations = userRelationMapper.groupPrepareInteger("prepare_goal");
  322. // 按考分分组
  323. List<UserPrepareRelation> userPrepareRelationList = new ArrayList<>();
  324. Integer[] goalGroup = new Integer[]{600, 650, 700, 750};
  325. for(Integer goal : goalGroup){
  326. UserPrepareRelation real = new UserPrepareRelation();
  327. real.setI(goal);
  328. real.setNumber(0);
  329. userPrepareRelationList.add(real);
  330. }
  331. for(UserPrepareRelation relation : relations){
  332. int goal = -1;
  333. for(int i = 0; i < goalGroup.length; i++){
  334. // 根据考分判断层级
  335. if (goalGroup[i] > relation.getI()){
  336. // 属于上一层
  337. goal = i - 1;
  338. break;
  339. }
  340. }
  341. if (goal > 0){
  342. // 按层级归类
  343. UserPrepareRelation real = userPrepareRelationList.get(goal);
  344. real.setNumber(real.getNumber()+relation.getNumber());
  345. }
  346. }
  347. return userPrepareRelationList;
  348. }
  349. /**
  350. * 获取备考统计:考试时间
  351. * @return
  352. */
  353. public List<UserPrepareRelation> statPrepareExaminationTime(){
  354. return userRelationMapper.groupPrepareString("prepare_examination_time");
  355. }
  356. /**
  357. * 获取备考统计:出分时间
  358. * @return
  359. */
  360. public List<UserPrepareRelation> statPrepareScoreTime(){
  361. // 直接按不同时间段统计
  362. Example example;
  363. List<UserPrepareRelation> userPrepareRelationList = new ArrayList<>();
  364. Calendar calendar = Calendar.getInstance();
  365. // 一个月内
  366. calendar.setTime(new Date());
  367. calendar.add(Calendar.MONTH, 1);
  368. example = new Example(User.class);
  369. example.and(
  370. example.createCriteria()
  371. .andLessThan("prepareScoreTime", calendar.getTime())
  372. );
  373. UserPrepareRelation oneMonth = new UserPrepareRelation();
  374. oneMonth.setS(PrepareExaminationTime.ONE_MONTH.key);
  375. oneMonth.setNumber(count(userMapper, example));
  376. userPrepareRelationList.add(oneMonth);
  377. // 两个月内
  378. calendar.setTime(new Date());
  379. calendar.add(Calendar.MONTH, 2);
  380. example = new Example(User.class);
  381. example.and(
  382. example.createCriteria()
  383. .andLessThan("prepareScoreTime", calendar.getTime())
  384. );
  385. UserPrepareRelation twoMonth = new UserPrepareRelation();
  386. twoMonth.setS(PrepareExaminationTime.TWO_MONTH.key);
  387. twoMonth.setNumber(count(userMapper, example) - oneMonth.getNumber());
  388. userPrepareRelationList.add(twoMonth);
  389. // 三个月内
  390. calendar.setTime(new Date());
  391. calendar.add(Calendar.MONTH, 3);
  392. example = new Example(User.class);
  393. example.and(
  394. example.createCriteria()
  395. .andLessThan("prepareScoreTime", calendar.getTime())
  396. );
  397. UserPrepareRelation threeMonth = new UserPrepareRelation();
  398. threeMonth.setS(PrepareExaminationTime.THREE_MONTH.key);
  399. threeMonth.setNumber(count(userMapper, example) - twoMonth.getNumber());
  400. userPrepareRelationList.add(threeMonth);
  401. // 半年
  402. calendar.setTime(new Date());
  403. calendar.add(Calendar.MONTH, 6);
  404. example = new Example(User.class);
  405. example.and(
  406. example.createCriteria()
  407. .andLessThan("prepareScoreTime", calendar.getTime())
  408. );
  409. UserPrepareRelation sixMonth = new UserPrepareRelation();
  410. sixMonth.setS(PrepareExaminationTime.SIX_MONTH.key);
  411. sixMonth.setNumber(count(userMapper, example) - threeMonth.getNumber());
  412. userPrepareRelationList.add(sixMonth);
  413. // 一年
  414. calendar.setTime(new Date());
  415. calendar.add(Calendar.MONTH, 12);
  416. example = new Example(User.class);
  417. example.and(
  418. example.createCriteria()
  419. .andLessThan("prepareScoreTime", calendar.getTime())
  420. );
  421. UserPrepareRelation oneYear = new UserPrepareRelation();
  422. oneYear.setS(PrepareExaminationTime.ONE_YEAR.key);
  423. oneYear.setNumber(count(userMapper, example) - sixMonth.getNumber());
  424. userPrepareRelationList.add(oneYear);
  425. // 其他
  426. example = new Example(User.class);
  427. example.and(
  428. example.createCriteria()
  429. // 设置过备考信息的人:mapper中做为基本条件
  430. .andGreaterThan("prepareGoal", 0)
  431. .andIsNull("prepareScoreTime")
  432. );
  433. UserPrepareRelation other = new UserPrepareRelation();
  434. other.setS(PrepareExaminationTime.OTHER.key);
  435. other.setNumber(count(userMapper, example));
  436. userPrepareRelationList.add(other);
  437. return userPrepareRelationList;
  438. }
  439. private Map<String, String> adminMap = new HashMap<String, String>(){{
  440. put("", "u");
  441. }};
  442. /**
  443. * 获取购买过课程的用户
  444. * @param page
  445. * @param pageSize
  446. * @param keyword
  447. * @param courseId
  448. * @return
  449. */
  450. public Page<User> listAdminByCourse(int page, int pageSize, String keyword, Integer courseId, String order, DirectionStatus direction){
  451. if(order == null || order.isEmpty()){
  452. order = "id";
  453. }
  454. if(adminMap.containsKey(order)){
  455. order = adminMap.get(order)+".`"+Tools.underscoreName(order)+"`";
  456. }else{
  457. order = adminMap.get("")+".`"+Tools.underscoreName(order)+"`";
  458. }
  459. if (direction == null){
  460. direction = DirectionStatus.DESC;
  461. }
  462. String finalOrder = order;
  463. DirectionStatus finalDirection = direction;
  464. Page<User> p = page(()->{
  465. userRelationMapper.listByCourse(keyword, courseId, finalOrder, finalDirection.key);
  466. }, page, pageSize);
  467. Collection ids = Transform.getIds(p, User.class, "id");
  468. // 获取详细数据
  469. List<User> list = select(ids);
  470. Transform.replace(p, list, User.class, "id");
  471. return p;
  472. }
  473. /**
  474. * 获取总用户数
  475. * @return
  476. */
  477. public Integer count(){
  478. Example example = new Example(User.class);
  479. return count(userMapper, example);
  480. }
  481. /**
  482. * 累加支付金额
  483. * @param userId
  484. * @param money
  485. */
  486. public void accumulation(Integer userId, BigDecimal money){
  487. userRelationMapper.accumulation(userId, money);
  488. }
  489. public Page<User> listAdmin(int page, int pageSize, String keyword, Boolean real, Boolean wechat, Boolean prepare, Date startTime, Date endTime, String order, DirectionStatus direction){
  490. Example example = new Example(User.class);
  491. if(keyword != null)
  492. example.and(
  493. example.createCriteria()
  494. .orLike("id", "%"+keyword+"%")
  495. .orLike("mobile", "%"+keyword+"%")
  496. );
  497. if (real != null)
  498. example.and(
  499. example.createCriteria().andEqualTo("realStatus", real?1:0)
  500. );
  501. if (wechat != null)
  502. example.and(
  503. wechat ? example.createCriteria().andNotEqualTo("wechatUnionid", "") : example.createCriteria().andEqualTo("wechatUnionid", "")
  504. );
  505. if (prepare != null)
  506. example.and(
  507. prepare ? example.createCriteria().andIsNotNull("prepareTime"):example.createCriteria().andIsNull("prepareTime")
  508. );
  509. if (startTime != null){
  510. example.and(
  511. example.createCriteria().andGreaterThanOrEqualTo("createTime", startTime)
  512. );
  513. }
  514. if(endTime != null){
  515. example.and(
  516. example.createCriteria().andLessThan("createTime", endTime)
  517. );
  518. }
  519. if(order==null||order.isEmpty()) order = "id";
  520. if (direction != null){
  521. switch(direction){
  522. case ASC:
  523. example.orderBy(order).asc();
  524. break;
  525. case DESC:
  526. default:
  527. example.orderBy(order).desc();
  528. }
  529. } else {
  530. example.orderBy(order).desc();
  531. }
  532. return select(userMapper, example, page, pageSize);
  533. }
  534. public boolean equalsPassword(User user, String password){
  535. return Objects.equals(user.getPassword(), Tools.stringMD5(Tools.stringMD5(password)));
  536. }
  537. public boolean changePassword(User user, String password){
  538. User updateUser = User.builder().id(user.getId()).password(Tools.stringMD5(Tools.stringMD5(password))).build();
  539. int result = update(userMapper, updateUser);
  540. return result > 0;
  541. }
  542. public User add(User user){
  543. if(user.getPassword() != null) user.setPassword(Tools.stringMD5(user.getPassword()));
  544. int result = insert(userMapper, user);
  545. user = one(userMapper, user.getId());
  546. if(user == null){
  547. throw new SystemException("用户添加失败");
  548. }
  549. return user;
  550. }
  551. public User edit(User user){
  552. User in = one(userMapper, user.getId());
  553. if(in == null){
  554. throw new ParameterException("用户不存在");
  555. }
  556. if(user.getPassword() != null) user.setPassword(Tools.stringMD5(user.getPassword()));
  557. int result = update(userMapper, user);
  558. return user;
  559. }
  560. public boolean delete(Number id){
  561. User in = one(userMapper, id);
  562. if(in == null){
  563. throw new ParameterException("用户不存在");
  564. }
  565. int result = delete(userMapper, id);
  566. return result > 0;
  567. }
  568. public User get(Number id){
  569. User in = one(userMapper, id);
  570. if(in == null){
  571. throw new ParameterException("用户不存在");
  572. }
  573. return in;
  574. }
  575. public Page<User> select(int page, int pageSize){return select(userMapper, page, pageSize);
  576. }
  577. public Page<User> select(Integer[] ids){
  578. return page(()->select(userMapper, ids), 1, ids.length);
  579. }
  580. public List<User> select(Collection ids){
  581. return select(userMapper, ids);
  582. }
  583. }