【新增】mysql本地判分

This commit is contained in:
YOHO\20373
2025-06-24 10:30:17 +08:00
48 changed files with 4687 additions and 2110 deletions

View File

@@ -1,4 +1,4 @@
package pc.exam.pp.module.judgement.controller.admin.Wps;
package pc.exam.pp.module.exam.controller.admin.wps;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
@@ -10,72 +10,74 @@ 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.wpspptx.WpsPptxLinkDO;
import pc.exam.pp.module.judgement.dal.dataobject.wpsword.WpsWordLinkDO;
import pc.exam.pp.module.judgement.service.wps_pptx.WpsPptxLinkService;
import pc.exam.pp.module.exam.controller.admin.wps.vo.pptx.PptxListReqVO;
import pc.exam.pp.module.exam.controller.admin.wps.vo.pptx.PptxRespVO;
import pc.exam.pp.module.exam.controller.admin.wps.vo.pptx.PptxSaveReqVO;
import pc.exam.pp.module.exam.controller.admin.wps.vo.pptx.PptxSimpleRespVO;
import pc.exam.pp.module.exam.dal.dataobject.wps.ExamWpsPptx;
import pc.exam.pp.module.exam.service.wps.pptx.ExamWpsPptxService;
import java.util.List;
import static pc.exam.pp.framework.common.pojo.CommonResult.success;
@Tag(name = "管理后台 - wps_pptx")
@Tag(name = "考试系统 - PPTX考点")
@RestController
@RequestMapping("/wps/pptx")
@RequestMapping("/exam/pptx")
@Validated
public class PptxController {
public class ExamWpsPptxController {
@Resource
private WpsPptxLinkService wpsPptxLinkService;
private ExamWpsPptxService examWpsPptxService;
@PostMapping("create")
@Operation(summary = "创建wps_pptx")
@Operation(summary = "创建PPTX考点")
public CommonResult<Long> createPptx(@Valid @RequestBody PptxSaveReqVO createReqVO) {
Long pptxId = wpsPptxLinkService.createPptx(createReqVO);
Long pptxId = examWpsPptxService.createPptx(createReqVO);
return success(pptxId);
}
@PutMapping("update")
@Operation(summary = "更新wps_pptx")
@Operation(summary = "更新PPTX考点")
public CommonResult<Boolean> updatePptx(@Valid @RequestBody PptxSaveReqVO updateReqVO) {
wpsPptxLinkService.updatePptx(updateReqVO);
examWpsPptxService.updatePptx(updateReqVO);
return success(true);
}
@DeleteMapping("delete")
@Operation(summary = "删除wps_pptx")
@Operation(summary = "删除PPTX考点")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
public CommonResult<Boolean> deletePptx(@RequestParam("id") Long id) {
wpsPptxLinkService.deletePptx(id);
examWpsPptxService.deletePptx(id);
return success(true);
}
@GetMapping("/list")
@Operation(summary = "获取wps_pptx列表")
@Operation(summary = "获取PPTX考点列表")
public CommonResult<List<PptxRespVO>> getPptxList(PptxListReqVO reqVO) {
List<WpsPptxLinkDO> list = wpsPptxLinkService.getPptxList(reqVO);
List<ExamWpsPptx> list = examWpsPptxService.getPptxList(reqVO);
return success(BeanUtils.toBean(list, PptxRespVO.class));
}
@GetMapping(value = {"/list-all-simple", "/simple-list"})
@Operation(summary = "获取wps_pptx精简信息列表", description = "只包含被开启的wps_pptx,主要用于前端的下拉选项")
@Operation(summary = "获取PPTX考点精简信息列表", description = "只包含被开启的PPTX考点,主要用于前端的下拉选项")
public CommonResult<List<PptxSimpleRespVO>> getSimplePptxList() {
List<WpsPptxLinkDO> list = wpsPptxLinkService.getPptxList(
List<ExamWpsPptx> list = examWpsPptxService.getPptxList(
new PptxListReqVO().setStatus(CommonStatusEnum.ENABLE.getStatus()));
return success(BeanUtils.toBean(list, PptxSimpleRespVO.class));
}
@GetMapping("/get")
@Operation(summary = "获得wps_pptx信息")
@Operation(summary = "获得PPTX考点信息")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
public CommonResult<PptxRespVO> getPptx(@RequestParam("id") Long id) {
WpsPptxLinkDO pptx = wpsPptxLinkService.getPptx(id);
ExamWpsPptx pptx = examWpsPptxService.getPptx(id);
return success(BeanUtils.toBean(pptx, PptxRespVO.class));
}
@GetMapping("/listInfo")
@Operation(summary = "获取wps_pptx列表")
public CommonResult<List<PptxRespVO>> getPptxListInfo(PptxListReqVO reqVO) {
List<WpsPptxLinkDO> list = wpsPptxLinkService.getPptxListInfo(reqVO);
return success(BeanUtils.toBean(list, PptxRespVO.class));
@GetMapping("/getByNameList")
public CommonResult<List<PptxRespVO>> getPptxByNameList(@RequestParam("title") String title) {
ExamWpsPptx pptx = examWpsPptxService.getPptxByTitle(title);
return success(BeanUtils.toBean(examWpsPptxService.getChildPptxList(pptx.getId()), PptxRespVO.class));
}
}

View File

@@ -0,0 +1,14 @@
package pc.exam.pp.module.exam.controller.admin.wps.vo.pptx;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Schema(description = "考试模块 - PPT考点列表 Request VO")
@Data
public class PptxListReqVO {
private String name;
private Integer status;
}

View File

@@ -0,0 +1,40 @@
package pc.exam.pp.module.exam.controller.admin.wps.vo.pptx;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDateTime;
@Schema(description = "考试模块 - PPT考点信息 Response VO")
@Data
public class PptxRespVO {
private Long id;
private String name;
private Long parentId;
private Integer sort;
private Integer status;
private String title;
private String chineseName;
private String dataType;
private Integer isText;
private String valueList;
private Integer isTrue;
private Integer titleType;
private Integer isParameter;
private LocalDateTime createTime;
}

View File

@@ -0,0 +1,42 @@
package pc.exam.pp.module.exam.controller.admin.wps.vo.pptx;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import lombok.Data;
import pc.exam.pp.framework.common.enums.CommonStatusEnum;
import pc.exam.pp.framework.common.validation.InEnum;
@Schema(description = "考试模块 - PPT考点创建/修改 Request VO")
@Data
public class PptxSaveReqVO {
private Long id;
private String name;
private Long parentId;
private Integer sort;
private Integer status;
private String title;
private String chineseName;
private String dataType;
private Integer isText;
private String valueList;
private Integer isTrue;
private Integer titleType;
private Integer isParameter;
}

View File

@@ -0,0 +1,20 @@
package pc.exam.pp.module.exam.controller.admin.wps.vo.pptx;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Schema(description = "考试模块 - 精简信息 Response VO")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class PptxSimpleRespVO {
private Long id;
private String name;
private Long parentId;
}

View File

@@ -0,0 +1,41 @@
package pc.exam.pp.module.exam.dal.dataobject.wps;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import pc.exam.pp.framework.tenant.core.db.TenantBaseDO;
import java.util.ArrayList;
import java.util.List;
/**
* wps pptx关系对应表
*
* @author REN
*/
@TableName("exam_wps_pptx")
@Data
@EqualsAndHashCode(callSuper = true)
public class ExamWpsPptx extends TenantBaseDO {
public static final Long PARENT_ID_ROOT = 0L;
@TableId
private Long id;
private String name;
private Long parentId;
private String title;
private Integer sort;
private String chineseName;
private String dataType;
private Integer status;
private String valueList;
private Integer isTrue;
private Integer isText;
private Integer titleType;
private Integer isParameter;
@TableField(exist = false)
private List<ExamWpsPptx> children = new ArrayList<>();
}

View File

@@ -41,6 +41,7 @@ public interface ExamQuestionMapper extends BaseMapperX<ExamQuestion>
default PageResult<ExamQuestion> selectExamQuestionList(QuestionVo questionVo) {
return selectPage(questionVo, new LambdaQueryWrapperX<ExamQuestion>()
.likeIfPresent(ExamQuestion::getQuNum, questionVo.getQuNum())
.likeIfPresent(ExamQuestion::getContent, questionVo.getContent())
.likeIfPresent(ExamQuestion::getQuId,questionVo.getQuId())
.likeIfPresent(ExamQuestion::getKeywords,questionVo.getKeywords())
.likeIfPresent(ExamQuestion::getQuLevel, questionVo.getQuLevel())

View File

@@ -0,0 +1,36 @@
package pc.exam.pp.module.exam.dal.mysql.wps;
import org.apache.ibatis.annotations.Mapper;
import pc.exam.pp.framework.mybatis.core.mapper.BaseMapperX;
import pc.exam.pp.framework.mybatis.core.query.LambdaQueryWrapperX;
import pc.exam.pp.module.exam.controller.admin.wps.vo.pptx.PptxListReqVO;
import pc.exam.pp.module.exam.dal.dataobject.wps.ExamWpsPptx;
import java.util.Collection;
import java.util.List;
@Mapper
public interface ExamWpsPptxMapper extends BaseMapperX<ExamWpsPptx> {
default List<ExamWpsPptx> selectList(PptxListReqVO reqVO) {
return selectList(new LambdaQueryWrapperX<ExamWpsPptx>()
.likeIfPresent(ExamWpsPptx::getName, reqVO.getName())
.eqIfPresent(ExamWpsPptx::getStatus, reqVO.getStatus()));
}
default ExamWpsPptx selectByParentIdAndName(Long parentId, String name) {
return selectOne(ExamWpsPptx::getParentId, parentId, ExamWpsPptx::getName, name);
}
default ExamWpsPptx selectByTitle(String title) {
return selectOne(ExamWpsPptx::getTitle, title);
}
default Long selectCountByParentId(Long parentId) {
return selectCount(ExamWpsPptx::getParentId, parentId);
}
default List<ExamWpsPptx> selectListByParentId(Collection<Long> parentIds) {
return selectList(ExamWpsPptx::getParentId, parentIds);
}
}

View File

@@ -0,0 +1,117 @@
package pc.exam.pp.module.exam.service.wps.pptx;
import pc.exam.pp.framework.common.util.collection.CollectionUtils;
import pc.exam.pp.module.exam.controller.admin.wps.vo.pptx.PptxListReqVO;
import pc.exam.pp.module.exam.controller.admin.wps.vo.pptx.PptxSaveReqVO;
import pc.exam.pp.module.exam.dal.dataobject.wps.ExamWpsPptx;
import java.util.*;
/**
* Pptx考点 Service 接口
*
* @author 朋辰
*/
public interface ExamWpsPptxService {
/**
* 创建Pptx考点
*
* @param createReqVO Pptx考点信息
* @return Pptx考点编号
*/
Long createPptx(PptxSaveReqVO createReqVO);
/**
* 更新Pptx考点
*
* @param updateReqVO Pptx考点信息
*/
void updatePptx(PptxSaveReqVO updateReqVO);
/**
* 删除Pptx考点
*
* @param id Pptx考点编号
*/
void deletePptx(Long id);
/**
* 获得Pptx考点信息
*
* @param id Pptx考点编号
* @return Pptx考点信息
*/
ExamWpsPptx getPptx(Long id);
/**
* 获得Pptx考点信息
*
* @param title Pptx考点标签
* @return Pptx考点信息
*/
ExamWpsPptx getPptxByTitle(String title);
/**
* 获得Pptx考点信息数组
*
* @param ids Pptx考点编号数组
* @return Pptx考点信息数组
*/
List<ExamWpsPptx> getPptxList(Collection<Long> ids);
/**
* 筛选Pptx考点列表
*
* @param reqVO 筛选条件请求 VO
* @return Pptx考点列表
*/
List<ExamWpsPptx> getPptxList(PptxListReqVO reqVO);
/**
* 获得指定编号的Pptx考点 Map
*
* @param ids Pptx考点编号数组
* @return Pptx考点 Map
*/
default Map<Long, ExamWpsPptx> getPptxMap(Collection<Long> ids) {
List<ExamWpsPptx> list = getPptxList(ids);
return CollectionUtils.convertMap(list, ExamWpsPptx::getId);
}
/**
* 获得指定Pptx考点的所有子Pptx考点
*
* @param id Pptx考点编号
* @return 子Pptx考点列表
*/
default List<ExamWpsPptx> getChildPptxList(Long id) {
return getChildPptxList(Collections.singleton(id));
}
/**
* 获得指定Pptx考点的所有子Pptx考点
*
* @param ids Pptx考点编号数组
* @return 子Pptx考点列表
*/
List<ExamWpsPptx> getChildPptxList(Collection<Long> ids);
/**
* 获得所有子Pptx考点从缓存中
*
* @param id 父Pptx考点编号
* @return 子Pptx考点列表
*/
Set<Long> getChildPptxIdListFromCache(Long id);
/**
* 校验Pptx考点们是否有效。如下情况视为无效
* 1. Pptx考点编号不存在
* 2. Pptx考点被禁用
*
* @param ids 角色编号数组
*/
void validatePptxList(Collection<Long> ids);
}

View File

@@ -0,0 +1,221 @@
package pc.exam.pp.module.exam.service.wps.pptx;
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.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.module.exam.controller.admin.wps.vo.pptx.PptxListReqVO;
import pc.exam.pp.module.exam.controller.admin.wps.vo.pptx.PptxSaveReqVO;
import pc.exam.pp.module.exam.dal.dataobject.wps.ExamWpsPptx;
import pc.exam.pp.module.exam.dal.mysql.wps.ExamWpsPptxMapper;
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.*;
/**
* PPTX考点 Service 实现类
*
* @author 朋辰
*/
@Service
@Validated
@Slf4j
public class ExamWpsPptxServiceImpl implements ExamWpsPptxService {
@Resource
private ExamWpsPptxMapper pptxMapper;
@Override
public Long createPptx(PptxSaveReqVO createReqVO) {
if (createReqVO.getParentId() == null) {
createReqVO.setParentId(ExamWpsPptx.PARENT_ID_ROOT);
}
// 校验父PPTX考点的有效性
validateParentPptx(null, createReqVO.getParentId());
// 校验PPTX考点名的唯一性
validatePptxNameUnique(null, createReqVO.getParentId(), createReqVO.getName());
// 插入PPTX考点
ExamWpsPptx pptx = BeanUtils.toBean(createReqVO, ExamWpsPptx.class);
pptxMapper.insert(pptx);
return pptx.getId();
}
@Override
public void updatePptx(PptxSaveReqVO updateReqVO) {
if (updateReqVO.getParentId() == null) {
updateReqVO.setParentId(ExamWpsPptx.PARENT_ID_ROOT);
}
// 校验自己存在
validatePptxExists(updateReqVO.getId());
// 校验父PPTX考点的有效性
validateParentPptx(updateReqVO.getId(), updateReqVO.getParentId());
// 校验PPTX考点名的唯一性
validatePptxNameUnique(updateReqVO.getId(), updateReqVO.getParentId(), updateReqVO.getName());
// 更新PPTX考点
ExamWpsPptx updateObj = BeanUtils.toBean(updateReqVO, ExamWpsPptx.class);
pptxMapper.updateById(updateObj);
}
@Override
public void deletePptx(Long id) {
// 校验是否存在
validatePptxExists(id);
// 校验是否有子PPTX考点
if (pptxMapper.selectCountByParentId(id) > 0) {
throw exception(PPTX_EXITS_CHILDREN);
}
// 删除PPTX考点
pptxMapper.deleteById(id);
}
@VisibleForTesting
void validatePptxExists(Long id) {
if (id == null) {
return;
}
ExamWpsPptx pptx = pptxMapper.selectById(id);
if (pptx == null) {
throw exception(PPTX_NOT_FOUND);
}
}
@VisibleForTesting
void validateParentPptx(Long id, Long parentId) {
if (parentId == null || ExamWpsPptx.PARENT_ID_ROOT.equals(parentId)) {
return;
}
// 1. 不能设置自己为父PPTX考点
if (Objects.equals(id, parentId)) {
throw exception(PPTX_PARENT_ERROR);
}
// 2. 父PPTX考点不存在
ExamWpsPptx parent = pptxMapper.selectById(parentId);
if (parent == null) {
throw exception(PPTX_PARENT_NOT_EXITS);
}
// 3. 递归校验父PPTX考点如果父PPTX考点是自己的子PPTX考点则报错避免形成环路
if (id == null) { // id 为空,说明新增,不需要考虑环路
return;
}
for (int i = 0; i < Short.MAX_VALUE; i++) {
// 3.1 校验环路
parentId = parent.getParentId();
if (Objects.equals(id, parentId)) {
throw exception(PPTX_PARENT_IS_CHILD);
}
// 3.2 继续递归下一级父PPTX考点
if (parentId == null || ExamWpsPptx.PARENT_ID_ROOT.equals(parentId)) {
break;
}
parent = pptxMapper.selectById(parentId);
if (parent == null) {
break;
}
}
}
@VisibleForTesting
void validatePptxNameUnique(Long id, Long parentId, String name) {
ExamWpsPptx dept = pptxMapper.selectByParentIdAndName(parentId, name);
if (dept == null) {
return;
}
// 如果 id 为空,说明不用比较是否为相同 id 的PPTX考点
if (id == null) {
throw exception(PPTX_NAME_DUPLICATE);
}
if (ObjectUtil.notEqual(dept.getId(), id)) {
throw exception(PPTX_NAME_DUPLICATE);
}
}
@Override
public ExamWpsPptx getPptx(Long id) {
return pptxMapper.selectById(id);
}
@Override
public ExamWpsPptx getPptxByTitle(String title) {
return pptxMapper.selectByTitle(title);
}
@Override
public List<ExamWpsPptx> getPptxList(Collection<Long> ids) {
if (CollUtil.isEmpty(ids)) {
return Collections.emptyList();
}
return pptxMapper.selectBatchIds(ids);
}
@Override
public List<ExamWpsPptx> getPptxList(PptxListReqVO reqVO) {
List<ExamWpsPptx> list = pptxMapper.selectList(reqVO);
list.sort(Comparator.comparing(ExamWpsPptx::getSort));
return list;
}
@Override
public Map<Long, ExamWpsPptx> getPptxMap(Collection<Long> ids) {
return ExamWpsPptxService.super.getPptxMap(ids);
}
@Override
public List<ExamWpsPptx> getChildPptxList(Long id) {
return ExamWpsPptxService.super.getChildPptxList(id);
}
@Override
public List<ExamWpsPptx> getChildPptxList(Collection<Long> ids) {
List<ExamWpsPptx> children = new LinkedList<>();
// 遍历每一层
Collection<Long> parentIds = ids;
for (int i = 0; i < Short.MAX_VALUE; i++) { // 使用 Short.MAX_VALUE 避免 bug 场景下,存在死循环
// 查询当前层所有的子PPTX考点
List<ExamWpsPptx> pptxs = pptxMapper.selectListByParentId(parentIds);
// 1. 如果没有子PPTX考点则结束遍历
if (CollUtil.isEmpty(pptxs)) {
break;
}
// 2. 如果有子PPTX考点继续遍历
children.addAll(pptxs);
parentIds = convertSet(pptxs, ExamWpsPptx::getId);
}
return children;
}
@Override
public Set<Long> getChildPptxIdListFromCache(Long id) {
List<ExamWpsPptx> children = getChildPptxList(id);
return convertSet(children, ExamWpsPptx::getId);
}
@Override
public void validatePptxList(Collection<Long> ids) {
if (CollUtil.isEmpty(ids)) {
return;
}
// 获得科室信息
Map<Long, ExamWpsPptx> pptxMap = getPptxMap(ids);
// 校验
ids.forEach(id -> {
ExamWpsPptx pptx = pptxMap.get(id);
if (pptx == null) {
throw exception(PPTX_NOT_FOUND);
}
if (!CommonStatusEnum.ENABLE.getStatus().equals(pptx.getStatus())) {
throw exception(PPTX_NOT_ENABLE, pptx.getName());
}
});
}
}

View File

@@ -2,18 +2,14 @@ package pc.exam.pp.module.judgement.controller.admin.Browser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import pc.exam.pp.framework.common.pojo.CommonResult;
import pc.exam.pp.module.judgement.controller.service.browser.IBrowserServerice;
import java.io.IOException;
@RestController
@RequestMapping("/tool/Browser")
public class BrowserComtroller {
public class BrowserController {
@Autowired
private IBrowserServerice browserServerice;

View File

@@ -1,13 +1,14 @@
package pc.exam.pp.module.judgement.controller.admin.Mysql;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
import pc.exam.pp.framework.common.pojo.CommonResult;
import pc.exam.pp.module.judgement.controller.admin.autoTools.vo.StuPaperReqVo;
import pc.exam.pp.module.judgement.controller.service.mysql.IMysqlLocalService;
import pc.exam.pp.module.judgement.controller.service.mysql.IMysqlServerice;
import java.io.IOException;
import java.math.BigDecimal;
import java.sql.SQLException;
@RestController
@@ -18,8 +19,18 @@ public class MysqlController {
@Autowired
private IMysqlServerice mysqlServerice;
@Autowired
private IMysqlLocalService mysqlLocalService;
/**
* 删除 本地学生的连接和库
* @param tName
* @throws Exception
*/
@GetMapping("/delMysqlConnect")
public void get(@RequestParam("tName") String tName) throws Exception {
mysqlLocalService.delMysqlConnect(tName);
}
/**
* Mysql判分

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<WpsPptxJudgementDto>> 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

@@ -1,26 +0,0 @@
package pc.exam.pp.module.judgement.controller.admin.Wps.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Schema(description = "管理后台 - WpsWord对应关系 Request VO")
@Data
public class PptxListReqVO {
@Schema(description = "节点名称模糊匹配", example = "芋道")
private String name;
@Schema(description = "展示状态,参见 CommonStatusEnum 枚举类", example = "1")
private Integer status;
/**
* 类型
*/
private Integer type;
private Integer belongTo;
private String nodeFunction;
private Integer isboo;
private Integer titleType;
private String unit;
private String page;
}

View File

@@ -1,44 +0,0 @@
package pc.exam.pp.module.judgement.controller.admin.Wps.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDateTime;
@Schema(description = "管理后台 - 节点信息 Response VO")
@Data
public class PptxRespVO {
@Schema(description = "节点编号", example = "1024")
private Long id;
@Schema(description = "节点名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋道")
private String name;
@Schema(description = "父节点 ID", example = "1024")
private Long parentId;
@Schema(description = "显示顺序", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private Integer sort;
@Schema(description = "节点方法")
private String nodeFunction;
@Schema(description = "转中文")
private String toChinese;
@Schema(description = "状态,见 CommonStatusEnum 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Integer status;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "时间戳格式")
private LocalDateTime createTime;
/**
* 类型
*/
private Integer type;
private Integer belongTo;
private Integer isboo;
private Integer titleType;
private String unit;
private String page;
}

View File

@@ -1,49 +0,0 @@
package pc.exam.pp.module.judgement.controller.admin.Wps.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import lombok.Data;
import pc.exam.pp.framework.common.enums.CommonStatusEnum;
import pc.exam.pp.framework.common.validation.InEnum;
@Schema(description = "管理后台 - 节点创建/修改 Request VO")
@Data
public class PptxSaveReqVO {
@Schema(description = "节点编号", example = "1024")
private Long id;
@Schema(description = "节点名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋道")
@NotBlank(message = "节点名称不能为空")
private String name;
/**
* 类型
*/
private Integer type;
private Integer belongTo;
private Integer isboo;
private Integer titleType;
private String unit;
private String page;
@Schema(description = "父节点 ID", example = "1024")
private Long parentId;
@Schema(description = "显示顺序", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
@NotNull(message = "显示顺序不能为空")
private Integer sort;
@Schema(description = "节点方法")
private String nodeFunction;
@Schema(description = "转中文")
private String toChinese;
@Schema(description = "状态,见 CommonStatusEnum 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "状态不能为空")
@InEnum(value = CommonStatusEnum.class, message = "修改状态必须是 {value}")
private Integer status;
}

View File

@@ -1,31 +0,0 @@
package pc.exam.pp.module.judgement.controller.admin.Wps.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Schema(description = "管理后台 - 节点精简信息 Response VO")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class PptxSimpleRespVO {
@Schema(description = "节点编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private Long id;
@Schema(description = "节点名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋道")
private String name;
@Schema(description = "父节点 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private Long parentId;
/**
* 类型
*/
private Integer type;
private Integer belongTo;
private Integer isboo;
private Integer titleType;
private String unit;
private String page;
}

View File

@@ -0,0 +1,16 @@
package pc.exam.pp.module.judgement.controller.service.mysql;
import pc.exam.pp.framework.common.pojo.CommonResult;
import pc.exam.pp.module.exam.dal.dataobject.ExamQuestion;
import pc.exam.pp.module.judgement.service.auto_tools.vo.SourceAndText;
import java.io.File;
import java.io.IOException;
import java.sql.SQLException;
public interface IMysqlLocalService {
SourceAndText Judgement(double sorce, File file, ExamQuestion examQuestion, String judgementStr) throws IOException, SQLException;
void delMysqlConnect(String tName);
}

View File

@@ -1,6 +1,7 @@
package pc.exam.pp.module.judgement.controller.service.mysql;
import pc.exam.pp.framework.common.pojo.CommonResult;
import pc.exam.pp.module.exam.dal.dataobject.ExamQuestion;
import pc.exam.pp.module.exam.dal.dataobject.ExamQuestionAnswer;
import pc.exam.pp.module.judgement.service.auto_tools.vo.SourceAndText;

View File

@@ -835,11 +835,9 @@ public class MysqlServericeImpl implements IMysqlServerice {
}
private static String compareTables(Set<Map<String, String>> standardSet, Set<Map<String, String>> studentSet, String dbTable, String tableName,String tableNameStu,String judgementStr) {
String yuju="";
int index = 1;
// 判断表名是否一致
String tableNameCheck = tableName.equalsIgnoreCase(tableNameStu) ? "" : "x";
// 输出
System.out.printf("%02d.【数据表】【%s】【名称】【%s】【%s】\n", index, dbTable, tableName, tableNameCheck);
appendToFile(answerLogPath, "%02d.【数据表】【%s】【名称】【%s】【%s】\n", index, dbTable, tableName, tableNameCheck);
@@ -855,45 +853,46 @@ public class MysqlServericeImpl implements IMysqlServerice {
String fullName = dbTable + "." + columnName;
String nameCheck = stuCol != null ? "" : "x";
judgementStr = HtmlAppender.appendHtmlLineMysql(judgementStr, "%02d.【字段】【%s】【名称】【%s】【%s】\n", index++, fullName, columnName, nameCheck);
appendToFile(answerLogPath, "%02d.【字段】【%s】【名称】【%s】【%s】\n", index++, fullName, columnName, nameCheck);
System.out.printf("%02d.【字段】【%s】【名称】【%s】【%s】\n", ++index, fullName, columnName, nameCheck);
judgementStr = HtmlAppender.appendHtmlLineMysql(judgementStr, "%02d.【字段】【%s】【名称】【%s】【%s】\n", index, fullName, columnName, nameCheck);
appendToFile(answerLogPath, "%02d.【字段】【%s】【名称】【%s】【%s】\n", index, fullName, columnName, nameCheck);
if (stuCol != null) {
MysqlVo mysqlVo1 = compareField(index, fullName, "类型", stdCol.get("COLUMN_TYPE"), stuCol.get("COLUMN_TYPE"),judgementStr);
index=mysqlVo1.getIndex();
yuju=mysqlVo1.getText();
MysqlVo mysqlVo2 = compareField(index, fullName, "允许为空", stdCol.get("IS_NULLABLE"), stuCol.get("IS_NULLABLE"),yuju);
judgementStr=mysqlVo1.getText();
MysqlVo mysqlVo2 = compareField(index, fullName, "允许为空", stdCol.get("IS_NULLABLE"), stuCol.get("IS_NULLABLE"),judgementStr);
index=mysqlVo2.getIndex();
yuju=mysqlVo2.getText();
MysqlVo mysqlVo3 = compareField(index, fullName, "扩展", stdCol.get("EXTRA"), stuCol.get("EXTRA"),yuju);
judgementStr=mysqlVo2.getText();
MysqlVo mysqlVo3 = compareField(index, fullName, "扩展", stdCol.get("EXTRA"), stuCol.get("EXTRA"),judgementStr);
index=mysqlVo3.getIndex();
yuju=mysqlVo3.getText();
MysqlVo mysqlVo4 = compareField(index, fullName, "键类型", stdCol.get("COLUMN_KEY"), stuCol.get("COLUMN_KEY"),yuju);
yuju=mysqlVo4.getText();
judgementStr=mysqlVo3.getText();
MysqlVo mysqlVo4 = compareField(index, fullName, "键类型", stdCol.get("COLUMN_KEY"), stuCol.get("COLUMN_KEY"),judgementStr);
judgementStr=mysqlVo4.getText();
} else {
// 缺失字段,直接输出所有属性错误
MysqlVo mysqlVo1 = printMissing(index, fullName, "类型", stdCol.get("COLUMN_TYPE"),judgementStr);
index=mysqlVo1.getIndex();
yuju=mysqlVo1.getText();
MysqlVo mysqlVo2 = printMissing(index, fullName, "允许为空", stdCol.get("IS_NULLABLE"),yuju);
judgementStr=mysqlVo1.getText();
MysqlVo mysqlVo2 = printMissing(index, fullName, "允许为空", stdCol.get("IS_NULLABLE"),judgementStr);
index=mysqlVo2.getIndex();
yuju=mysqlVo2.getText();
MysqlVo mysqlVo3 = printMissing(index, fullName, "扩展", stdCol.get("EXTRA"),yuju);
judgementStr=mysqlVo2.getText();
MysqlVo mysqlVo3 = printMissing(index, fullName, "扩展", stdCol.get("EXTRA"),judgementStr);
index=mysqlVo3.getIndex();
yuju=mysqlVo3.getText();
MysqlVo mysqlVo4 = printMissing(index, fullName, "键类型", stdCol.get("COLUMN_KEY"),yuju);
yuju=mysqlVo4.getText();
judgementStr=mysqlVo3.getText();
MysqlVo mysqlVo4 = printMissing(index, fullName, "键类型", stdCol.get("COLUMN_KEY"),judgementStr);
judgementStr=mysqlVo4.getText();
}
}
return yuju;
return judgementStr;
}
private static MysqlVo compareField(int index, String fullName, String property, String stdValue, String stuValue, String judgementStr) {
MysqlVo mysqlVo=new MysqlVo();
String mark = stdValue.equalsIgnoreCase(stuValue) ? "" : "x";
System.out.printf("%02d.【字段】【%s】【%s】【%s】【%s】\n", index, fullName, property, stuValue, mark);
appendToFile(answerLogPath, "%02d.【字段】【%s】【%s】【%s】【%s】\n", index, fullName, property, stuValue, mark);
judgementStr = HtmlAppender.appendHtmlLineMysql(judgementStr, "%02d.【字段】【%s】【%s】【%s】【%s】\n", index, fullName, property, stuValue, mark);
System.out.printf("%02d.【字段】【%s】【%s】【%s】【%s】\n", index + 1, fullName, property, stuValue, mark);
appendToFile(answerLogPath, "%02d.【字段】【%s】【%s】【%s】【%s】\n", index + 1, fullName, property, stuValue, mark);
judgementStr = HtmlAppender.appendHtmlLineMysql(judgementStr, "%02d.【字段】【%s】【%s】【%s】【%s】\n", index + 1, fullName, property, stuValue, mark);
mysqlVo.setText(judgementStr);
mysqlVo.setIndex(index + 1);
return mysqlVo;
@@ -901,9 +900,9 @@ public class MysqlServericeImpl implements IMysqlServerice {
private static MysqlVo printMissing(int index, String fullName, String property, String stdValue,String judgementStr) {
MysqlVo mysqlVo=new MysqlVo();
System.out.printf("%02d.【字段】【%s】【%s】【%s】【x】\n", index, fullName, property, stdValue);
appendToFile(answerLogPath, "%02d.【字段】【%s】【%s】【%s】【x】\n", index, fullName, property, stdValue);
judgementStr = HtmlAppender.appendHtmlLineMysql(judgementStr, "%02d.【字段】【%s】【%s】【%s】【x】\n", index, fullName, property, stdValue);
System.out.printf("%02d.【字段】【%s】【%s】【%s】【x】\n", index + 1, fullName, property, stdValue);
appendToFile(answerLogPath, "%02d.【字段】【%s】【%s】【%s】【x】\n", index + 1, fullName, property, stdValue);
judgementStr = HtmlAppender.appendHtmlLineMysql(judgementStr, "%02d.【字段】【%s】【%s】【%s】【x】\n", index + 1, fullName, property, stdValue);
mysqlVo.setText(judgementStr);
mysqlVo.setIndex(index + 1);
return mysqlVo;

View File

@@ -2,6 +2,7 @@ package pc.exam.pp.module.judgement.controller.service.mysql;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import pc.exam.pp.module.exam.dal.mysql.paper.EducationPaperMapper;
import pc.exam.pp.module.judgement.utils.EndStuMonitorUtils;
@Service
@@ -13,10 +14,9 @@ public class testServiceImpl implements testservice {
public boolean test() {
String s = endStuMonitorUtils.endStuMonitor("160", "2bf4510550e34d85a852394cea61b455");
endStuMonitorUtils.endStuMonitor("160","2bf4510550e34d85a852394cea61b455",20.0);
// String s = endStuMonitorUtils.endStuMonitor("160", "2bf4510550e34d85a852394cea61b455");
//
// endStuMonitorUtils.endStuMonitor("160","2bf4510550e34d85a852394cea61b455",20.0);
return true;
}

View File

@@ -0,0 +1,16 @@
package pc.exam.pp.module.judgement.controller.service.mysql.vo;
import lombok.Data;
@Data
public class MysqlBooleanVo {
/**
* 是否正确
*/
private boolean flag;
/**
* 文本
*/
private String text;
}

View File

@@ -1,72 +0,0 @@
package pc.exam.pp.module.judgement.dal.dataobject.wpspptx;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import pc.exam.pp.framework.common.enums.CommonStatusEnum;
import pc.exam.pp.framework.tenant.core.db.TenantBaseDO;
import java.util.ArrayList;
import java.util.List;
/**
* wps pptx关系对应表
*
* @author REN
*/
@TableName("wps_pptx_link")
@Data
@EqualsAndHashCode(callSuper = true)
public class WpsPptxLinkDO extends TenantBaseDO {
public static final Long PARENT_ID_ROOT = 0L;
/**
* 部门ID
*/
@TableId
private Long id;
/**
* 部门名称
*/
private String name;
/**
* 父部门ID
*
* 关联 {@link #id}
*/
private Long parentId;
/**
* 显示顺序
*/
private Integer sort;
/**
* 节点功能
*/
private String nodeFunction;
/**
* 中文描述
*/
private String toChinese;
/**
* 状态
*
* 枚举 {@link CommonStatusEnum}
*/
private Integer status;
/**
* 类型
*/
private Integer type;
private String belongTo;
private Integer isboo;
private Integer titleType;
private String unit;
private String page;
@TableField(exist = false)
private List<WpsPptxLinkDO> children = new ArrayList<>();
}

View File

@@ -1,48 +0,0 @@
package pc.exam.pp.module.judgement.dal.mysql.wpspptx;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.apache.ibatis.annotations.Mapper;
import pc.exam.pp.framework.mybatis.core.mapper.BaseMapperX;
import pc.exam.pp.framework.mybatis.core.query.LambdaQueryWrapperX;
import pc.exam.pp.module.judgement.controller.admin.Wps.vo.PptxListReqVO;
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.utils.tree.vo.TreeVO;
import java.util.Collection;
import java.util.List;
@Mapper
public interface WpsPptxLinkMapper extends BaseMapperX<WpsPptxLinkDO> {
default List<WpsPptxLinkDO> selectList(PptxListReqVO reqVO) {
return selectList(new LambdaQueryWrapperX<WpsPptxLinkDO>()
.likeIfPresent(WpsPptxLinkDO::getName, reqVO.getName())
.eq(reqVO.getBelongTo() != null, WpsPptxLinkDO::getBelongTo, reqVO.getBelongTo())
.eqIfPresent(WpsPptxLinkDO::getStatus, reqVO.getStatus()));
}
default WpsPptxLinkDO selectByParentIdAndName(Long parentId, String name) {
return selectOne(WpsPptxLinkDO::getParentId, parentId, WpsPptxLinkDO::getName, name);
}
default WpsPptxLinkDO selectByNodeFunction(String nodeFunction) {
LambdaQueryWrapper<WpsPptxLinkDO> wrapper = new LambdaQueryWrapper<>();
wrapper.like(WpsPptxLinkDO::getNodeFunction, nodeFunction);
return selectOne(wrapper);
}
default List<WpsPptxLinkDO> selectInfoList(Long id) {
return selectList(new LambdaQueryWrapperX<WpsPptxLinkDO>()
.eqIfPresent(WpsPptxLinkDO::getParentId, id));
}
default Long selectCountByParentId(Long parentId) {
return selectCount(WpsPptxLinkDO::getParentId, parentId);
}
default List<WpsPptxLinkDO> selectListByParentId(Collection<Long> parentIds) {
return selectList(WpsPptxLinkDO::getParentId, parentIds);
}
List<TreeVO> selectTreeListByNodeFunction();
}

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,8 @@ package pc.exam.pp.module.judgement.service.wps_excel;
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_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;
@@ -25,7 +27,7 @@ public interface JudgementWpsExcelService {
* @return 文件内得考点及描述
* @throws Exception 异常
*/
List<XlsxInfoVo> programmingWpsExcel(String path) throws Exception;
List<WpsPptxJudgementDto> 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,15 @@ 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.controller.admin.Wps.dto.WpsPptxJudgementDto;
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
@@ -42,12 +33,12 @@ public class JudgementWpsExcelServiceImpl implements JudgementWpsExcelService {
ConfigService configService;
@Override
public List<XlsxInfoVo> programmingWpsExcel(String path) throws Exception {
public List<WpsPptxJudgementDto> programmingWpsExcel(String path) throws Exception {
// 1、获取文件临时下载路径
ConfigDO config = configService.getConfigByKey("file_down_path");
// 2、下载文件并返回文件完整路径
String pathName = autoToolsService.downloadStudentFile(path, config.getValue());
List<XlsxInfoVo> margins = WpsExcelUtils.wpsExcel(pathName);
List<WpsPptxJudgementDto> margins = WpsExcelUtils.wpsExcel(pathName, "1");
// 5、已经读取完得考点删除源文件
File file = new File(pathName);
file.delete();
@@ -55,7 +46,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,8 +56,9 @@ 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);
List<WpsPptxJudgementDto> margins = WpsExcelUtils.wpsExcel(path, "0");
// 3、获取答案得组成
List<ExamQuestionAnswer> answerList = examQuestion.getAnswerList();
// 考点 sheetNumber@type@secondType@englishName@value
@@ -74,10 +67,9 @@ public class JudgementWpsExcelServiceImpl implements JudgementWpsExcelService {
for (ExamQuestionAnswer examQuestionAnswer : answerList) {
boolean flag = false;
double one_sorce = 0;
for (XlsxInfoVo xlsxInfoVo : margins) {
for (WpsPptxJudgementDto xlsxInfoVo : margins) {
// 原始考点
String originalTestPoint = xlsxInfoVo.getSheetNumber() + "@" + xlsxInfoVo.getType() + "@" + xlsxInfoVo.getSecondType() + "@" + xlsxInfoVo.getEnglishName() + "@" + xlsxInfoVo.getValue();
if (originalTestPoint.equals(examQuestionAnswer.getContent())) {
if (xlsxInfoVo.getContent().equals(examQuestionAnswer.getContent())) {
flag = true;
// 得分 根据权重进行得分 每个选项分值 = 总分 / 总权重
if (examQuestionAnswer.getScoreRate().equals("1")) {
@@ -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;

View File

@@ -1,113 +0,0 @@
package pc.exam.pp.module.judgement.service.wps_pptx;
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.dal.dataobject.wpspptx.WpsPptxLinkDO;
import pc.exam.pp.module.judgement.utils.tree.vo.TreeVO;
import java.util.*;
/**
* 节点 Service 接口
*
* @author 朋辰
*/
public interface WpsPptxLinkService {
/**
* 创建节点
*
* @param createReqVO 节点信息
* @return 节点编号
*/
Long createPptx(PptxSaveReqVO createReqVO);
/**
* 更新节点
*
* @param updateReqVO 节点信息
*/
void updatePptx(PptxSaveReqVO updateReqVO);
/**
* 删除节点
*
* @param id 节点编号
*/
void deletePptx(Long id);
/**
* 获得节点信息
*
* @param id 节点编号
* @return 节点信息
*/
WpsPptxLinkDO getPptx(Long id);
/**
* 获得节点信息数组
*
* @param ids 节点编号数组
* @return 节点信息数组
*/
List<WpsPptxLinkDO> getPptxList(Collection<Long> ids);
/**
* 筛选节点列表
*
* @param reqVO 筛选条件请求 VO
* @return 节点列表
*/
List<WpsPptxLinkDO> getPptxList(PptxListReqVO reqVO);
List<WpsPptxLinkDO> getPptxListInfo(PptxListReqVO reqVO);
/**
* 获得指定编号的节点 Map
*
* @param ids 节点编号数组
* @return 节点 Map
*/
default Map<Long, WpsPptxLinkDO> getPptxMap(Collection<Long> ids) {
List<WpsPptxLinkDO> list = getPptxList(ids);
return CollectionUtils.convertMap(list, WpsPptxLinkDO::getId);
}
/**
* 获得指定节点的所有子节点
*
* @param id 节点编号
* @return 子节点列表
*/
default List<WpsPptxLinkDO> getChildPptxList(Long id) {
return getChildPptxList(Collections.singleton(id));
}
/**
* 获得指定节点的所有子节点
*
* @param ids 节点编号数组
* @return 子节点列表
*/
List<WpsPptxLinkDO> getChildPptxList(Collection<Long> ids);
/**
* 获得所有子节点,从缓存中
*
* @param id 父节点编号
* @return 子节点列表
*/
Set<Long> getChildPptxIdListFromCache(Long id);
/**
* 校验节点们是否有效。如下情况,视为无效:
* 1. 节点编号不存在
* 2. 节点被禁用
*
* @param ids 角色编号数组
*/
void validatePptxList(Collection<Long> ids);
List<TreeVO> getPptxTreeList();
}

View File

@@ -1,250 +0,0 @@
package pc.exam.pp.module.judgement.service.wps_pptx;
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.PptxListReqVO;
import pc.exam.pp.module.judgement.controller.admin.Wps.vo.PptxSaveReqVO;
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.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 WpsPptxLinkServiceImpl implements WpsPptxLinkService {
@Resource
private WpsPptxLinkMapper wpsPptxLinkMapper;
@Override
@CacheEvict(cacheNames = RedisKeyConstants.WPS_PPTX_CHILDREN_ID_LIST,
allEntries = true) // allEntries 清空所有缓存,因为操作一个节点,涉及到多个缓存
public Long createPptx(PptxSaveReqVO createReqVO) {
if (createReqVO.getParentId() == null) {
createReqVO.setParentId(WpsPptxLinkDO.PARENT_ID_ROOT);
}
// 校验父节点的有效性
validateParentPptx(null, createReqVO.getParentId());
// 校验节点名的唯一性
validatePptxNameUnique(null, createReqVO.getParentId(), createReqVO.getName());
// 插入节点
WpsPptxLinkDO wpsPptxLinkDO = BeanUtils.toBean(createReqVO, WpsPptxLinkDO.class);
wpsPptxLinkMapper.insert(wpsPptxLinkDO);
return wpsPptxLinkDO.getId();
}
@Override
@CacheEvict(cacheNames = RedisKeyConstants.WPS_PPTX_CHILDREN_ID_LIST,
allEntries = true) // allEntries 清空所有缓存,因为操作一个节点,涉及到多个缓存
public void updatePptx(PptxSaveReqVO updateReqVO) {
if (updateReqVO.getParentId() == null) {
updateReqVO.setParentId(WpsPptxLinkDO.PARENT_ID_ROOT);
}
// 校验自己存在
validatePptxExists(updateReqVO.getId());
// 校验父节点的有效性
validateParentPptx(updateReqVO.getId(), updateReqVO.getParentId());
// 校验节点名的唯一性
validatePptxNameUnique(updateReqVO.getId(), updateReqVO.getParentId(), updateReqVO.getName());
// 更新节点
WpsPptxLinkDO updateObj = BeanUtils.toBean(updateReqVO, WpsPptxLinkDO.class);
wpsPptxLinkMapper.updateById(updateObj);
}
@Override
@CacheEvict(cacheNames = RedisKeyConstants.WPS_PPTX_CHILDREN_ID_LIST,
allEntries = true) // allEntries 清空所有缓存,因为操作一个节点,涉及到多个缓存
public void deletePptx(Long id) {
// 校验是否存在
validatePptxExists(id);
// 校验是否有子节点
if (wpsPptxLinkMapper.selectCountByParentId(id) > 0) {
throw exception(WORD_NOT_FOUND);
}
// 删除节点
wpsPptxLinkMapper.deleteById(id);
}
@VisibleForTesting
void validatePptxExists(Long id) {
if (id == null) {
return;
}
WpsPptxLinkDO wpsPptxLinkDO = wpsPptxLinkMapper.selectById(id);
if (wpsPptxLinkDO == null) {
throw exception(PPTX_NOT_FOUND);
}
}
@VisibleForTesting
void validateParentPptx(Long id, Long parentId) {
if (parentId == null || WpsPptxLinkDO.PARENT_ID_ROOT.equals(parentId)) {
return;
}
// 1. 不能设置自己为父节点
if (Objects.equals(id, parentId)) {
throw exception(PPTX_PARENT_ERROR);
}
// 2. 父节点不存在
WpsPptxLinkDO parentPptx = wpsPptxLinkMapper.selectById(parentId);
if (parentPptx == null) {
throw exception(PPTX_PARENT_NOT_EXITS);
}
// 3. 递归校验父节点,如果父节点是自己的子节点,则报错,避免形成环路
// id 为空,说明新增,不需要考虑环路
if (id == null) {
return;
}
for (int i = 0; i < Short.MAX_VALUE; i++) {
// 3.1 校验环路
parentId = parentPptx.getParentId();
if (Objects.equals(id, parentId)) {
throw exception(PPTX_PARENT_IS_CHILD);
}
// 3.2 继续递归下一级父节点
if (parentId == null || WpsPptxLinkDO.PARENT_ID_ROOT.equals(parentId)) {
break;
}
parentPptx = wpsPptxLinkMapper.selectById(parentId);
if (parentPptx == null) {
break;
}
}
}
@VisibleForTesting
void validatePptxNameUnique(Long id, Long parentId, String name) {
WpsPptxLinkDO wpsPptxLinkDO = wpsPptxLinkMapper.selectByParentIdAndName(parentId, name);
if (wpsPptxLinkDO == null) {
return;
}
// 如果 id 为空,说明不用比较是否为相同 id 的节点
if (id == null) {
throw exception(PPTX_NAME_DUPLICATE);
}
if (ObjectUtil.notEqual(wpsPptxLinkDO.getId(), id)) {
throw exception(PPTX_NAME_DUPLICATE);
}
}
@Override
public WpsPptxLinkDO getPptx(Long id) {
return wpsPptxLinkMapper.selectById(id);
}
@Override
public List<WpsPptxLinkDO> getPptxList(Collection<Long> ids) {
if (CollUtil.isEmpty(ids)) {
return Collections.emptyList();
}
return wpsPptxLinkMapper.selectBatchIds(ids);
}
@Override
public List<WpsPptxLinkDO> getPptxList(PptxListReqVO reqVO) {
List<WpsPptxLinkDO> list = wpsPptxLinkMapper.selectList(reqVO);
list.sort(Comparator.comparing(WpsPptxLinkDO::getSort));
return list;
}
@Override
public List<WpsPptxLinkDO> getPptxListInfo(PptxListReqVO reqVO) {
String nodeFunction = reqVO.getNodeFunction().split("\\[")[0];
List<WpsPptxLinkDO> pptxList = new ArrayList<>();
WpsPptxLinkDO data = wpsPptxLinkMapper.selectByNodeFunction(nodeFunction);
if (data == null) {
return Collections.emptyList();
}
List<WpsPptxLinkDO> wpsPptxLinkDOS = wpsPptxLinkMapper.selectInfoList(data.getId());
// 在依次判断是否还有子数据
for (WpsPptxLinkDO wpsPptxLinkDO : wpsPptxLinkDOS) {
pptxList.add(wpsPptxLinkDO);
List<WpsPptxLinkDO> datas = wpsPptxLinkMapper.selectInfoList(wpsPptxLinkDO.getId());
if (datas != null) {
for (WpsPptxLinkDO wpsPptxLinkDO1 : datas) {
pptxList.add(wpsPptxLinkDO1);
}
}
}
return pptxList;
}
@Override
public List<WpsPptxLinkDO> getChildPptxList(Collection<Long> ids) {
List<WpsPptxLinkDO> children = new LinkedList<>();
// 遍历每一层
Collection<Long> parentIds = ids;
// 使用 Short.MAX_VALUE 避免 bug 场景下,存在死循环
for (int i = 0; i < Short.MAX_VALUE; i++) {
// 查询当前层,所有的子节点
List<WpsPptxLinkDO> pptxs = wpsPptxLinkMapper.selectListByParentId(parentIds);
// 1. 如果没有子节点,则结束遍历
if (CollUtil.isEmpty(pptxs)) {
break;
}
// 2. 如果有子节点,继续遍历
children.addAll(pptxs);
parentIds = convertSet(pptxs, WpsPptxLinkDO::getId);
}
return children;
}
@Override
@DataPermission(enable = false) // 禁用数据权限,避免建立不正确的缓存
@Cacheable(cacheNames = RedisKeyConstants.WPS_PPTX_CHILDREN_ID_LIST, key = "#id")
public Set<Long> getChildPptxIdListFromCache(Long id) {
List<WpsPptxLinkDO> children = getChildPptxList(id);
return convertSet(children, WpsPptxLinkDO::getId);
}
@Override
public void validatePptxList(Collection<Long> ids) {
if (CollUtil.isEmpty(ids)) {
return;
}
// 获得科室信息
Map<Long, WpsPptxLinkDO> PptxMap = getPptxMap(ids);
// 校验
ids.forEach(id -> {
WpsPptxLinkDO Pptx = PptxMap.get(id);
if (Pptx == null) {
throw exception(PPTX_NOT_FOUND);
}
if (!CommonStatusEnum.ENABLE.getStatus().equals(Pptx.getStatus())) {
throw exception(PPTX_NOT_ENABLE, Pptx.getName());
}
});
}
@Override
@TenantIgnore
public List<TreeVO> getPptxTreeList() {
return wpsPptxLinkMapper.selectTreeListByNodeFunction();
}
}

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

@@ -10,10 +10,13 @@ import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.xmlbeans.XmlCursor;
import org.apache.xmlbeans.XmlObject;
import pc.exam.pp.module.judgement.controller.admin.Wps.dto.WpsPptxJudgementDto;
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,7 +39,74 @@ public class WpsExcelUtils {
public static int dxfId = 0;
public static List<XlsxInfoVo> wpsExcel(String filePath) throws Exception {
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<WpsPptxJudgementDto> wpsExcel(String filePath, String index) throws Exception {
// 获取共享字符串
String[] sharedStrings = extractSharedStrings(filePath);
// 读取样式xml
@@ -278,7 +348,28 @@ public class WpsExcelUtils {
} catch (InvalidFormatException e) {
throw new RuntimeException(e);
}
return xlsxInfoVos;
List<WpsPptxJudgementDto> xlsxInfos = new ArrayList<>();
for (XlsxInfoVo xlsxInfoVo : xlsxInfoVos) {
WpsPptxJudgementDto wpsPptxJudgementDto = new WpsPptxJudgementDto();
wpsPptxJudgementDto.setContentIn(xlsxInfoVo.getSheetName() + "@" + xlsxInfoVo.getTypeName() + "@" + xlsxInfoVo.getCell() + "@" + xlsxInfoVo.getSecondTypeName() + "@" + xlsxInfoVo.getChineseName() + "@"+ xlsxInfoVo.getValue());
wpsPptxJudgementDto.setContent(xlsxInfoVo.getSheetName() + "@" + xlsxInfoVo.getType() + "@" + xlsxInfoVo.getCell() + "@" + xlsxInfoVo.getSecondType() + "@" + xlsxInfoVo.getEnglishName() + "@"+ xlsxInfoVo.getValue());
wpsPptxJudgementDto.setScoreRate("1");
xlsxInfos.add(wpsPptxJudgementDto);
}
// TODO
if (index == "1") {
List<WpsPptxJudgementDto> randomItems = getRandomItems(xlsxInfos, 50);
return randomItems;
} else {
return xlsxInfos;
}
}
// 扁平化多维列表
public static <T> List<T> getRandomItems(List<T> list, int count) {
List<T> copy = new ArrayList<>(list); // 创建副本,避免修改原列表
Collections.shuffle(copy); // 打乱顺序
return copy.subList(0, Math.min(count, copy.size())); // 抽取前count个
}
// 支持所有类型的单元格

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<>();

View File

@@ -1,28 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="pc.exam.pp.module.judgement.dal.mysql.wpspptx.WpsPptxLinkMapper">
<!--
一般情况下,尽可能使用 Mapper 进行 CRUD 增删改查即可。
无法满足的场景,例如说多表关联查询,才使用 XML 编写 SQL。
代码生成器暂时只生成 Mapper XML 文件本身,更多推荐 MybatisX 快速开发插件来生成查询。
文档可见https://www.iocoder.cn/MyBatis/x-plugins/
-->
<resultMap id="NodeResultMap" type="pc.exam.pp.module.judgement.utils.tree.vo.TreeVO">
<id property="id" column="id" jdbcType="BIGINT"/>
<result property="name" column="name" jdbcType="VARCHAR"/>
<result property="parentId" column="parent_id" jdbcType="BIGINT"/>
<result property="nodeFunction" column="node_function" jdbcType="VARCHAR"/>
<result property="toChinese" column="to_chinese" jdbcType="VARCHAR"/>
<result property="type" column="type" jdbcType="TINYINT"/>
</resultMap>
<select id="selectTreeListByNodeFunction" resultMap="NodeResultMap">
SELECT
*
FROM
wps_pptx_link
</select>
</mapper>