github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/models/reply.go (about) 1 package models 2 3 import ( 4 "errors" 5 "fmt" 6 "log" 7 "os" 8 "strconv" 9 "time" 10 "github.com/insionng/yougam/helper" 11 ) 12 13 type Reply struct { 14 Id int64 15 Pid int64 `xorm:"index"` //上级Reply id 16 Uid int64 `xorm:"index"` 17 Tid int64 `xorm:"index"` 18 Sort int64 19 Ctype int64 `xorm:"index"` 20 Content string `xorm:"text"` 21 Tailinfo int64 `xorm:"index"` 22 Attachment string `xorm:"text"` 23 Avatar string `xorm:"index"` //200x200 24 AvatarLarge string `xorm:"index"` //100x100 25 AvatarMedium string `xorm:"index"` //48x48 26 AvatarSmall string `xorm:"index"` //32x32 27 Created int64 `xorm:"created index"` 28 Updated int64 `xorm:"updated"` 29 Hotness float64 `xorm:"index"` 30 Confidence float64 `xorm:"index"` 31 Hotup int64 `xorm:"index"` 32 Hotdown int64 `xorm:"index"` 33 Hotscore int64 `xorm:"index"` //Hotup - Hotdown 34 Hotvote int64 `xorm:"index"` //Hotup + Hotdown 35 Views int64 36 Author string `xorm:"index"` 37 AuthorSignature string `xorm:"index"` 38 Email string `xorm:"index"` 39 Website string `xorm:"index"` 40 ReplyTime int64 41 ReplyCount int64 42 ReplyLastUserId int64 43 ReplyLastUsername string 44 ReplyLastNickname string 45 ReplyLastTopic string //最后回复的话题之标题 46 Latitude float64 `xorm:"index"` 47 Longitude float64 `xorm:"index"` 48 } 49 50 type ReplyMark struct { 51 Id int64 52 Uid int64 `xorm:"index"` 53 Rid int64 `xorm:"index"` //Reply id 54 } 55 56 type Replyjuser struct { 57 Reply `xorm:"extends"` 58 User `xorm:"extends"` 59 } 60 61 type Replyjtopic struct { 62 Reply `xorm:"extends"` 63 Topic `xorm:"extends"` 64 } 65 66 func GetReplysByPid4Count(pid int64, offset int, limit int, ctype int64) (int64, error) { 67 68 if ctype != 0 { 69 return Engine.Where("(pid=? or id=?) and ctype=?", pid, pid, ctype).Limit(limit, offset).Count(&Reply{}) 70 } else { 71 return Engine.Where("pid=? or id=?", pid, pid).Limit(limit, offset).Count(&Reply{}) 72 } 73 74 } 75 76 func SetReplyMark(uid int64, rid int64) (int64, error) { 77 78 rpm := &ReplyMark{Uid: uid, Rid: rid} 79 rows, err := Engine.Insert(rpm) 80 return rows, err 81 } 82 83 func DelReplyMark(uid int64, rid int64) { 84 rpm := new(ReplyMark) 85 Engine.Where("uid=? and rid=?", uid, rid).Delete(rpm) 86 87 } 88 89 func ReplyMarkCount(rid int64) (int64, error) { 90 return Engine.Where("rid=?", rid).Count(&ReplyMark{}) 91 } 92 93 func ReplyMarkCountByUid(uid int64) (int64, error) { 94 return Engine.Where("uid=?", uid).Count(&ReplyMark{}) 95 } 96 97 func IsReplyMark(uid int64, rid int64) bool { 98 99 rpm := new(ReplyMark) 100 101 if has, err := Engine.Where("uid=? and rid=?", uid, rid).Get(rpm); err != nil { 102 return false 103 } else { 104 if has { 105 return (rpm.Uid == uid) 106 } else { 107 return false 108 } 109 } 110 111 } 112 113 func GetReplysByTidUsernameJoinTopic(tid int64, author string, ctype int64, offset int, limit int, field string) *[]*Replyjtopic { 114 115 rp := new([]*Replyjtopic) 116 117 //ctype等于-1为游客 ctype等于1为正常会员 这里ctype等于0的情况则返回两者 118 if tid == 0 { 119 if ctype != 0 { 120 Engine.Table("reply").Where("reply.ctype=? and reply.author=?", ctype, author).Limit(limit, offset).Desc("reply."+field).Join("LEFT", "topic", "reply.tid = topic.id").Find(rp) 121 } else { 122 Engine.Table("reply").Where("reply.author=?", author).Limit(limit, offset).Desc("reply."+field).Join("LEFT", "topic", "reply.tid = topic.id").Find(rp) 123 } 124 125 } else { 126 127 if ctype == 0 { 128 Engine.Table("reply").Where("reply.tid=? and reply.author=?", tid, author).Limit(limit, offset).Desc("reply."+field).Join("LEFT", "topic", "reply.tid = topic.id").Find(rp) 129 130 } else { 131 132 Engine.Table("reply").Where("reply.ctype=? and reply.tid=? and reply.author=?", ctype, tid, author).Limit(limit, offset).Desc("reply."+field).Join("LEFT", "topic", "reply.tid = topic.id").Find(rp) 133 } 134 } 135 return rp 136 } 137 138 func GetSubReplys(pid int64, offset int, limit int, field string) (*[]*Reply, error) { 139 rps := &[]*Reply{} 140 err := Engine.Where("pid=?", pid).Limit(limit, offset).Desc(field).Find(rps) 141 return rps, err 142 } 143 144 func PostReply(tid int64, rp *Reply) (int64, error) { 145 // 创建 Session 对象 146 sess := Engine.NewSession() 147 defer sess.Close() 148 // 启动事务 149 if err := sess.Begin(); err != nil { 150 return -1, err 151 } 152 153 //执行事务 154 replyid := int64(0) 155 if _, err := sess.Insert(rp); err == nil && rp != nil { 156 if rp.Tid > 0 { 157 n, _ := sess.Where("tid=?", rp.Tid).Count(&Reply{}) 158 159 if row, err := sess.Table(&Topic{}).Where("id=?", rp.Tid).Update(&map[string]interface{}{"author": rp.Author, "reply_time": time.Now().Unix(), "reply_count": n, "reply_last_user_id": rp.Uid}); err != nil || row == 0 { 160 sess.Rollback() 161 return -1, errors.New(fmt.Sprint("PostReply更新topic表相关信息时,执行:", row, "行变更,出现错误:", err)) 162 } 163 } 164 165 if rp.Uid > 0 { 166 n, _ := sess.Where("uid=?", rp.Uid).Count(&Reply{}) 167 168 if row, err := sess.Table(&User{}).Where("id=?", rp.Uid).Update(&map[string]interface{}{"reply_time": time.Now().Unix(), "reply_count": n, "reply_last_tid": rp.Tid, "reply_last_topic": rp.ReplyLastTopic}); err != nil || row == 0 { 169 sess.Rollback() 170 return -1, errors.New(fmt.Sprint("PostReply更新user表话题相关信息时,执行:", row, "行变更,出现错误:", err)) 171 } 172 } 173 174 replyid = rp.Id 175 } else { 176 sess.Rollback() 177 return -1, err 178 } 179 180 // 提交事务 181 return replyid, sess.Commit() 182 } 183 184 func PutReply(rid int64, rp *Reply) (int64, error) { 185 // 创建 Session 对象 186 sess := Engine.NewSession() 187 defer sess.Close() 188 // 启动事务 189 if err := sess.Begin(); err != nil { 190 return -1, err 191 } 192 193 //执行事务 194 replyid := int64(0) 195 if row, err := sess.Update(rp, &Reply{Id: rid}); err != nil || row <= 0 { 196 sess.Rollback() 197 return -1, err 198 } else { 199 if rp.Uid > 0 { 200 n, _ := sess.Where("uid=?", rp.Uid).Count(&Reply{}) 201 202 if row, err := sess.Table(&User{}).Where("id=?", rp.Uid).Update(&map[string]interface{}{"reply_time": time.Now().Unix(), "reply_count": n, "reply_last_tid": rp.Tid, "reply_last_topic": rp.ReplyLastTopic}); err != nil || row == 0 { 203 sess.Rollback() 204 return -1, errors.New(fmt.Sprint("PutReply更新user表话题相关信息时,执行:", row, "行变更,出现错误:", err)) 205 } 206 } 207 } 208 209 // 提交事务 210 return replyid, sess.Commit() 211 } 212 213 func GetAllReply() *[]*Reply { 214 rps := &[]*Reply{} 215 Engine.Desc("id").Find(rps) 216 return rps 217 } 218 219 func GetReply(id int64) (*Reply, error) { 220 221 rpy := &Reply{} 222 has, err := Engine.Id(id).Get(rpy) 223 if has { 224 return rpy, err 225 } else { 226 227 return nil, err 228 } 229 } 230 231 func GetReplysByPid(pid int64, ctype int64, offset int, limit int, field string) *[]*Reply { 232 rp := &[]*Reply{} 233 234 //ctype等于-1为游客 ctype等于1为正常会员 这里ctype等于0的情况则返回两者 235 if pid == 0 { 236 if ctype == 0 { 237 Engine.Limit(limit, offset).Desc(field).Find(rp) 238 } else { 239 Engine.Where("ctype=?", ctype).Limit(limit, offset).Desc(field).Find(rp) 240 } 241 } else { 242 243 if ctype == 0 { 244 //Engine.Where("(ctype=-1 or ctype=1) and pid=?", pid).Limit(limit, offset).Desc(field).Find(rp) 245 Engine.Where("pid=?", pid).Limit(limit, offset).Desc(field).Find(rp) 246 247 } else { 248 249 Engine.Where("ctype=? and pid=?", ctype, pid).Limit(limit, offset).Desc(field).Find(rp) 250 } 251 } 252 return rp 253 } 254 255 func GetReplysByTid(tid int64, ctype int64, offset int, limit int, field string) *[]*Reply { 256 rp := &[]*Reply{} 257 if field == "asc" { 258 259 //ctype等于-1为游客 ctype等于1为正常会员 这里ctype等于0的情况则返回两者 260 if tid == 0 { 261 if ctype != 0 { 262 Engine.Table("reply").Where("reply.ctype=?", ctype).Limit(limit, offset).Asc("reply.id").Find(rp) 263 } else { 264 Engine.Table("reply").Limit(limit, offset).Asc("reply.id").Find(rp) 265 } 266 267 } else { 268 269 if ctype == 0 { 270 Engine.Table("reply").Where("reply.tid=?", tid).Limit(limit, offset).Asc("reply.id").Find(rp) 271 272 } else { 273 274 Engine.Table("reply").Where("reply.ctype=? and reply.tid=?", ctype, tid).Limit(limit, offset).Asc("reply.id").Find(rp) 275 } 276 } 277 } else { 278 279 //ctype等于-1为游客 ctype等于1为正常会员 这里ctype等于0的情况则返回两者 280 if tid == 0 { 281 if ctype != 0 { 282 Engine.Table("reply").Where("reply.ctype=?", ctype).Limit(limit, offset).Desc("reply." + field).Find(rp) 283 } else { 284 Engine.Table("reply").Limit(limit, offset).Desc("reply." + field).Find(rp) 285 } 286 287 } else { 288 289 if ctype == 0 { 290 //Engine.Where("(ctype=-1 or ctype=1) and tid=?", tid).Limit(limit, offset).Desc(field).Find(rp) 291 Engine.Table("reply").Where("reply.tid=?", tid).Limit(limit, offset).Desc("reply." + field).Find(rp) 292 293 } else { 294 295 Engine.Table("reply").Where("reply.ctype=? and reply.tid=?", ctype, tid).Limit(limit, offset).Desc("reply." + field).Find(rp) 296 } 297 } 298 } 299 return rp 300 301 } 302 303 func GetReplysByTidJoinUser(tid int64, ctype int64, offset int, limit int, field string) *[]*Replyjuser { 304 rp := &[]*Replyjuser{} 305 if field == "asc" { 306 307 //ctype等于-1为游客 ctype等于1为正常会员 这里ctype等于0的情况则返回两者 308 if tid == 0 { 309 if ctype != 0 { 310 Engine.Table("reply").Where("reply.ctype=?", ctype).Limit(limit, offset).Asc("reply.id").Join("LEFT", "user", "user.id = reply.uid").Find(rp) 311 } else { 312 Engine.Table("reply").Limit(limit, offset).Asc("reply.id").Join("LEFT", "user", "user.id = reply.uid").Find(rp) 313 } 314 315 } else { 316 317 if ctype == 0 { 318 Engine.Table("reply").Where("reply.tid=?", tid).Limit(limit, offset).Asc("reply.id").Join("LEFT", "user", "user.id = reply.uid").Find(rp) 319 320 } else { 321 322 Engine.Table("reply").Where("reply.ctype=? and reply.tid=?", ctype, tid).Limit(limit, offset).Asc("reply.id").Join("LEFT", "user", "user.id = reply.uid").Find(rp) 323 } 324 } 325 } else { 326 327 //ctype等于-1为游客 ctype等于1为正常会员 这里ctype等于0的情况则返回两者 328 if tid == 0 { 329 if ctype != 0 { 330 Engine.Table("reply").Where("reply.ctype=?", ctype).Limit(limit, offset).Desc("reply."+field).Join("LEFT", "user", "user.id = reply.uid").Find(rp) 331 } else { 332 Engine.Table("reply").Limit(limit, offset).Desc("reply."+field).Join("LEFT", "user", "user.id = reply.uid").Find(rp) 333 } 334 335 } else { 336 337 if ctype == 0 { 338 //Engine.Where("(ctype=-1 or ctype=1) and tid=?", tid).Limit(limit, offset).Desc(field).Find(rp) 339 Engine.Table("reply").Where("reply.tid=?", tid).Limit(limit, offset).Desc("reply."+field).Join("LEFT", "user", "user.id = reply.uid").Find(rp) 340 341 } else { 342 343 Engine.Table("reply").Where("reply.ctype=? and reply.tid=?", ctype, tid).Limit(limit, offset).Desc("reply."+field).Join("LEFT", "user", "user.id = reply.uid").Find(rp) 344 } 345 } 346 } 347 return rp 348 349 } 350 351 func GetReplysByTidUid(tid int64, uid int64, ctype int64, offset int, limit int, field string) *[]*Reply { 352 rp := &[]*Reply{} 353 354 //ctype等于-1为游客 ctype等于1为正常会员 这里ctype等于0的情况则返回两者 355 if tid == 0 { 356 if ctype != 0 { 357 Engine.Where("ctype=? and uid=?", ctype, uid).Limit(limit, offset).Desc(field).Find(rp) 358 } else { 359 Engine.Where("uid=?", uid).Limit(limit, offset).Desc(field).Find(rp) 360 } 361 362 } else { 363 364 if ctype == 0 { 365 //Engine.Where("(ctype=-1 or ctype=1) and tid=?", tid).Limit(limit, offset).Desc(field).Find(rp) 366 Engine.Where("tid=? and uid=?", tid, uid).Limit(limit, offset).Desc(field).Find(rp) 367 368 } else { 369 370 Engine.Where("ctype=? and tid=? and uid=?", ctype, tid, uid).Limit(limit, offset).Desc(field).Find(rp) 371 } 372 } 373 return rp 374 } 375 376 func GetReplysByTidUsername(tid int64, author string, ctype int64, offset int, limit int, field string) *[]*Reply { 377 rp := &[]*Reply{} 378 379 //ctype等于-1为游客 ctype等于1为正常会员 这里ctype等于0的情况则返回两者 380 if tid == 0 { 381 if ctype != 0 { 382 Engine.Where("ctype=? and author=?", ctype, author).Limit(limit, offset).Desc(field).Find(rp) 383 } else { 384 Engine.Where("author=?", author).Limit(limit, offset).Desc(field).Find(rp) 385 } 386 387 } else { 388 389 if ctype == 0 { 390 //Engine.Where("(ctype=-1 or ctype=1) and tid=?", tid).Limit(limit, offset).Desc(field).Find(rp) 391 Engine.Where("tid=? and author=?", tid, author).Limit(limit, offset).Desc(field).Find(rp) 392 393 } else { 394 395 Engine.Where("ctype=? and tid=? and author=?", ctype, tid, author).Limit(limit, offset).Desc(field).Find(rp) 396 } 397 } 398 return rp 399 } 400 401 func SetReplyCountByPid(qid int64) (int64, error) { 402 n, _ := Engine.Where("pid=?", qid).Count(&Reply{Pid: qid}) 403 404 qs := &Topic{} 405 qs.ReplyCount = n 406 affected, err := Engine.Where("id=?", qid).Cols("reply_count").Update(qs) 407 return affected, err 408 } 409 410 func SetReplyCountByTid(tid int64) (int64, error) { 411 n, _ := Engine.Where("tid=?", tid).Count(&Reply{Tid: tid}) 412 413 qs := &Topic{} 414 qs.ReplyCount = n 415 affected, err := Engine.Where("id=?", tid).Cols("reply_count").Update(qs) 416 return affected, err 417 } 418 419 func GetReplyCountByPid(pid int64) int64 { 420 n, _ := Engine.Where("pid=?", pid).Count(&Reply{Pid: pid}) 421 return n 422 } 423 424 func GetReplyCountByTid(tid int64) int64 { 425 n, _ := Engine.Where("tid=?", tid).Count(&Reply{Tid: tid}) 426 return n + 1 427 } 428 429 func SetReply(rid int64, rp *Reply) (int64, error) { 430 rp.Id = rid 431 return Engine.Insert(rp) 432 } 433 434 func AddReply(tid, pid, uid, ctype int64, content, attachment, author, avatar, avatarLarge, avatarMedium, avatarSmall, author_signature, nickname, email, website string) (int64, error) { 435 // 创建 Session 对象 436 sess := Engine.NewSession() 437 defer sess.Close() 438 // 启动事务 439 if err := sess.Begin(); err != nil { 440 return -1, err 441 } 442 443 // 执行事务 444 replyid := int64(0) 445 { 446 rp := new(Reply) 447 rp.Tid = tid 448 rp.Pid = pid 449 rp.Uid = uid 450 rp.Ctype = ctype 451 rp.Content = content 452 rp.Attachment = attachment 453 rp.Author = author 454 rp.AuthorSignature = author_signature 455 rp.Email = email 456 rp.Website = website 457 rp.Avatar = avatar 458 rp.AvatarLarge = avatarLarge 459 rp.AvatarMedium = avatarMedium 460 rp.AvatarSmall = avatarSmall 461 rp.Created = time.Now().Unix() 462 rp.ReplyTime = time.Now().Unix() 463 464 if _, err := sess.Insert(rp); err == nil { 465 //更新话题中的回应相关记录 466 467 tp := new(Topic) 468 if has, err := sess.Id(tid).Get(tp); has { 469 tp.ReplyTime = time.Now().Unix() 470 ReplyCount, _ := sess.Where("tid=?", tid).Count(&Reply{Tid: tid}) 471 tp.ReplyCount = ReplyCount + 1 472 tp.ReplyLastUserId = uid 473 tp.ReplyLastUsername = author 474 tp.ReplyLastNickname = nickname 475 //if row, err := sess.Table(&Topic{}).Where("id=?", tid).Update(&map[string]interface{}{"reply_time": time.Now().Unix(), "reply_count": ReplyCount, "reply_last_user_id": uid, "reply_last_username": author, "reply_last_nickname": nickname}); err != nil || row <= 0 { 476 if row, err := sess.Table(&Topic{}).Where("id=?", tid).Update(tp); err != nil || row <= 0 { 477 sess.Rollback() 478 return -1, errors.New(fmt.Sprint("AddReply #", rp.Id, "更新topic表相关信息出现错误,row:", row, "错误:", err)) 479 } 480 } else { 481 sess.Rollback() 482 return -1, err 483 } 484 485 if rp.Uid > 0 { 486 n, _ := sess.Where("uid=?", rp.Uid).Count(&Reply{}) 487 488 if row, err := sess.Table(&User{}).Where("id=?", rp.Uid).Update(&map[string]interface{}{"reply_time": time.Now().Unix(), "reply_count": n, "reply_last_tid": rp.Tid, "reply_last_topic": rp.ReplyLastTopic}); err != nil || row == 0 { 489 sess.Rollback() 490 return -1, errors.New(fmt.Sprint("AddReply #", rp.Id, "更新user表相关信息出现错误,row:", row, "错误:", err)) 491 } 492 } 493 494 replyid = rp.Id 495 } 496 497 } 498 499 // 提交事务 500 return replyid, sess.Commit() 501 } 502 503 func SetReplyContentByRid(rid int64, Content string) error { 504 if row, err := Engine.Table(&Reply{}).Where("id=?", rid).Update(&map[string]interface{}{"content": Content}); err != nil || row == 0 { 505 log.Println("SetReplyContentByRid row:", row, "SetReplyContentByRid出现错误:", err) 506 return err 507 } else { 508 return nil 509 } 510 511 } 512 513 func DelReply(rid int64) error { 514 if row, err := Engine.Id(rid).Delete(new(Reply)); err != nil || row == 0 { 515 log.Println("row:", row, "删除回应错误:", err) 516 return errors.New("删除回应错误!") 517 } else { 518 return nil 519 } 520 521 } 522 523 func DelReplyByRole(rid int64, uid int64, role int64) error { 524 allow := bool(false) 525 if anz, err := GetReply(rid); err == nil && anz != nil { 526 if anz.Uid == uid { 527 allow = true 528 } else if role < 0 { 529 allow = true 530 } 531 if allow { 532 if row, err := Engine.Id(rid).Delete(new(Reply)); err != nil || row == 0 { 533 log.Println("row:", row, "删除回复发生错误:", err) 534 return errors.New("删除回复发生错误!") 535 } else { 536 return nil 537 } 538 } else { 539 return errors.New("你没有权限删除回复!") 540 } 541 542 } else { 543 return errors.New("没有办法删除根本不存在的回复!") 544 } 545 546 } 547 548 func DelReplysByPid(pid int64) error { 549 rpy := &[]*Reply{} 550 if err := Engine.Where("pid=?", pid).Find(rpy); err == nil && rpy != nil { 551 for _, v := range *rpy { 552 if err := DelReplyByRole(v.Id, v.Uid, -1000); err != nil { 553 log.Println("DelReplyByRole:", err) 554 } 555 } 556 return nil 557 } else { 558 return err 559 } 560 561 } 562 563 func DelReplysByTid(tid int64) error { 564 565 rpy := &[]*Reply{} 566 if err := Engine.Where("tid=?", tid).Find(rpy); err == nil && rpy != nil { 567 for _, v := range *rpy { 568 if err := DelReplyByRole(v.Id, v.Uid, -1000); err != nil { 569 log.Println("DelReplyByRole:", err) 570 } 571 572 //检查附件字段并尝试删除文件 573 if len(v.Attachment) > 0 { 574 allow := true //设为允许管理员权限 暂时不细分 575 if p := helper.URL2local(v.Attachment); helper.Exist(p) { 576 //验证是否管理员权限 577 if allow { 578 if err := os.Remove(p); err != nil { 579 //可以输出错误,但不要反回错误,以免陷入死循环无法删掉 580 log.Println("ROOT DEL Reply Attachment, Reply ID:", v.Id, ",ERR:", err) 581 } 582 } else { //检查用户对文件的所有权 583 if helper.VerifyUserfile(p, strconv.FormatInt(v.Uid, 10)) { 584 if err := os.Remove(p); err != nil { 585 log.Println("DEL Reply Attachment, Reply ID:", v.Id, ",ERR:", err) 586 } 587 } 588 } 589 } /*else { 590 591 ////删除七牛云存储中的图片 592 593 rsCli := rs.New(nil) 594 595 //2014-8-21-134506AB4F24A56EF60543.jpg,2014-8-21-134506AB4F24A56EF60543.jpg 596 imgkeys := strings.Split(v.Attachment, ",") 597 for _, v := range imgkeys { 598 tmpkey := strings.Split(v, ".") 599 delkey := tmpkey[0] //key是32位 不含后缀 600 rsCli.Delete(nil, BUCKET, delkey) 601 } 602 603 } 604 */ 605 606 } 607 } 608 return nil 609 } else { 610 return err 611 } 612 613 }