feat(票据,附件,审核): 票据增加,审核完善,附件查询

票据添加时,选择审核人,审核逻辑,附件查询
This commit is contained in:
Ftz123456 2024-02-19 12:40:47 +08:00
parent f57d6a5078
commit cf7d44f6dd
51 changed files with 355 additions and 602 deletions

View File

@ -7,6 +7,7 @@ import com.zsc.edu.bill.modules.system.entity.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/**
* @author ftz
@ -14,8 +15,9 @@ import lombok.Getter;
* 描述: TODO
*/
@EqualsAndHashCode(callSuper = true)
@TableName(value ="Audit")
@Data
@TableName(value ="audit")
@Getter
@Setter
public class Audit extends BaseEntity {
/*
* 票据Id

View File

@ -10,6 +10,7 @@ import lombok.Data;
*/
@Data
public class Auditdto {
private Long id;
/*
* 票据Id
* */
@ -25,5 +26,5 @@ public class Auditdto {
/*
* 审核状态
* */
private Audit.Result result;
private String result;
}

View File

@ -0,0 +1,31 @@
package com.zsc.edu.bill.modules.audited.vo;
import com.zsc.edu.bill.modules.audited.audit.Audit;
import lombok.Data;
/**
* @author ftz
* 创建时间:5/2/2024 下午3:24
* 描述:
*/
@Data
public class auditVo {
private Long auditId;
/*
* 票据Id
* */
private Long ticketId;
/*
*审核员id
* */
private Long auditorId;
/*
*审核意见
*/
private String comment;
/*
* 审核状态
* */
private Audit.Result result;
private String remark;
}

View File

@ -1,14 +1,18 @@
package com.zsc.edu.bill.modules.bills.controller;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zsc.edu.bill.modules.bills.dto.BillDto;
import com.zsc.edu.bill.modules.audited.audit.Audit;
import com.zsc.edu.bill.modules.audited.dto.Auditdto;
import com.zsc.edu.bill.modules.audited.service.AuditService;
import com.zsc.edu.bill.modules.bills.dto.BillDto;
import com.zsc.edu.bill.modules.bills.entity.Bill;
import com.zsc.edu.bill.modules.bills.query.BillQuery;
import com.zsc.edu.bill.modules.bills.service.BillService;
import com.zsc.edu.bill.modules.bills.vo.BillVo;
import lombok.AllArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
@ -23,11 +27,13 @@ import java.util.List;
public class BillController {
private final BillService service;
private final AuditService auditService;
/**
* 分页查询票据列表
* @return 票据列表
*/
@GetMapping
@PreAuthorize("hasAuthority('BILL_QUERY')")
public Page<Bill> list(BillQuery query, Page<Bill> page) {
return service.page(page, query.wrapper());
}
@ -36,6 +42,7 @@ public class BillController {
* @return ture/false
*/
@PostMapping
@PreAuthorize("hasAuthority('BILL_CREATE')")
public Boolean create(@RequestBody BillDto dto){
return service.create(dto);
}
@ -45,6 +52,7 @@ public class BillController {
* @return ture/false
*/
@PatchMapping("/{id}")
@PreAuthorize("hasAuthority('BILL_UPDATE')")
public Boolean update(@RequestBody BillDto dto, @PathVariable("id") Long id){
return service.update(dto, id);
}
@ -54,6 +62,7 @@ public class BillController {
* @return ture/false
*/
@DeleteMapping
@PreAuthorize("hasAuthority('BILL_DELETE')")
public Boolean delete(Long id){
return service.removeById(id);
}
@ -63,6 +72,7 @@ public class BillController {
* @return ture/false
*/
@DeleteMapping("batch")
@PreAuthorize("hasAuthority('BILL_DELETE')")
public Boolean deleteBatch(List<Long> ids){
return service.removeByIds(ids);
}
@ -73,15 +83,38 @@ public class BillController {
* @return 票据详情
*/
@GetMapping("{id}")
@PreAuthorize("hasAuthority('BILL_QUERY')")
public BillVo detail(@PathVariable Long id){
return service.findById(id);
}
/**
* 选择审核人
* */
@PatchMapping("choose/{id}")
@PreAuthorize("hasAuthority('BILL_CHOOSE_AUDITOR')")
public Boolean audit(@PathVariable Long id, @RequestBody Long auditorId){
Audit audit = new Audit();
audit.setAuditorId(auditorId);
audit.setTicketId(id);
return auditService.save(audit);
}
/*
*审核票据
**/
@PatchMapping("audit/{id}")
public Boolean audit(@PathVariable Long id, @RequestBody Audit audit){
@PatchMapping("audit/{id}")@PreAuthorize("hasAuthority('BILL_AUDIT')")
public Boolean audit(@PathVariable Long id, @RequestBody Auditdto audit){
return service.audit(id, audit);
}
/**
*审核人个人审核列表
*/
@GetMapping("audit/list")
@PreAuthorize("hasAuthority('BILL_QUERY')")
public Page<Bill> list1(BillQuery query, Page<Bill> page) {
return service.auditPage(page, query);
}
}

View File

@ -1,5 +1,6 @@
package com.zsc.edu.bill.modules.bills.dto;
import com.zsc.edu.bill.modules.bills.entity.Bill;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@ -13,6 +14,10 @@ import java.math.BigDecimal;
@AllArgsConstructor
@NoArgsConstructor
public class BillDto {
/**
*userID
* */
private Long userId;
/**
* 票据标题
@ -28,6 +33,10 @@ public class BillDto {
* 金额 票据金额
*/
private BigDecimal money;
/**
* 状态 0:未提交草稿;1:未审核2:审核通过3:退回审核未通过
*/
private String status;
/**
* 票据类型
@ -43,5 +52,17 @@ public class BillDto {
* 客户公司名称 票据对应的企业名称
*/
private String companyName;
/**
* 附件id
*/
private String attachId;
/**
* 审核人id
*/
private Long auditorId;
/**
* 提交状态 true/false
*/
private Boolean submit;
}

View File

@ -8,7 +8,6 @@ import lombok.Getter;
import lombok.Setter;
import java.math.BigDecimal;
import java.util.UUID;
/**
* 票据表
@ -65,6 +64,11 @@ public class Bill extends BaseEntity {
* 客户公司名称 票据对应的企业名称
*/
private String companyName;
/**
*附件id
*/
private String attachId;
@Getter
public enum Status {
@ -96,9 +100,9 @@ public class Bill extends BaseEntity {
}
@Getter
public enum billType {
Bank(0,"bank"),
Tax(1,"tax"),
Other(2,"other");
BANK(0,"银行支票"),
TAX(1,"税务支票"),
OTHER(2,"其他支票");

View File

@ -65,7 +65,7 @@ public class BillQuery {
queryWrapper.like(StringUtils.hasText(this.title), Bill::getTitle, this.title);
queryWrapper.eq(Objects.nonNull(this.money), Bill::getMoney, this.money);
queryWrapper.eq(Objects.nonNull(this.status), Bill::getStatus, this.status);
queryWrapper.like(Objects.nonNull(this.type), Bill::getType, this.type);
queryWrapper.eq(Objects.nonNull(this.type), Bill::getType, this.type);
queryWrapper.like(StringUtils.hasText(this.companyName), Bill::getCompanyName, this.companyName);
return queryWrapper;
}

View File

@ -1,6 +1,8 @@
package com.zsc.edu.bill.modules.bills.repo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zsc.edu.bill.modules.bills.entity.Bill;
import com.zsc.edu.bill.modules.bills.vo.BillVo;
import org.apache.ibatis.annotations.Select;

View File

@ -1,10 +1,13 @@
package com.zsc.edu.bill.modules.bills.service;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.zsc.edu.bill.modules.audited.dto.Auditdto;
import com.zsc.edu.bill.modules.bills.dto.BillDto;
import com.zsc.edu.bill.modules.audited.audit.Audit;
import com.zsc.edu.bill.modules.bills.entity.Bill;
import com.zsc.edu.bill.modules.bills.query.BillQuery;
import com.zsc.edu.bill.modules.bills.vo.BillVo;
/**
@ -20,5 +23,8 @@ public interface BillService extends IService<Bill> {
BillVo findById(Long id);
Boolean audit(Long id, Audit audit);
Boolean audit(Long id, Auditdto audit);
Page<Bill> auditPage(Page<Bill> page, BillQuery query);
}

View File

@ -1,10 +1,18 @@
package com.zsc.edu.bill.modules.bills.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zsc.edu.bill.modules.bills.dto.BillDto;
import com.zsc.edu.bill.framework.security.SecurityUtil;
import com.zsc.edu.bill.framework.security.UserDetailsImpl;
import com.zsc.edu.bill.modules.audited.audit.Audit;
import com.zsc.edu.bill.modules.audited.dto.Auditdto;
import com.zsc.edu.bill.modules.audited.repo.AuditRepository;
import com.zsc.edu.bill.modules.audited.service.AuditService;
import com.zsc.edu.bill.modules.bills.dto.BillDto;
import com.zsc.edu.bill.modules.bills.entity.Bill;
import com.zsc.edu.bill.modules.bills.mapper.BillMapper;
import com.zsc.edu.bill.modules.bills.query.BillQuery;
import com.zsc.edu.bill.modules.bills.repo.BillRepository;
import com.zsc.edu.bill.modules.bills.service.BillService;
import com.zsc.edu.bill.modules.bills.vo.BillVo;
@ -22,18 +30,39 @@ public class BillServiceImpl extends ServiceImpl<BillRepository, Bill> implement
private final BillMapper mapper;
private final BillRepository repository;
private final AuditRepository auditRepository;
private final AuditService auditService;
@Override
public Boolean create(BillDto dto) {
Bill bill = mapper.toEntity(dto);
bill.setUuid(UUID.randomUUID().toString());
return save(bill);
String uuid=UUID.randomUUID().toString();
bill.setUuid(uuid);
if (dto.getSubmit()) {
bill.setStatus(Bill.Status.EXAMINE);
}else {
bill.setStatus(Bill.Status.SUBMIT);}
if (dto.getUserId()==null){
UserDetailsImpl userInfo = SecurityUtil.getUserInfo();
bill.setUserId(userInfo.getId());
}
save(bill);
Bill one = repository.selectOne(new LambdaQueryWrapper<Bill>().eq(Bill::getUuid, uuid));
Audit audit = new Audit();
audit.setTicketId(one.getId());
audit.setAuditorId(dto.getAuditorId());
return auditService.save(audit);
}
@Override
public Boolean update(BillDto dto, Long id) {
Bill bill = getById(id);
mapper.convert(dto, bill);
if (dto.getAuditorId()!=null) {
Audit audit = auditService.getOne(new LambdaQueryWrapper<Audit>().eq(Audit::getTicketId, id));
audit.setAuditorId(dto.getAuditorId());
auditService.updateById(audit);
}
return updateById(bill);
}
@ -42,24 +71,45 @@ public class BillServiceImpl extends ServiceImpl<BillRepository, Bill> implement
Bill bill = getById(id);
BillVo vo = new BillVo();
Audit audit = auditRepository.selectOne(new LambdaQueryWrapper<Audit>().eq(Audit::getTicketId, id));
vo.setBill(bill);
vo.setAudit(audit);
return repository.findById(id);
return vo;
}
@Override
public Boolean audit(Long id, Audit audit) {
public Boolean audit(Long id, Auditdto audit) {
Bill bill = getById(id);
if (bill != null) {
bill.setStatus(Bill.Status.valueOf(audit.getResult().getName()));
return updateById(bill);
Audit audit1 = auditRepository.selectById(audit.getId());
audit1.setComment( audit.getComment());
if ("PASS".equals(audit.getResult())) {
bill.setStatus(Bill.Status.PASS);
audit1.setResult(Audit.Result.PASS);
}else if ("FAILED".equals(audit.getResult())) {
bill.setStatus(Bill.Status.FAILED);
audit1.setResult(Audit.Result.FAILED);
}if (bill!=null ) {
updateById(bill);
}
// Audit audit1 =
return null;
auditService.updateById(audit1);
return auditService.updateById(audit1);
}
/**
* 审核员分页
*/
@Override
public Page<Bill> auditPage(Page<Bill> page, BillQuery query) {
UserDetailsImpl userInfo = SecurityUtil.getUserInfo();
LambdaQueryWrapper<Bill> wrappered = query.wrapper();
wrappered.ne(Bill::getStatus, Bill.Status.SUBMIT);
wrappered.inSql(Bill::getId, "select ticket_id from audit where auditor_id = " + userInfo.getId());
return repository.selectPage(page, wrappered);
}
}

View File

@ -13,7 +13,4 @@ import lombok.Data;
public class BillVo {
Bill bill;
Audit audit;
}

View File

@ -1,116 +0,0 @@
package com.zsc.edu.bill.modules.file.controller;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zsc.edu.bill.modules.file.dto.AttachFileDto;
import com.zsc.edu.bill.modules.file.entity.AttachFile;
import com.zsc.edu.bill.modules.file.query.AttachFileQuery;
import jakarta.servlet.http.HttpServletResponse;
import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
/**
* @author ftz
* 创建时间:29/1/2024 上午10:06
* 描述: 附件Controller
*/
@AllArgsConstructor
@RestController
@RequestMapping("api/rest/attachFile")
public class AttachFileController {
private final com.zsc.edu.bill.modules.file.service.AttachFileService service;
/**
* 分页查询附件列表
* @return 附件列表
*/
@GetMapping
public Page<AttachFile> list(AttachFileQuery query, Page<AttachFile> page) {
return service.page(page, query.wrapper());
}
/**
* 创建附件
* @return ture/false
*/
@PostMapping
public Boolean create(@RequestBody AttachFileDto dto){
return service.create(dto);
}
/**
* 更新附件
* @return ture/false
*/
@PatchMapping("/{id}")
public Boolean update(@RequestBody AttachFileDto dto, @PathVariable("id") Long id){
return service.update(dto, id);
}
/**
* 删除附件
* @return ture/false
*/
@DeleteMapping
public Boolean delete(Long id){
return service.removeById(id);
}
/**
* 附件上传
*
* @return ture/false
*/
@PostMapping("/upload")
public AttachFile upload(@RequestParam("file") MultipartFile file) {
return service.upload(file);
}
/**
* 附件下载
* @return ture/false
*/
@GetMapping("/download/{uuid}")
public void download(@PathVariable("uuid") String uuid, HttpServletResponse response) {
service.download(uuid, response);
}
//
// /**
// * 附件预览
// * @return ture/false
// */
// @GetMapping("/preview/{uuid}")
// public void preview(@PathVariable("uuid") String uuid, HttpServletResponse response) {
// service.preview(uuid, response);
// }
//
// /**
// * 附件预览
// * @return ture/false
// */
// @GetMapping("/preview/{uuid}")
// public void preview(@PathVariable("uuid") String uuid, HttpServletResponse response) {
// service.preview(uuid, response);
// }
//
// /**
// * 附件预览
// * @return ture/false
// */
// @GetMapping("/preview/{uuid}")
// public void preview(@PathVariable("uuid") String uuid, HttpServletResponse response) {
// service.preview(uuid, response);
// }
//
// /**
// * 附件预览
// * @return ture/false
// */
// @GetMapping("/preview/{uuid}")
//
}

View File

@ -59,8 +59,8 @@ public class AttachmentController {
@PathVariable("id") String id
) {
Attachment.Wrapper wrapper = service.loadAsWrapper(id);
if (wrapper.attachment.filename != null) {
ContentDisposition contentDisposition = ContentDisposition.builder("attachment").filename(wrapper.attachment.filename, StandardCharsets.UTF_8).build();
if (wrapper.attachment.fileName != null) {
ContentDisposition contentDisposition = ContentDisposition.builder("attachment").filename(wrapper.attachment.fileName, StandardCharsets.UTF_8).build();
return ResponseEntity.ok().
header(HttpHeaders.CONTENT_DISPOSITION, contentDisposition.toString()).
header(HttpHeaders.CONTENT_TYPE, wrapper.attachment.mimeType).
@ -68,5 +68,13 @@ public class AttachmentController {
}
return ResponseEntity.ok(wrapper.resource);
}
/**
* 根据附件ID获取附件信息
* */
@GetMapping("find/{id}")
public Attachment getAttachmentInfo(@PathVariable("id") String id) {
return service.getById(id);
}
}

View File

@ -1,75 +0,0 @@
package com.zsc.edu.bill.modules.file.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.util.Date;
import com.zsc.edu.bill.modules.system.entity.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* 票据附件表
* @TableName attach_file
*/
@EqualsAndHashCode(callSuper = true)
@TableName(value ="attach_file")
@Data
public class AttachFile extends BaseEntity {
/**
* 文件名 文件名详细说明
*/
private String saveFilename;
/**
* 文件UUID 返回给前端的文件UUID
*/
private String uuid;
/**
* 上传时的文件名 原文件名
*/
private String originFilename;
/**
* 文件大小
*/
private Long fileSize;
/**
* 文件类型
*/
private String fileType;
/**
* 文件扩展名
*/
private String extendName;
/**
* 票据id 附件对应的票据id
*/
private Long ticketId;
private String remark;
/**
*
*/
private String fileUrl;
@TableField(exist = false)
private static final long serialVersionUID = 1L;
}

View File

@ -33,11 +33,13 @@ public class Attachment implements Serializable {
/**
* 文件名
*/
public String filename;
public String fileName;
/**
* 附件作用类型
*/
public String mimeType;
/**
@ -50,6 +52,7 @@ public class Attachment implements Serializable {
/**
* 文件上传时间
*/
public LocalDateTime uploadTime;
/**
@ -59,9 +62,9 @@ public class Attachment implements Serializable {
@TableField(exist = false)
public String url;
public Attachment(String id, String filename, String mimeType, Type type, LocalDateTime uploadTime) {
public Attachment(String id, String fileName, String mimeType, Type type, LocalDateTime uploadTime) {
this.id = id;
this.filename = filename;
this.fileName = fileName;
this.mimeType = mimeType;
// this.type = type;
this.uploadTime = uploadTime;

View File

@ -1,23 +0,0 @@
package com.zsc.edu.bill.modules.file.mapper;
import com.zsc.edu.bill.common.mapstruct.BaseMapper;
import com.zsc.edu.bill.modules.file.dto.AttachFileDto;
import com.zsc.edu.bill.modules.file.entity.AttachFile;
import org.mapstruct.Mapper;
import org.mapstruct.ReportingPolicy;
/**
* @author fantianzhi
* @description 针对表attach_file(票据附件表)的数据库操作Mapper
* @createDate 2024-01-28 19:48:22
* @Entity com.zsc.edu.bill.modules.file.entity.AttachFile
*/
@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface AttachFileMapper extends BaseMapper<AttachFileDto,AttachFile> {
}

View File

@ -1,54 +0,0 @@
package com.zsc.edu.bill.modules.file.query;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.zsc.edu.bill.modules.file.entity.AttachFile;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author ftz
* 创建时间:29/1/2024 上午10:09
* 描述:
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class AttachFileQuery {
/**
* 附件名称
*/
private String name;
/**
* 附件类型
*/
private String type;
/**
* 附件大小
*/
private Long size;
/**
* 附件描述
*/
private String description;
/**
* 附件票据id
*/
private Long TicketId;
/**
* 拼接查询条件
*/
public LambdaQueryWrapper<AttachFile> wrapper() {
LambdaQueryWrapper<AttachFile> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(AttachFile::getSaveFilename, this.name)
.eq(AttachFile::getFileType, this.type)
.eq(AttachFile::getFileSize, this.size)
.eq(AttachFile::getTicketId, this.TicketId);
return wrapper;
}
}

View File

@ -1,12 +0,0 @@
package com.zsc.edu.bill.modules.file.repo;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.zsc.edu.bill.modules.file.entity.AttachFile;
/**
* @author ftz
* 创建时间:29/1/2024 上午9:55
* 描述: TODO
*/
public interface AttachFileRepository extends BaseMapper<AttachFile>{
}

View File

@ -1,7 +1,6 @@
package com.zsc.edu.bill.modules.file.repo;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.zsc.edu.bill.modules.file.entity.AttachFile;
import com.zsc.edu.bill.modules.file.entity.Attachment;
/**

View File

@ -1,23 +0,0 @@
package com.zsc.edu.bill.modules.file.service;
import com.zsc.edu.bill.modules.file.dto.AttachFileDto;
import com.zsc.edu.bill.modules.file.entity.AttachFile;
import com.baomidou.mybatisplus.extension.service.IService;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.web.multipart.MultipartFile;
/**
* @author fantianzhi
* @description 针对表attach_file(票据附件表)的数据库操作Service
* @createDate 2024-01-28 19:48:22
*/
public interface AttachFileService extends IService<AttachFile> {
Boolean create(AttachFileDto dto);
Boolean update(AttachFileDto dto, Long id);
AttachFile upload(MultipartFile file);
void download(String uuid, HttpServletResponse response);
}

View File

@ -1,8 +1,8 @@
package com.zsc.edu.bill.modules.file.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.zsc.edu.bill.modules.bills.entity.Bill;
import com.zsc.edu.bill.modules.file.entity.Attachment;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
@ -12,7 +12,7 @@ import java.io.IOException;
* @description 针对表attach_file(票据附件表)的数据库操作Service
* @createDate 2024-01-28 19:48:22
*/
public interface AttachmentService {
public interface AttachmentService extends IService<Attachment> {
Attachment store(Attachment.Type type, MultipartFile file) throws IOException;

View File

@ -1,130 +0,0 @@
package com.zsc.edu.bill.modules.file.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zsc.edu.bill.exception.ConstraintException;
import com.zsc.edu.bill.modules.file.dto.AttachFileDto;
import com.zsc.edu.bill.modules.file.entity.AttachFile;
import com.zsc.edu.bill.modules.file.mapper.AttachFileMapper;
import com.zsc.edu.bill.modules.file.repo.AttachFileRepository;
import com.zsc.edu.bill.modules.file.service.AttachFileService;
import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.system.ApplicationHome;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.UUID;
/**
* @author fantianzhi
* @description 针对表attach_file(票据附件表)的数据库操作Service实现
* @createDate 2024-01-28 19:48:22
*/
@Service
public class AttachFileServiceImpl extends ServiceImpl<AttachFileRepository, AttachFile>
implements AttachFileService{
@Autowired
private AttachFileMapper mapper;
@Override
public Boolean create(AttachFileDto dto) {
AttachFile attachFile=mapper.toEntity(dto);
return save(attachFile);
}
@Override
public Boolean update(AttachFileDto dto, Long id) {
AttachFile attachFile=getById(id);
mapper.convert(dto,attachFile);
return updateById(attachFile);
}
@Override
public AttachFile upload(MultipartFile file) {
AttachFile attachFile = new AttachFile();
attachFile.setOriginFilename(file.getOriginalFilename());
attachFile.setFileType(file.getContentType());
attachFile.setFileSize(file.getSize());
attachFile.setUuid(UUID.randomUUID().toString());
if (file.isEmpty()) {
throw new ConstraintException("此文件为空");
}
// 给文件重命名
String fileName = UUID.randomUUID() + "." + file.getContentType()
.substring(file.getContentType().lastIndexOf("/") + 1);
attachFile.setSaveFilename(fileName);
attachFile.setFileUrl(getSavePath()+fileName);
try {
// 获取保存路径
String path = getSavePath();
File files = new File(path, fileName);
File parentFile = files.getParentFile();
if (!parentFile.exists()) {
parentFile.mkdir();
}
file.transferTo(files);
} catch (IOException e) {
e.printStackTrace();
}
return attachFile;
}
@Override
public void download(String uuid, HttpServletResponse response) {
AttachFile attachFile = getOne(new LambdaQueryWrapper<AttachFile>().eq(AttachFile::getUuid, uuid));
File file = new File(getSavePath(), attachFile.getSaveFilename());
try {
// 1定义输入流通过输入流读取文件内容
FileInputStream fileInputStream = new FileInputStream(file);
// 2通过response对象获取到输出流
ServletOutputStream outputStream = response.getOutputStream();
// 3通过response对象设置响应数据格式(image/jpeg)
response.setContentType("image/jpeg");
int len = 0;
byte[] bytes = new byte[1024];
while ((len = fileInputStream.read(bytes)) != -1){
// 4通过输入流读取文件数据然后通过上述的输出流写回浏览器
outputStream.write(bytes,0,len);
// 刷新
outputStream.flush();
}
// 5关闭资源
outputStream.close();
fileInputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
// File file = new File(getSavePath(), "17913cfb-bff1-4c5c-b77d-ef79f241a79d.png");
// if (!file.exists()) {
// throw new ConstraintException("文件不存在");
// }
// response.setContentType("application/octet-stream");
// response.addHeader("Content-Disposition", "attachment;filename=" + "17913cfb-bff1-4c5c-b77d-ef79f241a79d.png");
}
public String getSavePath() {
// 这里需要注意的是ApplicationHome是属于SpringBoot的类
ApplicationHome applicationHome = new ApplicationHome(this.getClass());
// 保存目录位置根据项目需求可随意更改
return applicationHome.getDir().getParentFile()
.getParentFile().getAbsolutePath() + "\\src\\main\\resources\\static";
}
}

View File

@ -1,9 +1,13 @@
package com.zsc.edu.bill.modules.file.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zsc.edu.bill.framework.storage.StorageProperties;
import com.zsc.edu.bill.framework.storage.exception.StorageFileEmptyException;
import com.zsc.edu.bill.framework.storage.exception.StorageFileNotFoundException;
import com.zsc.edu.bill.modules.bills.entity.Bill;
import com.zsc.edu.bill.modules.bills.repo.BillRepository;
import com.zsc.edu.bill.modules.bills.service.BillService;
import com.zsc.edu.bill.modules.file.entity.Attachment;
import com.zsc.edu.bill.modules.file.repo.AttachmentRepository;
import com.zsc.edu.bill.modules.file.service.AttachmentService;
@ -34,7 +38,7 @@ import java.util.List;
* @author harry_yao
*/
@Service
public class AttachmentServiceImpl implements AttachmentService {
public class AttachmentServiceImpl extends ServiceImpl<AttachmentRepository, Attachment> implements AttachmentService {
final static int[] illegalChars = {34, 60, 62, 124, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 58, 42, 63, 92, 47};

View File

@ -1,14 +1,19 @@
package com.zsc.edu.bill.modules.system.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zsc.edu.bill.framework.security.UserDetailsImpl;
import com.zsc.edu.bill.modules.system.dto.*;
import com.zsc.edu.bill.modules.system.entity.Authority;
import com.zsc.edu.bill.modules.system.entity.Role;
import com.zsc.edu.bill.modules.system.entity.User;
import com.zsc.edu.bill.modules.system.query.UserQuery;
import com.zsc.edu.bill.modules.system.service.DeptService;
import com.zsc.edu.bill.modules.system.service.RoleAuthService;
import com.zsc.edu.bill.modules.system.service.RoleService;
import com.zsc.edu.bill.modules.system.service.UserService;
import com.baomidou.mybatisplus.extension.plugins.pagination.PageDTO;
import com.zsc.edu.bill.modules.system.vo.UserDetail;
import com.zsc.edu.bill.modules.system.vo.UserVo;
import lombok.AllArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
@ -16,6 +21,7 @@ import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.web.csrf.CsrfToken;
import org.springframework.web.bind.annotation.*;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.Map;
@ -34,6 +40,7 @@ public class UserController {
private final RoleService roleService;
private final DeptService deptService;
private final RoleAuthService roleAuthService;
/**
* 登录前获取csrfToken信息
@ -58,10 +65,17 @@ public class UserController {
* @return 用户信息
*/
@GetMapping("self")
public User selfDetail(@AuthenticationPrincipal UserDetailsImpl userDetails) {
public UserDetail selfDetail(@AuthenticationPrincipal UserDetailsImpl userDetails) {
UserDetail userDetail = new UserDetail();
User user = service.selfDetail(userDetails);
user.dept = deptService.getById(user.deptId);
return user;
Role role= roleService.getOne(new QueryWrapper<Role>().eq("id",user.roleId));
userDetail.setPermissions(role.getName());
userDetail.setAuthorities(roleAuthService.getAuthorityByUserId(role.getId()));
userDetail.setUser(user);
return userDetail;
}
/**
@ -102,18 +116,8 @@ public class UserController {
public Page<UserVo> query(UserQuery query, PageDTO<User> page) {
return service.page(query, page);
}
/**
* 分页查询用户信息2 hasAuthority('USER_QUERY')
*
* @param query 查询表单
* @return 分页用户信息
*/
@GetMapping("query")
@PreAuthorize("hasAuthority('USER_QUERY')")
public PageDto<UserVo> query2(UserQuery query) {
return service.queryUserPage(query);
}
/**
* 新建用户 hasAuthority('USER_CREATE')
@ -180,5 +184,19 @@ public class UserController {
public Boolean delete(@PathVariable("id") Long id) {
return service.removeById(id);
}
/**
* 根据部门ID查询用户
* */
@GetMapping("dept/{id}")
public Collection<User> listByDept(@PathVariable("id") Long id) {
return service.list(new QueryWrapper<User>().eq("dept_id", id));
}
/**
* 根据ID查询用户
* */
@GetMapping("{id}")
public UserVo detail(@PathVariable("id") Long id) {
return service.detail(id);
}
}

View File

@ -30,7 +30,17 @@ public enum Authority implements GrantedAuthority {
USER_QUERY,
USER_CREATE,
USER_UPDATE,
USER_DELETE;
USER_DELETE,
/**
* 票据管理
* */
BILL_QUERY,
BILL_CREATE,
BILL_UPDATE,
BILL_AUDIT,
BILL_CHOOSE_AUDITOR,
BILL_DELETE;
@Override
public String getAuthority() {

View File

@ -1,28 +0,0 @@
package com.zsc.edu.bill.modules.system.query;
import lombok.Data;
/**
* @author ftz
* 创建时间:12/1/2024 下午1:49
* 描述: 分页查询
*/
@Data
public class PageQuery {
/**
* 页码
*/
private Integer page;
/**
* 每页大小
*/
private Integer size;
/**
* 排序字段
*/
private String orderBy;
/**
* 是否升序
*/
private Boolean asc;
}

View File

@ -1,22 +1,26 @@
package com.zsc.edu.bill.modules.system.query;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.zsc.edu.bill.modules.system.entity.User;
import com.zsc.edu.bill.modules.system.vo.UserVo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import org.springframework.util.StringUtils;
import java.util.Set;
import java.util.Objects;
/**
* 用户Query
*
* @author harry yao
*/
@EqualsAndHashCode(callSuper = true)
@Data
@AllArgsConstructor
@NoArgsConstructor
public class UserQuery extends PageQuery{
public class UserQuery {
/**
* 用户名
@ -46,16 +50,18 @@ public class UserQuery extends PageQuery{
/**
* 部门集合
*/
public Set<Long> deptIds;
public Long deptId;
// public LambdaQueryWrapper<User> wrapper() {
// LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
// queryWrapper.eq(StringUtils.hasText(this.username), User::getUsername, this.username);
// queryWrapper.eq(StringUtils.hasText(this.phone), User::getPhone, this.phone);
// queryWrapper.eq(StringUtils.hasText(this.email), User::getEmail, this.email);
// queryWrapper.eq(Objects.nonNull(this.enable), User::getEnabled, this.enable);
// return queryWrapper;
// }
public LambdaQueryWrapper<User> wrapper() {
LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(StringUtils.hasText(this.username), User::getUsername, this.username);
queryWrapper.eq(StringUtils.hasText(this.phone), User::getPhone, this.phone);
queryWrapper.eq(StringUtils.hasText(this.email), User::getEmail, this.email);
queryWrapper.eq(Objects.nonNull(this.enable), User::getEnabled, this.enable);
queryWrapper.eq(Objects.nonNull(this.deptId),User::getDeptId,this.deptId);
queryWrapper.eq(Objects.nonNull(this.roleId),User::getRoleId,this.roleId);
return queryWrapper;
}
}

View File

@ -20,10 +20,7 @@ import org.apache.ibatis.annotations.Select;
*/
public interface UserRepository extends BaseMapper<User> {
@Select("select u.*, d.name as deptName, GROUP_CONCAT(r.name SEPARATOR ', ') as roleNames from sys_user as u " +
"left join sys_dept as d on u.dept_id=d.id " +
"left join sys_users_roles as sur on u.id = sur.user_id " +
"join sys_role r on r.id = sur.role_id ${ew.customSqlSegment}")
Page<UserVo> page(Page pageDTO, @Param("ew") QueryWrapper<User> wrapper);
// @Select("select u.*, sr.*, sra.* from sys_user u " +
@ -32,4 +29,7 @@ public interface UserRepository extends BaseMapper<User> {
// "where u.username = #{username}")
// User findByUsername(String username);
User selectByUsername(String username);
UserVo detail(Long id);
}

View File

@ -3,6 +3,8 @@ package com.zsc.edu.bill.modules.system.service;
import com.zsc.edu.bill.modules.system.entity.RoleAuthority;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
/**
* <p>
* 角色权限表 服务类
@ -13,4 +15,6 @@ import com.baomidou.mybatisplus.extension.service.IService;
*/
public interface RoleAuthService extends IService<RoleAuthority> {
boolean removeByRoleId(Long id);
List<String> getAuthorityByUserId(Long id);
}

View File

@ -1,6 +1,7 @@
package com.zsc.edu.bill.modules.system.service;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.zsc.edu.bill.framework.security.UserDetailsImpl;
import com.zsc.edu.bill.modules.system.dto.*;
import com.zsc.edu.bill.modules.system.entity.User;
@ -38,7 +39,5 @@ public interface UserService extends IService<User> {
Boolean register(UserCreateDto dto);
Page<UserVo> page2(UserQuery query, PageDTO<User> page);
PageDto<UserVo> queryUserPage(UserQuery query);
UserVo detail(Long id);
}

View File

@ -7,10 +7,21 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.stream.Collectors;
@Service
public class RoleAuthServiceImpl extends ServiceImpl<RoleAuthoritiesRepository, RoleAuthority> implements RoleAuthService {
@Override
public boolean removeByRoleId(Long roleId) {
return remove(new LambdaQueryWrapper<RoleAuthority>().eq(RoleAuthority::getRoleId, roleId));
}
@Override
public List<String> getAuthorityByUserId(Long id) {
List<RoleAuthority> list = list(new LambdaQueryWrapper<RoleAuthority>().eq(RoleAuthority::getRoleId, id));
return list(new LambdaQueryWrapper<RoleAuthority>().eq(RoleAuthority::getRoleId, id)).stream().map(RoleAuthority::getAuthority).collect(Collectors.toList());
}
}

View File

@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zsc.edu.bill.exception.ConstraintException;
import com.zsc.edu.bill.framework.security.UserDetailsImpl;
import com.zsc.edu.bill.modules.system.dto.*;
import com.zsc.edu.bill.modules.system.entity.Dept;
import com.zsc.edu.bill.modules.system.entity.Role;
import com.zsc.edu.bill.modules.system.entity.User;
import com.zsc.edu.bill.modules.system.query.UserQuery;
@ -36,6 +37,7 @@ public class UserServiceImpl extends ServiceImpl<UserRepository, User> implement
private final PasswordEncoder passwordEncoder;
private final RoleServiceImpl roleService;
private final DeptServiceImpl deptService;
@Override
@ -80,9 +82,15 @@ public class UserServiceImpl extends ServiceImpl<UserRepository, User> implement
QueryWrapper<User> wrapper = new QueryWrapper<>();
// wrapper.like(!query.getUsername().isBlank(), "u.username", query.getUsername())
// wrapper
// .in(query.deptIds != null && !query.deptIds.isEmpty(), "d.id", query.getDeptIds())
// .in(query.deptId != null && !query.deptId.isEmpty(), "d.id", query.getDeptId())
// .in(query.roleId != null && !query.roleId.isEmpty(), "r.id", query.getRoleId());
//3.Mapper层连表查询SQL语句并把动态查询的代码段传递给Mapper接
wrapper.eq(query.getDeptId() != null&&query.deptId!=' ', "dept_id", query.getDeptId());
wrapper.eq(query.getRoleId() != null&&query.roleId!=' ', "role_id", query.getRoleId());
wrapper.eq(query.getEnable() != null, "enabled", query.getEnable());
wrapper.like(query.getUsername() != null, "username", query.getUsername());
wrapper.like(query.getPhone() != null, "phone", query.getPhone());
wrapper.like(query.getEmail() != null, "email", query.getEmail());
return this.baseMapper.page(pageDTO, wrapper);
}
@ -98,49 +106,25 @@ public class UserServiceImpl extends ServiceImpl<UserRepository, User> implement
}
user.setPassword(passwordEncoder.encode(dto.password));
if (dto.getRoleId()== null||dto.getRoleId() ==' ') {
user.setRoleId(roleService.getOne(new LambdaQueryWrapper<Role>().eq(Role::getName, "普通用户")).getId());
user.setRoleId(roleService.getOne(new LambdaQueryWrapper<Role>().eq(Role::getName, "user")).getId());
}else {
user.setRoleId(dto.getRoleId());
}
/**
* 如果没有传入部门id则默认为普通用户部门
* */
if (dto.getDeptId()== null||dto.getDeptId() ==' ') {
user.setDeptId(deptService.getOne(new LambdaQueryWrapper<Dept>().eq(Dept::getName,"普通用户部门")).getId());}
return save(user);
}
@Override
public Page<UserVo> page2(UserQuery query, PageDTO<User> page) {
QueryWrapper<User> wrapper = new QueryWrapper<>();
return this.baseMapper.page(page, wrapper);
public UserVo detail(Long id) {
return this.baseMapper.detail(id);
}
@Override
public PageDto<UserVo> queryUserPage(UserQuery query) {
String username = query.getUsername();
String phone = query.getPhone();
String email = query.getEmail();
Page<User> page = Page.of(query.getPage(), query.getSize());
if (query.getOrderBy()!=null) {
page.addOrder(new OrderItem().setColumn(query.getOrderBy()).setAsc(query.getAsc()));
} else {
page.addOrder(new OrderItem().setColumn("id").setAsc(false));
}
Page<User> p = lambdaQuery()
.like(username != null && !username.isBlank(), User::getUsername, username)
.like(phone != null && !phone.isBlank(), User::getPhone, phone)
.like(email != null && !email.isBlank(), User::getEmail, email)
.eq(query.getEnable() != null, User::getEnabled, query.getEnable())
.page(page);
PageDto<UserVo> dto = new PageDto<>();
dto.setTotal(p.getTotal());
dto.setPages((int) p.getPages());
List<UserVo> list = p.getRecords().stream().map(user -> {
UserVo vo = new UserVo();
BeanUtils.copyProperties(user, vo);
return vo;
}).toList();
dto.setList(list);
return dto;
}
@Override
public User selfDetail(UserDetailsImpl userDetails) {

View File

@ -0,0 +1,24 @@
package com.zsc.edu.bill.modules.system.vo;
import com.zsc.edu.bill.modules.system.entity.Authority;
import com.zsc.edu.bill.modules.system.entity.User;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
import java.util.Set;
/**
* @author ftz
* 创建时间:16/2/2024 下午6:20
* 描述: TODO
*/
@Getter
@Setter
public class UserDetail {
private User user;
private List<String> authorities;
private String permissions;
}

View File

@ -58,4 +58,5 @@ public class UserVo {
LocalDateTime createTime;
LocalDateTime updateTime;
}

View File

@ -9,9 +9,9 @@ mybatis-plus:
spring:
datasource:
url: jdbc:mysql://localhost:3306/bill?useSSL=false&allowPublicKeyRetrieval=true&createDatabaseIfNotExist=true&characterEncoding=utf8&serverTimezone=Hongkong
url: jdbc:mysql://59.110.238.182:3306/study?useSSL=false&allowPublicKeyRetrieval=true&createDatabaseIfNotExist=true&characterEncoding=utf8&serverTimezone=Hongkong
username: root
password: 123123
password: 2002
driver-class-name: com.mysql.cj.jdbc.Driver
servlet:
multipart:

View File

@ -1,30 +0,0 @@
<?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.zsc.edu.bill.modules.file.mapper.AttachFileMapper">
<resultMap id="BaseResultMap" type="com.zsc.edu.bill.modules.file.entity.AttachFile">
<id property="id" column="id" jdbcType="BIGINT"/>
<result property="saveFilename" column="save_filename" jdbcType="VARCHAR"/>
<result property="uuid" column="uuid" jdbcType="VARCHAR"/>
<result property="originFilename" column="origin_filename" jdbcType="VARCHAR"/>
<result property="fileSize" column="file_size" jdbcType="BIGINT"/>
<result property="fileType" column="file_type" jdbcType="VARCHAR"/>
<result property="extendName" column="extend_name" jdbcType="VARCHAR"/>
<result property="ticketId" column="ticket_id" jdbcType="BIGINT"/>
<result property="createBy" column="create_by" jdbcType="VARCHAR"/>
<result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
<result property="updateBy" column="update_by" jdbcType="VARCHAR"/>
<result property="updateTime" column="update_time" jdbcType="TIMESTAMP"/>
<result property="fileUrl" column="file_url" jdbcType="VARCHAR"/>
</resultMap>
<sql id="Base_Column_List">
id,save_filename,uuid,
origin_filename,file_size,file_type,
extend_name,ticket_id,create_by,
create_time,update_by,update_time,
file_url
</sql>
</mapper>

View File

@ -20,6 +20,7 @@
<result property="updateBy" column="update_by" jdbcType="VARCHAR"/>
<result property="updateTime" column="update_time" jdbcType="TIMESTAMP"/>
<result property="remark" column="remark" jdbcType="VARCHAR"/>
<result property="attachId" column="attach_id" jdbcType="VARCHAR"/>
</resultMap>
<resultMap id="BaseResultMap1" type="com.zsc.edu.bill.modules.bills.vo.BillVo">
<collection property="bill" ofType="com.zsc.edu.bill.modules.bills.entity.Bill">
@ -38,9 +39,10 @@
<result property="updateBy" column="update_by" jdbcType="VARCHAR"/>
<result property="updateTime" column="update_time" jdbcType="TIMESTAMP"/>
<result property="remark" column="remark" jdbcType="VARCHAR"/>
<result property="attachId" column="attach_id" jdbcType="VARCHAR"/>
</collection>
<collection property="audit" ofType="com.zsc.edu.bill.modules.audited.audit.Audit">
<id property="id" column="id" jdbcType="BIGINT"/>
<collection property="audit" ofType="com.zsc.edu.bill.modules.audited.vo.auditVo">
<id property="auditId" column="id" jdbcType="BIGINT"/>
<result property="ticketId" column="ticket_id" jdbcType="BIGINT"/>
<result property="auditorId" column="auditor_id" jdbcType="BIGINT"/>
<result property="result" column="result" jdbcType="TINYINT"/>

View File

@ -17,6 +17,18 @@
<id column="id" jdbcType="BIGINT" property="id"/>
<result column="name" jdbcType="VARCHAR" property="name"/>
</collection>
</resultMap>
<resultMap id="BaseResultMap1" type="com.zsc.edu.bill.modules.system.vo.UserVo">
<id column="id" jdbcType="BIGINT" property="id"/>
<result column="username" jdbcType="VARCHAR" property="username"/>
<result column="role_id" jdbcType="BIGINT" property="roleId"/>
<result column="dept_id" jdbcType="BIGINT" property="deptId"/>
<result column="email" jdbcType="VARCHAR" property="email"/>
<result column="phone" jdbcType="VARCHAR" property="phone"/>
<result column="nick_name" jdbcType="INTEGER" property="nickName"/>
<result column="avatar" jdbcType="VARCHAR" property="avatar"/>
<result column="address" jdbcType="VARCHAR" property="address"/>
<result column="create_time" jdbcType="TIMESTAMP" property="createTime"/>
</resultMap>
<sql id="Base_Column_List">
@ -30,5 +42,17 @@
left join study.sys_role sr on sys_user.role_id = sr.id
where username = #{username,jdbcType=VARCHAR}
</select>
<select id="page" resultType="com.zsc.edu.bill.modules.system.vo.UserVo" resultMap="BaseResultMap1">
select
*
from sys_user
${ew.customSqlSegment}
</select>
<select id="detail" resultType="com.zsc.edu.bill.modules.system.vo.UserVo" resultMap="BaseResultMap1">
select
*
from sys_user
where id = #{id}
</select>
</mapper>

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

BIN
storage/temp/3413499426300 Normal file

Binary file not shown.

BIN
storage/temp/3509847173300 Normal file

Binary file not shown.

BIN
storage/temp/3707745823700 Normal file

Binary file not shown.

BIN
storage/temp/4052535722300 Normal file

Binary file not shown.

BIN
storage/temp/4235836863599 Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

BIN
storage/temp/4279560243199 Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

BIN
storage/temp/4377215314899 Normal file

Binary file not shown.