@[TOC]
preface
To today is finally the most basic function to do, the front of a lot of repairs and changes, mainly the front end of the previous minor problems, debugging took a lot of time. After that, I tested mybatisPlus to implement multi-table query by using pure object facing method. I finally decided to use handwritten SQL. For a slightly more complicated query (multi-table), it would be difficult and troublesome to use pure object writing method, so it would be better to directly use XML file mapping. In addition to fixing a few minor bugs
Blog cover detection
Some websites do not allow js to load images, because Vue actually uses JS to load images dynamically, so some websites have a protection mechanism, so I have to check whether the image can be loaded. It’s important, or it won’t show. The front-end code for uploading blogs is modified as follows (in fact, it is mainly the front-end)
<template>
<div class="m_container">
<! -- Blog content -->
<div class="m_content">
<el-form ref="editForm" status-icon :model="editForm" label-width="80px">
<input type="text" name="blogname" placeholder="Please enter the title of the article" v-model="editForm.title">
<el-button id="submit" type="primary" @click="tosubmitForm('editForm')">Published articles</el-button>
<br>
<br>
<mavon-editor
v-model="editForm.content"
ref="md"
@imgAdd="imgAdd"
@change="change"
style="min-height: 800px; width: 100%"
/>
</el-form>
</div>
<! -- Dialog box content -->
<el-dialog title="Post an article" :visible.sync="dialogFormVisible" width="35%">
<el-form :model="editForm" ref="editForm2">
<el-form-item label="Description" prop="description">
<textarea :maxlength="120"
v-model="editForm.description" style=" width: 80%; height: 150px; border-color: lightgrey; border-radius: 5px"
class="texti" placeholder="Please write a blog description (required)"
></textarea>
</el-form-item>
<el-form-item label="Classified column" prop="channel_id" :rules="{required: true, message: 'Category column cannot be empty ', trigger: 'blur'}">
<el-select v-model="editForm.channel_id" placeholder="Please select channel">
<el-option v-for="(item,index) in baseChannels" :key="item.index" :label="item.channelName" :value="item.id + ''"></el-option>
</el-select>
</el-form-item>
<el-form-item label="Blog Cover" prop="first_picture" >
<el-input v-model="editForm.first_picture" placeholder="Please enter the cover URL"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogFormVisible = false">cancel</el-button>
<el-button type="primary" @click="submitBlog('editForm2')">determine</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { mavonEditor } from 'mavon-editor'
import 'mavon-editor/dist/css/index.css'
import axios from "axios";
export default {
name: "Writeboke".data() {
return {
editForm: { // The blog post form
title: ' '.description: ' '.first_picture: ' '.content: ' '.channel_id: ' '.flag:' '.published: null,},okimg: 1.baseChannels: [].// The thing that needs to be loaded when entering the page
success: null.// Interactive state!
editForm2: { // A form for validation
channel_id: null.flag:' '.published: null,},oldtags:' '.// String label
type: {// Category column
name:' '
},
dialogFormVisible: false.// Control the Publish blog dialog box
dialog2: false.// Control the new category column dialog box}},mounted() {
// Get the channel from the server. // Get the channel from the server
this.axios({
url: "/boot/getbasechannels".method: 'post',
}).then(res= >{
this.baseChannels = res.data.baseChannels
this.success = res.data.success
if(this.success == '0'){
alert("Data loading exception")}})},methods: {
// Go post the article
isokPic(){
this.axios({
url:this.editForm.first_picture,
}).catch(error= >{
this.okimg = 0})},toSubmit() {
this.dialogFormVisible = true
this.initType()
},
// Initialize the article column
initType(){},submitForm(formName) {
this.$refs[formName].validate((valid) = > {
if (valid) {
this.addNewType()
} else {
return false; }}); },// Verify the basic blog content form
tosubmitForm(formName) {
if(this.editForm.title == ' '){
alert("Article title cannot be empty.")
return
}
if(this.editForm.content == ' '){
alert("The content of the article cannot be empty.")
return
}
this.toSubmit()
},
// Verify the publish blog form and publish the blog after successful verification
submitBlog(formName) {
if(this.editForm.description == ' '){
alert("Article description cannot be empty.")
return
}
if(this.editForm.channel_id == ' '){
alert("Please select a category")
return;
}
this.isokPic()
console.log(this.okimg)
setTimeout(this.sendBlog,2000)},sendBlog(){
if(this.okimg == 1) {// Post a blog
this.editForm.content = this.html;
this.axios({
url: "/boot/userblog/saveblog".method: "post".data: {
boke: this.editForm
},
headers: {"token": localStorage.getExpire("tokenhole"),
}
}).then(res= >{
if(res.data.success == 0) {this.dialogFormVisible = false
alert("Blog delivery failed")
return
}
alert("Blog launched successfully.")
this.dialogFormVisible = false
})
console.log("Blog post")}else {
return false;
}
if(this.okimg == 0){
alert("The target image address denied our access, please change the image source!")
return}},imgAdd(pos, $file){
let param = new FormData()
param.append("file",$file)
this.axios({
url: "/boot/boke/bokeImg".method: "post".data: param,
headers: {'Content-Type': 'multipart/form-data'."token": localStorage.getExpire("tokenhole"),
}
}).then(res= >{
if(res.data.success == 0){
alert("Picture uploading failed")
return
}
let url = "/boot"+ res.data.bokeImg
this.$refs.md.$img2Url(pos,url)
})
},
// All operations will be parsed and re-rendered
change(value, render){ //value is the actual content in the editor, i.e. the markdown content, and render is the HTML content that is parsed
this.html = render;
},
/ / submit
submit(){ // If you click Submit, you can get both the HTML content and the Markdown content, and then save it to the server
console.log(this.editForm.content);
console.log(this.html); }}},</script>
<style>
.m_container{
margin-top: 20px;
}
.el-tag + .el-tag {
margin-left: 10px;
}
.button-new-tag {
margin-left: 10px;
height: 32px;
line-height: 30px;
padding-top: 0;
padding-bottom: 0;
}
.input-new-tag {
width: 90px;
margin-left: 10px;
vertical-align: bottom;
}
input {
width: 85%;
height: 30px;
border-width: 2px;
border-radius: 5px;
border-color: #00c4ff;
border-bottom-color: #2C7EEA;
color: #586e75;
font-size: 15px;
}
#submit {
width: 10%;
height: 35px;
border-width: 0px;
margin-left: 3%;
border-radius: 10px;
background: #1E90FF;
cursor: pointer;
outline: none;
color: white;
font-size: 17px;
}
#submit:hover {
background-color: #1E90FF;
box-shadow: 0 4px 0 powderblue;
}
.texti:focus{
border-color: #1e88e1;
outline: 0;
-webkit-box-shadow: inset 0 1px 1px rgba(0.0.0.075),0 0 8px rgba(102.175.233.6);
box-shadow: inset 0 1px 1px rgba(0.0.0.075),0 0 8px rgba(102.175.233.6)}textarea {
resize: none;
}
</style>
Copy the code
As you can see, I was asleep for 2 seconds on purpose, mainly to let the user verify that the image can be accessed, and also to make the user wait to prevent crawlers, and I will make a waiting to load thing later.
Multi-table query paging
So let’s get down to business. I introduced the structure of our entire table, so I’m not going to repeat it here. Where you need to use multiple tables is the channel table and the blog table, and the whole thing is the whole thing. Two methods are provided here
Using annotations
The whole thing is simple, let’s just write annotations in that Mapper file.
@Mapper
public interface BaseChannelMapper extends BaseMapper<BaseChannel> {
@Select("select * from userblogs as blog inner join blogandbasechannel as channel on channel.ChannelId=#{id}")
IPage<UserBlogs> GetChannelBlogs(@Param("page") IPage<UserBlogs> page, @Param("id") int id);
}
Copy the code
Use XML configuration files
There are a couple of things to note here. The first step is to set up your XML placement directory for MyAbtisPlus to scan. I put it hereTherefore, modify the configuration file
mybatis-plus:
global-config:
db-config:
id-type: auto
table-underline: false
mapper-locations:
- classpath*:/mapping/*.xml
configuration:
map-underscore-to-camel-case: false
Copy the code
Then I had fun writing that XML
<! DOCTYPEmapper
PUBLIC "- / / mybatis.org//DTD Mapper / 3.0 / EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.huterox.whiteholeboot.Entity.Mapper.BaseMapper.BaseChannelMapper">
<! --sql-->
<select id="GetChannelBlogs" resultType="com.huterox.whiteholeboot.Entity.Pojo.BokePojo.UserBlogs">
select * from userblogs as blog inner join blogandbasechannel as channel on channel.ChannelId=#{id} and blog.Id = channel.UserBlogsId
</select>
</mapper>
Copy the code
The pager
And then there’s the pager, the single-table one, which is basically the pager for our own defined methods, which is very important. This is actually quite simple, but pay attention to detail. Ok Until then, whether it is single table or multiple tables, we have to turn on our configuration
@Configuration
@EnableTransactionManagement
public class MyBatisPlusConfig {
@Bean
public PaginationInterceptor paginationInterceptor(a){
PaginationInterceptor page = new PaginationInterceptor();
page.setDialectType("mysql");
returnpage; }}Copy the code
And then we have to write this in our mapper
@Mapper
public interface BaseChannelMapper extends BaseMapper<BaseChannel> {
@Select("select * from userblogs as blog inner join blogandbasechannel as channel on channel.ChannelId=#{id}")
IPage<UserBlogs> GetChannelBlogs(@Param("page") IPage<UserBlogs> page, @Param("id") int id);
}
Copy the code
Pay attention to the type returned, remember. My myBatisplus 3.x is the only method that I have searched before, but it seems that this method is the only one that works. I am not sure if there are other methods, but the return type must be IPage.
And then there’s use.
public Page GetChannelBlogs(int channel_id,int page,int size){
Page<UserBlogs> page2 = new Page<>(page,size);
baseChannelMapper.GetChannelBlogs(page2,channel_id);
return page2;
}
Copy the code
Then there are the other queries, which are very simple.
Bloggers display
This is mostly a front end problem. There are two
Show picture size
Since I’m putting the HTML file in our database, we can load it directly, but it’s in V-HTML, so we have to change the style in it like this (assuming I change the image style, it’s ugly).
/deep/ img{
width: 70%;
height: 400px;
margin-left: 15%;
margin-top: 2%;
}
Copy the code
Add/deep /
Code highlighting
This is mainly to achieve this effectThis one was easy. I worked on it for a while. Import this thing
import 'highlight.js/styles/googlecode.css'
Copy the code
Finally, let’s look at the overall code
<template>
<div style="background-color: #f8f8e7">
<el-row class="main" type="flex" justify="center">
<el-col :span="16">
<div style="margin: 0 auto">
<h3>{{title}}</h3>
</div>
<br>
<h5>Author: {{author}}</h5>
<h4>
<i class="el-icon-time"></i>: {{time}}
</h4>
<br>
<p>The original:</p>
<div class="markdown-body" style="border-radius: 5px; border: solid 2px #47aeef" v-model="body" v-html="body"></div>
</el-col>
</el-row>
</div>
</template>
<script>
import 'mavon-editor/dist/css/index.css'
import 'highlight.js/styles/googlecode.css'
export default {
name: 'article'.data(){
return{
author :this.$route.params.autoer,
blogsId: this.$route.params.blogsId,
title: this.$route.params.title,
time: this.$route.params.time,
body: null}},mounted() {
this.axios({
url: "/boot/base/viewblog".params: {BlogId:this.blogsId
}
}).then(res= >{
this.body = res.data.body.body
if(res.data.success == "0"){
alert("Abnormal blog loading, please try again ~")}})}}</script>
<style scoped>
#artcle-info {
padding: 20px;
background-image: url(../assets/vue.jpg);
margin-bottom: 40px;
}
#artcle-info .abstract {
color: #ffffff;
border-left: 3px solid #F56C6C;
padding: 10px;
background-color: rgba(126.129.135.0.3);
}
#artcle-info .timeAndView {
padding: 20px;
line-height: 30px;
font-size: 16px;
color: #ffffff;
}
pre.has {
color: #ffffff;
background-color: rgba(0.0.0.0.8);
}
img.has {
width: 100%;
}
#statement {
border-left: 3px solid #F56C6C;
padding: 20px;
background-color: #EBEEF5;
}
/deep/ img{
width: 70%;
height: 400px;
margin-left: 15%;
margin-top: 2%;
}
</style>
Copy the code
conclusion
So far, the most basic function is ready, just can be used to, but there are still no time, so first come here, and I’m still lack of the front end of the background management code can’t continue to do so (here if you have a ready-made background management template is best vue 2 x, if possible, share with bai ~ ~). For now, it looks something like this:
Home page
The article page
Writing a blog pageChannel pageEnter the channel
Personal center Interesting toolsFriends and exchange chain