// 发表评论。入topics_reply库,更新topics和topics_ex库 // objname 注册的评论对象名 func PostComment(objid, objtype, uid int, content string, objname string) error { comment := model.NewComment() comment.Objid = objid comment.Objtype = objtype comment.Uid = uid comment.Content = content // TODO:评论楼层怎么处理,避免冲突?最后的楼层信息保存在内存中? // 暂时只是从数据库中取出最后的评论楼层 stringBuilder := util.NewBuffer() stringBuilder.Append("objid=").AppendInt(objid).Append(" AND objtype=").AppendInt(objtype) tmpCmt, err := model.NewComment().Where(stringBuilder.String()).Order("ctime DESC").Find() if err != nil { logger.Errorln("post comment service error:", err) return err } else { comment.Floor = tmpCmt.Floor + 1 } // 入评论库 cid, err := comment.Insert() if err != nil { logger.Errorln("post comment service error:", err) return err } // 回调,不关心处理结果(有些对象可能不需要回调) if commenter, ok := commenters[objname]; ok { logger.Debugf("评论[objid:%d] [objtype:%d] [uid:%d] 成功,通知被评论者更新", objid, objtype, uid) go commenter.UpdateComment(cid, objid, uid, time.Now().Format("2006-01-02 15:04:05")) } return nil }
// 更新该帖子的回复信息 // cid:评论id;objid:被评论对象id;uid:评论者;cmttime:评论时间 func (self TopicComment) UpdateComment(cid, objid, uid int, cmttime string) { tid := strconv.Itoa(objid) // 更新最后回复信息 stringBuilder := util.NewBuffer().Append("lastreplyuid=").AppendInt(uid).Append(",lastreplytime=").Append(cmttime) err := model.NewTopic().Set(stringBuilder.String()).Where("tid=" + tid).Update() if err != nil { logger.Errorln("更新帖子最后回复人信息失败:", err) } // 更新回复数(TODO:暂时每次都更新表) IncrTopicReply(tid, uid) }
// 发表评论(或回复)。 // objid 注册的评论对象 // uid 评论人 func PostComment(uid, objid int, form url.Values) (*model.Comment, error) { comment := model.NewComment() comment.Objid = objid objtype := util.MustInt(form.Get("objtype")) comment.Objtype = objtype comment.Uid = uid comment.Content = form.Get("content") // TODO:评论楼层怎么处理,避免冲突?最后的楼层信息保存在内存中? // 暂时只是从数据库中取出最后的评论楼层 stringBuilder := util.NewBuffer() stringBuilder.Append("objid=").AppendInt(objid).Append(" AND objtype=").AppendInt(objtype) tmpCmt, err := model.NewComment().Where(stringBuilder.String()).Order("ctime DESC").Find() if err != nil { logger.Errorln("post comment service error:", err) return nil, err } else { comment.Floor = tmpCmt.Floor + 1 } // 入评论库 cid, err := comment.Insert() if err != nil { logger.Errorln("post comment service error:", err) return nil, err } comment.Cid = cid comment.Ctime = util.TimeNow() decodeCmtContent(comment) // 回调,不关心处理结果(有些对象可能不需要回调) if commenter, ok := commenters[objtype]; ok { logger.Debugf("评论[objid:%d] [objtype:%d] [uid:%d] 成功,通知被评论者更新", objid, objtype, uid) go commenter.UpdateComment(cid, objid, uid, time.Now().Format("2006-01-02 15:04:05")) } // 发评论,活跃度+5 go IncUserWeight("uid="+strconv.Itoa(uid), 5) // 给被评论对象所有者发系统消息 ext := map[string]interface{}{ "objid": objid, "objtype": objtype, "cid": cid, "uid": uid, } go SendSystemMsgTo(0, objtype, ext) // @某人 发系统消息 go SendSysMsgAtUids(form.Get("uid"), ext) go SendSysMsgAtUsernames(form.Get("usernames"), ext) return comment, nil }
// 构造update语句中的set部分子句 func GenSetClause(form url.Values, fields []string) string { stringBuilder := util.NewBuffer() for _, field := range fields { if form.Get(field) != "" { stringBuilder.Append(",").Append(field).Append("=").Append(form.Get(field)) } } if stringBuilder.Len() > 0 { return stringBuilder.String()[1:] } return "" }
// 查询条件处理(TODO:暂时没有处理between和in) func (this *Dao) Where(condition string) { this.whereVal = make([]interface{}, 0) stringBuilder := util.NewBuffer() conditions := SplitIn(condition, []string{" and ", " AND ", " or ", " OR "}...) for _, condition := range conditions { condition = strings.TrimSpace(condition) parts := SplitIn(condition, "=", "<", ">") if len(parts) >= 3 { // 处理不等于 if strings.HasSuffix(parts[0], "!") { stringBuilder.Append("`" + strings.Trim(parts[0], "` !") + "` !") } else { stringBuilder.Append("`" + strings.Trim(parts[0], "` ") + "`") } stringBuilder.Append(strings.TrimSpace(parts[1])) if len(parts) > 3 { // 判断是不是 ">="或"<=" if strings.ContainsAny(parts[2], "= & < & >") { stringBuilder.Append(strings.TrimSpace(parts[2])) } start := len(parts[0]) + len(parts[1]) + 1 this.whereVal = append(this.whereVal, strings.TrimSpace(condition[start:])) } else { this.whereVal = append(this.whereVal, strings.TrimSpace(parts[2])) } stringBuilder.Append("?") } else { tmp := strings.ToUpper(parts[0]) if tmp == "OR" || tmp == "AND" { stringBuilder.Append(" ").Append(tmp).Append(" ") } else { // 处理"in"语句(TODO:用正则处理?) if strings.ContainsAny(strings.ToLower(parts[0]), "in & ( & )") { ins := Split(parts[0], "(", ")") if len(ins) == 3 { inVals := strings.Split(ins[1], ",") for _, inVal := range inVals { this.whereVal = append(this.whereVal, inVal) } // in中有多少个值 inLen := len(inVals) qms := strings.Repeat("?,", inLen) field := ins[0][:len(ins[0])-3] stringBuilder.Append("`" + strings.Trim(field, "` ") + "` in").Append("(").Append(qms[:len(qms)-1]).Append(")") } } else { stringBuilder.Append("`" + strings.Trim(parts[0], "` ") + "`") } } } } this.where = stringBuilder.String() }
//bug: next page is always same for popular/last/ective and /list/brief // 构造分页html // curPage 当前页码;total总记录数; PAGE_NUM 每页显示多少条 func GetPageHtml(curPage, total, PAGE_NUM int) string { // 总页数 pageCount := total / PAGE_NUM if total%PAGE_NUM != 0 { pageCount++ } if pageCount < 2 { return "" } // 显示5页,然后显示...,接着显示最后两页 stringBuilder := util.NewBuffer() stringBuilder.Append(`<li class="prev previous_page">`) // 当前是第一页 if curPage != 1 { stringBuilder.Append(`<a href="/topics?p=` + strconv.Itoa(curPage-1) + `">← 上一页</a>`) } stringBuilder.Append(`</li>`) before := 5 showPages := 8 for i := 0; i < pageCount; i++ { logger.Traceln(i, pageCount) if i >= showPages { break } if curPage == i+1 { stringBuilder.Append(`<li class="active"><a href="/topics?p=`).AppendInt(i + 1).Append(`">`).AppendInt(i + 1).Append("</a></li>") continue } // 分界点 if curPage >= before { if curPage >= 7 { before = 2 } else { before = curPage + 2 } showPages += 2 } if i == before { stringBuilder.Append(`<li class="disabled"><a href="#"><span class="gap">…</span></a></li>`) continue } stringBuilder.Append(`<li><a href="/topics?p=`).AppendInt(i + 1).Append(`">`).AppendInt(i + 1).Append("</a></li>") } stringBuilder.Append(`<li class="next next_page ">`) // 最后一页 if curPage < pageCount { stringBuilder.Append(`<a href="/topics?p=` + strconv.Itoa(curPage+1) + `">下一页 →</a>`) } stringBuilder.Append(`</li>`) return stringBuilder.String() }
func (this *SolrClient) Post() error { stringBuilder := util.NewBuffer().Append("{") needComma := false for _, addCommand := range this.addCommands { commandJson, err := json.Marshal(addCommand) if err != nil { continue } if stringBuilder.Len() == 1 { needComma = false } else { needComma = true } if needComma { stringBuilder.Append(",") } stringBuilder.Append(`"add":`).AppendBytes(commandJson) } if stringBuilder.Len() == 1 { logger.Errorln("post docs:no right addcommand") return errors.New("no right addcommand") } stringBuilder.Append("}") resp, err := http.Post(config.Config["engine_url"]+"/update?wt=json&commit=true", "application/json", stringBuilder) if err != nil { logger.Errorln("post error:", err) return err } defer resp.Body.Close() var result map[string]interface{} err = json.NewDecoder(resp.Body).Decode(&result) if err != nil { logger.Errorln("parse response error:", err) return err } return nil }
func updateSetClause(form url.Values, fields []string) (query string, args []interface{}) { stringBuilder := util.NewBuffer() for _, field := range fields { if _, ok := form[field]; !ok { continue } stringBuilder.Append(",").Append(field).Append("=?") args = append(args, form.Get(field)) } if stringBuilder.Len() > 0 { query = stringBuilder.String()[1:] } return }
func (this *User) String() string { buffer := util.NewBuffer() buffer.Append(this.Username).Append(this.Email).AppendInt(this.Uid).Append(this.Mtime) return buffer.String() }
// 构造分页html(new) // curPage 当前页码;pageNum 每页记录数;total总记录数;uri 当前uri func GenPageHtml(curPage, pageNum, total int, uri string) string { // 总页数 pageCount := total / pageNum if total%pageNum != 0 { pageCount++ } if pageCount < 2 { return "" } needQues := true if strings.Contains(uri, "?") { needQues = false } // 显示5页,然后显示...,接着显示最后两页 stringBuilder := util.NewBuffer() // 当前是第一页 if curPage != 1 { stringBuilder.Append(`<li><a href="`).Append(uri) if needQues { stringBuilder.Append("?") } else { stringBuilder.Append("&") } stringBuilder.Append("p=").AppendInt(curPage - 1).Append(`">«</a>`) } else { stringBuilder.Append(`<li class="disabled"><a href="#">«</a>`) } stringBuilder.Append(`</li>`) before := 5 showPages := 8 for i := 0; i < pageCount; i++ { if i >= showPages { break } if curPage == i+1 { stringBuilder.Append(`<li class="active"><a href="`).Append(uri) if needQues { stringBuilder.Append("?") } else { stringBuilder.Append("&") } stringBuilder.Append("p=").AppendInt(i + 1).Append(`">`).AppendInt(i + 1).Append("</a></li>") continue } // 分界点 if curPage >= before { if curPage >= 7 { before = 2 } else { before = curPage + 2 } showPages += 2 } if i == before { stringBuilder.Append(`<li class="disabled"><a href="#"><span class="gap">…</span></a></li>`) continue } stringBuilder.Append(`<li><a href="`).Append(uri) if needQues { stringBuilder.Append("?") } else { stringBuilder.Append("&") } stringBuilder.Append("p=").AppendInt(i + 1).Append(`">`).AppendInt(i + 1).Append("</a></li>") } // 最后一页 if curPage < pageCount { stringBuilder.Append(`<li><a href="`).Append(uri) if needQues { stringBuilder.Append("?") } else { stringBuilder.Append("&") } stringBuilder.Append("p=").AppendInt(curPage + 1).Append(`">»</a>`) } else { stringBuilder.Append(`<li class="disabled"><a href="#">»</a>`) } stringBuilder.Append(`</li>`) return stringBuilder.String() }