SpringBoot+Vue前后端分離實(shí)現(xiàn)審核功能的示例
一、前言
在實(shí)際開發(fā)中,審核功能是一個(gè)非常常用的功能,例如管理后臺(tái)的文章審核等等。本篇博文將介紹如何基于SpringBoot+Vue的前后端分離技術(shù)實(shí)現(xiàn)審核功能。
二、項(xiàng)目準(zhǔn)備
本項(xiàng)目使用的技術(shù)棧為:
- 前端:Vue+ElementUI
- 后端:SpringBoot+MySQL
首先,你需要在本地搭建好Vue和SpringBoot的開發(fā)環(huán)境,建議使用最新版本。
三、數(shù)據(jù)庫(kù)設(shè)計(jì)
本項(xiàng)目需要用到一個(gè)審核表,設(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)建時(shí)間', `update_time` datetime NOT NULL COMMENT '更新時(shí)間', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='審核表';
四、后端實(shí)現(xiàn)
1. 數(shù)據(jù)庫(kù)操作
首先,我們需要在后端設(shè)計(jì)一個(gè)操作數(shù)據(jù)庫(kù)的Dao層來實(shí)現(xiàn)對(duì)審核表的增刪改查操作。
@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 分頁(yè)頁(yè)碼
* @param pageSize 分頁(yè)大小
* @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 分頁(yè)頁(yè)碼
* @param pageSize 分頁(yè)大小
* @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. 頁(yè)面設(shè)計(jì)
在前端中,我們需要設(shè)計(jì)審核列表頁(yè)面和審核詳情頁(yè)面。審核列表頁(yè)面用來展示所有未審核通過的審核記錄,審核詳情頁(yè)面則用來展示審核詳情并提供審核通過和審核不通過的操作。
審核列表頁(yè)面設(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)建時(shí)間" width="170"></el-table-column>
<el-table-column prop="updateTime" label="更新時(shí)間" 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="'審核時(shí)間:' + 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>
審核詳情頁(yè)面設(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="'審核時(shí)間:' + 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ù)交互。
首先,我們定義一個(gè)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}`)
}
然后在頁(yè)面中使用這些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: '請(qǐng)輸入標(biāo)題', trigger: 'blur'}
],
content: [
{required: true, message: '請(qǐng)輸入內(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('請(qǐng)輸入不通過原因', '提示', {
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)前分頁(yè)頁(yè)碼
getCurrentPage(page) {
this.currentPage = page
this.getAuditList(page, this.pageSize)
},
// 對(duì)話框關(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)模式,這個(gè)模式中前后端各自擁有自己的代碼庫(kù),前端代碼負(fù)責(zé)渲染頁(yè)面和處理用戶交互,后端代碼負(fù)責(zé)處理數(shù)據(jù)邏輯和提供API接口。前端和后端通過API接口進(jìn)行通信。這種架構(gòu)模式的好處是可以很好地實(shí)現(xiàn)前后端分離,并且可以使開發(fā)效率更高。
2. 審核功能
審核功能是一個(gè)非常常用的功能,本文中實(shí)現(xiàn)了一個(gè)基本的審核功能,但實(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)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Jdbc的步驟以及簡(jiǎn)單實(shí)現(xiàn)代碼
下面小編就為大家?guī)硪黄狫dbc的步驟以及簡(jiǎn)單實(shí)現(xiàn)代碼。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2016-07-07
在IDEA中如何設(shè)置最多顯示文件標(biāo)簽個(gè)數(shù)
在使用IDEA進(jìn)行編程時(shí),可能會(huì)同時(shí)打開多個(gè)文件,當(dāng)文件過多時(shí),文件標(biāo)簽會(huì)占據(jù)大部分的IDEA界面,影響我們的編程效率,因此,我們可以通過設(shè)置IDEA的文件標(biāo)簽顯示個(gè)數(shù),來優(yōu)化我們的編程環(huán)境,具體的設(shè)置方法如下2024-10-10
java注解的類型知識(shí)點(diǎn)總結(jié)
在本篇文章里小編給大家整理了一篇關(guān)于java注解的類型知識(shí)點(diǎn)總結(jié)內(nèi)容,有興趣的朋友們可以學(xué)習(xí)下。2021-03-03
Springboot控制反轉(zhuǎn)與Bean對(duì)象的方法
文章介紹了Spring Boot中的控制反轉(zhuǎn)(IoC)概念,描述了IoC容器如何管理Bean的生命周期和依賴關(guān)系,它詳細(xì)講解了Bean的注冊(cè)過程,包括通過@ComponentScan和@Bean注解的方式,并討論了Bean的依賴注入方法,如構(gòu)造器注入、Setter注入和字段注入,感興趣的朋友一起看看吧2025-03-03
SpringBoot+WebSocket實(shí)現(xiàn)消息推送功能
WebSocket協(xié)議是基于TCP的一種新的網(wǎng)絡(luò)協(xié)議。本文將通過SpringBoot集成WebSocket實(shí)現(xiàn)消息推送功能,感興趣的可以了解一下2022-08-08
Java讀文件修改默認(rèn)換行符的實(shí)現(xiàn)
這篇文章主要介紹了Java讀文件修改默認(rèn)換行符的實(shí)現(xiàn)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-12-12
java.net.ConnectException: Connection refused問題解決辦法
這篇文章主要介紹了java.net.ConnectException: Connection refused問題解決辦法的相關(guān)資料,需要的朋友可以參考下2016-12-12
java 數(shù)據(jù)結(jié)構(gòu)之堆排序(HeapSort)詳解及實(shí)例
這篇文章主要介紹了java 數(shù)據(jù)結(jié)構(gòu)之堆排序(HeapSort)詳解及實(shí)例的相關(guān)資料,需要的朋友可以參考下2017-03-03
mybatis-plus動(dòng)態(tài)表名實(shí)現(xiàn)方法
本文主要介紹了mybatis-plus動(dòng)態(tài)表名實(shí)現(xiàn)方法,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-02-02

