feat: init yueqian-erp based on xingyun

- Change groupId: com.lframework -> com.yueqian
- Change artifactId: xingyun -> yueqian-erp
- Rename modules: xingyun-* -> yueqian-erp-*
- Update Java packages: com.lframework.xingyun -> com.yueqian.xingyun
- Preserve external Jugg framework dependencies as com.lframework
- Update README and documentation
This commit is contained in:
zdh
2026-06-13 20:07:18 +08:00
commit 0985dacbfe
1298 changed files with 130805 additions and 0 deletions
+23
View File
@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>yueqian-erp</artifactId>
<groupId>com.yueqian</groupId>
<version>1.0.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>yueqian-erp-comp</artifactId>
<name>【${project.artifactId}】公共组件服务层</name>
<dependencies>
<dependency>
<groupId>com.yueqian</groupId>
<artifactId>yueqian-erp-core</artifactId>
</dependency>
</dependencies>
</project>
@@ -0,0 +1,22 @@
package com.yueqian.xingyun.comp.bo.components;
import com.lframework.starter.web.core.bo.BaseBo;
import io.swagger.v3.oas.annotations.media.Schema;
import java.math.BigDecimal;
import lombok.Data;
@Data
public class MapLocationBo extends BaseBo {
/**
* 经度
*/
@Schema(description = "经度")
private BigDecimal lng;
/**
* 纬度
*/
@Schema(description = "纬度")
private BigDecimal lat;
}
@@ -0,0 +1,67 @@
package com.yueqian.xingyun.comp.bo.components;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.lframework.starter.common.constants.StringPool;
import com.lframework.starter.web.core.bo.BaseBo;
import com.lframework.starter.web.inner.entity.OrderTimeLine;
import io.swagger.v3.oas.annotations.media.Schema;
import java.time.LocalDateTime;
import lombok.Data;
/**
* @author zmj
* @since 2022/8/10
*/
@Data
public class OrderTimeLineBo extends BaseBo<OrderTimeLine> {
/**
* ID
*/
@Schema(description = "ID")
private String id;
/**
* 订单ID
*/
@Schema(description = "订单ID")
private String orderId;
/**
* 描述内容
*/
@Schema(description = "描述内容")
private String content;
/**
* 创建人
*/
@Schema(description = "创建人")
private String createBy;
/**
* 创建时间
*/
@Schema(description = "创建时间")
@JsonFormat(pattern = StringPool.DATE_TIME_PATTERN)
private LocalDateTime createTime;
/**
* 业务类型
*/
@Schema(description = "业务类型")
private Integer bizType;
public OrderTimeLineBo() {
}
public OrderTimeLineBo(OrderTimeLine dto) {
super(dto);
}
@Override
protected void afterInit(OrderTimeLine dto) {
this.bizType = dto.getBizType();
}
}
@@ -0,0 +1,37 @@
package com.yueqian.xingyun.comp.bo.dic;
import com.lframework.starter.web.core.bo.BaseBo;
import com.lframework.starter.web.inner.dto.dic.city.DicCityDto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
public class CitySelectorBo extends BaseBo<DicCityDto> {
/**
* ID
*/
@Schema(description = "ID")
private String id;
/**
* 名称
*/
@Schema(description = "名称")
private String name;
/**
* 父级ID
*/
@Schema(description = "父级ID")
private String parentId;
public CitySelectorBo() {
}
public CitySelectorBo(DicCityDto dto) {
super(dto);
}
}
@@ -0,0 +1,66 @@
package com.yueqian.xingyun.comp.bo.sw.excel;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.lframework.starter.common.constants.StringPool;
import com.lframework.starter.web.core.bo.BaseBo;
import com.yueqian.xingyun.comp.entity.OnlineExcel;
import io.swagger.v3.oas.annotations.media.Schema;
import java.time.LocalDateTime;
import lombok.Data;
/**
* <p>
* 在线Excel GetBo
* </p>
*/
@Data
public class GetOnlineExcelBo extends BaseBo<OnlineExcel> {
/**
* ID
*/
@Schema(description = "ID")
private String id;
/**
* 名称
*/
@Schema(description = "名称")
private String name;
/**
* 状态
*/
@Schema(description = "状态")
private Boolean available;
/**
* 备注
*/
@Schema(description = "备注")
private String description;
/**
* 创建时间
*/
@Schema(description = "创建时间")
@JsonFormat(pattern = StringPool.DATE_TIME_PATTERN)
private LocalDateTime createTime;
/**
* 修改时间
*/
@Schema(description = "修改时间")
@JsonFormat(pattern = StringPool.DATE_TIME_PATTERN)
private LocalDateTime updateTime;
public GetOnlineExcelBo() {
}
public GetOnlineExcelBo(OnlineExcel dto) {
super(dto);
}
}
@@ -0,0 +1,66 @@
package com.yueqian.xingyun.comp.bo.sw.excel;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.lframework.starter.common.constants.StringPool;
import com.lframework.starter.web.core.bo.BaseBo;
import com.yueqian.xingyun.comp.entity.OnlineExcel;
import io.swagger.v3.oas.annotations.media.Schema;
import java.time.LocalDateTime;
import lombok.Data;
/**
* <p>
* 在线Excel QueryBo
* </p>
*/
@Data
public class QueryOnlineExcelBo extends BaseBo<OnlineExcel> {
/**
* ID
*/
@Schema(description = "ID")
private String id;
/**
* 名称
*/
@Schema(description = "名称")
private String name;
/**
* 状态
*/
@Schema(description = "状态")
private Boolean available;
/**
* 备注
*/
@Schema(description = "备注")
private String description;
/**
* 创建时间
*/
@Schema(description = "创建时间")
@JsonFormat(pattern = StringPool.DATE_TIME_PATTERN)
private LocalDateTime createTime;
/**
* 修改时间
*/
@Schema(description = "修改时间")
@JsonFormat(pattern = StringPool.DATE_TIME_PATTERN)
private LocalDateTime updateTime;
public QueryOnlineExcelBo() {
}
public QueryOnlineExcelBo(OnlineExcel dto) {
super(dto);
}
}
@@ -0,0 +1,82 @@
package com.yueqian.xingyun.comp.bo.sw.filebox;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.lframework.starter.common.constants.StringPool;
import com.lframework.starter.web.core.annotations.convert.EnumConvert;
import com.lframework.starter.web.core.bo.BaseBo;
import com.yueqian.xingyun.comp.entity.FileBox;
import io.swagger.v3.oas.annotations.media.Schema;
import java.time.LocalDateTime;
import lombok.Data;
/**
* <p>
* 文件收纳箱 GetBo
* </p>
*/
@Data
public class GetFileBoxBo extends BaseBo<FileBox> {
/**
* ID
*/
@Schema(description = "ID")
private String id;
/**
* 名称
*/
@Schema(description = "名称")
private String name;
/**
* 上传记录ID
*/
@Schema(description = "上传记录ID")
private String recordId;
/**
* 上传类型
*/
@Schema(description = "上传类型")
private String contentType;
@Schema(description = "文件类型")
@EnumConvert
private Integer fileType;
/**
* 文件大小
*/
@Schema(description = "文件大小")
private String fileSize;
/**
* 备注
*/
@Schema(description = "备注")
private String description;
/**
* 创建时间
*/
@Schema(description = "创建时间")
@JsonFormat(pattern = StringPool.DATE_TIME_PATTERN)
private LocalDateTime createTime;
/**
* 创建人
*/
@Schema(description = "创建人")
private String createBy;
public GetFileBoxBo() {
}
public GetFileBoxBo(FileBox dto) {
super(dto);
}
}
@@ -0,0 +1,55 @@
package com.yueqian.xingyun.comp.bo.sw.filebox;
import com.lframework.starter.web.core.annotations.convert.EnumConvert;
import com.lframework.starter.web.core.bo.BaseBo;
import com.yueqian.xingyun.comp.entity.FileBox;
import io.swagger.v3.oas.annotations.media.Schema;
import java.time.LocalDateTime;
import lombok.Data;
/**
* <p>
* 文件收纳箱 QueryBo
* </p>
*/
@Data
public class QueryFileBoxBo extends BaseBo<FileBox> {
/**
* ID
*/
@Schema(description = "ID")
private String id;
/**
* 名称
*/
@Schema(description = "名称")
private String name;
@Schema(description = "文件大小")
private String fileSize;
@Schema(description = "文件类型")
@EnumConvert
private Integer fileType;
@Schema(description = "文件路径")
private String filePath;
/**
* 创建时间
*/
@Schema(description = "创建时间")
private LocalDateTime createTime;
public QueryFileBoxBo() {
}
public QueryFileBoxBo(FileBox dto) {
super(dto);
}
}
@@ -0,0 +1,78 @@
package com.yueqian.xingyun.comp.controller;
import com.lframework.starter.common.exceptions.impl.AccessDeniedException;
import com.lframework.starter.common.utils.FileUtil;
import com.lframework.starter.web.core.components.redis.RedisHandler;
import com.lframework.starter.web.core.controller.DefaultBaseController;
import com.lframework.starter.web.core.components.resp.InvokeResult;
import com.lframework.starter.web.core.components.resp.InvokeResultBuilder;
import com.lframework.starter.web.core.utils.ResponseUtil;
import com.lframework.starter.web.core.utils.UploadUtil;
import com.lframework.starter.web.inner.entity.SecurityUploadRecord;
import com.lframework.starter.web.inner.service.SecurityUploadRecordService;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.Operation;
import java.io.File;
import jakarta.validation.constraints.NotBlank;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 安全下载
*
* @author zmj
*/
@Tag(name = "安全下载")
@Slf4j
@Validated
@RestController
@RequestMapping("/download/security")
public class SecurityDownloadController extends DefaultBaseController {
@Autowired
private SecurityUploadRecordService securityUploadRecordService;
@Autowired
private RedisHandler redisHandler;
@Operation(summary = "下载文件(获取签名URL")
@Parameter(name = "id", description = "ID", in = ParameterIn.QUERY, required = true)
@GetMapping("/url")
public InvokeResult<String> getSecurityDownloadUrl(@NotBlank(message = "ID不能为空!") String id) {
SecurityUploadRecord record = securityUploadRecordService.getById(id);
if (record == null) {
throw new AccessDeniedException();
}
if (!record.getCreateById().equals(getCurrentUser().getId())) {
throw new AccessDeniedException();
}
return InvokeResultBuilder.success(
UploadUtil.generatePresignedUrl(record.getUploadType().getCode(), record.getFilePath()));
}
@Operation(summary = "下载文件")
@Parameter(name = "sign", description = "签名", in = ParameterIn.QUERY, required = true)
@GetMapping
public void download(@NotBlank(message = "签名不能为空!") String sign) {
Object val = redisHandler.hget("security-upload", sign);
if (val == null) {
throw new AccessDeniedException();
}
File file = new File(val.toString());
if (!FileUtil.exist(file) || !FileUtil.isFile(file)) {
log.info("下载的文件不存在,sign {} val {}", sign, val);
throw new AccessDeniedException();
}
ResponseUtil.download(file);
}
}
@@ -0,0 +1,49 @@
package com.yueqian.xingyun.comp.controller;
import com.lframework.starter.common.utils.CollectionUtil;
import com.lframework.starter.web.core.controller.DefaultBaseController;
import com.lframework.starter.web.core.components.resp.InvokeResult;
import com.lframework.starter.web.core.components.resp.InvokeResultBuilder;
import com.yueqian.xingyun.comp.bo.dic.CitySelectorBo;
import com.lframework.starter.web.inner.dto.dic.city.DicCityDto;
import com.lframework.starter.web.inner.service.DicCityService;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation;
import java.util.List;
import java.util.stream.Collectors;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 数据选择器
*
* @author zmj
*/
@Tag(name = "数据选择器")
@Validated
@RestController
@RequestMapping("/selector")
public class SelectorController extends DefaultBaseController {
@Autowired
private DicCityService dicCityService;
/**
* 城市数据
*/
@Operation(summary = "城市数据")
@GetMapping("/city")
public InvokeResult<List<CitySelectorBo>> dicCity() {
List<DicCityDto> datas = dicCityService.getAll();
List<CitySelectorBo> results = CollectionUtil.emptyList();
if (!CollectionUtil.isEmpty(datas)) {
results = datas.stream().map(CitySelectorBo::new).collect(Collectors.toList());
}
return InvokeResultBuilder.success(results);
}
}
@@ -0,0 +1,172 @@
package com.yueqian.xingyun.comp.controller.components;
import cn.hutool.crypto.SecureUtil;
import com.lframework.starter.common.constants.StringPool;
import com.lframework.starter.common.exceptions.ClientException;
import com.lframework.starter.common.exceptions.impl.DefaultClientException;
import com.lframework.starter.common.utils.CollectionUtil;
import com.lframework.starter.common.utils.FileUtil;
import com.lframework.starter.web.core.bo.ExcelImportBo;
import com.lframework.starter.web.core.controller.DefaultBaseController;
import com.lframework.starter.web.core.components.resp.InvokeResult;
import com.lframework.starter.web.core.components.resp.InvokeResultBuilder;
import com.lframework.starter.web.inner.service.SysConfService;
import com.lframework.starter.web.core.utils.ExcelImportUtil;
import com.lframework.starter.web.core.utils.HttpUtil;
import com.lframework.starter.web.core.utils.JsonUtil;
import com.lframework.starter.web.core.utils.UploadUtil;
import com.yueqian.xingyun.comp.bo.components.MapLocationBo;
import com.yueqian.xingyun.comp.bo.components.OrderTimeLineBo;
import com.lframework.starter.web.inner.entity.OrderTimeLine;
import com.lframework.starter.web.inner.service.GenerateCodeService;
import com.lframework.starter.web.inner.service.OrderTimeLineService;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.Operation;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
/**
* 公共组件 Controller
*/
@Slf4j
@Tag(name = "公共组件")
@Validated
@RestController
@RequestMapping("/component")
public class ComponentController extends DefaultBaseController {
@Autowired
private SysConfService sysConfService;
@Autowired
private OrderTimeLineService orderTimeLineService;
@Autowired
private GenerateCodeService generateCodeService;
@Operation(summary = "查询导入Excel任务")
@GetMapping("/import/task")
public InvokeResult<ExcelImportBo> getExcelImportTask(
@NotBlank(message = "ID不能为空!") String id) {
return InvokeResultBuilder.success(ExcelImportUtil.getTask(id));
}
@Operation(summary = "获取地图Key")
@GetMapping("/map/key")
public InvokeResult<String> getMapKey() {
String key = sysConfService.findRequiredByKey("tx-map.key");
return InvokeResultBuilder.success(key);
}
@Operation(summary = "根据地址查询经纬度")
@GetMapping("/map/location")
public InvokeResult<MapLocationBo> getMapLocation(
@NotEmpty(message = "地址不能为空!") String address) {
String key = sysConfService.findRequiredByKey("tx-map.key");
String secret = sysConfService.findRequiredByKey("tx-map.secret");
// 请求腾讯地图WebService Api
// Api文档地址:https://lbs.qq.com/service/webService/webServiceGuide/webServiceGeocoder
String baseUrl = "https://apis.map.qq.com/";
String uri = "/ws/geocoder/v1/";
String reqParams = "?address=" + address + "&key=" + key;
// Api使用签名方式
// 签名文档:https://lbs.qq.com/faq/serverFaq/webServiceKey
String sign = SecureUtil.md5(uri + reqParams + secret);
Map<String, Object> reqMap = new HashMap<>();
reqMap.put("address", address);
reqMap.put("key", key);
reqMap.put("sig", sign);
try {
String resp = HttpUtil.doGet(baseUrl + uri, reqMap);
Map<String, Object> respMap = JsonUtil.parseObject(resp, Map.class);
if (!"0".equals(String.valueOf(respMap.get("status")))) {
throw new DefaultClientException(String.valueOf(respMap.get("message")));
}
Map<String, Object> result = (Map<String, Object>) respMap.get("result");
Map<String, Object> location = (Map<String, Object>) result.get("location");
MapLocationBo bo = new MapLocationBo();
bo.setLng(new BigDecimal(String.valueOf(location.get("lng"))));
bo.setLat(new BigDecimal(String.valueOf(location.get("lat"))));
return InvokeResultBuilder.success(bo);
} catch (ClientException e) {
throw e;
} catch (Exception e) {
log.error(e.getMessage(), e);
throw new DefaultClientException("解析地址失败,请稍后再试!");
}
}
@Operation(summary = "单据时间轴")
@Parameter(name = "orderId", description = "单据ID", in = ParameterIn.QUERY, required = true)
@GetMapping("/timeline/order")
public InvokeResult<List<OrderTimeLineBo>> getOrderTimeLine(
@NotBlank(message = "单据ID不能为空!") String orderId) {
List<OrderTimeLine> datas = orderTimeLineService.getByOrder(orderId);
List<OrderTimeLineBo> results = datas.stream().map(OrderTimeLineBo::new)
.collect(Collectors.toList());
return InvokeResultBuilder.success(results);
}
@Operation(summary = "通用上传图片")
@PostMapping("/upload/image")
public InvokeResult<String> uploadImage(MultipartFile file) {
if (!FileUtil.IMG_SUFFIX.contains(
FileUtil.getSuffix(file.getOriginalFilename()).toLowerCase())) {
throw new DefaultClientException(
"上传图片仅支持【" + CollectionUtil.join(FileUtil.IMG_SUFFIX, StringPool.STR_SPLIT_CN)
+ "】格式!");
}
String url = UploadUtil.upload(file).getUrl();
return InvokeResultBuilder.success(url);
}
@Operation(summary = "通用上传视频")
@PostMapping("/upload/video")
public InvokeResult<String> uploadVideo(MultipartFile file) {
if (!FileUtil.VIDEO_SUFFIX.contains(
FileUtil.getSuffix(file.getOriginalFilename()).toLowerCase())) {
throw new DefaultClientException(
"上传视频仅支持【" + CollectionUtil.join(FileUtil.VIDEO_SUFFIX, StringPool.STR_SPLIT_CN)
+ "】格式!");
}
String url = UploadUtil.upload(file).getUrl();
return InvokeResultBuilder.success(url);
}
@Operation(summary = "获取编号")
@Parameter(name = "type", description = "编号类型", in = ParameterIn.QUERY, required = true)
@GetMapping("/generate/code")
public InvokeResult<String> generateCode(@NotNull(message = "编号类型不能为空!") Integer type) {
return InvokeResultBuilder.success(generateCodeService.generate(type));
}
}
@@ -0,0 +1,125 @@
package com.yueqian.xingyun.comp.controller.sw;
import com.lframework.starter.common.exceptions.impl.DefaultClientException;
import com.lframework.starter.common.utils.CollectionUtil;
import com.lframework.starter.web.core.controller.DefaultBaseController;
import com.lframework.starter.web.core.components.resp.InvokeResult;
import com.lframework.starter.web.core.components.resp.InvokeResultBuilder;
import com.lframework.starter.web.core.components.resp.PageResult;
import com.lframework.starter.web.core.utils.PageResultUtil;
import com.yueqian.xingyun.comp.bo.sw.filebox.GetFileBoxBo;
import com.yueqian.xingyun.comp.bo.sw.filebox.QueryFileBoxBo;
import com.yueqian.xingyun.comp.entity.FileBox;
import com.yueqian.xingyun.comp.service.FileBoxService;
import com.yueqian.xingyun.comp.vo.sw.filebox.CreateFileBoxDirVo;
import com.yueqian.xingyun.comp.vo.sw.filebox.QueryFileBoxVo;
import com.yueqian.xingyun.comp.vo.sw.filebox.UpdateFileBoxVo;
import com.yueqian.xingyun.comp.vo.sw.filebox.UploadFileBoxVo;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.Operation;
import java.util.List;
import java.util.stream.Collectors;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotEmpty;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
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.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 文件收纳箱 Controller
*/
@Tag(name = "文件收纳箱")
@Validated
@RestController
@RequestMapping("/sw/filebox")
public class FileBoxController extends DefaultBaseController {
@Autowired
private FileBoxService fileBoxService;
@Operation(summary = "创建文件夹")
@PostMapping("/dir")
public InvokeResult<Void> createDir(@Valid CreateFileBoxDirVo vo) {
fileBoxService.createDir(vo);
return InvokeResultBuilder.success();
}
/**
* 上传文件
*/
@Operation(summary = "上传文件")
@PostMapping("/upload")
public InvokeResult<Void> upload(@Valid UploadFileBoxVo vo) {
fileBoxService.upload(vo);
return InvokeResultBuilder.success();
}
/**
* 查询列表
*/
@Operation(summary = "查询列表")
@GetMapping("/query")
public InvokeResult<PageResult<QueryFileBoxBo>> query(@Valid QueryFileBoxVo vo) {
PageResult<FileBox> pageResult = fileBoxService.query(getPageIndex(vo), getPageSize(vo),
vo);
List<FileBox> datas = pageResult.getDatas();
List<QueryFileBoxBo> results = null;
if (!CollectionUtil.isEmpty(datas)) {
results = datas.stream().map(QueryFileBoxBo::new).collect(Collectors.toList());
}
return InvokeResultBuilder.success(PageResultUtil.rebuild(pageResult, results));
}
/**
* 根据ID查询
*/
@Operation(summary = "根据ID查询")
@Parameter(name = "id", description = "ID", in = ParameterIn.QUERY, required = true)
@GetMapping
public InvokeResult<GetFileBoxBo> get(@NotBlank(message = "id不能为空!") String id) {
FileBox data = fileBoxService.findById(id);
if (data == null) {
throw new DefaultClientException("文件收纳箱不存在!");
}
GetFileBoxBo result = new GetFileBoxBo(data);
return InvokeResultBuilder.success(result);
}
/**
* 修改
*/
@Operation(summary = "修改")
@PutMapping
public InvokeResult<Void> update(@Valid UpdateFileBoxVo vo) {
fileBoxService.update(vo);
return InvokeResultBuilder.success();
}
@Operation(summary = "删除")
@DeleteMapping
public InvokeResult<Void> deleteById(@NotEmpty(message = "ID不能为空!") String id) {
fileBoxService.deleteById(id);
return InvokeResultBuilder.success();
}
}
@@ -0,0 +1,159 @@
package com.yueqian.xingyun.comp.controller.sw;
import com.lframework.starter.common.exceptions.impl.DefaultClientException;
import com.lframework.starter.common.utils.CollectionUtil;
import com.lframework.starter.web.core.components.resp.PageResult;
import com.lframework.starter.web.core.utils.PageResultUtil;
import com.lframework.starter.web.core.controller.DefaultBaseController;
import com.lframework.starter.web.core.components.resp.InvokeResult;
import com.lframework.starter.web.core.components.resp.InvokeResultBuilder;
import com.lframework.starter.web.core.components.security.SecurityUtil;
import com.yueqian.xingyun.comp.bo.sw.excel.GetOnlineExcelBo;
import com.yueqian.xingyun.comp.bo.sw.excel.QueryOnlineExcelBo;
import com.yueqian.xingyun.comp.entity.OnlineExcel;
import com.yueqian.xingyun.comp.service.OnlineExcelService;
import com.yueqian.xingyun.comp.vo.sw.excel.BatchSendOnlineExcelVo;
import com.yueqian.xingyun.comp.vo.sw.excel.CreateOnlineExcelVo;
import com.yueqian.xingyun.comp.vo.sw.excel.QueryOnlineExcelVo;
import com.yueqian.xingyun.comp.vo.sw.excel.SendOnlineExcelVo;
import com.yueqian.xingyun.comp.vo.sw.excel.UpdateOnlineExcelContentVo;
import com.yueqian.xingyun.comp.vo.sw.excel.UpdateOnlineExcelVo;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.Operation;
import java.util.List;
import java.util.stream.Collectors;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
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.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 在线Excel Controller
*/
@Tag(name = "在线Excel")
@Validated
@RestController
@RequestMapping("/sw/excel")
public class OnlineExcelController extends DefaultBaseController {
@Autowired
private OnlineExcelService onlineExcelService;
/**
* 查询列表
*/
@Operation(summary = "查询列表")
@GetMapping("/query")
public InvokeResult<PageResult<QueryOnlineExcelBo>> query(@Valid QueryOnlineExcelVo vo) {
PageResult<OnlineExcel> pageResult = onlineExcelService.query(getPageIndex(vo), getPageSize(vo),
vo);
List<OnlineExcel> datas = pageResult.getDatas();
List<QueryOnlineExcelBo> results = null;
if (!CollectionUtil.isEmpty(datas)) {
results = datas.stream().map(QueryOnlineExcelBo::new).collect(Collectors.toList());
}
return InvokeResultBuilder.success(PageResultUtil.rebuild(pageResult, results));
}
/**
* 根据ID查询
*/
@Operation(summary = "根据ID查询")
@Parameter(name = "id", description = "ID", in = ParameterIn.QUERY, required = true)
@GetMapping
public InvokeResult<GetOnlineExcelBo> get(@NotBlank(message = "id不能为空!") String id) {
OnlineExcel data = onlineExcelService.findById(id);
if (data == null) {
throw new DefaultClientException("在线Excel不存在!");
}
GetOnlineExcelBo result = new GetOnlineExcelBo(data);
return InvokeResultBuilder.success(result);
}
/**
* 新增
*/
@Operation(summary = "新增")
@PostMapping
public InvokeResult<Void> create(@Valid CreateOnlineExcelVo vo) {
onlineExcelService.create(vo);
return InvokeResultBuilder.success();
}
/**
* 修改
*/
@Operation(summary = "修改")
@PutMapping
public InvokeResult<Void> update(@Valid UpdateOnlineExcelVo vo) {
onlineExcelService.update(vo);
return InvokeResultBuilder.success();
}
@Operation(summary = "查询内容")
@Parameter(name = "id", description = "ID", in = ParameterIn.QUERY, required = true)
@GetMapping("/content")
public InvokeResult<String> getContent(@NotBlank(message = "id不能为空!") String id) {
OnlineExcel data = onlineExcelService.findById(id);
if (data == null) {
throw new DefaultClientException("文件不存在!");
}
return InvokeResultBuilder.success(data.getContent());
}
@Operation(summary = "修改内容")
@PutMapping("/content")
public InvokeResult<Void> updateContent(@Valid UpdateOnlineExcelContentVo vo) {
onlineExcelService.updateContent(vo);
return InvokeResultBuilder.success();
}
@Operation(summary = "发送文件给他人")
@PostMapping("/send")
public InvokeResult<Void> send(@Valid SendOnlineExcelVo vo) {
if (vo.getUserId().equals(SecurityUtil.getCurrentUser().getId())) {
throw new DefaultClientException("文件不能发送给自己!");
}
onlineExcelService.send(vo);
return InvokeResultBuilder.success();
}
@Operation(summary = "批量发送文件给他人")
@PostMapping("/send/batch")
public InvokeResult<Void> batchSend(@Valid @RequestBody BatchSendOnlineExcelVo vo) {
if (vo.getUserId().equals(SecurityUtil.getCurrentUser().getId())) {
throw new DefaultClientException("文件不能发送给自己!");
}
onlineExcelService.batchSend(vo);
return InvokeResultBuilder.success();
}
}
@@ -0,0 +1,104 @@
package com.yueqian.xingyun.comp.entity;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.lframework.starter.web.core.entity.BaseEntity;
import com.lframework.starter.web.core.dto.BaseDto;
import com.yueqian.xingyun.comp.enums.FileBoxFileType;
import java.time.LocalDateTime;
import lombok.Data;
/**
* <p>
* 文件收纳箱
* </p>
*/
@Data
@TableName("sw_file_box")
public class FileBox extends BaseEntity implements BaseDto {
public static final String CACHE_NAME = "FileBox";
private static final long serialVersionUID = 1L;
/**
* ID
*/
private String id;
/**
* 名称
*/
private String name;
/**
* 上传记录ID
*/
private String recordId;
/**
* ContentType
*/
private String contentType;
/**
* 文件类型
*/
private FileBoxFileType fileType;
/**
* 文件大小
*/
private String fileSize;
/**
* 文件路径
*/
private String filePath;
/**
* 文件后缀
*/
private String fileSuffix;
/**
* 备注
*/
private String description;
/**
* 创建人ID 新增时赋值
*/
@TableField(fill = FieldFill.INSERT)
private String createById;
/**
* 创建人 新增时赋值
*/
@TableField(fill = FieldFill.INSERT)
private String createBy;
/**
* 创建时间
*/
@TableField(fill = FieldFill.INSERT)
private LocalDateTime createTime;
/**
* 修改人 新增和修改时赋值
*/
@TableField(fill = FieldFill.INSERT_UPDATE)
private String updateBy;
/**
* 修改人ID 新增和修改时赋值
*/
@TableField(fill = FieldFill.INSERT_UPDATE)
private String updateById;
/**
* 修改时间
*/
@TableField(fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updateTime;
}
@@ -0,0 +1,83 @@
package com.yueqian.xingyun.comp.entity;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.lframework.starter.web.core.entity.BaseEntity;
import com.lframework.starter.web.core.dto.BaseDto;
import java.time.LocalDateTime;
import lombok.Data;
/**
* <p>
* 在线Excel
* </p>
*/
@Data
@TableName("sw_online_excel")
public class OnlineExcel extends BaseEntity implements BaseDto {
public static final String CACHE_NAME = "OnlineExcel";
private static final long serialVersionUID = 1L;
/**
* ID
*/
private String id;
/**
* 名称
*/
private String name;
/**
* 内容
*/
private String content;
/**
* 状态
*/
private Boolean available;
/**
* 备注
*/
private String description;
/**
* 创建人ID 新增时赋值
*/
@TableField(fill = FieldFill.INSERT)
private String createById;
/**
* 创建人 新增时赋值
*/
@TableField(fill = FieldFill.INSERT)
private String createBy;
/**
* 创建时间
*/
@TableField(fill = FieldFill.INSERT)
private LocalDateTime createTime;
/**
* 修改人 新增和修改时赋值
*/
@TableField(fill = FieldFill.INSERT_UPDATE)
private String updateBy;
/**
* 修改人ID 新增和修改时赋值
*/
@TableField(fill = FieldFill.INSERT_UPDATE)
private String updateById;
/**
* 修改时间
*/
@TableField(fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updateTime;
}
@@ -0,0 +1,30 @@
package com.yueqian.xingyun.comp.enums;
import com.baomidou.mybatisplus.annotation.EnumValue;
import com.lframework.starter.web.core.enums.BaseEnum;
public enum FileBoxFileType implements BaseEnum<Integer> {
DIR(0, "目录"),
FILE(1, "文件"),
;
@EnumValue
private final Integer code;
private final String desc;
FileBoxFileType(Integer code, String desc) {
this.code = code;
this.desc = desc;
}
@Override
public Integer getCode() {
return this.code;
}
@Override
public String getDesc() {
return this.desc;
}
}
@@ -0,0 +1,23 @@
package com.yueqian.xingyun.comp.enums;
import com.lframework.starter.web.inner.enums.system.NodeType;
import java.io.Serializable;
import org.springframework.stereotype.Component;
@Component
public final class FileBoxNodeType implements NodeType, Serializable {
private static final long serialVersionUID = 1L;
@Override
public Integer getCode() {
return 3;
}
@Override
public String getDesc() {
return "文件收纳箱";
}
}
@@ -0,0 +1,12 @@
package com.yueqian.xingyun.comp.enums;
import com.lframework.starter.web.core.components.oplog.OpLogType;
import org.springframework.stereotype.Component;
@Component
public class SwOpLogType implements OpLogType {
@Override
public Integer getCode() {
return 4000;
}
}
@@ -0,0 +1,217 @@
package com.yueqian.xingyun.comp.impl;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.pagehelper.PageInfo;
import com.lframework.starter.common.constants.StringPool;
import com.lframework.starter.common.exceptions.impl.DefaultClientException;
import com.lframework.starter.common.utils.Assert;
import com.lframework.starter.common.utils.CollectionUtil;
import com.lframework.starter.common.utils.FileUtil;
import com.lframework.starter.common.utils.ObjectUtil;
import com.lframework.starter.common.utils.StringUtil;
import com.lframework.starter.web.core.annotations.oplog.OpLog;
import com.lframework.starter.web.core.components.resp.PageResult;
import com.lframework.starter.web.core.components.security.SecurityUtil;
import com.lframework.starter.web.core.components.upload.client.dto.UploadDto;
import com.lframework.starter.web.core.impl.BaseMpServiceImpl;
import com.lframework.starter.web.core.utils.IdUtil;
import com.lframework.starter.web.core.utils.PageHelperUtil;
import com.lframework.starter.web.core.utils.PageResultUtil;
import com.lframework.starter.web.core.utils.UploadUtil;
import com.lframework.starter.web.inner.service.RecursionMappingService;
import com.lframework.starter.web.core.utils.OpLogUtil;
import com.yueqian.xingyun.comp.entity.FileBox;
import com.yueqian.xingyun.comp.enums.FileBoxFileType;
import com.yueqian.xingyun.comp.enums.FileBoxNodeType;
import com.yueqian.xingyun.comp.enums.SwOpLogType;
import com.yueqian.xingyun.comp.mappers.FileBoxMapper;
import com.yueqian.xingyun.comp.service.FileBoxService;
import com.yueqian.xingyun.comp.vo.sw.filebox.CreateFileBoxDirVo;
import com.yueqian.xingyun.comp.vo.sw.filebox.QueryFileBoxVo;
import com.yueqian.xingyun.comp.vo.sw.filebox.UpdateFileBoxVo;
import com.yueqian.xingyun.comp.vo.sw.filebox.UploadFileBoxVo;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
@Service
public class FileBoxServiceImpl extends
BaseMpServiceImpl<FileBoxMapper, FileBox> implements FileBoxService {
@Autowired
private RecursionMappingService recursionMappingService;
@Override
public PageResult<FileBox> query(Integer pageIndex, Integer pageSize, QueryFileBoxVo vo) {
Assert.greaterThanZero(pageIndex);
Assert.greaterThanZero(pageSize);
PageHelperUtil.startPage(pageIndex, pageSize);
List<FileBox> datas = this.query(vo);
return PageResultUtil.convert(new PageInfo<>(datas));
}
@Override
public List<FileBox> query(QueryFileBoxVo vo) {
return getBaseMapper().query(vo, SecurityUtil.getCurrentUser().getId());
}
@Override
public FileBox findById(String id) {
return getBaseMapper().selectById(id);
}
@OpLog(type = SwOpLogType.class, name = "修改文件,ID{}", params = {"#id"})
@Transactional(rollbackFor = Exception.class)
@Override
public void update(UpdateFileBoxVo vo) {
FileBox data = getBaseMapper().selectById(vo.getId());
if (ObjectUtil.isNull(data)) {
throw new DefaultClientException("文件或文件夹不存在!");
}
LambdaUpdateWrapper<FileBox> updateWrapper = Wrappers.lambdaUpdate(FileBox.class)
.set(data.getFileType() != FileBoxFileType.DIR, FileBox::getName, vo.getName())
.set(FileBox::getDescription,
StringUtil.isBlank(vo.getDescription()) ? StringPool.EMPTY_STR
: vo.getDescription())
.eq(FileBox::getId, vo.getId());
getBaseMapper().update(updateWrapper);
OpLogUtil.setVariable("id", data.getId());
OpLogUtil.setExtra(vo);
}
@OpLog(type = SwOpLogType.class, name = "删除文件,ID{}", params = {"#id"})
@Transactional(rollbackFor = Exception.class)
@Override
public void deleteById(String id) {
List<String> delIds = new ArrayList<>();
delIds.add(id);
List<String> childIds = recursionMappingService.getNodeChildIds(id,
FileBoxNodeType.class);
delIds.addAll(childIds);
recursionMappingService.deleteNodeAndChildren(id,
FileBoxNodeType.class);
Wrapper<FileBox> deleteWrapper = Wrappers.lambdaQuery(FileBox.class)
.in(FileBox::getId, delIds)
.eq(FileBox::getCreateById, SecurityUtil.getCurrentUser().getId());
this.remove(deleteWrapper);
}
@OpLog(type = SwOpLogType.class, name = "创建文件夹,父级目录:{},文件夹名称:{}", params = {
"#vo.parentPath", "#vo.name"})
@Transactional(rollbackFor = Exception.class)
@Override
public void createDir(CreateFileBoxDirVo vo) {
Wrapper<FileBox> checkWrapper = Wrappers.lambdaQuery(FileBox.class)
.eq(FileBox::getName, vo.getName()).eq(FileBox::getFilePath, vo.getParentPath())
.eq(FileBox::getCreateById, SecurityUtil.getCurrentUser().getId());
if (this.count(checkWrapper) > 0) {
throw new DefaultClientException("文件夹名称重复,请重新输入!");
}
FileBox dir = new FileBox();
dir.setId(IdUtil.getId());
dir.setName(vo.getName());
dir.setFileType(FileBoxFileType.DIR);
dir.setFilePath(vo.getParentPath());
dir.setDescription(StringPool.EMPTY_STR);
this.save(dir);
if ("/".equals(vo.getParentPath())) {
recursionMappingService.saveNode(dir.getId(),
FileBoxNodeType.class);
} else {
String path = vo.getParentPath().substring(0,
vo.getParentPath().lastIndexOf("/") == 0 ? 1 : vo.getParentPath().lastIndexOf("/"));
String name = vo.getParentPath().substring(vo.getParentPath().lastIndexOf("/") + 1);
Wrapper<FileBox> queryWrapper = Wrappers.lambdaQuery(FileBox.class)
.eq(FileBox::getName, name).eq(FileBox::getFilePath, path)
.eq(FileBox::getCreateById, SecurityUtil.getCurrentUser().getId());
FileBox fileBox = this.getOne(queryWrapper);
if (fileBox == null) {
throw new DefaultClientException("父级目录不存在!");
}
List<String> parentIds = recursionMappingService.getNodeParentIds(fileBox.getId(),
FileBoxNodeType.class);
parentIds.add(fileBox.getId());
recursionMappingService.saveNode(dir.getId(),
FileBoxNodeType.class, parentIds);
}
}
@OpLog(type = SwOpLogType.class, name = "上传文件,父级目录:{},文件名称:{}", params = {
"#vo.path", "#vo.name"})
@Transactional(rollbackFor = Exception.class)
@Override
public void upload(UploadFileBoxVo vo) {
MultipartFile file = vo.getFile();
UploadDto uploadDto = UploadUtil.upload(file,
CollectionUtil.toList("filebox", SecurityUtil.getCurrentUser().getId()), true);
String recordId = uploadDto.getSecurityUploadRecordId();
FileBox record = new FileBox();
record.setId(IdUtil.getId());
record.setName(file.getOriginalFilename());
record.setRecordId(recordId);
record.setContentType(file.getContentType());
record.setFileType(FileBoxFileType.FILE);
record.setFileSize(FileUtil.readableFileSize(file.getSize()));
record.setFilePath(vo.getPath());
record.setFileSuffix(FileUtil.getSuffix(file.getOriginalFilename()));
record.setDescription(StringPool.EMPTY_STR);
this.save(record);
if ("/".equals(vo.getPath())) {
recursionMappingService.saveNode(record.getId(),
FileBoxNodeType.class);
} else {
String path = vo.getPath()
.substring(0, vo.getPath().lastIndexOf("/") == 0 ? 1 : vo.getPath().lastIndexOf("/"));
String name = vo.getPath().substring(vo.getPath().lastIndexOf("/") + 1);
Wrapper<FileBox> queryWrapper = Wrappers.lambdaQuery(FileBox.class)
.eq(FileBox::getName, name).eq(FileBox::getFilePath, path)
.eq(FileBox::getCreateById, SecurityUtil.getCurrentUser().getId());
FileBox fileBox = this.getOne(queryWrapper);
if (fileBox == null) {
throw new DefaultClientException("父级目录不存在!");
}
List<String> parentIds = recursionMappingService.getNodeParentIds(fileBox.getId(),
FileBoxNodeType.class);
parentIds.add(fileBox.getId());
recursionMappingService.saveNode(record.getId(),
FileBoxNodeType.class, parentIds);
}
}
@Override
public void cleanCacheByKey(Serializable key) {
}
}
@@ -0,0 +1,209 @@
package com.yueqian.xingyun.comp.impl;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.pagehelper.PageInfo;
import com.lframework.starter.common.constants.StringPool;
import com.lframework.starter.common.exceptions.impl.DefaultClientException;
import com.lframework.starter.common.utils.Assert;
import com.lframework.starter.common.utils.ObjectUtil;
import com.lframework.starter.common.utils.StringUtil;
import com.lframework.starter.web.core.components.security.SecurityUtil;
import com.lframework.starter.web.core.impl.BaseMpServiceImpl;
import com.lframework.starter.web.core.components.resp.PageResult;
import com.lframework.starter.web.core.utils.IdUtil;
import com.lframework.starter.web.core.utils.JsonUtil;
import com.lframework.starter.web.core.utils.PageHelperUtil;
import com.lframework.starter.web.core.utils.PageResultUtil;
import com.yueqian.xingyun.comp.entity.OnlineExcel;
import com.yueqian.xingyun.comp.mappers.OnlineExcelMapper;
import com.yueqian.xingyun.comp.service.OnlineExcelService;
import com.lframework.starter.web.core.annotations.oplog.OpLog;
import com.lframework.starter.web.inner.entity.SysUser;
import com.yueqian.xingyun.comp.enums.SwOpLogType;
import com.lframework.starter.web.core.utils.OpLogUtil;
import com.yueqian.xingyun.comp.vo.sw.excel.BatchSendOnlineExcelVo;
import com.yueqian.xingyun.comp.vo.sw.excel.CreateOnlineExcelVo;
import com.yueqian.xingyun.comp.vo.sw.excel.QueryOnlineExcelVo;
import com.yueqian.xingyun.comp.vo.sw.excel.SendOnlineExcelVo;
import com.yueqian.xingyun.comp.vo.sw.excel.UpdateOnlineExcelContentVo;
import com.yueqian.xingyun.comp.vo.sw.excel.UpdateOnlineExcelVo;
import com.lframework.starter.web.inner.service.system.SysUserService;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class OnlineExcelServiceImpl extends
BaseMpServiceImpl<OnlineExcelMapper, OnlineExcel> implements OnlineExcelService {
@Autowired
private SysUserService userService;
@Override
public PageResult<OnlineExcel> query(Integer pageIndex, Integer pageSize, QueryOnlineExcelVo vo) {
Assert.greaterThanZero(pageIndex);
Assert.greaterThanZero(pageSize);
PageHelperUtil.startPage(pageIndex, pageSize);
List<OnlineExcel> datas = this.query(vo);
return PageResultUtil.convert(new PageInfo<>(datas));
}
@Override
public List<OnlineExcel> query(QueryOnlineExcelVo vo) {
return getBaseMapper().query(vo, SecurityUtil.getCurrentUser().getId());
}
@Override
public OnlineExcel findById(String id) {
return getBaseMapper().selectById(id);
}
@OpLog(type = SwOpLogType.class, name = "新增在线ExcelID{}", params = {"#id"})
@Transactional(rollbackFor = Exception.class)
@Override
public String create(CreateOnlineExcelVo vo) {
OnlineExcel data = new OnlineExcel();
data.setId(IdUtil.getId());
data.setName(vo.getName());
data.setContent(vo.getContent());
data.setDescription(
StringUtil.isBlank(vo.getDescription()) ? StringPool.EMPTY_STR : vo.getDescription());
getBaseMapper().insert(data);
OpLogUtil.setVariable("id", data.getId());
OpLogUtil.setExtra(vo);
return data.getId();
}
@OpLog(type = SwOpLogType.class, name = "修改在线ExcelID{}", params = {"#id"})
@Transactional(rollbackFor = Exception.class)
@Override
public void update(UpdateOnlineExcelVo vo) {
OnlineExcel data = getBaseMapper().selectById(vo.getId());
if (ObjectUtil.isNull(data)) {
throw new DefaultClientException("在线Excel不存在!");
}
LambdaUpdateWrapper<OnlineExcel> updateWrapper = Wrappers.lambdaUpdate(OnlineExcel.class)
.set(OnlineExcel::getName, vo.getName()).set(OnlineExcel::getAvailable, vo.getAvailable())
.set(OnlineExcel::getDescription,
StringUtil.isBlank(vo.getDescription()) ? StringPool.EMPTY_STR : vo.getDescription())
.eq(OnlineExcel::getId, vo.getId());
getBaseMapper().update(updateWrapper);
OpLogUtil.setVariable("id", data.getId());
OpLogUtil.setExtra(vo);
}
@OpLog(type = SwOpLogType.class, name = "修改在线Excel内容,ID{}", params = {"#id"})
@Transactional(rollbackFor = Exception.class)
@Override
public void updateContent(UpdateOnlineExcelContentVo vo) {
OnlineExcel data = getBaseMapper().selectById(vo.getId());
if (ObjectUtil.isNull(data)) {
throw new DefaultClientException("在线Excel不存在!");
}
Map content = JsonUtil.parseObject(data.getContent(), Map.class);
List sheets = JsonUtil.parseList(vo.getContent(), Map.class);
content.put("sheets", sheets);
LambdaUpdateWrapper<OnlineExcel> updateWrapper = Wrappers.lambdaUpdate(OnlineExcel.class)
.set(OnlineExcel::getContent, JsonUtil.toJsonString(content))
.eq(OnlineExcel::getId, vo.getId());
getBaseMapper().update(updateWrapper);
OpLogUtil.setVariable("id", data.getId());
OpLogUtil.setExtra(vo);
}
@OpLog(type = SwOpLogType.class, name = "发送Excel文件,发送方{}, 接收方{}", params = {"#sender",
"#receiver"})
@Transactional(rollbackFor = Exception.class)
@Override
public void send(SendOnlineExcelVo vo) {
OnlineExcel record = this.getById(vo.getId());
if (record == null) {
throw new DefaultClientException("Excel文件不存在!");
}
SysUser receiver = userService.findById(vo.getUserId());
if (receiver == null) {
throw new DefaultClientException("接收方不存在!");
}
if (vo.getSelfSave()) {
record.setId(IdUtil.getId());
record.setAvailable(Boolean.TRUE);
record.setCreateById(receiver.getId());
record.setCreateBy(receiver.getName());
this.save(record);
} else {
record.setCreateById(receiver.getId());
record.setCreateBy(receiver.getName());
record.setAvailable(Boolean.TRUE);
this.updateById(record);
}
OpLogUtil.setVariable("sender", SecurityUtil.getCurrentUser().getId());
OpLogUtil.setVariable("receiver", vo.getUserId());
OpLogUtil.setExtra(vo);
}
@OpLog(type = SwOpLogType.class, name = "批量发送Excel文件,发送方{}, 接收方{}", params = {"#sender",
"#receiver"})
@Transactional(rollbackFor = Exception.class)
@Override
public void batchSend(BatchSendOnlineExcelVo vo) {
SysUser receiver = userService.findById(vo.getUserId());
if (receiver == null) {
throw new DefaultClientException("接收方不存在!");
}
for (String id : vo.getIds()) {
OnlineExcel record = this.getById(id);
if (record == null) {
throw new DefaultClientException("Excel文件不存在!");
}
if (vo.getSelfSave()) {
record.setId(IdUtil.getId());
record.setCreateById(receiver.getId());
record.setCreateBy(receiver.getName());
record.setAvailable(Boolean.TRUE);
this.save(record);
} else {
record.setCreateById(receiver.getId());
record.setCreateBy(receiver.getName());
record.setAvailable(Boolean.TRUE);
this.updateById(record);
}
}
OpLogUtil.setVariable("sender", SecurityUtil.getCurrentUser().getId());
OpLogUtil.setVariable("receiver", vo.getUserId());
OpLogUtil.setExtra(vo);
}
@Override
public void cleanCacheByKey(Serializable key) {
}
}
@@ -0,0 +1,23 @@
package com.yueqian.xingyun.comp.mappers;
import com.lframework.starter.web.core.mapper.BaseMapper;
import com.yueqian.xingyun.comp.entity.FileBox;
import com.yueqian.xingyun.comp.vo.sw.filebox.QueryFileBoxVo;
import java.util.List;
import org.apache.ibatis.annotations.Param;
/**
* <p>
* 收件收纳箱 Mapper 接口
* </p>
*/
public interface FileBoxMapper extends BaseMapper<FileBox> {
/**
* 查询列表
*
* @param vo
* @return
*/
List<FileBox> query(@Param("vo") QueryFileBoxVo vo, @Param("createById") String createById);
}
@@ -0,0 +1,23 @@
package com.yueqian.xingyun.comp.mappers;
import com.lframework.starter.web.core.mapper.BaseMapper;
import com.yueqian.xingyun.comp.entity.OnlineExcel;
import com.yueqian.xingyun.comp.vo.sw.excel.QueryOnlineExcelVo;
import java.util.List;
import org.apache.ibatis.annotations.Param;
/**
* <p>
* 在线Excel Mapper 接口
* </p>
*/
public interface OnlineExcelMapper extends BaseMapper<OnlineExcel> {
/**
* 查询列表
*
* @param vo
* @return
*/
List<OnlineExcel> query(@Param("vo") QueryOnlineExcelVo vo, @Param("createById") String createById);
}
@@ -0,0 +1,66 @@
package com.yueqian.xingyun.comp.service;
import com.lframework.starter.web.core.components.resp.PageResult;
import com.lframework.starter.web.core.service.BaseMpService;
import com.yueqian.xingyun.comp.entity.FileBox;
import com.yueqian.xingyun.comp.vo.sw.filebox.CreateFileBoxDirVo;
import com.yueqian.xingyun.comp.vo.sw.filebox.QueryFileBoxVo;
import com.yueqian.xingyun.comp.vo.sw.filebox.UpdateFileBoxVo;
import com.yueqian.xingyun.comp.vo.sw.filebox.UploadFileBoxVo;
import java.util.List;
/**
* 文件收纳箱 Service
*/
public interface FileBoxService extends BaseMpService<FileBox> {
/**
* 查询列表
*
* @return
*/
PageResult<FileBox> query(Integer pageIndex, Integer pageSize, QueryFileBoxVo vo);
/**
* 查询列表
*
* @param vo
* @return
*/
List<FileBox> query(QueryFileBoxVo vo);
/**
* 根据ID查询
*
* @param id
* @return
*/
FileBox findById(String id);
/**
* 修改
*
* @param vo
*/
void update(UpdateFileBoxVo vo);
/**
* 根据ID删除
* @param id
*/
void deleteById(String id);
/**
* 创建文件夹
* @param vo
*/
void createDir(CreateFileBoxDirVo vo);
/**
* 上传文件
* @param vo
*/
void upload(UploadFileBoxVo vo);
}
@@ -0,0 +1,78 @@
package com.yueqian.xingyun.comp.service;
import com.lframework.starter.web.core.components.resp.PageResult;
import com.lframework.starter.web.core.service.BaseMpService;
import com.yueqian.xingyun.comp.entity.OnlineExcel;
import com.yueqian.xingyun.comp.vo.sw.excel.BatchSendOnlineExcelVo;
import com.yueqian.xingyun.comp.vo.sw.excel.CreateOnlineExcelVo;
import com.yueqian.xingyun.comp.vo.sw.excel.QueryOnlineExcelVo;
import com.yueqian.xingyun.comp.vo.sw.excel.SendOnlineExcelVo;
import com.yueqian.xingyun.comp.vo.sw.excel.UpdateOnlineExcelContentVo;
import com.yueqian.xingyun.comp.vo.sw.excel.UpdateOnlineExcelVo;
import java.util.List;
/**
* 在线Excel Service
*/
public interface OnlineExcelService extends BaseMpService<OnlineExcel> {
/**
* 查询列表
*
* @return
*/
PageResult<OnlineExcel> query(Integer pageIndex, Integer pageSize, QueryOnlineExcelVo vo);
/**
* 查询列表
*
* @param vo
* @return
*/
List<OnlineExcel> query(QueryOnlineExcelVo vo);
/**
* 根据ID查询
*
* @param id
* @return
*/
OnlineExcel findById(String id);
/**
* 创建
*
* @param vo
* @return
*/
String create(CreateOnlineExcelVo vo);
/**
* 修改
*
* @param vo
*/
void update(UpdateOnlineExcelVo vo);
/**
* 修改内容
*
* @param vo
*/
void updateContent(UpdateOnlineExcelContentVo vo);
/**
* 发送
*
* @param vo
*/
void send(SendOnlineExcelVo vo);
/**
* 批量发送
*
* @param vo
*/
void batchSend(BatchSendOnlineExcelVo vo);
}
@@ -0,0 +1,39 @@
package com.yueqian.xingyun.comp.vo.sw.excel;
import com.lframework.starter.web.core.components.validation.TypeMismatch;
import com.lframework.starter.web.core.vo.BaseVo;
import io.swagger.v3.oas.annotations.media.Schema;
import java.io.Serializable;
import java.util.List;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
@Data
public class BatchSendOnlineExcelVo implements BaseVo, Serializable {
private static final long serialVersionUID = 1L;
/**
* ID
*/
@Schema(description = "ID", requiredMode = Schema.RequiredMode.REQUIRED)
@NotEmpty(message = "ID不能为空!")
private List<String> ids;
/**
* 用户ID
*/
@Schema(description = "用户ID", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "用户ID不能为空!")
private String userId;
/**
* 是否留存副本
*/
@Schema(description = "是否留存副本", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "是否留存副本不能为空!")
@TypeMismatch(message = "是否留存副本格式错误!")
private Boolean selfSave;
}
@@ -0,0 +1,34 @@
package com.yueqian.xingyun.comp.vo.sw.excel;
import com.lframework.starter.web.core.vo.BaseVo;
import io.swagger.v3.oas.annotations.media.Schema;
import java.io.Serializable;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
@Data
public class CreateOnlineExcelVo implements BaseVo, Serializable {
private static final long serialVersionUID = 1L;
/**
* 名称
*/
@Schema(description = "名称", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "请输入名称!")
private String name;
/**
* 内容
*/
@Schema(description = "内容", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "请输入内容!")
private String content;
/**
* 备注
*/
@Schema(description = "备注")
private String description;
}
@@ -0,0 +1,43 @@
package com.yueqian.xingyun.comp.vo.sw.excel;
import com.lframework.starter.web.core.components.validation.TypeMismatch;
import com.lframework.starter.web.core.vo.BaseVo;
import com.lframework.starter.web.core.vo.PageVo;
import io.swagger.v3.oas.annotations.media.Schema;
import java.io.Serializable;
import java.time.LocalDateTime;
import lombok.Data;
@Data
public class QueryOnlineExcelVo extends PageVo implements BaseVo, Serializable {
private static final long serialVersionUID = 1L;
/**
* 名称
*/
@Schema(description = "名称")
private String name;
/**
* 状态
*/
@Schema(description = "状态")
@TypeMismatch(message = "状态格式有误!")
private Boolean available;
/**
* 创建时间 起始时间
*/
@Schema(description = "创建时间 起始时间")
@TypeMismatch(message = "创建时间起始时间格式有误!")
private LocalDateTime createTimeStart;
/**
* 创建时间 截止时间
*/
@Schema(description = "创建时间 截止时间")
@TypeMismatch(message = "创建时间截止时间格式有误!")
private LocalDateTime createTimeEnd;
}
@@ -0,0 +1,37 @@
package com.yueqian.xingyun.comp.vo.sw.excel;
import com.lframework.starter.web.core.components.validation.TypeMismatch;
import com.lframework.starter.web.core.vo.BaseVo;
import io.swagger.v3.oas.annotations.media.Schema;
import java.io.Serializable;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
@Data
public class SendOnlineExcelVo implements BaseVo, Serializable {
private static final long serialVersionUID = 1L;
/**
* ID
*/
@Schema(description = "ID", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "ID不能为空!")
private String id;
/**
* 用户ID
*/
@Schema(description = "用户ID", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "用户ID不能为空!")
private String userId;
/**
* 是否留存副本
*/
@Schema(description = "是否留存副本", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "是否留存副本不能为空!")
@TypeMismatch(message = "是否留存副本格式错误!")
private Boolean selfSave;
}
@@ -0,0 +1,27 @@
package com.yueqian.xingyun.comp.vo.sw.excel;
import com.lframework.starter.web.core.vo.BaseVo;
import io.swagger.v3.oas.annotations.media.Schema;
import java.io.Serializable;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
@Data
public class UpdateOnlineExcelContentVo implements BaseVo, Serializable {
private static final long serialVersionUID = 1L;
/**
* ID
*/
@Schema(description = "ID", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "id不能为空!")
private String id;
/**
* 内容
*/
@Schema(description = "内容", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "内容不能为空!")
private String content;
}
@@ -0,0 +1,44 @@
package com.yueqian.xingyun.comp.vo.sw.excel;
import com.lframework.starter.web.core.components.validation.TypeMismatch;
import com.lframework.starter.web.core.vo.BaseVo;
import io.swagger.v3.oas.annotations.media.Schema;
import java.io.Serializable;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
@Data
public class UpdateOnlineExcelVo implements BaseVo, Serializable {
private static final long serialVersionUID = 1L;
/**
* ID
*/
@Schema(description = "ID", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "id不能为空!")
private String id;
/**
* 名称
*/
@Schema(description = "名称", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "请输入名称!")
private String name;
/**
* 状态
*/
@Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED)
@TypeMismatch(message = "状态格式有误!")
@NotNull(message = "请选择状态!")
private Boolean available;
/**
* 备注
*/
@Schema(description = "备注")
private String description;
}
@@ -0,0 +1,23 @@
package com.yueqian.xingyun.comp.vo.sw.filebox;
import com.lframework.starter.web.core.components.validation.Regex;
import com.lframework.starter.web.core.vo.BaseVo;
import io.swagger.v3.oas.annotations.media.Schema;
import java.io.Serializable;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
@Data
public class CreateFileBoxDirVo implements BaseVo, Serializable {
private static final long serialVersionUID = 1L;
@Schema(description = "父级目录", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "父级目录不能为空!")
private String parentPath;
@Schema(description = "文件夹名称", requiredMode = Schema.RequiredMode.REQUIRED)
@Regex(regexp = "^(?!^\\.)[^\\/:*?\"<>|\\s].*$", message = "文件夹名称不合法!")
@NotBlank(message = "文件夹名称不能为空!")
private String name;
}
@@ -0,0 +1,22 @@
package com.yueqian.xingyun.comp.vo.sw.filebox;
import com.lframework.starter.web.core.vo.BaseVo;
import com.lframework.starter.web.core.vo.PageVo;
import io.swagger.v3.oas.annotations.media.Schema;
import java.io.Serializable;
import lombok.Data;
@Data
public class QueryFileBoxVo extends PageVo implements BaseVo, Serializable {
private static final long serialVersionUID = 1L;
/**
* 名称
*/
@Schema(description = "名称")
private String name;
@Schema(description = "路径")
private String path;
}
@@ -0,0 +1,34 @@
package com.yueqian.xingyun.comp.vo.sw.filebox;
import com.lframework.starter.web.core.vo.BaseVo;
import io.swagger.v3.oas.annotations.media.Schema;
import java.io.Serializable;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
@Data
public class UpdateFileBoxVo implements BaseVo, Serializable {
private static final long serialVersionUID = 1L;
/**
* ID
*/
@Schema(description = "ID", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "id不能为空!")
private String id;
/**
* 名称
*/
@Schema(description = "名称", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "请输入名称!")
private String name;
/**
* 备注
*/
@Schema(description = "备注")
private String description;
}
@@ -0,0 +1,26 @@
package com.yueqian.xingyun.comp.vo.sw.filebox;
import com.lframework.starter.web.core.vo.BaseVo;
import io.swagger.v3.oas.annotations.media.Schema;
import java.io.Serializable;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import org.springframework.web.multipart.MultipartFile;
@Data
public class UploadFileBoxVo implements BaseVo, Serializable {
private static final long serialVersionUID = 1L;
/**
* 文件
*/
@Schema(description = "文件", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "文件不能为空!")
private MultipartFile file;
@Schema(description = "路径", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "路径不能为空!")
private String path;
}
@@ -0,0 +1,2 @@
config.stopBubbling=true
lombok.equalsAndHashCode.callSuper=call
@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yueqian.xingyun.comp.mappers.FileBoxMapper">
<select id="query" resultType="com.yueqian.xingyun.comp.entity.FileBox">
<include refid="FileBox_sql"/>
<where>
<if test="vo.name != null and vo.name != ''">
AND tb.name LIKE CONCAT('%', #{vo.name}, '%')
</if>
<if test="vo.path != null and vo.path != ''">
AND tb.file_path = #{vo.path}
</if>
AND tb.create_by_id = #{createById}
</where>
ORDER BY tb.name ASC
</select>
<sql id="FileBox_sql">
SELECT tb.*
FROM sw_file_box AS tb
</sql>
</mapper>
@@ -0,0 +1,52 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yueqian.xingyun.comp.mappers.OnlineExcelMapper">
<resultMap id="OnlineExcel" type="com.yueqian.xingyun.comp.entity.OnlineExcel">
<id column="id" property="id"/>
<result column="name" property="name"/>
<result column="content" property="content"/>
<result column="available" property="available"/>
<result column="description" property="description"/>
<result column="create_by" property="createBy"/>
<result column="create_time" property="createTime"/>
<result column="update_by" property="updateBy"/>
<result column="update_time" property="updateTime"/>
</resultMap>
<select id="query" resultMap="OnlineExcel">
<include refid="OnlineExcel_sql"/>
<where>
<if test="vo.name != null and vo.name != ''">
AND tb.name LIKE CONCAT('%', #{vo.name}, '%')
</if>
<if test="vo.available != null">
AND tb.available = #{vo.available}
</if>
<if test="vo.createTimeStart != null">
AND tb.update_time >= #{vo.createTimeStart}
</if>
<if test="vo.createTimeEnd != null">
<![CDATA[
AND tb.update_time <= #{vo.createTimeEnd}
]]>
</if>
AND tb.create_by_id = #{createById}
</where>
ORDER BY tb.update_time DESC
</select>
<sql id="OnlineExcel_sql">
SELECT tb.id,
tb.name,
tb.content,
tb.available,
tb.description,
tb.create_by,
tb.create_time,
tb.update_by,
tb.update_time
FROM sw_online_excel AS tb
</sql>
</mapper>