diff --git a/stdiet-admin/src/main/java/com/stdiet/web/controller/MyApplicationRunner.java b/stdiet-admin/src/main/java/com/stdiet/web/controller/MyApplicationRunner.java index 5357b59f4..7e9353e07 100644 --- a/stdiet-admin/src/main/java/com/stdiet/web/controller/MyApplicationRunner.java +++ b/stdiet-admin/src/main/java/com/stdiet/web/controller/MyApplicationRunner.java @@ -20,8 +20,8 @@ public class MyApplicationRunner implements ApplicationRunner { @Override public void run(ApplicationArguments args) throws Exception { - System.out.println("项目启动调用方法"); + /* System.out.println("项目启动调用方法"); String path = AliyunOSSUtils.uploadFileInputSteam(AliyunOSSConfig.casePrefix,"ceshi.png",new File("D:\\ceshi.png")); - System.out.println(path); + System.out.println(path);*/ } } diff --git a/stdiet-admin/src/main/java/com/stdiet/web/controller/custom/SysCustomerCaseController.java b/stdiet-admin/src/main/java/com/stdiet/web/controller/custom/SysCustomerCaseController.java index 66937d2d5..47c95eb63 100644 --- a/stdiet-admin/src/main/java/com/stdiet/web/controller/custom/SysCustomerCaseController.java +++ b/stdiet-admin/src/main/java/com/stdiet/web/controller/custom/SysCustomerCaseController.java @@ -1,16 +1,30 @@ package com.stdiet.web.controller.custom; +import java.io.InputStream; +import java.net.URLEncoder; import java.util.List; + +import com.stdiet.common.config.AliyunOSSConfig; +import com.stdiet.common.config.RuoYiConfig; +import com.stdiet.common.constant.Constants; +import com.stdiet.common.exception.file.FileNameLengthLimitExceededException; +import com.stdiet.common.utils.StringUtils; +import com.stdiet.common.utils.file.FileUploadUtils; +import com.stdiet.common.utils.file.FileUtils; +import com.stdiet.common.utils.file.MimeTypeUtils; +import com.stdiet.common.utils.oss.AliyunOSSUtils; +import com.stdiet.custom.domain.SysCustomerCaseFile; +import com.stdiet.custom.dto.request.FileRequest; +import com.sun.deploy.net.HttpResponse; +import io.swagger.models.auth.In; +import org.aspectj.weaver.loadtime.Aj; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.http.StreamingHttpOutputMessage; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.PutMapping; -import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import com.stdiet.common.annotation.Log; import com.stdiet.common.core.controller.BaseController; import com.stdiet.common.core.domain.AjaxResult; @@ -19,6 +33,10 @@ import com.stdiet.custom.domain.SysCustomerCase; import com.stdiet.custom.service.ISysCustomerCaseService; import com.stdiet.common.utils.poi.ExcelUtil; import com.stdiet.common.core.page.TableDataInfo; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; /** * 客户案例管理Controller @@ -100,4 +118,80 @@ public class SysCustomerCaseController extends BaseController { return toAjax(sysCustomerCaseService.deleteSysCustomerCaseByIds(ids)); } + + /** + * 查询客户案例文件列表 + */ + @GetMapping("/getFileListByCaseId") + @PreAuthorize("@ss.hasPermi('custom:customerCase:list')") + public TableDataInfo getFileListByCaseId(@RequestParam("caseId")Long caseId) + { + List<SysCustomerCaseFile> list = sysCustomerCaseService.getFileListByCaseId(caseId); + return getDataTable(list); + } + + /** + * 上传文件到OSS返回URL + */ + @PostMapping("/uploadCaseFile") + @PreAuthorize("@ss.hasPermi('custom:customerCase:list')") + public AjaxResult uploadCseFile(MultipartFile file) throws Exception { + try { + if(file == null){ + return AjaxResult.error("文件不存在"); + } + int fileNameLength = file.getOriginalFilename().length(); + if (fileNameLength > FileUploadUtils.DEFAULT_FILE_NAME_LENGTH) + { + throw new FileNameLengthLimitExceededException(FileUploadUtils.DEFAULT_FILE_NAME_LENGTH); + } + FileUploadUtils.assertAllowed(file, MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION); + + String fileUrl = AliyunOSSUtils.uploadFileInputSteam(AliyunOSSConfig.casePrefix, file.getOriginalFilename(), file); + + AjaxResult ajax = null; + if(StringUtils.isNotEmpty(fileUrl)){ + ajax = AjaxResult.success(); + ajax.put("fileUrl", fileUrl); + ajax.put("fileName", file.getOriginalFilename()); + }else{ + ajax = AjaxResult.error("文件上传失败"); + } + return ajax; + } catch (Exception e) { + return AjaxResult.error("文件上传失败"); + } + } + + /** + * 下载案例文件 + * @param + * @return + */ + @PostMapping("/downCaseFile") + @PreAuthorize("@ss.hasPermi('custom:customerCase:list')") + public void downCaseFile(@RequestBody FileRequest fileRequest, HttpServletRequest request, HttpServletResponse response) { + /*try{ + InputStream fileStream = AliyunOSSUtils.downloadFile(fileRequest.getFileUrl()); + byte[] body = new byte[fileStream.available()]; + fileStream.read(body); + HttpHeaders headers = new HttpHeaders(); + headers.add("Content-Disposition", "attchement;filename=" + fileRequest.getFileName()); + HttpStatus statusCode = HttpStatus.OK; + ResponseEntity<byte[]> entity = new ResponseEntity<byte[]>(body, headers, statusCode); + return entity; + }catch (Exception e) { + e.printStackTrace(); + } + return null;*/ + try { + response.setCharacterEncoding("utf-8"); + response.setContentType("multipart/form-data"); + response.setHeader("Content-Disposition", + "attachment;fileName=" + FileUtils.setFileDownloadHeader(request, fileRequest.getFileName())); + FileUtils.writeBytes(AliyunOSSUtils.downloadFile(fileRequest.getFileUrl()), response.getOutputStream()); + }catch (Exception e){ + e.printStackTrace(); + } + } } \ No newline at end of file diff --git a/stdiet-common/src/main/java/com/stdiet/common/utils/file/FileUtils.java b/stdiet-common/src/main/java/com/stdiet/common/utils/file/FileUtils.java index 3fb3479f8..c9a14466c 100644 --- a/stdiet-common/src/main/java/com/stdiet/common/utils/file/FileUtils.java +++ b/stdiet-common/src/main/java/com/stdiet/common/utils/file/FileUtils.java @@ -1,11 +1,6 @@ package com.stdiet.common.utils.file; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.OutputStream; -import java.io.UnsupportedEncodingException; +import java.io.*; import java.net.URLEncoder; import javax.servlet.http.HttpServletRequest; @@ -74,6 +69,55 @@ public class FileUtils extends org.apache.commons.io.FileUtils } } + /** + * 输出指定文件的byte数组 + * + * @param inputStream 输入流 + * @param os 输出流 + * @return + */ + public static void writeBytes(InputStream inputStream, OutputStream os) throws IOException + { + try + { + byte[] b = new byte[1024]; + int length; + while ((length = inputStream.read(b)) > 0) + { + os.write(b, 0, length); + } + } + catch (IOException e) + { + throw e; + } + finally + { + if (os != null) + { + try + { + os.close(); + } + catch (IOException e1) + { + e1.printStackTrace(); + } + } + if (inputStream != null) + { + try + { + inputStream.close(); + } + catch (IOException e1) + { + e1.printStackTrace(); + } + } + } + } + /** * 删除文件 * diff --git a/stdiet-common/src/main/java/com/stdiet/common/utils/oss/AliyunOSSUtils.java b/stdiet-common/src/main/java/com/stdiet/common/utils/oss/AliyunOSSUtils.java index c78611763..583042321 100644 --- a/stdiet-common/src/main/java/com/stdiet/common/utils/oss/AliyunOSSUtils.java +++ b/stdiet-common/src/main/java/com/stdiet/common/utils/oss/AliyunOSSUtils.java @@ -13,20 +13,10 @@ import java.io.IOException; import java.io.InputStream; import java.util.UUID; -public class AliyunOSSUtils { - - // 创建OSSClient实例 - private static OSS ossClient = null; +public class AliyunOSSUtils { ; public static OSS getOssClient() { - if (ossClient == null) { - synchronized (OSS.class) { - if (ossClient == null) { - ossClient = new OSSClientBuilder().build(AliyunOSSConfig.EndPoint, AliyunOSSConfig.AccessKeyID, AliyunOSSConfig.AccessKeySecret); - } - } - } - return ossClient; + return new OSSClientBuilder().build(AliyunOSSConfig.EndPoint, AliyunOSSConfig.AccessKeyID, AliyunOSSConfig.AccessKeySecret); } /** @@ -204,7 +194,7 @@ public class AliyunOSSUtils { * * @param fileURL 文件的url */ - public InputStream downloadFile(String fileURL) throws IOException { + public static InputStream downloadFile(String fileURL) throws IOException { //将url解析成objectName String objectName = getObjectName(fileURL); diff --git a/stdiet-custom/src/main/java/com/stdiet/custom/domain/SysCustomerCase.java b/stdiet-custom/src/main/java/com/stdiet/custom/domain/SysCustomerCase.java index a56bc8567..8fd166cc9 100644 --- a/stdiet-custom/src/main/java/com/stdiet/custom/domain/SysCustomerCase.java +++ b/stdiet-custom/src/main/java/com/stdiet/custom/domain/SysCustomerCase.java @@ -23,13 +23,21 @@ public class SysCustomerCase extends BaseEntity private String name; /** 案例关键词 */ - @Excel(name = "案例关键词") + @Excel(name = "关键词") private String keyword; /** 案例所属客户ID */ - @Excel(name = "案例所属客户ID") private Long customerId; + @Excel(name = "所属客户") + private String customerName; + /** 删除标识 0未删除 1已删除,默认0 */ private Long delFlag; + + //案例文件名称数组 + private String[] caseFileName; + + //案例文件URL数组 + private String[] caseFileUrl; } \ No newline at end of file diff --git a/stdiet-custom/src/main/java/com/stdiet/custom/dto/request/FileRequest.java b/stdiet-custom/src/main/java/com/stdiet/custom/dto/request/FileRequest.java new file mode 100644 index 000000000..a04825f30 --- /dev/null +++ b/stdiet-custom/src/main/java/com/stdiet/custom/dto/request/FileRequest.java @@ -0,0 +1,11 @@ +package com.stdiet.custom.dto.request; + +import lombok.Data; + +@Data +public class FileRequest { + + private String fileUrl; + + private String fileName; +} diff --git a/stdiet-custom/src/main/java/com/stdiet/custom/mapper/SysCustomerCaseFileMapper.java b/stdiet-custom/src/main/java/com/stdiet/custom/mapper/SysCustomerCaseFileMapper.java index 8d3294f6e..0a5fac733 100644 --- a/stdiet-custom/src/main/java/com/stdiet/custom/mapper/SysCustomerCaseFileMapper.java +++ b/stdiet-custom/src/main/java/com/stdiet/custom/mapper/SysCustomerCaseFileMapper.java @@ -2,6 +2,7 @@ package com.stdiet.custom.mapper; import java.util.List; import com.stdiet.custom.domain.SysCustomerCaseFile; +import org.apache.ibatis.annotations.Param; /** * 客户案例对应文件管理Mapper接口 @@ -58,4 +59,29 @@ public interface SysCustomerCaseFileMapper * @return 结果 */ public int deleteSysCustomerCaseFileByIds(Long[] ids); + + /** + * 根据案例ID删除该案例下的所有文件记录 + * @param caseId + */ + int deleteSysCustomerCaseFileByCaseId(@Param("caseId")Long caseId); + + /** + * 根据案例ID批量删除该案例下的所有文件记录 + * @param caseIds + */ + int deleteSysCustomerCaseFileByCaseIds(Long[] caseIds); + + /** + * 批量插入案例文件记录 + * @param list + */ + int insertBatch(List<SysCustomerCaseFile> list); + + /** + * 根据案例Id查询案例文件列表 + * @param caseId + * @return + */ + List<SysCustomerCaseFile> selectSysCustomerCaseFileListByCaseId(@Param("caseId") Long caseId); } \ No newline at end of file diff --git a/stdiet-custom/src/main/java/com/stdiet/custom/service/ISysCustomerCaseService.java b/stdiet-custom/src/main/java/com/stdiet/custom/service/ISysCustomerCaseService.java index 4e0661ba3..76dc9dc7e 100644 --- a/stdiet-custom/src/main/java/com/stdiet/custom/service/ISysCustomerCaseService.java +++ b/stdiet-custom/src/main/java/com/stdiet/custom/service/ISysCustomerCaseService.java @@ -2,6 +2,7 @@ package com.stdiet.custom.service; import java.util.List; import com.stdiet.custom.domain.SysCustomerCase; +import com.stdiet.custom.domain.SysCustomerCaseFile; /** * 客户案例管理Service接口 @@ -58,4 +59,11 @@ public interface ISysCustomerCaseService { */ public int deleteSysCustomerCaseById(Long id); + /** + * 根据案例ID获取对应文件列表 + * @param caseId + * @return + */ + List<SysCustomerCaseFile> getFileListByCaseId(Long caseId); + } \ No newline at end of file diff --git a/stdiet-custom/src/main/java/com/stdiet/custom/service/impl/SysCustomerCaseServiceImpl.java b/stdiet-custom/src/main/java/com/stdiet/custom/service/impl/SysCustomerCaseServiceImpl.java index 03dc6e488..dc91d3e1d 100644 --- a/stdiet-custom/src/main/java/com/stdiet/custom/service/impl/SysCustomerCaseServiceImpl.java +++ b/stdiet-custom/src/main/java/com/stdiet/custom/service/impl/SysCustomerCaseServiceImpl.java @@ -1,12 +1,16 @@ package com.stdiet.custom.service.impl; +import java.util.ArrayList; import java.util.List; import com.stdiet.common.utils.DateUtils; +import com.stdiet.custom.domain.SysCustomerCaseFile; +import com.stdiet.custom.mapper.SysCustomerCaseFileMapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.stdiet.custom.mapper.SysCustomerCaseMapper; import com.stdiet.custom.domain.SysCustomerCase; import com.stdiet.custom.service.ISysCustomerCaseService; +import org.springframework.transaction.annotation.Transactional; /** * 客户案例管理Service业务层处理 @@ -15,11 +19,15 @@ import com.stdiet.custom.service.ISysCustomerCaseService; * @date 2021-03-04 */ @Service +@Transactional public class SysCustomerCaseServiceImpl implements ISysCustomerCaseService { @Autowired private SysCustomerCaseMapper sysCustomerCaseMapper; + @Autowired + private SysCustomerCaseFileMapper sysCustomerCaseFileMapper; + /** * 查询客户案例管理 * @@ -54,7 +62,23 @@ public class SysCustomerCaseServiceImpl implements ISysCustomerCaseService public int insertSysCustomerCase(SysCustomerCase sysCustomerCase) { sysCustomerCase.setCreateTime(DateUtils.getNowDate()); - return sysCustomerCaseMapper.insertSysCustomerCase(sysCustomerCase); + int rows = sysCustomerCaseMapper.insertSysCustomerCase(sysCustomerCase); + if(rows > 0){ + //批量添加文件对应列表 + SysCustomerCaseFile caseFile = null; + if(sysCustomerCase.getCaseFileUrl() != null && sysCustomerCase.getCaseFileUrl().length > 0){ + List<SysCustomerCaseFile> caseFileList = new ArrayList<>(); + for (String url : sysCustomerCase.getCaseFileUrl()) { + caseFile = new SysCustomerCaseFile(); + caseFile.setCaseId(sysCustomerCase.getId()); + caseFile.setFileName(sysCustomerCase.getCaseFileName()[caseFileList.size()]); + caseFile.setFileUrl(url); + caseFileList.add(caseFile); + } + rows = sysCustomerCaseFileMapper.insertBatch(caseFileList); + } + } + return rows; } /** @@ -79,7 +103,11 @@ public class SysCustomerCaseServiceImpl implements ISysCustomerCaseService @Override public int deleteSysCustomerCaseByIds(Long[] ids) { - return sysCustomerCaseMapper.deleteSysCustomerCaseByIds(ids); + int rows = sysCustomerCaseMapper.deleteSysCustomerCaseByIds(ids); + if(rows > 0){ + rows = sysCustomerCaseFileMapper.deleteSysCustomerCaseFileByCaseIds(ids); + } + return rows; } /** @@ -91,6 +119,19 @@ public class SysCustomerCaseServiceImpl implements ISysCustomerCaseService @Override public int deleteSysCustomerCaseById(Long id) { - return sysCustomerCaseMapper.deleteSysCustomerCaseById(id); + int rows = sysCustomerCaseMapper.deleteSysCustomerCaseById(id); + if(rows > 0){ + rows = sysCustomerCaseFileMapper.deleteSysCustomerCaseFileByCaseId(id); + } + return rows; + } + + /** + * 根据案例ID获取对应文件列表 + * @param caseId + * @return + */ + public List<SysCustomerCaseFile> getFileListByCaseId(Long caseId){ + return sysCustomerCaseFileMapper.selectSysCustomerCaseFileListByCaseId(caseId); } } \ No newline at end of file diff --git a/stdiet-custom/src/main/resources/mapper/custom/SysCustomerCaseFileMapper.xml b/stdiet-custom/src/main/resources/mapper/custom/SysCustomerCaseFileMapper.xml index 088b64a93..94c5b23a8 100644 --- a/stdiet-custom/src/main/resources/mapper/custom/SysCustomerCaseFileMapper.xml +++ b/stdiet-custom/src/main/resources/mapper/custom/SysCustomerCaseFileMapper.xml @@ -21,14 +21,17 @@ </sql> <select id="selectSysCustomerCaseFileList" parameterType="SysCustomerCaseFile" resultMap="SysCustomerCaseFileResult"> - <include refid="selectSysCustomerCaseFileVo"/> - <where> - </where> + <include refid="selectSysCustomerCaseFileVo"/> where del_flag = 0 + </select> + + <!-- 根据案例ID查询文件列表 --> + <select id="selectSysCustomerCaseFileListByCaseId" parameterType="Long" resultMap="SysCustomerCaseFileResult"> + <include refid="selectSysCustomerCaseFileVo"/> where del_flag = 0 and case_id = #{caseId} </select> <select id="selectSysCustomerCaseFileById" parameterType="Long" resultMap="SysCustomerCaseFileResult"> <include refid="selectSysCustomerCaseFileVo"/> - where id = #{id} + where id = #{id} and del_flag = 0 </select> <insert id="insertSysCustomerCaseFile" parameterType="SysCustomerCaseFile" useGeneratedKeys="true" keyProperty="id"> @@ -70,15 +73,39 @@ where id = #{id} </update> - <delete id="deleteSysCustomerCaseFileById" parameterType="Long"> - delete from sys_customer_case_file where id = #{id} - </delete> + <update id="deleteSysCustomerCaseFileById" parameterType="Long"> + update sys_customer_case_file set del_flag = 1 where id = #{id} + </update> - <delete id="deleteSysCustomerCaseFileByIds" parameterType="String"> - delete from sys_customer_case_file where id in + <update id="deleteSysCustomerCaseFileByIds" parameterType="String"> + update sys_customer_case_file set del_flag = 1 where id in <foreach item="id" collection="array" open="(" separator="," close=")"> #{id} </foreach> - </delete> + </update> + + <!-- 根据案例ID删除该案例对应的所有文件记录 --> + <update id="deleteSysCustomerCaseFileByCaseId" parameterType="Long"> + update sys_customer_case_file set del_flag = 1 where case_id = #{caseId} + </update> + + <!-- 根据案例ID批量删除该案例对应的所有文件记录 --> + <update id="deleteSysCustomerCaseFileByCaseIds" parameterType="String"> + update sys_customer_case_file set del_flag = 1 where case_id in + <foreach item="caseId" collection="array" open="(" separator="," close=")"> + #{caseId} + </foreach> + </update> + + <!-- 批量插入案例文件记录 --> + <insert id="insertBatch"> + INSERT INTO sys_customer_case_file + (case_id, file_url, file_name) + VALUES + <foreach collection="list" item="caseFile" separator=","> + (#{caseFile.caseId}, #{caseFile.fileUrl}, #{caseFile.fileName}) + </foreach> + </insert> + </mapper> \ No newline at end of file diff --git a/stdiet-custom/src/main/resources/mapper/custom/SysCustomerCaseMapper.xml b/stdiet-custom/src/main/resources/mapper/custom/SysCustomerCaseMapper.xml index f23030552..8f1ce69c0 100644 --- a/stdiet-custom/src/main/resources/mapper/custom/SysCustomerCaseMapper.xml +++ b/stdiet-custom/src/main/resources/mapper/custom/SysCustomerCaseMapper.xml @@ -15,20 +15,31 @@ <result property="updateTime" column="update_time" /> <result property="updateBy" column="update_by" /> <result property="delFlag" column="del_flag" /> + + <result property="customerName" column="customer_name"></result> </resultMap> <sql id="selectSysCustomerCaseVo"> - select id, name, keyword, remark, customer_id, create_time, create_by, update_time, update_by, del_flag from sys_customer_case + select id, name, keyword, remark, customer_id, create_time from sys_customer_case </sql> <select id="selectSysCustomerCaseList" parameterType="SysCustomerCase" resultMap="SysCustomerCaseResult"> - <include refid="selectSysCustomerCaseVo"/> where del_flag = 0 - <if test="name != null and name != ''"> and name like concat('%', #{name}, '%')</if> + select scc.id, scc.name, scc.keyword, scc.remark, scc.customer_id, scc.create_time,sc.name as customer_name from sys_customer_case scc + left join sys_customer sc on sc.id = scc.customer_id and sc.del_flag = 0 + where scc.del_flag = 0 + <if test="name != null and name != ''"> + and (scc.name like concat('%', #{name}, '%') OR scc.keyword like concat('%', #{name}, '%') OR scc.remark like concat('%', #{name}, '%')) + </if> + <if test="customerName != null and customerName != ''"> + and sc.name like concat('%', #{customerName}, '%') + </if> + order by id desc </select> <select id="selectSysCustomerCaseById" parameterType="Long" resultMap="SysCustomerCaseResult"> - <include refid="selectSysCustomerCaseVo"/> - where id = #{id} and del_flag = 0 + select scc.id, scc.name, scc.keyword, scc.remark, scc.customer_id, scc.create_time,sc.name as customer_name from sys_customer_case scc + left join sys_customer sc on sc.id = scc.customer_id and sc.del_flag = 0 + where scc.id = #{id} and scc.del_flag = 0 </select> <insert id="insertSysCustomerCase" parameterType="SysCustomerCase" useGeneratedKeys="true" keyProperty="id"> diff --git a/stdiet-ui/src/api/custom/customerCase.js b/stdiet-ui/src/api/custom/customerCase.js new file mode 100644 index 000000000..1d8c6358a --- /dev/null +++ b/stdiet-ui/src/api/custom/customerCase.js @@ -0,0 +1,84 @@ +import request from '@/utils/request' + +// 查询客户案例管理列表 +export function listCustomerCase(query) { + return request({ + url: '/custom/customerCase/list', + method: 'get', + params: query + }) +} + +// 查询客户案例管理详细 +export function getCustomerCase(id) { + return request({ + url: '/custom/customerCase/' + id, + method: 'get' + }) +} + +// 新增客户案例管理 +export function addCustomerCase(data) { + return request({ + url: '/custom/customerCase', + method: 'post', + data: data + }) +} + +// 修改客户案例管理 +export function updateCustomerCase(data) { + return request({ + url: '/custom/customerCase', + method: 'put', + data: data + }) +} + +// 删除客户案例管理 +export function delCustomerCase(id) { + return request({ + url: '/custom/customerCase/' + id, + method: 'delete' + }) +} + +// 导出客户案例管理 +export function exportCustomerCase(query) { + return request({ + url: '/custom/customerCase/export', + method: 'get', + params: query + }) +} + +// 根据案例ID查询对应文件列表 +export function getFileListByCaseId(caseId) { + return request({ + url: '/custom/customerCase/getFileListByCaseId', + method: 'get', + params: {"caseId": caseId} + }) +} + +// 上传案例文件 +export function uploadCseFile(data) { + return request({ + url: '/custom/customerCase/uploadCseFile', + method: 'post', + data: data + }) +} + +// 下载案例文件 +export function downCaseFile(data) { + return request({ + url: '/custom/customerCase/downCaseFile', + method: 'post', + data: data + }) +} + + + + diff --git a/stdiet-ui/src/components/Customer/SelectCustomer.vue b/stdiet-ui/src/components/Customer/SelectCustomer.vue new file mode 100644 index 000000000..27e1daba1 --- /dev/null +++ b/stdiet-ui/src/components/Customer/SelectCustomer.vue @@ -0,0 +1,174 @@ +<template> + <!-- 选择用户对话框 --> + <el-dialog :title="title" :visible.sync="open" @closed="cancel" width="480px" append-to-body> + <div class="app-container"> + <el-form + :model="queryParams" + ref="queryForm" + :inline="true" + v-show="showSearch" + label-width="60px" style="margin-top: -20px"> + <el-form-item label="名字" prop="name"> + <el-input + v-model.trim="queryParams.name" + placeholder="请输入名字" + clearable + size="small" + /> + </el-form-item> + <el-form-item> + <el-button + type="cyan" + icon="el-icon-search" + size="mini" + @click="handleQuery" + >搜索</el-button + > + </el-form-item> + </el-form> + + <el-row :gutter="10" class="mb8"> + <!--<el-col :span="1.5"> + <el-button + type="success" + size="mini" + :disabled="single" + @click="handleSelect" + >选择当前勾选用户</el-button> + </el-col>--> + <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar> + </el-row> + + <el-table + v-loading="loading" + :data="customerCenterList" + @selection-change="handleSelectionChange" + ref="customerTable" + > + <!-- <el-table-column + label="创建时间" + align="center" + prop="createTime" + width="166" + />--> + <el-table-column type="selection" width="55" align="center" /> + <el-table-column label="客户姓名" align="center" prop="name" /> + <el-table-column label="手机号" align="center" prop="phone" /> + </el-table> + + <pagination + v-show="total > 0" + :total="total" + :page.sync="queryParams.pageNum" + :limit.sync="queryParams.pageSize" + :layout="'total, sizes, prev, next'" + :pageSizes="[5]" + @pagination="getList" + /> + + </div> + <div slot="footer" class="dialog-footer"> + <el-button + type="success" + :disabled="single" + @click="handleSelect" + >确定</el-button> + <el-button @click="cancel">取 消</el-button> + </div> + </el-dialog> +</template> + +<script> +import { + listCustomer, +} from "@/api/custom/customer"; + + +export default { + name: "selectCustomer", + components: { + + }, + data() { + return { + // 遮罩层 + loading: true, + // 选中数组 + ids: [], + // 选择名字数组 + names:[], + // 非单个禁用 + single: true, + // 非多个禁用 + multiple: true, + // 显示搜索条件 + showSearch: true, + // 总条数 + total: 0, + // 客户档案表格数据 + customerCenterList: [], + // 弹出层标题 + title: "", + // 是否显示弹出层 + open: false, + // 查询参数 + queryParams: { + pageNum: 1, + pageSize: 5, + name: null, + phone: null + } + }; + }, + created() { + this.getList(); + }, + computed: { + }, + methods: { + showDialog(title) { + this.title = title ? title : "选择客户"; + this.open = true; + }, + /** 查询客户档案列表 */ + getList() { + this.loading = true; + listCustomer(this.queryParams).then((response) => { + this.customerCenterList = response.rows; + this.total = response.total; + this.loading = false; + }); + }, + // 取消按钮 + cancel() { + this.open = false; + this.$refs.customerTable.clearSelection(); + }, + /** 搜索按钮操作 */ + handleQuery() { + this.queryParams.pageNum = 1; + this.getList(); + }, + /** 重置按钮操作 */ + resetQuery() { + this.resetForm("queryForm"); + this.handleQuery(); + }, + // 多选框选中数据 + handleSelectionChange(selection) { + this.ids = selection.map((item) => item.id); + this.names = selection.map((item) => item.name); + this.single = selection.length !== 1; + this.multiple = !selection.length; + }, + /** 选择用户操作 */ + handleSelect() { + const id = this.ids[0]; + const name = this.names[0]; + this.cancel(); + this.$emit('dealCustomerId', id, name); + }, + + }, +}; +</script> diff --git a/stdiet-ui/src/components/FileDownload/MuchFileDown.vue b/stdiet-ui/src/components/FileDownload/MuchFileDown.vue new file mode 100644 index 000000000..f677b5a4f --- /dev/null +++ b/stdiet-ui/src/components/FileDownload/MuchFileDown.vue @@ -0,0 +1,73 @@ +<template> + <!-- 多文件下载对话框 --> + <el-dialog :title="title" :visible.sync="open" @closed="cancel" width="600px" append-to-body> + <div class="app-container"> + + <el-table v-loading="loading" :data="fileList"> + <el-table-column label="文件名" align="center" prop="fileName" /> + <el-table-column label="上传时间" align="center" prop="createTime" /> + <el-table-column label="操作" align="center" class-name="small-padding fixed-width"> + <template slot-scope="scope"> + <el-button + size="mini" + type="text" + icon="el-icon-download" + @click="" + >下载</el-button> + </template> + </el-table-column> + </el-table> + + </div> + <div slot="footer" class="dialog-footer"> + <el-button @click="cancel">取 消</el-button> + </div> + </el-dialog> +</template> + +<script> +import { downCaseFile } from "@/api/custom/customerCase"; + +export default { + name: "MuchFileDown", + components: { + + }, + data() { + return { + // 遮罩层 + loading: true, + // 弹出层标题 + title: "", + // 是否显示弹出层 + open: false, + //案例id + caseId: null, + //文件列表 + fileList: [] + }; + }, + created() { + + }, + computed: { + }, + methods: { + showDialog(title, fileList) { + this.title = title ? title : "文件列表"; + this.fileList = fileList; + this.loading = false; + this.open = true; + }, + // 取消按钮 + cancel() { + this.open = false; + this.caseId = null; + this.fileList = []; + }, + downloadFile(file){ + downCaseFile(file); + } + }, +}; +</script> diff --git a/stdiet-ui/src/components/FileUpload/DragUpload.vue b/stdiet-ui/src/components/FileUpload/DragUpload.vue new file mode 100644 index 000000000..6ce5494b8 --- /dev/null +++ b/stdiet-ui/src/components/FileUpload/DragUpload.vue @@ -0,0 +1,126 @@ +<template> + <el-upload class="upload-demo" + ref="upload" + drag + :headers="upload.headers" + :action="upload.url" + :limit="upload.limit" + :disabled="upload.isUploading" + :file-list="upload.fileList" + :multiple="upload.multiple" + :on-change="handleFileChange" + :on-exceed="handleFileexceed" + :on-progress="handleFileUploadProgress" + :on-success="handleFileSuccess" + :on-error="handleFileFail" + :data="upload.data" + :auto-upload="false"> + <i class="el-icon-upload"></i> + <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div> + <div class="el-upload__tip" slot="tip">每个案例最多上传5个文件,且每个文件不超过50M</div> + </el-upload> +</template> +<script> + import { getToken } from '@/utils/auth' +export default { + name: "DragUpload", + components: { + + }, + data() { + return { + upload: { + // 是否禁用上传 + isUploading: false, + // 上传的地址 + url: process.env.VUE_APP_BASE_API + "/custom/customerCase/uploadCaseFile", + // 设置上传的请求头部 + headers: {Authorization: 'Bearer ' + getToken()}, + // 其他需要携带的数据 + data:{}, + //文件列表 + fileList:[], + //同时上传文件上限 + limit: 5, + //每个文件大小 + fileSize: 1024 * 1024 * 50, + //是否支持同时选择多张 + multiple: true + }, + uploadResult:{ + fileUrl:[], + fileName:[] + } + }; + }, + methods: { + uploadFile(){ + if(this.upload.fileList.length > 0 && this.uploadResult.fileUrl.length != this.upload.fileList.length){ + this.$refs.upload.submit(); + }else{ + this.$emit('callbackMethod', this.uploadResult); + } + }, + uploadReset(){ + this.upload.fileList = []; + this.uploadResult["fileUrl"] = []; + this.uploadResult["fileName"] = []; + }, + //监控上传文件列表 + handleFileChange(file, fileList) { + let sizeFlag = file.size > this.upload.fileSize; + if (sizeFlag) { + this.$message({ + message: "当前文件过大", + type: "warning", + }); + fileList.pop(); + } + this.upload.fileList = fileList; + }, + // 文件数量超过限度 + handleFileexceed(file, fileList){ + this.$message({ + message: "最多可上传"+ this.upload.limit +"份文件", + type: "warning", + }); + }, + // 文件上传中处理 + handleFileUploadProgress(event, file, fileList) { + //this.upload.isUploading = true; + }, + // 文件上传成功处理 + handleFileSuccess(response, file, fileList) { + if(response != null && response.code === 200){ + this.uploadResult.fileUrl.push(response.fileUrl); + this.uploadResult.fileName.push(response.fileName); + if(this.uploadResult.fileUrl.length === this.upload.fileList.length){ + //文件全部上传成功,则调用回调方法 + this.$emit('callbackMethod', this.uploadResult); + } + }else{ + this.upload.fileList = fileList.pop(); + this.$message.error('文件上传失败,请检查文件格式'); + } + }, + // 文件上传失败处理 + handleFileFail(err, file, fileList){ + this.$message.error('文件上传失败,请检查文件格式'); + this.upload.fileList = fileList.pop(); + } + }, + props: { + }, + created() { + + }, + +}; +</script> + +<style scoped> + + + +</style> + diff --git a/stdiet-ui/src/views/custom/customerCase/index.vue b/stdiet-ui/src/views/custom/customerCase/index.vue new file mode 100644 index 000000000..05805f672 --- /dev/null +++ b/stdiet-ui/src/views/custom/customerCase/index.vue @@ -0,0 +1,381 @@ +<template> + <div class="app-container"> + <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px"> + <el-form-item label="案例信息" prop="name"> + <el-input + v-model.trim="queryParams.name" + placeholder="请输入案例名称或关键字" + clearable + size="small" + /> + </el-form-item> + <el-form-item label="客户姓名" prop="customerName"> + <el-input + v-model.trim="queryParams.customerName" + placeholder="请输入客户姓名" + clearable + size="small" + /> + </el-form-item> + <el-form-item> + <el-button type="cyan" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button> + <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button> + </el-form-item> + </el-form> + + <el-row :gutter="10" class="mb8"> + <el-col :span="1.5"> + <el-button + type="primary" + icon="el-icon-plus" + size="mini" + @click="handleAdd" + v-hasPermi="['custom:customerCase:add']" + >新增</el-button> + </el-col> + <el-col :span="1.5"> + <el-button + type="success" + icon="el-icon-edit" + size="mini" + :disabled="single" + @click="handleUpdate" + v-hasPermi="['custom:customerCase:edit']" + >修改</el-button> + </el-col> + <el-col :span="1.5"> + <el-button + type="danger" + icon="el-icon-delete" + size="mini" + :disabled="multiple" + @click="handleDelete" + v-hasPermi="['custom:customerCase:remove']" + >删除</el-button> + </el-col> + <el-col :span="1.5"> + <el-button + type="warning" + icon="el-icon-download" + size="mini" + @click="handleExport" + v-hasPermi="['custom:customerCase:export']" + >导出</el-button> + </el-col> + <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar> + </el-row> + + <el-table v-loading="loading" :data="customerCaseList" @selection-change="handleSelectionChange"> + <el-table-column type="selection" width="55" align="center" /> + <el-table-column label="案例名称" align="center" prop="name" /> + <el-table-column label="关键词" align="center" prop="keyword" /> + <el-table-column label="备注" align="center" prop="remark" /> + <el-table-column label="所属客户" align="center" prop="customerName" /> + <el-table-column + label="文件" + align="center" + > + <template slot-scope="scope"> + <el-button + size="mini" + type="text" + @click="getFileListByCaseId(scope.row)" + >文件列表 + </el-button> + </template> + </el-table-column> + <el-table-column + label="创建时间" + align="center" + prop="createTime" + width="160" + > + <template slot-scope="scope"> + <span>{{ + parseTime(scope.row.createTime, "{y}-{m}-{d} {h}:{i}") + }}</span> + </template> + </el-table-column> + <el-table-column label="操作" align="center" class-name="small-padding fixed-width"> + <template slot-scope="scope"> + <el-button + size="mini" + type="text" + icon="el-icon-edit" + @click="handleUpdate(scope.row)" + v-hasPermi="['custom:customerCase:edit']" + >修改</el-button> + <el-button + size="mini" + type="text" + icon="el-icon-delete" + @click="handleDelete(scope.row)" + v-hasPermi="['custom:customerCase:remove']" + >删除</el-button> + </template> + </el-table-column> + </el-table> + + <pagination + v-show="total>0" + :total="total" + :page.sync="queryParams.pageNum" + :limit.sync="queryParams.pageSize" + @pagination="getList" + /> + + <!-- 添加或修改客户案例管理对话框 --> + <el-dialog :title="title" :visible.sync="open" @closed="cancel" width="500px" append-to-body> + <el-form ref="form" :model="form" :rules="rules" label-width="80px"> + <el-form-item label="案例名称" prop="name"> + <el-input v-model.trim="form.name" type="textarea" maxlength="50" rows = "1" show-word-limit placeholder="请输入案例名称" /> + </el-form-item> + <el-form-item label="关键词" prop="keywordArray"> + <el-select + v-model="form.keywordArray" + multiple + filterable + allow-create + default-first-option + placeholder="请创建案例关键词,按回车创建,最多20个" style="width: 100%;"> + </el-select> + </el-form-item> + <el-form-item label="案例备注" prop="remark"> + <el-input + type="textarea" + placeholder="请输入案例备注" + v-model.trim="form.remark" + maxlength="200" + rows = "4" + show-word-limit + ></el-input> + </el-form-item> + + <el-form-item label="所属客户" prop="customerId"> + <el-input v-model="form.customerName" placeholder="" style="width: 60%" :readonly="true" /> + <span style="margin-left: 10px"> <el-button type="primary" @click="selectCustomer">选择所属客户</el-button></span> + </el-form-item> + <el-form-item label="案例文件" prop="file" v-show="form.id == null || form.id <= 0"> + <DragUpload @callbackMethod="addCustomerCase" ref="uploadCaseFile"></DragUpload> + </el-form-item> + + </el-form> + <div slot="footer" class="dialog-footer"> + <el-button type="primary" @click="submitForm">确 定</el-button> + <el-button @click="cancel">取 消</el-button> + </div> + </el-dialog> + + <MuchFileDown ref="muchFileDownRef"></MuchFileDown> + <SelectCustomer @dealCustomerId="dealCustomerId" ref="selectCustomerRef"></SelectCustomer> + </div> +</template> + +<script> + import { listCustomerCase, getCustomerCase, delCustomerCase, addCustomerCase, updateCustomerCase, exportCustomerCase,getFileListByCaseId,downCaseFile } from "@/api/custom/customerCase"; + import DragUpload from "@/components/FileUpload/DragUpload"; + import SelectCustomer from "@/components/Customer/SelectCustomer"; + import MuchFileDown from "@/components/FileDownload/MuchFileDown"; + export default { + name: "CustomerCase", + data() { + return { + // 遮罩层 + loading: true, + // 选中数组 + ids: [], + // 非单个禁用 + single: true, + // 非多个禁用 + multiple: true, + // 显示搜索条件 + showSearch: true, + // 总条数 + total: 0, + // 客户案例管理表格数据 + customerCaseList: [], + // 弹出层标题 + title: "", + // 是否显示弹出层 + open: false, + // 查询参数 + queryParams: { + pageNum: 1, + pageSize: 10, + name: null, + customerName: null + }, + // 表单参数 + form: { + + }, + // 表单校验 + rules: { + name: [ + { required: true, message: "案例名称不能为空", trigger: "blur" }, + ], + keywordArray: [ + { required: true, message: "案例关键词不能为空", trigger: "blur" }, + ], + } + }; + }, + components: { + "DragUpload": DragUpload, + "SelectCustomer":SelectCustomer, + "MuchFileDown": MuchFileDown + }, + created() { + this.getList(); + }, + methods: { + /** 查询客户案例管理列表 */ + getList() { + this.loading = true; + listCustomerCase(this.queryParams).then(response => { + this.customerCaseList = response.rows; + this.total = response.total; + this.loading = false; + }); + }, + // 取消按钮 + cancel() { + this.open = false; + this.$refs["uploadCaseFile"].uploadReset(); + this.reset(); + }, + // 表单重置 + reset() { + this.form = { + id: null, + name: null, + keywordArray: null, + remark: null, + customerId: null, + customerName: null, + caseFileUrl: [], + caseFileName: [] + }; + this.resetForm("form"); + }, + /** 搜索按钮操作 */ + handleQuery() { + this.queryParams.pageNum = 1; + this.getList(); + }, + /** 重置按钮操作 */ + resetQuery() { + this.resetForm("queryForm"); + this.handleQuery(); + }, + // 多选框选中数据 + handleSelectionChange(selection) { + this.ids = selection.map(item => item.id) + this.single = selection.length!==1 + this.multiple = !selection.length + }, + /** 新增按钮操作 */ + handleAdd() { + this.reset(); + this.open = true; + this.title = "添加客户案例管理"; + }, + /** 修改按钮操作 */ + handleUpdate(row) { + this.reset(); + const id = row.id || this.ids + getCustomerCase(id).then(response => { + this.form = { + id: response.data.id, + name: response.data.name, + keywordArray: response.data.keyword.split(","), + remark: response.data.remark, + customerId: response.data.customerId, + customerName: response.data.customerName, + caseFileUrl: [], + caseFileName: [] + }; + this.open = true; + this.title = "修改客户案例管理"; + }); + }, + /** 提交按钮 */ + submitForm() { + this.$refs["form"].validate(valid => { + if (valid) { + this.form.keyword = this.form.keywordArray.join(","); + if (this.form.id != null) { + updateCustomerCase(this.form).then(response => { + if (response.code === 200) { + this.msgSuccess("修改成功"); + this.open = false; + this.getList(); + } + }); + } else { + this.$refs["uploadCaseFile"].uploadFile(); + } + } + }); + }, + addCustomerCase(fileResult){ + this.form.caseFileName = fileResult.fileName; + this.form.caseFileUrl = fileResult.fileUrl; + if(this.form.caseFileUrl.length == 0){ + this.$message.error('请至少选择一个文件上传'); + return; + } + addCustomerCase(this.form).then(response => { + if (response.code === 200) { + this.msgSuccess("新增成功"); + this.open = false; + this.$refs["uploadCaseFile"].uploadReset(); + this.getList(); + } + }); + }, + selectCustomer(){ + this.$refs['selectCustomerRef'].showDialog("选择案例所属客户"); + }, + dealCustomerId(customerId, customerName){ + //console.log(customerId); + this.form.customerId = customerId; + this.form.customerName = customerName; + }, + getFileListByCaseId(customerCase){ + getFileListByCaseId(customerCase.id).then(response => { + if (response.code === 200) { + this.$refs["muchFileDownRef"].showDialog(null, response.rows); + } + }); + }, + /** 删除按钮操作 */ + handleDelete(row) { + const ids = row.id || this.ids; + this.$confirm('是否确认删除客户案例管理编号为"' + ids + '"的数据项?', "警告", { + confirmButtonText: "确定", + cancelButtonText: "取消", + type: "warning" + }).then(function() { + return delCustomerCase(ids); + }).then(() => { + this.getList(); + this.msgSuccess("删除成功"); + }).catch(function() {}); + }, + /** 导出按钮操作 */ + handleExport() { + const queryParams = this.queryParams; + this.$confirm('是否确认导出所有客户案例管理数据项?', "警告", { + confirmButtonText: "确定", + cancelButtonText: "取消", + type: "warning" + }).then(function() { + return exportCustomerCase(queryParams); + }).then(response => { + this.download(response.msg); + }).catch(function() {}); + } + } + }; +</script>