github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/models/topic.go (about)

     1  package models
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"log"
     7  	"os"
     8  	"strconv"
     9  	"strings"
    10  	"time"
    11  	"github.com/insionng/yougam/helper"
    12  )
    13  
    14  type Topic struct {
    15  	Id                int64
    16  	Pid               int64   `xorm:"index"` //为0代表没有上级,本身就是顶层话题 大于0则本身是子话题,而该数字代表上级话题的id
    17  	Cid               int64   `xorm:"index"`
    18  	Nid               int64   `xorm:"index"` //nodeid
    19  	Uid               int64   `xorm:"index"`
    20  	Sort              int64   `xorm:"index"` //排序字段 需要手动对话题排序置顶等操作时使用
    21  	Ctype             int64   `xorm:"index"` //ctype作用在于区分话题的类型
    22  	Title             string  `xorm:"index"`
    23  	Excerpt           string  `xorm:"index"` //摘录
    24  	Content           string  `xorm:"text"`
    25  	Tailinfo          string  `xorm:"index"` //尾巴信息 附带内容,譬如回复可见类型的话题时作为存储评论者UID集合
    26  	Attachment        string  `xorm:"text"`  //附件 JSON
    27  	Thumbnails        string  `xorm:"index"` //Original remote file
    28  	ThumbnailsLarge   string  `xorm:"index"` //200x300
    29  	ThumbnailsMedium  string  `xorm:"index"` //200x150
    30  	ThumbnailsSmall   string  `xorm:"index"` //70x70
    31  	Avatar            string  `xorm:"index"` //200x200
    32  	AvatarLarge       string  `xorm:"index"` //100x100
    33  	AvatarMedium      string  `xorm:"index"` //48x48
    34  	AvatarSmall       string  `xorm:"index"` //32x32
    35  	Tags              string  `xorm:"index"`
    36  	Created           int64   `xorm:"created index"`
    37  	Updated           int64   `xorm:"updated"`
    38  	Hotness           float64 `xorm:"index"`
    39  	Confidence        float64 `xorm:"index"` //信任度数值
    40  	Hotup             int64   `xorm:"index"`
    41  	Hotdown           int64   `xorm:"index"`
    42  	Hotscore          int64   `xorm:"index"` //Hotup  -	Hotdown
    43  	Hotvote           int64   `xorm:"index"` //Hotup  + Hotdown
    44  	Views             int64
    45  	Author            string `xorm:"index"`
    46  	Template          string `xorm:"index"`
    47  	Category          string `xorm:"index"`
    48  	Node              string `xorm:"index"` //nodename
    49  	ReplyTime         int64
    50  	ReplyCount        int64
    51  	ReplyLastUserId   int64
    52  	ReplyLastUsername string
    53  	ReplyLastNickname string
    54  	FavoriteCount     int64
    55  	Latitude          float64 `xorm:"index"`   //纬度
    56  	Longitude         float64 `xorm:"index"`   //经度
    57  	Version           int64   `xorm:"version"` //乐观锁
    58  }
    59  
    60  type TopicMark struct {
    61  	Id  int64
    62  	Uid int64 `xorm:"index"`
    63  	Cid int64 `xorm:"index"` //该话题所属于的分类
    64  	Tid int64 `xorm:"index"` //Topic id
    65  }
    66  
    67  type Topicjuser struct {
    68  	Topic `xorm:"extends"`
    69  	User  `xorm:"extends"`
    70  }
    71  
    72  type Topicjtopicmark struct {
    73  	Topic     `xorm:"extends"`
    74  	TopicMark `xorm:"extends"`
    75  }
    76  
    77  type Topicjtopicmarkjuser struct {
    78  	Topic     `xorm:"extends"`
    79  	TopicMark `xorm:"extends"`
    80  	User      `xorm:"extends"`
    81  }
    82  
    83  /*
    84  func SetTopicMark(uid int64, tid int64) (int64, error) {
    85  
    86  	tpm := new(TopicMark)
    87  	tpm.Uid = uid
    88  	tpm.Tid = tid
    89  	rows, err := Engine.Insert(tpm)
    90  	return rows, err
    91  }
    92  */
    93  
    94  func SetTopicMark(uid, cid, tid int64) (int64, error) {
    95  	qm := &TopicMark{Uid: uid, Cid: cid, Tid: tid}
    96  	return Engine.Insert(qm)
    97  }
    98  
    99  /*
   100  func DelTopicMark(uid int64, tid int64) {
   101  	tpm := new(TopicMark)
   102  	Engine.Where("uid=? and tid=?", uid, tid).Delete(tpm)
   103  }
   104  */
   105  func DelTopicMark(uid, tid int64) (int64, error) {
   106  	return Engine.Where("uid=? and tid=?", uid, tid).Delete(new(TopicMark))
   107  }
   108  
   109  func TopicMarkCount(tid int64) (int64, error) {
   110  	return Engine.Where("tid=?", tid).Count(&TopicMark{})
   111  }
   112  
   113  func TopicMarkCountByUid(uid int64) (int64, error) {
   114  	return Engine.Where("uid=?", uid).Count(&TopicMark{})
   115  }
   116  
   117  func IsTopicMark(uid int64, tid int64) bool {
   118  
   119  	tpm := new(TopicMark)
   120  
   121  	if has, err := Engine.Where("uid=? and tid=?", uid, tid).Get(tpm); err != nil {
   122  		return false
   123  	} else {
   124  		if has {
   125  			return (tpm.Uid == uid)
   126  		} else {
   127  			return false
   128  		}
   129  	}
   130  
   131  }
   132  
   133  func GetTopicMarksViaUid(offset, limit int, uid int64, field string) (*[]*TopicMark, error) {
   134  	objs := new([]*TopicMark)
   135  	var err error
   136  	if len(field) > 0 {
   137  		err = Engine.Where("uid=?", uid).Limit(limit, offset).Desc(field).Find(objs)
   138  	} else {
   139  		err = Engine.Where("uid=?", uid).Limit(limit, offset).Find(objs)
   140  	}
   141  	return objs, err
   142  }
   143  
   144  func GetTopicMarksViaUidWithCid(offset, limit int, uid, cid int64, field string) (*[]*TopicMark, error) {
   145  	objs := new([]*TopicMark)
   146  	var err error
   147  	if len(field) > 0 {
   148  		err = Engine.Where("uid = ? and cid = ?", uid, cid).Limit(limit, offset).Desc(field).Find(objs)
   149  	} else {
   150  		err = Engine.Where("uid = ? and cid = ?", uid, cid).Limit(limit, offset).Find(objs)
   151  	}
   152  	return objs, err
   153  }
   154  
   155  func AddTopic(title, content, avatar, avatarLarge, avatarMedium, avatarSmall string, pid, cid, nid, uid int64) (int64, error) {
   156  	// 创建 Session 对象
   157  	sess := Engine.NewSession()
   158  	defer sess.Close()
   159  	// 启动事务
   160  	if err := sess.Begin(); err != nil {
   161  		return -1, err
   162  	}
   163  
   164  	//执行事务
   165  	topicid := int64(0)
   166  	{
   167  		cat := &Category{}
   168  		if cid > 0 {
   169  			if has, err := sess.Where("id=?", cid).Get(cat); (err != nil) || (has == false) {
   170  				sess.Rollback()
   171  				return -1, err
   172  			}
   173  		}
   174  
   175  		nd := &Node{}
   176  		if nid > 0 {
   177  			if has, err := sess.Where("id=?", nid).Get(nd); (err != nil) || (has == false) {
   178  				sess.Rollback()
   179  				return -1, err
   180  			}
   181  		}
   182  
   183  		usr := &User{}
   184  		if uid > 0 {
   185  			if has, err := sess.Where("id=?", uid).Get(usr); (err != nil) || (has == false) {
   186  				sess.Rollback()
   187  				return -1, err
   188  			}
   189  		}
   190  
   191  		tp := new(Topic)
   192  		tp.Pid = pid
   193  		tp.Cid = cat.Id
   194  		tp.Nid = nid
   195  		tp.Uid = uid
   196  		tp.Title = title
   197  		tp.Content = content
   198  		tp.Author = usr.Username
   199  		if pid == 0 { //若果本身是父级话题则处理
   200  			tp.Avatar = avatar
   201  			tp.AvatarLarge = avatarLarge
   202  			tp.AvatarMedium = avatarMedium
   203  			tp.AvatarSmall = avatarSmall
   204  		}
   205  		tp.Category = cat.Title
   206  		tp.Node = nd.Title
   207  		tp.Created = time.Now().Unix()
   208  
   209  		if row, err := sess.Insert(tp); (err == nil) && (row > 0) {
   210  			if tp.Uid > 0 {
   211  				n, _ := sess.Where("uid=?", tp.Uid).Count(&Topic{})
   212  				_u := map[string]interface{}{"topic_time": time.Now().Unix(), "topic_count": n, "topic_last_nid": tp.Nid, "topic_last_node": tp.Node}
   213  				if row, err := sess.Table(&User{}).Where("id=?", tp.Uid).Update(&_u); err != nil || row <= 0 {
   214  
   215  					return -1, errors.New(fmt.Sprint("AddTopic更新user表话题相关信息时:出现", row, "行影响,错误:", err))
   216  
   217  				}
   218  			}
   219  			topicid = tp.Id
   220  		} else {
   221  			sess.Rollback()
   222  			return -1, err
   223  		}
   224  
   225  	}
   226  
   227  	// 提交事务
   228  	return topicid, sess.Commit()
   229  }
   230  
   231  func SetTopic(tid int64, tp *Topic) (int64, error) {
   232  	tp.Id = tid
   233  	return Engine.Insert(tp)
   234  }
   235  
   236  func GetTopicsByHotnessNodes(nodelimit int, topiclimit int) []*[]*Topic {
   237  	//找出最热的节点:views优先 然后按 hotness排序 大概找出5到10个节点
   238  	//按上面找的节点读取下级话题
   239  	nds, _ := GetNodes(0, nodelimit, "hotness")
   240  	topics := make([]*[]*Topic, 0)
   241  
   242  	if len(*nds) > 0 {
   243  		i := 0
   244  		for _, v := range *nds {
   245  			i = i + 1
   246  			tps := GetTopicsByNid(v.Id, 0, topiclimit, 0, "views")
   247  			if len(*tps) != 0 {
   248  				topics = append(topics, tps)
   249  			}
   250  			if i == len(*nds)-1 {
   251  				break
   252  			}
   253  		}
   254  	}
   255  
   256  	return topics
   257  
   258  }
   259  
   260  func GetTopicsByScoreNodes(nodelimit int, topiclimit int) []*[]*Topic {
   261  	//找出最热的节点:views优先 然后按 hotness排序 大概找出5到10个节点
   262  	//按上面找的节点读取下级话题
   263  	nds, _ := GetNodes(0, nodelimit, "hotscore")
   264  	topics := make([]*[]*Topic, 0)
   265  
   266  	if len(*nds) > 0 {
   267  		i := 0
   268  		for _, v := range *nds {
   269  			i = i + 1
   270  			tps := GetTopicsByNid(v.Id, 0, topiclimit, 0, "views")
   271  			if len(*tps) != 0 {
   272  				topics = append(topics, tps)
   273  			}
   274  			if i == len(*nds) {
   275  				break
   276  			}
   277  		}
   278  	}
   279  
   280  	return topics
   281  
   282  }
   283  
   284  func GetTopicsByHotnessCategory(catlimit int, topiclimit int) []*[]*Topic {
   285  	//找出最热的分类:views优先 然后按 hotness排序 大概找出5到10个节点
   286  	//按上面找的节点读取下级话题
   287  	cats, _ := GetCategories(0, catlimit, "hotness")
   288  	topics := make([]*[]*Topic, 0)
   289  
   290  	if len(*cats) > 0 {
   291  		i := 0
   292  		for _, v := range *cats {
   293  			i = i + 1
   294  			//(cid int64, offset int, limit int, ctype int64, field string)
   295  			tps := GetTopicsByCid(v.Id, 0, topiclimit, 0, "views")
   296  			if len(*tps) != 0 {
   297  				topics = append(topics, tps)
   298  			}
   299  			if i == len(*cats) {
   300  				break
   301  			}
   302  		}
   303  	}
   304  
   305  	return topics
   306  
   307  }
   308  
   309  func GetTopic(id int64) (*Topic, error) {
   310  	tp := new(Topic)
   311  	has, err := Engine.Id(id).Get(tp)
   312  	if has {
   313  		return tp, err
   314  	} else {
   315  		return nil, err
   316  	}
   317  }
   318  
   319  func GetTopics(offset int, limit int, field string) (*[]*Topic, error) {
   320  	tps := new([]*Topic)
   321  	err := Engine.Limit(limit, offset).Desc(field).Find(tps)
   322  	return tps, err
   323  }
   324  
   325  func GetSubTopics(pid int64, offset int, limit int, field string) (*[]*Topic, error) {
   326  	tps := new([]*Topic)
   327  	err := Engine.Where("pid=?", pid).Limit(limit, offset).Desc(field).Find(tps)
   328  	return tps, err
   329  }
   330  
   331  func GetTopicsCount(offset int, limit int) (int64, error) {
   332  	total, err := Engine.Limit(limit, offset).Count(&Topic{})
   333  	return total, err
   334  }
   335  
   336  func GetTopicsByPid4Count(pid int64, offset int, limit int, ctype int64) (int64, error) {
   337  
   338  	if ctype != 0 {
   339  		return Engine.Where("(pid=? or id=?) and ctype=?", pid, pid, ctype).Limit(limit, offset).Count(&Topic{})
   340  	} else {
   341  		return Engine.Where("pid=? or id=?", pid, pid).Limit(limit, offset).Count(&Topic{})
   342  	}
   343  
   344  }
   345  
   346  func GetTopicsCountByNode(node string, offset int, limit int) (int64, error) {
   347  	total, err := Engine.Where("node=?", node).Limit(limit, offset).Count(&Topic{})
   348  	return total, err
   349  }
   350  
   351  func GetTopicsByCategoryCount(category string, offset int, limit int, field string) (int64, error) {
   352  	total, err := Engine.Where("category=?", category).Limit(limit, offset).Count(&Topic{})
   353  	return total, err
   354  }
   355  
   356  //GetTopicsByCid大数据下如出现性能问题 可以使用 GetTopicsByCidOnBetween
   357  func GetTopicsByCid(cid int64, offset int, limit int, ctype int64, field string) *[]*Topic {
   358  	//排序首先是热值优先,然后是时间优先。
   359  	tps := new([]*Topic)
   360  	switch {
   361  	case field == "asc":
   362  		if ctype != 0 {
   363  			Engine.Where("cid=? and ctype=?", cid, ctype).Limit(limit, offset).Asc("id").Find(tps)
   364  		} else {
   365  			Engine.Where("cid=?", cid).Limit(limit, offset).Asc("id").Find(tps)
   366  
   367  		}
   368  	case field == "views" || field == "reply_count":
   369  		if ctype != 0 {
   370  			Engine.Where("cid=? and ctype=?", cid, ctype).Desc(field).Limit(limit, offset).Find(tps)
   371  
   372  		} else {
   373  			if cid == 0 {
   374  				Engine.Desc(field).Limit(limit, offset).Find(tps)
   375  			} else {
   376  				Engine.Where("cid=?", cid).Desc(field).Limit(limit, offset).Find(tps)
   377  			}
   378  
   379  		}
   380  	default:
   381  		if ctype != 0 {
   382  			Engine.Where("cid=? and ctype=?", cid, ctype).Limit(limit, offset).Desc(field, "views", "reply_count", "created").Find(tps)
   383  		} else {
   384  			if cid == 0 {
   385  				Engine.Limit(limit, offset).Desc(field, "views", "reply_count", "created").Find(tps)
   386  			} else {
   387  				Engine.Where("cid=?", cid).Limit(limit, offset).Desc(field, "views", "reply_count", "created").Find(tps)
   388  			}
   389  		}
   390  
   391  	}
   392  	return tps
   393  }
   394  
   395  func GetSubjectsByCategory4Count(category string, offset int, limit int, ctype int64) (int64, error) {
   396  
   397  	if ctype != 0 {
   398  		return Engine.Where("pid=0 and category=? and ctype=?", category, ctype).Limit(limit, offset).Count(&Topic{})
   399  	} else {
   400  		if category == "" {
   401  			return Engine.Where("pid=0").Limit(limit, offset).Count(&Topic{})
   402  		} else {
   403  			return Engine.Where("pid=0 and category=?", category).Limit(limit, offset).Count(&Topic{})
   404  		}
   405  	}
   406  }
   407  
   408  func GetSubjectsByCid4Count(cid int64, offset int, limit int, ctype int64) (int64, error) {
   409  
   410  	if ctype != 0 {
   411  		return Engine.Where("pid=0 and cid=? and ctype=?", cid, ctype).Limit(limit, offset).Count(&Topic{})
   412  	} else {
   413  		if cid == 0 {
   414  			return Engine.Where("pid=0").Limit(limit, offset).Count(&Topic{})
   415  		} else {
   416  			return Engine.Where("pid=0 and cid=?", cid).Limit(limit, offset).Count(&Topic{})
   417  		}
   418  	}
   419  }
   420  
   421  func GetSubjectsByCid(cid int64, offset int, limit int, ctype int64, field string) *[]*Topic {
   422  
   423  	tps := new([]*Topic)
   424  	switch {
   425  	case field == "asc":
   426  		if ctype != 0 {
   427  			Engine.Table("topic").Where("topic.pid=0 and topic.cid=? and topic.ctype=?", cid, ctype).Limit(limit, offset).Asc("topic.id").Find(tps)
   428  		} else {
   429  			if cid == 0 {
   430  				Engine.Table("topic").Where("topic.pid=0").Limit(limit, offset).Asc("topic.id").Find(tps)
   431  			} else {
   432  				Engine.Table("topic").Where("topic.pid=0 and topic.cid=?", cid).Limit(limit, offset).Asc("topic.id").Find(tps)
   433  			}
   434  		}
   435  	case field == "views" || field == "reply_count":
   436  		if ctype != 0 {
   437  			Engine.Table("topic").Where("topic.pid=0 and topic.cid=? and topic.ctype=?", cid, ctype).Desc("topic."+field).Limit(limit, offset).Find(tps)
   438  
   439  		} else {
   440  			if cid == 0 {
   441  				Engine.Table("topic").Where("topic.pid=0").Desc("topic."+field).Limit(limit, offset).Find(tps)
   442  			} else {
   443  				Engine.Table("topic").Where("topic.pid=0 and topic.cid=?", cid).Desc("topic."+field).Limit(limit, offset).Find(tps)
   444  			}
   445  
   446  		}
   447  	default:
   448  		if ctype != 0 {
   449  			Engine.Table("topic").Where("topic.pid=0 and topic.cid=? and topic.ctype=?", cid, ctype).Limit(limit, offset).Desc("topic."+field, "topic.views", "topic.reply_count", "topic.created").Find(tps)
   450  		} else {
   451  			if cid == 0 {
   452  				Engine.Table("topic").Where("topic.pid=0").Limit(limit, offset).Desc("topic."+field, "topic.views", "topic.reply_count", "topic.created").Find(tps)
   453  			} else {
   454  				Engine.Table("topic").Where("topic.pid=0 and topic.cid=?", cid).Limit(limit, offset).Desc("topic."+field, "topic.views", "topic.reply_count", "topic.created").Find(tps)
   455  			}
   456  		}
   457  
   458  	}
   459  	return tps
   460  }
   461  
   462  func GetSubjectsByCidJoinUser(cid int64, offset int, limit int, ctype int64, field string) *[]*Topicjuser {
   463  
   464  	tps := new([]*Topicjuser)
   465  	switch {
   466  	case field == "asc":
   467  		if ctype != 0 {
   468  			Engine.Table("topic").Where("topic.pid=0 and topic.cid=? and topic.ctype=?", cid, ctype).Limit(limit, offset).Asc("topic.id").Join("LEFT", "user", "user.id = topic.uid").Find(tps)
   469  		} else {
   470  			if cid == 0 {
   471  				Engine.Table("topic").Where("topic.pid=0").Limit(limit, offset).Asc("topic.id").Join("LEFT", "user", "user.id = topic.uid").Find(tps)
   472  			} else {
   473  				Engine.Table("topic").Where("topic.pid=0 and topic.cid=?", cid).Limit(limit, offset).Asc("topic.id").Join("LEFT", "user", "user.id = topic.uid").Find(tps)
   474  			}
   475  		}
   476  	case field == "views" || field == "reply_count":
   477  		if ctype != 0 {
   478  			Engine.Table("topic").Where("topic.pid=0 and topic.cid=? and topic.ctype=?", cid, ctype).Desc("topic."+field).Limit(limit, offset).Join("LEFT", "user", "user.id = topic.uid").Find(tps)
   479  
   480  		} else {
   481  			if cid == 0 {
   482  				Engine.Table("topic").Where("topic.pid=0").Desc("topic."+field).Limit(limit, offset).Join("LEFT", "user", "user.id = topic.uid").Find(tps)
   483  			} else {
   484  				Engine.Table("topic").Where("topic.pid=0 and topic.cid=?", cid).Desc("topic."+field).Limit(limit, offset).Join("LEFT", "user", "user.id = topic.uid").Find(tps)
   485  			}
   486  
   487  		}
   488  	default:
   489  		if ctype != 0 {
   490  			Engine.Table("topic").Where("topic.pid=0 and topic.cid=? and topic.ctype=?", cid, ctype).Limit(limit, offset).Desc("topic."+field, "topic.views", "topic.reply_count", "topic.created").Join("LEFT", "user", "user.id = topic.uid").Find(tps)
   491  		} else {
   492  			if cid == 0 {
   493  				Engine.Table("topic").Where("topic.pid=0").Limit(limit, offset).Desc("topic."+field, "topic.views", "topic.reply_count", "topic.created").Join("LEFT", "user", "user.id = topic.uid").Find(tps)
   494  			} else {
   495  				Engine.Table("topic").Where("topic.pid=0 and topic.cid=?", cid).Limit(limit, offset).Desc("topic."+field, "topic.views", "topic.reply_count", "topic.created").Join("LEFT", "user", "user.id = topic.uid").Find(tps)
   496  			}
   497  		}
   498  
   499  	}
   500  	return tps
   501  }
   502  
   503  func GetSubjectsByCategory(category string, offset int, limit int, ctype int64, field string) *[]*Topic {
   504  
   505  	tps := new([]*Topic)
   506  	switch {
   507  	case field == "asc":
   508  		if ctype != 0 {
   509  			Engine.Table("topic").Where("topic.pid=0 and topic.category=? and topic.ctype=?", category, ctype).Limit(limit, offset).Asc("topic.id").Find(tps)
   510  		} else {
   511  			Engine.Table("topic").Where("topic.pid=0 and topic.category=?", category).Limit(limit, offset).Asc("topic.id").Find(tps)
   512  
   513  		}
   514  	case field == "views" || field == "reply_count":
   515  		if ctype != 0 {
   516  			Engine.Table("topic").Where("topic.pid=0 and topic.category=? and topic.ctype=?", category, ctype).Desc("topic."+field).Limit(limit, offset).Find(tps)
   517  
   518  		} else {
   519  			if category == "" {
   520  				Engine.Table("topic").Where("topic.pid=0").Desc("topic."+field).Limit(limit, offset).Find(tps)
   521  			} else {
   522  				Engine.Table("topic").Where("topic.pid=0 and topic.category=?", category).Desc("topic."+field).Limit(limit, offset).Find(tps)
   523  			}
   524  
   525  		}
   526  	default:
   527  		if ctype != 0 {
   528  			Engine.Table("topic").Where("topic.pid=0 and topic.category=? and topic.ctype=?", category, ctype).Limit(limit, offset).Desc("topic."+field, "topic.views", "topic.reply_count", "topic.created").Find(tps)
   529  		} else {
   530  			if category == "" {
   531  				Engine.Table("topic").Where("topic.pid=0").Limit(limit, offset).Desc("topic."+field, "topic.views", "topic.reply_count", "topic.created").Find(tps)
   532  			} else {
   533  				Engine.Table("topic").Where("topic.pid=0 and topic.category=?", category).Limit(limit, offset).Desc("topic."+field, "topic.views", "topic.reply_count", "topic.created").Find(tps)
   534  			}
   535  		}
   536  
   537  	}
   538  	return tps
   539  }
   540  
   541  func GetSubjectsByCategoryJoinUser(category string, offset int, limit int, ctype int64, field string) *[]*Topicjuser {
   542  
   543  	tps := new([]*Topicjuser)
   544  	switch {
   545  	case field == "asc":
   546  		if ctype != 0 {
   547  			Engine.Table("topic").Where("topic.pid=0 and topic.category=? and topic.ctype=?", category, ctype).Limit(limit, offset).Asc("topic.id").Join("LEFT", "user", "user.id = topic.uid").Find(tps)
   548  		} else {
   549  			Engine.Table("topic").Where("topic.pid=0 and topic.category=?", category).Limit(limit, offset).Asc("topic.id").Join("LEFT", "user", "user.id = topic.uid").Find(tps)
   550  
   551  		}
   552  	case field == "views" || field == "reply_count":
   553  		if ctype != 0 {
   554  			Engine.Table("topic").Where("topic.pid=0 and topic.category=? and topic.ctype=?", category, ctype).Desc("topic."+field).Limit(limit, offset).Join("LEFT", "user", "user.id = topic.uid").Find(tps)
   555  
   556  		} else {
   557  			if category == "" {
   558  				Engine.Table("topic").Where("topic.pid=0").Desc("topic."+field).Limit(limit, offset).Join("LEFT", "user", "user.id = topic.uid").Find(tps)
   559  			} else {
   560  				Engine.Table("topic").Where("topic.pid=0 and topic.category=?", category).Desc("topic."+field).Limit(limit, offset).Join("LEFT", "user", "user.id = topic.uid").Find(tps)
   561  			}
   562  
   563  		}
   564  	default:
   565  		if ctype != 0 {
   566  			Engine.Table("topic").Where("topic.pid=0 and topic.category=? and topic.ctype=?", category, ctype).Limit(limit, offset).Desc("topic."+field, "topic.views", "topic.reply_count", "topic.created").Join("LEFT", "user", "user.id = topic.uid").Find(tps)
   567  		} else {
   568  			if category == "" {
   569  				Engine.Table("topic").Where("topic.pid=0").Limit(limit, offset).Desc("topic."+field, "topic.views", "topic.reply_count", "topic.created").Join("LEFT", "user", "user.id = topic.uid").Find(tps)
   570  			} else {
   571  				Engine.Table("topic").Where("topic.pid=0 and topic.category=?", category).Limit(limit, offset).Desc("topic."+field, "topic.views", "topic.reply_count", "topic.created").Join("LEFT", "user", "user.id = topic.uid").Find(tps)
   572  			}
   573  		}
   574  
   575  	}
   576  	return tps
   577  }
   578  
   579  func GetSubjectsByUid(uid int64, offset int, limit int, ctype int64, field string) *[]*Topic {
   580  	//排序首先是热值优先,然后是时间优先。
   581  	tps := new([]*Topic)
   582  	switch {
   583  	case field == "asc":
   584  		if ctype != 0 {
   585  			Engine.Where("pid=0 and uid=? and ctype=?", uid, ctype).Limit(limit, offset).Asc("id").Find(tps)
   586  		} else {
   587  			Engine.Where("pid=0 and uid=?", uid).Limit(limit, offset).Asc("id").Find(tps)
   588  
   589  		}
   590  	case field == "views" || field == "reply_count":
   591  		if ctype != 0 {
   592  			Engine.Where("pid=0 and uid=? and ctype=?", uid, ctype).Desc(field).Limit(limit, offset).Find(tps)
   593  
   594  		} else {
   595  			if uid == 0 {
   596  				Engine.Where("pid=0").Desc(field).Limit(limit, offset).Find(tps)
   597  			} else {
   598  				Engine.Where("pid=0 and uid=?", uid).Desc(field).Limit(limit, offset).Find(tps)
   599  			}
   600  
   601  		}
   602  	default:
   603  		if ctype != 0 {
   604  			Engine.Where("pid=0 and uid=? and ctype=?", uid, ctype).Limit(limit, offset).Desc(field, "views", "reply_count", "created").Find(tps)
   605  		} else {
   606  			if uid == 0 {
   607  				Engine.Where("pid=0").Limit(limit, offset).Desc(field, "views", "reply_count", "created").Find(tps)
   608  			} else {
   609  				Engine.Where("pid=0 and uid=?", uid).Limit(limit, offset).Desc(field, "views", "reply_count", "created").Find(tps)
   610  			}
   611  		}
   612  
   613  	}
   614  	return tps
   615  }
   616  
   617  func GetSubjectsByUsername(author string, offset int, limit int, ctype int64, field string) *[]*Topic {
   618  	//排序首先是热值优先,然后是时间优先。
   619  	tps := new([]*Topic)
   620  	switch {
   621  	case field == "asc":
   622  		if ctype != 0 {
   623  			Engine.Where("pid=0 and author=? and ctype=?", author, ctype).Limit(limit, offset).Asc("id").Find(tps)
   624  		} else {
   625  			Engine.Where("pid=0 and author=?", author).Limit(limit, offset).Asc("id").Find(tps)
   626  
   627  		}
   628  	case field == "views" || field == "reply_count":
   629  		if ctype != 0 {
   630  			Engine.Where("pid=0 and author=? and ctype=?", author, ctype).Desc(field).Limit(limit, offset).Find(tps)
   631  
   632  		} else {
   633  			if len(author) == 0 {
   634  				Engine.Where("pid=0").Desc(field).Limit(limit, offset).Find(tps)
   635  			} else {
   636  				Engine.Where("pid=0 and author=?", author).Desc(field).Limit(limit, offset).Find(tps)
   637  			}
   638  
   639  		}
   640  	default:
   641  		if ctype != 0 {
   642  			Engine.Where("pid=0 and author=? and ctype=?", author, ctype).Limit(limit, offset).Desc(field, "views", "reply_count", "created").Find(tps)
   643  		} else {
   644  			if len(author) == 0 {
   645  				Engine.Where("pid=0").Limit(limit, offset).Desc(field, "views", "reply_count", "created").Find(tps)
   646  			} else {
   647  				Engine.Where("pid=0 and author=?", author).Limit(limit, offset).Desc(field, "views", "reply_count", "created").Find(tps)
   648  			}
   649  		}
   650  
   651  	}
   652  	return tps
   653  }
   654  
   655  func GetSubjectsCountByUsername(author string, offset int, limit int, ctype int64) (int64, error) {
   656  
   657  	if ctype != 0 {
   658  		return Engine.Where("pid=0 and author=? and ctype=?", author, ctype).Limit(limit, offset).Count(&Topic{})
   659  	} else {
   660  		if author == "" {
   661  			return Engine.Where("pid=0").Limit(limit, offset).Count(&Topic{})
   662  		} else {
   663  			return Engine.Where("pid=0 and author=?", author).Limit(limit, offset).Count(&Topic{})
   664  		}
   665  	}
   666  
   667  }
   668  
   669  func GetTopicsByCidOnBetween(cid int64, startid int64, endid int64, offset int, limit int, ctype int64, field string) *[]*Topic {
   670  	tps := new([]*Topic)
   671  	switch {
   672  	case field == "asc":
   673  		if ctype != 0 {
   674  			Engine.Where("cid=? and ctype=? and id>? and id<?", cid, ctype, startid-1, endid+1).Limit(limit, offset).Asc("id").Find(tps)
   675  		} else {
   676  			if cid == 0 {
   677  				Engine.Where("id>? and id<?", startid-1, endid+1).Limit(limit, offset).Asc("id").Find(tps)
   678  			} else {
   679  				Engine.Where("cid=? and id>? and id<?", cid, startid-1, endid+1).Limit(limit, offset).Asc("id").Find(tps)
   680  			}
   681  		}
   682  	default: //Desc
   683  		if ctype != 0 {
   684  			Engine.Where("cid=? and ctype=? and id>? and id<?", cid, ctype, startid-1, endid+1).Limit(limit, offset).Desc(field, "views", "reply_count", "created").Find(tps)
   685  		} else {
   686  			if cid == 0 {
   687  				Engine.Where("id>? and id<?", startid-1, endid+1).Limit(limit, offset).Desc(field, "views", "reply_count", "created").Find(tps)
   688  			} else {
   689  				Engine.Where("cid=? and id>? and id<?", cid, startid-1, endid+1).Limit(limit, offset).Desc(field, "views", "reply_count", "created").Find(tps)
   690  			}
   691  		}
   692  	}
   693  
   694  	return tps
   695  }
   696  
   697  func GetTopicsByCategory(category string, offset int, limit int, ctype int64, field string) *[]*Topic {
   698  	//排序首先是热值优先,然后是时间优先。
   699  	tps := new([]*Topic)
   700  	switch {
   701  	case field == "asc":
   702  		if ctype != 0 {
   703  			Engine.Where("category=? and ctype=?", category, ctype).Limit(limit, offset).Asc("id").Find(tps)
   704  		} else {
   705  			Engine.Where("category=?", category).Limit(limit, offset).Asc("id").Find(tps)
   706  
   707  		}
   708  	case field == "views" || field == "reply_count":
   709  		if ctype != 0 {
   710  			Engine.Where("category=? and ctype=?", category, ctype).Desc(field).Limit(limit, offset).Find(tps)
   711  
   712  		} else {
   713  			if category == "" {
   714  				Engine.Desc(field).Limit(limit, offset).Find(tps)
   715  			} else {
   716  				Engine.Where("category=?", category).Desc(field).Limit(limit, offset).Find(tps)
   717  			}
   718  
   719  		}
   720  	default:
   721  		if ctype != 0 {
   722  			Engine.Where("category=? and ctype=?", category, ctype).Limit(limit, offset).Desc(field, "views", "reply_count", "created").Find(tps)
   723  		} else {
   724  			if category == "" {
   725  				Engine.Limit(limit, offset).Desc(field, "views", "reply_count", "created").Find(tps)
   726  			} else {
   727  				Engine.Where("category=?", category).Limit(limit, offset).Desc(field, "views", "reply_count", "created").Find(tps)
   728  			}
   729  		}
   730  
   731  	}
   732  	return tps
   733  }
   734  
   735  //GetTopicsByUid不区分父子话题
   736  func GetTopicsByUid(uid int64, offset int, limit int, ctype int64, field string) *[]*Topic {
   737  	//排序首先是热值优先,然后是时间优先。
   738  	tps := new([]*Topic)
   739  
   740  	switch {
   741  	case field == "asc":
   742  		if uid == 0 {
   743  			//q.Offset(offset).Limit(limit).OrderByDesc(field).OrderByDesc("views").OrderByDesc("reply_count").OrderByDesc("created").FindAll(&allt)
   744  			return nil
   745  		} else {
   746  			if ctype != 0 {
   747  				Engine.Where("uid=? and ctype=?", uid, ctype).Limit(limit, offset).Asc("id").Find(tps)
   748  			} else {
   749  				Engine.Where("uid=?", uid).Limit(limit, offset).Asc("id").Find(tps)
   750  			}
   751  		}
   752  	default:
   753  		if uid <= 0 {
   754  			//q.Offset(offset).Limit(limit).OrderByDesc(field).OrderByDesc("views").OrderByDesc("reply_count").OrderByDesc("created").FindAll(&allt)
   755  			return nil
   756  		} else {
   757  			if ctype != 0 {
   758  				Engine.Where("uid=? and ctype=?", uid, ctype).Limit(limit, offset).Desc(field, "views", "reply_count", "created").Find(tps)
   759  			} else {
   760  				Engine.Where("uid=?", uid).Limit(limit, offset).Desc(field, "views", "reply_count", "created").Find(tps)
   761  			}
   762  		}
   763  	}
   764  	return tps
   765  }
   766  
   767  func GetTopicsByNid(nodeid int64, offset int, limit int, ctype int64, field string) *[]*Topic {
   768  	//排序首先是热值优先,然后是时间优先。
   769  	tps := new([]*Topic)
   770  
   771  	switch {
   772  	case field == "asc":
   773  		if nodeid == 0 {
   774  			//q.Offset(offset).Limit(limit).OrderByDesc(field).OrderByDesc("views").OrderByDesc("reply_count").OrderByDesc("created").FindAll(&allt)
   775  			return nil
   776  		} else {
   777  			if ctype != 0 {
   778  				Engine.Where("nid=? and ctype=?", nodeid, ctype).Limit(limit, offset).Asc("id").Find(tps)
   779  			} else {
   780  				Engine.Where("nid=?", nodeid).Limit(limit, offset).Asc("id").Find(tps)
   781  			}
   782  		}
   783  	default:
   784  		if nodeid == 0 {
   785  			//q.Offset(offset).Limit(limit).OrderByDesc(field).OrderByDesc("views").OrderByDesc("reply_count").OrderByDesc("created").FindAll(&allt)
   786  			return nil
   787  		} else {
   788  			if ctype != 0 {
   789  				Engine.Where("nid=? and ctype=?", nodeid, ctype).Limit(limit, offset).Desc(field, "views", "reply_count", "created").Find(tps)
   790  			} else {
   791  				Engine.Where("nid=?", nodeid).Limit(limit, offset).Desc(field, "views", "reply_count", "created").Find(tps)
   792  			}
   793  		}
   794  	}
   795  	return tps
   796  }
   797  
   798  func GetTopicsByPid(pid int64, offset int, limit int, ctype int64, field string) *[]*Topic {
   799  
   800  	tps := new([]*Topic)
   801  	if len(field) == 0 {
   802  		field = "id"
   803  	}
   804  	if limit == 0 {
   805  		switch {
   806  		case field == "asc":
   807  			{
   808  				if pid > 0 { //即只查询单个话题的父级与子级,此时sort字段无效,所以无须作为条件参与排序
   809  					if ctype != 0 {
   810  						Engine.Table("topic").Where("(topic.pid=? or topic.id=?) and topic.ctype=?", pid, pid, ctype).Asc("topic.id").Find(tps)
   811  					} else {
   812  						Engine.Table("topic").Where("(topic.pid=? or topic.id=?)", pid, pid).Asc("topic.id").Find(tps)
   813  					}
   814  				} else {
   815  					if ctype != 0 {
   816  						Engine.Table("topic").Where("(topic.pid=? or topic.id=?) and topic.ctype=? and topic.sort<=?", pid, pid, ctype, 0).Asc("topic.id").Find(tps)
   817  					} else {
   818  						Engine.Table("topic").Where("(topic.pid=? or topic.id=?) and topic.sort<=?", pid, pid, 0).Asc("topic.id").Find(tps)
   819  					}
   820  				}
   821  
   822  			}
   823  		case field == "cold":
   824  			{
   825  				if ctype != 0 {
   826  					Engine.Table("topic").Where("(topic.pid=? or topic.id=?) and topic.ctype=? and topic.sort<=?", pid, pid, ctype, 0).Asc("topic.views").Find(tps)
   827  				} else {
   828  					Engine.Table("topic").Where("(topic.pid=? or topic.id=?) and topic.sort<=?", pid, pid, 0).Asc("topic.views").Find(tps)
   829  				}
   830  			}
   831  		case field == "sort":
   832  			{ //Desc("topic.sort", "topic.confidence") ,这段即是"topic.sort"的优先级较"topic.confidence"要高
   833  				if ctype != 0 {
   834  					Engine.Table("topic").Where("(topic.pid=? or topic.id=?) and topic.ctype=? and topic.sort>?", pid, pid, ctype, 0).Desc("topic.sort", "topic.confidence").Find(tps)
   835  				} else {
   836  					Engine.Table("topic").Where("(topic.pid=? or topic.id=?) and topic.sort>?", pid, pid, 0).Desc("topic.sort", "topic.confidence").Find(tps)
   837  				}
   838  			}
   839  		default:
   840  			{
   841  				if field == "desc" {
   842  					field = "id"
   843  				}
   844  				if ctype != 0 {
   845  					Engine.Table("topic").Where("(topic.pid=? or topic.id=?) and topic.ctype=? and topic.sort<=?", pid, pid, ctype, 0).Desc("topic."+field, "topic.views", "topic.reply_count", "topic.created").Find(tps)
   846  				} else {
   847  					Engine.Table("topic").Where("(topic.pid=? or topic.id=?)", pid, pid).And("topic.sort<=?", 0).Desc("topic."+field, "topic.views", "topic.reply_count", "topic.created").Find(tps)
   848  				}
   849  			}
   850  		}
   851  	} else {
   852  		switch {
   853  		case field == "asc":
   854  			{
   855  				if pid > 0 { //即只查询单个话题的父级与子级,此时sort字段无效,所以无须作为条件参与排序
   856  					if ctype != 0 {
   857  						Engine.Table("topic").Where("(topic.pid=? or topic.id=?) and topic.ctype=?", pid, pid, ctype).Limit(limit, offset).Asc("topic.id").Find(tps)
   858  					} else {
   859  						Engine.Table("topic").Where("(topic.pid=? or topic.id=?)", pid, pid).Limit(limit, offset).Asc("topic.id").Find(tps)
   860  					}
   861  				} else {
   862  					if ctype != 0 {
   863  						Engine.Table("topic").Where("(topic.pid=? or topic.id=?) and topic.ctype=? and topic.sort<=?", pid, pid, ctype, 0).Limit(limit, offset).Asc("topic.id").Find(tps)
   864  					} else {
   865  						Engine.Table("topic").Where("(topic.pid=? or topic.id=?) and topic.sort<=?", pid, pid, 0).Limit(limit, offset).Asc("topic.id").Find(tps)
   866  					}
   867  				}
   868  
   869  			}
   870  		case field == "cold":
   871  			{
   872  				if ctype != 0 {
   873  					Engine.Table("topic").Where("(topic.pid=? or topic.id=?) and topic.ctype=? and topic.sort<=?", pid, pid, ctype, 0).Limit(limit, offset).Asc("topic.views").Find(tps)
   874  				} else {
   875  					Engine.Table("topic").Where("(topic.pid=? or topic.id=?) and topic.sort<=?", pid, pid, 0).Limit(limit, offset).Asc("topic.views").Find(tps)
   876  				}
   877  			}
   878  		case field == "sort":
   879  			{ //Desc("topic.sort", "topic.confidence") ,这段即是"topic.sort"的优先级较"topic.confidence"要高
   880  				if ctype != 0 {
   881  					Engine.Table("topic").Where("(topic.pid=? or topic.id=?) and topic.ctype=? and topic.sort>?", pid, pid, ctype, 0).Limit(limit, offset).Desc("topic.sort", "topic.confidence").Find(tps)
   882  				} else {
   883  					Engine.Table("topic").Where("(topic.pid=? or topic.id=?) and topic.sort>?", pid, pid, 0).Limit(limit, offset).Desc("topic.sort", "topic.confidence").Find(tps)
   884  				}
   885  			}
   886  		default:
   887  			{
   888  				if field == "desc" {
   889  					field = "id"
   890  				}
   891  				if ctype != 0 {
   892  					Engine.Table("topic").Where("(topic.pid=? or topic.id=?) and topic.ctype=? and topic.sort<=?", pid, pid, ctype, 0).Limit(limit, offset).Desc("topic."+field, "topic.views", "topic.reply_count", "topic.created").Find(tps)
   893  				} else {
   894  					Engine.Table("topic").Where("(topic.pid=? or topic.id=?)", pid, pid).And("topic.sort<=?", 0).Limit(limit, offset).Desc("topic."+field, "topic.views", "topic.reply_count", "topic.created").Find(tps)
   895  				}
   896  			}
   897  		}
   898  	}
   899  	return tps
   900  }
   901  
   902  func GetTopicsViaPid(pid int64, offset int, limit int, ctype int64, field string) *[]*Topic {
   903  	var objs = new([]*Topic)
   904  	if pid <= 0 {
   905  		switch {
   906  		case field == "asc":
   907  			{
   908  				if ctype != 0 {
   909  					Engine.Where("pid <= ? and ctype = ?", 0, ctype).Limit(limit, offset).Asc("id").Find(objs)
   910  				} else {
   911  					Engine.Where("pid <= ?", 0).Limit(limit, offset).Asc("id").Find(objs)
   912  				}
   913  			}
   914  		default:
   915  			{
   916  				if ctype != 0 {
   917  					Engine.Where("pid <= ? and ctype = ?", 0, ctype).Limit(limit, offset).Desc(field).Find(objs)
   918  				} else {
   919  					Engine.Where("pid <= ?", 0).Limit(limit, offset).Desc(field).Find(objs)
   920  				}
   921  			}
   922  		}
   923  	} else {
   924  		switch {
   925  		case field == "asc":
   926  			{
   927  				if ctype != 0 {
   928  					Engine.Where("pid=? and ctype=?", pid, ctype).Limit(limit, offset).Asc("id").Find(objs)
   929  				} else {
   930  					Engine.Where("pid=?", pid).Limit(limit, offset).Asc("id").Find(objs)
   931  				}
   932  			}
   933  		default:
   934  			{
   935  				if ctype != 0 {
   936  					Engine.Where("pid=? and ctype=?", pid, ctype).Limit(limit, offset).Desc(field).Find(objs)
   937  				} else {
   938  					Engine.Where("pid=?", pid).Limit(limit, offset).Desc(field).Find(objs)
   939  				}
   940  			}
   941  		}
   942  	}
   943  	return objs
   944  }
   945  
   946  func GetTopicsByPidJoinUser(pid int64, offset int, limit int, ctype int64, field string) *[]*Topicjuser {
   947  
   948  	tps := new([]*Topicjuser)
   949  
   950  	switch {
   951  	case field == "asc":
   952  		{
   953  			if pid > 0 { //即只查询单个话题的父级与子级,此时sort字段无效,所以无须作为条件参与排序
   954  				if ctype != 0 {
   955  					Engine.Table("topic").Where("(topic.pid=? or topic.id=?) and topic.ctype=?", pid, pid, ctype).Limit(limit, offset).Asc("topic.id").Join("LEFT", "user", "user.id = topic.uid").Find(tps)
   956  				} else {
   957  					Engine.Table("topic").Where("(topic.pid=? or topic.id=?)", pid, pid).Limit(limit, offset).Asc("topic.id").Join("LEFT", "user", "user.id = topic.uid").Find(tps)
   958  				}
   959  			} else {
   960  				if ctype != 0 {
   961  					Engine.Table("topic").Where("(topic.pid=? or topic.id=?) and topic.ctype=? and topic.sort<=?", pid, pid, ctype, 0).Limit(limit, offset).Asc("topic.id").Join("LEFT", "user", "user.id = topic.uid").Find(tps)
   962  				} else {
   963  					Engine.Table("topic").Where("(topic.pid=? or topic.id=?) and topic.sort<=?", pid, pid, 0).Limit(limit, offset).Asc("topic.id").Join("LEFT", "user", "user.id = topic.uid").Find(tps)
   964  				}
   965  			}
   966  
   967  		}
   968  	case field == "cold":
   969  		{
   970  			if ctype != 0 {
   971  				Engine.Table("topic").Where("(topic.pid=? or topic.id=?) and topic.ctype=? and topic.sort<=?", pid, pid, ctype, 0).Limit(limit, offset).Asc("topic.views").Join("LEFT", "user", "user.id = topic.uid").Find(tps)
   972  			} else {
   973  				Engine.Table("topic").Where("(topic.pid=? or topic.id=?) and topic.sort<=?", pid, pid, 0).Limit(limit, offset).Asc("topic.views").Join("LEFT", "user", "user.id = topic.uid").Find(tps)
   974  			}
   975  		}
   976  	case field == "sort":
   977  		{ //Desc("topic.sort", "topic.confidence") ,这段即是"topic.sort"的优先级较"topic.confidence"要高
   978  			if ctype != 0 {
   979  				Engine.Table("topic").Where("(topic.pid=? or topic.id=?) and topic.ctype=? and topic.sort>?", pid, pid, ctype, 0).Limit(limit, offset).Desc("topic.sort", "topic.confidence").Join("LEFT", "user", "user.id = topic.uid").Find(tps)
   980  			} else {
   981  				Engine.Table("topic").Where("(topic.pid=? or topic.id=?) and topic.sort>?", pid, pid, 0).Limit(limit, offset).Desc("topic.sort", "topic.confidence").Join("LEFT", "user", "user.id = topic.uid").Find(tps)
   982  			}
   983  		}
   984  	default:
   985  		{
   986  			if field == "desc" {
   987  				field = "id"
   988  			}
   989  			if ctype != 0 {
   990  				Engine.Table("topic").Where("(topic.pid=? or topic.id=?) and topic.ctype=? and topic.sort<=?", pid, pid, ctype, 0).Limit(limit, offset).Desc("topic."+field, "topic.views", "topic.reply_count", "topic.created").Join("LEFT", "user", "user.id = topic.uid").Find(tps)
   991  			} else {
   992  				Engine.Table("topic").Where("(topic.pid=? or topic.id=?)", pid, pid).And("topic.sort<=?", 0).Limit(limit, offset).Desc("topic."+field, "topic.views", "topic.reply_count", "topic.created").Join("LEFT", "user", "user.id = topic.uid").Find(tps)
   993  			}
   994  		}
   995  	}
   996  	return tps
   997  }
   998  
   999  func GetTopicsByPidSinceCreated(pid int64, offset int, limit int, ctype int64, field string, since int64) *[]*Topic {
  1000  
  1001  	switch tps := new([]*Topic); {
  1002  	case field == "asc":
  1003  		{
  1004  			if ctype != 0 {
  1005  				Engine.Table("topic").Where("topic.created>? and (topic.pid=? or topic.id=?) and topic.ctype=? and topic.sort<=?", since, pid, pid, ctype, 0).Limit(limit, offset).Asc("topic.id").Find(tps)
  1006  			} else {
  1007  				Engine.Table("topic").Where("topic.created>? and (topic.pid=? or topic.id=?) and topic.sort<=?", since, pid, pid, 0).Limit(limit, offset).Asc("topic.id").Find(tps)
  1008  			}
  1009  			return tps
  1010  		}
  1011  	default:
  1012  		{
  1013  			if ctype != 0 {
  1014  				Engine.Table("topic").Where("topic.created>? and (topic.pid=? or topic.id=?) and topic.ctype=? and topic.sort<=?", since, pid, pid, ctype, 0).Limit(limit, offset).Desc("topic."+field, "topic.views", "topic.reply_count", "topic.created").Find(tps)
  1015  			} else {
  1016  				Engine.Table("topic").Where("topic.created>? and (topic.pid=? or topic.id=?) and topic.sort<=?", since, pid, pid, 0).Limit(limit, offset).Desc("topic."+field, "topic.views", "topic.reply_count", "topic.created").Find(tps)
  1017  			}
  1018  			return tps
  1019  		}
  1020  	}
  1021  
  1022  }
  1023  
  1024  func GetTopicsByPidJoinUserSinceCreated(pid int64, offset int, limit int, ctype int64, field string, since int64) *[]*Topicjuser {
  1025  
  1026  	switch tps := new([]*Topicjuser); {
  1027  	case field == "asc":
  1028  		{
  1029  			if ctype != 0 {
  1030  				Engine.Table("topic").Where("topic.created>? and (topic.pid=? or topic.id=?) and topic.ctype=? and topic.sort<=?", since, pid, pid, ctype, 0).Limit(limit, offset).Asc("topic.id").Join("LEFT", "user", "user.id = topic.uid").Find(tps)
  1031  			} else {
  1032  				Engine.Table("topic").Where("topic.created>? and (topic.pid=? or topic.id=?) and topic.sort<=?", since, pid, pid, 0).Limit(limit, offset).Asc("topic.id").Join("LEFT", "user", "user.id = topic.uid").Find(tps)
  1033  			}
  1034  			return tps
  1035  		}
  1036  	default:
  1037  		{
  1038  			if ctype != 0 {
  1039  				Engine.Table("topic").Where("topic.created>? and (topic.pid=? or topic.id=?) and topic.ctype=? and topic.sort<=?", since, pid, pid, ctype, 0).Limit(limit, offset).Desc("topic."+field, "topic.views", "topic.reply_count", "topic.created").Join("LEFT", "user", "user.id = topic.uid").Find(tps)
  1040  			} else {
  1041  				Engine.Table("topic").Where("topic.created>? and (topic.pid=? or topic.id=?) and topic.sort<=?", since, pid, pid, 0).Limit(limit, offset).Desc("topic."+field, "topic.views", "topic.reply_count", "topic.created").Join("LEFT", "user", "user.id = topic.uid").Find(tps)
  1042  			}
  1043  			return tps
  1044  		}
  1045  	}
  1046  
  1047  }
  1048  
  1049  func GetTopicsByPidJoinTopicmark(pid int64, offset int, limit int, ctype int64, field string) *[]*Topicjtopicmark {
  1050  
  1051  	tps := new([]*Topicjtopicmark)
  1052  
  1053  	switch {
  1054  	case field == "asc":
  1055  		{
  1056  			if ctype != 0 {
  1057  				Engine.Table("topic").Where("(topic.pid=? or topic.id=?) and topic.ctype=?", pid, pid, ctype).Limit(limit, offset).Asc("topic.id").Join("LEFT", "topic_mark", "topic_mark.uid = topic.uid").Find(tps)
  1058  			} else {
  1059  				Engine.Table("topic").Where("topic.pid=? or topic.id=?", pid, pid).Limit(limit, offset).Asc("topic.id").Join("LEFT", "topic_mark", "topic_mark.uid = topic.uid").Find(tps)
  1060  			}
  1061  		}
  1062  	default:
  1063  		{
  1064  			if ctype != 0 {
  1065  				Engine.Table("topic").Where("(topic.pid=? or topic.id=?) and topic.ctype=?", pid, pid, ctype).Limit(limit, offset).Desc("topic."+field, "topic.views", "topic.reply_count", "topic.created").Join("LEFT", "topic_mark", "topic_mark.uid = topic.uid").Find(tps)
  1066  			} else {
  1067  				Engine.Table("topic").Where("topic.pid=? or topic.id=?", pid, pid).Limit(limit, offset).Desc("topic."+field, "topic.views", "topic.reply_count", "topic.created").Join("LEFT", "topic_mark", "topic_mark.uid = topic.uid").Find(tps)
  1068  			}
  1069  		}
  1070  	}
  1071  	return tps
  1072  }
  1073  
  1074  func JoinTopicmarkJoinUserForGetTopicsByPid(pid int64, offset int, limit int, field string) *[]*Topicjtopicmarkjuser {
  1075  	tps := new([]*Topicjtopicmarkjuser)
  1076  	switch {
  1077  	case field == "asc":
  1078  		{
  1079  			Engine.Table("topic_mark").Where("topic_mark.tid=?", pid).Limit(limit, offset).Asc("topic_mark.id").Join("LEFT", "topic", "topic_mark.tid = topic.id").Join("LEFT", "user", "user.id = topic.uid").Find(tps)
  1080  		}
  1081  	default:
  1082  		{
  1083  			Engine.Table("topic_mark").Where("topic_mark.tid=?", pid).Limit(limit, offset).Desc("topic_mark."+field).Join("LEFT", "topic", "topic_mark.tid = topic.id").Join("LEFT", "user", "user.id = topic.uid").Find(tps)
  1084  		}
  1085  	}
  1086  	return tps
  1087  }
  1088  
  1089  func JoinTopicmarkJoinUserForGetTopicsByUid(uid int64, offset int, limit int, field string) *[]*Topicjtopicmarkjuser {
  1090  	tps := new([]*Topicjtopicmarkjuser)
  1091  	switch {
  1092  	case field == "asc":
  1093  		{
  1094  			Engine.Table("topic_mark").Where("topic_mark.uid=?", uid).Limit(limit, offset).Asc("topic_mark.id").Join("LEFT", "topic", "topic_mark.tid = topic.id").Join("LEFT", "user", "user.id = topic.uid").Find(tps)
  1095  		}
  1096  	default:
  1097  		{
  1098  			Engine.Table("topic_mark").Where("topic_mark.uid=?", uid).Limit(limit, offset).Desc("topic_mark."+field).Join("LEFT", "topic", "topic_mark.tid = topic.id").Join("LEFT", "user", "user.id = topic.uid").Find(tps)
  1099  		}
  1100  	}
  1101  	return tps
  1102  }
  1103  
  1104  func GetSubjectsByNid4Count(nodeid int64, offset int, limit int, ctype int64) (int64, error) {
  1105  
  1106  	if nodeid == 0 {
  1107  		if ctype != 0 {
  1108  			return Engine.Where("pid=0 and ctype=?", ctype).Limit(limit, offset).Count(&Topic{})
  1109  		} else {
  1110  			return Engine.Where("pid=0").Limit(limit, offset).Count(&Topic{})
  1111  		}
  1112  	} else {
  1113  		if ctype != 0 {
  1114  			return Engine.Where("pid=0 and nid=? and ctype=?", nodeid, ctype).Limit(limit, offset).Count(&Topic{})
  1115  		} else {
  1116  			return Engine.Where("pid=0 and nid=?", nodeid).Limit(limit, offset).Count(&Topic{})
  1117  		}
  1118  	}
  1119  }
  1120  
  1121  func GetSubjectsByNid(nodeid int64, offset int, limit int, ctype int64, field string) *[]*Topic {
  1122  
  1123  	tps := new([]*Topic)
  1124  
  1125  	switch {
  1126  	case field == "asc":
  1127  		if nodeid == 0 {
  1128  			if ctype != 0 {
  1129  				Engine.Table("topic").Where("topic.pid=0 and topic.ctype=?", ctype).Limit(limit, offset).Asc("topic.id").Find(tps)
  1130  			} else {
  1131  				Engine.Table("topic").Where("topic.pid=0").Limit(limit, offset).Asc("topic.id").Find(tps)
  1132  			}
  1133  		} else {
  1134  			if ctype != 0 {
  1135  				Engine.Table("topic").Where("topic.pid=0 and topic.nid=? and topic.ctype=?", nodeid, ctype).Limit(limit, offset).Asc("topic.id").Find(tps)
  1136  			} else {
  1137  				Engine.Table("topic").Where("topic.pid=0 and topic.nid=?", nodeid).Limit(limit, offset).Asc("topic.id").Find(tps)
  1138  			}
  1139  		}
  1140  	default:
  1141  		if nodeid == 0 {
  1142  			if ctype != 0 {
  1143  				Engine.Table("topic").Where("topic.pid=0 and topic.ctype=?", ctype).Limit(limit, offset).Desc("topic."+field, "topic.views", "topic.reply_count", "topic.created").Find(tps)
  1144  			} else {
  1145  				Engine.Table("topic").Where("topic.pid=0").Limit(limit, offset).Desc("topic."+field, "topic.views", "topic.reply_count", "topic.created").Find(tps)
  1146  			}
  1147  		} else {
  1148  			if ctype != 0 {
  1149  				Engine.Table("topic").Where("topic.pid=0 and topic.nid=? and topic.ctype=?", nodeid, ctype).Limit(limit, offset).Desc("topic."+field, "topic.topic.views", "topic.reply_count", "topic.created").Find(tps)
  1150  			} else {
  1151  				Engine.Table("topic").Where("topic.pid=0 and topic.nid=?", nodeid).Limit(limit, offset).Desc("topic."+field, "topic.views", "topic.reply_count", "topic.created").Find(tps)
  1152  			}
  1153  		}
  1154  	}
  1155  	return tps
  1156  }
  1157  
  1158  func GetSubjectsByNidJoinUser(nodeid int64, offset int, limit int, ctype int64, field string) *[]*Topicjuser {
  1159  
  1160  	tps := new([]*Topicjuser)
  1161  
  1162  	switch {
  1163  	case field == "asc":
  1164  		if nodeid == 0 {
  1165  			if ctype != 0 {
  1166  				Engine.Table("topic").Where("topic.pid=0 and topic.ctype=?", ctype).Limit(limit, offset).Asc("topic.id").Join("LEFT", "user", "user.id = topic.uid").Find(tps)
  1167  			} else {
  1168  				Engine.Table("topic").Where("topic.pid=0").Limit(limit, offset).Asc("topic.id").Join("LEFT", "user", "user.id = topic.uid").Find(tps)
  1169  			}
  1170  		} else {
  1171  			if ctype != 0 {
  1172  				Engine.Table("topic").Where("topic.pid=0 and topic.nid=? and topic.ctype=?", nodeid, ctype).Limit(limit, offset).Asc("topic.id").Join("LEFT", "user", "user.id = topic.uid").Find(tps)
  1173  			} else {
  1174  				Engine.Table("topic").Where("topic.pid=0 and topic.nid=?", nodeid).Limit(limit, offset).Asc("topic.id").Join("LEFT", "user", "user.id = topic.uid").Find(tps)
  1175  			}
  1176  		}
  1177  	default:
  1178  		if nodeid == 0 {
  1179  			if ctype != 0 {
  1180  				Engine.Table("topic").Where("topic.pid=0 and topic.ctype=?", ctype).Limit(limit, offset).Desc("topic."+field, "topic.views", "topic.reply_count", "topic.created").Join("LEFT", "user", "user.id = topic.uid").Find(tps)
  1181  			} else {
  1182  				Engine.Table("topic").Where("topic.pid=0").Limit(limit, offset).Desc("topic."+field, "topic.views", "topic.reply_count", "topic.created").Join("LEFT", "user", "user.id = topic.uid").Find(tps)
  1183  			}
  1184  		} else {
  1185  			if ctype != 0 {
  1186  				Engine.Table("topic").Where("topic.pid=0 and topic.nid=? and topic.ctype=?", nodeid, ctype).Limit(limit, offset).Desc("topic."+field, "topic.topic.views", "topic.reply_count", "topic.created").Join("LEFT", "user", "user.id = topic.uid").Find(tps)
  1187  			} else {
  1188  				Engine.Table("topic").Where("topic.pid=0 and topic.nid=?", nodeid).Limit(limit, offset).Desc("topic."+field, "topic.views", "topic.reply_count", "topic.created").Join("LEFT", "user", "user.id = topic.uid").Find(tps)
  1189  			}
  1190  		}
  1191  	}
  1192  	return tps
  1193  }
  1194  
  1195  func GetTopicsByNode(node string, offset int, limit int, field string) (*[]*Topic, error) {
  1196  	tps := new([]*Topic)
  1197  	err := Engine.Where("node=?", node).Limit(limit, offset).Desc(field).Find(tps)
  1198  	return tps, err
  1199  }
  1200  
  1201  func GetSubjectsByNode4Count(node string, offset int, limit int, ctype int64) (int64, error) {
  1202  
  1203  	if node == "" {
  1204  		if ctype != 0 {
  1205  			return Engine.Where("pid=0 and ctype=?", ctype).Limit(limit, offset).Count(&Topic{})
  1206  		} else {
  1207  			return Engine.Where("pid=0").Limit(limit, offset).Count(&Topic{})
  1208  		}
  1209  	} else {
  1210  		if ctype != 0 {
  1211  			return Engine.Where("pid=0 and node=? and ctype=?", node, ctype).Limit(limit, offset).Count(&Topic{})
  1212  		} else {
  1213  			return Engine.Where("pid=0 and node=?", node).Limit(limit, offset).Count(&Topic{})
  1214  		}
  1215  	}
  1216  }
  1217  
  1218  func GetSubjectsByNode(node string, offset int, limit int, ctype int64, field string) *[]*Topic {
  1219  
  1220  	tps := new([]*Topic)
  1221  
  1222  	switch {
  1223  	case field == "asc":
  1224  		if len(node) == 0 {
  1225  			if ctype != 0 {
  1226  				Engine.Table("topic").Where("topic.pid=0 and topic.ctype=?", ctype).Limit(limit, offset).Asc("topic.id").Find(tps)
  1227  			} else {
  1228  				Engine.Table("topic").Where("topic.pid=0").Limit(limit, offset).Asc("topic.id").Find(tps)
  1229  			}
  1230  		} else {
  1231  			if ctype != 0 {
  1232  				Engine.Table("topic").Where("topic.pid=0 and topic.node=? and topic.ctype=?", node, ctype).Limit(limit, offset).Asc("topic.id").Find(tps)
  1233  			} else {
  1234  				Engine.Table("topic").Where("topic.pid=0 and topic.node=?", node).Limit(limit, offset).Asc("topic.id").Find(tps)
  1235  			}
  1236  		}
  1237  	default:
  1238  		if len(node) == 0 {
  1239  			if ctype != 0 {
  1240  				Engine.Table("topic").Where("topic.pid=0 and topic.ctype=?", ctype).Limit(limit, offset).Desc("topic."+field, "topic.views", "topic.reply_count", "topic.created").Find(tps)
  1241  			} else {
  1242  				Engine.Table("topic").Where("topic.pid=0").Limit(limit, offset).Desc("topic."+field, "topic.views", "topic.reply_count", "topic.created").Find(tps)
  1243  			}
  1244  		} else {
  1245  			if ctype != 0 {
  1246  				Engine.Table("topic").Where("topic.pid=0 and topic.node=? and topic.ctype=?", node, ctype).Limit(limit, offset).Desc("topic."+field, "topic.topic.views", "topic.reply_count", "topic.created").Find(tps)
  1247  			} else {
  1248  				Engine.Table("topic").Where("topic.pid=0 and topic.node=?", node).Limit(limit, offset).Desc("topic."+field, "topic.views", "topic.reply_count", "topic.created").Find(tps)
  1249  			}
  1250  		}
  1251  	}
  1252  	return tps
  1253  }
  1254  
  1255  func GetSubjectsByNodeJoinUser(node string, offset int, limit int, ctype int64, field string) *[]*Topicjuser {
  1256  
  1257  	tps := new([]*Topicjuser)
  1258  
  1259  	switch {
  1260  	case field == "asc":
  1261  		if len(node) == 0 {
  1262  			if ctype != 0 {
  1263  				Engine.Table("topic").Where("topic.pid=0 and topic.ctype=?", ctype).Limit(limit, offset).Asc("topic.id").Join("LEFT", "user", "user.id = topic.uid").Find(tps)
  1264  			} else {
  1265  				Engine.Table("topic").Where("topic.pid=0").Limit(limit, offset).Asc("topic.id").Join("LEFT", "user", "user.id = topic.uid").Find(tps)
  1266  			}
  1267  		} else {
  1268  			if ctype != 0 {
  1269  				Engine.Table("topic").Where("topic.pid=0 and topic.node=? and topic.ctype=?", node, ctype).Limit(limit, offset).Asc("topic.id").Join("LEFT", "user", "user.id = topic.uid").Find(tps)
  1270  			} else {
  1271  				Engine.Table("topic").Where("topic.pid=0 and topic.node=?", node).Limit(limit, offset).Asc("topic.id").Join("LEFT", "user", "user.id = topic.uid").Find(tps)
  1272  			}
  1273  		}
  1274  	default:
  1275  		if len(node) == 0 {
  1276  			if ctype != 0 {
  1277  				Engine.Table("topic").Where("topic.pid=0 and topic.ctype=?", ctype).Limit(limit, offset).Desc("topic."+field, "topic.views", "topic.reply_count", "topic.created").Join("LEFT", "user", "user.id = topic.uid").Find(tps)
  1278  			} else {
  1279  				Engine.Table("topic").Where("topic.pid=0").Limit(limit, offset).Desc("topic."+field, "topic.views", "topic.reply_count", "topic.created").Join("LEFT", "user", "user.id = topic.uid").Find(tps)
  1280  			}
  1281  		} else {
  1282  			if ctype != 0 {
  1283  				Engine.Table("topic").Where("topic.pid=0 and topic.node=? and topic.ctype=?", node, ctype).Limit(limit, offset).Desc("topic."+field, "topic.topic.views", "topic.reply_count", "topic.created").Join("LEFT", "user", "user.id = topic.uid").Find(tps)
  1284  			} else {
  1285  				Engine.Table("topic").Where("topic.pid=0 and topic.node=?", node).Limit(limit, offset).Desc("topic."+field, "topic.views", "topic.reply_count", "topic.created").Join("LEFT", "user", "user.id = topic.uid").Find(tps)
  1286  			}
  1287  		}
  1288  	}
  1289  	return tps
  1290  }
  1291  
  1292  func GetSubjectsByUser4Count(user string, offset int, limit int, ctype int64) (int64, error) {
  1293  
  1294  	if user == "" {
  1295  		if ctype != 0 {
  1296  			return Engine.Where("pid=0 and ctype=?", ctype).Limit(limit, offset).Count(&Topic{})
  1297  		} else {
  1298  			return Engine.Where("pid=0").Limit(limit, offset).Count(&Topic{})
  1299  		}
  1300  	} else {
  1301  		if ctype != 0 {
  1302  			return Engine.Where("pid=0 and author=? and ctype=?", user, ctype).Limit(limit, offset).Count(&Topic{})
  1303  		} else {
  1304  			return Engine.Where("pid=0 and author=?", user).Limit(limit, offset).Count(&Topic{})
  1305  		}
  1306  	}
  1307  }
  1308  
  1309  func GetSubjectsByUser(username string, offset int, limit int, ctype int64, field string) *[]*Topic {
  1310  
  1311  	tps := new([]*Topic)
  1312  
  1313  	switch {
  1314  	case field == "asc":
  1315  		if len(username) == 0 {
  1316  			if ctype != 0 {
  1317  				Engine.Table("topic").Where("topic.pid=0 and topic.ctype=?", ctype).Limit(limit, offset).Asc("topic.id").Find(tps)
  1318  			} else {
  1319  				Engine.Table("topic").Where("topic.pid=0").Limit(limit, offset).Asc("topic.id").Find(tps)
  1320  			}
  1321  		} else {
  1322  			if ctype != 0 {
  1323  				Engine.Table("topic").Where("topic.pid=0 and topic.author=? and topic.ctype=?", username, ctype).Limit(limit, offset).Asc("topic.id").Find(tps)
  1324  			} else {
  1325  				Engine.Table("topic").Where("topic.pid=0 and topic.author=?", username).Limit(limit, offset).Asc("topic.id").Find(tps)
  1326  			}
  1327  		}
  1328  	default:
  1329  		if len(username) == 0 {
  1330  			if ctype != 0 {
  1331  				Engine.Table("topic").Where("topic.pid=0 and topic.ctype=?", ctype).Limit(limit, offset).Desc("topic."+field, "topic.views", "topic.reply_count", "topic.created").Find(tps)
  1332  			} else {
  1333  				Engine.Table("topic").Where("topic.pid=0").Limit(limit, offset).Desc("topic."+field, "topic.views", "topic.reply_count", "topic.created").Find(tps)
  1334  			}
  1335  		} else {
  1336  			if ctype != 0 {
  1337  				Engine.Table("topic").Where("topic.pid=0 and topic.author=? and topic.ctype=?", username, ctype).Limit(limit, offset).Desc("topic."+field, "topic.topic.views", "topic.reply_count", "topic.created").Find(tps)
  1338  			} else {
  1339  				Engine.Table("topic").Where("topic.pid=0 and topic.author=?", username).Limit(limit, offset).Desc("topic."+field, "topic.views", "topic.reply_count", "topic.created").Find(tps)
  1340  			}
  1341  		}
  1342  	}
  1343  	return tps
  1344  }
  1345  
  1346  func GetSubjectsByUserJoinUser(username string, offset int, limit int, ctype int64, field string) *[]*Topicjuser {
  1347  
  1348  	tps := new([]*Topicjuser)
  1349  
  1350  	switch {
  1351  	case field == "asc":
  1352  		if len(username) == 0 {
  1353  			if ctype != 0 {
  1354  				Engine.Table("topic").Where("topic.pid=0 and topic.ctype=?", ctype).Limit(limit, offset).Asc("topic.id").Join("LEFT", "user", "user.id = topic.uid").Find(tps)
  1355  			} else {
  1356  				Engine.Table("topic").Where("topic.pid=0").Limit(limit, offset).Asc("topic.id").Join("LEFT", "user", "user.id = topic.uid").Find(tps)
  1357  			}
  1358  		} else {
  1359  			if ctype != 0 {
  1360  				Engine.Table("topic").Where("topic.pid=0 and topic.author=? and topic.ctype=?", username, ctype).Limit(limit, offset).Asc("topic.id").Join("LEFT", "user", "user.id = topic.uid").Find(tps)
  1361  			} else {
  1362  				Engine.Table("topic").Where("topic.pid=0 and topic.author=?", username).Limit(limit, offset).Asc("topic.id").Join("LEFT", "user", "user.id = topic.uid").Find(tps)
  1363  			}
  1364  		}
  1365  	default:
  1366  		if len(username) == 0 {
  1367  			if ctype != 0 {
  1368  				Engine.Table("topic").Where("topic.pid=0 and topic.ctype=?", ctype).Limit(limit, offset).Desc("topic."+field, "topic.views", "topic.reply_count", "topic.created").Join("LEFT", "user", "user.id = topic.uid").Find(tps)
  1369  			} else {
  1370  				Engine.Table("topic").Where("topic.pid=0").Limit(limit, offset).Desc("topic."+field, "topic.views", "topic.reply_count", "topic.created").Join("LEFT", "user", "user.id = topic.uid").Find(tps)
  1371  			}
  1372  		} else {
  1373  			if ctype != 0 {
  1374  				Engine.Table("topic").Where("topic.pid=0 and topic.author=? and topic.ctype=?", username, ctype).Limit(limit, offset).Desc("topic."+field, "topic.topic.views", "topic.reply_count", "topic.created").Join("LEFT", "user", "user.id = topic.uid").Find(tps)
  1375  			} else {
  1376  				Engine.Table("topic").Where("topic.pid=0 and topic.author=?", username).Limit(limit, offset).Desc("topic."+field, "topic.views", "topic.reply_count", "topic.created").Join("LEFT", "user", "user.id = topic.uid").Find(tps)
  1377  			}
  1378  		}
  1379  	}
  1380  	return tps
  1381  }
  1382  
  1383  //发布话题  返回 话题id,错误
  1384  func PostTopic(tp *Topic) (int64, error) {
  1385  	// 创建 Session 对象
  1386  	sess := Engine.NewSession()
  1387  	defer sess.Close()
  1388  	// 启动事务
  1389  	if err := sess.Begin(); err != nil {
  1390  		return -1, err
  1391  	}
  1392  
  1393  	//执行事务
  1394  	topicid := int64(0)
  1395  	if _, err := sess.Insert(tp); err == nil && tp != nil {
  1396  
  1397  		if tp.Nid > 0 {
  1398  			n, _ := sess.Where("nid=?", tp.Nid).Count(&Topic{})
  1399  			_n := map[string]interface{}{"author": tp.Author, "topic_time": time.Now().Unix(), "topic_count": n, "topic_last_user_id": tp.Uid}
  1400  			if row, err := sess.Table(&Node{}).Where("id=?", tp.Nid).Update(&_n); err != nil || row <= 0 {
  1401  				sess.Rollback()
  1402  				return -1, errors.New(fmt.Sprint("PostTopic更新node表话题相关信息时,执行:", row, "行变更,出现错误:", err))
  1403  			}
  1404  		}
  1405  
  1406  		if tp.Uid > 0 {
  1407  			n, _ := sess.Where("uid=?", tp.Uid).Count(&Topic{})
  1408  			_u := map[string]interface{}{"topic_time": time.Now().Unix(), "topic_count": n, "topic_last_nid": tp.Nid, "topic_last_node": tp.Node}
  1409  			if row, err := sess.Table(&User{}).Where("id=?", tp.Uid).Update(&_u); err != nil || row == 0 {
  1410  				sess.Rollback()
  1411  				return -1, errors.New(fmt.Sprint("PostTopic更新user表话题相关信息时,执行:", row, "行变更,出现错误:", err))
  1412  			}
  1413  		}
  1414  
  1415  		topicid = tp.Id
  1416  	} else {
  1417  		// 发生错误时进行回滚
  1418  		sess.Rollback()
  1419  		return -1, err
  1420  	}
  1421  
  1422  	// 提交事务
  1423  	return topicid, sess.Commit()
  1424  }
  1425  
  1426  func PutTopic(tid int64, tp *Topic) (int64, error) {
  1427  	// 创建 Session 对象
  1428  	sess := Engine.NewSession()
  1429  	defer sess.Close()
  1430  	// 启动事务
  1431  	if err := sess.Begin(); err != nil {
  1432  		return -1, err
  1433  	}
  1434  
  1435  	//执行事务
  1436  	topicid := int64(0)
  1437  	if _, err := sess.Id(tid).Update(tp); (err == nil) && (tp != nil) {
  1438  
  1439  		if tp.Nid > 0 {
  1440  			n, _ := sess.Where("nid=?", tp.Nid).Count(&Topic{})
  1441  			_n := map[string]interface{}{"author": tp.Author, "topic_time": time.Now().Unix(), "topic_count": n, "topic_last_user_id": tp.Uid}
  1442  			if row, err := sess.Table(&Node{}).Where("id=?", tp.Nid).Update(&_n); err != nil || row <= 0 {
  1443  				sess.Rollback()
  1444  				return -1, errors.New(fmt.Sprint("PutTopic更新node表话题相关信息时,执行:", row, "行变更,出现错误:", err))
  1445  			}
  1446  		}
  1447  
  1448  		if tp.Uid > 0 {
  1449  			n, _ := sess.Where("uid=?", tp.Uid).Count(&Topic{})
  1450  			_u := map[string]interface{}{"topic_time": time.Now().Unix(), "topic_count": n, "topic_last_nid": tp.Nid, "topic_last_node": tp.Node}
  1451  			if row, err := sess.Table(&User{}).Where("id=?", tp.Uid).Update(&_u); err != nil || row == 0 {
  1452  				sess.Rollback()
  1453  				return -1, errors.New(fmt.Sprint("PutTopic更新user表话题相关信息时,执行:", row, "行变更,出现错误:", err))
  1454  			}
  1455  		}
  1456  
  1457  		topicid = tp.Id
  1458  	} else {
  1459  		// 发生错误时进行回滚
  1460  		sess.Rollback()
  1461  		return -1, err
  1462  	}
  1463  
  1464  	// 提交事务
  1465  	return topicid, sess.Commit()
  1466  }
  1467  
  1468  /*
  1469  func PutTopic(tid int64, tp *Topic) (int64, error) {
  1470  	//覆盖式更新
  1471  	sess := Engine.NewSession()
  1472  	defer sess.Close()
  1473  	// 启动事务
  1474  	if err := sess.Begin(); err != nil {
  1475  		return -1, err
  1476  	}
  1477  
  1478  	//执行事务
  1479  	topicid := int64(0)
  1480  	//	tp.Id = tid
  1481  	if row, err := sess.Table(new(Topic)).Id(tid).Update(tp); (err != nil) || (row <= 0) {
  1482  		sess.Rollback()
  1483  		return -1, err
  1484  	} else {
  1485  		if tp.Uid > 0 {
  1486  			n, _ := sess.Where("uid=?", tp.Uid).Count(&Topic{})
  1487  			_u := map[string]interface{}{"topic_time": time.Now().Unix(), "topic_count": n, "topic_last_nid": tp.Nid, "topic_last_node": tp.Node}
  1488  			if row, err := sess.Table(&User{}).Where("id=?", tp.Uid).Update(&_u); err != nil || row <= 0 {
  1489  				sess.Rollback()
  1490  				return -1, errors.New(fmt.Sprint("PutTopic更新user表话题相关信息时,执行:", row, "行变更,出现错误:", err))
  1491  			}
  1492  		}
  1493  
  1494  		topicid = tp.Id
  1495  	}
  1496  
  1497  	// 提交事务
  1498  	return topicid, sess.Commit()
  1499  }
  1500  */
  1501  
  1502  func PutTopicViaVersion(tid int64, topic *Topic) (int64, error) {
  1503  	/*
  1504  		//乐观锁目前不支持map 以下句式无效!
  1505  			return Engine.Table(&Topic{}).Where("id=?", tid).Update(&map[string]interface{}{
  1506  				"views":   views,
  1507  				"version": version,
  1508  			})
  1509  	*/
  1510  	//return Engine.Table(&Topic{}).Where("id=?", tid).Update(topic)
  1511  	return Engine.Id(tid).Update(topic)
  1512  }
  1513  
  1514  func PutViews2TopicViaVersion(tid int64, topic *Topic) (int64, error) {
  1515  	/*
  1516  		return Engine.Table(&Topic{}).Where("id=?", tid).Update(&map[string]interface{}{
  1517  			"views": views,
  1518  		})
  1519  	*/
  1520  	return Engine.Id(tid).Cols("views").Update(topic)
  1521  }
  1522  
  1523  //func PutSort2Topic(tid int64, sort int64) (int64, error) {
  1524  func PutSort2TopicViaVersion(tid int64, topic *Topic) (int64, error) {
  1525  	/*
  1526  		return Engine.Table(&Topic{}).Where("id=?", tid).Update(&map[string]interface{}{
  1527  			"sort": sort,
  1528  		})
  1529  	*/
  1530  	return Engine.Id(tid).Cols("sort").Update(topic)
  1531  }
  1532  
  1533  /*
  1534  func PutTailinfo2Topic(tid int64, Tailinfo string) (int64, error) {
  1535  	return Engine.Table(&Topic{}).Where("id=?", tid).Update(&map[string]interface{}{
  1536  		"tailinfo": func() string {
  1537  			tp, e := GetTopic(tid)
  1538  			if (e != nil) || (tp == nil) {
  1539  				return ""
  1540  			}
  1541  			if len(tp.Tailinfo) == 0 {
  1542  				tp.Tailinfo = Tailinfo
  1543  			} else {
  1544  				tp.Tailinfo = tp.Tailinfo + "," + Tailinfo
  1545  			}
  1546  
  1547  			return tp.Tailinfo
  1548  
  1549  		},
  1550  	})
  1551  }
  1552  */
  1553  
  1554  func PutTailinfo2Topic(tid int64, Tailinfo string) (int64, error) {
  1555  
  1556  	tp, e := GetTopic(tid)
  1557  	if (e != nil) || (tp == nil) {
  1558  		return -1, e
  1559  	}
  1560  
  1561  	if len(tp.Tailinfo) == 0 {
  1562  		tp.Tailinfo = Tailinfo
  1563  	} else {
  1564  		tp.Tailinfo = tp.Tailinfo + "," + Tailinfo
  1565  	}
  1566  
  1567  	return PutTopic(tid, tp)
  1568  
  1569  }
  1570  
  1571  func IsTailinfoOfUser(tid, uid int64) bool {
  1572  	tp, e := GetTopic(tid)
  1573  	if (e != nil) || (tp == nil) {
  1574  		return false
  1575  	}
  1576  	if len(tp.Tailinfo) == 0 {
  1577  		return false
  1578  	} else {
  1579  		for _, v := range strings.Split(tp.Tailinfo, ",") {
  1580  			if fmt.Sprintf("%v", uid) == v {
  1581  				return true
  1582  			}
  1583  		}
  1584  	}
  1585  	return false
  1586  }
  1587  
  1588  func DelTopicsByPid(id int64, uid int64, role int64) (err error) {
  1589  	objs := GetTopicsByPid(id, 0, 0, 0, "id")
  1590  	for _, v := range *objs {
  1591  		if e := DelTopic(v.Id, uid, role); e != nil {
  1592  			err = fmt.Errorf("%v;%v", e, err)
  1593  		}
  1594  	}
  1595  	return
  1596  }
  1597  
  1598  func DelTopic(id int64, uid int64, role int64) error {
  1599  
  1600  	allow := false
  1601  	if role < 0 {
  1602  		allow = true
  1603  	}
  1604  
  1605  	topic := new(Topic)
  1606  
  1607  	if has, err := Engine.Id(id).Get(topic); has == true && err == nil {
  1608  
  1609  		if topic.Uid == uid || allow {
  1610  			//检查附件字段并尝试删除文件
  1611  			if len(topic.Attachment) > 0 {
  1612  				attachments := GetAttachmentsByPid(topic.Id, 0, 0, 0, "id")
  1613  				for _, v := range *attachments {
  1614  					if p := helper.URL2local(v.Content); helper.Exist(p) {
  1615  						//验证是否管理员权限
  1616  						if allow {
  1617  							if err := os.Remove(p); err != nil {
  1618  								//可以输出错误,但不要返回错误,以免陷入死循环无法删掉
  1619  								log.Println("ROOT DEL TOPIC Attachment, TOPIC ID:", id, ",ERR:", err)
  1620  							} else {
  1621  								topic.Attachment = "" // topic.Attachment - 1
  1622  							}
  1623  						} else { //检查用户对文件的所有权
  1624  							if helper.VerifyUserfile(p, strconv.Itoa(int(uid))) {
  1625  								if err := os.Remove(p); err != nil {
  1626  									log.Println("DEL TOPIC Attachment, TOPIC ID:", id, ",ERR:", err)
  1627  								} else {
  1628  									topic.Attachment = "" //topic.Attachment - 1
  1629  								}
  1630  							}
  1631  						}
  1632  					}
  1633  				}
  1634  			}
  1635  
  1636  			//检查内容字段并尝试删除文件
  1637  			if len(topic.Content) > 0 {
  1638  				//若内容中存在图片则开始尝试删除图片
  1639  				delfiles_local := []string{}
  1640  
  1641  				if m, n := helper.GetImages(topic.Content); n > 0 {
  1642  
  1643  					for _, v := range m {
  1644  						if helper.IsLocal(v) {
  1645  							delfiles_local = append(delfiles_local, v)
  1646  							//如果本地同时也存在banner缓存文件,则加入旧图集合中,等待后面一次性删除
  1647  							if p := helper.URL2local(helper.SetSuffix(v, "_banner.jpg")); helper.Exist(p) {
  1648  								delfiles_local = append(delfiles_local, p)
  1649  							}
  1650  							if p := helper.URL2local(helper.SetSuffix(v, "_large.jpg")); helper.Exist(p) {
  1651  								delfiles_local = append(delfiles_local, p)
  1652  							}
  1653  							if p := helper.URL2local(helper.SetSuffix(v, "_medium.jpg")); helper.Exist(p) {
  1654  								delfiles_local = append(delfiles_local, p)
  1655  							}
  1656  							if p := helper.URL2local(helper.SetSuffix(v, "_small.jpg")); helper.Exist(p) {
  1657  								delfiles_local = append(delfiles_local, p)
  1658  							}
  1659  						}
  1660  					}
  1661  					for k, v := range delfiles_local {
  1662  						if p := helper.URL2local(v); helper.Exist(p) { //如若文件存在,则处理,否则忽略
  1663  							//先行判断是否缩略图  如果不是则执行删除image表记录的操作 因为缩略图是没有存到image表记录里面的
  1664  							/*
  1665  								isThumbnails := bool(true) //false代表不是缩略图 true代表是缩略图
  1666  								if (!strings.HasSuffix(v, "_large.jpg")) &&
  1667  									(!strings.HasSuffix(v, "_medium.jpg")) &&
  1668  									(!strings.HasSuffix(v, "_small.jpg")) {
  1669  									isThumbnails = false
  1670  
  1671  								}
  1672  							*/
  1673  
  1674  							//验证是否管理员权限
  1675  							if allow {
  1676  								if err := os.Remove(p); err != nil {
  1677  									log.Println("#", k, ",ROOT DEL FILE ERROR:", err)
  1678  								}
  1679  
  1680  								//删除image表中已经被删除文件的记录
  1681  								/*
  1682  									if !isThumbnails {
  1683  										if e := DelImageByLocation(v); e != nil {
  1684  											fmt.Println("DelImageByLocation删除未使用文件", v, "的数据记录时候出现错误:", e)
  1685  										}
  1686  									}
  1687  								*/
  1688  							} else { //检查用户对文件的所有权
  1689  								if helper.VerifyUserfile(p, strconv.Itoa(int(uid))) {
  1690  									if err := os.Remove(p); err != nil {
  1691  										log.Println("#", k, ",DEL FILE ERROR:", err)
  1692  									}
  1693  
  1694  									//删除image表中已经被删除文件的记录
  1695  									/*
  1696  										if !isThumbnails {
  1697  											if e := DelImageByLocation(v); e != nil {
  1698  												fmt.Println("v:", v)
  1699  												fmt.Println("DelImageByLocation删除未使用文件", v, "的数据记录时候出现错误:", e)
  1700  											}
  1701  										}
  1702  									*/
  1703  								}
  1704  							}
  1705  
  1706  						}
  1707  					}
  1708  				}
  1709  			}
  1710  
  1711  			//不管实际路径中是否存在文件均删除该数据库记录,以免数据库记录陷入死循环无法删掉
  1712  			if topic.Id == id {
  1713  				if row, err := Engine.Id(id).Delete(new(Topic)); err != nil || row == 0 {
  1714  					log.Println("row:", row, "删除话题错误:", err)
  1715  					return errors.New("E,删除话题错误!")
  1716  				}
  1717  				return nil
  1718  			}
  1719  
  1720  		}
  1721  		return errors.New("你无权删除此话题:" + strconv.FormatInt(id, 10))
  1722  	}
  1723  	return errors.New("无法删除不存在的TOPIC ID:" + strconv.FormatInt(id, 10))
  1724  }
  1725  
  1726  func GetTopicCountByNid(nid int64) int64 {
  1727  	n, _ := Engine.Where("nid=?", nid).Count(&Topic{Nid: nid})
  1728  	return n
  1729  }