SpringBoot+Vue前后端分離實(shí)現(xiàn)審核功能的示例
一、前言
在實(shí)際開發(fā)中,審核功能是一個非常常用的功能,例如管理后臺的文章審核等等。本篇博文將介紹如何基于SpringBoot+Vue的前后端分離技術(shù)實(shí)現(xiàn)審核功能。
二、項(xiàng)目準(zhǔn)備
本項(xiàng)目使用的技術(shù)棧為:
- 前端:Vue+ElementUI
- 后端:SpringBoot+MySQL
首先,你需要在本地搭建好Vue和SpringBoot的開發(fā)環(huán)境,建議使用最新版本。
三、數(shù)據(jù)庫設(shè)計(jì)
本項(xiàng)目需要用到一個審核表,設(shè)計(jì)如下:
CREATE TABLE `audit` ( `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主鍵', `title` varchar(50) NOT NULL COMMENT '標(biāo)題', `content` text NOT NULL COMMENT '內(nèi)容', `status` tinyint(4) NOT NULL COMMENT '狀態(tài),0-待審核,1-審核通過,2-審核不通過', `create_time` datetime NOT NULL COMMENT '創(chuàng)建時間', `update_time` datetime NOT NULL COMMENT '更新時間', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='審核表';
四、后端實(shí)現(xiàn)
1. 數(shù)據(jù)庫操作
首先,我們需要在后端設(shè)計(jì)一個操作數(shù)據(jù)庫的Dao層來實(shí)現(xiàn)對審核表的增刪改查操作。
@Repository public interface AuditDao extends JpaRepository<Audit, Long> { }
以上是使用Spring Data JPA實(shí)現(xiàn)的Dao層。
2. 業(yè)務(wù)邏輯
在Service層中,我們需要實(shí)現(xiàn)審核操作的相關(guān)邏輯:
@Service public class AuditService { @Autowired private AuditDao auditDao; /** * 提交審核 * * @param audit 審核實(shí)體類 * @return 審核實(shí)體類 */ public Audit submitAudit(Audit audit) { audit.setStatus(Constant.AUDIT_STATUS_WAIT); // 默認(rèn)狀態(tài)為未審核 audit.setCreateTime(LocalDateTime.now()); audit.setUpdateTime(LocalDateTime.now()); return auditDao.save(audit); } /** * 審核通過 * * @param auditId 審核ID * @return 審核實(shí)體類 */ public Audit auditPass(Long auditId) { Audit audit = auditDao.findById(auditId).orElse(null); if (audit == null) { throw new RuntimeException("審核ID不存在!"); } audit.setStatus(Constant.AUDIT_STATUS_PASS); audit.setUpdateTime(LocalDateTime.now()); return auditDao.save(audit); } /** * 審核不通過 * * @param auditId 審核ID * @return 審核實(shí)體類 */ public Audit auditReject(Long auditId) { Audit audit = auditDao.findById(auditId).orElse(null); if (audit == null) { throw new RuntimeException("審核ID不存在!"); } audit.setStatus(Constant.AUDIT_STATUS_REJECT); audit.setUpdateTime(LocalDateTime.now()); return auditDao.save(audit); } /** * 查詢審核列表 * * @param pageNum 分頁頁碼 * @param pageSize 分頁大小 * @return 審核列表數(shù)據(jù) */ public Page<Audit> getAuditList(int pageNum, int pageSize) { return auditDao.findAll(PageRequest.of(pageNum - 1, pageSize, Sort.by(Sort.Order.desc("createTime"), Sort.Order.desc("id")))); } }
3. 接口實(shí)現(xiàn)
在Controller層中,我們需要實(shí)現(xiàn)審核相關(guān)接口的實(shí)現(xiàn):
@RestController @RequestMapping("/audit") public class AuditController { @Autowired private AuditService auditService; /** * 提交審核 * * @param audit 審核實(shí)體類 * @return 審核實(shí)體類 */ @PostMapping("/submitAudit") public Audit submitAudit(@RequestBody Audit audit) { return auditService.submitAudit(audit); } /** * 審核通過 * * @param auditId 審核ID * @return 審核實(shí)體類 */ @PostMapping("/auditPass") public Audit auditPass(@RequestParam("auditId")Long auditId) { return auditService.auditPass(auditId); } /** * 審核不通過 * * @param auditId 審核ID * @return 審核實(shí)體類 */ @PostMapping("/auditReject") public Audit auditReject(@RequestParam("auditId") Long auditId) { return auditService.auditReject(auditId); } /** * 查詢審核列表 * * @param pageNum 分頁頁碼 * @param pageSize 分頁大小 * @return 審核列表數(shù)據(jù) */ @GetMapping("/getAuditList") public Page<Audit> getAuditList(@RequestParam("pageNum") int pageNum, @RequestParam("pageSize") int pageSize) { return auditService.getAuditList(pageNum, pageSize); } }
這樣我們的后端實(shí)現(xiàn)就完成了。
五、前端實(shí)現(xiàn)
1. 頁面設(shè)計(jì)
在前端中,我們需要設(shè)計(jì)審核列表頁面和審核詳情頁面。審核列表頁面用來展示所有未審核通過的審核記錄,審核詳情頁面則用來展示審核詳情并提供審核通過和審核不通過的操作。
審核列表頁面設(shè)計(jì)如下:
<template> <div> <el-button type="primary" class="mb-md" @click="dialogFormVisible = true">提交審核</el-button> <el-table :data="tableData" border stripe style="margin-left: -12px"> <el-table-column prop="id" label="ID" width="70"></el-table-column> <el-table-column prop="title" label="標(biāo)題" width="250"></el-table-column> <el-table-column prop="content" label="內(nèi)容" width="580"></el-table-column> <el-table-column prop="createTime" label="創(chuàng)建時間" width="170"></el-table-column> <el-table-column prop="updateTime" label="更新時間" width="170"></el-table-column> <el-table-column prop="status" label="狀態(tài)" width="90" :formatter="statusFormatter" :cell-style="{textAlign: 'center'}" ></el-table-column> <el-table-column label="操作" width="120" :cell-style="{textAlign: 'center'}" :render-header="renderHeader" > <template slot-scope="scope"> <el-button type="primary" size="mini" v-if="scope.row.status === 0" @click="handlePass(scope.row.id)">通過</el-button> <el-button type="danger" size="mini" v-if="scope.row.status === 0" @click="handleReject(scope.row.id)">不通過</el-button> <el-button type="info" size="mini" :disabled="scope.row.status !== 1" @click="handleView(scope.row.id)">查看詳情</el-button> </template> </el-table-column> </el-table> <el-pagination background :page-size="pageSize" :total="total" layout="prev, pager, next" @current-change="getCurrentPage" > </el-pagination> <el-dialog title="提交審核" :visible.sync="dialogFormVisible" :close-on-click-modal="false" :before-close="handleDialogClose" > <el-form :model="form" :rules="rules" ref="form" label-width="120px"> <el-form-item label="標(biāo)題" prop="title"> <el-input v-model="form.title"></el-input> </el-form-item> <el-form-item label="內(nèi)容" prop="content"> <el-input v-model="form.content" type="textarea"></el-input> </el-form-item> <el-form-item> <el-button type="primary" @click="submitAudit">提交</el-button> <el-button @click="dialogFormVisible = false">取消</el-button> </el-form-item> </el-form> </el-dialog> <el-dialog title="審核詳情" :visible.sync="viewDialogVisible" :close-on-click-modal="false" :before-close="handleDialogClose" > <div v-html="viewData.content"></div> <el-divider content-position="center" style="margin-top: 20px;">審核結(jié)果</el-divider> <el-alert class="mt-md" :title="viewData.status === 1 ? '審核通過' : '審核不通過'" :type="viewData.status === 1 ? 'success' : 'error'" :description="'審核時間:' + viewData.updateTime" ></el-alert> <div style="text-align: center"> <el-button type="primary" @click="viewDialogVisible = false">關(guān)閉</el-button> </div> </el-dialog> </div> </template>
審核詳情頁面設(shè)計(jì)如下:
<template> <div> <div v-html="viewData.content"></div> <el-divider content-position="center" style="margin-top: 20px;">審核結(jié)果</el-divider> <el-alert class="mt-md" :title="viewData.status === 1 ? '審核通過' : '審核不通過'" :type="viewData.status === 1 ? 'success' : 'error'" :description="'審核時間:' + viewData.updateTime" ></el-alert> <div style="text-align: center"> <el-button type="primary" @click="handleBack">返回</el-button> </div> </div> </template>
2. 數(shù)據(jù)交互
然后我們需要通過Axios實(shí)現(xiàn)前端向后端的數(shù)據(jù)交互。
首先,我們定義一個api.js文件:
import axios from 'axios' axios.defaults.baseURL = '/api' // 審核操作 export function auditOp(opType, auditId) { return axios.post(`/audit/${opType}`, {auditId}) } // 獲取審核列表 export function getAuditList(pageNum, pageSize) { return axios.get(`/audit/getAuditList?pageNum=${pageNum}&pageSize=${pageSize}`) } // 提交審核 export function submitAudit(audit) { return axios.post('/audit/submitAudit', audit) } // 獲取審核詳情 export function getAuditDetail(auditId) { return axios.get(`/audit/${auditId}`) }
然后在頁面中使用這些api:
import * as api from '@/api' export default { name: 'AuditList', data() { return { tableData: [], total: 0, currentPage: 1, pageSize: 10, dialogFormVisible: false, viewDialogVisible: false, viewData: {}, form: { title: '', content: '' }, rules: { title: [ {required: true, message: '請輸入標(biāo)題', trigger: 'blur'} ], content: [ {required: true, message: '請輸入內(nèi)容', trigger: 'blur'} ] } } }, mounted() { this.getAuditList(this.currentPage, this.pageSize) }, methods: { // 獲取審核列表 getAuditList(pageNum, pageSize) { api.getAuditList(pageNum, pageSize) .then(res => { this.tableData = res.content this.total = res.totalElements }) }, // 審核通過 handlePass(id) { this.$confirm('確定要通過該審核嗎?', '提示', { confirmButtonText: '確定', cancelButtonText: '取消', type: 'warning' }).then(() => { api.auditOp('auditPass', id) .then(() => { this.$message({type: 'success', message: '審核通過'}) this.getAuditList(this.currentPage, this.pageSize) }) }) }, // 審核不通過 handleReject(id) { this.$prompt('請輸入不通過原因', '提示', { distinguishCancelAndClose: true, cancelButtonText: '取消', confirmButtonText: '確定' }).then(({value}) => { api.auditOp('auditReject', id) .then(() => { this.$message({type: 'success', message: '審核不通過'}) this.getAuditList(this.currentPage, this.pageSize) }) }) }, // 查看詳情 handleView(id) { api.getAuditDetail(id) .then(res => { this.viewData = res this.viewDialogVisible = true }) }, // 提交審核 submitAudit() { this.$refs['form'].validate(valid => { if (valid) { api.submitAudit(this.form) .then(() => { this.$message({type: 'success', message: '提交審核成功'}) this.dialogFormVisible = false this.getAuditList(this.currentPage, this.pageSize) }) } }) }, // 獲取當(dāng)前分頁頁碼 getCurrentPage(page) { this.currentPage = page this.getAuditList(page, this.pageSize) }, // 對話框關(guān)閉事件 handleDialogClose(done) { this.$confirm('確定要關(guān)閉嗎?') .then(() => { done() }).catch(() => {}) }, // 返回 handleBack() { this.viewDialogVisible = false }, // 狀態(tài)格式化 statusFormatter(row) { if (row.status === 0) { return '待審核' } else if (row.status === 1) { return '審核通過' } else { return '審核不通過' } }, // 表頭渲染 renderHeader() { return '操作' } } }
到此為止,我們的前端實(shí)現(xiàn)就完成了。
六、補(bǔ)充說明
1. 前后端分離架構(gòu)
本項(xiàng)目采用的是前后端分離的架構(gòu)模式,這個模式中前后端各自擁有自己的代碼庫,前端代碼負(fù)責(zé)渲染頁面和處理用戶交互,后端代碼負(fù)責(zé)處理數(shù)據(jù)邏輯和提供API接口。前端和后端通過API接口進(jìn)行通信。這種架構(gòu)模式的好處是可以很好地實(shí)現(xiàn)前后端分離,并且可以使開發(fā)效率更高。
2. 審核功能
審核功能是一個非常常用的功能,本文中實(shí)現(xiàn)了一個基本的審核功能,但實(shí)際開發(fā)中仍需要考慮更多的業(yè)務(wù)需求。例如:支持多種審核狀態(tài)、支持審核流程配置、支持審核人員配置等等。
七、總結(jié)
本篇博客介紹了如何基于SpringBoot+Vue的前后端分離技術(shù)實(shí)現(xiàn)審核功能。在實(shí)際開發(fā)中,這種前后端分離的架構(gòu)模式可以提高開發(fā)效率和開發(fā)質(zhì)量,并且可以輕松實(shí)現(xiàn)業(yè)務(wù)擴(kuò)展和維護(hù)。
到此這篇關(guān)于SpringBoot+Vue前后端分離實(shí)現(xiàn)審核功能的示例的文章就介紹到這了,更多相關(guān)SpringBoot Vue審核內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
在IDEA中如何設(shè)置最多顯示文件標(biāo)簽個數(shù)
在使用IDEA進(jìn)行編程時,可能會同時打開多個文件,當(dāng)文件過多時,文件標(biāo)簽會占據(jù)大部分的IDEA界面,影響我們的編程效率,因此,我們可以通過設(shè)置IDEA的文件標(biāo)簽顯示個數(shù),來優(yōu)化我們的編程環(huán)境,具體的設(shè)置方法如下2024-10-10Springboot控制反轉(zhuǎn)與Bean對象的方法
文章介紹了Spring Boot中的控制反轉(zhuǎn)(IoC)概念,描述了IoC容器如何管理Bean的生命周期和依賴關(guān)系,它詳細(xì)講解了Bean的注冊過程,包括通過@ComponentScan和@Bean注解的方式,并討論了Bean的依賴注入方法,如構(gòu)造器注入、Setter注入和字段注入,感興趣的朋友一起看看吧2025-03-03SpringBoot+WebSocket實(shí)現(xiàn)消息推送功能
WebSocket協(xié)議是基于TCP的一種新的網(wǎng)絡(luò)協(xié)議。本文將通過SpringBoot集成WebSocket實(shí)現(xiàn)消息推送功能,感興趣的可以了解一下2022-08-08Java讀文件修改默認(rèn)換行符的實(shí)現(xiàn)
這篇文章主要介紹了Java讀文件修改默認(rèn)換行符的實(shí)現(xiàn)方式,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-12-12java.net.ConnectException: Connection refused問題解決辦法
這篇文章主要介紹了java.net.ConnectException: Connection refused問題解決辦法的相關(guān)資料,需要的朋友可以參考下2016-12-12java 數(shù)據(jù)結(jié)構(gòu)之堆排序(HeapSort)詳解及實(shí)例
這篇文章主要介紹了java 數(shù)據(jù)結(jié)構(gòu)之堆排序(HeapSort)詳解及實(shí)例的相關(guān)資料,需要的朋友可以參考下2017-03-03mybatis-plus動態(tài)表名實(shí)現(xiàn)方法
本文主要介紹了mybatis-plus動態(tài)表名實(shí)現(xiàn)方法,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-02-02