6000a0b60f8cc5a996d2a7b128475af09bc91d10.svn-base 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  1. package com.chinacreator.videoalliance.order.service;
  2. import java.util.Arrays;
  3. import java.util.HashMap;
  4. import java.util.List;
  5. import java.util.Map;
  6. import javax.servlet.http.HttpServletRequest;
  7. import org.apache.commons.lang.StringUtils;
  8. import org.apache.log4j.Logger;
  9. import org.springframework.beans.factory.annotation.Autowired;
  10. import org.springframework.stereotype.Component;
  11. import org.springframework.web.context.request.RequestContextHolder;
  12. import org.springframework.web.context.request.ServletRequestAttributes;
  13. import com.chinacreator.common.exception.BusinessException;
  14. import com.chinacreator.common.util.RequestUtil;
  15. import com.chinacreator.videoalliance.common.dao.DictionaryDao;
  16. import com.chinacreator.videoalliance.order.bean.OrderInfo;
  17. import com.chinacreator.videoalliance.order.dao.BackBusiOrderDao;
  18. import com.chinacreator.videoalliance.order.dao.BusiOperlimitConfDao;
  19. import com.chinacreator.videoalliance.order.dao.SPDao;
  20. import com.chinacreator.videoalliance.order.util.IpAddrUtil;
  21. import com.chinacreator.videoalliance.order.util.JsonUtil;
  22. @Component
  23. public class OrderValiService {
  24. private static Logger errorlog = Logger.getLogger("orderError");
  25. private static Logger iplog = Logger.getLogger("iplog");
  26. @Autowired
  27. private SPDao sPDao;
  28. @Autowired
  29. private BackBusiOrderDao backBusiOrderDao;
  30. @Autowired
  31. private BusiOperlimitConfDao busiOperlimitConfDao;
  32. @Autowired
  33. private DictionaryDao dictionaryDao;
  34. public void vali(HttpServletRequest request,OrderInfo orderInfo) throws Exception{
  35. //IP验证
  36. if(!StringUtils.isEmpty(orderInfo.getInvokeface()) && !ipVali(orderInfo)){
  37. throw new BusinessException("9002", "IP验证未通过", new String[0]);
  38. }
  39. String ip = RequestUtil.getIpAddr(request);
  40. if("183.3.234.51".equals(ip) //|| "47.93.215.93".equals(ip)
  41. ){
  42. throw new BusinessException("9002", "非法访问", new String[0]);
  43. }
  44. //非后向接口请求要验证办理的是否后向产品
  45. if(!"backorder".equals(orderInfo.getInvokeface())){
  46. //验证CPID、SPID是否合法
  47. HashMap spInfo = backBusiOrderDao.getCpSp(orderInfo.getCpid(),orderInfo.getSpid());
  48. if(spInfo == null || spInfo.size() == 0){
  49. throw new BusinessException("9002", "非法访问", new String[0]);
  50. }
  51. //验证是否为后台产品
  52. List<HashMap> confList = backBusiOrderDao.getBackBusiConf(orderInfo.getCpid(),orderInfo.getSpid());
  53. if(confList != null && confList.size()>0){
  54. throw new BusinessException("9002", "非法访问", new String[0]);
  55. }
  56. }
  57. //验证业务办理是否限制
  58. this.valiOperLimit(request, orderInfo);
  59. //验证省份办理限制
  60. this.valiProvinceLimit(orderInfo);
  61. }
  62. /**
  63. * 验证业务操作限制(是否能订购,是否能退订)
  64. * @param request
  65. * @param orderInfo
  66. * @throws Exception
  67. */
  68. public void valiOperLimit(HttpServletRequest request,OrderInfo orderInfo) throws Exception {
  69. //请求IP
  70. String ip = RequestUtil.getIpAddr(request);
  71. //办理渠道
  72. String channel = "";
  73. //0订购,1退订
  74. String opertype = orderInfo.getStatus()+"";
  75. if("0".equals(opertype)){
  76. channel = orderInfo.getOrderchannel();
  77. }else{
  78. channel = orderInfo.getCancelchannel();
  79. }
  80. errorlog.info("userid=>"+orderInfo.getUserid()+"#cpid=>"+orderInfo.getCpid()+"#spid=>"+orderInfo.getSpid()+"#channel=>"+channel+"#type=>"+orderInfo.getStatus()+"#ip=>"+ip);
  81. //OPERTYPE和SPID如配置了多条数据,经过排序,如果配置了多条数据,为空的会在最后一条
  82. List<HashMap> dataList = busiOperlimitConfDao.valiOperLimit(orderInfo.getSpid(),opertype);
  83. //是否限制办理
  84. boolean haslimit = false;
  85. if(dataList != null && dataList.size()>0){
  86. for(HashMap tm : dataList){
  87. //能查到数据代表有限制,先设置为受限制
  88. haslimit = true;
  89. //配置了指定渠道不受限制,且渠道相同
  90. if(!StringUtils.isEmpty(channel) && channel.equals(tm.get("CHANNEL"))){
  91. //设置为不受限制
  92. haslimit = false;
  93. //配置了IP白名单,调用的IP必须在名单内
  94. if(!StringUtils.isEmpty((String)tm.get("IP"))){
  95. //先设置为受限制
  96. haslimit = true;
  97. //把IP转为LIST
  98. List<String> ipList = Arrays.asList(tm.get("IP").toString().split(","));
  99. //请求IP包含在白名单内
  100. if(ipList.contains(ip)){
  101. haslimit = false;
  102. }
  103. }
  104. }
  105. //如果不受限制,说明有匹配到了不受限制的配置数据,不再循环下一条
  106. if(!haslimit){
  107. break;
  108. }
  109. }
  110. //被限制抛异常
  111. if(haslimit){
  112. throw new BusinessException("7020", "该产品已下线,暂停办理");
  113. }
  114. }
  115. }
  116. /**
  117. * IP验证
  118. * @param invokeface 接口名称
  119. * @return
  120. */
  121. public boolean ipVali(OrderInfo orderInfo) {
  122. boolean result = false;
  123. //接口标识为空,不验证
  124. if(orderInfo == null || StringUtils.isEmpty(orderInfo.getInvokeface())){
  125. return true;
  126. }
  127. //访问IP列表
  128. List<String> ipList = null;
  129. Map<String,String> confdata = null;
  130. try {
  131. ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
  132. HttpServletRequest request = attributes.getRequest();
  133. //获取IP列表
  134. ipList = IpAddrUtil.getIpAddrList(request, orderInfo.getChannel());
  135. //获取IP白名单
  136. List<HashMap> ipconfList = busiOperlimitConfDao.valiIpLimit(orderInfo.getInvokeface());
  137. if(ipconfList != null && ipconfList.size()>0){
  138. confdata = ipconfList.get(0);
  139. }
  140. if(confdata != null && confdata.size()>0){
  141. String configIp = confdata.get("IP");
  142. if(StringUtils.isNotEmpty(configIp)) {
  143. //配置为*,无权限配置
  144. if(configIp.equals("*")){
  145. result = true;
  146. }else{
  147. //匹配白名单
  148. List<String> list = Arrays.asList(configIp.split("\\|"));
  149. for(String tmpip : list){
  150. //如果全包含
  151. if(ipList.contains(tmpip)){
  152. result = true;
  153. break;
  154. }
  155. //如果有部分配置*
  156. if(!result && tmpip.indexOf("*") != -1 && hasStartsWith(ipList, tmpip)){
  157. result = true;
  158. break;
  159. }
  160. }
  161. }
  162. }
  163. }else{
  164. result = true; //没配置白名单,不验证
  165. }
  166. } catch (Exception e) {
  167. e.printStackTrace();
  168. iplog.error(orderInfo.getInvokeface()+",IP验证出现异常,"+e.getMessage());
  169. } finally {
  170. iplog.info("invokeface=>"+orderInfo.getInvokeface()+", ipList=>"+ipList+",result=>"+result+",confdata=>"+confdata);
  171. }
  172. return result;
  173. }
  174. /**
  175. * 判断是否模糊匹配
  176. * @param ipList
  177. * @param confip
  178. * @return
  179. */
  180. private boolean hasStartsWith(List<String> ipList, String confip){
  181. boolean res = false;
  182. for(String ip : ipList){
  183. if(ip.startsWith(confip.split("[*]")[0])){
  184. res = true;
  185. break;
  186. }
  187. }
  188. return res;
  189. }
  190. /**
  191. * 验证省份限制
  192. * @param orderInfo
  193. * @throws Exception
  194. */
  195. public void valiProvinceLimit(OrderInfo orderInfo) throws Exception {
  196. String notProvinceLimitcpid = dictionaryDao.getValue("notProvinceLimitcpid");
  197. if(!StringUtils.isEmpty(notProvinceLimitcpid)){
  198. List<String> cpids = Arrays.asList(notProvinceLimitcpid.split(","));
  199. if(cpids != null && cpids.contains(orderInfo.getCpid())){
  200. return;
  201. }
  202. }
  203. if(!StringUtils.isEmpty(notProvinceLimitcpid)){
  204. List<String> cpids = Arrays.asList(notProvinceLimitcpid.split(","));
  205. if(cpids != null && cpids.contains(orderInfo.getCpid())){
  206. return;
  207. }
  208. }
  209. //0订购,1退订
  210. String opertype = orderInfo.getStatus()+"";
  211. //如果省份为空,设置为*
  212. String province = orderInfo.getProvince();
  213. if(StringUtils.isEmpty(province)) {
  214. province = "*";
  215. }
  216. List<HashMap> confList = busiOperlimitConfDao.valiProvinceLimit(orderInfo.getInvokeface(), province, opertype);
  217. if(confList != null && confList.size() > 0){
  218. //渠道是否不要验证
  219. if(this.valiNoprovinceLimitChannel(orderInfo)){
  220. return;
  221. }
  222. if("广东".equals(orderInfo.getProvince()) && "0".equals(opertype)){
  223. throw new BusinessException("9003", "业务平台满载,正在升级中,暂时无法受理新用户订购,敬请谅解");
  224. }else if("*".equals(province)){
  225. throw new BusinessException("9003", "您号码的归属地暂未开放该业务,敬请期待");
  226. }else{
  227. throw new BusinessException("9003", "您号码的归属地{0}暂未开放该业务,敬请期待", new String[]{orderInfo.getProvince()});
  228. }
  229. }
  230. }
  231. /**
  232. * 渠道是否放开了限制
  233. * @param orderInfo
  234. * @return true是,false否
  235. */
  236. private boolean valiNoprovinceLimitChannel(OrderInfo orderInfo){
  237. boolean res = false;
  238. try {
  239. //不要限制 渠道配置
  240. String notProvinceLimitchannel = dictionaryDao.getValue("notProvinceLimitchannel");
  241. String channel = orderInfo.getChannel();
  242. String subchannel = orderInfo.getSubchannel();
  243. //如果省份为空,设置为*
  244. String province = orderInfo.getProvince();
  245. if(StringUtils.isEmpty(province)) {
  246. province = "*";
  247. }
  248. //不要限制的渠道
  249. String nolimitchannel = "";
  250. if(!StringUtils.isEmpty(channel)){
  251. nolimitchannel += channel;
  252. }
  253. if(!StringUtils.isEmpty(channel) && !StringUtils.isEmpty(subchannel)){
  254. nolimitchannel += subchannel;
  255. }
  256. if(!StringUtils.isEmpty(nolimitchannel) && !StringUtils.isEmpty(notProvinceLimitchannel)){
  257. Map tmpMap = JsonUtil.jsonToMap(notProvinceLimitchannel);
  258. if(tmpMap != null && tmpMap.get(province) != null && !StringUtils.isEmpty(tmpMap.get(province).toString())){
  259. List<String> channels = Arrays.asList(tmpMap.get(province).toString().split(","));
  260. if(channels != null && channels.contains(nolimitchannel)){
  261. res = true;
  262. }
  263. }
  264. }
  265. } catch (Exception e) {
  266. // TODO Auto-generated catch block
  267. e.printStackTrace();
  268. }
  269. return res;
  270. }
  271. }