Browse Source

Merge branches 'dev' and 'dev_voice' of http://git.elinkit.com.cn:7070/r/epmet-cloud into dev_voice

dev_shibei_match
yinzuomei 5 years ago
parent
commit
ebbb5c6691
  1. 5
      epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/constant/AppClientConstant.java
  2. 1
      epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/constant/NumConstant.java
  3. 5
      epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/security/dto/TokenDto.java
  4. 9
      epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/security/resolver/LoginUserHandlerMethodArgumentResolver.java
  5. 2
      epmet-gateway/deploy/docker-compose-dev.yml
  6. 2
      epmet-gateway/pom.xml
  7. 117
      epmet-gateway/src/main/java/com/epmet/filter/CpAuthGatewayFilterFactory.java
  8. 168
      epmet-gateway/src/main/java/com/epmet/filter/FeignRequestFilter.java
  9. 32
      epmet-module/resi-group/resi-group-client/src/main/java/com/epmet/resi/group/dto/topic/result/ResiTopicClosingMsgResultDTO.java
  10. 5
      epmet-module/resi-group/resi-group-client/src/main/java/com/epmet/resi/group/dto/topic/result/ResiTopicIncludeIssueDetailResultDTO.java
  11. 34
      epmet-module/resi-group/resi-group-server/src/main/java/com/epmet/modules/topic/service/impl/ResiTopicServiceImpl.java
  12. 9
      epmet-module/resi-group/resi-group-server/src/main/java/com/epmet/modules/utils/ModuleConstant.java

5
epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/constant/AppClientConstant.java

@ -41,6 +41,11 @@ public interface AppClientConstant {
* */
String CLIENT = "client";
/**
* 客户ID
*/
String CUSTOMER_ID = "customerId";
/**
* 事务流水号每次请求串起来的多个服务拥有相同的流水号,便于日志追踪
*/

1
epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/constant/NumConstant.java

@ -39,6 +39,7 @@ public interface NumConstant {
long TWO_L = 2L;
long THREE_L = 3L;
long FOUR_L = 4L;
long MINUS_ONE_L = -1L;
String ZERO_STR = "0";
String ONE_STR = "1";

5
epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/security/dto/TokenDto.java

@ -40,6 +40,11 @@ public class TokenDto extends BaseTokenDto implements Serializable {
*/
private long updateTime;
/**
* 当前工作人员进入的客户id
*/
private String customerId;
@Override
public String toString() {
return JSON.toJSONString(this);

9
epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/security/resolver/LoginUserHandlerMethodArgumentResolver.java

@ -10,6 +10,7 @@ package com.epmet.commons.tools.security.resolver;
import com.alibaba.fastjson.JSON;
import com.epmet.commons.tools.annotation.LoginUser;
import com.epmet.commons.tools.constant.AppClientConstant;
import com.epmet.commons.tools.constant.Constant;
import com.epmet.commons.tools.exception.ErrorCode;
import com.epmet.commons.tools.exception.RenException;
@ -77,10 +78,12 @@ public class LoginUserHandlerMethodArgumentResolver implements HandlerMethodArgu
// String client=keyArray[1];
// String userId=keyArray[2];
// TokenDto tokenDto = cpUserDetailRedis.get(app,client,userId);
TokenDto tokenDto = new TokenDto();
tokenDto.setUserId(request.getHeader("userId"));
tokenDto.setApp(request.getHeader("app"));
tokenDto.setClient(request.getHeader("client"));
tokenDto.setUserId(request.getHeader(AppClientConstant.USER_ID));
tokenDto.setApp(request.getHeader(AppClientConstant.APP));
tokenDto.setClient(request.getHeader(AppClientConstant.CLIENT));
tokenDto.setCustomerId(request.getHeader(AppClientConstant.CUSTOMER_ID));
logger.info("resolveArgument TokenDto:"+ JSON.toJSONString(tokenDto));
logger.info("CURRENT-REDIS-DATABASE---------!!!!!!:"+redisDb);
return tokenDto;

2
epmet-gateway/deploy/docker-compose-dev.yml

@ -2,7 +2,7 @@ version: "3.7"
services:
epmet-gateway-server:
container_name: epmet-gateway-server-dev
image: 192.168.1.130:10080/epmet-cloud-dev/epmet-gateway:0.3.14
image: 192.168.1.130:10080/epmet-cloud-dev/epmet-gateway:0.3.15
ports:
- "8080:8080"
network_mode: host # 使用现有网络

2
epmet-gateway/pom.xml

@ -2,7 +2,7 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<version>0.3.14</version>
<version>0.3.15</version>
<parent>
<groupId>com.epmet</groupId>
<artifactId>epmet-cloud</artifactId>

117
epmet-gateway/src/main/java/com/epmet/filter/CpAuthGatewayFilterFactory.java

@ -70,43 +70,41 @@ public class CpAuthGatewayFilterFactory extends AbstractGatewayFilterFactory<CpA
ServerHttpRequest request = exchange.getRequest();
String requestUri = request.getPath().pathWithinApplication().value();
//请求放行,无需验证权限
if (!pathMatcher(requestUri)) {
return chain.filter(exchange);
}
logger.info("CpAuthGatewayFilterFactory当前requestUri=[" + requestUri + "]CpAuthGatewayFilterFactory拦截成功");
HttpHeaders headers = request.getHeaders();
String token = headers.getFirst(Constant.AUTHORIZATION_HEADER);
if (StringUtils.isBlank(token)) {
token = headers.getFirst(Constant.TOKEN_HEADER);
logger.info("token=" + token);
} else {
logger.info("authorization=" + token);
}
if (StringUtils.isBlank(token)) {
token = request.getQueryParams().getFirst(Constant.AUTHORIZATION_HEADER);
logger.info("params token:" + token);
}
if (StringUtils.isBlank(token)) {
return response(exchange,new Result<>().error(EpmetErrorCode.ERR10005.getCode(),EpmetErrorCode.ERR10005.getMsg()));
}
try {
BaseTokenDto baseTokenDto = getBaseTokenDto(token, jwtTokenUtils);
if (AppClientConstant.APP_RESI.equals(baseTokenDto.getApp())) {
// 居民端
TokenDto resiTokenDto = getLoginUserInfoByToken(token, jwtTokenUtils, cpUserDetailRedis, TokenDto.class);
validateTokenDto(resiTokenDto, token);
} else if (AppClientConstant.APP_GOV.equals(baseTokenDto.getApp())) {
// 政府端
GovTokenDto govTokenDto = getLoginUserInfoByToken(token, jwtTokenUtils, cpUserDetailRedis, GovTokenDto.class);
validateTokenDto(govTokenDto, token);
} else if(AppClientConstant.APP_OPER.equals(baseTokenDto.getApp())){
//运营端
TokenDto resiTokenDto = getLoginUserInfoByToken(token, jwtTokenUtils, cpUserDetailRedis, TokenDto.class);
validateTokenDto(resiTokenDto, token);
String token = getTokenFromRequest(request);
BaseTokenDto baseTokenDto = StringUtils.isNotBlank(token) ? getBaseTokenDto(token, jwtTokenUtils) : null;
String customerId = "";
//需要认证
if (needAuth(requestUri)) {
if (StringUtils.isBlank(token)) {
return response(exchange,new Result<>().error(EpmetErrorCode.ERR10005.getCode(),EpmetErrorCode.ERR10005.getMsg()));
}
// 校验token
try {
if (AppClientConstant.APP_RESI.equals(baseTokenDto.getApp())) {
// 居民端
TokenDto resiTokenDto = getLoginUserInfoByToken(token, jwtTokenUtils, cpUserDetailRedis, TokenDto.class);
validateTokenDto(resiTokenDto, token);
customerId = resiTokenDto.getCustomerId();
} else if (AppClientConstant.APP_GOV.equals(baseTokenDto.getApp())) {
// 政府端
GovTokenDto govTokenDto = getLoginUserInfoByToken(token, jwtTokenUtils, cpUserDetailRedis, GovTokenDto.class);
validateTokenDto(govTokenDto, token);
customerId = govTokenDto.getCustomerId();
} else if(AppClientConstant.APP_OPER.equals(baseTokenDto.getApp())){
//运营端
TokenDto resiTokenDto = getLoginUserInfoByToken(token, jwtTokenUtils, cpUserDetailRedis, TokenDto.class);
validateTokenDto(resiTokenDto, token);
customerId = resiTokenDto.getCustomerId();
}
} catch (RenException e) {
return response(exchange,new Result<>().error(e.getCode(),e.getMsg()));
}
}
//当前登录用户userId,添加到header中
if (baseTokenDto != null) {
String redisKey = baseTokenDto.getApp() + "-" + baseTokenDto.getClient() + "-" + baseTokenDto.getUserId();
logger.info("redisKey=" + redisKey);
ServerHttpRequest build = exchange.getRequest().mutate()
@ -114,14 +112,33 @@ public class CpAuthGatewayFilterFactory extends AbstractGatewayFilterFactory<CpA
.header(AppClientConstant.APP,baseTokenDto.getApp())
.header(AppClientConstant.CLIENT,baseTokenDto.getClient())
.header(AppClientConstant.USER_ID,baseTokenDto.getUserId())
.header(AppClientConstant.CUSTOMER_ID,customerId)
.header(AppClientConstant.TRANSACTION_SERIAL_KEY, new String[]{getTransactionSerial()})
.build();
return chain.filter(exchange.mutate().request(build).build());
}catch(RenException e){
return response(exchange,new Result<>().error(e.getCode(),e.getMsg()));
}
return chain.filter(exchange);
};
}
/**
* 获取事务流水号
* @return
*/
public static String getTransactionSerial() {
String[] letterPool = {"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n"
, "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"};
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 2; i++) {
sb.append(letterPool[(int) (Math.random() * 25)]);
}
sb.append(System.currentTimeMillis());
return sb.toString();
}
//public TokenDto getLoginUserInfo(String token) {
// //是否过期
// Claims claims = jwtTokenUtils.getClaimByToken(token);
@ -160,7 +177,12 @@ public class CpAuthGatewayFilterFactory extends AbstractGatewayFilterFactory<CpA
return exchange.getResponse().writeWith(Flux.just(buffer));
}
private boolean pathMatcher(String requestUri) {
/**
* 是否需要认证
* @param requestUri
* @return
*/
private boolean needAuth(String requestUri) {
for (String url : cpProperty.getSwaggerUrls()) {
if (antPathMatcher.match(url, requestUri)) {
return false;
@ -213,4 +235,25 @@ public class CpAuthGatewayFilterFactory extends AbstractGatewayFilterFactory<CpA
}
}
}
/**
* 从请求中获取token
* @param request
* @return
*/
private String getTokenFromRequest(ServerHttpRequest request) {
HttpHeaders headers = request.getHeaders();
String token = headers.getFirst(Constant.AUTHORIZATION_HEADER);
if (StringUtils.isBlank(token)) {
token = headers.getFirst(Constant.TOKEN_HEADER);
logger.info("token=" + token);
} else {
logger.info("authorization=" + token);
}
if (StringUtils.isBlank(token)) {
token = request.getQueryParams().getFirst(Constant.AUTHORIZATION_HEADER);
logger.info("params token:" + token);
}
return token;
}
}

168
epmet-gateway/src/main/java/com/epmet/filter/FeignRequestFilter.java

@ -1,83 +1,85 @@
package com.epmet.filter;
import com.epmet.commons.tools.constant.AppClientConstant;
import com.epmet.commons.tools.constant.Constant;
import com.epmet.commons.tools.security.dto.BaseTokenDto;
import com.epmet.commons.tools.utils.CpUserDetailRedis;
import com.epmet.jwt.JwtTokenUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.http.HttpHeaders;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
/**
* Feign调用发送请求的Filter
* 目前用于封装用户相关信息到request供上游微服务使用
*/
@Component
public class FeignRequestFilter implements GlobalFilter, UserTokenFilter {
private Logger logger = LoggerFactory.getLogger(getClass());
@Autowired
private JwtTokenUtils jwtTokenUtils;
@Autowired
private CpUserDetailRedis cpUserDetailRedis;
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
HttpHeaders headers = request.getHeaders();
String token = headers.getFirst(Constant.AUTHORIZATION_HEADER);
if (StringUtils.isBlank(token)) {
token = headers.getFirst(Constant.TOKEN_HEADER);
logger.info("token=" + token);
} else {
logger.info("authorization=" + token);
}
if (StringUtils.isBlank(token)) {
token = request.getQueryParams().getFirst(Constant.AUTHORIZATION_HEADER);
logger.info("params token:" + token);
}
if (StringUtils.isBlank(token)) {
return chain.filter(exchange);
}
BaseTokenDto baseTokenDto = getBaseTokenDto(token, jwtTokenUtils);
if (baseTokenDto != null) {
ServerHttpRequest build = exchange.getRequest().mutate()
.header(AppClientConstant.USER_ID, new String[]{baseTokenDto.getUserId()})
.header(AppClientConstant.TRANSACTION_SERIAL_KEY, new String[]{getTransactionSerial()})
.build();
return chain.filter(exchange.mutate().request(build).build());
}
return chain.filter(exchange);
}
/**
* 获取事务流水号
* @return
*/
public static String getTransactionSerial() {
String[] letterPool = {"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n"
, "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"};
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 2; i++) {
sb.append(letterPool[(int) (Math.random() * 25)]);
}
sb.append(System.currentTimeMillis());
return sb.toString();
}
}
//package com.epmet.filter;
//
//import com.epmet.commons.tools.constant.AppClientConstant;
//import com.epmet.commons.tools.constant.Constant;
//import com.epmet.commons.tools.security.dto.BaseTokenDto;
//import com.epmet.commons.tools.utils.CpUserDetailRedis;
//import com.epmet.jwt.JwtTokenUtils;
//import org.apache.commons.lang3.StringUtils;
//import org.slf4j.Logger;
//import org.slf4j.LoggerFactory;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.cloud.gateway.filter.GatewayFilterChain;
//import org.springframework.cloud.gateway.filter.GlobalFilter;
//import org.springframework.http.HttpHeaders;
//import org.springframework.http.server.reactive.ServerHttpRequest;
//import org.springframework.stereotype.Component;
//import org.springframework.web.server.ServerWebExchange;
//import reactor.core.publisher.Mono;
//
///**
// * Feign调用发送请求的Filter
// * 目前用于封装用户相关信息到request,供上游微服务使用
// * 已过时,功能移入CpAuthGatewayFilterFacotry
// */
//@Component
//@Deprecated
//public class FeignRequestFilter implements GlobalFilter, UserTokenFilter {
//
// private Logger logger = LoggerFactory.getLogger(getClass());
//
// @Autowired
// private JwtTokenUtils jwtTokenUtils;
// @Autowired
// private CpUserDetailRedis cpUserDetailRedis;
//
// @Override
// public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
// ServerHttpRequest request = exchange.getRequest();
// HttpHeaders headers = request.getHeaders();
// String token = headers.getFirst(Constant.AUTHORIZATION_HEADER);
// if (StringUtils.isBlank(token)) {
// token = headers.getFirst(Constant.TOKEN_HEADER);
// logger.info("token=" + token);
// } else {
// logger.info("authorization=" + token);
// }
// if (StringUtils.isBlank(token)) {
// token = request.getQueryParams().getFirst(Constant.AUTHORIZATION_HEADER);
// logger.info("params token:" + token);
// }
//
// if (StringUtils.isBlank(token)) {
// return chain.filter(exchange);
// }
//
// BaseTokenDto baseTokenDto = getBaseTokenDto(token, jwtTokenUtils);
//
// if (baseTokenDto != null) {
// ServerHttpRequest build = exchange.getRequest().mutate()
// .header(AppClientConstant.USER_ID, new String[]{baseTokenDto.getUserId()})
// .header(AppClientConstant.TRANSACTION_SERIAL_KEY, new String[]{getTransactionSerial()})
// .build();
// return chain.filter(exchange.mutate().request(build).build());
// }
//
// return chain.filter(exchange);
// }
//
// /**
// * 获取事务流水号
// * @return
// */
// public static String getTransactionSerial() {
// String[] letterPool = {"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n"
// , "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"};
//
// StringBuilder sb = new StringBuilder();
// for (int i = 0; i < 2; i++) {
// sb.append(letterPool[(int) (Math.random() * 25)]);
// }
//
// sb.append(System.currentTimeMillis());
// return sb.toString();
// }
//}

32
epmet-module/resi-group/resi-group-client/src/main/java/com/epmet/resi/group/dto/topic/result/ResiTopicClosingMsgResultDTO.java

@ -0,0 +1,32 @@
package com.epmet.resi.group.dto.topic.result;
import lombok.Data;
import java.io.Serializable;
/**
* @Description 关闭话题详情相关信息
* @ClassName ResiTopicClosingMsgResultDTO
* @Auth wangc
* @Date 2020-06-01 17:44
*/
@Data
public class ResiTopicClosingMsgResultDTO implements Serializable {
private static final long serialVersionUID = 3959914139163088792L;
/**
* 关闭人目前只有组长可以关闭话题
* */
private String closeUserName;
/**
* 关闭时间
* */
private Long closeDateTime;
/**
* 关闭理由
* */
private String closeReason;
}

5
epmet-module/resi-group/resi-group-client/src/main/java/com/epmet/resi/group/dto/topic/result/ResiTopicIncludeIssueDetailResultDTO.java

@ -65,4 +65,9 @@ public class ResiTopicIncludeIssueDetailResultDTO implements Serializable {
* 议题Id当shiftIssueFlag为false时返回""
* */
private String issueId;
/**
* 关闭详情 如果没有关闭 对象里的字符串属性为String
* */
private ResiTopicClosingMsgResultDTO closeDetail;
}

34
epmet-module/resi-group/resi-group-server/src/main/java/com/epmet/modules/topic/service/impl/ResiTopicServiceImpl.java

@ -18,6 +18,7 @@
package com.epmet.modules.topic.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.epmet.commons.mybatis.service.impl.BaseServiceImpl;
@ -29,7 +30,6 @@ import com.epmet.commons.tools.security.dto.TokenDto;
import com.epmet.commons.tools.utils.ConvertUtils;
import com.epmet.commons.tools.utils.DateUtils;
import com.epmet.commons.tools.utils.Result;
import com.epmet.commons.tools.validator.ValidatorUtils;
import com.epmet.dto.CustomerGridDTO;
import com.epmet.dto.form.*;
import com.epmet.dto.result.CommonDataFilterResultDTO;
@ -79,7 +79,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.management.monitor.MonitorSettingException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;
@ -523,15 +523,39 @@ public class ResiTopicServiceImpl extends BaseServiceImpl<ResiTopicDao, ResiTopi
resultDTO.setTopicImgs(attachmentUrls);
//3.拿取用户信息
ResiTopicDTO topic = get(topicId);
ResiGroupEntity group = resiGroupDao.selectById(topic.getGroupId());
//ResiTopicDTO topic = get(topicId);
ResiGroupEntity group = resiGroupDao.selectById(topicDetail.getGroupId());
ResiGroupMemberInfoRedisDTO memberRedis =
resiGroupMemberRedis.get(group.getId(),topic.getCreatedBy());
resiGroupMemberRedis.get(group.getId(),topicDetail.getCreatedBy());
if(null != memberRedis && StringUtils.isNotBlank(memberRedis.getUserId())){
resultDTO.setReleaseUserName(StringUtils.isBlank(memberRedis.getUserShowName()) ? "" : memberRedis.getUserShowName());
resultDTO.setReleaseUserHeadPhoto(StringUtils.isBlank(memberRedis.getUserHeadPhoto()) ? "" : memberRedis.getUserHeadPhoto());
}
//4.话题关闭详情
ResiTopicClosingMsgResultDTO closeDetail = new ResiTopicClosingMsgResultDTO();
closeDetail.setCloseReason(ModuleConstant.EMPTY_STR);
closeDetail.setCloseUserName(ModuleConstant.EMPTY_STR);
closeDetail.setCloseDateTime(NumConstant.MINUS_ONE_L);
if(StringUtils.equals(ModuleConstant.TOPIC_STATUS_CLOSED,topicDetail.getStatus())){
QueryWrapper<ResiTopicOperationEntity> queryWrapper = new QueryWrapper<>();
queryWrapper.eq(FieldConstant.DEL_FLAG,NumConstant.ZERO_STR);
queryWrapper.eq(ModuleConstant.FILED_TOPIC_ID,topicDetail.getId());
queryWrapper.eq(ModuleConstant.FIELD_OPERATION_TYPE,ModuleConstant.TOPIC_STATUS_CLOSED);
queryWrapper.orderByDesc(FieldConstant.CREATED_TIME);
List<ResiTopicOperationEntity> records =
resiTopicOperationDao.selectList(queryWrapper);
if(null != records && records.size() > NumConstant.ZERO){
closeDetail.setCloseReason(records.get(0).getOperationReason());
closeDetail.setCloseDateTime(records.get(0).getCreatedTime().getTime()/NumConstant.ONE_THOUSAND);
ResiGroupMemberInfoRedisDTO closedBy =
resiGroupMemberRedis.get(group.getId(),records.get(0).getCreatedBy());
if(null != closedBy){
closeDetail.setCloseUserName(closedBy.getUserShowName());
}
}
}
resultDTO.setCloseDetail(closeDetail);
return new Result<ResiTopicIncludeIssueDetailResultDTO>().ok(resultDTO);
}

9
epmet-module/resi-group/resi-group-server/src/main/java/com/epmet/modules/utils/ModuleConstant.java

@ -267,6 +267,11 @@ public interface ModuleConstant extends Constant {
* */
String TOPIC_OPERATION_TYPE_SHIFT_ISSUE = "shift_issue";
/**
* 话题状态 已关闭
* */
String TOPIC_STATUS_CLOSED = "closed";
/**
* 空字符串
* */
@ -317,4 +322,8 @@ public interface ModuleConstant extends Constant {
String NO_GROUP_CACHE_LOG_TEMPLATE = "没有相应的组缓存信息,组Id:【%s】";
String UPDATE_GROUP_CACHE_SUCCESSFULLY_LOG_TEMPLATE = "更新组缓存信息成功,组Id:【%s】";
String FILED_TOPIC_ID = "TOPIC_ID";
String FIELD_OPERATION_TYPE = "OPERATION_TYPE";
}

Loading…
Cancel
Save