Go項(xiàng)目實(shí)戰(zhàn)--用戶信息管理和GORM的事務(wù)管理實(shí)戰(zhàn)
本節(jié)我們進(jìn)行用戶模塊中最后一個(gè)功能用例--用戶地址信息維護(hù)的開發(fā),用戶信息維護(hù)這個(gè)用例展開后其實(shí)還有下面這些子個(gè)用例--每個(gè)子用例對應(yīng)一個(gè)具體的功能接口。
本文大綱
我們項(xiàng)目中這五個(gè)功能都已經(jīng)實(shí)現(xiàn),但是在文章里全展開說一遍篇幅就太長了,所以我們在教程中主要抓重點(diǎn)。
文章里我把新增、查看收貨地址列表和更新收貨地址這三個(gè)功能的實(shí)現(xiàn)過程詳細(xì)講一下,剩余的兩個(gè)功能:查看單個(gè)地址信息和刪除地址信息比較簡單,代碼中也有詳細(xì)的注釋,大家可以直接看項(xiàng)目的代碼,另外我會把這兩個(gè)功能的cURL放上來,方便大家在本地測試。
此外我還會把項(xiàng)目中常用的MySQL事務(wù)的形式和怎么用好GORM的事務(wù)功能做了講解,避免讓大家在開發(fā)項(xiàng)目時(shí)寫冤枉代碼。
新增收貨地址
收貨地址的設(shè)置相信大家平時(shí)使用淘寶、京東、拼多多的時(shí)候都設(shè)置過。它的整體流程不復(fù)雜,唯一有一點(diǎn)需要注意的是如果新加的收貨地址要設(shè)置成默認(rèn)地址,像這張圖這樣。
圖片
此時(shí)要確認(rèn)之前有無默認(rèn)地址,有則把原來的默認(rèn)地址設(shè)置為非默認(rèn)。
功能實(shí)現(xiàn)
因?yàn)槲覀冞€沒有為用戶收貨信息創(chuàng)建Model 類型,所以我們先創(chuàng)建 Model 在 dal/model 目錄新建 user_address.go 在其中創(chuàng)建 Model 。
// UserAddress 用戶收貨信息表
type UserAddress struct {
ID int64 `gorm:"column:id;primary_key;AUTO_INCREMENT"` // 收貨信息ID
UserId int64 `gorm:"column:user_id;NOT NULL"` // 用戶ID
UserName string `gorm:"column:user_name;NOT NULL"` // 收貨人姓名
UserPhone string `gorm:"column:user_phone;NOT NULL"` // 收貨人手機(jī)號
Default int `gorm:"column:default;default:0;NOT NULL"` // 是否為默認(rèn)收貨信息 0-非默認(rèn) 1-是默認(rèn)
ProvinceName string `gorm:"column:province_name;NOT NULL"` // 省
CityName string `gorm:"column:city_name;NOT NULL"` // 城
RegionName string `gorm:"column:region_name;NOT NULL"` // 區(qū)/縣
DetailAddress string `gorm:"column:detail_address;NOT NULL"` // 收件詳細(xì)地址(街道/樓宇/單元)
IsDel soft_delete.DeletedAt `gorm:"softDelete:flag"` // 刪除狀態(tài) 0-未刪除 1-已刪除
CreatedAt time.Time `gorm:"column:created_at;default:CURRENT_TIMESTAMP;NOT NULL"`// 添加時(shí)間
UpdatedAt time.Time `gorm:"column:updated_at;default:CURRENT_TIMESTAMP;NOT NULL"`// 修改時(shí)間
}
func (m *UserAddress) TableName() string {
return"user_address"
}
接下來我們先定義好請求數(shù)據(jù)對象和領(lǐng)域數(shù)據(jù)對象,明確后面服務(wù)方法該怎么操作數(shù)據(jù)。
在api/request/user.go 中定義請求對象。
type UserAddress struct {
UserName string `json:"user_name" binding:"required"`
UserPhone string `json:"user_phone" binding:"required"`
Default int `json:"default" binding:"notallow=0 1"`
ProvinceName string `json:"province_name" binding:"required"`
CityName string `json:"city_name" binding:"required"`
RegionName string `json:"region_name" binding:"required"`
DetailAddress string `json:"detail_address" binding:"required"`
}
開發(fā)功能時(shí)Controller 會把客戶端的請求數(shù)據(jù)綁定到請求對象上,同時(shí)會根據(jù)這里指定的驗(yàn)證規(guī)則進(jìn)行字段值的驗(yàn)證。
在 logic/do/user.go 中定義領(lǐng)域?qū)ο蟆?/span>
type UserAddressInfo struct {
ID int64
UserId int64
UserName string
UserPhone string
Default int
ProvinceName string
CityName string
RegionName string
DetailAddress string
IsDel int
CreatedAt time.Time
UpdatedAt time.Time
}
同理應(yīng)用服務(wù)會把請求數(shù)據(jù)對象轉(zhuǎn)換成領(lǐng)域?qū)ο蠼o到領(lǐng)域服務(wù),讓它完成添加用戶收貨地址的核心邏輯。
新增用戶收貨地址功能有兩個(gè)主要的邏輯分支:
- 新增非默認(rèn)收貨地址
- 新增默認(rèn)收貨地址,因?yàn)槭肇浀刂酚星抑挥幸粋€(gè)默認(rèn)地址,所有當(dāng)新加的收貨地址是默認(rèn)地址時(shí),要確認(rèn)之前有無默認(rèn)地址,有則把原來的默認(rèn)地址設(shè)置為非默認(rèn)的。
我們把這部分邏輯封裝在創(chuàng)建收貨地址的Dao方法中,主要是因?yàn)樯婕案露鄺l記錄時(shí)要用到事務(wù)提交,我們在這里封裝好了,領(lǐng)域服務(wù)中的邏輯會更簡單,不用關(guān)心事務(wù)管理這些數(shù)據(jù)庫層面的事情。