【新增】新版本使用docx4j验证word
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
package pc.exam.pp.module.exam.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.exam.controller.admin.wps.vo.docx.DocxListReqVO;
|
||||
import pc.exam.pp.module.exam.controller.admin.wps.vo.docx.DocxRespVO;
|
||||
import pc.exam.pp.module.exam.controller.admin.wps.vo.docx.DocxSaveReqVO;
|
||||
import pc.exam.pp.module.exam.controller.admin.wps.vo.docx.DocxSimpleRespVO;
|
||||
import pc.exam.pp.module.exam.dal.dataobject.wps.ExamWpsDocx;
|
||||
import pc.exam.pp.module.exam.service.wps.docx.ExamWpsDocxService;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static pc.exam.pp.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@Tag(name = "考试系统 - DOCX考点")
|
||||
@RestController
|
||||
@RequestMapping("/exam/docx")
|
||||
@Validated
|
||||
public class ExamWpsDocxController {
|
||||
|
||||
@Resource
|
||||
private ExamWpsDocxService examWpsDocxService;
|
||||
|
||||
@PostMapping("create")
|
||||
@Operation(summary = "创建Docx考点")
|
||||
public CommonResult<Long> createDocx(@Valid @RequestBody DocxSaveReqVO createReqVO) {
|
||||
Long DocxId = examWpsDocxService.createDocx(createReqVO);
|
||||
return success(DocxId);
|
||||
}
|
||||
|
||||
@PutMapping("update")
|
||||
@Operation(summary = "更新Docx考点")
|
||||
public CommonResult<Boolean> updateDocx(@Valid @RequestBody DocxSaveReqVO updateReqVO) {
|
||||
examWpsDocxService.updateDocx(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("delete")
|
||||
@Operation(summary = "删除Docx考点")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
public CommonResult<Boolean> deleteDocx(@RequestParam("id") Long id) {
|
||||
examWpsDocxService.deleteDocx(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/list")
|
||||
@Operation(summary = "获取Docx考点列表")
|
||||
public CommonResult<List<DocxRespVO>> getDocxList(DocxListReqVO reqVO) {
|
||||
List<ExamWpsDocx> list = examWpsDocxService.getDocxList(reqVO);
|
||||
return success(BeanUtils.toBean(list, DocxRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping(value = {"/list-all-simple", "/simple-list"})
|
||||
@Operation(summary = "获取Docx考点精简信息列表", description = "只包含被开启的Docx考点,主要用于前端的下拉选项")
|
||||
public CommonResult<List<DocxSimpleRespVO>> getSimpleDocxList() {
|
||||
List<ExamWpsDocx> list = examWpsDocxService.getDocxList(
|
||||
new DocxListReqVO().setStatus(CommonStatusEnum.ENABLE.getStatus()));
|
||||
return success(BeanUtils.toBean(list, DocxSimpleRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得Docx考点信息")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
public CommonResult<DocxRespVO> getDocx(@RequestParam("id") Long id) {
|
||||
ExamWpsDocx Docx = examWpsDocxService.getDocx(id);
|
||||
return success(BeanUtils.toBean(Docx, DocxRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/getByNameList")
|
||||
public CommonResult<List<DocxRespVO>> getDocxByNameList(@RequestParam("title") String title) {
|
||||
ExamWpsDocx Docx = examWpsDocxService.getDocxByTitle(title);
|
||||
return success(BeanUtils.toBean(examWpsDocxService.getChildDocxList(Docx.getId()), DocxRespVO.class));
|
||||
}
|
||||
}
|
@@ -0,0 +1,14 @@
|
||||
package pc.exam.pp.module.exam.controller.admin.wps.vo.docx;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
@Schema(description = "考试模块 - PPT考点列表 Request VO")
|
||||
@Data
|
||||
public class DocxListReqVO {
|
||||
|
||||
private String name;
|
||||
|
||||
private Integer status;
|
||||
|
||||
}
|
@@ -0,0 +1,40 @@
|
||||
package pc.exam.pp.module.exam.controller.admin.wps.vo.docx;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Schema(description = "考试模块 - PPT考点信息 Response VO")
|
||||
@Data
|
||||
public class DocxRespVO {
|
||||
|
||||
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;
|
||||
|
||||
}
|
@@ -0,0 +1,36 @@
|
||||
package pc.exam.pp.module.exam.controller.admin.wps.vo.docx;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
@Schema(description = "考试模块 - PPT考点创建/修改 Request VO")
|
||||
@Data
|
||||
public class DocxSaveReqVO {
|
||||
|
||||
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;
|
||||
|
||||
}
|
@@ -0,0 +1,20 @@
|
||||
package pc.exam.pp.module.exam.controller.admin.wps.vo.docx;
|
||||
|
||||
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 DocxSimpleRespVO {
|
||||
|
||||
private Long id;
|
||||
|
||||
private String name;
|
||||
|
||||
private Long parentId;
|
||||
|
||||
}
|
@@ -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 docx关系对应表
|
||||
*
|
||||
* @author REN
|
||||
*/
|
||||
@TableName("exam_wps_docx")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class ExamWpsDocx 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<ExamWpsDocx> children = new ArrayList<>();
|
||||
}
|
@@ -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.docx.DocxListReqVO;
|
||||
import pc.exam.pp.module.exam.dal.dataobject.wps.ExamWpsDocx;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
@Mapper
|
||||
public interface ExamWpsDocxMapper extends BaseMapperX<ExamWpsDocx> {
|
||||
|
||||
default List<ExamWpsDocx> selectList(DocxListReqVO reqVO) {
|
||||
return selectList(new LambdaQueryWrapperX<ExamWpsDocx>()
|
||||
.likeIfPresent(ExamWpsDocx::getName, reqVO.getName())
|
||||
.eqIfPresent(ExamWpsDocx::getStatus, reqVO.getStatus()));
|
||||
}
|
||||
|
||||
default ExamWpsDocx selectByParentIdAndName(Long parentId, String name) {
|
||||
return selectOne(ExamWpsDocx::getParentId, parentId, ExamWpsDocx::getName, name);
|
||||
}
|
||||
|
||||
default ExamWpsDocx selectByTitle(String title) {
|
||||
return selectOne(ExamWpsDocx::getTitle, title);
|
||||
}
|
||||
|
||||
default Long selectCountByParentId(Long parentId) {
|
||||
return selectCount(ExamWpsDocx::getParentId, parentId);
|
||||
}
|
||||
|
||||
default List<ExamWpsDocx> selectListByParentId(Collection<Long> parentIds) {
|
||||
return selectList(ExamWpsDocx::getParentId, parentIds);
|
||||
}
|
||||
}
|
@@ -0,0 +1,221 @@
|
||||
package pc.exam.pp.module.exam.service.wps.docx;
|
||||
|
||||
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.docx.DocxListReqVO;
|
||||
import pc.exam.pp.module.exam.controller.admin.wps.vo.docx.DocxSaveReqVO;
|
||||
import pc.exam.pp.module.exam.dal.dataobject.wps.ExamWpsDocx;
|
||||
import pc.exam.pp.module.exam.dal.mysql.wps.ExamWpsDocxMapper;
|
||||
|
||||
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.*;
|
||||
|
||||
/**
|
||||
* Docx考点 Service 实现类
|
||||
*
|
||||
* @author 朋辰
|
||||
*/
|
||||
@Service
|
||||
@Validated
|
||||
@Slf4j
|
||||
public class ExamWpsDcxoServiceImpl implements ExamWpsDocxService {
|
||||
|
||||
@Resource
|
||||
private ExamWpsDocxMapper DocxMapper;
|
||||
|
||||
@Override
|
||||
public Long createDocx(DocxSaveReqVO createReqVO) {
|
||||
if (createReqVO.getParentId() == null) {
|
||||
createReqVO.setParentId(ExamWpsDocx.PARENT_ID_ROOT);
|
||||
}
|
||||
// 校验父Docx考点的有效性
|
||||
validateParentDocx(null, createReqVO.getParentId());
|
||||
// 校验Docx考点名的唯一性
|
||||
validateDocxNameUnique(null, createReqVO.getParentId(), createReqVO.getName());
|
||||
|
||||
// 插入Docx考点
|
||||
ExamWpsDocx Docx = BeanUtils.toBean(createReqVO, ExamWpsDocx.class);
|
||||
DocxMapper.insert(Docx);
|
||||
return Docx.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateDocx(DocxSaveReqVO updateReqVO) {
|
||||
if (updateReqVO.getParentId() == null) {
|
||||
updateReqVO.setParentId(ExamWpsDocx.PARENT_ID_ROOT);
|
||||
}
|
||||
// 校验自己存在
|
||||
validateDocxExists(updateReqVO.getId());
|
||||
// 校验父Docx考点的有效性
|
||||
validateParentDocx(updateReqVO.getId(), updateReqVO.getParentId());
|
||||
// 校验Docx考点名的唯一性
|
||||
validateDocxNameUnique(updateReqVO.getId(), updateReqVO.getParentId(), updateReqVO.getName());
|
||||
|
||||
// 更新Docx考点
|
||||
ExamWpsDocx updateObj = BeanUtils.toBean(updateReqVO, ExamWpsDocx.class);
|
||||
DocxMapper.updateById(updateObj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteDocx(Long id) {
|
||||
// 校验是否存在
|
||||
validateDocxExists(id);
|
||||
// 校验是否有子Docx考点
|
||||
if (DocxMapper.selectCountByParentId(id) > 0) {
|
||||
throw exception(DOCX_EXITS_CHILDREN);
|
||||
}
|
||||
// 删除Docx考点
|
||||
DocxMapper.deleteById(id);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void validateDocxExists(Long id) {
|
||||
if (id == null) {
|
||||
return;
|
||||
}
|
||||
ExamWpsDocx Docx = DocxMapper.selectById(id);
|
||||
if (Docx == null) {
|
||||
throw exception(DOCX_NOT_FOUND);
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void validateParentDocx(Long id, Long parentId) {
|
||||
if (parentId == null || ExamWpsDocx.PARENT_ID_ROOT.equals(parentId)) {
|
||||
return;
|
||||
}
|
||||
// 1. 不能设置自己为父Docx考点
|
||||
if (Objects.equals(id, parentId)) {
|
||||
throw exception(DOCX_PARENT_ERROR);
|
||||
}
|
||||
// 2. 父Docx考点不存在
|
||||
ExamWpsDocx parent = DocxMapper.selectById(parentId);
|
||||
if (parent == null) {
|
||||
throw exception(DOCX_PARENT_NOT_EXITS);
|
||||
}
|
||||
// 3. 递归校验父Docx考点,如果父Docx考点是自己的子Docx考点,则报错,避免形成环路
|
||||
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(DOCX_PARENT_IS_CHILD);
|
||||
}
|
||||
// 3.2 继续递归下一级父Docx考点
|
||||
if (parentId == null || ExamWpsDocx.PARENT_ID_ROOT.equals(parentId)) {
|
||||
break;
|
||||
}
|
||||
parent = DocxMapper.selectById(parentId);
|
||||
if (parent == null) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void validateDocxNameUnique(Long id, Long parentId, String name) {
|
||||
ExamWpsDocx dept = DocxMapper.selectByParentIdAndName(parentId, name);
|
||||
if (dept == null) {
|
||||
return;
|
||||
}
|
||||
// 如果 id 为空,说明不用比较是否为相同 id 的Docx考点
|
||||
if (id == null) {
|
||||
throw exception(DOCX_NAME_DUPLICATE);
|
||||
}
|
||||
if (ObjectUtil.notEqual(dept.getId(), id)) {
|
||||
throw exception(DOCX_NAME_DUPLICATE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExamWpsDocx getDocx(Long id) {
|
||||
return DocxMapper.selectById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExamWpsDocx getDocxByTitle(String title) {
|
||||
return DocxMapper.selectByTitle(title);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ExamWpsDocx> getDocxList(Collection<Long> ids) {
|
||||
if (CollUtil.isEmpty(ids)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return DocxMapper.selectBatchIds(ids);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ExamWpsDocx> getDocxList(DocxListReqVO reqVO) {
|
||||
List<ExamWpsDocx> list = DocxMapper.selectList(reqVO);
|
||||
list.sort(Comparator.comparing(ExamWpsDocx::getSort));
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Long, ExamWpsDocx> getDocxMap(Collection<Long> ids) {
|
||||
return ExamWpsDocxService.super.getDocxMap(ids);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ExamWpsDocx> getChildDocxList(Long id) {
|
||||
return ExamWpsDocxService.super.getChildDocxList(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ExamWpsDocx> getChildDocxList(Collection<Long> ids) {
|
||||
List<ExamWpsDocx> children = new LinkedList<>();
|
||||
// 遍历每一层
|
||||
Collection<Long> parentIds = ids;
|
||||
for (int i = 0; i < Short.MAX_VALUE; i++) { // 使用 Short.MAX_VALUE 避免 bug 场景下,存在死循环
|
||||
// 查询当前层,所有的子Docx考点
|
||||
List<ExamWpsDocx> Docxs = DocxMapper.selectListByParentId(parentIds);
|
||||
// 1. 如果没有子Docx考点,则结束遍历
|
||||
if (CollUtil.isEmpty(Docxs)) {
|
||||
break;
|
||||
}
|
||||
// 2. 如果有子Docx考点,继续遍历
|
||||
children.addAll(Docxs);
|
||||
parentIds = convertSet(Docxs, ExamWpsDocx::getId);
|
||||
}
|
||||
return children;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Long> getChildDocxIdListFromCache(Long id) {
|
||||
List<ExamWpsDocx> children = getChildDocxList(id);
|
||||
return convertSet(children, ExamWpsDocx::getId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validateDocxList(Collection<Long> ids) {
|
||||
if (CollUtil.isEmpty(ids)) {
|
||||
return;
|
||||
}
|
||||
// 获得信息
|
||||
Map<Long, ExamWpsDocx> DocxMap = getDocxMap(ids);
|
||||
// 校验
|
||||
ids.forEach(id -> {
|
||||
ExamWpsDocx Docx = DocxMap.get(id);
|
||||
if (Docx == null) {
|
||||
throw exception(DOCX_NOT_FOUND);
|
||||
}
|
||||
if (!CommonStatusEnum.ENABLE.getStatus().equals(Docx.getStatus())) {
|
||||
throw exception(DOCX_NOT_ENABLE, Docx.getName());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,117 @@
|
||||
package pc.exam.pp.module.exam.service.wps.docx;
|
||||
|
||||
import pc.exam.pp.framework.common.util.collection.CollectionUtils;
|
||||
import pc.exam.pp.module.exam.controller.admin.wps.vo.docx.DocxListReqVO;
|
||||
import pc.exam.pp.module.exam.controller.admin.wps.vo.docx.DocxSaveReqVO;
|
||||
import pc.exam.pp.module.exam.dal.dataobject.wps.ExamWpsDocx;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Docx考点 Service 接口
|
||||
*
|
||||
* @author 朋辰
|
||||
*/
|
||||
public interface ExamWpsDocxService {
|
||||
|
||||
/**
|
||||
* 创建Docx考点
|
||||
*
|
||||
* @param createReqVO Docx考点信息
|
||||
* @return Docx考点编号
|
||||
*/
|
||||
Long createDocx(DocxSaveReqVO createReqVO);
|
||||
|
||||
/**
|
||||
* 更新Docx考点
|
||||
*
|
||||
* @param updateReqVO Docx考点信息
|
||||
*/
|
||||
void updateDocx(DocxSaveReqVO updateReqVO);
|
||||
|
||||
/**
|
||||
* 删除Docx考点
|
||||
*
|
||||
* @param id Docx考点编号
|
||||
*/
|
||||
void deleteDocx(Long id);
|
||||
|
||||
/**
|
||||
* 获得Docx考点信息
|
||||
*
|
||||
* @param id Docx考点编号
|
||||
* @return Docx考点信息
|
||||
*/
|
||||
ExamWpsDocx getDocx(Long id);
|
||||
|
||||
/**
|
||||
* 获得Docx考点信息
|
||||
*
|
||||
* @param title Docx考点标签
|
||||
* @return Docx考点信息
|
||||
*/
|
||||
ExamWpsDocx getDocxByTitle(String title);
|
||||
|
||||
/**
|
||||
* 获得Docx考点信息数组
|
||||
*
|
||||
* @param ids Docx考点编号数组
|
||||
* @return Docx考点信息数组
|
||||
*/
|
||||
List<ExamWpsDocx> getDocxList(Collection<Long> ids);
|
||||
|
||||
/**
|
||||
* 筛选Docx考点列表
|
||||
*
|
||||
* @param reqVO 筛选条件请求 VO
|
||||
* @return Docx考点列表
|
||||
*/
|
||||
List<ExamWpsDocx> getDocxList(DocxListReqVO reqVO);
|
||||
|
||||
/**
|
||||
* 获得指定编号的Docx考点 Map
|
||||
*
|
||||
* @param ids Docx考点编号数组
|
||||
* @return Docx考点 Map
|
||||
*/
|
||||
default Map<Long, ExamWpsDocx> getDocxMap(Collection<Long> ids) {
|
||||
List<ExamWpsDocx> list = getDocxList(ids);
|
||||
return CollectionUtils.convertMap(list, ExamWpsDocx::getId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得指定Docx考点的所有子Docx考点
|
||||
*
|
||||
* @param id Docx考点编号
|
||||
* @return 子Docx考点列表
|
||||
*/
|
||||
default List<ExamWpsDocx> getChildDocxList(Long id) {
|
||||
return getChildDocxList(Collections.singleton(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得指定Docx考点的所有子Docx考点
|
||||
*
|
||||
* @param ids Docx考点编号数组
|
||||
* @return 子Docx考点列表
|
||||
*/
|
||||
List<ExamWpsDocx> getChildDocxList(Collection<Long> ids);
|
||||
|
||||
/**
|
||||
* 获得所有子Docx考点,从缓存中
|
||||
*
|
||||
* @param id 父Docx考点编号
|
||||
* @return 子Docx考点列表
|
||||
*/
|
||||
Set<Long> getChildDocxIdListFromCache(Long id);
|
||||
|
||||
/**
|
||||
* 校验Docx考点们是否有效。如下情况,视为无效:
|
||||
* 1. Docx考点编号不存在
|
||||
* 2. Docx考点被禁用
|
||||
*
|
||||
* @param ids 角色编号数组
|
||||
*/
|
||||
void validateDocxList(Collection<Long> ids);
|
||||
|
||||
}
|
@@ -4,7 +4,9 @@ import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import pc.exam.pp.framework.common.pojo.CommonResult;
|
||||
import pc.exam.pp.module.infra.controller.admin.file.vo.file.FileUploadReqVO;
|
||||
import pc.exam.pp.module.judgement.controller.admin.AutoWps.vo.WpsDocxInfoVo;
|
||||
import pc.exam.pp.module.judgement.controller.admin.Wps.dto.WpsPptxJudgementDto;
|
||||
import pc.exam.pp.module.judgement.controller.admin.Wps.dto.WpsWordJudgementDto;
|
||||
@@ -14,6 +16,7 @@ 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_pptx.judgementVO.JudgementReqVo;
|
||||
import pc.exam.pp.module.judgement.utils.wps_pptx.vo.PptxInfoReqVo;
|
||||
import pc.exam.pp.module.judgement.utils.wps_word.docx4j.vo.DocxDataInfoVO;
|
||||
import pc.exam.pp.module.judgement.utils.wps_word.docx4j.vo.JudgementWordsVO;
|
||||
import pc.exam.pp.module.judgement.utils.wps_word.vo.WordInfoReqVo;
|
||||
|
||||
@@ -54,9 +57,9 @@ public class AutoWpsController {
|
||||
* wps word
|
||||
* @return 获取大类
|
||||
*/
|
||||
@GetMapping("/runWpsWord")
|
||||
public CommonResult<List<WordInfoReqVo>> runWpsWord(String path) throws Exception {
|
||||
return CommonResult.success(judgementWpsWordService.programmingWpsWord(path));
|
||||
@PostMapping("/docxDataInfo")
|
||||
public CommonResult<List<DocxDataInfoVO>> runWpsWord(FileUploadReqVO file) throws Exception {
|
||||
return CommonResult.success(judgementWpsWordService.docxDataInfo(file.getFile()));
|
||||
}
|
||||
|
||||
|
||||
|
@@ -1,85 +0,0 @@
|
||||
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.WordListReqVO;
|
||||
import pc.exam.pp.module.judgement.controller.admin.Wps.vo.WordRespVO;
|
||||
import pc.exam.pp.module.judgement.controller.admin.Wps.vo.WordSaveReqVO;
|
||||
import pc.exam.pp.module.judgement.controller.admin.Wps.vo.WordSimpleRespVO;
|
||||
import pc.exam.pp.module.judgement.dal.dataobject.wpsword.WpsWordLinkDO;
|
||||
import pc.exam.pp.module.judgement.service.wps_word.WpsWordLinkService;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static pc.exam.pp.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@Tag(name = "管理后台 - wps_word")
|
||||
@RestController
|
||||
@RequestMapping("/wps/word")
|
||||
@Validated
|
||||
public class WordController {
|
||||
|
||||
@Resource
|
||||
private WpsWordLinkService wpsWordLinkService;
|
||||
|
||||
@PostMapping("create")
|
||||
@Operation(summary = "创建wps_word")
|
||||
public CommonResult<Long> createWord(@Valid @RequestBody WordSaveReqVO createReqVO) {
|
||||
Long wordId = wpsWordLinkService.createWord(createReqVO);
|
||||
return success(wordId);
|
||||
}
|
||||
|
||||
@PutMapping("update")
|
||||
@Operation(summary = "更新wps_word")
|
||||
public CommonResult<Boolean> updateWord(@Valid @RequestBody WordSaveReqVO updateReqVO) {
|
||||
wpsWordLinkService.updateWord(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("delete")
|
||||
@Operation(summary = "删除wps_word")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
public CommonResult<Boolean> deleteWord(@RequestParam("id") Long id) {
|
||||
wpsWordLinkService.deleteWord(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/list")
|
||||
@Operation(summary = "获取wps_word列表")
|
||||
public CommonResult<List<WordRespVO>> getWordList(WordListReqVO reqVO) {
|
||||
List<WpsWordLinkDO> list = wpsWordLinkService.getWordList(reqVO);
|
||||
return success(BeanUtils.toBean(list, WordRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping(value = {"/list-all-simple", "/simple-list"})
|
||||
@Operation(summary = "获取wps_word精简信息列表", description = "只包含被开启的wps_word,主要用于前端的下拉选项")
|
||||
public CommonResult<List<WordSimpleRespVO>> getSimpleWordList() {
|
||||
List<WpsWordLinkDO> list = wpsWordLinkService.getWordList(
|
||||
new WordListReqVO().setStatus(CommonStatusEnum.ENABLE.getStatus()));
|
||||
return success(BeanUtils.toBean(list, WordSimpleRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得wps_word信息")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
public CommonResult<WordRespVO> getWord(@RequestParam("id") Long id) {
|
||||
WpsWordLinkDO word = wpsWordLinkService.getWord(id);
|
||||
return success(BeanUtils.toBean(word, WordRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/listInfo")
|
||||
@Operation(summary = "获取wps_word子数据列表")
|
||||
public CommonResult<List<WordRespVO>> getWordInfoList(WordListReqVO reqVO) {
|
||||
List<WpsWordLinkDO> list = wpsWordLinkService.getWordInfoList(reqVO);
|
||||
return success(BeanUtils.toBean(list, WordRespVO.class));
|
||||
}
|
||||
|
||||
}
|
@@ -53,23 +53,23 @@ public class WpsController {
|
||||
public CommonResult<List<JudgementWordsVO>> docxMaster(@RequestBody List<WpsDocxInfoVo> wpsDocxInfoVos) throws Exception {
|
||||
return CommonResult.success(judgementWpsWordService.docxMaster(wpsDocxInfoVos));
|
||||
}
|
||||
/**
|
||||
* wps word
|
||||
* @return 判分
|
||||
*/
|
||||
@PostMapping("/runWpsWordInfo")
|
||||
public CommonResult<List<WpsWordJudgementDto>> runWpsWordInfo(@RequestBody List<WpsWordReqDto> wordReqDto) throws Exception {
|
||||
return CommonResult.success(judgementWpsWordService.programmingInfo(wordReqDto));
|
||||
}
|
||||
|
||||
/**
|
||||
* wps word
|
||||
* @return 判分
|
||||
*/
|
||||
@GetMapping("/runWpsWord")
|
||||
public CommonResult<List<WordInfoReqVo>> runWpsWord(String path) throws Exception {
|
||||
return CommonResult.success(judgementWpsWordService.programmingWpsWord(path));
|
||||
}
|
||||
// /**
|
||||
// * wps word
|
||||
// * @return 判分
|
||||
// */
|
||||
// @PostMapping("/runWpsWordInfo")
|
||||
// public CommonResult<List<WpsWordJudgementDto>> runWpsWordInfo(@RequestBody List<WpsWordReqDto> wordReqDto) throws Exception {
|
||||
// return CommonResult.success(judgementWpsWordService.programmingInfo(wordReqDto));
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * wps word
|
||||
// * @return 判分
|
||||
// */
|
||||
// @GetMapping("/runWpsWord")
|
||||
// public CommonResult<List<WordInfoReqVo>> runWpsWord(String path) throws Exception {
|
||||
// return CommonResult.success(judgementWpsWordService.programmingWpsWord(path));
|
||||
// }
|
||||
/**
|
||||
* wps xlsx
|
||||
* @return 判分
|
||||
|
@@ -22,7 +22,7 @@ import pc.exam.pp.module.exam.service.stuPaperScore.StuPaperScoreService;
|
||||
import pc.exam.pp.module.exam.service.stu_paper_file.StuPaperFileService;
|
||||
import pc.exam.pp.module.judgement.controller.admin.autoTools.vo.StuPaperReqVo;
|
||||
import pc.exam.pp.module.judgement.controller.admin.autoTools.vo.StuPaperScoreInfoVo;
|
||||
import pc.exam.pp.module.judgement.service.auto_tools.AutoToolsService;
|
||||
//import pc.exam.pp.module.judgement.service.auto_tools.AutoToolsService;
|
||||
import pc.exam.pp.module.judgement.service.c_programming.JudgementService;
|
||||
import pc.exam.pp.module.judgement.service.wps_excel.JudgementWpsExcelService;
|
||||
import pc.exam.pp.module.judgement.service.wps_pptx.JudgementWpsPptxService;
|
||||
|
@@ -1,71 +0,0 @@
|
||||
package pc.exam.pp.module.judgement.dal.dataobject.wpsword;
|
||||
|
||||
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 pc.exam.pp.module.judgement.utils.tree.vo.TreeVO;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* wps word关系对应表
|
||||
*
|
||||
*/
|
||||
@TableName("wps_word_link")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class WpsWordLinkDO 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 Integer belongTo;
|
||||
private Integer isboo;
|
||||
private Integer titleType;
|
||||
private String unit;
|
||||
private String page;
|
||||
|
||||
@TableField(exist = false)
|
||||
private List<WpsWordLinkDO> children = new ArrayList<>();
|
||||
}
|
@@ -1,47 +0,0 @@
|
||||
package pc.exam.pp.module.judgement.dal.mysql.wpsword;
|
||||
|
||||
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.WordListReqVO;
|
||||
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 WpsWordLinkMapper extends BaseMapperX<WpsWordLinkDO> {
|
||||
|
||||
default List<WpsWordLinkDO> selectList(WordListReqVO reqVO) {
|
||||
return selectList(new LambdaQueryWrapperX<WpsWordLinkDO>()
|
||||
.likeIfPresent(WpsWordLinkDO::getName, reqVO.getName())
|
||||
.eq(reqVO.getBelongTo() != null, WpsWordLinkDO::getBelongTo, reqVO.getBelongTo())
|
||||
.eq(reqVO.getNodeFunction() != null, WpsWordLinkDO::getNodeFunction, reqVO.getNodeFunction())
|
||||
.eqIfPresent(WpsWordLinkDO::getStatus, reqVO.getStatus()));
|
||||
}
|
||||
|
||||
default WpsWordLinkDO selectByParentIdAndName(Long parentId, String name) {
|
||||
return selectOne(WpsWordLinkDO::getParentId, parentId, WpsWordLinkDO::getName, name);
|
||||
}
|
||||
|
||||
default WpsWordLinkDO selectByNodeFunction(String nodeFunction) {
|
||||
return selectOne(WpsWordLinkDO::getNodeFunction, nodeFunction);
|
||||
}
|
||||
|
||||
default List<WpsWordLinkDO> selectInfoList(Long id) {
|
||||
return selectList(new LambdaQueryWrapperX<WpsWordLinkDO>()
|
||||
.eqIfPresent(WpsWordLinkDO::getParentId, id));
|
||||
}
|
||||
|
||||
default Long selectCountByParentId(Long parentId) {
|
||||
return selectCount(WpsWordLinkDO::getParentId, parentId);
|
||||
}
|
||||
|
||||
default List<WpsWordLinkDO> selectListByParentId(Collection<Long> parentIds) {
|
||||
return selectList(WpsWordLinkDO::getParentId, parentIds);
|
||||
}
|
||||
|
||||
List<TreeVO> selectTreeListByNodeFunction();
|
||||
|
||||
}
|
@@ -1,38 +1,38 @@
|
||||
package pc.exam.pp.module.judgement.service.auto_tools;
|
||||
|
||||
import pc.exam.pp.framework.common.pojo.CommonResult;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
public interface AutoToolsService {
|
||||
|
||||
|
||||
// 文件自动上传
|
||||
|
||||
// Boolean autoFileTools(Long studentId, String paperId);
|
||||
|
||||
/**
|
||||
* 文件下载
|
||||
* @param fileUrl 文件url
|
||||
* @param filePath 要下载的文件路径
|
||||
* @return 下载后的文件path
|
||||
*/
|
||||
String downloadStudentFile(String fileUrl, String filePath);
|
||||
|
||||
//package pc.exam.pp.module.judgement.service.auto_tools;
|
||||
//
|
||||
|
||||
/**
|
||||
* 解压文件
|
||||
* @param zipFilePath zip文件路径
|
||||
* @return 解压后的目录
|
||||
*/
|
||||
String unzipToNamedFolder(String zipFilePath);
|
||||
|
||||
/**
|
||||
* 判分
|
||||
* @param stuId 学号
|
||||
* @param paperId 试卷ID
|
||||
* @return 分数
|
||||
*/
|
||||
CommonResult<BigDecimal> judgementScore(Long stuId, String paperId) throws Exception;
|
||||
}
|
||||
//import pc.exam.pp.framework.common.pojo.CommonResult;
|
||||
//
|
||||
//import java.math.BigDecimal;
|
||||
//
|
||||
//public interface AutoToolsService {
|
||||
//
|
||||
//
|
||||
// // 文件自动上传
|
||||
//
|
||||
// // Boolean autoFileTools(Long studentId, String paperId);
|
||||
//
|
||||
// /**
|
||||
// * 文件下载
|
||||
// * @param fileUrl 文件url
|
||||
// * @param filePath 要下载的文件路径
|
||||
// * @return 下载后的文件path
|
||||
// */
|
||||
// String downloadStudentFile(String fileUrl, String filePath);
|
||||
//
|
||||
// //
|
||||
//
|
||||
// /**
|
||||
// * 解压文件
|
||||
// * @param zipFilePath zip文件路径
|
||||
// * @return 解压后的目录
|
||||
// */
|
||||
// String unzipToNamedFolder(String zipFilePath);
|
||||
//
|
||||
// /**
|
||||
// * 判分
|
||||
// * @param stuId 学号
|
||||
// * @param paperId 试卷ID
|
||||
// * @return 分数
|
||||
// */
|
||||
// CommonResult<BigDecimal> judgementScore(Long stuId, String paperId) throws Exception;
|
||||
//}
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -29,5 +29,4 @@ public interface JudgementWpsExcelService {
|
||||
*/
|
||||
List<WpsPptxJudgementDto> programmingWpsExcel(String path) throws Exception;
|
||||
|
||||
SourceAndText judgementWpsXlsx(double sorce, String pathC, String path, ExamQuestion examQuestion, String judgementStr) throws Exception;
|
||||
}
|
||||
|
@@ -11,13 +11,15 @@ 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.dal.mysql.wpsxlsx.WpsXlsxLinkMapper;
|
||||
import pc.exam.pp.module.judgement.service.auto_tools.AutoToolsService;
|
||||
//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.xlsx_drawing.XlsxInfoVo;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.*;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
@@ -26,8 +28,8 @@ public class JudgementWpsExcelServiceImpl implements JudgementWpsExcelService {
|
||||
@Resource
|
||||
WpsXlsxLinkMapper wpsXlsxLinkMapper;
|
||||
|
||||
@Resource
|
||||
AutoToolsService autoToolsService;
|
||||
// @Resource
|
||||
// AutoToolsService autoToolsService;
|
||||
|
||||
@Resource
|
||||
ConfigService configService;
|
||||
@@ -37,65 +39,43 @@ public class JudgementWpsExcelServiceImpl implements JudgementWpsExcelService {
|
||||
// 1、获取文件临时下载路径
|
||||
ConfigDO config = configService.getConfigByKey("file_down_path");
|
||||
// 2、下载文件并返回文件完整路径
|
||||
String pathName = autoToolsService.downloadStudentFile(path, config.getValue());
|
||||
String pathName = downloadStudentFile(path, config.getValue());
|
||||
List<WpsPptxJudgementDto> margins = WpsExcelUtils.wpsExcel(pathName, "1");
|
||||
// 5、已经读取完得考点删除源文件
|
||||
File file = new File(pathName);
|
||||
file.delete();
|
||||
return margins;
|
||||
}
|
||||
public String downloadStudentFile(String fileUrl, String filePath) {
|
||||
try {
|
||||
URL url = new URL(fileUrl);
|
||||
URLConnection connection = url.openConnection();
|
||||
|
||||
@Override
|
||||
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();
|
||||
String fileName = new File(url.getPath()).getName();
|
||||
File dir = new File(filePath);
|
||||
if (!dir.exists()) dir.mkdirs();
|
||||
|
||||
// 拼接同级目录下的目标文件路径
|
||||
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<WpsPptxJudgementDto> margins = WpsExcelUtils.wpsExcel(path, "0");
|
||||
// 3、获取答案得组成
|
||||
List<ExamQuestionAnswer> answerList = examQuestion.getAnswerList();
|
||||
// 考点 sheetNumber@type@secondType@englishName@value
|
||||
// 中文 sheetName@typeName@secondTypeName@chineseName@value
|
||||
// 4、进行关联判断
|
||||
for (ExamQuestionAnswer examQuestionAnswer : answerList) {
|
||||
boolean flag = false;
|
||||
double one_sorce = 0;
|
||||
for (WpsPptxJudgementDto xlsxInfoVo : margins) {
|
||||
// 原始考点
|
||||
if (xlsxInfoVo.getContent().equals(examQuestionAnswer.getContent())) {
|
||||
flag = true;
|
||||
// 得分 根据权重进行得分 每个选项分值 = 总分 / 总权重
|
||||
if (examQuestionAnswer.getScoreRate().equals("1")) {
|
||||
// 说明权重相等,直接平分分数
|
||||
one_sorce = sorce / answerList.size();
|
||||
} else {
|
||||
one_sorce = sorce * Double.parseDouble(examQuestionAnswer.getScoreRate());
|
||||
File saveFile = new File(dir, fileName);
|
||||
|
||||
try (InputStream in = connection.getInputStream();
|
||||
FileOutputStream out = new FileOutputStream(saveFile)) {
|
||||
|
||||
byte[] buffer = new byte[4096];
|
||||
int bytesRead;
|
||||
while ((bytesRead = in.read(buffer)) != -1) {
|
||||
out.write(buffer, 0, bytesRead);
|
||||
}
|
||||
break;
|
||||
|
||||
System.out.println("✅ 下载成功: " + saveFile.getAbsolutePath());
|
||||
return saveFile.getAbsolutePath();
|
||||
} catch (FileNotFoundException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
System.err.println("❌ 下载失败: " + e.getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
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 sourceAndText;
|
||||
}
|
||||
}
|
||||
|
@@ -1,14 +1,8 @@
|
||||
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;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -17,10 +11,9 @@ 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> judgementWpsPptx(List<JudgementReqVo> judgementReq, String path) throws Exception;
|
||||
|
||||
}
|
||||
|
@@ -8,7 +8,7 @@ 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.service.auto_tools.AutoToolsService;
|
||||
//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.JudgementWpsPPT;
|
||||
@@ -18,7 +18,9 @@ import pc.exam.pp.module.judgement.utils.wps_pptx.vo.PptxInfoReqVo;
|
||||
import pc.exam.pp.module.system.dal.dataobject.user.AdminUserDO;
|
||||
import pc.exam.pp.module.system.service.user.AdminUserService;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.*;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@@ -30,8 +32,8 @@ import static pc.exam.pp.framework.security.core.util.SecurityFrameworkUtils.get
|
||||
@Service
|
||||
public class JudgementWpsPptxServiceImpl implements JudgementWpsPptxService {
|
||||
|
||||
@Resource
|
||||
AutoToolsService autoToolsService;
|
||||
// @Resource
|
||||
// AutoToolsService autoToolsService;
|
||||
|
||||
@Resource
|
||||
ConfigService configService;
|
||||
@@ -63,7 +65,7 @@ public class JudgementWpsPptxServiceImpl implements JudgementWpsPptxService {
|
||||
// pathName = config.getValue() + "\\" + user.getId() + "\\" + strPaht[strPaht.length - 1];
|
||||
// } else {
|
||||
// 2、下载文件并返回文件完整路径
|
||||
pathName = autoToolsService.downloadStudentFile(path, config.getValue() + "\\" + user.getId());
|
||||
pathName = downloadStudentFile(path, config.getValue() + "\\" + user.getId());
|
||||
// }
|
||||
// 4、pptx文件读取并返回考点及说明信息
|
||||
// List<PptxVO> margins = WpsPptxUtils.wpsPptx(pathName, paragraphList);
|
||||
@@ -74,65 +76,37 @@ public class JudgementWpsPptxServiceImpl implements JudgementWpsPptxService {
|
||||
return pptxInfoList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SourceAndText judgementWpsPptx(double sorce, String pathC, String path, ExamQuestion examQuestion, String judgementStr) throws Exception {
|
||||
SourceAndText sourceAndText = new SourceAndText();
|
||||
// 创建log文件txt,用于记录
|
||||
LogFileUtils.createFile(pathC + "/WPS_Word判分过程.txt");
|
||||
LogFileUtils.writeLine("✅ 开始WPS_Pptx判分");
|
||||
judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "✅ 开始WPS_Pptx判分");
|
||||
double wpsPptScore = 0;
|
||||
List<JudgementReqVo> judgementReq = new ArrayList<>();
|
||||
// 3、获取答案得组成
|
||||
List<ExamQuestionAnswer> answerList = examQuestion.getAnswerList();
|
||||
for (ExamQuestionAnswer examQuestionAnswer : answerList) {
|
||||
JudgementReqVo judgementReqVo = new JudgementReqVo();
|
||||
// 拆分数据、
|
||||
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]);
|
||||
judgementReqVo.setPath(path);
|
||||
judgementReq.add(judgementReqVo);
|
||||
public String downloadStudentFile(String fileUrl, String filePath) {
|
||||
try {
|
||||
URL url = new URL(fileUrl);
|
||||
URLConnection connection = url.openConnection();
|
||||
|
||||
String fileName = new File(url.getPath()).getName();
|
||||
File dir = new File(filePath);
|
||||
if (!dir.exists()) dir.mkdirs();
|
||||
|
||||
File saveFile = new File(dir, fileName);
|
||||
|
||||
try (InputStream in = connection.getInputStream();
|
||||
FileOutputStream out = new FileOutputStream(saveFile)) {
|
||||
|
||||
byte[] buffer = new byte[4096];
|
||||
int bytesRead;
|
||||
while ((bytesRead = in.read(buffer)) != -1) {
|
||||
out.write(buffer, 0, bytesRead);
|
||||
}
|
||||
List<WpsPptxJudgementDto> judgementDtos = JudgementWpsPPT.getValues(judgementReq);
|
||||
// 4、进行关联判断
|
||||
for (ExamQuestionAnswer examQuestionAnswer : answerList) {
|
||||
boolean flag = false;
|
||||
double one_sorce = 0;
|
||||
for (WpsPptxJudgementDto pptxJudgementDto : judgementDtos) {
|
||||
if (pptxJudgementDto.getContent().equals(examQuestionAnswer.getContent())) {
|
||||
flag = true;
|
||||
// 得分 根据权重进行得分 每个选项分值 = 总分 / 总权重
|
||||
if (examQuestionAnswer.getScoreRate().equals("1")) {
|
||||
// 说明权重相等,直接平分分数
|
||||
one_sorce = sorce / answerList.size();
|
||||
} else {
|
||||
one_sorce = sorce * Double.parseDouble(examQuestionAnswer.getScoreRate());
|
||||
|
||||
System.out.println("✅ 下载成功: " + saveFile.getAbsolutePath());
|
||||
return saveFile.getAbsolutePath();
|
||||
} catch (FileNotFoundException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
break;
|
||||
} catch (IOException e) {
|
||||
System.err.println("❌ 下载失败: " + e.getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
wpsPptScore += 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_Pptx判分,试题得分:" + wpsPptScore);
|
||||
// 关闭已经打开得文件
|
||||
LogFileUtils.close();
|
||||
sourceAndText.setScore(wpsPptScore);
|
||||
sourceAndText.setText(judgementStr);
|
||||
return sourceAndText;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -2,11 +2,13 @@ package pc.exam.pp.module.judgement.service.wps_word;
|
||||
|
||||
|
||||
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import pc.exam.pp.module.exam.dal.dataobject.ExamQuestion;
|
||||
import pc.exam.pp.module.judgement.controller.admin.AutoWps.vo.WpsDocxInfoVo;
|
||||
import pc.exam.pp.module.judgement.controller.admin.Wps.dto.WpsWordJudgementDto;
|
||||
import pc.exam.pp.module.judgement.controller.admin.Wps.dto.WpsWordReqDto;
|
||||
import pc.exam.pp.module.judgement.service.auto_tools.vo.SourceAndText;
|
||||
import pc.exam.pp.module.judgement.utils.wps_word.docx4j.vo.DocxDataInfoVO;
|
||||
import pc.exam.pp.module.judgement.utils.wps_word.docx4j.vo.JudgementWordsVO;
|
||||
import pc.exam.pp.module.judgement.utils.wps_word.vo.WordInfoReqVo;
|
||||
import pc.exam.pp.module.judgement.utils.wps_word.vo.WordVO;
|
||||
@@ -22,24 +24,19 @@ import java.util.List;
|
||||
public interface JudgementWpsWordService {
|
||||
|
||||
List<JudgementWordsVO> docxMaster(List<WpsDocxInfoVo> wpsDocxInfoVos) throws Exception;
|
||||
/**
|
||||
* 获取word文件内得考点及描述
|
||||
* @param path minio文件路径
|
||||
* @return 文件内得考点及描述
|
||||
* @throws Exception 异常
|
||||
*/
|
||||
List<WordInfoReqVo> programmingWpsWord(String path) throws Exception;
|
||||
|
||||
List<WpsWordJudgementDto> programmingInfo(List<WpsWordReqDto> wpsWordReqDtos) throws Exception;
|
||||
List<DocxDataInfoVO> docxDataInfo(MultipartFile file) throws Exception;
|
||||
|
||||
// /**
|
||||
// * 获取word文件内得考点及描述
|
||||
// * @param path minio文件路径
|
||||
// * @return 文件内得考点及描述
|
||||
// * @throws Exception 异常
|
||||
// */
|
||||
// List<WordInfoReqVo> programmingWpsWord(String path) throws Exception;
|
||||
//
|
||||
// List<WpsWordJudgementDto> programmingInfo(List<WpsWordReqDto> wpsWordReqDtos) throws Exception;
|
||||
//
|
||||
|
||||
|
||||
/**
|
||||
* 读取考生文件,与题型中要求进行判断
|
||||
* @param path 文件路径
|
||||
* @param examQuestion 试题参数
|
||||
* @param sorce 试题分数
|
||||
* @return 得分
|
||||
* @throws Exception 异常
|
||||
*/
|
||||
SourceAndText judgementWpsWord(double sorce, String pathC, String path, ExamQuestion examQuestion, String judgementStr) throws Exception;
|
||||
}
|
||||
|
@@ -1,9 +1,8 @@
|
||||
package pc.exam.pp.module.judgement.service.wps_word;
|
||||
|
||||
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import pc.exam.pp.module.exam.dal.dataobject.ExamQuestion;
|
||||
import pc.exam.pp.module.exam.dal.dataobject.ExamQuestionAnswer;
|
||||
import pc.exam.pp.module.exam.utils.file.LogFileUtils;
|
||||
@@ -14,13 +13,11 @@ import pc.exam.pp.module.judgement.controller.admin.Wps.dto.WpsWordChineseFuncti
|
||||
import pc.exam.pp.module.judgement.controller.admin.Wps.dto.WpsWordJudgementDto;
|
||||
import pc.exam.pp.module.judgement.controller.admin.Wps.dto.WpsWordReqDto;
|
||||
import pc.exam.pp.module.judgement.controller.admin.Wps.vo.WordListReqVO;
|
||||
import pc.exam.pp.module.judgement.dal.dataobject.wpsword.WpsWordLinkDO;
|
||||
import pc.exam.pp.module.judgement.dal.mysql.wpsword.WpsWordLinkMapper;
|
||||
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_word.WpsWordUtils;
|
||||
import pc.exam.pp.module.judgement.utils.wps_word.docx4j.DocxConversion;
|
||||
import pc.exam.pp.module.judgement.utils.wps_word.docx4j.DocxMaster;
|
||||
import pc.exam.pp.module.judgement.utils.wps_word.docx4j.vo.DocxDataInfoVO;
|
||||
import pc.exam.pp.module.judgement.utils.wps_word.docx4j.vo.JudgementWordsVO;
|
||||
import pc.exam.pp.module.judgement.utils.wps_word.vo.WordInfoReqVo;
|
||||
import pc.exam.pp.module.judgement.utils.wps_word.vo.WordVO;
|
||||
@@ -39,137 +36,56 @@ import static pc.exam.pp.framework.security.core.util.SecurityFrameworkUtils.get
|
||||
@Service
|
||||
public class JudgementWpsWordServiceImpl implements JudgementWpsWordService {
|
||||
|
||||
@Resource
|
||||
WpsWordLinkMapper wpsWordLinkMapper;
|
||||
|
||||
@Resource
|
||||
AutoToolsService autoToolsService;
|
||||
|
||||
@Resource
|
||||
ConfigService configService;
|
||||
|
||||
@Resource
|
||||
private AdminUserService userService;
|
||||
|
||||
@Override
|
||||
public List<JudgementWordsVO> docxMaster(List<WpsDocxInfoVo> wpsDocxInfoVos) throws Exception {
|
||||
// String pathName = "";
|
||||
// ConfigDO config = configService.getConfigByKey("file_down_wps_word_path");
|
||||
// AdminUserDO user = userService.getUser(getLoginUserId());
|
||||
// // 2、下载文件并返回文件完整路径
|
||||
// pathName = autoToolsService.downloadStudentFile(path, config.getValue() + "\\" + user.getId());
|
||||
return DocxMaster.docxMaster(wpsDocxInfoVos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<WordInfoReqVo> programmingWpsWord(String path) throws Exception {
|
||||
String pathName = "";
|
||||
String[] strPaht = path.split("/");
|
||||
// 1、获取文件临时下载路径
|
||||
ConfigDO config = configService.getConfigByKey("file_down_wps_word_path");
|
||||
AdminUserDO user = userService.getUser(getLoginUserId());
|
||||
// Path paths = Paths.get(config.getValue() + "\\" + user.getId());
|
||||
// if (Files.exists(paths)) {
|
||||
// pathName = config.getValue() + "\\" + user.getId() + "\\" + strPaht[strPaht.length - 1];
|
||||
// } else {
|
||||
// 2、下载文件并返回文件完整路径
|
||||
pathName = autoToolsService.downloadStudentFile(path, config.getValue() + "\\" + user.getId());
|
||||
public List<DocxDataInfoVO> docxDataInfo(MultipartFile file) throws Exception {
|
||||
return DocxConversion.DocxDataInfos(file);
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public List<WordInfoReqVo> programmingWpsWord(String path) throws Exception {
|
||||
// String pathName = "";
|
||||
// String[] strPaht = path.split("/");
|
||||
// // 1、获取文件临时下载路径
|
||||
// ConfigDO config = configService.getConfigByKey("file_down_wps_word_path");
|
||||
// AdminUserDO user = userService.getUser(getLoginUserId());
|
||||
//// Path paths = Paths.get(config.getValue() + "\\" + user.getId());
|
||||
//// if (Files.exists(paths)) {
|
||||
//// pathName = config.getValue() + "\\" + user.getId() + "\\" + strPaht[strPaht.length - 1];
|
||||
//// } else {
|
||||
// // 2、下载文件并返回文件完整路径
|
||||
// pathName = autoToolsService.downloadStudentFile(path, config.getValue() + "\\" + user.getId());
|
||||
//// }
|
||||
// // 4、docx文件读取并返回考点及说明信息
|
||||
// List<WordInfoReqVo> margins = WpsWordUtils.wpWord(pathName);
|
||||
// // 5、已经读取完得考点删除源文件
|
||||
//// File file = new File(pathName);
|
||||
//// file.delete();
|
||||
// return margins;
|
||||
// }
|
||||
// 4、docx文件读取并返回考点及说明信息
|
||||
List<WordInfoReqVo> margins = WpsWordUtils.wpWord(pathName);
|
||||
// 5、已经读取完得考点删除源文件
|
||||
// File file = new File(pathName);
|
||||
// file.delete();
|
||||
return margins;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<WpsWordJudgementDto> programmingInfo(List<WpsWordReqDto> wordReqDto) throws Exception {
|
||||
// List<WpsWordChineseFunctionDto> functionList = new ArrayList<>();
|
||||
// for (String function : wordReqDto.getFunction()) {
|
||||
// WpsWordChineseFunctionDto functionDto = new WpsWordChineseFunctionDto();
|
||||
// functionDto.setFunction(function);
|
||||
// WpsWordLinkDO wpsWordLinkDO = wpsWordLinkMapper.selectByNodeFunction(function);
|
||||
// functionDto.setChineseName(wpsWordLinkDO.getToChinese());
|
||||
// functionList.add(functionDto);
|
||||
//
|
||||
// @Override
|
||||
// public List<WpsWordJudgementDto> programmingInfo(List<WpsWordReqDto> wordReqDto) throws Exception {
|
||||
//// List<WpsWordChineseFunctionDto> functionList = new ArrayList<>();
|
||||
//// for (String function : wordReqDto.getFunction()) {
|
||||
//// WpsWordChineseFunctionDto functionDto = new WpsWordChineseFunctionDto();
|
||||
//// functionDto.setFunction(function);
|
||||
//// WpsWordLinkDO wpsWordLinkDO = wpsWordLinkMapper.selectByNodeFunction(function);
|
||||
//// functionDto.setChineseName(wpsWordLinkDO.getToChinese());
|
||||
//// functionList.add(functionDto);
|
||||
//// }
|
||||
// List<WpsWordJudgementDto> judgementDtos = WpsWordUtils.getWordInfo(wordReqDto);
|
||||
// return judgementDtos;
|
||||
// }
|
||||
List<WpsWordJudgementDto> judgementDtos = WpsWordUtils.getWordInfo(wordReqDto);
|
||||
return judgementDtos;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SourceAndText judgementWpsWord(double sorce, String pathC, String path, ExamQuestion examQuestion, String judgementStr) throws Exception {
|
||||
SourceAndText sourceAndText = new SourceAndText();
|
||||
// 创建log文件txt,用于记录
|
||||
LogFileUtils.createFile(pathC + "/WPS_Word判分过程.txt");
|
||||
LogFileUtils.writeLine("✅ 开始WPS_Word判分");
|
||||
judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "✅ 开始WPS_Word判分");
|
||||
double wps_word_sorce = 0;
|
||||
// 2、docx文件读取并返回考点及说明信息
|
||||
// List<WordVO> margins = WpsWordUtils.wps_word(path);
|
||||
// 3、获取答案得组成
|
||||
List<ExamQuestionAnswer> answerList = examQuestion.getAnswerList();
|
||||
// 4、进行关联判断
|
||||
for (ExamQuestionAnswer examQuestionAnswer : answerList) {
|
||||
// 拆分数据、
|
||||
String[] wordInfos = examQuestionAnswer.getContent().split("-/");
|
||||
String[] chineseName = examQuestionAnswer.getContentIn().split("-");
|
||||
String[] typeList = examQuestionAnswer.getImage().split("-");
|
||||
// 创建拼接数据
|
||||
// 只取三层结构
|
||||
List<WpsWordReqDto> wordReqDto = new ArrayList<>();
|
||||
WpsWordReqDto wpsWordReqDto = new WpsWordReqDto();
|
||||
wpsWordReqDto.setName(examQuestionAnswer.getContentIn());
|
||||
wpsWordReqDto.setEnglishName(wordInfos[0].split("]")[0] + "]");
|
||||
wpsWordReqDto.setFilePath(path);
|
||||
// 存放类型
|
||||
wpsWordReqDto.setType(typeList[0]);
|
||||
wpsWordReqDto.setBelongTo(typeList[1]);
|
||||
wpsWordReqDto.setIsboo(typeList[2]);
|
||||
wpsWordReqDto.setUnit(typeList[3]);
|
||||
wpsWordReqDto.setFunction(wordInfos[0]);
|
||||
wpsWordReqDto.setIsExam("1");
|
||||
wordReqDto.add(wpsWordReqDto);
|
||||
System.out.println(examQuestionAnswer.getContentIn());
|
||||
System.out.println(examQuestionAnswer.getContent());
|
||||
List<WpsWordJudgementDto> judgementDtos = WpsWordUtils.getWordInfo(wordReqDto);
|
||||
boolean flag = false;
|
||||
double one_sorce = 0;
|
||||
for (WpsWordJudgementDto wordJudgementDto : judgementDtos) {
|
||||
if (wordJudgementDto.getContent() != null) {
|
||||
// for (String str : wordJudgementDto.getFunction()) {
|
||||
int index = 0;
|
||||
if (wordJudgementDto.getContent().equals(examQuestionAnswer.getContent())) {
|
||||
flag = true;
|
||||
// 得分 根据权重进行得分 每个选项分值 = 总分 / 总权重
|
||||
if (examQuestionAnswer.getScoreRate().equals("1")) {
|
||||
// 说明权重相等,直接平分分数
|
||||
one_sorce = sorce / answerList.size();
|
||||
} else {
|
||||
one_sorce = sorce * Double.parseDouble(examQuestionAnswer.getScoreRate());
|
||||
}
|
||||
break;
|
||||
}
|
||||
// }
|
||||
}
|
||||
}
|
||||
wps_word_sorce += 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_Word判分,试题得分:" + wps_word_sorce);
|
||||
// 关闭已经打开得文件
|
||||
LogFileUtils.close();
|
||||
sourceAndText.setScore(wps_word_sorce);
|
||||
sourceAndText.setText(judgementStr);
|
||||
|
||||
return sourceAndText;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -1,120 +0,0 @@
|
||||
package pc.exam.pp.module.judgement.service.wps_word;
|
||||
|
||||
import pc.exam.pp.framework.common.util.collection.CollectionUtils;
|
||||
import pc.exam.pp.module.judgement.controller.admin.Wps.vo.WordListReqVO;
|
||||
import pc.exam.pp.module.judgement.controller.admin.Wps.vo.WordSaveReqVO;
|
||||
import pc.exam.pp.module.judgement.dal.dataobject.wpsword.WpsWordLinkDO;
|
||||
import pc.exam.pp.module.judgement.utils.tree.vo.TreeVO;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* 节点 Service 接口
|
||||
*
|
||||
* @author 朋辰
|
||||
*/
|
||||
public interface WpsWordLinkService {
|
||||
|
||||
/**
|
||||
* 创建节点
|
||||
*
|
||||
* @param createReqVO 节点信息
|
||||
* @return 节点编号
|
||||
*/
|
||||
Long createWord(WordSaveReqVO createReqVO);
|
||||
|
||||
/**
|
||||
* 更新节点
|
||||
*
|
||||
* @param updateReqVO 节点信息
|
||||
*/
|
||||
void updateWord(WordSaveReqVO updateReqVO);
|
||||
|
||||
/**
|
||||
* 删除节点
|
||||
*
|
||||
* @param id 节点编号
|
||||
*/
|
||||
void deleteWord(Long id);
|
||||
|
||||
/**
|
||||
* 获得节点信息
|
||||
*
|
||||
* @param id 节点编号
|
||||
* @return 节点信息
|
||||
*/
|
||||
WpsWordLinkDO getWord(Long id);
|
||||
|
||||
/**
|
||||
* 获得节点信息数组
|
||||
*
|
||||
* @param ids 节点编号数组
|
||||
* @return 节点信息数组
|
||||
*/
|
||||
List<WpsWordLinkDO> getWordList(Collection<Long> ids);
|
||||
|
||||
/**
|
||||
* 筛选节点列表
|
||||
*
|
||||
* @param reqVO 筛选条件请求 VO
|
||||
* @return 节点列表
|
||||
*/
|
||||
List<WpsWordLinkDO> getWordList(WordListReqVO reqVO);
|
||||
|
||||
/**
|
||||
* 筛选节点列表
|
||||
*
|
||||
* @param reqVO 筛选条件请求 VO
|
||||
* @return 节点列表
|
||||
*/
|
||||
List<WpsWordLinkDO> getWordInfoList(WordListReqVO reqVO);
|
||||
|
||||
/**
|
||||
* 获得指定编号的节点 Map
|
||||
*
|
||||
* @param ids 节点编号数组
|
||||
* @return 节点 Map
|
||||
*/
|
||||
default Map<Long, WpsWordLinkDO> getWordMap(Collection<Long> ids) {
|
||||
List<WpsWordLinkDO> list = getWordList(ids);
|
||||
return CollectionUtils.convertMap(list, WpsWordLinkDO::getId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得指定节点的所有子节点
|
||||
*
|
||||
* @param id 节点编号
|
||||
* @return 子节点列表
|
||||
*/
|
||||
default List<WpsWordLinkDO> getChildWordList(Long id) {
|
||||
return getChildWordList(Collections.singleton(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得指定节点的所有子节点
|
||||
*
|
||||
* @param ids 节点编号数组
|
||||
* @return 子节点列表
|
||||
*/
|
||||
List<WpsWordLinkDO> getChildWordList(Collection<Long> ids);
|
||||
|
||||
/**
|
||||
* 获得所有子节点,从缓存中
|
||||
*
|
||||
* @param id 父节点编号
|
||||
* @return 子节点列表
|
||||
*/
|
||||
Set<Long> getChildWordIdListFromCache(Long id);
|
||||
|
||||
/**
|
||||
* 校验节点们是否有效。如下情况,视为无效:
|
||||
* 1. 节点编号不存在
|
||||
* 2. 节点被禁用
|
||||
*
|
||||
* @param ids 角色编号数组
|
||||
*/
|
||||
void validateWordList(Collection<Long> ids);
|
||||
|
||||
List<TreeVO> getWordTreeList();
|
||||
|
||||
}
|
@@ -1,246 +0,0 @@
|
||||
package pc.exam.pp.module.judgement.service.wps_word;
|
||||
|
||||
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.WordListReqVO;
|
||||
import pc.exam.pp.module.judgement.controller.admin.Wps.vo.WordSaveReqVO;
|
||||
import pc.exam.pp.module.judgement.dal.dataobject.wpsword.WpsWordLinkDO;
|
||||
import pc.exam.pp.module.judgement.dal.mysql.wpsword.WpsWordLinkMapper;
|
||||
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 WpsWordLinkServiceImpl implements WpsWordLinkService {
|
||||
|
||||
@Resource
|
||||
private WpsWordLinkMapper wpsWordLinkMapper;
|
||||
|
||||
@Override
|
||||
@CacheEvict(cacheNames = RedisKeyConstants.WPS_WORD_CHILDREN_ID_LIST,
|
||||
allEntries = true) // allEntries 清空所有缓存,因为操作一个节点,涉及到多个缓存
|
||||
public Long createWord(WordSaveReqVO createReqVO) {
|
||||
if (createReqVO.getParentId() == null) {
|
||||
createReqVO.setParentId(WpsWordLinkDO.PARENT_ID_ROOT);
|
||||
}
|
||||
// 校验父节点的有效性
|
||||
validateParentWord(null, createReqVO.getParentId());
|
||||
// 校验节点名的唯一性
|
||||
validateWordNameUnique(null, createReqVO.getParentId(), createReqVO.getName());
|
||||
|
||||
// 插入节点
|
||||
WpsWordLinkDO wpsWordLinkDO = BeanUtils.toBean(createReqVO, WpsWordLinkDO.class);
|
||||
wpsWordLinkMapper.insert(wpsWordLinkDO);
|
||||
return wpsWordLinkDO.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
@CacheEvict(cacheNames = RedisKeyConstants.WPS_WORD_CHILDREN_ID_LIST,
|
||||
allEntries = true) // allEntries 清空所有缓存,因为操作一个节点,涉及到多个缓存
|
||||
public void updateWord(WordSaveReqVO updateReqVO) {
|
||||
if (updateReqVO.getParentId() == null) {
|
||||
updateReqVO.setParentId(WpsWordLinkDO.PARENT_ID_ROOT);
|
||||
}
|
||||
// 校验自己存在
|
||||
validateWordExists(updateReqVO.getId());
|
||||
// 校验父节点的有效性
|
||||
validateParentWord(updateReqVO.getId(), updateReqVO.getParentId());
|
||||
// 校验节点名的唯一性
|
||||
validateWordNameUnique(updateReqVO.getId(), updateReqVO.getParentId(), updateReqVO.getName());
|
||||
|
||||
// 更新节点
|
||||
WpsWordLinkDO updateObj = BeanUtils.toBean(updateReqVO, WpsWordLinkDO.class);
|
||||
wpsWordLinkMapper.updateById(updateObj);
|
||||
}
|
||||
|
||||
@Override
|
||||
@CacheEvict(cacheNames = RedisKeyConstants.WPS_WORD_CHILDREN_ID_LIST,
|
||||
allEntries = true) // allEntries 清空所有缓存,因为操作一个节点,涉及到多个缓存
|
||||
public void deleteWord(Long id) {
|
||||
// 校验是否存在
|
||||
validateWordExists(id);
|
||||
// 校验是否有子节点
|
||||
if (wpsWordLinkMapper.selectCountByParentId(id) > 0) {
|
||||
throw exception(WORD_NOT_FOUND);
|
||||
}
|
||||
// 删除节点
|
||||
wpsWordLinkMapper.deleteById(id);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void validateWordExists(Long id) {
|
||||
if (id == null) {
|
||||
return;
|
||||
}
|
||||
WpsWordLinkDO wpsWordLinkDO = wpsWordLinkMapper.selectById(id);
|
||||
if (wpsWordLinkDO == null) {
|
||||
throw exception(WORD_NOT_FOUND);
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void validateParentWord(Long id, Long parentId) {
|
||||
if (parentId == null || WpsWordLinkDO.PARENT_ID_ROOT.equals(parentId)) {
|
||||
return;
|
||||
}
|
||||
// 1. 不能设置自己为父节点
|
||||
if (Objects.equals(id, parentId)) {
|
||||
throw exception(WORD_PARENT_ERROR);
|
||||
}
|
||||
// 2. 父节点不存在
|
||||
WpsWordLinkDO parentWord = wpsWordLinkMapper.selectById(parentId);
|
||||
if (parentWord == null) {
|
||||
throw exception(WORD_PARENT_NOT_EXITS);
|
||||
}
|
||||
// 3. 递归校验父节点,如果父节点是自己的子节点,则报错,避免形成环路
|
||||
if (id == null) { // id 为空,说明新增,不需要考虑环路
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < Short.MAX_VALUE; i++) {
|
||||
// 3.1 校验环路
|
||||
parentId = parentWord.getParentId();
|
||||
if (Objects.equals(id, parentId)) {
|
||||
throw exception(WORD_PARENT_IS_CHILD);
|
||||
}
|
||||
// 3.2 继续递归下一级父节点
|
||||
if (parentId == null || WpsWordLinkDO.PARENT_ID_ROOT.equals(parentId)) {
|
||||
break;
|
||||
}
|
||||
parentWord = wpsWordLinkMapper.selectById(parentId);
|
||||
if (parentWord == null) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void validateWordNameUnique(Long id, Long parentId, String name) {
|
||||
WpsWordLinkDO wpsWordLinkDO = wpsWordLinkMapper.selectByParentIdAndName(parentId, name);
|
||||
if (wpsWordLinkDO == null) {
|
||||
return;
|
||||
}
|
||||
// 如果 id 为空,说明不用比较是否为相同 id 的节点
|
||||
if (id == null) {
|
||||
throw exception(WORD_NAME_DUPLICATE);
|
||||
}
|
||||
if (ObjectUtil.notEqual(wpsWordLinkDO.getId(), id)) {
|
||||
throw exception(WORD_NAME_DUPLICATE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public WpsWordLinkDO getWord(Long id) {
|
||||
return wpsWordLinkMapper.selectById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<WpsWordLinkDO> getWordList(Collection<Long> ids) {
|
||||
if (CollUtil.isEmpty(ids)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return wpsWordLinkMapper.selectBatchIds(ids);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<WpsWordLinkDO> getWordList(WordListReqVO reqVO) {
|
||||
List<WpsWordLinkDO> list = wpsWordLinkMapper.selectList(reqVO);
|
||||
list.sort(Comparator.comparing(WpsWordLinkDO::getSort));
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<WpsWordLinkDO> getWordInfoList(WordListReqVO reqVO) {
|
||||
List<WpsWordLinkDO> wordList = new ArrayList<>();
|
||||
WpsWordLinkDO data = wpsWordLinkMapper.selectByNodeFunction(reqVO.getNodeFunction());
|
||||
if (data == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<WpsWordLinkDO> wpsWordLinkDOS = wpsWordLinkMapper.selectInfoList(data.getId());
|
||||
// 在依次判断是否还有子数据
|
||||
for (WpsWordLinkDO wpsWordLinkDO : wpsWordLinkDOS) {
|
||||
wordList.add(wpsWordLinkDO);
|
||||
List<WpsWordLinkDO> datas = wpsWordLinkMapper.selectInfoList(wpsWordLinkDO.getId());
|
||||
if (datas != null) {
|
||||
for (WpsWordLinkDO wpsWordLinkDO1 : datas) {
|
||||
wordList.add(wpsWordLinkDO1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return wordList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<WpsWordLinkDO> getChildWordList(Collection<Long> ids) {
|
||||
List<WpsWordLinkDO> children = new LinkedList<>();
|
||||
// 遍历每一层
|
||||
Collection<Long> parentIds = ids;
|
||||
for (int i = 0; i < Short.MAX_VALUE; i++) { // 使用 Short.MAX_VALUE 避免 bug 场景下,存在死循环
|
||||
// 查询当前层,所有的子节点
|
||||
List<WpsWordLinkDO> words = wpsWordLinkMapper.selectListByParentId(parentIds);
|
||||
// 1. 如果没有子节点,则结束遍历
|
||||
if (CollUtil.isEmpty(words)) {
|
||||
break;
|
||||
}
|
||||
// 2. 如果有子节点,继续遍历
|
||||
children.addAll(words);
|
||||
parentIds = convertSet(words, WpsWordLinkDO::getId);
|
||||
}
|
||||
return children;
|
||||
}
|
||||
|
||||
@Override
|
||||
@DataPermission(enable = false) // 禁用数据权限,避免建立不正确的缓存
|
||||
@Cacheable(cacheNames = RedisKeyConstants.WPS_WORD_CHILDREN_ID_LIST, key = "#id")
|
||||
public Set<Long> getChildWordIdListFromCache(Long id) {
|
||||
List<WpsWordLinkDO> children = getChildWordList(id);
|
||||
return convertSet(children, WpsWordLinkDO::getId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validateWordList(Collection<Long> ids) {
|
||||
if (CollUtil.isEmpty(ids)) {
|
||||
return;
|
||||
}
|
||||
// 获得科室信息
|
||||
Map<Long, WpsWordLinkDO> wordMap = getWordMap(ids);
|
||||
// 校验
|
||||
ids.forEach(id -> {
|
||||
WpsWordLinkDO word = wordMap.get(id);
|
||||
if (word == null) {
|
||||
throw exception(WORD_NOT_FOUND);
|
||||
}
|
||||
if (!CommonStatusEnum.ENABLE.getStatus().equals(word.getStatus())) {
|
||||
throw exception(WORD_NOT_ENABLE, word.getName());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@TenantIgnore
|
||||
public List<TreeVO> getWordTreeList() {
|
||||
return wpsWordLinkMapper.selectTreeListByNodeFunction();
|
||||
}
|
||||
|
||||
}
|
@@ -1,6 +1,5 @@
|
||||
package pc.exam.pp.module.judgement.utils.tree;
|
||||
|
||||
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;
|
||||
|
||||
@@ -32,29 +31,7 @@ public class TreeUtils {
|
||||
// }
|
||||
// return roots;
|
||||
// }
|
||||
|
||||
public static List<WpsWordLinkDO> buildTree(List<WpsWordLinkDO> flatList) {
|
||||
Map<Integer, WpsWordLinkDO> nodeMap = new HashMap<>();
|
||||
List<WpsWordLinkDO> roots = new ArrayList<>();
|
||||
|
||||
// 先放入 map
|
||||
for (WpsWordLinkDO node : flatList) {
|
||||
nodeMap.put(Math.toIntExact(node.getId()), node);
|
||||
}
|
||||
|
||||
// 构建树关系
|
||||
for (WpsWordLinkDO node : flatList) {
|
||||
if (node.getParentId() == 0) {
|
||||
roots.add(node);
|
||||
} else {
|
||||
WpsWordLinkDO 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<>();
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,183 @@
|
||||
package pc.exam.pp.module.judgement.utils.wps_word.docx4j;
|
||||
|
||||
import org.apache.poi.xwpf.usermodel.XWPFDocument;
|
||||
import org.apache.xmlbeans.XmlCursor;
|
||||
import org.apache.xmlbeans.XmlObject;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import pc.exam.pp.module.judgement.utils.wps_word.WpsWordNameSpaces;
|
||||
import pc.exam.pp.module.judgement.utils.wps_word.XmlUtil;
|
||||
import pc.exam.pp.module.judgement.utils.wps_word.docx4j.vo.DocxDataInfoVO;
|
||||
import pc.exam.pp.module.judgement.utils.wps_word.vo.WordInfoReqVo;
|
||||
import pc.exam.pp.module.judgement.utils.wps_word.vo.WordSecondInfoVo;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
public class DocxConversion {
|
||||
public static List<DocxDataInfoVO> DocxDataInfos(MultipartFile file) throws Exception {
|
||||
List<DocxDataInfoVO> dataInfoVOS = new ArrayList<>();
|
||||
try (InputStream inputStream = file.getInputStream()) {
|
||||
// 1. 直接使用 InputStream 构造 XWPFDocument(无需本地文件)
|
||||
XWPFDocument document = new XWPFDocument(inputStream);
|
||||
|
||||
// 2. 读取文档内容(示例:提取所有段落文本)
|
||||
StringBuilder content = new StringBuilder();
|
||||
document.getParagraphs().forEach(paragraph -> {
|
||||
content.append(paragraph.getText()).append("\n");
|
||||
});
|
||||
|
||||
|
||||
String xmlString = XmlUtil.getDocumentXml(document);
|
||||
String namespace = WpsWordNameSpaces.getNameSpace(xmlString);
|
||||
XmlObject docXml = document.getDocument();
|
||||
// 1、获取文档段落W:P标签得数量,判断出一个有多少段
|
||||
XmlCursor wpCursor = docXml.newCursor();
|
||||
String wpPath = namespace + "/w:document/w:body/w:p";
|
||||
wpCursor.selectPath(wpPath);
|
||||
int wpIndex = 0;
|
||||
// 段落
|
||||
String firstIdWp = getStringRandom();
|
||||
setWordDataInfo(firstIdWp, "", "段落", "w:p", "", false, dataInfoVOS);
|
||||
List<WordSecondInfoVo> wordSecondWp = new ArrayList<>();
|
||||
while (wpCursor.toNextSelection()) {
|
||||
wpIndex ++;
|
||||
// 段落属性
|
||||
if (!wpCursor.xmlText().contains("w:sectPr")) {
|
||||
// 获取文本
|
||||
XmlCursor wpTextXml = wpCursor.newCursor();
|
||||
wpTextXml.selectPath(namespace + ".//w:r/w:t");
|
||||
if (wpTextXml.toNextSelection()) {
|
||||
String secondIdWp = getStringRandom();
|
||||
String text = wpTextXml.getTextValue();
|
||||
text = shorten(text);
|
||||
setWordDataInfo(secondIdWp, firstIdWp, "段落" + wpIndex + ":" + text, "w:p", String.valueOf(wpIndex), true, dataInfoVOS);
|
||||
// 使用 。 判断句子
|
||||
String[] texts = text.split("。");
|
||||
int textsIndex = 0;
|
||||
for (String s : texts) {
|
||||
String thirdIdWp = getStringRandom();
|
||||
textsIndex ++;
|
||||
s = shorten(s);
|
||||
setWordDataInfo(thirdIdWp, secondIdWp, "句子" + textsIndex + ":" + s, "w:t", String.valueOf(wpIndex), true, dataInfoVOS);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 2、页面
|
||||
XmlCursor wSectPrCursor = docXml.newCursor();
|
||||
String wSectPrPath = namespace + "//w:sectPr";
|
||||
wSectPrCursor.selectPath(wSectPrPath);
|
||||
int wSectPrIndex = 0;
|
||||
String firstIdSectPr = getStringRandom();
|
||||
setWordDataInfo(firstIdSectPr, "", "页面", "w:sectPr", "", false, dataInfoVOS);
|
||||
List<WordSecondInfoVo> wordSecondWSectPr = new ArrayList<>();
|
||||
while (wSectPrCursor.toNextSelection()) {
|
||||
wSectPrIndex ++;
|
||||
String secondIdSectPr = getStringRandom();
|
||||
setWordDataInfo(secondIdSectPr, firstIdSectPr, "节" + wSectPrIndex, "w:sectPr", String.valueOf(wSectPrIndex), true, dataInfoVOS);
|
||||
}
|
||||
// // 3、图形
|
||||
// XmlCursor wDrawingCursor = docXml.newCursor();
|
||||
// String wDrawingPath = namespace + "//w:drawing";
|
||||
// wDrawingCursor.selectPath(wDrawingPath);
|
||||
// int wDrawingIndex = 0;
|
||||
// String firstIdDrawing = getStringRandom();
|
||||
// setWordDataInfo(firstIdDrawing, "", "图形", "w:drawing", "", false, dataInfoVOS);
|
||||
// while (wDrawingCursor.toNextSelection()) {
|
||||
// wDrawingIndex ++;
|
||||
// String secondIdDrawing = getStringRandom();
|
||||
// XmlCursor wDrawingXml = wDrawingCursor.newCursor();
|
||||
// wDrawingXml.selectPath(namespace + ".//wp:anchor/wp:docPr/@name");
|
||||
// if (wDrawingXml.toNextSelection()) {
|
||||
// setWordDataInfo(firstIdSectPr, firstIdDrawing, "图形" + wDrawingIndex + ":" + wDrawingXml.getTextValue(), "w:drawing", String.valueOf(wDrawingIndex), true, dataInfoVOS);
|
||||
// setWordInfo("图形" + wDrawingIndex + ":" + wDrawingXml.getTextValue(), "(//w:drawing)[" + wDrawingIndex + "]", "w:drawing", filePath, secondIdDrawing, firstIdDrawing, wordInfoReqVos);
|
||||
// }
|
||||
// }
|
||||
// // 4、尾注
|
||||
// XmlCursor endnoteReferenceCursor = docXml.newCursor();
|
||||
// String endnoteReferencePath = namespace + "//w:endnoteReference";
|
||||
// endnoteReferenceCursor.selectPath(endnoteReferencePath);
|
||||
// int endnoteReferenceIndex = 0;
|
||||
// String firstIdEndnoteReference = getStringRandom();
|
||||
// while (endnoteReferenceCursor.toNextSelection()) {
|
||||
// if (endnoteReferenceIndex == 0) {
|
||||
// setWordInfo("引用", "w:endnoteReference", "w:endnoteReference", filePath, firstIdEndnoteReference, "", wordInfoReqVos);
|
||||
// }
|
||||
// endnoteReferenceIndex ++;
|
||||
// String secondIdEndnoteReference = getStringRandom();
|
||||
// setWordInfo("尾注", "(//w:endnoteReference)[" + endnoteReferenceIndex + "]", "w:endnoteReference", filePath, secondIdEndnoteReference, firstIdEndnoteReference, wordInfoReqVos);
|
||||
// }
|
||||
// // 5、表格
|
||||
// XmlCursor tblCursor = docXml.newCursor();
|
||||
// String tblCursorPath = namespace + "//w:tbl";
|
||||
// endnoteReferenceCursor.selectPath(tblCursorPath);
|
||||
// int tblIndex = 0;
|
||||
// String firstIdTbl = getStringRandom();
|
||||
// while (endnoteReferenceCursor.toNextSelection()) {
|
||||
// if (tblIndex == 0) {
|
||||
// setWordInfo("表格", "w:endnoteReference", "w:endnoteReference", filePath, firstIdTbl, "", wordInfoReqVos);
|
||||
// }
|
||||
// tblIndex ++;
|
||||
// String secondIdTbl = getStringRandom();
|
||||
// setWordInfo("表格:"+tblIndex, "(//w:tbl)[" + tblIndex + "]", "w:tbl", filePath, secondIdTbl, firstIdTbl, wordInfoReqVos);
|
||||
// }
|
||||
// // 5、域
|
||||
// XmlCursor yuCursor = docXml.newCursor();
|
||||
// String yuCursorPath = namespace + "//w:instrText";
|
||||
// endnoteReferenceCursor.selectPath(yuCursorPath);
|
||||
// int yuIndex = 0;
|
||||
// String firstIdyu = getStringRandom();
|
||||
// while (endnoteReferenceCursor.toNextSelection()) {
|
||||
// if (yuIndex == 0) {
|
||||
// setWordInfo("域", "w:instrText", "w:instrText", filePath, firstIdyu, "", wordInfoReqVos);
|
||||
// }
|
||||
// yuIndex ++;
|
||||
// String secondIdyu = getStringRandom();
|
||||
// setWordInfo("域:"+yuIndex, "(//w:instrText)[" + yuIndex + "]", "w:instrText", filePath, secondIdyu, firstIdyu, wordInfoReqVos);
|
||||
// }
|
||||
|
||||
// 3. 关闭资源(try-with-resources 自动关闭 InputStream)
|
||||
document.close();
|
||||
|
||||
return dataInfoVOS;
|
||||
}
|
||||
}
|
||||
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 void setWordDataInfo(String id, String parentId, String text,
|
||||
String type, String index, boolean isTrue, List<DocxDataInfoVO> dataInfoVOS) throws Exception {
|
||||
DocxDataInfoVO dataInfo = new DocxDataInfoVO();
|
||||
dataInfo.setId(id);
|
||||
dataInfo.setParentId(parentId);
|
||||
dataInfo.setName(text);
|
||||
dataInfo.setType(type);
|
||||
dataInfo.setIndex(index);
|
||||
dataInfo.setClick(isTrue);
|
||||
dataInfoVOS.add(dataInfo);
|
||||
}
|
||||
public static String shorten(String input) {
|
||||
if (input == null) return null;
|
||||
if (input.length() <= 14) {
|
||||
return input;
|
||||
}
|
||||
String prefix = input.substring(0, 6);
|
||||
String suffix = input.substring(input.length() - 2);
|
||||
return prefix + "..." + suffix;
|
||||
}
|
||||
}
|
@@ -0,0 +1,19 @@
|
||||
package pc.exam.pp.module.judgement.utils.wps_word.docx4j.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class DocxDataInfoVO {
|
||||
|
||||
private String name;
|
||||
|
||||
private String type;
|
||||
|
||||
private String id;
|
||||
|
||||
private String parentId;
|
||||
|
||||
private String index;
|
||||
|
||||
private boolean isClick;
|
||||
}
|
@@ -2,7 +2,6 @@ package pc.exam.pp.module.judgement.utils.wps_word.vo;
|
||||
|
||||
import lombok.Data;
|
||||
import org.apache.xmlbeans.XmlCursor;
|
||||
import pc.exam.pp.module.judgement.dal.dataobject.wpsword.WpsWordLinkDO;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
@@ -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.wpsword.WpsWordLinkMapper">
|
||||
|
||||
<!--
|
||||
一般情况下,尽可能使用 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_word_link
|
||||
</select>
|
||||
|
||||
</mapper>
|
@@ -176,13 +176,13 @@ public interface ErrorCodeConstants {
|
||||
|
||||
|
||||
// ========== WpsWOrd 1-002-030-000 ==========
|
||||
ErrorCode WORD_NAME_DUPLICATE = new ErrorCode(1_002_030_000, "已经存在该名字的WORD节点");
|
||||
ErrorCode WORD_PARENT_NOT_EXITS = new ErrorCode(1_002_030_001,"父级WORD节点不存在");
|
||||
ErrorCode WORD_NOT_FOUND = new ErrorCode(1_002_030_002, "当前WORD节点不存在");
|
||||
ErrorCode WORD_EXITS_CHILDREN = new ErrorCode(1_002_030_003, "存在子WORD节点,无法删除");
|
||||
ErrorCode WORD_PARENT_ERROR = new ErrorCode(1_002_030_004, "不能设置自己为父WORD节点");
|
||||
ErrorCode WORD_NOT_ENABLE = new ErrorCode(1_002_030_006, "WORD节点({})不处于开启状态,不允许选择");
|
||||
ErrorCode WORD_PARENT_IS_CHILD = new ErrorCode(1_002_030_007, "不能设置自己的子WORD节点为父WORD节点");
|
||||
ErrorCode DOCX_NAME_DUPLICATE = new ErrorCode(1_002_030_000, "已经存在该名字的WORD节点");
|
||||
ErrorCode DOCX_PARENT_NOT_EXITS = new ErrorCode(1_002_030_001,"父级WORD节点不存在");
|
||||
ErrorCode DOCX_NOT_FOUND = new ErrorCode(1_002_030_002, "当前WORD节点不存在");
|
||||
ErrorCode DOCX_EXITS_CHILDREN = new ErrorCode(1_002_030_003, "存在子WORD节点,无法删除");
|
||||
ErrorCode DOCX_PARENT_ERROR = new ErrorCode(1_002_030_004, "不能设置自己为父WORD节点");
|
||||
ErrorCode DOCX_NOT_ENABLE = new ErrorCode(1_002_030_006, "WORD节点({})不处于开启状态,不允许选择");
|
||||
ErrorCode DOCX_PARENT_IS_CHILD = new ErrorCode(1_002_030_007, "不能设置自己的子WORD节点为父WORD节点");
|
||||
|
||||
// ========== WpsPptx 1-002-031-000 ==========
|
||||
ErrorCode PPTX_NAME_DUPLICATE = new ErrorCode(1_002_031_000, "已经存在该名字的PPTX节点");
|
||||
|
Reference in New Issue
Block a user