【新增】 WPS相关提交

This commit is contained in:
DESKTOP-932OMT8\REN
2025-06-23 14:23:46 +08:00
parent bb9306dcdb
commit e1b84f4f53
28 changed files with 2729 additions and 1365 deletions

View File

@@ -13,10 +13,12 @@ import pc.exam.pp.module.judgement.service.wps_excel.JudgementWpsExcelService;
import pc.exam.pp.module.judgement.service.wps_pptx.JudgementWpsPptxService;
import pc.exam.pp.module.judgement.service.wps_word.JudgementWpsWordService;
//import pc.exam.pp.module.judgement.utils.wps_excel.vo.ExcelInfoReqVo;
import pc.exam.pp.module.judgement.utils.wps_excel.vo.ExcelInfoReqVo;
import pc.exam.pp.module.judgement.utils.wps_excel.vo.XlsxVO;
import pc.exam.pp.module.judgement.utils.wps_excel.vo.xlsx_all.XlsxAllDataReqVo;
import pc.exam.pp.module.judgement.utils.wps_excel.vo.xlsx_drawing.XlsxInfoVo;
import pc.exam.pp.module.judgement.utils.wps_excel.vo.xlsx_style.XlsxStyleVO;
import pc.exam.pp.module.judgement.utils.wps_pptx.judgementVO.JudgementReqVo;
import pc.exam.pp.module.judgement.utils.wps_pptx.vo.PptxInfoPointsVo;
import pc.exam.pp.module.judgement.utils.wps_pptx.vo.PptxInfoReqVo;
import pc.exam.pp.module.judgement.utils.wps_pptx.vo.PptxVO;
@@ -60,15 +62,6 @@ public class WpsController {
public CommonResult<List<WordInfoReqVo>> runWpsWord(String path) throws Exception {
return CommonResult.success(judgementWpsWordService.programmingWpsWord(path));
}
/**
* wps xlsx
* @return 判分
*/
@PostMapping("/runWpsPptxInfo")
public CommonResult<List<WpsPptxJudgementDto>> runWpsPptxInfo(@RequestBody List<PptxInfoPointsVo> pptxInfoPointsVos) throws Exception {
return CommonResult.success(judgementWpsPptxService.getWpsPptxInfo(pptxInfoPointsVos));
}
/**
* wps xlsx
* @return 判分
@@ -78,14 +71,24 @@ public class WpsController {
return CommonResult.success(judgementWpsPptxService.programmingWpsPptx(path));
}
/**
* wps xlsx
* @return 判分
*/
@PostMapping("/runTestpptx")
public CommonResult<List<WpsPptxJudgementDto>> runTestpptx(@RequestBody List<JudgementReqVo> judgementReq, String path) throws Exception {
return CommonResult.success(judgementWpsPptxService.judgementWpsPptx(judgementReq, path));
}
// /**
// * wps xlsx
// * @return 判分
// */
// @GetMapping("/runWpsXlsx")
// public CommonResult<List<ExcelInfoReqVo>> runWpsXlsx(String path) throws Exception {
// return CommonResult.success(judgementWpsExcelService.programmingWpsExcel(path));
// }
/**
* wps xlsx
* @return 判分
*/
@GetMapping("/runWpsXlsx")
public CommonResult<List<XlsxInfoVo>> runWpsXlsx(String path) throws Exception {
return CommonResult.success(judgementWpsExcelService.programmingWpsExcel(path));
}
}

View File

@@ -1,75 +1,75 @@
package pc.exam.pp.module.judgement.controller.admin.Wps;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import pc.exam.pp.framework.common.enums.CommonStatusEnum;
import pc.exam.pp.framework.common.pojo.CommonResult;
import pc.exam.pp.framework.common.util.object.BeanUtils;
import pc.exam.pp.module.judgement.controller.admin.Wps.vo.*;
import pc.exam.pp.module.judgement.dal.dataobject.wpsxlsx.WpsXlsxLinkDO;
import pc.exam.pp.module.judgement.service.wps_excel.WpsXlsxLinkService;
import java.util.List;
import static pc.exam.pp.framework.common.pojo.CommonResult.success;
@Tag(name = "管理后台 - wps_xlsx")
@RestController
@RequestMapping("/wps/xlsx")
@Validated
public class XlsxController {
@Resource
private WpsXlsxLinkService wpsXlsxLinkService;
@PostMapping("create")
@Operation(summary = "创建wps_xlsx")
public CommonResult<Long> createXlsx(@Valid @RequestBody XlsxSaveReqVO createReqVO) {
Long xlsxId = wpsXlsxLinkService.createXlsx(createReqVO);
return success(xlsxId);
}
@PutMapping("update")
@Operation(summary = "更新wps_xlsx")
public CommonResult<Boolean> updateXlsx(@Valid @RequestBody XlsxSaveReqVO updateReqVO) {
wpsXlsxLinkService.updateXlsx(updateReqVO);
return success(true);
}
@DeleteMapping("delete")
@Operation(summary = "删除wps_xlsx")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
public CommonResult<Boolean> deleteXlsx(@RequestParam("id") Long id) {
wpsXlsxLinkService.deleteXlsx(id);
return success(true);
}
@GetMapping("/list")
@Operation(summary = "获取wps_xlsx列表")
public CommonResult<List<XlsxRespVO>> getXlsxList(XlsxListReqVO reqVO) {
List<WpsXlsxLinkDO> list = wpsXlsxLinkService.getXlsxList(reqVO);
return success(BeanUtils.toBean(list, XlsxRespVO.class));
}
@GetMapping(value = {"/list-all-simple", "/simple-list"})
@Operation(summary = "获取wps_xlsx精简信息列表", description = "只包含被开启的wps_xlsx主要用于前端的下拉选项")
public CommonResult<List<XlsxSimpleRespVO>> getSimpleXlsxList() {
List<WpsXlsxLinkDO> list = wpsXlsxLinkService.getXlsxList(
new XlsxListReqVO().setStatus(CommonStatusEnum.ENABLE.getStatus()));
return success(BeanUtils.toBean(list, XlsxSimpleRespVO.class));
}
@GetMapping("/get")
@Operation(summary = "获得wps_xlsx信息")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
public CommonResult<XlsxRespVO> getPptx(@RequestParam("id") Long id) {
WpsXlsxLinkDO xlsx = wpsXlsxLinkService.getXlsx(id);
return success(BeanUtils.toBean(xlsx, XlsxRespVO.class));
}
}
//package pc.exam.pp.module.judgement.controller.admin.Wps;
//
//import io.swagger.v3.oas.annotations.Operation;
//import io.swagger.v3.oas.annotations.Parameter;
//import io.swagger.v3.oas.annotations.tags.Tag;
//import jakarta.annotation.Resource;
//import jakarta.validation.Valid;
//import org.springframework.validation.annotation.Validated;
//import org.springframework.web.bind.annotation.*;
//import pc.exam.pp.framework.common.enums.CommonStatusEnum;
//import pc.exam.pp.framework.common.pojo.CommonResult;
//import pc.exam.pp.framework.common.util.object.BeanUtils;
//import pc.exam.pp.module.judgement.controller.admin.Wps.vo.*;
//import pc.exam.pp.module.judgement.dal.dataobject.wpsxlsx.WpsXlsxLinkDO;
//import pc.exam.pp.module.judgement.service.wps_excel.WpsXlsxLinkService;
//
//import java.util.List;
//
//import static pc.exam.pp.framework.common.pojo.CommonResult.success;
//
//@Tag(name = "管理后台 - wps_xlsx")
//@RestController
//@RequestMapping("/wps/xlsx")
//@Validated
//public class XlsxController {
//
// @Resource
// private WpsXlsxLinkService wpsXlsxLinkService;
//
// @PostMapping("create")
// @Operation(summary = "创建wps_xlsx")
// public CommonResult<Long> createXlsx(@Valid @RequestBody XlsxSaveReqVO createReqVO) {
// Long xlsxId = wpsXlsxLinkService.createXlsx(createReqVO);
// return success(xlsxId);
// }
//
// @PutMapping("update")
// @Operation(summary = "更新wps_xlsx")
// public CommonResult<Boolean> updateXlsx(@Valid @RequestBody XlsxSaveReqVO updateReqVO) {
// wpsXlsxLinkService.updateXlsx(updateReqVO);
// return success(true);
// }
//
// @DeleteMapping("delete")
// @Operation(summary = "删除wps_xlsx")
// @Parameter(name = "id", description = "编号", required = true, example = "1024")
// public CommonResult<Boolean> deleteXlsx(@RequestParam("id") Long id) {
// wpsXlsxLinkService.deleteXlsx(id);
// return success(true);
// }
//
// @GetMapping("/list")
// @Operation(summary = "获取wps_xlsx列表")
// public CommonResult<List<XlsxRespVO>> getXlsxList(XlsxListReqVO reqVO) {
// List<WpsXlsxLinkDO> list = wpsXlsxLinkService.getXlsxList(reqVO);
// return success(BeanUtils.toBean(list, XlsxRespVO.class));
// }
//
// @GetMapping(value = {"/list-all-simple", "/simple-list"})
// @Operation(summary = "获取wps_xlsx精简信息列表", description = "只包含被开启的wps_xlsx主要用于前端的下拉选项")
// public CommonResult<List<XlsxSimpleRespVO>> getSimpleXlsxList() {
// List<WpsXlsxLinkDO> list = wpsXlsxLinkService.getXlsxList(
// new XlsxListReqVO().setStatus(CommonStatusEnum.ENABLE.getStatus()));
// return success(BeanUtils.toBean(list, XlsxSimpleRespVO.class));
// }
//
// @GetMapping("/get")
// @Operation(summary = "获得wps_xlsx信息")
// @Parameter(name = "id", description = "编号", required = true, example = "1024")
// public CommonResult<XlsxRespVO> getPptx(@RequestParam("id") Long id) {
// WpsXlsxLinkDO xlsx = wpsXlsxLinkService.getXlsx(id);
// return success(BeanUtils.toBean(xlsx, XlsxRespVO.class));
// }
//
//}

View File

@@ -461,53 +461,53 @@ public class AutoToolsServiceImpl implements AutoToolsService{
break;
}
}
if ("演示".equals(one_file.getName().split("\\.")[0])) {
if (file_one.getPath().contains("文档")) {
String judgementStrPptx = "";
SourceAndText pptxpojo = judgementWpsPptxService.judgementWpsPptx(Double.parseDouble(quScore), one_file.getPath(), file_one.getPath(), examQuestion, judgementStrPptx);
double wps_pptx_score = pptxpojo.getScore();
String judgementStr = "<p>-----------------------------------------------------------</p>";
judgementStr += "<p>试题编号" + examQuestion.getQuNum() + "</p>";
judgementStr += pptxpojo.getText();
// 通过学号+试卷ID+试题ID进行查询
StuPaperInfoDO stuPaperInfoDO = stuPaperInfoService.findByStuIDAndPaperIdAndExamId(stuId, paperId, examQuestion.getQuId());
if (stuPaperInfoDO != null) {
stuPaperInfoDO.setContent(judgementStr);
stuPaperInfoDO.setSort(stuPaperScoreDO.getSort());
stuPaperInfoService.updateStuPaperInfo(stuPaperInfoDO);
} else {
stuPaperInfoDO = new StuPaperInfoDO();
stuPaperInfoDO.setStuId(stuId);
stuPaperInfoDO.setPaperId(paperId);
stuPaperInfoDO.setQuId(examQuestion.getQuId());
stuPaperInfoDO.setContent(judgementStr);
stuPaperInfoDO.setSort(stuPaperScoreDO.getSort());
stuPaperInfoService.insertStuPaperInfo(stuPaperInfoDO);
}
score += wps_pptx_score;
stuPaperScoreDO.setScore(new BigDecimal(wps_pptx_score));
// 原始正确分数
stuPaperScoreDO.setTrueScore(new BigDecimal(quScore));
// 判断题是否正确
if (wps_pptx_score == Double.parseDouble(quScore)) {
stuPaperScoreDO.setIsTrue(0);
} else if (wps_pptx_score == 0) {
stuPaperScoreDO.setIsTrue(1);
} else {
stuPaperScoreDO.setIsTrue(2);
}
stuPaperScoreDO.setSubjectName(examQuestion.getSubjectName());
if (isNull) {
// 如果之前没做过,则插入该题的分数
stuPaperScoreService.insertStuPaperScore(stuPaperScoreDO);
} else {
// 如果之前做过,则更新该题的分数
stuPaperScoreService.updateStuPaperScore(stuPaperScoreDO);
}
System.out.println(wps_pptx_score+"wps_ppt得分");
break;
}
}
// if ("演示".equals(one_file.getName().split("\\.")[0])) {
// if (file_one.getPath().contains("文档")) {
// String judgementStrPptx = "";
// SourceAndText pptxpojo = judgementWpsPptxService.judgementWpsPptx(Double.parseDouble(quScore), one_file.getPath(), file_one.getPath(), examQuestion, judgementStrPptx);
// double wps_pptx_score = pptxpojo.getScore();
// String judgementStr = "<p>-----------------------------------------------------------</p>";
// judgementStr += "<p>试题编号" + examQuestion.getQuNum() + "</p>";
// judgementStr += pptxpojo.getText();
// // 通过学号+试卷ID+试题ID进行查询
// StuPaperInfoDO stuPaperInfoDO = stuPaperInfoService.findByStuIDAndPaperIdAndExamId(stuId, paperId, examQuestion.getQuId());
// if (stuPaperInfoDO != null) {
// stuPaperInfoDO.setContent(judgementStr);
// stuPaperInfoDO.setSort(stuPaperScoreDO.getSort());
// stuPaperInfoService.updateStuPaperInfo(stuPaperInfoDO);
// } else {
// stuPaperInfoDO = new StuPaperInfoDO();
// stuPaperInfoDO.setStuId(stuId);
// stuPaperInfoDO.setPaperId(paperId);
// stuPaperInfoDO.setQuId(examQuestion.getQuId());
// stuPaperInfoDO.setContent(judgementStr);
// stuPaperInfoDO.setSort(stuPaperScoreDO.getSort());
// stuPaperInfoService.insertStuPaperInfo(stuPaperInfoDO);
// }
// score += wps_pptx_score;
// stuPaperScoreDO.setScore(new BigDecimal(wps_pptx_score));
// // 原始正确分数
// stuPaperScoreDO.setTrueScore(new BigDecimal(quScore));
// // 判断题是否正确
// if (wps_pptx_score == Double.parseDouble(quScore)) {
// stuPaperScoreDO.setIsTrue(0);
// } else if (wps_pptx_score == 0) {
// stuPaperScoreDO.setIsTrue(1);
// } else {
// stuPaperScoreDO.setIsTrue(2);
// }
// stuPaperScoreDO.setSubjectName(examQuestion.getSubjectName());
// if (isNull) {
// // 如果之前没做过,则插入该题的分数
// stuPaperScoreService.insertStuPaperScore(stuPaperScoreDO);
// } else {
// // 如果之前做过,则更新该题的分数
// stuPaperScoreService.updateStuPaperScore(stuPaperScoreDO);
// }
// System.out.println(wps_pptx_score+"wps_ppt得分");
// break;
// }
// }
// if ("表格".equals(one_file.getName().split("\\.")[0])) {
// double wps_excel_score = judgementWpsExcelService.judgementWpsXlsx(Double.parseDouble(quScore), one_file.getPath(), file_one.getPath(), examQuestion);
// score += wps_excel_score;

View File

@@ -3,6 +3,7 @@ package pc.exam.pp.module.judgement.service.wps_excel;
import pc.exam.pp.module.exam.dal.dataobject.ExamQuestion;
import pc.exam.pp.module.judgement.service.auto_tools.vo.SourceAndText;
import pc.exam.pp.module.judgement.utils.wps_excel.vo.XlsxVO;
import pc.exam.pp.module.judgement.utils.wps_excel.vo.xlsx_all.XlsxAllDataReqVo;
import pc.exam.pp.module.judgement.utils.wps_excel.vo.xlsx_drawing.XlsxInfoVo;
@@ -27,5 +28,5 @@ public interface JudgementWpsExcelService {
*/
List<XlsxInfoVo> programmingWpsExcel(String path) throws Exception;
double judgementWpsXlsx(double sorce, String pathC, String path, ExamQuestion examQuestion) throws Exception;
SourceAndText judgementWpsXlsx(double sorce, String pathC, String path, ExamQuestion examQuestion, String judgementStr) throws Exception;
}

View File

@@ -9,24 +9,14 @@ import pc.exam.pp.module.exam.dal.dataobject.ExamQuestionAnswer;
import pc.exam.pp.module.exam.utils.file.LogFileUtils;
import pc.exam.pp.module.infra.dal.dataobject.config.ConfigDO;
import pc.exam.pp.module.infra.service.config.ConfigService;
import pc.exam.pp.module.judgement.controller.admin.Wps.vo.PptxListReqVO;
import pc.exam.pp.module.judgement.controller.admin.Wps.vo.WordListReqVO;
import pc.exam.pp.module.judgement.controller.admin.Wps.vo.XlsxListReqVO;
import pc.exam.pp.module.judgement.dal.dataobject.wpspptx.WpsPptxLinkDO;
import pc.exam.pp.module.judgement.dal.dataobject.wpsxlsx.WpsXlsxLinkDO;
import pc.exam.pp.module.judgement.dal.mysql.wpsword.WpsWordLinkMapper;
import pc.exam.pp.module.judgement.dal.mysql.wpsxlsx.WpsXlsxLinkMapper;
import pc.exam.pp.module.judgement.service.auto_tools.AutoToolsService;
import pc.exam.pp.module.judgement.service.auto_tools.vo.SourceAndText;
import pc.exam.pp.module.judgement.utils.HtmlAppender;
import pc.exam.pp.module.judgement.utils.wps_excel.WpsExcelUtils;
import pc.exam.pp.module.judgement.utils.wps_excel.vo.XlsxVO;
import pc.exam.pp.module.judgement.utils.wps_excel.vo.xlsx_all.XlsxAllDataReqVo;
import pc.exam.pp.module.judgement.utils.wps_excel.vo.xlsx_drawing.XlsxInfoVo;
import pc.exam.pp.module.judgement.utils.wps_excel.vo.xlsx_style.XlsxStyleVO;
import pc.exam.pp.module.judgement.utils.wps_pptx.WpsPptxUtils;
import pc.exam.pp.module.judgement.utils.wps_pptx.vo.PptxVO;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.List;
@Service
@@ -55,7 +45,8 @@ public class JudgementWpsExcelServiceImpl implements JudgementWpsExcelService {
}
@Override
public double judgementWpsXlsx(double sorce, String pathC, String path, ExamQuestion examQuestion) throws Exception {
public SourceAndText judgementWpsXlsx(double sorce, String pathC, String path, ExamQuestion examQuestion, String judgementStr) throws Exception {
SourceAndText sourceAndText = new SourceAndText();
// 1创建log文件txt用于记录
File pathCDir = new File(pathC);
File parentDir = pathCDir.getParentFile();
@@ -64,6 +55,7 @@ public class JudgementWpsExcelServiceImpl implements JudgementWpsExcelService {
String targetFilePath = new File(parentDir, "WPS_Xlsx判分过程.txt").getPath();
LogFileUtils.createFile(targetFilePath);
LogFileUtils.writeLine("✅ 开始WPS_Xlsx判分");
judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "✅ 开始WPS_Xlsx判分");
double wpsXlsxScore = 0;
List<XlsxInfoVo> margins = WpsExcelUtils.wpsExcel(path);
// 3、获取答案得组成
@@ -92,13 +84,18 @@ public class JudgementWpsExcelServiceImpl implements JudgementWpsExcelService {
wpsXlsxScore += one_sorce;
if (flag) {
LogFileUtils.writeLine("" + examQuestionAnswer.getContentIn() + " 得分成功,得分:" + one_sorce);
judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "" + examQuestionAnswer.getContentIn() + " 得分成功,得分:" + one_sorce);
} else {
LogFileUtils.writeLine("" + examQuestionAnswer.getContentIn() + " 得分失败");
judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "" + examQuestionAnswer.getContentIn() + " 得分失败");
}
}
LogFileUtils.writeLine("✅ 结束WPS_Xlsx判分试题得分" + wpsXlsxScore);
judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "✅ 结束WPS_Xlsx判分试题得分" + wpsXlsxScore);
sourceAndText.setText(judgementStr);
sourceAndText.setScore(wpsXlsxScore);
// 关闭已经打开得文件
LogFileUtils.close();
return wpsXlsxScore;
return sourceAndText;
}
}

View File

@@ -1,115 +1,112 @@
package pc.exam.pp.module.judgement.service.wps_excel;
import pc.exam.pp.framework.common.util.collection.CollectionUtils;
import pc.exam.pp.module.judgement.controller.admin.Wps.vo.PptxListReqVO;
import pc.exam.pp.module.judgement.controller.admin.Wps.vo.PptxSaveReqVO;
import pc.exam.pp.module.judgement.controller.admin.Wps.vo.XlsxListReqVO;
import pc.exam.pp.module.judgement.controller.admin.Wps.vo.XlsxSaveReqVO;
import pc.exam.pp.module.judgement.dal.dataobject.wpspptx.WpsPptxLinkDO;
import pc.exam.pp.module.judgement.dal.dataobject.wpsxlsx.WpsXlsxLinkDO;
import pc.exam.pp.module.judgement.utils.tree.vo.TreeVO;
import java.util.*;
/**
* 节点 Service 接口
*
* @author 朋辰
*/
public interface WpsXlsxLinkService {
/**
* 创建节点
*
* @param createReqVO 节点信息
* @return 节点编号
*/
Long createXlsx(XlsxSaveReqVO createReqVO);
/**
* 更新节点
*
* @param updateReqVO 节点信息
*/
void updateXlsx(XlsxSaveReqVO updateReqVO);
/**
* 删除节点
*
* @param id 节点编号
*/
void deleteXlsx(Long id);
/**
* 获得节点信息
*
* @param id 节点编号
* @return 节点信息
*/
WpsXlsxLinkDO getXlsx(Long id);
/**
* 获得节点信息数组
*
* @param ids 节点编号数组
* @return 节点信息数组
*/
List<WpsXlsxLinkDO> getXlsxList(Collection<Long> ids);
/**
* 筛选节点列表
*
* @param reqVO 筛选条件请求 VO
* @return 节点列表
*/
List<WpsXlsxLinkDO> getXlsxList(XlsxListReqVO reqVO);
/**
* 获得指定编号的节点 Map
*
* @param ids 节点编号数组
* @return 节点 Map
*/
default Map<Long, WpsXlsxLinkDO> getXlsxMap(Collection<Long> ids) {
List<WpsXlsxLinkDO> list = getXlsxList(ids);
return CollectionUtils.convertMap(list, WpsXlsxLinkDO::getId);
}
/**
* 获得指定节点的所有子节点
*
* @param id 节点编号
* @return 子节点列表
*/
default List<WpsXlsxLinkDO> getChildXlsxList(Long id) {
return getChildXlsxList(Collections.singleton(id));
}
/**
* 获得指定节点的所有子节点
*
* @param ids 节点编号数组
* @return 子节点列表
*/
List<WpsXlsxLinkDO> getChildXlsxList(Collection<Long> ids);
/**
* 获得所有子节点,从缓存中
*
* @param id 父节点编号
* @return 子节点列表
*/
Set<Long> getChildXlsxIdListFromCache(Long id);
/**
* 校验节点们是否有效。如下情况,视为无效:
* 1. 节点编号不存在
* 2. 节点被禁用
*
* @param ids 角色编号数组
*/
void validateXlsxList(Collection<Long> ids);
List<TreeVO> getXlsxTreeList();
}
//package pc.exam.pp.module.judgement.service.wps_excel;
//
//import pc.exam.pp.framework.common.util.collection.CollectionUtils;
//import pc.exam.pp.module.judgement.controller.admin.Wps.vo.XlsxListReqVO;
//import pc.exam.pp.module.judgement.controller.admin.Wps.vo.XlsxSaveReqVO;
//import pc.exam.pp.module.judgement.dal.dataobject.wpsxlsx.WpsXlsxLinkDO;
//import pc.exam.pp.module.judgement.utils.tree.vo.TreeVO;
//
//import java.util.*;
//
///**
// * 节点 Service 接口
// *
// * @author 朋辰
// */
//public interface WpsXlsxLinkService {
//
// /**
// * 创建节点
// *
// * @param createReqVO 节点信息
// * @return 节点编号
// */
// Long createXlsx(XlsxSaveReqVO createReqVO);
//
// /**
// * 更新节点
// *
// * @param updateReqVO 节点信息
// */
// void updateXlsx(XlsxSaveReqVO updateReqVO);
//
// /**
// * 删除节点
// *
// * @param id 节点编号
// */
// void deleteXlsx(Long id);
//
// /**
// * 获得节点信息
// *
// * @param id 节点编号
// * @return 节点信息
// */
// WpsXlsxLinkDO getXlsx(Long id);
//
// /**
// * 获得节点信息数组
// *
// * @param ids 节点编号数组
// * @return 节点信息数组
// */
// List<WpsXlsxLinkDO> getXlsxList(Collection<Long> ids);
//
// /**
// * 筛选节点列表
// *
// * @param reqVO 筛选条件请求 VO
// * @return 节点列表
// */
// List<WpsXlsxLinkDO> getXlsxList(XlsxListReqVO reqVO);
//
// /**
// * 获得指定编号的节点 Map
// *
// * @param ids 节点编号数组
// * @return 节点 Map
// */
// default Map<Long, WpsXlsxLinkDO> getXlsxMap(Collection<Long> ids) {
// List<WpsXlsxLinkDO> list = getXlsxList(ids);
// return CollectionUtils.convertMap(list, WpsXlsxLinkDO::getId);
// }
//
// /**
// * 获得指定节点的所有子节点
// *
// * @param id 节点编号
// * @return 子节点列表
// */
// default List<WpsXlsxLinkDO> getChildXlsxList(Long id) {
// return getChildXlsxList(Collections.singleton(id));
// }
//
// /**
// * 获得指定节点的所有子节点
// *
// * @param ids 节点编号数组
// * @return 子节点列表
// */
// List<WpsXlsxLinkDO> getChildXlsxList(Collection<Long> ids);
//
// /**
// * 获得所有子节点,从缓存中
// *
// * @param id 父节点编号
// * @return 子节点列表
// */
// Set<Long> getChildXlsxIdListFromCache(Long id);
//
// /**
// * 校验节点们是否有效。如下情况,视为无效:
// * 1. 节点编号不存在
// * 2. 节点被禁用
// *
// * @param ids 角色编号数组
// */
// void validateXlsxList(Collection<Long> ids);
//
// List<TreeVO> getXlsxTreeList();
//
//}

View File

@@ -1,228 +1,228 @@
package pc.exam.pp.module.judgement.service.wps_excel;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.google.common.annotations.VisibleForTesting;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import pc.exam.pp.framework.common.enums.CommonStatusEnum;
import pc.exam.pp.framework.common.util.object.BeanUtils;
import pc.exam.pp.framework.datapermission.core.annotation.DataPermission;
import pc.exam.pp.framework.tenant.core.aop.TenantIgnore;
import pc.exam.pp.module.judgement.controller.admin.Wps.vo.XlsxListReqVO;
import pc.exam.pp.module.judgement.controller.admin.Wps.vo.XlsxSaveReqVO;
import pc.exam.pp.module.judgement.dal.dataobject.wpspptx.WpsPptxLinkDO;
import pc.exam.pp.module.judgement.dal.dataobject.wpsxlsx.WpsXlsxLinkDO;
import pc.exam.pp.module.judgement.dal.mysql.wpsxlsx.WpsXlsxLinkMapper;
import pc.exam.pp.module.judgement.utils.tree.vo.TreeVO;
import pc.exam.pp.module.system.dal.redis.RedisKeyConstants;
import java.util.*;
import static pc.exam.pp.framework.common.exception.util.ServiceExceptionUtil.exception;
import static pc.exam.pp.framework.common.util.collection.CollectionUtils.convertSet;
import static pc.exam.pp.module.system.enums.ErrorCodeConstants.*;
/**
* 节点 Service 实现类
*
*/
@Service
@Validated
@Slf4j
public class WpsXlsxLinkServiceImpl implements WpsXlsxLinkService {
@Resource
private WpsXlsxLinkMapper wpsXlsxLinkMapper;
@Override
@CacheEvict(cacheNames = RedisKeyConstants.WPS_XLSX_CHILDREN_ID_LIST,
allEntries = true) // allEntries 清空所有缓存,因为操作一个节点,涉及到多个缓存
public Long createXlsx(XlsxSaveReqVO createReqVO) {
if (createReqVO.getParentId() == null) {
createReqVO.setParentId(WpsPptxLinkDO.PARENT_ID_ROOT);
}
// 校验父节点的有效性
validateParentXlsx(null, createReqVO.getParentId());
// 校验节点名的唯一性
validateXlsxNameUnique(null, createReqVO.getParentId(), createReqVO.getName());
// 插入节点
WpsXlsxLinkDO wpsXlsxLinkDO = BeanUtils.toBean(createReqVO, WpsXlsxLinkDO.class);
wpsXlsxLinkMapper.insert(wpsXlsxLinkDO);
return wpsXlsxLinkDO.getId();
}
@Override
@CacheEvict(cacheNames = RedisKeyConstants.WPS_XLSX_CHILDREN_ID_LIST,
allEntries = true) // allEntries 清空所有缓存,因为操作一个节点,涉及到多个缓存
public void updateXlsx(XlsxSaveReqVO updateReqVO) {
if (updateReqVO.getParentId() == null) {
updateReqVO.setParentId(WpsPptxLinkDO.PARENT_ID_ROOT);
}
// 校验自己存在
validateXlsxExists(updateReqVO.getId());
// 校验父节点的有效性
validateParentXlsx(updateReqVO.getId(), updateReqVO.getParentId());
// 校验节点名的唯一性
validateXlsxNameUnique(updateReqVO.getId(), updateReqVO.getParentId(), updateReqVO.getName());
// 更新节点
WpsXlsxLinkDO updateObj = BeanUtils.toBean(updateReqVO, WpsXlsxLinkDO.class);
wpsXlsxLinkMapper.updateById(updateObj);
}
@Override
@CacheEvict(cacheNames = RedisKeyConstants.WPS_XLSX_CHILDREN_ID_LIST,
allEntries = true) // allEntries 清空所有缓存,因为操作一个节点,涉及到多个缓存
public void deleteXlsx(Long id) {
// 校验是否存在
validateXlsxExists(id);
// 校验是否有子节点
if (wpsXlsxLinkMapper.selectCountByParentId(id) > 0) {
throw exception(XLSX_NOT_FOUND);
}
// 删除节点
wpsXlsxLinkMapper.deleteById(id);
}
@VisibleForTesting
void validateXlsxExists(Long id) {
if (id == null) {
return;
}
WpsXlsxLinkDO wpsXlsxLinkDO = wpsXlsxLinkMapper.selectById(id);
if (wpsXlsxLinkDO == null) {
throw exception(XLSX_NOT_FOUND);
}
}
@VisibleForTesting
void validateParentXlsx(Long id, Long parentId) {
if (parentId == null || WpsXlsxLinkDO.PARENT_ID_ROOT.equals(parentId)) {
return;
}
// 1. 不能设置自己为父节点
if (Objects.equals(id, parentId)) {
throw exception(DEPT_PARENT_ERROR);
}
// 2. 父节点不存在
WpsXlsxLinkDO parentXlsx = wpsXlsxLinkMapper.selectById(parentId);
if (parentXlsx == null) {
throw exception(XLSX_PARENT_NOT_EXITS);
}
// 3. 递归校验父节点,如果父节点是自己的子节点,则报错,避免形成环路
// id 为空,说明新增,不需要考虑环路
if (id == null) {
return;
}
for (int i = 0; i < Short.MAX_VALUE; i++) {
// 3.1 校验环路
parentId = parentXlsx.getParentId();
if (Objects.equals(id, parentId)) {
throw exception(XLSX_PARENT_IS_CHILD);
}
// 3.2 继续递归下一级父节点
if (parentId == null || WpsPptxLinkDO.PARENT_ID_ROOT.equals(parentId)) {
break;
}
parentXlsx = wpsXlsxLinkMapper.selectById(parentId);
if (parentXlsx == null) {
break;
}
}
}
@VisibleForTesting
void validateXlsxNameUnique(Long id, Long parentId, String name) {
WpsXlsxLinkDO wpsXlsxLinkDO = wpsXlsxLinkMapper.selectByParentIdAndName(parentId, name);
if (wpsXlsxLinkDO == null) {
return;
}
// 如果 id 为空,说明不用比较是否为相同 id 的节点
if (id == null) {
throw exception(XLSX_NAME_DUPLICATE);
}
if (ObjectUtil.notEqual(wpsXlsxLinkDO.getId(), id)) {
throw exception(XLSX_NAME_DUPLICATE);
}
}
@Override
public WpsXlsxLinkDO getXlsx(Long id) {
return wpsXlsxLinkMapper.selectById(id);
}
@Override
public List<WpsXlsxLinkDO> getXlsxList(Collection<Long> ids) {
if (CollUtil.isEmpty(ids)) {
return Collections.emptyList();
}
return wpsXlsxLinkMapper.selectBatchIds(ids);
}
@Override
public List<WpsXlsxLinkDO> getXlsxList(XlsxListReqVO reqVO) {
List<WpsXlsxLinkDO> list = wpsXlsxLinkMapper.selectList(reqVO);
list.sort(Comparator.comparing(WpsXlsxLinkDO::getSort));
return list;
}
@Override
public List<WpsXlsxLinkDO> getChildXlsxList(Collection<Long> ids) {
List<WpsXlsxLinkDO> children = new LinkedList<>();
// 遍历每一层
Collection<Long> parentIds = ids;
// 使用 Short.MAX_VALUE 避免 bug 场景下,存在死循环
for (int i = 0; i < Short.MAX_VALUE; i++) {
// 查询当前层,所有的子节点
List<WpsXlsxLinkDO> xlsxs = wpsXlsxLinkMapper.selectListByParentId(parentIds);
// 1. 如果没有子节点,则结束遍历
if (CollUtil.isEmpty(xlsxs)) {
break;
}
// 2. 如果有子节点,继续遍历
children.addAll(xlsxs);
parentIds = convertSet(xlsxs, WpsXlsxLinkDO::getId);
}
return children;
}
@Override
@DataPermission(enable = false) // 禁用数据权限,避免建立不正确的缓存
@Cacheable(cacheNames = RedisKeyConstants.WPS_XLSX_CHILDREN_ID_LIST, key = "#id")
public Set<Long> getChildXlsxIdListFromCache(Long id) {
List<WpsXlsxLinkDO> children = getChildXlsxList(id);
return convertSet(children, WpsXlsxLinkDO::getId);
}
@Override
public void validateXlsxList(Collection<Long> ids) {
if (CollUtil.isEmpty(ids)) {
return;
}
// 获得科室信息
Map<Long, WpsXlsxLinkDO> xlsxMap = getXlsxMap(ids);
// 校验
ids.forEach(id -> {
WpsXlsxLinkDO xlsx = xlsxMap.get(id);
if (xlsx == null) {
throw exception(XLSX_NOT_FOUND);
}
if (!CommonStatusEnum.ENABLE.getStatus().equals(xlsx.getStatus())) {
throw exception(XLSX_NOT_ENABLE, xlsx.getName());
}
});
}
@Override
@TenantIgnore
public List<TreeVO> getXlsxTreeList() {
return wpsXlsxLinkMapper.selectTreeListByNodeFunction();
}
}
//package pc.exam.pp.module.judgement.service.wps_excel;
//
//import cn.hutool.core.collection.CollUtil;
//import cn.hutool.core.util.ObjectUtil;
//import com.google.common.annotations.VisibleForTesting;
//import jakarta.annotation.Resource;
//import lombok.extern.slf4j.Slf4j;
//import org.springframework.cache.annotation.CacheEvict;
//import org.springframework.cache.annotation.Cacheable;
//import org.springframework.stereotype.Service;
//import org.springframework.validation.annotation.Validated;
//import pc.exam.pp.framework.common.enums.CommonStatusEnum;
//import pc.exam.pp.framework.common.util.object.BeanUtils;
//import pc.exam.pp.framework.datapermission.core.annotation.DataPermission;
//import pc.exam.pp.framework.tenant.core.aop.TenantIgnore;
//import pc.exam.pp.module.judgement.controller.admin.Wps.vo.XlsxListReqVO;
//import pc.exam.pp.module.judgement.controller.admin.Wps.vo.XlsxSaveReqVO;
//import pc.exam.pp.module.judgement.dal.dataobject.wpspptx.WpsPptxLinkDO;
//import pc.exam.pp.module.judgement.dal.dataobject.wpsxlsx.WpsXlsxLinkDO;
//import pc.exam.pp.module.judgement.dal.mysql.wpsxlsx.WpsXlsxLinkMapper;
//import pc.exam.pp.module.judgement.utils.tree.vo.TreeVO;
//import pc.exam.pp.module.system.dal.redis.RedisKeyConstants;
//
//import java.util.*;
//
//import static pc.exam.pp.framework.common.exception.util.ServiceExceptionUtil.exception;
//import static pc.exam.pp.framework.common.util.collection.CollectionUtils.convertSet;
//import static pc.exam.pp.module.system.enums.ErrorCodeConstants.*;
//
///**
// * 节点 Service 实现类
// *
// */
//@Service
//@Validated
//@Slf4j
//public class WpsXlsxLinkServiceImpl implements WpsXlsxLinkService {
//
// @Resource
// private WpsXlsxLinkMapper wpsXlsxLinkMapper;
//
// @Override
// @CacheEvict(cacheNames = RedisKeyConstants.WPS_XLSX_CHILDREN_ID_LIST,
// allEntries = true) // allEntries 清空所有缓存,因为操作一个节点,涉及到多个缓存
// public Long createXlsx(XlsxSaveReqVO createReqVO) {
// if (createReqVO.getParentId() == null) {
// createReqVO.setParentId(WpsPptxLinkDO.PARENT_ID_ROOT);
// }
// // 校验父节点的有效性
// validateParentXlsx(null, createReqVO.getParentId());
// // 校验节点名的唯一性
// validateXlsxNameUnique(null, createReqVO.getParentId(), createReqVO.getName());
//
// // 插入节点
// WpsXlsxLinkDO wpsXlsxLinkDO = BeanUtils.toBean(createReqVO, WpsXlsxLinkDO.class);
// wpsXlsxLinkMapper.insert(wpsXlsxLinkDO);
// return wpsXlsxLinkDO.getId();
// }
//
// @Override
// @CacheEvict(cacheNames = RedisKeyConstants.WPS_XLSX_CHILDREN_ID_LIST,
// allEntries = true) // allEntries 清空所有缓存,因为操作一个节点,涉及到多个缓存
// public void updateXlsx(XlsxSaveReqVO updateReqVO) {
// if (updateReqVO.getParentId() == null) {
// updateReqVO.setParentId(WpsPptxLinkDO.PARENT_ID_ROOT);
// }
// // 校验自己存在
// validateXlsxExists(updateReqVO.getId());
// // 校验父节点的有效性
// validateParentXlsx(updateReqVO.getId(), updateReqVO.getParentId());
// // 校验节点名的唯一性
// validateXlsxNameUnique(updateReqVO.getId(), updateReqVO.getParentId(), updateReqVO.getName());
//
// // 更新节点
// WpsXlsxLinkDO updateObj = BeanUtils.toBean(updateReqVO, WpsXlsxLinkDO.class);
// wpsXlsxLinkMapper.updateById(updateObj);
// }
//
// @Override
// @CacheEvict(cacheNames = RedisKeyConstants.WPS_XLSX_CHILDREN_ID_LIST,
// allEntries = true) // allEntries 清空所有缓存,因为操作一个节点,涉及到多个缓存
// public void deleteXlsx(Long id) {
// // 校验是否存在
// validateXlsxExists(id);
// // 校验是否有子节点
// if (wpsXlsxLinkMapper.selectCountByParentId(id) > 0) {
// throw exception(XLSX_NOT_FOUND);
// }
// // 删除节点
// wpsXlsxLinkMapper.deleteById(id);
// }
//
// @VisibleForTesting
// void validateXlsxExists(Long id) {
// if (id == null) {
// return;
// }
// WpsXlsxLinkDO wpsXlsxLinkDO = wpsXlsxLinkMapper.selectById(id);
// if (wpsXlsxLinkDO == null) {
// throw exception(XLSX_NOT_FOUND);
// }
// }
//
// @VisibleForTesting
// void validateParentXlsx(Long id, Long parentId) {
// if (parentId == null || WpsXlsxLinkDO.PARENT_ID_ROOT.equals(parentId)) {
// return;
// }
// // 1. 不能设置自己为父节点
// if (Objects.equals(id, parentId)) {
// throw exception(DEPT_PARENT_ERROR);
// }
// // 2. 父节点不存在
// WpsXlsxLinkDO parentXlsx = wpsXlsxLinkMapper.selectById(parentId);
// if (parentXlsx == null) {
// throw exception(XLSX_PARENT_NOT_EXITS);
// }
// // 3. 递归校验父节点,如果父节点是自己的子节点,则报错,避免形成环路
// // id 为空,说明新增,不需要考虑环路
// if (id == null) {
// return;
// }
// for (int i = 0; i < Short.MAX_VALUE; i++) {
// // 3.1 校验环路
// parentId = parentXlsx.getParentId();
// if (Objects.equals(id, parentId)) {
// throw exception(XLSX_PARENT_IS_CHILD);
// }
// // 3.2 继续递归下一级父节点
// if (parentId == null || WpsPptxLinkDO.PARENT_ID_ROOT.equals(parentId)) {
// break;
// }
// parentXlsx = wpsXlsxLinkMapper.selectById(parentId);
// if (parentXlsx == null) {
// break;
// }
// }
// }
//
// @VisibleForTesting
// void validateXlsxNameUnique(Long id, Long parentId, String name) {
// WpsXlsxLinkDO wpsXlsxLinkDO = wpsXlsxLinkMapper.selectByParentIdAndName(parentId, name);
// if (wpsXlsxLinkDO == null) {
// return;
// }
// // 如果 id 为空,说明不用比较是否为相同 id 的节点
// if (id == null) {
// throw exception(XLSX_NAME_DUPLICATE);
// }
// if (ObjectUtil.notEqual(wpsXlsxLinkDO.getId(), id)) {
// throw exception(XLSX_NAME_DUPLICATE);
// }
// }
//
// @Override
// public WpsXlsxLinkDO getXlsx(Long id) {
// return wpsXlsxLinkMapper.selectById(id);
// }
//
// @Override
// public List<WpsXlsxLinkDO> getXlsxList(Collection<Long> ids) {
// if (CollUtil.isEmpty(ids)) {
// return Collections.emptyList();
// }
// return wpsXlsxLinkMapper.selectBatchIds(ids);
// }
//
// @Override
// public List<WpsXlsxLinkDO> getXlsxList(XlsxListReqVO reqVO) {
// List<WpsXlsxLinkDO> list = wpsXlsxLinkMapper.selectList(reqVO);
// list.sort(Comparator.comparing(WpsXlsxLinkDO::getSort));
// return list;
// }
//
// @Override
// public List<WpsXlsxLinkDO> getChildXlsxList(Collection<Long> ids) {
// List<WpsXlsxLinkDO> children = new LinkedList<>();
// // 遍历每一层
// Collection<Long> parentIds = ids;
// // 使用 Short.MAX_VALUE 避免 bug 场景下,存在死循环
// for (int i = 0; i < Short.MAX_VALUE; i++) {
// // 查询当前层,所有的子节点
// List<WpsXlsxLinkDO> xlsxs = wpsXlsxLinkMapper.selectListByParentId(parentIds);
// // 1. 如果没有子节点,则结束遍历
// if (CollUtil.isEmpty(xlsxs)) {
// break;
// }
// // 2. 如果有子节点,继续遍历
// children.addAll(xlsxs);
// parentIds = convertSet(xlsxs, WpsXlsxLinkDO::getId);
// }
// return children;
// }
//
// @Override
// @DataPermission(enable = false) // 禁用数据权限,避免建立不正确的缓存
// @Cacheable(cacheNames = RedisKeyConstants.WPS_XLSX_CHILDREN_ID_LIST, key = "#id")
// public Set<Long> getChildXlsxIdListFromCache(Long id) {
// List<WpsXlsxLinkDO> children = getChildXlsxList(id);
// return convertSet(children, WpsXlsxLinkDO::getId);
// }
//
// @Override
// public void validateXlsxList(Collection<Long> ids) {
// if (CollUtil.isEmpty(ids)) {
// return;
// }
// // 获得科室信息
// Map<Long, WpsXlsxLinkDO> xlsxMap = getXlsxMap(ids);
// // 校验
// ids.forEach(id -> {
// WpsXlsxLinkDO xlsx = xlsxMap.get(id);
// if (xlsx == null) {
// throw exception(XLSX_NOT_FOUND);
// }
// if (!CommonStatusEnum.ENABLE.getStatus().equals(xlsx.getStatus())) {
// throw exception(XLSX_NOT_ENABLE, xlsx.getName());
// }
// });
// }
//
// @Override
// @TenantIgnore
// public List<TreeVO> getXlsxTreeList() {
// return wpsXlsxLinkMapper.selectTreeListByNodeFunction();
// }
//
//}

View File

@@ -3,6 +3,7 @@ package pc.exam.pp.module.judgement.service.wps_pptx;
import pc.exam.pp.module.exam.dal.dataobject.ExamQuestion;
import pc.exam.pp.module.judgement.controller.admin.Wps.dto.WpsPptxJudgementDto;
import pc.exam.pp.module.judgement.service.auto_tools.vo.SourceAndText;
import pc.exam.pp.module.judgement.utils.wps_pptx.judgementVO.JudgementReqVo;
import pc.exam.pp.module.judgement.utils.wps_pptx.vo.PptxInfoPointsVo;
import pc.exam.pp.module.judgement.utils.wps_pptx.vo.PptxInfoReqVo;
import pc.exam.pp.module.judgement.utils.wps_pptx.vo.PptxVO;
@@ -16,8 +17,10 @@ import java.util.List;
public interface JudgementWpsPptxService {
List<PptxInfoReqVo> programmingWpsPptx(String path) throws Exception;
//
SourceAndText judgementWpsPptx(double sorce, String pathC, String path, ExamQuestion examQuestion, String judgementStr) throws Exception;
List<WpsPptxJudgementDto> getWpsPptxInfo(List<PptxInfoPointsVo> pptxInfoPointsVos) throws IOException;
// List<WpsPptxJudgementDto> getWpsPptxInfo(List<PptxInfoPointsVo> pptxInfoPointsVos) throws IOException;
List<WpsPptxJudgementDto> judgementWpsPptx(List<JudgementReqVo> judgementReq, String path) throws Exception;
}

View File

@@ -8,28 +8,17 @@ import pc.exam.pp.module.exam.utils.file.LogFileUtils;
import pc.exam.pp.module.infra.dal.dataobject.config.ConfigDO;
import pc.exam.pp.module.infra.service.config.ConfigService;
import pc.exam.pp.module.judgement.controller.admin.Wps.dto.WpsPptxJudgementDto;
import pc.exam.pp.module.judgement.controller.admin.Wps.vo.PptxListReqVO;
import pc.exam.pp.module.judgement.controller.admin.Wps.vo.WordListReqVO;
import pc.exam.pp.module.judgement.dal.dataobject.wpspptx.WpsPptxLinkDO;
import pc.exam.pp.module.judgement.dal.dataobject.wpsword.WpsWordLinkDO;
import pc.exam.pp.module.judgement.dal.mysql.wpspptx.WpsPptxLinkMapper;
import pc.exam.pp.module.judgement.service.auto_tools.AutoToolsService;
import pc.exam.pp.module.judgement.service.auto_tools.vo.SourceAndText;
import pc.exam.pp.module.judgement.utils.HtmlAppender;
import pc.exam.pp.module.judgement.utils.wps_pptx.WpsPptxUtils;
import pc.exam.pp.module.judgement.utils.wps_pptx.JudgementWpsPPT;
import pc.exam.pp.module.judgement.utils.wps_pptx.judgementVO.JudgementReqVo;
import pc.exam.pp.module.judgement.utils.wps_pptx.vo.PptxInfoPointsVo;
import pc.exam.pp.module.judgement.utils.wps_pptx.vo.PptxInfoReqVo;
import pc.exam.pp.module.judgement.utils.wps_pptx.vo.PptxVO;
import pc.exam.pp.module.judgement.utils.wps_word.WpsWordUtils;
import pc.exam.pp.module.judgement.utils.wps_word.vo.WordVO;
import pc.exam.pp.module.system.dal.dataobject.user.AdminUserDO;
import pc.exam.pp.module.system.service.user.AdminUserService;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
@@ -47,18 +36,21 @@ public class JudgementWpsPptxServiceImpl implements JudgementWpsPptxService {
@Resource
ConfigService configService;
@Resource
WpsPptxLinkMapper wpsPptxLinkMapper;
@Resource
private AdminUserService userService;
// @Override
// public List<WpsPptxJudgementDto> getWpsPptxInfo(List<PptxInfoPointsVo> pptxInfoPointsVos) throws IOException {
// List<WpsPptxJudgementDto> judgementDtos = WpsPptxUtils.getWpsPptxInfos(pptxInfoPointsVos);
// return judgementDtos;
// }
@Override
public List<WpsPptxJudgementDto> getWpsPptxInfo(List<PptxInfoPointsVo> pptxInfoPointsVos) throws IOException {
List<WpsPptxJudgementDto> judgementDtos = WpsPptxUtils.getWpsPptxInfos(pptxInfoPointsVos);
return judgementDtos;
public List<WpsPptxJudgementDto> judgementWpsPptx(List<JudgementReqVo> judgementReq, String path) throws Exception {
return JudgementWpsPPT.getValues(judgementReq, path);
}
@Override
public List<PptxInfoReqVo> programmingWpsPptx(String path) throws Exception {
String pathName = "";
@@ -75,7 +67,7 @@ public class JudgementWpsPptxServiceImpl implements JudgementWpsPptxService {
// }
// 4、pptx文件读取并返回考点及说明信息
// List<PptxVO> margins = WpsPptxUtils.wpsPptx(pathName, paragraphList);
List<PptxInfoReqVo> pptxInfoList = WpsPptxUtils.wpsPptxInfo(pathName);
List<PptxInfoReqVo> pptxInfoList = JudgementWpsPPT.wpsPptxInfo(pathName);
// 5、已经读取完得考点删除源文件
// File file = new File(pathName);
// file.delete();
@@ -90,26 +82,24 @@ public class JudgementWpsPptxServiceImpl implements JudgementWpsPptxService {
LogFileUtils.writeLine("✅ 开始WPS_Pptx判分");
judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "✅ 开始WPS_Pptx判分");
double wpsPptScore = 0;
List<PptxInfoPointsVo> pptxInfoPointsVos = new ArrayList<>();
List<JudgementReqVo> judgementReq = new ArrayList<>();
// 3、获取答案得组成
List<ExamQuestionAnswer> answerList = examQuestion.getAnswerList();
for (ExamQuestionAnswer examQuestionAnswer : answerList) {
PptxInfoPointsVo pptxInfoPointsVo = new PptxInfoPointsVo();
JudgementReqVo judgementReqVo = new JudgementReqVo();
// 拆分数据、
String[] pptxInfos = examQuestionAnswer.getContent().split("\\?");
String[] chineseName = examQuestionAnswer.getContentIn().split("-");
String[] typeList = examQuestionAnswer.getImage().split("-");
pptxInfoPointsVo.setName(examQuestionAnswer.getContentIn());
pptxInfoPointsVo.setEnglishName(pptxInfos[0]);
pptxInfoPointsVo.setFunction(pptxInfos[1]);
pptxInfoPointsVo.setType(typeList[0]);
pptxInfoPointsVo.setBelongTo(typeList[1]);
pptxInfoPointsVo.setIsboo(typeList[2]);
pptxInfoPointsVo.setFilePath(path);
pptxInfoPointsVos.add(pptxInfoPointsVo);
String[] pptxInfos = examQuestionAnswer.getContent().split("@!");
judgementReqVo.setFileNama(pptxInfos[0]);
judgementReqVo.setParagraph(pptxInfos[1]);
judgementReqVo.setTitle(pptxInfos[2]);
judgementReqVo.setValueList(pptxInfos[3]);
judgementReqVo.setType(pptxInfos[4]);
judgementReqVo.setIsText(pptxInfos[5]);
judgementReqVo.setIsTrue(pptxInfos[6]);
judgementReqVo.setIsParameter(pptxInfos[7]);
judgementReq.add(judgementReqVo);
}
List<WpsPptxJudgementDto> judgementDtos = WpsPptxUtils.getWpsPptxInfos(pptxInfoPointsVos);
List<WpsPptxJudgementDto> judgementDtos = JudgementWpsPPT.getValues(judgementReq, path);
// 4、进行关联判断
for (ExamQuestionAnswer examQuestionAnswer : answerList) {
boolean flag = false;
@@ -129,7 +119,7 @@ public class JudgementWpsPptxServiceImpl implements JudgementWpsPptxService {
}
wpsPptScore += one_sorce;
if (flag) {
LogFileUtils.writeLine(" " + examQuestionAnswer.getContentIn() + " 得分成功,得分:" + one_sorce);
LogFileUtils.writeLine("" + examQuestionAnswer.getContentIn() + " 得分成功,得分:" + one_sorce);
judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "" + examQuestionAnswer.getContentIn() + " 得分成功,得分:" + one_sorce);
} else {
LogFileUtils.writeLine("" + examQuestionAnswer.getContentIn() + " 得分失败");

View File

@@ -1,6 +1,5 @@
package pc.exam.pp.module.judgement.utils.tree;
import pc.exam.pp.module.judgement.dal.dataobject.wpspptx.WpsPptxLinkDO;
import pc.exam.pp.module.judgement.dal.dataobject.wpsword.WpsWordLinkDO;
import pc.exam.pp.module.judgement.dal.dataobject.wpsxlsx.WpsXlsxLinkDO;
import pc.exam.pp.module.judgement.utils.wps_word.vo.WordInfoReqVo;
@@ -56,29 +55,6 @@ public class TreeUtils {
}
return roots;
}
public static List<WpsPptxLinkDO> buildTreePptx(List<WpsPptxLinkDO> flatList) {
Map<Integer, WpsPptxLinkDO> nodeMap = new HashMap<>();
List<WpsPptxLinkDO> roots = new ArrayList<>();
// 先放入 map
for (WpsPptxLinkDO node : flatList) {
nodeMap.put(Math.toIntExact(node.getId()), node);
}
// 构建树关系
for (WpsPptxLinkDO node : flatList) {
if (node.getParentId() == 0) {
roots.add(node);
} else {
WpsPptxLinkDO parent = nodeMap.get(node.getParentId().intValue());
if (parent != null) {
parent.getChildren().add(node);
}
}
}
return roots;
}
public static List<WpsXlsxLinkDO> buildTreeXlsx(List<WpsXlsxLinkDO> flatList) {
Map<Integer, WpsXlsxLinkDO> nodeMap = new HashMap<>();
List<WpsXlsxLinkDO> roots = new ArrayList<>();

View File

@@ -14,6 +14,8 @@ import pc.exam.pp.module.judgement.utils.wps_excel.vo.*;
import pc.exam.pp.module.judgement.utils.wps_excel.vo.xlsx_chart.ChartTypeEntry;
import pc.exam.pp.module.judgement.utils.wps_excel.vo.xlsx_drawing.XlsxInfoVo;
import pc.exam.pp.module.judgement.utils.wps_excel.vo.xlsx_drawing.XlsxDrawingSheetVo;
import pc.exam.pp.module.judgement.utils.wps_pptx.vo.PptxInfoReqVo;
import pc.exam.pp.module.judgement.utils.wps_word.vo.WordInfoReqVo;
import javax.xml.namespace.QName;
import java.io.FileInputStream;
@@ -36,6 +38,73 @@ public class WpsExcelUtils {
public static int dxfId = 0;
public static String getStringRandom() {
String characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
Random random = new Random();
StringBuilder sb = new StringBuilder();
// 生成指定长度的随机字符字符串
for (int i = 0; i < 10; i++) {
int randomIndex = random.nextInt(characters.length());
// 随机字符
sb.append(characters.charAt(randomIndex));
}
return sb.toString();
}
public static List<ExcelInfoReqVo> wpsExcelInfo(String filePath) throws Exception {
List<ExcelInfoReqVo> excelInfoReqVoList = new ArrayList<>();
try (FileInputStream fis = new FileInputStream(filePath);
OPCPackage pkg = OPCPackage.open(fis);
XSSFWorkbook workbook = new XSSFWorkbook(pkg)) {
// 获取有多少个工作表
int sheetNumber = workbook.getNumberOfSheets();
String firstIdSheet = getStringRandom();
for (int i = 0; i < sheetNumber; i++) {
String secondIdSheet = getStringRandom();
// 获取工作表内容
XSSFSheet sheetXss = workbook.getSheetAt(i);
// 获取工作表的XML对象
XmlObject worksheetXml = sheetXss.getCTWorksheet();
setWordInfo("Sheet" + sheetNumber + 1, "Sheet" + sheetNumber + 1, "sheet" + sheetNumber + 1 + ".xml", filePath, secondIdSheet, firstIdSheet, excelInfoReqVoList);
// 开始查找指定得 单元格、范围、行、列、数据排序、数据透视表、表格、图标、页面、试图、属性
String thirdIdC = getStringRandom();
setWordInfo("单元格", "c", "c", filePath, thirdIdC, secondIdSheet, excelInfoReqVoList);
String thirdIdCC = getStringRandom();
setWordInfo("范围", "cc", "cc", filePath, thirdIdCC, secondIdSheet, excelInfoReqVoList);
String thirdIdRow = getStringRandom();
setWordInfo("", "row", "row", filePath, thirdIdRow, secondIdSheet, excelInfoReqVoList);
String thirdIdCol = getStringRandom();
setWordInfo("", "cols", "cols", filePath, thirdIdCol, secondIdSheet, excelInfoReqVoList);
// String thirdIdCol = getStringRandom();
// 判断是否存在图表
setWordInfo("", "cols", "cols", filePath, thirdIdCol, secondIdSheet, excelInfoReqVoList);
System.out.println(worksheetXml.xmlText());
}
} catch (IOException e) {
e.printStackTrace();
} catch (InvalidFormatException e) {
throw new RuntimeException(e);
}
return excelInfoReqVoList;
}
public static void setWordInfo(String chineseName, String englishName, String selectName, String filePath, String id, String parentId, List<ExcelInfoReqVo> excelInfoReqVos) throws Exception {
ExcelInfoReqVo excelInfos = new ExcelInfoReqVo();
excelInfos.setName(chineseName);
excelInfos.setEnglishName(englishName);
excelInfos.setFilePath(filePath);
excelInfos.setId(id);
excelInfos.setSelectName(selectName);
excelInfos.setParentId(parentId);
excelInfoReqVos.add(excelInfos);
}
public static List<XlsxInfoVo> wpsExcel(String filePath) throws Exception {
// 获取共享字符串
String[] sharedStrings = extractSharedStrings(filePath);

View File

@@ -0,0 +1,28 @@
package pc.exam.pp.module.judgement.utils.wps_excel.vo;
import lombok.Data;
import java.util.ArrayList;
import java.util.List;
/**
* @author REN
*/
@Data
public class ExcelInfoReqVo {
private String name;
private String englishName;
private String filePath;
private String parentId;
private String selectName;
private String id;
private List<ExcelInfoReqVo> children = new ArrayList<>();
}

View File

@@ -0,0 +1,40 @@
package pc.exam.pp.module.judgement.utils.wps_pptx;
/**
* @author REN
*/
public class DeclareNamespaceForPPT {
public static String getNameSpace(String titleName) {
if ("p".equals(titleName)) {
return "http://schemas.openxmlformats.org/presentationml/2006/main";
}
if ("a".equals(titleName)) {
return "http://schemas.openxmlformats.org/drawingml/2006/main";
}
if ("pic".equals(titleName)) {
return "http://schemas.openxmlformats.org/drawingml/2006/picture";
}
if ("c".equals(titleName)) {
return "http://schemas.openxmlformats.org/drawingml/2006/chart";
}
if ("dgm".equals(titleName)) {
return "http://schemas.openxmlformats.org/drawingml/2006/diagram";
}
if ("lc".equals(titleName)) {
return "http://schemas.openxmlformats.org/drawingml/2006/lockedCanvas";
}
if ("v".equals(titleName)) {
return "urn:schemas-microsoft-com:vml";
}
if ("m".equals(titleName)) {
return "http://schemas.openxmlformats.org/officeDocument/2006/math";
}
if ("mc".equals(titleName)) {
return "http://schemas.openxmlformats.org/markup-compatibility/2006";
}
if ("a14".equals(titleName)) {
return "http://schemas.microsoft.com/office/drawing/2010/main";
}
return "";
}
}

View File

@@ -0,0 +1,161 @@
package pc.exam.pp.module.judgement.utils.wps_pptx;
import java.util.List;
/**
* @author REN
*/
public class JudgementConvert {
public static String getConvert(List<String> valueList, String formula){
String value = "";
if ("NULL".equals(formula)) {
value = valueList.get(0);
} else if (formula.contains("PageSize")) {
value = pageSize(valueList.get(0), valueList.get(1));
} else if (formula.contains("timing")) {
// 查询自定义动画效果
value = getTiming(valueList.get(0), valueList.get(1));
} else if (formula.contains("Timing_filter")) {
// 动画方向查询
value = getTimingFilter(valueList.get(0));
} else if (formula.contains("Timing_Evt")) {
// 动画触发方式
value = getTimingEvt(valueList.get(0));
}
// 继续转换
return value;
}
private static String getTimingEvt(String evt) {
String evtValue = "";
if (evt.contains("onBegin")) {
if (evt.contains("downRight")) {
evtValue += "自动开始";
}
if (evt.contains("onClick")) {
evtValue += "鼠标点击时开始";
}
if (evt.contains("afterPrevious")) {
evtValue += "在上一个动画之后开始";
}
if (evt.contains("withPrevious")) {
evtValue += "与上一个动画同时开始";
}
if (evt.contains("onEnd")) {
evtValue += "在另一个动画结束时开始";
}
if (evt.contains("onNext")) {
evtValue += "在下一动画前触发";
}
if (evt.contains("onPrev")) {
evtValue += "在上一动画前触发";
}
}
return evtValue;
}
private static String getTimingFilter(String filter) {
String filterValue = "";
if (filter.contains("strips")) {
if (filter.contains("downRight")) {
filterValue += "从左上往右下飞入";
}
if (filter.contains("upLeft")) {
filterValue += "从右下往左上飞入";
}
if (filter.contains("upRight")) {
filterValue += "从左下往右上飞入";
}
if (filter.contains("downLeft")) {
filterValue += "从右上往左下飞入";
}
}
return filterValue;
}
private static String getTiming(String transition, String filter){
String transitionValue = "";
String filterValue = "";
if ("in".equals(transition)) {
transitionValue = "进入动画";
if ("fade".equals(filter)) {
filterValue = "淡入淡出";
} else if ("fly(fromLeft)".equals(filter)) {
filterValue = "飞入(从左)";
} else if ("fly(fromRight)".equals(filter)) {
filterValue = "飞入(从右)";
} else if ("fly(fromTop)".equals(filter)) {
filterValue = "飞入(从上)";
} else if ("fly(fromBottom)".equals(filter)) {
filterValue = "飞入(从下)";
} else if ("strips(downRight)".equals(filter)) {
filterValue = "条纹(右下)";
} else if ("strips(upLeft)".equals(filter)) {
filterValue = "条纹(左上)";
} else if ("checkerboard(across)".equals(filter)) {
filterValue = "棋盘格(横向)";
} else if ("wipe(right)".equals(filter)) {
filterValue = "擦除(从左向右)";
} else if ("wipe(left)".equals(filter)) {
filterValue = "擦除(从右向左)";
} else if ("randomBars(vertical)".equals(filter)) {
filterValue = "随机条形(垂直)";
} else if ("zoom".equals(filter)) {
filterValue = "缩放";
} else if ("circle(out)".equals(filter)) {
filterValue = "圆形展开";
} else if ("plus(out)".equals(filter)) {
filterValue = "十字形展开";
} else if ("diamond(out)".equals(filter)) {
filterValue = "菱形展开";
} else if ("shape(circle)".equals(filter)) {
filterValue = "使用形状(圆形)";
}
} else if ("out".equals(transition)) {
transitionValue = "退出动画";
if ("fade".equals(filter)) {
filterValue = "淡出";
} else if ("fly(toLeft)".equals(filter)) {
filterValue = "飞出(向左)";
} else if ("fly(toRight)".equals(filter)) {
filterValue = "飞出(向右)";
} else if ("strips(upLeft)".equals(filter)) {
filterValue = "条纹(左上)";
} else if ("wipe(left)".equals(filter)) {
filterValue = "擦除(向左)";
} else if ("zoom".equals(filter)) {
filterValue = "缩小";
} else if ("shape(diamond)".equals(filter)) {
filterValue = "菱形消失";
}
} else if ("emph".equals(transition)) {
transitionValue = "强调动画";
} else if ("path".equals(transition)) {
transitionValue = "动作路径动画";
}
return transitionValue + filterValue;
}
private static String pageSize(String widthTwip, String heightTwip){
// 转换为 cm1 twip = 1/1440 英寸 = 2.54 / 1440 cm
double widthCm = Double.parseDouble(widthTwip) / 360000;
double heightCm = Double.parseDouble(heightTwip) / 360000;
// 四舍五入保留一位小数
widthCm = Math.round(widthCm * 10) / 10.0;
heightCm = Math.round(heightCm * 10) / 10.0;
// 判断标准纸型(以 cm 为单位进行匹配)
String paperType = "自定义";
if (approx(widthCm, 21.0) && approx(heightCm, 29.7)) {
paperType = "A4";
} else if (approx(widthCm, 29.7) && approx(heightCm, 42.0)) {
paperType = "A3";
} else if (approx(widthCm, 14.8) && approx(heightCm, 21.0)) {
paperType = "A5";
}
return paperType;
}
private static boolean approx(double a, double b) {
return Math.abs(a - b) < 0.5; // 误差范围 0.5cm 内
}
}

View File

@@ -0,0 +1,406 @@
package pc.exam.pp.module.judgement.utils.wps_pptx;
import org.apache.commons.io.IOUtils;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.xslf.usermodel.XMLSlideShow;
import org.apache.poi.xslf.usermodel.XSLFSlide;
import org.apache.xmlbeans.XmlCursor;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlObject;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import pc.exam.pp.module.judgement.controller.admin.Wps.dto.WpsPptxJudgementDto;
import pc.exam.pp.module.judgement.utils.wps_pptx.judgementVO.JudgementReqVo;
import pc.exam.pp.module.judgement.utils.wps_pptx.vo.PptxInfoReqVo;
import pc.exam.pp.module.judgement.utils.wps_pptx.vo.PptxSlidesVo;
import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.*;
/**
* @author REN
*/
public class JudgementWpsPPT {
public static List<WpsPptxJudgementDto> getValues(List<JudgementReqVo> judgementReq, String path) throws InvalidFormatException, IOException, ParserConfigurationException, SAXException {
// 1、文件路径或者文件的属性
// 2、查找文件的属性其中字段为name firstFunction SecondFunction ThirdFunction FourthFunction isboo betong 转换
// 3、名称 标签 标签段落 值标签 关联关系 关联文件名称 )
// 4、逻辑关系 通过name查询文档数据根据标签段落查询对应的段落值再根据标签地址查询对应在查询对应的值标签外部文件暂定
// String fileNama = "presentation";
// String functions = "(//p:presentation)[1]";
// String slide = "p:sldSz";
// String values = "cx#cy";
// 创建返回值
List<WpsPptxJudgementDto> judgementList = new ArrayList<>();
for (JudgementReqVo reqVo : judgementReq) {
String chineseName = reqVo.getChineseName();
String fileNama = reqVo.getFileNama();
String paragraph = reqVo.getParagraph();
String title = reqVo.getTitle();
String values = reqVo.getValueList();
String type = reqVo.getType();
String isText = reqVo.getIsText();
String isTrue = reqVo.getIsTrue();
String isParameter = reqVo.getIsParameter();
String firstName = paragraph.split(":")[0].split("/")[paragraph.split(":")[0].split("/").length -1];
// 组合之后可能用到的考点信息
String englishName = fileNama + "@!" + paragraph + "@!" + title + "@!" + values + "@!" + type + "@!" + isText + "@!" + isTrue + "@!" + isParameter;
XmlCursor cursor = getXmlCursor(path, fileNama, null);
System.out.println(cursor.xmlText());
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
DocumentBuilder builder = factory.newDocumentBuilder();
XmlCursor slideCursor = cursor;
if (title.contains(">")) {
// 说明想要
title = title.replace(">", "");
judgementList = setData(judgementList, chineseName + "正在开发中", englishName + "正在开发中");
} else
// 当标签存在特定值得时候,不需要继续第一段得查询,直接用所有得进行查找
if (title.contains("?")) {
title = title.replace("?", "");
// 条件成立
// 获取 XML 字符串
String xmlText = slideCursor.getObject().xmlText();
InputStream is = new ByteArrayInputStream(xmlText.getBytes(StandardCharsets.UTF_8));
// 然后再用 builder.parse
Document doc = builder.parse(is);
System.out.println(xmlText);
// 通过递归调用 查询标签位置,可能出现得层级关系,避免出现一层不对得情况查询多个标签地址
Element element = XmlRecursiveFinder.findElement(doc, title);
List<String> valuesList = new ArrayList<>();
if ("1".equals(isTrue)) {
String value = element == null ? "" : "" ;
judgementList = setData(judgementList, chineseName + value, englishName + value);
} else {
String[] valuesArr = values.split("#");
String oneValue = "";
for (String yivalue : valuesArr) {
if ("0".equals(isText)) {
oneValue = element.getAttribute(yivalue);
} else {
oneValue = element.getTextContent();
}
valuesList.add(oneValue);
}
// 开始进行考点等的判断
String pointValue = JudgementConvert.getConvert(valuesList, type);
if ("1".equals(isTrue)) {
pointValue = pointValue != null ? "" : "";
}
judgementList = setData(judgementList, chineseName + pointValue, englishName + pointValue);
}
} else {
if (!paragraph.isEmpty()) {
slideCursor.selectPath("declare namespace " + firstName + "='" + DeclareNamespaceForPPT.getNameSpace(firstName) + "' " + paragraph);
}
// 当查询到或者说不需要查询的时候进入
if (slideCursor.toNextSelection() || paragraph.isEmpty()) {
// 获取 XML 字符串
String xmlText = slideCursor.getObject().xmlText();
InputStream is = new ByteArrayInputStream(xmlText.getBytes(StandardCharsets.UTF_8));
// 然后再用 builder.parse
Document doc = builder.parse(is);
if ("Filling_Method".equals(type)) {
// 说明判断填充方式
String value = getFillingMethod(doc, slideCursor, title);
judgementList = setData(judgementList, chineseName + value, englishName + value);
} else if ("Filling_Bg".equals(type)) {
// 说明判断背景填充方式
String value = getFillingBg(doc, slideCursor, title);
judgementList = setData(judgementList, chineseName + value, englishName + value);
} else if ("Line_Spacing".equals(type)) {
// 行距类型
String value = getLineSpacing(doc, slideCursor, title);
judgementList = setData(judgementList, chineseName + value, englishName + value);
}
else {
// 通过递归调用 查询标签位置,可能出现得层级关系,避免出现一层不对得情况查询多个标签地址
Element element = XmlRecursiveFinder.findElement(doc, title);
List<String> valuesList = new ArrayList<>();
if ("1".equals(isTrue)) {
String value = element == null ? "" : "" ;
judgementList = setData(judgementList, chineseName + value, englishName + value);
} else {
String[] valuesArr = values.split("#");
String oneValue = "";
for (String yivalue : valuesArr) {
if ("0".equals(isText)) {
oneValue = element.getAttribute(yivalue);
} else {
oneValue = element.getTextContent();
}
valuesList.add(oneValue);
}
// 开始进行考点等的判断
String pointValue = JudgementConvert.getConvert(valuesList, type);
if ("1".equals(isTrue)) {
pointValue = pointValue != null ? "" : "";
}
judgementList = setData(judgementList, chineseName + pointValue, englishName + pointValue);
}
}
} else {
// 如果存在备选方案,使用备选的参数
// 先过去RID的对应的值所有方法中带有了#区分第一段是获取值,第二段是获取外文件的参数
}
}
}
return judgementList;
}
// 大纲
// 1、获取第一层目录 幻灯片 - 母版 - 设置 - 其他
// 2、获取第二层目录 第x页 - 幻灯片母版/备注母版 - 幻灯片设置 - 文件操作
// 3、获取第三层目录 幻灯片设置/形状 - 幻灯片母版 - 幻灯片设置 - 文件操作
public static List<PptxInfoReqVo> wpsPptxInfo(String filePath) throws FileNotFoundException {
List<PptxInfoReqVo> pptxInfoReqVos = new ArrayList<>();
try (FileInputStream fis = new FileInputStream(filePath);
XMLSlideShow pptxXml = new XMLSlideShow(fis)) {
int index = 0;
String firstId = getStringRandom();
setPptxInfo("幻灯片", "p:sld", "p:sld", filePath, firstId, "0", "", pptxInfoReqVos);
for (XSLFSlide slides : pptxXml.getSlides()){
index += 1;
String secondId = getStringRandom();
setPptxInfo(""+index+"", "slide"+index, "slide"+index, filePath, secondId, firstId, "", pptxInfoReqVos);
// 第三层
String thirdId = getStringRandom();
int indexCnvPr = 1;
setPptxInfo("幻灯片设置", "slide"+index, "(//p:bg)["+indexCnvPr+"]", filePath, thirdId, secondId,
"slide@setting", pptxInfoReqVos);
XmlCursor spCursor = slides.getXmlObject().newCursor();
spCursor.selectPath("declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' .//p:sp");
while (spCursor.toNextSelection()) {
XmlCursor cNvPrXml = spCursor.newCursor();
cNvPrXml.selectPath("declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' .//p:cNvPr/@name");
if (cNvPrXml.toNextSelection()) {
String name = cNvPrXml.getTextValue();
String fourId = getStringRandom();
setPptxInfo("形状"+indexCnvPr+"->"+name,
"slide"+index,
"(//p:sp)["+indexCnvPr+"]",
filePath,
fourId,
secondId,
"p:sp@p:pic", pptxInfoReqVos);
indexCnvPr += 1;
}
}
XmlCursor picCursor = slides.getXmlObject().newCursor();
System.out.println(picCursor.xmlText());
picCursor.selectPath("declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' .//p:pic");
int indexCnvPrPic = 1;
while (picCursor.toNextSelection()) {
String fourId = getStringRandom();
setPptxInfo("图像"+indexCnvPrPic+"->图像", "slide"+index, "(//p:pic)["+indexCnvPrPic+"]", filePath, fourId, secondId,
"p:sp@p:pic", pptxInfoReqVos);
indexCnvPrPic += 1;
}
}
// 设置
String firstIds = getStringRandom();
setPptxInfo("设置", "p:presentation", "p:presentation", filePath, firstIds, "0",
"p:sp@p:pic", pptxInfoReqVos);
String secondIds = getStringRandom();
setPptxInfo("幻灯片设置", "p:presentation", "p:presentation", filePath, secondIds, firstIds,
"p:sp@p:pic", pptxInfoReqVos);
// 母版
// String dFirstId = getStringRandom();
// setPptxInfo("母版", "p:sld", "p:sld", filePath, dFirstId, "0", pptxInfoReqVos);
} catch (Exception e) {
throw new RuntimeException(e);
}
return pptxInfoReqVos;
}
public static String getFillingMethod(Document doc, XmlCursor cursor, String titleName) {
String value = "";
for (String title : titleName.split("#")) {
// 获取填充方法
NodeList nodeList = doc.getElementsByTagNameNS(DeclareNamespaceForPPT.getNameSpace(title.split(":")[0]), title.split(":")[1]);
if (nodeList.getLength() > 0) {
if (title.equals("a:solidFill")) {
value = "纯色填充";
}
}
}
return value;
}
public static String getLineSpacing(Document doc, XmlCursor cursor, String titleName) {
String value = "";
for (String title : titleName.split("#")) {
// 获取填充方法
NodeList nodeList = doc.getElementsByTagNameNS(DeclareNamespaceForPPT.getNameSpace(title.split(":")[0]), title.split(":")[1]);
if (nodeList.getLength() > 0) {
if (title.equals("a:spcPts")) {
value = "固定行距";
}
if (title.equals("a:spcPct")) {
value = "多倍行距";
}
}
}
return value;
}
public static String getProjectSymbols(Document doc, XmlCursor cursor, String titleName) {
String value = "";
for (String title : titleName.split("#")) {
// 获取填充方法
NodeList nodeList = doc.getElementsByTagNameNS(DeclareNamespaceForPPT.getNameSpace(title.split(":")[0]), title.split(":")[1]);
if (nodeList.getLength() > 0) {
if (title.equals("a:buChar")) {
value = "普通圆点";
}
if (title.equals("a:buBlip")) {
value = "图片项目符号";
}
if (title.equals("a:buAutoNum")) {
value = "自动编号";
}
}
}
return value;
}
public static String getFillingBg(Document doc, XmlCursor cursor, String titleName) {
String value = "";
for (String title : titleName.split("#")) {
// 获取填充方法
NodeList nodeList = doc.getElementsByTagNameNS(DeclareNamespaceForPPT.getNameSpace(title.split(":")[0]), title.split(":")[1]);
if (nodeList.getLength() > 0) {
if (title.equals("a:solidFill")) {
value = "纯色填充";
}
if (title.equals("a:gradFill")) {
value = "渐变填充";
}
if (title.equals("a:blipFill")) {
value = "图片填充";
}
if (title.equals("a:pattFill")) {
value = "图案填充";
}
if (title.equals("a:grpFill")) {
value = "分组填充";
}
}
}
return value;
}
public static XmlCursor getXmlCursor(String path, String titleName, String value) throws IOException, InvalidFormatException {
XmlCursor cursor = null;
try (OPCPackage pkg = OPCPackage.open(path)) {
for (PackagePart part : pkg.getParts()) {
String entryName = part.getPartName().getName();
if (value == null) {
// 如果说明是空的话,直接查询文件名称
if (entryName.contains(titleName) && entryName.contains(".xml") && !entryName.contains(".rels")) {
try (InputStream is = part.getInputStream()) {
String xmlContent = IOUtils.toString(is, StandardCharsets.UTF_8);
XmlObject xmlObject = XmlObject.Factory.parse(xmlContent);
cursor = xmlObject.newCursor();
break;
} catch (XmlException e) {
throw new RuntimeException(e);
}
}
} else {
// 想查询外置文件
if (entryName.contains(titleName) && entryName.contains(".xml") && entryName.contains(".rels")) {
try (InputStream is = part.getInputStream()) {
String xmlContent = IOUtils.toString(is, StandardCharsets.UTF_8);
XmlObject xmlObject = XmlObject.Factory.parse(xmlContent);
xmlObject.newCursor().selectPath("declare namespace r='http://schemas.openxmlformats.org/package/2006/relationships' .//r:Relationships/r:Relationship");
if (xmlObject.newCursor().toNextSelection()) {
String id = xmlObject.newCursor().getAttributeText(new QName("Id"));
if (id.equals(value)) {
String target = xmlObject.newCursor().getAttributeText(new QName("Target"));
getXmlCursor(path, target.split("/")[target.split("/").length-1], null);
}
}
} catch (XmlException e) {
throw new RuntimeException(e);
}
}
}
}
}
return cursor;
}
/**
* 生成随机码
* @return 随机码
*/
public static String getStringRandom() {
String characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
Random random = new Random();
StringBuilder sb = new StringBuilder();
// 生成指定长度的随机字符字符串
for (int i = 0; i < 10; i++) {
int randomIndex = random.nextInt(characters.length());
// 随机字符
sb.append(characters.charAt(randomIndex));
}
return sb.toString();
}
/**
*
* @param chineseName
* @param englishName
* @param selectName
* @param filePath
* @param id
* @param parentId
* @param pptxInfoReqVos
* @throws Exception
*/
public static void setPptxInfo(String chineseName, String englishName, String selectName, String filePath, String id, String parentId, String title, List<PptxInfoReqVo> pptxInfoReqVos) throws Exception {
PptxInfoReqVo pptxInfos = new PptxInfoReqVo();
pptxInfos.setName(chineseName);
pptxInfos.setEnglishName(englishName);
pptxInfos.setFilePath(filePath);
pptxInfos.setId(id);
pptxInfos.setSelectName(selectName);
pptxInfos.setParentId(parentId);
pptxInfos.setTitle(title);
pptxInfoReqVos.add(pptxInfos);
}
/**
* 向考点对象存放数据
* @param wpsPptxJudgementDtoList 考点对象数组
* @param chineseName 给考点对象添加的中文描述
* @param englishName 给考点对象添加的英文描述
* @return 考点对象数组
*/
private static List<WpsPptxJudgementDto> setData(List<WpsPptxJudgementDto> wpsPptxJudgementDtoList,
String chineseName,
String englishName) {
WpsPptxJudgementDto judgementDto = new WpsPptxJudgementDto();
judgementDto.setContentIn(chineseName);
judgementDto.setContent(englishName);
judgementDto.setScoreRate("1");
wpsPptxJudgementDtoList.add(judgementDto);
return wpsPptxJudgementDtoList;
}
}

View File

@@ -0,0 +1,39 @@
package pc.exam.pp.module.judgement.utils.wps_pptx;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class XmlRecursiveFinder {
// 递归入口
public static Element findElementRecursive(Node startNode, String[] tags, int index) {
if (index >= tags.length || startNode == null) return null;
String tag = tags[index].split(":")[1];
String namespace = tags[index].split(":")[0];
NodeList children;
if (startNode instanceof Document) {
children = ((Document) startNode).getElementsByTagNameNS(DeclareNamespaceForPPT.getNameSpace(namespace), tag);
} else {
children = ((Element) startNode).getElementsByTagNameNS(DeclareNamespaceForPPT.getNameSpace(namespace), tag);
}
if (children.getLength() == 0) return null;
Element child = (Element) children.item(0);
if (index == tags.length - 1) {
// 最后一层,返回当前节点
return child;
}
return findElementRecursive(child, tags, index + 1);
}
// 封装外部调用
public static Element findElement(Document doc, String titleName) {
String[] title = titleName.split("@");
return findElementRecursive(doc, title, 0);
}
}

View File

@@ -0,0 +1,38 @@
package pc.exam.pp.module.judgement.utils.wps_pptx.judgementVO;
import lombok.Data;
/**
* @author REN
*/
@Data
public class JudgementReqVo {
// 中文考点
private String chineseName;
// 查询段落所在文件名称
private String fileNama;
// 查询的段落
private String paragraph;
// 需要查询的标签
private String title;
// 需要查询的参数 当isText == 1 为null
private String valueList;
// 值转换类型 String
private String type;
// 需要查找的是文本还是参数0参数1文本
private String isText;
// 对结果的判断0:否 返回值1:是 返回 是否)
private String isTrue;
// 0:内参数1外参数2内外参数方法使用#继续分割)
private String isParameter;
}

View File

@@ -21,6 +21,8 @@ public class PptxInfoReqVo {
private String selectName;
private String title;
private String id;
private List<PptxInfoReqVo> children = new ArrayList<>();