評論區實現 前端Vue

根據后端部分定義評論區功能實現 golang后端部分-CSDN博客,重點需要實現三個部分,1.當前用戶發起新根評論請求;2.評論區展示部分;3.某一根評論的子評論展示以及回復組件顯示。

整體流程解釋

數據從后端接收,整體在index文件中第一次進行存儲,利用inject注入方式,將數據從父組件傳遞到子組件當中進行顯示。對于每一個評論的獲取,依賴評論數據中的評論id進行定位,進行后續的回復發送等等。

效果如下所示。

1.當前用戶發起新根評論組件 組件名topCommentReply.vue

效果如下:

<template><div class="top-comment-input"><!-- 用戶頭像 --><img :src="userInfo.userAvatar" class="avatar" alt="用戶頭像" /><!-- 評論輸入區域 --><div class="input-area"><textareav-model="commentContent"placeholder="說點什么..."rows="3"></textarea><div class="btn-wrapper"><button @click="submitComment" :disabled="isLoading" v-loading="isLoading">發布</button></div></div></div></template><script>import { ObjectId } from 'bson';export default {inject:["sendWSMessage", "userInfo", "videoId"],name: 'TopCommentReply',data() {return {commentContent: '',isLoading: false};},methods: {submitComment() {if (!this.commentContent.trim()) {this.$message.error('請輸入評論內容');return;}this.isLoading = true;const replyComment = this.sendWSMessage;console.log('this.videoId', this.videoId);const comment = {"videoId": this.videoId,"curCommentId": new ObjectId().toString(),"userId": this.userInfo.userId,"userName": this.userInfo.userName,"userAvatar": this.userInfo.userAvatar,"content": this.commentContent,"commentType": 0,};replyComment(comment);this.$emit('post-submit-top-reply', comment);this.isLoading = false;}}};</script><style scoped>.top-comment-input {display: flex;gap: 12px;margin-bottom: 2em;}.avatar {width: 40px;height: 40px;border-radius: 50%;}.input-area {flex: 1;display: flex;flex-direction: column;gap: 10px;}.input-area textarea {width: 100%;padding: 10px;border-radius: 6px;border: 1px solid #ccc;resize: none;font-size: 14px;outline: none;}.btn-wrapper {display: flex;justify-content: flex-end;}.btn-wrapper button {padding: 8px 20px;background-color: #0f1014;color: #fff;border: none;border-radius: 4px;cursor: pointer;}.btn-wrapper button:hover {background-color: #2d2d2d;}.btn-wrapper button:disabled {opacity: 0.6;cursor: not-allowed;}</style>

2. 整體評論區部分分為兩個組件commentSection.Vue和commentReplyItem.vue

2.1commentSection.Vue

<template><div class="firstglobals"><!-- 頭像 --><div class="avatar"><img :src="data.userAvatar" style="width: 56px; height: 56px; border-radius: 50%;" alt="" /></div><!-- 內容 --><div class="content"><div class="usertop"><div style="display: flex;gap: 10px;"><div class="username">{{ data.userName }}</div><div class="tags" v-if="data.tag === 1">作者</div></div><div class="time">{{ formatTime(data.createTime) }}</div></div><div style="display: flex; flex-direction: column; margin-top: 1em;"><div class="text">{{ data.content }}</div><div style="display: flex; align-self: flex-end;"><img src="@/assets/images/點贊.png" style="width: 20px;" alt="" /></div><div class="but" @click="toggleReplyBox(data.curCommentId)">回復</div></div><div v-if="isReplyBoxVisible" class="reply-box"><textarea v-model="replyContent" placeholder="輸入你的回復..." rows="3"></textarea><button @click="submitReply(data.curCommentId)" v-loading='isLoading'>發布</button></div><!-- 回復組件 --><div><div  v-if = "replyComments != null"><div  v-for="(item, index) in replyComments" :key="index"><CommentReplyItem :dataCode="dataCode" :replyData="item"@post-submit-reply="handleSubmitReply" /></div></div><div class="reply-buttons"><div v-show="!showAllReplies" class="load-more" @click="showReplies">加載更多回復   </div><div v-show="isSomeRepliesLoaded" class="load-more" @click="hideReplies">收起回復</div></div></div></div></div></template><script>import CommentReplyItem from '@/views/video/components/commentReplyItem.vue';import { getComment,  } from '@/apis/comment/comment.js';import { ObjectId } from 'bson';export default {name: 'CommentSection',components: {CommentReplyItem},props: {data: {type: Object,required: true,validator(value) {return ['userImg', 'userName', 'time', 'content','ReplyData', 'id', 'tag'].every(prop => prop in value);}},dataCode: {type: Number,default: null}},data() {return {replyContent: '',isLoading: false,showAllReplies: false,isSomeRepliesLoaded: false,isAllRepliesLoaded: false,replyComments: [],curPage: 1,totalPage: 10,};},computed: {isReplyBoxVisible() {return this.activeReplyId === this.data.curCommentId;},},inject: ['activeReplyId', 'setActiveReplyId', `sendWSMessage`, `userInfo`, `videoId`],methods: {formatTime(ts) {if (!ts) return '';const date = new Date(ts * 1000); return date.toLocaleString(); },handleSubmitReply(comment) {this.replyComments.push(comment);this.$emit('post-submit-reply', comment);},toggleReplyBox(id) {console.log('toggleReplyBox called with id:', id);console.log('this.activeReplyId1:', this.activeReplyId);if (this.setActiveReplyId) {this.setActiveReplyId(this.isReplyBoxVisible ? null : id);console.log('this.activeReplyId2:', this.activeReplyId);}},submitReply(id) {if (this.replyContent.trim()) {console.log('提交的回復內容:', this.replyContent);this.isLoading = true;const replyComment = this.sendWSMessage;console.log('this.videoId', this.videoId);const comment = {"videoId": this.videoId,"rootCommentId": id,"parentId": id,"parentUserId": this.data.userId,"parentUserName": this.data.userName,"curCommentId": new ObjectId().toString(),"userId": this.userInfo.userId,"userName": this.userInfo.userName,"userAvatar": this.userInfo.userAvatar,"content": this.replyContent,"commentType": 1,};replyComment(comment);this.replyComments.push(comment);this.isLoading = false;this.replyContent = '';this.setActiveReplyId(null);} else {this.$message.error('請輸入回復內容');this.isLoading = false;}},async showReplies() {this.isSomeRepliesLoaded = true;const jsonData = {rootCommentId: this.data.curCommentId,commentType: 1,page: this.curPage,};try {this.curPage += 1;const [error, data] = await getComment(this.videoId, jsonData);if (error) throw error;if (data != null) {this.replyComments.push(...data.comments);console.log('獲取評論成功:', data.comments);}} catch (err) {console.error('獲取評論失敗:', err);}},hideReplies() {this.isSomeRepliesLoaded = false;this.showAllReplies = false;this.curPage = 1;this.replyComments = [];},},mounted() {console.log("頭像", this.data.userImg)console.log("評論數據", this.data);}};</script><style scoped>/* 樣式部分保持不變 */.but {width: 60px;padding: 5px 0px;background: #f1f1f1;border-radius: 4px;display: flex;justify-content: center;align-content: center;font-weight: 400;font-size: 14px;color: #0f1014;text-align: left;font-style: normal;text-transform: none;}.tags {width: 32px;height: 18px;background: #0F1014;border-radius: 4px;color: #FFFFFF;font-weight: 400;font-size: 10px;line-height: 12px;text-align: center;display: flex;justify-content: center;align-items: center;}.but:hover {background: #ebe4e4;}.text {font-weight: 400;font-size: 18px;color: #000000;line-height: 21px;text-align: left;font-style: normal;text-transform: none;}.time {font-weight: 400;font-size: 12px;color: #666666;line-height: 14px;text-align: left;font-style: normal;text-transform: none;}.avatar {width: 56px;height: 56px;border-radius: 30px;}.usertop {display: flex;flex-direction: column;gap: 5px;}.username {font-weight: 700;font-size: 16px;color: #0f1014;line-height: 19px;text-align: left;font-style: normal;text-transform: none;}.content {display: flex;flex-direction: column;margin-left: 1em;margin-top: 10px;flex: 1;}.firstglobals {display: flex;justify-content: start;margin-top: 2em;}.reply-buttons {display: flex;gap: 10px; /* 兩個按鈕之間的間距 */
}.load-more {display: inline-flex; /* 讓它變成“內聯元素 + 可用 flex” */align-items: center;margin-top: 30px;color: #0066cc;cursor: pointer;font-size: 14px;
}.load-more:hover {text-decoration: underline;}.reply-box {margin-top: 10px;display: flex;flex-direction: column;gap: 10px;align-items: end;position: relative;width: 98%;align-self: flex-end;}.reply-box textarea {width: 100%;padding: 10px;border-radius: 4px;border: 1px solid #ddd;resize: none;outline: none;}.reply-box button {align-self: flex-end;padding: 10px 20px;border-radius: 4px;border: none;background-color: #070707;color: white;cursor: pointer;}.reply-box button:hover {background-color: #2d2d2d;}</style>

2.2commentReplyItem.vue

<template><div class="reply-comments"><div class="top-user"><div style="display: flex; justify-content: center; align-content: center; gap: 8px;"><img :src="replyData.userAvatar" style="width: 24px; height: 24px; border-radius: 50%;" alt=""><span class="username">{{ replyData.userName }}</span></div><div class="tags" v-if="replyData.anthTags === 1 || replyData.anthTags === 3">作者</div><div class="hf">回復</div><div style="display: flex; justify-content: center; align-content: center; gap: 8px;"><!-- <img :src="replyData.userImg2" style="width: 24px; height: 24px; border-radius: 50%;" alt=""> --><span class="username">{{ replyData.parentUserName }}</span></div><div class="tags" v-if="replyData.anthTags === 2 || replyData.anthTags === 3">作者</div><div class="time">{{ formatTime(replyData.createTime) }}</div></div><div class="content">{{ replyData.content }}</div><div style="display: flex; align-self: flex-end;"><img src="@/assets/images/點贊.png" style="width: 20px;" alt=""></div><div class="but" @click="toggleReplyBox()">回復</div><div v-if="isReplyBoxVisible" class="reply-box"><textarea v-model="replyContent" placeholder="輸入你的回復..." rows="3"></textarea><button @click="submitReply(replyData.rootCommentId)" v-loading="isLoading">發布</button></div></div>
</template><script>import { ObjectId } from 'bson';
export default {name: 'CommentReplyItem',props: {replyData: {type: Object,required: true,validator(value) {return ['userImg1', 'userName1', 'userImg2', 'userName2','replytime', 'replycontent', 'anthTags', 'id'].every(prop => prop in value);}},dataCode: {type: Number,default: null}},data() {return {replyContent: '',isLoading: false};},computed: {isReplyBoxVisible() {return this.activeReplyId === this.replyData.curCommentId;}},inject: ['activeReplyId', 'setActiveReplyId', 'sendWSMessage', 'userInfo', 'videoId'],methods: {formatTime(ts) {if (!ts) return '';const date = new Date(ts * 1000); return date.toLocaleString(); },toggleReplyBox() {console.log('toggleReplyBox');if (this.setActiveReplyId) {this.setActiveReplyId(this.isReplyBoxVisible ? null : this.replyData.curCommentId);}},submitReply(id) {if (this.replyContent.trim()) {const replyComment = this.sendWSMessage;console.log('提交的回復內容:', this.replyContent);this.isLoading = true;console.log('this.videoId', this.videoId);const comment = {"videoId": this.videoId,"rootCommentId": id,"parentId": this.replyData.curCommentId,"parentUserId": this.replyData.userId,"parentUserName": this.replyData.userName,"curCommentId": new ObjectId().toString(),"userId": this.userInfo.userId,"userName": this.userInfo.userName,"userAvatar": this.userInfo.userAvatar,"content": this.replyContent,"commentType": 1,};replyComment(comment)this.$emit('post-submit-reply', comment);this.isLoading = false;this.replyContent = '';this.setActiveReplyId(null);} else {this.$message.error('請輸入回復內容');}}},watch: {replyData: {handler(newValue) {console.log('newValue', newValue.anthTags);},deep: true}},mounted() {console.log("newValue", this.replyData.anthTags);}
};
</script><style scoped>
/* 樣式部分保持不變 */
.but {width: 60px;padding: 5px 0px;background: #F1F1F1;border-radius: 4px;display: flex;justify-content: center;align-content: center;font-weight: 400;font-size: 14px;color: #0F1014;margin-left: 32px;cursor: pointer;
}.but:hover {background: #ebe4e4;
}.content {font-weight: 400;font-size: 18px;color: #000000;line-height: 21px;text-align: left;margin-left: 32px;margin-top: 10px;
}.time {font-weight: 400;font-size: 12px;color: #666666;line-height: 14px;text-align: left;
}.hf {font-weight: 400;font-size: 14px;color: #B9B9B9;line-height: 16px;text-align: left;
}.tags {width: 32px;height: 18px;background: #0F1014;border-radius: 4px;color: #FFFFFF;font-weight: 400;font-size: 10px;line-height: 12px;text-align: center;display: flex;justify-content: center;align-items: center;
}.username {height: 24px;font-weight: 500;font-size: 13px;color: #0F1014;line-height: 15px;display: flex;justify-content: center;align-items: center;
}.top-user {display: flex;align-items: center;gap: 8px;
}.reply-comments {display: flex;flex-direction: column;margin-top: 1em;
}.reply-box {margin-top: 10px;display: flex;flex-direction: column;gap: 10px;align-items: end;position: relative;width: 95%;align-self: flex-end;
}.reply-box textarea {width: 100%;padding: 10px;border-radius: 4px;border: 1px solid #ddd;resize: none;outline: none;
}.reply-box button {align-self: flex-end;padding: 10px 20px;border-radius: 4px;border: none;background-color: #070707;color: white;cursor: pointer;
}.reply-box button:hover {background-color: #2d2d2d;
}
</style>

3.index.Vue文件

<template><div class="video-page-container"><!-- 視頻播放區 --><div class="video-player-wrapper"><easy-player:key="videoUrl"ref="videoplay":video-url="videoUrl":show-progress="true"format="hls"class="video-player"@error="restartPlayer"/></div><!-- 評論發布區 --><div class="top-comment"><TopCommentReply @post-submit-top-reply="recvTopHandler" /></div><!-- 評論列表區 --><div class="comments-section"><divv-for="comment in commentList":key="comment.id"class="comment-wrapper"><CommentSection :data="comment" /></div></div></div>
</template><script>
import { computed, ref } from 'vue';
import CommentSection from './components/commentSection.vue';
import TopCommentReply from './components/topCommentReply.vue';
import { getComment } from '@/apis/comment/comment.js';
import { ElMessage } from 'element-plus';export default {name: "VideoPlayer",components: {CommentSection,TopCommentReply},inject:["userInfo", "ws"],data() {return {videoId: this.$route.params.videoId,videoUrl: this.$route.query.videoUrl,userId: 0,userImg: "",// userInfo: {},activeReplyId: ref(null),commentList: [],};},created() {this.fetchComments();// this.initWebSocket();},// mounted() {//   this.initWebSocket();// },provide() {return {sendWSMessage: this.sendWSMessage,setActiveReplyId: this.setActiveReplyId,activeReplyId: computed(() => this.activeReplyId),// userInfo: computed(() => this.userInfo),videoId: computed(() => this.videoId),};},// beforeUnmount() {//   if (this.ws) {//     this.ws.close();//   }// },methods: {async fetchComments() {const jsonData = {rootCommentId: "-1",commentType: 0,page: 1,};try {const [error, data] = await getComment(this.videoId, jsonData);if (error) throw error;this.commentList = data.comments;} catch (err) {console.error('獲取評論失敗:', err);}},// initWebSocket() {//   const Url = "ws://192.168.229.130:8080/video/ws/comment?userId=";//   this.userId = sessionStorage.getItem('userId')//   const wsUrl = Url + this.userId;//   console.log("wsUrl", wsUrl);//   // console.log("ws userInfo", this.userInfo);//   // this.userInfo = {//   //   userId: this.userId,//   //   userAvatar: "http://localhost:8888/video/static/covers/57739617071403008.png",//   //   userName: "JohnDoe",//   // };//   this.ws = new WebSocket(wsUrl);//   this.ws.onopen = () => {//     console.log("WebSocket連接成功");//   };//   this.ws.onmessage = (event) => {//     const msg = JSON.parse(event.data);//     console.log("WebSocket消息:", msg);//   };//   this.ws.onerror = (error) => {//     console.error("WebSocket錯誤:", error);//   };//   this.ws.onclose = () => {//     console.log("WebSocket連接關閉");//   };// },recvTopHandler(comment) {this.commentList.push(comment);},sendWSMessage(comment) {if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {console.error('WebSocket未連接');return false;}try {const jsonStr = JSON.stringify(comment);this.ws.send(jsonStr);ElMessage.success('消息已發送');return true;} catch (error) {ElMessage.error('消息發送失敗');console.error('消息發送失敗:', error);return false;}},setActiveReplyId(id) {this.activeReplyId = id;},restartPlayer() {console.log("播放器出錯,嘗試重新加載...");},},
};
</script><style scoped>
.video-page-container {display: flex;flex-direction: column;align-items: center;width: 100%;
}/* 視頻播放器區域 */
.video-player-wrapper {width: 100%;max-width: 1200px;background: #000;aspect-ratio: 16/9; /* 保持16:9比例 */margin-bottom: 20px;
}.video-player {width: 100%;height: 100%;object-fit: contain;
}/* 發布評論輸入框 */
.top-comment {width: 100%;max-width: 1200px;padding: 10px;background: #fff;margin-bottom: 10px;
}/* 評論區列表 */
.comments-section {width: 100%;max-width: 1200px;background: #fff;padding: 10px;box-sizing: border-box;
}.comment-wrapper {border-bottom: 1px solid #eee;padding: 10px 0;
}
</style>

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/90065.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/90065.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/90065.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

差分定位技術:原理、分類與應用場景

文章目錄 簡介基本概念位置差分偽距差分載波相位 差分定位技術精密單點定位&#xff08;PPP&#xff09;差分全球定位系統&#xff08;DGPS&#xff09;實時動態定位&#xff08;RTK&#xff09; 應用場景總結 簡介 差分定位&#xff08;Differential Positioning&#xff09;是…

tomcat的tar包轉換成rpm包的保姆級教程

環境說明 &#xff1a;centos 71. 安裝打包工具&#xff1a;yum install -y rpm-build rpmdevtools2. 創建 RPM 打包環境&#xff1a;rpmdev-setuptree?輸入之后是下面的結果~/rpmbuild/ ├── BUILD ├── RPMS ├── SOURCES ├── SPECS └── SRPMS?準備 Tomcat 源碼…

【牛客算法】小美的數組刪除

文章目錄 一、題目介紹二、解題思路三、解題算法實現四、算法分析4.1 代碼邏輯4.2 逆向遍歷求MEX的設計精妙之處4.2.1 逆向遍歷:解決MEX更新的連續性4.2.2 利用MEX的單調性4.2.3 空間復用與狀態壓縮4.2.4 與問題特性的完美契合4.2.5 總結:為什么說這個設計“妙”?五、算法復…

MyBatisPlus-01-環境初始化及簡單應用

文章目錄【README】【1】springboot集成mybatis-plus配置【1.1】目錄結構【相關說明】【1.2】代碼示例【pom.xml】【application.properties】【MybatisPlusNoteController】【UserAppService】【UserMapper】【UserPO】【建表語句】【2】演示【README】 本文代碼參見&#xf…

Web爬蟲編程語言選擇指南

剛學爬蟲的小伙伴常常為選擇那種語言來寫爬蟲而煩惱&#xff0c;今天我將總結幾種語言的優劣勢&#xff0c;然后選擇適合編寫 Web爬蟲 的編程語言。這就需要我們考慮開發效率、生態庫支持、并發性能等因素。以下是主流選擇及特點跟著一起看看吧&#xff1a; 1. Python&#xff…

學習日志06 python

加油&#xff0c;今天的任務是學習面向對象編程&#xff0c;設計一個簡單的寵物管理系統&#xff08;寵物類、貓 / 狗子類&#xff09;&#xff0c;先做5道題目開啟學習狀態吧&#xff01;1 setdefault()在 Python 中&#xff0c;setdefault() 是字典&#xff08;dict&#xff…

基于Java+springboot 的車險理賠信息管理系統

源碼、數據庫、包調試源碼編號&#xff1a;S595源碼名稱&#xff1a;基于springboot 的車險理賠信息管理系統用戶類型&#xff1a;多角色&#xff0c;用戶、事故調查員、管理員數據庫表數量&#xff1a;14 張表主要技術&#xff1a;Java、Vue、ElementUl 、SpringBoot、Maven運…

MyDockFinder 綠色便攜版 | 一鍵仿Mac桌面,非常簡單

如果你既不想升級到Win11&#xff0c;又想體驗Mac桌面的高級感&#xff0c;那么MyDockFinder將是你的最佳選擇。這是一款專為Windows系統設計的桌面美化工具&#xff0c;能夠將你的桌面轉變成MacOS的風格。它提供了類似Dock欄和Finder的功能&#xff0c;讓你在不更換操作系統的…

Babylon.js 材質克隆與紋理共享:你可能遇到的問題及解決方案

在 Babylon.js 中&#xff0c;材質&#xff08;Material&#xff09;和紋理&#xff08;Texture&#xff09;的克隆行為可能會影響渲染性能和內存管理&#xff0c;尤其是在多個材質共享同一紋理的情況下。本文將探討&#xff1a;PBRMetallicRoughnessMaterial 的克隆機制&#…

信息素養復賽模擬1和模擬2的編程題標程

信息素養復賽模擬 11&#xff1a;樓層編號 #include<bits/stdc.h> using namespace std; int main(){int n, t;cin >> n >> t;int res 0;for(int i 1; i < n; i ){int x i;bool ok true;while(x){if(x % 10 t){ok false;}x / 10;}res ok;} cout &l…

Hadoop高可用集群搭建

Hadoop高可用(HA)集群是企業級大數據平臺的核心基礎設施&#xff0c;通過多主節點冗余和自動故障轉移機制&#xff0c;確保系統在單點故障時仍能正常運行。本文將詳細介紹如何基于CentOS 7搭建Hadoop 3.X高可用集群&#xff0c;涵蓋環境準備、組件配置、集群啟動及管理的全流程…

Next.js 實戰筆記 1.0:架構重構與 App Router 核心機制詳解

Next.js 實戰筆記 1.0&#xff1a;架構重構與 App Router 核心機制詳解 上一次寫 Next 相關的東西都是 3 年前的事情了&#xff0c;這 3 年里 Next 也經歷了 2-3 次的大版本變化。當時寫的時候 Next 是 12 還是 13 的&#xff0c;現在已經是 15 了&#xff0c;從 build 到實現…

Pillow 安裝使用教程

一、Pillow 簡介 Pillow 是 Python 圖像處理庫 PIL&#xff08;Python Imaging Library&#xff09;的友好分支&#xff0c;是圖像處理的事實標準。它支持打開、編輯、轉換、保存多種圖像格式&#xff0c;常用于圖像批量處理、驗證碼識別、縮略圖生成等應用場景。 二、安裝 Pi…

SQL Server從入門到項目實踐(超值版)讀書筆記 20

9.4 數據的嵌套查詢所謂嵌套查詢&#xff0c;就是在一個查詢語句中&#xff0c;嵌套進另一個查詢語句&#xff0c;即&#xff0c;查詢語句中可以使用另一個查詢語句中得到的查詢結果&#xff0c;子查詢可以基于一張表或者多張表。子查詢中常用的操作符有ANY、SOME、ALL、IN、EX…

【MySQL\Oracle\PostgreSQL】遷移到openGauss數據出現的問題解決方案

【MySQL\Oracle\PostgreSQL】遷移到openGauss數據出現的問題解決方案 問題1&#xff1a;序列值不自動刷新問題 下面SQL只針對單庫操作以及每個序列只綁定一張表的情況 -- 自動生成的序列&#xff0c;設置序列值 with sequences as (select *from (select table_schema,table_…

【Maven】Maven命令大全手冊:28個核心指令使用場景

Maven命令大全手冊&#xff1a;28個核心指令使用場景 Maven命令大全手冊&#xff1a;28個核心指令深度解析一、構建生命周期核心命令1. mvn clean2. mvn compile3. mvn test4. mvn package5. mvn install6. mvn deploy二、依賴管理命令7. mvn dependency:tree8. mvn dependency…

大語言模型(LLM)按架構分類

大語言模型&#xff08;LLM&#xff09;按架構分類的深度解析 1. 僅編碼器架構&#xff08;Encoder-Only&#xff09; 原理 雙向注意力機制&#xff1a;通過Transformer編碼器同時捕捉上下文所有位置的依賴關系# 偽代碼示例&#xff1a;BERT的MLM任務 masked_input "Th…

MySQL(120)如何進行數據脫敏?

數據脫敏&#xff08;Data Masking&#xff09;是指通過某種方式對敏感數據進行變形&#xff0c;使其在使用過程中無法識別原始數據&#xff0c;從而保護數據隱私。數據脫敏通常應用在開發、測試和數據分析等場景中。下面我們詳細介紹如何在Java應用程序中進行數據脫敏&#xf…

使用 Dockerfile 構建基于 .NET9 的跨平臺基礎鏡像

官方基礎鏡像準備 微軟官方 dotnet sdk 基礎鏡像&#xff1a; docker pull mcr.microsoft.com/dotnet/sdk:9.0拉取 ubuntu 鏡像&#xff1a; docker pull ubuntu:24.04更多資源請參考&#xff1a; dotnet sdk images&#xff0c;https://mcr.microsoft.com/en-us/artifact/mar/…

C++ : 線程庫

C : 線程庫一、線程thread1.1 thread類1.1.1 thread對象構造函數1.1.2 thread類的成員函數1.1.3 線程函數的參數問題1.2 this_thread 命名空間域1.2.1 chrono二、mutex互斥量庫2.1 mutex的四種類型2.1.1 mutex 互斥鎖2.2.2 timed_mutex 時間鎖2.2.3 recursive_muetx 遞歸鎖2.2.…