对账单下载

This commit is contained in:
xiafang
2020-12-08 14:55:36 +08:00
parent ac6a5fffd9
commit ea05ff96d6
3 changed files with 136 additions and 21 deletions

View File

@@ -0,0 +1,66 @@
package cn.felord.payment.wechat.v3;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.MediaType;
import org.springframework.http.converter.*;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.MimeType;
import org.springframework.util.StreamUtils;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Type;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Objects;
/**
* @author Dax
* @since 12:46
*/
public class DownloadHttpMessageConverter extends AbstractHttpMessageConverter<ObjectNode> {
public DownloadHttpMessageConverter() {
}
public DownloadHttpMessageConverter(MediaType supportedMediaType) {
super(supportedMediaType);
}
@Override
protected boolean supports(Class<?> clazz) {
return clazz.isAssignableFrom(ObjectNode.class);
}
@Override
protected ObjectNode readInternal(Class<? extends ObjectNode> clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {
Charset charset = getContentTypeCharset(inputMessage.getHeaders().getContentType());
String s = StreamUtils.copyToString(inputMessage.getBody(), charset);
return new ObjectNode(JsonNodeFactory.withExactBigDecimals(true)).put("result", s);
}
@Override
protected void writeInternal(ObjectNode jsonNodes, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {
}
private Charset getContentTypeCharset(@Nullable MediaType contentType) {
if (contentType != null && contentType.getCharset() != null) {
return contentType.getCharset();
}
else if (contentType != null && contentType.isCompatibleWith(MediaType.APPLICATION_JSON)) {
// Matching to AbstractJackson2HttpMessageConverter#DEFAULT_CHARSET
return StandardCharsets.UTF_8;
}
else {
Charset charset = getDefaultCharset();
Assert.state(charset != null, "No default charset");
return charset;
}
}
}

View File

@@ -380,7 +380,8 @@ public class WechatMarketingFavorApi extends AbstractApi {
.function(this::downloadFlowFunction) .function(this::downloadFlowFunction)
.consumer(wechatResponseEntity::convert) .consumer(wechatResponseEntity::convert)
.request(); .request();
String csv = billDownload(wechatResponseEntity.getBody().get("url").asText());
wechatResponseEntity.getBody().put("csv", csv);
return wechatResponseEntity; return wechatResponseEntity;
} }
@@ -396,6 +397,8 @@ public class WechatMarketingFavorApi extends AbstractApi {
.function(this::downloadFlowFunction) .function(this::downloadFlowFunction)
.consumer(wechatResponseEntity::convert) .consumer(wechatResponseEntity::convert)
.request(); .request();
String csv = billDownload(wechatResponseEntity.getBody().get("url").asText());
wechatResponseEntity.getBody().put("csv", csv);
return wechatResponseEntity; return wechatResponseEntity;
} }
@@ -477,6 +480,19 @@ public class WechatMarketingFavorApi extends AbstractApi {
return post(uri, body, tenantId()); return post(uri, body, tenantId());
} }
public String billDownload(String link) {
return this.client().withType(WechatPayV3Type.FILE_DOWNLOAD, link)
.function(this::billDownloadFunction)
.download();
}
private RequestEntity<?> billDownloadFunction(WechatPayV3Type type, String link) {
URI uri = UriComponentsBuilder.fromHttpUrl(link)
.build()
.toUri();
return RequestEntity.get(uri).header("Pay-TenantId", tenantId()).build();
}
} }

View File

@@ -11,6 +11,7 @@ import org.springframework.http.*;
import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter; import org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.springframework.util.MimeType;
import org.springframework.util.MultiValueMap; import org.springframework.util.MultiValueMap;
import org.springframework.web.client.DefaultResponseErrorHandler; import org.springframework.web.client.DefaultResponseErrorHandler;
import org.springframework.web.client.RestOperations; import org.springframework.web.client.RestOperations;
@@ -88,6 +89,7 @@ public class WechatPayClient {
* @param wechatPayV3Type the v 3 pay type * @param wechatPayV3Type the v 3 pay type
* @param model the model * @param model the model
* @param signatureProvider the signature provider * @param signatureProvider the signature provider
* @param restOperations the rest operations
*/ */
Executor(WechatPayV3Type wechatPayV3Type, Executor(WechatPayV3Type wechatPayV3Type,
M model, M model,
@@ -124,7 +126,6 @@ public class WechatPayClient {
/** /**
* Request. * Request.
*/ */
@SneakyThrows
public void request() { public void request() {
RequestEntity<?> requestEntity = this.requestEntityBiFunction.apply(this.wechatPayV3Type, this.model); RequestEntity<?> requestEntity = this.requestEntityBiFunction.apply(this.wechatPayV3Type, this.model);
WechatRequestEntity<?> wechatRequestEntity = WechatRequestEntity.of(requestEntity, this.responseBodyConsumer); WechatRequestEntity<?> wechatRequestEntity = WechatRequestEntity.of(requestEntity, this.responseBodyConsumer);
@@ -132,6 +133,18 @@ public class WechatPayClient {
} }
/**
* Download string.
*
* @return the string
*/
public String download() {
RequestEntity<?> requestEntity = this.requestEntityBiFunction.apply(this.wechatPayV3Type, this.model);
WechatRequestEntity<?> wechatRequestEntity = WechatRequestEntity.of(requestEntity, this.responseBodyConsumer);
return this.doDownload(this.header(wechatRequestEntity));
}
/** /**
* 构造私钥签名. * 构造私钥签名.
* *
@@ -215,8 +228,27 @@ public class WechatPayClient {
} }
} }
private <T> String doDownload(WechatRequestEntity<T> requestEntity) {
ResponseEntity<String> responseEntity = restOperations.exchange(requestEntity, String.class);
String body = responseEntity.getBody();
if (!responseEntity.getStatusCode().is2xxSuccessful()) {
throw new PayException("wechat pay server error,result : " + body);
}
if (Objects.isNull(body)) {
throw new PayException("cant obtain wechat response body");
}
return body;
} }
}
/**
* Signature provider signature provider.
*
* @return the signature provider
*/
public SignatureProvider signatureProvider() { public SignatureProvider signatureProvider() {
return signatureProvider; return signatureProvider;
} }
@@ -229,6 +261,7 @@ public class WechatPayClient {
messageConverters.removeIf(httpMessageConverter -> httpMessageConverter instanceof AllEncompassingFormHttpMessageConverter); messageConverters.removeIf(httpMessageConverter -> httpMessageConverter instanceof AllEncompassingFormHttpMessageConverter);
messageConverters.add(new ExtensionFormHttpMessageConverter()); messageConverters.add(new ExtensionFormHttpMessageConverter());
// messageConverters.add(new DownloadHttpMessageConverter(MediaType.asMediaType(MimeType.valueOf("text/plain;charset=utf-8"))));
restTemplate.setMessageConverters(messageConverters); restTemplate.setMessageConverters(messageConverters);
this.restOperations = restTemplate; this.restOperations = restTemplate;
} }