当前位置:网站首页>EBook editing and deleting
EBook editing and deleting
2022-06-12 05:55:00 【Snow flies fast】
list page
establish src\views\book\list.vue file :
<template>
<div class="app-container">
<div class="filter-container">
<el-input v-model="listQuery.title" placeholder=" Title " style="width: 200px" class="filter-item" clearable @keyup.enter.native="handleFilter" @clear="handleFilter" @blur="handleFilter" />
<el-input v-model="listQuery.author" placeholder=" author " style="width: 200px" class="filter-item" clearable @keyup.enter.native="handleFilter" @clear="handleFilter" @blur="handleFilter" />
<el-select v-model="listQuery.category" placeholder=" classification " clearable class-item="filter-item" @change="handleFilter" >
<el-option v-for="item in categoryList" :key="item.value" :label="item.label + '(' + item.num + ')'" :value="item.value" />
</el-select>
<el-button v-waves class="filter-item" type="primary" icon="el-icon-search" style="margin-left: 10px" @click="handleFilter" >
Inquire about
</el-button>
<el-button class="filter-item" type="primary" icon="el-icon-edit" style="margin-left: 5px" @click="handleCreate" >
newly added
</el-button>
<el-checkbox v-model="showCover" class="filter-item" style="margin-left: 5px" @change="changeShowCover" >
Show cover page
</el-checkbox>
</div>
<el-table :key="tableKey" v-loading="listLoading" :data="list" border fit highlight-current-row style="width: 100%" @sort-change="sortChange" >
<el-table-column label="ID" prop="id" sortable="custom" align="center" width="80" />
<el-table-column label=" Title " align="center" width="150">
<template slot-scope="{ row: { titleWrapper } }">
<span v-html="titleWrapper" />
</template>
</el-table-column>
<el-table-column label=" author " align="center" width="150">
<template slot-scope="{ row: { authorWrapper } }">
<span v-html="authorWrapper" />
</template>
</el-table-column>
<el-table-column label=" Press. " prop="publisher" align="center" width="150" />
<el-table-column label=" classification " prop="categoryText" align="center" width="100" />
<el-table-column label=" Language " prop="language" align="center" />
<el-table-column v-if="showCover" label=" cover " align="center" width="100">
<template slot-scope="{ row: { cover } }">
<a :href="cover" target="_blank">
<img :src="cover" alt="" style="width: 120px;height: 180px" />
</a>
</template>
</el-table-column>
<el-table-column label=" file name " prop="fileName" width="100" align="center" />
<el-table-column label=" File path " prop="filePath" width="100" align="center">
<template slot-scope="{ row: { filePath } }">
<span>{
{ filePath | valueFilter }}</span>
</template>
</el-table-column>
<el-table-column label=" Cover path " prop="coverPath" width="100" align="center">
<template slot-scope="{ row: { coverPath } }">
<span>{
{ coverPath | valueFilter }}</span>
</template>
</el-table-column>
<el-table-column label=" Decompression path " prop="unzipPath" width="100" align="center">
<template slot-scope="{ row: { unzipPath } }">
<span>{
{ unzipPath | valueFilter }}</span>
</template>
</el-table-column>
<el-table-column label=" Uploading people " prop="createUser" width="100" align="center">
<template slot-scope="{ row: { createUser } }">
<span>{
{ createUser | valueFilter }}</span>
</template>
</el-table-column>
<el-table-column label=" Upload time " prop="createDt" width="100" align="center">
<template slot-scope="{ row: { createDt } }">
<span>{
{ createDt | timeFilter }}</span>
</template>
</el-table-column>
<el-table-column label=" operation " width="120" align="center" fixed="right">
<template slot-scope="{ row }">
<el-button type="text" icon="el-icon-edit" @click="handleUpdate(row)" />
<el-button type="text" icon="el-icon-delete" style="color: #f56c6c" @click="handleDelete(row)" />
</template>
</el-table-column>
</el-table>
<pagination v-if="total > 0" :total="total" :page.sync="listQuery.page" :limit.sync="listQuery.pageSize" @pagination="getList" />
</div>
</template>
<script> import Pagination from '@/components/Pagination' import waves from '@/directive/waves/waves' import {
parseTime } from '@/utils' export default {
name: 'List', components: {
Pagination }, directives: {
waves }, data() {
return {
tableKey: 0, listLoading: false, listQuery: {
}, list: [], categoryList: [], showCover: false, total: 0 } }, created() {
this.parseQuery() }, methods: {
parseQuery() {
const listQuery = {
page: 1, pageSize: 20, sort: '+id' } this.listQuery = {
...listQuery, ...this.listQuery } }, handleFilter() {
this.getList() }, handleCreate() {
this.$router.push('/book/create') }, handleUpdate(row) {
this.$router.push(`/book/edit/${
row.fileName}`) }, changeShowCover(value) {
this.showCover = value } } } </script>
modify src\router\index.js Medium component introduce :
{
path: '/book/list',
component: () => import('@/views/book/list'),
name: 'bookList',
meta: {
title: ' The book list ', icon: 'list', roles: ['editor'] }
}
Book classification API
front end : classification API , modify src\views\book\list.vue
mounted() {
this.getCategoryList()
},
methods: {
getCategoryList() {
getCategory().then(response => {
this.categoryList = response.data
})
},
}
modify src\api\book.js increase getCategory API
export function getCategory() {
return request({
url: '/book/category',
method: 'get'
})
}
Back end : increase /book/category Interface , stay router\book.js Add the following :
router.get('/category', (req, res, next) => {
bookService
.getCategory()
.then(category => {
new Result(category, ' Classification obtained successfully ').success(res)
})
.catch(err => next(boom.badImplementation(err)))
})
stay services\book.js Add the following :
asyncFunctionWill automatically convert the return value to Promise
async function getCategory() {
const sql = 'select * from category order by category asc'
const result = await db.querySql(sql)
const categoryList = []
result.forEach(item => {
categoryList.push({
label: item.categoryText,
value: item.category,
num: item.num,
})
})
return categoryList
}
SQL There may be errors when querying classified views 1:mysql5.7.X edition only_full_group_by Problem solving
- reason :
sql_modebyonly_full_group_by - resolvent :
set @@global.sql_mode=' '
error 2:1449 - The user specified as a definer (‘test’@’%’) does not exist
- keep
definerSecurity , Change the definition to the user existing on the server - resolvent : modify
Design view - senior - Definerby[email protected]. If you don't know the definer , You can put the design viewsqlCopy , Delete the view , Then recreate the view ( The view is created from the current existing table )
The book list API
Interface development
front end : The book list API, modify src\views\book\list.vue
mounted() {
this.getList()
},
methods: {
getList() {
this.listLoading = true
listBook(this.listQuery).then(response => {
})
},
}
modify src\api\book.js increase listBook API
export function listBook(params) {
return request({
url: '/book/list',
method: 'get',
params
})
}
Back end : increase /book/list Interface , stay router\book.js Add the following :
router.get('/list', (req, res, next) => {
bookService
.listBook(req.query)
.then(({
list }) => {
new Result({
list }, ' Successful acquisition of books ').success(res)
})
.catch(err => next(boom.badImplementation(err)))
})
stay services\book.js Add the following :
asyncFunctionWill automatically convert the return value to Promise
async function listBook(query) {
const {
category, title, author, page = 1, pageSize = 20 } = query
const offset = (page - 1) * pageSize
let bookSql = 'select * from book'
let where = 'where'
title && (where = db.andLike(where, 'title', title))
author && (where = db.andLike(where, 'author', author))
category && (where = db.and(where, 'category', category))
if (where !== 'where') {
bookSql = `${
bookSql} ${
where}`
}
bookSql = `${
bookSql} limit ${
pageSize} offset ${
offset}`
DEBUG && console.log(bookSql)
const list = await db.querySql(bookSql)
return {
list }
}
stay db\index.js newly added and and andLike Method :
function and(where, k, v) {
if (where === 'where') {
return `${
where} \`${
k}\`='${
v}'`
} else {
return `${
where} and \`${
k}\`='${
v}'`
}
}
function andLike(where, k, v) {
if (where === 'where') {
return `${
where} \`${
k}\` like '%${
v}%'`
} else {
return `${
where} and \`${
k}\` like '%${
v}%'`
}
}
Search keyword highlighting
stay getList Newly added titleWrapper and authorWrapper Two attributes
getList() {
this.listLoading = true
listBook(this.listQuery).then(response => {
const {
list, count } = response.data
this.list = list
this.total = count
this.listLoading = false
this.list.forEach(book => {
book.titleWrapper = this.wrapperKeyword('title', book.title)
book.authorWrapper = this.wrapperKeyword('author', book.author)
})
})
},
add to wrapperKeyword Highlight method
wrapperKeyword(k, v) {
function highlight(value) {
return `<span style="color: #1890ff">${
value}</span>`
}
if (!this.listQuery[k]) {
return v
} else {
return v.replace(new RegExp(this.listQuery[k], 'ig'), v => highlight(v))
}
},
Last in el-table-column Use in template Replace the corresponding content , Need to use v-html
<el-table-column label=" Title " align="center" width="150">
<template slot-scope="{ row: { titleWrapper } }">
<span v-html="titleWrapper" />
</template>
</el-table-column>
<el-table-column label=" author " align="center" width="150">
<template slot-scope="{ row: { authorWrapper } }">
<span v-html="authorWrapper" />
</template>
</el-table-column>
Sorting function
stay el-table Add sort-change Method
<el-table :key="tableKey" v-loading="listLoading" :data="list" border fit highlight-current-row style="width: 100%" @sort-change="sortChange" >
modify sortChange Method , Method will pass data Parameters ,data There are... In the parameters order ( positive sequence / In reverse order )、 prop ( According to the correspondence prop Sort ) and column ( The whole line of data )
sortChange(data) {
const {
prop, order } = data
this.sortBy(prop, order)
},
sortBy(prop, order) {
if (order === 'ascending') {
this.listQuery.sort = `+${
prop}`
} else {
this.listQuery.sort = `-${
prop}`
}
this.handleFilter()
},
Filters optimize table fields
Define in local filter
filters: {
valueFilter(value) {
return value || ' nothing '
},
timeFilter(time) {
return time ? parseTime(time) : ' nothing '
}
},
Last in el-table-column Use in template Replace the corresponding content
<el-table-column label=" Uploading people " prop="createUser" width="100" align="center">
<template slot-scope="{ row: { createUser } }">
<span>{
{ createUser | valueFilter }}</span>
</template>
</el-table-column>
<el-table-column label=" Upload time " prop="createDt" width="100" align="center">
<template slot-scope="{ row: { createDt } }">
<span>{
{ createDt | timeFilter }}</span>
</template>
</el-table-column>
Book deletion API
front end : The book list API, modify src\views\book\list.vue
handleDelete(row) {
this.$confirm(' This action will permanently delete the e-book , Whether or not to continue ', ' Tips ', {
confirmButtonText: ' determine ',
cancelButtonText: ' Cancel ',
type: 'warning'
})
.then(() => {
deleteBook(row.fileName).then(response => {
this.$notify({
title: ' success ',
message: response.msg || ' Delete successful ',
type: 'success',
duration: 2 * 1000
})
this.handleFilter()
})
})
.catch(() => {
})
},
modify src\api\book.js increase deleteBook API
export function deleteBook(fileName) {
return request({
url: '/book/delete',
method: 'get',
params: {
fileName }
})
}
Back end : increase /book/delete Interface , stay router\book.js Add the following :
router.get('/delete', (req, res, next) => {
const {
fileName } = req.query
if (!fileName) {
next(boom.badRequest(new Error(' Parameters fileName Can't be empty ')))
} else {
bookService
.deleteBook(fileName)
.then(book => {
new Result(book, ' Delete book information successfully ').success(res)
})
.catch(err => next(boom.badImplementation(err)))
}
})
stay services\book.js Add the following :
function deleteBook(fileName) {
return new Promise(async(resolve, reject) => {
let book = await getBook(fileName)
if (book) {
if (+book.updateType === 0) {
reject(new Error(' The built-in e-book cannot be deleted '))
} else {
const bookObj = new Book(null, book)
const sql = `delete from book where fileName='${
fileName}'`
db.querySql(sql).then(() => {
bookObj.reset()
resolve()
})
}
} else {
reject(new Error(' E-books don't exist '))
}
})
}
EBook list advanced optimization
Save the parameters of the search criteria ( Refreshing the page will have no effect )
beforeRouteUpdate(to, from, next) {
if (to.path === from.path) {
const newQuery = Object.assign({
}, to.query)
const oldQuery = Object.assign({
}, from.query)
if (JSON.stringify(newQuery) !== JSON.stringify(oldQuery)) {
this.getList()
}
}
next()
},
methods: {
parseQuery() {
const query = Object.assign({
}, this.$route.query)
let sort = '+id'
const listQuery = {
page: 1,
pageSize: 20,
sort: '+id'
}
if (query) {
query.page && (query.page = +query.page)
query.pageSize && (query.pageSize = +query.pageSize)
query.sort && (sort = query.sort)
}
const sortSymbol = sort[0]
const sortColumn = sort.slice(1, sort.length)
this.defaultSort = {
prop: sortColumn,
order: sortSymbol === '+' ? 'ascending' : 'descending'
}
this.listQuery = {
...listQuery, ...query }
},
refresh() {
this.$router.push({
path: '/book/list',
query: this.listQuery
})
},
handleFilter() {
this.listQuery.page = 1
this.refresh()
},
}
Found while refreshing category No restore , hold select Component binding value Change it to label
<el-select v-model="listQuery.category" placeholder=" classification " clearable class-item="filter-item" @change="handleFilter" >
<el-option v-for="item in categoryList" :key="item.value" :label="item.label + '(' + item.num + ')'" :value="item.label" />
</el-select>
services\book.js The corresponding server code needs to be modified to categoryText
category && (where = db.and(where, 'categoryText', category))
Switching pages is a problem , Need modification @pagination="refresh"
<pagination v-if="total > 0" :total="total" :page.sync="listQuery.page" :limit.sync="listQuery.pageSize" @pagination="refresh" />
to el-table increase default-sort attribute , And at the time of refresh parseQuery Intermediate processing
<el-table :key="tableKey" v-loading="listLoading" :data="list" border fit highlight-current-row style="width: 100%" :default-sort="defaultSort" @sort-change="sortChange" >
边栏推荐
- 【长时间序列预测】Aotoformer 代码详解之[4]自相关机制
- IO system - code example
- Select gb28181, RTSP or RTMP for data push?
- Go interface oriented programming practice
- Memory model, reference and function supplement of program
- Flex/fixed upper, middle and lower (mobile end)
- Conversion of Halcon 3D depth map to 3D image
- Rtmp/rtsp/hls public network real available test address
- [C language basics] macro definition usage
- Tabulation skills and matrix processing skills
猜你喜欢

肝了一个月的 DDD,一文带你掌握

Data integration framework seatunnel learning notes

Wireshark filter rule

Tabulation skills and matrix processing skills

Chapter 7 - pointer learning
![[fastapi] use pycharm to configure and use environment variables for fastapi projects](/img/a5/47cabfed3f12bf70b4b047ef29fc9d.jpg)
[fastapi] use pycharm to configure and use environment variables for fastapi projects

Introduction to redis high availability

Webrtc AEC process analysis

Makefile文件编写快速掌握

GRP development: four communication modes of GRP
随机推荐
Introduction to sringmvc
Wireshark filter rule
Memory model, reference and function supplement of program
Un mois de DDD hépatique.
TCP and UDP introduction
Oracle EBS interface/api (34) - update vendor API
数据库实验一:数据定义实验指导
Flex / fixed Upper, Middle and Lower (Mobile end)
Database Experiment 3: data query
China embolic coil market trend report, technical innovation and market forecast
Brief introduction to project development process
GRE protocol details
Heap classical problem
Redis transaction
How much Ma is the driving current of SIM card signal? Is it adjustable?
登录验证过滤器
Tabulation skills and matrix processing skills
Liunx Foundation
IO system - code example
[gin] gin framework for golang web development