feat(新增票据审核(未完成),票据附件上传,下载):

新增票据审核(未完成),票据附件上传,下载(已完成)。
This commit is contained in:
Ftz123456 2024-01-31 19:00:38 +08:00
parent 85e717da17
commit e26d837e35
39 changed files with 1062 additions and 18 deletions

View File

@ -0,0 +1,52 @@
package com.zsc.edu.bill.framework.mybatisplus;
import com.zsc.edu.bill.framework.security.SecurityUtil;
import com.zsc.edu.bill.framework.security.UserDetailsImpl;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import net.sf.jsqlparser.expression.Alias;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.LongValue;
import net.sf.jsqlparser.expression.operators.conditional.AndExpression;
import net.sf.jsqlparser.expression.operators.relational.EqualsTo;
import net.sf.jsqlparser.schema.Column;
import net.sf.jsqlparser.schema.Table;
import net.sf.jsqlparser.statement.select.PlainSelect;
/**
* @author ftz
* 创建时间:31/1/2024 下午4:26
* 描述: TODO
*/
@Slf4j
public class MyDataPermissionHandler {
/**
* 获取数据权限 SQL 片段
*
* @param plainSelect 查询对象
* @param whereSegment 查询条件片段
* @return JSqlParser 条件表达式
*/
@SneakyThrows(Exception.class)
public Expression getSqlSegment(PlainSelect plainSelect, String whereSegment) {
// 待执行 SQL Where 条件表达式
Expression where = plainSelect.getWhere();
// 获取权限过滤相关信息 -- TODO 这里模拟拿到该操作用户的权限进行处理即可...
UserDetailsImpl userInfo = SecurityUtil.getUserInfo();
if (userInfo == null) {
return where;
}
Table fromItem = (Table) plainSelect.getFromItem();
// 有别名用别名无别名用表名防止字段冲突报错
Alias fromItemAlias = fromItem.getAlias();
String mainTableName = fromItemAlias == null ? fromItem.getName() : fromItemAlias.getName();
// 数据权限SQL -- create_by = userId
EqualsTo selfEqualsTo = new EqualsTo();
selfEqualsTo.setLeftExpression(new Column(mainTableName + ".create_by"));
selfEqualsTo.setRightExpression(new LongValue(userInfo.getId()));
return new AndExpression(where, selfEqualsTo);
}
}

View File

@ -0,0 +1,73 @@
package com.zsc.edu.bill.framework.mybatisplus;
import com.baomidou.mybatisplus.core.plugins.InterceptorIgnoreHelper;
import com.baomidou.mybatisplus.core.toolkit.PluginUtils;
import com.baomidou.mybatisplus.extension.parser.JsqlParserSupport;
import com.baomidou.mybatisplus.extension.plugins.inner.InnerInterceptor;
import lombok.*;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.statement.select.PlainSelect;
import net.sf.jsqlparser.statement.select.Select;
import net.sf.jsqlparser.statement.select.SelectBody;
import net.sf.jsqlparser.statement.select.SetOperationList;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import java.sql.SQLException;
import java.util.List;
/**
* @author ftz
* 创建时间:31/1/2024 下午4:23
* 描述: TODO
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
@SuppressWarnings({"rawtypes"})
public class MyDataPermissionInterceptor extends JsqlParserSupport implements InnerInterceptor {
/**
* 数据权限处理器
*/
private MyDataPermissionHandler dataPermissionHandler;
@Override
public void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException {
if (InterceptorIgnoreHelper.willIgnoreDataPermission(ms.getId())) {
return;
}
PluginUtils.MPBoundSql mpBs = PluginUtils.mpBoundSql(boundSql);
mpBs.sql(this.parserSingle(mpBs.sql(), ms.getId()));
}
@Override
protected void processSelect(Select select, int index, String sql, Object obj) {
SelectBody selectBody = select.getSelectBody();
if (selectBody instanceof PlainSelect) {
this.setWhere((PlainSelect) selectBody, (String) obj);
} else if (selectBody instanceof SetOperationList) {
SetOperationList setOperationList = (SetOperationList) selectBody;
List<SelectBody> selectBodyList = setOperationList.getSelects();
selectBodyList.forEach(s -> this.setWhere((PlainSelect) s, (String) obj));
}
}
/**
* 设置 where 条件
*
* @param plainSelect 查询对象
* @param whereSegment 查询条件片段
*/
private void setWhere(PlainSelect plainSelect, String whereSegment) {
Expression sqlSegment = this.dataPermissionHandler.getSqlSegment(plainSelect, whereSegment);
if (null != sqlSegment) {
plainSelect.setWhere(sqlSegment);
}
}
}

View File

@ -22,7 +22,7 @@ public class MyMetaObjectHandler implements MetaObjectHandler {
UserDetailsImpl userInfo = SecurityUtil.getUserInfo();
this.strictInsertFill(metaObject, "createTime", LocalDateTime::now, LocalDateTime.class);
this.strictInsertFill(metaObject, "createBy", userInfo::getUsername, String.class);
this.strictInsertFill(metaObject, "createdBy", userInfo::getUsername, String.class);
}
@ -30,7 +30,7 @@ public class MyMetaObjectHandler implements MetaObjectHandler {
public void updateFill(MetaObject metaObject) {
UserDetailsImpl userInfo = SecurityUtil.getUserInfo();
this.strictUpdateFill(metaObject, "updateTime", LocalDateTime::now, LocalDateTime.class);
this.strictUpdateFill(metaObject, "updateBy", userInfo::getUsername, String.class);
this.strictUpdateFill(metaObject, "updatedBy", userInfo::getUsername, String.class);
}

View File

@ -18,6 +18,14 @@ public class MybatisPlusConfig {
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
// // 添加数据权限插件
// MyDataPermissionInterceptor dataPermissionInterceptor = new MyDataPermissionInterceptor();
// // 添加自定义的数据权限处理器
// dataPermissionInterceptor.setDataPermissionHandler(new MyDataPermissionHandler());
// interceptor.addInnerInterceptor(dataPermissionInterceptor);
return interceptor;
}
}

View File

@ -0,0 +1,64 @@
package com.zsc.edu.bill.modules.audited.audit;
import com.baomidou.mybatisplus.annotation.EnumValue;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonValue;
import com.zsc.edu.bill.modules.system.entity.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
/**
* @author ftz
* 创建时间:30/1/2024 下午8:58
* 描述: TODO
*/
@EqualsAndHashCode(callSuper = true)
@TableName(value ="Audit")
@Data
public class Audit extends BaseEntity {
/*
* 票据Id
* */
private Long ticketId;
/*
*审核员id
* */
private Long auditorId;
/*
*审核意见
*/
private String comment;
/*
* 审核状态
* */
private Result result;
@Getter
public enum Result{
PASS(2, "审核通过"),
FAILED(3, "审核未通过");
@EnumValue
private final int code;
@JsonValue
private final String name;
Result(int code, String name) {
this.code = code;
this.name = name;
}
public static Result get(String name) {
for (Result item : values()) {
if (item.getName() .equals(name)) {
return item;
}
}
return null;
}
}
}

View File

@ -0,0 +1,17 @@
package com.zsc.edu.bill.modules.audited.controller;
import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author ftz
* 创建时间:31/1/2024 下午6:52
* 描述: TODO
*/
@AllArgsConstructor
@RestController
@RequestMapping("api/rest/audit")
public class AuditeController {
}

View File

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

View File

@ -0,0 +1,22 @@
package com.zsc.edu.bill.modules.audited.mapper;
import com.zsc.edu.bill.common.mapstruct.BaseMapper;
import com.zsc.edu.bill.modules.audited.audit.Audit;
import com.zsc.edu.bill.modules.audited.dto.Auditdto;
import org.mapstruct.Mapper;
import org.mapstruct.ReportingPolicy;
/**
* @author fantianzhi
* @description 针对表audit(票据审核表 )的数据库操作Mapper
* @createDate 2024-01-31 18:30:42
* @Entity com.zsc.edu.bill.modules.audited.audit.Audit
*/
@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface AuditMapper extends BaseMapper<Auditdto,Audit> {
}

View File

@ -0,0 +1,12 @@
package com.zsc.edu.bill.modules.audited.repo;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.zsc.edu.bill.modules.audited.audit.Audit;
/**
* @author ftz
* 创建时间:31/1/2024 下午6:44
* 描述: TODO
*/
public interface AuditRepository extends BaseMapper<Audit>{
}

View File

@ -0,0 +1,13 @@
package com.zsc.edu.bill.modules.audited.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.zsc.edu.bill.modules.audited.audit.Audit;
/**
* @author fantianzhi
* @description 针对表audit(票据审核表 )的数据库操作Service
* @createDate 2024-01-31 18:30:42
*/
public interface AuditService extends IService<Audit> {
}

View File

@ -0,0 +1,23 @@
package com.zsc.edu.bill.modules.audited.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zsc.edu.bill.modules.audited.audit.Audit;
import com.zsc.edu.bill.modules.audited.repo.AuditRepository;
import com.zsc.edu.bill.modules.audited.service.AuditService;
import com.zsc.edu.bill.modules.audited.mapper.AuditMapper;
import org.springframework.stereotype.Service;
/**
* @author fantianzhi
* @description 针对表audit(票据审核表 )的数据库操作Service实现
* @createDate 2024-01-31 18:30:42
*/
@Service
public class AuditServiceImpl extends ServiceImpl<AuditRepository, Audit>
implements AuditService{
}

View File

@ -2,12 +2,13 @@ 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.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.web.bind.annotation.*;
import java.util.List;
/**
@ -68,11 +69,19 @@ public class BillController {
/**
* 获取票据详情
*
* @return 票据详情
*/
@GetMapping("{id}")
public Bill detail(@PathVariable Long id){
return service.getById(id);
public BillVo detail(@PathVariable Long id){
return service.findById(id);
}
/*
*审核票据
**/
@PatchMapping("audit/{id}")
public Boolean audit(@PathVariable Long id, @RequestBody Audit audit){
return service.audit(id, audit);
}
}

View File

@ -1,6 +1,5 @@
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;

View File

@ -23,7 +23,7 @@ public class Bill extends BaseEntity {
/**
* 票据uuid 提供给前端显示用
*/
private UUID uuid;
private String uuid;
/**
* 用户id 票据创建者id

View File

@ -5,6 +5,7 @@ package com.zsc.edu.bill.modules.bills.mapper;
import com.zsc.edu.bill.common.mapstruct.BaseMapper;
import com.zsc.edu.bill.modules.bills.dto.BillDto;
import com.zsc.edu.bill.modules.bills.entity.Bill;
import org.apache.ibatis.annotations.Param;
import org.mapstruct.Mapper;
import org.mapstruct.ReportingPolicy;

View File

@ -2,10 +2,14 @@ package com.zsc.edu.bill.modules.bills.repo;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.zsc.edu.bill.modules.bills.entity.Bill;
import com.zsc.edu.bill.modules.bills.vo.BillVo;
import org.apache.ibatis.annotations.Select;
/**
* @author yao
*/
public interface BillRepository extends BaseMapper<Bill> {
BillVo findById(Long id);
}

View File

@ -3,7 +3,9 @@ package com.zsc.edu.bill.modules.bills.service;
import com.baomidou.mybatisplus.extension.service.IService;
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.vo.BillVo;
/**
* @author fantianzhi
@ -15,4 +17,8 @@ public interface BillService extends IService<Bill> {
Boolean create(BillDto dto);
Boolean update(BillDto dto, Long id);
BillVo findById(Long id);
Boolean audit(Long id, Audit audit);
}

View File

@ -2,14 +2,15 @@ package com.zsc.edu.bill.modules.bills.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
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.mapper.BillMapper;
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;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.UUID;
/**
@ -20,11 +21,12 @@ import java.util.UUID;
public class BillServiceImpl extends ServiceImpl<BillRepository, Bill> implements BillService {
private final BillMapper mapper;
private final BillRepository repository;
@Override
public Boolean create(BillDto dto) {
Bill bill = mapper.toEntity(dto);
bill.setUuid(UUID.randomUUID());
bill.setUuid(UUID.randomUUID().toString());
return save(bill);
}
@ -34,6 +36,30 @@ public class BillServiceImpl extends ServiceImpl<BillRepository, Bill> implement
mapper.convert(dto, bill);
return updateById(bill);
}
@Override
public BillVo findById(Long id) {
Bill bill = getById(id);
BillVo vo = new BillVo();
return repository.findById(id);
}
@Override
public Boolean audit(Long id, Audit audit) {
Bill bill = getById(id);
if (bill != null) {
bill.setStatus(Bill.Status.valueOf(audit.getResult().getName()));
return updateById(bill);
}
// Audit audit1 =
return null;
}
}

View File

@ -0,0 +1,19 @@
package com.zsc.edu.bill.modules.bills.vo;
import com.zsc.edu.bill.modules.audited.audit.Audit;
import com.zsc.edu.bill.modules.bills.entity.Bill;
import lombok.Data;
/**
* @author ftz
* 创建时间:30/1/2024 下午8:35
* 描述: TODO
*/
@Data
public class BillVo {
Bill bill;
Audit audit;
}

View File

@ -0,0 +1,116 @@
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

@ -0,0 +1,64 @@
package com.zsc.edu.bill.modules.file.dto;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author ftz
* 创建时间:29/1/2024 上午10:00
* 描述: 附件Dto
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class AttachFileDto {
/**
* 文件名 文件名详细说明
*/
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;
/**
*文件url
*/
private String fileUrl;
}

View File

@ -0,0 +1,75 @@
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

@ -0,0 +1,23 @@
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

@ -0,0 +1,54 @@
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

@ -0,0 +1,12 @@
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

@ -0,0 +1,23 @@
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

@ -0,0 +1,130 @@
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

@ -0,0 +1,28 @@
package com.zsc.edu.bill.modules.file.util;
import java.io.File;
/**
* @author ftz
* 创建时间:30/1/2024 下午1:59
* 描述: TODO
*/
public class UploadUtils {
// 项目根路径下的目录 -- SpringBoot static 目录相当于是根路径下SpringBoot 默认
public final static String IMG_PATH_PREFIX = "static/upload/file";
public static File getImgDirFile(){
// 构建上传文件的存放 "文件夹" 路径
String fileDirPath = new String("src/main/resources/" + IMG_PATH_PREFIX);
File fileDir = new File(fileDirPath);
if(!fileDir.exists()){
// 递归生成文件夹
fileDir.mkdirs();
}
return fileDir;
}
}

View File

@ -5,7 +5,6 @@ import lombok.Data;
import lombok.NoArgsConstructor;
import jakarta.validation.constraints.*;
import java.util.Set;
/**
* 用户新建Dto
@ -57,7 +56,7 @@ public class UserCreateDto {
* 用户身份集合
*/
//@NotEmpty(message = "角色不能为空")
public Set<Long> roleIds;
public Long roleId;
/**
* 昵称
* */

View File

@ -33,13 +33,23 @@ public class BaseEntity implements Serializable {
*/
@TableField(value = "create_time", fill = FieldFill.INSERT)
public LocalDateTime createTime;
/*
* 创建人
* */
@TableField(value = "create_by", fill = FieldFill.INSERT)
public String createBy;
/**
* 更新时间
*/
@TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE)
public LocalDateTime updateTime;
/*
* 更新人
*
* */
@TableField(value = "update_by", fill = FieldFill.INSERT_UPDATE)
public String updateBy;
@Override
public boolean equals(Object o) {
if (this == o) {

View File

@ -32,6 +32,4 @@ public interface UserRepository extends BaseMapper<User> {
// "where u.username = #{username}")
// User findByUsername(String username);
User selectByUsername(String username);
Page<UserVo> page2(PageDTO<User> page, LambdaQueryWrapper<User> wrapper);
}

View File

@ -97,7 +97,12 @@ public class UserServiceImpl extends ServiceImpl<UserRepository, User> implement
throw new ConstraintException("email", dto.email, "邮箱地址已存在");
}
user.setPassword(passwordEncoder.encode(dto.password));
user.setRoleId(roleService.getOne(new LambdaQueryWrapper<Role>().eq(Role::getName, "普通用户")).getId());
if (dto.getRoleId()== null||dto.getRoleId() ==' ') {
user.setRoleId(roleService.getOne(new LambdaQueryWrapper<Role>().eq(Role::getName, "普通用户")).getId());
}else {
user.setRoleId(dto.getRoleId());
}
return save(user);
}
@ -122,6 +127,7 @@ public class UserServiceImpl extends ServiceImpl<UserRepository, User> implement
.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());

View File

@ -9,7 +9,11 @@ mybatis-plus:
spring:
datasource:
url: jdbc:mysql://localhost:3306/study?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
driver-class-name: com.mysql.cj.jdbc.Driver
password: 2002
driver-class-name: com.mysql.cj.jdbc.Driver
servlet:
multipart:
max-file-size: 40MB
max-request-size: 40MB

View File

@ -0,0 +1,30 @@
<?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

@ -0,0 +1,26 @@
<?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.audited.mapper.AuditMapper">
<resultMap id="BaseResultMap" type="com.zsc.edu.bill.modules.audited.audit.Audit">
<id property="id" column="id" jdbcType="BIGINT"/>
<result property="ticketId" column="ticket_id" jdbcType="BIGINT"/>
<result property="auditorId" column="auditor_id" jdbcType="BIGINT"/>
<result property="comment" column="comment" jdbcType="VARCHAR"/>
<result property="result" column="result" jdbcType="TINYINT"/>
<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="remark" column="remark" jdbcType="VARCHAR"/>
</resultMap>
<sql id="Base_Column_List">
id,ticket_id,auditor_id,
comment,result,create_by,
create_time,update_by,update_time,
remark
</sql>
</mapper>

View File

@ -0,0 +1,69 @@
<?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.bills.repo.BillRepository">
<resultMap id="BaseResultMap" type="com.zsc.edu.bill.modules.bills.entity.Bill">
<id property="id" column="id" jdbcType="BIGINT"/>
<result property="uuid" column="uuid" jdbcType="VARCHAR"/>
<result property="userId" column="user_id" jdbcType="BIGINT"/>
<result property="title" column="title" jdbcType="VARCHAR"/>
<result property="body" column="body" jdbcType="VARCHAR"/>
<result property="money" column="money" jdbcType="DECIMAL"/>
<result property="status" column="status" jdbcType="TINYINT"/>
<result property="type" column="type" jdbcType="TINYINT"/>
<result property="contactEmail" column="contact_email" jdbcType="VARCHAR"/>
<result property="companyName" column="company_name" jdbcType="VARCHAR"/>
<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="remark" column="remark" 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">
<id property="id" column="id" jdbcType="BIGINT"/>
<result property="uuid" column="uuid" jdbcType="VARCHAR"/>
<result property="userId" column="user_id" jdbcType="BIGINT"/>
<result property="title" column="title" jdbcType="VARCHAR"/>
<result property="body" column="body" jdbcType="VARCHAR"/>
<result property="money" column="money" jdbcType="DECIMAL"/>
<result property="status" column="status" jdbcType="TINYINT"/>
<result property="type" column="type" jdbcType="TINYINT"/>
<result property="contactEmail" column="contact_email" jdbcType="VARCHAR"/>
<result property="companyName" column="company_name" jdbcType="VARCHAR"/>
<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="remark" column="remark" jdbcType="VARCHAR"/>
</collection>
<collection property="audit" ofType="com.zsc.edu.bill.modules.audited.audit.Audit">
<id property="id" 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"/>
<result property="comment" column="comment" jdbcType="VARCHAR"/>
<result property="remark" column="remark" jdbcType="VARCHAR"/>
</collection>
</resultMap>
<sql id="Base_Column_List">
id,uuid,user_id,
title,body,money,
status,type,contact_email,
company_name,create_by,create_time,
update_by,update_time,remark
</sql>
<select id="findById" parameterType="java.lang.Long" resultMap="BaseResultMap1">
SELECT
*
FROM
bill AS a
LEFT JOIN ( audit AS b ) ON a.id = b.ticket_id
WHERE
a.id = ${id}
</select>
</mapper>

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 858 KiB