bug修复
This commit is contained in:
parent
4a48b4ee1c
commit
b1e6eabc26
|
|
@ -149,7 +149,7 @@ public class ArchiveController extends BaseController {
|
|||
// 如果子集有数据 无法修改
|
||||
Integer child = archiveMapper.getchild(dto);
|
||||
if (child > 0){
|
||||
return R.fail("该节点下有子集,无法修改");
|
||||
return R.fail("该节点下存在子节点或该节点下存在档案文件,无法修改");
|
||||
}
|
||||
Integer num = service.geMaxSort(vo.getParentId().toString());
|
||||
if (num == null) {
|
||||
|
|
@ -176,7 +176,7 @@ public class ArchiveController extends BaseController {
|
|||
if (i > 0) {
|
||||
return R.ok();
|
||||
} else {
|
||||
return R.fail("该节点下有子集,无法删除");
|
||||
return R.fail("该节点下存在子节点或该节点下存在档案文件,无法删除");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error(e.toString(), e);
|
||||
|
|
|
|||
|
|
@ -289,7 +289,7 @@ public class FileManagementController extends BaseController {
|
|||
try {
|
||||
Integer child = fileManageMapper.getchild(dto);
|
||||
if (child > 0){
|
||||
return R.fail("该节点下有子集,无法修改");
|
||||
return R.fail("该节点下存在子节点或该节点下存在档案文件,无法修改");
|
||||
}
|
||||
Integer num = fileManageService.getMaxSort(dto);
|
||||
if (num == null) {
|
||||
|
|
@ -314,7 +314,7 @@ public class FileManagementController extends BaseController {
|
|||
try {
|
||||
Integer child = fileManageMapper.getchild(dto);
|
||||
if (child > 0){
|
||||
return R.fail("该节点下有子集,无法删除");
|
||||
return R.fail("该节点下存在子节点或该节点下存在档案文件,无法删除");
|
||||
}
|
||||
Integer i = fileManageService.delFileManage(dto);
|
||||
if (i > 0) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,68 @@
|
|||
package com.bonus.web.controller.tool;
|
||||
|
||||
import com.bonus.common.annotation.RequiresPermissions;
|
||||
import com.bonus.common.annotation.SysLog;
|
||||
import com.bonus.common.core.controller.BaseController;
|
||||
import com.bonus.common.core.domain.AjaxResult;
|
||||
import com.bonus.common.core.domain.R;
|
||||
import com.bonus.common.core.page.TableDataInfo;
|
||||
import com.bonus.common.enums.OperaType;
|
||||
import com.bonus.system.domain.KyDataClassify;
|
||||
import com.bonus.system.domain.KyDataCollectData;
|
||||
import com.bonus.system.domain.vo.KyDataClassifyVo;
|
||||
import com.bonus.web.service.FileShareService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @Author:liang.chao
|
||||
* @Date:2025/10/23 - 14:07
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/file/share")
|
||||
@Slf4j
|
||||
public class FileShareController extends BaseController {
|
||||
|
||||
@Resource
|
||||
private FileShareService fileShareService;
|
||||
|
||||
/**
|
||||
* 获取数据分类管理下拉框
|
||||
* @param kyDataClassify
|
||||
* @return
|
||||
*/
|
||||
@RequiresPermissions("file:share:listAll")
|
||||
@GetMapping("/listAll")
|
||||
public TableDataInfo listAll(KyDataClassify kyDataClassify)
|
||||
{
|
||||
List<KyDataClassifyVo> list = fileShareService.listAll(kyDataClassify);
|
||||
return getDataTable(list);
|
||||
}
|
||||
/**
|
||||
* 根据数据类型数据汇集管理列表
|
||||
*
|
||||
* @param kyDataCollectData
|
||||
* @return
|
||||
*/
|
||||
@SysLog(title = "档案分享管理", businessType = OperaType.QUERY, module = "档案分享管理->档案分享管理", details = "根据档案文件数据汇集管理列表")
|
||||
@RequiresPermissions("file:share:list")
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo list(KyDataCollectData kyDataCollectData) {
|
||||
List<KyDataCollectData> list = fileShareService.selectKyDataCollectDataList(kyDataCollectData);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
@SysLog(title = "档案分享文件详情", businessType = OperaType.QUERY, module = "档案分享管理->档案分享管理", details = "档案分享文件详情")
|
||||
@GetMapping("/queryById")
|
||||
public void queryById(KyDataCollectData kyDataCollectData, HttpServletResponse response) {
|
||||
fileShareService.queryDetailById(kyDataCollectData,response);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
package com.bonus.web.mapper;
|
||||
|
||||
import com.bonus.system.domain.KyDataClassify;
|
||||
import com.bonus.system.domain.KyDataCollectData;
|
||||
import com.bonus.system.domain.vo.KyDataClassifyVo;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Author:liang.chao
|
||||
* @Date:2025/10/23 - 14:45
|
||||
*/
|
||||
@Mapper
|
||||
public interface FileShareMapper {
|
||||
|
||||
List<KyDataClassifyVo> getParenList();
|
||||
|
||||
List<KyDataClassify> listAll(KyDataClassify kyDataClassify);
|
||||
|
||||
List<KyDataCollectData> selectKyDataCollectDataList(KyDataCollectData kyDataCollectData);
|
||||
|
||||
String queryDetailById(KyDataCollectData kyDataCollectData);
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
package com.bonus.web.service;
|
||||
|
||||
import com.bonus.common.core.domain.R;
|
||||
import com.bonus.system.domain.KyDataClassify;
|
||||
import com.bonus.system.domain.KyDataCollectData;
|
||||
import com.bonus.system.domain.vo.KyDataClassifyVo;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @Author:liang.chao
|
||||
* @Date:2025/10/23 - 14:43
|
||||
*/
|
||||
public interface FileShareService {
|
||||
|
||||
List<KyDataClassifyVo> listAll(KyDataClassify kyDataClassify);
|
||||
|
||||
List<KyDataCollectData> selectKyDataCollectDataList(KyDataCollectData kyDataCollectData);
|
||||
|
||||
void queryDetailById(KyDataCollectData kyDataCollectData, HttpServletResponse response);
|
||||
}
|
||||
|
|
@ -0,0 +1,190 @@
|
|||
package com.bonus.web.service.impl;
|
||||
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.alibaba.fastjson2.JSONArray;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.bonus.common.core.domain.R;
|
||||
import com.bonus.system.domain.KyDataClassify;
|
||||
import com.bonus.system.domain.KyDataCollectData;
|
||||
import com.bonus.system.domain.vo.KyDataClassifyVo;
|
||||
import com.bonus.web.domain.vo.DaKyProFilesContentsVo;
|
||||
import com.bonus.web.mapper.FileShareMapper;
|
||||
import com.bonus.web.service.FileManageService;
|
||||
import com.bonus.web.service.FileShareService;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.util.Base64;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @Author:liang.chao
|
||||
* @Date:2025/10/23 - 14:43
|
||||
*/
|
||||
@Service
|
||||
public class FileShareServiceImpl implements FileShareService {
|
||||
|
||||
@Resource
|
||||
private FileShareMapper fileShareMapper;
|
||||
@Resource
|
||||
private FileManageService fileManageService;
|
||||
|
||||
@Value("${bonus.profile}")
|
||||
private String uploadDir;
|
||||
|
||||
|
||||
@Override
|
||||
public List<KyDataClassifyVo> listAll(KyDataClassify kyDataClassify) {
|
||||
//获取父级
|
||||
List<KyDataClassifyVo> KyDataClassifyVoList = fileShareMapper.getParenList();
|
||||
if (KyDataClassifyVoList.size() > 0) {
|
||||
//获取子级
|
||||
for (KyDataClassifyVo kyDataClassifyVo : KyDataClassifyVoList) {
|
||||
kyDataClassify.setPid(kyDataClassifyVo.getCode());
|
||||
List<KyDataClassify> kyDataClassifyList = fileShareMapper.listAll(kyDataClassify);
|
||||
kyDataClassifyVo.setKyDataClassifyList(kyDataClassifyList);
|
||||
}
|
||||
}
|
||||
return KyDataClassifyVoList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<KyDataCollectData> selectKyDataCollectDataList(KyDataCollectData kyDataCollectData) {
|
||||
return fileShareMapper.selectKyDataCollectDataList(kyDataCollectData);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void queryDetailById(KyDataCollectData kyDataCollectData, HttpServletResponse response) {
|
||||
try {
|
||||
String jsonData = fileShareMapper.queryDetailById(kyDataCollectData);
|
||||
if (jsonData != null) {
|
||||
JSONArray objects = JSON.parseArray(jsonData);
|
||||
for (Object obj : objects) {
|
||||
JSONObject object = (JSONObject) obj;
|
||||
if (object != null) {
|
||||
String id = object.getString("id");
|
||||
if (id.equals(kyDataCollectData.getJsonId().toString())) {
|
||||
DaKyProFilesContentsVo record = fileManageService.getFileById(Long.parseLong(id));
|
||||
|
||||
if (record == null || StringUtils.isBlank(record.getFilePath())) {
|
||||
response.setStatus(HttpStatus.NOT_FOUND.value());
|
||||
return;
|
||||
}
|
||||
|
||||
String safeFullPath = buildSecureFullPath(uploadDir, record.getFilePath());
|
||||
if (safeFullPath == null) {
|
||||
response.setStatus(HttpStatus.BAD_REQUEST.value());
|
||||
return;
|
||||
}
|
||||
|
||||
File file = new File(safeFullPath);
|
||||
if (!file.exists() || !file.isFile()) {
|
||||
response.setStatus(HttpStatus.NOT_FOUND.value());
|
||||
return;
|
||||
}
|
||||
|
||||
// 设置响应头
|
||||
String contentType = getContentType(record.getSuffixName());
|
||||
response.setContentType(contentType);
|
||||
String encodedFileName = URLEncoder.encode(record.getFileName(), String.valueOf(StandardCharsets.UTF_8))
|
||||
.replaceAll("\\+", "%20");
|
||||
response.setHeader("Content-Disposition", "inline; filename*=UTF-8''" + encodedFileName);
|
||||
|
||||
// 写入文件流到响应
|
||||
Files.copy(file.toPath(), response.getOutputStream());
|
||||
response.flushBuffer();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
response.setStatus(HttpStatus.NOT_FOUND.value());
|
||||
} catch (Exception e) {
|
||||
response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
|
||||
}
|
||||
}
|
||||
|
||||
private String getContentType(String suffix) {
|
||||
if (StringUtils.isBlank(suffix)) {
|
||||
return "application/octet-stream";
|
||||
}
|
||||
|
||||
switch (suffix.toLowerCase()) {
|
||||
case "jpg":
|
||||
case "jpeg":
|
||||
return "image/jpeg";
|
||||
case "png":
|
||||
return "image/png";
|
||||
case "gif":
|
||||
return "image/gif";
|
||||
case "bmp":
|
||||
return "image/bmp";
|
||||
case "webp":
|
||||
return "image/webp";
|
||||
case "svg":
|
||||
return "image/svg+xml";
|
||||
default:
|
||||
return "application/octet-stream";
|
||||
}
|
||||
}
|
||||
|
||||
private String buildSecureFullPath(String baseDir, String filePath) {
|
||||
if (StringUtils.isBlank(filePath)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// 统一路径分隔符
|
||||
String unifiedPath = filePath.replace('\\', '/');
|
||||
|
||||
// 移除开头的斜杠
|
||||
unifiedPath = unifiedPath.replaceAll("^/+", "");
|
||||
|
||||
// 检查路径遍历
|
||||
if (unifiedPath.contains("../") || unifiedPath.contains("..\\")) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// 检查绝对路径
|
||||
if (unifiedPath.matches("^[a-zA-Z]:/.*") || unifiedPath.startsWith("/")) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// 构建完整路径
|
||||
String fullPath;
|
||||
if (baseDir.endsWith(File.separator)) {
|
||||
fullPath = baseDir + unifiedPath;
|
||||
} else {
|
||||
fullPath = baseDir + File.separator + unifiedPath;
|
||||
}
|
||||
|
||||
// 使用File的getCanonicalPath进行最终验证
|
||||
try {
|
||||
File canonicalFile = new File(fullPath);
|
||||
String canonicalPath = canonicalFile.getCanonicalPath();
|
||||
|
||||
// 验证是否仍在基础目录内
|
||||
String canonicalBaseDir = new File(baseDir).getCanonicalPath();
|
||||
if (!canonicalPath.startsWith(canonicalBaseDir)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return canonicalPath;
|
||||
} catch (IOException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
<?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="com.bonus.web.mapper.FileShareMapper">
|
||||
|
||||
<select id="getParenList" resultType="com.bonus.system.domain.vo.KyDataClassifyVo">
|
||||
select dict_value as code,dict_label as name
|
||||
from da_ky_sys_dict_data where dict_type = 'file_share_collect' and status='0'
|
||||
</select>
|
||||
<select id="listAll" resultType="com.bonus.system.domain.KyDataClassify">
|
||||
select id,data_type_name
|
||||
from da_ky_file_share where del_flag='1' and pid =#{pid}
|
||||
<if test="dataTypeName!=null">
|
||||
AND INSTR(data_type_name, #{dataTypeName}) > 0
|
||||
</if>
|
||||
</select>
|
||||
<select id="selectKyDataCollectDataList" resultType="com.bonus.system.domain.KyDataCollectData">
|
||||
select id,data_classify_id,data_json
|
||||
from da_ky_file_share_data
|
||||
where del_flag = '1'
|
||||
<if test="dataClassifyId!=null">
|
||||
AND data_classify_id = #{dataClassifyId}
|
||||
</if>
|
||||
</select>
|
||||
<select id="queryDetailById" resultType="java.lang.String">
|
||||
select data_json
|
||||
from da_ky_file_share_data
|
||||
where id = #{id}
|
||||
</select>
|
||||
</mapper>
|
||||
|
|
@ -74,6 +74,7 @@ public class ResourcesConfig implements WebMvcConfigurer
|
|||
.excludePathPatterns("/smartArchives/session/check")
|
||||
.excludePathPatterns("/smartArchives/sys/config/getConfig")
|
||||
.excludePathPatterns("/smartArchives/data/Collect/queryById")
|
||||
.excludePathPatterns("/smartArchives/file/share/queryById")
|
||||
.excludePathPatterns(EXCLUDEURLS)
|
||||
.order(-15);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@ public class SecurityConfig
|
|||
.authorizeHttpRequests((requests) -> {
|
||||
permitAllUrl.getUrls().forEach(url -> requests.antMatchers(url).permitAll());
|
||||
// 对于登录login 注册register 验证码captchaImage 允许匿名访问
|
||||
requests.antMatchers("/login", "/register", "/captchaImage","/sys/config/getConfig","/session/check","/data/Collect/queryById").permitAll()
|
||||
requests.antMatchers("/login", "/register", "/captchaImage","/sys/config/getConfig","/session/check","/data/Collect/queryById","/file/share/queryById").permitAll()
|
||||
// 静态资源,可匿名访问
|
||||
.antMatchers(HttpMethod.GET, "/", "/*.html", "/**/*.html", "/**/*.css", "/**/*.js", "/profile/**").permitAll()
|
||||
.antMatchers("/swagger-ui.html", "/swagger-resources/**", "/webjars/**", "/*/api-docs", "/druid/**").permitAll()
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ public class ReplayAttackInterceptor implements HandlerInterceptor {
|
|||
ignoreUrlPatterns.add("/smartArchives/getRouters");
|
||||
ignoreUrlPatterns.add("/smartArchives/session/check");
|
||||
ignoreUrlPatterns.add("/smartArchives/sys/config/getConfig");
|
||||
ignoreUrlPatterns.add("/smartArchives/data/Collect/queryById");
|
||||
ignoreUrlPatterns.add("/smartArchives/file/share/queryById");
|
||||
}
|
||||
|
||||
private final RedisCache redisUtil;
|
||||
|
|
|
|||
Loading…
Reference in New Issue