QueryServiceImpl.java 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518
  1. package com.ruoyi.system.service.impl;
  2. import com.aliyuncs.dysmsapi.model.v20170525.QuerySendDetailsResponse;
  3. import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
  4. import com.aliyuncs.exceptions.ClientException;
  5. import com.ruoyi.common.constant.UserConstants;
  6. import com.ruoyi.common.core.domain.AjaxResult;
  7. import com.ruoyi.common.core.redis.RedisCache;
  8. import com.ruoyi.common.utils.DateUtils;
  9. import com.ruoyi.common.utils.QRCodeUtils;
  10. import com.ruoyi.common.utils.SendSmsUtils;
  11. import com.ruoyi.common.utils.StringUtils;
  12. import com.ruoyi.system.domain.MiniprogramQueryLog;
  13. import com.ruoyi.system.domain.QueryConfig;
  14. import com.ruoyi.system.domain.ReportDetail;
  15. import com.ruoyi.system.domain.ReportQueryLog;
  16. import com.ruoyi.system.mapper.MiniprogramQueryLogMapper;
  17. import com.ruoyi.system.mapper.QueryConfigMapper;
  18. import com.ruoyi.system.mapper.ReportDetailMapper;
  19. import com.ruoyi.system.mapper.ReportQueryLogMapper;
  20. import com.ruoyi.system.service.IQueryService;
  21. import org.springframework.beans.factory.annotation.Autowired;
  22. import org.springframework.beans.factory.annotation.Value;
  23. import org.springframework.stereotype.Service;
  24. import java.util.Calendar;
  25. import java.util.concurrent.TimeUnit;
  26. import static com.ruoyi.common.core.domain.AjaxResult.MSG_TAG;
  27. import static com.ruoyi.common.utils.SecurityUtils.getUsername;
  28. /**
  29. * @author tjf
  30. * @Date: 2021/12/27/11:37
  31. */
  32. @Service
  33. public class QueryServiceImpl implements IQueryService {
  34. @Autowired
  35. private ReportDetailMapper reportDetailMapper;
  36. @Autowired
  37. private ReportQueryLogMapper reportQueryLogMapper;
  38. @Autowired
  39. private RedisCache redisCache;
  40. @Autowired
  41. private QueryConfigMapper queryConfigMapper;
  42. @Autowired
  43. private MiniprogramQueryLogMapper miniprogramQueryLogMapper;
  44. //短信参数
  45. @Value("${sms_aliyun_accessKeyId}")
  46. String accessKeyId;// accessKeyId
  47. @Value("${sms_aliyun_accessKeySecret}")
  48. String accessKeySecret;// accessKeySecret
  49. @Value("${sms_aliyun_signName}")
  50. String signName;
  51. @Value("${sms_aliyun_templateCode}")
  52. String templateCode;
  53. @Value("${sms_aliyun_signNameQuery}")
  54. String signNameQuery;
  55. @Value("${sms_aliyun_templateCodeQuery}")
  56. String templateCodeQuery;
  57. /**
  58. * 门户查询报告信息
  59. *
  60. * @param reportQueryLog
  61. * @return
  62. */
  63. @Override
  64. public AjaxResult selectReport(ReportQueryLog reportQueryLog) {
  65. //通用校验
  66. AjaxResult validateResult = queryPublic(reportQueryLog,true);
  67. if (!UserConstants.QUERY_SUCCESS.equals(validateResult.get(MSG_TAG))) {
  68. return validateResult;
  69. }
  70. //获取查询方式
  71. String queryMode = reportQueryLog.getQueryMode();
  72. //二维码查询
  73. if (UserConstants.QUERY_MODE_QR.equals(queryMode)) {
  74. return queryByQr(reportQueryLog);
  75. //粗略查询
  76. } else if (UserConstants.QUERY_MODE_ROUGH.equals(queryMode)) {
  77. return queryByRough(reportQueryLog);
  78. //详细查询
  79. } else if (UserConstants.QUERY_MODE_DETAIL.equals(queryMode)) {
  80. return queryByDetail(reportQueryLog);
  81. }
  82. return AjaxResult.success();
  83. }
  84. /**
  85. * 小程序根据二维码查询
  86. * @param reportQueryLog
  87. * @return
  88. */
  89. @Override
  90. public AjaxResult queryQr(ReportQueryLog reportQueryLog) {
  91. String qrImage = reportQueryLog.getQrImage();
  92. String remark = "";
  93. if (StringUtils.isBlank(qrImage)) {
  94. remark = "未接收到二维码";
  95. return AjaxResult.error(remark);
  96. }
  97. try {
  98. //解析二维码
  99. String reportNumber = QRCodeUtils.decode(qrImage);
  100. if (StringUtils.isBlank(reportNumber)) {
  101. remark = "二维码解析失败";
  102. return AjaxResult.error(remark);
  103. }
  104. /* //查询二维码有效期
  105. String verifyKey = UserConstants.QR_IMAGE + reportNumber;
  106. Object cacheObject = redisCache.getCacheObject(verifyKey);
  107. if (cacheObject == null) {
  108. remark = "二维码已过期";
  109. reportQueryLog.setRemark(remark);
  110. reportQueryLogMapper.insertReportQueryLog(reportQueryLog);
  111. return AjaxResult.error(remark);
  112. }*/
  113. ReportDetail reportDetail = reportDetailMapper.selectReportDetailByReportNumber(reportNumber);
  114. if (reportDetail != null) {
  115. reportDetail.setReportUrl(null);
  116. MiniprogramQueryLog miniprogramQueryLog = new MiniprogramQueryLog();
  117. miniprogramQueryLog.setReportNumber(reportNumber);
  118. miniprogramQueryLog.setQueryPhone(reportQueryLog.getQueryPhone());
  119. miniprogramQueryLog.setCreateTime(DateUtils.getNowDate());
  120. miniprogramQueryLog.setCreateBy(reportQueryLog.getQueryPhone());
  121. miniprogramQueryLog.setQueryMode("1");
  122. miniprogramQueryLogMapper.insertMiniprogramQueryLog(miniprogramQueryLog);
  123. return AjaxResult.success(reportDetail);
  124. }
  125. } catch (Exception e) {
  126. e.printStackTrace();
  127. return AjaxResult.error("未查询到对应信息");
  128. }
  129. return AjaxResult.error("未查询到对应信息");
  130. }
  131. /**
  132. * 小程序根据编号查询
  133. * @param reportQueryLog
  134. * @return
  135. */
  136. @Override
  137. public AjaxResult queryReportNum(ReportQueryLog reportQueryLog) {
  138. String reportNumber = reportQueryLog.getReportNumber();
  139. ReportDetail reportDetail = reportDetailMapper.selectReportDetailByReportNumber(reportNumber);
  140. if (reportDetail != null) {
  141. reportDetail.setReportUrl(null);
  142. MiniprogramQueryLog miniprogramQueryLog = new MiniprogramQueryLog();
  143. miniprogramQueryLog.setReportNumber(reportNumber);
  144. miniprogramQueryLog.setQueryPhone(reportQueryLog.getQueryPhone());
  145. miniprogramQueryLog.setCreateTime(DateUtils.getNowDate());
  146. miniprogramQueryLog.setCreateBy(reportQueryLog.getQueryPhone());
  147. miniprogramQueryLog.setQueryMode("2");
  148. miniprogramQueryLogMapper.insertMiniprogramQueryLog(miniprogramQueryLog);
  149. return AjaxResult.success(reportDetail);
  150. }
  151. return AjaxResult.error("查询的文档编号不存在");
  152. }
  153. /**
  154. * 发送短信验证码
  155. *
  156. * @param reportQueryLog
  157. * @return
  158. */
  159. @Override
  160. public AjaxResult sendSms(ReportQueryLog reportQueryLog) {
  161. //判断该手机号是否超过查询次数
  162. //获取查询主体
  163. String queryType = reportQueryLog.getQueryType();
  164. String queryMode = reportQueryLog.getQueryMode();
  165. //查询手机号
  166. String phone = "";
  167. QueryConfig queryConfig = new QueryConfig();
  168. queryConfig.setQueryType(queryType);
  169. queryConfig.setQueryMode(queryMode);
  170. if (UserConstants.QUERY_TYPE_PEOPLE.equals(queryType)) {
  171. phone = reportQueryLog.getQueryPhone();
  172. } else if (UserConstants.QUERY_TYPE_UNIT.equals(queryType)) {
  173. phone = reportQueryLog.getCompanyPhone();
  174. }
  175. String verifyKey = UserConstants.QUERY_CODE_KEY + phone;
  176. String codeNotConsume = redisCache.getCacheObject(verifyKey);
  177. if (StringUtils.isNotBlank(codeNotConsume)) {
  178. //说明有未消费的验证码
  179. return AjaxResult.error("请勿重复获取验证码");
  180. }
  181. //如果没有验证码判断今天是否有查询次数
  182. //校验查询次数
  183. QueryConfig queryConfigRough = queryConfigMapper.selectQueryConfig(queryConfig);
  184. String resultQueryNumber = validateQueryNumber(phone, queryConfigRough);
  185. if (!UserConstants.QUERY_SUCCESS.equals(resultQueryNumber)) {
  186. return AjaxResult.error(resultQueryNumber);
  187. }
  188. //发送短信验证码
  189. if (StringUtils.isNotBlank(phone)) {
  190. try {
  191. String code = SendSmsUtils.getCode(6);
  192. SendSmsResponse sendSmsResponse = SendSmsUtils.sendSms(phone, "{\"code\":\"" + code + "\"}", accessKeyId, accessKeySecret, signName, templateCode);
  193. QuerySendDetailsResponse querySendDetailsResponse = SendSmsUtils.querySendDetails(sendSmsResponse.getBizId(), phone, accessKeyId, accessKeySecret);
  194. String ok = querySendDetailsResponse.getCode();
  195. if ("OK".equals(ok)) {
  196. //设置验证码10分钟有效期
  197. redisCache.setCacheObject(UserConstants.QUERY_CODE_KEY + phone, code, 10, TimeUnit.MINUTES);
  198. return AjaxResult.success("发送成功");
  199. } else {
  200. return AjaxResult.error(querySendDetailsResponse.getMessage());
  201. }
  202. } catch (ClientException e) {
  203. e.printStackTrace();
  204. }
  205. }
  206. return AjaxResult.error("未发现手机号");
  207. }
  208. /**
  209. * 给档案拥有者发送询问短信
  210. *
  211. * @param reportQueryLog
  212. * @return
  213. */
  214. @Override
  215. public AjaxResult sendQueryNum(ReportQueryLog reportQueryLog) {
  216. //发送查询码前,先校验验证码是否通过,且不删除redis中key
  217. AjaxResult result = queryPublic(reportQueryLog,false);
  218. if (!UserConstants.QUERY_SUCCESS.equals(result.get(MSG_TAG))) {
  219. return result;
  220. }
  221. //验证码通过后,给文档原始人,发送询问查询码的短信
  222. String reportNumber = reportQueryLog.getReportNumber();
  223. if (StringUtils.isNotBlank(reportNumber)) {
  224. ReportDetail reportDetail = reportDetailMapper.selectReportDetailByReportNumberDetail(reportNumber);
  225. if (reportDetail != null){
  226. //档案拥有者的手机号码
  227. String phonenumber = reportDetail.getPhonenumber();
  228. if (StringUtils.isNotBlank(phonenumber)) {
  229. //给文档创建人发送询问短信
  230. try {
  231. String queryType = reportQueryLog.getQueryType();
  232. StringBuilder sb = new StringBuilder();
  233. String phone = "";
  234. if (UserConstants.QUERY_TYPE_PEOPLE.equals(queryType)) {
  235. sb.append(reportQueryLog.getQueryName()).append("(个人)");
  236. phone = reportQueryLog.getQueryPhone();
  237. }
  238. if (UserConstants.QUERY_TYPE_UNIT.equals(queryType)) {
  239. sb.append(reportQueryLog.getCompanyName()).append("(单位)");
  240. phone = reportQueryLog.getCompanyPhone();
  241. }
  242. //"{\"code\":\"" + code + "\"}"
  243. SendSmsResponse sendSmsResponse = SendSmsUtils.sendSms(phonenumber, "{\"name\":\"" + sb.toString() + "\",\"reportNumber\":\"" + reportNumber + "\"}", accessKeyId, accessKeySecret, signNameQuery, templateCodeQuery);
  244. QuerySendDetailsResponse querySendDetailsResponse = SendSmsUtils.querySendDetails(sendSmsResponse.getBizId(), phonenumber, accessKeyId, accessKeySecret);
  245. String ok = querySendDetailsResponse.getCode();
  246. if ("OK".equals(ok)) {
  247. //redis存储查询人的手机号码
  248. redisCache.setCacheObject(UserConstants.QUERY_NUM_CREATE + phonenumber, phone, 30, TimeUnit.MINUTES);
  249. return AjaxResult.success("发送成功,请等待对方回复");
  250. } else {
  251. return AjaxResult.error(querySendDetailsResponse.getMessage());
  252. }
  253. } catch (ClientException e) {
  254. e.printStackTrace();
  255. }
  256. }else {
  257. return AjaxResult.error("文档拥有者暂未填写手机号,无法获得查询码");
  258. }
  259. }else {
  260. return AjaxResult.error("查询的文档编号不存在");
  261. }
  262. }
  263. return AjaxResult.error("未填写查询报告编号");
  264. }
  265. /**
  266. * 查询方式是二维码
  267. *
  268. * @param reportQueryLog
  269. * @return
  270. */
  271. private AjaxResult queryByQr(ReportQueryLog reportQueryLog) {
  272. String qrImage = reportQueryLog.getQrImage();
  273. String remark = "";
  274. if (StringUtils.isBlank(qrImage)) {
  275. remark = "未接收到二维码";
  276. reportQueryLog.setRemark(remark);
  277. reportQueryLogMapper.insertReportQueryLog(reportQueryLog);
  278. return AjaxResult.error(remark);
  279. }
  280. try {
  281. //解析二维码
  282. String reportNumber = QRCodeUtils.decode(qrImage);
  283. if (StringUtils.isBlank(reportNumber)) {
  284. remark = "二维码解析失败";
  285. reportQueryLog.setRemark(remark);
  286. reportQueryLogMapper.insertReportQueryLog(reportQueryLog);
  287. return AjaxResult.error(remark);
  288. }
  289. //查询二维码有效期
  290. String verifyKey = UserConstants.QR_IMAGE + reportNumber;
  291. Object cacheObject = redisCache.getCacheObject(verifyKey);
  292. if (cacheObject == null) {
  293. remark = "二维码已过期";
  294. reportQueryLog.setRemark(remark);
  295. reportQueryLogMapper.insertReportQueryLog(reportQueryLog);
  296. return AjaxResult.error(remark);
  297. }
  298. ReportDetail reportDetail = reportDetailMapper.selectReportDetailByReportNumber(reportNumber);
  299. if (reportDetail != null) {
  300. reportDetail.setReportUrl(null);
  301. reportQueryLog.setIsSuccess("Y");
  302. reportQueryLog.setRemark(UserConstants.QUERY_SUCCESS);
  303. reportQueryLogMapper.insertReportQueryLog(reportQueryLog);
  304. return AjaxResult.success(reportDetail);
  305. }
  306. } catch (Exception e) {
  307. e.printStackTrace();
  308. return AjaxResult.error("未查询到对应信息");
  309. }
  310. return AjaxResult.error("未查询到对应信息");
  311. }
  312. /**
  313. * 查询方式是粗查
  314. *
  315. * @param reportQueryLog
  316. * @return
  317. */
  318. private AjaxResult queryByRough(ReportQueryLog reportQueryLog) {
  319. String reportNumber = reportQueryLog.getReportNumber();
  320. ReportDetail reportDetail = reportDetailMapper.selectReportDetailByReportNumber(reportNumber);
  321. if (reportDetail != null) {
  322. reportDetail.setReportUrl(null);
  323. reportQueryLog.setRemark(UserConstants.QUERY_SUCCESS);
  324. reportQueryLog.setIsSuccess("Y");
  325. reportQueryLogMapper.insertReportQueryLog(reportQueryLog);
  326. return AjaxResult.success(reportDetail);
  327. }
  328. reportQueryLog.setRemark("查询的文档编号不存在");
  329. reportQueryLogMapper.insertReportQueryLog(reportQueryLog);
  330. return AjaxResult.error("查询的文档编号不存在");
  331. }
  332. /**
  333. * 查询方式是详情
  334. *
  335. * @param reportQueryLog
  336. * @return
  337. */
  338. private AjaxResult queryByDetail(ReportQueryLog reportQueryLog) {
  339. //查询手机号
  340. String phone = "";
  341. //获取查询主体
  342. String queryType = reportQueryLog.getQueryType();
  343. if (UserConstants.QUERY_TYPE_PEOPLE.equals(queryType)) {
  344. phone = reportQueryLog.getQueryPhone();
  345. } else if (UserConstants.QUERY_TYPE_UNIT.equals(queryType)) {
  346. phone = reportQueryLog.getCompanyPhone();
  347. }
  348. //校验查询码
  349. String resultNum = validateNum(phone, reportQueryLog.getQueryNum());
  350. if (!UserConstants.QUERY_SUCCESS.equals(resultNum)) {
  351. reportQueryLog.setRemark(resultNum);
  352. reportQueryLogMapper.insertReportQueryLog(reportQueryLog);
  353. return AjaxResult.error(resultNum);
  354. }
  355. String reportNumber = reportQueryLog.getReportNumber();
  356. ReportDetail reportDetail = reportDetailMapper.selectReportDetailByReportNumber(reportNumber);
  357. if (reportDetail != null) {
  358. reportQueryLog.setIsSuccess("Y");
  359. reportQueryLog.setRemark(UserConstants.QUERY_SUCCESS);
  360. reportQueryLogMapper.insertReportQueryLog(reportQueryLog);
  361. return AjaxResult.success(reportDetail);
  362. }
  363. reportQueryLog.setRemark("查询的文档编号不存在");
  364. reportQueryLogMapper.insertReportQueryLog(reportQueryLog);
  365. return AjaxResult.error("查询的文档编号不存在");
  366. }
  367. /**
  368. * 查询通用校验模块
  369. */
  370. private AjaxResult queryPublic(ReportQueryLog reportQueryLog,Boolean isDelKey) {
  371. //获取查询主体
  372. String queryType = reportQueryLog.getQueryType();
  373. String queryMode = reportQueryLog.getQueryMode();
  374. //查询手机号
  375. String phone = "";
  376. QueryConfig queryConfig = new QueryConfig();
  377. queryConfig.setQueryType(queryType);
  378. queryConfig.setQueryMode(queryMode);
  379. queryConfig.setQueryMode(UserConstants.QUERY_MODE_ROUGH);
  380. if (UserConstants.QUERY_TYPE_PEOPLE.equals(queryType)) {
  381. phone = reportQueryLog.getQueryPhone();
  382. } else if (UserConstants.QUERY_TYPE_UNIT.equals(queryType)) {
  383. phone = reportQueryLog.getCompanyPhone();
  384. }
  385. //校验查询次数
  386. QueryConfig queryConfigRough = queryConfigMapper.selectQueryConfig(queryConfig);
  387. String resultQueryNumber = validateQueryNumber(phone, queryConfigRough);
  388. if (!UserConstants.QUERY_SUCCESS.equals(resultQueryNumber)) {
  389. reportQueryLog.setRemark(resultQueryNumber);
  390. reportQueryLogMapper.insertReportQueryLog(reportQueryLog);
  391. return AjaxResult.error(resultQueryNumber);
  392. }
  393. //校验验证码
  394. String resultCaptcha = validateCaptcha(phone, reportQueryLog.getCode(),isDelKey);
  395. if (!UserConstants.QUERY_SUCCESS.equals(resultCaptcha)) {
  396. reportQueryLog.setRemark(resultCaptcha);
  397. reportQueryLogMapper.insertReportQueryLog(reportQueryLog);
  398. return AjaxResult.error(resultCaptcha);
  399. }
  400. return AjaxResult.success(UserConstants.QUERY_SUCCESS);
  401. }
  402. /**
  403. * 校验验证码
  404. *
  405. * @param queryPhone 查询者手机号
  406. * @return 结果
  407. */
  408. public String validateCaptcha(String queryPhone, String code,Boolean isDelKey) {
  409. String verifyKey = UserConstants.QUERY_CODE_KEY + queryPhone;
  410. String captcha = redisCache.getCacheObject(verifyKey);
  411. if (captcha == null) {
  412. return "验证码不存在或已过期,请重新获取";
  413. }
  414. if (!code.equalsIgnoreCase(captcha)) {
  415. return "验证码不正确,请检查";
  416. }
  417. if (isDelKey){
  418. redisCache.deleteObject(verifyKey);
  419. }
  420. return UserConstants.QUERY_SUCCESS;
  421. }
  422. /**
  423. * 校验查询码
  424. *
  425. * @param queryPhone 查询者手机号
  426. * @return 结果
  427. */
  428. public String validateNum(String queryPhone, String code) {
  429. String verifyKey = UserConstants.QUERY_NUM_KEY + queryPhone;
  430. String captcha = redisCache.getCacheObject(verifyKey);
  431. if (captcha == null) {
  432. return "查询码不存在或已过期,请重新获取";
  433. }
  434. if (!code.equalsIgnoreCase(captcha)) {
  435. return "查询码不正确,请检查";
  436. }
  437. redisCache.deleteObject(verifyKey);
  438. return UserConstants.QUERY_SUCCESS;
  439. }
  440. /**
  441. * 校验查询次数
  442. *
  443. * @param queryPhone 查询的手机号
  444. * @return
  445. */
  446. public String validateQueryNumber(String queryPhone, QueryConfig queryConfigRough) {
  447. Integer queryNumber = 0;
  448. if (queryConfigRough != null) {
  449. //可用的查询次数
  450. queryNumber = queryConfigRough.getQueryNumber();
  451. }
  452. String verifyKey = UserConstants.QUERY_CODE_NUMBER + queryPhone;
  453. Object queryNum = redisCache.getCacheObject(verifyKey);
  454. if (queryNum == null) {
  455. //说明一次没查询判断可用的查询次数是否设置等于0就是不限制查询
  456. redisCache.setCacheObject(verifyKey, 1, getSecondsNextEarlyMorning(), TimeUnit.SECONDS);
  457. return UserConstants.QUERY_SUCCESS;
  458. } else {
  459. //判断如果设置的查询次数是0
  460. if (queryNumber == 0) {
  461. redisCache.setCacheObject(verifyKey, Integer.parseInt(queryNum.toString()) + 1, getSecondsNextEarlyMorning(), TimeUnit.SECONDS);
  462. return UserConstants.QUERY_SUCCESS;
  463. } else {
  464. if (queryNumber >= Integer.parseInt(queryNum.toString())) {
  465. return "当前没有查询次数";
  466. } else {
  467. redisCache.setCacheObject(verifyKey, Integer.parseInt(queryNum.toString()) + 1, getSecondsNextEarlyMorning(), TimeUnit.SECONDS);
  468. return UserConstants.QUERY_SUCCESS;
  469. }
  470. }
  471. }
  472. }
  473. /**
  474. * 判断当前时间距离第二天凌晨的秒数
  475. *
  476. * @return 返回值单位为[s:秒]
  477. */
  478. public int getSecondsNextEarlyMorning() {
  479. Calendar cal = Calendar.getInstance();
  480. cal.add(Calendar.DAY_OF_YEAR, 1);
  481. cal.set(Calendar.HOUR_OF_DAY, 0);
  482. cal.set(Calendar.SECOND, 0);
  483. cal.set(Calendar.MINUTE, 0);
  484. cal.set(Calendar.MILLISECOND, 0);
  485. return (int) (cal.getTimeInMillis() - System.currentTimeMillis()) / 1000;
  486. }
  487. }