├── .gitignore ├── .hz ├── README.md ├── biz ├── handler │ ├── user.go │ └── video.go └── router │ └── register.go ├── conf.temp.ini ├── conf └── config.go ├── deploy ├── grafana │ └── dashbord.json ├── log │ └── zaplog.go └── promethus │ ├── mysqlexport │ ├── my.cnf │ └── my.temp.cnf │ └── server │ └── prometheus.yml ├── dump.rdb ├── go.mod ├── go.sum ├── main.go ├── middleware ├── covermaker │ ├── cover.go │ └── cover_test.go ├── jwt.go ├── limiter │ └── limiter.go └── rc │ └── client.go ├── router.go ├── router_gen.go ├── rpc ├── usercenter.go └── videocenter.go ├── snowflake_service ├── build.sh ├── handler.go ├── idl │ └── snowflake.proto ├── kitex.yaml ├── kitex_gen │ ├── snowflake.pb.fast.go │ ├── snowflake.pb.go │ └── snowflake │ │ ├── client.go │ │ ├── invoker.go │ │ ├── server.go │ │ └── snowflake.go ├── main.go ├── script │ └── bootstrap.sh └── snowfalke │ ├── id.go │ ├── id_test.go │ ├── lease.go │ └── lease_test.go ├── static ├── covers │ └── bear.png └── videos │ └── bear.mp4 ├── user_service ├── build.sh ├── dal │ ├── model │ │ ├── follower.go │ │ ├── message.go │ │ └── user.go │ ├── orm_test.go │ └── query │ │ ├── init.go │ │ └── user.go ├── handler.go ├── idl │ └── usercenter.proto ├── kitex.yaml ├── kitex_gen │ ├── usercenter.pb.fast.go │ ├── usercenter.pb.go │ └── usercenter │ │ ├── client.go │ │ ├── invoker.go │ │ ├── server.go │ │ └── usercenter.go ├── main.go ├── script │ └── bootstrap.sh ├── service │ ├── user_center.go │ └── user_center_test.go └── util │ ├── salt.go │ └── salt_test.go ├── uuidmaker └── maker.go └── video_service ├── build.sh ├── dal ├── model │ ├── comment.go │ ├── favorite.go │ └── video.go ├── orm_test.go └── query │ ├── comment.go │ ├── favorite.go │ ├── init.go │ └── video.go ├── handler.go ├── idl └── videocenter.proto ├── kitex.yaml ├── kitex_gen ├── videocenter.pb.fast.go ├── videocenter.pb.go └── videocenter │ ├── client.go │ ├── invoker.go │ ├── server.go │ └── videocenter.go ├── main.go ├── script └── bootstrap.sh └── service └── video_center.go /.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | *.a 3 | *.so 4 | _obj 5 | _test 6 | *.[568vq] 7 | [568vq].out 8 | *.cgo1.go 9 | *.cgo2.c 10 | _cgo_defun.c 11 | _cgo_gotypes.go 12 | _cgo_export.* 13 | _testmain.go 14 | *.exe 15 | *.exe~ 16 | *.test 17 | *.prof 18 | *.rar 19 | *.zip 20 | *.gz 21 | *.psd 22 | *.bmd 23 | *.cfg 24 | *.pptx 25 | *.log 26 | *nohup.out 27 | *settings.pyc 28 | *.sublime-project 29 | *.sublime-workspace 30 | !.gitkeep 31 | .DS_Store 32 | /.idea 33 | /.vscode 34 | dousheng_server 35 | /default.etcd/ 36 | */output/ 37 | static/videos/* 38 | static/covers/* 39 | !static/videos/bear.mp4 40 | !static/covers/bear.png 41 | conf.ini 42 | *.local.yml 43 | depoly/promethus/server/data/ 44 | dumped_hertz_remote_config.json 45 | depoly/promethus/mysqlexport/my.cnf 46 | -------------------------------------------------------------------------------- /.hz: -------------------------------------------------------------------------------- 1 | // Code generated by hz. DO NOT EDIT. 2 | 3 | hz version: v0.5.2 -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # dousheng_server 2 | 3 | 字节跳动青训营大作业~~ 4 | 5 | # 运行方法 6 | 7 | ## 配置 8 | 9 | * 新建conf.ini 10 | * 复制conf.template.ini到conf.ini 11 | * 修改conf.template.ini 12 | 13 | ~~~ cmd 14 | # wsl情况下 15 | # 启动mysql 16 | service mysql start 17 | # 启动etcd 18 | etcd 19 | # 进入项目目录 20 | # 启动uuid生成服务 21 | sh snowflake_service/build.sh && sh snowflake_service/output/bootstrap.sh 22 | # 启动用户服务 23 | sh user_service/build.sh && sh user_service/output/bootstrap.sh 24 | # 启动video服务 25 | sh video_service/build.sh && sh video_service/output/bootstrap.sh 26 | # 启动hertz 27 | go build -o dousheng_server && ./dousheng_server 28 | ~~~ 29 | 30 | # TODO List 31 | 32 | ## 基础接口 33 | 34 | - [x] 视频流 35 | - [x] 用户注册 36 | - [x] 用户登录 37 | - [x] 用户信息 38 | - [x] 视频投稿 39 | - [x] 发布列表 40 | 41 | ## 互动接口 42 | 43 | - [x] 赞 44 | - [x] 喜欢列表 45 | - [x] 评论 46 | - [x] 视频评论列表 47 | 48 | ## 社交接口 49 | 50 | - [x] 关系操作 51 | - [x] 用户关注列表 52 | - [x] 用户粉丝列表 53 | - [x] 用户好友列表 54 | - [x] 发送消息 55 | - [x] 消息列表 56 | 57 | 58 | 59 | # 项目详情 60 | 61 | ## http框架:hertz 62 | 63 | ~~~ cmd 64 | go build -o dousheng_server && ./dousheng_server 65 | ~~~ 66 | 67 | ## 微服务内框架:kitex 68 | 69 | ~~~ cmd 70 | kitex -module dousheng_server -service 服务名 idl文件路径 71 | ~~~ 72 | 73 | ## 服务启动命令 74 | 75 | ~~~ cmd 76 | sh build.sh && sh output/bootstrap.sh 77 | ~~~ 78 | 79 | #### prometheus 80 | 81 | ~~~ cmd 82 | prometheus --config.file=prometheus.yml 83 | ~~~ 84 | 85 | #### mysql-export 86 | 87 | ~~~ cmd 88 | mysqld_exporter --config.my-cnf=my.cnf 89 | ~~~ 90 | 91 | #### grafana 92 | 93 | ~~~ cmd 94 | sudo systemctl start grafana-server 95 | ~~~ 96 | 97 | 98 | 99 | ### 服务端口预分配 100 | 101 | | 服务 | 端口 | 102 | |------------|------| 103 | | hertz | 8080、9980 | 104 | | user | 8900、9900 | 105 | | snowflake | 8901、9901 | 106 | | video | 8902、9902 | 107 | | prometheus | 9090 | 108 | 109 | 110 | 111 | ## orm框架:gorm 112 | 113 | ### user模型 114 | 115 | ~~~ golang 116 | type User struct { 117 | UUID int64 `gorm:"primaryKey" json:"id"` 118 | Username string `json:"name"` 119 | Password string `json:"password"` 120 | FollowCount int64 `json:"follow_count"` 121 | FollowerCount int64 `json:"follower_count"` 122 | Followers []Follower `gorm:"foreignKey:user_id;foreignKey:follow_id"` 123 | Messages []Message `gorm:"foreignKey:from_user_id;foreignKey:to_user_id"` 124 | CreatedAt time.Time 125 | UpdatedAt time.Time 126 | DeletedAt gorm.DeletedAt `gorm:"index"` 127 | } 128 | ~~~ 129 | 130 | ### Follower模型 131 | ~~~ golang 132 | type Follower struct { 133 | // UserId 关注了 FollowID 134 | UserId int64 `gorm:"primaryKey" json:"userId"` 135 | FollowId int64 `gorm:"primaryKey" json:"followerId"` 136 | } 137 | ~~~ 138 | 139 | ### Message模型 140 | ~~~ golang 141 | type Message struct { 142 | //FromUserId对ToUserId发消息 143 | Id int64 `gorm:"primaryKey" json:"id"` 144 | ToUserId int64 `gorm:"to_user_id,index:idx_to" json:"to_user_id"` 145 | FromUserId int64 `gorm:"from_user_id,index:idx_from" json:"from_user_id"` 146 | Messages string `gorm:"message" json:"content"` 147 | CreatedAt int64 `gorm:"index:idx_create" json:"create_time"` 148 | } 149 | ~~~ 150 | 151 | ### video模型 152 | 153 | ~~~ golang 154 | type Video struct { 155 | UUID int64 `gorm:"primaryKey" json:"id"` 156 | UserID int64 `json:"user_id"` 157 | PlayURL string `json:"play_url"` 158 | CoverURL string `json:"cover_url"` 159 | FavoriteCount int64 `json:"favorite_count"` 160 | CommentCount int64 `json:"comment_count"` 161 | Title string `json:"title"` 162 | CreatedAt time.Time 163 | UpdatedAt time.Time 164 | DeletedAt gorm.DeletedAt `gorm:"index"` 165 | //外键 166 | User model.User `gorm:"foreignKey:user_id"` 167 | } 168 | ~~~ 169 | 170 | ### favorite模型 171 | 172 | ~~~ golang 173 | type Favorite struct { 174 | UserId int64 `gorm:"index:idx_user" json:"user_id"` 175 | VideoId int64 `json:"video_id"` 176 | //外键 177 | User model.User `gorm:"foreignKey:user_id"` 178 | } 179 | ~~~ 180 | 181 | ### comment模型 182 | 183 | ~~~ golang 184 | type Comment struct { 185 | CommentId int64 `gorm:"primaryKey" json:"comment_id"` 186 | UserId int64 `gorm:"index:idx_user" json:"user_id"` 187 | VideoId int64 `gorm:"index:idx_video" json:"video_id"` 188 | Content string `json:"content"` 189 | CreateDate string `gorm:"index:idx_create,sort:desc" json:"create_date"` 190 | CreatedAt time.Time 191 | } 192 | ~~~ 193 | 194 | ## 优化 195 | 196 | * UUID使用雪花算法生成 197 | * 使用etcd的lease机制维护雪花算法 198 | * 密码使用bcrypt加盐 199 | * 使用令牌桶限流 200 | -------------------------------------------------------------------------------- /biz/handler/user.go: -------------------------------------------------------------------------------- 1 | package handler 2 | 3 | import ( 4 | "context" 5 | zaplog "dousheng_server/deploy/log" 6 | "dousheng_server/middleware" 7 | "dousheng_server/rpc" 8 | "dousheng_server/user_service/dal/model" 9 | "errors" 10 | "github.com/cloudwego/hertz/pkg/app" 11 | "github.com/cloudwego/hertz/pkg/common/utils" 12 | "github.com/cloudwego/hertz/pkg/protocol/consts" 13 | "strconv" 14 | "strings" 15 | ) 16 | 17 | // CheckUser 登录校验 18 | func CheckUser(ctx context.Context, c *app.RequestContext) { 19 | middleware.JwtMiddleware.LoginHandler(ctx, c) 20 | zaplog.ZapLogger.Infof("用户:[%s]登陆成功", c.Query("username")) 21 | } 22 | 23 | // Register 注册 24 | func Register(ctx context.Context, c *app.RequestContext) { 25 | // 1. 验证参数 26 | username := c.Query("username") 27 | password := c.Query("password") 28 | if username == "" || password == "" || len(username) > 32 || len(password) > 32 { 29 | c.JSON(consts.StatusBadRequest, utils.H{ 30 | "status_code": -1, 31 | "status_msg": errors.New("wrong request param"), 32 | }) 33 | return 34 | } 35 | // 2. 调用rpc服务 36 | err := rpc.Register(username, password) 37 | // 3. 返回 38 | if err != nil { 39 | c.JSON(consts.StatusServiceUnavailable, utils.H{ 40 | "status_code": -1, 41 | "status_msg": err.Error(), 42 | }) 43 | zaplog.ZapLogger.Errorf("rpc.Register failed to visit err:%v", err) 44 | return 45 | } 46 | // 4. 登录 47 | middleware.JwtMiddleware.LoginHandler(ctx, c) 48 | } 49 | 50 | // Info 用户信息 51 | func Info(ctx context.Context, c *app.RequestContext) { 52 | // 1. 验证参数 53 | idStr := c.Query("user_id") 54 | requester, _ := c.Get("identity") 55 | 56 | userId, err := strconv.ParseInt(idStr, 10, 64) 57 | if err != nil { 58 | c.JSON(consts.StatusServiceUnavailable, utils.H{ 59 | "status_code": -1, 60 | "status_msg": "wrong request param" + err.Error(), 61 | }) 62 | return 63 | } 64 | if err != nil { 65 | c.JSON(consts.StatusServiceUnavailable, utils.H{ 66 | "status_code": -1, 67 | "status_msg": "wrong request param" + err.Error(), 68 | }) 69 | return 70 | } 71 | userGet, err := rpc.GetUserInfo(requester.(*model.User).UUID, userId) 72 | if err != nil { 73 | c.JSON(consts.StatusServiceUnavailable, utils.H{ 74 | "status_code": -1, 75 | "status_msg": err.Error(), 76 | }) 77 | zaplog.ZapLogger.Errorf("rpc.GetUserInfo failed to visit err:%v", err) 78 | return 79 | } 80 | c.JSON(consts.StatusOK, utils.H{ 81 | "status_code": 0, 82 | "status_msg": "success", 83 | "user": userGet, 84 | }) 85 | } 86 | 87 | // Follow 关注 88 | func Follow(ctx context.Context, c *app.RequestContext) { 89 | toId := c.Query("to_user_id") 90 | actionType := c.Query("action_type") 91 | requester, _ := c.Get("identity") 92 | userId := requester.(*model.User).UUID 93 | followId, err := strconv.ParseInt(toId, 10, 64) 94 | if err != nil { 95 | c.JSON(consts.StatusServiceUnavailable, utils.H{ 96 | "status_code": -1, 97 | "status_msg": "wrong request param" + err.Error(), 98 | }) 99 | return 100 | } 101 | switch actionType { 102 | case "1": 103 | err := rpc.Follow(userId, followId) 104 | if err != nil { 105 | c.JSON(consts.StatusServiceUnavailable, utils.H{ 106 | "status_code": -1, 107 | "status_msg": "wrong rpc" + err.Error(), 108 | }) 109 | zaplog.ZapLogger.Errorf("rpc.Follow failed to visit err:%v", err) 110 | return 111 | } 112 | case "2": 113 | err := rpc.CancelFollow(userId, followId) 114 | if err != nil { 115 | c.JSON(consts.StatusServiceUnavailable, utils.H{ 116 | "status_code": -1, 117 | "status_msg": "wrong rpc" + err.Error(), 118 | }) 119 | zaplog.ZapLogger.Errorf("rpc.CancelFollow failed to visit err:%v", err) 120 | return 121 | } 122 | default: 123 | c.JSON(consts.StatusServiceUnavailable, utils.H{ 124 | "status_code": -1, 125 | "status_msg": "wrong request param" + err.Error(), 126 | }) 127 | return 128 | } 129 | c.JSON(consts.StatusOK, utils.H{ 130 | "status_code": 0, 131 | "status_msg": "success", 132 | }) 133 | return 134 | } 135 | 136 | // FollowList 关注列表 137 | func FollowList(ctx context.Context, c *app.RequestContext) { 138 | Id := c.Query("user_id") 139 | userId, err := strconv.ParseInt(Id, 10, 64) 140 | if err != nil { 141 | c.JSON(consts.StatusServiceUnavailable, utils.H{ 142 | "status_code": -1, 143 | "status_msg": "wrong request param" + err.Error(), 144 | }) 145 | return 146 | } 147 | userModel, err := rpc.FollowList(userId) 148 | if err != nil { 149 | c.JSON(consts.StatusServiceUnavailable, utils.H{ 150 | "status_code": -1, 151 | "status_msg": err.Error(), 152 | "user_list": nil, 153 | }) 154 | zaplog.ZapLogger.Errorf("rpc.FollowList failed to visit err:%v", err) 155 | return 156 | } 157 | c.JSON(consts.StatusOK, utils.H{ 158 | "status_code": 0, 159 | "status_msg": "success", 160 | "user_list": userModel, 161 | }) 162 | return 163 | } 164 | 165 | // FollowerList 粉丝列表 166 | func FollowerList(ctx context.Context, c *app.RequestContext) { 167 | Id := c.Query("user_id") 168 | 169 | userId, err := strconv.ParseInt(Id, 10, 64) 170 | if err != nil { 171 | c.JSON(consts.StatusServiceUnavailable, utils.H{ 172 | "status_code": -1, 173 | "status_msg": "wrong request param" + err.Error(), 174 | }) 175 | return 176 | } 177 | userModel, err := rpc.FollowerList(userId) 178 | zaplog.ZapLogger.Errorf("rpc.Register failed to visit err:%v", err) 179 | if err != nil { 180 | c.JSON(consts.StatusServiceUnavailable, utils.H{ 181 | "status_code": -1, 182 | "status_msg": err.Error(), 183 | "user_list": nil, 184 | }) 185 | return 186 | } 187 | c.JSON(consts.StatusOK, utils.H{ 188 | "status_code": 0, 189 | "status_msg": "success", 190 | "user_list": userModel, 191 | }) 192 | return 193 | } 194 | 195 | // FriendList 好友列表 196 | func FriendList(ctx context.Context, c *app.RequestContext) { 197 | Id := c.Query("user_id") 198 | 199 | userId, err := strconv.ParseInt(Id, 10, 64) 200 | if err != nil { 201 | c.JSON(consts.StatusServiceUnavailable, utils.H{ 202 | "status_code": -1, 203 | "status_msg": "wrong request param" + err.Error(), 204 | }) 205 | return 206 | } 207 | userModel, err := rpc.FriendList(userId) 208 | if err != nil { 209 | c.JSON(consts.StatusServiceUnavailable, utils.H{ 210 | "status_code": -1, 211 | "status_msg": err.Error(), 212 | "user_list": nil, 213 | }) 214 | zaplog.ZapLogger.Errorf("rpc.FriendList failed to visit err:%v", err) 215 | return 216 | } 217 | c.JSON(consts.StatusOK, utils.H{ 218 | "status_code": 0, 219 | "status_msg": "success", 220 | "user_list": userModel, 221 | }) 222 | return 223 | } 224 | 225 | // SendMessage 发送消息 226 | func SendMessage(ctx context.Context, c *app.RequestContext) { 227 | Id := c.Query("to_user_id") 228 | toUserId, err := strconv.ParseInt(Id, 10, 64) 229 | if err != nil { 230 | c.JSON(consts.StatusServiceUnavailable, utils.H{ 231 | "status_code": -1, 232 | "status_msg": "wrong request param" + err.Error(), 233 | }) 234 | return 235 | } 236 | message := c.Query("content") 237 | if message == "" || strings.Replace(message, " ", "", -1) == "" { 238 | c.JSON(consts.StatusServiceUnavailable, utils.H{ 239 | "status_code": -1, 240 | "status_msg": "wrong request param:message is null", 241 | }) 242 | return 243 | } 244 | actionType := c.Query("action_type") 245 | requester, _ := c.Get("identity") 246 | fromUserId := requester.(*model.User).UUID 247 | switch actionType { 248 | case "1": 249 | err := rpc.SendMessage(fromUserId, toUserId, message) 250 | if err != nil { 251 | c.JSON(consts.StatusServiceUnavailable, utils.H{ 252 | "status_code": -1, 253 | "status_msg": "wrong rpc" + err.Error(), 254 | }) 255 | zaplog.ZapLogger.Errorf("rpc.SendMessage failed to visit err:%v", err) 256 | return 257 | } 258 | default: 259 | c.JSON(consts.StatusServiceUnavailable, utils.H{ 260 | "status_code": -1, 261 | "status_msg": "wrong request param" + err.Error(), 262 | }) 263 | return 264 | } 265 | c.JSON(consts.StatusOK, utils.H{ 266 | "status_code": 0, 267 | "status_msg": "success", 268 | }) 269 | 270 | } 271 | 272 | // MessageList 获取消息列表 273 | func MessageList(ctx context.Context, c *app.RequestContext) { 274 | Id := c.Query("to_user_id") 275 | toUserId, err := strconv.ParseInt(Id, 10, 64) 276 | if err != nil { 277 | c.JSON(consts.StatusServiceUnavailable, utils.H{ 278 | "status_code": -1, 279 | "status_msg": "wrong request param" + err.Error(), 280 | }) 281 | return 282 | } 283 | lastTimeTemp := c.Query("pre_msg_time") 284 | 285 | lastTime, err := strconv.ParseInt(lastTimeTemp, 10, 64) 286 | if err != nil { 287 | c.JSON(consts.StatusServiceUnavailable, utils.H{ 288 | "status_code": -1, 289 | "status_msg": "wrong request param" + err.Error(), 290 | }) 291 | return 292 | } 293 | requester, _ := c.Get("identity") 294 | fromUserId := requester.(*model.User).UUID 295 | messageList, err := rpc.MessageList(fromUserId, toUserId, lastTime) 296 | if err != nil { 297 | c.JSON(consts.StatusServiceUnavailable, utils.H{ 298 | "status_code": -1, 299 | "status_msg": err.Error(), 300 | "message_list": nil, 301 | }) 302 | zaplog.ZapLogger.Errorf("rpc.MessageList failed to visit err:%v", err) 303 | return 304 | } 305 | c.JSON(consts.StatusOK, utils.H{ 306 | "status_code": 0, 307 | "status_msg": "success", 308 | "message_list": messageList, 309 | }) 310 | return 311 | 312 | } 313 | -------------------------------------------------------------------------------- /biz/handler/video.go: -------------------------------------------------------------------------------- 1 | package handler 2 | 3 | import ( 4 | "context" 5 | zaplog "dousheng_server/deploy/log" 6 | "dousheng_server/middleware" 7 | "dousheng_server/middleware/covermaker" 8 | "dousheng_server/rpc" 9 | usermodel "dousheng_server/user_service/dal/model" 10 | "dousheng_server/video_service/dal/model" 11 | "fmt" 12 | "github.com/cloudwego/hertz/pkg/app" 13 | "github.com/cloudwego/hertz/pkg/common/utils" 14 | "github.com/cloudwego/hertz/pkg/protocol/consts" 15 | "github.com/hertz-contrib/jwt" 16 | "io" 17 | "mime/multipart" 18 | "os" 19 | "strconv" 20 | "strings" 21 | "time" 22 | ) 23 | 24 | // Publish . 25 | func Publish(ctx context.Context, c *app.RequestContext) { 26 | userGet, _ := c.Get("identity") 27 | user := userGet.(*usermodel.User) 28 | type fileParam struct { 29 | f *multipart.FileHeader `form:"data"` 30 | token string `form:"token"` 31 | title string `form:"title"` 32 | } 33 | // 1. 验证参数 34 | req := fileParam{} 35 | err := c.Bind(&req) 36 | if err != nil { 37 | c.JSON(consts.StatusBadRequest, utils.H{ 38 | "status_code": -1, 39 | "status_msg": "wong param" + err.Error(), 40 | }) 41 | return 42 | } 43 | // 获取文件后缀 44 | filenameArr := strings.Split(req.f.Filename, ".") 45 | suffix := filenameArr[len(filenameArr)-1] 46 | 47 | // 2. 调用服务 48 | uuid, errRpc := rpc.PublishVideo(&model.Video{ 49 | UserID: user.UUID, 50 | // 向服务传递文件后缀 51 | // 通过UUID+后缀保存文件 52 | // 防止文件冲突 53 | PlayURL: suffix, 54 | CoverURL: "", 55 | FavoriteCount: 0, 56 | CommentCount: 0, 57 | Title: req.title, 58 | }) 59 | 60 | // 3.1 保存视频 61 | videoPath := fmt.Sprintf("static/videos/%d.%s", uuid, suffix) 62 | coverPath := fmt.Sprintf("static/covers/%d", uuid) 63 | file, errSave := os.OpenFile(videoPath, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 066) 64 | defer file.Close() 65 | fileSaved, _ := req.f.Open() 66 | io.Copy(file, fileSaved) 67 | // 3.2 保存封面 68 | _, errCover := covermaker.GetSnapshot(videoPath, coverPath, 1) 69 | // 4. 失败一个全部回调 70 | if errSave != nil || errRpc != nil || errCover != nil { 71 | _ = os.Remove(videoPath) 72 | _ = os.Remove(coverPath + ".png") 73 | _ = rpc.DeleteVideo(uuid) 74 | c.JSON(consts.StatusBadRequest, utils.H{ 75 | "status_code": -1, 76 | "status_msg": "rpc.PublishVideo wrong", 77 | }) 78 | zaplog.ZapLogger.Errorf("save video failed errSave:%v, errRpc:%v, errCover:%v", errSave, errRpc, errCover) 79 | return 80 | } 81 | // 5. 返回 82 | c.JSON(consts.StatusOK, utils.H{ 83 | "status_code": 0, 84 | "status_msg": "success", 85 | }) 86 | } 87 | 88 | // Feed . 89 | func Feed(ctx context.Context, c *app.RequestContext) { 90 | // 1. 初始化可选参数 91 | var uuid int64 92 | lastTimeStamp := time.Now().UnixMilli() 93 | // 2. 通过时间戳生成time 94 | lastTimeStr := c.Query("latest_time") 95 | if lastTimeStr != "" { 96 | lastTimeStamp, _ = strconv.ParseInt(lastTimeStr, 10, 64) 97 | //lastTimeStamp = lastTimeStamp * 100 98 | } 99 | // 4. 通过token字符串解析uuid 100 | tokenString := c.Query("token") 101 | if tokenString != "" { 102 | requesterToken, _ := middleware.JwtMiddleware.ParseTokenString(tokenString) 103 | claim := jwt.ExtractClaimsFromToken(requesterToken) 104 | uuid = int64(claim["identity"].(float64)) 105 | } 106 | // 5. 返回 107 | videos, nextTime, err := rpc.Feed(lastTimeStamp, uuid) 108 | if len(videos) < 3 { 109 | // 时间设置为当前时间即可完成循环 110 | nextTime = time.Now().UnixMilli() 111 | } 112 | if err != nil { 113 | c.JSON(consts.StatusBadRequest, utils.H{ 114 | "status_code": -1, 115 | "status_msg": err.Error(), 116 | }) 117 | zaplog.ZapLogger.Errorf("rpc.Feed failed to visit err:%v", err) 118 | return 119 | } 120 | 121 | c.JSON(consts.StatusOK, utils.H{ 122 | "status_code": 0, 123 | "status_msg": "success", 124 | "next_time": nextTime, 125 | "video_list": videos, 126 | }) 127 | } 128 | 129 | // VideoList . 130 | func VideoList(ctx context.Context, c *app.RequestContext) { 131 | userIdStr := c.Query("user_id") 132 | userId, err := strconv.ParseInt(userIdStr, 10, 64) 133 | if err != nil { 134 | c.JSON(consts.StatusBadRequest, utils.H{ 135 | "status_code": -1, 136 | "status_msg": "wrong param" + err.Error(), 137 | }) 138 | return 139 | } 140 | videos, err := rpc.VideoList(userId) 141 | if err != nil { 142 | c.JSON(consts.StatusBadRequest, utils.H{ 143 | "status_code": -1, 144 | "status_msg": err.Error(), 145 | }) 146 | zaplog.ZapLogger.Errorf("rpc.VideoList failed to visit err:%v", err) 147 | return 148 | } 149 | c.JSON(consts.StatusOK, utils.H{ 150 | "status_code": 0, 151 | "status_msg": "success", 152 | "video_list": videos, 153 | }) 154 | } 155 | 156 | // VideoLike 点赞或取消点赞 157 | func VideoLike(ctx context.Context, c *app.RequestContext) { 158 | // 1. 验证参数 159 | userGet, _ := c.Get("identity") 160 | videoGet := c.Query("video_id") 161 | actionTypeGet := c.Query("action_type") 162 | userId := userGet.(*usermodel.User).UUID 163 | videoId, err := strconv.ParseInt(videoGet, 10, 64) 164 | if err != nil { 165 | c.JSON(consts.StatusBadRequest, utils.H{ 166 | "status_code": -1, 167 | "status_msg": "wrong param : video_id" + err.Error(), 168 | }) 169 | return 170 | } 171 | actionType, err := strconv.ParseInt(actionTypeGet, 10, 32) 172 | if err != nil || (actionType != 1 && actionType != 2) { 173 | c.JSON(consts.StatusBadRequest, utils.H{ 174 | "status_code": -1, 175 | "status_msg": "wrong param : action_type", 176 | }) 177 | return 178 | } 179 | // 2. 调用rpc服务 180 | err = rpc.LikeVideo(userId, videoId, int32(actionType)) 181 | if err != nil { 182 | c.JSON(consts.StatusBadRequest, utils.H{ 183 | "status_code": -1, 184 | "status_msg": "rpc.LikeVideo wrong" + err.Error(), 185 | }) 186 | zaplog.ZapLogger.Errorf("rpc.LikeVideo failed to visit err:%v", err) 187 | return 188 | } 189 | // 3. 返回 190 | c.JSON(consts.StatusOK, utils.H{ 191 | "status_code": 0, 192 | "status_msg": "success", 193 | }) 194 | } 195 | 196 | // FavoriteList . 197 | func FavoriteList(ctx context.Context, c *app.RequestContext) { 198 | // 1. 验证参数 199 | userIdStr := c.Query("user_id") 200 | requester, _ := c.Get("identity") 201 | 202 | userId, err := strconv.ParseInt(userIdStr, 10, 64) 203 | tokenId := requester.(*usermodel.User).UUID 204 | if err != nil { 205 | c.JSON(consts.StatusBadRequest, utils.H{ 206 | "status_code": -1, 207 | "status_msg": "wrong param : video_id" + err.Error(), 208 | }) 209 | return 210 | } 211 | // 2. 请求服务 212 | videos, err := rpc.FavoriteVideoList(tokenId, userId) 213 | if err != nil { 214 | c.JSON(consts.StatusBadRequest, utils.H{ 215 | "status_code": -1, 216 | "status_msg": "rpc.FavoriteVideoList wrong" + err.Error(), 217 | }) 218 | zaplog.ZapLogger.Errorf("rpc.FavoriteVideoList failed to visit err:%v", err) 219 | return 220 | } 221 | c.JSON(consts.StatusOK, utils.H{ 222 | "status_code": 0, 223 | "status_msg": "success", 224 | "video_list": videos, 225 | }) 226 | } 227 | 228 | // CommentAction . 229 | func CommentAction(ctx context.Context, c *app.RequestContext) { 230 | // 1. 验证参数 231 | userGet, _ := c.Get("identity") 232 | user := userGet.(*usermodel.User) 233 | videoGet := c.Query("video_id") 234 | videoId, err := strconv.ParseInt(videoGet, 10, 64) 235 | tokenId := user.UUID 236 | if err != nil { 237 | c.JSON(consts.StatusBadRequest, utils.H{ 238 | "status_code": -1, 239 | "status_msg": "wong param video_id" + err.Error(), 240 | }) 241 | return 242 | } 243 | actionType := c.Query("action_type") 244 | 245 | switch actionType { 246 | case "1": // 2.1 发布 247 | // 2.2 验证评论文本 248 | content := c.Query("comment_text") 249 | if content == "" { 250 | c.JSON(consts.StatusBadRequest, utils.H{ 251 | "status_code": -1, 252 | "status_msg": "content is empty" + err.Error(), 253 | }) 254 | return 255 | } 256 | // 2.3 调用rpc 257 | comment, err := rpc.PostComment(tokenId, model.Comment{ 258 | UserId: user.UUID, 259 | VideoId: videoId, 260 | Content: content, 261 | }) 262 | // 2.4 返回 263 | if err != nil { 264 | c.JSON(consts.StatusBadRequest, utils.H{ 265 | "status_code": -1, 266 | "status_msg": "rpc.PostComment wrong" + err.Error(), 267 | }) 268 | zaplog.ZapLogger.Errorf("rpc.postComment failed to visit err:%v", err) 269 | return 270 | } 271 | 272 | c.JSON(consts.StatusOK, utils.H{ 273 | "status_code": 0, 274 | "status_msg": "success", 275 | "comment": comment, 276 | }) 277 | 278 | case "2": // 2.1 删除 279 | // 2.2 验证评论uuid 280 | uuidStr := c.Query("comment_id") 281 | uuid, err := strconv.ParseInt(uuidStr, 10, 64) 282 | // 2.3 调用rpc 283 | err = rpc.DeleteComment(uuid) 284 | if err != nil { 285 | c.JSON(consts.StatusBadRequest, utils.H{ 286 | "status_code": -1, 287 | "status_msg": "rpc.DeleteComment wrong", 288 | }) 289 | return 290 | } 291 | c.JSON(consts.StatusOK, utils.H{ 292 | "status_code": 0, 293 | "status_msg": "success", 294 | "comment": nil, 295 | }) 296 | 297 | default: 298 | c.JSON(consts.StatusBadRequest, utils.H{ 299 | "status_code": -1, 300 | "status_msg": "wong param action_type", 301 | }) 302 | return 303 | } 304 | } 305 | 306 | // GetComment . 307 | func GetComment(ctx context.Context, c *app.RequestContext) { 308 | // 1. 验证参数 309 | videoIdStr := c.Query("video_id") 310 | requester, _ := c.Get("identity") 311 | videoId, err := strconv.ParseInt(videoIdStr, 10, 64) 312 | tokenId := requester.(*usermodel.User).UUID 313 | if err != nil { 314 | c.JSON(consts.StatusBadRequest, utils.H{ 315 | "status_code": -1, 316 | "status_msg": "wrong param : video_id", 317 | }) 318 | return 319 | } 320 | // 2. 调用服务 321 | comments, err := rpc.GetComment(tokenId, videoId) 322 | if err != nil { 323 | c.JSON(consts.StatusBadRequest, utils.H{ 324 | "status_code": -1, 325 | "status_msg": "rpc.GetComment wrong" + err.Error(), 326 | }) 327 | zaplog.ZapLogger.Errorf("rpc.GetComment failed to visit err:%v", err) 328 | return 329 | } 330 | // 3. 返回 331 | c.JSON(consts.StatusOK, utils.H{ 332 | "status_code": 0, 333 | "status_msg": "success", 334 | "comment_list": comments, 335 | }) 336 | } 337 | -------------------------------------------------------------------------------- /biz/router/register.go: -------------------------------------------------------------------------------- 1 | // Code generated by hertz generator. DO NOT EDIT. 2 | 3 | package router 4 | 5 | import ( 6 | "github.com/cloudwego/hertz/pkg/app/server" 7 | ) 8 | 9 | // GeneratedRegister registers routers generated by IDL. 10 | func GeneratedRegister(r *server.Hertz) { 11 | //INSERT_POINT: DO NOT DELETE THIS LINE! 12 | } 13 | -------------------------------------------------------------------------------- /conf.temp.ini: -------------------------------------------------------------------------------- 1 | [etcd] 2 | url=127.0.0.1:2379 3 | 4 | [mysql] 5 | url=127.0.0.1:3306 6 | user=root 7 | password=123456 8 | database=dousheng 9 | 10 | [static] 11 | saverIp=127.0.0.1 12 | reflect=/root/go/src/github.com/cloudwego/dousheng_server -------------------------------------------------------------------------------- /conf/config.go: -------------------------------------------------------------------------------- 1 | package conf 2 | 3 | import ( 4 | "gopkg.in/ini.v1" 5 | ) 6 | 7 | var Conf DConfig 8 | 9 | type DConfig struct { 10 | EtcdConfig `ini:"etcd"` 11 | MysqlConfig `ini:"mysql"` 12 | StaticConfig `ini:"static"` 13 | } 14 | 15 | type EtcdConfig struct { 16 | Url string `ini:"url"` 17 | } 18 | 19 | type MysqlConfig struct { 20 | Url string `ini:"url"` 21 | User string `ini:"user"` 22 | Password string `ini:"password"` 23 | Database string `ini:"database"` 24 | } 25 | 26 | type StaticConfig struct { 27 | SaverIp string `ini:"saverIp"` 28 | Reflect string `ini:"reflect"` 29 | } 30 | 31 | func init() { 32 | // 先实例化结构体,将指针传入MapTo方法中 33 | err := ini.MapTo(&Conf, "./conf.ini") 34 | if err != nil { 35 | // 服务使用的相对路径 36 | err = ini.MapTo(&Conf, "../conf.ini") 37 | } 38 | if err != nil { 39 | // 数据库测试使用的相对路径 40 | err = ini.MapTo(&Conf, "../../conf.ini") 41 | } 42 | if err != nil { 43 | panic("failed when init conf err : " + err.Error()) 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /deploy/log/zaplog.go: -------------------------------------------------------------------------------- 1 | package zaplog 2 | 3 | import ( 4 | hertzzap "github.com/hertz-contrib/logger/zap" 5 | "go.uber.org/zap" 6 | "go.uber.org/zap/zapcore" 7 | "gopkg.in/natefinch/lumberjack.v2" 8 | ) 9 | 10 | var ZapLogger *hertzzap.Logger 11 | 12 | func InitLogger() { 13 | ZapLogger = hertzzap.NewLogger( 14 | hertzzap.WithCores([]hertzzap.CoreConfig{ 15 | { 16 | Enc: zapcore.NewJSONEncoder(simpleEncoderConfig()), 17 | Ws: getWriteSyncer("./deploy/log/info/log.log"), 18 | Lvl: zap.NewAtomicLevelAt(zapcore.LevelOf( 19 | zap.LevelEnablerFunc(func(lev zapcore.Level) bool { 20 | return lev == zap.InfoLevel 21 | }))), 22 | }, 23 | { 24 | Enc: zapcore.NewJSONEncoder(simpleEncoderConfig()), 25 | Ws: getWriteSyncer("./deploy/log/warn/log.log"), 26 | Lvl: zap.NewAtomicLevelAt(zapcore.LevelOf( 27 | zap.LevelEnablerFunc(func(lev zapcore.Level) bool { 28 | return lev == zap.WarnLevel 29 | }))), 30 | }, 31 | { 32 | Enc: zapcore.NewJSONEncoder(simpleEncoderConfig()), 33 | Ws: getWriteSyncer("./deploy/log/error/log.log"), 34 | Lvl: zap.NewAtomicLevelAt(zapcore.LevelOf( 35 | zap.LevelEnablerFunc(func(lev zapcore.Level) bool { 36 | return lev == zap.ErrorLevel 37 | }))), 38 | }, 39 | }...)) 40 | defer ZapLogger.Sync() 41 | } 42 | 43 | func simpleEncoderConfig() zapcore.EncoderConfig { 44 | cfg := basicEncoderConfig() 45 | cfg.EncodeTime = zapcore.ISO8601TimeEncoder 46 | cfg.EncodeLevel = zapcore.CapitalLevelEncoder 47 | cfg.EncodeDuration = zapcore.StringDurationEncoder 48 | return cfg 49 | } 50 | 51 | func getWriteSyncer(file string) zapcore.WriteSyncer { 52 | lumberJackLogger := &lumberjack.Logger{ 53 | Filename: file, 54 | MaxSize: 10, 55 | MaxBackups: 50000, 56 | MaxAge: 1000, 57 | Compress: true, 58 | LocalTime: true, 59 | } 60 | return zapcore.AddSync(lumberJackLogger) 61 | } 62 | 63 | func basicEncoderConfig() zapcore.EncoderConfig { 64 | return zapcore.EncoderConfig{ 65 | MessageKey: "msg", 66 | LevelKey: "level", 67 | NameKey: "name", 68 | TimeKey: "ts", 69 | CallerKey: "caller", 70 | FunctionKey: "func", 71 | StacktraceKey: "stacktrace", 72 | LineEnding: "\n", 73 | EncodeTime: zapcore.EpochTimeEncoder, 74 | EncodeLevel: zapcore.LowercaseLevelEncoder, 75 | EncodeDuration: zapcore.SecondsDurationEncoder, 76 | EncodeCaller: zapcore.ShortCallerEncoder, 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /deploy/promethus/mysqlexport/my.cnf: -------------------------------------------------------------------------------- 1 | [client] 2 | host=127.0.0.1 3 | port=3306 4 | user=mysql_exporter 5 | password=123456 6 | -------------------------------------------------------------------------------- /deploy/promethus/mysqlexport/my.temp.cnf: -------------------------------------------------------------------------------- 1 | [client] 2 | host=127.0.0.1 3 | port=3306 4 | user=root 5 | password=123456 6 | -------------------------------------------------------------------------------- /deploy/promethus/server/prometheus.yml: -------------------------------------------------------------------------------- 1 | scrape_configs: 2 | - job_name: 'prometheus' 3 | scrape_interval: 15s #global catch time 4 | static_configs: 5 | - targets: ['0.0.0.0:9090'] 6 | 7 | - job_name: 'rpc-user' 8 | static_configs: 9 | - targets: [ 'localhost:9900' ] 10 | labels: 11 | job: rpc-user 12 | app: rpc-user 13 | env: dev 14 | 15 | - job_name: 'rpc-snowflake' 16 | static_configs: 17 | - targets: ['localhost:9901'] 18 | labels: 19 | job: rpc-snowflake 20 | app: rpc-snowflake 21 | env: dev 22 | 23 | - job_name: 'rpc-video' 24 | static_configs: 25 | - targets: ['localhost:9902'] 26 | labels: 27 | job: rpc-video 28 | app: rpc-video 29 | env: dev 30 | 31 | - job_name: 'api-hertz' 32 | static_configs: 33 | - targets: ['localhost:9080'] 34 | labels: 35 | job: api-hertz 36 | app: api-hertz 37 | env: dev 38 | 39 | - job_name: 'mysql' 40 | static_configs: 41 | - targets: ['localhost:9104'] 42 | labels: 43 | job: mysql 44 | app: mysql 45 | 46 | - job_name: 'linux' 47 | static_configs: 48 | - targets: ['localhost:9100'] 49 | labels: 50 | job: linux 51 | -------------------------------------------------------------------------------- /dump.rdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/writiger/dousheng_server/53ccc0d9a945dcdf2359be27e5a3a973d10374b4/dump.rdb -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module dousheng_server 2 | 3 | go 1.19 4 | 5 | require ( 6 | github.com/cloudwego/fastpb v0.0.3 7 | github.com/cloudwego/hertz v0.5.2 8 | github.com/cloudwego/kitex v0.4.4 9 | github.com/disintegration/imaging v1.6.2 10 | github.com/go-redis/redis/v8 v8.11.5 11 | github.com/hertz-contrib/cors v0.0.0-20220601061225-50f4e582beaf 12 | github.com/hertz-contrib/gzip v0.0.1 13 | github.com/hertz-contrib/jwt v1.0.2 14 | github.com/hertz-contrib/logger/zap v0.0.0-20230206071608-2de215a9fd50 15 | github.com/hertz-contrib/monitor-prometheus v0.0.0-20221109015426-47eab4e08245 16 | github.com/kitex-contrib/monitor-prometheus v0.0.0-20210817080809-024dd7bd51e1 17 | github.com/kitex-contrib/obs-opentelemetry v0.1.0 18 | github.com/kitex-contrib/registry-etcd v0.1.0 19 | github.com/u2takey/ffmpeg-go v0.4.1 20 | go.etcd.io/etcd/client/v3 v3.5.7 21 | go.uber.org/zap v1.23.0 22 | golang.org/x/crypto v0.5.0 23 | google.golang.org/protobuf v1.28.1 24 | gopkg.in/ini.v1 v1.67.0 25 | gopkg.in/natefinch/lumberjack.v2 v2.0.0 26 | gorm.io/driver/mysql v1.4.5 27 | gorm.io/gorm v1.24.5 28 | ) 29 | 30 | require ( 31 | github.com/apache/thrift v0.13.0 // indirect 32 | github.com/aws/aws-sdk-go v1.38.20 // indirect 33 | github.com/beorn7/perks v1.0.1 // indirect 34 | github.com/bytedance/go-tagexpr/v2 v2.9.2 // indirect 35 | github.com/bytedance/gopkg v0.0.0-20220531084716-665b4f21126f // indirect 36 | github.com/bytedance/sonic v1.5.0 // indirect 37 | github.com/cespare/xxhash/v2 v2.1.2 // indirect 38 | github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06 // indirect 39 | github.com/chenzhuoyu/iasm v0.0.0-20220818063314-28c361dae733 // indirect 40 | github.com/choleraehyq/pid v0.0.15 // indirect 41 | github.com/cloudwego/frugal v0.1.3 // indirect 42 | github.com/cloudwego/netpoll v0.3.1 // indirect 43 | github.com/cloudwego/thriftgo v0.2.4 // indirect 44 | github.com/coreos/go-semver v0.3.0 // indirect 45 | github.com/coreos/go-systemd/v22 v22.3.2 // indirect 46 | github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect 47 | github.com/fsnotify/fsnotify v1.5.4 // indirect 48 | github.com/go-logr/logr v1.2.3 // indirect 49 | github.com/go-logr/stdr v1.2.2 // indirect 50 | github.com/go-sql-driver/mysql v1.7.0 // indirect 51 | github.com/gogo/protobuf v1.3.2 // indirect 52 | github.com/golang-jwt/jwt/v4 v4.4.1 // indirect 53 | github.com/golang/protobuf v1.5.2 // indirect 54 | github.com/google/pprof v0.0.0-20220608213341-c488b8fa1db3 // indirect 55 | github.com/henrylee2cn/ameda v1.4.10 // indirect 56 | github.com/henrylee2cn/goutil v0.0.0-20210127050712-89660552f6f8 // indirect 57 | github.com/hertz-contrib/pprof v0.1.0 // indirect 58 | github.com/jhump/protoreflect v1.8.2 // indirect 59 | github.com/jinzhu/inflection v1.0.0 // indirect 60 | github.com/jinzhu/now v1.1.5 // indirect 61 | github.com/jmespath/go-jmespath v0.4.0 // indirect 62 | github.com/json-iterator/go v1.1.12 // indirect 63 | github.com/klauspost/cpuid/v2 v2.1.0 // indirect 64 | github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect 65 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect 66 | github.com/modern-go/reflect2 v1.0.2 // indirect 67 | github.com/nyaruka/phonenumbers v1.0.55 // indirect 68 | github.com/oleiade/lane v1.0.1 // indirect 69 | github.com/prometheus/client_golang v1.14.0 // indirect 70 | github.com/prometheus/client_model v0.3.0 // indirect 71 | github.com/prometheus/common v0.37.0 // indirect 72 | github.com/prometheus/procfs v0.8.0 // indirect 73 | github.com/savsgio/gotils v0.0.0-20220530130905-52f3993e8d6d // indirect 74 | github.com/tidwall/gjson v1.14.3 // indirect 75 | github.com/tidwall/match v1.1.1 // indirect 76 | github.com/tidwall/pretty v1.2.0 // indirect 77 | github.com/twitchyliquid64/golang-asm v0.15.1 // indirect 78 | github.com/u2takey/go-utils v0.3.1 // indirect 79 | go.etcd.io/etcd/api/v3 v3.5.7 // indirect 80 | go.etcd.io/etcd/client/pkg/v3 v3.5.7 // indirect 81 | go.opentelemetry.io/otel v1.9.0 // indirect 82 | go.opentelemetry.io/otel/metric v0.31.0 // indirect 83 | go.opentelemetry.io/otel/sdk v1.9.0 // indirect 84 | go.opentelemetry.io/otel/trace v1.9.0 // indirect 85 | go.uber.org/atomic v1.8.0 // indirect 86 | go.uber.org/multierr v1.8.0 // indirect 87 | golang.org/x/arch v0.0.0-20220722155209-00200b7164a7 // indirect 88 | golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8 // indirect 89 | golang.org/x/net v0.5.0 // indirect 90 | golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f // indirect 91 | golang.org/x/sys v0.4.0 // indirect 92 | golang.org/x/text v0.6.0 // indirect 93 | google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1 // indirect 94 | google.golang.org/grpc v1.46.2 // indirect 95 | gopkg.in/yaml.v3 v3.0.1 // indirect 96 | ) 97 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | // Code generated by hertz generator. 2 | 3 | package main 4 | 5 | import ( 6 | zaplog "dousheng_server/deploy/log" 7 | "dousheng_server/middleware/limiter" 8 | "github.com/cloudwego/hertz/pkg/app/server" 9 | "github.com/cloudwego/hertz/pkg/network/standard" 10 | "github.com/hertz-contrib/cors" 11 | "github.com/hertz-contrib/gzip" 12 | "github.com/hertz-contrib/monitor-prometheus" 13 | ) 14 | 15 | func main() { 16 | limiter.InitLimiter() 17 | zaplog.InitLogger() 18 | h := server.Default( 19 | server.WithStreamBody(true), 20 | server.WithTransport(standard.NewTransporter), 21 | server.WithHostPorts("0.0.0.0:8080"), 22 | server.WithHandleMethodNotAllowed(true), 23 | server.WithTracer(prometheus.NewServerTracer(":9080", "/metrics"))) 24 | 25 | // 使用限流中间件 26 | h.Use(limiter.LimiterMiddleware()) 27 | h.Use(cors.New(cors.Config{AllowAllOrigins: true})) 28 | h.Use(gzip.Gzip(gzip.DefaultCompression)) 29 | register(h) 30 | h.Spin() 31 | } 32 | -------------------------------------------------------------------------------- /middleware/covermaker/cover.go: -------------------------------------------------------------------------------- 1 | package covermaker 2 | 3 | import ( 4 | "bytes" 5 | zaplog "dousheng_server/deploy/log" 6 | "fmt" 7 | "github.com/disintegration/imaging" 8 | ffmpeg "github.com/u2takey/ffmpeg-go" 9 | "os" 10 | "strings" 11 | ) 12 | 13 | func GetSnapshot(videoPath, snapshotPath string, frameNum int) (snapshotName string, err error) { 14 | buf := bytes.NewBuffer(nil) 15 | err = ffmpeg.Input(videoPath). 16 | Filter("select", ffmpeg.Args{fmt.Sprintf("gte(n,%d)", frameNum)}). 17 | Output("pipe:", ffmpeg.KwArgs{"vframes": 1, "format": "image2", "vcodec": "mjpeg"}). 18 | GlobalArgs("-loglevel", "quiet"). 19 | WithOutput(buf, os.Stdout). 20 | Run() 21 | if err != nil { 22 | zaplog.ZapLogger.Warnf("failed when making cover err:%v", err) 23 | return "", err 24 | } 25 | 26 | img, err := imaging.Decode(buf) 27 | if err != nil { 28 | zaplog.ZapLogger.Warnf("failed when making cover err:%v", err) 29 | return "", err 30 | } 31 | 32 | err = imaging.Save(img, snapshotPath+".png") 33 | if err != nil { 34 | zaplog.ZapLogger.Warnf("failed when making cover err:%v", err) 35 | return "", err 36 | } 37 | 38 | names := strings.Split(snapshotPath, "\\") 39 | snapshotName = names[len(names)-1] + ".png" 40 | return 41 | } 42 | -------------------------------------------------------------------------------- /middleware/covermaker/cover_test.go: -------------------------------------------------------------------------------- 1 | package covermaker 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | ) 7 | 8 | func TestGetSnapshot(t *testing.T) { 9 | t.Run("测试", func(t *testing.T) { 10 | fmt.Println(GetSnapshot("../static/videos/630185627949727744.mp4", "../static/covers/630185627949727744", 1)) 11 | }) 12 | } 13 | -------------------------------------------------------------------------------- /middleware/jwt.go: -------------------------------------------------------------------------------- 1 | package middleware 2 | 3 | import ( 4 | "context" 5 | "dousheng_server/rpc" 6 | "dousheng_server/user_service/dal/model" 7 | "github.com/cloudwego/hertz/pkg/app" 8 | "github.com/cloudwego/hertz/pkg/common/utils" 9 | "github.com/hertz-contrib/jwt" 10 | "net/http" 11 | "time" 12 | ) 13 | 14 | var JwtMiddleware *jwt.HertzJWTMiddleware 15 | 16 | func init() { 17 | var err error 18 | JwtMiddleware, err = jwt.New(&jwt.HertzJWTMiddleware{ 19 | Key: []byte("revres_gnehsoud"), 20 | Timeout: time.Hour * 7 * 24, 21 | MaxRefresh: time.Hour * 7 * 24, 22 | TokenLookup: "query: token, header: Authorization, form: token", 23 | TokenHeadName: "Bearer", 24 | // 解析 25 | IdentityHandler: func(ctx context.Context, c *app.RequestContext) interface{} { 26 | claims := jwt.ExtractClaims(ctx, c) 27 | return &model.User{ 28 | UUID: int64(claims[jwt.IdentityKey].(float64)), 29 | } 30 | }, 31 | // 负载信息 32 | PayloadFunc: func(data interface{}) jwt.MapClaims { 33 | if v, ok := data.(int64); ok { 34 | return jwt.MapClaims{ 35 | jwt.IdentityKey: v, 36 | } 37 | } 38 | return jwt.MapClaims{} 39 | }, 40 | // 验证 41 | Authenticator: func(ctx context.Context, c *app.RequestContext) (interface{}, error) { 42 | username := c.Query("username") 43 | password := c.Query("password") 44 | if len(username) == 0 || len(password) == 0 || len(username) > 32 || len(password) > 32 { 45 | return "", jwt.ErrMissingLoginValues 46 | } 47 | uuid, err := rpc.LoginByPassword(username, password) 48 | c.Set("uuidmaker", uuid) 49 | return uuid, err 50 | }, 51 | LoginResponse: func(ctx context.Context, c *app.RequestContext, code int, token string, expire time.Time) { 52 | uuid, _ := c.Get("uuidmaker") 53 | c.JSON(http.StatusOK, utils.H{ 54 | "status_code": 0, 55 | "status_msg": "success", 56 | "user_id": uuid, 57 | "token": token, 58 | }) 59 | }, 60 | Unauthorized: func(ctx context.Context, c *app.RequestContext, code int, message string) { 61 | c.JSON(http.StatusOK, utils.H{ 62 | "code": -1, 63 | "message": message, 64 | }) 65 | }, 66 | }) 67 | if err != nil { 68 | panic("init jwt failed") 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /middleware/limiter/limiter.go: -------------------------------------------------------------------------------- 1 | package limiter 2 | 3 | import ( 4 | "context" 5 | "dousheng_server/middleware/rc" 6 | "errors" 7 | "github.com/cloudwego/hertz/pkg/app" 8 | "github.com/go-redis/redis/v8" 9 | "time" 10 | ) 11 | 12 | const tokenBucketLimiterTryAcquireRedisScript = ` 13 | -- ARGV[1]: 容量 14 | -- ARGV[2]: 发放令牌速率/秒 15 | -- ARGV[3]: 当前时间(秒) 16 | 17 | local capacity = tonumber(ARGV[1]) 18 | local rate = tonumber(ARGV[2]) 19 | local now = tonumber(ARGV[3]) 20 | 21 | local lastTime = tonumber(redis.call("hget", KEYS[1], "lastTime")) 22 | local currentTokens = tonumber(redis.call("hget", KEYS[1], "currentTokens")) 23 | -- 初始化 24 | if lastTime == nil then 25 | lastTime = now 26 | currentTokens = capacity 27 | redis.call("hmset", KEYS[1], "currentTokens", currentTokens, "lastTime", lastTime) 28 | end 29 | 30 | -- 尝试发放令牌 31 | -- 距离上次发放令牌的时间 32 | local interval = now - lastTime 33 | if interval > 0 then 34 | -- 当前令牌数量+距离上次发放令牌的时间(秒)*发放令牌速率 35 | local newTokens = currentTokens + interval * rate 36 | if newTokens > capacity then 37 | newTokens = capacity 38 | end 39 | currentTokens = newTokens 40 | redis.call("hmset", KEYS[1], "currentTokens", newTokens, "lastTime", now) 41 | end 42 | 43 | -- 如果没有令牌,请求失败 44 | if currentTokens == 0 then 45 | return 0 46 | end 47 | -- 果有令牌,当前令牌-1,请求成功 48 | redis.call("hincrby", KEYS[1], "currentTokens", -1) 49 | redis.call("expire", KEYS[1], capacity / rate) 50 | return 1 51 | ` 52 | 53 | var limiter *TokenBucketLimiter 54 | 55 | func InitLimiter() { 56 | limiter = &TokenBucketLimiter{ 57 | capacity: 10, 58 | rate: 10, 59 | client: rc.RedisClient, 60 | script: redis.NewScript(tokenBucketLimiterTryAcquireRedisScript), 61 | } 62 | } 63 | 64 | // TokenBucketLimiter 令牌桶限流器 65 | type TokenBucketLimiter struct { 66 | capacity int // 容量 67 | rate int // 发放令牌速率/秒 68 | client *redis.Client // Redis客户端 69 | script *redis.Script // TryAcquire脚本 70 | } 71 | 72 | func (l *TokenBucketLimiter) TryAcquire(ctx context.Context, resource string) error { 73 | // 当前时间 74 | now := time.Now().Unix() 75 | success, err := l.script.Run(ctx, l.client, []string{resource}, l.capacity, l.rate, now).Bool() 76 | if err != nil { 77 | return err 78 | } 79 | // 若到达窗口请求上限,请求失败 80 | if !success { 81 | return errors.New("bucket script failed") 82 | } 83 | return nil 84 | } 85 | 86 | // LimiterMiddleware 封装为中间件 87 | func LimiterMiddleware() app.HandlerFunc { 88 | return func(ctx context.Context, c *app.RequestContext) { 89 | 90 | err := limiter.TryAcquire(context.Background(), "currentTokens") 91 | if err != nil { 92 | c.AbortWithMsg("too many requests, server traffic limiting", 1) 93 | } 94 | c.Next(ctx) 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /middleware/rc/client.go: -------------------------------------------------------------------------------- 1 | package rc 2 | 3 | import "github.com/go-redis/redis/v8" 4 | 5 | var RedisClient *redis.Client 6 | 7 | func init() { 8 | RedisClient = redis.NewClient(&redis.Options{ 9 | Addr: "127.0.0.1:6379", 10 | Password: "", // no password set 11 | DB: 0, // use default DB 12 | }) 13 | } 14 | -------------------------------------------------------------------------------- /router.go: -------------------------------------------------------------------------------- 1 | // Code generated by hertz generator. 2 | 3 | package main 4 | 5 | import ( 6 | "dousheng_server/biz/handler" 7 | "dousheng_server/conf" 8 | "dousheng_server/middleware" 9 | "github.com/cloudwego/hertz/pkg/app/server" 10 | ) 11 | 12 | // customizeRegister registers customize routers. 13 | func customizedRegister(r *server.Hertz) { 14 | // 静态资源映射 15 | r.Static("/static/", conf.Conf.StaticConfig.Reflect) 16 | 17 | dy := r.Group("/douyin") 18 | auth := r.Group("/douyin") 19 | auth.Use(middleware.JwtMiddleware.MiddlewareFunc()) 20 | 21 | // 基础接口 22 | dy.GET("/feed/", handler.Feed) 23 | dy.POST("/user/register/", handler.Register) 24 | dy.POST("/user/login/", handler.CheckUser) 25 | auth.GET("/user/", handler.Info) 26 | auth.POST("/publish/action/", handler.Publish) 27 | auth.GET("/publish/list/", handler.VideoList) 28 | 29 | // 互动接口 30 | auth.POST("/favorite/action/", handler.VideoLike) 31 | auth.GET("/favorite/list/", handler.FavoriteList) 32 | auth.POST("/comment/action/", handler.CommentAction) 33 | auth.GET("/comment/list/", handler.GetComment) 34 | 35 | // 社交接口 36 | auth.POST("/relation/action/", handler.Follow) 37 | auth.GET("/relation/follow/list/", handler.FollowList) 38 | auth.GET("/relation/follower/list/", handler.FollowerList) 39 | auth.GET("/relation/friend/list/", handler.FriendList) 40 | auth.POST("/message/action/", handler.SendMessage) 41 | auth.GET("/message/chat/", handler.MessageList) 42 | } 43 | -------------------------------------------------------------------------------- /router_gen.go: -------------------------------------------------------------------------------- 1 | // Code generated by hertz generator. DO NOT EDIT. 2 | 3 | package main 4 | 5 | import ( 6 | router "dousheng_server/biz/router" 7 | "github.com/cloudwego/hertz/pkg/app/server" 8 | ) 9 | 10 | // register registers all routers. 11 | func register(r *server.Hertz) { 12 | 13 | router.GeneratedRegister(r) 14 | 15 | customizedRegister(r) 16 | } 17 | -------------------------------------------------------------------------------- /rpc/usercenter.go: -------------------------------------------------------------------------------- 1 | // Package rpc 2 | // 封装与service的请求与返回 3 | package rpc 4 | 5 | import ( 6 | "context" 7 | "dousheng_server/conf" 8 | "dousheng_server/user_service/kitex_gen" 9 | "dousheng_server/user_service/kitex_gen/usercenter" 10 | "errors" 11 | "github.com/cloudwego/kitex/client" 12 | "github.com/kitex-contrib/obs-opentelemetry/tracing" 13 | etcd "github.com/kitex-contrib/registry-etcd" 14 | ) 15 | 16 | var userClient usercenter.Client 17 | 18 | func init() { 19 | // 通过etcd发现服务 20 | r, err := etcd.NewEtcdResolver([]string{conf.Conf.EtcdConfig.Url}) 21 | if err != nil { 22 | panic(err) 23 | } 24 | 25 | userClient, err = usercenter.NewClient( 26 | "userservice", 27 | client.WithResolver(r), 28 | client.WithSuite(tracing.NewClientSuite())) 29 | if err != nil { 30 | panic(err) 31 | } 32 | } 33 | 34 | type UserInfo struct { 35 | UUID int64 `gorm:"primaryKey" json:"id"` 36 | UserName string `json:"name"` 37 | FollowCount int64 `json:"follow_count"` 38 | FollowerCount int64 `json:"follower_count"` 39 | IsFollow bool `json:"is_follow"` 40 | Avatar string `json:"avatar"` 41 | BackgroundImage string `json:"background_image"` 42 | Signature string `json:"signature"` 43 | TotalFavorited int64 `json:"total_favorited"` 44 | WorkCount int64 `json:"work_count"` 45 | FavoriteCount int64 `json:"favorite_count"` 46 | } 47 | type Message struct { 48 | // UserId 关注了 FollowID 49 | Id int64 `json:"id"` 50 | ToUserId int64 `json:"to_user_id"` 51 | FromUserId int64 `json:"from_user_id"` 52 | Messages string `json:"content"` 53 | CreatedAt int64 `json:"create_time"` 54 | } 55 | type Friend struct { 56 | Message string `json:"message"` 57 | MsgType int64 `json:"msgType"` 58 | *UserInfo 59 | } 60 | 61 | // Register . 62 | func Register(username, password string) error { 63 | req := kitex_gen.RegisterRequest{ 64 | Username: username, 65 | Password: password, 66 | } 67 | resp, err := userClient.Register(context.Background(), &req) 68 | if err != nil { 69 | return err 70 | } 71 | if resp.StatusCode != 0 { 72 | return errors.New("wrong in userClient.Register()") 73 | } 74 | return nil 75 | } 76 | 77 | // LoginByPassword . 78 | func LoginByPassword(username, password string) (int64, error) { 79 | req := kitex_gen.LoginRequest{ 80 | Username: username, 81 | Password: password, 82 | } 83 | resp, err := userClient.Login(context.Background(), &req) 84 | if err != nil { 85 | return 0, err 86 | } 87 | return resp.UserId, nil 88 | } 89 | 90 | // GetUserInfo . 91 | func GetUserInfo(tokenId, userId int64) (*UserInfo, error) { 92 | req := kitex_gen.GetInfoRequest{Uuid: userId} 93 | resp, err := userClient.GetInfo(context.Background(), &req) 94 | if err != nil { 95 | return nil, err 96 | } 97 | isFollowed := false 98 | // 没登陆的用户 99 | if tokenId != 0 { 100 | isFollowed, err = IsFollowed(tokenId, userId) 101 | if err != nil { 102 | return nil, err 103 | } 104 | } 105 | totalFavorited, err := BePraisedCounts(userId) 106 | if err != nil { 107 | return nil, err 108 | } 109 | workCount, err := WorkCounts(userId) 110 | if err != nil { 111 | return nil, err 112 | } 113 | favoriteCount, err := FavouriteCounts(userId) 114 | if err != nil { 115 | return nil, err 116 | } 117 | userInfo := UserInfo{ 118 | UUID: resp.User.Id, 119 | UserName: resp.User.Name, 120 | FollowCount: resp.User.FollowCount, 121 | FollowerCount: resp.User.FollowerCount, 122 | IsFollow: isFollowed, 123 | Avatar: "http://192.168.101.112:8080/static/covers/img.png", 124 | BackgroundImage: "http://192.168.101.112:8080/static/covers/img.png", 125 | Signature: "个人简介为空", 126 | TotalFavorited: totalFavorited, 127 | WorkCount: workCount, 128 | FavoriteCount: favoriteCount, 129 | } 130 | return &userInfo, nil 131 | } 132 | 133 | // Follow 关注 134 | func Follow(userId, followId int64) error { 135 | req := kitex_gen.FollowRequest{ 136 | UserId: userId, 137 | FollowId: followId, 138 | } 139 | _, err := userClient.Follow(context.Background(), &req) 140 | return err 141 | } 142 | 143 | // CancelFollow 取消关注 144 | func CancelFollow(userId, followId int64) error { 145 | req := kitex_gen.FollowRequest{ 146 | UserId: userId, 147 | FollowId: followId, 148 | } 149 | _, err := userClient.CancelFollow(context.Background(), &req) 150 | return err 151 | } 152 | 153 | // FollowList 关注列表 154 | func FollowList(userId int64) ([]UserInfo, error) { 155 | var res []UserInfo 156 | req := kitex_gen.GetInfoRequest{Uuid: userId} 157 | resp, err := userClient.FollowList(context.Background(), &req) 158 | if err != nil { 159 | return nil, err 160 | } 161 | for _, item := range resp.Followers { 162 | userInfo, err := GetUserInfo(userId, item.FollowId) 163 | if err != nil { 164 | return nil, err 165 | } 166 | //is, err := query.JudgeFollow(userId, userInfo.UUID) 167 | //关注列表里的人肯定关注了,所以不用判断了 168 | if err != nil { 169 | return nil, err 170 | } 171 | res = append(res, *userInfo) 172 | } 173 | return res, nil 174 | } 175 | 176 | // FollowerList 粉丝列表 177 | func FollowerList(userId int64) ([]UserInfo, error) { 178 | var res []UserInfo 179 | req := kitex_gen.GetInfoRequest{Uuid: userId} 180 | resp, err := userClient.FollowerList(context.Background(), &req) 181 | if err != nil { 182 | return nil, err 183 | } 184 | for _, item := range resp.Followers { 185 | userInfo, err := GetUserInfo(userId, item.UserId) 186 | if err != nil { 187 | return nil, err 188 | } 189 | if err != nil { 190 | return nil, err 191 | } 192 | res = append(res, *userInfo) 193 | } 194 | return res, nil 195 | } 196 | 197 | // FriendList 好友列表 198 | func FriendList(userId int64) ([]Friend, error) { 199 | var res []Friend 200 | var msg Message 201 | var msgList []Message 202 | req := kitex_gen.GetInfoRequest{Uuid: userId} 203 | resp, err := userClient.FriendList(context.Background(), &req) 204 | if err != nil { 205 | return nil, err 206 | } 207 | if resp == nil { 208 | return nil, err 209 | } 210 | for _, item := range resp.Followers { 211 | userInfo, err := GetUserInfo(userId, item.FollowId) 212 | if err != nil { 213 | return nil, err 214 | } 215 | //如果关系表userInfo中的选取的id等于传进来的userId就说明好友应该获取另一个id 216 | if userId == userInfo.UUID { 217 | userInfo, err = GetUserInfo(userId, item.UserId) 218 | if err != nil { 219 | return nil, err 220 | } 221 | } 222 | msgList, err = MessageList(userId, userInfo.UUID, 0) 223 | if err != nil { 224 | return nil, err 225 | } 226 | var msgType int64 227 | msgType = 0 228 | content := "" 229 | if msgList != nil { 230 | msg = msgList[len(msgList)-1] 231 | if msg.FromUserId == userId { 232 | msgType = 1 233 | } 234 | content = msg.Messages 235 | } 236 | res = append(res, Friend{ 237 | UserInfo: userInfo, 238 | Message: content, 239 | MsgType: msgType, 240 | }) 241 | } 242 | return res, nil 243 | } 244 | 245 | // IsFollowed 是否关注 246 | func IsFollowed(userId, followId int64) (bool, error) { 247 | req := kitex_gen.FollowRequest{UserId: userId, FollowId: followId} 248 | resp, err := userClient.JudgeFollow(context.Background(), &req) 249 | if err != nil { 250 | return false, err 251 | } 252 | return resp.Is, nil 253 | } 254 | 255 | // 发送消息 256 | func SendMessage(fromUserId, ToUserId int64, message string) error { 257 | req := kitex_gen.SendMessageRequest{ 258 | UserId: fromUserId, 259 | ToId: ToUserId, 260 | Message: message, 261 | } 262 | _, err := userClient.SendMessage(context.Background(), &req) 263 | if err != nil { 264 | return err 265 | } 266 | return nil 267 | } 268 | 269 | // 消息列表 270 | func MessageList(fromUserId, ToUserId, lastTime int64) ([]Message, error) { 271 | var messageList []Message 272 | req := kitex_gen.MessageListRequest{ 273 | UserId: fromUserId, 274 | ToId: ToUserId, 275 | LastTime: lastTime, 276 | } 277 | resp, err := userClient.MessageList(context.Background(), &req) 278 | if err != nil { 279 | return nil, err 280 | } 281 | if resp == nil || len(resp.MessageList) == 0 { 282 | return nil, err 283 | } 284 | for _, item := range resp.MessageList { 285 | messageList = append(messageList, Message{ 286 | Id: item.Id, 287 | FromUserId: item.FromUserId, 288 | ToUserId: item.ToUserId, 289 | Messages: item.Content, 290 | CreatedAt: item.CreateTime, 291 | }) 292 | } 293 | 294 | return messageList, err 295 | } 296 | 297 | // 作品数 298 | func WorkCounts(uuid int64) (int64, error) { 299 | var count int64 300 | req := kitex_gen.GetInfoRequest{Uuid: uuid} 301 | item, err := userClient.WorkCounts(context.Background(), &req) 302 | if err != nil { 303 | return 0, err 304 | } 305 | if item != nil { 306 | count = item.Counts 307 | } 308 | return count, err 309 | } 310 | 311 | // 喜欢数 312 | func FavouriteCounts(uuid int64) (int64, error) { 313 | var count int64 314 | req := kitex_gen.GetInfoRequest{Uuid: uuid} 315 | item, err := userClient.FavouriteCounts(context.Background(), &req) 316 | if err != nil { 317 | return 0, err 318 | } 319 | if item != nil { 320 | count = item.Counts 321 | } 322 | return count, err 323 | } 324 | 325 | // 获赞数 326 | func BePraisedCounts(uuid int64) (int64, error) { 327 | var count int64 328 | req := kitex_gen.GetInfoRequest{Uuid: uuid} 329 | item, err := userClient.BePraisedCounts(context.Background(), &req) 330 | if err != nil { 331 | return 0, err 332 | } 333 | if item != nil { 334 | count = item.Counts 335 | } 336 | return count, err 337 | } 338 | -------------------------------------------------------------------------------- /rpc/videocenter.go: -------------------------------------------------------------------------------- 1 | package rpc 2 | 3 | import ( 4 | "context" 5 | "dousheng_server/conf" 6 | "dousheng_server/video_service/dal/model" 7 | "dousheng_server/video_service/kitex_gen" 8 | "dousheng_server/video_service/kitex_gen/videocenter" 9 | "github.com/cloudwego/kitex/client" 10 | "github.com/kitex-contrib/obs-opentelemetry/tracing" 11 | etcd "github.com/kitex-contrib/registry-etcd" 12 | "time" 13 | ) 14 | 15 | var videoClient videocenter.Client 16 | 17 | func init() { 18 | // 通过etcd发现服务 19 | r, err := etcd.NewEtcdResolver([]string{conf.Conf.EtcdConfig.Url}) 20 | if err != nil { 21 | panic(err) 22 | } 23 | 24 | videoClient, err = videocenter.NewClient( 25 | "videoservice", 26 | client.WithResolver(r), 27 | client.WithSuite(tracing.NewClientSuite())) 28 | if err != nil { 29 | panic(err) 30 | } 31 | } 32 | 33 | // VideoWithUser 将用户信息中的user_id替换为user 34 | type VideoWithUser struct { 35 | UUID int64 `json:"id"` 36 | UserInfo UserInfo `json:"author"` 37 | PlayURL string `json:"play_url"` 38 | CoverURL string `json:"cover_url"` 39 | FavoriteCount int64 `json:"favorite_count"` 40 | CommentCount int64 `json:"comment_count"` 41 | Title string `json:"title"` 42 | IsFavorite bool `json:"is_favorite"` 43 | CreatedAt time.Time 44 | } 45 | 46 | // CommentWithUser 将用户信息中的user_id替换为user 47 | type CommentWithUser struct { 48 | UUID int64 `json:"id"` 49 | UserInfo UserInfo `json:"user"` 50 | Content string `json:"content"` 51 | CreateDate string `json:"createDate"` 52 | } 53 | 54 | // PublishVideo . 55 | func PublishVideo(video *model.Video) (int64, error) { 56 | req := kitex_gen.PublishRequest{ 57 | UserId: video.UserID, 58 | PlayUrl: video.PlayURL, 59 | CoverUrl: video.CoverURL, 60 | Title: video.Title, 61 | } 62 | resp, err := videoClient.Publish(context.Background(), &req) 63 | if err != nil { 64 | return 0, err 65 | } 66 | return resp.Uuid, nil 67 | } 68 | 69 | // DeleteVideo . 70 | func DeleteVideo(uuid int64) error { 71 | req := kitex_gen.DeleteRequest{VideoId: uuid} 72 | _, err := videoClient.Delete(context.Background(), &req) 73 | return err 74 | } 75 | 76 | // Feed 返回视频列表和最早时间戳 77 | func Feed(timeStamp, userId int64) ([]VideoWithUser, int64, error) { 78 | var res []VideoWithUser 79 | timestamp := time.Now().UnixMilli() 80 | 81 | req := kitex_gen.FeedRequest{ 82 | LastTime: timeStamp, 83 | } 84 | resp, err := videoClient.Feed(context.Background(), &req) 85 | if err != nil || resp == nil { 86 | return nil, 0, err 87 | } 88 | // 修饰返回值 89 | for _, item := range resp.Videos { 90 | if item.CreateTime < timestamp { 91 | timestamp = item.CreateTime 92 | } 93 | // 替换用户信息 94 | userInfo, err := GetUserInfo(userId, item.UserId) 95 | if err != nil { 96 | return nil, 0, err 97 | } 98 | // 判断是否点过赞 99 | isFavorite, err := IsFavorite(userId, item.Uuid) 100 | if err != nil { 101 | return nil, 0, err 102 | } 103 | res = append(res, VideoWithUser{ 104 | UUID: item.Uuid, 105 | UserInfo: *userInfo, 106 | PlayURL: item.PlayUrl, 107 | CoverURL: item.CoverUrl, 108 | FavoriteCount: item.FavoriteCount, 109 | CommentCount: item.CommentCount, 110 | Title: item.Title, 111 | IsFavorite: isFavorite, 112 | }) 113 | } 114 | return res, timestamp, nil 115 | } 116 | 117 | // VideoList . 118 | func VideoList(userId int64) ([]VideoWithUser, error) { 119 | var res []VideoWithUser 120 | req := kitex_gen.VideoListRequest{UserId: userId} 121 | resp, err := videoClient.VideoList(context.Background(), &req) 122 | if err != nil || resp == nil { 123 | return nil, err 124 | } 125 | // 修饰返回值 126 | for _, item := range resp.Videos { 127 | // 替换用户信息 128 | // 不能关注自己 129 | userInfo, err := GetUserInfo(0, item.UserId) 130 | if err != nil { 131 | return nil, err 132 | } 133 | res = append(res, VideoWithUser{ 134 | UUID: item.Uuid, 135 | UserInfo: *userInfo, 136 | PlayURL: item.PlayUrl, 137 | CoverURL: item.CoverUrl, 138 | FavoriteCount: item.FavoriteCount, 139 | CommentCount: item.CommentCount, 140 | Title: item.Title, 141 | }) 142 | } 143 | return res, nil 144 | } 145 | 146 | // LikeVideo . 147 | func LikeVideo(userId, videoId int64, actionType int32) error { 148 | req := kitex_gen.LikeRequest{ 149 | UserId: userId, 150 | VideoId: videoId, 151 | ActionType: actionType, 152 | } 153 | _, err := videoClient.Like(context.Background(), &req) 154 | return err 155 | } 156 | 157 | // FavoriteVideoList . 158 | func FavoriteVideoList(tokenId, userId int64) ([]VideoWithUser, error) { 159 | var res []VideoWithUser 160 | req := kitex_gen.GetVideoRequest{Uuid: userId} 161 | resp, err := videoClient.GetFavoriteVideo(context.Background(), &req) 162 | if err != nil { 163 | return nil, err 164 | } 165 | if err != nil || resp == nil { 166 | return nil, err 167 | } 168 | // 修饰返回值 169 | for _, item := range resp.Videos { 170 | // 替换用户信息 171 | userInfo, err := GetUserInfo(tokenId, item.UserId) 172 | if err != nil { 173 | return nil, err 174 | } 175 | res = append(res, VideoWithUser{ 176 | UUID: item.Uuid, 177 | UserInfo: *userInfo, 178 | PlayURL: item.PlayUrl, 179 | CoverURL: item.CoverUrl, 180 | FavoriteCount: item.FavoriteCount, 181 | CommentCount: item.CommentCount, 182 | Title: item.Title, 183 | IsFavorite: true, 184 | }) 185 | } 186 | return res, nil 187 | } 188 | 189 | // IsFavorite . 190 | func IsFavorite(userId, videoId int64) (bool, error) { 191 | req := kitex_gen.IsFavoriteRequest{ 192 | UserId: userId, 193 | VideoId: videoId, 194 | } 195 | resp, err := videoClient.IsFavorite(context.Background(), &req) 196 | // 没研究出来为什么 197 | // 使用返回值中有false 198 | // 返回的resp就是nil 199 | if resp.StatusMsg == "true" { 200 | return true, err 201 | } 202 | return false, err 203 | } 204 | 205 | // PostComment . 206 | func PostComment(tokenId int64, comment model.Comment) (*CommentWithUser, error) { 207 | req := kitex_gen.PostCommentRequest{ 208 | UserId: comment.UserId, 209 | VideoId: comment.VideoId, 210 | Content: comment.Content, 211 | } 212 | resp, err := videoClient.PostComment(context.Background(), &req) 213 | if err != nil { 214 | return nil, err 215 | } 216 | // 替换用户信息 217 | userInfo, err := GetUserInfo(tokenId, resp.Comment.UserId) 218 | // 转换参数 219 | return &CommentWithUser{ 220 | UUID: resp.Comment.Uuid, 221 | UserInfo: *userInfo, 222 | Content: resp.Comment.Content, 223 | CreateDate: resp.Comment.CreateDate, 224 | }, nil 225 | } 226 | 227 | // DeleteComment . 228 | func DeleteComment(uuid int64) error { 229 | req := kitex_gen.DeleteCommentRequest{Uuid: uuid} 230 | _, err := videoClient.DeleteComment(context.Background(), &req) 231 | return err 232 | } 233 | 234 | // GetComment . 235 | func GetComment(tokenId, uuid int64) ([]CommentWithUser, error) { 236 | var res []CommentWithUser 237 | req := kitex_gen.GetCommentRequest{VideoId: uuid} 238 | resp, err := videoClient.GetComment(context.Background(), &req) 239 | if err != nil { 240 | return nil, err 241 | } 242 | if resp == nil { 243 | return nil, err 244 | } 245 | for _, item := range resp.Comments { 246 | userInfo, err := GetUserInfo(tokenId, item.UserId) 247 | if err != nil { 248 | return nil, err 249 | } 250 | res = append(res, CommentWithUser{ 251 | UUID: item.Uuid, 252 | UserInfo: *userInfo, 253 | Content: item.Content, 254 | CreateDate: item.CreateDate, 255 | }) 256 | } 257 | return res, nil 258 | } 259 | -------------------------------------------------------------------------------- /snowflake_service/build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | RUN_NAME="snowflake_service" 3 | 4 | mkdir -p output/bin 5 | cp script/* output/ 6 | chmod +x output/bootstrap.sh 7 | 8 | if [ "$IS_SYSTEM_TEST_ENV" != "1" ]; then 9 | go build -o output/bin/${RUN_NAME} 10 | else 11 | go test -c -covermode=set -o output/bin/${RUN_NAME} -coverpkg=./... 12 | fi 13 | 14 | -------------------------------------------------------------------------------- /snowflake_service/handler.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "dousheng_server/snowflake_service/kitex_gen" 6 | "dousheng_server/snowflake_service/snowfalke" 7 | ) 8 | 9 | // SnowflakeImpl implements the last service interface defined in the IDL. 10 | type SnowflakeImpl struct{} 11 | 12 | // NewID implements the SnowflakeImpl interface. 13 | func (s *SnowflakeImpl) NewID(ctx context.Context, req *kitex_gen.NewIDRequest) (resp *kitex_gen.NewIDResponse, err error) { 14 | resp = new(kitex_gen.NewIDResponse) 15 | resp.ID = snowfalke.NewUUID() 16 | return 17 | } 18 | -------------------------------------------------------------------------------- /snowflake_service/idl/snowflake.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package snowflake; 4 | 5 | option go_package="/"; 6 | 7 | message NewIDRequest { 8 | } 9 | 10 | message NewIDResponse { 11 | int64 ID = 1; 12 | } 13 | 14 | service Snowflake { 15 | rpc NewID(NewIDRequest) returns(NewIDResponse); 16 | } -------------------------------------------------------------------------------- /snowflake_service/kitex.yaml: -------------------------------------------------------------------------------- 1 | kitexinfo: 2 | ServiceName: 'snowflake_service' 3 | ToolVersion: 'v0.4.4' 4 | 5 | -------------------------------------------------------------------------------- /snowflake_service/kitex_gen/snowflake.pb.fast.go: -------------------------------------------------------------------------------- 1 | // Code generated by Fastpb v0.0.2. DO NOT EDIT. 2 | 3 | package kitex_gen 4 | 5 | import ( 6 | fmt "fmt" 7 | fastpb "github.com/cloudwego/fastpb" 8 | ) 9 | 10 | var ( 11 | _ = fmt.Errorf 12 | _ = fastpb.Skip 13 | ) 14 | 15 | func (x *NewIDRequest) FastRead(buf []byte, _type int8, number int32) (offset int, err error) { 16 | switch number { 17 | default: 18 | offset, err = fastpb.Skip(buf, _type, number) 19 | if err != nil { 20 | goto SkipFieldError 21 | } 22 | } 23 | return offset, nil 24 | SkipFieldError: 25 | return offset, fmt.Errorf("%T cannot parse invalid wire-format data, error: %s", x, err) 26 | } 27 | 28 | func (x *NewIDResponse) FastRead(buf []byte, _type int8, number int32) (offset int, err error) { 29 | switch number { 30 | case 1: 31 | offset, err = x.fastReadField1(buf, _type) 32 | if err != nil { 33 | goto ReadFieldError 34 | } 35 | default: 36 | offset, err = fastpb.Skip(buf, _type, number) 37 | if err != nil { 38 | goto SkipFieldError 39 | } 40 | } 41 | return offset, nil 42 | SkipFieldError: 43 | return offset, fmt.Errorf("%T cannot parse invalid wire-format data, error: %s", x, err) 44 | ReadFieldError: 45 | return offset, fmt.Errorf("%T read field %d '%s' error: %s", x, number, fieldIDToName_NewIDResponse[number], err) 46 | } 47 | 48 | func (x *NewIDResponse) fastReadField1(buf []byte, _type int8) (offset int, err error) { 49 | x.ID, offset, err = fastpb.ReadInt64(buf, _type) 50 | return offset, err 51 | } 52 | 53 | func (x *NewIDRequest) FastWrite(buf []byte) (offset int) { 54 | if x == nil { 55 | return offset 56 | } 57 | return offset 58 | } 59 | 60 | func (x *NewIDResponse) FastWrite(buf []byte) (offset int) { 61 | if x == nil { 62 | return offset 63 | } 64 | offset += x.fastWriteField1(buf[offset:]) 65 | return offset 66 | } 67 | 68 | func (x *NewIDResponse) fastWriteField1(buf []byte) (offset int) { 69 | if x.ID == 0 { 70 | return offset 71 | } 72 | offset += fastpb.WriteInt64(buf[offset:], 1, x.ID) 73 | return offset 74 | } 75 | 76 | func (x *NewIDRequest) Size() (n int) { 77 | if x == nil { 78 | return n 79 | } 80 | return n 81 | } 82 | 83 | func (x *NewIDResponse) Size() (n int) { 84 | if x == nil { 85 | return n 86 | } 87 | n += x.sizeField1() 88 | return n 89 | } 90 | 91 | func (x *NewIDResponse) sizeField1() (n int) { 92 | if x.ID == 0 { 93 | return n 94 | } 95 | n += fastpb.SizeInt64(1, x.ID) 96 | return n 97 | } 98 | 99 | var fieldIDToName_NewIDRequest = map[int32]string{} 100 | 101 | var fieldIDToName_NewIDResponse = map[int32]string{ 102 | 1: "ID", 103 | } 104 | -------------------------------------------------------------------------------- /snowflake_service/kitex_gen/snowflake.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-go. DO NOT EDIT. 2 | // versions: 3 | // protoc-gen-go v1.28.1 4 | // protoc v3.21.11 5 | // source: idl/snowflake.proto 6 | 7 | package kitex_gen 8 | 9 | import ( 10 | context "context" 11 | protoreflect "google.golang.org/protobuf/reflect/protoreflect" 12 | protoimpl "google.golang.org/protobuf/runtime/protoimpl" 13 | reflect "reflect" 14 | sync "sync" 15 | ) 16 | 17 | const ( 18 | // Verify that this generated code is sufficiently up-to-date. 19 | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) 20 | // Verify that runtime/protoimpl is sufficiently up-to-date. 21 | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) 22 | ) 23 | 24 | type NewIDRequest struct { 25 | state protoimpl.MessageState 26 | sizeCache protoimpl.SizeCache 27 | unknownFields protoimpl.UnknownFields 28 | } 29 | 30 | func (x *NewIDRequest) Reset() { 31 | *x = NewIDRequest{} 32 | if protoimpl.UnsafeEnabled { 33 | mi := &file_idl_snowflake_proto_msgTypes[0] 34 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 35 | ms.StoreMessageInfo(mi) 36 | } 37 | } 38 | 39 | func (x *NewIDRequest) String() string { 40 | return protoimpl.X.MessageStringOf(x) 41 | } 42 | 43 | func (*NewIDRequest) ProtoMessage() {} 44 | 45 | func (x *NewIDRequest) ProtoReflect() protoreflect.Message { 46 | mi := &file_idl_snowflake_proto_msgTypes[0] 47 | if protoimpl.UnsafeEnabled && x != nil { 48 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 49 | if ms.LoadMessageInfo() == nil { 50 | ms.StoreMessageInfo(mi) 51 | } 52 | return ms 53 | } 54 | return mi.MessageOf(x) 55 | } 56 | 57 | // Deprecated: Use NewIDRequest.ProtoReflect.Descriptor instead. 58 | func (*NewIDRequest) Descriptor() ([]byte, []int) { 59 | return file_idl_snowflake_proto_rawDescGZIP(), []int{0} 60 | } 61 | 62 | type NewIDResponse struct { 63 | state protoimpl.MessageState 64 | sizeCache protoimpl.SizeCache 65 | unknownFields protoimpl.UnknownFields 66 | 67 | ID int64 `protobuf:"varint,1,opt,name=ID,proto3" json:"ID,omitempty"` 68 | } 69 | 70 | func (x *NewIDResponse) Reset() { 71 | *x = NewIDResponse{} 72 | if protoimpl.UnsafeEnabled { 73 | mi := &file_idl_snowflake_proto_msgTypes[1] 74 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 75 | ms.StoreMessageInfo(mi) 76 | } 77 | } 78 | 79 | func (x *NewIDResponse) String() string { 80 | return protoimpl.X.MessageStringOf(x) 81 | } 82 | 83 | func (*NewIDResponse) ProtoMessage() {} 84 | 85 | func (x *NewIDResponse) ProtoReflect() protoreflect.Message { 86 | mi := &file_idl_snowflake_proto_msgTypes[1] 87 | if protoimpl.UnsafeEnabled && x != nil { 88 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 89 | if ms.LoadMessageInfo() == nil { 90 | ms.StoreMessageInfo(mi) 91 | } 92 | return ms 93 | } 94 | return mi.MessageOf(x) 95 | } 96 | 97 | // Deprecated: Use NewIDResponse.ProtoReflect.Descriptor instead. 98 | func (*NewIDResponse) Descriptor() ([]byte, []int) { 99 | return file_idl_snowflake_proto_rawDescGZIP(), []int{1} 100 | } 101 | 102 | func (x *NewIDResponse) GetID() int64 { 103 | if x != nil { 104 | return x.ID 105 | } 106 | return 0 107 | } 108 | 109 | var File_idl_snowflake_proto protoreflect.FileDescriptor 110 | 111 | var file_idl_snowflake_proto_rawDesc = []byte{ 112 | 0x0a, 0x13, 0x69, 0x64, 0x6c, 0x2f, 0x73, 0x6e, 0x6f, 0x77, 0x66, 0x6c, 0x61, 0x6b, 0x65, 0x2e, 113 | 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x09, 0x73, 0x6e, 0x6f, 0x77, 0x66, 0x6c, 0x61, 0x6b, 0x65, 114 | 0x22, 0x0e, 0x0a, 0x0c, 0x4e, 0x65, 0x77, 0x49, 0x44, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 115 | 0x22, 0x1f, 0x0a, 0x0d, 0x4e, 0x65, 0x77, 0x49, 0x44, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 116 | 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x49, 117 | 0x44, 0x32, 0x47, 0x0a, 0x09, 0x53, 0x6e, 0x6f, 0x77, 0x66, 0x6c, 0x61, 0x6b, 0x65, 0x12, 0x3a, 118 | 0x0a, 0x05, 0x4e, 0x65, 0x77, 0x49, 0x44, 0x12, 0x17, 0x2e, 0x73, 0x6e, 0x6f, 0x77, 0x66, 0x6c, 119 | 0x61, 0x6b, 0x65, 0x2e, 0x4e, 0x65, 0x77, 0x49, 0x44, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 120 | 0x1a, 0x18, 0x2e, 0x73, 0x6e, 0x6f, 0x77, 0x66, 0x6c, 0x61, 0x6b, 0x65, 0x2e, 0x4e, 0x65, 0x77, 121 | 0x49, 0x44, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x2d, 0x5a, 0x2b, 0x64, 0x6f, 122 | 0x75, 0x73, 0x68, 0x65, 0x6e, 0x67, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, 0x73, 0x6e, 123 | 0x6f, 0x77, 0x66, 0x6c, 0x61, 0x6b, 0x65, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2f, 124 | 0x6b, 0x69, 0x74, 0x65, 0x78, 0x5f, 0x67, 0x65, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 125 | 0x33, 126 | } 127 | 128 | var ( 129 | file_idl_snowflake_proto_rawDescOnce sync.Once 130 | file_idl_snowflake_proto_rawDescData = file_idl_snowflake_proto_rawDesc 131 | ) 132 | 133 | func file_idl_snowflake_proto_rawDescGZIP() []byte { 134 | file_idl_snowflake_proto_rawDescOnce.Do(func() { 135 | file_idl_snowflake_proto_rawDescData = protoimpl.X.CompressGZIP(file_idl_snowflake_proto_rawDescData) 136 | }) 137 | return file_idl_snowflake_proto_rawDescData 138 | } 139 | 140 | var file_idl_snowflake_proto_msgTypes = make([]protoimpl.MessageInfo, 2) 141 | var file_idl_snowflake_proto_goTypes = []interface{}{ 142 | (*NewIDRequest)(nil), // 0: snowflake.NewIDRequest 143 | (*NewIDResponse)(nil), // 1: snowflake.NewIDResponse 144 | } 145 | var file_idl_snowflake_proto_depIdxs = []int32{ 146 | 0, // 0: snowflake.Snowflake.NewID:input_type -> snowflake.NewIDRequest 147 | 1, // 1: snowflake.Snowflake.NewID:output_type -> snowflake.NewIDResponse 148 | 1, // [1:2] is the sub-list for method output_type 149 | 0, // [0:1] is the sub-list for method input_type 150 | 0, // [0:0] is the sub-list for extension type_name 151 | 0, // [0:0] is the sub-list for extension extendee 152 | 0, // [0:0] is the sub-list for field type_name 153 | } 154 | 155 | func init() { file_idl_snowflake_proto_init() } 156 | func file_idl_snowflake_proto_init() { 157 | if File_idl_snowflake_proto != nil { 158 | return 159 | } 160 | if !protoimpl.UnsafeEnabled { 161 | file_idl_snowflake_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { 162 | switch v := v.(*NewIDRequest); i { 163 | case 0: 164 | return &v.state 165 | case 1: 166 | return &v.sizeCache 167 | case 2: 168 | return &v.unknownFields 169 | default: 170 | return nil 171 | } 172 | } 173 | file_idl_snowflake_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { 174 | switch v := v.(*NewIDResponse); i { 175 | case 0: 176 | return &v.state 177 | case 1: 178 | return &v.sizeCache 179 | case 2: 180 | return &v.unknownFields 181 | default: 182 | return nil 183 | } 184 | } 185 | } 186 | type x struct{} 187 | out := protoimpl.TypeBuilder{ 188 | File: protoimpl.DescBuilder{ 189 | GoPackagePath: reflect.TypeOf(x{}).PkgPath(), 190 | RawDescriptor: file_idl_snowflake_proto_rawDesc, 191 | NumEnums: 0, 192 | NumMessages: 2, 193 | NumExtensions: 0, 194 | NumServices: 1, 195 | }, 196 | GoTypes: file_idl_snowflake_proto_goTypes, 197 | DependencyIndexes: file_idl_snowflake_proto_depIdxs, 198 | MessageInfos: file_idl_snowflake_proto_msgTypes, 199 | }.Build() 200 | File_idl_snowflake_proto = out.File 201 | file_idl_snowflake_proto_rawDesc = nil 202 | file_idl_snowflake_proto_goTypes = nil 203 | file_idl_snowflake_proto_depIdxs = nil 204 | } 205 | 206 | var _ context.Context 207 | 208 | // Code generated by Kitex v0.4.4. DO NOT EDIT. 209 | 210 | type Snowflake interface { 211 | NewID(ctx context.Context, req *NewIDRequest) (res *NewIDResponse, err error) 212 | } 213 | -------------------------------------------------------------------------------- /snowflake_service/kitex_gen/snowflake/client.go: -------------------------------------------------------------------------------- 1 | // Code generated by Kitex v0.4.4. DO NOT EDIT. 2 | 3 | package snowflake 4 | 5 | import ( 6 | "context" 7 | kitex_gen "dousheng_server/snowflake_service/kitex_gen" 8 | client "github.com/cloudwego/kitex/client" 9 | callopt "github.com/cloudwego/kitex/client/callopt" 10 | ) 11 | 12 | // Client is designed to provide IDL-compatible methods with call-option parameter for kitex framework. 13 | type Client interface { 14 | NewID(ctx context.Context, Req *kitex_gen.NewIDRequest, callOptions ...callopt.Option) (r *kitex_gen.NewIDResponse, err error) 15 | } 16 | 17 | // NewClient creates a client for the service defined in IDL. 18 | func NewClient(destService string, opts ...client.Option) (Client, error) { 19 | var options []client.Option 20 | options = append(options, client.WithDestService(destService)) 21 | 22 | options = append(options, opts...) 23 | 24 | kc, err := client.NewClient(serviceInfo(), options...) 25 | if err != nil { 26 | return nil, err 27 | } 28 | return &kSnowflakeClient{ 29 | kClient: newServiceClient(kc), 30 | }, nil 31 | } 32 | 33 | // MustNewClient creates a client for the service defined in IDL. It panics if any error occurs. 34 | func MustNewClient(destService string, opts ...client.Option) Client { 35 | kc, err := NewClient(destService, opts...) 36 | if err != nil { 37 | panic(err) 38 | } 39 | return kc 40 | } 41 | 42 | type kSnowflakeClient struct { 43 | *kClient 44 | } 45 | 46 | func (p *kSnowflakeClient) NewID(ctx context.Context, Req *kitex_gen.NewIDRequest, callOptions ...callopt.Option) (r *kitex_gen.NewIDResponse, err error) { 47 | ctx = client.NewCtxWithCallOptions(ctx, callOptions) 48 | return p.kClient.NewID(ctx, Req) 49 | } 50 | -------------------------------------------------------------------------------- /snowflake_service/kitex_gen/snowflake/invoker.go: -------------------------------------------------------------------------------- 1 | // Code generated by Kitex v0.4.4. DO NOT EDIT. 2 | 3 | package snowflake 4 | 5 | import ( 6 | kitex_gen "dousheng_server/snowflake_service/kitex_gen" 7 | server "github.com/cloudwego/kitex/server" 8 | ) 9 | 10 | // NewInvoker creates a server.Invoker with the given handler and options. 11 | func NewInvoker(handler kitex_gen.Snowflake, opts ...server.Option) server.Invoker { 12 | var options []server.Option 13 | 14 | options = append(options, opts...) 15 | 16 | s := server.NewInvoker(options...) 17 | if err := s.RegisterService(serviceInfo(), handler); err != nil { 18 | panic(err) 19 | } 20 | if err := s.Init(); err != nil { 21 | panic(err) 22 | } 23 | return s 24 | } 25 | -------------------------------------------------------------------------------- /snowflake_service/kitex_gen/snowflake/server.go: -------------------------------------------------------------------------------- 1 | // Code generated by Kitex v0.4.4. DO NOT EDIT. 2 | package snowflake 3 | 4 | import ( 5 | kitex_gen "dousheng_server/snowflake_service/kitex_gen" 6 | server "github.com/cloudwego/kitex/server" 7 | ) 8 | 9 | // NewServer creates a server.Server with the given handler and options. 10 | func NewServer(handler kitex_gen.Snowflake, opts ...server.Option) server.Server { 11 | var options []server.Option 12 | 13 | options = append(options, opts...) 14 | 15 | svr := server.NewServer(options...) 16 | if err := svr.RegisterService(serviceInfo(), handler); err != nil { 17 | panic(err) 18 | } 19 | return svr 20 | } 21 | -------------------------------------------------------------------------------- /snowflake_service/kitex_gen/snowflake/snowflake.go: -------------------------------------------------------------------------------- 1 | // Code generated by Kitex v0.4.4. DO NOT EDIT. 2 | 3 | package snowflake 4 | 5 | import ( 6 | "context" 7 | kitex_gen "dousheng_server/snowflake_service/kitex_gen" 8 | "fmt" 9 | client "github.com/cloudwego/kitex/client" 10 | kitex "github.com/cloudwego/kitex/pkg/serviceinfo" 11 | streaming "github.com/cloudwego/kitex/pkg/streaming" 12 | proto "google.golang.org/protobuf/proto" 13 | ) 14 | 15 | func serviceInfo() *kitex.ServiceInfo { 16 | return snowflakeServiceInfo 17 | } 18 | 19 | var snowflakeServiceInfo = NewServiceInfo() 20 | 21 | func NewServiceInfo() *kitex.ServiceInfo { 22 | serviceName := "Snowflake" 23 | handlerType := (*kitex_gen.Snowflake)(nil) 24 | methods := map[string]kitex.MethodInfo{ 25 | "NewID": kitex.NewMethodInfo(newIDHandler, newNewIDArgs, newNewIDResult, false), 26 | } 27 | extra := map[string]interface{}{ 28 | "PackageName": "snowflake", 29 | } 30 | svcInfo := &kitex.ServiceInfo{ 31 | ServiceName: serviceName, 32 | HandlerType: handlerType, 33 | Methods: methods, 34 | PayloadCodec: kitex.Protobuf, 35 | KiteXGenVersion: "v0.4.4", 36 | Extra: extra, 37 | } 38 | return svcInfo 39 | } 40 | 41 | func newIDHandler(ctx context.Context, handler interface{}, arg, result interface{}) error { 42 | switch s := arg.(type) { 43 | case *streaming.Args: 44 | st := s.Stream 45 | req := new(kitex_gen.NewIDRequest) 46 | if err := st.RecvMsg(req); err != nil { 47 | return err 48 | } 49 | resp, err := handler.(kitex_gen.Snowflake).NewID(ctx, req) 50 | if err != nil { 51 | return err 52 | } 53 | if err := st.SendMsg(resp); err != nil { 54 | return err 55 | } 56 | case *NewIDArgs: 57 | success, err := handler.(kitex_gen.Snowflake).NewID(ctx, s.Req) 58 | if err != nil { 59 | return err 60 | } 61 | realResult := result.(*NewIDResult) 62 | realResult.Success = success 63 | } 64 | return nil 65 | } 66 | func newNewIDArgs() interface{} { 67 | return &NewIDArgs{} 68 | } 69 | 70 | func newNewIDResult() interface{} { 71 | return &NewIDResult{} 72 | } 73 | 74 | type NewIDArgs struct { 75 | Req *kitex_gen.NewIDRequest 76 | } 77 | 78 | func (p *NewIDArgs) FastRead(buf []byte, _type int8, number int32) (n int, err error) { 79 | if !p.IsSetReq() { 80 | p.Req = new(kitex_gen.NewIDRequest) 81 | } 82 | return p.Req.FastRead(buf, _type, number) 83 | } 84 | 85 | func (p *NewIDArgs) FastWrite(buf []byte) (n int) { 86 | if !p.IsSetReq() { 87 | return 0 88 | } 89 | return p.Req.FastWrite(buf) 90 | } 91 | 92 | func (p *NewIDArgs) Size() (n int) { 93 | if !p.IsSetReq() { 94 | return 0 95 | } 96 | return p.Req.Size() 97 | } 98 | 99 | func (p *NewIDArgs) Marshal(out []byte) ([]byte, error) { 100 | if !p.IsSetReq() { 101 | return out, fmt.Errorf("No req in NewIDArgs") 102 | } 103 | return proto.Marshal(p.Req) 104 | } 105 | 106 | func (p *NewIDArgs) Unmarshal(in []byte) error { 107 | msg := new(kitex_gen.NewIDRequest) 108 | if err := proto.Unmarshal(in, msg); err != nil { 109 | return err 110 | } 111 | p.Req = msg 112 | return nil 113 | } 114 | 115 | var NewIDArgs_Req_DEFAULT *kitex_gen.NewIDRequest 116 | 117 | func (p *NewIDArgs) GetReq() *kitex_gen.NewIDRequest { 118 | if !p.IsSetReq() { 119 | return NewIDArgs_Req_DEFAULT 120 | } 121 | return p.Req 122 | } 123 | 124 | func (p *NewIDArgs) IsSetReq() bool { 125 | return p.Req != nil 126 | } 127 | 128 | type NewIDResult struct { 129 | Success *kitex_gen.NewIDResponse 130 | } 131 | 132 | var NewIDResult_Success_DEFAULT *kitex_gen.NewIDResponse 133 | 134 | func (p *NewIDResult) FastRead(buf []byte, _type int8, number int32) (n int, err error) { 135 | if !p.IsSetSuccess() { 136 | p.Success = new(kitex_gen.NewIDResponse) 137 | } 138 | return p.Success.FastRead(buf, _type, number) 139 | } 140 | 141 | func (p *NewIDResult) FastWrite(buf []byte) (n int) { 142 | if !p.IsSetSuccess() { 143 | return 0 144 | } 145 | return p.Success.FastWrite(buf) 146 | } 147 | 148 | func (p *NewIDResult) Size() (n int) { 149 | if !p.IsSetSuccess() { 150 | return 0 151 | } 152 | return p.Success.Size() 153 | } 154 | 155 | func (p *NewIDResult) Marshal(out []byte) ([]byte, error) { 156 | if !p.IsSetSuccess() { 157 | return out, fmt.Errorf("No req in NewIDResult") 158 | } 159 | return proto.Marshal(p.Success) 160 | } 161 | 162 | func (p *NewIDResult) Unmarshal(in []byte) error { 163 | msg := new(kitex_gen.NewIDResponse) 164 | if err := proto.Unmarshal(in, msg); err != nil { 165 | return err 166 | } 167 | p.Success = msg 168 | return nil 169 | } 170 | 171 | func (p *NewIDResult) GetSuccess() *kitex_gen.NewIDResponse { 172 | if !p.IsSetSuccess() { 173 | return NewIDResult_Success_DEFAULT 174 | } 175 | return p.Success 176 | } 177 | 178 | func (p *NewIDResult) SetSuccess(x interface{}) { 179 | p.Success = x.(*kitex_gen.NewIDResponse) 180 | } 181 | 182 | func (p *NewIDResult) IsSetSuccess() bool { 183 | return p.Success != nil 184 | } 185 | 186 | type kClient struct { 187 | c client.Client 188 | } 189 | 190 | func newServiceClient(c client.Client) *kClient { 191 | return &kClient{ 192 | c: c, 193 | } 194 | } 195 | 196 | func (p *kClient) NewID(ctx context.Context, Req *kitex_gen.NewIDRequest) (r *kitex_gen.NewIDResponse, err error) { 197 | var _args NewIDArgs 198 | _args.Req = Req 199 | var _result NewIDResult 200 | if err = p.c.Call(ctx, "NewID", &_args, &_result); err != nil { 201 | return 202 | } 203 | return _result.GetSuccess(), nil 204 | } 205 | -------------------------------------------------------------------------------- /snowflake_service/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "dousheng_server/conf" 5 | "dousheng_server/snowflake_service/kitex_gen/snowflake" 6 | "github.com/cloudwego/kitex/pkg/rpcinfo" 7 | "github.com/cloudwego/kitex/server" 8 | kServer "github.com/cloudwego/kitex/server" 9 | prometheus "github.com/kitex-contrib/monitor-prometheus" 10 | etcd "github.com/kitex-contrib/registry-etcd" 11 | "log" 12 | "net" 13 | ) 14 | 15 | func main() { 16 | addr, _ := net.ResolveTCPAddr("tcp", ":8901") 17 | 18 | r, err := etcd.NewEtcdRegistry([]string{conf.Conf.EtcdConfig.Url}) 19 | if err != nil { 20 | log.Fatal(err) 21 | } 22 | svr := snowflake.NewServer(new(SnowflakeImpl), 23 | server.WithServerBasicInfo(&rpcinfo.EndpointBasicInfo{ServiceName: "snowflakeservice"}), 24 | server.WithRegistry(r), 25 | server.WithServiceAddr(addr), 26 | kServer.WithTracer(prometheus.NewServerTracer(":9901", "/metrics"))) 27 | 28 | err = svr.Run() 29 | 30 | if err != nil { 31 | log.Println(err.Error()) 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /snowflake_service/script/bootstrap.sh: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env bash 2 | CURDIR=$(cd $(dirname $0); pwd) 3 | 4 | if [ "X$1" != "X" ]; then 5 | RUNTIME_ROOT=$1 6 | else 7 | RUNTIME_ROOT=${CURDIR} 8 | fi 9 | 10 | export KITEX_RUNTIME_ROOT=$RUNTIME_ROOT 11 | export KITEX_LOG_DIR="$RUNTIME_ROOT/log" 12 | 13 | if [ ! -d "$KITEX_LOG_DIR/app" ]; then 14 | mkdir -p "$KITEX_LOG_DIR/app" 15 | fi 16 | 17 | if [ ! -d "$KITEX_LOG_DIR/rpc" ]; then 18 | mkdir -p "$KITEX_LOG_DIR/rpc" 19 | fi 20 | 21 | exec "$CURDIR/bin/snowflake_service" 22 | 23 | -------------------------------------------------------------------------------- /snowflake_service/snowfalke/id.go: -------------------------------------------------------------------------------- 1 | package snowfalke 2 | 3 | import ( 4 | zaplog "dousheng_server/deploy/log" 5 | "errors" 6 | "sync" 7 | "time" 8 | ) 9 | 10 | const ( 11 | workerBits uint8 = 10 12 | numberBits uint8 = 12 13 | workerMax int64 = -1 ^ (-1 << workerBits) 14 | numberMax int64 = -1 ^ (-1 << numberBits) 15 | timeShift uint8 = workerBits + numberBits 16 | workerShift uint8 = numberBits 17 | startTime int64 = 1525705533000 // 如果在程序跑了一段时间修改了epoch这个值 可能会导致生成相同的ID 18 | ) 19 | 20 | var iDMaker *worker 21 | 22 | func init() { 23 | var err error 24 | workerId, err := NewLeaseMaker().getLease() 25 | iDMaker, err = newWorker(workerId) 26 | if err != nil { 27 | zaplog.ZapLogger.Error("IDMaker Init Error") 28 | panic("IDMaker Init Error") 29 | } 30 | } 31 | 32 | type worker struct { 33 | mu sync.Mutex 34 | timestamp int64 35 | workerId int64 36 | number int64 37 | } 38 | 39 | // NewUUID 通过雪花算法生成UUID 40 | func NewUUID() int64 { 41 | return iDMaker.getId() 42 | } 43 | 44 | func newWorker(workerId int64) (*worker, error) { 45 | if workerId < 0 || workerId > workerMax { 46 | return nil, errors.New("err: worker ID excess of quantity") 47 | } 48 | // 生成一个新节点 49 | return &worker{ 50 | timestamp: 0, 51 | workerId: workerId, 52 | number: 0, 53 | }, nil 54 | } 55 | 56 | func (w *worker) getId() int64 { 57 | w.mu.Lock() 58 | defer w.mu.Unlock() 59 | now := time.Now().UnixNano() / 1e6 60 | if w.timestamp == now { 61 | w.number++ 62 | if w.number > numberMax { 63 | for now <= w.timestamp { 64 | now = time.Now().UnixNano() / 1e6 65 | } 66 | } 67 | } else { 68 | w.number = 0 69 | w.timestamp = now 70 | } 71 | ID := (now-startTime)< ?"+ 152 | " OR from_user_id = ? AND to_user_id = ? AND created_at > ?", 153 | FromId, ToId, nowTime, ToId, FromId, nowTime).Order("created_at").Find(&messageList).Error 154 | return &messageList, err 155 | } 156 | 157 | // 作品数 158 | func WorkCounts(userID int64) (count int64, err error) { 159 | err = GormClient.Model(&video.Video{}).Where("user_id = ?", userID).Count(&count).Error 160 | return 161 | } 162 | 163 | // 喜欢数 164 | func FavouriteCounts(userID int64) (count int64, err error) { 165 | err = GormClient.Model(&video.Favorite{}).Where("user_id = ?", userID).Count(&count).Error 166 | return 167 | } 168 | 169 | // 获赞数 170 | func BePraisedCounts(userID int64) (count int64, err error) { 171 | var resultList []int64 172 | err = GormClient.Model(&video.Video{}).Select("uuid").Where("user_id = ?", userID).Find(&resultList).Error 173 | if err != nil { 174 | return 175 | } 176 | err = GormClient.Model(&video.Favorite{}).Where("video_id IN ?", resultList).Count(&count).Error 177 | return 178 | } 179 | -------------------------------------------------------------------------------- /user_service/handler.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "dousheng_server/user_service/kitex_gen" 6 | "dousheng_server/user_service/service" 7 | "fmt" 8 | ) 9 | 10 | // UserCenterImpl implements the last service interface defined in the IDL. 11 | type UserCenterImpl struct{} 12 | 13 | // Ping implements the UserCenterImpl interface. 14 | func (s *UserCenterImpl) Ping(ctx context.Context, req *kitex_gen.Request) (resp *kitex_gen.Response, err error) { 15 | resp = new(kitex_gen.Response) 16 | fmt.Println("Get Ping Message:", req.Ping) 17 | resp.Pong = "Hello Client" 18 | return 19 | } 20 | 21 | // Register implements the UserCenterImpl interface. 22 | func (s *UserCenterImpl) Register(ctx context.Context, req *kitex_gen.RegisterRequest) (*kitex_gen.BasicResponse, error) { 23 | err := service.UserCenter{}.CreateUser(req.Username, req.Password) 24 | if err != nil { 25 | return &kitex_gen.BasicResponse{ 26 | StatusCode: -1, 27 | StatusMsg: "user create failed", 28 | }, err 29 | } 30 | return &kitex_gen.BasicResponse{ 31 | StatusCode: 0, 32 | StatusMsg: "success", 33 | }, nil 34 | } 35 | 36 | // Login implements the UserCenterImpl interface. 37 | func (s *UserCenterImpl) Login(ctx context.Context, req *kitex_gen.LoginRequest) (resp *kitex_gen.LoginResponse, err error) { 38 | userModel, err := service.UserCenter{}.LoginByPassword(req.Username, req.Password) 39 | 40 | if err != nil { 41 | return &kitex_gen.LoginResponse{ 42 | StatusCode: -1, 43 | StatusMsg: "UserCenter{}.LoginByPassword wrong", 44 | }, err 45 | } 46 | if userModel.UUID == 0 { 47 | return &kitex_gen.LoginResponse{ 48 | StatusCode: -1, 49 | StatusMsg: "failed", 50 | }, nil 51 | } 52 | return &kitex_gen.LoginResponse{ 53 | StatusCode: 0, 54 | StatusMsg: "success", 55 | UserId: userModel.UUID, 56 | }, nil 57 | } 58 | 59 | // GetInfo implements the UserCenterImpl interface. 60 | func (s *UserCenterImpl) GetInfo(ctx context.Context, req *kitex_gen.GetInfoRequest) (*kitex_gen.GetInfoResponse, error) { 61 | userModel, err := service.UserCenter{}.GetInfo(req.Uuid) 62 | if err != nil { 63 | return &kitex_gen.GetInfoResponse{ 64 | StatusCode: -1, 65 | StatusMsg: "get user failed", 66 | }, err 67 | } 68 | user := &kitex_gen.User{ 69 | Id: userModel.UUID, 70 | Name: userModel.Username, 71 | FollowCount: userModel.FollowCount, 72 | FollowerCount: userModel.FollowerCount, 73 | IsFollow: false, 74 | } 75 | return &kitex_gen.GetInfoResponse{ 76 | StatusCode: 0, 77 | StatusMsg: "success", 78 | User: user, 79 | }, nil 80 | } 81 | 82 | // Follow implements the UserCenterImpl interface. 83 | func (s *UserCenterImpl) Follow(ctx context.Context, req *kitex_gen.FollowRequest) (resp *kitex_gen.BasicResponse, err error) { 84 | err = service.UserCenter{}.Follow(req.UserId, req.FollowId) 85 | if err != nil { 86 | resp = &kitex_gen.BasicResponse{ 87 | StatusCode: 1, 88 | StatusMsg: "follow failed err:" + err.Error(), 89 | } 90 | return 91 | } 92 | resp = &kitex_gen.BasicResponse{ 93 | StatusCode: 0, 94 | StatusMsg: "success", 95 | } 96 | return 97 | } 98 | 99 | // CancelFollow implements the UserCenterImpl interface. 100 | func (s *UserCenterImpl) CancelFollow(ctx context.Context, req *kitex_gen.FollowRequest) (resp *kitex_gen.BasicResponse, err error) { 101 | err = service.UserCenter{}.CancelFollow(req.UserId, req.FollowId) 102 | if err != nil { 103 | resp = &kitex_gen.BasicResponse{ 104 | StatusCode: 1, 105 | StatusMsg: "cancel follow failed err:" + err.Error(), 106 | } 107 | return 108 | } 109 | resp = &kitex_gen.BasicResponse{ 110 | StatusCode: 0, 111 | StatusMsg: "success", 112 | } 113 | return 114 | } 115 | 116 | // FollowList implements the UserCenterImpl interface. 117 | func (s *UserCenterImpl) FollowList(ctx context.Context, req *kitex_gen.GetInfoRequest) (*kitex_gen.FollowListResponse, error) { 118 | resp, err := service.UserCenter{}.FollowList(req.Uuid) 119 | if err != nil { 120 | return &kitex_gen.FollowListResponse{ 121 | StatusCode: 1, 122 | StatusMsg: "follow list query failed", 123 | Followers: nil, 124 | }, err 125 | } 126 | return &kitex_gen.FollowListResponse{ 127 | StatusCode: 0, 128 | StatusMsg: "success", 129 | Followers: resp, 130 | }, err 131 | } 132 | 133 | // FollowerList implements the UserCenterImpl interface. 134 | func (s *UserCenterImpl) FollowerList(ctx context.Context, req *kitex_gen.GetInfoRequest) (*kitex_gen.FollowListResponse, error) { 135 | resp, err := service.UserCenter{}.FollowerList(req.Uuid) 136 | if err != nil { 137 | return &kitex_gen.FollowListResponse{ 138 | StatusCode: 1, 139 | StatusMsg: "follower list query failed", 140 | Followers: nil, 141 | }, err 142 | } 143 | return &kitex_gen.FollowListResponse{ 144 | StatusCode: 0, 145 | StatusMsg: "success", 146 | Followers: resp, 147 | }, err 148 | } 149 | 150 | // FriendList implements the UserCenterImpl interface. 151 | func (s *UserCenterImpl) FriendList(ctx context.Context, req *kitex_gen.GetInfoRequest) (*kitex_gen.FollowListResponse, error) { 152 | resp, err := service.UserCenter{}.FriendList(req.Uuid) 153 | if err != nil { 154 | return &kitex_gen.FollowListResponse{ 155 | StatusCode: 1, 156 | StatusMsg: "friend list query failed", 157 | Followers: nil, 158 | }, err 159 | } 160 | return &kitex_gen.FollowListResponse{ 161 | StatusCode: 0, 162 | StatusMsg: "success", 163 | Followers: resp, 164 | }, err 165 | } 166 | 167 | // JudgeFollow implements the UserCenterImpl interface. 168 | func (s *UserCenterImpl) JudgeFollow(ctx context.Context, req *kitex_gen.FollowRequest) (resp *kitex_gen.JudgeFollowResponse, err error) { 169 | var isFollowed bool 170 | isFollowed, err = service.UserCenter{}.JudgeFollow(req.UserId, req.FollowId) 171 | if err != nil { 172 | resp = &kitex_gen.JudgeFollowResponse{ 173 | StatusCode: 1, 174 | StatusMsg: "failed followed err:" + err.Error(), 175 | Is: isFollowed, 176 | } 177 | return 178 | } 179 | resp = &kitex_gen.JudgeFollowResponse{ 180 | StatusCode: 0, 181 | StatusMsg: "success", 182 | Is: isFollowed, 183 | } 184 | return 185 | } 186 | 187 | // SendMessage implements the UserCenterImpl interface. 188 | func (s *UserCenterImpl) SendMessage(ctx context.Context, req *kitex_gen.SendMessageRequest) (resp *kitex_gen.BasicResponse, err error) { 189 | err = service.UserCenter{}.SendMessages(req.UserId, req.ToId, req.Message) 190 | if err != nil { 191 | resp = &kitex_gen.BasicResponse{ 192 | StatusCode: 1, 193 | StatusMsg: "failed send-message err:" + err.Error(), 194 | } 195 | return 196 | } 197 | resp = &kitex_gen.BasicResponse{ 198 | StatusCode: 0, 199 | StatusMsg: "success", 200 | } 201 | return 202 | } 203 | 204 | // MessageList implements the UserCenterImpl interface. 205 | func (s *UserCenterImpl) MessageList(ctx context.Context, req *kitex_gen.MessageListRequest) (resp *kitex_gen.MessageListResponse, err error) { 206 | messageList, err := service.UserCenter{}.MessageList(req.UserId, req.ToId, req.LastTime) 207 | if err != nil { 208 | resp = &kitex_gen.MessageListResponse{ 209 | StatusCode: 1, 210 | StatusMsg: "message list query failed", 211 | MessageList: nil, 212 | } 213 | return 214 | } 215 | resp = &kitex_gen.MessageListResponse{ 216 | StatusCode: 0, 217 | StatusMsg: "success", 218 | MessageList: messageList, 219 | } 220 | return 221 | } 222 | 223 | // WorkCounts implements the UserCenterImpl interface. 224 | func (s *UserCenterImpl) WorkCounts(ctx context.Context, req *kitex_gen.GetInfoRequest) (resp *kitex_gen.CountsResponse, err error) { 225 | counts, err := service.UserCenter{}.WorkCounts(req.Uuid) 226 | if err != nil { 227 | resp = &kitex_gen.CountsResponse{ 228 | StatusCode: -1, 229 | StatusMsg: "work counts query failed" + err.Error(), 230 | Counts: 0, 231 | } 232 | return 233 | } 234 | resp = &kitex_gen.CountsResponse{ 235 | StatusCode: 0, 236 | StatusMsg: "success", 237 | Counts: counts, 238 | } 239 | return 240 | } 241 | 242 | // FavouriteCounts implements the UserCenterImpl interface. 243 | func (s *UserCenterImpl) FavouriteCounts(ctx context.Context, req *kitex_gen.GetInfoRequest) (resp *kitex_gen.CountsResponse, err error) { 244 | counts, err := service.UserCenter{}.FavouriteCounts(req.Uuid) 245 | if err != nil { 246 | resp = &kitex_gen.CountsResponse{ 247 | StatusCode: -1, 248 | StatusMsg: "favourite counts query failed" + err.Error(), 249 | Counts: 0, 250 | } 251 | return 252 | } 253 | resp = &kitex_gen.CountsResponse{ 254 | StatusCode: 0, 255 | StatusMsg: "success", 256 | Counts: counts, 257 | } 258 | return 259 | } 260 | 261 | // BePraisedCounts implements the UserCenterImpl interface. 262 | func (s *UserCenterImpl) BePraisedCounts(ctx context.Context, req *kitex_gen.GetInfoRequest) (resp *kitex_gen.CountsResponse, err error) { 263 | counts, err := service.UserCenter{}.BePraisedCounts(req.Uuid) 264 | if err != nil { 265 | resp = &kitex_gen.CountsResponse{ 266 | StatusCode: -1, 267 | StatusMsg: "be praise counts query failed" + err.Error(), 268 | Counts: 0, 269 | } 270 | return 271 | } 272 | resp = &kitex_gen.CountsResponse{ 273 | StatusCode: 0, 274 | StatusMsg: "success", 275 | Counts: counts, 276 | } 277 | return 278 | } 279 | -------------------------------------------------------------------------------- /user_service/idl/usercenter.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package user; 4 | option go_package="/"; 5 | 6 | message Request { 7 | string ping = 1; 8 | } 9 | 10 | message Response { 11 | string pong = 1; 12 | } 13 | 14 | message BasicResponse { 15 | int32 status_code = 1; // 状态码,0-成功,其他值-失败 16 | string status_msg = 2; // 返回状态描述 17 | } 18 | 19 | message RegisterRequest { 20 | string username = 1; // 注册用户名,最长32个字符 21 | string password = 2; // 密码,最长32个字符 22 | } 23 | 24 | message LoginRequest { 25 | string username = 1; // 登陆用户名 26 | string password = 2; // 密码 27 | } 28 | 29 | message LoginResponse{ 30 | int32 status_code = 1; // 状态码,0-成功,其他值-失败 31 | string status_msg = 2; // 返回状态描述 32 | int64 user_id = 3; // UUID 33 | } 34 | 35 | message GetInfoRequest{ 36 | int64 uuid = 1; 37 | } 38 | 39 | message GetInfoResponse{ 40 | int32 status_code = 1; // 状态码,0-成功,其他值-失败 41 | string status_msg = 2; // 返回状态描述 42 | User user = 3; 43 | } 44 | 45 | message FollowRequest{ 46 | int64 user_id = 1; 47 | int64 follow_id = 2; 48 | } 49 | 50 | message FollowListResponse{ 51 | int32 status_code = 1; // 状态码,0-成功,其他值-失败 52 | string status_msg = 2; // 返回状态描述 53 | repeated Follower followers = 3; 54 | } 55 | 56 | message JudgeFollowResponse{ 57 | int32 status_code = 1; // 状态码,0-成功,其他值-失败 58 | string status_msg = 2; // 返回状态描述 59 | bool is = 3; // 是否关注 60 | } 61 | message SendMessageRequest{ 62 | int64 user_id = 1; 63 | int64 to_id = 2; 64 | string message = 3; 65 | } 66 | message MessageListRequest{ 67 | int64 user_id = 1; 68 | int64 to_id = 2; 69 | int64 last_time = 3; 70 | } 71 | message MessageListResponse{ 72 | int32 status_code = 1; // 状态码,0-成功,其他值-失败 73 | string status_msg = 2; // 返回状态描述 74 | repeated Message message_list =3; 75 | } 76 | message CountsResponse{ 77 | int32 status_code = 1; // 状态码,0-成功,其他值-失败 78 | string status_msg = 2; // 返回状态描述 79 | int64 counts = 3; // 数量 80 | } 81 | service UserCenter { 82 | rpc Ping(Request) returns(Response); 83 | rpc Register(RegisterRequest) returns (BasicResponse); 84 | rpc Login(LoginRequest) returns (LoginResponse); 85 | rpc GetInfo(GetInfoRequest)returns(GetInfoResponse); 86 | rpc Follow(FollowRequest) returns (BasicResponse); 87 | rpc CancelFollow(FollowRequest) returns (BasicResponse); 88 | rpc JudgeFollow(FollowRequest) returns (JudgeFollowResponse); 89 | rpc FollowList(GetInfoRequest) returns (FollowListResponse); 90 | rpc FollowerList(GetInfoRequest) returns (FollowListResponse); 91 | rpc FriendList(GetInfoRequest) returns (FollowListResponse); 92 | rpc SendMessage(SendMessageRequest) returns(BasicResponse); 93 | rpc MessageList(MessageListRequest) returns(MessageListResponse); 94 | rpc WorkCounts(GetInfoRequest) returns(CountsResponse); 95 | rpc FavouriteCounts(GetInfoRequest) returns(CountsResponse); 96 | rpc BePraisedCounts(GetInfoRequest) returns(CountsResponse); 97 | } 98 | 99 | message User { 100 | int64 id = 1; // 用户id 101 | string name = 2; // 用户名称 102 | int64 follow_count = 3; // 关注总数 103 | int64 follower_count = 4; // 粉丝总数 104 | bool is_follow = 5; // true-已关注,false-未关注 105 | } 106 | 107 | message Follower{ 108 | int64 UserId = 1;//粉丝id 109 | int64 FollowId = 2;//被关注者id 110 | } 111 | message Message{ 112 | int64 id =1;//消息id 113 | int64 from_user_id =2;//消息发送者id 114 | int64 to_user_id =3;//消息接收者id 115 | string content =4;//消息内容 116 | int64 create_time =5;//消息发送时间 117 | 118 | } -------------------------------------------------------------------------------- /user_service/kitex.yaml: -------------------------------------------------------------------------------- 1 | kitexinfo: 2 | ServiceName: 'user_service' 3 | ToolVersion: 'v0.4.4' 4 | 5 | -------------------------------------------------------------------------------- /user_service/kitex_gen/usercenter/client.go: -------------------------------------------------------------------------------- 1 | // Code generated by Kitex v0.4.4. DO NOT EDIT. 2 | 3 | package usercenter 4 | 5 | import ( 6 | "context" 7 | kitex_gen "dousheng_server/user_service/kitex_gen" 8 | client "github.com/cloudwego/kitex/client" 9 | callopt "github.com/cloudwego/kitex/client/callopt" 10 | ) 11 | 12 | // Client is designed to provide IDL-compatible methods with call-option parameter for kitex framework. 13 | type Client interface { 14 | Ping(ctx context.Context, Req *kitex_gen.Request, callOptions ...callopt.Option) (r *kitex_gen.Response, err error) 15 | Register(ctx context.Context, Req *kitex_gen.RegisterRequest, callOptions ...callopt.Option) (r *kitex_gen.BasicResponse, err error) 16 | Login(ctx context.Context, Req *kitex_gen.LoginRequest, callOptions ...callopt.Option) (r *kitex_gen.LoginResponse, err error) 17 | GetInfo(ctx context.Context, Req *kitex_gen.GetInfoRequest, callOptions ...callopt.Option) (r *kitex_gen.GetInfoResponse, err error) 18 | Follow(ctx context.Context, Req *kitex_gen.FollowRequest, callOptions ...callopt.Option) (r *kitex_gen.BasicResponse, err error) 19 | CancelFollow(ctx context.Context, Req *kitex_gen.FollowRequest, callOptions ...callopt.Option) (r *kitex_gen.BasicResponse, err error) 20 | JudgeFollow(ctx context.Context, Req *kitex_gen.FollowRequest, callOptions ...callopt.Option) (r *kitex_gen.JudgeFollowResponse, err error) 21 | FollowList(ctx context.Context, Req *kitex_gen.GetInfoRequest, callOptions ...callopt.Option) (r *kitex_gen.FollowListResponse, err error) 22 | FollowerList(ctx context.Context, Req *kitex_gen.GetInfoRequest, callOptions ...callopt.Option) (r *kitex_gen.FollowListResponse, err error) 23 | FriendList(ctx context.Context, Req *kitex_gen.GetInfoRequest, callOptions ...callopt.Option) (r *kitex_gen.FollowListResponse, err error) 24 | SendMessage(ctx context.Context, Req *kitex_gen.SendMessageRequest, callOptions ...callopt.Option) (r *kitex_gen.BasicResponse, err error) 25 | MessageList(ctx context.Context, Req *kitex_gen.MessageListRequest, callOptions ...callopt.Option) (r *kitex_gen.MessageListResponse, err error) 26 | WorkCounts(ctx context.Context, Req *kitex_gen.GetInfoRequest, callOptions ...callopt.Option) (r *kitex_gen.CountsResponse, err error) 27 | FavouriteCounts(ctx context.Context, Req *kitex_gen.GetInfoRequest, callOptions ...callopt.Option) (r *kitex_gen.CountsResponse, err error) 28 | BePraisedCounts(ctx context.Context, Req *kitex_gen.GetInfoRequest, callOptions ...callopt.Option) (r *kitex_gen.CountsResponse, err error) 29 | } 30 | 31 | // NewClient creates a client for the service defined in IDL. 32 | func NewClient(destService string, opts ...client.Option) (Client, error) { 33 | var options []client.Option 34 | options = append(options, client.WithDestService(destService)) 35 | 36 | options = append(options, opts...) 37 | 38 | kc, err := client.NewClient(serviceInfo(), options...) 39 | if err != nil { 40 | return nil, err 41 | } 42 | return &kUserCenterClient{ 43 | kClient: newServiceClient(kc), 44 | }, nil 45 | } 46 | 47 | // MustNewClient creates a client for the service defined in IDL. It panics if any error occurs. 48 | func MustNewClient(destService string, opts ...client.Option) Client { 49 | kc, err := NewClient(destService, opts...) 50 | if err != nil { 51 | panic(err) 52 | } 53 | return kc 54 | } 55 | 56 | type kUserCenterClient struct { 57 | *kClient 58 | } 59 | 60 | func (p *kUserCenterClient) Ping(ctx context.Context, Req *kitex_gen.Request, callOptions ...callopt.Option) (r *kitex_gen.Response, err error) { 61 | ctx = client.NewCtxWithCallOptions(ctx, callOptions) 62 | return p.kClient.Ping(ctx, Req) 63 | } 64 | 65 | func (p *kUserCenterClient) Register(ctx context.Context, Req *kitex_gen.RegisterRequest, callOptions ...callopt.Option) (r *kitex_gen.BasicResponse, err error) { 66 | ctx = client.NewCtxWithCallOptions(ctx, callOptions) 67 | return p.kClient.Register(ctx, Req) 68 | } 69 | 70 | func (p *kUserCenterClient) Login(ctx context.Context, Req *kitex_gen.LoginRequest, callOptions ...callopt.Option) (r *kitex_gen.LoginResponse, err error) { 71 | ctx = client.NewCtxWithCallOptions(ctx, callOptions) 72 | return p.kClient.Login(ctx, Req) 73 | } 74 | 75 | func (p *kUserCenterClient) GetInfo(ctx context.Context, Req *kitex_gen.GetInfoRequest, callOptions ...callopt.Option) (r *kitex_gen.GetInfoResponse, err error) { 76 | ctx = client.NewCtxWithCallOptions(ctx, callOptions) 77 | return p.kClient.GetInfo(ctx, Req) 78 | } 79 | 80 | func (p *kUserCenterClient) Follow(ctx context.Context, Req *kitex_gen.FollowRequest, callOptions ...callopt.Option) (r *kitex_gen.BasicResponse, err error) { 81 | ctx = client.NewCtxWithCallOptions(ctx, callOptions) 82 | return p.kClient.Follow(ctx, Req) 83 | } 84 | 85 | func (p *kUserCenterClient) CancelFollow(ctx context.Context, Req *kitex_gen.FollowRequest, callOptions ...callopt.Option) (r *kitex_gen.BasicResponse, err error) { 86 | ctx = client.NewCtxWithCallOptions(ctx, callOptions) 87 | return p.kClient.CancelFollow(ctx, Req) 88 | } 89 | 90 | func (p *kUserCenterClient) JudgeFollow(ctx context.Context, Req *kitex_gen.FollowRequest, callOptions ...callopt.Option) (r *kitex_gen.JudgeFollowResponse, err error) { 91 | ctx = client.NewCtxWithCallOptions(ctx, callOptions) 92 | return p.kClient.JudgeFollow(ctx, Req) 93 | } 94 | 95 | func (p *kUserCenterClient) FollowList(ctx context.Context, Req *kitex_gen.GetInfoRequest, callOptions ...callopt.Option) (r *kitex_gen.FollowListResponse, err error) { 96 | ctx = client.NewCtxWithCallOptions(ctx, callOptions) 97 | return p.kClient.FollowList(ctx, Req) 98 | } 99 | 100 | func (p *kUserCenterClient) FollowerList(ctx context.Context, Req *kitex_gen.GetInfoRequest, callOptions ...callopt.Option) (r *kitex_gen.FollowListResponse, err error) { 101 | ctx = client.NewCtxWithCallOptions(ctx, callOptions) 102 | return p.kClient.FollowerList(ctx, Req) 103 | } 104 | 105 | func (p *kUserCenterClient) FriendList(ctx context.Context, Req *kitex_gen.GetInfoRequest, callOptions ...callopt.Option) (r *kitex_gen.FollowListResponse, err error) { 106 | ctx = client.NewCtxWithCallOptions(ctx, callOptions) 107 | return p.kClient.FriendList(ctx, Req) 108 | } 109 | 110 | func (p *kUserCenterClient) SendMessage(ctx context.Context, Req *kitex_gen.SendMessageRequest, callOptions ...callopt.Option) (r *kitex_gen.BasicResponse, err error) { 111 | ctx = client.NewCtxWithCallOptions(ctx, callOptions) 112 | return p.kClient.SendMessage(ctx, Req) 113 | } 114 | 115 | func (p *kUserCenterClient) MessageList(ctx context.Context, Req *kitex_gen.MessageListRequest, callOptions ...callopt.Option) (r *kitex_gen.MessageListResponse, err error) { 116 | ctx = client.NewCtxWithCallOptions(ctx, callOptions) 117 | return p.kClient.MessageList(ctx, Req) 118 | } 119 | 120 | func (p *kUserCenterClient) WorkCounts(ctx context.Context, Req *kitex_gen.GetInfoRequest, callOptions ...callopt.Option) (r *kitex_gen.CountsResponse, err error) { 121 | ctx = client.NewCtxWithCallOptions(ctx, callOptions) 122 | return p.kClient.WorkCounts(ctx, Req) 123 | } 124 | 125 | func (p *kUserCenterClient) FavouriteCounts(ctx context.Context, Req *kitex_gen.GetInfoRequest, callOptions ...callopt.Option) (r *kitex_gen.CountsResponse, err error) { 126 | ctx = client.NewCtxWithCallOptions(ctx, callOptions) 127 | return p.kClient.FavouriteCounts(ctx, Req) 128 | } 129 | 130 | func (p *kUserCenterClient) BePraisedCounts(ctx context.Context, Req *kitex_gen.GetInfoRequest, callOptions ...callopt.Option) (r *kitex_gen.CountsResponse, err error) { 131 | ctx = client.NewCtxWithCallOptions(ctx, callOptions) 132 | return p.kClient.BePraisedCounts(ctx, Req) 133 | } 134 | -------------------------------------------------------------------------------- /user_service/kitex_gen/usercenter/invoker.go: -------------------------------------------------------------------------------- 1 | // Code generated by Kitex v0.4.4. DO NOT EDIT. 2 | 3 | package usercenter 4 | 5 | import ( 6 | kitex_gen "dousheng_server/user_service/kitex_gen" 7 | server "github.com/cloudwego/kitex/server" 8 | ) 9 | 10 | // NewInvoker creates a server.Invoker with the given handler and options. 11 | func NewInvoker(handler kitex_gen.UserCenter, opts ...server.Option) server.Invoker { 12 | var options []server.Option 13 | 14 | options = append(options, opts...) 15 | 16 | s := server.NewInvoker(options...) 17 | if err := s.RegisterService(serviceInfo(), handler); err != nil { 18 | panic(err) 19 | } 20 | if err := s.Init(); err != nil { 21 | panic(err) 22 | } 23 | return s 24 | } 25 | -------------------------------------------------------------------------------- /user_service/kitex_gen/usercenter/server.go: -------------------------------------------------------------------------------- 1 | // Code generated by Kitex v0.4.4. DO NOT EDIT. 2 | package usercenter 3 | 4 | import ( 5 | kitex_gen "dousheng_server/user_service/kitex_gen" 6 | server "github.com/cloudwego/kitex/server" 7 | ) 8 | 9 | // NewServer creates a server.Server with the given handler and options. 10 | func NewServer(handler kitex_gen.UserCenter, opts ...server.Option) server.Server { 11 | var options []server.Option 12 | 13 | options = append(options, opts...) 14 | 15 | svr := server.NewServer(options...) 16 | if err := svr.RegisterService(serviceInfo(), handler); err != nil { 17 | panic(err) 18 | } 19 | return svr 20 | } 21 | -------------------------------------------------------------------------------- /user_service/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "dousheng_server/conf" 5 | "dousheng_server/user_service/kitex_gen/usercenter" 6 | "github.com/cloudwego/kitex/pkg/rpcinfo" 7 | "github.com/cloudwego/kitex/server" 8 | kServer "github.com/cloudwego/kitex/server" 9 | prometheus "github.com/kitex-contrib/monitor-prometheus" 10 | etcd "github.com/kitex-contrib/registry-etcd" 11 | "log" 12 | "net" 13 | ) 14 | 15 | func main() { 16 | addr, _ := net.ResolveTCPAddr("tcp", ":8900") 17 | r, err := etcd.NewEtcdRegistry([]string{conf.Conf.EtcdConfig.Url}) 18 | if err != nil { 19 | log.Fatal(err) 20 | } 21 | svr := usercenter.NewServer(new(UserCenterImpl), 22 | server.WithServerBasicInfo(&rpcinfo.EndpointBasicInfo{ServiceName: "userservice"}), 23 | server.WithRegistry(r), 24 | server.WithServiceAddr(addr), 25 | kServer.WithTracer(prometheus.NewServerTracer(":9900", "/metrics"))) 26 | 27 | err = svr.Run() 28 | 29 | if err != nil { 30 | log.Println(err.Error()) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /user_service/script/bootstrap.sh: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env bash 2 | CURDIR=$(cd $(dirname $0); pwd) 3 | 4 | if [ "X$1" != "X" ]; then 5 | RUNTIME_ROOT=$1 6 | else 7 | RUNTIME_ROOT=${CURDIR} 8 | fi 9 | 10 | export KITEX_RUNTIME_ROOT=$RUNTIME_ROOT 11 | export KITEX_LOG_DIR="$RUNTIME_ROOT/log" 12 | 13 | if [ ! -d "$KITEX_LOG_DIR/app" ]; then 14 | mkdir -p "$KITEX_LOG_DIR/app" 15 | fi 16 | 17 | if [ ! -d "$KITEX_LOG_DIR/rpc" ]; then 18 | mkdir -p "$KITEX_LOG_DIR/rpc" 19 | fi 20 | 21 | exec "$CURDIR/bin/user_service" 22 | 23 | -------------------------------------------------------------------------------- /user_service/service/user_center.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | zaplog "dousheng_server/deploy/log" 5 | "dousheng_server/user_service/dal/model" 6 | "dousheng_server/user_service/dal/query" 7 | "dousheng_server/user_service/kitex_gen" 8 | "dousheng_server/user_service/util" 9 | "dousheng_server/uuidmaker" 10 | "errors" 11 | ) 12 | 13 | type UserCenter struct { 14 | } 15 | 16 | // CreateUser 注册用户 17 | func (uc UserCenter) CreateUser(userName, password string) error { 18 | // 1. 判断用户名是否存在 19 | existed, err := query.IsUserNameExisted(userName) 20 | if err != nil { 21 | return err 22 | } 23 | 24 | if existed == 1 { 25 | return errors.New("用户名已存在") 26 | } 27 | // 2. 生成用户 28 | // 获取uuid 29 | uuid, err := uuidmaker.GetUUID() 30 | if err != nil { 31 | zaplog.ZapLogger.Error("failed when generating uuid err:%v", err) 32 | return err 33 | } 34 | 35 | // 加密 36 | passwd, err := util.HashAndSalt(password) 37 | if err != nil { 38 | return err 39 | } 40 | user := &model.User{ 41 | UUID: uuid, 42 | Username: userName, 43 | Password: passwd, 44 | FollowCount: 0, 45 | FollowerCount: 0, 46 | } 47 | 48 | // 3. 保存 49 | err = query.CreateUser(user) 50 | if err != nil { 51 | return err 52 | } 53 | // 4. 生成Token返回 54 | return nil 55 | } 56 | 57 | // LoginByPassword 使用用户名-密码登录 58 | func (uc UserCenter) LoginByPassword(userName, password string) (*model.User, error) { 59 | return query.CheckPassword(userName, password) 60 | } 61 | 62 | // GetInfo 通过UUID获取用户信息 63 | func (uc UserCenter) GetInfo(uuid int64) (*model.User, error) { 64 | return query.GetUser(uuid) 65 | } 66 | 67 | // Follow 关注用户 68 | func (uc UserCenter) Follow(userId, followId int64) error { 69 | return query.Follow(userId, followId) 70 | } 71 | 72 | // CancelFollow 取消关注用户 73 | func (uc UserCenter) CancelFollow(userId, followId int64) error { 74 | return query.CancelFollow(userId, followId) 75 | } 76 | 77 | // JudgeFollow 判断用户是否关注 78 | func (uc UserCenter) JudgeFollow(userId, followId int64) (bool, error) { 79 | return query.JudgeFollow(userId, followId) 80 | } 81 | 82 | // FollowList 通过UUID获取关注列表 83 | func (uc UserCenter) FollowList(uuid int64) ([]*kitex_gen.Follower, error) { 84 | followers, err := query.FollowList(uuid) 85 | return modelToKitexFollower(followers), err 86 | } 87 | 88 | // FollowerList 通过UUID获取粉丝列表 89 | func (uc UserCenter) FollowerList(uuid int64) ([]*kitex_gen.Follower, error) { 90 | followers, err := query.FollowerList(uuid) 91 | return modelToKitexFollower(followers), err 92 | } 93 | 94 | // FriendList 通过UUID获取好友列表 95 | func (uc UserCenter) FriendList(uuid int64) ([]*kitex_gen.Follower, error) { 96 | followers, err := query.FriendList(uuid) 97 | return modelToKitexFollower(followers), err 98 | } 99 | 100 | // SendMessages 发消息 101 | func (uc UserCenter) SendMessages(FromUser, ToUser int64, message string) error { 102 | id, err := uuidmaker.GetUUID() 103 | if err != nil { 104 | zaplog.ZapLogger.Error("failed when generating uuid err:%v", err) 105 | return err 106 | } 107 | messageModel := &model.Message{ 108 | Id: id, 109 | Messages: message, 110 | FromUserId: FromUser, 111 | ToUserId: ToUser, 112 | } 113 | err = query.SendMessage(messageModel) 114 | if err != nil { 115 | return err 116 | } 117 | return nil 118 | } 119 | 120 | // MessageList 消息列表 121 | func (uc UserCenter) MessageList(FromUserId, ToUserId, lastTime int64) ([]*kitex_gen.Message, error) { 122 | messageList, err := query.MessageList(FromUserId, ToUserId, lastTime) 123 | return modelToKitexMessage(messageList), err 124 | 125 | } 126 | 127 | // 作品数 128 | func (uc UserCenter) WorkCounts(uuid int64) (int64, error) { 129 | return query.WorkCounts(uuid) 130 | } 131 | 132 | // 喜欢数 133 | func (uc UserCenter) FavouriteCounts(uuid int64) (int64, error) { 134 | return query.FavouriteCounts(uuid) 135 | } 136 | 137 | // 获赞数 138 | func (uc UserCenter) BePraisedCounts(uuid int64) (int64, error) { 139 | return query.BePraisedCounts(uuid) 140 | } 141 | 142 | // 将model中的follower转换为kitex中生成的follower 143 | func modelToKitexFollower(follower *[]model.Follower) []*kitex_gen.Follower { 144 | var followerList []*kitex_gen.Follower 145 | for _, item := range *follower { 146 | followerList = append(followerList, &kitex_gen.Follower{ 147 | UserId: item.UserId, 148 | FollowId: item.FollowId, 149 | }) 150 | } 151 | return followerList 152 | } 153 | 154 | // 将model中的Message转换为kitex中生成的Message 155 | func modelToKitexMessage(message *[]model.Message) []*kitex_gen.Message { 156 | var messageList []*kitex_gen.Message 157 | for _, item := range *message { 158 | messageList = append(messageList, &kitex_gen.Message{ 159 | Id: item.Id, 160 | FromUserId: item.FromUserId, 161 | ToUserId: item.ToUserId, 162 | Content: item.Messages, 163 | CreateTime: item.CreatedAt, 164 | }) 165 | } 166 | return messageList 167 | } 168 | -------------------------------------------------------------------------------- /user_service/service/user_center_test.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | "dousheng_server/user_service/kitex_gen" 6 | "dousheng_server/user_service/kitex_gen/usercenter" 7 | "fmt" 8 | "github.com/cloudwego/kitex/client" 9 | etcd "github.com/kitex-contrib/registry-etcd" 10 | "log" 11 | "testing" 12 | ) 13 | 14 | func TestUserCenter_CreateUser(t *testing.T) { 15 | r, err := etcd.NewEtcdResolver([]string{"127.0.0.1:2379"}) // r不应重复使用。 16 | userClient, err := usercenter.NewClient("userservice", client.WithResolver(r)) 17 | if err != nil { 18 | log.Fatal(err) 19 | } 20 | req := kitex_gen.RegisterRequest{ 21 | Username: "hello3", 22 | Password: "test", 23 | } 24 | resp, err := userClient.Register(context.Background(), &req) 25 | if err != nil { 26 | fmt.Println(err.Error()) 27 | } 28 | fmt.Println(resp) 29 | } 30 | -------------------------------------------------------------------------------- /user_service/util/salt.go: -------------------------------------------------------------------------------- 1 | package util 2 | 3 | import "golang.org/x/crypto/bcrypt" 4 | 5 | // HashAndSalt 加密密码 6 | func HashAndSalt(pwdStr string) (pwdHash string, err error) { 7 | pwd := []byte(pwdStr) 8 | hash, err := bcrypt.GenerateFromPassword(pwd, bcrypt.MinCost) 9 | if err != nil { 10 | return 11 | } 12 | pwdHash = string(hash) 13 | return 14 | } 15 | 16 | // ComparePasswords 验证密码 17 | func ComparePasswords(hashedPwd string, plainPwd string) bool { 18 | byteHash := []byte(hashedPwd) 19 | bytePwd := []byte(plainPwd) 20 | err := bcrypt.CompareHashAndPassword(byteHash, bytePwd) 21 | if err != nil { 22 | return false 23 | } 24 | return true 25 | } 26 | -------------------------------------------------------------------------------- /user_service/util/salt_test.go: -------------------------------------------------------------------------------- 1 | package util 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | ) 7 | 8 | func TestPassword(t *testing.T) { 9 | passwdSaved, err := HashAndSalt("testing") 10 | if err != nil { 11 | fmt.Println(err.Error()) 12 | } 13 | t.Run("测试1", func(t *testing.T) { 14 | res := ComparePasswords(passwdSaved, "testing") 15 | if !res { 16 | t.Fatal("理应返回正确") 17 | } 18 | }) 19 | t.Run("测试2", func(t *testing.T) { 20 | res := ComparePasswords(passwdSaved, "hello") 21 | if res { 22 | t.Fatal("理应返回错误") 23 | } 24 | }) 25 | } 26 | -------------------------------------------------------------------------------- /uuidmaker/maker.go: -------------------------------------------------------------------------------- 1 | package uuidmaker 2 | 3 | import ( 4 | "context" 5 | snowflake_gen "dousheng_server/snowflake_service/kitex_gen" 6 | "dousheng_server/snowflake_service/kitex_gen/snowflake" 7 | "github.com/cloudwego/kitex/client" 8 | etcd "github.com/kitex-contrib/registry-etcd" 9 | ) 10 | 11 | var snowClient snowflake.Client 12 | 13 | func init() { 14 | // 1. 通过etcd发现服务 15 | r, err := etcd.NewEtcdResolver([]string{"127.0.0.1:2379"}) // r不应重复使用。 16 | snowClient, err = snowflake.NewClient("snowflakeservice", client.WithResolver(r)) 17 | if err != nil { 18 | panic("wrong on snowflake_service") 19 | } 20 | } 21 | 22 | func GetUUID() (int64, error) { 23 | var req snowflake_gen.NewIDRequest 24 | resp, err := snowClient.NewID(context.Background(), &req) 25 | if err != nil { 26 | return -1, err 27 | } 28 | return resp.ID, nil 29 | } 30 | -------------------------------------------------------------------------------- /video_service/build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | RUN_NAME="videocenter" 3 | 4 | mkdir -p output/bin 5 | cp script/* output/ 6 | chmod +x output/bootstrap.sh 7 | 8 | if [ "$IS_SYSTEM_TEST_ENV" != "1" ]; then 9 | go build -o output/bin/${RUN_NAME} 10 | else 11 | go test -c -covermode=set -o output/bin/${RUN_NAME} -coverpkg=./... 12 | fi 13 | 14 | -------------------------------------------------------------------------------- /video_service/dal/model/comment.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | import "time" 4 | 5 | type Comment struct { 6 | CommentId int64 `gorm:"primaryKey" json:"comment_id"` 7 | UserId int64 `gorm:"index:idx_user" json:"user_id"` 8 | VideoId int64 `gorm:"index:idx_video" json:"video_id"` 9 | Content string `json:"content"` 10 | CreateDate string `gorm:"index:idx_create,sort:desc" json:"create_date"` 11 | CreatedAt time.Time 12 | } 13 | -------------------------------------------------------------------------------- /video_service/dal/model/favorite.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | import "dousheng_server/user_service/dal/model" 4 | 5 | type Favorite struct { 6 | UserId int64 `gorm:"index:idx_user" json:"user_id"` 7 | VideoId int64 `json:"video_id"` 8 | //外键 9 | User model.User `gorm:"foreignKey:user_id"` 10 | } 11 | -------------------------------------------------------------------------------- /video_service/dal/model/video.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | import ( 4 | "dousheng_server/user_service/dal/model" 5 | "gorm.io/gorm" 6 | "time" 7 | ) 8 | 9 | type Video struct { 10 | UUID int64 `gorm:"primaryKey" json:"id"` 11 | UserID int64 `json:"user_id"` 12 | PlayURL string `json:"play_url"` 13 | CoverURL string `json:"cover_url"` 14 | FavoriteCount int64 `json:"favorite_count"` 15 | CommentCount int64 `json:"comment_count"` 16 | Title string `json:"title"` 17 | CreatedAt time.Time 18 | UpdatedAt time.Time 19 | DeletedAt gorm.DeletedAt `gorm:"index"` 20 | //外键 21 | User model.User `gorm:"foreignKey:user_id"` 22 | } 23 | -------------------------------------------------------------------------------- /video_service/dal/orm_test.go: -------------------------------------------------------------------------------- 1 | package dal 2 | 3 | import ( 4 | "dousheng_server/video_service/dal/model" 5 | "dousheng_server/video_service/dal/query" 6 | "fmt" 7 | "testing" 8 | "time" 9 | ) 10 | 11 | func TestCreateVideo(t *testing.T) { 12 | t.Run("成功投稿视频测试", func(t *testing.T) { 13 | err := query.CreateVideo(&model.Video{ 14 | UUID: 1, 15 | UserID: 1, 16 | PlayURL: "http://localhost:8080/static/videos/bear.mp4", 17 | CoverURL: "http://localhost:8080/static/covers/bear.png", 18 | FavoriteCount: 0, 19 | CommentCount: 0, 20 | Title: "测试1", 21 | }) 22 | if err != nil { 23 | t.Fatalf(err.Error()) 24 | return 25 | } 26 | }) 27 | } 28 | 29 | func TestDeleteVideo(t *testing.T) { 30 | t.Run("删除视频测试", func(t *testing.T) { 31 | err := query.DeleteVideo(630179868037873664) 32 | if err != nil { 33 | t.Fatalf(err.Error()) 34 | return 35 | } 36 | }) 37 | } 38 | 39 | func TestFeed(t *testing.T) { 40 | t.Run("Feed测试", func(t *testing.T) { 41 | lastTime := time.Now() 42 | videos, err := query.Feed(lastTime) 43 | if err != nil { 44 | t.Fatalf(err.Error()) 45 | return 46 | } 47 | for _, item := range *videos { 48 | fmt.Println(item) 49 | } 50 | }) 51 | } 52 | 53 | func TestList(t *testing.T) { 54 | t.Run("测试投稿列表", func(t *testing.T) { 55 | list, err := query.VideoList(629648834103869440) 56 | if err != nil { 57 | t.Fatalf(err.Error()) 58 | return 59 | } 60 | for _, item := range *list { 61 | fmt.Println(item) 62 | } 63 | }) 64 | } 65 | 66 | func TestCreateFavorite(t *testing.T) { 67 | t.Run("点赞", func(t *testing.T) { 68 | err := query.Favorite(629648834103869440, 631256877056917504) 69 | if err != nil { 70 | t.Fatalf(err.Error()) 71 | return 72 | } 73 | }) 74 | } 75 | 76 | func TestUndoFavorite(t *testing.T) { 77 | t.Run("取消点赞", func(t *testing.T) { 78 | err := query.UndoFavorite(629648834103869440, 631256877056917504) 79 | if err != nil { 80 | t.Fatalf(err.Error()) 81 | return 82 | } 83 | }) 84 | } 85 | 86 | func TestIsLiked(t *testing.T) { 87 | t.Run("是否点赞", func(t *testing.T) { 88 | res := query.IsLiked(629648834103869440, 631256877056917504) 89 | 90 | fmt.Println(res) 91 | }) 92 | } 93 | 94 | func TestFavoriteList(t *testing.T) { 95 | t.Run("喜欢列表测试", func(t *testing.T) { 96 | list, err := query.FavoriteList(629648834103869440) 97 | if err != nil { 98 | t.Fatalf(err.Error()) 99 | return 100 | } 101 | fmt.Println(list) 102 | }) 103 | } 104 | 105 | func TestCreateComment(t *testing.T) { 106 | t.Run("发表评论测试", func(t *testing.T) { 107 | comment, err := query.CreateComment(&model.Comment{ 108 | CommentId: 629648834103869443, 109 | UserId: 629648834103869440, 110 | VideoId: 631256877056917504, 111 | Content: "发表评论测试2", 112 | CreateDate: time.Now().Format("01-02"), 113 | }) 114 | if err != nil { 115 | t.Fatalf(err.Error()) 116 | return 117 | } 118 | fmt.Println(comment) 119 | }) 120 | } 121 | 122 | func TestDeleteComment(t *testing.T) { 123 | t.Run("删除评论测试", func(t *testing.T) { 124 | err := query.DeleteComment(629648834103869442) 125 | if err != nil { 126 | t.Fatalf(err.Error()) 127 | return 128 | } 129 | }) 130 | } 131 | 132 | func TestGetComment(t *testing.T) { 133 | t.Run("获取视频评论", func(t *testing.T) { 134 | comments, err := query.GetComment(631256877056917504) 135 | if err != nil { 136 | t.Fatalf(err.Error()) 137 | return 138 | } 139 | fmt.Println(comments) 140 | }) 141 | } 142 | -------------------------------------------------------------------------------- /video_service/dal/query/comment.go: -------------------------------------------------------------------------------- 1 | package query 2 | 3 | import ( 4 | "dousheng_server/video_service/dal/model" 5 | "gorm.io/gorm" 6 | ) 7 | 8 | // CreateComment 新增评论 9 | func CreateComment(comment *model.Comment) (*model.Comment, error) { 10 | err := GormClient.Transaction(func(tx *gorm.DB) error { 11 | if err := tx.Create(comment).Error; err != nil { 12 | return err 13 | } 14 | if err := tx.Where("uuid = ?", comment.VideoId).Model(&model.Video{}). 15 | Update("comment_count", gorm.Expr("comment_count + 1")). 16 | Error; err != nil { 17 | return err 18 | } 19 | return nil 20 | }) 21 | return comment, err 22 | } 23 | 24 | // DeleteComment 删除评论 25 | func DeleteComment(uuid int64) error { 26 | return GormClient.Transaction(func(tx *gorm.DB) error { 27 | comment := &model.Comment{CommentId: uuid} 28 | if err := tx.First(comment).Error; err != nil { 29 | return err 30 | } 31 | if err := tx.Where("uuid = ?", comment.VideoId).Model(&model.Video{}). 32 | Update("comment_count", gorm.Expr("comment_count - 1")). 33 | Error; err != nil { 34 | return err 35 | } 36 | if err := tx.Delete(comment).Error; err != nil { 37 | return err 38 | } 39 | return nil 40 | }) 41 | } 42 | 43 | // GetComment 查看视频的评论 44 | func GetComment(uuid int64) (*[]model.Comment, error) { 45 | var res []model.Comment 46 | err := GormClient.Order("created_at desc").Where("video_id = ?", uuid).Find(&res).Error 47 | return &res, err 48 | } 49 | -------------------------------------------------------------------------------- /video_service/dal/query/favorite.go: -------------------------------------------------------------------------------- 1 | package query 2 | 3 | import ( 4 | "dousheng_server/video_service/dal/model" 5 | "errors" 6 | "gorm.io/gorm" 7 | ) 8 | 9 | // Favorite 点赞 10 | func Favorite(userId, videoId int64) error { 11 | favorite := model.Favorite{ 12 | UserId: userId, 13 | VideoId: videoId, 14 | } 15 | if ok := IsLiked(userId, videoId); ok { 16 | return errors.New("already liked") 17 | } 18 | return GormClient.Transaction(func(tx *gorm.DB) error { 19 | err := tx.Create(&favorite).Error 20 | if err != nil { 21 | return err 22 | } else { 23 | if err := tx.Where("uuid = ?", videoId).Model(&model.Video{}). 24 | Update("favorite_count", gorm.Expr("favorite_count + 1")). 25 | Error; err != nil { 26 | return err 27 | } 28 | } 29 | return nil 30 | }) 31 | } 32 | 33 | // UndoFavorite 取消点赞 34 | func UndoFavorite(userId, videoId int64) error { 35 | return GormClient.Transaction(func(tx *gorm.DB) error { 36 | err := tx.Where("user_id = ? AND video_id = ?", userId, videoId).Delete(&model.Favorite{}).Error 37 | if err != nil { 38 | return err 39 | } else { 40 | if err := tx.Where("uuid = ?", videoId).Model(&model.Video{}). 41 | Update("favorite_count", gorm.Expr("favorite_count - 1")). 42 | Error; err != nil { 43 | return err 44 | } 45 | } 46 | return nil 47 | }) 48 | } 49 | 50 | // IsLiked 判断此视频该用户是否点过赞 51 | func IsLiked(userId, videoId int64) bool { 52 | favorite := model.Favorite{} 53 | //err := GormClient.Where("video_id = ?", videoId).Find(&favorite).Error 54 | result := GormClient.Where("user_id = ? AND video_id = ?", userId, videoId).Find(&favorite) 55 | return result.RowsAffected != 0 56 | } 57 | 58 | // FavoriteList 点赞过的视频uuid列表 59 | func FavoriteList(userId int64) ([]int64, error) { 60 | res := make([]int64, 0) 61 | var favorites []model.Favorite 62 | err := GormClient.Where("user_id = ?", userId).Find(&favorites).Error 63 | for _, item := range favorites { 64 | res = append(res, item.VideoId) 65 | } 66 | return res, err 67 | } 68 | -------------------------------------------------------------------------------- /video_service/dal/query/init.go: -------------------------------------------------------------------------------- 1 | package query 2 | 3 | import ( 4 | "dousheng_server/conf" 5 | zaplog "dousheng_server/deploy/log" 6 | "dousheng_server/video_service/dal/model" 7 | "gorm.io/driver/mysql" 8 | "gorm.io/gorm" 9 | ) 10 | 11 | var GormClient *gorm.DB 12 | 13 | func init() { 14 | dsn := conf.Conf.MysqlConfig.User + ":" + 15 | conf.Conf.MysqlConfig.Password + "@tcp(" + 16 | conf.Conf.MysqlConfig.Url + ")/" + 17 | conf.Conf.MysqlConfig.Database + "?charset=utf8mb4&parseTime=True&loc=Local" 18 | var err error 19 | GormClient, err = gorm.Open(mysql.Open(dsn), &gorm.Config{}) 20 | if err != nil { 21 | zaplog.ZapLogger.Error("failed when opening gorm:%s err:%v", conf.Conf.Database, err) 22 | panic(err.Error()) 23 | } 24 | err = GormClient.AutoMigrate(&model.Comment{}, &model.Video{}, &model.Favorite{}) 25 | if err != nil { 26 | zaplog.ZapLogger.Error("failed when init gorm table err:%v", err) 27 | panic("gorm init table failed ") 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /video_service/dal/query/video.go: -------------------------------------------------------------------------------- 1 | package query 2 | 3 | import ( 4 | "dousheng_server/video_service/dal/model" 5 | "time" 6 | ) 7 | 8 | // CreateVideo 新增视频 9 | func CreateVideo(video *model.Video) error { 10 | return GormClient.Create(video).Error 11 | } 12 | 13 | // DeleteVideo 软删除视频 14 | func DeleteVideo(uuid int64) error { 15 | return GormClient.Where("uuid = ?", uuid).Delete(&model.Video{}).Error 16 | } 17 | 18 | // Feed 获取视频 19 | func Feed(lastTime time.Time) (*[]model.Video, error) { 20 | var videos []model.Video 21 | err := GormClient.Limit(3).Order("created_at desc").Where("created_at < ?", lastTime).Find(&videos).Error 22 | return &videos, err 23 | } 24 | 25 | // VideoList 获取用户投稿过的视频列表 26 | func VideoList(userId int64) (*[]model.Video, error) { 27 | var videos []model.Video 28 | err := GormClient.Where("user_id = ?", userId).Find(&videos).Error 29 | return &videos, err 30 | } 31 | 32 | // GetVideo 通过uuid获取video 33 | func GetVideo(uuid int64) (*model.Video, error) { 34 | var res model.Video 35 | err := GormClient.Where("uuid = ?", uuid).Find(&res).Error 36 | return &res, err 37 | } 38 | -------------------------------------------------------------------------------- /video_service/handler.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | kitex_gen "dousheng_server/video_service/kitex_gen" 6 | "dousheng_server/video_service/service" 7 | "fmt" 8 | ) 9 | 10 | // VideoCenterImpl implements the last service interface defined in the IDL. 11 | type VideoCenterImpl struct{} 12 | 13 | // Publish implements the VideoCenterImpl interface. 14 | func (s *VideoCenterImpl) Publish(ctx context.Context, req *kitex_gen.PublishRequest) (*kitex_gen.PublishResponse, error) { 15 | uuid, err := service.VideoCenter{}.Publish(req) 16 | if err != nil { 17 | return nil, err 18 | } 19 | return &kitex_gen.PublishResponse{ 20 | StatusCode: 0, 21 | StatusMsg: "success", 22 | Uuid: uuid, 23 | }, nil 24 | } 25 | 26 | // Delete implements the VideoCenterImpl interface. 27 | func (s *VideoCenterImpl) Delete(ctx context.Context, req *kitex_gen.DeleteRequest) (*kitex_gen.BasicResponse, error) { 28 | err := service.VideoCenter{}.Delete(req.VideoId) 29 | if err != nil { 30 | return &kitex_gen.BasicResponse{ 31 | StatusCode: -1, 32 | StatusMsg: err.Error(), 33 | }, err 34 | } 35 | return &kitex_gen.BasicResponse{ 36 | StatusCode: 0, 37 | StatusMsg: "success", 38 | }, nil 39 | } 40 | 41 | // Feed implements the VideoCenterImpl interface. 42 | func (s *VideoCenterImpl) Feed(ctx context.Context, req *kitex_gen.FeedRequest) (*kitex_gen.FeedResponse, error) { 43 | videos, err := service.VideoCenter{}.Feed(req.LastTime) 44 | if err != nil { 45 | return nil, err 46 | } 47 | return &kitex_gen.FeedResponse{Videos: videos}, nil 48 | } 49 | 50 | // VideoList implements the VideoCenterImpl interface. 51 | func (s *VideoCenterImpl) VideoList(ctx context.Context, req *kitex_gen.VideoListRequest) (resp *kitex_gen.VideoListResponse, err error) { 52 | videos, err := service.VideoCenter{}.VideoList(req.UserId) 53 | if err != nil { 54 | return nil, err 55 | } 56 | return &kitex_gen.VideoListResponse{Videos: videos}, nil 57 | } 58 | 59 | // Like implements the VideoCenterImpl interface. 60 | func (s *VideoCenterImpl) Like(ctx context.Context, req *kitex_gen.LikeRequest) (*kitex_gen.BasicResponse, error) { 61 | err := service.VideoCenter{}.Like(req.UserId, req.VideoId, req.ActionType) 62 | if err != nil { 63 | return nil, err 64 | } 65 | return &kitex_gen.BasicResponse{ 66 | StatusCode: 0, 67 | StatusMsg: "success", 68 | }, nil 69 | } 70 | 71 | // GetVideo implements the VideoCenterImpl interface. 72 | func (s *VideoCenterImpl) GetVideo(ctx context.Context, req *kitex_gen.GetVideoRequest) (resp *kitex_gen.GetVideoResponse, err error) { 73 | video, err := service.VideoCenter{}.GetVideo(req.Uuid) 74 | if err != nil { 75 | return nil, err 76 | } 77 | return &kitex_gen.GetVideoResponse{Video: video}, nil 78 | } 79 | 80 | // GetFavoriteVideo implements the VideoCenterImpl interface. 81 | func (s *VideoCenterImpl) GetFavoriteVideo(ctx context.Context, req *kitex_gen.GetVideoRequest) (*kitex_gen.GetFavoriteVideosResponse, error) { 82 | videos, err := service.VideoCenter{}.FavoriteList(req.Uuid) 83 | if err != nil { 84 | return nil, err 85 | } 86 | return &kitex_gen.GetFavoriteVideosResponse{Videos: videos}, nil 87 | } 88 | 89 | // PostComment implements the VideoCenterImpl interface. 90 | func (s *VideoCenterImpl) PostComment(ctx context.Context, req *kitex_gen.PostCommentRequest) (*kitex_gen.PostCommentResponse, error) { 91 | comment, err := service.VideoCenter{}.PostComment(req) 92 | if err != nil { 93 | return nil, err 94 | } 95 | return &kitex_gen.PostCommentResponse{Comment: comment}, nil 96 | } 97 | 98 | // DeleteComment implements the VideoCenterImpl interface. 99 | func (s *VideoCenterImpl) DeleteComment(ctx context.Context, req *kitex_gen.DeleteCommentRequest) (*kitex_gen.BasicResponse, error) { 100 | err := service.VideoCenter{}.DeleteComment(req.Uuid) 101 | if err != nil { 102 | return &kitex_gen.BasicResponse{ 103 | StatusCode: -1, 104 | StatusMsg: "delete comment wrong", 105 | }, err 106 | } 107 | return &kitex_gen.BasicResponse{ 108 | StatusCode: 0, 109 | StatusMsg: "success", 110 | }, nil 111 | } 112 | 113 | // GetComment implements the VideoCenterImpl interface. 114 | func (s *VideoCenterImpl) GetComment(ctx context.Context, req *kitex_gen.GetCommentRequest) (*kitex_gen.GetCommentResponse, error) { 115 | comments, err := service.VideoCenter{}.GetComment(req.VideoId) 116 | if err != nil { 117 | return nil, err 118 | } 119 | return &kitex_gen.GetCommentResponse{Comments: comments}, nil 120 | } 121 | 122 | // IsFavorite implements the VideoCenterImpl interface. 123 | func (s *VideoCenterImpl) IsFavorite(ctx context.Context, req *kitex_gen.IsFavoriteRequest) (*kitex_gen.BasicResponse, error) { 124 | res := service.VideoCenter{}.IsFavorite(req.UserId, req.VideoId) 125 | return &kitex_gen.BasicResponse{StatusMsg: fmt.Sprint(res), StatusCode: 0}, nil 126 | } 127 | -------------------------------------------------------------------------------- /video_service/idl/videocenter.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package video; 4 | 5 | option go_package="/"; 6 | 7 | message BasicResponse{ 8 | int64 status_code = 1; 9 | string status_msg = 2; 10 | } 11 | 12 | message PublishRequest{ 13 | int64 user_id = 1; 14 | string play_url = 2; 15 | string cover_url = 3; 16 | string title = 4; 17 | } 18 | 19 | message PublishResponse{ 20 | int64 status_code = 1; 21 | string status_msg = 2; 22 | int64 uuid = 3; 23 | } 24 | 25 | message DeleteRequest{ 26 | int64 user_id = 1; 27 | int64 video_id = 2; 28 | string content = 3; 29 | } 30 | 31 | message FeedRequest{ 32 | int64 last_time = 1; 33 | } 34 | 35 | message FeedResponse{ 36 | repeated Video videos = 1; 37 | } 38 | 39 | message VideoListRequest { 40 | int64 user_id = 1; 41 | } 42 | 43 | message VideoListResponse{ 44 | repeated Video videos = 1; 45 | } 46 | 47 | message LikeRequest{ 48 | int64 user_id = 1; 49 | int64 video_id = 2; 50 | int32 action_type = 3; 51 | } 52 | 53 | message GetVideoRequest { 54 | int64 uuid = 1; 55 | } 56 | 57 | message GetVideoResponse { 58 | Video video = 1; 59 | } 60 | 61 | message GetFavoriteVideosResponse{ 62 | repeated Video videos = 1; 63 | } 64 | 65 | message PostCommentRequest { 66 | int64 user_id = 1; 67 | int64 video_id = 2; 68 | string content = 3; 69 | } 70 | 71 | message PostCommentResponse{ 72 | Comment comment = 1; 73 | } 74 | 75 | message DeleteCommentRequest { 76 | int64 uuid = 1; 77 | } 78 | 79 | message GetCommentRequest{ 80 | int64 video_id = 1; 81 | } 82 | 83 | message GetCommentResponse{ 84 | repeated Comment comments = 1; 85 | } 86 | 87 | message IsFavoriteRequest{ 88 | int64 user_id = 1; 89 | int64 video_id = 2; 90 | } 91 | 92 | message IsFavoriteResponse { 93 | int64 status_code = 1; 94 | bool res = 2; 95 | } 96 | 97 | service VideoCenter { 98 | rpc Publish(PublishRequest) returns (PublishResponse); 99 | rpc Delete(DeleteRequest) returns (BasicResponse); 100 | rpc Feed(FeedRequest) returns (FeedResponse); 101 | rpc VideoList(VideoListRequest) returns (VideoListResponse); 102 | rpc Like(LikeRequest) returns (BasicResponse); 103 | rpc GetVideo(GetVideoRequest) returns (GetVideoResponse); 104 | rpc GetFavoriteVideo(GetVideoRequest) returns (GetFavoriteVideosResponse); 105 | rpc PostComment(PostCommentRequest) returns (PostCommentResponse); 106 | rpc DeleteComment(DeleteCommentRequest) returns (BasicResponse); 107 | rpc GetComment(GetCommentRequest) returns (GetCommentResponse); 108 | rpc IsFavorite(IsFavoriteRequest) returns (BasicResponse); 109 | } 110 | 111 | message Comment { 112 | int64 uuid = 1; 113 | int64 user_id = 2; 114 | int64 video_id = 3; 115 | string create_date = 4; 116 | string content = 5; 117 | } 118 | 119 | message Video { 120 | int64 uuid = 1; 121 | int64 user_id = 2; 122 | string play_url = 3; 123 | string cover_url = 4; 124 | int64 favorite_count = 5; 125 | int64 comment_count = 6; 126 | string title = 7; 127 | int64 create_time = 8; 128 | } -------------------------------------------------------------------------------- /video_service/kitex.yaml: -------------------------------------------------------------------------------- 1 | kitexinfo: 2 | ServiceName: 'videocenter' 3 | ToolVersion: 'v0.4.4' 4 | 5 | -------------------------------------------------------------------------------- /video_service/kitex_gen/videocenter/client.go: -------------------------------------------------------------------------------- 1 | // Code generated by Kitex v0.4.4. DO NOT EDIT. 2 | 3 | package videocenter 4 | 5 | import ( 6 | "context" 7 | kitex_gen "dousheng_server/video_service/kitex_gen" 8 | client "github.com/cloudwego/kitex/client" 9 | callopt "github.com/cloudwego/kitex/client/callopt" 10 | ) 11 | 12 | // Client is designed to provide IDL-compatible methods with call-option parameter for kitex framework. 13 | type Client interface { 14 | Publish(ctx context.Context, Req *kitex_gen.PublishRequest, callOptions ...callopt.Option) (r *kitex_gen.PublishResponse, err error) 15 | Delete(ctx context.Context, Req *kitex_gen.DeleteRequest, callOptions ...callopt.Option) (r *kitex_gen.BasicResponse, err error) 16 | Feed(ctx context.Context, Req *kitex_gen.FeedRequest, callOptions ...callopt.Option) (r *kitex_gen.FeedResponse, err error) 17 | VideoList(ctx context.Context, Req *kitex_gen.VideoListRequest, callOptions ...callopt.Option) (r *kitex_gen.VideoListResponse, err error) 18 | Like(ctx context.Context, Req *kitex_gen.LikeRequest, callOptions ...callopt.Option) (r *kitex_gen.BasicResponse, err error) 19 | GetVideo(ctx context.Context, Req *kitex_gen.GetVideoRequest, callOptions ...callopt.Option) (r *kitex_gen.GetVideoResponse, err error) 20 | GetFavoriteVideo(ctx context.Context, Req *kitex_gen.GetVideoRequest, callOptions ...callopt.Option) (r *kitex_gen.GetFavoriteVideosResponse, err error) 21 | PostComment(ctx context.Context, Req *kitex_gen.PostCommentRequest, callOptions ...callopt.Option) (r *kitex_gen.PostCommentResponse, err error) 22 | DeleteComment(ctx context.Context, Req *kitex_gen.DeleteCommentRequest, callOptions ...callopt.Option) (r *kitex_gen.BasicResponse, err error) 23 | GetComment(ctx context.Context, Req *kitex_gen.GetCommentRequest, callOptions ...callopt.Option) (r *kitex_gen.GetCommentResponse, err error) 24 | IsFavorite(ctx context.Context, Req *kitex_gen.IsFavoriteRequest, callOptions ...callopt.Option) (r *kitex_gen.BasicResponse, err error) 25 | } 26 | 27 | // NewClient creates a client for the service defined in IDL. 28 | func NewClient(destService string, opts ...client.Option) (Client, error) { 29 | var options []client.Option 30 | options = append(options, client.WithDestService(destService)) 31 | 32 | options = append(options, opts...) 33 | 34 | kc, err := client.NewClient(serviceInfo(), options...) 35 | if err != nil { 36 | return nil, err 37 | } 38 | return &kVideoCenterClient{ 39 | kClient: newServiceClient(kc), 40 | }, nil 41 | } 42 | 43 | // MustNewClient creates a client for the service defined in IDL. It panics if any error occurs. 44 | func MustNewClient(destService string, opts ...client.Option) Client { 45 | kc, err := NewClient(destService, opts...) 46 | if err != nil { 47 | panic(err) 48 | } 49 | return kc 50 | } 51 | 52 | type kVideoCenterClient struct { 53 | *kClient 54 | } 55 | 56 | func (p *kVideoCenterClient) Publish(ctx context.Context, Req *kitex_gen.PublishRequest, callOptions ...callopt.Option) (r *kitex_gen.PublishResponse, err error) { 57 | ctx = client.NewCtxWithCallOptions(ctx, callOptions) 58 | return p.kClient.Publish(ctx, Req) 59 | } 60 | 61 | func (p *kVideoCenterClient) Delete(ctx context.Context, Req *kitex_gen.DeleteRequest, callOptions ...callopt.Option) (r *kitex_gen.BasicResponse, err error) { 62 | ctx = client.NewCtxWithCallOptions(ctx, callOptions) 63 | return p.kClient.Delete(ctx, Req) 64 | } 65 | 66 | func (p *kVideoCenterClient) Feed(ctx context.Context, Req *kitex_gen.FeedRequest, callOptions ...callopt.Option) (r *kitex_gen.FeedResponse, err error) { 67 | ctx = client.NewCtxWithCallOptions(ctx, callOptions) 68 | return p.kClient.Feed(ctx, Req) 69 | } 70 | 71 | func (p *kVideoCenterClient) VideoList(ctx context.Context, Req *kitex_gen.VideoListRequest, callOptions ...callopt.Option) (r *kitex_gen.VideoListResponse, err error) { 72 | ctx = client.NewCtxWithCallOptions(ctx, callOptions) 73 | return p.kClient.VideoList(ctx, Req) 74 | } 75 | 76 | func (p *kVideoCenterClient) Like(ctx context.Context, Req *kitex_gen.LikeRequest, callOptions ...callopt.Option) (r *kitex_gen.BasicResponse, err error) { 77 | ctx = client.NewCtxWithCallOptions(ctx, callOptions) 78 | return p.kClient.Like(ctx, Req) 79 | } 80 | 81 | func (p *kVideoCenterClient) GetVideo(ctx context.Context, Req *kitex_gen.GetVideoRequest, callOptions ...callopt.Option) (r *kitex_gen.GetVideoResponse, err error) { 82 | ctx = client.NewCtxWithCallOptions(ctx, callOptions) 83 | return p.kClient.GetVideo(ctx, Req) 84 | } 85 | 86 | func (p *kVideoCenterClient) GetFavoriteVideo(ctx context.Context, Req *kitex_gen.GetVideoRequest, callOptions ...callopt.Option) (r *kitex_gen.GetFavoriteVideosResponse, err error) { 87 | ctx = client.NewCtxWithCallOptions(ctx, callOptions) 88 | return p.kClient.GetFavoriteVideo(ctx, Req) 89 | } 90 | 91 | func (p *kVideoCenterClient) PostComment(ctx context.Context, Req *kitex_gen.PostCommentRequest, callOptions ...callopt.Option) (r *kitex_gen.PostCommentResponse, err error) { 92 | ctx = client.NewCtxWithCallOptions(ctx, callOptions) 93 | return p.kClient.PostComment(ctx, Req) 94 | } 95 | 96 | func (p *kVideoCenterClient) DeleteComment(ctx context.Context, Req *kitex_gen.DeleteCommentRequest, callOptions ...callopt.Option) (r *kitex_gen.BasicResponse, err error) { 97 | ctx = client.NewCtxWithCallOptions(ctx, callOptions) 98 | return p.kClient.DeleteComment(ctx, Req) 99 | } 100 | 101 | func (p *kVideoCenterClient) GetComment(ctx context.Context, Req *kitex_gen.GetCommentRequest, callOptions ...callopt.Option) (r *kitex_gen.GetCommentResponse, err error) { 102 | ctx = client.NewCtxWithCallOptions(ctx, callOptions) 103 | return p.kClient.GetComment(ctx, Req) 104 | } 105 | 106 | func (p *kVideoCenterClient) IsFavorite(ctx context.Context, Req *kitex_gen.IsFavoriteRequest, callOptions ...callopt.Option) (r *kitex_gen.BasicResponse, err error) { 107 | ctx = client.NewCtxWithCallOptions(ctx, callOptions) 108 | return p.kClient.IsFavorite(ctx, Req) 109 | } 110 | -------------------------------------------------------------------------------- /video_service/kitex_gen/videocenter/invoker.go: -------------------------------------------------------------------------------- 1 | // Code generated by Kitex v0.4.4. DO NOT EDIT. 2 | 3 | package videocenter 4 | 5 | import ( 6 | kitex_gen "dousheng_server/video_service/kitex_gen" 7 | server "github.com/cloudwego/kitex/server" 8 | ) 9 | 10 | // NewInvoker creates a server.Invoker with the given handler and options. 11 | func NewInvoker(handler kitex_gen.VideoCenter, opts ...server.Option) server.Invoker { 12 | var options []server.Option 13 | 14 | options = append(options, opts...) 15 | 16 | s := server.NewInvoker(options...) 17 | if err := s.RegisterService(serviceInfo(), handler); err != nil { 18 | panic(err) 19 | } 20 | if err := s.Init(); err != nil { 21 | panic(err) 22 | } 23 | return s 24 | } 25 | -------------------------------------------------------------------------------- /video_service/kitex_gen/videocenter/server.go: -------------------------------------------------------------------------------- 1 | // Code generated by Kitex v0.4.4. DO NOT EDIT. 2 | package videocenter 3 | 4 | import ( 5 | kitex_gen "dousheng_server/video_service/kitex_gen" 6 | server "github.com/cloudwego/kitex/server" 7 | ) 8 | 9 | // NewServer creates a server.Server with the given handler and options. 10 | func NewServer(handler kitex_gen.VideoCenter, opts ...server.Option) server.Server { 11 | var options []server.Option 12 | 13 | options = append(options, opts...) 14 | 15 | svr := server.NewServer(options...) 16 | if err := svr.RegisterService(serviceInfo(), handler); err != nil { 17 | panic(err) 18 | } 19 | return svr 20 | } 21 | -------------------------------------------------------------------------------- /video_service/kitex_gen/videocenter/videocenter.go: -------------------------------------------------------------------------------- 1 | // Code generated by Kitex v0.4.4. DO NOT EDIT. 2 | 3 | package videocenter 4 | 5 | import ( 6 | "context" 7 | kitex_gen "dousheng_server/video_service/kitex_gen" 8 | "fmt" 9 | client "github.com/cloudwego/kitex/client" 10 | kitex "github.com/cloudwego/kitex/pkg/serviceinfo" 11 | streaming "github.com/cloudwego/kitex/pkg/streaming" 12 | proto "google.golang.org/protobuf/proto" 13 | ) 14 | 15 | func serviceInfo() *kitex.ServiceInfo { 16 | return videoCenterServiceInfo 17 | } 18 | 19 | var videoCenterServiceInfo = NewServiceInfo() 20 | 21 | func NewServiceInfo() *kitex.ServiceInfo { 22 | serviceName := "VideoCenter" 23 | handlerType := (*kitex_gen.VideoCenter)(nil) 24 | methods := map[string]kitex.MethodInfo{ 25 | "Publish": kitex.NewMethodInfo(publishHandler, newPublishArgs, newPublishResult, false), 26 | "Delete": kitex.NewMethodInfo(deleteHandler, newDeleteArgs, newDeleteResult, false), 27 | "Feed": kitex.NewMethodInfo(feedHandler, newFeedArgs, newFeedResult, false), 28 | "VideoList": kitex.NewMethodInfo(videoListHandler, newVideoListArgs, newVideoListResult, false), 29 | "Like": kitex.NewMethodInfo(likeHandler, newLikeArgs, newLikeResult, false), 30 | "GetVideo": kitex.NewMethodInfo(getVideoHandler, newGetVideoArgs, newGetVideoResult, false), 31 | "GetFavoriteVideo": kitex.NewMethodInfo(getFavoriteVideoHandler, newGetFavoriteVideoArgs, newGetFavoriteVideoResult, false), 32 | "PostComment": kitex.NewMethodInfo(postCommentHandler, newPostCommentArgs, newPostCommentResult, false), 33 | "DeleteComment": kitex.NewMethodInfo(deleteCommentHandler, newDeleteCommentArgs, newDeleteCommentResult, false), 34 | "GetComment": kitex.NewMethodInfo(getCommentHandler, newGetCommentArgs, newGetCommentResult, false), 35 | "IsFavorite": kitex.NewMethodInfo(isFavoriteHandler, newIsFavoriteArgs, newIsFavoriteResult, false), 36 | } 37 | extra := map[string]interface{}{ 38 | "PackageName": "video", 39 | } 40 | svcInfo := &kitex.ServiceInfo{ 41 | ServiceName: serviceName, 42 | HandlerType: handlerType, 43 | Methods: methods, 44 | PayloadCodec: kitex.Protobuf, 45 | KiteXGenVersion: "v0.4.4", 46 | Extra: extra, 47 | } 48 | return svcInfo 49 | } 50 | 51 | func publishHandler(ctx context.Context, handler interface{}, arg, result interface{}) error { 52 | switch s := arg.(type) { 53 | case *streaming.Args: 54 | st := s.Stream 55 | req := new(kitex_gen.PublishRequest) 56 | if err := st.RecvMsg(req); err != nil { 57 | return err 58 | } 59 | resp, err := handler.(kitex_gen.VideoCenter).Publish(ctx, req) 60 | if err != nil { 61 | return err 62 | } 63 | if err := st.SendMsg(resp); err != nil { 64 | return err 65 | } 66 | case *PublishArgs: 67 | success, err := handler.(kitex_gen.VideoCenter).Publish(ctx, s.Req) 68 | if err != nil { 69 | return err 70 | } 71 | realResult := result.(*PublishResult) 72 | realResult.Success = success 73 | } 74 | return nil 75 | } 76 | func newPublishArgs() interface{} { 77 | return &PublishArgs{} 78 | } 79 | 80 | func newPublishResult() interface{} { 81 | return &PublishResult{} 82 | } 83 | 84 | type PublishArgs struct { 85 | Req *kitex_gen.PublishRequest 86 | } 87 | 88 | func (p *PublishArgs) FastRead(buf []byte, _type int8, number int32) (n int, err error) { 89 | if !p.IsSetReq() { 90 | p.Req = new(kitex_gen.PublishRequest) 91 | } 92 | return p.Req.FastRead(buf, _type, number) 93 | } 94 | 95 | func (p *PublishArgs) FastWrite(buf []byte) (n int) { 96 | if !p.IsSetReq() { 97 | return 0 98 | } 99 | return p.Req.FastWrite(buf) 100 | } 101 | 102 | func (p *PublishArgs) Size() (n int) { 103 | if !p.IsSetReq() { 104 | return 0 105 | } 106 | return p.Req.Size() 107 | } 108 | 109 | func (p *PublishArgs) Marshal(out []byte) ([]byte, error) { 110 | if !p.IsSetReq() { 111 | return out, fmt.Errorf("No req in PublishArgs") 112 | } 113 | return proto.Marshal(p.Req) 114 | } 115 | 116 | func (p *PublishArgs) Unmarshal(in []byte) error { 117 | msg := new(kitex_gen.PublishRequest) 118 | if err := proto.Unmarshal(in, msg); err != nil { 119 | return err 120 | } 121 | p.Req = msg 122 | return nil 123 | } 124 | 125 | var PublishArgs_Req_DEFAULT *kitex_gen.PublishRequest 126 | 127 | func (p *PublishArgs) GetReq() *kitex_gen.PublishRequest { 128 | if !p.IsSetReq() { 129 | return PublishArgs_Req_DEFAULT 130 | } 131 | return p.Req 132 | } 133 | 134 | func (p *PublishArgs) IsSetReq() bool { 135 | return p.Req != nil 136 | } 137 | 138 | type PublishResult struct { 139 | Success *kitex_gen.PublishResponse 140 | } 141 | 142 | var PublishResult_Success_DEFAULT *kitex_gen.PublishResponse 143 | 144 | func (p *PublishResult) FastRead(buf []byte, _type int8, number int32) (n int, err error) { 145 | if !p.IsSetSuccess() { 146 | p.Success = new(kitex_gen.PublishResponse) 147 | } 148 | return p.Success.FastRead(buf, _type, number) 149 | } 150 | 151 | func (p *PublishResult) FastWrite(buf []byte) (n int) { 152 | if !p.IsSetSuccess() { 153 | return 0 154 | } 155 | return p.Success.FastWrite(buf) 156 | } 157 | 158 | func (p *PublishResult) Size() (n int) { 159 | if !p.IsSetSuccess() { 160 | return 0 161 | } 162 | return p.Success.Size() 163 | } 164 | 165 | func (p *PublishResult) Marshal(out []byte) ([]byte, error) { 166 | if !p.IsSetSuccess() { 167 | return out, fmt.Errorf("No req in PublishResult") 168 | } 169 | return proto.Marshal(p.Success) 170 | } 171 | 172 | func (p *PublishResult) Unmarshal(in []byte) error { 173 | msg := new(kitex_gen.PublishResponse) 174 | if err := proto.Unmarshal(in, msg); err != nil { 175 | return err 176 | } 177 | p.Success = msg 178 | return nil 179 | } 180 | 181 | func (p *PublishResult) GetSuccess() *kitex_gen.PublishResponse { 182 | if !p.IsSetSuccess() { 183 | return PublishResult_Success_DEFAULT 184 | } 185 | return p.Success 186 | } 187 | 188 | func (p *PublishResult) SetSuccess(x interface{}) { 189 | p.Success = x.(*kitex_gen.PublishResponse) 190 | } 191 | 192 | func (p *PublishResult) IsSetSuccess() bool { 193 | return p.Success != nil 194 | } 195 | 196 | func deleteHandler(ctx context.Context, handler interface{}, arg, result interface{}) error { 197 | switch s := arg.(type) { 198 | case *streaming.Args: 199 | st := s.Stream 200 | req := new(kitex_gen.DeleteRequest) 201 | if err := st.RecvMsg(req); err != nil { 202 | return err 203 | } 204 | resp, err := handler.(kitex_gen.VideoCenter).Delete(ctx, req) 205 | if err != nil { 206 | return err 207 | } 208 | if err := st.SendMsg(resp); err != nil { 209 | return err 210 | } 211 | case *DeleteArgs: 212 | success, err := handler.(kitex_gen.VideoCenter).Delete(ctx, s.Req) 213 | if err != nil { 214 | return err 215 | } 216 | realResult := result.(*DeleteResult) 217 | realResult.Success = success 218 | } 219 | return nil 220 | } 221 | func newDeleteArgs() interface{} { 222 | return &DeleteArgs{} 223 | } 224 | 225 | func newDeleteResult() interface{} { 226 | return &DeleteResult{} 227 | } 228 | 229 | type DeleteArgs struct { 230 | Req *kitex_gen.DeleteRequest 231 | } 232 | 233 | func (p *DeleteArgs) FastRead(buf []byte, _type int8, number int32) (n int, err error) { 234 | if !p.IsSetReq() { 235 | p.Req = new(kitex_gen.DeleteRequest) 236 | } 237 | return p.Req.FastRead(buf, _type, number) 238 | } 239 | 240 | func (p *DeleteArgs) FastWrite(buf []byte) (n int) { 241 | if !p.IsSetReq() { 242 | return 0 243 | } 244 | return p.Req.FastWrite(buf) 245 | } 246 | 247 | func (p *DeleteArgs) Size() (n int) { 248 | if !p.IsSetReq() { 249 | return 0 250 | } 251 | return p.Req.Size() 252 | } 253 | 254 | func (p *DeleteArgs) Marshal(out []byte) ([]byte, error) { 255 | if !p.IsSetReq() { 256 | return out, fmt.Errorf("No req in DeleteArgs") 257 | } 258 | return proto.Marshal(p.Req) 259 | } 260 | 261 | func (p *DeleteArgs) Unmarshal(in []byte) error { 262 | msg := new(kitex_gen.DeleteRequest) 263 | if err := proto.Unmarshal(in, msg); err != nil { 264 | return err 265 | } 266 | p.Req = msg 267 | return nil 268 | } 269 | 270 | var DeleteArgs_Req_DEFAULT *kitex_gen.DeleteRequest 271 | 272 | func (p *DeleteArgs) GetReq() *kitex_gen.DeleteRequest { 273 | if !p.IsSetReq() { 274 | return DeleteArgs_Req_DEFAULT 275 | } 276 | return p.Req 277 | } 278 | 279 | func (p *DeleteArgs) IsSetReq() bool { 280 | return p.Req != nil 281 | } 282 | 283 | type DeleteResult struct { 284 | Success *kitex_gen.BasicResponse 285 | } 286 | 287 | var DeleteResult_Success_DEFAULT *kitex_gen.BasicResponse 288 | 289 | func (p *DeleteResult) FastRead(buf []byte, _type int8, number int32) (n int, err error) { 290 | if !p.IsSetSuccess() { 291 | p.Success = new(kitex_gen.BasicResponse) 292 | } 293 | return p.Success.FastRead(buf, _type, number) 294 | } 295 | 296 | func (p *DeleteResult) FastWrite(buf []byte) (n int) { 297 | if !p.IsSetSuccess() { 298 | return 0 299 | } 300 | return p.Success.FastWrite(buf) 301 | } 302 | 303 | func (p *DeleteResult) Size() (n int) { 304 | if !p.IsSetSuccess() { 305 | return 0 306 | } 307 | return p.Success.Size() 308 | } 309 | 310 | func (p *DeleteResult) Marshal(out []byte) ([]byte, error) { 311 | if !p.IsSetSuccess() { 312 | return out, fmt.Errorf("No req in DeleteResult") 313 | } 314 | return proto.Marshal(p.Success) 315 | } 316 | 317 | func (p *DeleteResult) Unmarshal(in []byte) error { 318 | msg := new(kitex_gen.BasicResponse) 319 | if err := proto.Unmarshal(in, msg); err != nil { 320 | return err 321 | } 322 | p.Success = msg 323 | return nil 324 | } 325 | 326 | func (p *DeleteResult) GetSuccess() *kitex_gen.BasicResponse { 327 | if !p.IsSetSuccess() { 328 | return DeleteResult_Success_DEFAULT 329 | } 330 | return p.Success 331 | } 332 | 333 | func (p *DeleteResult) SetSuccess(x interface{}) { 334 | p.Success = x.(*kitex_gen.BasicResponse) 335 | } 336 | 337 | func (p *DeleteResult) IsSetSuccess() bool { 338 | return p.Success != nil 339 | } 340 | 341 | func feedHandler(ctx context.Context, handler interface{}, arg, result interface{}) error { 342 | switch s := arg.(type) { 343 | case *streaming.Args: 344 | st := s.Stream 345 | req := new(kitex_gen.FeedRequest) 346 | if err := st.RecvMsg(req); err != nil { 347 | return err 348 | } 349 | resp, err := handler.(kitex_gen.VideoCenter).Feed(ctx, req) 350 | if err != nil { 351 | return err 352 | } 353 | if err := st.SendMsg(resp); err != nil { 354 | return err 355 | } 356 | case *FeedArgs: 357 | success, err := handler.(kitex_gen.VideoCenter).Feed(ctx, s.Req) 358 | if err != nil { 359 | return err 360 | } 361 | realResult := result.(*FeedResult) 362 | realResult.Success = success 363 | } 364 | return nil 365 | } 366 | func newFeedArgs() interface{} { 367 | return &FeedArgs{} 368 | } 369 | 370 | func newFeedResult() interface{} { 371 | return &FeedResult{} 372 | } 373 | 374 | type FeedArgs struct { 375 | Req *kitex_gen.FeedRequest 376 | } 377 | 378 | func (p *FeedArgs) FastRead(buf []byte, _type int8, number int32) (n int, err error) { 379 | if !p.IsSetReq() { 380 | p.Req = new(kitex_gen.FeedRequest) 381 | } 382 | return p.Req.FastRead(buf, _type, number) 383 | } 384 | 385 | func (p *FeedArgs) FastWrite(buf []byte) (n int) { 386 | if !p.IsSetReq() { 387 | return 0 388 | } 389 | return p.Req.FastWrite(buf) 390 | } 391 | 392 | func (p *FeedArgs) Size() (n int) { 393 | if !p.IsSetReq() { 394 | return 0 395 | } 396 | return p.Req.Size() 397 | } 398 | 399 | func (p *FeedArgs) Marshal(out []byte) ([]byte, error) { 400 | if !p.IsSetReq() { 401 | return out, fmt.Errorf("No req in FeedArgs") 402 | } 403 | return proto.Marshal(p.Req) 404 | } 405 | 406 | func (p *FeedArgs) Unmarshal(in []byte) error { 407 | msg := new(kitex_gen.FeedRequest) 408 | if err := proto.Unmarshal(in, msg); err != nil { 409 | return err 410 | } 411 | p.Req = msg 412 | return nil 413 | } 414 | 415 | var FeedArgs_Req_DEFAULT *kitex_gen.FeedRequest 416 | 417 | func (p *FeedArgs) GetReq() *kitex_gen.FeedRequest { 418 | if !p.IsSetReq() { 419 | return FeedArgs_Req_DEFAULT 420 | } 421 | return p.Req 422 | } 423 | 424 | func (p *FeedArgs) IsSetReq() bool { 425 | return p.Req != nil 426 | } 427 | 428 | type FeedResult struct { 429 | Success *kitex_gen.FeedResponse 430 | } 431 | 432 | var FeedResult_Success_DEFAULT *kitex_gen.FeedResponse 433 | 434 | func (p *FeedResult) FastRead(buf []byte, _type int8, number int32) (n int, err error) { 435 | if !p.IsSetSuccess() { 436 | p.Success = new(kitex_gen.FeedResponse) 437 | } 438 | return p.Success.FastRead(buf, _type, number) 439 | } 440 | 441 | func (p *FeedResult) FastWrite(buf []byte) (n int) { 442 | if !p.IsSetSuccess() { 443 | return 0 444 | } 445 | return p.Success.FastWrite(buf) 446 | } 447 | 448 | func (p *FeedResult) Size() (n int) { 449 | if !p.IsSetSuccess() { 450 | return 0 451 | } 452 | return p.Success.Size() 453 | } 454 | 455 | func (p *FeedResult) Marshal(out []byte) ([]byte, error) { 456 | if !p.IsSetSuccess() { 457 | return out, fmt.Errorf("No req in FeedResult") 458 | } 459 | return proto.Marshal(p.Success) 460 | } 461 | 462 | func (p *FeedResult) Unmarshal(in []byte) error { 463 | msg := new(kitex_gen.FeedResponse) 464 | if err := proto.Unmarshal(in, msg); err != nil { 465 | return err 466 | } 467 | p.Success = msg 468 | return nil 469 | } 470 | 471 | func (p *FeedResult) GetSuccess() *kitex_gen.FeedResponse { 472 | if !p.IsSetSuccess() { 473 | return FeedResult_Success_DEFAULT 474 | } 475 | return p.Success 476 | } 477 | 478 | func (p *FeedResult) SetSuccess(x interface{}) { 479 | p.Success = x.(*kitex_gen.FeedResponse) 480 | } 481 | 482 | func (p *FeedResult) IsSetSuccess() bool { 483 | return p.Success != nil 484 | } 485 | 486 | func videoListHandler(ctx context.Context, handler interface{}, arg, result interface{}) error { 487 | switch s := arg.(type) { 488 | case *streaming.Args: 489 | st := s.Stream 490 | req := new(kitex_gen.VideoListRequest) 491 | if err := st.RecvMsg(req); err != nil { 492 | return err 493 | } 494 | resp, err := handler.(kitex_gen.VideoCenter).VideoList(ctx, req) 495 | if err != nil { 496 | return err 497 | } 498 | if err := st.SendMsg(resp); err != nil { 499 | return err 500 | } 501 | case *VideoListArgs: 502 | success, err := handler.(kitex_gen.VideoCenter).VideoList(ctx, s.Req) 503 | if err != nil { 504 | return err 505 | } 506 | realResult := result.(*VideoListResult) 507 | realResult.Success = success 508 | } 509 | return nil 510 | } 511 | func newVideoListArgs() interface{} { 512 | return &VideoListArgs{} 513 | } 514 | 515 | func newVideoListResult() interface{} { 516 | return &VideoListResult{} 517 | } 518 | 519 | type VideoListArgs struct { 520 | Req *kitex_gen.VideoListRequest 521 | } 522 | 523 | func (p *VideoListArgs) FastRead(buf []byte, _type int8, number int32) (n int, err error) { 524 | if !p.IsSetReq() { 525 | p.Req = new(kitex_gen.VideoListRequest) 526 | } 527 | return p.Req.FastRead(buf, _type, number) 528 | } 529 | 530 | func (p *VideoListArgs) FastWrite(buf []byte) (n int) { 531 | if !p.IsSetReq() { 532 | return 0 533 | } 534 | return p.Req.FastWrite(buf) 535 | } 536 | 537 | func (p *VideoListArgs) Size() (n int) { 538 | if !p.IsSetReq() { 539 | return 0 540 | } 541 | return p.Req.Size() 542 | } 543 | 544 | func (p *VideoListArgs) Marshal(out []byte) ([]byte, error) { 545 | if !p.IsSetReq() { 546 | return out, fmt.Errorf("No req in VideoListArgs") 547 | } 548 | return proto.Marshal(p.Req) 549 | } 550 | 551 | func (p *VideoListArgs) Unmarshal(in []byte) error { 552 | msg := new(kitex_gen.VideoListRequest) 553 | if err := proto.Unmarshal(in, msg); err != nil { 554 | return err 555 | } 556 | p.Req = msg 557 | return nil 558 | } 559 | 560 | var VideoListArgs_Req_DEFAULT *kitex_gen.VideoListRequest 561 | 562 | func (p *VideoListArgs) GetReq() *kitex_gen.VideoListRequest { 563 | if !p.IsSetReq() { 564 | return VideoListArgs_Req_DEFAULT 565 | } 566 | return p.Req 567 | } 568 | 569 | func (p *VideoListArgs) IsSetReq() bool { 570 | return p.Req != nil 571 | } 572 | 573 | type VideoListResult struct { 574 | Success *kitex_gen.VideoListResponse 575 | } 576 | 577 | var VideoListResult_Success_DEFAULT *kitex_gen.VideoListResponse 578 | 579 | func (p *VideoListResult) FastRead(buf []byte, _type int8, number int32) (n int, err error) { 580 | if !p.IsSetSuccess() { 581 | p.Success = new(kitex_gen.VideoListResponse) 582 | } 583 | return p.Success.FastRead(buf, _type, number) 584 | } 585 | 586 | func (p *VideoListResult) FastWrite(buf []byte) (n int) { 587 | if !p.IsSetSuccess() { 588 | return 0 589 | } 590 | return p.Success.FastWrite(buf) 591 | } 592 | 593 | func (p *VideoListResult) Size() (n int) { 594 | if !p.IsSetSuccess() { 595 | return 0 596 | } 597 | return p.Success.Size() 598 | } 599 | 600 | func (p *VideoListResult) Marshal(out []byte) ([]byte, error) { 601 | if !p.IsSetSuccess() { 602 | return out, fmt.Errorf("No req in VideoListResult") 603 | } 604 | return proto.Marshal(p.Success) 605 | } 606 | 607 | func (p *VideoListResult) Unmarshal(in []byte) error { 608 | msg := new(kitex_gen.VideoListResponse) 609 | if err := proto.Unmarshal(in, msg); err != nil { 610 | return err 611 | } 612 | p.Success = msg 613 | return nil 614 | } 615 | 616 | func (p *VideoListResult) GetSuccess() *kitex_gen.VideoListResponse { 617 | if !p.IsSetSuccess() { 618 | return VideoListResult_Success_DEFAULT 619 | } 620 | return p.Success 621 | } 622 | 623 | func (p *VideoListResult) SetSuccess(x interface{}) { 624 | p.Success = x.(*kitex_gen.VideoListResponse) 625 | } 626 | 627 | func (p *VideoListResult) IsSetSuccess() bool { 628 | return p.Success != nil 629 | } 630 | 631 | func likeHandler(ctx context.Context, handler interface{}, arg, result interface{}) error { 632 | switch s := arg.(type) { 633 | case *streaming.Args: 634 | st := s.Stream 635 | req := new(kitex_gen.LikeRequest) 636 | if err := st.RecvMsg(req); err != nil { 637 | return err 638 | } 639 | resp, err := handler.(kitex_gen.VideoCenter).Like(ctx, req) 640 | if err != nil { 641 | return err 642 | } 643 | if err := st.SendMsg(resp); err != nil { 644 | return err 645 | } 646 | case *LikeArgs: 647 | success, err := handler.(kitex_gen.VideoCenter).Like(ctx, s.Req) 648 | if err != nil { 649 | return err 650 | } 651 | realResult := result.(*LikeResult) 652 | realResult.Success = success 653 | } 654 | return nil 655 | } 656 | func newLikeArgs() interface{} { 657 | return &LikeArgs{} 658 | } 659 | 660 | func newLikeResult() interface{} { 661 | return &LikeResult{} 662 | } 663 | 664 | type LikeArgs struct { 665 | Req *kitex_gen.LikeRequest 666 | } 667 | 668 | func (p *LikeArgs) FastRead(buf []byte, _type int8, number int32) (n int, err error) { 669 | if !p.IsSetReq() { 670 | p.Req = new(kitex_gen.LikeRequest) 671 | } 672 | return p.Req.FastRead(buf, _type, number) 673 | } 674 | 675 | func (p *LikeArgs) FastWrite(buf []byte) (n int) { 676 | if !p.IsSetReq() { 677 | return 0 678 | } 679 | return p.Req.FastWrite(buf) 680 | } 681 | 682 | func (p *LikeArgs) Size() (n int) { 683 | if !p.IsSetReq() { 684 | return 0 685 | } 686 | return p.Req.Size() 687 | } 688 | 689 | func (p *LikeArgs) Marshal(out []byte) ([]byte, error) { 690 | if !p.IsSetReq() { 691 | return out, fmt.Errorf("No req in LikeArgs") 692 | } 693 | return proto.Marshal(p.Req) 694 | } 695 | 696 | func (p *LikeArgs) Unmarshal(in []byte) error { 697 | msg := new(kitex_gen.LikeRequest) 698 | if err := proto.Unmarshal(in, msg); err != nil { 699 | return err 700 | } 701 | p.Req = msg 702 | return nil 703 | } 704 | 705 | var LikeArgs_Req_DEFAULT *kitex_gen.LikeRequest 706 | 707 | func (p *LikeArgs) GetReq() *kitex_gen.LikeRequest { 708 | if !p.IsSetReq() { 709 | return LikeArgs_Req_DEFAULT 710 | } 711 | return p.Req 712 | } 713 | 714 | func (p *LikeArgs) IsSetReq() bool { 715 | return p.Req != nil 716 | } 717 | 718 | type LikeResult struct { 719 | Success *kitex_gen.BasicResponse 720 | } 721 | 722 | var LikeResult_Success_DEFAULT *kitex_gen.BasicResponse 723 | 724 | func (p *LikeResult) FastRead(buf []byte, _type int8, number int32) (n int, err error) { 725 | if !p.IsSetSuccess() { 726 | p.Success = new(kitex_gen.BasicResponse) 727 | } 728 | return p.Success.FastRead(buf, _type, number) 729 | } 730 | 731 | func (p *LikeResult) FastWrite(buf []byte) (n int) { 732 | if !p.IsSetSuccess() { 733 | return 0 734 | } 735 | return p.Success.FastWrite(buf) 736 | } 737 | 738 | func (p *LikeResult) Size() (n int) { 739 | if !p.IsSetSuccess() { 740 | return 0 741 | } 742 | return p.Success.Size() 743 | } 744 | 745 | func (p *LikeResult) Marshal(out []byte) ([]byte, error) { 746 | if !p.IsSetSuccess() { 747 | return out, fmt.Errorf("No req in LikeResult") 748 | } 749 | return proto.Marshal(p.Success) 750 | } 751 | 752 | func (p *LikeResult) Unmarshal(in []byte) error { 753 | msg := new(kitex_gen.BasicResponse) 754 | if err := proto.Unmarshal(in, msg); err != nil { 755 | return err 756 | } 757 | p.Success = msg 758 | return nil 759 | } 760 | 761 | func (p *LikeResult) GetSuccess() *kitex_gen.BasicResponse { 762 | if !p.IsSetSuccess() { 763 | return LikeResult_Success_DEFAULT 764 | } 765 | return p.Success 766 | } 767 | 768 | func (p *LikeResult) SetSuccess(x interface{}) { 769 | p.Success = x.(*kitex_gen.BasicResponse) 770 | } 771 | 772 | func (p *LikeResult) IsSetSuccess() bool { 773 | return p.Success != nil 774 | } 775 | 776 | func getVideoHandler(ctx context.Context, handler interface{}, arg, result interface{}) error { 777 | switch s := arg.(type) { 778 | case *streaming.Args: 779 | st := s.Stream 780 | req := new(kitex_gen.GetVideoRequest) 781 | if err := st.RecvMsg(req); err != nil { 782 | return err 783 | } 784 | resp, err := handler.(kitex_gen.VideoCenter).GetVideo(ctx, req) 785 | if err != nil { 786 | return err 787 | } 788 | if err := st.SendMsg(resp); err != nil { 789 | return err 790 | } 791 | case *GetVideoArgs: 792 | success, err := handler.(kitex_gen.VideoCenter).GetVideo(ctx, s.Req) 793 | if err != nil { 794 | return err 795 | } 796 | realResult := result.(*GetVideoResult) 797 | realResult.Success = success 798 | } 799 | return nil 800 | } 801 | func newGetVideoArgs() interface{} { 802 | return &GetVideoArgs{} 803 | } 804 | 805 | func newGetVideoResult() interface{} { 806 | return &GetVideoResult{} 807 | } 808 | 809 | type GetVideoArgs struct { 810 | Req *kitex_gen.GetVideoRequest 811 | } 812 | 813 | func (p *GetVideoArgs) FastRead(buf []byte, _type int8, number int32) (n int, err error) { 814 | if !p.IsSetReq() { 815 | p.Req = new(kitex_gen.GetVideoRequest) 816 | } 817 | return p.Req.FastRead(buf, _type, number) 818 | } 819 | 820 | func (p *GetVideoArgs) FastWrite(buf []byte) (n int) { 821 | if !p.IsSetReq() { 822 | return 0 823 | } 824 | return p.Req.FastWrite(buf) 825 | } 826 | 827 | func (p *GetVideoArgs) Size() (n int) { 828 | if !p.IsSetReq() { 829 | return 0 830 | } 831 | return p.Req.Size() 832 | } 833 | 834 | func (p *GetVideoArgs) Marshal(out []byte) ([]byte, error) { 835 | if !p.IsSetReq() { 836 | return out, fmt.Errorf("No req in GetVideoArgs") 837 | } 838 | return proto.Marshal(p.Req) 839 | } 840 | 841 | func (p *GetVideoArgs) Unmarshal(in []byte) error { 842 | msg := new(kitex_gen.GetVideoRequest) 843 | if err := proto.Unmarshal(in, msg); err != nil { 844 | return err 845 | } 846 | p.Req = msg 847 | return nil 848 | } 849 | 850 | var GetVideoArgs_Req_DEFAULT *kitex_gen.GetVideoRequest 851 | 852 | func (p *GetVideoArgs) GetReq() *kitex_gen.GetVideoRequest { 853 | if !p.IsSetReq() { 854 | return GetVideoArgs_Req_DEFAULT 855 | } 856 | return p.Req 857 | } 858 | 859 | func (p *GetVideoArgs) IsSetReq() bool { 860 | return p.Req != nil 861 | } 862 | 863 | type GetVideoResult struct { 864 | Success *kitex_gen.GetVideoResponse 865 | } 866 | 867 | var GetVideoResult_Success_DEFAULT *kitex_gen.GetVideoResponse 868 | 869 | func (p *GetVideoResult) FastRead(buf []byte, _type int8, number int32) (n int, err error) { 870 | if !p.IsSetSuccess() { 871 | p.Success = new(kitex_gen.GetVideoResponse) 872 | } 873 | return p.Success.FastRead(buf, _type, number) 874 | } 875 | 876 | func (p *GetVideoResult) FastWrite(buf []byte) (n int) { 877 | if !p.IsSetSuccess() { 878 | return 0 879 | } 880 | return p.Success.FastWrite(buf) 881 | } 882 | 883 | func (p *GetVideoResult) Size() (n int) { 884 | if !p.IsSetSuccess() { 885 | return 0 886 | } 887 | return p.Success.Size() 888 | } 889 | 890 | func (p *GetVideoResult) Marshal(out []byte) ([]byte, error) { 891 | if !p.IsSetSuccess() { 892 | return out, fmt.Errorf("No req in GetVideoResult") 893 | } 894 | return proto.Marshal(p.Success) 895 | } 896 | 897 | func (p *GetVideoResult) Unmarshal(in []byte) error { 898 | msg := new(kitex_gen.GetVideoResponse) 899 | if err := proto.Unmarshal(in, msg); err != nil { 900 | return err 901 | } 902 | p.Success = msg 903 | return nil 904 | } 905 | 906 | func (p *GetVideoResult) GetSuccess() *kitex_gen.GetVideoResponse { 907 | if !p.IsSetSuccess() { 908 | return GetVideoResult_Success_DEFAULT 909 | } 910 | return p.Success 911 | } 912 | 913 | func (p *GetVideoResult) SetSuccess(x interface{}) { 914 | p.Success = x.(*kitex_gen.GetVideoResponse) 915 | } 916 | 917 | func (p *GetVideoResult) IsSetSuccess() bool { 918 | return p.Success != nil 919 | } 920 | 921 | func getFavoriteVideoHandler(ctx context.Context, handler interface{}, arg, result interface{}) error { 922 | switch s := arg.(type) { 923 | case *streaming.Args: 924 | st := s.Stream 925 | req := new(kitex_gen.GetVideoRequest) 926 | if err := st.RecvMsg(req); err != nil { 927 | return err 928 | } 929 | resp, err := handler.(kitex_gen.VideoCenter).GetFavoriteVideo(ctx, req) 930 | if err != nil { 931 | return err 932 | } 933 | if err := st.SendMsg(resp); err != nil { 934 | return err 935 | } 936 | case *GetFavoriteVideoArgs: 937 | success, err := handler.(kitex_gen.VideoCenter).GetFavoriteVideo(ctx, s.Req) 938 | if err != nil { 939 | return err 940 | } 941 | realResult := result.(*GetFavoriteVideoResult) 942 | realResult.Success = success 943 | } 944 | return nil 945 | } 946 | func newGetFavoriteVideoArgs() interface{} { 947 | return &GetFavoriteVideoArgs{} 948 | } 949 | 950 | func newGetFavoriteVideoResult() interface{} { 951 | return &GetFavoriteVideoResult{} 952 | } 953 | 954 | type GetFavoriteVideoArgs struct { 955 | Req *kitex_gen.GetVideoRequest 956 | } 957 | 958 | func (p *GetFavoriteVideoArgs) FastRead(buf []byte, _type int8, number int32) (n int, err error) { 959 | if !p.IsSetReq() { 960 | p.Req = new(kitex_gen.GetVideoRequest) 961 | } 962 | return p.Req.FastRead(buf, _type, number) 963 | } 964 | 965 | func (p *GetFavoriteVideoArgs) FastWrite(buf []byte) (n int) { 966 | if !p.IsSetReq() { 967 | return 0 968 | } 969 | return p.Req.FastWrite(buf) 970 | } 971 | 972 | func (p *GetFavoriteVideoArgs) Size() (n int) { 973 | if !p.IsSetReq() { 974 | return 0 975 | } 976 | return p.Req.Size() 977 | } 978 | 979 | func (p *GetFavoriteVideoArgs) Marshal(out []byte) ([]byte, error) { 980 | if !p.IsSetReq() { 981 | return out, fmt.Errorf("No req in GetFavoriteVideoArgs") 982 | } 983 | return proto.Marshal(p.Req) 984 | } 985 | 986 | func (p *GetFavoriteVideoArgs) Unmarshal(in []byte) error { 987 | msg := new(kitex_gen.GetVideoRequest) 988 | if err := proto.Unmarshal(in, msg); err != nil { 989 | return err 990 | } 991 | p.Req = msg 992 | return nil 993 | } 994 | 995 | var GetFavoriteVideoArgs_Req_DEFAULT *kitex_gen.GetVideoRequest 996 | 997 | func (p *GetFavoriteVideoArgs) GetReq() *kitex_gen.GetVideoRequest { 998 | if !p.IsSetReq() { 999 | return GetFavoriteVideoArgs_Req_DEFAULT 1000 | } 1001 | return p.Req 1002 | } 1003 | 1004 | func (p *GetFavoriteVideoArgs) IsSetReq() bool { 1005 | return p.Req != nil 1006 | } 1007 | 1008 | type GetFavoriteVideoResult struct { 1009 | Success *kitex_gen.GetFavoriteVideosResponse 1010 | } 1011 | 1012 | var GetFavoriteVideoResult_Success_DEFAULT *kitex_gen.GetFavoriteVideosResponse 1013 | 1014 | func (p *GetFavoriteVideoResult) FastRead(buf []byte, _type int8, number int32) (n int, err error) { 1015 | if !p.IsSetSuccess() { 1016 | p.Success = new(kitex_gen.GetFavoriteVideosResponse) 1017 | } 1018 | return p.Success.FastRead(buf, _type, number) 1019 | } 1020 | 1021 | func (p *GetFavoriteVideoResult) FastWrite(buf []byte) (n int) { 1022 | if !p.IsSetSuccess() { 1023 | return 0 1024 | } 1025 | return p.Success.FastWrite(buf) 1026 | } 1027 | 1028 | func (p *GetFavoriteVideoResult) Size() (n int) { 1029 | if !p.IsSetSuccess() { 1030 | return 0 1031 | } 1032 | return p.Success.Size() 1033 | } 1034 | 1035 | func (p *GetFavoriteVideoResult) Marshal(out []byte) ([]byte, error) { 1036 | if !p.IsSetSuccess() { 1037 | return out, fmt.Errorf("No req in GetFavoriteVideoResult") 1038 | } 1039 | return proto.Marshal(p.Success) 1040 | } 1041 | 1042 | func (p *GetFavoriteVideoResult) Unmarshal(in []byte) error { 1043 | msg := new(kitex_gen.GetFavoriteVideosResponse) 1044 | if err := proto.Unmarshal(in, msg); err != nil { 1045 | return err 1046 | } 1047 | p.Success = msg 1048 | return nil 1049 | } 1050 | 1051 | func (p *GetFavoriteVideoResult) GetSuccess() *kitex_gen.GetFavoriteVideosResponse { 1052 | if !p.IsSetSuccess() { 1053 | return GetFavoriteVideoResult_Success_DEFAULT 1054 | } 1055 | return p.Success 1056 | } 1057 | 1058 | func (p *GetFavoriteVideoResult) SetSuccess(x interface{}) { 1059 | p.Success = x.(*kitex_gen.GetFavoriteVideosResponse) 1060 | } 1061 | 1062 | func (p *GetFavoriteVideoResult) IsSetSuccess() bool { 1063 | return p.Success != nil 1064 | } 1065 | 1066 | func postCommentHandler(ctx context.Context, handler interface{}, arg, result interface{}) error { 1067 | switch s := arg.(type) { 1068 | case *streaming.Args: 1069 | st := s.Stream 1070 | req := new(kitex_gen.PostCommentRequest) 1071 | if err := st.RecvMsg(req); err != nil { 1072 | return err 1073 | } 1074 | resp, err := handler.(kitex_gen.VideoCenter).PostComment(ctx, req) 1075 | if err != nil { 1076 | return err 1077 | } 1078 | if err := st.SendMsg(resp); err != nil { 1079 | return err 1080 | } 1081 | case *PostCommentArgs: 1082 | success, err := handler.(kitex_gen.VideoCenter).PostComment(ctx, s.Req) 1083 | if err != nil { 1084 | return err 1085 | } 1086 | realResult := result.(*PostCommentResult) 1087 | realResult.Success = success 1088 | } 1089 | return nil 1090 | } 1091 | func newPostCommentArgs() interface{} { 1092 | return &PostCommentArgs{} 1093 | } 1094 | 1095 | func newPostCommentResult() interface{} { 1096 | return &PostCommentResult{} 1097 | } 1098 | 1099 | type PostCommentArgs struct { 1100 | Req *kitex_gen.PostCommentRequest 1101 | } 1102 | 1103 | func (p *PostCommentArgs) FastRead(buf []byte, _type int8, number int32) (n int, err error) { 1104 | if !p.IsSetReq() { 1105 | p.Req = new(kitex_gen.PostCommentRequest) 1106 | } 1107 | return p.Req.FastRead(buf, _type, number) 1108 | } 1109 | 1110 | func (p *PostCommentArgs) FastWrite(buf []byte) (n int) { 1111 | if !p.IsSetReq() { 1112 | return 0 1113 | } 1114 | return p.Req.FastWrite(buf) 1115 | } 1116 | 1117 | func (p *PostCommentArgs) Size() (n int) { 1118 | if !p.IsSetReq() { 1119 | return 0 1120 | } 1121 | return p.Req.Size() 1122 | } 1123 | 1124 | func (p *PostCommentArgs) Marshal(out []byte) ([]byte, error) { 1125 | if !p.IsSetReq() { 1126 | return out, fmt.Errorf("No req in PostCommentArgs") 1127 | } 1128 | return proto.Marshal(p.Req) 1129 | } 1130 | 1131 | func (p *PostCommentArgs) Unmarshal(in []byte) error { 1132 | msg := new(kitex_gen.PostCommentRequest) 1133 | if err := proto.Unmarshal(in, msg); err != nil { 1134 | return err 1135 | } 1136 | p.Req = msg 1137 | return nil 1138 | } 1139 | 1140 | var PostCommentArgs_Req_DEFAULT *kitex_gen.PostCommentRequest 1141 | 1142 | func (p *PostCommentArgs) GetReq() *kitex_gen.PostCommentRequest { 1143 | if !p.IsSetReq() { 1144 | return PostCommentArgs_Req_DEFAULT 1145 | } 1146 | return p.Req 1147 | } 1148 | 1149 | func (p *PostCommentArgs) IsSetReq() bool { 1150 | return p.Req != nil 1151 | } 1152 | 1153 | type PostCommentResult struct { 1154 | Success *kitex_gen.PostCommentResponse 1155 | } 1156 | 1157 | var PostCommentResult_Success_DEFAULT *kitex_gen.PostCommentResponse 1158 | 1159 | func (p *PostCommentResult) FastRead(buf []byte, _type int8, number int32) (n int, err error) { 1160 | if !p.IsSetSuccess() { 1161 | p.Success = new(kitex_gen.PostCommentResponse) 1162 | } 1163 | return p.Success.FastRead(buf, _type, number) 1164 | } 1165 | 1166 | func (p *PostCommentResult) FastWrite(buf []byte) (n int) { 1167 | if !p.IsSetSuccess() { 1168 | return 0 1169 | } 1170 | return p.Success.FastWrite(buf) 1171 | } 1172 | 1173 | func (p *PostCommentResult) Size() (n int) { 1174 | if !p.IsSetSuccess() { 1175 | return 0 1176 | } 1177 | return p.Success.Size() 1178 | } 1179 | 1180 | func (p *PostCommentResult) Marshal(out []byte) ([]byte, error) { 1181 | if !p.IsSetSuccess() { 1182 | return out, fmt.Errorf("No req in PostCommentResult") 1183 | } 1184 | return proto.Marshal(p.Success) 1185 | } 1186 | 1187 | func (p *PostCommentResult) Unmarshal(in []byte) error { 1188 | msg := new(kitex_gen.PostCommentResponse) 1189 | if err := proto.Unmarshal(in, msg); err != nil { 1190 | return err 1191 | } 1192 | p.Success = msg 1193 | return nil 1194 | } 1195 | 1196 | func (p *PostCommentResult) GetSuccess() *kitex_gen.PostCommentResponse { 1197 | if !p.IsSetSuccess() { 1198 | return PostCommentResult_Success_DEFAULT 1199 | } 1200 | return p.Success 1201 | } 1202 | 1203 | func (p *PostCommentResult) SetSuccess(x interface{}) { 1204 | p.Success = x.(*kitex_gen.PostCommentResponse) 1205 | } 1206 | 1207 | func (p *PostCommentResult) IsSetSuccess() bool { 1208 | return p.Success != nil 1209 | } 1210 | 1211 | func deleteCommentHandler(ctx context.Context, handler interface{}, arg, result interface{}) error { 1212 | switch s := arg.(type) { 1213 | case *streaming.Args: 1214 | st := s.Stream 1215 | req := new(kitex_gen.DeleteCommentRequest) 1216 | if err := st.RecvMsg(req); err != nil { 1217 | return err 1218 | } 1219 | resp, err := handler.(kitex_gen.VideoCenter).DeleteComment(ctx, req) 1220 | if err != nil { 1221 | return err 1222 | } 1223 | if err := st.SendMsg(resp); err != nil { 1224 | return err 1225 | } 1226 | case *DeleteCommentArgs: 1227 | success, err := handler.(kitex_gen.VideoCenter).DeleteComment(ctx, s.Req) 1228 | if err != nil { 1229 | return err 1230 | } 1231 | realResult := result.(*DeleteCommentResult) 1232 | realResult.Success = success 1233 | } 1234 | return nil 1235 | } 1236 | func newDeleteCommentArgs() interface{} { 1237 | return &DeleteCommentArgs{} 1238 | } 1239 | 1240 | func newDeleteCommentResult() interface{} { 1241 | return &DeleteCommentResult{} 1242 | } 1243 | 1244 | type DeleteCommentArgs struct { 1245 | Req *kitex_gen.DeleteCommentRequest 1246 | } 1247 | 1248 | func (p *DeleteCommentArgs) FastRead(buf []byte, _type int8, number int32) (n int, err error) { 1249 | if !p.IsSetReq() { 1250 | p.Req = new(kitex_gen.DeleteCommentRequest) 1251 | } 1252 | return p.Req.FastRead(buf, _type, number) 1253 | } 1254 | 1255 | func (p *DeleteCommentArgs) FastWrite(buf []byte) (n int) { 1256 | if !p.IsSetReq() { 1257 | return 0 1258 | } 1259 | return p.Req.FastWrite(buf) 1260 | } 1261 | 1262 | func (p *DeleteCommentArgs) Size() (n int) { 1263 | if !p.IsSetReq() { 1264 | return 0 1265 | } 1266 | return p.Req.Size() 1267 | } 1268 | 1269 | func (p *DeleteCommentArgs) Marshal(out []byte) ([]byte, error) { 1270 | if !p.IsSetReq() { 1271 | return out, fmt.Errorf("No req in DeleteCommentArgs") 1272 | } 1273 | return proto.Marshal(p.Req) 1274 | } 1275 | 1276 | func (p *DeleteCommentArgs) Unmarshal(in []byte) error { 1277 | msg := new(kitex_gen.DeleteCommentRequest) 1278 | if err := proto.Unmarshal(in, msg); err != nil { 1279 | return err 1280 | } 1281 | p.Req = msg 1282 | return nil 1283 | } 1284 | 1285 | var DeleteCommentArgs_Req_DEFAULT *kitex_gen.DeleteCommentRequest 1286 | 1287 | func (p *DeleteCommentArgs) GetReq() *kitex_gen.DeleteCommentRequest { 1288 | if !p.IsSetReq() { 1289 | return DeleteCommentArgs_Req_DEFAULT 1290 | } 1291 | return p.Req 1292 | } 1293 | 1294 | func (p *DeleteCommentArgs) IsSetReq() bool { 1295 | return p.Req != nil 1296 | } 1297 | 1298 | type DeleteCommentResult struct { 1299 | Success *kitex_gen.BasicResponse 1300 | } 1301 | 1302 | var DeleteCommentResult_Success_DEFAULT *kitex_gen.BasicResponse 1303 | 1304 | func (p *DeleteCommentResult) FastRead(buf []byte, _type int8, number int32) (n int, err error) { 1305 | if !p.IsSetSuccess() { 1306 | p.Success = new(kitex_gen.BasicResponse) 1307 | } 1308 | return p.Success.FastRead(buf, _type, number) 1309 | } 1310 | 1311 | func (p *DeleteCommentResult) FastWrite(buf []byte) (n int) { 1312 | if !p.IsSetSuccess() { 1313 | return 0 1314 | } 1315 | return p.Success.FastWrite(buf) 1316 | } 1317 | 1318 | func (p *DeleteCommentResult) Size() (n int) { 1319 | if !p.IsSetSuccess() { 1320 | return 0 1321 | } 1322 | return p.Success.Size() 1323 | } 1324 | 1325 | func (p *DeleteCommentResult) Marshal(out []byte) ([]byte, error) { 1326 | if !p.IsSetSuccess() { 1327 | return out, fmt.Errorf("No req in DeleteCommentResult") 1328 | } 1329 | return proto.Marshal(p.Success) 1330 | } 1331 | 1332 | func (p *DeleteCommentResult) Unmarshal(in []byte) error { 1333 | msg := new(kitex_gen.BasicResponse) 1334 | if err := proto.Unmarshal(in, msg); err != nil { 1335 | return err 1336 | } 1337 | p.Success = msg 1338 | return nil 1339 | } 1340 | 1341 | func (p *DeleteCommentResult) GetSuccess() *kitex_gen.BasicResponse { 1342 | if !p.IsSetSuccess() { 1343 | return DeleteCommentResult_Success_DEFAULT 1344 | } 1345 | return p.Success 1346 | } 1347 | 1348 | func (p *DeleteCommentResult) SetSuccess(x interface{}) { 1349 | p.Success = x.(*kitex_gen.BasicResponse) 1350 | } 1351 | 1352 | func (p *DeleteCommentResult) IsSetSuccess() bool { 1353 | return p.Success != nil 1354 | } 1355 | 1356 | func getCommentHandler(ctx context.Context, handler interface{}, arg, result interface{}) error { 1357 | switch s := arg.(type) { 1358 | case *streaming.Args: 1359 | st := s.Stream 1360 | req := new(kitex_gen.GetCommentRequest) 1361 | if err := st.RecvMsg(req); err != nil { 1362 | return err 1363 | } 1364 | resp, err := handler.(kitex_gen.VideoCenter).GetComment(ctx, req) 1365 | if err != nil { 1366 | return err 1367 | } 1368 | if err := st.SendMsg(resp); err != nil { 1369 | return err 1370 | } 1371 | case *GetCommentArgs: 1372 | success, err := handler.(kitex_gen.VideoCenter).GetComment(ctx, s.Req) 1373 | if err != nil { 1374 | return err 1375 | } 1376 | realResult := result.(*GetCommentResult) 1377 | realResult.Success = success 1378 | } 1379 | return nil 1380 | } 1381 | func newGetCommentArgs() interface{} { 1382 | return &GetCommentArgs{} 1383 | } 1384 | 1385 | func newGetCommentResult() interface{} { 1386 | return &GetCommentResult{} 1387 | } 1388 | 1389 | type GetCommentArgs struct { 1390 | Req *kitex_gen.GetCommentRequest 1391 | } 1392 | 1393 | func (p *GetCommentArgs) FastRead(buf []byte, _type int8, number int32) (n int, err error) { 1394 | if !p.IsSetReq() { 1395 | p.Req = new(kitex_gen.GetCommentRequest) 1396 | } 1397 | return p.Req.FastRead(buf, _type, number) 1398 | } 1399 | 1400 | func (p *GetCommentArgs) FastWrite(buf []byte) (n int) { 1401 | if !p.IsSetReq() { 1402 | return 0 1403 | } 1404 | return p.Req.FastWrite(buf) 1405 | } 1406 | 1407 | func (p *GetCommentArgs) Size() (n int) { 1408 | if !p.IsSetReq() { 1409 | return 0 1410 | } 1411 | return p.Req.Size() 1412 | } 1413 | 1414 | func (p *GetCommentArgs) Marshal(out []byte) ([]byte, error) { 1415 | if !p.IsSetReq() { 1416 | return out, fmt.Errorf("No req in GetCommentArgs") 1417 | } 1418 | return proto.Marshal(p.Req) 1419 | } 1420 | 1421 | func (p *GetCommentArgs) Unmarshal(in []byte) error { 1422 | msg := new(kitex_gen.GetCommentRequest) 1423 | if err := proto.Unmarshal(in, msg); err != nil { 1424 | return err 1425 | } 1426 | p.Req = msg 1427 | return nil 1428 | } 1429 | 1430 | var GetCommentArgs_Req_DEFAULT *kitex_gen.GetCommentRequest 1431 | 1432 | func (p *GetCommentArgs) GetReq() *kitex_gen.GetCommentRequest { 1433 | if !p.IsSetReq() { 1434 | return GetCommentArgs_Req_DEFAULT 1435 | } 1436 | return p.Req 1437 | } 1438 | 1439 | func (p *GetCommentArgs) IsSetReq() bool { 1440 | return p.Req != nil 1441 | } 1442 | 1443 | type GetCommentResult struct { 1444 | Success *kitex_gen.GetCommentResponse 1445 | } 1446 | 1447 | var GetCommentResult_Success_DEFAULT *kitex_gen.GetCommentResponse 1448 | 1449 | func (p *GetCommentResult) FastRead(buf []byte, _type int8, number int32) (n int, err error) { 1450 | if !p.IsSetSuccess() { 1451 | p.Success = new(kitex_gen.GetCommentResponse) 1452 | } 1453 | return p.Success.FastRead(buf, _type, number) 1454 | } 1455 | 1456 | func (p *GetCommentResult) FastWrite(buf []byte) (n int) { 1457 | if !p.IsSetSuccess() { 1458 | return 0 1459 | } 1460 | return p.Success.FastWrite(buf) 1461 | } 1462 | 1463 | func (p *GetCommentResult) Size() (n int) { 1464 | if !p.IsSetSuccess() { 1465 | return 0 1466 | } 1467 | return p.Success.Size() 1468 | } 1469 | 1470 | func (p *GetCommentResult) Marshal(out []byte) ([]byte, error) { 1471 | if !p.IsSetSuccess() { 1472 | return out, fmt.Errorf("No req in GetCommentResult") 1473 | } 1474 | return proto.Marshal(p.Success) 1475 | } 1476 | 1477 | func (p *GetCommentResult) Unmarshal(in []byte) error { 1478 | msg := new(kitex_gen.GetCommentResponse) 1479 | if err := proto.Unmarshal(in, msg); err != nil { 1480 | return err 1481 | } 1482 | p.Success = msg 1483 | return nil 1484 | } 1485 | 1486 | func (p *GetCommentResult) GetSuccess() *kitex_gen.GetCommentResponse { 1487 | if !p.IsSetSuccess() { 1488 | return GetCommentResult_Success_DEFAULT 1489 | } 1490 | return p.Success 1491 | } 1492 | 1493 | func (p *GetCommentResult) SetSuccess(x interface{}) { 1494 | p.Success = x.(*kitex_gen.GetCommentResponse) 1495 | } 1496 | 1497 | func (p *GetCommentResult) IsSetSuccess() bool { 1498 | return p.Success != nil 1499 | } 1500 | 1501 | func isFavoriteHandler(ctx context.Context, handler interface{}, arg, result interface{}) error { 1502 | switch s := arg.(type) { 1503 | case *streaming.Args: 1504 | st := s.Stream 1505 | req := new(kitex_gen.IsFavoriteRequest) 1506 | if err := st.RecvMsg(req); err != nil { 1507 | return err 1508 | } 1509 | resp, err := handler.(kitex_gen.VideoCenter).IsFavorite(ctx, req) 1510 | if err != nil { 1511 | return err 1512 | } 1513 | if err := st.SendMsg(resp); err != nil { 1514 | return err 1515 | } 1516 | case *IsFavoriteArgs: 1517 | success, err := handler.(kitex_gen.VideoCenter).IsFavorite(ctx, s.Req) 1518 | if err != nil { 1519 | return err 1520 | } 1521 | realResult := result.(*IsFavoriteResult) 1522 | realResult.Success = success 1523 | } 1524 | return nil 1525 | } 1526 | func newIsFavoriteArgs() interface{} { 1527 | return &IsFavoriteArgs{} 1528 | } 1529 | 1530 | func newIsFavoriteResult() interface{} { 1531 | return &IsFavoriteResult{} 1532 | } 1533 | 1534 | type IsFavoriteArgs struct { 1535 | Req *kitex_gen.IsFavoriteRequest 1536 | } 1537 | 1538 | func (p *IsFavoriteArgs) FastRead(buf []byte, _type int8, number int32) (n int, err error) { 1539 | if !p.IsSetReq() { 1540 | p.Req = new(kitex_gen.IsFavoriteRequest) 1541 | } 1542 | return p.Req.FastRead(buf, _type, number) 1543 | } 1544 | 1545 | func (p *IsFavoriteArgs) FastWrite(buf []byte) (n int) { 1546 | if !p.IsSetReq() { 1547 | return 0 1548 | } 1549 | return p.Req.FastWrite(buf) 1550 | } 1551 | 1552 | func (p *IsFavoriteArgs) Size() (n int) { 1553 | if !p.IsSetReq() { 1554 | return 0 1555 | } 1556 | return p.Req.Size() 1557 | } 1558 | 1559 | func (p *IsFavoriteArgs) Marshal(out []byte) ([]byte, error) { 1560 | if !p.IsSetReq() { 1561 | return out, fmt.Errorf("No req in IsFavoriteArgs") 1562 | } 1563 | return proto.Marshal(p.Req) 1564 | } 1565 | 1566 | func (p *IsFavoriteArgs) Unmarshal(in []byte) error { 1567 | msg := new(kitex_gen.IsFavoriteRequest) 1568 | if err := proto.Unmarshal(in, msg); err != nil { 1569 | return err 1570 | } 1571 | p.Req = msg 1572 | return nil 1573 | } 1574 | 1575 | var IsFavoriteArgs_Req_DEFAULT *kitex_gen.IsFavoriteRequest 1576 | 1577 | func (p *IsFavoriteArgs) GetReq() *kitex_gen.IsFavoriteRequest { 1578 | if !p.IsSetReq() { 1579 | return IsFavoriteArgs_Req_DEFAULT 1580 | } 1581 | return p.Req 1582 | } 1583 | 1584 | func (p *IsFavoriteArgs) IsSetReq() bool { 1585 | return p.Req != nil 1586 | } 1587 | 1588 | type IsFavoriteResult struct { 1589 | Success *kitex_gen.BasicResponse 1590 | } 1591 | 1592 | var IsFavoriteResult_Success_DEFAULT *kitex_gen.BasicResponse 1593 | 1594 | func (p *IsFavoriteResult) FastRead(buf []byte, _type int8, number int32) (n int, err error) { 1595 | if !p.IsSetSuccess() { 1596 | p.Success = new(kitex_gen.BasicResponse) 1597 | } 1598 | return p.Success.FastRead(buf, _type, number) 1599 | } 1600 | 1601 | func (p *IsFavoriteResult) FastWrite(buf []byte) (n int) { 1602 | if !p.IsSetSuccess() { 1603 | return 0 1604 | } 1605 | return p.Success.FastWrite(buf) 1606 | } 1607 | 1608 | func (p *IsFavoriteResult) Size() (n int) { 1609 | if !p.IsSetSuccess() { 1610 | return 0 1611 | } 1612 | return p.Success.Size() 1613 | } 1614 | 1615 | func (p *IsFavoriteResult) Marshal(out []byte) ([]byte, error) { 1616 | if !p.IsSetSuccess() { 1617 | return out, fmt.Errorf("No req in IsFavoriteResult") 1618 | } 1619 | return proto.Marshal(p.Success) 1620 | } 1621 | 1622 | func (p *IsFavoriteResult) Unmarshal(in []byte) error { 1623 | msg := new(kitex_gen.BasicResponse) 1624 | if err := proto.Unmarshal(in, msg); err != nil { 1625 | return err 1626 | } 1627 | p.Success = msg 1628 | return nil 1629 | } 1630 | 1631 | func (p *IsFavoriteResult) GetSuccess() *kitex_gen.BasicResponse { 1632 | if !p.IsSetSuccess() { 1633 | return IsFavoriteResult_Success_DEFAULT 1634 | } 1635 | return p.Success 1636 | } 1637 | 1638 | func (p *IsFavoriteResult) SetSuccess(x interface{}) { 1639 | p.Success = x.(*kitex_gen.BasicResponse) 1640 | } 1641 | 1642 | func (p *IsFavoriteResult) IsSetSuccess() bool { 1643 | return p.Success != nil 1644 | } 1645 | 1646 | type kClient struct { 1647 | c client.Client 1648 | } 1649 | 1650 | func newServiceClient(c client.Client) *kClient { 1651 | return &kClient{ 1652 | c: c, 1653 | } 1654 | } 1655 | 1656 | func (p *kClient) Publish(ctx context.Context, Req *kitex_gen.PublishRequest) (r *kitex_gen.PublishResponse, err error) { 1657 | var _args PublishArgs 1658 | _args.Req = Req 1659 | var _result PublishResult 1660 | if err = p.c.Call(ctx, "Publish", &_args, &_result); err != nil { 1661 | return 1662 | } 1663 | return _result.GetSuccess(), nil 1664 | } 1665 | 1666 | func (p *kClient) Delete(ctx context.Context, Req *kitex_gen.DeleteRequest) (r *kitex_gen.BasicResponse, err error) { 1667 | var _args DeleteArgs 1668 | _args.Req = Req 1669 | var _result DeleteResult 1670 | if err = p.c.Call(ctx, "Delete", &_args, &_result); err != nil { 1671 | return 1672 | } 1673 | return _result.GetSuccess(), nil 1674 | } 1675 | 1676 | func (p *kClient) Feed(ctx context.Context, Req *kitex_gen.FeedRequest) (r *kitex_gen.FeedResponse, err error) { 1677 | var _args FeedArgs 1678 | _args.Req = Req 1679 | var _result FeedResult 1680 | if err = p.c.Call(ctx, "Feed", &_args, &_result); err != nil { 1681 | return 1682 | } 1683 | return _result.GetSuccess(), nil 1684 | } 1685 | 1686 | func (p *kClient) VideoList(ctx context.Context, Req *kitex_gen.VideoListRequest) (r *kitex_gen.VideoListResponse, err error) { 1687 | var _args VideoListArgs 1688 | _args.Req = Req 1689 | var _result VideoListResult 1690 | if err = p.c.Call(ctx, "VideoList", &_args, &_result); err != nil { 1691 | return 1692 | } 1693 | return _result.GetSuccess(), nil 1694 | } 1695 | 1696 | func (p *kClient) Like(ctx context.Context, Req *kitex_gen.LikeRequest) (r *kitex_gen.BasicResponse, err error) { 1697 | var _args LikeArgs 1698 | _args.Req = Req 1699 | var _result LikeResult 1700 | if err = p.c.Call(ctx, "Like", &_args, &_result); err != nil { 1701 | return 1702 | } 1703 | return _result.GetSuccess(), nil 1704 | } 1705 | 1706 | func (p *kClient) GetVideo(ctx context.Context, Req *kitex_gen.GetVideoRequest) (r *kitex_gen.GetVideoResponse, err error) { 1707 | var _args GetVideoArgs 1708 | _args.Req = Req 1709 | var _result GetVideoResult 1710 | if err = p.c.Call(ctx, "GetVideo", &_args, &_result); err != nil { 1711 | return 1712 | } 1713 | return _result.GetSuccess(), nil 1714 | } 1715 | 1716 | func (p *kClient) GetFavoriteVideo(ctx context.Context, Req *kitex_gen.GetVideoRequest) (r *kitex_gen.GetFavoriteVideosResponse, err error) { 1717 | var _args GetFavoriteVideoArgs 1718 | _args.Req = Req 1719 | var _result GetFavoriteVideoResult 1720 | if err = p.c.Call(ctx, "GetFavoriteVideo", &_args, &_result); err != nil { 1721 | return 1722 | } 1723 | return _result.GetSuccess(), nil 1724 | } 1725 | 1726 | func (p *kClient) PostComment(ctx context.Context, Req *kitex_gen.PostCommentRequest) (r *kitex_gen.PostCommentResponse, err error) { 1727 | var _args PostCommentArgs 1728 | _args.Req = Req 1729 | var _result PostCommentResult 1730 | if err = p.c.Call(ctx, "PostComment", &_args, &_result); err != nil { 1731 | return 1732 | } 1733 | return _result.GetSuccess(), nil 1734 | } 1735 | 1736 | func (p *kClient) DeleteComment(ctx context.Context, Req *kitex_gen.DeleteCommentRequest) (r *kitex_gen.BasicResponse, err error) { 1737 | var _args DeleteCommentArgs 1738 | _args.Req = Req 1739 | var _result DeleteCommentResult 1740 | if err = p.c.Call(ctx, "DeleteComment", &_args, &_result); err != nil { 1741 | return 1742 | } 1743 | return _result.GetSuccess(), nil 1744 | } 1745 | 1746 | func (p *kClient) GetComment(ctx context.Context, Req *kitex_gen.GetCommentRequest) (r *kitex_gen.GetCommentResponse, err error) { 1747 | var _args GetCommentArgs 1748 | _args.Req = Req 1749 | var _result GetCommentResult 1750 | if err = p.c.Call(ctx, "GetComment", &_args, &_result); err != nil { 1751 | return 1752 | } 1753 | return _result.GetSuccess(), nil 1754 | } 1755 | 1756 | func (p *kClient) IsFavorite(ctx context.Context, Req *kitex_gen.IsFavoriteRequest) (r *kitex_gen.BasicResponse, err error) { 1757 | var _args IsFavoriteArgs 1758 | _args.Req = Req 1759 | var _result IsFavoriteResult 1760 | if err = p.c.Call(ctx, "IsFavorite", &_args, &_result); err != nil { 1761 | return 1762 | } 1763 | return _result.GetSuccess(), nil 1764 | } 1765 | -------------------------------------------------------------------------------- /video_service/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "dousheng_server/conf" 5 | "dousheng_server/video_service/kitex_gen/videocenter" 6 | "github.com/cloudwego/kitex/pkg/rpcinfo" 7 | "github.com/cloudwego/kitex/server" 8 | kServer "github.com/cloudwego/kitex/server" 9 | prometheus "github.com/kitex-contrib/monitor-prometheus" 10 | etcd "github.com/kitex-contrib/registry-etcd" 11 | "log" 12 | "net" 13 | ) 14 | 15 | func main() { 16 | addr, _ := net.ResolveTCPAddr("tcp", ":8902") 17 | r, err := etcd.NewEtcdRegistry([]string{conf.Conf.EtcdConfig.Url}) 18 | if err != nil { 19 | log.Fatal(err) 20 | } 21 | svr := videocenter.NewServer(new(VideoCenterImpl), 22 | server.WithServerBasicInfo(&rpcinfo.EndpointBasicInfo{ServiceName: "videoservice"}), 23 | server.WithRegistry(r), 24 | server.WithServiceAddr(addr), 25 | kServer.WithTracer(prometheus.NewServerTracer(":9902", "/metrics"))) 26 | 27 | err = svr.Run() 28 | 29 | if err != nil { 30 | log.Println(err.Error()) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /video_service/script/bootstrap.sh: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env bash 2 | CURDIR=$(cd $(dirname $0); pwd) 3 | 4 | if [ "X$1" != "X" ]; then 5 | RUNTIME_ROOT=$1 6 | else 7 | RUNTIME_ROOT=${CURDIR} 8 | fi 9 | 10 | export KITEX_RUNTIME_ROOT=$RUNTIME_ROOT 11 | export KITEX_LOG_DIR="$RUNTIME_ROOT/log" 12 | 13 | if [ ! -d "$KITEX_LOG_DIR/app" ]; then 14 | mkdir -p "$KITEX_LOG_DIR/app" 15 | fi 16 | 17 | if [ ! -d "$KITEX_LOG_DIR/rpc" ]; then 18 | mkdir -p "$KITEX_LOG_DIR/rpc" 19 | fi 20 | 21 | exec "$CURDIR/bin/videocenter" 22 | 23 | -------------------------------------------------------------------------------- /video_service/service/video_center.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | zaplog "dousheng_server/deploy/log" 5 | "dousheng_server/uuidmaker" 6 | "dousheng_server/video_service/dal/model" 7 | "dousheng_server/video_service/dal/query" 8 | "dousheng_server/video_service/kitex_gen" 9 | "errors" 10 | "fmt" 11 | "time" 12 | ) 13 | 14 | type VideoCenter struct { 15 | } 16 | 17 | // Publish 投稿视频 18 | func (vc VideoCenter) Publish(req *kitex_gen.PublishRequest) (int64, error) { 19 | // 1. 申请UUID 20 | uuid, err := uuidmaker.GetUUID() 21 | if err != nil { 22 | zaplog.ZapLogger.Error("failed when generating uuid err:%v", err) 23 | return 0, err 24 | } 25 | // 2. 生成 26 | saverIp := "http://192.168.101.112:8080" 27 | video := &model.Video{ 28 | UUID: uuid, 29 | UserID: req.UserId, 30 | PlayURL: fmt.Sprintf(saverIp+"/static/videos/%d.%s", uuid, req.PlayUrl), 31 | CoverURL: fmt.Sprintf(saverIp+"/static/covers/%d.%s", uuid, "png"), 32 | FavoriteCount: 0, 33 | CommentCount: 0, 34 | Title: req.Title, 35 | } 36 | err = query.CreateVideo(video) 37 | return uuid, err 38 | } 39 | 40 | // Delete 删除视频 41 | func (vc VideoCenter) Delete(uuid int64) error { 42 | return query.DeleteVideo(uuid) 43 | } 44 | 45 | // Feed 获取视频 46 | func (vc VideoCenter) Feed(timeStamp int64) ([]*kitex_gen.Video, error) { 47 | lastTime := time.UnixMilli(timeStamp) 48 | videos, err := query.Feed(lastTime) 49 | if videos == nil { 50 | return nil, err 51 | } 52 | if err != nil { 53 | return nil, err 54 | } 55 | return modelToKitexVideo(videos), nil 56 | } 57 | 58 | // VideoList 获取发布视频列表 59 | func (vc VideoCenter) VideoList(userId int64) ([]*kitex_gen.Video, error) { 60 | videos, err := query.VideoList(userId) 61 | if err != nil { 62 | return nil, err 63 | } 64 | return modelToKitexVideo(videos), nil 65 | } 66 | 67 | // Like 点赞或取消 68 | func (vc VideoCenter) Like(userId, videoId int64, actionType int32) error { 69 | switch actionType { 70 | case 1: // 点赞 71 | err := query.Favorite(userId, videoId) 72 | if err != nil { 73 | return err 74 | } 75 | case 2: // 取消 76 | err := query.UndoFavorite(userId, videoId) 77 | if err != nil { 78 | return err 79 | } 80 | default: 81 | return errors.New("wrong action type") 82 | } 83 | return nil 84 | } 85 | 86 | // IsFavorite 判断是否点过赞 87 | func (vc VideoCenter) IsFavorite(userId, videoId int64) bool { 88 | return query.IsLiked(userId, videoId) 89 | } 90 | 91 | // GetVideo 获取视频 92 | func (vc VideoCenter) GetVideo(uuid int64) (*kitex_gen.Video, error) { 93 | video, err := query.GetVideo(uuid) 94 | createTime := video.CreatedAt.UnixMilli() 95 | res := &kitex_gen.Video{ 96 | Uuid: video.UUID, 97 | UserId: video.UserID, 98 | PlayUrl: video.PlayURL, 99 | CoverUrl: video.CoverURL, 100 | FavoriteCount: video.FavoriteCount, 101 | CommentCount: video.CommentCount, 102 | Title: video.Title, 103 | CreateTime: createTime, 104 | } 105 | return res, err 106 | } 107 | 108 | // FavoriteList 获取点赞过的是视频列表 109 | func (vc VideoCenter) FavoriteList(userId int64) ([]*kitex_gen.Video, error) { 110 | var res []*kitex_gen.Video 111 | videoIds, err := query.FavoriteList(userId) 112 | if err != nil { 113 | return nil, err 114 | } 115 | for _, item := range videoIds { 116 | temp, err := vc.GetVideo(item) 117 | if err != nil { 118 | return nil, err 119 | } 120 | res = append(res, temp) 121 | } 122 | return res, nil 123 | } 124 | 125 | // PostComment 发表评论 126 | func (vc VideoCenter) PostComment(req *kitex_gen.PostCommentRequest) (*kitex_gen.Comment, error) { 127 | // 1. 申请uuid 128 | uuid, err := uuidmaker.GetUUID() 129 | if err != nil { 130 | zaplog.ZapLogger.Error("failed when generating uuid err:%v", err) 131 | return nil, err 132 | } 133 | // 2. 生成comment 134 | comment := &model.Comment{ 135 | CommentId: uuid, 136 | UserId: req.UserId, 137 | VideoId: req.VideoId, 138 | Content: req.Content, 139 | CreateDate: time.Now().Format("01-02"), 140 | } 141 | // 3. 保存 142 | comment, err = query.CreateComment(comment) 143 | if err != nil { 144 | return nil, err 145 | } 146 | 147 | return &kitex_gen.Comment{ 148 | Uuid: comment.CommentId, 149 | UserId: comment.UserId, 150 | VideoId: comment.VideoId, 151 | CreateDate: comment.CreateDate, 152 | Content: comment.Content, 153 | }, nil 154 | } 155 | 156 | // DeleteComment 删除评论 157 | func (vc VideoCenter) DeleteComment(uuid int64) error { 158 | return query.DeleteComment(uuid) 159 | } 160 | 161 | // GetComment 获取视频评论 162 | func (vc VideoCenter) GetComment(uuid int64) ([]*kitex_gen.Comment, error) { 163 | comments, err := query.GetComment(uuid) 164 | if err != nil { 165 | return nil, err 166 | } 167 | return modelToKitexComment(comments), nil 168 | } 169 | 170 | // 将model中的comment转换为kitex中生成的comment 171 | func modelToKitexComment(comments *[]model.Comment) []*kitex_gen.Comment { 172 | var commentList []*kitex_gen.Comment 173 | for _, item := range *comments { 174 | commentList = append(commentList, &kitex_gen.Comment{ 175 | Uuid: item.CommentId, 176 | UserId: item.UserId, 177 | VideoId: item.VideoId, 178 | CreateDate: item.CreateDate, 179 | Content: item.Content, 180 | }) 181 | } 182 | return commentList 183 | } 184 | 185 | // 将model中的video转换为kitex中生成的video 186 | func modelToKitexVideo(videos *[]model.Video) []*kitex_gen.Video { 187 | var videoList []*kitex_gen.Video 188 | for _, item := range *videos { 189 | createTime := item.CreatedAt.UnixMilli() 190 | videoList = append(videoList, &kitex_gen.Video{ 191 | Uuid: item.UUID, 192 | UserId: item.UserID, 193 | PlayUrl: item.PlayURL, 194 | CoverUrl: item.CoverURL, 195 | FavoriteCount: item.FavoriteCount, 196 | CommentCount: item.CommentCount, 197 | Title: item.Title, 198 | CreateTime: createTime, 199 | }) 200 | } 201 | return videoList 202 | } 203 | --------------------------------------------------------------------------------