Commit 412436e5 authored by fangxinjiang's avatar fangxinjiang

企微智能表格开发(目前只支持文本数据查询,具体格式未开发)-fxj

parent 574abf10
......@@ -13,14 +13,16 @@ import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/**
* 招行卡相关控制器
* @author hgw
* @date 2025-9-9 11:24:36
*/
* @Author fxj
* @Description 企微智能表格API调用
* @Date 17:44 2025/9/29
* @Param
* @return
**/
@RestController
@RequiredArgsConstructor
@RequestMapping("/qwExcelApi")
@Tag(name = "招行卡相关控制器")
@Tag(name = "企微智能表格API调用")
public class QwExcelApiController {
private final QwExcelApiService qwExcelApiService;
......@@ -38,4 +40,18 @@ public class QwExcelApiController {
}
/**
* @Author fxj
* @Description 企业微信智能表格API定时任务
* @Date 15:56 2025/9/26
* @Param
* @return
**/
@Inner
@PostMapping("/inner/wxExcelApi")
public void wxExcelApi() {
qwExcelApiService.wxExcelApi();
}
}
......@@ -2,17 +2,17 @@ package com.yifu.cloud.plus.v1.ekp.service.impl.QwExce;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yifu.cloud.plus.v1.ekp.config.WxConfig;
import com.yifu.cloud.plus.v1.ekp.entity.EkpBankAtta;
import com.yifu.cloud.plus.v1.ekp.entity.EkpInvoiceInfo;
import com.yifu.cloud.plus.v1.ekp.mapper.EkpBankAttaMapper;
import com.yifu.cloud.plus.v1.ekp.mapper.QwExcelApiMapper;
import com.yifu.cloud.plus.v1.ekp.service.QwExcelApiService;
import com.yifu.cloud.plus.v1.ekp.util.SmartSheetDebugService;
import com.yifu.cloud.plus.v1.ekp.util.WeComSmartSheetManager;
import com.yifu.cloud.plus.v1.yifu.common.core.constant.CommonConstants;
import com.yifu.cloud.plus.v1.yifu.common.core.util.MonthCalculationUtils;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import java.util.ArrayList;
import java.util.List;
......@@ -31,47 +31,83 @@ public class QwExcelApiServiceImpl extends ServiceImpl<QwExcelApiMapper, EkpInvo
private SmartSheetDebugService debugService;
@Autowired
private WxConfig wxConfig;
@Autowired
WeComSmartSheetManager weComSmartSheetManager;
@Override
public void wxExcelApi() {
//获取accessToken
String corpId = "wwbcb090af0dfe50e5";
//HR审批应用 agentid: 1000009,corpSecret:R0nKkvsY-oF41fuQvUXZ-kFG3_g_Ce0bpZt6mByx524
String corpSecret = "16kqEL_eU-ARwYyqLgEBWHgxm8gXVnkzv_eJMLy9NpU";
String docId = "dcTSMCj4lWV9MEP7lquZacOY8WS4g-iHxP_jVYA02tdYwb2YYc3BpDR8NrFWkEngHUg8abET4eTIpo9Zv-571NEA";
//智能表格发票数据表ID
String sheetId = "q979lj";
String accessToken = weComSmartSheetManager.getAccessToken(corpId,corpSecret);
if (accessToken == null || accessToken.isEmpty()) {
log.error("获取access_token失败");
return;
}
int batchSize = 1000;
int batchCount = 0;
log.info("微信智能表格发票数据插入开始...");
//获取最近24个月的发票信息,按月去插入到智能表格中
String[] monthRange =null;
List<Map<String, Object>> records = new ArrayList<>();
List<Map<String, Object>> tempRecords = null;
for (int i = 0; i < 24; i++){
monthRange =MonthCalculationUtils.calculateMonthRange(i);
if (null != monthRange && monthRange.length == CommonConstants.dingleDigitIntArray[2]){
tempRecords = baseMapper.selectInvoiceList(monthRange[0],monthRange[1]);
}
if (tempRecords != null) {
records.addAll(tempRecords);
//List<String> strings = new ArrayList<>();
//strings.add("FeiTaiLang_Fang");
//strings.add("ZhangQianQian");
//weComSmartSheetManager.addSheet(accessToken,docId,"合同基础信息表");
log.info("微信智能表格发票数据删除开始...");
weComSmartSheetManager.deleteAllRows(accessToken,docId,sheetId);
log.info("微信智能表格发票数据删除完成");
log.info("微信智能表格发票数据插入开始...");
//获取最近24个月的发票信息,按月去插入到智能表格中
monthRange = MonthCalculationUtils.calculateMonthRange(0);
if (null != monthRange && monthRange.length == CommonConstants.dingleDigitIntArray[2]){
records = baseMapper.selectInvoiceList(monthRange[0],monthRange[1]);
}
//分批插入
if (null != records && !records.isEmpty()){
batchCount = records.size() / batchSize;
//如果记录数不能被batchSize整除,需要增加一个批次
if (records.size() % batchSize != 0) {
batchCount++;
}
//分批插入
if (null != records && !records.isEmpty()){
batchCount = records.size() / batchSize;
for (int j = 0; j < batchCount; j++) {
tempRecords = records.subList(j * batchSize, (j + 1) * batchSize);
debugService.debugInsertIssue(wxConfig,tempRecords);
}
for (int j = 0; j < batchCount; j++) {
tempRecords = records.subList(j * batchSize, Math.min((j + 1) * batchSize, records.size()));
debugService.debugInsertIssueAsso(accessToken,tempRecords,docId,sheetId);
break;
}
}
log.info("微信智能表格发票数据插入完成");
//智能表格合同数据表ID
/*sheetId = "EuVt8X";
log.info("微信智能表格合同数据删除开始...");
weComSmartSheetManager.deleteAllRows(accessToken,docId,sheetId);
log.info("微信智能表格合同数据删除完成");
log.info("微信智能表格合同数据插入开始...");
//开始处理合同信息,先获取合同数,然后分批次插入数据,每批次1000条
int contractCount = baseMapper.selectContractListCount();
batchCount = contractCount / batchSize;
if (contractCount % batchSize != 0) {
batchCount++;
batchSize = contractCount / batchCount;
for (int i = 0; i < batchCount; i++) {
tempRecords = baseMapper.selectContractList(i * batchSize, (i + 1) * batchSize);
if (contractCount != 0) {
batchCount = contractCount / batchSize;
if (batchCount != 0){
for (int i = 0; i <= batchCount; i++) {
tempRecords = baseMapper.selectContractList(i * batchSize, batchSize);
if (tempRecords != null) {
debugService.debugInsertIssueAsso(accessToken,tempRecords,docId,sheetId);
}
}
}else {
tempRecords = baseMapper.selectContractList(0, batchSize);
if (tempRecords != null) {
debugService.debugInsertIssue(wxConfig,tempRecords);
debugService.debugInsertIssueAsso(accessToken,tempRecords,docId,sheetId);
}
}
}
log.info("微信智能表格合同数据插入完成");
log.info("微信智能表格合同数据插入完成");*/
}
}
......@@ -77,4 +77,55 @@ public class SmartSheetDebugService {
log.info("\n=== 调试完成 ===");
}
/**
* 调试企业微信智能表格记录添加问题
*
*/
public void debugInsertIssueAsso(String accessToken,List<Map<String, Object>> records,String docId,String sheetId) {
if (Common.isEmpty( accessToken)){
log.error("accessToken为空");
return;
}
if (Common.isEmpty( records)){
log.error("数据为空");
return;
}
log.info("=== 开始调试企业微信智能表格记录添加问题 ===");
// 1. 获取并打印表格字段信息
log.info("=== 表格字段信息 ===");
List<WeComSmartSheetDebugger.FieldInfo> fields = debugger.getSheetFields(accessToken,docId, sheetId);
if (fields.isEmpty()) {
log.info("未能获取到表格字段信息,请检查参数是否正确");
return;
}
Map<String,String> fieldMap = new HashMap<>();
for (WeComSmartSheetDebugger.FieldInfo field : fields) {
fieldMap.put(field.getTitle(),field.getType());
log.info("字段ID: " + field.getFieldId() +
", 字段标题: '" + field.getTitle() + "'" +
", 字段类型: " + field.getType());
}
// 3. 验证字段匹配性
/*log.info("\n=== 字段匹配性验证 ===");
List<String> mismatches = debugger.validateFields(accessToken, docId, sheetId, records);
if (mismatches.isEmpty()) {
log.info("所有字段都匹配");
} else {
log.info("以下字段不匹配:");
for (String mismatch : mismatches) {
log.info("- " + mismatch);
}
log.info("请根据以上信息修正数据后重试");
return;
}*/
// 4. 测试插入数据并查看详细响应
log.info("\n=== 数据插入 ===");
String response = debugger.insertData(accessToken, docId, sheetId, records,fieldMap );
//log.info("API响应: " + response);
log.info("\n=== 调试完成 ===");
}
}
\ No newline at end of file
......@@ -4,6 +4,8 @@ import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.yifu.cloud.plus.v1.ekp.config.WxConfig;
import com.yifu.cloud.plus.v1.yifu.common.core.util.DateUtil;
import lombok.extern.log4j.Log4j2;
import org.springframework.http.*;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
......@@ -17,6 +19,7 @@ import java.util.Map;
* 企业微信智能表格调试工具类
* 用于诊断和解决企业微信智能表格记录添加后不显示的问题
*/
@Log4j2
@Component
public class WeComSmartSheetDebugger {
......@@ -61,19 +64,42 @@ public class WeComSmartSheetDebugger {
// 1. 获取access_token
String accessToken = getAccessToken(corpId, corpSecret);//wxConfig.getAccessToken(restTemplate);
if (accessToken == null || accessToken.isEmpty()) {
System.err.println("获取access_token失败");
log.error("获取access_token失败");
return fieldInfos;
}
// 2. 获取字段信息
fieldInfos = fetchFields(accessToken, docId, sheetId);
} catch (Exception e) {
System.err.println("获取表格字段信息时发生异常: " + e.getMessage());
log.error("获取表格字段信息时发生异常: " + e.getMessage());
e.printStackTrace();
}
return fieldInfos;
}
/**
* 获取表格字段信息
*
* @param accessToken accessToken
* @param docId 文档ID
* @param sheetId 工作表ID
* @return 字段信息列表
*/
public List<FieldInfo> getSheetFields(String accessToken,String docId, String sheetId) {
List<FieldInfo> fieldInfos = new ArrayList<>();
try {
if (accessToken == null || accessToken.isEmpty()) {
log.error("获取access_token失败");
return fieldInfos;
}
// 2. 获取字段信息
fieldInfos = fetchFields(accessToken, docId, sheetId);
} catch (Exception e) {
log.error("获取表格字段信息时发生异常: " + e.getMessage());
e.printStackTrace();
}
return fieldInfos;
}
/**
* 验证字段匹配性
*
......@@ -120,12 +146,61 @@ public class WeComSmartSheetDebugger {
}
}
} catch (Exception e) {
System.err.println("验证字段匹配性时发生异常: " + e.getMessage());
log.error("验证字段匹配性时发生异常: " + e.getMessage());
e.printStackTrace();
}
return mismatches;
}
/**
* 验证字段匹配性
*
* @param accessToken accessToken
* @param docId 文档ID
* @param sheetId 工作表ID
* @param records 要插入的记录列表
* @return 不匹配的字段列表
*/
public List<String> validateFields(String accessToken, String docId, String sheetId,
List<Map<String, Object>> records) {
List<String> mismatches = new ArrayList<>();
try {
// 1. 获取表格字段信息
List<FieldInfo> fieldInfos = getSheetFields(accessToken, docId, sheetId);
Map<String, FieldInfo> fieldMap = new HashMap<>();
for (FieldInfo fieldInfo : fieldInfos) {
fieldMap.put(fieldInfo.getTitle(), fieldInfo);
}
// 2. 检查记录中的字段
for (Map<String, Object> record : records) {
Map<String, Object> values = (Map<String, Object>) record.get("values");
if (values != null) {
for (Map.Entry<String, Object> entry : values.entrySet()) {
String fieldName = entry.getKey();
Object fieldValue = entry.getValue();
// 检查字段是否存在
if (!fieldMap.containsKey(fieldName)) {
mismatches.add("字段 '" + fieldName + "' 在表格中不存在");
continue;
}
// 检查字段类型是否匹配
FieldInfo fieldInfo = fieldMap.get(fieldName);
String fieldType = fieldInfo.getType();
if (!isFieldTypeMatch(fieldType, fieldValue)) {
mismatches.add("字段 '" + fieldName + "' 类型不匹配,表格中为 " + fieldType +
" 类型,但传入的是 " + fieldValue.getClass().getSimpleName() + " 类型");
}
}
}
}
} catch (Exception e) {
log.error("验证字段匹配性时发生异常: " + e.getMessage());
e.printStackTrace();
}
return mismatches;
}
/**
* 测试插入数据
*
......@@ -183,12 +258,82 @@ public class WeComSmartSheetDebugger {
// 3. 发送请求
return insertRecords(accessToken, requestBody);
} catch (Exception e) {
System.err.println("测试插入数据时发生异常: " + e.getMessage());
log.error("测试插入数据时发生异常: " + e.getMessage());
e.printStackTrace();
return "测试插入数据时发生异常: " + e.getMessage();
}
}
/**
* 插入数据
*
* @param accessToken accessToken
* @param docId 文档ID
* @param sheetId 工作表ID
* @param records 要插入的记录列表
* @return API响应结果
*/
public String insertData(String accessToken, String docId, String sheetId,
List<Map<String, Object>> records,Map<String,String> fieldMap ) {
try {
if (accessToken == null || accessToken.isEmpty()) {
return "获取access_token失败";
}
// 2. 构造请求体
JSONObject requestBody = new JSONObject();
requestBody.put("docid", docId);
requestBody.put("sheet_id", sheetId);
requestBody.put("key_type", "CELL_VALUE_KEY_TYPE_FIELD_TITLE");
// 构造records数组
// 格式化
JSONArray recordsArray = new JSONArray();
for (Map<String, Object> fieldData : records) {
JSONObject recordObj = new JSONObject();
JSONObject values = new JSONObject();
for (Map.Entry<String, Object> entry : fieldData.entrySet()) {
String fieldName = entry.getKey();
String fieldValue = entry.getValue().toString();
// 构造字段值格式[{"type": "text", "text": "文本内容"}]
JSONArray fieldValueArray = new JSONArray();
JSONObject textObject = new JSONObject();
//根据fieldMap 对应的字段类型 初始化对应的企业微信的字段
if(fieldMap.containsKey(fieldName)){
/* if (fieldMap.get(fieldName).equals("FIELD_TYPE_DATE_TIME")){
textObject.put("type", "Date");
textObject.put("text", fieldValue);
}else if (fieldMap.get(fieldName).equals("FIELD_TYPE_NUMBER")){
textObject.put("type", "double");
textObject.put("text", 11111.00);
}else {
textObject.put("type", "text");
textObject.put("text", fieldValue);
}*/
textObject.put("type", "text");
textObject.put("text", fieldValue);
}
fieldValueArray.add(textObject);
values.put(fieldName, fieldValueArray);
}
recordObj.put("values", values);
recordsArray.add(recordObj);
}
requestBody.put("records", recordsArray);
// 3. 发送请求
return insertRecords(accessToken, requestBody);
} catch (Exception e) {
log.error("测试插入数据时发生异常: " + e.getMessage());
e.printStackTrace();
return "测试插入数据时发生异常: " + e.getMessage();
}
}
/**
* 检查字段类型是否匹配
*
......@@ -229,13 +374,13 @@ public class WeComSmartSheetDebugger {
if (jsonObject.getInteger("errcode") == 0) {
return jsonObject.getString("access_token");
} else {
System.err.println("获取access_token失败,错误代码:" + jsonObject.getInteger("errcode")
log.error("获取access_token失败,错误代码:" + jsonObject.getInteger("errcode")
+ ",错误信息:" + jsonObject.getString("errmsg"));
return null;
}
}
} catch (Exception e) {
System.err.println("获取access_token时发生异常: " + e.getMessage());
log.error("获取access_token时发生异常: " + e.getMessage());
e.printStackTrace();
}
return null;
......@@ -282,12 +427,12 @@ public class WeComSmartSheetDebugger {
}
}
} else {
System.err.println("获取字段信息失败,错误代码:" + jsonObject.getInteger("errcode")
log.error("获取字段信息失败,错误代码:" + jsonObject.getInteger("errcode")
+ ",错误信息:" + jsonObject.getString("errmsg"));
}
}
} catch (Exception e) {
System.err.println("获取字段信息时发生异常: " + e.getMessage());
log.error("获取字段信息时发生异常: " + e.getMessage());
e.printStackTrace();
}
return fieldInfos;
......@@ -310,12 +455,12 @@ public class WeComSmartSheetDebugger {
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<String> request = new HttpEntity<>(requestBody.toJSONString(), headers);
System.err.println("插入数据的JSON:" + request.getBody());
//log.info("插入数据的JSON:" + request.getBody());
ResponseEntity<String> response = restTemplate.postForEntity(url, request, String.class);
return response.getBody();
} catch (Exception e) {
System.err.println("插入记录时发生异常: " + e.getMessage());
log.error("插入记录时发生异常: " + e.getMessage());
e.printStackTrace();
return "插入记录时发生异常: " + e.getMessage();
}
......
......@@ -30,7 +30,7 @@
a.fd_3b05ade863b120 AS "开票金额",
date_format(a.fd_3afa7c1b153ff8, '%Y-%m-%d') AS "开票时间",
date_format(a.fd_3afa7c1b153ff8, '%Y-%m') AS "开票月份",
a.fd_3afac373e38ec4 AS "购买名称",
a.fd_3afac373e38ec4 AS "购买名称",
a.fd_3b0f037ecc0ed0 AS "发票状态",
a.fd_3b1bb0ccc14760 AS "红冲状态",
concat(
......@@ -39,7 +39,8 @@
ifnull(a.fd_3afac373e38ec4, ''),
'&amp;',
ifnull(date_format(a.fd_3afa7c1b153ff8, '%Y-%m'), '')
) AS "发票号&amp;购买方名称&amp;开票月份组合"
) AS "发票号&amp;购买方名称&amp;开票月份组合",
date_format(b.doc_create_time, '%Y-%m-%d') AS "创建时间"
FROM ekp_bacdf3a32d242279ceb6 a
LEFT JOIN modeling_simple_main b ON a.fd_id = b.fd_id
<where>
......@@ -72,12 +73,12 @@
FROM
ekp_0103c453b2848c3bb31c a
LEFT JOIN sys_org_element b ON a.fd_3b1141597b4894 = b.fd_id
<where>
<where> 1=1 ORDER BY a.fd_3ade33763baa0e DESC
<if test="limitStart != null and limitEnd != null">
limit #{limitStart},#{limitEnd}
</if>
</where>
ORDER BY a.fd_3ade33763baa0e DESC
</select>
<select id="selectContractListCount" resultType="java.lang.Integer">
SELECT
......
......@@ -105,4 +105,15 @@ public class EkpTask {
,"/zhaoHang/inner/doGetZhaoHangInfo","", Object.class, SecurityConstants.FROM_IN);
log.info("------------每天获取招行卡流水-定时任务结束------------");
}
/**
* @Author fxj
* @Description 微智能表格数据-定时任务
* @Date 9:41 2025/10/9
**/
public void wxExcelApi() {
log.info("------------定时生成企微智能表格数据-定时任务开始------------");
HttpDaprUtil.invokeMethodPost(daprEkpProperties.getAppUrl(),daprEkpProperties.getAppId(),"/qwExcelApi/inner/wxExcelApi","", Object.class, SecurityConstants.FROM_IN);
log.info("------------定时生成企微智能表格数据-定时任务结束------------");
}
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment