@Aop("redis")
 public CResult add(Topic topic, int userId) {
   if (userId < 1) {
     return _fail("请先登录");
   }
   if (Strings.isBlank(topic.getTitle())
       || topic.getTitle().length() > 1024
       || topic.getTitle().length() < 5) {
     return _fail("标题长度不合法");
   }
   if (Strings.isBlank(topic.getContent())) {
     return _fail("内容不合法");
   }
   if (topic.getTags() != null && topic.getTags().size() > 10) {
     return _fail("最多只能有10个tag");
   }
   if (0 != dao.count(Topic.class, Cnd.where("title", "=", topic.getTitle().trim()))) {
     return _fail("相同标题已经发过了");
   }
   topic.setTitle(Strings.escapeHtml(topic.getTitle().trim()));
   topic.setUserId(userId);
   topic.setTop(false);
   topic.setTags(new HashSet<String>());
   if (topic.getType() == null) topic.setType(TopicType.ask);
   topic.setContent(Toolkit.filteContent(topic.getContent()));
   String oldContent = topic.getContent();
   topic.setContentId(bigContentService.put(topic.getContent()));
   topic.setContent(null);
   dao.insert(topic);
   try {
     topic.setContent(oldContent);
     topicSearchService.add(topic);
   } catch (Exception e) {
   }
   // 如果是ask类型,把帖子加入到 "未回复"列表
   Pipeline pipe = jedis().pipelined();
   if (TopicType.ask.equals(topic.getType())) {
     pipe.zadd(RKEY_TOPIC_NOREPLY, System.currentTimeMillis(), topic.getId());
   }
   pipe.zadd(RKEY_TOPIC_UPDATE + topic.getType(), System.currentTimeMillis(), topic.getId());
   if (topic.getType() != TopicType.shortit)
     pipe.zadd(RKEY_TOPIC_UPDATE_ALL, System.currentTimeMillis(), topic.getId());
   pipe.zincrby(RKEY_USER_SCORE, 100, "" + userId);
   pipe.sync();
   String replyAuthorName = dao.fetch(User.class, userId).getName();
   for (Integer watcherId : globalWatcherIds) {
     if (watcherId != userId)
       pushUser(
           watcherId,
           "新帖:" + topic.getTitle(),
           topic.getId(),
           replyAuthorName,
           topic.getTitle(),
           PushService.PUSH_TYPE_REPLY);
   }
   updateTopicTypeCount();
   return _ok(topic.getId());
 }
 /**
  * @api {post} /yvr/api/v1/topics 发表帖子, 以json格式提交数据
  * @apiGroup Topic
  * @apiVersion 1.0.0
  * @apiUse TOKEN
  * @apiUse TOKEN_ERROR
  * @apiParam {String} title 标题
  * @apiParam {String} content 内容
  * @apiParam {String} [tab=ask] 类型,默认为问答
  * @apiSuccess {boolean} success 是否成功
  * @apiSuccess {String} [topic_id] 成功时返回帖子的Id
  * @apiSuccess {String} [message] 失败时返回原因
  */
 @POST
 @At("/topics")
 @AdaptBy(type = WhaleAdaptor.class)
 @Filters(@By(type = AccessTokenFilter.class))
 public Object add(
     @Param("..") Topic topic,
     @Attr(scope = Scope.SESSION, value = "me") int userId,
     @Param("tab") String tab) {
   if (tab != null) topic.setType(TopicType.valueOf(tab));
   CResult re = yvrService.add(topic, userId);
   if (re.isOk()) {
     return _map("success", true, "topic_id", re.as(String.class));
   } else {
     return _map("success", false, "message", re.getMsg());
   }
 }