Commit ee907e37 by 李小龙

通用接口

parent deca68c1
Showing with 987 additions and 37 deletions
...@@ -22,10 +22,10 @@ import java.util.Arrays; ...@@ -22,10 +22,10 @@ import java.util.Arrays;
*/ */
@Configuration @Configuration
@Conditional(BizCondition.class) @Conditional(BizCondition.class)
public class SwaggerFixtureConfig { public class SwaggerSaasConfig {
@Bean @Bean
public SwaggerModuleConfig fixtureModule() { public SwaggerModuleConfig saasModule() {
SwaggerModuleConfig config = new SwaggerModuleConfig(); SwaggerModuleConfig config = new SwaggerModuleConfig();
config.setPackageList(Arrays.asList("com.makeit.controller")); config.setPackageList(Arrays.asList("com.makeit.controller"));
config.setModuleName("saas管理"); config.setModuleName("saas管理");
...@@ -34,7 +34,7 @@ public class SwaggerFixtureConfig { ...@@ -34,7 +34,7 @@ public class SwaggerFixtureConfig {
@Bean @Bean
public Docket fixtureApi() { public Docket saasApi() {
Docket docket = new Docket(DocumentationType.SWAGGER_2) Docket docket = new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo()) .apiInfo(apiInfo())
......
...@@ -43,7 +43,8 @@ public class SaasUserController { ...@@ -43,7 +43,8 @@ public class SaasUserController {
@ApiOperation("分页列表") @ApiOperation("分页列表")
@PostMapping("page") @PostMapping("page")
public ApiResponseEntity<PageVO<SaasUserDTOVO>> page(@RequestBody PageReqDTO<PlatUserQueryDTO> page){ public ApiResponseEntity<PageVO<SaasUserDTOVO>> page(@RequestBody PageReqDTO<PlatUserQueryDTO> page){
return ApiResponseUtils.success(saasUserService.page(page)); //return ApiResponseUtils.success(saasUserService.page(page));
return ApiResponseUtils.success(null);
} }
@ApiOperation("分页列表") @ApiOperation("分页列表")
......
package com.makeit.controller.sys;
import com.makeit.utils.old.DateUtils;
import com.makeit.utils.old.StringUtils;
import com.makeit.utils.storage.AccessoryRepository;
import com.makeit.utils.storage.LocalRepository;
import com.makeit.utils.storage.StorageProperty;
import org.springframework.beans.factory.annotation.Autowired;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
/**
* @author liuhb
* @date 2021/12/14
*/
@SuppressWarnings("ALL")
public abstract class BaseController {
private static String HOST = null;
public static final String OSS = "1";
@Autowired
StorageProperty storageProperty;
@Autowired
protected HttpServletRequest req;
@Autowired
public AccessoryRepository accessoryRepository;
// @Autowired
public LocalRepository localRepository;
public static final String FILE_PATH = "${basePath}/${yyyyMM}/${day}/${fileName}.${type}";
/**
* 获取存储类型
*
* @param type 0 本地 1 oss
* @return
*/
public AccessoryRepository storageRepository(String type) {
// if (StringUtils.equals(OSS, type) && accessoryRepository.isValid()) {
// return accessoryRepository;
// }
// return localRepository;
if (StringUtils.equals(OSS, type)) {
return accessoryRepository;
}
return localRepository;
}
/**
* 获取实际ip地址
*
* @param req
* @return
*/
public String getIp(HttpServletRequest req) {
try {
String ip = req.getHeader("X-Forwarded-For");
if (StringUtils.isNotEmpty(ip) && !"unKnown".equalsIgnoreCase(ip)) {
//多次反向代理后会有多个ip值,第一个ip才是真实ip
int index = ip.indexOf(",");
if (index != -1) {
return ip.substring(0, index);
} else {
return ip;
}
}
ip = req.getHeader("X-Real-IP");
if (StringUtils.isNotEmpty(ip) && !"unKnown".equalsIgnoreCase(ip)) {
return ip;
}
return req.getRemoteAddr();
} catch (Exception e) {
}
return null;
}
/**
* 获取全路径
*
* @param url
* @return
*/
public String getUri(String url) {
// if (url == null) {
// return null;
// }
// if (url.toLowerCase().contains("http")) {
// return url;
// }
// if (StringUtils.isEmpty(HOST)) {
// HOST = getHost();
// }
// return HOST + url;
return url;
}
/**
* 获取主机地址
*
* @return
*/
private String getHost() {
String host = req.getHeader("x-forwarded-host");
String prefix = StringUtils.defaultString(req.getHeader("x-forwarded-prefix"), "");
String proto = StringUtils.defaultString(req.getHeader("x-forwarded-proto"), "");
String origin = req.getHeader("origin");
if (StringUtils.isEmpty(host) && StringUtils.isNotEmpty(req.getHeader("host"))) {
host = req.getHeader("host");
} else if (StringUtils.isNotEmpty(origin)) {
host = StringUtils.substringAfter(origin, "://");
}
if (StringUtils.isEmpty(proto)) {
proto = StringUtils.defaultString(StringUtils.substringBefore(origin, ":"), "http");
}
if (StringUtils.isEmpty(host)) {
return "";
}
Map<String, String> param = new HashMap<>(0);
param.put("proto", proto);
param.put("host", host);
param.put("prefix", prefix);
//return StringUtils.fillTemplateByEl("${proto}://${host}${prefix}/", param);
return StringUtils.fillTemplateByEl("${proto}://${host}${prefix}", param);
}
protected String getFullPath(String basePath, String originalFilename) {
basePath = StringUtils.defaultString(basePath, "");
String[] type = originalFilename.split("\\.");
Map<String, String> param = new HashMap<>();
param.put("basePath", basePath);
param.put("yyyyMM", DateUtils.formatDate(new Date(), "yyyyMM"));
param.put("day", DateUtils.formatDate(new Date(), "dd"));
param.put("fileName", UUID.randomUUID().toString().replaceAll("-", ""));
param.put("type", type[type.length - 1]);
return StringUtils.fillTemplateByEl(FILE_PATH, param);
}
}
package com.makeit.controller.sys;
import com.makeit.common.dto.BaseIdDTO;
import com.makeit.common.response.ApiResponseEntity;
import com.makeit.common.response.ApiResponseUtils;
import com.makeit.module.system.dto.SysConfigCategoryDTOVO;
import com.makeit.module.system.service.SysConfigCategoryService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@Api(tags = "配置分类")
@RestController
@RequestMapping("/sys/configCategory")
public class SysConfigCategoryController {
@Autowired
private SysConfigCategoryService sysConfigCategoryService;
@ApiOperation(value = "列表", notes = "")
@PostMapping("/list")
public ApiResponseEntity<List<SysConfigCategoryDTOVO>> list(@RequestBody SysConfigCategoryDTOVO sysConfigCategory) {
return ApiResponseUtils.success(sysConfigCategoryService.list(sysConfigCategory));
}
@ApiOperation(value = "列表(AuthIgnore)", notes = "")
@PostMapping("/listAuthIgnore")
public ApiResponseEntity<List<SysConfigCategoryDTOVO>> listAuthIgnore(@RequestBody SysConfigCategoryDTOVO sysConfigCategory) {
return ApiResponseUtils.success(sysConfigCategoryService.list(sysConfigCategory));
}
@ApiOperation(value = "新增", notes = "")
@PostMapping("/add")
public ApiResponseEntity<?> add(@Validated @RequestBody SysConfigCategoryDTOVO sysConfigCategory) {
sysConfigCategoryService.add(sysConfigCategory);
return ApiResponseUtils.success();
}
@ApiOperation(value = "编辑", notes = "")
@PostMapping("/edit")
public ApiResponseEntity<?> edit(@Validated @RequestBody SysConfigCategoryDTOVO sysConfigCategory) {
sysConfigCategoryService.edit(sysConfigCategory);
return ApiResponseUtils.success();
}
@ApiOperation(value = "详情", notes = "")
@PostMapping("/view")
public ApiResponseEntity<SysConfigCategoryDTOVO> view(@RequestBody BaseIdDTO baseIdDTO) {
return ApiResponseUtils.success(sysConfigCategoryService.view(baseIdDTO.getId()));
}
@ApiOperation(value = "删除", notes = "")
@PostMapping("/del")
public ApiResponseEntity<?> del(@RequestBody BaseIdDTO baseIdDTO) {
sysConfigCategoryService.del(baseIdDTO.getId());
return ApiResponseUtils.success();
}
}
package com.makeit.controller.sys;
import com.makeit.common.dto.BaseIdDTO;
import com.makeit.common.page.PageReqDTO;
import com.makeit.common.page.PageVO;
import com.makeit.common.response.ApiResponseEntity;
import com.makeit.common.response.ApiResponseUtils;
import com.makeit.module.system.entity.SysConfig;
import com.makeit.module.system.entity.SysConfigCategory;
import com.makeit.module.system.service.SysConfigService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@Api(tags = "配置")
@RestController
@RequestMapping("/sys/config")
public class SysConfigController {
@Autowired
private SysConfigService sysConfigService;
@ApiOperation(value = "列表", notes = "")
@PostMapping("/list")
public ApiResponseEntity<List<SysConfig>> list(@RequestBody SysConfig sysConfig) {
return ApiResponseUtils.success(sysConfigService.list(sysConfig));
}
@ApiOperation(value = "分页列表", notes = "")
@PostMapping("/page")
public ApiResponseEntity<PageVO<SysConfig>> page(@RequestBody PageReqDTO<SysConfig> page) {
return ApiResponseUtils.success(sysConfigService.page(page));
}
@ApiOperation(value = "列表(AuthIgnore)", notes = "")
@PostMapping("/listAuthIgnore")
public ApiResponseEntity<List<SysConfig>> listAuthIgnore(@RequestBody SysConfig sysConfig) {
return ApiResponseUtils.success(sysConfigService.list(sysConfig));
}
@ApiOperation(value = "分页列表(AuthIgnore)", notes = "")
@PostMapping("/pageAuthIgnore")
public ApiResponseEntity<PageVO<SysConfig>> pageAuthIgnore(@RequestBody PageReqDTO<SysConfig> page) {
return ApiResponseUtils.success(sysConfigService.page(page));
}
@ApiOperation(value = "新增", notes = "")
@PostMapping("/add")
public ApiResponseEntity<?> add(@Validated @RequestBody SysConfig sysConfig) {
sysConfigService.add(sysConfig);
return ApiResponseUtils.success();
}
@ApiOperation(value = "编辑", notes = "")
@PostMapping("/edit")
public ApiResponseEntity<?> edit(@Validated @RequestBody SysConfig sysConfig) {
sysConfigService.edit(sysConfig);
return ApiResponseUtils.success();
}
@ApiOperation(value = "详情", notes = "")
@PostMapping("/view")
public ApiResponseEntity<SysConfig> view(@RequestBody BaseIdDTO baseIdDTO) {
return ApiResponseUtils.success(sysConfigService.view(baseIdDTO.getId()));
}
@ApiOperation(value = "根据分类code获取详情", notes = "")
@PostMapping("/viewByCategoryCode")
public ApiResponseEntity<SysConfigCategory> viewByCategoryCode(@RequestBody SysConfigCategory sysConfigCategory) {
return ApiResponseUtils.success(sysConfigService.viewByCategoryCode(sysConfigCategory.getCode()));
}
@ApiOperation(value = "删除", notes = "")
@PostMapping("/del")
public ApiResponseEntity<?> del(@RequestBody BaseIdDTO baseIdDTO) {
sysConfigService.del(baseIdDTO.getId());
return ApiResponseUtils.success();
}
}
package com.makeit.controller.sys;
import com.makeit.common.dto.BaseIdDTO;
import com.makeit.common.response.ApiResponseEntity;
import com.makeit.common.response.ApiResponseUtils;
import com.makeit.module.system.entity.SysDictionaryCategory;
import com.makeit.module.system.service.SysDictionaryCategoryService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* 数据字典类型
*
*/
@Api(tags = "数据字典分类(用户不可见)")
@RestController
@RequestMapping("/sys/dictionaryCategory")
public class SysDictionaryCategoryController {
@Autowired
private SysDictionaryCategoryService dictionaryCategoryService;
@ApiOperation(value = "列表-带字典", notes = "")
@PostMapping("/getDictionaryCategoryByList")
public ApiResponseEntity<List<SysDictionaryCategory>> getDictionaryCategoryByList() {
List<SysDictionaryCategory> dictionaryCategoryList = dictionaryCategoryService.getEpDictionaryCategoryByList();
return ApiResponseUtils.success(dictionaryCategoryList);
}
@ApiOperation(value = "列表", notes = "")
@PostMapping("/list")
public ApiResponseEntity<List<SysDictionaryCategory>> list(@RequestBody SysDictionaryCategory platConfigCategory) {
return ApiResponseUtils.success(dictionaryCategoryService.list(platConfigCategory));
}
@ApiOperation(value = "新增", notes = "")
@PostMapping("/add")
public ApiResponseEntity<?> add(@Validated @RequestBody SysDictionaryCategory sysDictionaryCategory) {
return ApiResponseUtils.success(dictionaryCategoryService.add(sysDictionaryCategory));
}
@ApiOperation(value = "编辑", notes = "")
@PostMapping("/edit")
public ApiResponseEntity<?> edit(@Validated @RequestBody SysDictionaryCategory sysDictionaryCategory) {
dictionaryCategoryService.edit(sysDictionaryCategory);
return ApiResponseUtils.success();
}
@ApiOperation(value = "删除", notes = "")
@PostMapping("/del")
public ApiResponseEntity<?> del(@RequestBody BaseIdDTO baseIdDTO) {
dictionaryCategoryService.del(baseIdDTO.getId());
return ApiResponseUtils.success();
}
}
package com.makeit.controller.sys;
import com.makeit.common.dto.BaseIdDTO;
import com.makeit.common.response.ApiResponseEntity;
import com.makeit.common.response.ApiResponseUtils;
import com.makeit.module.system.entity.SysDictionary;
import com.makeit.module.system.service.SysDictionaryService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@Api(tags = "数据字典(用户不可见)")
@RestController
@RequestMapping("/sys/dictionary")
public class SysDictionaryController {
@Autowired
private SysDictionaryService sysDictionaryService;
@ApiOperation(value = "重新加载", notes = "")
@PostMapping("/reload")
public ApiResponseEntity<?> reload() {
sysDictionaryService.load();
return ApiResponseUtils.success();
}
@ApiOperation(value = "列表", notes = "")
@PostMapping("/list")
public ApiResponseEntity<List<SysDictionary>> list(@RequestBody SysDictionary sysDictionary) {
return ApiResponseUtils.success(sysDictionaryService.list(sysDictionary));
}
@ApiOperation(value = "新增", notes = "")
@PostMapping("/add")
public ApiResponseEntity<?> add(@Validated @RequestBody SysDictionary sysDictionary) {
sysDictionaryService.add(sysDictionary);
return ApiResponseUtils.success();
}
@ApiOperation(value = "编辑", notes = "")
@PostMapping("/edit")
public ApiResponseEntity<?> edit(@Validated @RequestBody SysDictionary sysDictionary) {
sysDictionaryService.edit(sysDictionary);
return ApiResponseUtils.success();
}
@ApiOperation(value = "删除", notes = "")
@PostMapping("/del")
public ApiResponseEntity<?> del(@RequestBody BaseIdDTO baseIdDTO) {
sysDictionaryService.del(baseIdDTO.getId());
return ApiResponseUtils.success();
}
}
package com.makeit.controller.sys;
import com.makeit.common.dto.BaseIdDTO;
import com.makeit.common.response.ApiResponseEntity;
import com.makeit.common.response.ApiResponseUtils;
import com.makeit.module.system.dto.SysFileDTOVO;
import com.makeit.module.system.entity.SysFile;
import com.makeit.module.system.service.SysFileService;
import com.makeit.utils.data.convert.BeanDtoVoUtils;
import com.makeit.utils.data.convert.StreamUtil;
import com.makeit.utils.storage.AccessoryRepository;
import com.makeit.utils.storage.DataWithMeta;
import com.makeit.utils.sys.FileUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.util.UriUtils;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.Arrays;
import java.util.List;
@Api(tags = "前台-系统-文件路径")
@RestController
@RequestMapping("sys/file")
public class SysFileController {
@Autowired
public AccessoryRepository accessoryRepository;
@Autowired
private SysFileService sysFileService;
@ApiOperation("获取文件临时路径路径")
@PostMapping("getFileTmp")
public ApiResponseEntity<SysFileDTOVO> getFileTmp(@RequestBody BaseIdDTO baseIdDTO) {
SysFileDTOVO sysFileDTOVO = BeanDtoVoUtils.convert(sysFileService.getById(baseIdDTO.getId()), SysFileDTOVO.class);
sysFileDTOVO.setFullUrl(accessoryRepository.getTmpURL(sysFileDTOVO.getUrl()));
return ApiResponseUtils.success(sysFileDTOVO);
}
@ApiOperation("获取文件路径")
@PostMapping("getFile")
public ApiResponseEntity<List<SysFileDTOVO>> getFile(@RequestBody BaseIdDTO baseIdDTO) {
return ApiResponseUtils.success(FileUtil.convertMultiply(Arrays.asList(baseIdDTO.getId())).get(0));
}
@ApiOperation("获取文件路径集合")
@PostMapping("getFileList")
public ApiResponseEntity<List<List<SysFileDTOVO>>> getFile(@RequestBody List<String> list) {
return ApiResponseUtils.success(FileUtil.convertMultiply(list));
}
//这种方式可以 只是不能设置下载文件名
// @ApiOperation("下载文件")
// @PostMapping("downloadFile")
// public byte[] downloadFile(@RequestBody BaseIdDTO baseIdDTO) {
// return aliyunOSSRepository.getBytes(UriUtils.decode(StringUtils.substringAfter(sysFileService.getById(baseIdDTO.getId()).getUrl(), "oss/"), "UTF-8"));
// }
void downloadFile(HttpServletResponse response, String id) throws IOException {
SysFile sysFile = sysFileService.getById(id);
response.setCharacterEncoding("UTF-8");
response.setContentType("application/octet-stream");
// 设置文件头:最后一个参数是设置下载文件名
response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(sysFile.getFileName(), "UTF-8"));
OutputStream outputStream = response.getOutputStream();
outputStream.write(accessoryRepository.getBytes(UriUtils.decode(StringUtils.substringAfter(sysFile.getUrl(), "oss/"), "UTF-8")));
}
//这样是可以
// private void previewFile(HttpServletResponse response, String id) throws IOException {
//
// SysFile sysFile = sysFileService.getById(id);
//
// response.setCharacterEncoding("UTF-8");
// response.setContentType("application/octet-stream");
// // 设置文件头:最后一个参数是设置下载文件名
// response.setHeader("Content-disposition", "inline;filename=" + URLEncoder.encode(sysFile.getFileName(), "UTF-8"));
//
// String suffix = sysFile.getUrl().substring(sysFile.getUrl().lastIndexOf("."));
//
// Map<String, String> map = new HashMap<>(16);
// map.put(".pdf", "application/pdf");
// map.put(".png", "image/png");
// map.put(".jpg", "image/jpg");
// map.put(".jpeg", "image/jpeg");
//
// String contentType = map.get(suffix);
// if (StringUtils.isNotBlank(contentType)) {
// response.setContentType(contentType);
// }
//
// OutputStream outputStream = response.getOutputStream();
// outputStream.write(aliyunOSSRepository.getBytes(UriUtils.decode(StringUtils.substringAfter(sysFile.getUrl(), "oss/"), "UTF-8")));
// outputStream.close();
// }
private void previewFile(HttpServletResponse response, String id) throws IOException {
SysFile sysFile = sysFileService.getById(id);
response.setCharacterEncoding("UTF-8");
// 设置文件头:最后一个参数是设置下载文件名
response.setHeader("Content-disposition", "inline;filename=" + URLEncoder.encode(sysFile.getFileName(), "UTF-8"));
DataWithMeta dataWithMeta = accessoryRepository.getDataWithMeta(UriUtils.decode(StringUtils.substringAfter(sysFile.getUrl(), "oss/"), "UTF-8"));
response.setContentType(dataWithMeta.getContentType());
OutputStream outputStream = response.getOutputStream();
outputStream.write(dataWithMeta.getBytes());
outputStream.close();
}
@ApiOperation("下载文件(json id)")
@RequestMapping(value = "downloadFile", method = {RequestMethod.GET, RequestMethod.POST})
public void downloadFile(HttpServletResponse response, @RequestBody BaseIdDTO baseIdDTO) throws IOException {
downloadFile(response, baseIdDTO.getId());
}
@ApiOperation("预览文件(json id)")
@RequestMapping(value = "previewFile", method = {RequestMethod.GET, RequestMethod.POST})
public void previewFile(HttpServletResponse response, @RequestBody BaseIdDTO baseIdDTO) throws IOException {
previewFile(response, baseIdDTO.getId());
}
@ApiOperation("下载文件")
@RequestMapping(value = "downloadFileParam", method = {RequestMethod.GET, RequestMethod.POST})
public void downloadFileParam(HttpServletResponse response, String id) throws IOException {
downloadFile(response, id);
}
@ApiOperation("预览文件")
@RequestMapping(value = "previewFileParam", method = {RequestMethod.GET, RequestMethod.POST})
public void previewFileParam(HttpServletResponse response, String id) throws IOException {
previewFile(response, id);
}
@ApiOperation("批量保存")
@PostMapping("addList")
public ApiResponseEntity<?> addList(@RequestBody List<SysFileDTOVO> list) {
List<SysFile> fileList = BeanDtoVoUtils.listVo(list, SysFile.class);
sysFileService.saveBatch(fileList);
return ApiResponseUtils.success(StreamUtil.map(fileList, SysFile::getId));
}
}
package com.makeit.controller.sys;
import com.makeit.common.response.ApiResponseEntity;
import com.makeit.common.response.ApiResponseUtils;
import com.makeit.module.system.dto.SysFileDTOVO;
import com.makeit.module.system.dto.UploadKeyDTO;
import com.makeit.module.system.entity.SysFile;
import com.makeit.module.system.service.SysFileService;
import com.makeit.utils.contract.word.WordConverterUtil;
import com.makeit.utils.data.convert.BeanDtoVoUtils;
import com.makeit.utils.data.convert.StreamUtil;
import com.makeit.utils.storage.HwObsRepository;
import com.makeit.utils.storage.PostSignature;
import com.makeit.utils.sys.FileUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StopWatch;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
/**
* @author liuhb
* @date 2021/12/14
*/
@Api(tags = "系统-文件上传")
@RestController
@RequestMapping("storage")
public class UploadController extends BaseController {
@Autowired
private SysFileService sysFileService;
private static final Logger logger = LoggerFactory.getLogger(UploadController.class);
// @ApiOperation(value = "获取key")
// @PostMapping("getKey")
// public String getKey(@ApiParam(value = "originalFilename") String originalFilename) {
// String fullPath = getFullPath(null, originalFilename);
// return getUri(accessoryRepository.getKey(fullPath));
// }
@ApiOperation(value = "获取key")
@PostMapping("getKey")
public SysFileDTOVO getKey(@RequestBody UploadKeyDTO dto) {
SysFileDTOVO sysFile = new SysFileDTOVO();
sysFile.setFileName(dto.getOriginalFilename());
String fullPath = getFullPath(null, dto.getOriginalFilename());
sysFile.setUrl(getUri(HwObsRepository.APIURI + accessoryRepository.getKey(fullPath)));
sysFile.setKey(accessoryRepository.getKey(fullPath));
return sysFile;
}
@ApiOperation(value = "获取签名")
@PostMapping("getSignature")
public PostSignature getPostSignature() {
return accessoryRepository.getPostSignature();
}
private String replaceSuffix(String name) {
int index = name.lastIndexOf(".");
return name.substring(0, index) + ".pdf";
}
private List<SysFile> uploadInternal(List<MultipartFile> files, String convertToPdf) {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
List<SysFile> sysFileList = StreamUtil.map(files, e -> {
try {
SysFile sysFile = new SysFile();
sysFile.setFileName(e.getOriginalFilename());
String fullPath = getFullPath(null, e.getOriginalFilename());
sysFile.setUrl(getUri(storageRepository("1").save(e.getBytes(), fullPath)));
if ("1".equals(convertToPdf)) {
fullPath = getFullPath(null, replaceSuffix(e.getOriginalFilename()));
sysFile.setPdfUrl(getUri(storageRepository("1").save(WordConverterUtil.convert(e.getInputStream()), fullPath)));
}
sysFile.setMime(e.getContentType());
return sysFile;
} catch (IOException ex) {
throw new RuntimeException(ex);
}
});
sysFileService.saveBatch(sysFileList);
stopWatch.stop();
logger.info("文件上传耗时:{} ms", stopWatch.getLastTaskTimeMillis());
return sysFileList;
}
private List<SysFile> convertAndUploadInternal(List<MultipartFile> files) {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
List<SysFile> sysFileList = StreamUtil.map(files, e -> {
try {
SysFile sysFile = new SysFile();
sysFile.setFileName(replaceSuffix(e.getOriginalFilename()));
String fullPath = getFullPath(null, replaceSuffix(e.getOriginalFilename()));
sysFile.setUrl(getUri(storageRepository("1").save(WordConverterUtil.convert(e.getInputStream()), fullPath)));
sysFile.setMime(e.getContentType());
return sysFile;
} catch (IOException ex) {
throw new RuntimeException(ex);
}
});
sysFileService.saveBatch(sysFileList);
stopWatch.stop();
logger.info("文件上传耗时:{} ms", stopWatch.getLastTaskTimeMillis());
return sysFileList;
}
@ApiOperation(value = "统一文件上传")
@PostMapping("uploadFile")
public ApiResponseEntity<List<String>> uploadFile(
@ApiParam(value = "convertToPdf") @RequestParam(defaultValue = "0") String convertToPdf,
@ApiParam(value = "files") List<MultipartFile> files) {
List<SysFile> sysFileList = uploadInternal(files, convertToPdf);
return ApiResponseUtils.success(StreamUtil.map(sysFileList, SysFile::getId));
}
@ApiOperation(value = "统一文件上传返回路径")
@PostMapping("uploadFileUrl")
public ApiResponseEntity<List<SysFileDTOVO>> uploadFileUrl(
@ApiParam(value = "convertToPdf") @RequestParam(defaultValue = "0") String convertToPdf,
@ApiParam(value = "files") List<MultipartFile> files) {
List<SysFile> sysFileList = uploadInternal(files, convertToPdf);
List<SysFileDTOVO> voList = BeanDtoVoUtils.listVo(sysFileList, SysFileDTOVO.class);
FileUtil.fillFullUrl(voList);
FileUtil.fillPdfFullUrl(voList);
return ApiResponseUtils.success(voList);
}
@ApiOperation(value = "统一转换为pdf后上传")
@PostMapping("convertAndUploadFile")
public ApiResponseEntity<List<String>> convertAndUploadFile(
@ApiParam(value = "files") List<MultipartFile> files) {
List<SysFile> sysFileList = convertAndUploadInternal(files);
return ApiResponseUtils.success(StreamUtil.map(sysFileList, SysFile::getId));
}
@ApiOperation(value = "统一转换为pdf后上传返回路径")
@PostMapping("convertAndUploadFileUrl")
public ApiResponseEntity<List<SysFileDTOVO>> convertAndUploadFileUrl(
@ApiParam(value = "files") List<MultipartFile> files) {
List<SysFile> sysFileList = convertAndUploadInternal(files);
List<SysFileDTOVO> voList = BeanDtoVoUtils.listVo(sysFileList, SysFileDTOVO.class);
FileUtil.fillFullUrl(voList);
//FileUtil.fillPdfFullUrl(voList);
return ApiResponseUtils.success(voList);
}
//下面两个的作用
//返回给前端的路径 要基于下面两个转发
@ApiOperation("获取oss文件")
@RequestMapping(value = "oss/**", method = RequestMethod.GET)
public void getOssFile(HttpServletRequest req, HttpServletResponse resp) throws Exception {
// String filepath = req.getRequestURI();
// filepath = UriUtils.decode(StringUtils.substringAfter(filepath, "oss"), "UTF-8");
// //.toString().split("\\?")[0];
// resp.sendRedirect(accessoryRepository.getPermanentURL(filepath));
resp.sendRedirect(accessoryRepository.getPermanentURL(req.getRequestURI()));
}
@ApiOperation("获取oss文件(临时路径)")
@RequestMapping(value = "tmp/oss/**", method = RequestMethod.GET)
public void getOssFileTmpPath(HttpServletRequest req, HttpServletResponse resp) throws Exception {
// String filepath = req.getRequestURI();
// filepath = UriUtils.decode(StringUtils.substringAfter(filepath, "tmp/oss"), "UTF-8");
// //.toString().split("\\?")[0];
// resp.sendRedirect(accessoryRepository.getTmpURL(filepath));
resp.sendRedirect(accessoryRepository.getTmpURL(req.getRequestURI()));
}
//private String name;
// private String nameOrigin;
// private String extName;
// private Long fileSize;
// private String storeType;//video audio img pdf等
// private String relativePath;
}
package com.makeit.utils.contract.word;
import com.makeit.utils.ThreadUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.UUID;
@Component
public class WordConverterUtil {
private static final Logger logger = LoggerFactory.getLogger(WordConverterUtil.class);
private static String libreOffice;
public static byte[] convert(byte[] bytes) {
return convert(new ByteArrayInputStream(bytes));
}
public static byte[] convert(InputStream inputStream) {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
try {
File projectPath = PathUtil.userDirPath();
String tmpName = UUID.randomUUID().toString().replaceAll("-", "");
File wordFile = new File(projectPath, tmpName + ".docx");
File pdfFile = new File(projectPath, tmpName + ".pdf");
try (FileOutputStream fileOutputStream = new FileOutputStream(wordFile)) {
byte[] b = new byte[1024];
int i = inputStream.read(b);
while (i != -1) {
fileOutputStream.write(b, 0, i);
i = inputStream.read(b);
}
}
convert(wordFile.getAbsolutePath(), projectPath.getAbsolutePath());
byte[] bytes;
try (FileInputStream fileInputStream = new FileInputStream(pdfFile);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) {
byte[] b = new byte[1024];
int i = fileInputStream.read(b);
while (i != -1) {
byteArrayOutputStream.write(b, 0, i);
i = fileInputStream.read(b);
}
bytes = byteArrayOutputStream.toByteArray();
}
// wordFile.delete();
// pdfFile.delete();
ThreadUtil.run(wordFile::delete);
ThreadUtil.run(pdfFile::delete);
return bytes;
} catch (Exception ex) {
throw new RuntimeException(ex);
}finally {
stopWatch.stop();
logger.info("word转换成pdf 耗时:{} ms", stopWatch.getLastTaskTimeMillis());
}
}
public static void convert(String libreOffice, String inputFile, String outDir) {
long start = System.currentTimeMillis();
String command = "";
String osName = System.getProperty("os.name");
command = libreOffice + " --headless --invisible --convert-to pdf:writer_pdf_Export " + inputFile + " --outdir " + outDir;
exec(command);
long end = System.currentTimeMillis();
logger.info("用时:{} ms", end - start);
}
public static void convert(String inputFile, String outDir) {
//convert("C:\\Program Files\\LibreOffice\\program\\soffice",inputFile,outDir);
convert(libreOffice, inputFile, outDir);
}
private static boolean exec(String command) {
Process process;// Process可以控制该子进程的执行或获取该子进程的信息
try {
logger.info("exec cmd : {}", command);
process = Runtime.getRuntime().exec(command);// exec()方法指示Java虚拟机创建一个子进程执行指定的可执行程序,并返回与该子进程对应的Process对象实例。
} catch (IOException e) {
logger.error(" exec {} error", command, e);
return false;
}
int exitStatus = 0;
try {
exitStatus = process.waitFor();// 等待子进程完成再往下执行,返回值是子线程执行完毕的返回值,返回0表示正常结束
// 第二种接受返回值的方法
int i = process.exitValue(); // 接收执行完毕的返回值
logger.info("i----" + i);
} catch (InterruptedException e) {
logger.error("InterruptedException exec {}", command, e);
return false;
}
if (exitStatus != 0) {
logger.error("exec cmd exitStatus {}", exitStatus);
} else {
logger.info("exec cmd exitStatus {}", exitStatus);
}
process.destroy(); // 销毁子进程
process = null;
return true;
}
@Value("${libreOffice}")
public void setLibreOffice(String libreOffice) {
WordConverterUtil.libreOffice = libreOffice;
}
}
...@@ -10,7 +10,7 @@ import lombok.Data; ...@@ -10,7 +10,7 @@ import lombok.Data;
*/ */
@TableName(value ="tnt_auth_menu") @TableName(value ="tnt_auth_menu")
@Data @Data
public class TntAuthMenu extends BaseEntity { public class PlatAuthMenu extends BaseEntity {
/** /**
* 父级id * 父级id
......
...@@ -12,7 +12,7 @@ import java.util.Date; ...@@ -12,7 +12,7 @@ import java.util.Date;
*/ */
@TableName(value ="tnt_tenant") @TableName(value ="tnt_tenant")
@Data @Data
public class TntTenant extends BaseEntity { public class PlatTenant extends BaseEntity {
/** /**
* 名称 * 名称
......
package com.makeit.mapper.saas; package com.makeit.mapper.saas;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.makeit.entity.saas.TntAuthMenu; import com.makeit.entity.saas.PlatAuthMenu;
/** /**
* @author lixl * @author lixl
...@@ -9,7 +9,7 @@ import com.makeit.entity.saas.TntAuthMenu; ...@@ -9,7 +9,7 @@ import com.makeit.entity.saas.TntAuthMenu;
* @createDate 2023-08-29 14:29:10 * @createDate 2023-08-29 14:29:10
* @Entity com.makeit.entity.saas.TntAuthMenu * @Entity com.makeit.entity.saas.TntAuthMenu
*/ */
public interface TntAuthMenuMapper extends BaseMapper<TntAuthMenu> { public interface PlatAuthMenuMapper extends BaseMapper<PlatAuthMenu> {
} }
package com.makeit.mapper.saas; package com.makeit.mapper.saas;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.makeit.entity.saas.TntTenant; import com.makeit.entity.saas.PlatTenant;
/** /**
* @author lixl * @author lixl
...@@ -9,7 +9,7 @@ import com.makeit.entity.saas.TntTenant; ...@@ -9,7 +9,7 @@ import com.makeit.entity.saas.TntTenant;
* @createDate 2023-08-29 14:29:10 * @createDate 2023-08-29 14:29:10
* @Entity com.makeit.entity.saas.TntTenant * @Entity com.makeit.entity.saas.TntTenant
*/ */
public interface TntTenantMapper extends BaseMapper<TntTenant> { public interface PlatTenantMapper extends BaseMapper<PlatTenant> {
} }
package com.makeit.service.saas; package com.makeit.service.saas;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
import com.makeit.entity.saas.TntAuthMenu; import com.makeit.entity.saas.PlatAuthMenu;
/** /**
* @author lixl * @author lixl
* @description 针对表【tnt_auth_menu(租户端资源管理)】的数据库操作Service * @description 针对表【tnt_auth_menu(租户端资源管理)】的数据库操作Service
* @createDate 2023-08-29 14:29:10 * @createDate 2023-08-29 14:29:10
*/ */
public interface TntAuthMenuService extends IService<TntAuthMenu> { public interface PlatAuthMenuService extends IService<PlatAuthMenu> {
} }
package com.makeit.service.saas; package com.makeit.service.saas;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
import com.makeit.entity.saas.TntTenant; import com.makeit.entity.saas.PlatTenant;
/** /**
* @author lixl * @author lixl
* @description 针对表【tnt_tenant(租户管理)】的数据库操作Service * @description 针对表【tnt_tenant(租户管理)】的数据库操作Service
* @createDate 2023-08-29 14:29:10 * @createDate 2023-08-29 14:29:10
*/ */
public interface TntTenantService extends IService<TntTenant> { public interface PlatTenantService extends IService<PlatTenant> {
} }
package com.makeit.service.saas.impl; package com.makeit.service.saas.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.makeit.entity.saas.TntAuthMenu; import com.makeit.entity.saas.PlatAuthMenu;
import com.makeit.mapper.saas.TntAuthMenuMapper; import com.makeit.mapper.saas.PlatAuthMenuMapper;
import com.makeit.service.saas.TntAuthMenuService; import com.makeit.service.saas.PlatAuthMenuService;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
/** /**
...@@ -12,7 +12,7 @@ import org.springframework.stereotype.Service; ...@@ -12,7 +12,7 @@ import org.springframework.stereotype.Service;
* @createDate 2023-08-29 14:29:10 * @createDate 2023-08-29 14:29:10
*/ */
@Service @Service
public class TntAuthMenuServiceImpl extends ServiceImpl<TntAuthMenuMapper, TntAuthMenu> public class PlatAuthMenuServiceImpl extends ServiceImpl<PlatAuthMenuMapper, PlatAuthMenu>
implements TntAuthMenuService{ implements PlatAuthMenuService {
} }
package com.makeit.service.saas.impl; package com.makeit.service.saas.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.makeit.entity.saas.TntTenant; import com.makeit.entity.saas.PlatTenant;
import com.makeit.mapper.saas.TntTenantMapper; import com.makeit.mapper.saas.PlatTenantMapper;
import com.makeit.service.saas.TntTenantService; import com.makeit.service.saas.PlatTenantService;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
/** /**
...@@ -12,7 +12,7 @@ import org.springframework.stereotype.Service; ...@@ -12,7 +12,7 @@ import org.springframework.stereotype.Service;
* @createDate 2023-08-29 14:29:10 * @createDate 2023-08-29 14:29:10
*/ */
@Service @Service
public class TntTenantServiceImpl extends ServiceImpl<TntTenantMapper, TntTenant> public class PlatTenantServiceImpl extends ServiceImpl<PlatTenantMapper, PlatTenant>
implements TntTenantService{ implements PlatTenantService {
} }
...@@ -13,7 +13,7 @@ import com.makeit.entity.saas.SaasRole; ...@@ -13,7 +13,7 @@ import com.makeit.entity.saas.SaasRole;
import com.makeit.entity.saas.SaasRoleMenu; import com.makeit.entity.saas.SaasRoleMenu;
import com.makeit.entity.saas.SaasUser; import com.makeit.entity.saas.SaasUser;
import com.makeit.entity.saas.SaasUserRole; import com.makeit.entity.saas.SaasUserRole;
import com.makeit.entity.saas.TntTenant; import com.makeit.entity.saas.PlatTenant;
import com.makeit.enums.CodeMessageEnum; import com.makeit.enums.CodeMessageEnum;
import com.makeit.enums.CommonEnum; import com.makeit.enums.CommonEnum;
import com.makeit.enums.biz.auth.SysEnum; import com.makeit.enums.biz.auth.SysEnum;
...@@ -31,7 +31,7 @@ import com.makeit.service.saas.SaasRoleMenuService; ...@@ -31,7 +31,7 @@ import com.makeit.service.saas.SaasRoleMenuService;
import com.makeit.service.saas.SaasRoleService; import com.makeit.service.saas.SaasRoleService;
import com.makeit.service.saas.SaasUserRoleService; import com.makeit.service.saas.SaasUserRoleService;
import com.makeit.service.saas.SaasUserService; import com.makeit.service.saas.SaasUserService;
import com.makeit.service.saas.TntTenantService; import com.makeit.service.saas.PlatTenantService;
import com.makeit.utils.data.convert.BeanDtoVoUtils; import com.makeit.utils.data.convert.BeanDtoVoUtils;
import com.makeit.utils.data.convert.PageUtil; import com.makeit.utils.data.convert.PageUtil;
import com.makeit.utils.data.convert.StreamUtil; import com.makeit.utils.data.convert.StreamUtil;
...@@ -75,7 +75,7 @@ implements SaasUserService{ ...@@ -75,7 +75,7 @@ implements SaasUserService{
private SaasRoleMenuService saasRoleMenuService; private SaasRoleMenuService saasRoleMenuService;
@Autowired @Autowired
private TntTenantService tntTenantService; private PlatTenantService platTenantService;
// @Autowired // @Autowired
// private TntLoginLogService tntLoginLogService; // private TntLoginLogService tntLoginLogService;
...@@ -464,7 +464,7 @@ implements SaasUserService{ ...@@ -464,7 +464,7 @@ implements SaasUserService{
PlatUserVO userVO = PlatUserUtil.getUserVO(); PlatUserVO userVO = PlatUserUtil.getUserVO();
if (IdConst.SUPER_ADMIN_ID.equals(userVO.getId())) { if (IdConst.SUPER_ADMIN_ID.equals(userVO.getId())) {
List<String> tenantIdList = StreamUtil.map(tntTenantService.list(), TntTenant::getId);//还是要直接返回null 那边直接不过滤 List<String> tenantIdList = StreamUtil.map(platTenantService.list(), PlatTenant::getId);//还是要直接返回null 那边直接不过滤
tenantIdList.add(-1 + ""); tenantIdList.add(-1 + "");
return tenantIdList; return tenantIdList;
} else { } else {
...@@ -482,7 +482,7 @@ implements SaasUserService{ ...@@ -482,7 +482,7 @@ implements SaasUserService{
boolean allFlag = false; boolean allFlag = false;
allFlag = roleList.stream().anyMatch(e -> TenantEnum.DataScopeTypeEnum.ALL.getValue().equals(e.getDataScopeType())); allFlag = roleList.stream().anyMatch(e -> TenantEnum.DataScopeTypeEnum.ALL.getValue().equals(e.getDataScopeType()));
if (allFlag) { if (allFlag) {
List<String> tenantIdList = StreamUtil.map(tntTenantService.list(), TntTenant::getId);//还是要直接返回null 那边直接不过滤 List<String> tenantIdList = StreamUtil.map(platTenantService.list(), PlatTenant::getId);//还是要直接返回null 那边直接不过滤
tenantIdList.add(-1 + ""); tenantIdList.add(-1 + "");
return tenantIdList; return tenantIdList;
} }
......
...@@ -2,9 +2,9 @@ ...@@ -2,9 +2,9 @@
<!DOCTYPE mapper <!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd"> "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.makeit.mapper.saas.TntAuthMenuMapper"> <mapper namespace="com.makeit.mapper.saas.PlatAuthMenuMapper">
<resultMap id="BaseResultMap" type="com.makeit.entity.saas.TntAuthMenu"> <resultMap id="BaseResultMap" type="com.makeit.entity.saas.PlatAuthMenu">
<id property="id" column="id" jdbcType="VARCHAR"/> <id property="id" column="id" jdbcType="VARCHAR"/>
<result property="parentId" column="parent_id" jdbcType="VARCHAR"/> <result property="parentId" column="parent_id" jdbcType="VARCHAR"/>
<result property="name" column="name" jdbcType="VARCHAR"/> <result property="name" column="name" jdbcType="VARCHAR"/>
......
...@@ -2,9 +2,9 @@ ...@@ -2,9 +2,9 @@
<!DOCTYPE mapper <!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd"> "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.makeit.mapper.saas.TntTenantMapper"> <mapper namespace="com.makeit.mapper.saas.PlatTenantMapper">
<resultMap id="BaseResultMap" type="com.makeit.entity.saas.TntTenant"> <resultMap id="BaseResultMap" type="com.makeit.entity.saas.PlatTenant">
<id property="id" column="id" jdbcType="VARCHAR"/> <id property="id" column="id" jdbcType="VARCHAR"/>
<result property="name" column="name" jdbcType="VARCHAR"/> <result property="name" column="name" jdbcType="VARCHAR"/>
<result property="status" column="status" jdbcType="VARCHAR"/> <result property="status" column="status" jdbcType="VARCHAR"/>
......
...@@ -84,4 +84,6 @@ maven: ...@@ -84,4 +84,6 @@ maven:
profile: profile:
redis: redis:
prefix: prefix:
\ No newline at end of file
libreOffice: C:\\Program Files\\LibreOffice\\program\\soffice
\ No newline at end of file
...@@ -87,4 +87,4 @@ maven: ...@@ -87,4 +87,4 @@ maven:
profile: profile:
redis: redis:
prefix: prefix:
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment