提交 3a50f4e0 编写于 作者: rushui.chen's avatar rushui.chen

20190828 登录接口实现

上级 188a5aca
流水线 #13770 已失败 于阶段
in 0 second
......@@ -4,6 +4,7 @@ import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.pica.cloud.account.account.server.configuration.PropertiesConfiguration;
import com.pica.cloud.account.account.server.constants.Constants;
import com.pica.cloud.account.account.server.entity.AccountUser;
import com.pica.cloud.account.account.server.util.PICAPSendMsgModel;
import com.pica.cloud.foundation.entity.PicaException;
import com.pica.cloud.foundation.entity.PicaResultCode;
......@@ -136,4 +137,12 @@ public abstract class AccountBaseController extends BaseController {
return 0;
}
/**
* 账户信息
*
* @return
*/
protected AccountUser getAccountUser() {
return new AccountUser();
}
}
package com.pica.cloud.account.account.server.controller;
import com.pica.cloud.account.account.server.entity.AccountUser;
import com.pica.cloud.account.account.server.entity.EncryptEntity;
import com.pica.cloud.account.account.server.entity.LogLoginEntity;
import com.pica.cloud.account.account.server.enums.EnumsType;
import com.pica.cloud.account.account.server.log.PicaLogUtils;
import com.pica.cloud.account.account.server.req.BaseRequest;
import com.pica.cloud.account.account.server.service.LoginService;
import com.pica.cloud.account.account.server.service.RegisterService;
import com.pica.cloud.account.account.server.util.AccountUtils;
import com.pica.cloud.account.account.server.util.CryptoUtil;
import com.pica.cloud.foundation.entity.PicaResponse;
import com.pica.cloud.foundation.redis.ICacheClient;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import java.util.Date;
@Api("登录资源")
@RestController
public class LoginController {
public class LoginController extends AccountBaseController {
@Autowired
private LoginService loginService;
@Autowired
@Qualifier("cacheMigrateClient")
private ICacheClient redisClient;
@Autowired
private PicaLogUtils picaLogUtils;
/**
* 密码登录接口
*
* @param entity
* @return
* @throws Exception
*/
@ApiOperation("密码登录接口")
@PostMapping("/login")
public PicaResponse<String> loginByPassword(@RequestBody EncryptEntity entity) throws Exception {
BaseRequest request = CryptoUtil.decrypt(entity, BaseRequest.class);
request.setProductType(super.getProductType());
request.setSourceType(super.getSourceType());
request.setLoginIp(super.getIpAddr());
AccountUtils.checkMobilePhone(request.getMobile());
AccountUtils.checkPassword(request.getPassword());
String result = loginService.login(request);
//todo:查询是否完善过信息
return PicaResponse.toResponse(result);
}
/**
* 一键登录
*
* @param entity
* @return
* @throws Exception
*/
@ApiOperation("一键登录接口")
@PostMapping(value = "/login-register")
public PicaResponse loginAndRegister(@RequestBody EncryptEntity entity) throws Exception {
BaseRequest request = CryptoUtil.decrypt(entity, BaseRequest.class);
AccountUtils.checkMobilePhone(request.getMobile());
AccountUtils.getAuthCodeKey(request.getSysCode(), EnumsType.SYSCODE_TYPE_REGISTER.getCode() + "");
request.setProductType(super.getProductType());
request.setSourceType(super.getSourceType());
request.setLoginIp(super.getIpAddr());
String json = loginService.loginAndRegister(request);
return PicaResponse.toResponse(json);
}
/**
* 退出登录接口
*
* @return
*/
@ApiOperation(value = "退出登录接口")
@GetMapping("/logout")
public PicaResponse loginOut() {
//只有在登录状态下才能调用此接口;
AccountUser accountUser = super.getAccountUser();
String token = accountUser.getToken();
if (StringUtils.isNotEmpty(token)) {
Integer id = accountUser.getAcctId();
LogLoginEntity entity = new LogLoginEntity();
entity.setAcctId(id);
entity.setCreateId(id);
entity.setCreateTime(new Date());
entity.setModifyId(id);
entity.setModifyTime(new Date());
entity.setDeleteFlag(1);
entity.setLoginTime(new Date());
entity.setProductType(super.getProductType());
entity.setSourceType(super.getSourceType());
entity.setLoginType(EnumsType.LOGIN_OUT.getCode());
entity.setLoginIp(super.getIpAddr());
entity.setLoginStatus(EnumsType.LOGIN_STATUS_SUCCESS.getCode());
entity.setLogType(EnumsType.LOG_TYPE_LOGIN.getCode());
picaLogUtils.info(entity);
if (redisClient.deleteToken(token)) {
return PicaResponse.toResponse();
}
}
return null;
}
}
......@@ -23,7 +23,6 @@ public class RegisterController extends AccountBaseController {
@Autowired
private RegisterService registerService;
@ApiOperation("注册接口")
@PostMapping(value = "")
public PicaResponse<String> register(@RequestBody EncryptEntity entity) throws Exception {
......@@ -34,7 +33,8 @@ public class RegisterController extends AccountBaseController {
request.setFlag(EnumsType.SYSCODE_TYPE_REGISTER.getCode());
request.setProductType(super.getProductType());
request.setSourceType(super.getSourceType());
PicaResponse picaResponse = registerService.register(request);
return picaResponse;
request.setLoginIp(super.getIpAddr());
String result = registerService.register(request);
return PicaResponse.toResponse(result);
}
}
......@@ -37,7 +37,7 @@ public class SysCodeController extends AccountBaseController {
@ApiOperation("获取短信验证码")
@PostMapping(value = "")
public PicaResponse getSysCode(@RequestBody EncryptEntity entity) throws Exception {
BaseRequest request = CryptoUtil.decrypt(entity);
BaseRequest request = CryptoUtil.decrypt(entity,BaseRequest.class);
request.setFlag(0);
AccountUtils.checkMobilePhone(request.getMobile());
processSysCode(request.getMobile(), request.getFlag());
......
package com.pica.cloud.account.account.server.entity;
import com.pica.cloud.foundation.utils.entity.PicaUser;
public class AccountUser extends PicaUser {
private Integer acctId;
public Integer getAcctId() {
return acctId;
}
public void setAcctId(Integer acctId) {
this.acctId = acctId;
}
}
package com.pica.cloud.account.account.server.entity;
import com.pica.cloud.account.account.server.log.PicaLogEntity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.util.Date;
@ApiModel
public class LogLoginEntity extends PicaLogEntity {
private Integer id;
......@@ -21,6 +24,8 @@ public class LogLoginEntity extends PicaLogEntity {
private Date loginTime;
//成功,失败
@ApiModelProperty("登陆状态")
private int loginStatus;
private Integer createId;
......
......@@ -9,19 +9,19 @@ import com.pica.cloud.account.account.server.enums.EnumsType;
import com.pica.cloud.account.account.server.mapper.LogLoginMapper;
import com.pica.cloud.account.account.server.mapper.LogPWDModifyMapper;
import com.pica.cloud.account.account.server.mapper.LogUserInfoMapper;
import com.pica.cloud.account.account.server.util.BeanUtil;
import com.pica.cloud.foundation.utils.utils.SpringContextUtil;
import org.springframework.beans.factory.annotation.Autowired;
public class PicaLogTask implements Runnable {
@Autowired
private LogLoginMapper loginLogMapper;
@Autowired
private LogPWDModifyMapper logPWDModifyMapper;
@Autowired
private LogUserInfoMapper logUserInfoMapper;
/**
* 日志类型
*/
......@@ -35,7 +35,9 @@ public class PicaLogTask implements Runnable {
PicaLogTask(PicaLogEntity picaLogEntity) {
this.picaLogEntity = picaLogEntity;
type = picaLogEntity.getLogType();
loginLogMapper = BeanUtil.getBean(LogLoginMapper.class);
logPWDModifyMapper = BeanUtil.getBean(LogPWDModifyMapper.class);
logUserInfoMapper = BeanUtil.getBean(LogUserInfoMapper.class);
}
@Override
......
......@@ -24,7 +24,7 @@ public interface AccountInfoDetailMapper {
*
* @param acctId
*/
void insertCreateInfo(int acctId);
void updateCreateInfo(int acctId);
......
......@@ -14,6 +14,8 @@ public class BaseRequest {
private int productType;
@ApiModelProperty("渠道来源")
private int sourceType;
@ApiModelProperty("登录ip")
private String loginIp;
public String getMobile() {
......@@ -63,4 +65,12 @@ public class BaseRequest {
public void setSourceType(int sourceType) {
this.sourceType = sourceType;
}
public String getLoginIp() {
return loginIp;
}
public void setLoginIp(String loginIp) {
this.loginIp = loginIp;
}
}
package com.pica.cloud.account.account.server.service;
import com.pica.cloud.account.account.server.req.BaseRequest;
public interface LoginService {
/**
* 密码登陆功能
*
* @param request
* @return
*/
String login(BaseRequest request);
/**
* 一键登录功能
*
* @param request
* @return
*/
String loginAndRegister(BaseRequest request);
}
package com.pica.cloud.account.account.server.service;
import com.pica.cloud.account.account.server.req.BaseRequest;
import com.pica.cloud.foundation.entity.PicaResponse;
public interface RegisterService {
PicaResponse register(BaseRequest baseRequest);
String register(BaseRequest baseRequest);
}
......@@ -10,15 +10,31 @@ public class Test {
// String json="{\"key\":\"密钥\",\"content\": {\"mobilePhone\" : \"1302412588\", \"flag\": \"1\"}}\n" +
// " }";
//获取验证码参数
BaseRequest request = new BaseRequest();
request.setFlag(1);
request.setMobile("13024112588");
String string = JSONObject.toJSONString(request);
System.out.println(string);
EncryptEntity encryptEntity = new EncryptEntity();
encryptEntity.setContent(string);
System.out.println(JSONObject.toJSONString(encryptEntity));
System.out.println("------------------------------>");
//获取注册参数
BaseRequest register=null;
register = new BaseRequest();
register.setMobile("13024112588");
register.setPassword("qq123456");
register.setSysCode("111111");
String registerString = JSONObject.toJSONString(register);
System.out.println(registerString);
EncryptEntity registerEncryptEntity = new EncryptEntity();
registerEncryptEntity.setContent(registerString);
System.out.println(JSONObject.toJSONString(registerEncryptEntity));
System.out.println("------------------------------>");
}
......
package com.pica.cloud.account.account.server.service.impl;
import com.alibaba.fastjson.JSONObject;
import com.pica.cloud.account.account.server.entity.Account;
import com.pica.cloud.account.account.server.entity.AccountInfoEntity;
import com.pica.cloud.account.account.server.entity.LogLoginEntity;
import com.pica.cloud.account.account.server.enums.EnumsType;
import com.pica.cloud.account.account.server.enums.ExceptionType;
import com.pica.cloud.account.account.server.log.PicaLogUtils;
import com.pica.cloud.account.account.server.mapper.AccountInfoDetailMapper;
import com.pica.cloud.account.account.server.req.AccountReq;
import com.pica.cloud.account.account.server.req.BaseRequest;
import com.pica.cloud.account.account.server.service.LoginService;
import com.pica.cloud.account.account.server.service.RegisterService;
import com.pica.cloud.account.account.server.util.AccountUtils;
import com.pica.cloud.account.account.server.util.TokenUtils;
import com.pica.cloud.foundation.entity.PicaException;
import com.pica.cloud.foundation.entity.PicaResultCode;
import com.pica.cloud.foundation.redis.ICacheClient;
import com.pica.cloud.foundation.utils.utils.EncryptCreateUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import java.util.Date;
@Service
public class LoginServiceImpl implements LoginService {
private Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
private AccountInfoDetailMapper accountInfoDetailMapper;
@Autowired
private PicaLogUtils picaLogUtils;
@Autowired
private TokenUtils tokenUtils;
@Autowired
private RegisterService registerService;
@Autowired
@Qualifier("cacheMigrateClient")
private ICacheClient redisClient;
@Override
public String login(BaseRequest request) {
String mobile = request.getMobile();
AccountInfoEntity accountInfoEntity = accountInfoDetailMapper.selectByMobile(EncryptCreateUtil.encrypt(mobile));
if (accountInfoEntity != null) {
String oldPwd = accountInfoEntity.getPassword();
String password = request.getPassword();
if (password.equals(EncryptCreateUtil.dencrypt(oldPwd))) {
//登陆成功,返回新的token
Integer id = accountInfoEntity.getId();
int productType = request.getProductType();
int sourceType = request.getSourceType();
Account account = new Account();
//account.setId(userId.longValue());
account.setAcctId(id);
account.setCreatTime(new Date());
account.setMobilePhone(mobile);
account.setRegisterSource(sourceType);
String newToken = tokenUtils.generateToken(account);
JSONObject jsonObject = new JSONObject();
jsonObject.put("token", newToken);
//todo:登陆成功是否要返回用户id
jsonObject.put("userId", newToken);
LogLoginEntity entity = new LogLoginEntity();
entity.setAcctId(id);
entity.setCreateId(id);
entity.setCreateTime(new Date());
entity.setModifyId(id);
entity.setModifyTime(new Date());
entity.setDeleteFlag(1);
entity.setLoginTime(new Date());
entity.setProductType(productType);
entity.setSourceType(request.getSourceType());
entity.setLoginType(EnumsType.LOGIN_REGISTER.getCode());
entity.setLoginIp(request.getLoginIp());
entity.setLoginStatus(EnumsType.LOGIN_STATUS_SUCCESS.getCode());
entity.setLogType(EnumsType.LOG_TYPE_LOGIN.getCode());
picaLogUtils.info(entity);
return jsonObject.toJSONString();
} else {
logger.info("login failure:" + mobile);
throw new PicaException(ExceptionType.PICA_PASSWORD_ERROR.getCode(), ExceptionType.PICA_PASSWORD_ERROR.getMessage());
}
} else {
throw new PicaException(ExceptionType.PICA_NOT_REGISTER.getCode(), ExceptionType.PICA_NOT_REGISTER.getMessage());
}
}
@Override
public String loginAndRegister(BaseRequest baseRequest) {
String mobile = baseRequest.getMobile();
int productType = baseRequest.getProductType();
int sourceType = baseRequest.getSourceType();
AccountInfoEntity accountInfoEntity = accountInfoDetailMapper.selectByMobile(EncryptCreateUtil.encrypt(mobile));
if (accountInfoEntity == null) {
return registerService.register(baseRequest);
} else {
Integer id = accountInfoEntity.getId();
//验证码登陆:只要相同即可成功
AccountReq accountReq = new AccountReq();
accountReq.setAuthCode(baseRequest.getSysCode());
accountReq.setMobilePhone(mobile);
accountReq.setFlag("0");
checkAuthCode(accountReq);
Account account = new Account();
//account.setId(userId.longValue());
account.setAcctId(id);
account.setCreatTime(new Date());
account.setMobilePhone(mobile);
account.setRegisterSource(sourceType);
String newToken = tokenUtils.generateToken(account);
JSONObject jsonObject = new JSONObject();
jsonObject.put("token", newToken);
//todo:登陆成功是否要返回用户id
LogLoginEntity entity = new LogLoginEntity();
entity.setAcctId(id);
entity.setCreateId(id);
entity.setCreateTime(new Date());
entity.setModifyId(id);
entity.setModifyTime(new Date());
entity.setDeleteFlag(1);
entity.setLoginTime(new Date());
entity.setProductType(productType);
entity.setSourceType(baseRequest.getSourceType());
entity.setLoginType(EnumsType.LOGIN_REGISTER.getCode());
entity.setLoginIp(baseRequest.getLoginIp());
entity.setLoginStatus(EnumsType.LOGIN_STATUS_SUCCESS.getCode());
entity.setLogType(EnumsType.LOG_TYPE_LOGIN.getCode());
picaLogUtils.info(entity);
return jsonObject.toJSONString();
}
}
//校验验证码
private void checkAuthCode(AccountReq req) {
String flag = StringUtils.isBlank(req.getFlag()) ? "0" : req.getFlag();
if (StringUtils.isBlank(req.getAuthCode())) {
throw new PicaException(PicaResultCode.PARAM_IS_INVALID.code(), "短信验证码错误");
}
String authCodeKey = AccountUtils.getAuthCodeKey(req.getMobilePhone(), flag);
String cacheCode = redisClient.get(authCodeKey); //从redis获取验证码
if (StringUtils.isBlank(cacheCode)) {
throw new PicaException(PicaResultCode.RESULE_DATA_NONE.code(), "短信验证码已过期,请重新获取");
}
if (!StringUtils.equals(req.getAuthCode(), cacheCode)) {
throw new PicaException(PicaResultCode.PARAM_IS_INVALID.code(), "短信验证码错误");
}
redisClient.del(authCodeKey); //清除验证码
}
}
package com.pica.cloud.account.account.server.service;
package com.pica.cloud.account.account.server.service.impl;
import com.alibaba.fastjson.JSONObject;
import com.pica.cloud.account.account.server.entity.Account;
import com.pica.cloud.account.account.server.entity.AccountInfoEntity;
import com.pica.cloud.account.account.server.entity.AccountUserInfoEntity;
import com.pica.cloud.account.account.server.entity.LogLoginEntity;
import com.pica.cloud.account.account.server.enums.EnumsType;
import com.pica.cloud.account.account.server.enums.ExceptionType;
import com.pica.cloud.account.account.server.log.PicaLogUtils;
import com.pica.cloud.account.account.server.mapper.AccountInfoDetailMapper;
import com.pica.cloud.account.account.server.mapper.AccountUserInfoMapper;
import com.pica.cloud.account.account.server.req.BaseRequest;
import com.pica.cloud.account.account.server.service.RegisterService;
import com.pica.cloud.account.account.server.util.AccountUtils;
import com.pica.cloud.foundation.entity.PicaException;
import com.pica.cloud.foundation.entity.PicaResponse;
......@@ -30,34 +35,38 @@ public class RegisterServiceImpl implements RegisterService {
private AccountInfoDetailMapper accountInfoDetailMapper;
@Autowired
private UserInfoService userInfoService;
private AccountUserInfoMapper accountUserInfoMapper;
@Autowired
@Qualifier("cacheMigrateClient")
private ICacheClient cacheClient;
@Autowired
private PicaLogUtils picaLogUtils;
@Override
public PicaResponse register(BaseRequest baseRequest) {
public String register(BaseRequest baseRequest) {
String mobile = EncryptCreateUtil.encrypt(baseRequest.getMobile());
//校验用户是否已经注册
AccountInfoEntity accountInfoEntity = accountInfoDetailMapper.selectByMobile(mobile);
if (accountInfoEntity != null) {
if (accountInfoEntity == null) {
int productType = baseRequest.getProductType();
int sourceType = baseRequest.getSourceType();
AccountInfoEntity accountInfo = new AccountInfoEntity();
accountInfo.setMobilePhone(baseRequest.getMobile());
accountInfo.setPassword(baseRequest.getPassword());
accountInfo.setMobilePhone(EncryptCreateUtil.encrypt(baseRequest.getMobile()));
accountInfo.setPassword(EncryptCreateUtil.encrypt(baseRequest.getPassword()));
accountInfo.setCreatedTime(new Date());
accountInfo.setCreatedId(0);
accountInfo.setModifiedId(0);
accountInfo.setModifiedTime(new Date());
accountInfo.setRegTime(new Date());
accountInfo.setDeleteFlag(1);
accountInfo.setRegisterProduct(baseRequest.getProductType());
accountInfo.setRegisterSource(baseRequest.getSourceType());
accountInfo.setSex(0);
accountInfo.setRegisterProduct(productType);
accountInfo.setRegisterSource(sourceType);
accountInfoDetailMapper.insertSelective(accountInfo);
//账户id
Integer acctId = accountInfo.getId();
accountInfoDetailMapper.insertCreateInfo(acctId);
accountInfoDetailMapper.updateCreateInfo(acctId);
AccountUserInfoEntity accountUserInfoEntity = new AccountUserInfoEntity();
accountUserInfoEntity.setAcctId(acctId);
accountUserInfoEntity.setDeleteFlag(1);
......@@ -65,23 +74,34 @@ public class RegisterServiceImpl implements RegisterService {
accountUserInfoEntity.setModifyId(acctId);
accountUserInfoEntity.setCreateTime(new Date());
accountUserInfoEntity.setModifyTime(new Date());
userInfoService.insertUserInfo(accountUserInfoEntity);
accountUserInfoMapper.insertSelective(accountUserInfoEntity);
Integer userId = accountUserInfoEntity.getId();
Account account = new Account();
account.setId(userId.longValue());
account.setAcctId(acctId);
account.setCreatTime(new Date());
account.setMobilePhone(mobile);
account.setRegisterSource(baseRequest.getSourceType());
account.setRegisterSource(sourceType);
String newToken = this.generateToken(account);
JSONObject jsonObject = new JSONObject();
jsonObject.put("token", newToken);
jsonObject.put("userId", userId);
return PicaResponse.toResponse(jsonObject.toJSONString());
//用户信息表记录
LogLoginEntity entity = new LogLoginEntity();
entity.setAcctId(acctId);
entity.setCreateId(acctId);
entity.setCreateTime(new Date());
entity.setModifyId(acctId);
entity.setModifyTime(new Date());
entity.setDeleteFlag(1);
entity.setLoginTime(new Date());
entity.setProductType(productType);
entity.setSourceType(baseRequest.getSourceType());
entity.setLoginType(EnumsType.LOGIN_REGISTER.getCode());
entity.setLoginIp(baseRequest.getLoginIp());
entity.setLoginStatus(EnumsType.LOGIN_STATUS_SUCCESS.getCode());
entity.setLogType(EnumsType.LOG_TYPE_LOGIN.getCode());
picaLogUtils.info(entity);
return jsonObject.toJSONString();
} else {
throw new PicaException(ExceptionType.PICA_ALREADY_REGISTER.getCode(), ExceptionType.PICA_ALREADY_REGISTER.getMessage());
}
......
......@@ -9,5 +9,7 @@ public class UserInfoServerImpl implements UserInfoService {
@Override
public AccountUserInfoEntity insertUserInfo(AccountUserInfoEntity accountUserInfoEntity) {
return null;
//
}
}
package com.pica.cloud.account.account.server.util;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
@Component
public class BeanUtil implements ApplicationContextAware {
private static ApplicationContext context;
@Override
public void setApplicationContext(ApplicationContext paramApplicationContext)
throws BeansException {
context = paramApplicationContext;
}
public static ApplicationContext getContext() {
return context;
}
public static Object getBean(String beanName) {
return context.getBean(beanName);
}
public static <T> T getBean(Class<T> beanClass) {
return context.getBean(beanClass);
}
}
......@@ -39,11 +39,9 @@
</select>
<!--插入注册人信息-->
<insert id="insertCreateInfo" parameterType="com.pica.cloud.account.account.server.entity.AccountInfoEntity">
insert into account_info (id, created_id,modified_id)
values (#{acctId},#{acctId},#{acctId})
</insert>
<update id="updateCreateInfo" parameterType="com.pica.cloud.account.account.server.entity.AccountInfoEntity">
update account_info set created_id=#{acctId}, modified_id=#{acctId} where id=#{acctId}
</update>
<delete id="deleteByPrimaryKey" parameterType="java.lang.Integer">
delete from account_info
......@@ -63,7 +61,9 @@
#{createdTime,jdbcType=TIMESTAMP}, #{modifiedId,jdbcType=INTEGER}, #{modifiedTime,jdbcType=TIMESTAMP}
)
</insert>
<insert id="insertSelective" parameterType="com.pica.cloud.account.account.server.entity.AccountInfoEntity">
<insert id="insertSelective" parameterType="com.pica.cloud.account.account.server.entity.AccountInfoEntity"
useGeneratedKeys="true" keyProperty="id">
insert into account_info
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="id != null">
......
Markdown 格式
0% or
您添加了 0 到此讨论。请谨慎行事。
先完成此消息的编辑!
想要评论请 注册