商家入驻接口开发
This commit is contained in:
parent
39e86f5668
commit
faa943df0a
@ -59,7 +59,6 @@ import com.suisung.mall.common.utils.pojo.dto.EmailDTO;
|
|||||||
import com.suisung.mall.core.web.service.CloundService;
|
import com.suisung.mall.core.web.service.CloundService;
|
||||||
import com.suisung.mall.core.web.service.RedisService;
|
import com.suisung.mall.core.web.service.RedisService;
|
||||||
import com.suisung.mall.core.web.service.impl.BaseServiceImpl;
|
import com.suisung.mall.core.web.service.impl.BaseServiceImpl;
|
||||||
import com.sun.javafx.geom.ConcentricShapePair;
|
|
||||||
import io.seata.common.util.StringUtils;
|
import io.seata.common.util.StringUtils;
|
||||||
import io.seata.spring.annotation.GlobalTransactional;
|
import io.seata.spring.annotation.GlobalTransactional;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
@ -94,6 +93,7 @@ import static com.suisung.mall.common.utils.I18nUtil._;
|
|||||||
public class AccountUserBaseServiceImpl extends BaseServiceImpl<AccountUserBaseMapper, AccountUserBase> implements AccountUserBaseService {
|
public class AccountUserBaseServiceImpl extends BaseServiceImpl<AccountUserBaseMapper, AccountUserBase> implements AccountUserBaseService {
|
||||||
|
|
||||||
private final String VERIFY_CODE_KEY = "register:verifyCode:";
|
private final String VERIFY_CODE_KEY = "register:verifyCode:";
|
||||||
|
private final Logger logger = LoggerFactory.getLogger(AccountUserBaseServiceImpl.class);
|
||||||
@Autowired
|
@Autowired
|
||||||
private AuthService authService;
|
private AuthService authService;
|
||||||
@Autowired
|
@Autowired
|
||||||
@ -138,7 +138,6 @@ public class AccountUserBaseServiceImpl extends BaseServiceImpl<AccountUserBaseM
|
|||||||
private AccountUserBaseMapper accountUserBaseMapper;
|
private AccountUserBaseMapper accountUserBaseMapper;
|
||||||
@Autowired
|
@Autowired
|
||||||
private CloundService cloundService;
|
private CloundService cloundService;
|
||||||
private final Logger logger = LoggerFactory.getLogger(AccountUserBaseServiceImpl.class);
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CommonResult login(Map<String, String> params) {
|
public CommonResult login(Map<String, String> params) {
|
||||||
@ -157,7 +156,9 @@ public class AccountUserBaseServiceImpl extends BaseServiceImpl<AccountUserBaseM
|
|||||||
// throw new ApiException(ResultCode.USERPWD_FAILED);
|
// throw new ApiException(ResultCode.USERPWD_FAILED);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
if (restResult.getStatus() != 200) return restResult;
|
if (restResult.getStatus() != 200) {
|
||||||
|
return restResult;
|
||||||
|
}
|
||||||
|
|
||||||
//成功使用,删除验证码
|
//成功使用,删除验证码
|
||||||
if (hasKey) {
|
if (hasKey) {
|
||||||
@ -172,7 +173,7 @@ public class AccountUserBaseServiceImpl extends BaseServiceImpl<AccountUserBaseM
|
|||||||
try {
|
try {
|
||||||
jwsObject = JWSObject.parse(token);
|
jwsObject = JWSObject.parse(token);
|
||||||
} catch (ParseException e) {
|
} catch (ParseException e) {
|
||||||
logger.error("解析token信息异常!" + e.getMessage(), e);
|
logger.error("解析token信息异常:{} {}", e.getMessage(), e);
|
||||||
}
|
}
|
||||||
|
|
||||||
UserDto userDto = JSONUtil.toBean(jwsObject.getPayload().toString(), UserDto.class);
|
UserDto userDto = JSONUtil.toBean(jwsObject.getPayload().toString(), UserDto.class);
|
||||||
@ -222,7 +223,9 @@ public class AccountUserBaseServiceImpl extends BaseServiceImpl<AccountUserBaseM
|
|||||||
Map<String, Object> adminMap = BeanUtil.beanToMap(admin);
|
Map<String, Object> adminMap = BeanUtil.beanToMap(admin);
|
||||||
Map<String, Object> userInfoMap = BeanUtil.beanToMap(userInfo);
|
Map<String, Object> userInfoMap = BeanUtil.beanToMap(userInfo);
|
||||||
|
|
||||||
if (ObjectUtil.isNull(userInfo)) return adminMap;
|
if (ObjectUtil.isNull(userInfo)) {
|
||||||
|
return adminMap;
|
||||||
|
}
|
||||||
|
|
||||||
adminMap.putAll(userInfoMap);
|
adminMap.putAll(userInfoMap);
|
||||||
|
|
||||||
@ -2968,11 +2971,11 @@ public class AccountUserBaseServiceImpl extends BaseServiceImpl<AccountUserBaseM
|
|||||||
if (null != entity) {
|
if (null != entity) {
|
||||||
Class<?> cls = entity.getClass();
|
Class<?> cls = entity.getClass();
|
||||||
TableInfo tableInfo = TableInfoHelper.getTableInfo(cls);
|
TableInfo tableInfo = TableInfoHelper.getTableInfo(cls);
|
||||||
Assert.notNull(tableInfo, "error: can not execute. because can not find cache of TableInfo for entity!", new Object[0]);
|
Assert.notNull(tableInfo, "error: can not execute. because can not find cache of TableInfo for entity!");
|
||||||
String keyProperty = tableInfo.getKeyProperty();
|
String keyProperty = tableInfo.getKeyProperty();
|
||||||
Assert.notEmpty(keyProperty, "error: can not execute. because can not find column for id from entity!", new Object[0]);
|
Assert.notEmpty(keyProperty, "error: can not execute. because can not find column for id from entity!");
|
||||||
Object idVal = ReflectionKit.getFieldValue(entity, tableInfo.getKeyProperty());
|
Object idVal = ReflectionKit.getFieldValue(entity, tableInfo.getKeyProperty());
|
||||||
flag = !com.baomidou.mybatisplus.core.toolkit.StringUtils.checkValNull(idVal) && !Objects.isNull(this.getById((Serializable)idVal)) ? this.edit(entity) : this.add(entity);
|
flag = !com.baomidou.mybatisplus.core.toolkit.StringUtils.checkValNull(idVal) && !Objects.isNull(this.getById((Serializable) idVal)) ? this.edit(entity) : this.add(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Pair.of(flag, entity);
|
return Pair.of(flag, entity);
|
||||||
|
|||||||
@ -13,7 +13,6 @@ import org.slf4j.LoggerFactory;
|
|||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.security.oauth2.common.OAuth2AccessToken;
|
import org.springframework.security.oauth2.common.OAuth2AccessToken;
|
||||||
import org.springframework.security.oauth2.provider.endpoint.TokenEndpoint;
|
import org.springframework.security.oauth2.provider.endpoint.TokenEndpoint;
|
||||||
import org.springframework.web.HttpRequestMethodNotSupportedException;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestMethod;
|
import org.springframework.web.bind.annotation.RequestMethod;
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
@ -31,7 +30,7 @@ import java.util.Map;
|
|||||||
@RequestMapping("/oauth")
|
@RequestMapping("/oauth")
|
||||||
public class AuthController {
|
public class AuthController {
|
||||||
|
|
||||||
private static Logger logger = LoggerFactory.getLogger(AuthController.class);
|
private static final Logger logger = LoggerFactory.getLogger(AuthController.class);
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private TokenEndpoint tokenEndpoint;
|
private TokenEndpoint tokenEndpoint;
|
||||||
@ -46,7 +45,7 @@ public class AuthController {
|
|||||||
@ApiImplicitParam(name = "password", value = "登录密码")
|
@ApiImplicitParam(name = "password", value = "登录密码")
|
||||||
})
|
})
|
||||||
@RequestMapping(value = "/token", method = RequestMethod.POST)
|
@RequestMapping(value = "/token", method = RequestMethod.POST)
|
||||||
public CommonResult postAccessToken(@ApiIgnore Principal principal, @ApiIgnore @RequestParam Map<String, String> parameters) throws HttpRequestMethodNotSupportedException {
|
public CommonResult postAccessToken(@ApiIgnore Principal principal, @ApiIgnore @RequestParam Map<String, String> parameters) {
|
||||||
OAuth2AccessToken oAuth2AccessToken = null;
|
OAuth2AccessToken oAuth2AccessToken = null;
|
||||||
Oauth2TokenDto oauth2TokenDto = null;
|
Oauth2TokenDto oauth2TokenDto = null;
|
||||||
try {
|
try {
|
||||||
|
|||||||
@ -0,0 +1,70 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2025. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
||||||
|
* Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan.
|
||||||
|
* Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna.
|
||||||
|
* Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus.
|
||||||
|
* Vestibulum commodo. Ut rhoncus gravida arcu.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.suisung.mall.common.modules.esign;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import io.swagger.annotations.ApiModel;
|
||||||
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = false)
|
||||||
|
@Accessors(chain = true)
|
||||||
|
@TableName("esign_contract")
|
||||||
|
@ApiModel(value = "EsignContract 对象", description = "合作多方电子签名审核主表")
|
||||||
|
public class EsignContract implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@TableId(value = "id", type = IdType.INPUT)
|
||||||
|
@ApiModelProperty(value = "自增ID")
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "店铺编号")
|
||||||
|
private String store_id;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "合同编号,自定义生成")
|
||||||
|
private String contract_number;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "合同名称")
|
||||||
|
private String contract_name;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "合同模版Id")
|
||||||
|
private String doc_template_id;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "生成的未签署合同地址(30天有效期)")
|
||||||
|
private String unsigned_contract_url;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "生成的未签署合同地址(30天有效期)")
|
||||||
|
private String signed_contract_url;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "未签署合同地址本地下载地址")
|
||||||
|
private String local_contract_url;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "记录状态:1-有效;2-无效;")
|
||||||
|
private Integer status;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "创建人用户ID")
|
||||||
|
private String created_by;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "修改人用户ID")
|
||||||
|
private String updated_by;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "记录创建时间")
|
||||||
|
private Date created_at;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "记录更新时间")
|
||||||
|
private Date updated_at;
|
||||||
|
}
|
||||||
@ -0,0 +1,70 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2025. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
||||||
|
* Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan.
|
||||||
|
* Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna.
|
||||||
|
* Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus.
|
||||||
|
* Vestibulum commodo. Ut rhoncus gravida arcu.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.suisung.mall.common.modules.esign;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import io.swagger.annotations.ApiModel;
|
||||||
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = false)
|
||||||
|
@Accessors(chain = true)
|
||||||
|
@TableName("esign_contract_filling_file")
|
||||||
|
@ApiModel(value = "EsignContractFillingFile 对象", description = "待签署合同填充的文件表")
|
||||||
|
public class EsignContractFillingFile implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@TableId(value = "id", type = IdType.INPUT)
|
||||||
|
@ApiModelProperty(value = "自增ID")
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "店铺编号")
|
||||||
|
private String store_id;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "合同编号,自定义生成")
|
||||||
|
private String contract_number;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "合同名称")
|
||||||
|
private String contract_name;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "模版编号")
|
||||||
|
private String doc_template_id;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "模版填充json键值对数据")
|
||||||
|
private String doc_template_filling_values;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "生成的未签署合同地址(30天有效期)")
|
||||||
|
private String unsigned_contract_url;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "未签署合同地址本地下载地址")
|
||||||
|
private String unsigned_contract_local_url;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "记录状态:1-有效;2-无效;")
|
||||||
|
private Integer status;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "创建人用户ID")
|
||||||
|
private String created_by;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "修改人用户ID")
|
||||||
|
private String updated_by;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "记录创建时间")
|
||||||
|
private Date created_at;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "记录更新时间")
|
||||||
|
private Date updated_at;
|
||||||
|
}
|
||||||
@ -0,0 +1,71 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2025. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
||||||
|
* Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan.
|
||||||
|
* Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna.
|
||||||
|
* Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus.
|
||||||
|
* Vestibulum commodo. Ut rhoncus gravida arcu.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.suisung.mall.common.modules.esign;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import io.swagger.annotations.ApiModel;
|
||||||
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = false)
|
||||||
|
@Accessors(chain = true)
|
||||||
|
@TableName("esign_contract_party")
|
||||||
|
@ApiModel(value = "EsignContractParty 对象", description = "合作多方电子签名审核子项表(多合作方)")
|
||||||
|
public class EsignContractParty implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@TableId(value = "id", type = IdType.INPUT)
|
||||||
|
@ApiModelProperty(value = "自增ID")
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "合同编号,自定义生成")
|
||||||
|
private String contract_number;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "合作方名称")
|
||||||
|
private String party_name;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "合作方签署状态:1-签署;2-未签署;")
|
||||||
|
private Integer sign_status;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "合作方签署时间")
|
||||||
|
private Date sign_time;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "合作方签署方式:1-人脸识别;2-身份证认证;")
|
||||||
|
private Integer sign_style;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "是否签署方:1-发起方;2-签署方;")
|
||||||
|
private Integer is_signer;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "合作方审核状态:1-审核已通过;2-审核未通过;")
|
||||||
|
private String audit_status;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "合作方审核意见")
|
||||||
|
private String audit_remark;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "签署流程ID")
|
||||||
|
private String sign_flow_id;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "签署流程主题")
|
||||||
|
private String sign_flow_title;
|
||||||
|
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "记录创建时间")
|
||||||
|
private Date created_at;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "记录更新时间")
|
||||||
|
private Date updated_at;
|
||||||
|
}
|
||||||
@ -0,0 +1,163 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2025. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
||||||
|
* Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan.
|
||||||
|
* Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna.
|
||||||
|
* Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus.
|
||||||
|
* Vestibulum commodo. Ut rhoncus gravida arcu.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.suisung.mall.common.modules.merch;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import io.swagger.annotations.ApiModel;
|
||||||
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = false)
|
||||||
|
@Accessors(chain = true)
|
||||||
|
@TableName("shop_mch_entry")
|
||||||
|
@ApiModel(value = "ShopMerchEntry 实体", description = "商家入驻信息表")
|
||||||
|
public class ShopMerchEntry implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "自增ID")
|
||||||
|
@TableId(value = "id", type = IdType.INPUT)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "入驻商家的登录手机号")
|
||||||
|
private String login_mobile;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "商家店铺的ID")
|
||||||
|
private String store_id;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "商家店铺的名称")
|
||||||
|
private String store_name;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "入驻商家的联系人姓名")
|
||||||
|
private String contact_name;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "商家经营的类目,用数字表示不同类目")
|
||||||
|
private Integer biz_category;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "除去运费的商家分成比列,如:95.00,最大100,最小0")
|
||||||
|
private String split_ratio;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "分账到账方式:1-T+0;2-T+1,3-T+3...")
|
||||||
|
private Integer settlement_method;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "商家入驻合同的编号")
|
||||||
|
private String contract_number;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "入驻商家正式合同的下载地址")
|
||||||
|
private String contract_download_url;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "入驻商家店铺经度")
|
||||||
|
private String store_longitude;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "入驻商家店铺维度")
|
||||||
|
private String store_latitude;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "入驻商家店铺所在的省")
|
||||||
|
private String province_id;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "入驻商家店铺所在的市")
|
||||||
|
private String city_id;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "入驻商家店铺所在的县区")
|
||||||
|
private String county_id;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "入驻商家店铺的详细地址")
|
||||||
|
private String store_address;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "入驻商家店铺门面正面图片的存储路径")
|
||||||
|
private String front_facade_image;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "入驻商家店铺门面环境图片的存储路径")
|
||||||
|
private String environment_image;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "入驻主体类型,企业或个人:1-企业;2-个人;")
|
||||||
|
private Integer entity_type;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "企业入驻时的营业执照编号")
|
||||||
|
private String biz_license_number;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "入驻商家营业执照图片的存储路径")
|
||||||
|
private String biz_license_image;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "入驻商家的许可证类型:1-许可证;2-特许证件,3-其他证件")
|
||||||
|
private Integer license_type;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "入驻商家的许可证编号")
|
||||||
|
private String license_number;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "入驻商家许可证图片的存储路径")
|
||||||
|
private String license_image;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "入驻商家的法人姓名")
|
||||||
|
private String legal_person_name;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "入驻商家的法人姓名")
|
||||||
|
private String legal_person_mobile;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "入驻商家的法人身份证号码")
|
||||||
|
private String legal_person_id_number;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "入驻商家法人身份证正面图片的存储路径")
|
||||||
|
private String legal_person_id_images;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "入驻商家法人身份证反面图片的存储路径")
|
||||||
|
private String legal_person_id_images2;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "个人入驻时的身份证号码")
|
||||||
|
private String individual_id_number;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "个人入驻时身份证正面图片的存储路径")
|
||||||
|
private String individual_id_images;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "个人入驻时身份证反面图片的存储路径")
|
||||||
|
private String individual_id_images2;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "入驻商家的开户银行")
|
||||||
|
private String bank_name;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "入驻商家开户银行的支行名称")
|
||||||
|
private String bank_branch_name;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "入驻商家的收款账户号码")
|
||||||
|
private String account_number;
|
||||||
|
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "入驻商家的收款账户姓名")
|
||||||
|
private String account_holder_name;
|
||||||
|
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "入驻商家的审批状态:1-已通过;2-未通过;3-待审核;")
|
||||||
|
private Integer approval_status;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "入驻商家审批时的备注信息")
|
||||||
|
private String approval_remark;
|
||||||
|
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "该商家入驻记录是否有效,0:无效,1:有效")
|
||||||
|
private Integer status;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "创建该商家入驻记录的用户")
|
||||||
|
private String created_by;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "最后修改该商家入驻记录的用户")
|
||||||
|
private String updated_by;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "商家入驻记录的创建时间")
|
||||||
|
private Date created_at;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "商家入驻记录的更新时间")
|
||||||
|
private Date updated_at;
|
||||||
|
}
|
||||||
@ -1,15 +1,12 @@
|
|||||||
package com.suisung.mall.common.utils;
|
package com.suisung.mall.common.utils;
|
||||||
|
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import cn.hutool.json.JSONUtil;
|
|
||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.google.gson.*;
|
import com.google.gson.*;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.w3c.dom.Document;
|
import org.w3c.dom.Document;
|
||||||
import org.xml.sax.InputSource;
|
import org.xml.sax.InputSource;
|
||||||
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
|
|
||||||
|
|
||||||
import javax.xml.parsers.DocumentBuilder;
|
import javax.xml.parsers.DocumentBuilder;
|
||||||
import javax.xml.parsers.DocumentBuilderFactory;
|
import javax.xml.parsers.DocumentBuilderFactory;
|
||||||
@ -359,18 +356,20 @@ public final class StringUtils extends org.apache.commons.lang3.StringUtils {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 将 JSON 字符串中驼峰命名的键转换为下划线命名
|
* 将 JSON 字符串中驼峰命名的键转换为下划线命名
|
||||||
|
*
|
||||||
* @param jsonString 输入的 JSON 字符串
|
* @param jsonString 输入的 JSON 字符串
|
||||||
* @return 转换后的 JSON 字符串
|
* @return 转换后的 JSON 字符串
|
||||||
*/
|
*/
|
||||||
public static String convertCamelToSnake(String jsonString) {
|
public static String convertCamelToSnake(String jsonString) {
|
||||||
Gson gson = new Gson();
|
Gson gson = new Gson();
|
||||||
JsonElement jsonElement = JsonParser.parseString(jsonString);
|
JsonElement jsonElement = JsonParser.parseString(jsonString);
|
||||||
JsonElement convertedElement = convertKeys(jsonElement,true);
|
JsonElement convertedElement = convertKeys(jsonElement, true);
|
||||||
return gson.toJson(convertedElement);
|
return gson.toJson(convertedElement);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 将 JSON 字符串中蛇形命名的键转换为驼峰命名
|
* 将 JSON 字符串中蛇形命名的键转换为驼峰命名
|
||||||
|
*
|
||||||
* @param jsonString 输入的 JSON 字符串
|
* @param jsonString 输入的 JSON 字符串
|
||||||
* @return 转换后的 JSON 字符串
|
* @return 转换后的 JSON 字符串
|
||||||
*/
|
*/
|
||||||
@ -379,13 +378,14 @@ public final class StringUtils extends org.apache.commons.lang3.StringUtils {
|
|||||||
// 解析 JSON 字符串为 JsonElement 对象
|
// 解析 JSON 字符串为 JsonElement 对象
|
||||||
JsonElement jsonElement = JsonParser.parseString(jsonString);
|
JsonElement jsonElement = JsonParser.parseString(jsonString);
|
||||||
// 递归转换键名
|
// 递归转换键名
|
||||||
JsonElement convertedElement = convertKeys(jsonElement,true);
|
JsonElement convertedElement = convertKeys(jsonElement, true);
|
||||||
// 将转换后的 JsonElement 转换回 JSON 字符串
|
// 将转换后的 JsonElement 转换回 JSON 字符串
|
||||||
return gson.toJson(convertedElement);
|
return gson.toJson(convertedElement);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 递归转换 JSON 元素中的键名
|
* 递归转换 JSON 元素中的键名
|
||||||
|
*
|
||||||
* @param element 要转换的 JSON 元素
|
* @param element 要转换的 JSON 元素
|
||||||
* @return 转换后的 JSON 元素
|
* @return 转换后的 JSON 元素
|
||||||
*/
|
*/
|
||||||
@ -395,10 +395,10 @@ public final class StringUtils extends org.apache.commons.lang3.StringUtils {
|
|||||||
JsonObject newJsonObject = new JsonObject();
|
JsonObject newJsonObject = new JsonObject();
|
||||||
for (Map.Entry<String, JsonElement> entry : jsonObject.entrySet()) {
|
for (Map.Entry<String, JsonElement> entry : jsonObject.entrySet()) {
|
||||||
|
|
||||||
String newKey ;
|
String newKey;
|
||||||
if(isCamelToSnake) {
|
if (isCamelToSnake) {
|
||||||
newKey = camelToSnake(entry.getKey());
|
newKey = camelToSnake(entry.getKey());
|
||||||
}else{
|
} else {
|
||||||
newKey = snakeToCamel(entry.getKey());
|
newKey = snakeToCamel(entry.getKey());
|
||||||
}
|
}
|
||||||
JsonElement value = entry.getValue();
|
JsonElement value = entry.getValue();
|
||||||
@ -417,9 +417,9 @@ public final class StringUtils extends org.apache.commons.lang3.StringUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 将单个驼峰命名的字符串转换为下划线命名
|
* 将单个驼峰命名的字符串转换为下划线命名
|
||||||
|
*
|
||||||
* @param camelCase 驼峰命名的字符串
|
* @param camelCase 驼峰命名的字符串
|
||||||
* @return 下划线命名的字符串
|
* @return 下划线命名的字符串
|
||||||
*/
|
*/
|
||||||
@ -437,6 +437,7 @@ public final class StringUtils extends org.apache.commons.lang3.StringUtils {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 将单个蛇形命名的字符串转换为驼峰命名
|
* 将单个蛇形命名的字符串转换为驼峰命名
|
||||||
|
*
|
||||||
* @param snakeCase 蛇形命名的字符串
|
* @param snakeCase 蛇形命名的字符串
|
||||||
* @return 驼峰命名的字符串
|
* @return 驼峰命名的字符串
|
||||||
*/
|
*/
|
||||||
@ -462,6 +463,7 @@ public final class StringUtils extends org.apache.commons.lang3.StringUtils {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据文件名获取文件后缀
|
* 根据文件名获取文件后缀
|
||||||
|
*
|
||||||
* @param fileName 文件名
|
* @param fileName 文件名
|
||||||
* @return 文件后缀,如果没有后缀则返回空字符串
|
* @return 文件后缀,如果没有后缀则返回空字符串
|
||||||
*/
|
*/
|
||||||
@ -476,6 +478,110 @@ public final class StringUtils extends org.apache.commons.lang3.StringUtils {
|
|||||||
return fileName.substring(lastIndex + 1);
|
return fileName.substring(lastIndex + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 校验内地身份证号码
|
||||||
|
*
|
||||||
|
* @param idCard 身份证号码
|
||||||
|
* @return 是否有效
|
||||||
|
*/
|
||||||
|
public static boolean validateMainlandIDCard(String idCard) {
|
||||||
|
if (idCard == null || idCard.length() != 18) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return Pattern.matches("^[1-9]\\d{5}(18|19|20)\\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\\d|3[01])\\d{3}[0-9Xx]$", idCard);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 校验香港身份证号码
|
||||||
|
*
|
||||||
|
* @param idCard 身份证号码
|
||||||
|
* @return 是否有效
|
||||||
|
*/
|
||||||
|
public static boolean validateHongKongIDCard(String idCard) {
|
||||||
|
if (idCard == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
idCard = idCard.toUpperCase();
|
||||||
|
if (!Pattern.matches("^[A-Z]{1,2}\\d{6}[\\dA]$", idCard)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// 计算校验码
|
||||||
|
int sum = 0;
|
||||||
|
if (idCard.length() == 9) {
|
||||||
|
sum += (idCard.charAt(0) - 55) * 8;
|
||||||
|
sum += (idCard.charAt(1) - 55) * 7;
|
||||||
|
} else {
|
||||||
|
sum += 36 * 8;
|
||||||
|
sum += (idCard.charAt(0) - 55) * 7;
|
||||||
|
}
|
||||||
|
sum += (idCard.charAt(idCard.length() - 7) - 48) * 6;
|
||||||
|
sum += (idCard.charAt(idCard.length() - 6) - 48) * 5;
|
||||||
|
sum += (idCard.charAt(idCard.length() - 5) - 48) * 4;
|
||||||
|
sum += (idCard.charAt(idCard.length() - 4) - 48) * 3;
|
||||||
|
sum += (idCard.charAt(idCard.length() - 3) - 48) * 2;
|
||||||
|
sum += (idCard.charAt(idCard.length() - 2) - 48);
|
||||||
|
int remainder = sum % 11;
|
||||||
|
int checkDigit = 11 - remainder;
|
||||||
|
if (checkDigit == 11) {
|
||||||
|
checkDigit = 0;
|
||||||
|
} else if (checkDigit == 10) {
|
||||||
|
checkDigit = 'A';
|
||||||
|
}
|
||||||
|
char lastChar = idCard.charAt(idCard.length() - 1);
|
||||||
|
return (checkDigit == (lastChar >= '0' && lastChar <= '9' ? lastChar - 48 : lastChar));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 校验澳门身份证号码
|
||||||
|
*
|
||||||
|
* @param idCard 身份证号码
|
||||||
|
* @return 是否有效
|
||||||
|
*/
|
||||||
|
public static boolean validateMacaoIDCard(String idCard) {
|
||||||
|
if (idCard == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return Pattern.matches("^[1|5|7]\\d{6}[\\dA]$", idCard);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 校验台湾身份证号码
|
||||||
|
*
|
||||||
|
* @param idCard 身份证号码
|
||||||
|
* @return 是否有效
|
||||||
|
*/
|
||||||
|
public static boolean validateTaiwanIDCard(String idCard) {
|
||||||
|
if (idCard == null || idCard.length() != 10) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!Pattern.matches("^[A-Z][12]\\d{8}$", idCard)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// 计算校验码
|
||||||
|
int[] weights = {1, 9, 8, 7, 6, 5, 4, 3, 2, 1};
|
||||||
|
int[] areaCodes = {10, 11, 12, 13, 14, 15, 16, 17, 34, 18, 19, 20, 21, 22, 35, 23, 24, 25, 26, 27, 28, 29, 32, 30, 31, 33};
|
||||||
|
int sum = 0;
|
||||||
|
char firstChar = idCard.charAt(0);
|
||||||
|
int areaIndex = firstChar - 'A';
|
||||||
|
int areaValue = areaCodes[areaIndex];
|
||||||
|
sum += areaValue / 10 * weights[0];
|
||||||
|
sum += areaValue % 10 * weights[1];
|
||||||
|
for (int i = 1; i < 9; i++) {
|
||||||
|
sum += (idCard.charAt(i) - '0') * weights[i + 1];
|
||||||
|
}
|
||||||
|
int checkDigit = (10 - sum % 10) % 10;
|
||||||
|
return checkDigit == (idCard.charAt(9) - '0');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 综合校验身份证号码
|
||||||
|
*
|
||||||
|
* @param idCard 身份证号码
|
||||||
|
* @return 是否有效
|
||||||
|
*/
|
||||||
|
public static boolean validateIDCard(String idCard) {
|
||||||
|
return validateMainlandIDCard(idCard) || validateHongKongIDCard(idCard) || validateMacaoIDCard(idCard) || validateTaiwanIDCard(idCard);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -46,16 +46,13 @@ import java.util.stream.Collectors;
|
|||||||
@Slf4j
|
@Slf4j
|
||||||
public class AccountBaseConfigServiceImpl extends BaseServiceImpl<AccountBaseConfigMapper, AccountBaseConfig> implements AccountBaseConfigService, CommandLineRunner {
|
public class AccountBaseConfigServiceImpl extends BaseServiceImpl<AccountBaseConfigMapper, AccountBaseConfig> implements AccountBaseConfigService, CommandLineRunner {
|
||||||
|
|
||||||
|
public static Map<String, AccountBaseConfig> configMap;
|
||||||
|
public static Long version = 0L;
|
||||||
@Autowired
|
@Autowired
|
||||||
private AccountService accountService;
|
private AccountService accountService;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private RedisService redisService;
|
private RedisService redisService;
|
||||||
|
|
||||||
public static Map<String, AccountBaseConfig> configMap;
|
|
||||||
|
|
||||||
public static Long version = 0L;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据config_key 获取 config_value
|
* 根据config_key 获取 config_value
|
||||||
*
|
*
|
||||||
@ -63,9 +60,15 @@ public class AccountBaseConfigServiceImpl extends BaseServiceImpl<AccountBaseCon
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public String getConfig(String config_key) {
|
public String getConfig(String config_key) {
|
||||||
if (configMap == null) syncCache(false);
|
if (configMap == null) {
|
||||||
|
syncCache(false);
|
||||||
|
}
|
||||||
|
|
||||||
AccountBaseConfig accountBaseConfig = configMap.get(config_key);
|
AccountBaseConfig accountBaseConfig = configMap.get(config_key);
|
||||||
if (ObjectUtil.isNull(accountBaseConfig) || CheckUtil.isEmpty(accountBaseConfig.getConfig_enable())) return "";
|
if (ObjectUtil.isNull(accountBaseConfig) || CheckUtil.isEmpty(accountBaseConfig.getConfig_enable())) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
return accountBaseConfig.getConfig_value();
|
return accountBaseConfig.getConfig_value();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2025. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
||||||
|
* Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan.
|
||||||
|
* Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna.
|
||||||
|
* Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus.
|
||||||
|
* Vestibulum commodo. Ut rhoncus gravida arcu.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.suisung.mall.shop.esign.controller.admin;
|
||||||
|
|
||||||
|
import com.suisung.mall.common.service.impl.BaseControllerImpl;
|
||||||
|
import com.suisung.mall.shop.esign.service.FileAndTemplateService;
|
||||||
|
import io.swagger.annotations.Api;
|
||||||
|
import io.swagger.annotations.ApiOperation;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMethod;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
|
||||||
|
@Api(tags = "店铺表-用户可以多店铺-需要分表")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/admin/shop/esign")
|
||||||
|
public class EsignController extends BaseControllerImpl {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private FileAndTemplateService fileAndTemplateService;
|
||||||
|
|
||||||
|
@ApiOperation(value = "店铺基础信息表-查找所有店铺编号和名称", notes = "店铺基础信息表-查找所有店铺编号和名称")
|
||||||
|
@RequestMapping(value = "/testcase", method = RequestMethod.POST)
|
||||||
|
public Object testCase() {
|
||||||
|
return fileAndTemplateService.fillDocTemplate("11", "11");
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,17 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2025. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
||||||
|
* Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan.
|
||||||
|
* Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna.
|
||||||
|
* Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus.
|
||||||
|
* Vestibulum commodo. Ut rhoncus gravida arcu.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.suisung.mall.shop.esign.mapper;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import com.suisung.mall.common.modules.esign.EsignContractFillingFile;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public interface EsignContractFillingFileMapper extends BaseMapper<EsignContractFillingFile> {
|
||||||
|
}
|
||||||
@ -0,0 +1,12 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2025. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
||||||
|
* Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan.
|
||||||
|
* Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna.
|
||||||
|
* Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus.
|
||||||
|
* Vestibulum commodo. Ut rhoncus gravida arcu.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.suisung.mall.shop.esign.service;
|
||||||
|
|
||||||
|
public interface EsignContractFillingFileService {
|
||||||
|
}
|
||||||
@ -0,0 +1,23 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2025. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
||||||
|
* Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan.
|
||||||
|
* Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna.
|
||||||
|
* Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus.
|
||||||
|
* Vestibulum commodo. Ut rhoncus gravida arcu.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.suisung.mall.shop.esign.service;
|
||||||
|
|
||||||
|
import com.suisung.mall.common.modules.esign.EsignContractFillingFile;
|
||||||
|
|
||||||
|
public interface FileAndTemplateService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 填充合同模版,生成合同文件地址
|
||||||
|
*
|
||||||
|
* @param storeId
|
||||||
|
* @param docTemplateId
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
EsignContractFillingFile fillDocTemplate(String storeId, String docTemplateId);
|
||||||
|
}
|
||||||
@ -0,0 +1,19 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2025. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
||||||
|
* Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan.
|
||||||
|
* Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna.
|
||||||
|
* Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus.
|
||||||
|
* Vestibulum commodo. Ut rhoncus gravida arcu.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.suisung.mall.shop.esign.service.impl;
|
||||||
|
|
||||||
|
import com.suisung.mall.common.modules.esign.EsignContractFillingFile;
|
||||||
|
import com.suisung.mall.core.web.service.impl.BaseServiceImpl;
|
||||||
|
import com.suisung.mall.shop.esign.mapper.EsignContractFillingFileMapper;
|
||||||
|
import com.suisung.mall.shop.esign.service.EsignContractFillingFileService;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class EsignContractFillingFileServiceImpl extends BaseServiceImpl<EsignContractFillingFileMapper, EsignContractFillingFile> implements EsignContractFillingFileService {
|
||||||
|
}
|
||||||
@ -0,0 +1,83 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2025. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
||||||
|
* Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan.
|
||||||
|
* Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna.
|
||||||
|
* Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus.
|
||||||
|
* Vestibulum commodo. Ut rhoncus gravida arcu.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.suisung.mall.shop.esign.service.impl;
|
||||||
|
|
||||||
|
import cn.hutool.json.JSONObject;
|
||||||
|
import cn.hutool.json.JSONUtil;
|
||||||
|
import com.suisung.mall.common.modules.esign.EsignContractFillingFile;
|
||||||
|
import com.suisung.mall.shop.esign.service.FileAndTemplateService;
|
||||||
|
import com.suisung.mall.shop.esign.utils.comm.EsignHttpHelper;
|
||||||
|
import com.suisung.mall.shop.esign.utils.comm.EsignHttpResponse;
|
||||||
|
import com.suisung.mall.shop.esign.utils.enums.EsignRequestType;
|
||||||
|
import com.suisung.mall.shop.esign.utils.exception.EsignDemoException;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
public class FileAndTemplateServiceImpl implements FileAndTemplateService {
|
||||||
|
@Value("${esign.server_url}")
|
||||||
|
private String serverUrl;
|
||||||
|
|
||||||
|
@Value("${esign.app_id}")
|
||||||
|
private String appId;
|
||||||
|
|
||||||
|
@Value("${esign.app_secret}")
|
||||||
|
private String appSecret;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 填充合同模版,生成合同文件地址
|
||||||
|
*
|
||||||
|
* @param storeId
|
||||||
|
* @param docTemplateId
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public EsignContractFillingFile fillDocTemplate(String storeId, String docTemplateId) {
|
||||||
|
// 获取模版文件
|
||||||
|
String templateId = "b411907d8f4640a1af593bea98c6b6c1";
|
||||||
|
String apiaddr = "/v3/files/create-by-doc-template";
|
||||||
|
|
||||||
|
// 获取填充模版的数据
|
||||||
|
JSONObject fillJson = new JSONObject();
|
||||||
|
fillJson.put("docTemplateId", templateId)
|
||||||
|
.put("fileName", "小发同城入驻协议测试");
|
||||||
|
|
||||||
|
String componentJson = "[{'componentKey':'yf_company','componentValue':'桂平厚德贸易有限公司'},{'componentKey':'sign_date','componentValue':'2025-02-20'}]";
|
||||||
|
fillJson.put("components", JSONUtil.parseArray(componentJson));
|
||||||
|
|
||||||
|
String jsonParma = fillJson.toString();
|
||||||
|
|
||||||
|
// 填充模版操作
|
||||||
|
/* 填写模板生成文件*/
|
||||||
|
|
||||||
|
//请求方法
|
||||||
|
EsignRequestType requestType = EsignRequestType.POST;
|
||||||
|
//生成签名鉴权方式的的header
|
||||||
|
Map<String, String> header = null;
|
||||||
|
try {
|
||||||
|
header = EsignHttpHelper.signAndBuildSignAndJsonHeader(appId, appSecret, jsonParma, requestType.name(), apiaddr, true);
|
||||||
|
//发起接口请求
|
||||||
|
EsignHttpResponse createByDocTemplate = EsignHttpHelper.doCommHttp(serverUrl, apiaddr, requestType, jsonParma, header, true);
|
||||||
|
|
||||||
|
log.info("{}", createByDocTemplate);
|
||||||
|
} catch (EsignDemoException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
EsignContractFillingFile esignContractFillingFile = new EsignContractFillingFile();
|
||||||
|
// esignContractFillingFile.set
|
||||||
|
return esignContractFillingFile;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,99 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||||||
|
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.suisung.mall.shop.esign.utils.comm;
|
||||||
|
|
||||||
|
import org.apache.commons.codec.binary.Base64;
|
||||||
|
|
||||||
|
import javax.crypto.BadPaddingException;
|
||||||
|
import javax.crypto.Cipher;
|
||||||
|
import javax.crypto.IllegalBlockSizeException;
|
||||||
|
import javax.crypto.NoSuchPaddingException;
|
||||||
|
import javax.crypto.spec.GCMParameterSpec;
|
||||||
|
import javax.crypto.spec.SecretKeySpec;
|
||||||
|
import java.security.InvalidAlgorithmParameterException;
|
||||||
|
import java.security.InvalidKeyException;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AES对称加密工具类
|
||||||
|
*
|
||||||
|
* @author 澄泓
|
||||||
|
* @date 2019年7月18日
|
||||||
|
*/
|
||||||
|
public class AESUtils {
|
||||||
|
|
||||||
|
private static final String KEY_ALGORITHM = "AES";
|
||||||
|
// AES/GCM加密算法,不用补位
|
||||||
|
private static final String DEFAULT_CIPHER_ALGORITHM = "AES/GCM/NoPadding";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AES 加密操作
|
||||||
|
*
|
||||||
|
* @param content 待加密内容
|
||||||
|
* @param AESSecret AES秘钥
|
||||||
|
* @return 返回Base64转码后的加密数据
|
||||||
|
*/
|
||||||
|
public static String encrypt(String content, String AESSecret) {
|
||||||
|
try {
|
||||||
|
Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);
|
||||||
|
cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(Base64.decodeBase64(AESSecret), KEY_ALGORITHM));
|
||||||
|
byte[] iv = cipher.getIV();
|
||||||
|
assert iv.length == 12;
|
||||||
|
byte[] encryptData = cipher.doFinal(content.getBytes());
|
||||||
|
assert encryptData.length == content.getBytes().length + 16;
|
||||||
|
byte[] message = new byte[12 + content.getBytes().length + 16];
|
||||||
|
System.arraycopy(iv, 0, message, 0, 12);
|
||||||
|
System.arraycopy(encryptData, 0, message, 12, encryptData.length);
|
||||||
|
return Base64.encodeBase64URLSafeString(message);
|
||||||
|
} catch (InvalidKeyException | NoSuchAlgorithmException | NoSuchPaddingException | IllegalBlockSizeException
|
||||||
|
| BadPaddingException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AES 解密操作
|
||||||
|
*
|
||||||
|
* @param base64Content
|
||||||
|
* @param AESSecret AES秘钥
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static String decrypt(String base64Content, String AESSecret) {
|
||||||
|
byte[] content = Base64.decodeBase64(base64Content);
|
||||||
|
if (content.length < 12 + 16)
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
GCMParameterSpec params = new GCMParameterSpec(128, content, 0, 12);
|
||||||
|
try {
|
||||||
|
Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);
|
||||||
|
cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(Base64.decodeBase64(AESSecret), KEY_ALGORITHM), params);
|
||||||
|
byte[] decryptData = cipher.doFinal(content, 12, content.length - 12);
|
||||||
|
return new String(decryptData);
|
||||||
|
} catch (InvalidKeyException | NoSuchAlgorithmException | NoSuchPaddingException
|
||||||
|
| InvalidAlgorithmParameterException | IllegalBlockSizeException | BadPaddingException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
// 待加密的字符串
|
||||||
|
String s = "{\"name\":\"张三\",\"idNo\":\"320333xxxxxxx12522\"}";
|
||||||
|
// 秘钥
|
||||||
|
String pass = "D/RA+2esbSbfSVOQsTGlpg==";
|
||||||
|
// 加密
|
||||||
|
String encoded = encrypt(s, pass);
|
||||||
|
System.out.println("加密之前:" + s);
|
||||||
|
System.out.println("加密结果:" + encoded);
|
||||||
|
System.out.println("解密结果:" + decrypt(encoded, pass));
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,26 @@
|
|||||||
|
package com.suisung.mall.shop.esign.utils.comm;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* esignSDK-core信息类
|
||||||
|
*
|
||||||
|
* @author 澄泓
|
||||||
|
* @date 2022/2/22 13:59
|
||||||
|
*/
|
||||||
|
public class EsignCoreSdkInfo {
|
||||||
|
private static final String SdkVersion = "Esign-Sdk-Core1.0";
|
||||||
|
private static final String SupportedVersion = "JDK1.7 MORE THAN";
|
||||||
|
|
||||||
|
private static final String Info = "sdk-esign-api核心工具包,主要处理e签宝公有云产品接口调用时的签名计算以及网络请求,通过EsignHttpHelper.signAndBuildSignAndJsonHeader构造签名鉴权+json数据格式的请求头,通过HttpHelper.doCommHttp方法入参发起网络请求。让开发者无需关注具体的请求签名算法,专注于接口业务的json参数构造";
|
||||||
|
|
||||||
|
public static String getSdkVersion() {
|
||||||
|
return SdkVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getInfo() {
|
||||||
|
return Info;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getSupportedVersion() {
|
||||||
|
return SupportedVersion;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,375 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||||||
|
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.suisung.mall.shop.esign.utils.comm;
|
||||||
|
|
||||||
|
import com.suisung.mall.shop.esign.utils.exception.EsignDemoException;
|
||||||
|
import org.apache.commons.codec.binary.Base64;
|
||||||
|
import org.apache.http.message.BasicNameValuePair;
|
||||||
|
|
||||||
|
import javax.crypto.Mac;
|
||||||
|
import javax.crypto.spec.SecretKeySpec;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.security.InvalidKeyException;
|
||||||
|
import java.security.MessageDigest;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.text.Collator;
|
||||||
|
import java.text.MessageFormat;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author 澄泓
|
||||||
|
* @description 请求数据通用处理类
|
||||||
|
* @date 2020年10月22日 下午14:25:31
|
||||||
|
* @since JDK1.7
|
||||||
|
*/
|
||||||
|
public class EsignEncryption {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 不允许外部创建实例
|
||||||
|
*/
|
||||||
|
private EsignEncryption() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 拼接待签名字符串
|
||||||
|
*
|
||||||
|
* @param httpMethod
|
||||||
|
* @param url
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static String appendSignDataString(String httpMethod, String contentMd5, String accept, String contentType, String headers, String date, String url) throws EsignDemoException {
|
||||||
|
StringBuffer sb = new StringBuffer();
|
||||||
|
sb.append(httpMethod).append("\n").append(accept).append("\n").append(contentMd5).append("\n")
|
||||||
|
.append(contentType).append("\n");
|
||||||
|
|
||||||
|
if ("".equals(date) || date == null) {
|
||||||
|
sb.append("\n");
|
||||||
|
} else {
|
||||||
|
sb.append(date).append("\n");
|
||||||
|
}
|
||||||
|
if ("".equals(headers) || headers == null) {
|
||||||
|
sb.append(url);
|
||||||
|
} else {
|
||||||
|
sb.append(headers).append("\n").append(url);
|
||||||
|
}
|
||||||
|
return new String(sb);
|
||||||
|
}
|
||||||
|
|
||||||
|
/***
|
||||||
|
* Content-MD5的计算方法
|
||||||
|
* @param str 待计算的消息
|
||||||
|
* @return MD5计算后摘要值的Base64编码(ContentMD5)
|
||||||
|
* @throws EsignDemoException 加密过程中的异常信息
|
||||||
|
*/
|
||||||
|
public static String doContentMD5(String str) throws EsignDemoException {
|
||||||
|
byte[] md5Bytes = null;
|
||||||
|
MessageDigest md5 = null;
|
||||||
|
String contentMD5 = null;
|
||||||
|
try {
|
||||||
|
md5 = MessageDigest.getInstance("MD5");
|
||||||
|
// 计算md5函数
|
||||||
|
md5.update(str.getBytes(StandardCharsets.UTF_8));
|
||||||
|
// 获取文件MD5的二进制数组(128位)
|
||||||
|
md5Bytes = md5.digest();
|
||||||
|
// 把MD5摘要后的二进制数组md5Bytes使用Base64进行编码(而不是对32位的16进制字符串进行编码)
|
||||||
|
contentMD5 = Base64.encodeBase64String(md5Bytes);
|
||||||
|
|
||||||
|
} catch (NoSuchAlgorithmException e) {
|
||||||
|
EsignDemoException ex = new EsignDemoException("不支持此算法", e);
|
||||||
|
ex.initCause(e);
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
return contentMD5;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***
|
||||||
|
* 计算请求签名值-HmacSHA256摘要
|
||||||
|
* @param message 待签名字符串
|
||||||
|
* @param secret 密钥APP KEY
|
||||||
|
* @return reqSignature HmacSHA256计算后摘要值的Base64编码
|
||||||
|
* @throws EsignDemoException 加密过程中的异常信息
|
||||||
|
*/
|
||||||
|
public static String doSignatureBase64(String message, String secret) throws EsignDemoException {
|
||||||
|
String algorithm = "HmacSHA256";
|
||||||
|
Mac hmacSha256;
|
||||||
|
String digestBase64 = null;
|
||||||
|
try {
|
||||||
|
hmacSha256 = Mac.getInstance(algorithm);
|
||||||
|
byte[] keyBytes = secret.getBytes(StandardCharsets.UTF_8);
|
||||||
|
byte[] messageBytes = message.getBytes(StandardCharsets.UTF_8);
|
||||||
|
hmacSha256.init(new SecretKeySpec(keyBytes, 0, keyBytes.length, algorithm));
|
||||||
|
// 使用HmacSHA256对二进制数据消息Bytes计算摘要
|
||||||
|
byte[] digestBytes = hmacSha256.doFinal(messageBytes);
|
||||||
|
// 把摘要后的结果digestBytes使用Base64进行编码
|
||||||
|
digestBase64 = Base64.encodeBase64String(digestBytes);
|
||||||
|
} catch (NoSuchAlgorithmException e) {
|
||||||
|
EsignDemoException ex = new EsignDemoException("不支持此算法", e);
|
||||||
|
ex.initCause(e);
|
||||||
|
throw ex;
|
||||||
|
} catch (InvalidKeyException e) {
|
||||||
|
EsignDemoException ex = new EsignDemoException("无效的密钥规范", e);
|
||||||
|
ex.initCause(e);
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
return digestBase64;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取时间戳
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static String timeStamp() {
|
||||||
|
long timeStamp = System.currentTimeMillis();
|
||||||
|
return String.valueOf(timeStamp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* byte字节数组转换成字符串
|
||||||
|
*
|
||||||
|
* @param b
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static String byteArrayToHexString(byte[] b) {
|
||||||
|
StringBuilder hs = new StringBuilder();
|
||||||
|
String stmp;
|
||||||
|
for (int n = 0; b != null && n < b.length; n++) {
|
||||||
|
stmp = Integer.toHexString(b[n] & 0XFF);
|
||||||
|
if (stmp.length() == 1)
|
||||||
|
hs.append('0');
|
||||||
|
hs.append(stmp);
|
||||||
|
}
|
||||||
|
return hs.toString().toLowerCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* hash散列加密算法
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static String Hmac_SHA256(String message, String key) throws EsignDemoException {
|
||||||
|
byte[] rawHmac = null;
|
||||||
|
try {
|
||||||
|
SecretKeySpec sk = new SecretKeySpec(key.getBytes(), "HmacSHA256");
|
||||||
|
Mac mac = Mac.getInstance("HmacSHA256");
|
||||||
|
mac.init(sk);
|
||||||
|
rawHmac = mac.doFinal(message.getBytes());
|
||||||
|
} catch (InvalidKeyException e) {
|
||||||
|
EsignDemoException ex = new EsignDemoException("无效的密钥规范", e);
|
||||||
|
ex.initCause(e);
|
||||||
|
throw ex;
|
||||||
|
} catch (NoSuchAlgorithmException e) {
|
||||||
|
EsignDemoException ex = new EsignDemoException("不支持此算法", e);
|
||||||
|
ex.initCause(e);
|
||||||
|
throw ex;
|
||||||
|
} catch (Exception e) {
|
||||||
|
EsignDemoException ex = new EsignDemoException("hash散列加密算法报错", e);
|
||||||
|
ex.initCause(e);
|
||||||
|
throw ex;
|
||||||
|
} finally {
|
||||||
|
return byteArrayToHexString(rawHmac);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MD5加密32位
|
||||||
|
*/
|
||||||
|
public static String MD5Digest(String text) throws EsignDemoException {
|
||||||
|
byte[] digest = null;
|
||||||
|
try {
|
||||||
|
MessageDigest md5 = MessageDigest.getInstance("MD5");
|
||||||
|
md5.update(text.getBytes());
|
||||||
|
digest = md5.digest();
|
||||||
|
} catch (NoSuchAlgorithmException e) {
|
||||||
|
EsignDemoException ex = new EsignDemoException("不支持此算法", e);
|
||||||
|
ex.initCause(e);
|
||||||
|
throw ex;
|
||||||
|
} finally {
|
||||||
|
return byteArrayToHexString(digest);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void formDataSort(List<BasicNameValuePair> param) {
|
||||||
|
Collections.sort(param, new Comparator<BasicNameValuePair>() {
|
||||||
|
@Override
|
||||||
|
public int compare(BasicNameValuePair o1, BasicNameValuePair o2) {
|
||||||
|
Comparator<Object> com = Collator.getInstance(Locale.CHINA);
|
||||||
|
return com.compare(o1.getName(), o2.getName());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/***
|
||||||
|
* 字符串是否为空(含空格校验)
|
||||||
|
* @param str
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static boolean isBlank(String str) {
|
||||||
|
if (null == str || 0 == str.length()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int strLen = str.length();
|
||||||
|
|
||||||
|
for (int i = 0; i < strLen; i++) {
|
||||||
|
if (!Character.isWhitespace(str.charAt(i))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***
|
||||||
|
* 对请求URL中的Query参数按照字段名的 ASCII 码从小到大排序(字典排序)
|
||||||
|
*
|
||||||
|
* @param apiUrl
|
||||||
|
* @return 排序后的API接口地址
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public static String sortApiUrl(String apiUrl) throws EsignDemoException {
|
||||||
|
|
||||||
|
if (!apiUrl.contains("?")) {
|
||||||
|
return apiUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
int queryIndex = apiUrl.indexOf("?");
|
||||||
|
String apiUrlPath = apiUrl.substring(0, queryIndex + 1);
|
||||||
|
String apiUrlQuery = apiUrl.substring(queryIndex + 1);
|
||||||
|
//apiUrlQuery为空时返回
|
||||||
|
if (isBlank(apiUrlQuery)) {
|
||||||
|
return apiUrl.substring(0, apiUrl.length() - 1);
|
||||||
|
}
|
||||||
|
// 请求URL中Query参数转成Map
|
||||||
|
Map<Object, Object> queryParamsMap = new HashMap<Object, Object>();
|
||||||
|
String[] params = apiUrlQuery.split("&");
|
||||||
|
for (String str : params) {
|
||||||
|
int index = str.indexOf("=");
|
||||||
|
String key = str.substring(0, index);
|
||||||
|
String value = str.substring(index + 1);
|
||||||
|
if (queryParamsMap.containsKey(key)) {
|
||||||
|
String msg = MessageFormat.format("请求URL中的Query参数的{0}重复", key);
|
||||||
|
throw new EsignDemoException(msg);
|
||||||
|
}
|
||||||
|
queryParamsMap.put(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
ArrayList<String> queryMapKeys = new ArrayList<String>();
|
||||||
|
for (Map.Entry<Object, Object> entry : queryParamsMap.entrySet()) {
|
||||||
|
queryMapKeys.add((String) entry.getKey());
|
||||||
|
}
|
||||||
|
// 按照字段名的 ASCII 码从小到大排序(字典排序)
|
||||||
|
Collections.sort(queryMapKeys, new Comparator<String>() {
|
||||||
|
@Override
|
||||||
|
public int compare(String o1, String o2) {
|
||||||
|
return (o1.compareToIgnoreCase(o2) == 0 ? -o1.compareTo(o2) : o1.compareToIgnoreCase(o2));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
StringBuffer queryString = new StringBuffer();
|
||||||
|
// 构造Query参数键值对值对的格式
|
||||||
|
for (int i = 0; i < queryMapKeys.size(); i++) {
|
||||||
|
String key = queryMapKeys.get(i);
|
||||||
|
String value = (String) queryParamsMap.get(key);
|
||||||
|
queryString.append(key);
|
||||||
|
queryString.append("=");
|
||||||
|
queryString.append(value);
|
||||||
|
queryString.append("&");
|
||||||
|
}
|
||||||
|
if (queryString.length() > 0) {
|
||||||
|
queryString = queryString.deleteCharAt(queryString.length() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Query参数排序后的接口请求地址
|
||||||
|
String sortApiUrl = apiUrlPath +
|
||||||
|
queryString;
|
||||||
|
return sortApiUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取query
|
||||||
|
*
|
||||||
|
* @param apiUrl
|
||||||
|
* @return
|
||||||
|
* @throws EsignDemoException
|
||||||
|
*/
|
||||||
|
public static ArrayList<BasicNameValuePair> getQuery(String apiUrl) throws EsignDemoException {
|
||||||
|
ArrayList<BasicNameValuePair> BasicNameValuePairList = new ArrayList<>();
|
||||||
|
|
||||||
|
if (!apiUrl.contains("?")) {
|
||||||
|
return BasicNameValuePairList;
|
||||||
|
}
|
||||||
|
|
||||||
|
int queryIndex = apiUrl.indexOf("\\?");
|
||||||
|
String apiUrlQuery = apiUrl.substring(queryIndex);
|
||||||
|
|
||||||
|
// 请求URL中Query参数转成Map
|
||||||
|
Map<Object, Object> queryParamsMap = new HashMap<Object, Object>();
|
||||||
|
String[] params = apiUrlQuery.split("&");
|
||||||
|
for (String str : params) {
|
||||||
|
int index = str.indexOf("=");
|
||||||
|
String key = str.substring(0, index);
|
||||||
|
String value = str.substring(index + 1);
|
||||||
|
if (queryParamsMap.containsKey(key)) {
|
||||||
|
String msg = MessageFormat.format("请求URL中的Query参数的{0}重复", key);
|
||||||
|
throw new EsignDemoException(msg);
|
||||||
|
}
|
||||||
|
BasicNameValuePairList.add(new BasicNameValuePair(key, value));
|
||||||
|
queryParamsMap.put(key, value);
|
||||||
|
}
|
||||||
|
return BasicNameValuePairList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public static boolean callBackCheck(String timestamp, String requestQuery, String body, String key, String signature) {
|
||||||
|
String algorithm = "HmacSHA256";
|
||||||
|
String encoding = "UTF-8";
|
||||||
|
Mac mac = null;
|
||||||
|
try {
|
||||||
|
String data = timestamp + requestQuery + body;
|
||||||
|
mac = Mac.getInstance(algorithm);
|
||||||
|
SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(encoding), algorithm);
|
||||||
|
mac.init(secretKey);
|
||||||
|
mac.update(data.getBytes(encoding));
|
||||||
|
} catch (NoSuchAlgorithmException | InvalidKeyException | UnsupportedEncodingException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
System.out.println("获取Signature签名信息异常:" + e.getMessage());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return byte2hex(mac.doFinal()).equalsIgnoreCase(signature);
|
||||||
|
}
|
||||||
|
|
||||||
|
/***
|
||||||
|
* 将byte[]转成16进制字符串
|
||||||
|
*
|
||||||
|
* @param data
|
||||||
|
*
|
||||||
|
* @return 16进制字符串
|
||||||
|
*/
|
||||||
|
public static String byte2hex(byte[] data) {
|
||||||
|
StringBuilder hash = new StringBuilder();
|
||||||
|
String stmp;
|
||||||
|
for (int n = 0; data != null && n < data.length; n++) {
|
||||||
|
stmp = Integer.toHexString(data[n] & 0XFF);
|
||||||
|
if (stmp.length() == 1)
|
||||||
|
hash.append('0');
|
||||||
|
hash.append(stmp);
|
||||||
|
}
|
||||||
|
return hash.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,56 @@
|
|||||||
|
package com.suisung.mall.shop.esign.utils.comm;
|
||||||
|
|
||||||
|
import com.suisung.mall.shop.esign.utils.exception.EsignDemoException;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author 澄泓
|
||||||
|
* @version JDK1.7
|
||||||
|
* @description 文件基础信息封装类
|
||||||
|
* @date 2020/10/26 14:54
|
||||||
|
*/
|
||||||
|
public class EsignFileBean {
|
||||||
|
//文件名称
|
||||||
|
private final String fileName;
|
||||||
|
//文件大小
|
||||||
|
private final int fileSize;
|
||||||
|
//文件内容MD5
|
||||||
|
private final String fileContentMD5;
|
||||||
|
//文件地址
|
||||||
|
private final String filePath;
|
||||||
|
|
||||||
|
|
||||||
|
public EsignFileBean(String filePath) throws EsignDemoException {
|
||||||
|
this.filePath = filePath;
|
||||||
|
this.fileContentMD5 = FileTransformation.getFileContentMD5(filePath);
|
||||||
|
File file = new File(filePath);
|
||||||
|
if (!file.exists()) {
|
||||||
|
throw new EsignDemoException("文件不存在");
|
||||||
|
}
|
||||||
|
this.fileName = file.getName();
|
||||||
|
this.fileSize = (int) file.length();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFileName() {
|
||||||
|
return fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getFileSize() {
|
||||||
|
return fileSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFileContentMD5() {
|
||||||
|
return fileContentMD5;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 传入本地文件地址获取二进制数据
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* @throws EsignDemoException
|
||||||
|
*/
|
||||||
|
public byte[] getFileBytes() throws EsignDemoException {
|
||||||
|
return FileTransformation.fileToBytes(filePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,465 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||||||
|
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.suisung.mall.shop.esign.utils.comm;
|
||||||
|
|
||||||
|
import com.suisung.mall.shop.esign.utils.enums.EsignRequestType;
|
||||||
|
import com.suisung.mall.shop.esign.utils.exception.EsignDemoException;
|
||||||
|
import org.apache.http.*;
|
||||||
|
import org.apache.http.auth.AuthScope;
|
||||||
|
import org.apache.http.auth.UsernamePasswordCredentials;
|
||||||
|
import org.apache.http.client.ClientProtocolException;
|
||||||
|
import org.apache.http.client.CredentialsProvider;
|
||||||
|
import org.apache.http.client.HttpRequestRetryHandler;
|
||||||
|
import org.apache.http.client.config.RequestConfig;
|
||||||
|
import org.apache.http.client.entity.UrlEncodedFormEntity;
|
||||||
|
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||||
|
import org.apache.http.client.methods.HttpRequestBase;
|
||||||
|
import org.apache.http.client.protocol.HttpClientContext;
|
||||||
|
import org.apache.http.config.Registry;
|
||||||
|
import org.apache.http.config.RegistryBuilder;
|
||||||
|
import org.apache.http.conn.ConnectTimeoutException;
|
||||||
|
import org.apache.http.conn.socket.ConnectionSocketFactory;
|
||||||
|
import org.apache.http.conn.socket.LayeredConnectionSocketFactory;
|
||||||
|
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
|
||||||
|
import org.apache.http.conn.ssl.NoopHostnameVerifier;
|
||||||
|
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
|
||||||
|
import org.apache.http.entity.ByteArrayEntity;
|
||||||
|
import org.apache.http.entity.ContentType;
|
||||||
|
import org.apache.http.entity.StringEntity;
|
||||||
|
import org.apache.http.impl.client.BasicCredentialsProvider;
|
||||||
|
import org.apache.http.impl.client.CloseableHttpClient;
|
||||||
|
import org.apache.http.impl.client.HttpClientBuilder;
|
||||||
|
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
|
||||||
|
import org.apache.http.protocol.HttpContext;
|
||||||
|
import org.apache.http.util.EntityUtils;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import javax.net.ssl.*;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InterruptedIOException;
|
||||||
|
import java.net.UnknownHostException;
|
||||||
|
import java.security.cert.CertificateException;
|
||||||
|
import java.security.cert.X509Certificate;
|
||||||
|
import java.text.MessageFormat;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author 澄泓
|
||||||
|
* @description Http请求 辅助类
|
||||||
|
* @since JDK1.7
|
||||||
|
*/
|
||||||
|
public class EsignHttpCfgHelper {
|
||||||
|
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(EsignHttpCfgHelper.class);
|
||||||
|
/**
|
||||||
|
* 超时时间,默认15000毫秒
|
||||||
|
*/
|
||||||
|
private static int MAX_TIMEOUT = 15000;
|
||||||
|
/**
|
||||||
|
* 请求池最大连接数,默认100个
|
||||||
|
*/
|
||||||
|
private static int MAX_TOTAL = 100;
|
||||||
|
/**
|
||||||
|
* 单域名最大的连接数,默认50个
|
||||||
|
*/
|
||||||
|
private static int ROUTE_MAX_TOTAL = 50;
|
||||||
|
/**
|
||||||
|
* 请求失败重试次数,默认3次
|
||||||
|
*/
|
||||||
|
private static int MAX_RETRY = 3;
|
||||||
|
/**
|
||||||
|
* 是否需要域名校验,默认不需要校验
|
||||||
|
*/
|
||||||
|
private static boolean SSL_VERIFY = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 正向代理IP
|
||||||
|
*/
|
||||||
|
private static String PROXY_IP;
|
||||||
|
/**
|
||||||
|
* 正向代理端口,默认8888
|
||||||
|
*/
|
||||||
|
private static int PROXY_PORT = 8888;
|
||||||
|
/**
|
||||||
|
* 代理协议,默认http
|
||||||
|
*/
|
||||||
|
private static String PROXY_AGREEMENT = "http";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否开启代理,默认false
|
||||||
|
*/
|
||||||
|
private static boolean OPEN_PROXY = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 代理服务器用户名
|
||||||
|
*/
|
||||||
|
private static String PROXY_USERNAME = "";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 代理服务器密码
|
||||||
|
*/
|
||||||
|
private static String PROXY_PASSWORD = "";
|
||||||
|
|
||||||
|
|
||||||
|
private static PoolingHttpClientConnectionManager connMgr; //连接池
|
||||||
|
private static HttpRequestRetryHandler retryHandler; //重试机制
|
||||||
|
|
||||||
|
private static CloseableHttpClient httpClient = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 不允许外部创建实例
|
||||||
|
*/
|
||||||
|
private EsignHttpCfgHelper() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int getMaxTimeout() {
|
||||||
|
return MAX_TIMEOUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setMaxTimeout(int maxTimeout) {
|
||||||
|
MAX_TIMEOUT = maxTimeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int getMaxTotal() {
|
||||||
|
return MAX_TOTAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setMaxTotal(int maxTotal) {
|
||||||
|
MAX_TOTAL = maxTotal;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int getRouteMaxTotal() {
|
||||||
|
return ROUTE_MAX_TOTAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setRouteMaxTotal(int routeMaxTotal) {
|
||||||
|
ROUTE_MAX_TOTAL = routeMaxTotal;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int getMaxRetry() {
|
||||||
|
return MAX_RETRY;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setMaxRetry(int maxRetry) {
|
||||||
|
MAX_RETRY = maxRetry;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isSslVerify() {
|
||||||
|
return SSL_VERIFY;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setSslVerify(boolean sslVerify) {
|
||||||
|
SSL_VERIFY = sslVerify;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getProxyIp() {
|
||||||
|
return PROXY_IP;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setProxyIp(String proxyIp) {
|
||||||
|
PROXY_IP = proxyIp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int getProxyPort() {
|
||||||
|
return PROXY_PORT;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setProxyPort(int proxyPort) {
|
||||||
|
PROXY_PORT = proxyPort;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getProxyAgreement() {
|
||||||
|
return PROXY_AGREEMENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setProxyAgreement(String proxyAgreement) {
|
||||||
|
PROXY_AGREEMENT = proxyAgreement;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean getOpenProxy() {
|
||||||
|
return OPEN_PROXY;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setOpenProxy(boolean openProxy) {
|
||||||
|
OPEN_PROXY = openProxy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getProxyUsername() {
|
||||||
|
return PROXY_USERNAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setProxyUserame(String proxyUsername) {
|
||||||
|
PROXY_USERNAME = proxyUsername;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getProxyPassword() {
|
||||||
|
return PROXY_PASSWORD;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setProxyPassword(String proxyPassword) {
|
||||||
|
PROXY_PASSWORD = proxyPassword;
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------公有方法start--------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param reqType {@link EsignRequestType} 请求类型 GET、 POST 、 DELETE 、 PUT
|
||||||
|
* @param httpUrl {@link String} 请求目标地址
|
||||||
|
* @param headers {@link Map} 请求头
|
||||||
|
* @param param {@link Object} 参数
|
||||||
|
* @return
|
||||||
|
* @throws EsignDemoException
|
||||||
|
* @description 发起HTTP / HTTPS 请求
|
||||||
|
* @author 澄泓
|
||||||
|
*/
|
||||||
|
public static EsignHttpResponse sendHttp(EsignRequestType reqType, String httpUrl, Map<String, String> headers, Object param, boolean debug)
|
||||||
|
throws EsignDemoException {
|
||||||
|
HttpRequestBase reqBase = null;
|
||||||
|
if (httpUrl.startsWith("http")) {
|
||||||
|
reqBase = reqType.getHttpType(httpUrl);
|
||||||
|
} else {
|
||||||
|
throw new EsignDemoException("请求url地址格式错误");
|
||||||
|
}
|
||||||
|
if (debug) {
|
||||||
|
LOGGER.info("请求头:{}", headers + "\n");
|
||||||
|
LOGGER.info("请求参数\n{}", param + "\n");
|
||||||
|
LOGGER.info("请求地址\n:{}\n请求方式\n:{}", reqBase.getURI(), reqType + "\n");
|
||||||
|
}
|
||||||
|
//请求方法不是GET或者DELETE时传入body体,否则不传入。
|
||||||
|
String[] methods = {"DELETE", "GET"};
|
||||||
|
if (param instanceof String && Arrays.binarySearch(methods, reqType.name()) < 0) {//POST或者PUT请求
|
||||||
|
((HttpEntityEnclosingRequest) reqBase).setEntity(
|
||||||
|
new StringEntity(String.valueOf(param), ContentType.create("application/json", "UTF-8")));
|
||||||
|
}
|
||||||
|
//参数时字节流数组
|
||||||
|
else if (param instanceof byte[]) {
|
||||||
|
reqBase = reqType.getHttpType(httpUrl);
|
||||||
|
byte[] paramBytes = (byte[]) param;
|
||||||
|
((HttpEntityEnclosingRequest) reqBase).setEntity(new ByteArrayEntity(paramBytes));
|
||||||
|
}
|
||||||
|
//参数是form表单时
|
||||||
|
else if (param instanceof List) {
|
||||||
|
((HttpEntityEnclosingRequest) reqBase).setEntity(new UrlEncodedFormEntity((Iterable<? extends NameValuePair>) param));
|
||||||
|
}
|
||||||
|
httpClient = getHttpClient();
|
||||||
|
config(reqBase);
|
||||||
|
|
||||||
|
//设置请求头
|
||||||
|
if (headers != null && headers.size() > 0) {
|
||||||
|
for (Map.Entry<String, String> entry : headers.entrySet()) {
|
||||||
|
reqBase.setHeader(entry.getKey(), entry.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//响应对象
|
||||||
|
CloseableHttpResponse res = null;
|
||||||
|
//响应内容
|
||||||
|
String resCtx = null;
|
||||||
|
int status;
|
||||||
|
EsignHttpResponse esignHttpResponse = new EsignHttpResponse();
|
||||||
|
try {
|
||||||
|
//执行请求
|
||||||
|
res = httpClient.execute(reqBase);
|
||||||
|
status = res.getStatusLine().getStatusCode();
|
||||||
|
|
||||||
|
//获取请求响应对象和响应entity
|
||||||
|
HttpEntity httpEntity = res.getEntity();
|
||||||
|
if (httpEntity != null) {
|
||||||
|
resCtx = EntityUtils.toString(httpEntity, "utf-8");
|
||||||
|
}
|
||||||
|
if (debug) {
|
||||||
|
LOGGER.info("响应\n{}", resCtx + "\n");
|
||||||
|
LOGGER.info("----------------------------end------------------------");
|
||||||
|
}
|
||||||
|
} catch (NoHttpResponseException e) {
|
||||||
|
throw new EsignDemoException("服务器丢失了", e);
|
||||||
|
} catch (SSLHandshakeException e) {
|
||||||
|
String msg = MessageFormat.format("SSL握手异常", e);
|
||||||
|
EsignDemoException ex = new EsignDemoException(msg, e);
|
||||||
|
throw ex;
|
||||||
|
} catch (UnknownHostException e) {
|
||||||
|
EsignDemoException ex = new EsignDemoException("服务器找不到", e);
|
||||||
|
ex.initCause(e);
|
||||||
|
throw ex;
|
||||||
|
} catch (ConnectTimeoutException e) {
|
||||||
|
EsignDemoException ex = new EsignDemoException("连接超时", e);
|
||||||
|
ex.initCause(e);
|
||||||
|
throw ex;
|
||||||
|
} catch (SSLException e) {
|
||||||
|
EsignDemoException ex = new EsignDemoException("SSL异常", e);
|
||||||
|
ex.initCause(e);
|
||||||
|
throw ex;
|
||||||
|
} catch (ClientProtocolException e) {
|
||||||
|
EsignDemoException ex = new EsignDemoException("请求头异常", e);
|
||||||
|
ex.initCause(e);
|
||||||
|
throw ex;
|
||||||
|
} catch (IOException e) {
|
||||||
|
EsignDemoException ex = new EsignDemoException("网络请求失败", e);
|
||||||
|
ex.initCause(e);
|
||||||
|
throw ex;
|
||||||
|
} finally {
|
||||||
|
if (res != null) {
|
||||||
|
try {
|
||||||
|
res.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
EsignDemoException ex = new EsignDemoException("--->>关闭请求响应失败", e);
|
||||||
|
ex.initCause(e);
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
esignHttpResponse.setStatus(status);
|
||||||
|
esignHttpResponse.setBody(resCtx);
|
||||||
|
return esignHttpResponse;
|
||||||
|
}
|
||||||
|
//------------------------------公有方法end----------------------------------------------
|
||||||
|
|
||||||
|
//------------------------------私有方法start--------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param httpReqBase
|
||||||
|
* @description 请求头和超时时间配置
|
||||||
|
* @author 澄泓
|
||||||
|
*/
|
||||||
|
private static void config(HttpRequestBase httpReqBase) {
|
||||||
|
// 配置请求的超时设置
|
||||||
|
RequestConfig.Builder builder = RequestConfig.custom()
|
||||||
|
.setConnectionRequestTimeout(MAX_TIMEOUT)
|
||||||
|
.setConnectTimeout(MAX_TIMEOUT)
|
||||||
|
.setSocketTimeout(MAX_TIMEOUT);
|
||||||
|
if (OPEN_PROXY) {
|
||||||
|
HttpHost proxy = new HttpHost(PROXY_IP, PROXY_PORT, PROXY_AGREEMENT);
|
||||||
|
builder.setProxy(proxy);
|
||||||
|
}
|
||||||
|
RequestConfig requestConfig = builder.build();
|
||||||
|
httpReqBase.setConfig(requestConfig);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return
|
||||||
|
* @description 连接池配置
|
||||||
|
* @author 澄泓
|
||||||
|
*/
|
||||||
|
private static void cfgPoolMgr() throws EsignDemoException {
|
||||||
|
ConnectionSocketFactory plainsf = PlainConnectionSocketFactory.getSocketFactory();
|
||||||
|
LayeredConnectionSocketFactory sslsf = SSLConnectionSocketFactory.getSocketFactory();
|
||||||
|
if (!SSL_VERIFY) {
|
||||||
|
sslsf = sslConnectionSocketFactory();
|
||||||
|
}
|
||||||
|
|
||||||
|
Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
|
||||||
|
.register("http", plainsf)
|
||||||
|
.register("https", sslsf)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
//连接池管理器
|
||||||
|
connMgr = new PoolingHttpClientConnectionManager(registry);
|
||||||
|
//请求池最大连接数
|
||||||
|
connMgr.setMaxTotal(MAX_TOTAL);
|
||||||
|
//但域名最大的连接数
|
||||||
|
connMgr.setDefaultMaxPerRoute(ROUTE_MAX_TOTAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 设置重试机制
|
||||||
|
* @author 澄泓
|
||||||
|
*/
|
||||||
|
private static void cfgRetryHandler() {
|
||||||
|
retryHandler = new HttpRequestRetryHandler() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean retryRequest(IOException e, int excCount, HttpContext ctx) {
|
||||||
|
//超过最大重试次数,就放弃
|
||||||
|
if (excCount > MAX_RETRY) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
//服务器丢掉了链接,就重试
|
||||||
|
if (e instanceof NoHttpResponseException) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
//不重试SSL握手异常
|
||||||
|
if (e instanceof SSLHandshakeException) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
//中断
|
||||||
|
if (e instanceof InterruptedIOException) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
//目标服务器不可达
|
||||||
|
if (e instanceof UnknownHostException) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
//连接超时
|
||||||
|
//SSL异常
|
||||||
|
if (e instanceof SSLException) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
HttpClientContext clientCtx = HttpClientContext.adapt(ctx);
|
||||||
|
HttpRequest req = clientCtx.getRequest();
|
||||||
|
//如果是幂等请求,就再次尝试
|
||||||
|
return !(req instanceof HttpEntityEnclosingRequest);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 忽略域名校验
|
||||||
|
*/
|
||||||
|
private static SSLConnectionSocketFactory sslConnectionSocketFactory() throws EsignDemoException {
|
||||||
|
try {
|
||||||
|
SSLContext ctx = SSLContext.getInstance("TLS"); // 创建一个上下文(此处指定的协议类型似乎不是重点)
|
||||||
|
X509TrustManager tm = new X509TrustManager() { // 创建一个跳过SSL证书的策略
|
||||||
|
public X509Certificate[] getAcceptedIssuers() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
ctx.init(null, new TrustManager[]{tm}, null); // 使用上面的策略初始化上下文
|
||||||
|
return new SSLConnectionSocketFactory(ctx, new String[]{"SSLv3", "TLSv1", "TLSv1.1", "TLSv1.2"}, null, NoopHostnameVerifier.INSTANCE);
|
||||||
|
} catch (Exception e) {
|
||||||
|
EsignDemoException ex = new EsignDemoException("忽略域名校验失败", e);
|
||||||
|
ex.initCause(e);
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return
|
||||||
|
* @description 获取单例HttpClient
|
||||||
|
* @author 澄泓
|
||||||
|
*/
|
||||||
|
private static synchronized CloseableHttpClient getHttpClient() throws EsignDemoException {
|
||||||
|
if (httpClient == null) {
|
||||||
|
CredentialsProvider credsProvider = new BasicCredentialsProvider();
|
||||||
|
credsProvider.setCredentials(new AuthScope(PROXY_IP, PROXY_PORT), new UsernamePasswordCredentials(PROXY_USERNAME, PROXY_PASSWORD));
|
||||||
|
cfgPoolMgr();
|
||||||
|
cfgRetryHandler();
|
||||||
|
HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
|
||||||
|
httpClient = httpClientBuilder.setDefaultCredentialsProvider(credsProvider).setConnectionManager(connMgr).setRetryHandler(retryHandler).build();
|
||||||
|
}
|
||||||
|
return httpClient;
|
||||||
|
|
||||||
|
}
|
||||||
|
//------------------------------私有方法end----------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,167 @@
|
|||||||
|
package com.suisung.mall.shop.esign.utils.comm;
|
||||||
|
|
||||||
|
import com.suisung.mall.shop.esign.utils.enums.EsignHeaderConstant;
|
||||||
|
import com.suisung.mall.shop.esign.utils.enums.EsignRequestType;
|
||||||
|
import com.suisung.mall.shop.esign.utils.exception.EsignDemoException;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author 澄泓
|
||||||
|
* @description Http 请求 辅助类
|
||||||
|
* @since JDK1.7
|
||||||
|
*/
|
||||||
|
public class EsignHttpHelper {
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(EsignHttpHelper.class);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 不允许外部创建实例
|
||||||
|
*/
|
||||||
|
private EsignHttpHelper() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param reqType 请求方式
|
||||||
|
* @param url 请求路径
|
||||||
|
* @param paramStr 请求参数
|
||||||
|
* @return
|
||||||
|
* @throws EsignDemoException
|
||||||
|
* @description 发送常规HTTP 请求
|
||||||
|
* @author 澄泓
|
||||||
|
*/
|
||||||
|
public static EsignHttpResponse doCommHttp(String host, String url, EsignRequestType reqType, Object paramStr, Map<String, String> httpHeader, boolean debug) throws EsignDemoException {
|
||||||
|
return EsignHttpCfgHelper.sendHttp(reqType, host + url, httpHeader, paramStr, debug);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param reqType 请求方式
|
||||||
|
* @param uploadUrl 请求路径
|
||||||
|
* @param param 请求参数
|
||||||
|
* @param fileContentMd5 文件fileContentMd5
|
||||||
|
* @param contentType 文件MIME类型
|
||||||
|
* @return
|
||||||
|
* @throws EsignDemoException
|
||||||
|
* @description 发送文件流上传 HTTP 请求
|
||||||
|
* @author 澄泓
|
||||||
|
*/
|
||||||
|
public static EsignHttpResponse doUploadHttp(String uploadUrl, EsignRequestType reqType, byte[] param, String fileContentMd5,
|
||||||
|
String contentType, boolean debug) throws EsignDemoException {
|
||||||
|
Map<String, String> uploadHeader = buildUploadHeader(fileContentMd5, contentType);
|
||||||
|
if (debug) {
|
||||||
|
LOGGER.info("----------------------------start------------------------");
|
||||||
|
LOGGER.info("fileContentMd5:{}", fileContentMd5);
|
||||||
|
LOGGER.info("contentType:{}", contentType);
|
||||||
|
}
|
||||||
|
return EsignHttpCfgHelper.sendHttp(reqType, uploadUrl, uploadHeader, param, debug);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return
|
||||||
|
* @description 构建一个签名鉴权+json数据的esign请求头
|
||||||
|
* @author 澄泓
|
||||||
|
*/
|
||||||
|
public static Map<String, String> buildSignAndJsonHeader(String projectId, String contentMD5, String accept, String contentType, String authMode) {
|
||||||
|
|
||||||
|
Map<String, String> header = new HashMap<>();
|
||||||
|
header.put("X-Tsign-Open-App-Id", projectId);
|
||||||
|
header.put("X-Tsign-Open-Version-Sdk", EsignCoreSdkInfo.getSdkVersion());
|
||||||
|
header.put("X-Tsign-Open-Ca-Timestamp", EsignEncryption.timeStamp());
|
||||||
|
header.put("Accept", accept);
|
||||||
|
header.put("Content-MD5", contentMD5);
|
||||||
|
header.put("Content-Type", contentType);
|
||||||
|
header.put("X-Tsign-Open-Auth-Mode", authMode);
|
||||||
|
return header;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 签名计算并且构建一个签名鉴权+json数据的esign请求头
|
||||||
|
*
|
||||||
|
* @param httpMethod * The name of a supported {@linkplain java.nio.charset.Charset
|
||||||
|
* * charset}
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static Map<String, String> signAndBuildSignAndJsonHeader(String projectId, String secret, String paramStr, String httpMethod, String url, boolean debug) throws EsignDemoException {
|
||||||
|
String contentMD5 = "";
|
||||||
|
//统一转大写处理
|
||||||
|
httpMethod = httpMethod.toUpperCase();
|
||||||
|
if ("GET".equals(httpMethod) || "DELETE".equals(httpMethod)) {
|
||||||
|
paramStr = null;
|
||||||
|
contentMD5 = "";
|
||||||
|
} else if ("PUT".equals(httpMethod) || "POST".equals(httpMethod)) {
|
||||||
|
//对body体做md5摘要
|
||||||
|
contentMD5 = EsignEncryption.doContentMD5(paramStr);
|
||||||
|
} else {
|
||||||
|
throw new EsignDemoException(String.format("不支持的请求方法%s", httpMethod));
|
||||||
|
}
|
||||||
|
//构造一个初步的请求头
|
||||||
|
Map<String, String> esignHeaderMap = buildSignAndJsonHeader(projectId, contentMD5, EsignHeaderConstant.ACCEPT.VALUE(), EsignHeaderConstant.CONTENTTYPE_JSON.VALUE(), EsignHeaderConstant.AUTHMODE.VALUE());
|
||||||
|
//排序
|
||||||
|
url = EsignEncryption.sortApiUrl(url);
|
||||||
|
//传入生成的bodyMd5,加上其他请求头部信息拼接成字符串
|
||||||
|
String message = EsignEncryption.appendSignDataString(httpMethod, esignHeaderMap.get("Content-MD5"), esignHeaderMap.get("Accept"), esignHeaderMap.get("Content-Type"), esignHeaderMap.get("Headers"), esignHeaderMap.get("Date"), url);
|
||||||
|
//整体做sha256签名
|
||||||
|
String reqSignature = EsignEncryption.doSignatureBase64(message, secret);
|
||||||
|
//请求头添加签名值
|
||||||
|
esignHeaderMap.put("X-Tsign-Open-Ca-Signature", reqSignature);
|
||||||
|
if (debug) {
|
||||||
|
LOGGER.info("----------------------------start------------------------");
|
||||||
|
LOGGER.info("待计算body值:{}", paramStr + "\n");
|
||||||
|
LOGGER.info("MD5值:{}", contentMD5 + "\n");
|
||||||
|
LOGGER.info("待签名字符串:{}", message + "\n");
|
||||||
|
LOGGER.info("签名值:{}", reqSignature + "\n");
|
||||||
|
}
|
||||||
|
return esignHeaderMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return
|
||||||
|
* @description 构建一个Token鉴权+jsons数据的esign请求头
|
||||||
|
* @author 澄泓
|
||||||
|
*/
|
||||||
|
public static Map<String, String> buildTokenAndJsonHeader(String appid, String token) {
|
||||||
|
Map<String, String> esignHeader = new HashMap<>();
|
||||||
|
esignHeader.put("X-Tsign-Open-Version-Sdk", EsignCoreSdkInfo.getSdkVersion());
|
||||||
|
esignHeader.put("Content-Type", EsignHeaderConstant.CONTENTTYPE_JSON.VALUE());
|
||||||
|
esignHeader.put("X-Tsign-Open-App-Id", appid);
|
||||||
|
esignHeader.put("X-Tsign-Open-Token", token);
|
||||||
|
return esignHeader;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return
|
||||||
|
* @description 构建一个form表单数据的esign请求头
|
||||||
|
* @author 澄泓
|
||||||
|
*/
|
||||||
|
public static Map<String, String> buildFormDataHeader(String appid) {
|
||||||
|
Map<String, String> esignHeader = new HashMap<>();
|
||||||
|
esignHeader.put("X-Tsign-Open-Version-Sdk", EsignCoreSdkInfo.getSdkVersion());
|
||||||
|
esignHeader.put("X-Tsign-Open-Authorization-Version", "v2");
|
||||||
|
esignHeader.put("Content-Type", EsignHeaderConstant.CONTENTTYPE_FORMDATA.VALUE());
|
||||||
|
esignHeader.put("X-Tsign-Open-App-Id", appid);
|
||||||
|
return esignHeader;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param fileContentMd5
|
||||||
|
* @param contentType
|
||||||
|
* @return
|
||||||
|
* @description 创建文件流上传 请求头
|
||||||
|
* @author 澄泓
|
||||||
|
*/
|
||||||
|
public static Map<String, String> buildUploadHeader(String fileContentMd5, String contentType) {
|
||||||
|
Map<String, String> header = new HashMap<>();
|
||||||
|
header.put("Content-MD5", fileContentMd5);
|
||||||
|
header.put("Content-Type", contentType);
|
||||||
|
|
||||||
|
return header;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------私有方法end----------------------------------------------
|
||||||
|
}
|
||||||
@ -0,0 +1,28 @@
|
|||||||
|
package com.suisung.mall.shop.esign.utils.comm;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 网络请求的response类
|
||||||
|
*
|
||||||
|
* @author 澄泓
|
||||||
|
* @date 2022/2/21 17:28
|
||||||
|
*/
|
||||||
|
public class EsignHttpResponse {
|
||||||
|
private int status;
|
||||||
|
private String body;
|
||||||
|
|
||||||
|
public int getStatus() {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStatus(int status) {
|
||||||
|
this.status = status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getBody() {
|
||||||
|
return body;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBody(String body) {
|
||||||
|
this.body = body;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,284 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||||||
|
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.suisung.mall.shop.esign.utils.comm;
|
||||||
|
|
||||||
|
import com.suisung.mall.shop.esign.utils.exception.EsignDemoException;
|
||||||
|
import org.apache.commons.codec.binary.Base64;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.net.HttpURLConnection;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.security.MessageDigest;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author 澄泓
|
||||||
|
* @version JDK1.7
|
||||||
|
* @description 文件转换类
|
||||||
|
* @date 2020/10/26 10:47
|
||||||
|
*/
|
||||||
|
public class FileTransformation {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 传入本地文件路径转二进制byte
|
||||||
|
*
|
||||||
|
* @param srcFilePath 本地文件路径
|
||||||
|
* @return
|
||||||
|
* @throws EsignDemoException
|
||||||
|
*/
|
||||||
|
public static byte[] fileToBytes(String srcFilePath) throws EsignDemoException {
|
||||||
|
return getBytes(srcFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 图片转base64
|
||||||
|
*
|
||||||
|
* @param filePath 本地文件路径
|
||||||
|
* @return
|
||||||
|
* @throws EsignDemoException
|
||||||
|
*/
|
||||||
|
public static String fileToBase64(String filePath) throws EsignDemoException {
|
||||||
|
byte[] bytes;
|
||||||
|
String base64 = null;
|
||||||
|
bytes = fileToBytes(filePath);
|
||||||
|
base64 = Base64.encodeBase64String(bytes);
|
||||||
|
base64 = base64.replaceAll("\r\n", "");
|
||||||
|
return base64;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) throws EsignDemoException {
|
||||||
|
System.out.println(getFileContentMD5("D:\\文档\\PLT2022-02124CT.pdf"));
|
||||||
|
}
|
||||||
|
|
||||||
|
/***
|
||||||
|
* 计算文件内容的Content-MD5
|
||||||
|
* @param filePath 文件路径
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static String getFileContentMD5(String filePath) throws EsignDemoException {
|
||||||
|
// 获取文件MD5的二进制数组(128位)
|
||||||
|
byte[] bytes = getFileMD5Bytes128(filePath);
|
||||||
|
// 对文件MD5的二进制数组进行base64编码
|
||||||
|
return Base64.encodeBase64String(bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 下载文件
|
||||||
|
*
|
||||||
|
* @param httpUrl 网络文件地址url
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static boolean downLoadFileByUrl(String httpUrl, String dir) throws EsignDemoException {
|
||||||
|
InputStream fis = null;
|
||||||
|
FileOutputStream fileOutputStream = null;
|
||||||
|
try {
|
||||||
|
URL url = new URL(httpUrl);
|
||||||
|
HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
|
||||||
|
httpConn.connect();
|
||||||
|
fis = httpConn.getInputStream();
|
||||||
|
fileOutputStream = new FileOutputStream(new File(dir));
|
||||||
|
byte[] md5Bytes = null;
|
||||||
|
|
||||||
|
byte[] buffer = new byte[1024];
|
||||||
|
int length = -1;
|
||||||
|
while ((length = fis.read(buffer, 0, 1024)) != -1) {
|
||||||
|
fileOutputStream.write(buffer, 0, length);
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
EsignDemoException ex = new EsignDemoException("获取文件流异常", e);
|
||||||
|
ex.initCause(e);
|
||||||
|
throw ex;
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
if (fis != null) {
|
||||||
|
fis.close();
|
||||||
|
}
|
||||||
|
if (fileOutputStream != null) {
|
||||||
|
fileOutputStream.close();
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
EsignDemoException ex = new EsignDemoException("关闭文件流异常", e);
|
||||||
|
ex.initCause(e);
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 网络文件转二进制MD5数组并获取文件大小
|
||||||
|
*
|
||||||
|
* @param fileUrl 网络文件地址url
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static Map fileUrlToBytes(String fileUrl) throws EsignDemoException {
|
||||||
|
HashMap<String, Object> map = new HashMap<String, Object>();
|
||||||
|
try {
|
||||||
|
URL url = new URL(fileUrl);
|
||||||
|
HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
|
||||||
|
httpConn.connect();
|
||||||
|
InputStream fis = httpConn.getInputStream();
|
||||||
|
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
|
||||||
|
outStream.close();
|
||||||
|
map.put("fileSize", fis.available());
|
||||||
|
byte[] md5Bytes = null;
|
||||||
|
MessageDigest md5 = MessageDigest.getInstance("MD5");
|
||||||
|
byte[] buffer = new byte[1024];
|
||||||
|
int length = -1;
|
||||||
|
while ((length = fis.read(buffer, 0, 1024)) != -1) {
|
||||||
|
md5.update(buffer, 0, length);
|
||||||
|
outStream.write(buffer, 0, length);
|
||||||
|
}
|
||||||
|
md5Bytes = md5.digest();
|
||||||
|
byte[] fileData = outStream.toByteArray();
|
||||||
|
map.put("fileData", fileData);
|
||||||
|
outStream.close();
|
||||||
|
fis.close();
|
||||||
|
map.put("md5Bytes", md5Bytes);
|
||||||
|
} catch (IOException e) {
|
||||||
|
EsignDemoException ex = new EsignDemoException("获取文件流异常", e);
|
||||||
|
ex.initCause(e);
|
||||||
|
throw ex;
|
||||||
|
} catch (NoSuchAlgorithmException e) {
|
||||||
|
EsignDemoException ex = new EsignDemoException("文件计算异常", e);
|
||||||
|
ex.initCause(e);
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***
|
||||||
|
* 获取文件MD5的二进制数组(128位)
|
||||||
|
* @param filePath
|
||||||
|
* @return
|
||||||
|
* @throws EsignDemoException
|
||||||
|
*/
|
||||||
|
public static byte[] getFileMD5Bytes128(String filePath) throws EsignDemoException {
|
||||||
|
FileInputStream fis = null;
|
||||||
|
byte[] md5Bytes = null;
|
||||||
|
try {
|
||||||
|
File file = new File(filePath);
|
||||||
|
fis = new FileInputStream(file);
|
||||||
|
MessageDigest md5 = MessageDigest.getInstance("MD5");
|
||||||
|
byte[] buffer = new byte[1024];
|
||||||
|
int length = -1;
|
||||||
|
while ((length = fis.read(buffer, 0, 1024)) != -1) {
|
||||||
|
md5.update(buffer, 0, length);
|
||||||
|
}
|
||||||
|
md5Bytes = md5.digest();
|
||||||
|
fis.close();
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
EsignDemoException ex = new EsignDemoException("文件找不到", e);
|
||||||
|
ex.initCause(e);
|
||||||
|
throw ex;
|
||||||
|
} catch (NoSuchAlgorithmException e) {
|
||||||
|
EsignDemoException ex = new EsignDemoException("不支持此算法", e);
|
||||||
|
ex.initCause(e);
|
||||||
|
throw ex;
|
||||||
|
} catch (IOException e) {
|
||||||
|
EsignDemoException ex = new EsignDemoException("输入流或输出流异常", e);
|
||||||
|
ex.initCause(e);
|
||||||
|
throw ex;
|
||||||
|
} finally {
|
||||||
|
if (fis != null) {
|
||||||
|
try {
|
||||||
|
fis.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
EsignDemoException ex = new EsignDemoException("关闭文件输入流失败", e);
|
||||||
|
ex.initCause(e);
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return md5Bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param path
|
||||||
|
* @return
|
||||||
|
* @throws EsignDemoException
|
||||||
|
* @description 根据文件路径,获取文件base64
|
||||||
|
* @author 宫清
|
||||||
|
* @date 2019年7月21日 下午4:22:08
|
||||||
|
*/
|
||||||
|
public static String getBase64Str(String path) throws EsignDemoException {
|
||||||
|
InputStream is = null;
|
||||||
|
try {
|
||||||
|
is = new FileInputStream(new File(path));
|
||||||
|
byte[] bytes = new byte[is.available()];
|
||||||
|
is.read(bytes);
|
||||||
|
return Base64.encodeBase64String(bytes);
|
||||||
|
} catch (Exception e) {
|
||||||
|
EsignDemoException ex = new EsignDemoException("获取文件输入流失败", e);
|
||||||
|
ex.initCause(e);
|
||||||
|
throw ex;
|
||||||
|
} finally {
|
||||||
|
if (is != null) {
|
||||||
|
try {
|
||||||
|
is.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
EsignDemoException ex = new EsignDemoException("关闭文件输入流失败", e);
|
||||||
|
ex.initCause(e);
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param path 文件路径
|
||||||
|
* @return
|
||||||
|
* @description 获取文件名称
|
||||||
|
* @author 宫清
|
||||||
|
* @date 2019年7月21日 下午8:21:16
|
||||||
|
*/
|
||||||
|
public static String getFileName(String path) {
|
||||||
|
return new File(path).getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param filePath {@link String} 文件地址
|
||||||
|
* @return
|
||||||
|
* @throws EsignDemoException
|
||||||
|
* @description 获取文件字节流
|
||||||
|
* @date 2019年7月10日 上午9:17:00
|
||||||
|
* @author 宫清
|
||||||
|
*/
|
||||||
|
public static byte[] getBytes(String filePath) throws EsignDemoException {
|
||||||
|
File file = new File(filePath);
|
||||||
|
FileInputStream fis = null;
|
||||||
|
byte[] buffer = null;
|
||||||
|
try {
|
||||||
|
fis = new FileInputStream(file);
|
||||||
|
buffer = new byte[(int) file.length()];
|
||||||
|
fis.read(buffer);
|
||||||
|
} catch (Exception e) {
|
||||||
|
EsignDemoException ex = new EsignDemoException("获取文件字节流失败", e);
|
||||||
|
ex.initCause(e);
|
||||||
|
throw ex;
|
||||||
|
} finally {
|
||||||
|
if (fis != null) {
|
||||||
|
try {
|
||||||
|
fis.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
EsignDemoException ex = new EsignDemoException("关闭文件字节流失败", e);
|
||||||
|
ex.initCause(e);
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,28 @@
|
|||||||
|
package com.suisung.mall.shop.esign.utils.enums;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author 澄泓
|
||||||
|
* @version JDK1.7
|
||||||
|
* @description 头部信息常量
|
||||||
|
* @date 2020/10/22 15:05
|
||||||
|
*/
|
||||||
|
public enum EsignHeaderConstant {
|
||||||
|
ACCEPT("*/*"),
|
||||||
|
DATE(""),
|
||||||
|
HEADERS(""),
|
||||||
|
CONTENTTYPE_FORMDATA("application/x-www-form-urlencoded"),
|
||||||
|
CONTENTTYPE_JSON("application/json; charset=UTF-8"),
|
||||||
|
CONTENTTYPE_PDF("application/pdf"),
|
||||||
|
CONTENTTYPE_STREAM("application/octet-stream"),
|
||||||
|
AUTHMODE("Signature");
|
||||||
|
|
||||||
|
private final String value;
|
||||||
|
|
||||||
|
EsignHeaderConstant(String value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String VALUE() {
|
||||||
|
return this.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,39 @@
|
|||||||
|
package com.suisung.mall.shop.esign.utils.enums;
|
||||||
|
|
||||||
|
import org.apache.http.client.methods.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author 澄泓
|
||||||
|
* @description 请求类型
|
||||||
|
* @since JDK1.7
|
||||||
|
*/
|
||||||
|
public enum EsignRequestType {
|
||||||
|
|
||||||
|
POST {
|
||||||
|
@Override
|
||||||
|
public HttpRequestBase getHttpType(String url) {
|
||||||
|
return new HttpPost(url);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
GET {
|
||||||
|
@Override
|
||||||
|
public HttpRequestBase getHttpType(String url) {
|
||||||
|
return new HttpGet(url);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
DELETE {
|
||||||
|
@Override
|
||||||
|
public HttpRequestBase getHttpType(String url) {
|
||||||
|
return new HttpDelete(url);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
PUT {
|
||||||
|
@Override
|
||||||
|
public HttpRequestBase getHttpType(String url) {
|
||||||
|
return new HttpPut(url);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
;
|
||||||
|
|
||||||
|
public abstract HttpRequestBase getHttpType(String url);
|
||||||
|
}
|
||||||
@ -0,0 +1,35 @@
|
|||||||
|
package com.suisung.mall.shop.esign.utils.exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* description 自定义全局异常
|
||||||
|
*
|
||||||
|
* @author 澄泓
|
||||||
|
* datetime 2019年7月1日上午10:43:24
|
||||||
|
*/
|
||||||
|
public class EsignDemoException extends Exception {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 4359180081622082792L;
|
||||||
|
private Exception e;
|
||||||
|
|
||||||
|
public EsignDemoException(String msg) {
|
||||||
|
super(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
public EsignDemoException(String msg, Throwable cause) {
|
||||||
|
super(msg, cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
public EsignDemoException() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public Exception getE() {
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setE(Exception e) {
|
||||||
|
this.e = e;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -33,7 +33,7 @@ public class LklTkController extends BaseControllerImpl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@ApiOperation(value = "请求获取token(商户进件)", notes = "请求获取token(商户进件)")
|
@ApiOperation(value = "请求获取token(商户进件)", notes = "请求获取token(商户进件)")
|
||||||
@RequestMapping(value = "/token", method = RequestMethod.POST)
|
@RequestMapping(value = "/token1", method = RequestMethod.POST)
|
||||||
public String getLklTkAuthorization1() {
|
public String getLklTkAuthorization1() {
|
||||||
return commonService.getLklTkAuthorization();
|
return commonService.getLklTkAuthorization();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2025. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
||||||
|
* Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan.
|
||||||
|
* Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna.
|
||||||
|
* Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus.
|
||||||
|
* Vestibulum commodo. Ut rhoncus gravida arcu.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.suisung.mall.shop.merch.controller.admin;
|
||||||
|
|
||||||
|
import cn.hutool.json.JSONObject;
|
||||||
|
import com.suisung.mall.common.api.CommonResult;
|
||||||
|
import com.suisung.mall.common.service.impl.BaseControllerImpl;
|
||||||
|
import com.suisung.mall.shop.merch.service.ShopMerchEntryService;
|
||||||
|
import io.swagger.annotations.Api;
|
||||||
|
import io.swagger.annotations.ApiOperation;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMethod;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
|
||||||
|
@Api(tags = "店铺基础信息表")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/admin/shop/merch")
|
||||||
|
public class ShopMerchEntryAdminController extends BaseControllerImpl {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private ShopMerchEntryService shopMerchEntryService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 商家申请入驻商城平台
|
||||||
|
*
|
||||||
|
* @param shopMerchEntryJSON
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@ApiOperation(value = "后台-商家申请入驻分页列表", notes = "商家申请入驻分页列表")
|
||||||
|
@RequestMapping(value = "/list", method = RequestMethod.POST)
|
||||||
|
public CommonResult shopMerchEntryList(@RequestBody JSONObject shopMerchEntryJSON) {
|
||||||
|
return shopMerchEntryService.shopMerchEntryList(shopMerchEntryJSON.getStr("keyword"), shopMerchEntryJSON.getInt("page"), shopMerchEntryJSON.getInt("pageSize"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation(value = "后台-获取商家入驻资料详情", notes = "后台-获取商家入驻资料详情")
|
||||||
|
@RequestMapping(value = "/detail", method = RequestMethod.POST)
|
||||||
|
public CommonResult shopMerchEntryDetail(@RequestBody JSONObject jsonParam) {
|
||||||
|
return shopMerchEntryService.shopMerchEntryDetail(jsonParam.getLong("id"), "", null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation(value = "商家入驻审批", notes = "商家入驻审批")
|
||||||
|
@RequestMapping(value = "/approval", method = RequestMethod.POST)
|
||||||
|
public CommonResult shopMerchEntryApproval(@RequestBody JSONObject jsonParam) {
|
||||||
|
// approvalStatus 入驻商家的审批状态:1-已通过;2-未通过;3-待审核;
|
||||||
|
return shopMerchEntryService.shopMerchEntryApproval(jsonParam.getLong("id"), jsonParam.getInt("approvalStatus"), jsonParam.getStr("approvalRemark"));
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2025. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
||||||
|
* Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan.
|
||||||
|
* Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna.
|
||||||
|
* Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus.
|
||||||
|
* Vestibulum commodo. Ut rhoncus gravida arcu.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.suisung.mall.shop.merch.controller.mobile;
|
||||||
|
|
||||||
|
import cn.hutool.json.JSONObject;
|
||||||
|
import com.suisung.mall.common.api.CommonResult;
|
||||||
|
import com.suisung.mall.common.service.impl.BaseControllerImpl;
|
||||||
|
import com.suisung.mall.shop.merch.service.ShopMerchEntryService;
|
||||||
|
import io.swagger.annotations.Api;
|
||||||
|
import io.swagger.annotations.ApiOperation;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMethod;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Api(tags = "店铺基础信息表")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/mobile/shop/merch")
|
||||||
|
public class ShopMerchEntryController extends BaseControllerImpl {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private ShopMerchEntryService shopMerchEntryService;
|
||||||
|
|
||||||
|
|
||||||
|
@ApiOperation(value = "店铺主营分类(类目)", notes = "店铺主营分类(类目)")
|
||||||
|
@RequestMapping(value = "/business/category", method = RequestMethod.POST)
|
||||||
|
public CommonResult shopStoreBusinessCategoryList() {
|
||||||
|
return shopMerchEntryService.storeBusinessCategoryList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation(value = "商家申请入驻商城平台", notes = "商家申请入驻商城平台")
|
||||||
|
@RequestMapping(value = "/apply", method = RequestMethod.POST)
|
||||||
|
public CommonResult shopMerchEntryApply(@RequestBody JSONObject shopMerchEntryJSON) {
|
||||||
|
return shopMerchEntryService.shopMerchEntryApply(shopMerchEntryJSON);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation(value = "获取商家入驻资料详情", notes = "获取商家入驻资料详情")
|
||||||
|
@RequestMapping(value = "/detail", method = RequestMethod.POST)
|
||||||
|
public CommonResult shopMerchEntryDetail(@RequestBody JSONObject jsonParam) {
|
||||||
|
// approvalStatus 入驻商家的审批状态:1-已通过;2-未通过;3-待审核;
|
||||||
|
List<Integer> approvalStatusList = new ArrayList<Integer>();
|
||||||
|
approvalStatusList.add(2);
|
||||||
|
approvalStatusList.add(3);
|
||||||
|
return shopMerchEntryService.shopMerchEntryDetail(null, jsonParam.getStr("mobile"), approvalStatusList);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,17 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2025. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
||||||
|
* Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan.
|
||||||
|
* Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna.
|
||||||
|
* Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus.
|
||||||
|
* Vestibulum commodo. Ut rhoncus gravida arcu.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.suisung.mall.shop.merch.mapper;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import com.suisung.mall.common.modules.merch.ShopMerchEntry;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public interface ShopMerchEntryMapper extends BaseMapper<ShopMerchEntry> {
|
||||||
|
}
|
||||||
@ -0,0 +1,72 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2025. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
||||||
|
* Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan.
|
||||||
|
* Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna.
|
||||||
|
* Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus.
|
||||||
|
* Vestibulum commodo. Ut rhoncus gravida arcu.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.suisung.mall.shop.merch.service;
|
||||||
|
|
||||||
|
import cn.hutool.json.JSONObject;
|
||||||
|
import com.suisung.mall.common.api.CommonResult;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public interface ShopMerchEntryService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取店铺的经营类目列表
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
CommonResult storeBusinessCategoryList();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 商品入驻申请
|
||||||
|
*
|
||||||
|
* @param shopMerchEntryJSON
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
CommonResult shopMerchEntryApply(JSONObject shopMerchEntryJSON);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 商家入驻申请列表
|
||||||
|
*
|
||||||
|
* @param keyword
|
||||||
|
* @param pageIndex
|
||||||
|
* @param pageSize
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
CommonResult shopMerchEntryList(String keyword, Integer pageIndex, Integer pageSize);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过 mobile 申请手机号或自增 ID 获取商家入驻申请详情
|
||||||
|
*
|
||||||
|
* @param recordId
|
||||||
|
* @param mobile
|
||||||
|
* @param approvalStatusList
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
CommonResult shopMerchEntryDetail(Long recordId, String mobile, List<Integer> approvalStatusList);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 商家入驻审批
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* @param approvalStatus
|
||||||
|
* @param approvalRemark
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
CommonResult shopMerchEntryApproval(Long id, Integer approvalStatus, String approvalRemark);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查手机和营业执照是否已经申请过?
|
||||||
|
*
|
||||||
|
* @param mobile
|
||||||
|
* @param bizLicenseNumber
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
Boolean isApplied(String mobile, String bizLicenseNumber);
|
||||||
|
}
|
||||||
@ -0,0 +1,313 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2025. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
||||||
|
* Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan.
|
||||||
|
* Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna.
|
||||||
|
* Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus.
|
||||||
|
* Vestibulum commodo. Ut rhoncus gravida arcu.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.suisung.mall.shop.merch.service.impl;
|
||||||
|
|
||||||
|
import cn.hutool.core.collection.CollectionUtil;
|
||||||
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import cn.hutool.json.JSONArray;
|
||||||
|
import cn.hutool.json.JSONObject;
|
||||||
|
import cn.hutool.json.JSONUtil;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import com.suisung.mall.common.api.CommonResult;
|
||||||
|
import com.suisung.mall.common.constant.CommonConstant;
|
||||||
|
import com.suisung.mall.common.modules.merch.ShopMerchEntry;
|
||||||
|
import com.suisung.mall.common.utils.StringUtils;
|
||||||
|
import com.suisung.mall.common.utils.phone.PhoneNumberUtils;
|
||||||
|
import com.suisung.mall.core.web.service.impl.BaseServiceImpl;
|
||||||
|
import com.suisung.mall.shop.base.service.AccountBaseConfigService;
|
||||||
|
import com.suisung.mall.shop.merch.mapper.ShopMerchEntryMapper;
|
||||||
|
import com.suisung.mall.shop.merch.service.ShopMerchEntryService;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
public class ShopMerchEntryServiceImpl extends BaseServiceImpl<ShopMerchEntryMapper, ShopMerchEntry> implements ShopMerchEntryService {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private AccountBaseConfigService accountBaseConfigService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取店铺的经营类目列表
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public CommonResult storeBusinessCategoryList() {
|
||||||
|
// UserDto user = getCurrentUser();
|
||||||
|
// if (user == null) {
|
||||||
|
// return CommonResult.failed("无权限操作!");
|
||||||
|
// }
|
||||||
|
|
||||||
|
String businessCategoryList = accountBaseConfigService.getConfig("shop_business_category");
|
||||||
|
if (StrUtil.isBlank(businessCategoryList)) {
|
||||||
|
return CommonResult.success(new String[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
JSONArray businessCategoryJSONObject = JSONUtil.parseArray(businessCategoryList);
|
||||||
|
if (businessCategoryJSONObject == null) {
|
||||||
|
return CommonResult.success(new String[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return CommonResult.success(businessCategoryJSONObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 商品入驻申请
|
||||||
|
*
|
||||||
|
* @param shopMerchEntryJSON
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public CommonResult shopMerchEntryApply(JSONObject shopMerchEntryJSON) {
|
||||||
|
// 检查是否已登录?
|
||||||
|
String userId = "0";
|
||||||
|
|
||||||
|
// UserDto user = getCurrentUser();
|
||||||
|
// if (user == null || user.getId() == null) {
|
||||||
|
// return CommonResult.failed("请先登录!");
|
||||||
|
// }
|
||||||
|
// userId = user.getId().toString();
|
||||||
|
|
||||||
|
// 参数校验流程
|
||||||
|
if (shopMerchEntryJSON == null) {
|
||||||
|
return CommonResult.failed("缺少必要参数!");
|
||||||
|
}
|
||||||
|
|
||||||
|
ShopMerchEntry record = JSONUtil.toBean(shopMerchEntryJSON, ShopMerchEntry.class);
|
||||||
|
if (record == null || StrUtil.isBlank(record.getLogin_mobile())) {
|
||||||
|
log.error("###商家入驻参数转换失败###");
|
||||||
|
return CommonResult.failed("缺少必要参数!");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (StrUtil.isBlank(record.getStore_name()) || StrUtil.isBlank(record.getStore_address())
|
||||||
|
|| StrUtil.isBlank(record.getStore_longitude())
|
||||||
|
|| StrUtil.isBlank(record.getStore_latitude())) {
|
||||||
|
return CommonResult.failed("缺少店铺名或详细地址!");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ObjectUtil.isEmpty(record.getBiz_category())) {
|
||||||
|
return CommonResult.failed("请选择经营品类!");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ObjectUtil.isEmpty(record.getContact_name())) {
|
||||||
|
return CommonResult.failed("请填写联系人!");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 校验身份证,手机号格式
|
||||||
|
if (StrUtil.isNotBlank(record.getLegal_person_id_number()) && !StringUtils.validateIDCard(record.getLegal_person_id_number())) {
|
||||||
|
return CommonResult.failed("法人身份证号码有误!");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (StrUtil.isNotBlank(record.getIndividual_id_number()) && !StringUtils.validateIDCard(record.getIndividual_id_number())) {
|
||||||
|
return CommonResult.failed("个人身份证号码有误!");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (StrUtil.isNotBlank(record.getLogin_mobile())) {
|
||||||
|
// String mobile = StrUtil.startWith(record.getLogin_mobile(), "+") ? record.getLogin_mobile() : CommonConstant.IDD_ZH_CN + record.getLogin_mobile();
|
||||||
|
if (!PhoneNumberUtils.checkPhoneNumber(record.getLogin_mobile())) {
|
||||||
|
return CommonResult.failed("申请人手机号码有误!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (StrUtil.isNotBlank(record.getLegal_person_mobile())) {
|
||||||
|
// String mobile = StrUtil.startWith(record.getLegal_person_mobile(), "+") ? record.getLegal_person_mobile() : CommonConstant.IDD_ZH_CN + record.getLegal_person_mobile();
|
||||||
|
if (!PhoneNumberUtils.checkPhoneNumber(record.getLegal_person_mobile())) {
|
||||||
|
return CommonResult.failed("法人手机号码有误!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查企业、法人或个人的营业执照或身份证
|
||||||
|
if (ObjectUtil.isNotEmpty(record.getEntity_type()) && record.getEntity_type().equals(2)) {
|
||||||
|
// 个人
|
||||||
|
if (StrUtil.isBlank(record.getIndividual_id_number()) || StrUtil.isBlank(record.getIndividual_id_images()) || StrUtil.isBlank(record.getIndividual_id_images2())) {
|
||||||
|
return CommonResult.failed("缺少个人身份证信息!");
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// 企业
|
||||||
|
if (StrUtil.isBlank(record.getBiz_license_number()) || StrUtil.isBlank(record.getBiz_license_image())) {
|
||||||
|
return CommonResult.failed("缺少企业营业执照信息!");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (StrUtil.isBlank(record.getLegal_person_id_images()) || StrUtil.isBlank(record.getLegal_person_id_images2())) {
|
||||||
|
return CommonResult.failed("缺少企业法人身份证信息!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查银行账号
|
||||||
|
if (StrUtil.isBlank(record.getBank_name()) || StrUtil.isBlank(record.getAccount_number()) || StrUtil.isBlank(record.getAccount_holder_name())) {
|
||||||
|
return CommonResult.failed("缺少银行账号信息!");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查店铺是否已经申请过入驻
|
||||||
|
if (isApplied(record.getLogin_mobile(), record.getBiz_license_number())) {
|
||||||
|
return CommonResult.failed("您手机号或营业执照已经申请过入驻!");
|
||||||
|
}
|
||||||
|
|
||||||
|
record.setCreated_by(userId);
|
||||||
|
record.setStatus(CommonConstant.Enable);
|
||||||
|
if (!add(record)) {
|
||||||
|
return CommonResult.failed("入驻信息提交失败!");
|
||||||
|
}
|
||||||
|
|
||||||
|
return CommonResult.success();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 商家入驻申请列表
|
||||||
|
*
|
||||||
|
* @param keyword
|
||||||
|
* @param pageIndex
|
||||||
|
* @param pageSize
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public CommonResult shopMerchEntryList(String keyword, Integer pageIndex, Integer pageSize) {
|
||||||
|
// 检查登录用户是否有管理权限
|
||||||
|
// UserDto user = getCurrentUser();
|
||||||
|
// if (!user.isAdmin()) {
|
||||||
|
// return CommonResult.failed("权限不足!");
|
||||||
|
// }
|
||||||
|
|
||||||
|
QueryWrapper<ShopMerchEntry> queryWrapper = new QueryWrapper<>();
|
||||||
|
if (StrUtil.isNotBlank(keyword)) {
|
||||||
|
queryWrapper.like("store_name", keyword);
|
||||||
|
}
|
||||||
|
|
||||||
|
queryWrapper.orderByDesc("id");
|
||||||
|
|
||||||
|
if (ObjectUtil.isEmpty(pageIndex)) {
|
||||||
|
pageIndex = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ObjectUtil.isEmpty(pageSize)) {
|
||||||
|
pageSize = 20;
|
||||||
|
}
|
||||||
|
|
||||||
|
Page<ShopMerchEntry> listPage = lists(queryWrapper, pageIndex, pageSize);
|
||||||
|
|
||||||
|
return CommonResult.success(listPage);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过 mobile 申请手机号或自增 ID 获取商家入驻申请详情
|
||||||
|
*
|
||||||
|
* @param recordId
|
||||||
|
* @param mobile
|
||||||
|
* @param approvalStatusList
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public CommonResult shopMerchEntryDetail(Long recordId, String mobile, List<Integer> approvalStatusList) {
|
||||||
|
// 检查登录用户是否有管理权限或者是用户自己
|
||||||
|
|
||||||
|
// approvalStatus 入驻商家的审批状态:1-已通过;2-未通过;3-待审核;
|
||||||
|
if (ObjectUtil.isEmpty(recordId) && StrUtil.isBlank(mobile)) {
|
||||||
|
return CommonResult.failed("缺少必要参数!");
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryWrapper<ShopMerchEntry> queryWrapper = new QueryWrapper<>();
|
||||||
|
if (ObjectUtil.isNotEmpty(recordId)) {
|
||||||
|
queryWrapper.eq("id", recordId);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (StrUtil.isNotBlank(mobile)) {
|
||||||
|
queryWrapper.eq("login_mobile", mobile);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CollectionUtil.isNotEmpty(approvalStatusList)) {
|
||||||
|
queryWrapper.in("approval_status", approvalStatusList);
|
||||||
|
}
|
||||||
|
queryWrapper.orderByDesc("id");
|
||||||
|
List<ShopMerchEntry> recordList = list(queryWrapper);
|
||||||
|
if (CollectionUtil.isEmpty(recordList)) {
|
||||||
|
return CommonResult.success(null, "暂无申请记录!");
|
||||||
|
}
|
||||||
|
|
||||||
|
return CommonResult.success(recordList.get(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 商家入驻审批
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* @param approvalStatus
|
||||||
|
* @param approvalRemark
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public CommonResult shopMerchEntryApproval(Long id, Integer approvalStatus, String approvalRemark) {
|
||||||
|
// 检查登录用户是否有管理权限
|
||||||
|
String userId = "0";
|
||||||
|
|
||||||
|
// UserDto user = getCurrentUser();
|
||||||
|
// if (!user.isAdmin()) {
|
||||||
|
// return CommonResult.failed("权限不足!");
|
||||||
|
// }
|
||||||
|
// userId = user.getId().toString();
|
||||||
|
|
||||||
|
if (ObjectUtil.isEmpty(id) || ObjectUtil.isEmpty(approvalStatus)) {
|
||||||
|
return CommonResult.failed("缺少必要参数!");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!approvalStatus.equals(1) && !approvalStatus.equals(2)) {
|
||||||
|
return CommonResult.failed("审批状态有误!");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (approvalStatus.equals(1) && StrUtil.isBlank(approvalRemark)) {
|
||||||
|
approvalRemark = "审核通过,后续将到签署电子合同流程。";
|
||||||
|
} else if (approvalStatus.equals(2) && StrUtil.isBlank(approvalRemark)) {
|
||||||
|
approvalRemark = "审核未通过,申请材料有待完善。";
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateWrapper<ShopMerchEntry> updateWrapper = new UpdateWrapper<>();
|
||||||
|
updateWrapper.eq("id", id).set("approval_status", approvalStatus)
|
||||||
|
.set("approval_remark", approvalRemark)
|
||||||
|
.set("updated_by", userId);
|
||||||
|
|
||||||
|
if (!update(updateWrapper)) {
|
||||||
|
return CommonResult.failed("审批出错,请联系管理员!");
|
||||||
|
}
|
||||||
|
|
||||||
|
return CommonResult.success();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查手机和营业执照是否已经申请过?
|
||||||
|
*
|
||||||
|
* @param mobile
|
||||||
|
* @param bizLicenseNumber
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Boolean isApplied(String mobile, String bizLicenseNumber) {
|
||||||
|
if (StrUtil.isBlank(mobile) || StrUtil.isBlank(bizLicenseNumber)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryWrapper<ShopMerchEntry> queryWrapper = new QueryWrapper<>();
|
||||||
|
if (StrUtil.isNotBlank(mobile)) {
|
||||||
|
queryWrapper.eq("login_mobile", mobile);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (StrUtil.isNotBlank(mobile)) {
|
||||||
|
queryWrapper.eq("biz_license_number", bizLicenseNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
return count(queryWrapper) > 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -13,6 +13,8 @@ import cn.hutool.core.comparator.FieldsComparator;
|
|||||||
import cn.hutool.core.convert.Convert;
|
import cn.hutool.core.convert.Convert;
|
||||||
import cn.hutool.core.util.NumberUtil;
|
import cn.hutool.core.util.NumberUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import cn.hutool.json.JSONObject;
|
||||||
|
import cn.hutool.json.JSONUtil;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
import com.suisung.mall.common.api.CommonResult;
|
import com.suisung.mall.common.api.CommonResult;
|
||||||
import com.suisung.mall.common.api.ResultCode;
|
import com.suisung.mall.common.api.ResultCode;
|
||||||
@ -23,13 +25,13 @@ import com.suisung.mall.common.modules.store.ShopStoreBase;
|
|||||||
import com.suisung.mall.common.modules.store.ShopStoreSameCityTransport;
|
import com.suisung.mall.common.modules.store.ShopStoreSameCityTransport;
|
||||||
import com.suisung.mall.common.modules.store.ShopStoreSameCityTransportBase;
|
import com.suisung.mall.common.modules.store.ShopStoreSameCityTransportBase;
|
||||||
import com.suisung.mall.common.pojo.dto.DeliveryFeeResultDTO;
|
import com.suisung.mall.common.pojo.dto.DeliveryFeeResultDTO;
|
||||||
import com.suisung.mall.common.pojo.dto.KeyValueDTO;
|
|
||||||
import com.suisung.mall.common.pojo.dto.SameCityDeliveryFeeRespDTO;
|
import com.suisung.mall.common.pojo.dto.SameCityDeliveryFeeRespDTO;
|
||||||
import com.suisung.mall.common.pojo.dto.ShopStoreSameCityTransportBaseDTO;
|
import com.suisung.mall.common.pojo.dto.ShopStoreSameCityTransportBaseDTO;
|
||||||
import com.suisung.mall.common.utils.CommonUtil;
|
import com.suisung.mall.common.utils.CommonUtil;
|
||||||
import com.suisung.mall.common.utils.I18nUtil;
|
import com.suisung.mall.common.utils.I18nUtil;
|
||||||
import com.suisung.mall.common.utils.PositionUtil;
|
import com.suisung.mall.common.utils.PositionUtil;
|
||||||
import com.suisung.mall.core.web.service.impl.BaseServiceImpl;
|
import com.suisung.mall.core.web.service.impl.BaseServiceImpl;
|
||||||
|
import com.suisung.mall.shop.base.service.AccountBaseConfigService;
|
||||||
import com.suisung.mall.shop.store.mapper.ShopStoreSameCityTransportBaseMapper;
|
import com.suisung.mall.shop.store.mapper.ShopStoreSameCityTransportBaseMapper;
|
||||||
import com.suisung.mall.shop.store.service.ShopStoreBaseService;
|
import com.suisung.mall.shop.store.service.ShopStoreBaseService;
|
||||||
import com.suisung.mall.shop.store.service.ShopStoreSameCityTransportBaseService;
|
import com.suisung.mall.shop.store.service.ShopStoreSameCityTransportBaseService;
|
||||||
@ -59,6 +61,8 @@ public class ShopStoreSameCityTransportBaseServiceImpl extends BaseServiceImpl<S
|
|||||||
private ShopStoreSameCityTransportService shopStoreSameCityTransportService;
|
private ShopStoreSameCityTransportService shopStoreSameCityTransportService;
|
||||||
@Autowired
|
@Autowired
|
||||||
private ShopStoreBaseService shopStoreBaseService;
|
private ShopStoreBaseService shopStoreBaseService;
|
||||||
|
@Resource
|
||||||
|
private AccountBaseConfigService accountBaseConfigService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取同城配送设置详情信息
|
* 获取同城配送设置详情信息
|
||||||
@ -143,46 +147,60 @@ public class ShopStoreSameCityTransportBaseServiceImpl extends BaseServiceImpl<S
|
|||||||
return CommonResult.failed("无权限操作!");
|
return CommonResult.failed("无权限操作!");
|
||||||
}
|
}
|
||||||
|
|
||||||
List<KeyValueDTO> list = new ArrayList<KeyValueDTO>() {{
|
String businessCategoryList = accountBaseConfigService.getConfig("shop_business_category");
|
||||||
add(new KeyValueDTO(1, "快餐"));
|
if (StrUtil.isBlank(businessCategoryList)) {
|
||||||
add(new KeyValueDTO(2, "药品"));
|
return CommonResult.success(new String[0]);
|
||||||
add(new KeyValueDTO(3, "百货"));
|
}
|
||||||
add(new KeyValueDTO(4, "脏衣服收"));
|
|
||||||
add(new KeyValueDTO(5, "干净衣服派"));
|
|
||||||
add(new KeyValueDTO(6, "生鲜"));
|
|
||||||
add(new KeyValueDTO(8, "高端饮品"));
|
|
||||||
add(new KeyValueDTO(10, "快递"));
|
|
||||||
add(new KeyValueDTO(12, "文件"));
|
|
||||||
add(new KeyValueDTO(13, "蛋糕"));
|
|
||||||
add(new KeyValueDTO(14, "鲜花"));
|
|
||||||
add(new KeyValueDTO(15, "数码"));
|
|
||||||
add(new KeyValueDTO(16, "服装"));
|
|
||||||
add(new KeyValueDTO(17, "汽配"));
|
|
||||||
add(new KeyValueDTO(18, "珠宝"));
|
|
||||||
add(new KeyValueDTO(20, "披萨"));
|
|
||||||
add(new KeyValueDTO(21, "中餐"));
|
|
||||||
add(new KeyValueDTO(22, "水产"));
|
|
||||||
add(new KeyValueDTO(32, "中端饮品"));
|
|
||||||
add(new KeyValueDTO(33, "便利店"));
|
|
||||||
add(new KeyValueDTO(34, "面包糕点"));
|
|
||||||
add(new KeyValueDTO(35, "火锅"));
|
|
||||||
add(new KeyValueDTO(36, "证照"));
|
|
||||||
add(new KeyValueDTO(40, "烧烤小龙虾"));
|
|
||||||
add(new KeyValueDTO(41, "外部落地配"));
|
|
||||||
add(new KeyValueDTO(44, "年夜饭"));
|
|
||||||
add(new KeyValueDTO(47, "烟酒行"));
|
|
||||||
add(new KeyValueDTO(48, "成人用品"));
|
|
||||||
add(new KeyValueDTO(53, "冷链医药"));
|
|
||||||
add(new KeyValueDTO(55, "宠物用品"));
|
|
||||||
add(new KeyValueDTO(56, "母婴用品"));
|
|
||||||
add(new KeyValueDTO(57, "美妆用品"));
|
|
||||||
add(new KeyValueDTO(58, "家居建材"));
|
|
||||||
add(new KeyValueDTO(59, "眼镜行"));
|
|
||||||
add(new KeyValueDTO(60, "图文广告"));
|
|
||||||
add(new KeyValueDTO(81, "中药"));
|
|
||||||
}};
|
|
||||||
|
|
||||||
return CommonResult.success(list, "");
|
JSONObject businessCategoryJSONObject = JSONUtil.parseObj(businessCategoryList);
|
||||||
|
if (businessCategoryJSONObject == null) {
|
||||||
|
return CommonResult.success(new String[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return CommonResult.success(businessCategoryJSONObject);
|
||||||
|
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// List<KeyValueDTO> list = new ArrayList<KeyValueDTO>() {{
|
||||||
|
// add(new KeyValueDTO(1, "快餐"));
|
||||||
|
// add(new KeyValueDTO(2, "药品"));
|
||||||
|
// add(new KeyValueDTO(3, "百货"));
|
||||||
|
// add(new KeyValueDTO(4, "脏衣服收"));
|
||||||
|
// add(new KeyValueDTO(5, "干净衣服派"));
|
||||||
|
// add(new KeyValueDTO(6, "生鲜"));
|
||||||
|
// add(new KeyValueDTO(8, "高端饮品"));
|
||||||
|
// add(new KeyValueDTO(10, "快递"));
|
||||||
|
// add(new KeyValueDTO(12, "文件"));
|
||||||
|
// add(new KeyValueDTO(13, "蛋糕"));
|
||||||
|
// add(new KeyValueDTO(14, "鲜花"));
|
||||||
|
// add(new KeyValueDTO(15, "数码"));
|
||||||
|
// add(new KeyValueDTO(16, "服装"));
|
||||||
|
// add(new KeyValueDTO(17, "汽配"));
|
||||||
|
// add(new KeyValueDTO(18, "珠宝"));
|
||||||
|
// add(new KeyValueDTO(20, "披萨"));
|
||||||
|
// add(new KeyValueDTO(21, "中餐"));
|
||||||
|
// add(new KeyValueDTO(22, "水产"));
|
||||||
|
// add(new KeyValueDTO(32, "中端饮品"));
|
||||||
|
// add(new KeyValueDTO(33, "便利店"));
|
||||||
|
// add(new KeyValueDTO(34, "面包糕点"));
|
||||||
|
// add(new KeyValueDTO(35, "火锅"));
|
||||||
|
// add(new KeyValueDTO(36, "证照"));
|
||||||
|
// add(new KeyValueDTO(40, "烧烤小龙虾"));
|
||||||
|
// add(new KeyValueDTO(41, "外部落地配"));
|
||||||
|
// add(new KeyValueDTO(44, "年夜饭"));
|
||||||
|
// add(new KeyValueDTO(47, "烟酒行"));
|
||||||
|
// add(new KeyValueDTO(48, "成人用品"));
|
||||||
|
// add(new KeyValueDTO(53, "冷链医药"));
|
||||||
|
// add(new KeyValueDTO(55, "宠物用品"));
|
||||||
|
// add(new KeyValueDTO(56, "母婴用品"));
|
||||||
|
// add(new KeyValueDTO(57, "美妆用品"));
|
||||||
|
// add(new KeyValueDTO(58, "家居建材"));
|
||||||
|
// add(new KeyValueDTO(59, "眼镜行"));
|
||||||
|
// add(new KeyValueDTO(60, "图文广告"));
|
||||||
|
// add(new KeyValueDTO(81, "中药"));
|
||||||
|
// }};
|
||||||
|
//
|
||||||
|
// return CommonResult.success(list, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -145,4 +145,11 @@ lakala:
|
|||||||
client_id: lsycs
|
client_id: lsycs
|
||||||
client_secret: XPa1HB5d55Ig0qV8
|
client_secret: XPa1HB5d55Ig0qV8
|
||||||
api_pub_key_path: payKey/lakala/dev/tk_api_public_key.txt
|
api_pub_key_path: payKey/lakala/dev/tk_api_public_key.txt
|
||||||
api_pri_key_path: payKey/lakala/dev/tk_api_private_key.txt
|
api_pri_key_path: payKey/lakala/dev/tk_api_private_key.txt
|
||||||
|
#e签宝配置
|
||||||
|
esign:
|
||||||
|
server_url: https://smlopenapi.esign.cn
|
||||||
|
#正式地址 https://openapi.esign.cn
|
||||||
|
app_id: 7439053575
|
||||||
|
app_secret: 8da2e1eeeaf88e09bcf432a2fdd3e4d7
|
||||||
|
app_rsa: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAiC+fUc0+O9m45VEcGciJQ5QQNXs3NkHoHM2qDAdrXOnTwku0Be1IPeWUZ4s7w8xqubyirAAJDc3LpRkwCK84NicA2VwraD4on8MNtX8MLALZjLc1jZTmRAPKVfTKAcainR7ET78Y+QKJgezNvI7u45FO4Db+dWCC7pbedxBo+kHKA8im+/G0hpQaklxw1wjIMNv+x+YBnm8FOXRPWJZ+eItF5qJOT2C16QCY7hdeHknom+NMpZD8E/WAMtf03BcgigsoavTVnPI0xnN8BCrgykDWgO5bUXeIgNEF1LJS6r8s6BaMl+ZWbuODtbsrQ941GbFOe6x8tnhPIeehIa1AWQIDAQAB
|
||||||
|
|||||||
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
|
<mapper namespace="com.suisung.mall.shop.esign.mapper.EsignContractFillingFileMapper">
|
||||||
|
<!-- 通用查询结果列 -->
|
||||||
|
<sql id="Base_Column_List">
|
||||||
|
*
|
||||||
|
</sql>
|
||||||
|
</mapper>
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
|
<mapper namespace="com.suisung.mall.shop.merch.mapper.ShopMerchEntryMapper">
|
||||||
|
<!-- 通用查询结果列 -->
|
||||||
|
<sql id="Base_Column_List">
|
||||||
|
*
|
||||||
|
</sql>
|
||||||
|
</mapper>
|
||||||
Loading…
Reference in New Issue
Block a user