作者 钟来

坤泰日志功能对接

package com.ruoyi.system.domain.log;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
@ApiModel("水产舆情")
public class LogExcelSub {
@ApiModelProperty(value="主键")
private Integer id; // int NOT NULL AUTO_INCREMENT COMMENT '主键',
@ApiModelProperty(value="记录id")
private String log_id; //
@ApiModelProperty(value="平台类型(1:飞书,2:wps)")
private Integer system_type; // int NOT NULL COMMENT '平台类型(1:飞书,2:wps)',
@ApiModelProperty(value="创建时间")
private String create_time; // datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
@ApiModelProperty(value="表格唯一主键")
private String excel_id; // varchar(50) DEFAULT NULL COMMENT '表格唯一主键',
@ApiModelProperty(value="sheet唯一主键")
private String sheet_id; // varchar(50) DEFAULT NULL COMMENT 'sheet唯一主键',
@ApiModelProperty(value="提交的数据")
private String sub_data; // json DEFAULT NULL,
public String getLog_id() {
return log_id;
}
public void setLog_id(String log_id) {
this.log_id = log_id;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getSystem_type() {
return system_type;
}
public void setSystem_type(Integer system_type) {
this.system_type = system_type;
}
public String getCreate_time() {
return create_time;
}
public void setCreate_time(String create_time) {
this.create_time = create_time;
}
public String getExcel_id() {
return excel_id;
}
public void setExcel_id(String excel_id) {
this.excel_id = excel_id;
}
public String getSheet_id() {
return sheet_id;
}
public void setSheet_id(String sheet_id) {
this.sheet_id = sheet_id;
}
public String getSub_data() {
return sub_data;
}
public void setSub_data(String sub_data) {
this.sub_data = sub_data;
}
}
... ...
package com.zhonglai.luhui.dao.dto;
import com.zhonglai.luhui.dao.dto.SqlResult;
import com.ruoyi.common.annotation.PublicSQLConfig;
import org.apache.commons.lang3.StringUtils;
... ... @@ -782,4 +784,26 @@ public class PublicSQL {
}
return select;
}
public String buildSql(Map<String, Object> para) {
SqlResult sqlResult = (SqlResult) para.get("sqlResult");
String sql = sqlResult.getSql();
// 参数列表
List<Object> params = sqlResult.getParams();
// 将 “?” 替换为 #{param1}, #{param2}……
if (params != null) {
for (int i = 0; i < params.size(); i++) {
para.put("param" + (i + 1), params.get(i));
// 用第一个 '?' 替换为 #{paramX}
sql = sql.replaceFirst("\\?", "#{param" + (i + 1) + "}");
}
}
return sql;
}
}
... ...
package com.zhonglai.luhui.dao.dto;
import java.util.List;
public class SqlResult {
private String sql;
private List<Object> params;
public String getSql() {
return sql;
}
public void setSql(String sql) {
this.sql = sql;
}
public List<Object> getParams() {
return params;
}
public void setParams(List<Object> params) {
this.params = params;
}
}
... ...
package com.zhonglai.luhui.dao.mapper;
import com.zhonglai.luhui.dao.dto.PublicSQL;
import com.zhonglai.luhui.dao.dto.SqlResult;
import org.apache.ibatis.annotations.*;
import org.springframework.stereotype.Component;
... ... @@ -153,4 +154,7 @@ public interface PublicMapper {
@Options(useGeneratedKeys = false)
@InsertProvider(type = PublicSQL.class, method = "updateBySql")
int insertIntoBySql(@Param("sql") String sql);
@SelectProvider(type = PublicSQL.class, method = "buildSql")
List<Map<String, Object>> getDynamicList(@Param("sqlResult") SqlResult sqlResult);
}
... ...
package com.zhonglai.luhui.dao.service;
import com.zhonglai.luhui.dao.dto.SqlResult;
import java.util.List;
import java.util.Map;
... ... @@ -127,4 +129,6 @@ public interface PublicService {
int insertIntoBySql(String sql);
public Long selectCountBySql(String sql);
public List<Map<String,Object>> getDynamicList(SqlResult sqlResult);
}
... ...
package com.zhonglai.luhui.dao.service.impl;
import com.alibaba.fastjson.JSONObject;
import com.zhonglai.luhui.dao.dto.SqlResult;
import com.zhonglai.luhui.dao.mapper.PublicMapper;
import com.zhonglai.luhui.dao.service.PublicService;
import org.springframework.beans.factory.annotation.Autowired;
... ... @@ -220,4 +221,9 @@ public class PublicServiceImpl implements PublicService {
{
return publicMapper.insertIntoBySql(sql);
}
public List<Map<String,Object>> getDynamicList(SqlResult sqlResult)
{
return publicMapper.getDynamicList(sqlResult);
}
}
... ...
package com.ruoyi.common.utils;
import com.ruoyi.common.utils.html.HttpUtils;
import okhttp3.Response;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.Locale;
import java.util.Map;
public class WpsUtil {
private static final Logger logger = LoggerFactory.getLogger(WpsUtil.class);
private static final String accessKey = "AK123456";
private static final String secretKey = "sk098765";
public static final class Out {
private final String date; // X-Kso-Date
private final String authorization; // X-Kso-Authorization
public Out(String date, String authorization) {
this.date = date;
this.authorization = authorization;
}
public String getDate() {
return date;
}
public String getAuthorization() {
return authorization;
}
}
public static Out kso1Sign(String method, String uri, String contentType, String ksoDate, byte[] requestBody) throws NoSuchAlgorithmException, InvalidKeyException {
String ksoSignature = getKso1Signature(method, uri, contentType, ksoDate, requestBody);
String authorization = String.format("KSO-1 %s:%s", accessKey, ksoSignature);
return new Out(ksoDate, authorization);
}
private static String getKso1Signature(String method, String uri, String contentType, String ksoDate, byte[] requestBody) throws NoSuchAlgorithmException, InvalidKeyException {
String sha256Hex = "";
if (requestBody != null && requestBody.length > 0) {
MessageDigest digest = MessageDigest.getInstance("SHA-256");
byte[] hash = digest.digest(requestBody);
sha256Hex = bytesToHex(hash);
}
System.out.println("sha256: " + sha256Hex);
String dataToSign = "KSO-1" + method + uri + contentType + ksoDate + sha256Hex;
Mac mac = Mac.getInstance("HmacSHA256");
SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getBytes(StandardCharsets.UTF_8), "HmacSHA256");
mac.init(secretKeySpec);
byte[] macBytes = mac.doFinal(dataToSign.getBytes(StandardCharsets.UTF_8));
return bytesToHex(macBytes);
}
private static String bytesToHex(byte[] bytes) {
StringBuilder result = new StringBuilder();
for (byte b : bytes) {
result.append(String.format("%02x", b));
}
return result.toString();
}
public static String getFeishuTable(String authorization, String date, String file_id, Map<String,Object> body)
{
String url = "https://openapi.wps.cn/v7/coop/dbsheet/"+file_id+"/sheets/{sheet_id}/records/search";
try {
Response response = HttpUtils.postJsonBody(url, builder -> {
builder.addHeader("Content-Type", "application/json");
// builder.addHeader("Authorization", "Bearer " + tenant_access_token);
}, jsonObject -> {
if(null != body && body.size() > 0)
{
for(String key : body.keySet())
{
jsonObject.put(key,body.get(key));
}
}
});
String str = response.body().string();
return str;
} catch (IOException e) {
logger.error("查询飞书表数据异常",e);
}
return null;
}
public static void main(String[] args) throws Exception {
final String method = "POST";
final String uri = "/v7/test/body";
final String contentType = "application/json";
final String contentDate = ZonedDateTime.now(ZoneId.of("GMT")).format(DateTimeFormatter
.ofPattern("EEE, dd MMM yyyy HH:mm:ss z", Locale.ENGLISH));
final byte[] requestBody = "{\"key\": \"value\"}".getBytes(StandardCharsets.UTF_8);
Out out = kso1Sign(method, uri, contentType, contentDate, requestBody);
System.out.println(out.getDate());
System.out.println(out.getAuthorization());
}
}
... ...
... ... @@ -6,7 +6,11 @@ import com.google.gson.JsonObject;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.FeishuUtil;
import com.ruoyi.common.utils.GsonConstructor;
import com.ruoyi.system.domain.log.LogExcelSub;
import com.zhonglai.luhui.api.controller.test.dto.ClueData;
import com.zhonglai.luhui.api.controller.test.dto.FindExcelDataDto;
import com.zhonglai.luhui.dao.dto.SqlResult;
import com.zhonglai.luhui.dao.service.PublicService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.batik.transcoder.Transcoder;
... ... @@ -15,6 +19,7 @@ import org.apache.batik.transcoder.TranscoderInput;
import org.apache.batik.transcoder.TranscoderOutput;
import org.apache.batik.transcoder.image.JPEGTranscoder;
import org.apache.batik.transcoder.image.PNGTranscoder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StreamUtils;
import org.springframework.web.bind.annotation.*;
... ... @@ -24,14 +29,14 @@ import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.StringReader;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.*;
@Api(tags = "测试")
@RestController
@RequestMapping("/test")
public class TestController {
@Autowired
private PublicService publicService;
@ApiOperation("账号密码登陆")
@GetMapping("/t1")
public AjaxResult t1()
... ... @@ -109,6 +114,43 @@ public class TestController {
return str;
}
@ApiOperation("新增多维表格数据")
@RequestMapping(value = "addExcelData")
public AjaxResult addExcelData(Integer system_type,String log_id,String excel_id,String sheet_id,@RequestBody String sub_data) throws IOException {
LogExcelSub logExcelSub = new LogExcelSub();
logExcelSub.setExcel_id(excel_id);
logExcelSub.setSheet_id(sheet_id);
logExcelSub.setSub_data(sub_data);
logExcelSub.setSystem_type(system_type);
logExcelSub.setLog_id(log_id);
return AjaxResult.success(publicService.insert(logExcelSub));
}
@ApiOperation("修改多维表格数据")
@RequestMapping(value = "upExcelData")
public AjaxResult upExcelData(Integer system_type,String log_id,String excel_id,String sheet_id,@RequestBody String sub_data) throws IOException {
LogExcelSub logExcelSub = new LogExcelSub();
logExcelSub.setExcel_id(excel_id);
logExcelSub.setSheet_id(sheet_id);
logExcelSub.setSystem_type(system_type);
logExcelSub.setLog_id(log_id);
Long nub = publicService.getObjectListTotle(logExcelSub,null);
logExcelSub.setSub_data(sub_data);
if(0==nub)
{
return AjaxResult.success(publicService.insert(logExcelSub));
}
return AjaxResult.success(publicService.updateObject(logExcelSub,"system_type,excel_id,sheet_id,log_id"));
}
@ApiOperation("查询多维表格数据")
@RequestMapping(value = "findExcelData")
public AjaxResult findExcelData(@RequestBody FindExcelDataDto findExcelDataDto) throws IOException {
List<Map<String,Object>> list =publicService.getDynamicList(buildDynamicSqlSecure(findExcelDataDto.getSelectFields(),findExcelDataDto.getEqualConditions(),findExcelDataDto.getRangeConditions(),findExcelDataDto.getSystemType(),findExcelDataDto.getExcelId(),findExcelDataDto.getSheetId(),findExcelDataDto.getOrderFields(),findExcelDataDto.getOrderDirections()));
return AjaxResult.success(list);
}
@ApiOperation("重写Highcharts导出")
@RequestMapping(value = "getFeishuTable")
public void getFeishuTable(HttpServletRequest request, HttpServletResponse response) throws IOException {
... ... @@ -202,4 +244,113 @@ public class TestController {
FeishuUtil.subFeishuTables(FeishuUtil.gettenant_access_token("cli_a77e560b9475100c","7E80HFwgkmHjngFWDNsz6Pe1aqtKLC3m"),"YY58bkeMjahX5Uskh4WcnYOCnZc","tbldo1VjlU9jY51Y",field);
}
public SqlResult buildDynamicSqlSecure(
List<String> selectFields, // 需要返回的字段
Map<String, Object> equalConditions, // JSON 等值条件
Map<String, Object[]> rangeConditions, // JSON 范围条件 [start, end]
Integer systemType, // system_type
String excel_id,
String sheetId, // sheet_id
List<String> orderFields, // 排序字段
List<String> orderDirections // 排序方向 ASC/DESC
) {
SqlResult result = new SqlResult();
StringBuilder sql = new StringBuilder();
List<Object> params = new ArrayList<>();
sql.append("SELECT id, log_id, ");
// SELECT JSON 字段
for (int i = 0; i < selectFields.size(); i++) {
String field = selectFields.get(i);
sql.append("JSON_UNQUOTE(JSON_EXTRACT(sub_data, '$.\"")
.append(field)
.append("\"')) AS `")
.append(field)
.append("`");
if (i < selectFields.size() - 1) sql.append(", ");
}
sql.append(" FROM log_excel_sub WHERE 1=1 ");
// system_type
if (systemType != null) {
sql.append(" AND system_type = ? ");
params.add(systemType);
}
// sheet_id
if (excel_id != null) {
sql.append(" AND excel_id = ? ");
params.add(excel_id);
}
// sheet_id
if (sheetId != null) {
sql.append(" AND sheet_id = ? ");
params.add(sheetId);
}
// 等值查询
if (equalConditions != null) {
for (Map.Entry<String, Object> entry : equalConditions.entrySet()) {
sql.append(" AND JSON_UNQUOTE(JSON_EXTRACT(sub_data, '$.\"")
.append(entry.getKey())
.append("\"')) = ? ");
params.add(entry.getValue());
}
}
// 范围查询
if (rangeConditions != null) {
for (Map.Entry<String, Object[]> entry : rangeConditions.entrySet()) {
String field = entry.getKey();
Object[] range = entry.getValue();
sql.append(" AND STR_TO_DATE(JSON_UNQUOTE(JSON_EXTRACT(sub_data, '$.\"")
.append(field)
.append("\"')), '%Y/%m/%d %H:%i:%s') ");
if (range[0] != null && range[1] != null) {
sql.append("BETWEEN ? AND ? ");
params.add(range[0]);
params.add(range[1]);
} else if (range[0] != null) {
sql.append(">= ? ");
params.add(range[0]);
} else if (range[1] != null) {
sql.append("<= ? ");
params.add(range[1]);
}
}
}
// 排序
if (orderFields != null && !orderFields.isEmpty()) {
sql.append(" ORDER BY ");
for (int i = 0; i < orderFields.size(); i++) {
String field = orderFields.get(i);
String direction = (orderDirections != null && orderDirections.size() > i)
? orderDirections.get(i)
: "ASC";
sql.append("JSON_UNQUOTE(JSON_EXTRACT(sub_data, '$.\"")
.append(field)
.append("\"')) ")
.append(direction);
if (i < orderFields.size() - 1) {
sql.append(", ");
}
}
}
result.setSql(sql.toString());
result.setParams(params);
return result;
}
}
... ...
package com.zhonglai.luhui.api.controller.test.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.util.List;
import java.util.Map;
@ApiModel("查询多维表格数据参数")
public class FindExcelDataDto {
@ApiModelProperty("需要返回的字段")
private List<String> selectFields; // // 需要返回的字段
@ApiModelProperty("JSON 等值条件")
private Map<String, Object> equalConditions; // // JSON 等值条件
@ApiModelProperty("JSON 范围条件 [start, end]")
private Map<String, Object[]> rangeConditions; // // JSON 范围条件 [start, end]
@ApiModelProperty("系统平台类型")
private Integer systemType; // // system_type
@ApiModelProperty("多维表id")
private String excelId; // // sheet_id
@ApiModelProperty("sheet表id")
private String sheetId; // // sheet_id
@ApiModelProperty("排序字段")
private List<String> orderFields; // // 排序字段
@ApiModelProperty("排序方向 ASC/DESC")
private List<String> orderDirections; // 排序方向 ASC/DESC
public String getExcelId() {
return excelId;
}
public void setExcelId(String excelId) {
this.excelId = excelId;
}
public List<String> getSelectFields() {
return selectFields;
}
public void setSelectFields(List<String> selectFields) {
this.selectFields = selectFields;
}
public Map<String, Object> getEqualConditions() {
return equalConditions;
}
public void setEqualConditions(Map<String, Object> equalConditions) {
this.equalConditions = equalConditions;
}
public Map<String, Object[]> getRangeConditions() {
return rangeConditions;
}
public void setRangeConditions(Map<String, Object[]> rangeConditions) {
this.rangeConditions = rangeConditions;
}
public Integer getSystemType() {
return systemType;
}
public void setSystemType(Integer systemType) {
this.systemType = systemType;
}
public String getSheetId() {
return sheetId;
}
public void setSheetId(String sheetId) {
this.sheetId = sheetId;
}
public List<String> getOrderFields() {
return orderFields;
}
public void setOrderFields(List<String> orderFields) {
this.orderFields = orderFields;
}
public List<String> getOrderDirections() {
return orderDirections;
}
public void setOrderDirections(List<String> orderDirections) {
this.orderDirections = orderDirections;
}
}
... ...