Spring Boot + Vue3前后端分離實戰wiki知識庫系統十二--用戶管理單點登錄開發一...

目標:

在上一次https://www.cnblogs.com/webor2006/p/17533745.html我們已經完成了文檔管理的功能模塊開發,接下來則開啟新模塊的學習---用戶登錄,這塊還是有不少知識點值得學習的,先來看一下整體的效果,關于效果官網有一個體驗地址:wiki.courseimooc.com,如下:

其效果也是人人熟知的,下面直接開擼。

用戶表設計與持久層代碼生成:

用戶表設計:

一個模塊的開始通常就是從表的設計開始,這里先來將用戶表的sql貼出來,當然實際對于表設計肯定不會直接給出個sql,表的設計其實也是非常有學問的,這里重點是操練功能,所以直接貼sql了:

-- 用戶表
drop table if exists `user`;
create table `user`
(`id`         bigint      not null comment 'ID',`login_name` varchar(50) not null comment '登陸名',`name`       varchar(50) comment '昵稱',`password`   char(32)    not null comment '密碼',primary key (`id`),unique key `login_name_unique` (`login_name`)
) engine = innodb default charset = utf8mb4 comment ='用戶';

然后執行一下sql:

此時查看一下數據庫中用戶表有木有生成?

妥妥的,然后我們默認生插入一個用戶數據:

看一下表數據:

持久層代碼生成:

接下來則來生成持久層的代碼,這塊在之前已經用得很熟練了,就不過多說明:

然后執行此命令開始生成:

此時看一下本地生成的文件是否正常生成?

在這里我其實一直有一個反思:對于一個初學者來說,這樣逃避手寫sql層的代碼是不是不利于自己的學習呀,其實我看了下公司Java后端的代碼是沒有使用這種自動生成的方式的,但是,多學一種“高效率”的方式有利無害呀,畢竟對于實際做項目來說效率是非常重要的,哪怕公司里沒用到,到時寫自己的項目是有可能用到的呀,總之,擁抱變化,任何學到的新知識,在未來總會發揮它的余熱的~~

完成用戶表基本增刪改查功能:

如之前實現電子書和文檔的增刪改查功能一樣,使用非常厲害的CV大法就可以了,這邊不厭其煩地再來走一遍流程,下面開始。

后端代碼:

1、UserController:

這里從EbookController拷貝過來:

然后再替換一下里面的內容,兩個步驟,還記得么?

此時代碼中一堆紅,不要理,之后隨著全局替換完都會自動消失了。

2、UserService:

同樣拷貝至EbookService:

然后里面的內容也是那兩步進行全局替換,這里就不說明了,替換完成之后,有一個點這里需要修改一下:

3、UserQueryReq:

這里查詢只需根據用戶名查,這里直接貼內容:

package com.cexo.wiki.req;public class UserQueryReq extends PageReq {private String loginName;public String getLoginName() {return loginName;}public void setLoginName(String loginName) {this.loginName = loginName;}@Overridepublic String toString() {return "UserQueryReq{" +"loginName='" + loginName + '\'' +"} " + super.toString();}
}

4、UserQueryResp:

這個直接從domain中的User類中拷貝既可:

5、UserSaveReq:

它也可以拷至EbookSaveReq,不過表單校驗規則需要改一下,這里直接將內容貼出:

package com.cexo.wiki.req;import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;public class UserSaveReq {private Long id;@NotNull(message = "【用戶名】不能為空")private String loginName;@NotNull(message = "【昵稱】不能為空")private String name;@NotNull(message = "【密碼】不能為空")// @Length(min = 6, max = 20, message = "【密碼】6~20位")@Pattern(regexp = "^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,32}$", message = "【密碼】至少包含 數字和英文,長度6-32")private String password;public Long getId() {return id;}public void setId(Long id) {this.id = id;}public String getLoginName() {return loginName;}public void setLoginName(String loginName) {this.loginName = loginName;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}@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(", loginName=").append(loginName);sb.append(", name=").append(name);sb.append(", password=").append(password);sb.append("]");return sb.toString();}
}

其中有個小細節需要說明一下:

最后需要解決一個報錯:

對于用戶來說只需要根據用戶名稱來查詢,所以需要改一下條件,如下:

前端代碼:

1、 admin-user.vue:

它的內容同樣可以拷貝至電子書的,里面的內容需要做一些減法,因為它沒有像電子書中的樹形分類數據,這里直接把內容貼一下:

<template><a-layout><a-layout-content:style="{ background: '#fff', padding: '24px', margin: 0, minHeight: '280px' }"><p><a-form layout="inline" :model="param"><a-form-item><a-input v-model:value="param.loginName" placeholder="登陸名"></a-input></a-form-item><a-form-item><a-button type="primary" @click="handleQuery({page: 1, size: pagination.pageSize})">查詢</a-button></a-form-item><a-form-item><a-button type="primary" @click="add()">新增</a-button></a-form-item></a-form></p><a-table:columns="columns":row-key="record => record.id":data-source="users":pagination="pagination":loading="loading"@change="handleTableChange"><template v-slot:action="{ text, record }"><a-space size="small"><a-button type="primary" @click="edit(record)">編輯</a-button><a-popconfirmtitle="刪除后不可恢復,確認刪除?"ok-text="是"cancel-text="否"@confirm="handleDelete(record.id)"><a-button type="danger">刪除</a-button></a-popconfirm></a-space></template></a-table></a-layout-content></a-layout><a-modaltitle="用戶表單"v-model:visible="modalVisible":confirm-loading="modalLoading"@ok="handleModalOk"><a-form :model="user" :label-col="{ span: 6 }" :wrapper-col="{ span: 18 }"><a-form-item label="登陸名"><a-input v-model:value="user.loginName" :disabled="!!user.id"/></a-form-item><a-form-item label="昵稱"><a-input v-model:value="user.name"/></a-form-item><a-form-item label="密碼" v-show="!user.id"><a-input v-model:value="user.password"/></a-form-item></a-form></a-modal>
</template><script lang="ts">
import {defineComponent, onMounted, ref} from 'vue';
import axios from 'axios';
import {message} from 'ant-design-vue';
import {Tool} from "@/util/tool";export default defineComponent({name: 'AdminUser',setup() {const param = ref();param.value = {};const users = ref();const pagination = ref({current: 1,pageSize: 10,total: 0});const loading = ref(false);const columns = [{title: '登陸名',dataIndex: 'loginName'},{title: '名稱',dataIndex: 'name'},{title: '密碼',dataIndex: 'password'},{title: 'Action',key: 'action',slots: {customRender: 'action'}}];/*** 數據查詢**/const handleQuery = (params: any) => {loading.value = true;// 如果不清空現有數據,則編輯保存重新加載數據后,再點編輯,則列表顯示的還是編輯前的數據users.value = [];axios.get("/user/list", {params: {page: params.page,size: params.size,loginName: param.value.loginName}}).then((response) => {loading.value = false;const data = response.data;if (data.success) {users.value = data.content.list;// 重置分頁按鈕pagination.value.current = params.page;pagination.value.total = data.content.total;} else {message.error(data.message);}});};/*** 表格點擊頁碼時觸發*/const handleTableChange = (pagination: any) => {console.log("看看自帶的分頁參數都有啥:" + pagination);handleQuery({page: pagination.current,size: pagination.pageSize});};// -------- 表單 ---------const user = ref();const modalVisible = ref(false);const modalLoading = ref(false);const handleModalOk = () => {modalLoading.value = true;axios.post("/user/save", user.value).then((response) => {modalLoading.value = false;const data = response.data; // data = commonRespif (data.success) {modalVisible.value = false;// 重新加載列表handleQuery({page: pagination.value.current,size: pagination.value.pageSize,});} else {message.error(data.message);}});};/*** 編輯*/const edit = (record: any) => {modalVisible.value = true;user.value = Tool.copy(record);};/*** 新增*/const add = () => {modalVisible.value = true;user.value = {};};const handleDelete = (id: number) => {axios.delete("/user/delete/" + id).then((response) => {const data = response.data; // data = commonRespif (data.success) {// 重新加載列表handleQuery({page: pagination.value.current,size: pagination.value.pageSize,});} else {message.error(data.message);}});};onMounted(() => {handleQuery({page: 1,size: pagination.value.pageSize,});});return {param,users,pagination,columns,loading,handleTableChange,handleQuery,edit,add,user,modalVisible,modalLoading,handleModalOk,handleDelete,}}
});
</script><style scoped>
img {width: 50px;height: 50px;
}
</style>

里面的內容都是之前學過了,沒有任何難點,所以不過多解釋。

2、index.ts添加路由信息:

3、頭部增加用戶管理菜單入口:

4、整體運行:

用戶名重復校驗與自定義異常:

概述:

對于用戶名,在后端我們表設計時是設置了它的唯一性,不能重復的:

而目前我們并沒有做重復名稱的校驗,看一下:

界面一直轉圈,此時后端報異常了:

所以接下來咱們做一下重復用戶名的校驗邏輯。

實現:

1、后端插入進行用戶名的校驗:

目前在插入邏輯中并沒有根據用戶名參數到數據庫中查詢是否存在:

咱們先提供一個根據用戶名查詢的方法:

然后插入邏輯就可以修改為:

2、新建業務異常:

接下來這個用戶名已存在的業務異常,則采用自定義異常的方式來處理,先來新建一個自定義的異常類:

package com.cexo.wiki.exception;public enum BusinessExceptionCode {USER_LOGIN_NAME_EXIST("登錄名已存在"),;private String desc;BusinessExceptionCode(String desc) {this.desc = desc;}public String getDesc() {return desc;}public void setDesc(String desc) {this.desc = desc;}
}

異常code是通過枚舉來定義的,接下來這個異常類的內容為:

package com.cexo.wiki.exception;public class BusinessException extends RuntimeException{private BusinessExceptionCode code;public BusinessException (BusinessExceptionCode code) {super(code.getDesc());this.code = code;}public BusinessExceptionCode getCode() {return code;}public void setCode(BusinessExceptionCode code) {this.code = code;}/*** 不寫入堆棧信息,提高性能*/@Overridepublic Throwable fillInStackTrace() {return this;}
}

其中:

它的意思是不拋出一堆的異常堆棧信息了,因為這個屬于業務異常,并非系統異常,通過業務異常的code其實就知道此異常的問題,它是純業務邏輯,并非是因為程序的缺陷,所以這里就重寫一下fillInStackTrace()。

3、拋出異常:

接下來咱們就可以在用戶名重復的處理處這樣來拋出業務異常了:

4、統一異常處理:

還記得在之前https://www.cnblogs.com/webor2006/p/17238571.html使用過SpingBoot的全局異常處理么?對于這個自定義的異常處理也類似,處理如下:

5、運行:

接下來咱們運行看一下效果:

6、編輯用戶名問題:

還有一個細節需要再說明一下,就是編輯用戶時,是不允許編輯用戶名的,目前控制它的地方在這:

也就是當用戶的id不為空,說明是編輯操作,此時登陸名是只讀的不允許編輯,而當用戶的id為空,則說明是新增操作,當然登錄名是可寫入的,另外目前密碼不可以編輯,可以把這個條件暫且先去掉,因為接下來就要對密碼進行進一步處理,目前密碼名文存在庫中肯定是不合理的:

此時編輯的時候就可以編輯密碼了:

這個不是說的重點,重點是它:

為啥要加“!!”兩個嘆號呢?那將它去掉看會有什么影響就知道了:

此時就可以使用“!!”來繞過語法檢查,這個算是一個小技巧。

另外目前貌似前端用戶名已經禁用輸入來防止更改用戶名已經完美了,但是!!!對于前端的東東用戶都可以繞過去的,最典型的是通過瀏覽器的調試來繞過,如下:

所以有必要在后端針對這種從前端繞過去來修改用戶名的情況進行一下處理,那如何處理呢?有一種簡單的改法,就是在后端忽略用戶名的更新既可,也就是不管前端針對用戶名做何等操作,都忽略,具體可以這樣來做:

其實它有另一個方法可以滿足咱們目前的場景:

而它的功能其實跟進去看一下它的sql定義就知道了:

也就是只有有值的情況下才會更新,為空則就不會更新了,那么思路來了,我們在調它之前,主動將loginName給置空不就行了,如下:

好,此時再運行看一下效果:

完美解決。

關于密碼的兩層加密處理:

概述:

接下來咱們來處理密碼加密的問題了,如上面也提到過,目前咱們的用戶名的密碼都是明文存儲的:

這是一個非常危險的事情,假如數據被泄漏了,所有用戶的密碼也就知道了,所以必須得加密存儲,下面來處理下。

密碼加密存儲:

修改也比較簡單,在后端保存的時候,使用springframework的md5進行一下加密既可,如下:

此時運行看一下:

此時看一下庫里的密碼是否已經加密了:

但是!!!現在加密之后在前端編輯時就會有一些問題了,每次編輯,如果不想改密碼只改昵稱,貌似密碼也每次都會變:

關于這個問題之后再來解決,目前先解決保存時加密的問題。?

密碼加密傳輸:

看似目前編輯加密沒問題,其實在前端這塊傳輸還是有問題的,這里看一下:

發現問題了么?前端的密碼其實還是明文的,那當然也得加密嘍,其加密方式也是用MD5,下面來實現一下。

1、拷貝一個md5加密的js:

而此md5的文件地址為:https://blog-static.cnblogs.com/files/webor2006/md5.js?t=1691852396&download=true,其中我們需要調用的函數就是:

2、引入到頁面中:

接下來咱們就可以將這個js引入到用戶管理的頁面中了,其引入方法如下:

然后在用戶管理頁面在保存時對用戶的密碼進行一下加密處理:

加入這么一句:

但是!!!報錯了呀,其中hexMd5就是調用我們新引入的md5.js中的函數,因為它是全局的,哪個頁面都可以調用,而KEY也是定義在md5.js中的:

這個叫“鹽值”,俗稱的“加鹽”,為啥要加一個鹽值呢?關于這塊可以網上搜一下,比如密碼“123”,如果不加鹽值,它的md5是固定的,根據md5可能很容易知道它是"123",但是如果這個密碼加了一串特殊字符再進行md5,此時用戶就很難逆推出來原密了。好,還是回到解決這個報錯問題上來,其實是因為我們頁面上使用的typescript,它默認是無法直接識別javascript的這個方法和變量,需要這樣聲明一下就可以了:

此時咱們再來運行看一下:

這就是密碼的兩層加密,一層是前端的md5,另一層是后端的md5。

增加重置密碼功能:

修改用戶時,不能修改密碼:

對于加了密的密碼,在編輯時是不應該再讓用戶能進行修改的,畢竟加了密的密文再編輯是沒有意義的,所以這里還是在編輯時將密碼表單欄隱藏,但是在新增用戶時是需要顯示的,如下:

與v-show功能類似的還有一個v-if,關于這倆的區別其實在之前的學習中也提到過了,可以參考它:https://www.cnblogs.com/webor2006/p/17510360.html,運行看一下:

同樣的,對于后端也需要做一下處理,避免繞過前端能對密碼進行修改,如下:

單獨開發重置密碼表單和接口:

概述:

對于用戶的密碼有可能會有忘記的情況,此時就應該有一個重置用戶密碼的功能。

1、準備接口:

這里先來準備重置的接口,如下:

其中UserResetPasswordReq新建了一個,因為它里面的入參只需要一個密碼既可,跟用戶保存的入參是不一樣的:

package com.cexo.wiki.req;import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;public class UserResetPasswordReq {private Long id;@NotNull(message = "【密碼】不能為空")// @Length(min = 6, max = 20, message = "【密碼】6~20位")@Pattern(regexp = "^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,32}$", message = "【密碼】至少包含 數字和英文,長度6-32")private String password;public Long getId() {return id;}public void setId(Long id) {this.id = id;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}@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(", password=").append(password);sb.append("]");return sb.toString();}
}

接下來再來實現service層的代碼:

2、準備重置入口:

先在列表操作按鈕上新增一個重置:

此時運行看一下:

其中點擊事件定義如下:

3、實現重置:

接下來則來實現重置的功能。

1、準備重置的模態框:

這個模態框可以copy至編輯時的模態框,只是表單內容不一樣,比較簡單,這里細節就略過了,直接貼相關的代碼:

代碼:

  <a-modaltitle="重置密碼"v-model:visible="resetModalVisible":confirm-loading="resetModalLoading"@ok="handleResetModalOk"><a-form :model="user" :label-col="{ span: 6 }" :wrapper-col="{ span: 18 }"><a-form-item label="新密碼"><a-input v-model:value="user.password"/></a-form-item></a-form></a-modal>

然后定義相關的變量及函數實現,這塊也沒有任何新的技術點,也直接貼出來了:

代碼:

// -------- 重置密碼 ---------const resetModalVisible = ref(false);const resetModalLoading = ref(false);const handleResetModalOk = () => {resetModalLoading.value = true;user.value.password = hexMd5(user.value.password + KEY);axios.post("/user/reset-password", user.value).then((response) => {resetModalLoading.value = false;const data = response.data;if (data.success) {resetModalVisible.value = false;// 重新加載列表handleQuery({page: pagination.value.current,size: pagination.value.pageSize,});} else {message.error(data.message);}});};

2、重置密碼點擊事件處理:

接下來則來實現密碼重置點擊事件的邏輯,也就是將咱們準備的重置模態框給展示出來:

?

4、運行:

接下來咱們運行看一下效果:

可以看到,我新建了一個賬號,將密碼設置成123之后,跟test2這個用戶密碼也是123最后生成的md5是同一個值:

證明密碼重置之后的密碼是好使的,當然最終得要實現了登錄功能再來進行這塊密碼修改功能是否一切正常,用戶登錄模塊后續做到時再來驗證。

單點登錄token與JWT介紹:

目前為止,咱們已經將用戶的管理功能實現了,那接下來就可以來進行用戶登錄功能的開發了,這里在開發之前,先理論化了解登錄的一些概念,剛好也篇末了,埋個伏筆。

登錄流程:

這里先來了解一下通常登錄的整個流程,總體分為兩大塊:登錄和校驗。

登錄:

1、前端輸入用戶名和密碼。

2、校驗用戶名和密碼。(包含基本的用戶名和密碼的格式校驗、用戶名和密碼是否匹配校驗)。

3、生成token,也稱令牌、登錄標識,其實也就是一串“唯一”的字符串(既使是同一個用戶,登錄多次,每次的token也是不一樣的)。

4、后端保存token(最終會保存到redis中)。

5、前端保存token。

校驗:

1、前端請求時,帶上token,但并非所有的接口都需要校驗,一般就是管理類的接口(增刪改)是需要校驗token的。(通常是token是放在header請求頭里)

2、登錄攔截器,校驗token。(到redis獲取token)?

3、校驗成功則繼續后面的業務。

4、校驗失敗則跳回到登錄界面。

單點登錄系統:【了解】

在上面的登錄流程中可以看到其流程還是很多的, 如果有很多系統都需要來自己實現一遍,那成本比較高,也不好維護,所以可以將它做成一個登錄系統,以后所有產品需要登錄功能都跳到這個系統里,當然做法有兩種:一種是該系統已經帶登錄界面及接口,第二種是各個產品自己維護登錄界面,這套系統只維護登錄相關的接口。而通常這套系統包含如下功能:用戶管理、登錄、登錄校驗、退出登錄,簡單了解一下,不同公司對于它的定義也不一樣。

token與JWT:【了解】

再來了解一下概念,對于token+redis,其實這個token,只要保證它唯一,可以用md5字符串、時間戳等,它的特點就是其值是無意義的,因為它不能代表任何業務意義;但是對于JWT就不一樣了,說到不一樣當然它的token是有意義的嘍,是的,因為它是將用戶的業務信息通過加密手段而生成的token,所以通過token就可以解出來用戶的信息,說了這么多,先度娘一下JWT,在這篇https://blog.csdn.net/weixin_45410366/article/details/125031959文章里是這么說明的:

也一知半解,它其實有一個官網https://jwt.io/,打開了解一下:

哦,原來JWT的全稱是JSON Web Tokens,官網這句描述其實也不知道它是干嘛的,往下翻,官網直接給出了一個在線的效果:

其中加密的算法有很多種,可以根據實際情況來選擇:

也就是這個token信息是有意義的,通過這個token是可以解密的,而要使用它,則需要添加如下依賴:

而核心使用就是這兩個:

這里僅當做個知識了解,待未來真正使用到它時再進一步了解,下篇就正式進入用戶登錄功能的開發,這篇先這樣了。

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

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

相關文章

2023全國大學生數學建模競賽C提思路模型代碼

目錄 1.C題思路模型&#xff1a;比賽開始后&#xff0c;第一時間更新&#xff0c;獲取見文末名片 2.比賽時間&#xff1a;2023年9月7日18點到2023年9月10日20點 3 全國大學生數學建模競賽常見數模問題 3.1 分類問題 3.2 優化問題 詳細思路見此名片&#xff0c;開賽第一時間…

YOLOv8目標檢測算法

YOLOv8目標檢測算法相較于前幾代YOLO系列算法具有如下的幾點優勢&#xff1a; 更友好的安裝/運行方式速度更快、準確率更高新的backbone&#xff0c;將YOLOv5中的C3更換為C2FYOLO系列第一次嘗試使用anchor-free新的損失函數 YOLOv8簡介 YOLOv8 是 Ultralytics 公司繼 YOLOv5…

FiboSearch Pro – Ajax Search for WooCommerce 商城AJAX實時搜索插件

FiboSearch Pro是最受歡迎的WooCommerce 產品搜索插件。它為您的用戶提供精心設計的高級 AJAX 搜索欄&#xff0c;并提供實時搜索建議。默認情況下&#xff0c;WooCommerce 提供非常簡單的搜索解決方案&#xff0c;沒有實時產品搜索&#xff0c;甚至沒有 SKU 搜索。FiboSearch&…

網絡基礎(一)橋接網絡

網絡基礎知識 橋接網絡 橋接網絡是一種網絡設計技術&#xff0c;其目的是將兩個或多個網絡段連接在一起&#xff0c;使它們在邏輯上表現為單個網絡。這通過使用網絡橋來實現&#xff0c;網絡橋工作在數據鏈路層&#xff08;第2層&#xff09;&#xff0c;只關心MAC地址&#…

uniapp開發微信小程序底部地區選擇彈框

個人項目地址&#xff1a; SubTopH前端開發個人站 &#xff08;自己開發的前端功能和UI組件&#xff0c;一些有趣的小功能&#xff0c;感興趣的伙伴可以訪問&#xff0c;歡迎提出更好的想法&#xff0c;私信溝通&#xff0c;網站屬于靜態頁面&#xff09; SubTopH前端開發個人站…

React Native 圖片組件基礎知識

在 React Native 中使用圖片其實跟 HTML 中使用圖片一樣簡單&#xff0c;在 React Native 中我們使用Image組件來呈現圖片的內容&#xff0c;其中主要的屬性有&#xff1a;source。這個屬性主要是設置圖片的內容&#xff0c;它可以是網絡圖像地址、靜態資源、臨時本地圖像以及本…

Android側滑欄(一)可縮放可一起移動的側滑欄

在實際的各類App開發中&#xff0c;經常會需要做一個左側的側滑欄&#xff0c;類似于QQ這種。 今天這篇文章總結下自己在開發中遇到的這類可以跟隨移動且可以縮放的側滑欄。 一、實現原理 使用 HorizontalScrollView 實現一個水平方向的可滑動的View&#xff0c;左布局為側滑…

MySQL-MGR報錯MY-011526

問題背景: 單主MGR集群&#xff0c;主節點在服務器意外重啟之后&#xff0c;無法重新加入現有MGR集群&#xff0c;報錯誤[MY-011526] [Repl] Plugin group_replication reported: This member has more executed transactions than those present in the group. Local transact…

2023年度漏洞預警

1 漏洞 漏洞是硬件&#xff0c;軟件&#xff0c;協議的具體實現或系統安全策略上存在的缺陷。從而可以使用攻擊者能夠在破壞系統。 2 漏洞匯總數據 以下數據針對 23 年截至8月期間爆發的高危嚴重漏洞進行了數據統計和分析&#xff0c; 具體的數據如下所示&#xff1a; 漏洞…

Camx--概述

該部分代碼主要位于 vendor/qcom/proprietary/ 目錄下&#xff1a; 其中 camx 代表了通用功能性接口的代碼實現集合&#xff08;CamX&#xff09;&#xff0c;chi-cdk代表了可定制化需求的代碼實現集合&#xff08;CHI&#xff09;&#xff0c;從圖中可以看出Camx部分對上作為H…

v3s平臺學習

printf 應用程序 arm-linux-gnueabihf-gcc test.c 復制a.out 到 sd卡 /media/shen/rootfs/root 運行a.out 不顯示 解決方法 https://blog.csdn.net/whatday/article/details/85137031/?utm_mediumdistribute.pc_relevant.none-task-blog-2defaultbaidujs_baidulandingword~def…

Linux 性能分析之iostat命令詳解

Linux 性能分析之iostat命令詳解 iostat命令是IO性能分析的常用工具&#xff0c;其是input/output statistics的縮寫。本文將著重于下面幾個方面介紹iostat命令&#xff1a; iostat的安裝iostat命令行選項說明iostat輸出內容分析如何確定磁盤IO的瓶頸iostat實際案例 命令的安…

django boostrap html實現可拖拽的左右布局,鼠標拖動調整左右布局的大小或占比

一、實現的效果 最近需要在Django項目中,實現一個左右布局的html頁面,頁面框架使用的是boostrap。但這個布局不是簡單的左右分欄布局,而是需要實現可以通過鼠標拖拽的方式動態調整左右兩側布局的大小和占比。效果大致如下: 一開始,頁面分為左右兩塊布局: 鼠標放到中間的…

Python腳本之連接MySQL【四】

本文為博主原創&#xff0c;未經授權&#xff0c;嚴禁轉載及使用。 本文鏈接&#xff1a;https://blog.csdn.net/zyooooxie/article/details/124640412 之前寫了篇 Python腳本之連接MySQL【三】&#xff0c;日常使用過程中&#xff0c;代碼實際有很多改動&#xff0c;特此更新…

阿里云SMS,APi接口返回錯誤碼

API錯誤碼 更新時間&#xff1a;2023-06-29 16:33提交缺陷 產品詳情 相關技術圈 我的收藏 調用API接口失敗時&#xff0c;會返回錯誤碼。本文檔為您提供API接口錯誤碼列表&#xff0c;請根據錯誤碼和對應錯誤信息排查問題。 錯誤碼&#xff08;Code&#xff09; 錯誤信息…

【先進PID控制算法(ADRC,TD,ESO)加入永磁同步電機發電控制仿真模型研究(Matlab代碼實現)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;歡迎來到本博客????&#x1f4a5;&#x1f4a5; &#x1f3c6;博主優勢&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客內容盡量做到思維縝密&#xff0c;邏輯清晰&#xff0c;為了方便讀者。 ??座右銘&a…

EJB基本概念和使用

一、EJB是什么&#xff1f; EJB是sun的JavaEE服務器端組件模型&#xff0c;是一種規范&#xff0c;設計目標與核心應用是部署分布式應用程序。EJB2.0過于復雜&#xff0c;EJB3.0的推出減輕了開發人員進行底層開發的工作量&#xff0c;它取消或最小化了很多(以前這些是必須實現)…

如何使用Flask-RESTPlus構建強大的API

如何使用Flask-RESTPlus構建強大的API 引言&#xff1a; 在Web開發中&#xff0c;構建API&#xff08;應用程序接口&#xff09;是非常常見和重要的。API是一種允許不同應用程序之間交互的方式&#xff0c;它定義了如何請求和響應數據的規范。Flask-RESTPlus是一個基于Flask的…

定量分析計算51單片機復位電路工作原理 怎么計算單片機復位電容和電阻大小

下面畫出等效電路圖 可以知道單片機內必然有一個電阻RX&#xff0c;為了簡化分析&#xff0c;我們假設他是線性電阻&#xff08;不帶電容&#xff0c;電感的支路&#xff09; 還有一個基礎知識&#xff1a; 電容器的充電放電曲線&#xff1a; 還需要知道電容電壓的變化是連續…

微信小程序data-item設置獲取不到數據的問題

微信小程序data-item設置獲取不到數據的問題 簡單說明&#xff1a; 在微信小程序中&#xff0c;通過列表渲染使用wx:for根據數組中的每一項重復渲染組件。同時使用bindtap給每一項綁定點擊事件clickItem&#xff0c;再通過data-item綁定數據。 **問題&#xff1a;**通過data-i…