(Vue+SpringBoot+elementUi+WangEditer)仿论坛项目

项目使用到的技术与库

1.前端 Vue2 elementUi Cookie WangEditer

2.后端 SpringBoot Mybatis-Plus

3.数据库 MySql

一、效果展示

1.1主页效果:

1.2 文章编辑页面:

1.3 成功发布文章

1.4 文章关键字搜索提示

 1.5 文章查询结果展示

1.6 文章内容及交互展示


二、表单设计的sql

用户:

create table paitool.user
(id                int auto_incrementprimary key,account           varchar(255)                                          not null,password          varchar(255)                                          not null,phone             varchar(20)                                           null,address           varchar(255)                                          null,isVip             tinyint(1)                  default 0                 null,email             varchar(255)                                          null,registration_date datetime                    default CURRENT_TIMESTAMP null,last_login        datetime                                              null,status            enum ('active', 'inactive') default 'active'          null,constraint account_UNIQUEunique (account),constraint email_UNIQUEunique (email),constraint phone_UNIQUEunique (phone)
);

文章:

create table paitool.forum_posts
(id         int auto_incrementprimary key,title      varchar(255)                            not null,content    text                                    not null,author_id  int                                     not null,created_at timestamp     default CURRENT_TIMESTAMP null,updated_at timestamp     default CURRENT_TIMESTAMP null on update CURRENT_TIMESTAMP,heat_value int           default 0                 null,rating     decimal(3, 2) default 0.00              null,tag        varchar(10)   default '其它'              null,constraint forum_posts_ibfk_1foreign key (author_id) references paitool.user (id)
);

文章交互表-点赞:

create table paitool.forum_post_likes
(user_id int not null,post_id int not null,primary key (user_id, post_id),constraint forum_post_likes_ibfk_1foreign key (user_id) references paitool.user (id),constraint forum_post_likes_ibfk_2foreign key (post_id) references paitool.forum_posts (id)
);

文章交互表-收藏:

create table paitool.forum_post_favorites
(user_id int not null,post_id int not null,primary key (user_id, post_id),constraint forum_post_favorites_ibfk_1foreign key (user_id) references paitool.user (id),constraint forum_post_favorites_ibfk_2foreign key (post_id) references paitool.forum_posts (id)
);

文章交互表-评论

create table paitool.forum_comments
(id           int auto_incrementprimary key,post_id      int                                 not null,user_id      int                                 not null,comment_text text                                not null,created_at   timestamp default CURRENT_TIMESTAMP null,constraint forum_comments_ibfk_1foreign key (user_id) references paitool.user (id),constraint forum_comments_ibfk_2foreign key (post_id) references paitool.forum_posts (id)
);

三、前端代码

3.1 论坛主页

Html:

<template><div id="forumLayOut"><div id="Top" style="background-color: rgb(250, 250, 250); padding-top: 20px"><div id="serchBorder" style="padding-bottom: 13px;"><!-- 搜索框 --><el-autocomplete v-model="searchKeyWord" :fetch-suggestions="querySearchAsync" :trigger-on-focus="false"placeholder="请输入关键字" style="width: 300px;" @select="handleSelect"></el-autocomplete><el-button type="primary" @click="onSubmit">查询</el-button></div><!-- 分类查询 --><div><div style="margin-bottom: 15px;"><el-checkbox-group v-model="checkboxGroup1" :max="1"><el-checkbox-button v-for="city in cities" :label="city" :key="city">{{ city}}</el-checkbox-button></el-checkbox-group></div></div><div style="height: 380px; width: 100%;"><!-- 轮播图 --><div class="block" style="width: 30%; float: left; margin-left: 5%; height: 400px;"><el-carousel height="350px" style="width: 100%;  "><el-carousel-item v-for="item in 4" :key="item"><img src="https://img95.699pic.com/photo/50035/3211.jpg_wh860.jpg" alt="风景测试"><h3 class="small">{{ item }}</h3></el-carousel-item></el-carousel></div><div style=" height: 350px; background-color: rgb(250, 250, 250); width: 25%; float: left;border: 1px solid rgb(240, 240, 242);  margin-left: 3%;"><div style="height: 50px; width: 100%; background-color: rgb(245, 245, 245); "><i class="el-icon-share"></i><div><b>热门</b></div><hr></div><div class="link-container"><a href="#" class="link" id="TurnLink">杀死谷歌,成为AI时代的搜索皇帝!</a><p style="color: gray;">Perplexity CEO 最新四万字访谈</p></div><div class="link-container"><a href="#" class="link" id="TurnLink">重写系统后痛批:这门语言烂透了!</a><p style="color: gray;">耗时18个月,开发者弃TypeScript投Rust</p></div><div class="link-container"><a href="#" class="link" id="TurnLink">Shire 编码智能体语言</a><p style="color: gray;">打造你的专属 AI 编程助手</p></div></div><div style="float: left;  margin-left: 3%; height: 350px; background-color: rgb(250, 250, 250); width: 25%; float: left;border: 1px solid rgb(240, 240, 242); "><div style="height: 50px; width: 100%; background-color: rgb(245, 245, 245); "><i class="el-icon-message-solid"></i><div><b>头条</b></div><hr></div><div class="link-container"><a href="#" class="link" id="TurnLink">史上开发最久的游戏!</a><p style="color: gray;">耗时 22 年,5 名打工人凑了几百欧就开工,只剩 1 人坚守到发布...</p></div><div class="link-container"><a href="#" class="link" id="TurnLink">实习期间创下 Transformer</a><p style="color: gray;">他说:当年整个 AI 圈都无法预见我们今天的高度</p></div><div class="link-container"><a href="#" class="link" id="TurnLink">杀死谷歌,成为AI时代的搜索皇帝!</a><p style="color: gray;">Perplexity CEO 最新四万字访谈</p></div></div></div></div><el-divider></el-divider><div id="bottom"><!-- Tabs 标签页  --><el-tabs v-model="activeName" @tab-click="handleClick" style="padding-left: 2em; "><el-tab-pane label="我的文章" name="first"><div class="parent-div" style="min-height: 500px"><div v-if="posts.length === 0"><el-empty :image-size="200"></el-empty></div><div class="custom-card" v-for="(post, index) in posts" :key="index"@click="getForumPostDetail(post.id)"><div class="card-content"><h1 class="card-title">标题: {{ post.title }}</h1><div class="card-meta"><span>作者: {{ post.account }}</span><span>标签: {{ post.tag }}</span><span><i class="el-icon-view">{{ post.heatValue }}</i></span></div><div class="card-rating"><span>文章评分:</span><el-rate v-model="post.rating" disabled show-score text-color="#ff9900"score-template="{value}" style="display: inline-block;"></el-rate></div></div></div></div></el-tab-pane><el-tab-pane label="推荐文章" name="second"><div v-if="posts.length === 0"><el-empty :image-size="200"></el-empty></div><div class="custom-card" v-for="(post, index) in posts" :key="index"@click="getForumPostDetail(post.postId)"><div class="card-content"><h1 class="card-title">标题: {{ post.title }}</h1><div class="card-meta"><span>作者: {{ post.account }}</span><span>标签: {{ post.tag }}</span><span><i class="el-icon-view">{{ post.heat_value }}</i></span></div><div class="card-rating"><span>文章评分:</span><el-rate v-model="post.rating" disabled show-score text-color="#ff9900"score-template="{value}" style="display: inline-block;"></el-rate></div></div></div></el-tab-pane><el-tab-pane label="热门文章" name="third"><div class="parent-div" style="min-height: 500px"><div v-if="posts.length === 0"><el-empty :image-size="200"></el-empty></div><div class="custom-card" v-for="(post, index) in posts" :key="index"@click="getForumPostDetail(post.id)"><div class="card-content"><h1 class="card-title">标题: {{ post.title }}</h1><div class="card-meta"><span>作者: {{ post.account }}</span><span>标签: {{ post.tag }}</span><span><i class="el-icon-view">{{ post.heatValue }}</i></span></div><div class="card-rating"><span>文章评分:</span><el-rate v-model="post.rating" disabled show-score text-color="#ff9900"score-template="{value}" style="display: inline-block;"></el-rate></div></div></div></div></el-tab-pane><el-tab-pane label="优质文章" name="fourth"><div class="parent-div" style="min-height: 500px"><div v-if="posts.length === 0"><el-empty :image-size="200"></el-empty></div><div class="custom-card" v-for="(post, index) in posts" :key="index"@click="getForumPostDetail(post.id)"><div class="card-content"><h1 class="card-title">标题: {{ post.title }}</h1><div class="card-meta"><span>作者: {{ post.account }}</span><span>标签: {{ post.tag }}</span><span><i class="el-icon-view">{{ post.heatValue }}</i></span></div><div class="card-rating"><span>文章评分:</span><el-rate v-model="post.rating" disabled show-score text-color="#ff9900"score-template="{value}" style="display: inline-block;"></el-rate></div></div></div></div></el-tab-pane><el-tab-pane label="我的收藏" name="fifth"><div v-if="posts.length === 0"><el-empty :image-size="200"></el-empty></div><div class="parent-div" style="min-height: 500px"><div v-if="posts.length === 0"><el-empty :image-size="200"></el-empty></div><div class="custom-card" v-for="(post, index) in posts" :key="index"@click="getForumPostDetail(post.id)"><div class="card-content"><h1 class="card-title">标题: {{ post.title }}</h1><div class="card-meta"><span>作者: {{ post.account }}</span><span>标签: {{ post.tag }}</span><span><i class="el-icon-view">{{ post.heatValue }}</i></span></div><div class="card-rating"><span>文章评分:</span><el-rate v-model="post.rating" disabled show-score text-color="#ff9900"score-template="{value}" style="display: inline-block;"></el-rate></div></div></div></div></el-tab-pane></el-tabs><el-button type="warning" round id="iWantPost" @click="navigateToPostEdit">我要发布文章</el-button></div></div>
</template>

js:

<script>
import axios from 'axios';
import Cookies from 'js-cookie';const cityOptions = ['新闻报道', '科技动态', '生活时尚', '教育学习', '健康养生'];
export default {components: {},data() {return {searchKeyWord: '',suggestions: [], // 添加这个属性checkboxGroup1: [],cities: cityOptions,activeName: 'first',currentPage1: 5,currentPage2: 5,currentPage3: 5,currentPage4: 4,posts: [],}},methods: {onSubmit() {this.$router.push({name: 'ArticalSearchView',params: {searchKeyWord: this.searchKeyWord}})},handleClick(tab) {// 我的文章if (tab.name === 'first') {this.posts = []this.getMyArticle();}// 推荐文章if (tab.name === 'second') {this.posts = [];axios.get('/api/forum/getAllForumPost', {params: {pageSize: 1,pageNumber: 10}}).then((response) => {console.log(response.data.data);this.posts = response.data.data;});}// 热门文章if (tab.name === 'third') {this.posts = [];axios.get('/api/forum/getHotPosts').then((response) => {console.log(response.data.data);this.posts = response.data.data;});}// 优质文章if (tab.name === 'fourth') {this.posts = [];axios.get('/api/forum/getOutStandPosts').then((response) => {console.log(response.data.data);this.posts = response.data.data;});}// 我的收藏if (tab.name === 'fifth') {this.posts = [];const id = Cookies.get("userId");if (id === null) {this.$message({message: '请先登录',type: 'warning'});return;}axios.get('/api/forum/getMyFavorite', {params: {id: id}}).then((response) => {console.log(response.data.data);this.posts = response.data.data;});}},// 处理分页功能handleSizeChange(val) {console.log(`每页 ${val} 条`);},handleCurrentChange(val) {console.log(`当前页: ${val}`);},navigateToPostEdit() {this.$router.push({ name: 'ForumPostEditView' });},// 跳转到文章详情getForumPostDetail(postId) {console.log("getForumPostDetail");console.log(postId);this.$router.push(`/post/${postId}`);},getMyArticle() {this.posts = [];const id = Cookies.get("userId");if (id === null) {this.$message({message: '请先登录',type: 'warning'});return;} else {axios.get('/api/forum/MyArticle', {params: {id: id}}).then((response) => {console.log(response.data.data);this.posts = response.data.data;})}},// 异步获取建议列表querySearchAsync(queryString, cb) {if (queryString.length === 0) {return cb([]); // 当查询字符串为空时,直接返回空数组}axios.get('/api/forum/getLikeSearch', { params: { keyword: queryString } }).then(response => {// 确保从后端返回的数据中提取出正确的数组const results = response.data.data || [];// 调用callback函数,传入搜索结果cb(results);}).catch(error => {console.error('Error fetching search suggestions:', error);cb([]);});},// 处理选择事件handleSelect(item) {this.searchKeyWord = item.value; this.onSubmit();}},mounted() {this.getMyArticle();}}</script>

css:

<style scoped>
#forumLayOut {background-color: white;height: auto;width: 100%;line-height: normal;
}#serchBorder {line-height: normal;
}.el-carousel__item h3 {color: #475669;font-size: 14px;opacity: 0.75;line-height: 150px;margin: 0;
}.el-carousel__item:nth-child(2n) {background-color: #99a9bf;
}.el-carousel__item:nth-child(2n+1) {background-color: #d3dce6;
}#Pagination {align-self: center;/* 居中对齐 */margin-bottom: 1rem;/* 可选,增加底部边距 */margin-top: 10%;
}#iWantPost {position: fixed;/* 设置为固定定位 */bottom: 60px;/* 距离底部的距离,可根据需要调整 */right: 40px;/* 距离右侧的距离,可根据需要调整 */
}.el-tabs__content {overflow: hidden;position: relative;height: auto;
}.custom-card {background-color: #ffffff;border-radius: 4px;box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);margin-bottom: 16px;transition: box-shadow 0.3s ease-in-out;
}.custom-card:hover {box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);cursor: pointer;background-color: rgb(245, 245, 245);
}.card-content {padding: 16px;
}.card-title {font-size: 1.2em;margin-bottom: 8px;color: #333;
}.card-meta {display: flex;align-items: center;justify-content: space-between;margin-bottom: 12px;color: #666;
}.card-rating {color: #666;
}.link-container {line-height: normal;float: left;width: 100%;text-align: left;padding-left: 40px;padding-top: 10px;
}.link {text-decoration: none;font-size: large;color: black;
}.link:hover {text-decoration: underline;
}
</style>

 

3.2 发布文章页面

<template><div style="border: 1px solid #ccc; line-height: normal; height: 100%;"><div><el-form :inline="true" :model="formInline" class="demo-form-inline"><el-form-item label="文章标题"><el-input v-model="formInline.title" placeholder="请输入文章标题" maxlength="20"></el-input></el-form-item><el-form-item label="类别"><el-select v-model="formInline.category" placeholder="请选择文章类别"><el-option label="新闻报道" value="news"></el-option><el-option label="科技动态" value="technology"></el-option><el-option label="生活时尚" value="lifestyle"></el-option><el-option label="教育学习" value="education"></el-option><el-option label="健康养生" value="health"></el-option></el-select></el-form-item><el-form-item><el-button type="primary" @click="onSubmit"v-loading.fullscreen.lock="fullscreenLoading">提交</el-button></el-form-item></el-form></div><Toolbar style="border-bottom: 1px solid #ccc" :editor="editor" :defaultConfig="toolbarConfig" :mode="mode" /><Editor style="height: 500px; overflow-y: hidden; height: 100%;" v-model="html" :defaultConfig="editorConfig":mode="mode" @onCreated="onCreated" /></div></template><script>
import Vue from 'vue'
import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
import axios from 'axios'
import Cookies from 'js-cookie'export default Vue.extend({components: { Editor, Toolbar },data() {return {editor: null,html: ' ',toolbarConfig: {},editorConfig: { placeholder: '请输入内容...' },mode: 'default', // or 'simple'formInline: {title: '',category: ''},fullscreenLoading: false}},methods: {onCreated(editor) {this.editor = Object.seal(editor) // 一定要用 Object.seal() ,否则会报错},onSubmit() {this.fullscreenLoading = true;const userId = Cookies.get('userId'); // 获取并转换userIdaxios.post('/api/forum/add', {"title": this.formInline.title,"content": this.editor.getHtml(), "authorId": userId,"tag": this.formInline.category,}).then((response) => {console.log(response.data);this.fullscreenLoading = false;this.$router.push({ name: 'ForumSucessPostView' });}).catch(error => {console.error(error);this.fullscreenLoading = false;});},},mounted() {},beforeDestroy() {const editor = this.editorif (editor == null) returneditor.destroy() // 组件销毁时,及时销毁编辑器},})
</script><style src="@wangeditor/editor/dist/css/style.css"></style>

3.3 文章发布成功页面


3.4 查看文章页面

html:

<template><div style="line-height: normal; background-color: rgb(246, 247, 249); height: auto; min-height: 80%;"><!-- 文章信息 --><div style="padding-top: 10px; width: auto; min-width: 40%;"><!-- 实现文字垂直居中 --><div id="Infor" style="background-color: white;"><h1 style="font-size: 28px; text-align: center">文章标题:{{title}}</h1><span>创作者:{{author}}</span><span style="margin-left: 20px;">创作日期:{{createAt}}</span><span style="margin-left: 20px;"><i class="el-icon-view">{{heatValue}}</i></span></div><el-divider><i class="el-icon-mobile-phone"></i></el-divider><!-- 文章内容展示区 --><div id="contentDisplay"><div v-html="content"style="padding-left: 2em; padding-top: 15px; padding-right: 2em; padding-bottom: 30px;"></div></div></div><el-divider><i class="el-icon-edit"></i></el-divider><!-- 交互按键 --><div id="buttom"><el-button type="warning" round @click="getBackToForum">返回到论坛</el-button><el-button type="warning" icon="el-icon-star-off" circle @click="PostFavorite"></el-button><el-button type="danger" icon="el-icon-thumb" circle @click="PostLike"></el-button></div><!-- 评论区 --><div id="commentListShow"><el-card class="box-card"><div slot="header" class="clearfix"><span>评论详情</span></div><div id="commentInputArea"><el-input type="textarea" placeholder="请您输入友善的评论吧" v-model="textarea" maxlength="300"show-word-limit id="inputFrame" :clearable="clearAble" resize="none"></el-input><div style="margin-top: 10px; padding-bottom: 50px;"><el-button type="primary" @click="SubmitComment">发表评论</el-button><el-button type="primary" @click="CancelComment">取消评论</el-button></div></div><div id="commentList"><div class="comment-card" v-for="comment in comments" :key="comment.id"><div class="comment-head"><h1 class="username">{{ comment.account }}</h1><p class="created-at">发表于:{{ comment.createdAt }}</p></div><el-divider></el-divider><p class="comment-text">{{ comment.commentText }}</p></div></div></el-card></div></div>
</template>

script:

<script>
import axios from 'axios';
import Cookies from 'js-cookie';export default{data() {return {postId: '',title: '',content: '',value1: null,textarea: '',userId:'',clearAble: true,comments:{},author:'',createAt:'',heatValue:'',}},created() {this.postId = this.$route.params.postId;this.fetchPostDetail(this.$route.params.postId);this.userId = Cookies.get('userId');},mounted() {this.readComment();},methods: {// 前端实现路径传参async fetchPostDetail(postId) {try {this.fullscreenLoading = true;const url = `/api/forum/post/${postId}`;// 发起GET请求const response = await axios.get(url);if (response.status === 200) {// 请求成功,处理响应数据const postData = response.data;console.log('文章详情:', postData);// 更新组件状态或执行其他操作this.title = response.data.data.title;this.content = response.data.data.content;this.author = response.data.data.account;this.createAt = response.data.data.createdAt;this.heatValue = response.data.data.heatValue;this.fullscreenLoading = false;} else {console.error('请求失败,状态码:', response.status);}} catch (error) {console.error('请求错误:', error);}},getBackToForum() {this.$router.push({ name: 'forum' });},// 取消评论CancelComment(){this.textarea = '';},// 执行点赞按钮PostLike(){this.isLogin();axios.get('/api/forum/like',{params:{postId : this.postId,userId : this.userId}}).then((response)=>{this.MessageNotify(response);})},// 执行收藏按钮PostFavorite(){this.isLogin();axios.get('/api/forum/favorite',{params:{postId : this.postId,userId : this.userId}}).then((response)=>{this.MessageNotify(response);})},SubmitComment(){this.isLogin();axios.post('/api/forum/writeComment',{postId : this.postId,userId : this.userId,commentText : this.textarea}).then((response)=>{this.MessageNotify(response);this.textarea = '';this.readComment();})console.log("submit");},isLogin(){if(Cookies.get('userId') == null){this.$message.error('请先登录');return;}},// 消息提醒MessageNotify(response){if(response.data.code == 200){this.$message.success(response.data.data);}else{console.log(response.data);this.$message.error(response.data.message);}},readComment(){axios.get('/api/forum/getComment',{params:{postId : this.postId}}).then((response)=>{this.comments = response.data.data;})},}}</script>

css:


3.5 文章搜索页面

html:

<template><div id="layout"><div id="searchFrame"><div id="InputFrame"><el-input type="textarea" placeholder="请输入内容" v-model="textarea" rows="1" resize="none"style="font-size: larger; width: 80%;"></el-input><el-button type="warning" @click="SearchSubmit"  icon="el-icon-search">查询</el-button></div></div><div id="excess"><div id="Interate"><i class="el-icon-search"> 搜索结果</i></div></div><div id="SearchContent"><div v-if="posts.length === 0"><el-empty :image-size="200"></el-empty></div><div class="custom-card" v-for="(post, index) in posts" :key="index" @click="getForumPostDetail(post.id)"><div class="card-content"><h1 class="card-title">标题: {{ post.title }}</h1><div class="card-meta"><span>作者: {{ post.account }}</span><span>标签: {{ post.tag }}</span><span><i class="el-icon-view">{{ post.heatValue }}</i></span></div><div class="card-rating"><span>文章评分:</span><el-rate v-model="post.rating" disabled show-score text-color="#ff9900" score-template="{value}"style="display: inline-block;"></el-rate></div></div></div></div></div>
</template>

script:

<script>
import axios from 'axios';export default {data() {return {textarea: '',searchKeyWord: '',posts: [],}},methods: {SearchSubmit() {console.log(this.textarea);axios.get('/api/forum/search', {params: {searchKeyWord: this.textarea}}).then((response) => {if (response.data.code !== 200) {this.$notify({title: '警告',message: '搜索失败',type: 'warning'});}console.log(response.data.data);this.posts = response.data.data;});},Search() {axios.get('/api/forum/search', {params: {searchKeyWord: this.searchKeyWord}}).then((response) => {if (response.data.code !== 200) {this.$notify({title: '警告',message: '搜索失败',type: 'warning'});}console.log(response.data.data);this.posts = response.data.data;});},// 跳转到文章详情getForumPostDetail(postId) {console.log("getForumPostDetail");console.log(postId);this.$router.push(`/post/${postId}`);},},mounted() {this.searchKeyWord = this.$route.params.searchKeyWord;this.textarea = this.searchKeyWord;this.Search();}}
</script>

css:

<style scoped>
#layout {width: 100%;min-height: 90%;background-color: rgb(245, 246, 247);line-height: normal;
}#SearchContent{min-height: 800px;}#searchFrame {height: 70px;width: 100%;background-color: white;box-shadow: 0 2px 4px rgba(0, 0, 0, .12), 0 0 6px rgba(0, 0, 0, .04);position: -webkit-sticky;/* Safari */position: sticky;top: 0;z-index: 1000;line-height: normal;
}#InputFrame {width: 40%;margin: 0 auto;height: 60%;padding-top: 15px;
}#Interate {float: left;margin-top: 20px;margin-left: 20px;
}#excess {height: 61px;width: 80%;background-color: white;margin: 0 auto;margin-top: 25px;border: 1px solid rgb(245, 245, 245);border-radius: 4px;
}.custom-card {background-color: #ffffff;border-radius: 4px;box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);margin-bottom: 16px;transition: box-shadow 0.3s ease-in-out;width: 80%;margin: 0 auto;border: 1px solid rgb(245, 245, 245);
}.custom-card:hover {box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);cursor: pointer;background-color: rgb(245, 245, 245);
}.card-content {padding: 16px;
}.card-title {font-size: 1.2em;margin-bottom: 8px;color: #333;
}.card-meta {display: flex;align-items: center;justify-content: space-between;margin-bottom: 12px;color: #666;
}.card-rating {color: #666;
}.card-rating {color: #666;
}
</style>

 


 

四、后端代码

4.1项目后端依赖库

        <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><scope>compile</scope></dependency><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><scope>runtime</scope></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.3.1</version></dependency><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.11</version></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.3.1</version></dependency><!--swagger--><dependency><groupId>com.github.xiaoymin</groupId><artifactId>knife4j-spring-boot-starter</artifactId><version>3.0.2</version></dependency><!--web--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>5.3.15</version></dependency><dependency><groupId>io.springfox</groupId><artifactId>springfox-spring-web</artifactId><version>3.0.0</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.76</version></dependency><!-- https://mvnrepository.com/artifact/com.alibaba/dashscope-sdk-java --><dependency><groupId>com.alibaba</groupId><artifactId>dashscope-sdk-java</artifactId><version>2.8.2</version></dependency><!--okhttp3 依赖--><dependency><groupId>com.squareup.okhttp3</groupId><artifactId>okhttp</artifactId><version>4.9.3</version></dependency><!-- Lombok dependency --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><!--        验证码模块--><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.12.0</version></dependency>

4.2工具类Result类与实体类

public class Result<T> {// 状态码常量public static final int SUCCESS = 200;public static final int ERROR = 500;private int code; // 状态码private String message; // 消息private T data; // 数据// 构造函数,用于创建成功的结果对象private Result(int code, String message, T data) {this.code = code;this.message = message;this.data = data;}// 成功结果的静态方法public static <T> Result<T> success(T data) {return new Result<>(SUCCESS, "Success", data);}// 错误结果的静态方法public static <T> Result<T> error(String message) {return new Result<>(ERROR, message, null);}// 错误结果的静态方法,可以传入自定义的状态码public static <T> Result<T> error(int code, String message) {return new Result<>(code, message, null);}// 获取状态码public int getCode() {return code;}// 设置状态码public void setCode(int code) {this.code = code;}// 获取消息public String getMessage() {return message;}// 设置消息public void setMessage(String message) {this.message = message;}// 获取数据public T getData() {return data;}// 设置数据public void setData(T data) {this.data = data;}// 用于转换为Map类型的方法,方便序列化为JSONpublic Map<String, Object> toMap() {Map<String, Object> map = new HashMap<>();map.put("code", code);map.put("message", message);map.put("data", data);return map;}
}

Entity:

Forumpost:

@TableName(value ="forum_posts")
@Data
public class ForumPosts implements Serializable {/*** */@TableId(value = "id", type = IdType.AUTO)private Integer id;/*** */@TableField(value = "title")private String title;/*** */@TableField(value = "content")private String content;/*** */@TableField(value = "author_id")private Integer authorId;/*** */@TableField(value = "created_at")private LocalDateTime createdAt;/*** */@TableField(value = "updated_at")private LocalDateTime updatedAt;/*** */@TableField(value = "heat_value")private Integer heatValue;/*** */@TableField(value = "rating")private BigDecimal rating;/*** */@TableField(value = "tag")private String tag;@TableField(exist = false)private static final long serialVersionUID = 1L;@Overridepublic boolean equals(Object that) {if (this == that) {return true;}if (that == null) {return false;}if (getClass() != that.getClass()) {return false;}ForumPosts other = (ForumPosts) that;return (this.getId() == null ? other.getId() == null : this.getId().equals(other.getId()))&& (this.getTitle() == null ? other.getTitle() == null : this.getTitle().equals(other.getTitle()))&& (this.getContent() == null ? other.getContent() == null : this.getContent().equals(other.getContent()))&& (this.getAuthorId() == null ? other.getAuthorId() == null : this.getAuthorId().equals(other.getAuthorId()))&& (this.getCreatedAt() == null ? other.getCreatedAt() == null : this.getCreatedAt().equals(other.getCreatedAt()))&& (this.getUpdatedAt() == null ? other.getUpdatedAt() == null : this.getUpdatedAt().equals(other.getUpdatedAt()))&& (this.getHeatValue() == null ? other.getHeatValue() == null : this.getHeatValue().equals(other.getHeatValue()))&& (this.getRating() == null ? other.getRating() == null : this.getRating().equals(other.getRating()))&& (this.getTag() == null ? other.getTag() == null : this.getTag().equals(other.getTag()));}@Overridepublic int hashCode() {final int prime = 31;int result = 1;result = prime * result + ((getId() == null) ? 0 : getId().hashCode());result = prime * result + ((getTitle() == null) ? 0 : getTitle().hashCode());result = prime * result + ((getContent() == null) ? 0 : getContent().hashCode());result = prime * result + ((getAuthorId() == null) ? 0 : getAuthorId().hashCode());result = prime * result + ((getCreatedAt() == null) ? 0 : getCreatedAt().hashCode());result = prime * result + ((getUpdatedAt() == null) ? 0 : getUpdatedAt().hashCode());result = prime * result + ((getHeatValue() == null) ? 0 : getHeatValue().hashCode());result = prime * result + ((getRating() == null) ? 0 : getRating().hashCode());result = prime * result + ((getTag() == null) ? 0 : getTag().hashCode());return result;}@Overridepublic String toString() {StringBuilder sb = new StringBuilder();sb.append(getClass().getSimpleName());sb.append(" [");sb.append("Hash = ").append(hashCode());sb.append(", id=").append(id);sb.append(", title=").append(title);sb.append(", content=").append(content);sb.append(", authorId=").append(authorId);sb.append(", createdAt=").append(createdAt);sb.append(", updatedAt=").append(updatedAt);sb.append(", heatValue=").append(heatValue);sb.append(", rating=").append(rating);sb.append(", tag=").append(tag);sb.append(", serialVersionUID=").append(serialVersionUID);sb.append("]");return sb.toString();}
}
ForumPostLike:
@Data@TableName(value ="forum_post_likes")public class ForumPostLike {private int userId;private int postId;}
ForumPostFavorites:
@Data
@TableName(value ="forum_post_favorites")
public class ForumPostFavorites {private int userId;private int postId;}
ForumComments
@TableName(value ="forum_comments")
@Data
public class ForumComments implements Serializable {/*** */@TableId(value = "id", type = IdType.AUTO)private Integer id;/*** */@TableField(value = "post_id")private Integer postId;/*** */@TableField(value = "user_id")private Integer userId;/*** */@TableField(value = "comment_text")private String commentText;/*** */@TableField(value = "created_at")private LocalDateTime createdAt;@TableField(exist = false)private static final long serialVersionUID = 1L;@Overridepublic boolean equals(Object that) {if (this == that) {return true;}if (that == null) {return false;}if (getClass() != that.getClass()) {return false;}ForumComments other = (ForumComments) that;return (this.getId() == null ? other.getId() == null : this.getId().equals(other.getId()))&& (this.getPostId() == null ? other.getPostId() == null : this.getPostId().equals(other.getPostId()))&& (this.getUserId() == null ? other.getUserId() == null : this.getUserId().equals(other.getUserId()))&& (this.getCommentText() == null ? other.getCommentText() == null : this.getCommentText().equals(other.getCommentText()))&& (this.getCreatedAt() == null ? other.getCreatedAt() == null : this.getCreatedAt().equals(other.getCreatedAt()));}@Overridepublic int hashCode() {final int prime = 31;int result = 1;result = prime * result + ((getId() == null) ? 0 : getId().hashCode());result = prime * result + ((getPostId() == null) ? 0 : getPostId().hashCode());result = prime * result + ((getUserId() == null) ? 0 : getUserId().hashCode());result = prime * result + ((getCommentText() == null) ? 0 : getCommentText().hashCode());result = prime * result + ((getCreatedAt() == null) ? 0 : getCreatedAt().hashCode());return result;}@Overridepublic String toString() {StringBuilder sb = new StringBuilder();sb.append(getClass().getSimpleName());sb.append(" [");sb.append("Hash = ").append(hashCode());sb.append(", id=").append(id);sb.append(", postId=").append(postId);sb.append(", userId=").append(userId);sb.append(", commentText=").append(commentText);sb.append(", createdAt=").append(createdAt);sb.append(", serialVersionUID=").append(serialVersionUID);sb.append("]");return sb.toString();}
}

 DTO:

@Data
public class CommentDTO {private int  userId;private int postId;private String commentText;}
@Data
public class ForumAddPostDTO {@JsonProperty("title")private String title;@JsonProperty("content")private String content;@JsonProperty("authorId")private Integer authorId;@JsonProperty("tag")private String tag;
}

 VO:

@Data
public class ArticleVO {private String title;private String content;private String account;private Integer heatValue;@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")private LocalDateTime createdAt;}
@Data
public class CommentVo {private int id;private String commentText;@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")private LocalDateTime createdAt;private String account;
}
@Data
public class LikeSearchVo {private String value;
}

 


4.3 自定义异常与全局异常

public class BaseException extends RuntimeException{public BaseException(){}public BaseException(String msg){super(msg);}}
public class NotFoundArticleException extends BaseException{public NotFoundArticleException(String msg){super(msg);}}
public class AlreadyLikeException extends BaseException{public AlreadyLikeException(String msg){super(msg);}}

全局异常处理类:

@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {@ExceptionHandlerpublic Result exceptionHandler(BaseException ex){log.error("异常信息:{}", ex.getMessage());return Result.error(ex.getMessage());}}

4.4Controller层

1.ForumPostController

@RequestMapping("/forum")
@RestController
@Api(tags = "文章管理")
@Slf4j
public class ForumPostController {@AutowiredForumPostsService forumPostsService;@AutowiredUserService userService;@AutowiredForumCommentsService forumCommentsService;@ApiOperation("新增文章")@PostMapping("/add")public Result addForumPost(@RequestBody ForumAddPostDTO forumAddPostDTO) throws ParseException {ForumPosts forumPosts = new ForumPosts();BeanUtils.copyProperties(forumAddPostDTO, forumPosts);forumPostsService.save(forumPosts);return Result.success("新增成功");}@GetMapping("/getAllForumPost")@ApiOperation("推荐文章查询")public Result getAllForumPost(@RequestParam(value="pageSize", defaultValue = "10") int pageSize,@RequestParam(value="pageNumber", defaultValue = "1") int pageNumber){Page<ForumPosts> page = new Page<>(pageNumber, pageSize);// 创建查询包装器并指定排序规则QueryWrapper<ForumPosts> queryWrapper = new QueryWrapper<>();// 假设你想按照创建时间降序排序queryWrapper.orderByDesc("created_at");Page<ForumPosts> paged = forumPostsService.page(page,queryWrapper);List<ForumPosts> postsList = paged.getRecords();List<ForumPageVO> posts = new ArrayList<>();for (ForumPosts post : postsList) {ForumPageVO vo = new ForumPageVO();// 获取账户信息User user = userService.getById(post.getAuthorId());vo.setAccount(user.getAccount());// 直接从ForumPosts对象复制其他字段vo.setTag(post.getTag());vo.setRating(post.getRating()); // 如果需要字符串形式vo.setTitle(post.getTitle());vo.setPostId(post.getId());vo.setHeat_value(post.getHeatValue());// 添加到列表posts.add(vo);}return Result.success(posts);}//    文章阅读@ApiOperation("读取文章")@GetMapping("post/{id}")public Result<ArticleVO> readArtical(@PathVariable int id){ArticleVO articleVO =  forumPostsService.readArticle(id);return Result.success(articleVO);}//   我的文章功能@ApiOperation("我的文章")@GetMapping("/MyArticle")public Result getMyArticle(@Param("id") int id){List<ForumPosts> forumPostsList = forumPostsService.getByAuthorId(id);return Result.success(forumPostsList);}//    热门文章功能@ApiOperation("热门文章")@GetMapping("/getHotPosts")public Result getHotPosts(){QueryWrapper<ForumPosts> queryWrapper = new QueryWrapper();queryWrapper.orderByDesc("heat_value");List<ForumPosts> forumPosts = forumPostsService.list(queryWrapper);return Result.success(forumPosts);}//    热门文章功能@ApiOperation("优质文章")@GetMapping("/getOutStandPosts")public Result getOutStandPosts(){QueryWrapper<ForumPosts> queryWrapper = new QueryWrapper();queryWrapper.orderByDesc("rating");List<ForumPosts> forumPosts = forumPostsService.list(queryWrapper);return Result.success(forumPosts);}//  我的收藏@ApiOperation("我的收藏")@GetMapping("/getMyFavorite")public Result getMyFavorite(@Param("id") int id){List<ForumPosts> forumPostsList =  forumPostsService.getMyFavorite(id);return Result.success(forumPostsList);}//    文章查询@ApiOperation("文章查询")@GetMapping("/search")public Result postSearch(@RequestParam("searchKeyWord") String searchText){if (searchText == null){return Result.error("不能输入为空噢");}LambdaQueryWrapper<ForumPosts> lambdaQueryWrapper = new LambdaQueryWrapper<>();//        TODO:通过LamdaQueryWrapper 模糊查询// 模糊查询title字段,%searchText%会被自动添加lambdaQueryWrapper.like(ForumPosts::getTitle, searchText);// 假设这里有一个service接口用于操作ForumPosts表List<ForumPosts> postsList = forumPostsService.list(lambdaQueryWrapper);// 根据你的Result类的具体实现,返回查询结果return Result.success(postsList);}/*** 标题模糊查询* @param keyword 关键词* @return 匹配的标题列表*/@GetMapping("/getLikeSearch")@ApiOperation("标题模糊查询")public Result getLikeSearch(@RequestParam String keyword){List<LikeSearchVo> titles = forumPostsService.findTitlesByKeyword(keyword);return Result.success(titles);}//    用户交互//    点赞@ApiOperation("点赞")@GetMapping("/like")public Result PostLike(@RequestParam("postId") int postId,@RequestParam("userId") int userId){String result =  forumPostsService.PostLike(postId,userId);return Result.success(result);}//    收藏@ApiOperation("收藏")@GetMapping("/favorite")public Result PostFavorite(@RequestParam("postId") int postId,@RequestParam("userId") int userId){String result = forumPostsService.PostFavorite(postId,userId);return Result.success(result);}//    写评论@ApiOperation("写评论")@PostMapping("/writeComment")public Result WriteComment(@RequestBody CommentDTO commentdto){ForumComments forumComments = new ForumComments();BeanUtils.copyProperties(commentdto,forumComments);forumCommentsService.save(forumComments);return Result.success("评论成功");}//    读评论@ApiOperation("读取评论")@GetMapping("/getComment")public Result<List<CommentVo>> GetComment(@RequestParam("postId") int postId){List<CommentVo> comment = forumCommentsService.getComment(postId);return Result.success(comment);}}


4.5 Service层
 

public interface ForumPostsService extends IService<ForumPosts> {List<ForumPosts> getByAuthorId(Integer id);String PostLike(int postId, int userId);String PostFavorite(int postId, int userId);ArticleVO readArticle(int id);List<ForumPosts> getMyFavorite(int id);List<LikeSearchVo> findTitlesByKeyword(String keyword);
}
public interface ForumCommentsService extends IService<ForumComments> {List<CommentVo> getComment(int postId);
}

4.6 Mapper层

public interface ForumCommentsMapper extends BaseMapper<ForumComments> {}
@Mapper
public interface ForumPostFavoritesMapper extends BaseMapper<ForumPostFavorites> {
}
@Mapper
public interface ForumPostLikeMapper extends BaseMapper<ForumPostLike> {
}
@Mapper
public interface ForumPostsMapper extends BaseMapper<ForumPosts> {@Select("select  * from paitool.user as a,paitool.forum_posts as b where  a.id=b.author_id and a.id = #{id}")List<ForumPosts> getByAuthorId(Integer id);}

 


五、进阶思路

1.通过ElasticSearch优化搜索引擎

2.使用Redis存储热门文章,以减少数据库压力

3.通过若依框架+AI 完善管理系统


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/45623.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

linux怎么查看系统重启原因?LINUX系统不明原因重启解决步骤,在Linux中如何排查系统启动问题?

linux怎么查看系统重启原因&#xff1f;LINUX系统不明原因重启解决步骤&#xff0c;在Linux中如何排查系统启动问题&#xff1f; linux怎么查看系统重启原因&#xff0c;网上大部分总结的步骤如下&#xff1a; 查看系统日志&#xff1a;系统日志中存储了系统重启异常的情况及其…

TransT: 基于类型的多重嵌入表示用于知识图谱补全

1 引言 1.1 问题 仅仅依赖于三元组的结构化信息有其局限性&#xff0c;因为它们往往忽略了知识图谱中丰富的语义信息以及由这些语义信息所代表的先验知识。语义信息是指实体和关系的含义&#xff0c;比如“北京”是“中国”的首都&#xff0c;“苹果”是一种水果。先验知识则…

ESP32CAM物联网教学12

ESP32CAM物联网教学12 MicroPython 视频服务 小智希望能在MicroPython中实现摄像头的视频服务&#xff0c;就像官方示例程序CameraWebServer那样。 下载视频服务驱动库 小智通过上网搜索&#xff0c;发现相关的教学材料还不少&#xff0c;并且知道有人已经写出了视频服务的驱…

24/7/12总结

axios Axios 是一个基于 promise 网络请求库&#xff0c;作用于node.js 和浏览器中。 它是 isomorphic 的(即同一套代码可以运行在浏览器和node.js中)。在服务端它使用原生 node.js http 模块, 而在客户端 (浏览端) 则使用 XMLHttpRequests。 get请求: <script>function…

【Linux网络】数据链路层【下】{MAC/MTU/ARP/ICMP/NAT/PING/代理服务器原理}

文章目录 1.逐步深入数据链路层1.1MAC帧1.2由集线器到交换机1.3认识MTU 2.ARP 地址解析协议/RARP逆地址解析协议3.DNS(Domain Name System)域名从输入url后到能看到网页 发生了什么【典中典】 4.ICMP协议&#xff1a;一个网络层协议有了TCP&#xff0c;为什么还要用ICMPICMP协议…

HSP_15章 Python_模板设计模式和oop进阶总结

P136 模板设计模式 1. 设计模式简介 设计模式是在大量的实践中总结和理论化之后优选的代码结构、编程风格、以及解决问题的思考方式 设计模式就像是经典的棋谱&#xff0c;不同的棋局&#xff0c;我们用不同的棋谱&#xff0c;免去我们自己再思考和摸索 2. 模板设计模式 基本…

【面试八股总结】单例模式实现详解

一、基本概念 单例设计模式是⼀种确保⼀个类只有⼀个实例&#xff0c;并提供⼀个全局访问点来访问该实例的创建模式。 关键概念&#xff1a; 一个私有构造函数&#xff1a;确保只能单例类自己创建实例一个私有静态变量&#xff1a;确保只有一个实例&#xff0c;私有静态变量用…

4-4 词嵌入技术(word2vec)

4-4 词嵌入技术&#xff08;word2vec&#xff09; 词嵌入技术&#xff08;word2vec&#xff09;是自然语言处理&#xff08;NLP&#xff09;中的一种关键技术&#xff0c;通过将词语映射到低维向量空间中&#xff0c;使得计算机能够理解和处理语言中的语义信息。词嵌入不仅可以…

【性能测试】第一节.性能测试基础

文章目录 前言一、性能测试概述二、常见的性能测试指标 2.1 并发 2.2 响应时间 2.3 事务 2.4 点击率 2.5 吞吐量 2.6 资源利用率三、性能测试的分类 3.1 一般性能测试 3.2 负载测试 3.3 压力测试 3.4 稳定性测试总结 前言 一…

CAS详解

文章目录 CAS使用示例Unsafe类实现原理CAS问题 CAS CAS全称为Compare and Swap被译为比较并交换&#xff0c;是一种无锁算法。用于实现并发编程中的原子操作。CAS操作检查某个变量是否与预期的值相同&#xff0c;如果相同则将其更新为新值。CAS操作是原子的&#xff0c;这意味…

【错题集-编程题】栈和排序(栈 + 贪心)

牛客对于题目连接&#xff1a;栈和排序_牛客题霸_牛客网 (nowcoder.com) 一、分析题目 每次尽可能的先让当前需要的最大值弹出去。 二、代码 // 修改后的代码 class Solution { public:/*** 代码中的类名、方法名、参数名已经指定&#xff0c;请勿修改&#xff0c;直接返回方…

【2024_CUMCM】Matlab快速入门

目录 常识 disp and input 字符串合并 sum 提取矩阵指定位置的元素 指定行列 指定行or指定列&#xff08;返回行/列向量&#xff09; 指定某些行 指定全部元素&#xff0c;按列拼接 size repmat 矩阵的运算 基本运算 形状相同的矩阵运算 每个元素同时和常数相乘或相…

C++相关概念和易错语法(19)(继承规则、继承下的构造和析构、函数隐藏)

1.继承规则 继承的本质是复用&#xff0c;是结构上的继承而不是内容上的继承&#xff0c;近似于在子类中声明了父类的成员变量。 &#xff08;1&#xff09;写法&#xff1a;class student : public person 派生类&#xff08;子类&#xff09;&#xff0c;继承方式&…

泛二级泛目录多模板程序程序(泛目录和二级目录的区别)

泛解析站群_优化网站排名吸引百度蜘蛛必备程序主要功能&#xff1a; 1、网站支持无限生成页面不存在死链的风险每个也是不是网站栏目就是文章内容! 2、支持域名泛解析绑定&#xff0c;每个二级域名都是一个独立的 3、支持百度自动提交收录&#xff0c;每天随机自动提交无限自己…

echarts图表:类目轴

category 类目轴&#xff0c;适用于离散的类目数据。 例如商品名称、时间等。 类目轴上的每个刻度代表一个类目&#xff0c;刻度之间没有量的关系&#xff0c;只是简单的分类。 在类目轴上&#xff0c;数据点会对应到相应的类目上。

运行前端项目提示 run `npm fund` for details,如何解决?

经常出现在前端的一个小坑&#xff0c;分享一下技巧。 运行npm install命令终端提示&#xff1a; 107 packages are looking for funding run npm fund for details 解决方案&#xff1a; npm install --no-fund

Linux 进程 PID 管理

文章目录 1. 前言2. 进程 PID 相关数据结构3. 进程 PID 的构建3.1 第一个进程 PID 构建3.2 第二个进程 PID 的构建过程3.2.1 从当前进程复制进程 PID 信息3.2.2 创建每进程的 PID 管理数据 (struct pid) 并初始化3.2.3 绑定进程和其相关的 PID 管理数据 3.3 进程的 PID 建立过程…

【Oracle】实验三 Oracle数据库的创建和管理

【实验目的】 掌握Oracle数据库的创建方法使用DBCA创建数据库在数据库中装入SCOTT用户及其表 【实验内容】 使用DBCA创建数据库&#xff0c;名为MYDB&#xff0c;找到其初始化文件(文本型和服务器型文件都要找到)&#xff0c;查看各类默认位置并记录下来(包括物理文件所在目…

LINUX系统编程:基于环形队列和信号量的生产者消费者模型

目录 1.环形队列 2.加上信号量的理解 3.代码 1.环形队列 环形队列使用vector封装出来的。 环形队列可以实现并发生产和消费&#xff0c;就是在消费的同时也可以生产。 这个是建立在生产者消费者位置不重合的情况下。 因为位置重合之后&#xff0c;环形队列为空或者满&#xf…

Linux DRM 那些事 - HDMI 接口 DTS 配置

本文基于RockPI 4A单板Debian系统 Linux 4.4 内核介绍DRM框架HDMI接口DTS配置。 在DTS中主要实现&#xff1a;HDMI的使能、VOP绑定、IOMUX引脚配置和HDMI控制器配置。 一、HDMI 配置 文件&#xff1a;arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi #include "rk3…