5632411515b04419b9ef7ee5140ad8786dad7def.svn-base 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. package com.iamberry.app.service;
  2. import static com.iamberry.app.config.ImberryConfig.SMS_PASSWORD;
  3. import static com.iamberry.app.config.ImberryConfig.SMS_TEXT;
  4. import static com.iamberry.app.config.ImberryConfig.SMS_URL;
  5. import static com.iamberry.app.config.ImberryConfig.SMS_USERNAME;
  6. import java.text.MessageFormat;
  7. import java.util.ArrayList;
  8. import java.util.Date;
  9. import java.util.HashMap;
  10. import java.util.List;
  11. import java.util.Map;
  12. import org.apache.commons.lang3.StringUtils;
  13. import org.apache.http.HttpEntity;
  14. import org.apache.http.NameValuePair;
  15. import org.apache.http.client.entity.UrlEncodedFormEntity;
  16. import org.apache.http.client.methods.CloseableHttpResponse;
  17. import org.apache.http.client.methods.HttpPost;
  18. import org.apache.http.impl.client.CloseableHttpClient;
  19. import org.apache.http.impl.client.HttpClients;
  20. import org.apache.http.message.BasicNameValuePair;
  21. import org.apache.http.util.EntityUtils;
  22. import org.springframework.beans.factory.annotation.Autowired;
  23. import org.springframework.stereotype.Service;
  24. import com.iamberry.app.core.entity.CodeValid;
  25. import com.iamberry.app.face.CodeService;
  26. import com.iamberry.app.mapper.CodeMapper;
  27. import com.iamberry.app.tool.util.Result;
  28. import com.iamberry.app.ulitity.Utility;
  29. import com.iamberry.wechat.tools.ResponseJson;
  30. import com.thoughtworks.xstream.XStream;
  31. import com.thoughtworks.xstream.io.xml.StaxDriver;
  32. /**
  33. * @company 深圳爱贝源科技有限公司
  34. * @website www.iamberry.com
  35. * @author 献
  36. * @tel 18271840547
  37. * @date 2016年11月1日
  38. * @explain 验证码业务实现类
  39. */
  40. @Service
  41. public class CodeServiceImpl implements CodeService {
  42. @Autowired
  43. private CodeMapper codeMapper;
  44. @Override
  45. public ResponseJson sendCode(String phone, int codeScenario) {
  46. // TODO Auto-generated method stub
  47. // 第一步,判断使用通道,如果是+86开头,优先使用国内通道,否则默认使用国外通道
  48. ResponseJson json = new ResponseJson();
  49. if (StringUtils.isEmpty(phone)) {
  50. json.setReturnCode(404);
  51. json.addResponseKeyValue("Phone Empty!");
  52. return json;
  53. }
  54. // 第二步,如果是国内,判断是否存在
  55. CodeValid codeValid = codeMapper.getLast(phone);
  56. // 通道是否是中国的
  57. boolean IS_CHANNEL_ZH = false;
  58. if (StringUtils.indexOf(phone, "+") != -1) {
  59. if (StringUtils.startsWith(phone, "+86")) {
  60. IS_CHANNEL_ZH = true;
  61. }
  62. } else {
  63. IS_CHANNEL_ZH = true;
  64. }
  65. // 判断通道
  66. Date now = new Date();
  67. if (IS_CHANNEL_ZH && codeValid != null) {
  68. // ** 切换通道需求:每次请求验证码,如果上一次验证码在一分钟以后,三分钟以内没有使用,那么切换通道 **//
  69. if (now.getTime() <= (codeValid.getCodeValidDate().getTime()) &&
  70. (now.getTime() - 60000) >= codeValid.getCodeSendDate().getTime() && codeValid.getCodeUse() == 2 && codeValid.getCodeScenario() == codeScenario) {
  71. // 如果等待三分钟后,那么切换通道,暂时不切换
  72. // IS_CHANNEL_ZH = false;
  73. }
  74. }
  75. // 获取验证码
  76. String code = Utility.getRandomCode(4);
  77. json = sendCMS(phone, code, IS_CHANNEL_ZH ? 1 : 2);
  78. if (json.getReturnCode() != 200) {
  79. json = sendCMS(phone, code, IS_CHANNEL_ZH ? 1 : 2);
  80. }
  81. // 保存发送记录
  82. codeValid = new CodeValid();
  83. codeValid.setCodeChannel(IS_CHANNEL_ZH ? 1 : 2);
  84. codeValid.setCodeMsg(json.getReturnMsg().get("returnMsg").toString());
  85. codeValid.setCodePhone(phone);
  86. codeValid.setCodeScenario(codeScenario);
  87. codeValid.setCodeSendDate(now);
  88. codeValid.setCodeValidDate(new Date(now.getTime() + 180000));
  89. codeValid.setCodeStatus(json.getReturnCode() == 200 ? 3 : 4);
  90. codeValid.setCodeUse(2);
  91. codeValid.setCodeValue(Integer.parseInt(code));
  92. codeMapper.save(codeValid);
  93. return json;
  94. }
  95. /**
  96. * @param phone 手机号码
  97. * @param code 短信验证码
  98. * @param channel 通道 1:主通道;2:备用通道(国外的电话通通使用此)
  99. * @return
  100. */
  101. private ResponseJson sendCMS(String phone, String code, int channel) {
  102. // 国内号码
  103. ResponseJson json = new ResponseJson();
  104. json.setReturnCode(500);
  105. String result = null;
  106. try {
  107. if (channel == 1) {
  108. // 使用主通道
  109. result = sendZHCMS(phone, code);
  110. } else {
  111. // 使用备用通道
  112. result = sendOtherCMS(phone, code);
  113. }
  114. } catch (Exception e) {
  115. result = e.getMessage();
  116. }
  117. if (StringUtils.equals(result, "SUCCESS")) {
  118. json.setReturnCode(200);
  119. }
  120. json.addResponseKeyValue(result);
  121. return json;
  122. }
  123. private String sendOtherCMS(String phone, String code) {
  124. System.out.println("使用备用通道,发送验证码成功!" + code);
  125. return "SUCCESS";
  126. }
  127. private String sendZHCMS(String phone, String code) throws Exception {
  128. CloseableHttpClient client = HttpClients.createDefault();
  129. Map<String, String> params = new HashMap<String, String>();
  130. CloseableHttpResponse response = null;
  131. params.put("username", SMS_USERNAME);
  132. params.put("password", SMS_PASSWORD);
  133. params.put("mobile", phone);
  134. params.put("content", MessageFormat.format(SMS_TEXT, code));
  135. HttpPost method = new HttpPost(SMS_URL);
  136. if (params != null) {
  137. List<NameValuePair> paramList = new ArrayList<NameValuePair>();
  138. for (Map.Entry<String, String> param : params.entrySet()) {
  139. NameValuePair pair = new BasicNameValuePair(param.getKey(), param.getValue());
  140. paramList.add(pair);
  141. }
  142. method.setEntity(new UrlEncodedFormEntity(paramList, "UTF-8"));
  143. }
  144. response = client.execute(method);
  145. HttpEntity entity = response.getEntity();
  146. if (entity != null) {
  147. String result = EntityUtils.toString(entity);
  148. XStream xs = new XStream(new StaxDriver());
  149. xs.alias("result", Result.class);
  150. Result object = (Result)xs.fromXML(result);
  151. response.close();
  152. if (0 == object.getResultcode()) {
  153. return "SUCCESS";
  154. } else {
  155. return object.getResultcode() + ":" + object.getErrordescription();
  156. }
  157. }
  158. return null;
  159. }
  160. @Override
  161. public ResponseJson validCode(String phone, String code, int codeScenario) {
  162. ResponseJson json = new ResponseJson();
  163. // 校验
  164. CodeValid codeValid = codeMapper.getLast(phone);
  165. if (codeValid == null) {
  166. // 操作有误
  167. json.setReturnCode(404);
  168. json.addResponseKeyValue("Wrong operation, No send record");
  169. return json;
  170. }
  171. Date now = new Date();
  172. if (now.getTime() >= codeValid.getCodeValidDate().getTime()) {
  173. // 验证码无效
  174. json.setReturnCode(403);
  175. json.addResponseKeyValue("Verification code is invalid");
  176. return json;
  177. }
  178. // 验证码是否使用 1:已经使用;2:未使用
  179. if (codeValid.getCodeUse().intValue() == 1) {
  180. // 验证码无效
  181. json.setReturnCode(402);
  182. json.addResponseKeyValue("Verification code has been used");
  183. return json;
  184. }
  185. // 必须 验证码正确,并且场景正确
  186. if (!(codeValid.getCodeValue() == (Integer.parseInt(code))
  187. && codeScenario == codeValid.getCodeScenario())) {
  188. // 验证码错误
  189. json.setReturnCode(405);
  190. json.addResponseKeyValue("Verification code error");
  191. return json;
  192. }
  193. // 只要校验成功,表示本次验证码已使用
  194. codeMapper.update(codeValid.getCodeId());
  195. json.setReturnCode(200);
  196. json.addResponseKeyValue("SUCCESS");
  197. return json;
  198. }
  199. }