新增:利元亨现场增加外部数据获取公共模块

This commit is contained in:
yangyang01000846
2025-12-19 13:53:48 +08:00
parent 0f3cfc380d
commit 51472b2e29
21 changed files with 382 additions and 14 deletions

142
outbridge/pom.xml Normal file
View File

@@ -0,0 +1,142 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.sdm</groupId>
<artifactId>SDM</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>outbridge</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>outbridge</name>
<description>outbridge</description>
<properties>
<java.version>17</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<spring-boot.version>3.3.5</spring-boot.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
<version>4.1.4</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-loadbalancer</artifactId>
<version>4.1.4</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<!-- FTP -->
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>3.11.1</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
</dependency>
<!--aop-->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
</dependency>
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>4.4.0</version>
</dependency>
<!-- Spring Boot 3.x 适配Jakarta EE Servlet API仅编译期依赖 -->
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<version>5.0.0</version> <!-- 与 Spring Boot 3.x 兼容,对应 Servlet 5.0 规范 -->
<scope>provided</scope> <!-- 关键:运行时由 web 模块的容器(如 Tomcat提供实现 -->
</dependency>
<!-- 引入模块common -->
<dependency>
<groupId>com.sdm</groupId>
<artifactId>common</artifactId>
<version>0.0.1-SNAPSHOT</version>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<!-- <plugin>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-maven-plugin</artifactId>-->
<!-- &lt;!&ndash;命名可执行jar名字默认可执行Jar包与普通jar命名相同前者会将后者覆盖可执行Jar不能够被其他模块引用&ndash;&gt;-->
<!-- <configuration>-->
<!-- <classifier>exec</classifier>-->
<!-- </configuration>-->
<!-- </plugin>-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>17</source>
<target>17</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<!-- <plugin>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-maven-plugin</artifactId>-->
<!-- <configuration>-->
<!-- <excludes>-->
<!-- <exclude>-->
<!-- <groupId>org.projectlombok</groupId>-->
<!-- <artifactId>lombok</artifactId>-->
<!-- </exclude>-->
<!-- </excludes>-->
<!-- <includeSystemScope>true</includeSystemScope>-->
<!-- </configuration>-->
<!-- </plugin>-->
</plugins>
</build>
</project>

View File

@@ -0,0 +1,31 @@
package com.sdm.outbridge.config; //// common模块com.xxx.common.config.CommonConfig
import org.springframework.boot.env.YamlPropertySourceLoader;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.io.support.DefaultPropertySourceFactory;
import org.springframework.core.io.support.EncodedResource;
import java.io.IOException;
import java.util.List;
/**
* 加载common模块的自定义配置文件
* encoding解决中文乱码
*/
@Configuration
@PropertySource(value = "classpath:common.yml", factory = CommonConfig.YamlPropertySourceFactory.class)
public class CommonConfig {
// 自定义YamlPropertySourceFactory解决@PropertySource不支持yml的问题
public static class YamlPropertySourceFactory extends DefaultPropertySourceFactory {
@Override
public org.springframework.core.env.PropertySource<?> createPropertySource(String name, EncodedResource resource) throws IOException {
if (resource == null) {
return super.createPropertySource(name, resource);
}
List<org.springframework.core.env.PropertySource<?>> sources = new YamlPropertySourceLoader()
.load(resource.getResource().getFilename(), resource.getResource());
return sources.get(0);
}
}
}

View File

@@ -0,0 +1,79 @@
package com.sdm.outbridge.config;
import com.baomidou.mybatisplus.core.MybatisConfiguration;
import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import javax.sql.DataSource;
import java.io.IOException;
/**
* 第二个数据源的MyBatis-Plus配置
* 扫描专属的Mapper包使用独立的数据源
*/
@Configuration
// 扫描第二个数据源的Mapper包指定专属的sqlSessionFactory
@MapperScan(
basePackages = "com.sdm.outbridge.dao",
sqlSessionFactoryRef = "secondSqlSessionFactory"
)
public class SecondMybatisPlusConfig {
/**
* 初始化第二个数据源
*/
@Bean(name = "secondDataSource")
@ConfigurationProperties(prefix = "spring.datasource.second") // 对应yml中的second数据源配置
public DataSource secondDataSource() {
return DataSourceBuilder.create().build();
}
/**
* 第二个数据源的事务管理器
* 非Primary因为原有动态数据源已标记为Primary
*/
@Bean(name = "secondTransactionManager")
public DataSourceTransactionManager secondTransactionManager(
@Qualifier("secondDataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
/**
* 第二个数据源的SqlSessionFactory
*/
@Bean(name = "secondSqlSessionFactory")
public MybatisSqlSessionFactoryBean secondSqlSessionFactory(
@Qualifier("secondDataSource") DataSource dataSource) throws IOException {
MybatisSqlSessionFactoryBean fb = new MybatisSqlSessionFactoryBean();
// 设置第二个数据源的Mapper.xml路径建议独立存放避免冲突
fb.setMapperLocations(new PathMatchingResourcePatternResolver()
.getResources("classpath*:mapper/second/*.xml"));
// 绑定第二个数据源
fb.setDataSource(dataSource);
// 开启下划线转驼峰(和原有配置保持一致)
MybatisConfiguration configuration = new MybatisConfiguration();
configuration.setMapUnderscoreToCamelCase(true);
fb.setConfiguration(configuration);
// 如需分页插件,可在此添加(和原有配置一致)
// fb.setPlugins(new MybatisPlusInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)));
return fb;
}
/**
* 第二个数据源的SqlSessionTemplate可选MyBatis-Plus可自动适配建议添加
*/
@Bean(name = "secondSqlSessionTemplate")
public SqlSessionTemplate secondSqlSessionTemplate(
@Qualifier("secondSqlSessionFactory") MybatisSqlSessionFactoryBean sqlSessionFactory) throws Exception {
return new SqlSessionTemplate(sqlSessionFactory.getObject());
}
}

View File

@@ -0,0 +1,13 @@
package com.sdm.outbridge.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.sdm.outbridge.entity.ViewLyricconfig;
/**
*
* @author author
* @since 2025-11-05
*/
public interface ViewLyricConfigMapper extends BaseMapper<ViewLyricconfig> {
}

View File

@@ -0,0 +1,50 @@
package com.sdm.outbridge.entity;
import com.baomidou.mybatisplus.annotation.*;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* <p>
* 测试查询视图
* </p>
*
* @author author
* @since 2025-12-01
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("view_lyricconfig")
@Schema(description = "测试查询视图")
public class ViewLyricconfig implements Serializable {
private static final long serialVersionUID = 1L;
@Schema(description = "自增主键")
@TableId(value = "id", type = IdType.AUTO)
private Long id;
@Schema(description = "占位符英文名称")
@TableField("keyEnName")
private String keyEnName;
@Schema(description = "占位符中文名称")
@TableField("keyCnName")
private String keyCnName;
@Schema(description = "创建时间")
@TableField(value = "createTime", fill = FieldFill.INSERT)
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonIgnore
private LocalDateTime createTime;
}

View File

@@ -0,0 +1,8 @@
package com.sdm.outbridge.mode;
public class HkCloudSignObject {
public String jobNo;
public String appKey;
}

View File

@@ -0,0 +1,41 @@
package com.sdm.outbridge.mode;
import io.swagger.v3.oas.annotations.media.Schema;
import java.util.ArrayList;
import java.util.List;
public class HkUploadFileReq {
@Schema(description = "权限编码")
public String filePower = "2456236750149124114";
@Schema(description = "是否加水印")
public boolean waterMarkFlag = false;
@Schema(description = "水印内容")
public String waterMarkContent = "";
@Schema(description = "系统ID")
public long sysId = 1691399963692630016L;
@Schema(description = "表单ID")
public long formId = 1847115435993071616L;
@Schema(description = "控件ID")
public long componentInstId = 8000004142460000204L;
@Schema(description = "表名称")
public String tableName = "oa_threee_d_review";
@Schema(description = "字段名称")
public String columnName = "simulation_table;";
@Schema(description = "项目号")
public String xmh = "";
@Schema(description = "工位号")
public String gwh = "";
@Schema(description = "上传文件")
public List<String> files = new ArrayList<String>();
}

View File

@@ -0,0 +1,40 @@
package com.sdm.outbridge.mode;
public class LyricAttachmentInfo {
public int id;
public String name;
public String filePath;
public String thumbnailPath;
public int fileId;
public long fileSize;
public String fileType;
public String createBy;
public String modifyBy;
public String createTime;
public String modifyTime;
public String source;
public String copyId;
public String haiKuiFileKey;
public String oaProcessId;
public String copyCurrentApprovalNode;
public String copyCurrentApproveBy;
public String copyApproveTime;
}

View File

@@ -0,0 +1,45 @@
package com.sdm.outbridge.mode;
import io.swagger.v3.oas.annotations.media.Schema;
public class LyricMainPlanInfo {
@Schema(description = "计划完成时间")
public String requirements_time;
@Schema(description = "计划工期")
public String plan_duration;
@Schema(description = "计划工时")
public String work_hour_plan;
@Schema(description = "标准工时")
public String offer_duration;
@Schema(description = "进度")
public String progress;
@Schema(description = "状态")
public String status;
@Schema(description = "开始时间")
public String start_time;
@Schema(description = "完成时间")
public String finish_time;
@Schema(description = "实际工期")
public String standard_duration;
@Schema(description = "实际工时")
public String real_work_hour;
@Schema(description = "风险等级")
public String risk_classify;
@Schema(description = "项目表ID")
public String project_id;
@Schema(description = "批次表ID")
public String batch_id;
}

View File

@@ -0,0 +1,48 @@
package com.sdm.outbridge.mode;
public class LyricProjectBaseInfo {
public String project_num;
public String project_name;
public String stage;
public String domain;
public String client_name;
public String difficultyType;
public String abnormal_rate;
public String produceLine;
public String process_section;
public String program_manager;
public String program_team;
public String reference_item;
public String schemes_finishorclose_time;
public String schemes_close_reasons;
public String drawings;
public String reuse_drawings;
public String plan_io;
public String part;
public String material_quality;
public String put_mode;
public String screw_material;
public String machine_type;
}

View File

@@ -0,0 +1,36 @@
package com.sdm.outbridge.mode;
import io.swagger.v3.oas.annotations.media.Schema;
public class LyricProjectBatchInfo {
@Schema(description = "项目ID")
public String project_id;
@Schema(description = "批次名称")
public String batch;
@Schema(description = "工厂")
public String works;
@Schema(description = "订单数量")
public int order_quantity;
@Schema(description = "项目状态")
public int status;
@Schema(description = "批次进度")
public int project_progress_status;
@Schema(description = "项目出机条件")
public String minted_condition;
@Schema(description = "设备出机地址(市)")
public String client_city;
@Schema(description = "设备出机地址(区)")
public String client_region;
@Schema(description = "军令状时间")
public String sat_time;
}

View File

@@ -0,0 +1,27 @@
package com.sdm.outbridge.mode;
import io.swagger.v3.oas.annotations.media.Schema;
public class LyricProjectPdt {
@Schema(description = "项目ID")
public String project_id;
@Schema(description = "项目号")
public String project_num;
@Schema(description = "项目角色")
public String project_role;
@Schema(description = "角色类型")
public String type;
@Schema(description = "角色类型")
public String user;
@Schema(description = "人员姓名")
public String name;
@Schema(description = "机台号")
public String machine_number;
}

View File

@@ -0,0 +1,201 @@
package com.sdm.outbridge.mode;
import io.swagger.v3.oas.annotations.media.Schema;
public class LyricTodoEntity {
public int id;
@Schema(description = "待办ID")
public int todo_id;
@Schema(description = "3D负责人")
public String three_dimensional_performer;
@Schema(description = "仿真负责人")
public String emulation_performer;
@Schema(description = "仿真登记人")
public String emulation_registrant;
@Schema(description = "仿真执行人")
public String emulation_executor;
@Schema(description = "仿真类型")
public String emulation_type;
@Schema(description = "仿真结果")
public String emulation_result;
@Schema(description = "仿真需求")
public String emulation_demand;
@Schema(description = "机器人品牌")
public String robot_brand;
@Schema(description = "四轴,六轴")
public String axis;
@Schema(description = "节拍要求")
public String beat_requirements;
@Schema(description = "3D存放路径")
public String three_dimensional_repository_path;
@Schema(description = "报告路径")
public String result_path;
@Schema(description = "结果描述")
public String result_describe;
@Schema(description = "分析类型")
public String analysis_type;
@Schema(description = "分析数量")
public int analysis_num;
@Schema(description = "仿真耗时")
public float emulation_time;
@Schema(description = "使用软件")
public String software;
@Schema(description = "完成时间")
public String result_finish_time;
@Schema(description = "类型(仿真结果,仿真信息)")
public String type;
@Schema(description = "创建人")
public String create_by;
@Schema(description = "创建时间")
public String create_time;
@Schema(description = "修改人")
public String modify_by;
@Schema(description = "修改时间")
public String modify_time;
@Schema(description = "仿真结果附加")
public String result_file_id;
@Schema(description = "难度等级1-5")
public String difficulty;
@Schema(description = "需求时间")
public String required_time;
@Schema(description = "是否长期待办")
public byte is_long_term;
@Schema(description = "动画用途")
public String animation_use;
@Schema(description = "有限元仿真用途")
public String limited_use;
@Schema(description = "紧急情况说明")
public String emergency_statement;
@Schema(description = "状态")
public String status;
@Schema(description = "主题")
public String subject;
@Schema(description = "描述")
public String describes;
@Schema(description = "项目")
public String project;
@Schema(description = "责任人(多个用逗号隔开)")
public String performer;
@Schema(description = "计划开始时间")
public String plan_start_time;
@Schema(description = "要求完成时间")
public String requirements_time;
@Schema(description = "开始时间")
public String start_time;
@Schema(description = "完成时间")
public String finish_time;
@Schema(description = "暂停时间")
public String paused_time;
@Schema(description = "提出人")
public String introduce_by;
@Schema(description = "关闭人")
public String close_by;
@Schema(description = "关闭时间")
public String close_time;
@Schema(description = "关注人(多个用逗号隔开)")
public String follow_by;
@Schema(description = "工位")
public String station_num;
@Schema(description = "项目名称")
public String project_name;
@Schema(description = "项目机型")
public String project_model;
@Schema(description = "项目阶段")
public String project_stage;
@Schema(description = "确认人工号")
public String verifier_no;
@Schema(description = "进度")
public String progress;
@Schema(description = "任务单号")
public String todo_num;
@Schema(description = "进度说明")
public String progress_description;
@Schema(description = "实际工时")
public String real_work_hour;
@Schema(description = "确认人")
public String verifier;
@Schema(description = "关注人")
public String follow_by_name;
@Schema(description = "责任人姓名")
public String performer_name;
@Schema(description = "计划工时")
public String work_hour_plan;
@Schema(description = "提出人姓名")
public String introduce_by_name;
@Schema(description = "驳回原因")
public String turn_down_reason;
@Schema(description = "项目类型")
public String project_type;
@Schema(description = "项目组")
public String project_group;
@Schema(description = "完成人")
public String finished_by;
@Schema(description = "标准工时")
public String standard_work_hour;
}

View File

@@ -0,0 +1,11 @@
package com.sdm.outbridge.service.impl.lyric;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sdm.outbridge.dao.ViewLyricConfigMapper;
import com.sdm.outbridge.entity.ViewLyricconfig;
import com.sdm.outbridge.service.lyric.IViewLyricConfigService;
import org.springframework.stereotype.Service;
@Service
public class ViewLyricConfigServiceImpl extends ServiceImpl<ViewLyricConfigMapper, ViewLyricconfig> implements IViewLyricConfigService {
}

View File

@@ -0,0 +1,8 @@
package com.sdm.outbridge.service.lyric;
import com.baomidou.mybatisplus.extension.service.IService;
import com.sdm.outbridge.entity.ViewLyricconfig;
/* 这个接口只是测试的 */
public interface IViewLyricConfigService extends IService<ViewLyricconfig> {
}

View File

@@ -0,0 +1,420 @@
package com.sdm.outbridge.service.lyric;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.JSONWriter;
import com.sdm.common.common.SdmResponse;
import com.sdm.common.utils.HttpUtil;
import com.sdm.outbridge.mode.HkUploadFileReq;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;
import javax.net.ssl.SSLContext;
import java.io.File;
import java.nio.charset.StandardCharsets;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.sql.*;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
@Service
@Slf4j
@RefreshScope
public class LyricIntegrateService {
//测试开发环境
@Value("${appKey}")
private String appKey;
@Value("${appSecret}")
private String appSecret;
//海葵云url
@Value("${HK_CLOUD_URL}")
private String HK_CLOUD_URL;
//海葵云获取用户token url后缀
@Value("${HK_USER_TOKEN_URL_SUFFIX}")
private String HK_USER_TOKEN_URL_SUFFIX;
//海葵云获取单个用户信息url后缀
@Value("${HK_SIMPLE_USER_URL_SUFFIX}")
private String HK_SIMPLE_USER_URL_SUFFIX;
//海葵云上传文件url后缀
@Value("${HK_UPLOAD_FILE_URL_SUFFIX}")
private String HK_UPLOAD_FILE_URL_SUFFIX;
//EP系统URL
@Value("${EP_URL}")
private String EP_URL;
//推送代办状态url后缀
@Value("${QUERY_TODO_STATUS_SUFFIX}")
private String PUSH_TODO_STATUS_SUFFIX;
//查询待办结果url后缀
@Value("${QUERY_TODO_RESULT_SUFFIX}")
private String QUERY_TODO_RESULT_SUFFIX;
//查询待办附加url后缀
@Value("${QUERY_TOD_ATTACHMENT_SUFFIX}")
private String QUERY_TOD_ATTACHMENT_SUFFIX;
//生产环境
/**
private final String EP_URL = "https://ep-url.lyh.haikuicloud.com;
*/
@Value("${URL}")
private String URL;
@Value("${USER_NAME}")
private String USERNAME; // 你的 MySQL 用户名
@Value("${PASSWORD}")
private String PASSWORD; // 你的 MySQL 密码
/**
* 生成海葵云token签名
*
* @param object
* @param appSecret
* @param appSecret
* @return
*/
private String calculateSignHkcloud(Object object, String appSecret) {
JSONObject fastjson = JSONObject.parseObject(JSONObject.toJSONString(object));
fastjson.remove("sign");
fastjson.put("appSecret", appSecret);
String addSalStr = JSONObject.toJSONString(fastjson, JSONWriter.Feature.MapSortField);
return DigestUtils.md5DigestAsHex(addSalStr.getBytes(StandardCharsets.UTF_8));
}
/**
* 校验签名
* @param object
* @param sign
* @param appSecret
* @return
*/
private boolean verificationSign(Object object, String sign,String appSecret) {
String calcSign = calculateSignHkcloud(object, appSecret);
return calcSign.equals(sign);
}
/**
* 获取根据工号获取用户token
*
* @param appKey
* @param appSecret
* @param jobNo
* @param tokenUrl
* @return
*/
public String getHKCloudToken(String appKey, String appSecret, String jobNo, String tokenUrl) {
JSONObject jsonObject = new JSONObject();
jsonObject.put("appKey", appKey);
jsonObject.put("jobNo", jobNo);
String sign = calculateSignHkcloud(jsonObject, appSecret);
boolean verify = verificationSign(jsonObject, sign, appSecret);
String token = null;
JSONObject paramObject = new JSONObject();
paramObject.put("jobNo", jobNo);
paramObject.put("appKey", appKey);
paramObject.put("sign", sign);
try {
String result = HttpUtil.httpPost(tokenUrl, null, jsonObject.toJSONString());
JSONObject resultJson = JSONObject.parseObject(result);
String code = resultJson.getString("code");
if (code.equals("0000")) {
JSONObject dataObject = resultJson.getJSONObject("data");
if (dataObject != null) {
token = dataObject.getString("token");
}
}
} catch (Exception e) {
e.printStackTrace();
}
return token;
}
/**
* 获取当前用户的
*
* @param jobNo
* @return
*/
public SdmResponse getHKCloudSimpleUserInfo(String jobNo) {
SdmResponse response = SdmResponse.success();
String tokenUrl = HK_CLOUD_URL + HK_USER_TOKEN_URL_SUFFIX;
String token = getHKCloudToken(appKey, appSecret, jobNo, tokenUrl);
if (token == null || token.isEmpty()) {
response = SdmResponse.failed("获取海葵云token失败");
} else {
String simpleUserUrl = HK_CLOUD_URL + HK_SIMPLE_USER_URL_SUFFIX;
Map<String, String> headers = new HashMap<String, String>();
headers.put("authorization", token);
try {
String result = HttpUtil.httpPost(simpleUserUrl, headers, "");
JSONObject resultJson = JSONObject.parseObject(result);
String code = resultJson.getString("code");
if (code.equals("0000")) {
JSONObject dataObject = resultJson.getJSONObject("data");
if (dataObject != null) {
response.setData(dataObject);
}
} else {
response = SdmResponse.failed("获取海葵云单个用户信息失败");
}
} catch (Exception e) {
e.printStackTrace();
response = SdmResponse.failed("获取海葵云单个用户信息失败");
}
}
return response;
}
/**
* 构建信任所有证书的CloseableHttpClient
* @return
*/
private static CloseableHttpClient createHttpsClient() {
try {
// 1. 构建SSL上下文信任所有证书
SSLContext sslContext = SSLContextBuilder.create()
.loadTrustMaterial(null, (chain, authType) -> true) // 信任所有证书
.build();
// 2. 创建SSL连接工厂忽略主机名验证
SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(
sslContext,
NoopHostnameVerifier.INSTANCE // 信任所有主机名
);
// 3. 配置超时参数
RequestConfig requestConfig = RequestConfig.custom()
.setConnectTimeout(30000) // 连接超时30秒
.setSocketTimeout(300000) // 读取超时5分钟
.setConnectionRequestTimeout(5000) // 连接池超时5秒
.build();
// 4. 构建HttpClient
return HttpClients.custom()
.setSSLSocketFactory(sslSocketFactory)
.setDefaultRequestConfig(requestConfig)
.build();
} catch (NoSuchAlgorithmException | KeyManagementException | KeyStoreException e) {
throw new RuntimeException("创建HTTPS客户端失败", e);
}
}
/**
* 上传仿真报告
*
* @param jobNo
* @param hkUploadFileReq
* @return
*/
public SdmResponse uploadHkFile(String jobNo, HkUploadFileReq hkUploadFileReq) {
SdmResponse response = SdmResponse.failed("文件上传失败");
String token = getHKCloudToken(appKey, appSecret, jobNo, HK_CLOUD_URL);
if (token == null || token.isEmpty())
{
response = SdmResponse.failed("获取token失败");
}
else
{
String url = HK_CLOUD_URL + HK_UPLOAD_FILE_URL_SUFFIX;
HttpPost httpPost = new HttpPost(url);
MultipartEntityBuilder builder = MultipartEntityBuilder.create()
.setCharset(StandardCharsets.UTF_8); // 解决中文乱码
// 添加普通参数
builder.addPart("filePower", new StringBody(hkUploadFileReq.filePower,
ContentType.TEXT_PLAIN.withCharset(StandardCharsets.UTF_8)));
builder.addPart("waterMarkFlag", new StringBody(String.valueOf(hkUploadFileReq.waterMarkFlag),
ContentType.TEXT_PLAIN.withCharset(StandardCharsets.UTF_8)));
builder.addPart("waterMarkContent", new StringBody(hkUploadFileReq.waterMarkContent,
ContentType.TEXT_PLAIN.withCharset(StandardCharsets.UTF_8)));
builder.addPart("sysId", new StringBody(String.valueOf(hkUploadFileReq.sysId),
ContentType.TEXT_PLAIN.withCharset(StandardCharsets.UTF_8)));
builder.addPart("formId", new StringBody(String.valueOf(hkUploadFileReq.formId),
ContentType.TEXT_PLAIN.withCharset(StandardCharsets.UTF_8)));
builder.addPart("ComponentInstId", new StringBody(String.valueOf(hkUploadFileReq.componentInstId),
ContentType.TEXT_PLAIN.withCharset(StandardCharsets.UTF_8)));
builder.addPart("tableName", new StringBody(hkUploadFileReq.tableName,
ContentType.TEXT_PLAIN.withCharset(StandardCharsets.UTF_8)));
builder.addPart("columnName", new StringBody(hkUploadFileReq.columnName,
ContentType.TEXT_PLAIN.withCharset(StandardCharsets.UTF_8)));
builder.addPart("xmh", new StringBody(hkUploadFileReq.xmh,
ContentType.TEXT_PLAIN.withCharset(StandardCharsets.UTF_8)));
builder.addPart("gwh", new StringBody(hkUploadFileReq.gwh,
ContentType.TEXT_PLAIN.withCharset(StandardCharsets.UTF_8)));
// 追加多个文件同一字段名files
for (String filePath : hkUploadFileReq.files) {
File file = new File(filePath);
if (file.exists())
builder.addPart("files", new FileBody(file, ContentType.DEFAULT_BINARY, file.getName()));
}
// 构建HttpPost请求
httpPost.setEntity(builder.build());
try
{
CloseableHttpClient httpclient = createHttpsClient();
CloseableHttpResponse fileResponse = httpclient.execute(httpPost);
String responseContent = EntityUtils.toString(fileResponse.getEntity(), StandardCharsets.UTF_8);
if(responseContent != null && !responseContent.isEmpty())
{
JSONObject responseJson = JSONObject.parseObject(responseContent);
if(responseJson.containsKey("code"))
{
String code = responseJson.getString("code");
if(code != null && code.equals("0000"))
{
response = SdmResponse.success();
}
}
}
}
catch (Exception e)
{
e.printStackTrace();
response = SdmResponse.failed("上传文件异常");
}
}
return response;
}
/**
* 推送代办状态
* @param todoId
* @param reason
* @param progress
* @param progressDescription
* @param userNo
* @param statusType doing(启动)turnDown(驳回)pause(暂停)restart(重启)updateProgress(提交进度)finished(完成)closed(关闭)
* @return
*/
public SdmResponse pushTodoStatus(int todoId,String reason,int progress,String progressDescription,String userNo,String statusType)
{
SdmResponse response = SdmResponse.failed("推送代办状态失败");
String url = EP_URL+PUSH_TODO_STATUS_SUFFIX;
Map<String,String> header = new HashMap<>();
header.put("Content-Type","application/x-www-form-urlencoded,application/json");
JSONObject paramObj = new JSONObject();
paramObj.put("todoId",todoId);
paramObj.put("reason",reason);
paramObj.put("progress",progress);
paramObj.put("progressDescription",progressDescription);
paramObj.put("userNo",userNo);
paramObj.put("statusType",statusType);
try {
String result = HttpUtil.httpPost(url, header, paramObj.toJSONString());
if(result != null && !result.isEmpty())
{
JSONObject responseJson = JSONObject.parseObject(result);
if(responseJson != null && responseJson.containsKey("success"))
{
if(responseJson.getBoolean("success"))
{
response = SdmResponse.success();
}
}
}
}
catch (Exception e)
{
e.printStackTrace();
}
return response;
}
/**
* 查询待办附件
* @param todoId
* @return
*/
public SdmResponse queryTodoAttachments(int todoId)
{
SdmResponse response = SdmResponse.failed("获取待办附件失败");
String url = EP_URL+QUERY_TOD_ATTACHMENT_SUFFIX+"?todoId="+todoId;
Map<String,String> header = new HashMap<>();
header.put("Content-Type","application/x-www-form-urlencoded");
try
{
String result = HttpUtil.httpPost(url, header, "");
if(result != null && !result.isEmpty())
{
JSONObject responseJson = JSONObject.parseObject(result);
if(responseJson != null && responseJson.containsKey("data"))
{
JSONArray data = responseJson.getJSONArray("data");
response = SdmResponse.success();
response.setData(data);
}
}
}
catch (Exception e)
{
e.printStackTrace();
}
return response;
}
/**
* 获取待办列表
* @return
*/
public SdmResponse getTodoList() {
String todayStartTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(LocalDate.now().atStartOfDay().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli()));
String sql = "SELECT * FROM V_TODO_EMULATION_INFO WHERE create_time > ? AND status = ?";
// 声明JDBC核心对象try-with-resources 自动关闭资源)
try (Connection conn = DriverManager.getConnection(URL, USERNAME, PASSWORD)) {
PreparedStatement stmt = conn.prepareStatement(sql);
stmt.setString(1,todayStartTime);
stmt.setString(2,"0");
// 执行视图查询
ResultSet rs = stmt.executeQuery();
while (rs.next()) {
String projectName = rs.getString("projectName");
String status = rs.getString("status");
Date createTime = rs.getDate("createTime");
log.info("projectName为{}status{}createTime为{}", projectName, status,createTime);
}
} catch (SQLException e) {
// 异常处理
System.err.println("JDBC 操作异常:" + e.getMessage());
log.info(e.getMessage());
}
return SdmResponse.success();
}
}

View File

@@ -0,0 +1,41 @@
spring:
application:
name: pbs
datasource:
second:
username: root
password: mysql
jdbc-url: jdbc:mysql://192.168.65.161:3306/spdm_baseline?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=Asia/Shanghai
driver-class-name: com.mysql.cj.jdbc.Driver
# 测试开发环境
#appKey : 380ad3deb578424c9ca5178383f732c1
#appSecret : 805c316f35024b8b9566ca67b4991c42
#appKey : d39820947556421aa329b070e669dfa2
#corpKey : e906d13947944947921bb32c8fcffc6e
#appSecret : 13cff5f8fb1c479297370a7d41853158
appKey : e9eb516aa02a43a29e227a0d901ec5f1
appSecret : 9fac43db08634aaf8a9fe5fb9468de9d
# 海葵云url
HK_CLOUD_URL : https://url.lyhhaikuicloud.com
# 海葵云获取用户token url后缀
HK_USER_TOKEN_URL_SUFFIX : /merchant/openapi/user/login/jobNo
# 海葵云获取单个用户信息url后缀
HK_SIMPLE_USER_URL_SUFFIX : /merchant/api/user/getSimpleUserInfo
# 海葵云上传文件url后缀
HK_UPLOAD_FILE_URL_SUFFIX : /haikui-oa/autoCreateFlow/uploadFile
# EP系统URL
EP_URL : https://ep-url.dev.haikuicloud.com
# 推送代办状态url后缀
QUERY_TODO_STATUS_SUFFIX : /todoApi/todo/emulation/dm/status
# 查询待办结果url后缀
QUERY_TODO_RESULT_SUFFIX : /todoApi/todo/emulation/dm/result
# 查询待办附加url后缀
QUERY_TOD_ATTACHMENT_SUFFIX : /todoApi/todo/emulation/dm/attachments
# 海葵云 数据库连接
URL : jdbc:mysql://127.0.0.1:3306/spdm_baseline?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
# 海葵云 数据库用户名
USER_NAME : root
# 海葵云 数据库密码
PASSWORD : ldy123456