源码地址:https://github.com/18291907191/gwc_manage

Vue实现狗尾草博客后台管理系统第六章

本章节内容

  1. 文章列表

  2. 文章详情

  3. 草稿箱

  4. 文章发布。

本章节内容呢,开发的很是随意哈,因为多数就是element-ui的使用,熟悉的童鞋,是可以很快完成本章节的内容的。

为啥文章模块会有这么多东西呢?

因为狗尾草想着以后,文章如果是待发布的话就需要一个地方去存放起来,一开始删除的文章呢,也将会被移入到草稿箱中,这样的话,文章就不会被随便的更改啦。

文章列表

先给大家一张效果图

是不是感觉非常轻松,一个table就可以搞定,

这里的代码呢,我就直接贴出来,因为没有什么值得注意的地方都是基础。

article>list.vue

<template>
<div class="article-wrap">
<el-table
:data="articleList"
height="100%"
stripe> <el-table-column
prop="id"
align="center"
label="文章编号">
</el-table-column> <el-table-column
prop="create_time"
align="center"
label="创建时间">
<template slot-scope="scope">
{{$moment(scope.row.create_time).format('YYYY-MM-DD HH:mm')}}
</template>
</el-table-column> <el-table-column
prop="tags"
align="center"
label="标签">
<template slot-scope="scope">
{{$utils.formatTableFont(scope.row.tags)}}
</template>
</el-table-column> <el-table-column
prop="title"
align="center"
label="标题">
<template slot-scope="scope">
{{$utils.formatTableFont(scope.row.title)}}
</template>
</el-table-column> <el-table-column
prop="title_image"
align="center"
label="标题图片">
<template slot-scope="scope">
<img v-if="scope.row.title_image" class="title-img" :src="scope.row.title_image" />
<span v-else>-</span>
</template>
</el-table-column> <el-table-column
prop="reader_number"
align="center"
label="阅读数">
<template slot-scope="scope">
{{$utils.formatTableData(scope.row.reader_number)}}
</template>
</el-table-column> <el-table-column
prop="good_number"
align="center"
label="点赞数">
<template slot-scope="scope">
{{$utils.formatTableData(scope.row.good_number)}}
</template>
</el-table-column> <el-table-column
label="操作"
align="center"
fixed="right">
<template slot-scope="scope">
<el-button size="mini" @click.stop="$router.push({path:'/article/detail',query:{articleId:scope.row.id,status:1}})">编辑</el-button>
</template>
</el-table-column>
</el-table>
</div>
</template>
<script>
export default {
data() {
return {
articleList: [],
params: {
searchParams: '',
page: ,
size: ,
status:
},
}
},
methods: {
// 获取文章列表
async getArticleList() {
try {
const { articleData } = await this.$http.getRequest('/article/api/v1/article_list',this.params);
this.articleList = articleData;
} catch(err) {
throw new Error('获取文章列表失败',err);
}
}
},
mounted() {
this.getArticleList();
}
}
</script>
<style lang="less" scoped>
.article-wrap {
height: %;
overflow: hidden;
/deep/.title-img {
width: 90px;
height: 90px;
}
}
</style>

这里呢,接口呢,都已经完成了。这类先不做说明,后面会单独将node.js抽离出来的哈。

不过呢,这里的formatTableData方法呢,是因为我们在做表格数据显示的时候呢,会有没有数据的情景,所以这里。我封装了一个方法,专门的针对表格的数据进行一个处理,在没有数据的时候呢就显示'-',如果是数字类型的呢,这里就显示0

给大家把方法贴出来,至于如果把方法挂在到全局,前面有讲到啦。这里也不需要这样做,因为直接方法utils文件中,utils挂载到全局,是可以直接使用的了。

utils>plugins.js

import * as http from './http';
import VueCookies from 'vue-cookies'
import moment from 'moment';
import utils from './plugins'; const install = (Vue, opts = {}) => {
if (install.installed) return;
Vue.prototype.$http = http;
Vue.prototype.$cookies = VueCookies;
Vue.prototype.$moment = moment;
Vue.prototype.$utils = utils;
} export default install

utils>index.js

/**
* @description 封装的工具类
* @author chaizhiyang
*/
class Util {
/**
* 保留小数点后两位
* @param {Number} data 需要处理的数值
* @return {Number} 保留两位小数的数值
* @author Czy 2018-10-25
*/
returnFloat(data) {
return data.toFixed()
} //el-table表格数据的处理
formatTableFont(val) {
//格式化数据,为空或0或null时,显示无
let formatTableData;
if (!val) {
formatTableData = "-";
} else {
formatTableData = val;
}
return formatTableData;
}; //el-table表格数据的处理
formatTableData(val) {
//格式化数据,为空或0或null时,显示无
let formatTableData;
if (!val) {
formatTableData = "";
} else {
formatTableData = val;
}
return formatTableData;
}; // 返回性别
sexStatus(status) {
if (!status) return
switch (status) {
case :
return '男';
break;
case :
return '女';
break;
default:
return '未知';
break;
}
} /**
* 正则验证
* @param {Number,String} str 需要验证的内容如:手机号,邮箱等
* @param {String} type 需要正则验证的类型
* @return {Boolean} true: 正则通过,输入无误。false: 正则验证失败,输入有误
* @author Czy 2018-10-25
*/
checkStr(str, type) {
switch (type) {
case 'phone': //手机号码
return /^[||||][-]{}$/.test(str);
case 'tel': //座机
return /^(\d{,}-\d{,})(-\d{,})?$/.test(str);
case 'card': //身份证
return /^\d{}|\d{}$/.test(str);
case 'account': //账号 ,长度4~16之间,只能包含数字,中文,字母和下划线
return /^(\w|[\u4E00-\u9FA5])*$/.test(str);
case 'pwd': //密码以字母开头,长度在6~18之间,只能包含字母、数字和下划线
return /^[a-zA-Z]\w{,}$/.test(str);
case 'postal': //邮政编码
return /[-]\d{}(?!\d)/.test(str);
case 'QQ': //QQ号
return /^[-][-]{,}$/.test(str);
case 'email': //邮箱
return /^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$/.test(str);
case 'money': //金额(小数点2位)
return /^\d*(?:\.\d{,})?$/.test(str);
case 'URL': //网址
return /(http|ftp|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&:/~\+#]*[\w\-\@?^=%&/~\+#])?/.test(str);
case 'IP': //IP
return /((?:(?:[-]|[-]\\d|[]?\\d?\\d)\\.){}(?:[-]|[-]\\d|[]?\\d?\\d))/.test(str);
case 'date': //日期时间
return /^(\d{})\-(\d{})\-(\d{}) (\d{})(?:\:\d{}|:(\d{}):(\d{}))$/.test(str) || /^(\d{})\-(\d{})\-(\d{})$/.test(str);
case 'number': //数字
return /^[-]$/.test(str);
case 'english': //英文
return /^[a-zA-Z]+$/.test(str);
case 'chinese': //中文
return /^[\u4E00-\u9FA5]+$/.test(str);
case 'lower': //小写
return /^[a-z]+$/.test(str);
case 'upper': //大写
return /^[A-Z]+$/.test(str);
case 'HTML': //HTML标记
return /<("[^"]*"|'[^']*'|[^'">])*>/.test(str);
default:
return true;
}
} /**
* 类型判断
* @param {*} o 进行判断的内容
* @return {Boolean} true: 是该类型,false: 不是该类型
* @author Czy 2018-10-25
*/
isString(o) { //是否字符串
return Object.prototype.toString.call(o).slice(, -) === 'String'
} isNumber(o) { //是否数字
return Object.prototype.toString.call(o).slice(, -) === 'Number'
} isObj(o) { //是否对象
return Object.prototype.toString.call(o).slice(, -) === 'Object'
} isArray(o) { //是否数组
return Object.prototype.toString.call(o).slice(, -) === 'Array'
} isDate(o) { //是否时间
return Object.prototype.toString.call(o).slice(, -) === 'Date'
} isBoolean(o) { //是否boolean
return Object.prototype.toString.call(o).slice(, -) === 'Boolean'
} isFunction(o) { //是否函数
return Object.prototype.toString.call(o).slice(, -) === 'Function'
} isNull(o) { //是否为null
return Object.prototype.toString.call(o).slice(, -) === 'Null'
} isUndefined(o) { //是否undefined
return Object.prototype.toString.call(o).slice(, -) === 'Undefined'
} isFalse(o) {
if (o == '' || o == undefined || o == null || o == 'null' || o == 'undefined' || o == || o == false || o == NaN) {
return true
}
return false
} isTrue(o) {
return !this.isFalse(o)
}
} export default new Util();

这里直接挂在到全局。使用方法呢就是this.$utils.func就可以了

文章详情

这里的主要功能呢就是根据id去回显该文章的所有信息,并可以进行修改,删除,移入草稿箱等得操作。这里呢,因为详情和发布是相同的,所以呢,这里也就发一份。当然了就有同学问我,为什么不讲两个页面放到一个页面中呢。

这里给大家解释一下哈:

项目初期往往会比较简单,大多人选择将相同的地方进行封装,给前妻开发带来很大方便,但是项目越往后,会发现,在一个页面反复的添加,修改判断。页面的逻辑处理变得十分复杂,便后悔当初没有还不如分开处理。当然,另一个原因就是,这里路由也做了懒加载,我们在不进入另一个路由的同时呢。他是不会被加载的。性能损耗而言呢,也就是多占了份空间,当然,不要为了封装而封装,不要过度封装。适用才是最合适的!

article>publish

<template>
<section class="wraper">
<el-form ref="form" :model="form" label-width="92px" :rules="rules">
<!--S 标题 -->
<admin-title :title="title.tit1"></admin-title>
<el-form-item label="Article Title" prop="title">
<el-col :span="">
<el-input v-model="form.title"></el-input>
</el-col>
</el-form-item>
<el-form-item label="Title Image" prop="title_image"
>
<el-col :span="">
<el-input v-model="form.title_image"></el-input>
</el-col>
</el-form-item>
<admin-title :title="title.tit2"></admin-title>
<el-form-item label="Article Tags" prop="tags">
<el-col :span="">
<el-select
style="width: 100%;"
v-model="form.tags"
multiple
filterable
allow-create
default-first-option
placeholder="请选择文章标签">
<el-option
v-for="item in tagList"
:key="item.id"
:label="item.tag"
:value="item.id">
</el-option>
</el-select>
</el-col>
</el-form-item>
<admin-title :title="title.tit3"></admin-title>
<el-form-item label="Abstract" prop="describe" align="left">
<textarea class="abstract" v-bind:maxlength="" v-model="form.describe" rows="" cols="" type="text" name="abstract">
</textarea>
<span style="font-size:16px;"><font style="color: #3576e0;">{{ - form.describe.length}}</font>/</span>
</el-form-item>
<el-form-item label="Content" prop="content">
<mavon-editor v-model="form.content"/>
</el-form-item>
<el-form-item align="left">
<el-col>
<el-button type="primary" @click.native="handleSubmit('rules')" :loading="buttonLoading.publishLoading">文章发布</el-button>
<el-button type="primary" @click.native="handleMoveDraft('rules')" :loading="buttonLoading.draftLoading">保存草稿</el-button>
</el-col>
</el-form-item>
</el-form>
</section>
</template>
<script>
import AdminTitle from '@/components/commons/Title'; export default {
components: {
AdminTitle,
},
watch: {
'form.describe'(curVal, oldVal) {
if (curVal.length > this.textNum) {
this.textareaValue = String(curVal).slice(, this.textNum);
}
}
},
data() {
return {
title: {
tit1: '文章标题',
tit2: '文章标签',
tit3: '文章摘要',
}, //标题
form: {
title: '',
tags: [],
title_image: '',
describe: '',
content: '',
status: ,
}, //提交数据
tagList: [], //标签选择器
textNum: ,
previewMarkdown: '<h1>测试</h1>',
buttonLoading: {
publishLoading: false,
draftLoading: false
},
rules: {
title: [
{ required: true, message: '请输入文章标题', trigger: 'blur'}
],
title_img: [
{ required: false, message: '请输入标题图片', trigger: 'blur'}
],
tags: [
{ required: false, message: '请选择文章标签', trigger: 'change'}
],
describe: [
{ required: true, message: '请输入文章摘要', trigger: ['change','blur']}
],
content: [
{ required: true, message: '请输入文章内容', trigger: ['blur','change']}
]
}, // 表单规则校验
}
},
methods: {
//发布文章
async handleSubmit() {
let isOk = this.validata();
if(!isOk) {
return ;
}
this.form.status = ;
this.publishLoading = true;
try {
const result = await this.$http.postRequest('/article/api/v1/article_add',this.form);
this.publishLoading = false;
this.$message({
type: 'success',
message: '文章发布成功!'
})
this.$router.push({
path: '/article/list'
})
} catch(err) {
throw new Error('文章更新失败',err);
this.publishLoading = false;
}
},
// 保存草稿
async handleMoveDraft() {
this.form.status = ;
this.publishLoading = true;
try {
const result = await this.$http.postRequest('/article/api/v1/article_add',this.form);
this.publishLoading = false;
this.$message({
type: 'success',
message: '保存草稿箱成功!'
})
this.$router.push({
path: '/article/draft'
})
} catch(err) {
this.publishLoading = false;
throw new Error('保存草稿失败',err);
}
},
// 表单校验
validata() {
let isForm;
this.$refs.form.validate(valid => {
isForm = valid;
});
if (!isForm) {
return false;
}
return true;
},
// 获取文章所有标签
getTags() {
let hash = {};
let arr = [];
axios.get('/article/api/v1/articleTags')
.then(res => {
arr = res.reduce((item,next) => {
hash[next.tag] ? '' : hash[next.tag] = true && item.push(next);
return item;
},[]);
this.tagList = arr;
})
}
},
}
</script>
<style lang="less" scoped>
.wraper {
width: %;
height: %;
.abstract {
padding: 10px;
font-size: 14px;
}
/deep/.el-form-item__label {
text-align: left;
padding-right: ;
}
} </style>

这里有一个重点,需要大家着重记一下的是,表单的校验,我们在添加好了以后,往往在需要提交的时候去进行判断,将不符合规则的表单给提示出来。不会使用的人,便会去写很多的if判断,this.$message({type:'error',message:'xxx'})的方法给出来,

但是element_ui明明已经给了一个合理的解决方案了。大家就要学会去使用,给我们带来便捷!

  // 表单校验
validata() {
let isForm;
this.$refs.form.validate(valid => {
isForm = valid;
});
if (!isForm) {
return false;
}
return true;
},

这块的表单校验,通过给 form表单起一个名称,在提交的时候,调用validate方法就可以方便的达到校验表单的效果。根据返回结果去判断是否继续往下执行就可以啦。get到了有木有。

封装的一个subtitle组件

compoents/commons/Title.vue

<template>
<p class="title">{{title}}</p>
</template> <script>
export default {
name: "AdminTitle",
props: {
title: String
},
data () {
return { };
}
};
</script> <style lang="less">
.title {
display: flex;
align-items: center;
margin: 20px ;
color: #;
position: relative;
&::before {
content: "";
display: inline-block;
position: absolute;
left: -15px;
width: 2px;
height: 13px;
background-color: #3576e0;
border-radius: 1px;
}
}
</style>

这里呢,狗尾草选择使用了<mavon-editor v-model="form.content"/>富文本编辑器,富文本编辑器很多哈。这里就不做特殊说明,有使用遇到坎坷的童鞋呢,可以留言咨询哦。(大家可以查看后期我的react前端文章详情的回显效果)

草稿箱

这里的草稿箱呢,其实表面上看和列表页是一样的。但是呢。文章没有写完的依旧可以放在草稿箱中。待发布的也可以放在草稿箱中,这也就是像个完全不同功能的模块了。

article>draft.vue

<template>
<div class="article-wrap">
<el-table
:data="articleList"
height="100%"
stripe> <el-table-column
prop="id"
align="center"
label="文章编号">
</el-table-column> <el-table-column
prop="create_time"
align="center"
label="创建时间">
<template slot-scope="scope">
{{$moment(scope.row.create_time).format('YYYY-MM-DD HH:mm')}}
</template>
</el-table-column> <el-table-column
prop="tags"
align="center"
label="标签">
<template slot-scope="scope">
{{$utils.formatTableFont(scope.row.tags)}}
</template>
</el-table-column> <el-table-column
prop="title"
align="center"
label="标题">
<template slot-scope="scope">
{{$utils.formatTableFont(scope.row.title)}}
</template>
</el-table-column> <el-table-column
prop="title_image"
align="center"
label="标题图片">
<template slot-scope="scope">
<img v-if="scope.row.title_image" class="title-img" :src="scope.row.title_image" />
<span v-else>-</span>
</template>
</el-table-column> <el-table-column
prop="reader_number"
align="center"
label="阅读数">
<template slot-scope="scope">
{{$utils.formatTableData(scope.row.reader_number)}}
</template>
</el-table-column> <el-table-column
prop="good_number"
align="center"
label="点赞数">
<template slot-scope="scope">
{{$utils.formatTableData(scope.row.good_number)}}
</template>
</el-table-column> <el-table-column
label="操作"
align="center"
fixed="right">
<template slot-scope="scope">
<el-button size="mini" @click.stop="$router.push({path:'/article/detail',query:{articleId:scope.row.id,status:2}})">编辑</el-button>
<el-button size="mini" type="danger" @click.stop="handleDeleteDraft(scope.row.id)">删除</el-button>
</template>
</el-table-column>
</el-table>
</div>
</template>
<script>
export default {
data() {
return {
articleList: [],
params: {
searchParams: '',
page: ,
size: ,
status:
}
}
},
methods: {
//获取文章列表
async getArticleList() {
try {
const { articleData } = await this.$http.getRequest('/article/api/v1/article_list',this.params);
this.articleList = articleData;
} catch(err) {
throw new Error('获取文章列表失败',err);
}
},
handleDeleteDraft(id) {
this.$confirm('此操作将永久删除该文章,不可复原, 是否继续?', '删除提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(async () => {
try {
const result = await this.$http.postRequest('/article/api/v1/article_delete',{ id });
this.$message({
type: 'success',
message: '文章已删除!'
})
this.getArticleList();
} catch(err) {
throw new Error('删除草稿失败',err);
}
this.$message({
type: 'success',
message: '删除成功!'
});
}).catch(() => {
this.$message({
type: 'info',
message: '已取消删除'
});
});
}
},
mounted() {
this.getArticleList();
}
}
</script>
<style lang="less" scoped>
.article-wrap {
height: %;
overflow: hidden;
/deep/.title-img {
width: 90px;
height: 90px;
}
}
</style>

这里给大家理一下这里的思路哈。

文章列表可编辑,编辑时,可选择将文章进行更新发布或者移入草稿箱。发布没有啥说的,移入草稿箱呢,其实也就是将该文章的状态进行更改。

在草稿箱中,主需要根据状态去查询文章即可。 但是草稿箱中的删除操作也就会将文章彻底的删除。

最后呢,附上更改后的路由

router>index.js

import Vue from 'vue'
import Router from 'vue-router'
// import HelloWorld from '@/components/HelloWorld'
Vue.use(Router) const _import = file => () => import('@/pages/' + file + '.vue');
const _import_ = file => () => import('@/components/' + file + '.vue'); const asyncRouterMap = []; const constantRouterMap = [
{
path: '/login',
name: 'Login',
component: _import('login/index'),
},
{
path: '/',
name: '概况',
component: _import_('commons/Layout'),
redirect: '/index',
children: [
{
path: '/index',
name: '总览',
component: _import('home/index'),
meta: {
isAlive: false,
auth: true,
title: '概况数据'
}
}
]
},
{
path: '/article',
name: '文章',
component: _import_('commons/Layout'),
redirect: '/article/publish',
children: [
{
path: '/article/publish',
name: '文章发布',
component: _import('article/publish'),
meta: {
auth: true,
isAlive: true,
isFooter: false,
title: '文章发布'
}
},
{
path: '/article/list',
name: '列表',
component: _import('article/list'),
meta: {
auth: true,
isAlive: false,
isFooter: true,
title: '列表'
}
},
{
path: '/article/draft',
name: '草稿箱',
component: _import('article/draft'),
meta: {
auth: true,
isAlive: false,
isFooter: true,
title: '草稿箱'
}
},
{
path: '/article/detail',
name: '文章详情',
component: _import('article/detail'),
meta: {
auth: true,
isAlive: false,
isFooter: false,
title: '文章详情'
}
}
]
},
{
path: '/404',
name: '',
component: _import('error/index'),
meta: {
title: "请求页面未找到",
auth: false
},
},
{
path: '*',
meta: {
title: "请求页面未找到",
auth: false
},
redirect: '/404'
}
]; const router = new Router({
mode: 'history',
routes: constantRouterMap,
linkActiveClass: "router-link-active",
}); export default router

总结

1.表单提交时的校验。

2.不要为了封装而封装。避免过度封装。适用才是王道。

下一章节

Vuex的进阶使用

Vue实战狗尾草博客管理平台第六章的更多相关文章

  1. Vue实战狗尾草博客管理平台第四章

    本章主要内容如下: 填补上期的坑. iconfont仓库的关联,引入. 开发登录页面 填坑 上期中我们功能都已正常使用.但不知道有没有小伙伴测试过error页面,当访问地址不存在时,路由是否能正常挑战 ...

  2. Vue实战狗尾草博客管理平台第五章

    本章主要内容如下: 静态资源服务器的配置.学会如何使用静态资源服务器引入静态资源.并给大家推荐一个免费可使用的oss服务器~ 页面的开发由于近期做出的更改较大.就放在下一篇中. 静态资源服务器 静态资 ...

  3. Vue实战狗尾草博客后台管理系统第七章

    Vue实战狗尾草博客后台管理平台第七章 本章内容为借助模块化来阐述Vuex的进阶使用. 在复杂项目的架构中,对于数据的处理是一个非常头疼的问题.处理不当,不仅对维护增加相当的工作负担,也给开发增加巨大 ...

  4. Vue实战狗尾草博客后台管理系统第三章

    Vue实现狗尾草博客后台管理系统第三章 本章节,咱们开发管理系统侧边栏及面包屑功能. 先上一张效果图 样式呢,作者前端初审,关于设计上毫无美感可言,大家可根据自己情况设计更好看的哦~ 侧边栏 这里我们 ...

  5. Vue实战狗尾草博客管理系统第一章

    Vue实战狗尾草博客后台管理系统第一章 这里准备采用的技术栈为:vue全家桶+element-ui 这里因为是后台管理系统,没有做SSR的必要.所以这里就采用前后端分离来昨晚这个项目~ 项目搭建 vu ...

  6. Vue实战狗尾草博客管理系统第二章

    伙伴们出来啦,探讨各问题,关于项目中大量的表单,大家是怎么处理的? 本章主要内容如下:底层布局,路由配置,github仓库推送关联. 关联GitHub仓库 关联建立在github已创建账号的基础上 登 ...

  7. 一个 Vue + Node + MongoDB 博客系统

    源码 耗时半载(半个月)的大项目终于完成了.这是一个博客系统,使用 Vue 做前端框架,Node + express 做后端,数据库使用的是 MongoDB.实现了用户注册.用户登录.博客管理(文章的 ...

  8. 关于vue项目管理项目的架构管理平台

    关于vue项目管理项目的架构管理平台 https://panjiachen.github.io/vue-element-admin-site/#/zh-cn/faq 31.4k 次浏览 完整项目地址: ...

  9. python drf+xadmin+react+dva+react-native+sentry+nginx 搭建前后端分离的博客完整平台

    前言: 经过差不多半年的开发,搭建从前端到服务器,实现了前后端分离的一个集PC端.移动端的多端应用,实属不易,今天得空,好好写篇文章,记录这些天的成果.同时也做个分享. 演示网站地址: http:// ...

随机推荐

  1. execjs使用时异常

    一.异常信息(...gbk.....) UnicodeDecodeError: 'gbk' codec can't decode byte 0xa1 in position 26: illegal m ...

  2. 【Gradle】自定义Android Gradle工程

    自定义Android Gradle工程 defaultConfig默认配置 defaultConfig是Android对象中的一个配置项,负责定义所有的默认配置.一个基本的defaultConfig配 ...

  3. mssql sqlserver 如何编写case when 多条件呢?

    摘要: 下文讲述case when中多条件的编写方法,如下所示: 实验环境:sql server 2008 R2  case when 多条件编写方法  case when多条件编写语法: case ...

  4. Redis—简介与安装

    Redis 简介 Redis 安装 Redis 配置文件 # Redis默认不是以守护进程的方式运行,可以通过该配置项修改,使用yes启用守护进程.daemonize yes # 当Redis以守护进 ...

  5. Linux:Apache服务器的搭建

    下载安装并启动apache服务 安装apache服务 yum install -y httpd 启动apache服务 systemctl start httpd.service apache服务器的目 ...

  6. Druid-代码段-4-1

    所属文章:池化技术(一)Druid是如何管理数据库连接的? 本代码段对应主流程4,丢弃连接的守护线程: //连接池瘦身,参考主流程4 public class DestroyConnectionThr ...

  7. jango rest-framework page_size更新

    老项目是三年前写的, 这周的新项目要用上DRF的分页功能时,发现老的写法无效了. 于是看了一些文档,原来写法变了. https://blog.csdn.net/dqchouyang/article/d ...

  8. Leetcode 1239. 串联字符串的最大长度

    地址 https://leetcode-cn.com/problems/maximum-length-of-a-concatenated-string-with-unique-characters/s ...

  9. 第05组 Alpha事后诸葛亮

    组长博客链接(2分) 组长博客链接 现代软件工程 项目Postmortem 模板(27分) 设想和目标(2分) 1.我们的软件要解决什么问题?是否定义得很清楚?是否对典型用户和典型场景有清晰的描述? ...

  10. 更新GitHub项目出现There is no tracking information for the current branch. Please specify which branch you want to merge with. 怎么解决

    git pull命令用于从另一个存储库或本地分支获取并集成(整合).git pull命令的作用是:取回远程主机某个分支的更新,再与本地的指定分支合并,它的完整格式稍稍有点复杂. 如果当前分支只有一个追 ...