package org.jeecg.modules.demo.contract.controller; import com.alibaba.excel.EasyExcel; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.toolkit.SerializationUtils; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import io.undertow.util.Headers; import jakarta.servlet.http.HttpServletRequest; import kong.unirest.Unirest; import lombok.extern.slf4j.Slf4j; import org.apache.commons.beanutils.BeanUtils; import org.apache.commons.lang.StringUtils; import org.apache.shiro.authz.annotation.RequiresPermissions; import org.jeecg.common.api.vo.Result; import org.jeecg.modules.demo.contract.entity.Contract; import org.jeecg.modules.demo.contract.entity.ExcelDataDTO; import org.jeecg.modules.demo.contract.entity.SemanticWord; import org.jeecg.modules.demo.contract.service.IContractService; import org.jeecg.modules.demo.contract.service.ISemanticWordService; import org.jeecg.modules.demo.copywriting.controller.CopywritingAsyncService; import org.jeecg.modules.demo.copywriting.entity.Copywriting; import org.jeecg.modules.demo.copywriting.service.ICopywritingService; import org.jeecg.modules.listener.ExcelDataListener; import org.jeecg.modules.system.entity.SysUser; import org.jeecg.modules.system.service.ISysUserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.net.http.HttpResponse; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.List; import java.util.Random; /** * 适配新Excel列的导入接口控制器 */ @RestController @RequestMapping("/api/excel") @Slf4j public class ExcelImportController { @Autowired private ISysUserService sysUserService; @Autowired private ISemanticWordService semanticWordService; @Autowired private IContractService contractService; @Autowired public ICopywritingService copywritingService; /** * Excel文件导入接口(适配大类、品牌等五列) * @return 导入结果 */ @RequiresPermissions("contract:contract:importContract") @PostMapping("/importContract") public Result importExcel(@RequestPart SemanticWord importParam, @RequestPart MultipartFile file, HttpServletRequest req) { // 1. 文件基础校验 if (file.isEmpty()) { return Result.error("上传的文件不能为空"); } String fileName = file.getOriginalFilename(); if (fileName == null || (!fileName.endsWith(".xlsx") && !fileName.endsWith(".xls"))) { return Result.error("仅支持上传Excel文件(.xlsx/.xls)"); } // 2. 解析Excel文件 ExcelDataListener listener = new ExcelDataListener(); try { EasyExcel.read(file.getInputStream(), ExcelDataDTO.class, listener) .sheet() // 读取第一个sheet(如需指定sheet,可传sheet名称/索引,如.sheet("数据sheet")) .doRead(); // 3. 获取解析后的数据,可执行业务逻辑 List dataList = listener.getDataList(); dataList.remove(0); List semanticWords = new ArrayList<>(); int i = 0; for (ExcelDataDTO data : dataList) { LambdaQueryWrapper sem = new LambdaQueryWrapper<>(); sem.eq(SemanticWord::getContractId, importParam.getContractId()); sem.eq(SemanticWord::getWord, data.getLeakWord()); sem.eq(SemanticWord::getOutWord, data.getSemanticQuestion()); long count = semanticWordService.count(sem); if (count > 0) { i ++; } else { SemanticWord copy = new SemanticWord(); BeanUtils.copyProperties(copy, importParam); copy.setContractId(importParam.getContractId()); copy.setBrand(data.getBrand()); copy.setCategoryOne(data.getCategory()); copy.setWord(data.getSemanticQuestion()); copy.setOutWord(data.getLeakWord()); QueryWrapper qw = new QueryWrapper(); qw.eq("realName", data.getCreator()); Page result = (Page) sysUserService.queryPageList(req, qw, 2, 1).getResult(); if (result.getTotal() != 1) { return Result.error("未查询到用户:" + data.getCreator()); } String userId = ((SysUser)(result).getRecords().get(0)).getId(); copy.setChanger(userId); semanticWords.add(copy); } } semanticWordService.saveBatch(semanticWords); Contract contract = new Contract(); contract.setId(importParam.getContractId()); contract.setIsImportStatus("1"); contractService.updateById(contract); // 示例:调用Service保存数据(替换为你的实际业务逻辑) // excelDataService.saveBatch(dataList); return Result.ok("Excel导入成功!共导入" + (dataList.size() - i) + "条数据,重复" + i + "条数据"); } catch (IOException e) { log.error("文件读取失败", e); return Result.error("文件读取失败:" + e.getMessage()); } catch (RuntimeException e) { log.error("数据解析失败", e); return Result.error("数据解析失败:" + e.getMessage()); } catch (InvocationTargetException e) { throw new RuntimeException(e); } catch (IllegalAccessException e) { throw new RuntimeException(e); } } @Autowired private CopywritingAsyncService copywritingAsyncService; @RequiresPermissions("contract:contract:batchGenerateCopy") @RequestMapping(value = "/batchGenerateCopy", method = RequestMethod.POST) public Result batchGenerateCopy(@RequestBody ContractParam cp) { if (cp.getContractId().isEmpty()) { return Result.error("文案编号不能为空"); } else if (cp.getFileName().isEmpty()) { return Result.error("文件不能为空"); } else if (cp.getYoushang().isEmpty()) { return Result.error("友商不能为空"); } else if (cp.getAuditor().isEmpty() || cp.getAuditorName().isEmpty()) { return Result.error("用户不能为空"); } QueryWrapper semanticWordQueryWrapper = new QueryWrapper<>(); semanticWordQueryWrapper.eq("contract_id", cp.getContractId()); List list = semanticWordService.list(semanticWordQueryWrapper); if (list.isEmpty()) { return Result.error("该合同不存在语义词"); } else { // 调用异步方法执行实际生成逻辑 copywritingAsyncService.asyncBatchGenerateCopy( cp.getContractId(), list, cp.getFileName(), cp.getYoushang(), cp.getBenchmarkUrl(),cp.getAuditor(), cp.getAuditorName() ); // 立即返回响应,不等待生成完成 return Result.OK("开始生成,任务已提交至后台处理"); } } public static String getRandomElementFromArray(String[] strArray) { // 1. 校验数组合法性:空数组/Null直接返回null,避免异常 if (strArray == null || strArray.length == 0) { return null; } // 2. 创建随机数生成器,生成0到数组长度-1的随机索引 Random random = new Random(); int randomIndex = random.nextInt(strArray.length); // 3. 根据随机索引返回对应元素 return strArray[randomIndex]; } private static final DateTimeFormatter DEFAULT_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); /** * 方法1:返回当前时间的完整格式化字符串(yyyy-MM-dd HH:mm:ss) * @return 格式化后的时间字符串,如:2026-02-06 20:15:30 */ public static String getCurrentTimeStr() { return LocalDateTime.now().format(DEFAULT_FORMATTER); } @RequiresPermissions("contract:contract:batchPublish") @PostMapping("/batchPublish") public Result batchPublish(@RequestParam("contractId") String contractId) { if (contractId.isEmpty()) { return Result.error("合同编号不能为空!"); } String[] arr = new String[]{"14457","28879","20838"}; QueryWrapper wrapper = new QueryWrapper<>(); // 手动拼接 LEFT JOIN 和筛选条件 wrapper.select("copywriting.*") .inSql("word_id", // 使用正确的关联字段 word_id "SELECT id FROM semantic_word WHERE contract_id = '" + contractId + "'"); wrapper.isNull("order_nid"); wrapper.eq("status",3); List copywritingList = copywritingService.list(wrapper); if (copywritingList.isEmpty()) { return Result.error("该合同不存在状态为审核可发稿的文案"); } for (Copywriting copywriting : copywritingList) { kong.unirest.HttpResponse response = Unirest.post("http://8.138.187.158:8082/api/media/send") .field("api_key", "sk_4c8f6a970de896e232909e2959254441") .field("resource_id", getRandomElementFromArray(arr)) .field("title", copywriting.getTitle()) .field("content", copywriting.getText()) .field("remark", getCurrentTimeStr()) .field("third_id", copywriting.getCreateBy()) .asString(); // 1. 校验响应状态和响应体非空 if (response != null && response.getStatus() == 200 && StringUtils.isNotBlank(response.getBody())) { // 2. 解析JSON响应体 JSONObject responseJson = JSON.parseObject(response.getBody()); // 3. 校验code是否为1(投稿成功),再提取order_nid if (responseJson.getInteger("code") == 1) { JSONObject dataObj = responseJson.getJSONObject("data"); if (dataObj != null && dataObj.containsKey("order_nid")) { // 获取order_nid(转为String,适配Copywriting的orderNid字段类型) String orderNid = dataObj.get("order_nid").toString(); // 4. 赋值并更新数据库 copywriting.setOrderNid(orderNid); copywriting.setStatus("4"); copywritingService.updateById(copywriting); } else { // 日志记录:响应体无data或order_nid字段 System.err.println("投稿成功但未获取到order_nid,响应体:" + response.getBody()); } } else { // 日志记录:接口返回非成功状态 System.err.println("投稿失败,响应体:" + response.getBody()); } } } return Result.ok("批量投稿成功!"); } }