current position:Home>Springboot + Vue realize audit function (minimalist version)
Springboot + Vue realize audit function (minimalist version)
2022-04-29 20:46:27【Programmer Qingge】
Pre learning video : from 0 Start giving you a hand roll SpringBoot+Vue Background management system (2022 Latest edition of )
Supporting explanation video :https://www.bilibili.com/video/BV13R4y1K73e
sql
CREATE TABLE `goods` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT ' Item name ',
`user` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT ' Owner ',
`img` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT ' Item pictures ',
`time` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT ' Repair time ',
`state` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT ' To audit ' COMMENT ' Repair status ',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
Background modification
// Add or update
@PostMapping
public Result save(@RequestBody Goods goods) {
if (goods.getId() == null) {
// newly added
goods.setTime(DateUtil.today());
goods.setUser(TokenUtils.getCurrentUser().getUsername());
}
goodsService.saveOrUpdate(goods);
return Result.success();
}
// Do some filtering for paging query
@GetMapping("/page")
public Result findPage(@RequestParam(defaultValue = "") String name,
@RequestParam Integer pageNum,
@RequestParam Integer pageSize) {
QueryWrapper<Goods> queryWrapper = new QueryWrapper<>();
queryWrapper.orderByDesc("id");
if (!"".equals(name)) {
queryWrapper.like("name", name);
}
User currentUser = TokenUtils.getCurrentUser();
if (RoleEnum.ROLE_USER.toString().equals(currentUser.getRole())) {
// The role is an ordinary user
queryWrapper.eq("user", currentUser.getUsername());
}
return Result.success(goodsService.page(new Page<>(pageNum, pageSize), queryWrapper));
}
The front desk Vue
<el-table-column label=" to examine " v-if="user.role === 'ROLE_ADMIN'" width="240">
<template v-slot="scope">
<el-button type="success" @click="changeState(scope.row, ' Approved by ')" :disabled="scope.row.state !== ' To audit '"> Approved by </el-button>
<el-button type="danger" @click="changeState(scope.row, ' The audit failed ')" :disabled="scope.row.state !== ' To audit '"> The audit failed </el-button>
</template>
</el-table-column>
<!-- methods Just add this method to the -->
changeState(row, state) {
this.form = JSON.parse(JSON.stringify(row))
this.form.state = state;
this.save();
},
Vue Complete code :
<template>
<div>
<div style="margin: 10px 0">
<el-input style="width: 200px" placeholder=" Please enter name " suffix-icon="el-icon-search" v-model="name"></el-input>
<!-- <el-input style="width: 200px" placeholder=" Please enter " suffix-icon="el-icon-message" class="ml-5" v-model="email"></el-input>-->
<!-- <el-input style="width: 200px" placeholder=" Please enter " suffix-icon="el-icon-position" class="ml-5" v-model="address"></el-input>-->
<el-button class="ml-5" type="primary" @click="load"> Search for </el-button>
<el-button type="warning" @click="reset"> Reset </el-button>
</div>
<div style="margin: 10px 0">
<el-button type="primary" @click="handleAdd"> Create a repair request <i class="el-icon-circle-plus-outline"></i></el-button>
<el-popconfirm
class="ml-5"
confirm-button-text=' determine '
cancel-button-text=' I'll think about it again '
icon="el-icon-info"
icon-color="red"
title=" Are you sure to delete these data in batch ?"
@confirm="delBatch"
>
<el-button type="danger" slot="reference" v-if="user.role === 'ROLE_ADMIN'"> Batch deletion <i class="el-icon-remove-outline"></i></el-button>
</el-popconfirm>
<!-- <el-upload action="http://localhost:9090/goods/import" :show-file-list="false" accept="xlsx" :on-success="handleExcelImportSuccess" style="display: inline-block">
<el-button type="primary" class="ml-5"> Import <i class="el-icon-bottom"></i></el-button>
</el-upload>
<el-button type="primary" @click="exp" class="ml-5"> export <i class="el-icon-top"></i></el-button> -->
</div>
<el-table :data="tableData" border stripe :header-cell-class-name="'headerBg'" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55"></el-table-column>
<el-table-column prop="id" label="ID" width="80" sortable></el-table-column>
<el-table-column prop="name" label=" Item name "></el-table-column>
<el-table-column prop="user" label=" Owner "></el-table-column>
<el-table-column label=" picture "><template slot-scope="scope"><el-image style="width: 100px; height: 100px" :src="scope.row.img" :preview-src-list="[scope.row.img]"></el-image></template></el-table-column>
<el-table-column prop="time" label=" Repair time "></el-table-column>
<el-table-column prop="state" label=" Repair status "></el-table-column>
<el-table-column label=" to examine " v-if="user.role === 'ROLE_ADMIN'" width="240">
<template v-slot="scope">
<el-button type="success" @click="changeState(scope.row, ' Approved by ')" :disabled="scope.row.state !== ' To audit '"> Approved by </el-button>
<el-button type="danger" @click="changeState(scope.row, ' The audit failed ')" :disabled="scope.row.state !== ' To audit '"> The audit failed </el-button>
</template>
</el-table-column>
<el-table-column label=" operation " width="180" align="center">
<template slot-scope="scope" v-if="scope.row.user === user.username || user.role === 'ROLE_ADMIN'">
<el-button type="success" @click="handleEdit(scope.row)"> edit <i class="el-icon-edit"></i></el-button>
<el-popconfirm
class="ml-5"
confirm-button-text=' determine '
cancel-button-text=' I'll think about it again '
icon="el-icon-info"
icon-color="red"
title=" Are you sure to delete ?"
@confirm="del(scope.row.id)"
>
<el-button type="danger" slot="reference"> Delete <i class="el-icon-remove-outline"></i></el-button>
</el-popconfirm>
</template>
</el-table-column>
</el-table>
<div style="padding: 10px 0">
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="pageNum"
:page-sizes="[2, 5, 10, 20]"
:page-size="pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="total">
</el-pagination>
</div>
<el-dialog title=" Information " :visible.sync="dialogFormVisible" width="30%" :close-on-click-modal="false">
<el-form label-width="100px" size="small" style="width: 90%">
<el-form-item label=" Item name ">
<el-input v-model="form.name" autocomplete="off"></el-input>
</el-form-item>
<!-- <el-form-item label=" Owner ">-->
<!-- <el-input v-model="form.user" autocomplete="off"></el-input>-->
<!-- </el-form-item>-->
<el-form-item label=" Item pictures ">
<el-upload action="http://localhost:9090/file/upload" ref="img" :on-success="handleImgUploadSuccess">
<el-button size="small" type="primary"> Click upload </el-button>
</el-upload>
</el-form-item>
<!-- <el-form-item label=" Repair time ">-->
<!-- <el-date-picker v-model="form.time" type="datetime" value-format="yyyy-MM-dd HH:mm:ss" placeholder=" Choose the date and time "></el-date-picker>-->
<!-- </el-form-item>-->
<!-- <el-form-item label=" Repair status ">-->
<!-- <el-input v-model="form.state" autocomplete="off"></el-input>-->
<!-- </el-form-item>-->
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogFormVisible = false"> take eliminate </el-button>
<el-button type="primary" @click="save"> indeed set </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
export default {
name: "Goods",
data() {
return {
tableData: [],
total: 0,
pageNum: 1,
pageSize: 10,
name: "",
form: {},
dialogFormVisible: false,
multipleSelection: [],
user: localStorage.getItem("user") ? JSON.parse(localStorage.getItem("user")) : {}
}
},
created() {
this.load()
},
methods: {
changeState(row, state) {
this.form = JSON.parse(JSON.stringify(row))
this.form.state = state;
this.save();
},
load() {
this.request.get("/goods/page", {
params: {
pageNum: this.pageNum,
pageSize: this.pageSize,
name: this.name,
}
}).then(res => {
this.tableData = res.data.records
this.total = res.data.total
})
},
save() {
this.request.post("/goods", this.form).then(res => {
if (res.code === '200') {
this.$message.success(" Saved successfully ")
this.dialogFormVisible = false
this.load()
} else {
this.$message.error(" Save failed ")
}
})
},
handleAdd() {
this.dialogFormVisible = true
this.form = {}
this.$nextTick(() => {
if(this.$refs.img) {
this.$refs.img.clearFiles();
}
if(this.$refs.file) {
this.$refs.file.clearFiles();
}
})
},
handleEdit(row) {
this.form = JSON.parse(JSON.stringify(row))
this.dialogFormVisible = true
this.$nextTick(() => {
if(this.$refs.img) {
this.$refs.img.clearFiles();
}
if(this.$refs.file) {
this.$refs.file.clearFiles();
}
})
},
del(id) {
this.request.delete("/goods/" + id).then(res => {
if (res.code === '200') {
this.$message.success(" Delete successful ")
this.load()
} else {
this.$message.error(" Delete failed ")
}
})
},
handleSelectionChange(val) {
console.log(val)
this.multipleSelection = val
},
delBatch() {
if (!this.multipleSelection.length) {
this.$message.error(" Please select the data to be deleted ")
return
}
let ids = this.multipleSelection.map(v => v.id) // [{}, {}, {}] => [1,2,3]
this.request.post("/goods/del/batch", ids).then(res => {
if (res.code === '200') {
this.$message.success(" Batch deletion succeeded ")
this.load()
} else {
this.$message.error(" Batch deletion failed ")
}
})
},
reset() {
this.name = ""
this.load()
},
handleSizeChange(pageSize) {
console.log(pageSize)
this.pageSize = pageSize
this.load()
},
handleCurrentChange(pageNum) {
console.log(pageNum)
this.pageNum = pageNum
this.load()
},
handleFileUploadSuccess(res) {
this.form.file = res
},
handleImgUploadSuccess(res) {
this.form.img = res
},
download(url) {
window.open(url)
},
exp() {
window.open("http://localhost:9090/goods/export")
},
handleExcelImportSuccess() {
this.$message.success(" Successful import ")
this.load()
}
}
}
</script>
<style>
.headerBg {
background: #eee!important;
}
</style>
copyright notice
author[Programmer Qingge],Please bring the original link to reprint, thank you.
https://en.qdmana.com/2022/04/202204292046223830.html
The sidebar is recommended
- Talking about nodejs server
- Node. js&lt; I & gt—— Encounter node and repl usage
- Vue basic API: calculation attribute + filter + listener
- 1-stm32 + mn316 (nb-iot) remote upgrade OTA (self built Internet of things platform) - STM32 uses HTTP to download program files and upgrade programs through mn316 (MCU program rotation check and update)
- Vue Axios response interception
- vue3 ref
- How does Vue transfer the data from the parent component to the child component intact?
- The back-end interface developed by springboot in idea and the Vue front-end developed by vscode. How to integrate Vue code into springboot?
- Fried cold rice series 4: scope and closure in JavaScript
- Typescript type compatibility learning
guess what you like
Summary of bugs encountered in front-end development
Chrome developer tool: performance analysis using web panel
Collation of common semantic elements and global attributes in HTML
Life cycle in Vue
5.1 fear of traffic jam? With a budget of less than 100000, these cars with adaptive cruise make it easy for you to travel
Docker compose deploy nginx configure SSL
The content of element type “mapper“ must match “(cache-ref|cache|resultMap*|parameterMap*|sql*|inse
-CSS-
Vue uses two-way binding to implement the user registration page
Is Infiniti qx60 worth less than 400000 yuan? It depends on the discount
Random recommended
- "Element Fangjian: first heart version" public beta welfare release, go to the great God app to receive red envelopes and prizes
- What is the role of webpack cli in webpack packaging
- Vue3 configuration method using Axios
- How to configure Google reverse proxy on nginx server
- Volume comparison between Vue and react
- What are the three ways to define components in react
- How to install and configure the blogging program Typecho on the nginx server
- How to configure load balancing for TCP in nginx server
- How to configure nginx server under Windows system
- How to configure AB to do stress testing for nginx server
- Analysis of location configuration in nginx server
- How to integrate Linux and redmine into the redmine system
- How to build the production environment of nginx + PHP with PHP FPM
- How to optimize the performance of nginx supporting SSL
- How to configure nginx server to prevent flood attack
- [Axios learning] basic use of Axios
- [Axios learning] Axios request mode, concurrent request, global configuration, instance and interceptor
- Use the virtual queue implemented by list to view the first element of the queue in Python without taking it out
- This dependency was not found and to install it, you can run: NPM install score JS
- Front end serial communication
- leedcode. 203 remove linked list elements
- Dialogue with Liu Dayong, information director of Jiuyang shares: key elements of enterprise digital intelligence transformation
- JQuery gets the method summary of parent element, child element and brother element
- Web Security: analysis of DOM XSS vulnerability source code of jquery
- The sales volume of Genesys in China is 283, less than 300, and the domestic sales volume is dismal
- This beast was blessed with skills to test drive the DHT version of Harvard beast
- Bootstrap and jQuery implement tree structure
- Fried cold rice series 5: recursion in JavaScript?
- 2022 open source summer | serverless devs accompany you to "become stronger"
- How to create a high-performance full screen red envelope rain
- Detailed process of spring boot free HTTPS project configuration!
- Create a simple vue3 project
- How to create a simple react project
- Vue custom text background
- Front end HTML
- leetcode:462. Minimum number of moves to make array elements equal II [sort + find the middle]
- City selection (provincial and urban cascade) plug-in v-distpicker component details and a full set of usage
- How to use js to achieve such a drag and zoom effect
- Quick report ~ node JS 18 coming! Let's see what's new
- Easily manage projects using Vue UI graphical interface