• 全部
...

SpringBoot 实现审核功能

狮子也疯狂 元老
全栈领域优质创作者
博客专家认证
2023-07-24 08:57:35
blog.csdn.net/weixin_65950231/article/details/128756143

一、审核功能实现的方式

1、普通

方案:经办时入A表,审核后从A表读取数据,然后操作目标B表;

优势:思路简单

劣势:对后端功能实行高度的嵌入;审核功能数据操作不统一

2、弹框式

方案:前台实现,操作时判断是否需要权限控制,如果需要,则弹出框,由审核人员进行审核,审核通过后,进行后续操作。

优势:对后台功能无嵌入;可支持查询、导出、操作等全部功能;

劣势:需要经办人和审核人同时在场操作

3、入参缓冲时

方案:审核功能是独立的功能,前台发起业务后,入参存入数据库。待审核通过后,后台触发调用相应的接口,并将执行结果通知到经办人。

优势:对前后台功能均无嵌入;支持导出及操作类;经办人和审核人可以异步操作;审核功能数据操作统一;

劣势:需要框架层支持;实现逻辑稍微复杂

4、临时表

方案:所有需要审核功能涉及的表均增加相应的表,该表比源表主要增加1个字段,即审核流水,其余字段命名完全一致;所有功能操作时先入该表,审核通过后,由后台从该表将数据同步至正表。

优势:无需要框架支持;支持导出及操作类;经办人和审核人可以异步操作;审核功能数据操作统一;

劣势:对后端功能实行高度的嵌入;


二、SpringBoot实现

1.创建数据库表SQL

  1. CREATE TABLE `audit` (
  2. `id` int NOT NULL AUTO_INCREMENT COMMENT 'ID',
  3. `name` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '报修名称',
  4. `user` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '报修人',
  5. `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '报修时间',
  6. `img` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '详情图片',
  7. `state` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT '待审核' COMMENT '待审核,审核通过,审核不通过',
  8. PRIMARY KEY (`id`)
  9. ) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

2.写Java后端

图片

其实审核功能最主要的就是我们的新增功能,用户只有新增过后,我们的管理员才能去对你的申请进行审核,最后实现效果。

AuditController

  1. import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
  2. import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
  3. import com.example.demo.common.Result;
  4. import com.example.demo.entity.Audit;
  5. import com.example.demo.entity.Sanitation;
  6. import com.example.demo.entity.User;
  7. import com.example.demo.mapper.FileMapper;
  8. import com.example.demo.service.IAuditService;
  9. import com.example.demo.utils.TokenUtils;
  10. import org.springframework.web.bind.annotation.*;
  11. import javax.annotation.Resource;
  12. import java.util.List;
  13. @CrossOrigin
  14. @RestController
  15. @RequestMapping("/audit")
  16. public class AuditController {
  17. @Resource
  18. private IAuditService auditService;
  19. @Resource
  20. private FileMapper fileMapper;
  21. // //新增或者更新
  22. // @PostMapping
  23. // public Result save(@RequestBody Audit audit) {
  24. // audit.setUser(TokenUtils.getCurrentUser().getUsername());
  25. audit.setImg(Files.url);
  26. // return Result.success(auditService.saveOrUpdate(audit));
  27. // }
  28. // 新增或者更新
  29. @PostMapping
  30. public Result save(@RequestBody Audit audit) {
  31. if (audit.getId() == null) {
  32. // 新增
  33. audit.setUser(TokenUtils.getCurrentUser().getUsername());
  34. }
  35. auditService.saveOrUpdate(audit);
  36. return Result.success();
  37. }
  38. //删除
  39. // @DeleteMapping("/{id}")
  40. // public Result delete(@PathVariable Integer id) {
  41. // return Result.success(userService.removeById(id));
  42. // }
  43. @PostMapping("/del/batch")
  44. public Result deleteBatch(@RequestBody List<Integer> ids) {//批量删除
  45. return Result.success(auditService.removeByIds(ids));
  46. }
  47. //查询所有数据
  48. @GetMapping
  49. public Result findAll() {
  50. return Result.success(auditService.list());
  51. }
  52. // @GetMapping("/role/{role}")
  53. // public Result findNames(@PathVariable String role) {
  54. // QueryWrapper<Audit> queryWrapper = new QueryWrapper<>();
  55. // queryWrapper.eq("role", role);
  56. // List<Audit> list = auditService.list(queryWrapper);
  57. // return Result.success(list);
  58. // }
  59. @GetMapping("/{id}")
  60. public Result findOne(@PathVariable Integer id) {
  61. return Result.success(auditService.getById(id));
  62. }
  63. @GetMapping("/username/{username}")
  64. public Result findByUsername(@PathVariable String username) {
  65. QueryWrapper<Audit> queryWrapper = new QueryWrapper<>();
  66. queryWrapper.eq("username", username);
  67. return Result.success(auditService.getOne(queryWrapper));
  68. }
  69. @GetMapping("/page")
  70. public Result findPage(@RequestParam Integer pageNum,
  71. @RequestParam Integer pageSize,
  72. @RequestParam(defaultValue = "") String name) {
  73. QueryWrapper<Audit> queryWrapper = new QueryWrapper<>();
  74. queryWrapper.orderByDesc("id");
  75. if (!"".equals(name)) {
  76. queryWrapper.like("name", name);
  77. }
  78. User currentUser = TokenUtils.getCurrentUser();
  79. // if (RoleEnum.ROLE_USER.toString().equals(currentUser.getRole())) { // 角色是普通用户
  80. // queryWrapper.eq("user", currentUser.getUsername());
  81. // }
  82. return Result.success(auditService.page(new Page<>(pageNum, pageSize), queryWrapper));
  83. }
  84. }

三、前端调用

1.实现效果

图片

2.核心代码

图片

  1. <el-table-column label="审核" width="240">
  2. <template v-slot="scope">
  3. <el-button type="success" @click="changeState(scope.row, '审核通过...师傅正在赶来的路上')" :disabled="scope.row.state !== '待审核'">审核通过</el-button>
  4. <el-button type="danger" @click="changeState(scope.row, '审核不通过')" :disabled="scope.row.state !== '待审核'">审核不通过</el-button>
  5. </template>
  6. </el-table-column>

3.后台管理

图片

4.后台管理核心代码

  1. import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
  2. import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
  3. import com.example.demo.common.Result;
  4. import com.example.demo.entity.Audit;
  5. import com.example.demo.entity.User;
  6. import com.example.demo.mapper.FileMapper;
  7. import com.example.demo.service.IAuditService;
  8. import com.example.demo.utils.TokenUtils;
  9. import org.springframework.web.bind.annotation.*;
  10. import javax.annotation.Resource;
  11. import java.util.List;
  12. @CrossOrigin
  13. @RestController
  14. @RequestMapping("/audit")
  15. public class AuditController {
  16. @Resource
  17. private IAuditService auditService;
  18. @Resource
  19. private FileMapper fileMapper;
  20. // //新增或者更新
  21. // @PostMapping
  22. // public Result save(@RequestBody Audit audit) {
  23. // audit.setUser(TokenUtils.getCurrentUser().getUsername());
  24. audit.setImg(Files.url);
  25. // return Result.success(auditService.saveOrUpdate(audit));
  26. // }
  27. // 新增或者更新
  28. @PostMapping
  29. public Result save(@RequestBody Audit audit) {
  30. if (audit.getId() == null) {
  31. // 新增
  32. audit.setUser(TokenUtils.getCurrentUser().getUsername());
  33. }
  34. auditService.saveOrUpdate(audit);
  35. return Result.success();
  36. }
  37. //删除
  38. // @DeleteMapping("/{id}")
  39. // public Result delete(@PathVariable Integer id) {
  40. // return Result.success(userService.removeById(id));
  41. // }
  42. @PostMapping("/del/batch")
  43. public Result deleteBatch(@RequestBody List<Integer> ids) {//批量删除
  44. return Result.success(auditService.removeByIds(ids));
  45. }
  46. //查询所有数据
  47. @GetMapping
  48. public Result findAll() {
  49. return Result.success(auditService.list());
  50. }
  51. @GetMapping("/{id}")
  52. public Result findOne(@PathVariable Integer id) {
  53. return Result.success(auditService.getById(id));
  54. }
  55. @GetMapping("/username/{username}")
  56. public Result findByUsername(@PathVariable String username) {
  57. QueryWrapper<Audit> queryWrapper = new QueryWrapper<>();
  58. queryWrapper.eq("username", username);
  59. return Result.success(auditService.getOne(queryWrapper));
  60. }
  61. @GetMapping("/page")
  62. public Result findPage(@RequestParam Integer pageNum,
  63. @RequestParam Integer pageSize,
  64. @RequestParam(defaultValue = "") String name) {
  65. QueryWrapper<Audit> queryWrapper = new QueryWrapper<>();
  66. queryWrapper.orderByDesc("id");
  67. if (!"".equals(name)) {
  68. queryWrapper.like("name", name);
  69. }
  70. User currentUser = TokenUtils.getCurrentUser();
  71. // if (RoleEnum.ROLE_USER.toString().equals(currentUser.getRole())) { // 角色是普通用户
  72. // queryWrapper.eq("user", currentUser.getUsername());
  73. // }
  74. return Result.success(auditService.page(new Page<>(pageNum, pageSize), queryWrapper));
  75. }
  76. }

5.vue前台完整代码

(1)、前台功能页面

前台负责新增请求,然后保存请求之后,我们管理员审核通过之后就不可以编辑和删除我们的请求,我们会保留数据在前台页面

  1. <template>
  2. <div>
  3. <div style="margin: 10px 0">
  4. <el-input style="width: 200px; margin-left: 10px" placeholder="请输入报修描述" clearable v-model="name" ></el-input>
  5. <el-button class="ml-5" type="primary" @click="load"><i class="el-icon-search" />搜索</el-button>
  6. <el-button type="warning" @click="reset"><i class="el-icon-refresh" />刷新</el-button>
  7. </div>
  8. <div style="margin: 10px 0">
  9. <el-button type="primary" @click="handleAdd" class="ml-10"><i class="el-icon-circle-plus-outline" />新增</el-button>
  10. <el-popconfirm
  11. class="ml-5"
  12. confirm-button-text='确认'
  13. cancel-button-text='取消'
  14. icon="el-icon-info"
  15. icon-color="red"
  16. title="确定批量删除这些信息吗?"
  17. @confirm="delBatch">
  18. <el-button type="danger" slot="reference" ><i class="el-icon-remove-outline" />删除</el-button>
  19. </el-popconfirm>
  20. </div>
  21. <el-table :data="tableData" border stripe :header-cell-class-name="headerBg"
  22. @selection-change="handleSelectionChange">
  23. <el-table-column type="selection" width="55"></el-table-column>
  24. <el-table-column prop="name" label="报修描述" ></el-table-column>
  25. <el-table-column prop="user" label="用户" ></el-table-column>
  26. <el-table-column prop="createTime" label="创建时间" ></el-table-column>
  27. <el-table-column label="图片">
  28. <template slot-scope="scope">
  29. <el-image style="width: 100px; height: 100px" :src="scope.row.img" :preview-src-list="[scope.row.img]"></el-image>
  30. </template>
  31. </el-table-column>
  32. <el-table-column prop="state" label="进度"></el-table-column>
  33. <el-table-column label="操作">
  34. <template slot-scope="scope">
  35. <el-button type="success" @click="handleEdit(scope.row)" :disabled="scope.row.state !== '待审核'"><i class="el-icon-edit-outline" />编辑</el-button>
  36. </template>
  37. </el-table-column>
  38. </el-table>
  39. <div style="padding: 10px 0">
  40. <el-pagination
  41. @size-change="handleSizeChange"
  42. @current-change="handleCurrentChange"
  43. :current-page="pageNum"
  44. :page-sizes="[ 5, 10, 15]"
  45. :page-size="pageSize"
  46. layout="total, sizes, prev, pager, next, jumper"
  47. :total="total">
  48. </el-pagination>
  49. </div>
  50. <el-dialog title="用户信息" :visible.sync="dialogFormVisible" width="30%">
  51. <el-form label-width="100px" size="small">
  52. <el-form-item label="报修描述" >
  53. <el-input v-model="form.name" autocomplete="off"></el-input>
  54. </el-form-item>
  55. <el-form-item label="物品图片">
  56. <el-upload action="http://localhost:9090/file/upload" ref="img" :on-success="handleImgUploadSuccess">
  57. <el-button size="small" type="primary">点击上传</el-button>
  58. </el-upload>
  59. </el-form-item>
  60. </el-form>
  61. <div slot="footer" class="dialog-footer">
  62. <el-button @click="dialogFormVisible = false">取 消</el-button>
  63. <el-button type="primary" @click="save">确 定</el-button>
  64. </div>
  65. </el-dialog>
  66. </div>
  67. </template>
  68. <script>
  69. export default {
  70. name: "Audit",
  71. data() {
  72. return {
  73. tableData: [],
  74. total: 0,
  75. pageNum: 1,
  76. pageSize: 5,
  77. name: "",
  78. form: {},
  79. dialogFormVisible: false,
  80. multipleSelection: [],
  81. headerBg: "headerBg",
  82. roles: [],
  83. user: localStorage.getItem("user") ? JSON.parse(localStorage.getItem("user")) : {}
  84. }
  85. },
  86. created() {
  87. this.load()
  88. },
  89. methods: {
  90. load: function () {
  91. this.request.get("/audit/page", {
  92. params: {
  93. pageNum: this.pageNum,
  94. pageSize: this.pageSize,
  95. name: this.name,
  96. }
  97. }).then(res => {
  98. this.tableData = res.data.records
  99. this.total = res.data.total
  100. })
  101. // this.request.get("/role").then(res => {
  102. // this.roles = res.data
  103. // })
  104. },
  105. home() {
  106. this.$router.push("/")
  107. },
  108. save() {
  109. this.request.post("/audit", this.form).then(res => {
  110. if (res.code === '200') {
  111. this.$message.success("保存成功")
  112. this.dialogFormVisible = false
  113. this.load()
  114. } else {
  115. this.$message.error("保存失败")
  116. }
  117. })
  118. },
  119. handleAdd() {
  120. this.dialogFormVisible = true
  121. this.form = {}
  122. },
  123. handleEdit(row) {
  124. this.form = row
  125. this.dialogFormVisible = true
  126. },
  127. handleSelectionChange(val) {
  128. console.log(val)
  129. this.multipleSelection = val;
  130. },
  131. delBatch() {
  132. let ids = this.multipleSelection.map(v => v.id) //[{}, {}, {}] => [1,2,3]
  133. this.request.post("/audit/del/batch", ids).then(res => {
  134. if (res.code === '200') {
  135. this.$message.success("删除信息成功")
  136. this.load()
  137. } else {
  138. this.$message.error("删除信息失败")
  139. }
  140. })
  141. },
  142. reset() {
  143. this.name = ""
  144. this.load()
  145. },
  146. handleSizeChange(pageSize) {
  147. console.log(pageSize)
  148. this.pageSize = pageSize
  149. this.load()
  150. },
  151. handleCurrentChange(pageNum) {
  152. console.log(pageNum)
  153. this.pageNum = pageNum
  154. this.load()
  155. },
  156. handleImgUploadSuccess(res) {
  157. this.form.img = res
  158. },
  159. }
  160. }
  161. </script>
  162. <style>
  163. .headerBg {
  164. background: #eee!important;
  165. }
  166. </style>

(2)、后台管理功能页面

  1. <template>
  2. <div>
  3. <!-- <div style="margin: 10px 0">-->
  4. <!-- <el-input style="width: 200px; margin-left: 10px" placeholder="请输入用户名" clearable suffix-icon="el-icon-user" v-model="username" ></el-input>-->
  5. <!-- <el-button class="ml-5" type="primary" @click="load"><i class="el-icon-search" />搜索</el-button>-->
  6. <!-- <el-button type="warning" @click="reset"><i class="el-icon-refresh" />刷新</el-button>-->
  7. <!-- </div>-->
  8. <div style="margin: 10px 0">
  9. <!-- <el-button type="primary" @click="handleAdd" class="ml-10"><i class="el-icon-circle-plus-outline" />新增</el-button>-->
  10. <el-popconfirm
  11. class="ml-5"
  12. confirm-button-text='确认'
  13. cancel-button-text='取消'
  14. icon="el-icon-info"
  15. icon-color="red"
  16. title="确定批量删除这些信息吗?"
  17. @confirm="delBatch">
  18. <el-button type="danger" slot="reference" ><i class="el-icon-remove-outline" />删除</el-button>
  19. </el-popconfirm>
  20. </div>
  21. <el-table :data="tableData" border stripe :header-cell-class-name="headerBg"
  22. @selection-change="handleSelectionChange">
  23. <el-table-column type="selection" width="55"></el-table-column>
  24. <el-table-column prop="name" label="报修描述" ></el-table-column>
  25. <el-table-column prop="user" label="用户" ></el-table-column>
  26. <el-table-column prop="createTime" label="创建时间" ></el-table-column>
  27. <el-table-column prop="img" label="详情图片" >
  28. <template slot-scope="scope">
  29. <el-image style="width: 100px; height: 100px" :src="scope.row.img" :preview-src-list="[scope.row.img]"></el-image>
  30. </template>
  31. </el-table-column>
  32. <el-table-column prop="state" label="进度"></el-table-column>
  33. <el-table-column label="审核" width="240">
  34. <template v-slot="scope">
  35. <el-button type="success" @click="changeState(scope.row, '审核通过...师傅正在赶来的路上')" :disabled="scope.row.state !== '待审核'">审核通过</el-button>
  36. <el-button type="danger" @click="changeState(scope.row, '审核不通过')" :disabled="scope.row.state !== '待审核'">审核不通过</el-button>
  37. </template>
  38. </el-table-column>
  39. </el-table>
  40. <div style="padding: 10px 0">
  41. <el-pagination
  42. @size-change="handleSizeChange"
  43. @current-change="handleCurrentChange"
  44. :current-page="pageNum"
  45. :page-sizes="[ 5, 10, 15]"
  46. :page-size="pageSize"
  47. layout="total, sizes, prev, pager, next, jumper"
  48. :total="total">
  49. </el-pagination>
  50. </div>
  51. </div>
  52. </template>
  53. <script>
  54. export default {
  55. name: "Audit",
  56. data() {
  57. return {
  58. tableData: [],
  59. total: 0,
  60. pageNum: 1,
  61. pageSize: 5,
  62. username: "",
  63. form: {},
  64. // dialogFormVisible: false,
  65. multipleSelection: [],
  66. headerBg: "headerBg",
  67. roles: [],
  68. user: localStorage.getItem("user") ? JSON.parse(localStorage.getItem("user")) : {},
  69. }
  70. },
  71. created() {
  72. this.load()
  73. },
  74. methods: {
  75. load: function () {
  76. this.request.get("/audit/page", {
  77. params: {
  78. pageNum: this.pageNum,
  79. pageSize: this.pageSize,
  80. username: this.username,
  81. }
  82. }).then(res => {
  83. this.tableData = res.data.records
  84. this.total = res.data.total
  85. })
  86. this.request.get("/role").then(res => {
  87. this.roles = res.data
  88. })
  89. },
  90. home() {
  91. this.$router.push("/")
  92. },
  93. save() {
  94. this.request.post("/audit", this.form).then(res => {
  95. if (res.code === '200') {
  96. this.$message.success("保存成功")
  97. this.dialogFormVisible = false
  98. this.load()
  99. } else {
  100. this.$message.error("保存失败")
  101. }
  102. })
  103. },
  104. handleAdd() {
  105. this.dialogFormVisible = true
  106. this.form = {}
  107. },
  108. handleEdit(row) {
  109. this.form = row
  110. this.dialogFormVisible = true
  111. },
  112. handleSelectionChange(val) {
  113. console.log(val)
  114. this.multipleSelection = val;
  115. },
  116. delBatch() {
  117. let ids = this.multipleSelection.map(v => v.id) //[{}, {}, {}] => [1,2,3]
  118. this.request.post("/audit/del/batch", ids).then(res => {
  119. if (res.code === '200') {
  120. this.$message.success("删除信息成功")
  121. this.load()
  122. } else {
  123. this.$message.error("删除信息失败")
  124. }
  125. })
  126. },
  127. reset() {
  128. this.username = ""
  129. this.load()
  130. },
  131. handleSizeChange(pageSize) {
  132. console.log(pageSize)
  133. this.pageSize = pageSize
  134. this.load()
  135. },
  136. handleCurrentChange(pageNum) {
  137. console.log(pageNum)
  138. this.pageNum = pageNum
  139. this.load()
  140. },
  141. changeState(row, state) {
  142. this.form = JSON.parse(JSON.stringify(row))
  143. this.form.state = state;
  144. this.save();
  145. },
  146. // handleImgUploadSuccess() {
  147. // this.$message.success("图片上传成功")
  148. // this.load()
  149. // },
  150. }
  151. }
  152. </script>
  153. <style>
  154. .headerBg {
  155. background: #eee!important;
  156. }
  157. </style>

重点!!!!图片上传

图片

核心代码

  1. CREATE TABLE `file` (
  2. `id` int NOT NULL AUTO_INCREMENT COMMENT 'ID',
  3. `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '文件名称',
  4. `type` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '文件类型',
  5. `size` bigint DEFAULT NULL COMMENT '文件大小(kb)',
  6. `url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '下载链接',
  7. `md5` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '文件md5',
  8. `creat_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '时间',
  9. `is_delete` tinyint(1) DEFAULT '0' COMMENT '是否删除',
  10. PRIMARY KEY (`id`) USING BTREE
  11. ) ENGINE=InnoDB AUTO_INCREMENT=115 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
  12. import cn.hutool.core.io.FileUtil;
  13. import cn.hutool.core.util.IdUtil;
  14. import cn.hutool.core.util.StrUtil;
  15. import cn.hutool.crypto.SecureUtil;
  16. import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
  17. import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
  18. import com.example.demo.common.Constants;
  19. import com.example.demo.common.Result;
  20. import com.example.demo.entity.Files;
  21. import com.example.demo.mapper.FileMapper;
  22. import org.springframework.beans.factory.annotation.Autowired;
  23. import org.springframework.beans.factory.annotation.Value;
  24. import org.springframework.data.redis.core.StringRedisTemplate;
  25. import org.springframework.web.bind.annotation.*;
  26. import org.springframework.web.multipart.MultipartFile;
  27. import javax.annotation.Resource;
  28. import javax.servlet.ServletOutputStream;
  29. import javax.servlet.http.HttpServletResponse;
  30. import java.io.File;
  31. import java.io.IOException;
  32. import java.net.URLEncoder;
  33. import java.util.List;
  34. @RestController
  35. @RequestMapping("/file")
  36. public class FileController {
  37. @Value("${files.upload.path}")
  38. private String fileUploadPath;
  39. @Value("${server.ip}")
  40. private String serverIp;
  41. @Resource
  42. private FileMapper fileMapper;
  43. @Autowired
  44. private StringRedisTemplate stringRedisTemplate;
  45. @PostMapping("/upload")
  46. public String upload(@RequestParam MultipartFile file) throws IOException {
  47. String originalFilename = file.getOriginalFilename();
  48. String type = FileUtil.extName(originalFilename);
  49. long size = file.getSize();
  50. // 定义一个文件唯一的标识码
  51. String fileUUID = IdUtil.fastSimpleUUID() + StrUtil.DOT + type;
  52. File uploadFile = new File(fileUploadPath + fileUUID);
  53. // 判断配置的文件目录是否存在,若不存在则创建一个新的文件目录
  54. File parentFile = uploadFile.getParentFile();
  55. //判断目录是否存在,不存在就新建
  56. if (!parentFile.exists()) {
  57. parentFile.mkdirs();
  58. }
  59. String url;
  60. // 获取文件的md5
  61. String md5 = SecureUtil.md5(file.getInputStream());
  62. // 从数据库查询是否存在相同的记录
  63. Files dbFiles = getFileByMd5(md5);
  64. if (dbFiles != null) {
  65. url = dbFiles.getUrl();
  66. } else {
  67. // 上传文件到磁盘
  68. file.transferTo(uploadFile);
  69. // 数据库若不存在重复文件,则不删除刚才上传的文件
  70. url = "http://" + serverIp + ":9090/file/" + fileUUID;
  71. }
  72. //存储到数据库
  73. Files saveFile = new Files();
  74. saveFile.setName(originalFilename);
  75. saveFile.setType(type);
  76. saveFile.setSize(size/1024);
  77. saveFile.setUrl(url);
  78. saveFile.setMd5(md5);
  79. fileMapper.insert(saveFile);
  80. return url;
  81. // String md5 = SecureUtil.md5(file.getInputStream());
  82. // Files files = getFileByMd5(md5);
  83. //
  84. // String url;
  85. // if (files != null) {
  86. // url = files.getUrl();
  87. // } else {
  88. // file.transferTo(uploadFile);
  89. // url = "http://localhost:9090/file/" + fileUUID;
  90. // }
  91. // //存储到数据库
  92. // Files saveFile = new Files();
  93. // saveFile.setName(originalFilename);
  94. // saveFile.setType(type);
  95. // saveFile.setSize(size/1024);
  96. // saveFile.setUrl(url);
  97. // saveFile.setMd5(md5);
  98. // fileMapper.insert(saveFile);
  99. // return url;
  100. }
  101. @GetMapping("/{fileUUID}")
  102. public void download(@PathVariable String fileUUID, HttpServletResponse response) throws IOException {
  103. // 根据文件的唯一标识码获取文件
  104. File uploadFile = new File(fileUploadPath + fileUUID);
  105. // 设置输出流的格式
  106. ServletOutputStream os = response.getOutputStream();
  107. response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileUUID, "UTF-8"));
  108. response.setContentType("application/octet-stream");
  109. // 读取文件的字节流
  110. os.write(FileUtil.readBytes(uploadFile));
  111. os.flush();
  112. os.close();
  113. }
  114. /**
  115. * 通过文件的md5查询文件
  116. * @param md5
  117. * @return
  118. */
  119. private Files getFileByMd5(String md5) {
  120. // 查询文件的md5是否存在
  121. QueryWrapper<Files> queryWrapper = new QueryWrapper<>();
  122. queryWrapper.eq("md5", md5);
  123. List<Files> filesList = fileMapper.selectList(queryWrapper);
  124. return filesList.size() == 0 ? null : filesList.get(0);
  125. }
  126. // @CachePut(value = "files", key = "'frontAll'")
  127. @PostMapping("/update")
  128. public Result update(@RequestBody Files files) {
  129. fileMapper.updateById(files);
  130. flushRedis(Constants.FILES_KEY);
  131. return Result.success();
  132. }
  133. @GetMapping("/detail/{id}")
  134. public Result getById(@PathVariable Integer id) {
  135. return Result.success(fileMapper.selectById(id));
  136. }
  137. //清除一条缓存,key为要清空的数据
  138. // @CacheEvict(value="files",key="'frontAll'")
  139. @DeleteMapping("/{id}")
  140. public Result delete(@PathVariable Integer id) {
  141. Files files = fileMapper.selectById(id);
  142. files.setIsDelete(true);
  143. fileMapper.updateById(files);
  144. flushRedis(Constants.FILES_KEY);
  145. return Result.success();
  146. }
  147. @PostMapping("/del/batch")
  148. public Result deleteBatch(@RequestBody List<Integer> ids) {
  149. // select * from sys_file where id in (id,id,id...)
  150. QueryWrapper<Files> queryWrapper = new QueryWrapper<>();
  151. queryWrapper.in("id", ids);
  152. List<Files> files = fileMapper.selectList(queryWrapper);
  153. for (Files file : files) {
  154. file.setIsDelete(true);
  155. fileMapper.updateById(file);
  156. }
  157. return Result.success();
  158. }
  159. /**
  160. * 分页查询接口
  161. * @param pageNum
  162. * @param pageSize
  163. * @param name
  164. * @return
  165. */
  166. @GetMapping("/page")
  167. public Result findPage(@RequestParam Integer pageNum,
  168. @RequestParam Integer pageSize,
  169. @RequestParam(defaultValue = "") String name) {
  170. QueryWrapper<Files> queryWrapper = new QueryWrapper<>();
  171. // 查询未删除的记录
  172. queryWrapper.eq("is_delete", false);
  173. queryWrapper.orderByDesc("id");
  174. if (!"".equals(name)) {
  175. queryWrapper.like("name", name);
  176. }
  177. return Result.success(fileMapper.selectPage(new Page<>(pageNum, pageSize), queryWrapper));
  178. }
  179. // 删除缓存
  180. private void flushRedis(String key) {
  181. stringRedisTemplate.delete(key);
  182. }
  183. }

小结


以上就是对怎么利用SpringBoot实现审核功能简单的概述,让我们更加了解SpringBoot的作用,为我们的知识储备又加上一笔。

...全文
给本帖投票
125 回复 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

118

社区成员

发帖
与我相关
我的任务
社区描述
csdn新星计划top3 | csdn全栈新星创作者 | 阿里云博客专家 | 喜欢编程,主攻Java后端方向 | 希望在csdn能和你共同进步
java-zookeeperjava-rabbitmqspring boot 个人社区 广东省·广州市
社区管理员
  • 狮子也疯狂
  • 码银
  • bluetata
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧

手机看
关注公众号

关注公众号

客服 返回
顶部