diff --git a/jeecg-boot-master/jeecg-module-demo/src/main/java/org/jeecg/modules/demo/awardpersion/entity/AwardPersion.java b/jeecg-boot-master/jeecg-module-demo/src/main/java/org/jeecg/modules/demo/awardpersion/entity/AwardPersion.java index c6da4338..ab248c03 100644 --- a/jeecg-boot-master/jeecg-module-demo/src/main/java/org/jeecg/modules/demo/awardpersion/entity/AwardPersion.java +++ b/jeecg-boot-master/jeecg-module-demo/src/main/java/org/jeecg/modules/demo/awardpersion/entity/AwardPersion.java @@ -113,4 +113,9 @@ public class AwardPersion implements Serializable { @ApiModelProperty(value = "学生所属学院") private String studentorg; + /**上传证书*/ + @ApiModelProperty(value = "上传证书") + private String sczs; + + } diff --git a/jeecg-boot-master/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/CommonController.java b/jeecg-boot-master/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/CommonController.java index 21e4bdfd..18c17df6 100644 --- a/jeecg-boot-master/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/CommonController.java +++ b/jeecg-boot-master/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/system/controller/CommonController.java @@ -45,6 +45,9 @@ public class CommonController { @Value(value = "${jeecg.path.upload}") private String uploadpath; + @Value(value = "${jeecg.path.uploadzs}") + private String uploadpathzs; + /** * 本地:local minio:minio 阿里:alioss */ @@ -126,6 +129,114 @@ public class CommonController { return result; } + /** + * 证书上传统一方法 + * @param request + * @param response + * @return + */ + @PostMapping(value = "/uploadzs") + public Result uploadzs(HttpServletRequest request, HttpServletResponse response) throws Exception { + Result result = new Result<>(); + String savePath = ""; + String bizPath = request.getParameter("biz"); + + //LOWCOD-2580 sys/common/upload接口存在任意文件上传漏洞 + if (oConvertUtils.isNotEmpty(bizPath)) { + if(bizPath.contains(SymbolConstant.SPOT_SINGLE_SLASH) || bizPath.contains(SymbolConstant.SPOT_DOUBLE_BACKSLASH)){ + throw new JeecgBootException("上传目录bizPath,格式非法!"); + } + } + + MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request; + // 获取上传文件对象 + MultipartFile file = multipartRequest.getFile("file"); + if(oConvertUtils.isEmpty(bizPath)){ + if(CommonConstant.UPLOAD_TYPE_OSS.equals(uploadType)){ + //未指定目录,则用阿里云默认目录 upload + bizPath = "uploadzs"; + //result.setMessage("使用阿里云文件上传时,必须添加目录!"); + //result.setSuccess(false); + //return result; + }else{ + bizPath = ""; + } + } + if(CommonConstant.UPLOAD_TYPE_LOCAL.equals(uploadType)){ + //update-begin-author:liusq date:20221102 for: 过滤上传文件类型 + FileTypeFilter.fileTypeFilter(file); + //update-end-author:liusq date:20221102 for: 过滤上传文件类型 + //update-begin-author:lvdandan date:20200928 for:修改JEditor编辑器本地上传 + savePath = this.uploadLocalzs(file,bizPath); + //update-begin-author:lvdandan date:20200928 for:修改JEditor编辑器本地上传 + /** 富文本编辑器及markdown本地上传时,采用返回链接方式 + //针对jeditor编辑器如何使 lcaol模式,采用 base64格式存储 + String jeditor = request.getParameter("jeditor"); + if(oConvertUtils.isNotEmpty(jeditor)){ + result.setMessage(CommonConstant.UPLOAD_TYPE_LOCAL); + result.setSuccess(true); + return result; + }else{ + savePath = this.uploadLocal(file,bizPath); + } + */ + }else{ + //update-begin-author:taoyan date:20200814 for:文件上传改造 + savePath = CommonUtils.upload(file, bizPath, uploadType); + //update-end-author:taoyan date:20200814 for:文件上传改造 + } + if(oConvertUtils.isNotEmpty(savePath)){ + result.setMessage(savePath); + result.setSuccess(true); + }else { + result.setMessage("上传失败!"); + result.setSuccess(false); + } + return result; + } + + /** + * 本地文件上传 + * @param mf 文件 + * @param bizPath 自定义路径 + * @return + */ + private String uploadLocalzs(MultipartFile mf,String bizPath){ + try { + String ctxPath = uploadpathzs; + String fileName = null; + File file = new File(ctxPath + File.separator + bizPath + File.separator ); + if (!file.exists()) { + // 创建文件根目录 + file.mkdirs(); + } + // 获取文件名 + String orgName = mf.getOriginalFilename(); + orgName = CommonUtils.getFileName(orgName); + if(orgName.indexOf(SymbolConstant.SPOT)!=-1){ + fileName = orgName.substring(0, orgName.lastIndexOf(".")) + "_" + System.currentTimeMillis() + orgName.substring(orgName.lastIndexOf(".")); + }else{ + fileName = orgName+ "_" + System.currentTimeMillis(); + } + String savePath = file.getPath() + File.separator + fileName; + File savefile = new File(savePath); + FileCopyUtils.copy(mf.getBytes(), savefile); + String dbpath = null; + if(oConvertUtils.isNotEmpty(bizPath)){ + dbpath = bizPath + File.separator + fileName; + }else{ + dbpath = fileName; + } + if (dbpath.contains(SymbolConstant.DOUBLE_BACKSLASH)) { + dbpath = dbpath.replace(SymbolConstant.DOUBLE_BACKSLASH, SymbolConstant.SINGLE_SLASH); + } + return dbpath; + } catch (IOException e) { + log.error(e.getMessage(), e); + } + return ""; + } + /** * 本地文件上传 * @param mf 文件 @@ -267,6 +378,68 @@ public class CommonController { } + /** + * 预览图片&下载文件 + * 请求地址:http://localhost:8080/common/static/{user/20190119/e1fe9925bc315c60addea1b98eb1cb1349547719_1547866868179.jpg} + * + * @param request + * @param response + */ + @GetMapping(value = "/staticzs/**") + public void viewzs(HttpServletRequest request, HttpServletResponse response) { + // ISO-8859-1 ==> UTF-8 进行编码转换 + String imgPath = extractPathFromPattern(request); + if(oConvertUtils.isEmpty(imgPath) || CommonConstant.STRING_NULL.equals(imgPath)){ + return; + } + // 其余处理略 + InputStream inputStream = null; + OutputStream outputStream = null; + try { + imgPath = imgPath.replace("..", "").replace("../",""); + if (imgPath.endsWith(SymbolConstant.COMMA)) { + imgPath = imgPath.substring(0, imgPath.length() - 1); + } + String filePath = uploadpathzs + File.separator + imgPath; + File file = new File(filePath); + if(!file.exists()){ + response.setStatus(404); + throw new RuntimeException("文件["+imgPath+"]不存在.."); + } + // 设置强制下载不打开 + response.setContentType("application/force-download"); + response.addHeader("Content-Disposition", "attachment;fileName=" + new String(file.getName().getBytes("UTF-8"),"iso-8859-1")); + inputStream = new BufferedInputStream(new FileInputStream(filePath)); + outputStream = response.getOutputStream(); + byte[] buf = new byte[1024]; + int len; + while ((len = inputStream.read(buf)) > 0) { + outputStream.write(buf, 0, len); + } + response.flushBuffer(); + } catch (IOException e) { + log.error("预览文件失败" + e.getMessage()); + response.setStatus(404); + e.printStackTrace(); + } finally { + if (inputStream != null) { + try { + inputStream.close(); + } catch (IOException e) { + log.error(e.getMessage(), e); + } + } + if (outputStream != null) { + try { + outputStream.close(); + } catch (IOException e) { + log.error(e.getMessage(), e); + } + } + } + + } + // /** // * 下载文件 // * 请求地址:http://localhost:8080/common/download/{user/20190119/e1fe9925bc315c60addea1b98eb1cb1349547719_1547866868179.jpg} diff --git a/jeecg-boot-master/jeecg-module-system/jeecg-system-start/src/main/resources/application-dev.yml b/jeecg-boot-master/jeecg-module-system/jeecg-system-start/src/main/resources/application-dev.yml index b34ed5d4..28ff842c 100644 --- a/jeecg-boot-master/jeecg-module-system/jeecg-system-start/src/main/resources/application-dev.yml +++ b/jeecg-boot-master/jeecg-module-system/jeecg-system-start/src/main/resources/application-dev.yml @@ -184,6 +184,8 @@ jeecg: path: #文件上传根目录 设置 upload: /opt/upFiles + #文件上传根目录 设置 + uploadzs: /opt/upFileszs #webapp文件路径 webapp: /opt/webapp shiro: diff --git a/jeecgboot-vue3-master/src/api/common/api.ts b/jeecgboot-vue3-master/src/api/common/api.ts index 47d5cfbb..38d07129 100644 --- a/jeecgboot-vue3-master/src/api/common/api.ts +++ b/jeecgboot-vue3-master/src/api/common/api.ts @@ -21,6 +21,11 @@ enum Api { */ export const uploadUrl = `${baseUploadUrl}/sys/common/upload`; +/** + * 上传父路径 + */ +export const uploadUrlzs = `${baseUploadUrl}/sys/common/uploadzs`; + /** * 职务列表 * @param params diff --git a/jeecgboot-vue3-master/src/components/Form/src/jeecg/components/JImageUploadzs.vue b/jeecgboot-vue3-master/src/components/Form/src/jeecg/components/JImageUploadzs.vue new file mode 100644 index 00000000..fe613408 --- /dev/null +++ b/jeecgboot-vue3-master/src/components/Form/src/jeecg/components/JImageUploadzs.vue @@ -0,0 +1,260 @@ + + + diff --git a/jeecgboot-vue3-master/src/utils/common/compUtils.ts b/jeecgboot-vue3-master/src/utils/common/compUtils.ts index b36eebbf..202db76c 100644 --- a/jeecgboot-vue3-master/src/utils/common/compUtils.ts +++ b/jeecgboot-vue3-master/src/utils/common/compUtils.ts @@ -28,6 +28,29 @@ export const getFileAccessHttpUrl = (fileUrl, prefix = 'http') => { return result; }; +/** + * 获取文件服务访问路径 + * @param fileUrl 文件路径 + * @param prefix(默认http) 文件路径前缀 http/https + */ +export const getFileAccessHttpUrlzs = (fileUrl, prefix = 'http') => { + let result = fileUrl; + try { + if (fileUrl && fileUrl.length > 0 && !fileUrl.startsWith(prefix)) { + //判断是否是数组格式 + let isArray = fileUrl.indexOf('[') != -1; + if (!isArray) { + let prefix = `${baseApiUrl}/sys/common/staticzs/`; + // 判断是否已包含前缀 + if (!fileUrl.startsWith(prefix)) { + result = `${prefix}${fileUrl}`; + } + } + } + } catch (err) {} + return result; +}; + /** * 触发 window.resize */ diff --git a/jeecgboot-vue3-master/src/utils/common/renderUtils.ts b/jeecgboot-vue3-master/src/utils/common/renderUtils.ts index cf8d1d63..87792927 100644 --- a/jeecgboot-vue3-master/src/utils/common/renderUtils.ts +++ b/jeecgboot-vue3-master/src/utils/common/renderUtils.ts @@ -1,6 +1,6 @@ import { h } from 'vue'; import { Avatar, Tag, Tooltip } from 'ant-design-vue'; -import { getFileAccessHttpUrl } from '/@/utils/common/compUtils'; +import { getFileAccessHttpUrl,getFileAccessHttpUrlzs } from '/@/utils/common/compUtils'; import { Tinymce } from '/@/components/Tinymce'; import Icon from '/@/components/Icon'; import { getDictItemsByCode } from '/@/utils/dict/index'; @@ -83,6 +83,35 @@ const render = { ); //update-end-author:taoyan date:2022-5-24 for: VUEN-1084 【vue3】online表单测试发现的新问题 41、生成的代码,树默认图大小未改 }, + /** + * 渲染证书图片 + * @param text + */ + renderImagezs: ({ text }) => { + if (!text) { + //update-begin-author:taoyan date:2022-5-24 for: VUEN-1084 【vue3】online表单测试发现的新问题 41、生成的代码,树默认图大小未改 + return h( + Avatar, + { shape: 'square', size: 25 }, + { + icon: () => h(Icon, { icon: 'ant-design:file-image-outlined', size: 25 }), + } + ); + } + let avatarList = text.split(','); + return h( + 'span', + avatarList.map((item) => { + return h(Avatar, { + src: getFileAccessHttpUrlzs(item), + shape: 'square', + size: 25, + style: { marginRight: '5px' }, + }); + }) + ); + //update-end-author:taoyan date:2022-5-24 for: VUEN-1084 【vue3】online表单测试发现的新问题 41、生成的代码,树默认图大小未改 + }, /** * 渲染 Tooltip * @param text diff --git a/jeecgboot-vue3-master/src/views/awardpersion/AwardPersion.api.ts b/jeecgboot-vue3-master/src/views/awardpersion/AwardPersion.api.ts index 02fd55eb..7cf35623 100644 --- a/jeecgboot-vue3-master/src/views/awardpersion/AwardPersion.api.ts +++ b/jeecgboot-vue3-master/src/views/awardpersion/AwardPersion.api.ts @@ -16,7 +16,7 @@ enum Api { queryCompId = '/annualcompgroup/annualCompGroup/queryCompId', queryOptions = '/awardpersion/awardPersion/queryOptions', personalAbilityEvaluation = '/abilityEvaluation/personalAbilityEvaluation/personalAbilityEvaluation2', - + sczs='/awardpersion/awardPersion/sczs', } @@ -91,6 +91,16 @@ export const saveOrUpdate1 = (params, isUpdate) => { return defHttp.post({ url: url, params }, { isTransformResponse: false }); } +/** + * 上传证书 + * @param params + * @param isUpdate + */ +export const sczs = (params, isUpdate) => { + let url = isUpdate ? Api.sczs : Api.sczs; + return defHttp.post({ url: url, params }, { isTransformResponse: false }); +} + // 个人能力量化 export const personalAbilityEvaluation = (params,handleSuccess) => { createConfirm({ diff --git a/jeecgboot-vue3-master/src/views/awardpersion/AwardPersion.data.ts b/jeecgboot-vue3-master/src/views/awardpersion/AwardPersion.data.ts index 9a384a3f..9e125b4f 100644 --- a/jeecgboot-vue3-master/src/views/awardpersion/AwardPersion.data.ts +++ b/jeecgboot-vue3-master/src/views/awardpersion/AwardPersion.data.ts @@ -39,6 +39,12 @@ export const columns: BasicColumn[] = [ align: "center", dataIndex: 'studentname' }, + { + title: '证书', + align: "center", + dataIndex: 'sczs', + customRender: render.renderImagezs, + }, /* { title: '状态', align: "center", diff --git a/jeecgboot-vue3-master/src/views/awardpersion/components/AwardPersionForm2.vue b/jeecgboot-vue3-master/src/views/awardpersion/components/AwardPersionForm2.vue new file mode 100644 index 00000000..2f8c386e --- /dev/null +++ b/jeecgboot-vue3-master/src/views/awardpersion/components/AwardPersionForm2.vue @@ -0,0 +1,148 @@ + + + + + diff --git a/jeecgboot-vue3-master/src/views/awardpersion/components/AwardPersionModal2.vue b/jeecgboot-vue3-master/src/views/awardpersion/components/AwardPersionModal2.vue new file mode 100644 index 00000000..a7af411f --- /dev/null +++ b/jeecgboot-vue3-master/src/views/awardpersion/components/AwardPersionModal2.vue @@ -0,0 +1,75 @@ + + + + +