Merge branch 'main' of https://git.jsspisoft.com/ry-das
This commit is contained in:
commit
bfcb771437
@ -20,7 +20,7 @@ if (USE_SQLITE3)
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
set (CMAKE_BUILD_TYPE Release)
|
||||
# set (CMAKE_BUILD_TYPE Release)
|
||||
|
||||
option (USE_32BITS "Build 32Bits application?" OFF)
|
||||
if (USE_32BITS)
|
||||
|
@ -2829,10 +2829,12 @@ void CRYDevice::heart_beat(int status)
|
||||
#endif
|
||||
jsonValue["linkId"] = linkId;
|
||||
jsonValue["online"] = (config.processes[i].real_softdog >= PROCESS_WATCHDOG_TIME) ? false : true;
|
||||
#if 1
|
||||
jsonValue["real"] = (config.processes[i].real_softdog >= PROCESS_WATCHDOG_TIME) ? false : true;
|
||||
if ((config.processes[i].state & 0x20) == 0x20) {
|
||||
jsonValue["ftp"] = (config.processes[i].real_softdog >= PROCESS_WATCHDOG_TIME) ? false : true;
|
||||
}
|
||||
#endif
|
||||
jsonLink.append(jsonValue);
|
||||
}
|
||||
}
|
||||
@ -2853,6 +2855,12 @@ void CRYDevice::heart_beat(int status)
|
||||
#endif
|
||||
jsonValue["deviceId"] = deviceId;
|
||||
jsonValue["online"] = (config.units[i].real_softdog >= UNIT_WATCHDOG_TIME) ? false : true;
|
||||
#if 0
|
||||
jsonValue["real"] = (config.units[i].real_softdog >= UNIT_WATCHDOG_TIME) ? false : true;
|
||||
if ((config.units[i].state & 0x20) == 0x20) {
|
||||
jsonValue["ftp"] = (config.units[i].real_softdog >= UNIT_WATCHDOG_TIME) ? false : true;
|
||||
}
|
||||
#endif
|
||||
jsonDevice.append(jsonValue);
|
||||
}
|
||||
}
|
||||
|
@ -1741,14 +1741,7 @@ void CProcess::Destroy(void)
|
||||
{
|
||||
m_bRunFlag = FALSE;
|
||||
|
||||
char name[16];
|
||||
memset(name, '\0', sizeof(name));
|
||||
if (pthread_getname_np(m_pid, name, sizeof(name)) != 0)
|
||||
{
|
||||
memset(name, '\0', sizeof(name));
|
||||
}
|
||||
|
||||
vLog(LOG_DEBUG, "waiting for protocol thread [%d,%s] destroy.\n", m_nProcess, (name[0] != '\0') ? name : "unknow");
|
||||
vLog(LOG_DEBUG, "waiting for protocol thread [%d,%s] destroy.\n", m_nProcess, config.processes[m_nProcess].name);
|
||||
pthread_join(m_pid, NULL);
|
||||
|
||||
int i = 0;
|
||||
@ -1757,7 +1750,7 @@ void CProcess::Destroy(void)
|
||||
DestroyItem(i, FALSE);
|
||||
}
|
||||
|
||||
vLog(LOG_DEBUG, "current protocol thread [%d,%s] is destroyed.\n", m_nProcess, (name[0] != '\0') ? name : "unknow");
|
||||
vLog(LOG_DEBUG, "current protocol thread [%d,%s] is destroyed.\n", m_nProcess, config.processes[m_nProcess].name);
|
||||
}
|
||||
|
||||
BOOLEAN CProcess::Run(void)
|
||||
|
@ -703,15 +703,10 @@ CHostADSBFProcess::~CHostADSBFProcess()
|
||||
fwrite(&m_currentDirStartFileNo, sizeof(LONG), 1, pf);
|
||||
fclose(pf);
|
||||
}
|
||||
char name[16];
|
||||
memset(name, '\0', sizeof(name));
|
||||
if (pthread_getname_np(m_cpid, name, sizeof(name)) != 0)
|
||||
{
|
||||
memset(name, '\0', sizeof(name));
|
||||
}
|
||||
vLog(LOG_DEBUG, "waiting for child thread [%s] destroy.\n", (name[0] != '\0') ? name : "unknow");
|
||||
|
||||
vLog(LOG_DEBUG, "waiting for child thread [%s] destroy.\n", (m_cpidName[0] != '\0') ? m_cpidName : "unknow");
|
||||
pthread_join(m_cpid, NULL);
|
||||
vLog(LOG_DEBUG, "child protocol thread [%s] is destroyed.\n", (name[0] != '\0') ? name : "unknow");
|
||||
vLog(LOG_DEBUG, "child protocol thread [%s] is destroyed.\n", (m_cpidName[0] != '\0') ? m_cpidName : "unknow");
|
||||
}
|
||||
}
|
||||
|
||||
@ -748,6 +743,7 @@ BOOLEAN CHostADSBFProcess::calc(void)
|
||||
pData = GetUnitYCParamByPoint(uid, n);
|
||||
if (pData[4] == 1) continue;
|
||||
registerAddr = MAKEWORD(pData[0], pData[1]);
|
||||
if (registerAddr <= 0) continue;
|
||||
if (registerAddr < DATA_BLOCK_BOUNDARY)
|
||||
{
|
||||
if (!m_adsDatas[0].inuse) m_adsDatas[0].inuse = TRUE;
|
||||
@ -775,6 +771,7 @@ BOOLEAN CHostADSBFProcess::calc(void)
|
||||
pData = GetUnitYMParamByPoint(uid, n);
|
||||
if (pData[4] == 1) continue;
|
||||
registerAddr = MAKEWORD(pData[0], pData[1]);
|
||||
if (registerAddr <= 0) continue;
|
||||
if (registerAddr < DATA_BLOCK_BOUNDARY)
|
||||
{
|
||||
if (!m_adsDatas[0].inuse) m_adsDatas[0].inuse = TRUE;
|
||||
@ -802,6 +799,7 @@ BOOLEAN CHostADSBFProcess::calc(void)
|
||||
pData = GetUnitYXParamByPoint(uid, n);
|
||||
if (pData[4] == 1) continue;
|
||||
registerAddr = MAKEWORD(pData[0], pData[1]);
|
||||
if (registerAddr <= 0) continue;
|
||||
value_type = pData[2];
|
||||
if (registerAddr < DATA_BLOCK_BOUNDARY)
|
||||
{
|
||||
@ -857,14 +855,17 @@ BOOLEAN CHostADSBFProcess::OnPreCreate(int id)
|
||||
//需要给单元添加一个是否有ftp数据的标识
|
||||
|
||||
int uid = GetCurUnitID();
|
||||
if (uid < 0 || uid >= UNIT_NUM) return FALSE;
|
||||
//if (uid < 0 || uid >= UNIT_NUM) return FALSE;
|
||||
if (m_bHaveFTP) {
|
||||
config.units[uid].state |= 0x20; //存在ftp标识
|
||||
if (uid >= 0 && uid < UNIT_NUM)
|
||||
{
|
||||
config.units[uid].state |= 0x20; //存在ftp标识
|
||||
}
|
||||
config.processes[id].state |= 0x20;
|
||||
}
|
||||
calc();
|
||||
|
||||
//vLog(LOG_DEBUG, "%s local ip is: %s, netid is: %s, remote ip is: %s, and netid is: %s\n", m_pidName.c_str(), m_localIp.c_str(), m_localNetId.c_str(), m_remoteIp.c_str(), m_remoteNetId.c_str());
|
||||
vLog(LOG_DEBUG, "%s local ip is: %s, netid is: %s, remote ip is: %s, and netid is: %s\n", m_pidName.c_str(), m_localIp.c_str(), m_localNetId.c_str(), m_remoteIp.c_str(), m_remoteNetId.c_str());
|
||||
|
||||
m_turbine = NULL;
|
||||
m_bRouteAdded = FALSE;
|
||||
@ -911,9 +912,8 @@ BOOLEAN CHostADSBFProcess::OnPreCreate(int id)
|
||||
vLog(LOG_ERROR, "ads create ryftp_process error(%d,%s).\n", errno, strerror(errno));
|
||||
return TRUE;
|
||||
}
|
||||
char name[17];
|
||||
snprintf(name, 16, "%s_ftp", m_pidName.c_str());
|
||||
pthread_setname_np(m_cpid, name);
|
||||
snprintf(m_cpidName, 16, "%s_ftp", m_pidName.c_str());
|
||||
pthread_setname_np(m_cpid, m_cpidName);
|
||||
|
||||
pthread_attr_destroy(&attr);
|
||||
}
|
||||
@ -1027,10 +1027,11 @@ BOOLEAN CHostADSBFProcess::readFileID()
|
||||
AdsVariable <DWORD> wFirstFileNoRecoverable {*m_turbine, ".gwFirstFileNoRecoverable"};
|
||||
//vLog(LOG_DEBUG, "Read back with first value %d\n", (DWORD)wFirstFileNoRecoverable);
|
||||
#else
|
||||
WORD wPathInfoInvalid;
|
||||
WORD wPathInfoInvalid = 1;
|
||||
myAdsVariable myPathInfoInvalid {*m_turbine, ".gwPathInfoInvalid"};
|
||||
if (!myPathInfoInvalid.Read(2, &wPathInfoInvalid))
|
||||
{
|
||||
vLog(LOG_ERROR, "Read .gwPathInfoInvalid error.\n");
|
||||
m_bRouteAdded = FALSE;
|
||||
delete m_turbine;
|
||||
m_turbine = NULL;
|
||||
@ -1104,10 +1105,10 @@ BOOLEAN CHostADSBFProcess::readFileID()
|
||||
}
|
||||
#endif
|
||||
|
||||
m_iv = (WORD)wPathInfoInvalid;
|
||||
if (m_iv) {
|
||||
m_iv = (int)wPathInfoInvalid;
|
||||
if (m_iv == 1) {
|
||||
vLog(LOG_DEBUG, "路径信息无效\n");
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
//当前文件夹路径名
|
||||
m_currentDirNo = (DWORD)wCurrentFolderNo;
|
||||
|
@ -33,6 +33,9 @@ struct myAdsVariable {
|
||||
{
|
||||
if (!m_Route.IsConnected()) return FALSE;
|
||||
uint32_t bytesRead = 0;
|
||||
if (*m_Handle.get() == 0xffffffff) {
|
||||
return TRUE;
|
||||
}
|
||||
auto error = m_Route.ReadReqEx2(m_IndexGroup,
|
||||
*m_Handle,
|
||||
size,
|
||||
@ -103,8 +106,8 @@ private:
|
||||
|
||||
public:
|
||||
std::string m_pidName;
|
||||
|
||||
BOOLEAN m_bHaveFTP; //存在FTP协议
|
||||
char m_cpidName[16];
|
||||
|
||||
//ftp参数信息
|
||||
char m_user[64];
|
||||
|
@ -794,9 +794,9 @@ CHostModbusTcpBFProcess::~CHostModbusTcpBFProcess()
|
||||
{
|
||||
memset(name, '\0', sizeof(name));
|
||||
}
|
||||
vLog(LOG_DEBUG, "waiting for child thread [%s] destroy.\n", (name[0] != '\0') ? name : "unknow");
|
||||
vLog(LOG_DEBUG, "waiting for child thread [%s] destroy.\n", (m_cpidName[0] != '\0') ? m_cpidName : "unknow");
|
||||
pthread_join(m_cpid, NULL);
|
||||
vLog(LOG_DEBUG, "child protocol thread [%s] is destroyed.\n", (name[0] != '\0') ? name : "unknow");
|
||||
vLog(LOG_DEBUG, "child protocol thread [%s] is destroyed.\n", (m_cpidName[0] != '\0') ? m_cpidName : "unknow");
|
||||
}
|
||||
}
|
||||
|
||||
@ -1175,13 +1175,13 @@ BOOLEAN CHostModbusTcpBFProcess::OnPreCreate(int id)
|
||||
pthread_attr_setstacksize(&attr, MEMERY_1M);
|
||||
pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
|
||||
|
||||
if (pthread_create(&m_cpid, &attr, ryftp_process, this) < 0) {
|
||||
if (pthread_create(&m_cpid, &attr, ryftp_process, this) < 0)
|
||||
{
|
||||
vLog(LOG_ERROR, "rymodbus create ryftp_process error(%d,%s).\n", errno, strerror(errno));
|
||||
return TRUE;
|
||||
}
|
||||
char name[17];
|
||||
snprintf(name, 16, "%s_ftp", m_pidName.c_str());
|
||||
pthread_setname_np(m_cpid, name);
|
||||
snprintf(m_cpidName, 16, "%s_ftp", m_pidName.c_str());
|
||||
pthread_setname_np(m_cpid, m_cpidName);
|
||||
|
||||
pthread_attr_destroy(&attr);
|
||||
}
|
||||
|
@ -65,6 +65,7 @@ private:
|
||||
public:
|
||||
std::string m_pidName;
|
||||
BOOLEAN m_bHaveFTP; //存在FTP协议
|
||||
char m_cpidName[16];
|
||||
|
||||
//ftp参数信息
|
||||
char m_user[64];
|
||||
|
19
das-dn/third_party/AdsLib/AdsDevice.cpp
vendored
19
das-dn/third_party/AdsLib/AdsDevice.cpp
vendored
@ -108,7 +108,7 @@ AdsHandle AdsDevice::GetHandle(const uint32_t offset) const
|
||||
|
||||
AdsHandle AdsDevice::GetHandle(const std::string& symbolName) const
|
||||
{
|
||||
if(m_Connected == true)
|
||||
if (m_Connected == true)
|
||||
{
|
||||
uint32_t handle = 0;
|
||||
uint32_t bytesRead = 0;
|
||||
@ -121,9 +121,12 @@ AdsHandle AdsDevice::GetHandle(const std::string& symbolName) const
|
||||
);
|
||||
|
||||
if (error || (sizeof(handle) != bytesRead)) {
|
||||
LOG_ERROR("AdsDevice GetSymbolHandle is failed: "<<symbolName<<".");
|
||||
LOG_ERROR("AdsDevice GetSymbolHandle is failed: " << symbolName << ".");
|
||||
//throw AdsException(error);
|
||||
}else{
|
||||
return {new uint32_t {0xffffffff}, {[](uint32_t){ return 0; }}};
|
||||
}
|
||||
else
|
||||
{
|
||||
handle = Beckhoff::letoh(handle);
|
||||
return {new uint32_t {handle}, {std::bind(&AdsDevice::DeleteSymbolHandle, this, std::placeholders::_1)}};
|
||||
}
|
||||
@ -137,7 +140,8 @@ AdsHandle AdsDevice::GetHandle(const uint32_t indexGroup,
|
||||
PAdsNotificationFuncEx callback,
|
||||
const uint32_t hUser) const
|
||||
{
|
||||
if(m_Connected == true){
|
||||
if (m_Connected == true)
|
||||
{
|
||||
uint32_t handle = 0;
|
||||
auto error = AdsSyncAddDeviceNotificationReqEx(
|
||||
*m_LocalPort, &m_Addr,
|
||||
@ -146,10 +150,13 @@ AdsHandle AdsDevice::GetHandle(const uint32_t indexGroup,
|
||||
callback,
|
||||
hUser,
|
||||
&handle);
|
||||
if (error || !handle) {
|
||||
if (error || !handle)
|
||||
{
|
||||
LOG_WARN("AdsDevice GetNotificationHandle is failed.");
|
||||
//throw AdsException(error);
|
||||
}else{
|
||||
}
|
||||
else
|
||||
{
|
||||
handle = Beckhoff::letoh(handle);
|
||||
return {new uint32_t {handle}, {std::bind(&AdsDevice::DeleteNotificationHandle, this, std::placeholders::_1)}};
|
||||
}
|
||||
|
@ -32,7 +32,6 @@
|
||||
<disruptor.version>3.4.4</disruptor.version>
|
||||
<aviator.version>5.4.3</aviator.version>
|
||||
<minio.version>8.4.3</minio.version>
|
||||
<jfreechart.version>1.5.3</jfreechart.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
@ -217,11 +216,6 @@
|
||||
<artifactId>minio</artifactId>
|
||||
<version>${minio.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jfree</groupId>
|
||||
<artifactId>jfreechart</artifactId>
|
||||
<version>${jfreechart.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
@ -1,5 +1,6 @@
|
||||
package com.das.modules.cache.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@ -10,6 +11,8 @@ public class IotFieldInfoCache {
|
||||
private Integer porder;
|
||||
private Integer highspeed;
|
||||
private String datatype;
|
||||
private Integer level;
|
||||
private String stateDesc;
|
||||
|
||||
public boolean isHighSpeed() {
|
||||
return highspeed.equals(1) && attributeType.equals(138);
|
||||
|
@ -1,7 +1,16 @@
|
||||
package com.das.modules.cache.service;
|
||||
|
||||
import com.das.modules.cache.domain.IotFieldInfoCache;
|
||||
import com.das.modules.equipment.entity.SysIotModel;
|
||||
import com.das.modules.equipment.entity.SysIotModelField;
|
||||
|
||||
public interface IotModelCache {
|
||||
public boolean isHighSpeed(Long modelId, String attr);
|
||||
public boolean isLowSpeed(Long modelId, String attr);
|
||||
public boolean isCalculate(Long modelId, String attr);
|
||||
void refreshIotFieldCache(SysIotModelField sysIotModelField);
|
||||
void removeIotFieldCache(Long modelId, String attributeCode);
|
||||
void refreshIotModelInfoIdMap(SysIotModel sysIotModel);
|
||||
void removeIotModelInfoIdMap(Long modelId);
|
||||
IotFieldInfoCache getIotFiledCache(Long modelId,String attr);
|
||||
}
|
||||
|
@ -3,6 +3,8 @@ package com.das.modules.cache.service.impl;
|
||||
import com.das.modules.cache.domain.IotFieldInfoCache;
|
||||
import com.das.modules.cache.domain.IotModelInfoCache;
|
||||
import com.das.modules.cache.service.IotModelCache;
|
||||
import com.das.modules.equipment.entity.SysIotModel;
|
||||
import com.das.modules.equipment.entity.SysIotModelField;
|
||||
import com.das.modules.equipment.mapper.SysIotModelMapper;
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import jakarta.annotation.PreDestroy;
|
||||
@ -38,6 +40,8 @@ public class IotModelCacheImpl implements IotModelCache {
|
||||
fieldInfoCache.setAttributeType(item.getAttributeType());
|
||||
fieldInfoCache.setHighspeed(item.getHighSpeed());
|
||||
fieldInfoCache.setDatatype(item.getDataType());
|
||||
fieldInfoCache.setLevel(item.getLevel());
|
||||
fieldInfoCache.setStateDesc(item.getStateDesc());
|
||||
iotFieldsMap.put(String.format("%d_%s", k, item.getAttributeCode()), fieldInfoCache);
|
||||
});
|
||||
});
|
||||
@ -75,4 +79,42 @@ public class IotModelCacheImpl implements IotModelCache {
|
||||
}
|
||||
return fieldInfoCache.isCalculate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refreshIotFieldCache(SysIotModelField sysIotModelField) {
|
||||
IotFieldInfoCache fieldInfoCache = new IotFieldInfoCache();
|
||||
fieldInfoCache.setAttributeCode(sysIotModelField.getAttributeCode());
|
||||
fieldInfoCache.setPorder(sysIotModelField.getPorder());
|
||||
fieldInfoCache.setAttributeName(sysIotModelField.getAttributeName());
|
||||
fieldInfoCache.setAttributeType(sysIotModelField.getAttributeType());
|
||||
fieldInfoCache.setHighspeed(sysIotModelField.getHighSpeed());
|
||||
fieldInfoCache.setDatatype(sysIotModelField.getDataType());
|
||||
fieldInfoCache.setLevel(sysIotModelField.getLevel());
|
||||
fieldInfoCache.setStateDesc(sysIotModelField.getStateDesc());
|
||||
iotFieldsMap.put(String.format("%d_%s", sysIotModelField.getIotModelId(), sysIotModelField.getAttributeCode()), fieldInfoCache);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeIotFieldCache(Long modelId, String attributeCode){
|
||||
iotFieldsMap.remove(String.format("%d_%s", modelId, attributeCode));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void refreshIotModelInfoIdMap(SysIotModel sysIotModel){
|
||||
IotModelInfoCache info = new IotModelInfoCache();
|
||||
info.setIotModelId(sysIotModel.getId());
|
||||
info.setIodModelCode(sysIotModel.getIotModelCode());
|
||||
iotModelInfoIdMap.put(sysIotModel.getId(), info);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeIotModelInfoIdMap(Long modelId) {
|
||||
iotModelInfoIdMap.remove(modelId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IotFieldInfoCache getIotFiledCache(Long modelId, String attr) {
|
||||
return iotFieldsMap.get(String.format("%d_%s", modelId, attr));
|
||||
}
|
||||
}
|
||||
|
@ -67,6 +67,9 @@ public class TDEngineService {
|
||||
}
|
||||
}
|
||||
|
||||
public HikariDataSource getHikariDataSource(){
|
||||
return hikariDataSource;
|
||||
}
|
||||
/**
|
||||
* 创建超级表
|
||||
*/
|
||||
|
@ -25,6 +25,7 @@ import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.StopWatch;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.Function;
|
||||
|
@ -0,0 +1,122 @@
|
||||
package com.das.modules.data.service.impl;
|
||||
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.core.util.ZipUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.das.modules.data.service.TDEngineService;
|
||||
import com.das.modules.equipment.entity.SysEquipment;
|
||||
import com.das.modules.equipment.mapper.SysEquipmentMapper;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.StopWatch;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.sql.*;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
public class ExportTdDataServiceImpl {
|
||||
|
||||
@Autowired
|
||||
SysEquipmentMapper sysEquipmentMapper;
|
||||
|
||||
@Autowired
|
||||
private TDEngineService tdEngineService;
|
||||
|
||||
@Value("${zipUrl}")
|
||||
private String fileUrl;
|
||||
|
||||
|
||||
public void exportDataCsvZip() throws IOException, SQLException {
|
||||
StopWatch stopWatch = new StopWatch();
|
||||
stopWatch.start("导出风机数据zip");
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.add(Calendar.DAY_OF_MONTH, -1);
|
||||
String yesterday = new SimpleDateFormat("yyyy-MM-dd").format(calendar.getTime());
|
||||
|
||||
//获取所有风机数据
|
||||
QueryWrapper<SysEquipment> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("object_type", 10002);
|
||||
List<SysEquipment> sysEquipments = sysEquipmentMapper.selectList(queryWrapper);
|
||||
//获取临时目录文件路径
|
||||
String tempDir = String.valueOf(Files.createTempDirectory(null));
|
||||
File zipFile = new File(fileUrl + "/data_"+yesterday+".zip");
|
||||
List<File> fileList = new ArrayList<>();
|
||||
try {
|
||||
for (SysEquipment item : sysEquipments) {
|
||||
|
||||
String hTableName = "h" + item.getId();
|
||||
String lTableName = "l" + item.getId();
|
||||
File fileHighSpeed = new File(tempDir +"/" + "h_"+item.getCode()+"_"+yesterday + ".csv");
|
||||
File fileLowSpeed = new File(tempDir +"/" + "l_"+item.getCode()+"_"+yesterday + ".csv");
|
||||
getYesterdayData(hTableName, yesterday, fileHighSpeed.getPath());
|
||||
getYesterdayData(lTableName, yesterday, fileLowSpeed.getPath());
|
||||
fileList.add(fileLowSpeed);
|
||||
fileList.add(fileHighSpeed);
|
||||
}
|
||||
//压缩文件
|
||||
// 将文件添加到压缩文件中
|
||||
ZipUtil.zip(zipFile, false, fileList.toArray(new File[0]));
|
||||
stopWatch.stop();
|
||||
log.debug(stopWatch.prettyPrint(TimeUnit.SECONDS));
|
||||
}catch (Exception e){
|
||||
log.error("导出风机数据zip失败{}",e);
|
||||
}
|
||||
finally {
|
||||
if (!CollectionUtils.isEmpty(fileList)){
|
||||
FileUtil.del(new File(fileList.get(0).getParent()));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void getYesterdayData(String tableName, String time, String csvFilePath) {
|
||||
// TDengine 查询语句
|
||||
String query = "SELECT * FROM " + tableName + " WHERE updatetime >= '" + time + " 00:00:00' AND updatetime < '" + time + " 23:59:59.999'";
|
||||
try (Connection conn = tdEngineService.getHikariDataSource().getConnection();
|
||||
Statement smt = conn.createStatement();
|
||||
ResultSet rs = smt.executeQuery(query)) {
|
||||
writeResultSetToCsv(rs, csvFilePath);
|
||||
}catch (Exception e){
|
||||
log.error(tableName +"获取数据异常{}",e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void writeResultSetToCsv(ResultSet resultSet, String csvFilePath) throws IOException, SQLException {
|
||||
try (BufferedWriter writer = new BufferedWriter(new FileWriter(csvFilePath))) {
|
||||
// 写入列名
|
||||
ResultSetMetaData metaData = resultSet.getMetaData();
|
||||
int columnCount = metaData.getColumnCount();
|
||||
for (int i = 1; i <= columnCount; i++) {
|
||||
writer.write(metaData.getColumnName(i));
|
||||
if (i < columnCount) writer.write(",");
|
||||
}
|
||||
writer.newLine();
|
||||
|
||||
// 写入数据
|
||||
while (resultSet.next()) {
|
||||
for (int i = 1; i <= columnCount; i++) {
|
||||
String value = resultSet.getString(i);
|
||||
writer.write(value == null ? "" : resultSet.getString(i));
|
||||
if (i < columnCount) writer.write(",");
|
||||
}
|
||||
writer.newLine();
|
||||
}
|
||||
}catch (Exception e){
|
||||
log.error("数据写入csv文件失败{}",e);
|
||||
}
|
||||
}
|
||||
}
|
@ -10,6 +10,7 @@ import com.das.common.config.SessionUtil;
|
||||
import com.das.common.exceptions.ServiceException;
|
||||
import com.das.common.utils.*;
|
||||
import com.das.modules.auth.domain.vo.SysUserVo;
|
||||
import com.das.modules.cache.service.CacheService;
|
||||
import com.das.modules.data.service.impl.DataServiceImpl;
|
||||
import com.das.modules.equipment.domain.dto.SysIotModelDto;
|
||||
import com.das.modules.equipment.domain.dto.SysIotModelFieldDto;
|
||||
@ -65,6 +66,9 @@ public class SysIotModelServiceImpl implements SysIotModelService {
|
||||
@Autowired
|
||||
SysRecordLogService sysRecordLogService;
|
||||
|
||||
@Autowired
|
||||
CacheService cacheService;
|
||||
|
||||
public SysIotModelVo creatSysIotModel(SysIotModelDto sysIotModelDto) {
|
||||
SysIotModel sysIotModel = new SysIotModel();
|
||||
BeanCopyUtils.copy(sysIotModelDto, sysIotModel);
|
||||
@ -81,7 +85,9 @@ public class SysIotModelServiceImpl implements SysIotModelService {
|
||||
|
||||
sysIotModel.setRevision(1);
|
||||
sysIotModelMapper.insert(sysIotModel);
|
||||
//刷新缓存
|
||||
addModelCache(sysIotModel);
|
||||
cacheService.getIotModelCache().refreshIotModelInfoIdMap(sysIotModel);
|
||||
SysIotModelVo sysIotModelVo = new SysIotModelVo();
|
||||
BeanCopyUtils.copy(sysIotModel, sysIotModelVo);
|
||||
sysIotModelVo.setIotModelCode(sysIotModelDto.getIotModelCode());
|
||||
@ -119,6 +125,8 @@ public class SysIotModelServiceImpl implements SysIotModelService {
|
||||
throw new RuntimeException("该物模型下面有类型,不能删除");
|
||||
}
|
||||
sysIotModelMapper.deleteById(sysIotModelDto.getId());
|
||||
//刷新缓存
|
||||
cacheService.getIotModelCache().removeIotModelInfoIdMap(sysIotModelDto.getId());
|
||||
deleteModelCache(sysIotModelDto.getId());
|
||||
|
||||
}
|
||||
@ -184,6 +192,7 @@ public class SysIotModelServiceImpl implements SysIotModelService {
|
||||
|
||||
sysIotModelFieldMapper.insert(sysIotModelField);
|
||||
//新增物模型属性缓存
|
||||
cacheService.getIotModelCache().refreshIotFieldCache(sysIotModelField);
|
||||
addModelFieldCache(sysIotModelField);
|
||||
SysIotModelFieldVo sysIotModelFieldVo = new SysIotModelFieldVo();
|
||||
BeanCopyUtils.copy(sysIotModelField, sysIotModelFieldVo);
|
||||
@ -216,6 +225,7 @@ public class SysIotModelServiceImpl implements SysIotModelService {
|
||||
if (!oldSysIotField.getAttributeCode().equals(sysIotModelField.getAttributeCode()) || !oldSysIotField.getDataType().equals(sysIotModelField.getDataType()) || Objects.equals(oldSysIotField.getHighSpeed(), sysIotModelField.getHighSpeed())) {
|
||||
//更新td表结构
|
||||
updateTDStableOrColumn(sysIotModelField, oldSysIotField);
|
||||
cacheService.getIotModelCache().refreshIotFieldCache(sysIotModelField);
|
||||
updateModelFieldCache(sysIotModelField, oldSysIotField);
|
||||
}
|
||||
sysIotModelFieldMapper.updateById(sysIotModelField);
|
||||
@ -232,6 +242,7 @@ public class SysIotModelServiceImpl implements SysIotModelService {
|
||||
|
||||
sysIotModelFieldMapper.deleteById(sysIotModelFieldDto.getId());
|
||||
//删除物模型属性缓存
|
||||
cacheService.getIotModelCache().removeIotFieldCache(sysIotModelField.getIotModelId(), sysIotModelField.getAttributeCode());
|
||||
deleteModelFieldCache(sysIotModelField);
|
||||
}
|
||||
|
||||
@ -488,6 +499,10 @@ public class SysIotModelServiceImpl implements SysIotModelService {
|
||||
}
|
||||
//新增pg数据库
|
||||
sysIotModelFieldMapper.insertBatch(sysIotModelFieldList);
|
||||
//刷新缓存
|
||||
for (SysIotModelField item : sysIotModelFieldList){
|
||||
cacheService.getIotModelCache().refreshIotFieldCache(item);
|
||||
}
|
||||
}
|
||||
if (CollectionUtils.isNotEmpty(updateSysIotModelFieldList)) {
|
||||
for (SysIotModelField item : updateSysIotModelFieldList) {
|
||||
@ -496,6 +511,7 @@ public class SysIotModelServiceImpl implements SysIotModelService {
|
||||
if (!oldSysIotField.getAttributeCode().equals(item.getAttributeCode()) && oldSysIotField.getDataType().equals(item.getDataType()) && Objects.equals(oldSysIotField.getHighSpeed(), item.getHighSpeed())) {
|
||||
//更新td表结构
|
||||
updateTDStableOrColumn(item, oldSysIotField);
|
||||
cacheService.getIotModelCache().refreshIotFieldCache(item);
|
||||
updateModelFieldCache(item, oldSysIotField);
|
||||
}
|
||||
}
|
||||
@ -509,6 +525,7 @@ public class SysIotModelServiceImpl implements SysIotModelService {
|
||||
for (SysIotModelField item : delSysIotModelFieldList) {
|
||||
deleteTDStableOrColumn(item);
|
||||
sysIotModelFieldMapper.deleteById(item);
|
||||
cacheService.getIotModelCache().removeIotFieldCache(item.getIotModelId(), item.getAttributeCode());
|
||||
deleteModelFieldCache(item);
|
||||
}
|
||||
}
|
||||
|
@ -1,17 +1,17 @@
|
||||
package com.das.modules.node.command;
|
||||
|
||||
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
|
||||
import com.das.common.exceptions.ServiceException;
|
||||
import com.das.common.utils.AdminRedisTemplate;
|
||||
import com.das.common.utils.StringUtils;
|
||||
import com.das.modules.cache.domain.DeviceInfoCache;
|
||||
import com.das.modules.cache.domain.IotFieldInfoCache;
|
||||
import com.das.modules.cache.service.CacheService;
|
||||
import com.das.modules.data.domain.DeviceEventInfo;
|
||||
import com.das.modules.data.service.TDEngineService;
|
||||
import com.das.modules.data.service.impl.DataServiceImpl;
|
||||
import com.das.modules.node.constant.NodeConstant;
|
||||
import com.das.modules.node.domain.bo.TerminalMessage;
|
||||
import com.das.modules.node.domain.vo.DeviceEventVo;
|
||||
import com.das.modules.node.service.NodeMessageService;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
@ -29,9 +29,6 @@ public class DeviceEventCommand implements BaseCommand{
|
||||
@Autowired
|
||||
AdminRedisTemplate adminRedisTemplate;
|
||||
|
||||
@Autowired
|
||||
private DataServiceImpl dataService;
|
||||
|
||||
@Autowired
|
||||
TDEngineService tdEngineService;
|
||||
|
||||
@ -72,18 +69,20 @@ public class DeviceEventCommand implements BaseCommand{
|
||||
deviceEventInfo.setDeviceCode(deviceInfoCache.getDeviceCode());
|
||||
deviceEventInfo.setFirstTriggeredCode(firstTriggeredCode);
|
||||
String eventType = getEventType(item.getEventType());
|
||||
String model = dataService.deviceModelMap.get(item.getDeviceId());
|
||||
if (StringUtils.isEmpty(model)) {
|
||||
Long iotModelId = deviceInfoCache.getIotModelId();
|
||||
if (iotModelId == null) {
|
||||
log.debug("未查询到物模型code,设备id:{}", item.getDeviceId());
|
||||
}
|
||||
String fieldName = dataService.fieldCodeNameMap.get(model).get(item.getAttrCode());
|
||||
if (StringUtils.isEmpty(fieldName)) {
|
||||
log.debug("未查询到物模型属性code,设备id:{}", item.getDeviceId());
|
||||
IotFieldInfoCache iotFiledCache = cacheService.getIotModelCache().getIotFiledCache(iotModelId, item.getAttrCode());
|
||||
if (iotFiledCache == null) {
|
||||
log.debug("未查询到物模型属性,设备id:{},属性AttrCode:{}", item.getDeviceId(),item.getAttrCode());
|
||||
throw new ServiceException("未查询到物模型属性,设备id:"+item.getDeviceId()+",属性AttrCode:"+item.getAttrCode());
|
||||
}
|
||||
String fieldName = iotFiledCache.getAttributeName();
|
||||
deviceEventInfo.setEventType(item.getEventType());
|
||||
deviceEventInfo.setConfirmed(0);
|
||||
if (!StringUtils.isEmpty(eventType) && eventType.equals("遥信变位")) {
|
||||
String stateDesc = dataService.stateDescMap.get(model).get(item.getAttrCode());
|
||||
String stateDesc = iotFiledCache.getStateDesc();
|
||||
if (item.getAttrValue().equals(0)) {
|
||||
deviceEventInfo.setEventText(item.getAttrCode() + fieldName + " 复归");
|
||||
if (StringUtils.isNotEmpty(stateDesc)) {
|
||||
@ -97,7 +96,7 @@ public class DeviceEventCommand implements BaseCommand{
|
||||
List<String> descList = Arrays.stream(stateDesc.split("\\|")).toList();
|
||||
deviceEventInfo.setEventText(item.getAttrCode() + fieldName + descList.get(1));
|
||||
}
|
||||
Integer level = dataService.eventLevelMap.get(model).get(item.getAttrCode());
|
||||
Integer level = iotFiledCache.getLevel();
|
||||
log.debug("level:{}", level);
|
||||
log.debug("fieldname{}", fieldName);
|
||||
deviceEventInfo.setEventLevel(level == null ? 0 : level);
|
||||
|
@ -28,35 +28,18 @@ import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.poi.ss.usermodel.ClientAnchor;
|
||||
import org.apache.poi.ss.usermodel.HorizontalAlignment;
|
||||
import org.apache.poi.ss.usermodel.VerticalAlignment;
|
||||
import org.apache.poi.ss.usermodel.Workbook;
|
||||
import org.apache.poi.ss.util.CellRangeAddress;
|
||||
import org.apache.poi.xddf.usermodel.chart.*;
|
||||
import org.apache.poi.xssf.usermodel.XSSFChart;
|
||||
import org.apache.poi.xssf.usermodel.XSSFClientAnchor;
|
||||
import org.apache.poi.xssf.usermodel.XSSFDrawing;
|
||||
import org.apache.poi.xssf.usermodel.XSSFSheet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jfree.chart.ChartFactory;
|
||||
import org.jfree.chart.ChartUtils;
|
||||
import org.jfree.chart.JFreeChart;
|
||||
import org.jfree.chart.axis.CategoryAxis;
|
||||
import org.jfree.chart.axis.CategoryLabelPositions;
|
||||
import org.jfree.chart.plot.CategoryPlot;
|
||||
import org.jfree.chart.plot.PlotOrientation;
|
||||
import org.jfree.chart.renderer.category.CategoryItemRenderer;
|
||||
import org.jfree.chart.title.LegendTitle;
|
||||
import org.jfree.chart.title.TextTitle;
|
||||
import org.jfree.data.category.DefaultCategoryDataset;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.awt.*;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.IntStream;
|
||||
@ -105,13 +88,9 @@ public class StatisticalAnalysisServiceImpl implements StatisticalAnalysisServic
|
||||
List<Map<String, Object>> dataList = new ArrayList<>();
|
||||
// 遍历数据,填充Excel数据集
|
||||
setTrendAnalyseExcelValue(mapsList, dataList);
|
||||
//获取图表类别集
|
||||
List<String> chartKey = getCharKey(map);
|
||||
ExcelWriter writer = ExcelUtil.getWriter(RandomUtil.randomInt(100, 1000) + "statistics" + ".xlsx");
|
||||
//设置Excel样式
|
||||
setExcelStyle(writer, map, dataList);
|
||||
//生成折线图
|
||||
addChartToExcel(writer,dataList,StatisticalAnalysisConstant.TREND_ANALYSE,chartKey);
|
||||
//下载Excel
|
||||
downloadExcel(response, writer,StatisticalAnalysisConstant.TREND_ANALYSE);
|
||||
}
|
||||
@ -150,18 +129,9 @@ public class StatisticalAnalysisServiceImpl implements StatisticalAnalysisServic
|
||||
setPowerCurveExcelValue(resultMap, dataList, curveItemEntitieList);
|
||||
//获取功率曲线的列
|
||||
LinkedHashMap<String, String> map = getPowerCurveColumnName(param);
|
||||
//获取图表类别集
|
||||
List<String> chartKey = getCharKey(map);
|
||||
ExcelWriter writer = ExcelUtil.getWriter(RandomUtil.randomInt(100, 1000) + "statistics" + ".xlsx");
|
||||
//设置Excel样式
|
||||
setExcelStyle(writer, map, dataList);
|
||||
//生成折线图
|
||||
if (param.getDisplayCurve()==1){
|
||||
addChartToExcel(writer,dataList,StatisticalAnalysisConstant.POWER_CURVE,chartKey);
|
||||
}else {
|
||||
//生成散点图
|
||||
addScattersChartToExcel(writer,dataList,StatisticalAnalysisConstant.POWER_CURVE,chartKey);
|
||||
}
|
||||
//下载Excel
|
||||
downloadExcel(response, writer,StatisticalAnalysisConstant.POWER_CURVE);
|
||||
}
|
||||
@ -191,15 +161,11 @@ public class StatisticalAnalysisServiceImpl implements StatisticalAnalysisServic
|
||||
//自定义别名 别名的key和实体类中的名称要对应上!
|
||||
LinkedHashMap<String, String> map = gettrendContrastColumnName(param);
|
||||
List<Map<String, Object>> dataList = new ArrayList<>();
|
||||
//图表类别集
|
||||
List<String> charKey = getCharKey(map);
|
||||
// 遍历数据,将数据添加到dataList中
|
||||
setTrendContrastExcelValue(maps, dataList);
|
||||
ExcelWriter writer = ExcelUtil.getWriter(RandomUtil.randomInt(100, 1000) + "statistics" + ".xlsx");
|
||||
//设置Excel样式
|
||||
setExcelStyle(writer, map, dataList);
|
||||
//生成折线图
|
||||
addChartToExcel(writer,dataList,StatisticalAnalysisConstant.TREND_CONTRAST,charKey);
|
||||
//下载Excel
|
||||
downloadExcel(response, writer,StatisticalAnalysisConstant.TREND_CONTRAST);
|
||||
}
|
||||
@ -284,22 +250,7 @@ public class StatisticalAnalysisServiceImpl implements StatisticalAnalysisServic
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取图表类别集
|
||||
* @param map Excel的列
|
||||
* @return 图表类别集
|
||||
*/
|
||||
private List<String> getCharKey(LinkedHashMap<String, String> map) {
|
||||
//获取图表类别集
|
||||
List<String> chartKey = new ArrayList<>();
|
||||
for (Map.Entry<String, String> stringStringEntry : map.entrySet()) {
|
||||
String value = stringStringEntry.getValue();
|
||||
if (!value.contains("时间")){
|
||||
chartKey.add(value);
|
||||
}
|
||||
}
|
||||
return chartKey;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 趋势对比填充Excel数据集
|
||||
@ -542,75 +493,20 @@ public class StatisticalAnalysisServiceImpl implements StatisticalAnalysisServic
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用JFreeChart生成折线图(图片),已弃用
|
||||
* @param data excel数据集
|
||||
* @param writer excel对象
|
||||
* @param dataset 图表数据集
|
||||
* @param titleStr 标题
|
||||
* 获取图表类别集
|
||||
* @param map Excel的列
|
||||
* @return 图表类别集
|
||||
*/
|
||||
private void createChart(List<Map<String, Object>> data, ExcelWriter writer,
|
||||
DefaultCategoryDataset dataset, String titleStr) {
|
||||
// 获取Sheet对象
|
||||
XSSFSheet xssfSheet = (XSSFSheet) writer.getSheet();
|
||||
Workbook workbook = writer.getWorkbook();
|
||||
JFreeChart chart = ChartFactory.createLineChart(
|
||||
titleStr, // 图表标题
|
||||
"", // 横轴标签
|
||||
"", // 纵轴标签
|
||||
dataset, // 数据集
|
||||
PlotOrientation.VERTICAL, // 图表方向
|
||||
true, // 是否显示图例
|
||||
true, // 是否使用工具提示
|
||||
false // 是否生成URL链接
|
||||
);
|
||||
// 设置图表标题的字体
|
||||
TextTitle title = chart.getTitle();
|
||||
title.setFont(new java.awt.Font("SimSun", java.awt.Font.BOLD, 16));
|
||||
// 获取图表的绘图区域
|
||||
CategoryPlot plot = chart.getCategoryPlot();
|
||||
// 设置横轴标签
|
||||
CategoryAxis domainAxis = plot.getDomainAxis();
|
||||
domainAxis.setLabelFont(new java.awt.Font("SimSun", java.awt.Font.PLAIN, 12));
|
||||
domainAxis.setMaximumCategoryLabelLines(1); // 可以控制标签行数
|
||||
domainAxis.setCategoryMargin(3); // 控制类别之间的间距
|
||||
domainAxis.setCategoryLabelPositions(CategoryLabelPositions.UP_45); // 旋转横轴标签为45度,90度为:UP_90
|
||||
domainAxis.setLabelFont(new Font("SansSerif", Font.PLAIN, 7));//调整字体大小
|
||||
// if (data.size() > 50) {
|
||||
// domainAxis.setVisible(false); // 隐藏横坐标
|
||||
// }
|
||||
// 设置图例的字体
|
||||
LegendTitle legend = chart.getLegend();
|
||||
if (legend != null) {
|
||||
legend.setItemFont(new java.awt.Font("SimSun", java.awt.Font.PLAIN, 12));
|
||||
private List<String> getCharKey(LinkedHashMap<String, String> map) {
|
||||
//获取图表类别集
|
||||
List<String> chartKey = new ArrayList<>();
|
||||
for (Map.Entry<String, String> stringStringEntry : map.entrySet()) {
|
||||
String value = stringStringEntry.getValue();
|
||||
if (!value.contains("时间")){
|
||||
chartKey.add(value);
|
||||
}
|
||||
}
|
||||
// 设置绘图区域的背景颜色
|
||||
plot.setBackgroundPaint(Color.WHITE);
|
||||
// 设置绘图区域的边框
|
||||
plot.setOutlinePaint(Color.LIGHT_GRAY);
|
||||
plot.setOutlineVisible(true);
|
||||
// 设置网格线的颜色
|
||||
plot.setDomainGridlinePaint(Color.LIGHT_GRAY);
|
||||
plot.setRangeGridlinePaint(Color.LIGHT_GRAY);
|
||||
// 设置线条的宽度
|
||||
CategoryItemRenderer renderer1 = plot.getRenderer();
|
||||
renderer1.setSeriesStroke(0, new BasicStroke(2.0f)); // 设置线条宽度
|
||||
// 将图表保存为 PNG 文件
|
||||
String chartFilePath = "lineChart.png";
|
||||
// 调整图表尺寸
|
||||
int width = 750;
|
||||
int height = 400;
|
||||
try {
|
||||
ChartUtils.saveChartAsPNG(new File(chartFilePath), chart, width, height);
|
||||
byte[] bytes = java.nio.file.Files.readAllBytes(java.nio.file.Paths.get(chartFilePath));
|
||||
int pictureIdx = workbook.addPicture(bytes, Workbook.PICTURE_TYPE_PNG);
|
||||
// 计算数据的最后一行,创建图表插入位置的锚点
|
||||
XSSFClientAnchor anchor = new XSSFClientAnchor(0, 1, 0, 1, 0, data.size() + 2, 15, data.size() + 30);
|
||||
XSSFDrawing drawing = xssfSheet.createDrawingPatriarch();
|
||||
drawing.createPicture(anchor, pictureIdx);
|
||||
} catch (IOException e) {
|
||||
throw new ServiceException("图表保存失败==" + e);
|
||||
}
|
||||
|
||||
return chartKey;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -111,3 +111,5 @@ minio:
|
||||
bucket: das
|
||||
accessKey: das
|
||||
secretKey: zaq12WSX
|
||||
|
||||
zipUrl: /log/zip/
|
@ -114,3 +114,5 @@ minio:
|
||||
publicBucket: das-dock
|
||||
accessKey: das
|
||||
secretKey: zaq12WSX
|
||||
|
||||
zipUrl: /log/zip/
|
Loading…
Reference in New Issue
Block a user