mirror of
https://github.com/dataease/dataease.git
synced 2026-05-14 04:12:11 +08:00
feat: Add Playwright
This commit is contained in:
committed by
fit2cloud-chenyw
parent
2b27a330ab
commit
00548d8331
@@ -65,6 +65,8 @@ public class ReportCreator implements Serializable {
|
||||
|
||||
private List<VisualizationReportFilterVO> reportFilter;
|
||||
|
||||
private Integer dataPermission = 0;
|
||||
|
||||
@JsonIgnore
|
||||
private Long logTaskId;
|
||||
}
|
||||
|
||||
@@ -64,4 +64,6 @@ public class ReportInfoVO implements Serializable {
|
||||
private Integer retryLimit;
|
||||
|
||||
private Integer retryInterval;
|
||||
|
||||
private Integer dataPermission = 0;
|
||||
}
|
||||
|
||||
@@ -5,7 +5,9 @@ import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
|
||||
import io.dataease.api.permissions.auth.dto.*;
|
||||
import io.dataease.api.permissions.auth.vo.PermissionVO;
|
||||
import io.dataease.api.permissions.auth.vo.ResourceItemVO;
|
||||
import io.dataease.api.permissions.auth.vo.ResourceVO;
|
||||
import io.swagger.v3.oas.annotations.Hidden;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
@@ -72,4 +74,8 @@ public interface AuthApi {
|
||||
void saveMenuTargetPer(@RequestBody MenuTargetPerCreator creator);
|
||||
|
||||
|
||||
@Hidden
|
||||
@PostMapping("/busiTargetPermissionAll")
|
||||
List<ResourceItemVO> busiTargetPermissionAll(@RequestBody BusiPermissionRequest request);
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
package io.dataease.api.permissions.auth.vo;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Data
|
||||
public class ResourceItemVO extends ResourceNodeVO {
|
||||
private String account;
|
||||
}
|
||||
@@ -1,12 +1,19 @@
|
||||
package io.dataease.api.permissions.auth.vo;
|
||||
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Data
|
||||
public class ResourceNodeVO implements Serializable {
|
||||
|
||||
@JsonSerialize(using= ToStringSerializer.class)
|
||||
private Long id;
|
||||
|
||||
private String name;
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
package io.dataease.utils;
|
||||
|
||||
import io.dataease.exception.DEException;
|
||||
import lombok.Data;
|
||||
import org.apache.commons.collections4.MapUtils;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.http.HttpEntity;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.HttpStatus;
|
||||
import org.apache.http.NameValuePair;
|
||||
import org.apache.http.client.entity.EntityBuilder;
|
||||
import org.apache.http.client.entity.UrlEncodedFormEntity;
|
||||
@@ -38,6 +40,8 @@ import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.*;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static io.dataease.result.ResultCode.SYSTEM_INNER_ERROR;
|
||||
@@ -666,4 +670,113 @@ public class HttpClientUtil {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static MultipartResponse postForScreenshot(
|
||||
String url, Map<String,String> body, HttpClientConfig config) throws IOException {
|
||||
CloseableHttpClient httpClient = null;
|
||||
try {
|
||||
httpClient = buildHttpClient(url);
|
||||
HttpPost httpPost = new HttpPost(url);
|
||||
if (config == null) {
|
||||
config = new HttpClientConfig();
|
||||
}
|
||||
httpPost.setConfig(config.buildRequestConfig());
|
||||
Map<String, String> header = config.getHeader();
|
||||
for (String key : header.keySet()) {
|
||||
httpPost.addHeader(key, header.get(key));
|
||||
}
|
||||
EntityBuilder entityBuilder = EntityBuilder.create();
|
||||
String json = JsonUtil.toJSONString(body).toString();
|
||||
entityBuilder.setText(json);
|
||||
entityBuilder.setContentType(ContentType.APPLICATION_JSON);
|
||||
HttpEntity requestEntity = entityBuilder.build();
|
||||
httpPost.setEntity(requestEntity);
|
||||
|
||||
|
||||
try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
|
||||
if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
|
||||
throw new DEException(response.getStatusLine().getStatusCode(), response.toString());
|
||||
}
|
||||
HttpEntity entity = response.getEntity();
|
||||
byte[] bytes = EntityUtils.toByteArray(entity); // raw bytes
|
||||
String contentType = response.getFirstHeader("Content-Type").getValue();
|
||||
if (contentType.startsWith("multipart/")) {
|
||||
return MultipartParser.parse(bytes, contentType); // see util below
|
||||
} else {
|
||||
throw new IOException("unexpected response: " + contentType);
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class MultipartResponse {
|
||||
Map<String,Object> metadata;
|
||||
byte[] image;
|
||||
}
|
||||
|
||||
public class MultipartParser {
|
||||
public static MultipartResponse parse(byte[] body, String contentType) throws IOException {
|
||||
String boundary = extractBoundary(contentType);
|
||||
String delim = "--" + boundary;
|
||||
byte[] delimBytes = delim.getBytes();
|
||||
MultipartResponse resp = new MultipartResponse();
|
||||
resp.metadata = new HashMap<>();
|
||||
|
||||
int idx = 0;
|
||||
while (idx < body.length) {
|
||||
int start = indexOf(body, delimBytes, idx);
|
||||
if (start < 0) break;
|
||||
idx = start + delimBytes.length;
|
||||
if (idx + 1 < body.length && body[idx] == '-' && body[idx+1] == '-') break; // final boundary
|
||||
// skip CRLF
|
||||
if (body[idx] == '\r' && body[idx+1] == '\n') idx += 2;
|
||||
|
||||
// read headers
|
||||
int headerEnd = indexOf(body, "\r\n\r\n".getBytes(), idx);
|
||||
String headers = new String(body, idx, headerEnd - idx);
|
||||
idx = headerEnd + 4;
|
||||
|
||||
boolean isImage = headers.contains("name=\"image\"");
|
||||
int nextBoundary = indexOf(body, delimBytes, idx);
|
||||
if (nextBoundary < 0) break;
|
||||
|
||||
byte[] part = new byte[nextBoundary - idx - 2]; // strip trailing CRLF
|
||||
System.arraycopy(body, idx, part, 0, part.length);
|
||||
|
||||
if (isImage) {
|
||||
resp.image = part;
|
||||
} else {
|
||||
String json = new String(part);
|
||||
// 最简单把整个 JSON 字符串放到 metadata map;
|
||||
// 你也可以用 Jackson/Gson 解析成具体字段
|
||||
resp.metadata = JsonUtil.parseObject(json, Map.class);
|
||||
}
|
||||
idx = nextBoundary;
|
||||
}
|
||||
return resp;
|
||||
}
|
||||
|
||||
private static String extractBoundary(String contentType) {
|
||||
Pattern p = Pattern.compile("boundary=(.*)");
|
||||
Matcher m = p.matcher(contentType);
|
||||
if (m.find()) {
|
||||
return m.group(1);
|
||||
}
|
||||
throw new IllegalArgumentException("No boundary in content-type");
|
||||
}
|
||||
|
||||
private static int indexOf(byte[] array, byte[] target, int start) {
|
||||
outer:
|
||||
for (int i = start; i <= array.length - target.length; i++) {
|
||||
for (int j = 0; j < target.length; j++) {
|
||||
if (array[i+j] != target[j]) continue outer;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user