Explorar el Código

Merge remote-tracking branch 'origin/uuhelper' into dev

huangct hace 8 años
padre
commit
fab1614d2e
Se han modificado 38 ficheros con 4356 adiciones y 438 borrados
  1. 25 2
      jpress-model/src/main/java/io/jpress/model/Comment.java
  2. 59 16
      jpress-model/src/main/java/io/jpress/model/Content.java
  3. 31 0
      jpress-model/src/main/java/io/jpress/model/Vote.java
  4. 20 4
      jpress-model/src/main/java/io/jpress/model/base/BaseComment.java
  5. 224 0
      jpress-model/src/main/java/io/jpress/model/base/BaseVote.java
  6. 137 5
      jpress-model/src/main/java/io/jpress/model/query/CommentQuery.java
  7. 149 0
      jpress-model/src/main/java/io/jpress/model/query/ContentQuery.java
  8. 8 2
      jpress-model/src/main/java/io/jpress/model/query/MetaDataQuery.java
  9. 10 6
      jpress-model/src/main/java/io/jpress/model/query/TaxonomyQuery.java
  10. 74 0
      jpress-model/src/main/java/io/jpress/model/query/VoteQuery.java
  11. 49 8
      jpress-web-admin/src/main/java/io/jpress/admin/controller/_CommentController.java
  12. 187 22
      jpress-web-admin/src/main/java/io/jpress/admin/controller/_ContentController.java
  13. 29 3
      jpress-web-admin/src/main/webapp/WEB-INF/admin/attachment/choose_layer.html
  14. 231 133
      jpress-web-admin/src/main/webapp/WEB-INF/admin/comment/index.html
  15. 1 1
      jpress-web-admin/src/main/webapp/WEB-INF/admin/comment/reply_layer.html
  16. 171 0
      jpress-web-admin/src/main/webapp/WEB-INF/admin/comment/uuHelperCommentList.html
  17. 206 0
      jpress-web-admin/src/main/webapp/WEB-INF/admin/comment/uuHelperGroupDetail.html
  18. 127 0
      jpress-web-admin/src/main/webapp/WEB-INF/admin/comment/uuHelperGroupList.html
  19. 481 56
      jpress-web-admin/src/main/webapp/WEB-INF/admin/content/_edit_include.html
  20. 350 155
      jpress-web-admin/src/main/webapp/WEB-INF/admin/content/_index_include.html
  21. 74 9
      jpress-web-admin/src/main/webapp/WEB-INF/admin/content/edit.html
  22. 29 0
      jpress-web-admin/src/main/webapp/WEB-INF/admin/content/index.html
  23. 10 4
      jpress-web-core/src/main/java/io/jpress/ui/freemarker/tag/CommentPageTag.java
  24. BIN
      jpress-web-core/src/main/webapp/static/jpress/admin/image/dot.png
  25. BIN
      jpress-web-core/src/main/webapp/static/jpress/admin/image/hands.png
  26. BIN
      jpress-web-core/src/main/webapp/static/jpress/admin/image/loading.png
  27. BIN
      jpress-web-core/src/main/webapp/static/jpress/admin/image/pen.png
  28. BIN
      jpress-web-core/src/main/webapp/static/jpress/admin/image/support.png
  29. BIN
      jpress-web-core/src/main/webapp/static/jpress/admin/image/xiala.png
  30. 174 7
      jpress-web-front/src/main/java/io/jpress/front/controller/CommentController.java
  31. 86 4
      jpress-web-front/src/main/java/io/jpress/front/controller/ContentController.java
  32. 41 0
      jpress-web-template-usoftchina/src/main/webapp/templates/usoftchina/assets/css/imgareaselect-default.css
  33. 730 0
      jpress-web-template-usoftchina/src/main/webapp/templates/usoftchina/assets/js/jquery.imgareaselect.js
  34. 0 0
      jpress-web-template-usoftchina/src/main/webapp/templates/usoftchina/assets/js/jquery.imgareaselect.min.js
  35. 0 0
      jpress-web-template-usoftchina/src/main/webapp/templates/usoftchina/assets/js/jquery.imgareaselect.pack.js
  36. 434 0
      jpress-web-template-usoftchina/src/main/webapp/templates/usoftchina/content_uuhelper.html
  37. 205 0
      jpress-web-template-usoftchina/src/main/webapp/templates/usoftchina/taxonomy_uuhelper.html
  38. 4 1
      jpress-web-template-usoftchina/src/main/webapp/templates/usoftchina/tpl_config.xml

+ 25 - 2
jpress-model/src/main/java/io/jpress/model/Comment.java

@@ -15,13 +15,14 @@
  */
  */
 package io.jpress.model;
 package io.jpress.model;
 
 
-import java.math.BigInteger;
-
 import io.jpress.model.base.BaseComment;
 import io.jpress.model.base.BaseComment;
 import io.jpress.model.core.Table;
 import io.jpress.model.core.Table;
 import io.jpress.model.query.CommentQuery;
 import io.jpress.model.query.CommentQuery;
 import io.jpress.model.query.ContentQuery;
 import io.jpress.model.query.ContentQuery;
 import io.jpress.model.query.UserQuery;
 import io.jpress.model.query.UserQuery;
+import io.jpress.model.query.VoteQuery;
+
+import java.math.BigInteger;
 
 
 @Table(tableName = "comment", primaryKey = "id")
 @Table(tableName = "comment", primaryKey = "id")
 public class Comment extends BaseComment<Comment> {
 public class Comment extends BaseComment<Comment> {
@@ -49,6 +50,10 @@ public class Comment extends BaseComment<Comment> {
 		return content;
 		return content;
 	}
 	}
 
 
+	public Content getContentById(BigInteger id) {
+		return ContentQuery.me().findById(id);
+	}
+
 	public void setContent(Content content) {
 	public void setContent(Content content) {
 		this.content = content;
 		this.content = content;
 	}
 	}
@@ -130,4 +135,22 @@ public class Comment extends BaseComment<Comment> {
 
 
 		return super.save();
 		return super.save();
 	}
 	}
+
+	public Comment getlatestSon(BigInteger id){
+        return CommentQuery.me().findLatestSon(id);
+	}
+
+	public boolean updateVoteUpCount() {
+		long count = VoteQuery.me().findCountByCommentId(getId());
+		if (count > 0) {
+			setVoteUp(count);
+			return this.update();
+		}
+		return false;
+	}
+
+	//判断是否处于已赞状态
+	public boolean isvoted(BigInteger commentId, BigInteger userId, BigInteger uuUserId) {
+		return VoteQuery.me().findCommentCountVote(commentId, userId, uuUserId);
+	}
 }
 }

+ 59 - 16
jpress-model/src/main/java/io/jpress/model/Content.java

@@ -15,28 +15,15 @@
  */
  */
 package io.jpress.model;
 package io.jpress.model;
 
 
-import java.io.File;
-import java.math.BigInteger;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
 import com.jfinal.core.JFinal;
 import com.jfinal.core.JFinal;
 import com.jfinal.kit.PathKit;
 import com.jfinal.kit.PathKit;
 import com.jfinal.plugin.ehcache.CacheKit;
 import com.jfinal.plugin.ehcache.CacheKit;
 import com.jfinal.plugin.ehcache.IDataLoader;
 import com.jfinal.plugin.ehcache.IDataLoader;
-
 import io.jpress.Consts;
 import io.jpress.Consts;
 import io.jpress.model.ModelSorter.ISortModel;
 import io.jpress.model.ModelSorter.ISortModel;
 import io.jpress.model.base.BaseContent;
 import io.jpress.model.base.BaseContent;
 import io.jpress.model.core.Table;
 import io.jpress.model.core.Table;
-import io.jpress.model.query.CommentQuery;
-import io.jpress.model.query.ContentQuery;
-import io.jpress.model.query.MappingQuery;
-import io.jpress.model.query.MetaDataQuery;
-import io.jpress.model.query.TaxonomyQuery;
-import io.jpress.model.query.UserQuery;
+import io.jpress.model.query.*;
 import io.jpress.model.router.ContentRouter;
 import io.jpress.model.router.ContentRouter;
 import io.jpress.model.router.PageRouter;
 import io.jpress.model.router.PageRouter;
 import io.jpress.template.TemplateManager;
 import io.jpress.template.TemplateManager;
@@ -44,6 +31,13 @@ import io.jpress.template.Thumbnail;
 import io.jpress.utils.JsoupUtils;
 import io.jpress.utils.JsoupUtils;
 import io.jpress.utils.StringUtils;
 import io.jpress.utils.StringUtils;
 
 
+import java.io.File;
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
 @Table(tableName = "content", primaryKey = "id")
 @Table(tableName = "content", primaryKey = "id")
 public class Content extends BaseContent<Content> implements ISortModel<Content> {
 public class Content extends BaseContent<Content> implements ISortModel<Content> {
 
 
@@ -204,7 +198,7 @@ public class Content extends BaseContent<Content> implements ISortModel<Content>
 		}
 		}
 		return metadatas;
 		return metadatas;
 	}
 	}
-	
+
 	public String getMetadataByKey(String key) {
 	public String getMetadataByKey(String key) {
 		Metadata metadata = MetaDataQuery.me().findByTypeAndIdAndKey(METADATA_TYPE, getId(), key);
 		Metadata metadata = MetaDataQuery.me().findByTypeAndIdAndKey(METADATA_TYPE, getId(), key);
 		return metadata.getMetaValue();
 		return metadata.getMetaValue();
@@ -441,7 +435,12 @@ public class Content extends BaseContent<Content> implements ISortModel<Content>
 	public String getSummary() {
 	public String getSummary() {
 		String summary = super.getSummary();
 		String summary = super.getSummary();
 		if (StringUtils.isBlank(summary)) {
 		if (StringUtils.isBlank(summary)) {
-			summary = summaryWithLen(100);
+			//uu软文摘要不填默认截取前54个字
+			if ("uuhelper".equals(super.getModule())) {
+				summary = summaryWithLen(54);
+			} else {
+				summary = summaryWithLen(100);
+			}
 		}
 		}
 		return summary;
 		return summary;
 	}
 	}
@@ -468,4 +467,48 @@ public class Content extends BaseContent<Content> implements ISortModel<Content>
 		super.setSlug(slug);
 		super.setSlug(slug);
 	}
 	}
 
 
+	//判断该移动端用户是否以及评论过此uu软文
+	public boolean isUuUserReplied(BigInteger uuUserId) {
+		if (uuUserId == null) {
+			return false;
+		}
+		long count = CommentQuery.me().findCountByContentIdAndUuUserId(getId(), uuUserId);
+		if (count > 0) {
+			return true;
+		}
+		return false;
+	}
+
+	//判断该官网用户是否以及评论过此uu软文
+	public boolean isUserReplied(BigInteger userId) {
+		if (userId == null) {
+			return false;
+		}
+		long count = CommentQuery.me().findCountByContentIdAndUserId(getId(), userId);
+		if (count > 0) {
+			return true;
+		}
+		return false;
+	}
+
+	public boolean updateVoteUpCount(String status) {
+		long count = getVoteUp();
+
+		if ("up".equals(status)) {
+			count++;
+		} else {
+			count--;
+		}
+
+		if (count < 0) {
+			count = 0;
+		}
+		setVoteUp(count);
+		return this.update();
+	}
+
+	//判断是否处于已赞状态
+	public boolean isvoted(BigInteger content, BigInteger userId, BigInteger uuUserId) {
+		return VoteQuery.me().findContentCountVote(content, userId, uuUserId);
+	}
 }
 }

+ 31 - 0
jpress-model/src/main/java/io/jpress/model/Vote.java

@@ -0,0 +1,31 @@
+/**
+ * Copyright (c) 2015-2016, Michael Yang 杨福海 (fuhai999@gmail.com).
+ *
+ * Licensed under the GNU Lesser General Public License (LGPL) ,Version 3.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.gnu.org/licenses/lgpl-3.0.txt
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.jpress.model;
+
+import io.jpress.model.base.BaseVote;
+import io.jpress.model.core.Table;
+
+@Table(tableName = "vote", primaryKey = "id")
+public class Vote extends BaseVote<Vote> {
+
+	private static final long serialVersionUID = 1L;
+
+	public static String STATUS_DELETE = "delete";
+	public static String STATUS_DRAFT = "draft";
+	public static String STATUS_NORMAL = "normal";
+
+
+}

+ 20 - 4
jpress-model/src/main/java/io/jpress/model/base/BaseComment.java

@@ -15,15 +15,15 @@
  */
  */
 package io.jpress.model.base;
 package io.jpress.model.base;
 
 
+import com.jfinal.plugin.activerecord.IBean;
+import com.jfinal.plugin.ehcache.CacheKit;
+import com.jfinal.plugin.ehcache.IDataLoader;
 import io.jpress.message.MessageKit;
 import io.jpress.message.MessageKit;
 import io.jpress.model.Metadata;
 import io.jpress.model.Metadata;
 import io.jpress.model.core.JModel;
 import io.jpress.model.core.JModel;
 import io.jpress.model.query.MetaDataQuery;
 import io.jpress.model.query.MetaDataQuery;
-import java.math.BigInteger;
 
 
-import com.jfinal.plugin.activerecord.IBean;
-import com.jfinal.plugin.ehcache.CacheKit;
-import com.jfinal.plugin.ehcache.IDataLoader;
+import java.math.BigInteger;
 
 
 /**
 /**
  *  Auto generated by JPress, do not modify this file.
  *  Auto generated by JPress, do not modify this file.
@@ -300,4 +300,20 @@ public abstract class BaseComment<M extends BaseComment<M>> extends JModel<M> im
 		return get("lng");
 		return get("lng");
 	}
 	}
 
 
+	public void setUuUserId(java.math.BigInteger uuUserId) {
+		set("uu_user_id", uuUserId);
+	}
+
+	public java.math.BigInteger getUuUserId() {
+		return get("uu_user_id");
+	}
+
+    public void setUuUserAvatar(java.lang.String uuUserAvatar) {
+        set("uu_user_avatar", uuUserAvatar);
+    }
+
+    public java.lang.String getUuUserAvatar() {
+        return get("uu_user_avatar");
+    }
+
 }
 }

+ 224 - 0
jpress-model/src/main/java/io/jpress/model/base/BaseVote.java

@@ -0,0 +1,224 @@
+/**
+ * Copyright (c) 2015-2016, Michael Yang 杨福海 (fuhai999@gmail.com).
+ *
+ * Licensed under the GNU Lesser General Public License (LGPL) ,Version 3.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.gnu.org/licenses/lgpl-3.0.txt
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.jpress.model.base;
+
+import com.jfinal.plugin.activerecord.IBean;
+import com.jfinal.plugin.ehcache.CacheKit;
+import com.jfinal.plugin.ehcache.IDataLoader;
+import io.jpress.message.MessageKit;
+import io.jpress.model.Metadata;
+import io.jpress.model.core.JModel;
+import io.jpress.model.query.MetaDataQuery;
+
+import java.math.BigInteger;
+
+/**
+ * @author 黄诚天
+ * @param <M>
+ */
+@SuppressWarnings("serial")
+public abstract class BaseVote<M extends BaseVote<M>> extends JModel<M> implements IBean {
+
+	public static final String CACHE_NAME = "vote";
+	public static final String METADATA_TYPE = "vote";
+
+	public static final String ACTION_ADD = "vote:add";
+	public static final String ACTION_DELETE = "vote:delete";
+	public static final String ACTION_UPDATE = "vote:update";
+
+	public void removeCache(Object key){
+		if(key == null) return;
+		CacheKit.remove(CACHE_NAME, key);
+	}
+
+	public void putCache(Object key,Object value){
+		CacheKit.put(CACHE_NAME, key, value);
+	}
+
+	public M getCache(Object key){
+		return CacheKit.get(CACHE_NAME, key);
+	}
+
+	public M getCache(Object key,IDataLoader dataloader){
+		return CacheKit.get(CACHE_NAME, key, dataloader);
+	}
+
+	public Metadata createMetadata(){
+		Metadata md = new Metadata();
+		md.setObjectId(getId());
+		md.setObjectType(METADATA_TYPE);
+		return md;
+	}
+
+	public Metadata createMetadata(String key,String value){
+		Metadata md = new Metadata();
+		md.setObjectId(getId());
+		md.setObjectType(METADATA_TYPE);
+		md.setMetaKey(key);
+		md.setMetaValue(value);
+		return md;
+	}
+
+	public boolean saveOrUpdateMetadta(String key,String value){
+		Metadata metadata = MetaDataQuery.me().findByTypeAndIdAndKey(METADATA_TYPE, getId(), key);
+		if (metadata == null) {
+			metadata = createMetadata(key, value);
+			return metadata.save();
+		}
+		metadata.setMetaValue(value);
+		return metadata.update();
+	}
+
+	public String metadata(String key) {
+		Metadata m = MetaDataQuery.me().findByTypeAndIdAndKey(METADATA_TYPE, getId(), key);
+		if (m != null) {
+			return m.getMetaValue();
+		}
+		return null;
+	}
+
+	@Override
+	public boolean equals(Object o) {
+		if(o == null){ return false; }
+		if(!(o instanceof BaseVote<?>)){return false;}
+
+		BaseVote<?> m = (BaseVote<?>) o;
+		if(m.getId() == null){return false;}
+
+		return m.getId().compareTo(this.getId()) == 0;
+	}
+
+	@Override
+	public boolean save() {
+		boolean saved = super.save();
+		if (saved) { MessageKit.sendMessage(ACTION_ADD, this); }
+		return saved;
+	}
+
+	@Override
+	public boolean delete() {
+		boolean deleted = super.delete();
+		if (deleted) { MessageKit.sendMessage(ACTION_DELETE, this); }
+		return deleted;
+	}
+
+	@Override
+	public boolean deleteById(Object idValue) {
+		boolean deleted = super.deleteById(idValue);
+		if (deleted) { MessageKit.sendMessage(ACTION_DELETE, this); }
+		return deleted;
+	}
+
+	@Override
+	public boolean update() {
+		boolean update = super.update();
+		if (update) { MessageKit.sendMessage(ACTION_UPDATE, this); }
+		return update;
+	}
+
+	public void setId(BigInteger id) {
+		set("id", id);
+	}
+
+	public BigInteger getId() {
+		Object id = get("id");
+		if (id == null)
+			return null;
+
+		return id instanceof BigInteger ? (BigInteger)id : new BigInteger(id.toString());
+	}
+
+	public void setContentId(BigInteger contentId) {
+		set("content_id", contentId);
+	}
+
+	public BigInteger getContentId() {
+		return get("content_id");
+	}
+
+	public void setCommentId(BigInteger commentId) {
+		set("comment_id", commentId);
+	}
+
+	public BigInteger getCommentId() {
+		return get("comment_id");
+	}
+
+	public void setUserId(BigInteger userId) {
+		set("user_id", userId);
+	}
+
+	public BigInteger getUserId() {
+		return get("user_id");
+	}
+
+	public void setUuUserId(BigInteger uuUserId) {
+		set("uu_user_id", uuUserId);
+	}
+
+	public BigInteger getUuUserId() {
+		return get("uu_user_id");
+	}
+
+	public void setUp(java.lang.Boolean up) {
+		set("up", up);
+	}
+
+	public java.lang.Boolean getUp() {
+		return get("up");
+	}
+
+	public void setDown(java.lang.Boolean down) {
+		set("down", down);
+	}
+
+	public java.lang.Boolean getDown() {
+		return get("down");
+	}
+
+	public void setStatus(java.lang.String status) {
+		set("status", status);
+	}
+
+	public java.lang.String getStatus() {
+		return get("status");
+	}
+
+	public void setIp(java.lang.String ip) {
+		set("ip", ip);
+	}
+
+	public java.lang.String getIp() {
+		return get("ip");
+	}
+
+	public void setAgent(java.lang.String agent) {
+		set("agent", agent);
+	}
+
+	public java.lang.String getAgent() {
+		return get("agent");
+	}
+
+	public void setCreated(java.util.Date created) {
+		set("created", created);
+	}
+
+	public java.util.Date getCreated() {
+		return get("created");
+	}
+
+}

+ 137 - 5
jpress-model/src/main/java/io/jpress/model/query/CommentQuery.java

@@ -15,14 +15,14 @@
  */
  */
 package io.jpress.model.query;
 package io.jpress.model.query;
 
 
-import java.math.BigInteger;
-import java.util.LinkedList;
-
 import com.jfinal.plugin.activerecord.Page;
 import com.jfinal.plugin.activerecord.Page;
 import com.jfinal.plugin.ehcache.IDataLoader;
 import com.jfinal.plugin.ehcache.IDataLoader;
-
 import io.jpress.model.Comment;
 import io.jpress.model.Comment;
 
 
+import java.math.BigInteger;
+import java.util.LinkedList;
+import java.util.List;
+
 public class CommentQuery extends JBaseQuery {
 public class CommentQuery extends JBaseQuery {
 
 
 	protected static final Comment DAO = new Comment();
 	protected static final Comment DAO = new Comment();
@@ -53,7 +53,44 @@ public class CommentQuery extends JBaseQuery {
 		needWhere = appendIfNotEmpty(fromBuilder, " c.parent_id", parentCommentId, params, needWhere);
 		needWhere = appendIfNotEmpty(fromBuilder, " c.parent_id", parentCommentId, params, needWhere);
 		needWhere = appendIfNotEmpty(fromBuilder, " content.id", contentId, params, needWhere);
 		needWhere = appendIfNotEmpty(fromBuilder, " content.id", contentId, params, needWhere);
 
 
-		fromBuilder.append("order by c.created desc");
+		if ("uuhelper".equals(module)) {
+			//软文详情页评论排序,先按是否置顶排,再按点赞数排,最后按评论时间排。
+			fromBuilder.append("ORDER BY c.order_number desc,c.vote_up desc, c.created desc");
+		} else {
+			fromBuilder.append("order by c.created desc");
+		}
+
+		if (params.isEmpty()) {
+			return DAO.paginate(pageNumber, pageSize, select, fromBuilder.toString());
+		}
+		return DAO.paginate(pageNumber, pageSize, select, fromBuilder.toString(), params.toArray());
+	}
+
+	public Page<Comment> uuHelperPaginateWithContent(int pageNumber, int pageSize, String module, String type,
+											 BigInteger contentId, BigInteger parentCommentId, String status) {
+
+		String select = " select DISTINCT c.id, c.*,content.title content_title,u.username,u.nickname,u.avatar, "
+				+ "quote_comment.text qc_content,quote_comment.author qc_author,quote_comment.id qc_id,quote_comment.vote_up qc_vote_up,"
+				+ "quote_user.username qc_username,quote_user.nickname qc_nickname,quote_user.avatar qc_avatar ";
+
+		StringBuilder fromBuilder = new StringBuilder("  from comment c");
+		fromBuilder.append(" left join content on c.content_id = content.id");
+		fromBuilder.append(" left join user u on c.user_id = u.id ");
+		fromBuilder.append(" left join comment quote_comment on c.id = quote_comment.parent_id");
+		fromBuilder.append(" left join user quote_user on quote_comment.user_id = quote_user.id ");
+
+		LinkedList<Object> params = new LinkedList<Object>();
+		boolean needWhere = true;
+		needWhere = appendIfNotEmpty(fromBuilder, " c.`type`", type, params, needWhere);
+		needWhere = appendIfNotEmpty(fromBuilder, " c.content_module", module, params, needWhere);
+		needWhere = appendIfNotEmpty(fromBuilder, " c.`status`", status, params, needWhere);
+		//needWhere = appendIfNotEmpty(fromBuilder, " c.parent_id", parentCommentId, params, needWhere);
+		needWhere = appendIfNotEmpty(fromBuilder, " content.id", contentId, params, needWhere);
+
+
+		//软文详情页评论排序,先按是否置顶排,再按点赞数排,最后按评论时间排。
+		fromBuilder.append("and c.parent_id is null GROUP BY c.id ORDER BY c.order_number desc,c.vote_up desc, c.created desc");
+
 
 
 		if (params.isEmpty()) {
 		if (params.isEmpty()) {
 			return DAO.paginate(pageNumber, pageSize, select, fromBuilder.toString());
 			return DAO.paginate(pageNumber, pageSize, select, fromBuilder.toString());
@@ -90,10 +127,50 @@ public class CommentQuery extends JBaseQuery {
 		return DAO.paginate(pageNumber, pageSize, select, fromBuilder.toString(), params.toArray());
 		return DAO.paginate(pageNumber, pageSize, select, fromBuilder.toString(), params.toArray());
 	}
 	}
 
 
+	public Page<Comment> paginateWithContentAndSon(int pageNumber, int pageSize, String module, String type,
+														BigInteger contentId, BigInteger parentCommentId, Boolean hasSon) {
+
+		String select = " select c.*,content.title content_title,u.username,u.nickname,u.avatar, "
+				+ "quote_comment.text qc_content,quote_comment.author qc_author,"
+				+ "quote_user.username qc_username,quote_user.nickname qc_nickname,quote_user.avatar qc_avatar ";
+
+		StringBuilder fromBuilder = new StringBuilder("  from comment c");
+		fromBuilder.append(" left join content on c.content_id = content.id");
+		fromBuilder.append(" left join user u on c.user_id = u.id ");
+		fromBuilder.append(" left join comment quote_comment on c.parent_id = quote_comment.id");
+		fromBuilder.append(" left join user quote_user on quote_comment.user_id = quote_user.id ");
+
+		fromBuilder.append(" WHERE c.status <> '" + Comment.STATUS_DELETE + "' ");
+
+		if (hasSon == true) {
+			fromBuilder.append("and c.parent_id is not null ");
+		} else {
+			//不找作者本身的回复(需再思考  数量和实际显示)
+			fromBuilder.append("and c.parent_id is null and c.user_id != content.user_id ");
+		}
+
+		LinkedList<Object> params = new LinkedList<Object>();
+		appendIfNotEmpty(fromBuilder, " c.`type`", type, params, false);
+		appendIfNotEmpty(fromBuilder, " c.content_module", module, params, false);
+		appendIfNotEmpty(fromBuilder, " c.parent_id", parentCommentId, params, false);
+		appendIfNotEmpty(fromBuilder, " content.id", contentId, params, false);
+
+		fromBuilder.append("order by c.created desc");
+
+		if (params.isEmpty()) {
+			return DAO.paginate(pageNumber, pageSize, select, fromBuilder.toString());
+		}
+		return DAO.paginate(pageNumber, pageSize, select, fromBuilder.toString(), params.toArray());
+	}
+
 	public Page<Comment> paginateByContentId(int pageNumber, int pageSize, BigInteger contentId) {
 	public Page<Comment> paginateByContentId(int pageNumber, int pageSize, BigInteger contentId) {
 		return paginateWithContent(pageNumber, pageSize, null, null, contentId, null, Comment.STATUS_NORMAL);
 		return paginateWithContent(pageNumber, pageSize, null, null, contentId, null, Comment.STATUS_NORMAL);
 	}
 	}
 
 
+	public Page<Comment> uuHelperPaginateByContentId(int pageNumber, int pageSize, BigInteger contentId, String module) {
+		return uuHelperPaginateWithContent(pageNumber, pageSize, module, null, contentId, null, Comment.STATUS_NORMAL);
+	}
+
 	public long findCountByContentIdInNormal(BigInteger contentId) {
 	public long findCountByContentIdInNormal(BigInteger contentId) {
 		return findCountByContentId(contentId, Comment.STATUS_NORMAL);
 		return findCountByContentId(contentId, Comment.STATUS_NORMAL);
 	}
 	}
@@ -139,4 +216,59 @@ public class CommentQuery extends JBaseQuery {
 		return DAO.doFindCount("content_module = ? and status=?", module, status);
 		return DAO.doFindCount("content_module = ? and status=?", module, status);
 	}
 	}
 
 
+	public long findCountByModuleAndSonAndContentId(BigInteger contentId, String module, boolean hasSon) {
+		io.jpress.model.Content content = DAO.getContentById(contentId);
+		BigInteger authorUserId = null;
+		if (content != null) {
+			authorUserId = content.getUserId();
+		}
+		Long count = new Long(0);
+		if (hasSon == true) {
+			count = DAO.doFindCount("content_module = ? and parent_id is not null and content_id = ?", module ,contentId);
+		} else {
+			if (authorUserId == null) {
+				count = DAO.doFindCount("content_module = ? and parent_id is null and content_id = ? ", module ,contentId);
+			} else {
+				count = DAO.doFindCount("content_module = ? and parent_id is null and content_id = ? and user_id != ?", module ,contentId ,authorUserId);
+			}
+		}
+
+		return count;
+	}
+
+	public long findCountByModuleAndStatusAndContentId(BigInteger contentId, String module, String status) {
+		return DAO.doFindCount(" content_id = ? and content_module = ? and status=?",contentId, module, status);
+	}
+
+	public long findCountByModuleAndStatusAndContentId(BigInteger contentId, String module, boolean parent) {
+		Long count = new Long(0);
+		if (parent == true) {
+			count = DAO.doFindCount("content_module = ? and parent_id is not null and content_id = " + contentId, module);
+		} else {
+			count = DAO.doFindCount("content_module = ? and parent_id is null and content_id = " + contentId, module);
+		}
+
+		return count;
+	}
+
+	//查当前移动端用户是否评论过此文章
+	public long findCountByContentIdAndUuUserId(BigInteger contentId, BigInteger uuUserId) {
+		return DAO.doFindCount(" content_id = ? and uu_user_id=? ", contentId, uuUserId);
+	}
+
+	//查当前官网用户是否评论过此文章
+	public long findCountByContentIdAndUserId(BigInteger contentId, BigInteger userId) {
+		return DAO.doFindCount(" content_id = ? and user_id=? ", contentId, userId);
+	}
+
+	//只获取最新的一条作者回复(子回复)
+	public Comment findLatestSon(BigInteger id) {
+		Comment comment = null;
+		List<Comment> list = DAO.find("SELECT * from jpress_comment where parent_id= " + id +" ORDER BY created desc LIMIT 1");
+		if (list.size() > 0) {
+			comment = list.get(0);
+		}
+		return comment;
+	}
+
 }
 }

+ 149 - 0
jpress-model/src/main/java/io/jpress/model/query/ContentQuery.java

@@ -65,6 +65,13 @@ public class ContentQuery extends JBaseQuery {
 		return paginate(page, pagesize, modules, keyword, status, tids, null, month, null);
 		return paginate(page, pagesize, modules, keyword, status, tids, null, month, null);
 	}
 	}
 
 
+	public Page<Content> uuHelperPaginateBySearch(int page, int pagesize, String module, String keyword,
+												  String pushTime, String author, String copyRight, String taxonomy,
+												  String status, BigInteger[] tids, String month) {
+		String[] modules = StringUtils.isNotBlank(module) ? new String[] { module } : null;
+		return uuHelperPaginate(page, pagesize, modules, keyword, pushTime, author, copyRight, taxonomy, status, tids, null, month, null);
+	}
+
 	public Page<Content> paginateByModuleInNormal(int page, int pagesize, String module) {
 	public Page<Content> paginateByModuleInNormal(int page, int pagesize, String module) {
 		return paginate(page, pagesize, module, null, Content.STATUS_NORMAL, null, null, null);
 		return paginate(page, pagesize, module, null, Content.STATUS_NORMAL, null, null, null);
 	}
 	}
@@ -107,6 +114,62 @@ public class ContentQuery extends JBaseQuery {
 		return DAO.paginate(page, pagesize, true, select, sql.toString(), params.toArray());
 		return DAO.paginate(page, pagesize, true, select, sql.toString(), params.toArray());
 	}
 	}
 
 
+	public Page<Content> uuHelperPaginateByModuleNotInDelete(int page, int pagesize, String module, String keyword,
+															 String pushTime, String author, String copyRight, String taxonomy,
+															 BigInteger[] taxonomyIds, String month) {
+
+		StringBuilder sql = new StringBuilder(" from content c");
+		sql.append(" left join mapping m on c.id = m.`content_id`");
+		sql.append(" left join taxonomy  t on  m.`taxonomy_id` = t.id");
+		sql.append(" left join metadata d on c.id = d.`object_id`");
+		sql.append(" left join metadata d1 on c.id = d1.`object_id`");
+		sql.append(" where c.status <> ?");
+
+		LinkedList<Object> params = new LinkedList<Object>();
+		params.add(Content.STATUS_DELETE);
+
+		appendIfNotEmpty(sql, "c.module", module, params, false);
+		//uuhelper过滤筛选
+		if (StringUtils.isNotBlank(pushTime)) {
+			appendIfNotEmpty(sql, "d.meta_key", "push_time", params, false);
+			appendIfNotEmpty(sql, "d.meta_value", pushTime, params, false);
+		}
+		if (StringUtils.isNotBlank(copyRight)) {
+			appendIfNotEmpty(sql, "d1.meta_key", "copy_right", params, false);
+			appendIfNotEmpty(sql, "d1.meta_value", copyRight, params, false);
+		}
+		if (StringUtils.isNotBlank(author)) {
+			appendIfNotEmpty(sql, "c.author", author, params, false);
+		}
+		if (StringUtils.isNotBlank(taxonomy)) {
+			appendIfNotEmpty(sql, "t.title", taxonomy, params, false);
+		}
+
+		if (StringUtils.isNotBlank(keyword)) {
+			sql.append(" AND c.title like ? ");
+			params.add("%" + keyword + "%");
+		}
+
+		if (taxonomyIds != null && taxonomyIds.length > 0) {
+			sql.append(" AND t.id in " + toString(taxonomyIds));
+		}
+
+		if (StringUtils.isNotBlank(month)) {
+			sql.append(" DATE_FORMAT( c.created, \"%Y-%m\" ) = ?");
+			params.add(month);
+		}
+
+		sql.append(" group by c.id");
+		sql.append(" ORDER BY c.created DESC");
+
+		String select = "select c.*";
+		if (params.isEmpty()) {
+			return DAO.paginate(page, pagesize, true, select, sql.toString());
+		}
+
+		return DAO.paginate(page, pagesize, true, select, sql.toString(), params.toArray());
+	}
+
 	public Page<Content> paginateInNormal(int page, int pagesize, String module, BigInteger[] taxonomyIds,
 	public Page<Content> paginateInNormal(int page, int pagesize, String module, BigInteger[] taxonomyIds,
 										  String orderBy) {
 										  String orderBy) {
 
 
@@ -244,6 +307,88 @@ public class ContentQuery extends JBaseQuery {
 		return DAO.paginate(page, pagesize, true, select, sql.toString(), params.toArray());
 		return DAO.paginate(page, pagesize, true, select, sql.toString(), params.toArray());
 	}
 	}
 
 
+	public Page<Content> uuHelperPaginate(int page, int pagesize, String[] modules, String keyword,
+										  String pushTime, String author, String copyRight, String taxonomy,
+										  String status, BigInteger[] taxonomyIds, BigInteger userId, String month, String orderBy) {
+
+		String[] texts = null;
+		// 关键词处理
+		if (keyword != null) {
+			texts = keyword.split(" ");
+		}
+
+		String select = "select c.*";
+
+		StringBuilder sql = new StringBuilder(" from content c");
+		sql.append(" left join mapping m on c.id = m.`content_id`");
+		sql.append(" left join taxonomy  t on  m.`taxonomy_id` = t.id");
+
+		//连接元数据表
+		sql.append(" left join metadata d on c.id = d.`object_id`");
+		//uuhelper元数据过滤时用
+		sql.append(" left join metadata d1 on c.id = d1.`object_id`");
+
+		LinkedList<Object> params = new LinkedList<Object>();
+
+		boolean needWhere = true;
+		needWhere = appendIfNotEmpty(sql, "c.module", modules, params, needWhere);
+		needWhere = appendIfNotEmpty(sql, "c.status", status, params, needWhere);
+		needWhere = appendIfNotEmpty(sql, "c.user_id", userId, params, needWhere);
+
+		//uuhelper过滤筛选
+		if (StringUtils.isNotBlank(pushTime)) {
+			needWhere = appendIfNotEmpty(sql, "d.meta_key", "push_time", params, needWhere);
+			needWhere = appendIfNotEmpty(sql, "d.meta_value", pushTime, params, needWhere);
+		}
+		if (StringUtils.isNotBlank(copyRight)) {
+			needWhere = appendIfNotEmpty(sql, "d1.meta_key", "copy_right", params, needWhere);
+			needWhere = appendIfNotEmpty(sql, "d1.meta_value", copyRight, params, needWhere);
+		}
+		if (StringUtils.isNotBlank(author)) {
+			needWhere = appendIfNotEmpty(sql, "c.author", author, params, needWhere);
+		}
+		if (StringUtils.isNotBlank(taxonomy)) {
+			needWhere = appendIfNotEmpty(sql, "t.title", taxonomy, params, needWhere);
+		}
+
+		// 比对
+		if (null != texts) {
+			for (String key : texts) {
+				if (StringUtils.isNotBlank(key)) {
+					needWhere = appendWhereOrAnd(sql, needWhere);
+					sql.append(" (c.title like ? ");
+					params.add("%" + key + "%");
+					sql.append(" or c.text like ? ");
+					params.add("%" + key + "%");
+					sql.append(" or c.summary like ? )");
+					params.add("%" + key + "%");
+				}
+			}
+		}
+		sql.append(" and c.text is not null ");
+
+		if (taxonomyIds != null && taxonomyIds.length > 0) {
+			needWhere = appendWhereOrAnd(sql, needWhere);
+			sql.append(" t.id in " + toString(taxonomyIds));
+		}
+
+		if (StringUtils.isNotBlank(month)) {
+			needWhere = appendWhereOrAnd(sql, needWhere);
+			sql.append(" DATE_FORMAT( c.created, \"%Y-%m\" ) = ?");
+			params.add(month);
+		}
+
+		sql.append(" group by c.id");
+
+		buildOrderBy(orderBy, sql);
+
+		if (params.isEmpty()) {
+			return DAO.paginate(page, pagesize, true, select, sql.toString());
+		}
+
+		return DAO.paginate(page, pagesize, true, select, sql.toString(), params.toArray());
+	}
+
 	protected String toString(Object[] a) {
 	protected String toString(Object[] a) {
 		int iMax = a.length - 1;
 		int iMax = a.length - 1;
 		StringBuilder b = new StringBuilder();
 		StringBuilder b = new StringBuilder();
@@ -760,4 +905,8 @@ public class ContentQuery extends JBaseQuery {
 		return datas;
 		return datas;
 	}
 	}
 
 
+	public List<Content> findAuthorByModule(String module) {
+		return DAO.find("SELECT DISTINCT author from content WHERE module='" +module+ "'");
+	}
+
 }
 }

+ 8 - 2
jpress-model/src/main/java/io/jpress/model/query/MetaDataQuery.java

@@ -15,11 +15,11 @@
  */
  */
 package io.jpress.model.query;
 package io.jpress.model.query;
 
 
+import io.jpress.model.Metadata;
+
 import java.math.BigInteger;
 import java.math.BigInteger;
 import java.util.List;
 import java.util.List;
 
 
-import io.jpress.model.Metadata;
-
 public class MetaDataQuery extends JBaseQuery {
 public class MetaDataQuery extends JBaseQuery {
 
 
 	protected static final Metadata DAO = new Metadata();
 	protected static final Metadata DAO = new Metadata();
@@ -51,4 +51,10 @@ public class MetaDataQuery extends JBaseQuery {
 				"object_type = ? and object_id = ? and meta_key = ? ", type, id, key);
 				"object_type = ? and object_id = ? and meta_key = ? ", type, id, key);
 
 
 	}
 	}
+
+	public List<Metadata> findListByModuleAndKey(String module, String key) {
+		return DAO.find("SELECT DISTINCT m.meta_value from metadata m LEFT JOIN content c on m.object_id=c.id\n" +
+				"where m.meta_key= '" +key+ "' and c.module= '" +module+ "' order by m.meta_value desc;");
+
+	}
 }
 }

+ 10 - 6
jpress-model/src/main/java/io/jpress/model/query/TaxonomyQuery.java

@@ -15,18 +15,17 @@
  */
  */
 package io.jpress.model.query;
 package io.jpress.model.query;
 
 
-import java.math.BigInteger;
-import java.util.ArrayList;
-import java.util.LinkedList;
-import java.util.List;
-
 import com.jfinal.plugin.activerecord.Page;
 import com.jfinal.plugin.activerecord.Page;
 import com.jfinal.plugin.ehcache.IDataLoader;
 import com.jfinal.plugin.ehcache.IDataLoader;
-
 import io.jpress.model.ModelSorter;
 import io.jpress.model.ModelSorter;
 import io.jpress.model.Taxonomy;
 import io.jpress.model.Taxonomy;
 import io.jpress.utils.StringUtils;
 import io.jpress.utils.StringUtils;
 
 
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+
 public class TaxonomyQuery extends JBaseQuery {
 public class TaxonomyQuery extends JBaseQuery {
 
 
 	protected static final Taxonomy DAO = new Taxonomy();
 	protected static final Taxonomy DAO = new Taxonomy();
@@ -217,4 +216,9 @@ public class TaxonomyQuery extends JBaseQuery {
 		return keyBuffer.toString().replace(" ", "");
 		return keyBuffer.toString().replace(" ", "");
 	}
 	}
 
 
+	public List<Taxonomy> findTagsByModule(String module) {
+		return DAO.find("SELECT DISTINCT title from taxonomy WHERE type='tag' and content_module='" +module+ "'");
+
+	}
+
 }
 }

+ 74 - 0
jpress-model/src/main/java/io/jpress/model/query/VoteQuery.java

@@ -0,0 +1,74 @@
+/**
+ * Copyright (c) 2015-2016, Michael Yang 杨福海 (fuhai999@gmail.com).
+ *
+ * Licensed under the GNU Lesser General Public License (LGPL) ,Version 3.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.gnu.org/licenses/lgpl-3.0.txt
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.jpress.model.query;
+
+import io.jpress.model.Vote;
+
+import java.math.BigInteger;
+import java.util.List;
+
+public class VoteQuery extends JBaseQuery {
+
+	protected static final Vote DAO = new Vote();
+	private static final VoteQuery QUERY = new VoteQuery();
+
+	public static VoteQuery me() {
+		return QUERY;
+	}
+
+	public long findCountByCommentId(BigInteger commentId) {
+		return DAO.doFindCount("comment_id = ? and up=1", commentId);
+	}
+
+	public Vote findCommentVote(BigInteger commentId, BigInteger userId, BigInteger uuUserId){
+		List<Vote> list = DAO.doFind("comment_id = ? and (user_id = ? or uu_user_id = ?)", commentId, userId, uuUserId);
+		Vote vote = null;
+		if (list.size() > 0) {
+			vote = list.get(0);
+		}
+
+		return vote;
+	}
+
+	public Vote findContentVote(BigInteger contentId, BigInteger userId, BigInteger uuUserId){
+		List<Vote> list = DAO.doFind("content_id = ? and (user_id = ? or uu_user_id = ?)", contentId, userId, uuUserId);
+		Vote vote = null;
+		if (list.size() > 0) {
+			vote = list.get(0);
+		}
+
+		return vote;
+	}
+
+	public boolean findCommentCountVote(BigInteger commentId, BigInteger userId, BigInteger uuUserId){
+		long count = DAO.doFindCount("comment_id = ? and (user_id = ? or uu_user_id = ?) and up=1 ", commentId, userId, uuUserId);
+		if (count > 0) {
+			return true;
+		}
+
+		return false;
+	}
+
+	public boolean findContentCountVote(BigInteger contentId, BigInteger userId, BigInteger uuUserId){
+		long count = DAO.doFindCount("content_id = ? and (user_id = ? or uu_user_id = ?) and up=1 ", contentId, userId, uuUserId);
+		if (count > 0) {
+			return true;
+		}
+
+		return false;
+	}
+
+}

+ 49 - 8
jpress-web-admin/src/main/java/io/jpress/admin/controller/_CommentController.java

@@ -15,12 +15,8 @@
  */
  */
 package io.jpress.admin.controller;
 package io.jpress.admin.controller;
 
 
-import java.math.BigInteger;
-import java.util.Date;
-
 import com.jfinal.aop.Before;
 import com.jfinal.aop.Before;
 import com.jfinal.plugin.activerecord.Page;
 import com.jfinal.plugin.activerecord.Page;
-
 import io.jpress.core.JBaseCRUDController;
 import io.jpress.core.JBaseCRUDController;
 import io.jpress.core.interceptor.ActionCacheClearInterceptor;
 import io.jpress.core.interceptor.ActionCacheClearInterceptor;
 import io.jpress.interceptor.UCodeInterceptor;
 import io.jpress.interceptor.UCodeInterceptor;
@@ -35,6 +31,9 @@ import io.jpress.template.TemplateManager;
 import io.jpress.utils.JsoupUtils;
 import io.jpress.utils.JsoupUtils;
 import io.jpress.utils.StringUtils;
 import io.jpress.utils.StringUtils;
 
 
+import java.math.BigInteger;
+import java.util.Date;
+
 @RouterMapping(url = "/admin/comment", viewPath = "/WEB-INF/admin/comment")
 @RouterMapping(url = "/admin/comment", viewPath = "/WEB-INF/admin/comment")
 @Before(ActionCacheClearInterceptor.class)
 @Before(ActionCacheClearInterceptor.class)
 @RouterNotAllowConvert
 @RouterNotAllowConvert
@@ -48,16 +47,29 @@ public class _CommentController extends JBaseCRUDController<Comment> {
 		return getPara("t");
 		return getPara("t");
 	}
 	}
 
 
+	private boolean getSon() {
+		return Boolean.parseBoolean(getPara("son"));
+	}
+
 	@Override
 	@Override
 	public void index() {
 	public void index() {
 
 
 		keepPara();
 		keepPara();
 
 
 		setAttr("module", TemplateManager.me().currentTemplateModule(getModule()));
 		setAttr("module", TemplateManager.me().currentTemplateModule(getModule()));
-		setAttr("delete_count", CommentQuery.me().findCountByModuleAndStatus(getModule(), Comment.STATUS_DELETE));
-		setAttr("draft_count", CommentQuery.me().findCountByModuleAndStatus(getModule(), Comment.STATUS_DRAFT));
-		setAttr("normal_count", CommentQuery.me().findCountByModuleAndStatus(getModule(), Comment.STATUS_NORMAL));
-		setAttr("count", CommentQuery.me().findCountInNormalByModule(getModule()));
+
+		if ("uuhelper".equals(getModule())) {
+			setAttr("answered_count", CommentQuery.me().findCountByModuleAndSonAndContentId(getParaToBigInteger("cid"), getModule(), true));
+			setAttr("unanswered_count", CommentQuery.me().findCountByModuleAndSonAndContentId(getParaToBigInteger("cid"), getModule(), false));
+			setAttr("draft_count", CommentQuery.me().findCountByModuleAndStatusAndContentId(getParaToBigInteger("cid"), getModule(), Comment.STATUS_DRAFT));
+			setAttr("normal_count", CommentQuery.me().findCountByModuleAndStatusAndContentId(getParaToBigInteger("cid"), getModule(), Comment.STATUS_NORMAL));
+			setAttr("delete_count", CommentQuery.me().findCountByModuleAndStatusAndContentId(getParaToBigInteger("cid"), getModule(), Comment.STATUS_DELETE));
+		} else {
+			setAttr("delete_count", CommentQuery.me().findCountByModuleAndStatus(getModule(), Comment.STATUS_DELETE));
+			setAttr("draft_count", CommentQuery.me().findCountByModuleAndStatus(getModule(), Comment.STATUS_DRAFT));
+			setAttr("normal_count", CommentQuery.me().findCountByModuleAndStatus(getModule(), Comment.STATUS_NORMAL));
+			setAttr("count", CommentQuery.me().findCountInNormalByModule(getModule()));
+		}
 
 
 		super.index();
 		super.index();
 	}
 	}
@@ -71,6 +83,9 @@ public class _CommentController extends JBaseCRUDController<Comment> {
 		if (StringUtils.isNotBlank(getPara("s"))) {
 		if (StringUtils.isNotBlank(getPara("s"))) {
 			return CommentQuery.me().paginateWithContent(pageNumber, pageSize, getModule(), getType(), contentId,
 			return CommentQuery.me().paginateWithContent(pageNumber, pageSize, getModule(), getType(), contentId,
 					parentCommentId, getPara("s"));
 					parentCommentId, getPara("s"));
+		} else if (StringUtils.isNotBlank(getPara("son"))) {
+			return CommentQuery.me().paginateWithContentAndSon(pageNumber, pageSize, getModule(), getType(), contentId,
+					parentCommentId,getSon());
 		}
 		}
 		return CommentQuery.me().paginateWithContentNotInDelete(pageNumber, pageSize, getModule(), getType(), contentId,
 		return CommentQuery.me().paginateWithContentNotInDelete(pageNumber, pageSize, getModule(), getType(), contentId,
 				parentCommentId);
 				parentCommentId);
@@ -203,4 +218,30 @@ public class _CommentController extends JBaseCRUDController<Comment> {
 		comment.save();
 		comment.save();
 		renderAjaxResultForSuccess();
 		renderAjaxResultForSuccess();
 	}
 	}
+
+	@Before(UCodeInterceptor.class)
+	public void changeCommentTopSataus() {
+		BigInteger id = getParaToBigInteger("id");
+		Comment c = CommentQuery.me().findById(id);
+		String commentTopStatus = getPara("commentTopStatus");
+		if (c != null) {
+
+			if ("top".equals(commentTopStatus)) {
+				c.setOrderNumber(Long.parseLong("1"));
+			} else {
+				c.setOrderNumber(Long.parseLong("0"));
+			}
+
+			if (c.saveOrUpdate()) {
+				renderAjaxResultForSuccess("success");
+			} else {
+				renderAjaxResultForError("restore error!");
+			}
+		} else {
+			renderAjaxResultForError("restore error!");
+		}
+	}
+
+
+
 }
 }

+ 187 - 22
jpress-web-admin/src/main/java/io/jpress/admin/controller/_ContentController.java

@@ -15,20 +15,11 @@
  */
  */
 package io.jpress.admin.controller;
 package io.jpress.admin.controller;
 
 
-import java.math.BigInteger;
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
+import com.alibaba.fastjson.JSONObject;
 import com.jfinal.aop.Before;
 import com.jfinal.aop.Before;
 import com.jfinal.plugin.activerecord.Db;
 import com.jfinal.plugin.activerecord.Db;
 import com.jfinal.plugin.activerecord.IAtom;
 import com.jfinal.plugin.activerecord.IAtom;
 import com.jfinal.plugin.activerecord.Page;
 import com.jfinal.plugin.activerecord.Page;
-
 import io.jpress.Consts;
 import io.jpress.Consts;
 import io.jpress.core.JBaseCRUDController;
 import io.jpress.core.JBaseCRUDController;
 import io.jpress.core.interceptor.ActionCacheClearInterceptor;
 import io.jpress.core.interceptor.ActionCacheClearInterceptor;
@@ -36,22 +27,23 @@ import io.jpress.core.render.AjaxResult;
 import io.jpress.interceptor.UCodeInterceptor;
 import io.jpress.interceptor.UCodeInterceptor;
 import io.jpress.message.Actions;
 import io.jpress.message.Actions;
 import io.jpress.message.MessageKit;
 import io.jpress.message.MessageKit;
-import io.jpress.model.Content;
-import io.jpress.model.Taxonomy;
-import io.jpress.model.User;
-import io.jpress.model.query.ContentQuery;
-import io.jpress.model.query.MappingQuery;
-import io.jpress.model.query.TaxonomyQuery;
-import io.jpress.model.query.UserQuery;
+import io.jpress.model.*;
+import io.jpress.model.query.*;
 import io.jpress.model.router.ContentRouter;
 import io.jpress.model.router.ContentRouter;
 import io.jpress.router.RouterMapping;
 import io.jpress.router.RouterMapping;
 import io.jpress.router.RouterNotAllowConvert;
 import io.jpress.router.RouterNotAllowConvert;
 import io.jpress.template.TemplateManager;
 import io.jpress.template.TemplateManager;
 import io.jpress.template.TplModule;
 import io.jpress.template.TplModule;
 import io.jpress.template.TplTaxonomyType;
 import io.jpress.template.TplTaxonomyType;
+import io.jpress.utils.HttpUtils;
 import io.jpress.utils.JsoupUtils;
 import io.jpress.utils.JsoupUtils;
 import io.jpress.utils.StringUtils;
 import io.jpress.utils.StringUtils;
 
 
+import java.math.BigInteger;
+import java.sql.SQLException;
+import java.text.SimpleDateFormat;
+import java.util.*;
+
 @RouterMapping(url = "/admin/content", viewPath = "/WEB-INF/admin/content")
 @RouterMapping(url = "/admin/content", viewPath = "/WEB-INF/admin/content")
 @Before(ActionCacheClearInterceptor.class)
 @Before(ActionCacheClearInterceptor.class)
 @RouterNotAllowConvert
 @RouterNotAllowConvert
@@ -65,9 +57,24 @@ public class _ContentController extends JBaseCRUDController<Content> {
 		return getPara("s");
 		return getPara("s");
 	}
 	}
 
 
+	private String getPushTime() {
+		return getPara("pushTime");
+	}
+
+	private String getAuthor() {
+		return getPara("author");
+	}
+
+	private String getCopyRight() {
+		return getPara("copyRight");
+	}
+
+	private String getTaxonomy() {
+		return getPara("taxonomy");
+	}
+
 	@Override
 	@Override
 	public void index() {
 	public void index() {
-
 		TplModule module = TemplateManager.me().currentTemplateModule(getModuleName());
 		TplModule module = TemplateManager.me().currentTemplateModule(getModuleName());
 		setAttr("module", module);
 		setAttr("module", module);
 		setAttr("delete_count", ContentQuery.me().findCountByModuleAndStatus(getModuleName(), Content.STATUS_DELETE));
 		setAttr("delete_count", ContentQuery.me().findCountByModuleAndStatus(getModuleName(), Content.STATUS_DELETE));
@@ -75,6 +82,18 @@ public class _ContentController extends JBaseCRUDController<Content> {
 		setAttr("normal_count", ContentQuery.me().findCountByModuleAndStatus(getModuleName(), Content.STATUS_NORMAL));
 		setAttr("normal_count", ContentQuery.me().findCountByModuleAndStatus(getModuleName(), Content.STATUS_NORMAL));
 		setAttr("count", ContentQuery.me().findCountInNormalByModule(getModuleName()));
 		setAttr("count", ContentQuery.me().findCountInNormalByModule(getModuleName()));
 
 
+		if ("uuhelper".equals(getModuleName())) {
+			setAttr("push_time_list",getMetaDatas("push_time"));
+			setAttr("copy_right_list",getMetaDatas("copy_right"));
+			setAttr("author_list",getAuthors());
+			setAttr("tag_list",getTags());
+
+			setAttr("defaultPushTime",getPushTime());
+			setAttr("defaultAuthor",getAuthor());
+			setAttr("defaultCopyRight",getCopyRight());
+			setAttr("defaultTaxonomy",getTaxonomy());
+		}
+
 		setAttr("tids", getPara("tids"));
 		setAttr("tids", getPara("tids"));
 		BigInteger[] tids = null;
 		BigInteger[] tids = null;
 		String[] tidStrings = getPara("tids", "").split(",");
 		String[] tidStrings = getPara("tids", "").split(",");
@@ -91,11 +110,23 @@ public class _ContentController extends JBaseCRUDController<Content> {
 
 
 		Page<Content> page = null;
 		Page<Content> page = null;
 		if (StringUtils.isNotBlank(getStatus())) {
 		if (StringUtils.isNotBlank(getStatus())) {
-			page = ContentQuery.me().paginateBySearch(getPageNumber(), getPageSize(), getModuleName(), keyword,
-					getStatus(), tids, null);
+            if ("uuhelper".equals(getModuleName())) {
+                page = ContentQuery.me().uuHelperPaginateBySearch(getPageNumber(), getPageSize(), getModuleName(), keyword,
+                        getPushTime(), getAuthor(), getCopyRight(), getTaxonomy(),
+                        getStatus(), tids, null);
+            } else {
+                page = ContentQuery.me().paginateBySearch(getPageNumber(), getPageSize(), getModuleName(), keyword,
+                        getStatus(), tids, null);
+            }
 		} else {
 		} else {
-			page = ContentQuery.me().paginateByModuleNotInDelete(getPageNumber(), getPageSize(), getModuleName(),
-					keyword, tids, null);
+            if ("uuhelper".equals(getModuleName())) {
+                page = ContentQuery.me().uuHelperPaginateByModuleNotInDelete(getPageNumber(), getPageSize(), getModuleName(),
+						keyword, getPushTime(), getAuthor(), getCopyRight(), getTaxonomy(),
+                        tids, null);
+            } else {
+                page = ContentQuery.me().paginateByModuleNotInDelete(getPageNumber(), getPageSize(), getModuleName(),
+                        keyword, tids, null);
+            }
 		}
 		}
 
 
 		filterUI(tids);
 		filterUI(tids);
@@ -427,17 +458,63 @@ public class _ContentController extends JBaseCRUDController<Content> {
 			return;
 			return;
 		}
 		}
 
 
+		if ("uuhelper".equals(content.getModule()) && Content.STATUS_NORMAL.equals(content.getStatus())) {
+			pushUuHelper(content);
+		}
+
 		AjaxResult ar = new AjaxResult();
 		AjaxResult ar = new AjaxResult();
 		ar.setErrorCode(0);
 		ar.setErrorCode(0);
 		ar.setData(content.getId());
 		ar.setData(content.getId());
 		renderAjaxResult("save ok", 0, content.getId());
 		renderAjaxResult("save ok", 0, content.getId());
 	}
 	}
 
 
+	private void pushUuHelper(Content content) {
+		Map<String, String> map = new HashMap<>();
+		String requestUrlMessage = this.getRequest().getScheme() +"://" + this.getRequest().getServerName() + ":" + this.getRequest().getServerPort();
+		JSONObject bodyJO = new JSONObject(true);
+		bodyJO.put("content", content.getTitle());
+		bodyJO.put("fromUserId", "10000");
+		bodyJO.put("fromUserName", "系统消息");
+		bodyJO.put("type", 1);
+		bodyJO.put("timeSend", "");
+		String imageUrl = requestUrlMessage + content.getThumbnail();
+		String iconUrl = requestUrlMessage + content.getThumbnail();
+		String linkUrl = requestUrlMessage + content.getUrl();
+		if (content.getThumbnail() == null) {
+			imageUrl = null;
+		}
+		if (content.getThumbnail() == null) {
+			iconUrl = null;
+		}
+		if (content.getUrl() == null) {
+			linkUrl = null;
+		}
+
+		bodyJO.put("imageUrl", imageUrl);
+		bodyJO.put("iconUrl", iconUrl);
+		bodyJO.put("linkUrl", linkUrl);
+		String body = bodyJO.toString();
+		String url = "http://113.105.74.140:8092/user/pushToAll?fromUserId=10000&body="+body;
+
+		try {
+			String response = HttpUtils.post(url);
+			System.out.println(response);
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+	}
+
 	private Content getContent() {
 	private Content getContent() {
 		Content content = getModel(Content.class);
 		Content content = getModel(Content.class);
 
 
 		content.setText(JsoupUtils.getBodyHtml(content.getText()));
 		content.setText(JsoupUtils.getBodyHtml(content.getText()));
 
 
+		if (content.getCommentStatus() == null) {
+			content.setCommentStatus(Content.COMMENT_STATUS_CLOSE);
+		} else {
+			content.setCommentStatus(content.getCommentStatus());
+		}
+
 		if (content.getCreated() == null) {
 		if (content.getCreated() == null) {
 			content.setCreated(new Date());
 			content.setCreated(new Date());
 		}
 		}
@@ -449,4 +526,92 @@ public class _ContentController extends JBaseCRUDController<Content> {
 		return content;
 		return content;
 	}
 	}
 
 
+	//切换开启评论状态(uuhelper)
+	@Before(UCodeInterceptor.class)
+	public void changeCommentSataus() {
+		Content c = ContentQuery.me().findById(getParaToBigInteger("id"));
+		String commentStatus = getPara("commentStatus");
+		if (c != null) {
+			c.setCommentStatus(commentStatus);
+			c.saveOrUpdate();
+			renderAjaxResultForSuccess("success");
+		} else {
+			renderAjaxResultForError("change comment status error!");
+		}
+	}
+
+	//uuhelper后台软文列表页筛选项获取所有元数据
+	private List<String> getMetaDatas(String metaKey) {
+		List<String> metaValues = new ArrayList<String>();
+		List<Metadata> metaDatas = new ArrayList<Metadata>();
+		metaDatas = MetaDataQuery.me().findListByModuleAndKey(getModuleName(), metaKey);
+		for (int i = 0; i < metaDatas.size(); i++) {
+			metaValues.add(metaDatas.get(i).getMetaValue());
+		}
+		return metaValues;
+	}
+
+	//uuhelper后台软文列表页筛选项获取所有作者
+	private List<String> getAuthors() {
+		List<String> authors = new ArrayList<String>();
+		List<Content> contents = new ArrayList<Content>();
+		contents = ContentQuery.me().findAuthorByModule(getModuleName());
+		for (int i = 0; i < contents.size(); i++) {
+			authors.add(contents.get(i).getAuthor());
+		}
+		return authors;
+	}
+
+	//uuhelper后台软文列表页筛选项获取所有类别(即所有tag标签)
+	private List<String> getTags() {
+		List<String> tags = new ArrayList<String>();
+		List<Taxonomy> taxonomys = new ArrayList<Taxonomy>();
+		taxonomys = TaxonomyQuery.me().findTagsByModule(getModuleName());
+		for (int i = 0; i < taxonomys.size(); i++) {
+			tags.add(taxonomys.get(i).getTitle());
+		}
+		return tags;
+	}
+
+	@Before(UCodeInterceptor.class)
+	public void lazyLoad() {
+		String[] modules = new String[1];
+		modules[0] = getPara("module");
+
+		//findListInNormal 的page参数并非页数,只是行数。未改其方法源码,本人在此处直接作乘pagesize处理
+		List<Content> list = ContentQuery.me().findListInNormal(((getParaToInt("pagenumber")-1)*getParaToInt("pagesize"))+1, getParaToInt("pagesize"), getPara("orderBy"), null, null, null, modules, null, null, null, null, null, null, null, null);
+		StringBuilder htmlBuilder = new StringBuilder();
+		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+		for (int i=0; i < list.size(); i++) {
+			Content content = list.get(i);
+			String pushTime = content.getMetadataByKey("push_time");
+			if (pushTime == null) {
+				pushTime = "";
+			}
+			htmlBuilder.append("<tr>\n" +
+									"<td class=\"messageTitle\">"+ content.getTitle() +"</td>\n" +
+									"<td class=\"messageTime\">"+ pushTime + "</td>");
+				htmlBuilder.append(" <td class=\"isOpenMessage\">\n" +
+										"<select id=\"commentStatus"+content.getId()+"\" onchange=\"changeCommentSataus"+content.getId()+"\">");
+					if (StringUtils.isNotBlank(content.getCommentStatus()) && "close".equals(content.getCommentStatus())) {
+						htmlBuilder.append("<option value=\"close\" selected=\"selected\">关闭</option>");
+					} else {
+						htmlBuilder.append("<option value=\"close\">关闭</option>");
+					}
+
+					if (StringUtils.isNotBlank(content.getCommentStatus()) && "open".equals(content.getCommentStatus())) {
+						htmlBuilder.append("<option value=\"open\" selected=\"selected\">开启</option>");
+					} else {
+						htmlBuilder.append("option value=\"open\">开启</option>");
+					}
+					htmlBuilder.append("</select>\n" +
+									"</td>\n" +
+									"<td class=\"handleMessage\">\n" +
+										"<a class=\"replay\" href=\""+ getPara("CPATH") +"/admin/comment?t=comment&m=uuhelper&p=uuhelper&c=comment&cid="+ content.getId() +"&way=detail\">查看</a>\n" +
+									"</td>\n" +
+								"</tr>");
+		}
+		renderAjaxResultForSuccess(htmlBuilder.toString());
+	}
+
 }
 }

+ 29 - 3
jpress-web-admin/src/main/webapp/WEB-INF/admin/attachment/choose_layer.html

@@ -25,6 +25,8 @@ $(document).ready(function(){
     $(this).parent().addClass("jp-borwer-active-li");
     $(this).parent().addClass("jp-borwer-active-li");
     $(this).next().show();
     $(this).next().show();
   });
   });
+
+    $('.jp-grids-photos').imgAreaSelect({ maxWidth: 200, maxHeight: 170, handles: true });
 });
 });
 
 
 $('#fine-uploader-gallery').fineUploader({
 $('#fine-uploader-gallery').fineUploader({
@@ -47,15 +49,30 @@ $('#fine-uploader-gallery').fineUploader({
 </#macro> 
 </#macro> 
 <#macro script_import>
 <#macro script_import>
 <script src="${CPATH}/static/plugins/fine-uploader/jquery.fine-uploader.js"></script>
 <script src="${CPATH}/static/plugins/fine-uploader/jquery.fine-uploader.js"></script>
+<script src="${CTPATH}/assets/js/jquery.imgareaselect.pack.js"></script>
 </#macro>
 </#macro>
 <#macro css_import>
 <#macro css_import>
 <link href="${CPATH}/static/plugins/fine-uploader/fine-uploader-new.css" rel="stylesheet">
 <link href="${CPATH}/static/plugins/fine-uploader/fine-uploader-new.css" rel="stylesheet">
+<link rel="stylesheet" type="text/css" href="${CTPATH}/assets/css/imgareaselect-default.css"/>
 </#macro>
 </#macro>
 <#macro css>
 <#macro css>
 .list-inline>li {
 .list-inline>li {
     display: inline-block;
     display: inline-block;
     padding: 3px;
     padding: 3px;
 }
 }
+    .list-items li button{
+    display: none;
+    cursor: pointer;
+    width: 50px;
+    height: 25px;
+    line-height: 25px;
+    text-align: center;
+    border: none;
+    border-radius: 5px;
+    }
+    .list-items li:hover button{
+    display: block;
+    }
 </#macro>
 </#macro>
 <@layout >
 <@layout >
 <div class="row">
 <div class="row">
@@ -80,11 +97,17 @@ $('#fine-uploader-gallery').fineUploader({
 					</div>
 					</div>
 
 
 				</div>
 				</div>
-
-
 				<div class="tab-pane active" id="tab_2">
 				<div class="tab-pane active" id="tab_2">
 					<div class="jp-borwer">
 					<div class="jp-borwer">
-							<ul class="list-inline list-unstyled">
+                        <form action="${CPATH}/admin/attachment/doUpload" method="post">
+                            <input type="hidden" name="x1" value="" />
+                            <input type="hidden" name="y1" value="" />
+                            <input type="hidden" name="x2" value="" />
+                            <input type="hidden" name="y2" value="" />
+                            <input type="hidden" name="sourceId" value="" />
+                            <!--<input type="submit" name="submit" value="截取" />-->
+
+							<ul class="list-inline list-unstyled list-items">
 								<#if page??> 
 								<#if page??> 
 								<#list page.getList() as bean>
 								<#list page.getList() as bean>
 								<li>
 								<li>
@@ -96,10 +119,12 @@ $('#fine-uploader-gallery').fineUploader({
 									<div class="brower-active-icon" style="display: none">
 									<div class="brower-active-icon" style="display: none">
 										<i class="fa fa-check-square-o fa-2x" aria-hidden="true"></i>
 										<i class="fa fa-check-square-o fa-2x" aria-hidden="true"></i>
 									</div>
 									</div>
+                                    <button>确定</button>
 								</li>
 								</li>
 								</#list>
 								</#list>
 								</#if>
 								</#if>
 							</ul>
 							</ul>
+                        </form>
 					</div>
 					</div>
 					<#include "../_inc/_paginate_wrapper.html" />
 					<#include "../_inc/_paginate_wrapper.html" />
 				</div>
 				</div>
@@ -107,6 +132,7 @@ $('#fine-uploader-gallery').fineUploader({
 		</div>
 		</div>
 	</div>
 	</div>
 </div>
 </div>
+
 <button class="btn btn-block btn-primary jp-submiti-button" onclick="doConfirm()"> 确&nbsp;定 </button>
 <button class="btn btn-block btn-primary jp-submiti-button" onclick="doConfirm()"> 确&nbsp;定 </button>
 <script type="text/template" id="qq-template-gallery">
 <script type="text/template" id="qq-template-gallery">
         <div class="qq-uploader-selector qq-uploader qq-gallery" qq-drop-area-text="或拖动文件到此上传">
         <div class="qq-uploader-selector qq-uploader qq-gallery" qq-drop-area-text="或拖动文件到此上传">

+ 231 - 133
jpress-web-admin/src/main/webapp/WEB-INF/admin/comment/index.html

@@ -1,5 +1,55 @@
 <#include "../_inc/_layout.html"/> 
 <#include "../_inc/_layout.html"/> 
 <#macro script>
 <#macro script>
+function changeCommentSataus(id) {
+	var commentStatusObj = $("#commentStatus"+id);
+	var commentStatus = commentStatusObj.find("option:selected").val();
+
+	$.get("${CPATH}/admin/content/changeCommentSataus?ucode=${ucode}&id="+id+"&commentStatus="+commentStatus, function(result){
+		if(result.errorCode > 0){
+			alert(result.message);
+		}else{
+			location.reload();
+		}
+	});
+}
+
+function changePage(flag) {
+	var comment = $('.commentManage');
+	var group = $('.groupManage');
+	var pageChange = $('.pageChange');
+	if (flag == 0 && !comment.hasClass("active")) {
+		comment.addClass("active");
+		group.removeClass("active");
+	} else if (flag == 1 && !group.hasClass("active")) {
+		group.addClass("active");
+		comment.removeClass("active");
+	}
+}
+
+function showMessageSelect(id) {
+	var isShowMessageSelect = $("#isShowMessageSelect"+id);
+	var showStatus = isShowMessageSelect.find("option:selected").val();
+	if (showStatus == "normal") {
+		pub(id);
+	} else if (showStatus == "draft") {
+        draft(id);
+	}
+}
+
+function topSelect(id) {
+	var topSelectObj = $("#isTopSelect"+id);
+	var commentTopStatus = topSelectObj.find("option:selected").val();
+
+	$.get("${CPATH}/admin/comment/changeCommentTopSataus?ucode=${ucode}&id="+id+"&commentTopStatus="+commentTopStatus, function(result){
+		if(result.errorCode > 0){
+			alert(result.message);
+		}else{
+			location.reload();
+		}
+	});
+}
+
+
 function trash(id){
 function trash(id){
 	$.get("${CPATH}/admin/comment/trash?ucode=${ucode}&id="+id, function(result){
 	$.get("${CPATH}/admin/comment/trash?ucode=${ucode}&id="+id, function(result){
 		if(result.errorCode > 0){
 		if(result.errorCode > 0){
@@ -65,147 +115,195 @@ function reply(id){
  
  
  }
  }
  
  
-</#macro> 
+</#macro>
+<style>
+	.navUas{
+		margin-top: 20px;
+		color: #333;
+		font-size: 18px;
+		border-bottom: 1px solid #d9d2de;
+	}
+	.navUas a{
+		display: inline-block;
+		text-align: center;
+		padding-bottom: 50px;
+		width: 120px;
+		height: 40px;
+		line-height: 40px;
+		margin-right: 30px;
+		color: #333;
+	}
+	.navUas a.active,.navUas a:hover{
+		border-bottom: 3px solid #1ba047;
+	}
+
+</style>
 <@layout active_id=p child_active_id=c>
 <@layout active_id=p child_active_id=c>
-<section class="content-header">
-	<h1>所有内容</h1>
-</section>
-
-<!-- Main content -->
-<section class="content">
-	<div class="row content-row">
-		<ul class="list-inline" style="float: left">
-			<li class="all">
-				<a class="current" href="${CPATH}/admin/comment?m=${m!}&p=${p!}&c=${c!}">
-					全部 <span class="count">(${count!"0"})</span>
-				</a>
-				|
-			</li>
-			<li class="publish">
-				<a href="${CPATH}/admin/comment?m=${m!}&p=${p!}&c=${c!}&s=normal">
-					已发布 <span class="count">(${normal_count!"0"})</span>
-				</a>
-				|
-			</li>
-			<li class="publish">
-				<a href="${CPATH}/admin/comment?m=${m!}&p=${p!}&c=${c!}&s=draft">
-					待审核 <span class="count">(${draft_count!"0"})</span>
-				</a>
-				|
-			</li>
-			<li class="trash">
-				<a href="${CPATH}/admin/comment?m=${m!}&p=${p!}&c=${c!}&s=delete">
-					垃圾箱 <span class="count">(${delete_count!"0"})</span>
-				</a>
-			</li>
-		</ul>
-
-
-
-		<form class="form-horizontal" style="float: right">
-			<div class="input-group input-group-sm">
-				<input id="post-search-input" class="form-control  " type="search" value="" name="" placeholder="请输入关键词">&nbsp;&nbsp;
-				<input id="search-submit" class="btn btn-default btn-sm" type="submit" value="搜索">
-			</div>
 
 
-		</form>
-	</div>
-	<div class="row content-row">
-		<div class="jp-left ">
-			<select class="form-control input-sm jp-width120">
-				<option value="10">==批量操作==</option>
-				<option value="25">删除</option>
-				<option value="50">置顶</option>
-			</select>
+<#if module ?? && module.name=="uuhelper">
+	<!-- 留言管理 头页面 -->
+	<section class="content-header">
+		<h1>留言管理</h1>
+	</section>
+	<section class="content-header">
+		<div class="navUas">
+			<a class="commentManage <#if !way?? || (way?? && way == 'comment')>active</#if>" onclick="changePage(0)" href="${CPATH}/admin/comment?t=comment&m=uuhelper&p=uuhelper&c=comment&way=comment">留言管理</a>
+            <a class="groupManage <#if way?? && (way == 'group' || way == 'detail')>active</#if>" onclick="changePage(1)" href="${CPATH}/admin/comment?t=comment&m=uuhelper&p=uuhelper&c=comment&way=group">群发消息管理</a>
 		</div>
 		</div>
-		<div class="jp-left   ">
-			<button class="btn btn-block btn-sm btn-default" type="button">应用</button>
+	</section>
+	<!-- Main content -->
+	<#if way?? && way == "comment">
+		<#include "uuHelperCommentList.html" />
+	<#elseif way?? && way == "group">
+		<#include "uuHelperGroupList.html" />
+	<#elseif way?? && way == "detail">
+		<#include "uuHelperGroupDetail.html" />
+	<#else>
+		<#include "uuHelperCommentList.html" />
+	</#if>
+
+
+<#else>
+	<section class="content-header">
+		<h1>所有内容</h1>
+	</section>
+
+	<!-- Main content -->
+	<section class="content">
+		<div class="row content-row">
+			<ul class="list-inline" style="float: left">
+				<li class="all">
+					<a class="current" href="${CPATH}/admin/comment?m=${m!}&p=${p!}&c=${c!}">
+						全部 <span class="count">(${count!"0"})</span>
+					</a>
+					|
+				</li>
+				<li class="publish">
+					<a href="${CPATH}/admin/comment?m=${m!}&p=${p!}&c=${c!}&s=normal">
+						已发布 <span class="count">(${normal_count!"0"})</span>
+					</a>
+					|
+				</li>
+				<li class="publish">
+					<a href="${CPATH}/admin/comment?m=${m!}&p=${p!}&c=${c!}&s=draft">
+						待审核 <span class="count">(${draft_count!"0"})</span>
+					</a>
+					|
+				</li>
+				<li class="trash">
+					<a href="${CPATH}/admin/comment?m=${m!}&p=${p!}&c=${c!}&s=delete">
+						垃圾箱 <span class="count">(${delete_count!"0"})</span>
+					</a>
+				</li>
+			</ul>
+
+
+
+			<form class="form-horizontal" style="float: right">
+				<div class="input-group input-group-sm">
+					<input id="post-search-input" class="form-control  " type="search" value="" name="" placeholder="请输入关键词">&nbsp;&nbsp;
+					<input id="search-submit" class="btn btn-default btn-sm" type="submit" value="搜索">
+				</div>
+
+			</form>
 		</div>
 		</div>
-	</div>
-
-
-	<div class="box ">
-
-		<!-- /.box-header -->
-		<div class="box-body jp-cancel-pad">
-			<table class="table table-striped">
-				<thead>
-					<tr>
-						<th style="width: 2%"><input name="dataItem" onclick="checkAll(this)" type="checkbox"></th>
-						<th style="width: 10%">作者</th>
-						<th style="width: 33%">内容</th>
-						<th style="width: 15%">回复至</th>
-						<th style="width: 10%"><i class="fa fa-commenting"></i></th>
-						<th style="width: 10%">日期</th>
-					</tr>
-				</thead>
-				<tbody>
-
-					<#if page??> 
-					<#list page.getList() as bean>
-					<tr class="jp-onmouse">
-						<td><input name="dataItem" type="checkbox"></td>
-						<td><a href="${CPATH}/admin/user/edit?id=${bean.user_id!}&c=list&p=user"> ${(bean.user.username)!comment.author!} </a></td>
-						<td><strong><a href="#">
-									<span class="article-title">${bean.text!}</span>
-								</a><#if "draft" == bean.status!>(待审核)</#if>
-								</strong>
-							<div class="jp-flash-comment">
-								<p class="row-actions jp-cancel-pad">
-									<#if "normal" == bean.status!>
-									<span class="approve"><a class="vim-a" href="javascript:reply(${bean.id})">回复</a></span> 
-									<span class="approve">|<a class="vim-a" href="${CPATH}/admin/comment/edit?id=${bean.id!}&p=${(p)!}&c=${(c)!}">编辑</a></span>
-									<span class="spam">|<a class="vim-s vim-destructive" href="javascript:draft(${bean.id})">待审核</a></span>
-									<span class="spam">|<a class="vim-s vim-destructive" href="javascript:trash(${bean.id})">垃圾箱</a></span> 
-									<#elseif "draft" == bean.status!>
-									<span class="approve"><a class="vim-a" href="javascript:reply(${bean.id})">回复</a></span> 
-									<span class="approve">|<a class="vim-a" href="${CPATH}/admin/comment/edit?id=${bean.id!}&p=${(p)!}&c=${(c)!}">编辑</a></span>
-									<span class="spam">|<a class="vim-s vim-destructive" href="javascript:pub(${bean.id})">允许发布</a></span> 
-									<span class="spam">|<a class="vim-s vim-destructive" href="javascript:trash(${bean.id})">垃圾箱</a></span> 
-									<#else>
-									<span class="approve"> <a class="vim-a" href="javascript:restore(${bean.id})">放回草稿</a></span> 
-									<span class="spam">|<a class="vim-s vim-destructive" href="javascript:del(${bean.id})">永久删除</a></span> 
-									</#if>
-								</p>
-							</div>
+		<div class="row content-row">
+			<div class="jp-left ">
+				<select class="form-control input-sm jp-width120">
+					<option value="10">==批量操作==</option>
+					<option value="25">删除</option>
+					<option value="50">置顶</option>
+				</select>
+			</div>
+			<div class="jp-left   ">
+				<button class="btn btn-block btn-sm btn-default" type="button">应用</button>
+			</div>
+		</div>
+
+
+		<div class="box ">
+
+			<!-- /.box-header -->
+			<div class="box-body jp-cancel-pad">
+				<table class="table table-striped">
+					<thead>
+						<tr>
+							<th style="width: 2%"><input name="dataItem" onclick="checkAll(this)" type="checkbox"></th>
+							<th style="width: 10%">作者</th>
+							<th style="width: 33%">内容</th>
+							<th style="width: 15%">回复至</th>
+							<th style="width: 10%"><i class="fa fa-commenting"></i></th>
+							<th style="width: 10%">日期</th>
+						</tr>
+					</thead>
+					<tbody>
+
+						<#if page??>
+						<#list page.getList() as bean>
+						<tr class="jp-onmouse">
+							<td><input name="dataItem" type="checkbox"></td>
+							<td><a href="${CPATH}/admin/user/edit?id=${bean.user_id!}&c=list&p=user"> ${(bean.user.username)!comment.author!} </a></td>
+							<td><strong><a href="#">
+										<span class="article-title">${bean.text!}</span>
+									</a><#if "draft" == bean.status!>(待审核)</#if>
+									</strong>
+								<div class="jp-flash-comment">
+									<p class="row-actions jp-cancel-pad">
+										<#if "normal" == bean.status!>
+										<span class="approve"><a class="vim-a" href="javascript:reply(${bean.id})">回复</a></span>
+										<span class="approve">|<a class="vim-a" href="${CPATH}/admin/comment/edit?id=${bean.id!}&p=${(p)!}&c=${(c)!}">编辑</a></span>
+										<span class="spam">|<a class="vim-s vim-destructive" href="javascript:draft(${bean.id})">待审核</a></span>
+										<span class="spam">|<a class="vim-s vim-destructive" href="javascript:trash(${bean.id})">垃圾箱</a></span>
+										<#elseif "draft" == bean.status!>
+										<span class="approve"><a class="vim-a" href="javascript:reply(${bean.id})">回复</a></span>
+										<span class="approve">|<a class="vim-a" href="${CPATH}/admin/comment/edit?id=${bean.id!}&p=${(p)!}&c=${(c)!}">编辑</a></span>
+										<span class="spam">|<a class="vim-s vim-destructive" href="javascript:pub(${bean.id})">允许发布</a></span>
+										<span class="spam">|<a class="vim-s vim-destructive" href="javascript:trash(${bean.id})">垃圾箱</a></span>
+										<#else>
+										<span class="approve"> <a class="vim-a" href="javascript:restore(${bean.id})">放回草稿</a></span>
+										<span class="spam">|<a class="vim-s vim-destructive" href="javascript:del(${bean.id})">永久删除</a></span>
+										</#if>
+									</p>
+								</div>
+								</td>
+
+							<td>
+							<a href="${bean.contentUrl!}" target="_blank">${bean.content_title!}</a>
 							</td>
 							</td>
+							<td>${bean.comment_count!}</td>
+							<td>${bean.created!}</td>
+						</tr>
+						</#list>
+						</#if>
+
 
 
-						<td>
-						<a href="${bean.contentUrl!}" target="_blank">${bean.content_title!}</a>
-						</td>
-						<td>${bean.comment_count!}</td>
-						<td>${bean.created!}</td>
-					</tr>
-					</#list> 
-					</#if>
-
-
-				</tbody>
-				<tfoot>
-					<tr>
-						<th style="width: 2%"><input name="dataItem" onclick="checkAll(this)" type="checkbox"></th>
-						<th style="width: 10%">作者</th>
-						<th style="width: 33%">内容</th>
-						<th style="width: 15%">回复至</th>
-						<th style="width: 10%"><i class="fa fa-commenting"></i></th>
-						<th style="width: 10%">日期</th>
-					</tr>
-				</tfoot>
-			</table>
+					</tbody>
+					<tfoot>
+						<tr>
+							<th style="width: 2%"><input name="dataItem" onclick="checkAll(this)" type="checkbox"></th>
+							<th style="width: 10%">作者</th>
+							<th style="width: 33%">内容</th>
+							<th style="width: 15%">回复至</th>
+							<th style="width: 10%"><i class="fa fa-commenting"></i></th>
+							<th style="width: 10%">日期</th>
+						</tr>
+					</tfoot>
+				</table>
+			</div>
+			<!-- /.box-body -->
 		</div>
 		</div>
-		<!-- /.box-body -->
-	</div>
-	<!-- /.box -->
-	<div class="cf">
-		<div class="pull-right ">
-		<#if page??> 
-		<#include "../_inc/_paginate.html" /> 
-		<@paginate currentPage=page.pageNumber totalPage=page.totalPage actionUrl="?p="+(p!)+"&c="+(c!)+"&m="+(m!)+"&t="+(t!)+"&s="+(s!)+"&k="+(k!)+"&pid="+(pid!)+"&cid="+(cid!)+"&page="/> 
-		</#if>
+		<!-- /.box -->
+		<div class="cf">
+			<div class="pull-right ">
+			<#if page??>
+			<#include "../_inc/_paginate.html" />
+			<@paginate currentPage=page.pageNumber totalPage=page.totalPage actionUrl="?p="+(p!)+"&c="+(c!)+"&m="+(m!)+"&t="+(t!)+"&s="+(s!)+"&k="+(k!)+"&pid="+(pid!)+"&cid="+(cid!)+"&page="/>
+			</#if>
+			</div>
 		</div>
 		</div>
-	</div>
-</section>
-<!-- /.content -->
+	</section>
+	<!-- /.content -->
+</#if>
 </@layout>
 </@layout>
 
 
 
 

+ 1 - 1
jpress-web-admin/src/main/webapp/WEB-INF/admin/comment/reply_layer.html

@@ -93,7 +93,7 @@ function save(){
 			<!-- /.col -->
 			<!-- /.col -->
 			<div class="col-md-12">
 			<div class="col-md-12">
 				<div class="form-group">
 				<div class="form-group">
-					您准备回复 ${comment.author!}在文章《<a href="${comment.contentUrl!}" target="_blank">${comment.content_title!}</a>》评论的如下内容:<br />
+					您准备回复 ${comment.author!}在文章《<a href="${comment.getContent().url!}" target="_blank">${comment.getContent().title!}</a>》评论的如下内容:<br />
 					${(comment.text)!}
 					${(comment.text)!}
 				</div>
 				</div>
 				<div class="box box-solid">
 				<div class="box box-solid">

+ 171 - 0
jpress-web-admin/src/main/webapp/WEB-INF/admin/comment/uuHelperCommentList.html

@@ -0,0 +1,171 @@
+<style>
+    /*table表格*/
+    .box-content .box-message{
+        border-top: none;
+        margin-top: 40px;
+    }
+    .box-content .box-message table thead tr{
+        background: #f1f1f1;
+    }
+    .bodyUas  table tbody td{
+        vertical-align: middle;
+        height: 70px;
+    }
+    .bodyUas .messageContent{
+        overflow: hidden;
+        width: 300px;
+        border-bottom: 1px solid #d9d2de;
+        padding-left: 30px;
+    }
+    .bodyUas .messageContent .leftImg{
+        width: 65px;
+        height: 50px;
+        float: left;
+    }
+    .bodyUas .messageContent .leftImg img{
+        max-width: 65px;
+        max-height: 50px;
+    }
+    .bodyUas .messageContent .rightContent{
+        width: 70%;
+        float: left;
+        margin-left: 10px;
+    }
+    .bodyUas .messageContent .rightContent p{
+        width: 175px;
+        text-overflow: ellipsis;
+        overflow: hidden;
+        white-space: nowrap;
+        font-size: 14px;
+        color: #333;
+    }
+    .bodyUas .messageContent .rightContent span{
+        width: 175px;
+        text-overflow: ellipsis;
+        overflow: hidden;
+        white-space: nowrap;
+        font-size: 14px;
+        color: #9d9d9d;
+        display: inline-block;
+    }
+    .bodyUas .messageTitle{
+        font-size: 16px;
+        color: #000;
+        font-weight: bold;
+    }
+    .bodyUas .messageTime,.bodyUas .isShowMessage{
+        font-size: 14px;
+        color: #333;
+    }
+    .bodyUas .messageTime,.bodyUas .isShowMessage select{
+        border: none;
+        outline: none;
+    }
+    .bodyUas .handleMessage a{
+        font-size: 14px;
+        color: #333;
+        margin-right: 20px;
+    }
+    .bodyUas .handleMessage a.replay{
+        color: #0a44ff;
+    }
+    .box-content .box-message .table tbody.bodyUas tr {
+        background-color: #fff;
+    }
+    .box-content .box-message .table tbody.bodyUas tr td{
+        vertical-align: middle;
+        height: 70px;
+    }
+    .content-wrapper{
+        background-color: #fff!important;
+    }
+    /*分頁*/
+    .box-content .pageUas{
+        margin-top: 20px;
+    }
+</style>
+<!-- Main content -->
+<section class="content box-content">
+    <div class="box box-message">
+        <!-- /.box-header -->
+        <div class="box-body">
+            <form action="" method="POST" id="form">
+                <input type="hidden" name="ucode" value="${ucode}">
+                <table class="table table-striped" style="word-break:break-all">
+                    <thead>
+                    <tr>
+                        <th width="450" style="padding-left: 40px;">留言</th>
+                        <th width="330">文章标题</th>
+                        <th width="260">时间</th>
+                        <th width="230">是否显示</th>
+                        <th width="200">操作</th>
+                    </tr>
+                    </thead>
+                    <tbody class="bodyUas">
+                    <#if page??>
+                        <#list page.getList() as bean>
+                            <tr class="jp-onmouse">
+                                <td>
+                                    <div class="messageContent">
+                                        <div class="leftImg">
+                                            <img src="${(bean.uu_user_avatar)!(bean.user.avatar)!CPATH+'/static/jpress/admin/image/nothumbnail.jpg'}" alt="头像">
+                                        </div>
+                                        <div class="rightContent">
+                                            <p>${bean.author!}</p>
+                                            <span>
+                                                ${bean.text!}<#if "draft" == bean.status!>(待审核)</#if>
+                                            </span>
+                                        </div>
+                                    </div>
+                                    <!--<div class="jp-flash-comment">-->
+                                        <!--<p class="row-actions jp-cancel-pad">-->
+                                            <!--<#if "normal" == bean.status!>-->
+                                                <!--<span class="approve"><a class="vim-a" href="javascript:reply(${bean.id})">回复</a></span>-->
+                                                <!--<span class="approve">|<a class="vim-a" href="${CPATH}/admin/comment/edit?id=${bean.id!}&p=${(p)!}&c=${(c)!}">编辑</a></span>-->
+                                                <!--<span class="spam">|<a class="vim-s vim-destructive" href="javascript:draft(${bean.id})">待审核</a></span>-->
+                                                <!--<span class="spam">|<a class="vim-s vim-destructive" href="javascript:trash(${bean.id})">垃圾箱</a></span>-->
+                                                <!--<#elseif "draft" == bean.status!>-->
+                                                    <!--<span class="approve"><a class="vim-a" href="javascript:reply(${bean.id})">回复</a></span>-->
+                                                    <!--<span class="approve">|<a class="vim-a" href="${CPATH}/admin/comment/edit?id=${bean.id!}&p=${(p)!}&c=${(c)!}">编辑</a></span>-->
+                                                    <!--<span class="spam">|<a class="vim-s vim-destructive" href="javascript:pub(${bean.id})">允许发布</a></span>-->
+                                                    <!--<span class="spam">|<a class="vim-s vim-destructive" href="javascript:trash(${bean.id})">垃圾箱</a></span>-->
+                                                    <!--<#else>-->
+                                                        <!--<span class="approve"> <a class="vim-a" href="javascript:restore(${bean.id})">放回草稿</a></span>-->
+                                                        <!--<span class="spam">|<a class="vim-s vim-destructive" href="javascript:del(${bean.id})">永久删除</a></span>-->
+                                            <!--</#if>-->
+                                        <!--</p>-->
+                                    <!--</div>-->
+                                </td>
+                                <td class="messageTitle">${bean.content_title!}</td>
+                                <td class="messageTime">
+                                    ${bean.created!}
+                                </td>
+                                <td class="isShowMessage">
+                                    <select id="isShowMessageSelect${bean.id}" onchange="showMessageSelect(${bean.id})">
+                                        <option value="draft" <#if bean?? && bean.status?? && bean.status=="draft"> selected="selected" </#if>>不显示</option>
+                                        <option value="normal" <#if bean?? && bean.status?? && bean.status=="normal"> selected="selected" </#if>>显示</option>
+                                    </select>
+                                </td>
+                                <td class="handleMessage">
+                                    <a href="javascript:reply(${bean.id})">回复</a><a href="javascript:trash(${bean.id})">删除</a>
+                                </td>
+                            </tr>
+                        </#list>
+                    </#if>
+
+                    </tbody>
+                </table>
+            </form>
+        </div>
+        <!-- /.box-body -->
+    </div>
+    <div class="cf pageUas">
+        <div class="pull-right " >
+            <#if page??>
+                <#include "../_inc/_paginate.html" />
+                <@paginate currentPage=page.pageNumber totalPage=page.totalPage actionUrl="?p="+(p!)+"&c="+(c!)+"&m="+(m!)+"&t="+(t!)+"&s="+(s!)+"&k="+(k!)+"&tids="+(tids!)+"&page="/>
+            </#if>
+        </div>
+    </div>
+    <!-- /.row -->
+</section>

+ 206 - 0
jpress-web-admin/src/main/webapp/WEB-INF/admin/comment/uuHelperGroupDetail.html

@@ -0,0 +1,206 @@
+<style>
+    /*table表格*/
+    .box-content .box-message{
+        border-top: none;
+        margin-top: 40px;
+    }
+    .box-content .box-message table thead tr{
+        background: #f1f1f1;
+    }
+    .box-content .box-message table thead tr th.chooseCount span{
+        color: #9d9d9d;
+    }
+    .bodyUas .messageContent{
+        overflow: hidden;
+        width: 300px;
+    }
+    .bodyUas .messageContent .leftImg{
+        width: 65px;
+        height: 50px;
+        float: left;
+    }
+    .bodyUas .messageContent .leftImg img{
+        max-width: 65px;
+        max-height: 50px;
+    }
+    .bodyUas .messageContent .rightContent{
+        width: 70%;
+        float: left;
+        margin-left: 10px;
+    }
+    .bodyUas .messageContent .rightContent p{
+        width: 175px;
+        text-overflow: ellipsis;
+        overflow: hidden;
+        white-space: nowrap;
+        font-size: 14px;
+        color: #333;
+    }
+    .bodyUas .messageContent .rightContent span{
+        width: 175px;
+        text-overflow: ellipsis;
+        overflow: hidden;
+        white-space: nowrap;
+        font-size: 14px;
+        color: #9d9d9d;
+        display: inline-block;
+    }
+    .bodyUas .messageTime{
+        font-size: 14px;
+        color: #333;
+    }
+    .bodyUas .handleMessage select {
+        border: none;
+        outline: none;
+    }
+    .bodyUas .handleMessage a{
+        margin-right: 20px;
+        font-size: 14px;
+        color: #0a44ff;
+    }
+    .box-content .box-message .table tbody.bodyUas tr {
+        background-color: #fff;
+    }
+    .box-content .box-message .table tbody.bodyUas tr td{
+        vertical-align: middle;
+        height: 70px;
+    }
+    .box-content .box-message .table tbody.bodyUas tr:last-child{
+        border-bottom: 2px solid #000;
+    }
+    .box-content .box-message .messageNav{
+        margin-bottom: 15px;
+    }
+    .box-content .box-message .messageNav ul{
+        overflow: hidden;
+        height: 40px;
+    }
+    .box-content .box-message .messageNav ul li{
+        float: left;
+        width: 140px;
+        height: 40px;
+        line-height: 40px;
+        text-align: center;
+
+        list-style: none;
+    }
+    .box-content .box-message .messageNav ul li a{
+        display: inline-block;
+        width: 140px;
+        height: 40px;
+        color: #333;
+        border-radius: 5px;
+        border: 1px solid #797979;
+    }
+    .box-content .box-message .messageNav ul li:hover a,.box-content .box-message .messageNav ul li.active a{
+        border: none;
+        background: #379bd5;
+        color: #fff;
+    }
+    .content-wrapper{
+        background-color: #fff!important;
+    }
+    /*分頁*/
+    .box-content .pageUas{
+        margin-top: 20px;
+    }
+</style>
+<!-- Main content -->
+<section class="content box-content">
+    <div class="box box-message">
+        <div class="messageNav">
+            <ul>
+                <li><a href="${CPATH}/admin/comment?t=${t!}&m=${m!}&p=${p!}&c=${c!}&s=normal&cid=${cid!}&way=${way!}">
+                        已显示 <span class="count">(${normal_count!"0"})</span>
+                    </a>
+                </li>
+
+                <li><a href="${CPATH}/admin/comment?t=${t!}&m=${m!}&p=${p!}&c=${c!}&s=draft&cid=${cid!}&way=${way!}">
+                        未显示 <span class="count">(${draft_count!"0"})</span>
+                    </a>
+                </li>
+                <li><a href="${CPATH}/admin/comment?t=${t!}&m=${m!}&p=${p!}&c=${c!}&son=true&cid=${cid!}&way=${way!}">
+                        已回复<span class="count">(${answered_count!"0"})</span>
+                    </a>
+                </li>
+                <li><a href="${CPATH}/admin/comment?t=${t!}&m=${m!}&p=${p!}&c=${c!}&son=false&cid=${cid!}&way=${way!}">
+                        未回复<span class="count">(${unanswered_count!"0"})</span>
+                    </a>
+                </li>
+                <li><a href="${CPATH}/admin/comment?t=${t!}&m=${m!}&p=${p!}&c=${c!}&s=delete&cid=${cid!}&way=${way!}">
+                        垃圾箱 <span class="count">(${delete_count!"0"})</span>
+                    </a>
+                </li>
+            </ul>
+        </div>
+        <!-- /.box-header -->
+        <div class="box-body">
+            <form action="" method="POST" id="form">
+                <input type="hidden" name="ucode" value="${ucode}">
+                <table class="table table-striped" style="word-break:break-all">
+                    <thead>
+                    <tr>
+                        <th style="padding-left: 40px;" width="25"><input name="dataItem" onclick="checkAll(this)" type="checkbox"></th>
+                        <th width="500" class="chooseCount">留言 <span>(已选中 <span>0</span>条)</span></th>
+                        <th width="400">留言时间</th>
+                        <th width="400">操作</th>
+                    </tr>
+                    </thead>
+                    <tbody class="bodyUas">
+
+                    <#if page??>
+                        <#list page.getList() as bean>
+                            <tr>
+                                <td style="padding-left: 40px;"><input name="dataItem" type="checkbox"></td>
+                                <td>
+                                    <div class="messageContent">
+                                        <div class="leftImg">
+                                            <img src="${(bean.user.avatar)!CPATH+'/static/jpress/admin/image/nothumbnail.jpg'}" alt="头像">
+                                        </div>
+                                        <div class="rightContent">
+                                            <p>${bean.author!}</p>
+                                            <span>${bean.text!}<#if "draft" == bean.status!>(待审核)<#elseif "delete" == bean.status!>(垃圾箱)</#if></span>
+                                        </div>
+                                    </div>
+                                </td>
+                                <td class="messageTime">
+                                    ${bean.created!}
+                                </td>
+                                <td class="handleMessage">
+                                    <#if "delete" == bean.status!>
+                                        <a href="javascript:restore(${bean.id})">放回草稿</a>
+                                        <a href="javascript:del(${bean.id})">永久删除</a>
+                                    <#else>
+                                        <a><select id="isShowMessageSelect${bean.id}" onchange="showMessageSelect(${bean.id})">
+                                            <option value="draft" <#if bean?? && bean.status?? && bean.status=="draft"> selected="selected" </#if>>不显示</option>
+                                            <option value="normal" <#if bean?? && bean.status?? && bean.status=="normal"> selected="selected" </#if>>显示</option>
+                                        </select>
+                                        </a>
+                                        <a><select id="isTopSelect${bean.id}" onchange="topSelect(${bean.id})">
+                                            <option value="default" <#if bean?? && bean.order_number?? && bean.order_number==0> selected="selected" </#if>>默认</option>
+                                            <option value="top" <#if bean?? && bean.order_number?? && bean.order_number==1> selected="selected" </#if>>置顶</option>
+                                        </select>
+                                        </a>
+                                        <a href="javascript:reply(${bean.id})">回复</a>
+                                        <a href="javascript:trash(${bean.id})">删除</a>
+                                    </#if>
+                                </td>
+                            </tr>
+                        </#list>
+                    </#if>
+                    </tbody>
+                </table>
+            </form>
+        </div>
+        <!-- /.box-body -->
+    </div>
+    <div class="cf pageUas">
+        <div class="pull-right " >
+            <#if page??>
+                <#include "../_inc/_paginate.html" />
+                <@paginate currentPage=page.pageNumber totalPage=page.totalPage actionUrl="?p="+(p!)+"&c="+(c!)+"&m="+(m!)+"&t="+(t!)+"&s="+(s!)+"&k="+(k!)+"&tids="+(tids!)+"&page="/>
+            </#if>
+        </div>
+    </div>
+    <!-- /.row -->
+</section>

+ 127 - 0
jpress-web-admin/src/main/webapp/WEB-INF/admin/comment/uuHelperGroupList.html

@@ -0,0 +1,127 @@
+<style>
+    /*table表格*/
+    .box-content .box-message{
+        border-top: none;
+        margin-top: 40px;
+    }
+    .box-content .box-message table thead tr{
+        background: #f1f1f1;
+    }
+    .bodyUas .messageTitle{
+        font-size: 16px;
+        font-weight: bold;
+        color: #000;
+        padding-left: 30px;
+    }
+    .bodyUas .messageTime{
+        font-size: 14px;
+        color: #333;
+    }
+    .bodyUas .isOpenMessage{
+        font-size: 14px;
+        color: #333;
+    }
+    .bodyUas .isOpenMessage select{
+        width: 60px;
+        border: none;
+        outline: none;
+    }
+    .bodyUas .handleMessage a.replay{
+        margin-right: 20px;
+        font-size: 14px;
+        color: #0a44ff;
+    }
+    .box-content .box-message .table tbody.bodyUas tr {
+        background-color: #fff;
+    }
+    .box-content .box-message .table tbody.bodyUas tr td{
+        vertical-align: middle;
+        height: 70px;
+    }
+    .content-wrapper{
+        background-color: #fff!important;
+    }
+    /*分頁*/
+    .box-content .pageUas{
+        margin-top: 20px;
+    }
+</style>
+<!-- Main content -->
+<section class="content box-content">
+    <div class="box box-message">
+        <!-- /.box-header -->
+        <div class="box-body">
+            <form action="" method="POST" id="form">
+                <input type="hidden" name="ucode" value="${ucode}">
+                <table class="table table-striped" style="word-break:break-all">
+                    <thead>
+                    <tr>
+                        <th width="700" style="padding-left: 40px;">文章标题</th>
+                        <th width="310">时间</th>
+                        <th width="310">是否开启</th>
+                        <th width="310">操作</th>
+                    </tr>
+                    </thead>
+                    <tbody class="bodyUas">
+
+                        <@jp.contents module="uuhelper" orderBy="meta:push_time desc">
+                        <#list contents as content>
+                            <tr>
+                                <td class="messageTitle">${content.title!}</td>
+                                <td class="messageTime">
+                                    ${(content.getMetadataByKey("push_time"))!}
+                                </td>
+                                <td class="isOpenMessage">
+                                    <select id="commentStatus${content.id!}" onchange="changeCommentSataus(${content.id!})">
+                                        <#if (content.comment_status)?? && "close" == content.comment_status >
+                                            <option value="close" selected="selected">关闭</option>
+                                        <#else>
+                                            <option value="close">关闭</option>
+                                        </#if>
+                                        <#if (content.comment_status)?? && "open" == content.comment_status >
+                                            <option value="open" selected="selected">开启</option>
+                                        <#else>
+                                            <option value="open">开启</option>
+                                        </#if>
+                                    </select>
+                                </td>
+                                <td class="handleMessage">
+                                    <a class="replay" href="${CPATH}/admin/comment?t=comment&m=uuhelper&p=uuhelper&c=comment&cid=${content.id!}&way=detail">查看</a>
+                                </td>
+                            </tr>
+                        </#list>
+                        </@jp.contents>
+
+                    </tbody>
+                </table>
+            </form>
+        </div>
+        <!-- /.box-body -->
+    </div>
+    <!-- /.row -->
+</section>
+<script type="text/javascript" src="${CTPATH}/assets/js/jquery.min.js"></script>
+<script>
+    //下拉加载更多
+    var aa = 1, timers = null;
+    //加载数据
+    var LoadingDataFn = function() {
+        $.get("${CPATH}/admin/content/lazyLoad?ucode=${ucode!}&CPATH=${CPATH!}&pagesize=10&orderBy=meta:push_time desc&module=uuhelper&pagenumber="+aa, function(result){
+            var dom = '';
+            dom += result.message;
+            $('.bodyUas').append(dom);
+        });
+
+    };
+    //初始化
+    //滚动加载方法
+    $(window).scroll(function() {
+        if (($(window).height() + $(window).scrollTop() + 60) >= $(document).height()) {
+            clearTimeout(timers);
+            timers = setTimeout(function() {
+                aa++;
+                LoadingDataFn();
+            }, 300);
+        }
+    });
+</script>

+ 481 - 56
jpress-web-admin/src/main/webapp/WEB-INF/admin/content/_edit_include.html

@@ -1,61 +1,486 @@
-<section class="content-header">
-	<h1>${(module.addTitle)!}</h1>
-</section>
-<!-- Main content -->
-<section class="content" style="z-index: 9999">
-	<form action="${CPATH}/admin/content/save" id="form" method="post">
-		<input type="hidden" name="content.module" value="${(content.module)!m!}"> 
-		<input type="hidden" id="content_id" name="content.id" value="${(content.id)!}"> 
-		<input type="hidden" name="content.status" value="normal" id="content_status"> 
-		<input type="hidden" name="content.created" value="${(content.created)!}" > 
-		<input type="hidden" id="content_slug" name="content.slug" value="${(content.slug)!}" > 
-		<input type="hidden" name="ucode" value="${ucode}">
-		<div class="row">
-			<!-- /.col -->
-			<div class="col-md-9">
-				<div class="form-group">
-					<input name="content.title" class="form-control input-lg" id="title" value="${(content.title)!}" type="text" placeholder="在此输入标题">
-				</div>
-				<div class="pull-right"><a href="javascript:void(0);" onclick="doChangeEditor()">切换编辑器 </a> </div>
-				<label>
-				<#if slugDisplay ??>
-					网址:<span id="url_preffix"></span><span id="slug_text">${(content.slug)!}</span>${(urlSuffix)!}
-				</#if>
-				</label>
-				<div class="box box-solid">
-					<div  class="box-body no-padding">
-						<textarea id="textarea"  name="content.text" >${(content.text)!}</textarea>
+<style>
+	.editUas{
+		padding: 8px 20px;
+		height: 45px;
+		background: #dbdddf;
+	}
+	.editUas span{
+		display: inline-block;
+		margin-right: 10px;
+		width: 70px;
+		height: 30px;
+		line-height: 30px;
+		text-align: center;
+		background: #fff;
+		color: #666;
+		border-radius: 3px;
+		cursor: pointer;
+	}
+	.authorUas{
+		height: 40px;
+		overflow: hidden;
+		border-bottom:  1px solid #aaacad;
+	}
+	.authorUas .form-group{
+		margin-right: 55px;
+		float: left;
+		height: 40px;
+		line-height: 40px;
+		font-size: 14px;
+	}
+	.authorUas .form-group input{
+		display: inline-block;
+		width: 120px;
+		height: 28px;
+		color: #6a8bdd;
+	}
+	.authorUas .dateUas{
+		float: left;
+		height: 40px;
+		line-height: 40px;
+		font-size: 14px;
+	}
+	.authorUas .dateUas a{
+		text-decoration: underline;
+		color: #6a8bdd;
+	}
+	.authorUas .dateUas input{
+		border: none;
+		outline: none;
+	}
+	.themeUas{
+		height: 60px;
+		line-height: 60px;
+		font-size: 16px;
+		color: #323232;
+	}
+	.themeUas .form-group{
+		height: 60px;
+	}
+	.themeUas .form-group input{
+		display: inline-block;
+		height: 35px;
+		width: 93%;
+		margin-left: 5px;
+	}
+	.box-solidUas{
+		box-shadow: none;
+	}
+	.box-solidUas .box-bodyUas{
+		overflow: hidden;
+		background: #ecf0f5;
+	}
+	.box-solidUas .box-bodyUas span{
+		float: left;
+		margin-right: 10px;
+		font-size: 16px;
+		color: #323232;
+	}
+	.setUas{
+		width: 270px;
+		margin-top: 40px;
+		background: #fff;
+		border: 1px solid #aaacad;
+	}
+	.setUas .setUas-header{
+		padding-left: 20px;
+		width: 270px;
+		height: 35px;
+		line-height: 35px;
+		border-bottom: 1px solid #aaacad;
+	}
+	.setUas .setUas-body .form-group{
+		overflow: hidden;
+		margin-bottom: 0;
+		width: 235px;
+		height: 40px;
+		line-height: 25px;
+	}
+	.setUas .setUas-body span{
+		float: left;
+		padding: 6px 12px;
+		font-size: 14px;
+		font-weight: 400;
+		color: #555;
+	}
+	.setUas .setUas-body input{
+		margin-top: 7px;
+		width: 110px;
+		height: 25px;
+	}
+	.setUas .setUas-footer{
+		border-top: 1px solid #aaacad;
+	}
+	.setUas .setUas-footer .form-group{
+		overflow: hidden;
+		margin-bottom: 0;
+		width: 235px;
+		height: 40px;
+		line-height: 25px;
+	}
+	.setUas .setUas-footer span{
+		float: left;
+		padding: 6px 12px;
+		font-size: 14px;
+		font-weight: 400;
+		color: #555;
+	}
+	/*滑动开关*/
+	.setUas .setUas-footer p.switch .checkbox {
+		width: 54px;
+		margin: 0 auto;
+		text-align: center;
+		position: relative;
+		display: block;
+	}
+	.setUas .setUas-footer p.switch .checkbox span {
+		width: 48px;
+		height: 24px;
+		display: inline-block;
+		border-radius: 18px;
+		border: #e4e4e4 1px solid;
+		cursor: pointer;
+		position: relative;
+		box-shadow: 1px 1px 5px #eee;
+		background: -webkit-gradient(linear,0% 0%, 0% 100%, from(#E0E0E0), to(#E8E8E8), color-stop(0.5,#F2F2F2));
+		transition: background-color .1s ease-out;
+	}
+	.setUas .setUas-footer p.switch .checkbox.active span{
+		background: #b9cffa;
+	}
+	.setUas .setUas-footer p.switch .checkbox.active span em{
+		left: 27px;
+	}
+	.setUas .setUas-footer .checkbox span em{
+		position: absolute;
+		width: 25px;
+		height: 25px;
+		top: -4px;
+		left: 0;
+		line-height: 16px;
+		background-color: #fff;
+		border: #eee 1px solid;
+		border-radius: 50%;
+		box-shadow: -1px 2px 1px #999;
+		transition: background-color .1s ease-out;
+		color: #666;
+		font-size: 12px;
+	}
+
+
+	/*设置封面*/
+	.coverUas{
+		font-size: 14px;
+		margin-top: 25px;
+		padding: 5px 0;
+		border-top: 1px solid #aaacad;
+	}
+	.coverContentUas{
+		padding: 50px 0 50px 60px;
+		width: 930px;
+		background: #fff;
+	}
+	.coverContentUas p{
+		font-size: 16px;
+		margin: 5px 0;
+	}
+	.coverContentUas p.styleUas{
+		margin-bottom: 50px;
+	}
+	.coverContentUas .inputUas{
+		display: inline-block;
+		position: relative;
+		margin-top: 35px;
+		margin-right: 230px;
+		width: 150px;
+		height: 40px;
+	}
+	.coverContentUas .inputUas em{
+		display: inline-block;
+		width: 120px;
+		height: 40px;
+		line-height: 40px;
+		text-align: center;
+		font-size: 16px;
+		font-style: normal;
+		border: 1px solid #aaacad;
+		border-radius: 3px;
+	}
+	.coverContentUas .inputUas input{
+		position: absolute;
+		top:0;
+		left:0;
+		width: 155px;
+		height: 40px;
+		opacity: 0;
+		cursor: pointer;
+	}
+	.coverContentUas textarea {
+		width: 745px;
+		height: 145px;
+	}
+	.coverContentUas .detailUas{
+		position: relative;
+		margin-top: 25px;
+	}
+	.coverContentUas .CountUas{
+		position: absolute;
+		bottom: -20px;
+		right: 125px;
+	}
+	.coverContentUas .chooseImg{
+		overflow: hidden;
+	}
+	.coverContentUas .chooseImg .choose{
+		/*float: left;*/
+	}
+	.coverContentUas .chooseImg .choose em{
+		cursor: pointer;
+	}
+	.coverContentUas .chooseImg .showImg {
+		margin-top: 32px;
+		margin-right: 62px;
+		float: left;
+		width: 322px;
+		height: 181px;
+		line-height: 181px;
+		text-align: center;
+		overflow: hidden;
+		border: 1px solid #aaacad;
+	}
+	.coverContentUas .chooseImg .showImg  img{
+		width: 322px;
+		height: 181px;
+	}
+	.coverContentUas .chooseImg .showImgs {
+		margin-top: 32px;
+		float: left;
+		width: 100px;
+		height: 100px;
+		line-height: 100px;
+		text-align: center;
+		overflow: hidden;
+		border: 1px solid #aaacad;
+	}
+	.coverContentUas .chooseImg .showImgs  img{
+		width: 100px;
+		height: 100px;
+	}
+	.copyright h5{
+		margin: 5px 0;
+	}
+	.copyright input{
+		width: 930px;
+		height: 30px;
+	}
+</style>
+
+<#if module ?? && module.name=="uuhelper">
+	<!-- 软文发布界面 -->
+    <section class="content-header">
+        <h1>${(module.addTitle)!}</h1>
+    </section>
+    <!-- Main content -->
+	<input type="hidden" id="content_url" name="content.url" value="${(content.url)!}">
+    <section class="content" style="z-index: 9999">
+        <form action="${CPATH}/admin/content/save" id="form" method="post">
+            <input type="hidden" name="content.module" value="${(content.module)!m!}">
+            <input type="hidden" id="content_id" name="content.id" value="${(content.id)!}">
+            <input type="hidden" name="content.status" value="normal" id="content_status">
+            <input type="hidden" name="content.created" value="${(content.created)!}" >
+            <input type="hidden" id="content_slug" name="content.slug" value="${(content.slug)!}" >
+            <input type="hidden" name="ucode" value="${ucode}">
+            <div class="row">
+                <!-- /.col -->
+                <div class="col-md-12">
+					<div class="editUas">
+						<div class="pull-right"><span><a href="${CPATH}/admin/content/edit?m=uuhelper&p=uuhelper&c=edit">取消</a></span></div>
+						<div><span onclick="saveAsDraft()">保存</span><span onclick="save()">发送</span><span onclick="doPreview()">浏览</span></div>
+					</div>
+					<div class="row">
+						<div class="col-md-9">
+							<div class="leftUas"></div>
+							<div class="authorUas">
+								<div class="form-group">
+									<label for="content_author" class="control-label">作者:</label>
+									<input type="text" class="form-control" name="content.author" id="content_author" value="${USER.nickname!USER.username}">
+								</div>
+								<div class="dateUas">
+									<span>发布日期:</span>
+									<#list module.metadatas as metadata>
+										<#if metadata.name == "push_time">
+											<input type="hidden" class="push_time" id="meta:push_time" name="meta:push_time" value="${(content.metadata(metadata.name))!}">
+											<a><input id="createDefaultTime" type="date" value="${(content.metadata(metadata.name))!}" onchange="getPushTime()"></a>
+										</#if>
+									</#list>
+								</div>
+							</div>
+							<div class="themeUas">
+								<div class="form-group">
+									<label for="title" class="control-label col-ms-1">主题</label>
+									<input type="text" class="form-control col-ms-11" name="content.title" id="title" value="${(content.title)!}" >
+								</div>
+							</div>
+							<div class="box box-solid box-solidUas">
+							<div  class="box-body no-padding box-bodyUas">
+							   <span>正文</span><textarea id="textarea"  name="content.text" >${(content.text)!}</textarea>
+							</div>
+						</div>
+						</div>
+						<div class="col-md-3">
+							<div>
+								<#if module ??>
+									<#list module.taxonomyTypes! as taxonomyType >
+										<#if taxonomyType.formType == "select">
+											<#include "_select_box.html" />
+											<#else>
+												<#include "_input_box.html" />
+										</#if>
+									</#list>
+								</#if>
+							</div>
+							<div class="setUas">
+								<div class="setUas-header">
+									<p>设置</p>
+								</div>
+								<div class="setUas-body">
+									<div class="form-group input-group">
+										<span>初始化阅读量:</span>
+										<input name="content.view_count" class="form-control" id="view_content" value="${(content.view_count)!0}" type="text">
+									</div>
+									<div class="form-group input-group">
+										<span>初始化点赞量:</span>
+										<input name="content.vote_up" class="form-control" id="vote_up" value="${(content.vote_up)!0}" type="text">
+									</div>
+								</div>
+								<div class="setUas-footer">
+									<div class="form-group">
+										<span>是否可以留言:</span>
+										<p class="switch">
+											<input type="hidden" id="comment_status" name="content.comment_status">
+											<#if (content.comment_status)?? && "open" == content.comment_status >
+												<span class="checkbox active" onclick="commentable()">
+													<span><em></em></span>
+												</span>
+											<#else>
+												<span class="checkbox" onclick="commentable()">
+													<span><em></em></span>
+												</span>
+											</#if>
+										</p>
+									</div>
+								</div>
+							</div>
+						</div>
+					</div>
+                </div>
+                <!-- /.col -->
+            </div>
+            <!-- /.row -->
+			<div class="row">
+				<div class="col-md-12">
+					<h5 class="coverUas">设置封面</h5>
+					<div class="coverContentUas">
+						<p class="styleUas">发布样式编辑</p>
+						<div class="chooseImg">
+							<div class="choose">
+								<p>封面</p>
+								<!--大图-->
+								<input type="hidden" name="content.thumbnail" value="${(content.thumbnail)!}" id="content_thumbnail">
+								<span class="inputUas" onclick="doSelectThumbnail()" onchange="Javascript:validImg(this);"><em>从图库选择</em><!--<input type="file">--></span>
+								<!--小图-->
+								<input type="hidden" name="content.thumbnail" value="${(content.thumbnail)!}" id="content_thumbnail">
+								<span class="inputUas" onclick="doSelectThumbnail()" onchange="Javascript:validImg(this);"><em>从图库选择</em><!--<input type="file">--></span>
+							</div>
+							<!--大图-->
+							<div class="showImg">
+								<img src="${(content.thumbnail)!CPATH+'/static/jpress/admin/image/nothumbnail.jpg'}" id="thumbnail" class="jp-content-thumbnail content-thumbnail"/>
+							</div>
+							<!--小图-->
+							<div class="showImgs">
+								<img src="${(content.thumbnail)!CPATH+'/static/jpress/admin/image/nothumbnail.jpg'}" id="thumbnail" class="jp-content-thumbnail content-thumbnail"/>
+							</div>
+						</div>
+						<div class="detailUas">
+							<p>摘要</p>
+							<textarea name="content.summary" id="content_summary" cols="30" rows="10" placeholder="选填,如果不填写会默认抓取正文前54个字" oninput="countSummaryLength()">${(content.summary)!}</textarea>
+							<span class="CountUas"><span class="CountLengthUas">${(content.summary.length())!0}</span><span>/120</span></span>
+						</div>
+					</div>
+					<div class="copyright">
+						<#list module.metadatas as metadata>
+							<#if metadata.name == "copy_right">
+								<h5>设置版权归属</h5>
+								<input type="text" placeholder="${metadata.placeholder!}" id="meta:${metadata.name!}" name="meta:${metadata.name!}" value="${(content.metadata(metadata.name))!}">
+							</#if>
+						</#list>
+
 					</div>
 					</div>
 				</div>
 				</div>
-				<div class="form-group input-group">
-					<span class="input-group-addon">设置排序权重:</span>
-					<input name="content.order_number" class="col-xs-6 form-control input-lg" id="order_number" value="${(content.order_number)!0}" type="text" placeholder="排序权重,正整数,数字越大的权重最大,非必填">
-				</div>
-				<div class="form-group input-group">
-					<span class="input-group-addon">设置初始阅读量:</span>
-					<input name="content.view_count" class="col-xs-6 form-control input-lg" id="view_content" value="${(content.view_count)!0}" type="text" placeholder="初始阅读数量,非必填">
+			</div>
+        </form>
+    </section>
+<#else>
+	<section class="content-header">
+		<h1>${(module.addTitle)!}</h1>
+	</section>
+	<!-- Main content -->
+	<section class="content" style="z-index: 9999">
+		<form action="${CPATH}/admin/content/save" id="form" method="post">
+			<input type="hidden" name="content.module" value="${(content.module)!m!}">
+			<input type="hidden" id="content_id" name="content.id" value="${(content.id)!}">
+			<input type="hidden" name="content.status" value="normal" id="content_status">
+			<input type="hidden" name="content.created" value="${(content.created)!}" >
+			<input type="hidden" id="content_slug" name="content.slug" value="${(content.slug)!}" >
+			<input type="hidden" name="ucode" value="${ucode}">
+			<div class="row">
+				<!-- /.col -->
+				<div class="col-md-9">
+					<div class="form-group">
+						<input name="content.title" class="form-control input-lg" id="title" value="${(content.title)!}" type="text" placeholder="在此输入标题">
+					</div>
+					<div class="pull-right"><a href="javascript:void(0);" onclick="doChangeEditor()">切换编辑器 </a> </div>
+					<label>
+						<#if slugDisplay ??>
+							网址:<span id="url_preffix"></span><span id="slug_text">${(content.slug)!}</span>${(urlSuffix)!}
+						</#if>
+					</label>
+					<div class="box box-solid">
+						<div  class="box-body no-padding">
+							<textarea id="textarea"  name="content.text" >${(content.text)!}</textarea>
+						</div>
+					</div>
+					<div class="form-group input-group">
+						<span class="input-group-addon">设置排序权重:</span>
+						<input name="content.order_number" class="col-xs-6 form-control input-lg" id="order_number" value="${(content.order_number)!0}" type="text" placeholder="排序权重,正整数,数字越大的权重最大,非必填">
+					</div>
+					<div class="form-group input-group">
+						<span class="input-group-addon">设置初始阅读量:</span>
+						<input name="content.view_count" class="col-xs-6 form-control input-lg" id="view_content" value="${(content.view_count)!0}" type="text" placeholder="初始阅读数量,非必填">
+					</div>
+					<div class="form-group input-group">
+						<span class="input-group-addon">设置标签:</span>
+						<input name="content.flag" class="col-xs-6 form-control input-lg" id="flag" value="${(content.flag)!}" type="text" placeholder="例如 UAS,B2B,IM,B2C,被其他应用读取时作为区分">
+					</div>
+					<#include "_props_box.html" />
 				</div>
 				</div>
-				<div class="form-group input-group">
-					<span class="input-group-addon">设置标签:</span>
-					<input name="content.flag" class="col-xs-6 form-control input-lg" id="flag" value="${(content.flag)!}" type="text" placeholder="例如 UAS,B2B,IM,B2C,被其他应用读取时作为区分">
+				<!-- /.col -->
+				<div class="col-md-3">
+					<#include "_action_box.html" />
+					<#if module ??>
+						<#list module.taxonomyTypes! as taxonomyType >
+							<#if taxonomyType.formType == "select">
+								<#include "_select_box.html" />
+								<#else>
+									<#include "_input_box.html" />
+							</#if>
+						</#list>
+					</#if>
+					<#include "_thumbnail_box.html" />
 				</div>
 				</div>
-				<#include "_props_box.html" /> 
-			</div>
-			<!-- /.col -->
-			<div class="col-md-3">
-			<#include "_action_box.html" /> 
-			<#if module ??> 
-				<#list module.taxonomyTypes! as taxonomyType > 
-					<#if taxonomyType.formType == "select"> 
-						<#include "_select_box.html" />
-					<#else> 
-						<#include "_input_box.html" /> 
-					</#if> 
-				</#list>
-			</#if> 
-			<#include "_thumbnail_box.html" />
 			</div>
 			</div>
-		</div>
-		<!-- /.row -->
-	</form>
-</section>
+			<!-- /.row -->
+		</form>
+	</section>
+</#if>
+

+ 350 - 155
jpress-web-admin/src/main/webapp/WEB-INF/admin/content/_index_include.html

@@ -1,174 +1,369 @@
-<section class="content-header">
-	<h1>
-		所有内容
-	</h1>
-</section>
-
-<!-- Main content -->
-<section class="content">
-
-	<div class="row content-row">
-		<ul class="list-inline" style="float: left">
-			<li class="all">
-				<a class="current" href="${CPATH}/admin/content?m=${m!}&p=${p!}&c=${c!}">
-					全部 <span class="count">(${count!"0"})</span>
-				</a>
-				|
-			</li>
-			<li class="publish">
-				<a href="${CPATH}/admin/content?m=${m!}&p=${p!}&c=${c!}&s=normal">
-					已发布 <span class="count">(${normal_count!"0"})</span>
-				</a>
-				|
-			</li>
-			<li class="publish">
-				<a href="${CPATH}/admin/content?m=${m!}&p=${p!}&c=${c!}&s=draft">
-					草稿 <span class="count">(${draft_count!"0"})</span>
-				</a>
-				|
-			</li>
-			<li class="trash">
-				<a href="${CPATH}/admin/content?m=${m!}&p=${p!}&c=${c!}&s=delete">
-					垃圾箱 <span class="count">(${delete_count!"0"})</span>
-				</a>
-			</li>
-		</ul>
-
-
-		<form class="form-horizontal" method="POST" style="float: right" action="${CPATH}/admin/content?m=${m!}&p=${p!}&c=${c!}&s=${s!}&tids=${tids!}">
-			<div class="input-group input-group-sm">
-				<input id="post-search-input" class="form-control" type="search" value="${k!}" name="k" placeholder="请输入关键词">&nbsp;&nbsp;
-				<input id="search-submit" class="btn btn-default btn-sm" type="submit" value="搜索">
-			</div>
-		</form>
-	</div>
-
-	<div class="row content-row">
-		<div class="jp-left">
-			<select class="form-control input-sm jp-width120" name="action">
-				<option value="">==批量操作==</option>
-				<option value="delete">删除</option>
-			</select>
-		</div>
-		<div class="jp-left  ">
-			<button class="btn btn-block btn-sm btn-default" type="button" onclick="batchAction()">应用</button>
-		</div>
-		
-		<#if _taxonomyMap ??>
-		<#list  _taxonomyMap.keySet() as _title>
-			<div class="jp-left">
-				<select class="form-control input-sm jp-width120 jp-selected"  >
-					<option value="">全部${_title!}</option>
-					<#if _taxonomyMap.get(_title) ??>
-						<#list _taxonomyMap.get(_title) as taxonomy >
-						<option value="${taxonomy.id!}" ${taxonomy._selected!}>${taxonomy.layerString!}${taxonomy.title!}</option>
-						</#list> 
-					</#if>
-				</select>
-			</div>
-		</#list> 
-		</#if>
-		
-		<#if _taxonomyMap ??>
-		<div class="jp-left  ">
-			<form action="${CPATH}/admin/content?m=${m!}&p=${p!}&c=${c!}&s=${s!}&k=${k!}" method="POST">
-			<input type="hidden"  class="tids" name="tids" >
-			<input type="submit" class="btn btn-block btn-sm btn-default" value="筛选" />
+<style>
+	.bodyUas td.chooseUas select{
+		width: 130px;
+		/*height: 30px;*/
+		border: 1px solid #aaacad;
+	}
+	.bodyUas tr td.titleUas input{
+		margin-right: 5px;
+	}
+	.bodyUas tr td.titleUas{
+		color: #3a9cf4;
+	}
+	.bodyUas tr:nth-child(even){
+		background: #f8f8f8 ;
+	}
+    /*分頁*/
+    .content .pageUas{
+        margin-top: 20px;
+    }
+</style>
+<#if module ?? && module.name=="uuhelper">
+	<!-- admin后台软文列表界面 -->
+	<section class="content-header">
+		<h1>
+			所有内容
+		</h1>
+	</section>
+
+	<!-- Main content -->
+	<section class="content">
+
+		<div class="row content-row">
+			<ul class="list-inline" style="float: left">
+                <!-- class="current" 控制初始显示 -->
+				<li class="publish">
+					<a class="current" href="${CPATH}/admin/content?m=${m!}&p=${p!}&c=${c!}&s=normal">
+						已发布 <span class="count">(${normal_count!"0"})</span>
+					</a>
+					|
+				</li>
+				<li class="publish">
+					<a href="${CPATH}/admin/content?m=${m!}&p=${p!}&c=${c!}&s=draft">
+						草稿 <span class="count">(${draft_count!"0"})</span>
+					</a>
+					|
+				</li>
+				<li class="trash">
+					<a href="${CPATH}/admin/content?m=${m!}&p=${p!}&c=${c!}&s=delete">
+						垃圾箱 <span class="count">(${delete_count!"0"})</span>
+					</a>
+				</li>
+			</ul>
+
+
+			<form class="form-horizontal" method="POST" style="float: right" action="${CPATH}/admin/content/index?m=${m!}&p=${p!}&c=${c!}&s=${s!}&tids=${tids!}">
+				<div class="input-group input-group-sm">
+					<input type="hidden" id="choosePushTime" name="pushTime" value="${defaultPushTime!}">
+					<input type="hidden" id="chooseAuthor" name="author" value="${defaultAuthor!}">
+					<input type="hidden" id="chooseCopyRight" name="copyRight" value="${defaultCopyRight!}">
+					<input type="hidden" id="chooseTaxonomy" name="taxonomy" value="${defaultTaxonomy!}">
+
+
+					<input id="post-search-input" class="form-control" type="search" value="${k!}" name="k" placeholder="请输入关键词">&nbsp;&nbsp;
+					<input id="search-submit" class="btn btn-default btn-sm" type="submit" value="搜索">
+				</div>
 			</form>
 			</form>
 		</div>
 		</div>
-		</#if>	
-	</div>
-
-	<div class="box">
-		<!-- /.box-header -->
-		<div class="box-body">
-			<form action="" method="POST" id="form">
-				<input type="hidden" name="ucode" value="${ucode}">
-				<table class="table table-striped" style="word-break:break-all">
-					<thead>
+		<div class="box">
+			<!-- /.box-header -->
+			<div class="box-body">
+				<form action="" method="POST" id="form">
+					<input type="hidden" name="ucode" value="${ucode}">
+					<table class="table table-striped" style="word-break:break-all">
+						<thead>
 						<tr>
 						<tr>
-							<th style="width:20px;"><input name="dataItem" onclick="checkAll(this)" type="checkbox" value="0"></th>
-							<th >标题</th>
-							<th style="width:10%">作者</th> 
-							<#if (module.taxonomyTypes) ??> 
-								<#list module.taxonomyTypes as taxonomyType>
-								<th style="width:15%">${(taxonomyType.title)!}</th> 
-								</#list> 
-							</#if>
-							<th style="width:5%"><i class="fa fa-commenting"></i></th>
-							<th style="width:90px;">发布日期</th>
+							<th width="20"><input type="checkbox"></th>
+							<th width="200">标题</th>
+							<th width="135">日期</th>
+							<th width="110">作者</th>
+							<th width="110">版权</th>
+							<th width="120">类别</th>
+							<th width="100">留言条数</th>
+						</tr>
+						</thead>
+						<tbody class="bodyUas">
+						<tr>
+							<td><input name="dataItem" onclick="checkAll(this)" type="checkbox" value="0"></td>
+							<td></td>
+							<td class="chooseUas">
+								<select style="position: absolute;z-index: 1; width: 110px;"  class="choose choosePushTime"
+										onmousedown="if(this.options.length>5){this.size=6}" onblur="this.size=0" onchange="this.size=0;choosePushTime()">
+									<option value="">所有</option>
+									<#if push_time_list??>
+										<#list push_time_list as push_time>
+											<option <#if defaultPushTime?? && push_time?? && defaultPushTime == push_time>selected="selected"</#if> value="${push_time!}">${push_time!}</option>
+										</#list>
+									</#if>
+								</select>
+							</td>
+							<td class="chooseUas">
+								<select style="position: absolute;z-index: 1; width: 110px;"  class="choose chooseAuthor"
+										onmousedown="if(this.options.length>5){this.size=6}" onblur="this.size=0" onchange="this.size=0;chooseAuthor()">
+									<option value="">所有</option>
+									<#if author_list??>
+										<#list author_list as author>
+											<option <#if defaultAuthor?? && author?? && defaultAuthor == author>selected="selected"</#if> value="${author!}">${author!}</option>
+										</#list>
+									</#if>
+								</select>
+							</td>
+							<td class="chooseUas">
+								<select style="position: absolute;z-index: 1;"  class="choose chooseCopyRight"
+										onmousedown="if(this.options.length>5){this.size=6}" onblur="this.size=0" onchange="this.size=0;chooseCopyRight()">
+									<option value="">所有</option>
+									<#if copy_right_list??>
+										<#list copy_right_list as copy_right>
+											<option <#if defaultCopyRight?? && copy_right?? && defaultCopyRight == copy_right>selected="selected"</#if> value="${copy_right!}">${copy_right!}</option>
+										</#list>
+									</#if>
+								</select>
+							</td>
+							<td class="chooseUas">
+								<select style="position: absolute;z-index: 1;width: 110px;"  class="choose chooseTaxonomy"
+										onmousedown="if(this.options.length>5){this.size=6}" onblur="this.size=0" onchange="this.size=0;chooseTaxonomy()">
+									<option value="">所有</option>
+									<#if tag_list??>
+										<#list tag_list as tag>
+											<option <#if defaultTaxonomy?? && tag?? && defaultTaxonomy == tag>selected="selected"</#if> value="${tag!}">${tag!}</option>
+										</#list>
+									</#if>
+								</select>
+							</td>
+							<td class="chooseUas">
+								<select style="position: absolute;z-index: 1; width: 110px;"  class="choose"
+										onmousedown="if(this.options.length>5){this.size=6}" onblur="this.size=0" onchange="this.size=0">
+									<option></option>
+								</select>
+							</td>
 						</tr>
 						</tr>
-					</thead>
-					<tbody>
 						<#if page??> <#list page.getList() as bean>
 						<#if page??> <#list page.getList() as bean>
+                        <!-- class="jp-onmouse" 控制操作显示 -->
 						<tr class="jp-onmouse">
 						<tr class="jp-onmouse">
-							<td><input name="dataItem" type="checkbox" value="${bean.id}"></td>
-							<td><strong><a href="${CPATH}/admin/content/edit?id=${bean.id}&c=edit&p=${p!}">
-							<span class="article-title">${bean.title!}</span></a> <#if "draft" == bean.status!>(草稿)</#if></strong>
+							<td class="titleUas"><input name="dataItem" type="checkbox" value="${bean.id}"></td>
+							<td>
+								<strong>
+									<a href="${CPATH}/admin/content/edit?id=${bean.id}&c=edit&p=${p!}">
+									    <span class="article-title">${bean.title!}</span>
+									</a> <#if "draft" == bean.status!>(草稿)</#if>
+								</strong>
 								<div class="jp-flash-comment">
 								<div class="jp-flash-comment">
 									<p class="row-actions jp-cancel-pad">
 									<p class="row-actions jp-cancel-pad">
-										<#if "delete" != s!> 
-										<span class="approve"> <a class="vim-a" href="${CPATH}/admin/content/edit?id=${bean.id}&c=edit&p=${p!}&m=${m!}">编辑</a></span> 
-											<#if "draft" != bean.status!> 
-											<span class="approve">|<a class="vim-a" href="javascript:draft('${bean.id}')">草稿</a></span> 
-											</#if>
-										<span class="spam">|<a class="vim-s vim-destructive" href="javascript:trash('${bean.id}')">垃圾箱</a></span> 
-										<span class="trash">|<a class="delete vim-d vim-destructive" href="${bean.url!}" target="_blank">查看</a>
-										</span> 
-										<#else> 
-										<span class="approve"> <a class="vim-a" href="javascript:restore('${bean.id}')">还原</a></span> 
-										<span class="spam">|<a class="vim-s vim-destructive" href="javascript:del('${bean.id}')">永久删除</a></span> 
+									<#if "delete" != s!>
+										<span class="approve"> <a class="vim-a" href="${CPATH}/admin/content/edit?id=${bean.id}&c=edit&p=${p!}&m=${m!}">编辑</a></span>
+										<#if "draft" != bean.status!>
+											<span class="approve">|<a class="vim-a" href="javascript:draft('${bean.id}')">草稿</a></span>
 										</#if>
 										</#if>
+										<span class="spam">|<a class="vim-s vim-destructive" href="javascript:trash('${bean.id}')">垃圾箱</a></span>
+										<span class="trash">|<a class="delete vim-d vim-destructive" href="${bean.url!}" target="_blank">查看</a></span>
+									<#else>
+										<span class="approve"> <a class="vim-a" href="javascript:restore('${bean.id}')">还原</a></span>
+										<span class="spam">|<a class="vim-s vim-destructive" href="javascript:del('${bean.id}')">永久删除</a></span>
+									</#if>
 									</p>
 									</p>
 								</div>
 								</div>
 							</td>
 							</td>
-							<td>${(bean.username)!}</td> 
-							<#if (module.taxonomyTypes) ??>  
-								<#list module.taxonomyTypes as taxonomyType>
-								<td>${(bean.getTaxonomyAsUrl(taxonomyType.name,"target=\"_blank\""))!}</td> 
-								</#list> 
-							</#if>
-							<td>
-							<a href="${CPATH}/admin/comment?t=comment&c=comment&m=${m!}&p=${p!}&cid=${bean.id!}">
-							${bean.commentCount!}
-							</a>
-							</td>
-							<td>${bean.created!}</td>
+							<td>${(bean.metadata("push_time"))!}</td>
+							<td>${(bean.author)!}</td>
+							<td>${(bean.metadata("copy_right"))!}</td>
+							<td>${bean.getTaxonomyAsString("tag")!}</td>
+							<td>${(bean.comment_count)!}</td>
 						</tr>
 						</tr>
-						</#list> 
+						</#list>
 						</#if>
 						</#if>
-					</tbody>
-					<tfoot>
-						<tr>
-							<th style="width:20px;"><input name="dataItem" onclick="checkAll(this)" type="checkbox" value="0"></th>
-							<th >标题</th>
-							<th style="width:10%">作者</th> 
-							<#if (module.taxonomyTypes) ??> 
-								<#list module.taxonomyTypes as taxonomyType>
-								<th style="width:15%">${(taxonomyType.title)!}</th> 
-								</#list> 
-							</#if>
-							<th style="width:5%"><i class="fa fa-commenting"></i></th>
-							<th style="width:90px;">发布日期</th>
-						</tr>
-					</tfoot>
-				</table>
+						</tbody>
+						<tfoot>
+					</table>
 				</form>
 				</form>
+			</div>
+			<!-- /.box-body -->
 		</div>
 		</div>
-		<!-- /.box-body -->
-	</div>
-	
-	<div class="cf">
-		<div class="pull-right " >
-			
-			<#if page??> 
-			<#include "../_inc/_paginate.html" /> 
-			<@paginate currentPage=page.pageNumber totalPage=page.totalPage actionUrl="?p="+(p!)+"&c="+(c!)+"&m="+(m!)+"&t="+(t!)+"&s="+(s!)+"&k="+(k!)+"&tids="+(tids!)+"&page="/> 
+
+		<div class="cf pageUas">
+			<div class="pull-right " >
+
+				<#if page??>
+					<#include "../_inc/_paginate.html" />
+					<@paginate currentPage=page.pageNumber totalPage=page.totalPage actionUrl="?p="+(p!)+"&c="+(c!)+"&m="+(m!)+"&t="+(t!)+"&s="+(s!)+"&k="+(k!)+"&pushTime="+(defaultPushTime!)+"&author="+(defaultAuthor!)+"&copyRight="+(defaultCopyRight!)+"&taxonomy="+(defaultTaxonomy!)+"&tids="+(tids!)+"&page="/>
+				</#if>
+
+			</div>
+		</div>
+
+		<!-- /.row -->
+	</section>
+
+<#else>
+	<section class="content-header">
+		<h1>
+			所有内容
+		</h1>
+	</section>
+
+	<!-- Main content -->
+	<section class="content">
+
+		<div class="row content-row">
+			<ul class="list-inline" style="float: left">
+				<li class="all">
+					<a class="current" href="${CPATH}/admin/content?m=${m!}&p=${p!}&c=${c!}">
+						全部 <span class="count">(${count!"0"})</span>
+					</a>
+					|
+				</li>
+				<li class="publish">
+					<a href="${CPATH}/admin/content?m=${m!}&p=${p!}&c=${c!}&s=normal">
+						已发布 <span class="count">(${normal_count!"0"})</span>
+					</a>
+					|
+				</li>
+				<li class="publish">
+					<a href="${CPATH}/admin/content?m=${m!}&p=${p!}&c=${c!}&s=draft">
+						草稿 <span class="count">(${draft_count!"0"})</span>
+					</a>
+					|
+				</li>
+				<li class="trash">
+					<a href="${CPATH}/admin/content?m=${m!}&p=${p!}&c=${c!}&s=delete">
+						垃圾箱 <span class="count">(${delete_count!"0"})</span>
+					</a>
+				</li>
+			</ul>
+
+
+			<form class="form-horizontal" method="POST" style="float: right" action="${CPATH}/admin/content?m=${m!}&p=${p!}&c=${c!}&s=${s!}&tids=${tids!}">
+				<div class="input-group input-group-sm">
+					<input id="post-search-input" class="form-control" type="search" value="${k!}" name="k" placeholder="请输入关键词">&nbsp;&nbsp;
+					<input id="search-submit" class="btn btn-default btn-sm" type="submit" value="搜索">
+				</div>
+			</form>
+		</div>
+
+		<div class="row content-row">
+			<div class="jp-left">
+				<select class="form-control input-sm jp-width120" name="action">
+					<option value="">==批量操作==</option>
+					<option value="delete">删除</option>
+				</select>
+			</div>
+			<div class="jp-left  ">
+				<button class="btn btn-block btn-sm btn-default" type="button" onclick="batchAction()">应用</button>
+			</div>
+
+			<#if _taxonomyMap ??>
+			<#list  _taxonomyMap.keySet() as _title>
+				<div class="jp-left">
+					<select class="form-control input-sm jp-width120 jp-selected"  >
+						<option value="">全部${_title!}</option>
+						<#if _taxonomyMap.get(_title) ??>
+							<#list _taxonomyMap.get(_title) as taxonomy >
+							<option value="${taxonomy.id!}" ${taxonomy._selected!}>${taxonomy.layerString!}${taxonomy.title!}</option>
+							</#list>
+						</#if>
+					</select>
+				</div>
+			</#list>
+			</#if>
+
+			<#if _taxonomyMap ??>
+			<div class="jp-left  ">
+				<form action="${CPATH}/admin/content?m=${m!}&p=${p!}&c=${c!}&s=${s!}&k=${k!}" method="POST">
+				<input type="hidden"  class="tids" name="tids" >
+				<input type="submit" class="btn btn-block btn-sm btn-default" value="筛选" />
+				</form>
+			</div>
 			</#if>
 			</#if>
+		</div>
 
 
+		<div class="box">
+			<!-- /.box-header -->
+			<div class="box-body">
+				<form action="" method="POST" id="form">
+					<input type="hidden" name="ucode" value="${ucode}">
+					<table class="table table-striped" style="word-break:break-all">
+						<thead>
+							<tr>
+								<th style="width:20px;"><input name="dataItem" onclick="checkAll(this)" type="checkbox" value="0"></th>
+								<th >标题</th>
+								<th style="width:10%">作者</th>
+								<#if (module.taxonomyTypes) ??>
+									<#list module.taxonomyTypes as taxonomyType>
+									<th style="width:15%">${(taxonomyType.title)!}</th>
+									</#list>
+								</#if>
+								<th style="width:5%"><i class="fa fa-commenting"></i></th>
+								<th style="width:90px;">发布日期</th>
+							</tr>
+						</thead>
+						<tbody>
+							<#if page??> <#list page.getList() as bean>
+							<tr class="jp-onmouse">
+								<td><input name="dataItem" type="checkbox" value="${bean.id}"></td>
+								<td><strong><a href="${CPATH}/admin/content/edit?id=${bean.id}&c=edit&p=${p!}">
+								<span class="article-title">${bean.title!}</span></a> <#if "draft" == bean.status!>(草稿)</#if></strong>
+									<div class="jp-flash-comment">
+										<p class="row-actions jp-cancel-pad">
+											<#if "delete" != s!>
+											<span class="approve"> <a class="vim-a" href="${CPATH}/admin/content/edit?id=${bean.id}&c=edit&p=${p!}&m=${m!}">编辑</a></span>
+												<#if "draft" != bean.status!>
+												<span class="approve">|<a class="vim-a" href="javascript:draft('${bean.id}')">草稿</a></span>
+												</#if>
+											<span class="spam">|<a class="vim-s vim-destructive" href="javascript:trash('${bean.id}')">垃圾箱</a></span>
+											<span class="trash">|<a class="delete vim-d vim-destructive" href="${bean.url!}" target="_blank">查看</a>
+											</span>
+											<#else>
+											<span class="approve"> <a class="vim-a" href="javascript:restore('${bean.id}')">还原</a></span>
+											<span class="spam">|<a class="vim-s vim-destructive" href="javascript:del('${bean.id}')">永久删除</a></span>
+											</#if>
+										</p>
+									</div>
+								</td>
+								<td>${(bean.username)!}</td>
+								<#if (module.taxonomyTypes) ??>
+									<#list module.taxonomyTypes as taxonomyType>
+									<td>${(bean.getTaxonomyAsUrl(taxonomyType.name,"target=\"_blank\""))!}</td>
+									</#list>
+								</#if>
+								<td>
+								<a href="${CPATH}/admin/comment?t=comment&c=comment&m=${m!}&p=${p!}&cid=${bean.id!}">
+								${bean.commentCount!}
+								</a>
+								</td>
+								<td>${bean.created!}</td>
+							</tr>
+							</#list>
+							</#if>
+						</tbody>
+						<tfoot>
+							<tr>
+								<th style="width:20px;"><input name="dataItem" onclick="checkAll(this)" type="checkbox" value="0"></th>
+								<th >标题</th>
+								<th style="width:10%">作者</th>
+								<#if (module.taxonomyTypes) ??>
+									<#list module.taxonomyTypes as taxonomyType>
+									<th style="width:15%">${(taxonomyType.title)!}</th>
+									</#list>
+								</#if>
+								<th style="width:5%"><i class="fa fa-commenting"></i></th>
+								<th style="width:90px;">发布日期</th>
+							</tr>
+						</tfoot>
+					</table>
+					</form>
+			</div>
+			<!-- /.box-body -->
+		</div>
+		<div class="cf">
+			<div class="pull-right " >
+
+				<#if page??>
+				<#include "../_inc/_paginate.html" />
+				<@paginate currentPage=page.pageNumber totalPage=page.totalPage actionUrl="?p="+(p!)+"&c="+(c!)+"&m="+(m!)+"&t="+(t!)+"&s="+(s!)+"&k="+(k!)+"&tids="+(tids!)+"&page="/>
+				</#if>
+
+			</div>
 		</div>
 		</div>
-	</div>
-		
-	<!-- /.row -->
-</section>
-<!-- /.content -->
+		<!-- /.row -->
+	</section>
+	<!-- /.content -->
+</#if>

+ 74 - 9
jpress-web-admin/src/main/webapp/WEB-INF/admin/content/edit.html

@@ -1,5 +1,41 @@
 <#include "../_inc/_layout.html"/> 
 <#include "../_inc/_layout.html"/> 
 <#macro script>
 <#macro script>
+
+function commentable(){
+    var checkbox = $('.checkbox')[0];
+	var commentStatus = $('#comment_status');
+    if (checkbox.classList.contains("active")) {
+		commentStatus.attr("value","close");
+		checkbox.classList.remove('active');
+	} else {
+		commentStatus.attr("value","open");
+		checkbox.classList.add('active');
+	}
+}
+
+function getPushTime(){
+	//var now = new Date();
+	//格式化日,如果小于9,前面补0
+	//var day = ("0" + now.getDate()).slice(-2);
+	//格式化月,如果小于9,前面补0
+	//var month = ("0" + (now.getMonth() + 1)).slice(-2);
+	//拼装完整日期格式
+	//var today = now.getFullYear()+"-"+(month)+"-"+(day) ;
+	//完成赋值
+	//$('#createDefaultTime').val(today);
+
+	var pushDate = $('.push_time');
+	var createDefaultTime = $('#createDefaultTime');
+	createDefaultTime.attr("value",createDefaultTime.val());
+	pushDate.attr("value",createDefaultTime.val());
+}
+
+function countSummaryLength(){
+    var summary = $('#content_summary');
+    var CountUas = $('.CountLengthUas');
+    CountUas.html(summary.val().length);
+}
+
 var data={
 var data={
     url:'',
     url:'',
     alt:''
     alt:''
@@ -32,7 +68,7 @@ function initTinymce(){
 			    		callback(data.url, {alt: data.alt});
 			    		callback(data.url, {alt: data.alt});
 			    	}
 			    	}
 			    }
 			    }
-			}); 
+			});
 		 },
 		 },
         plugins: [
         plugins: [
 		    "advlist autolink autosave link image media imagetools lists charmap print preview hr anchor pagebreak spellchecker",
 		    "advlist autolink autosave link image media imagetools lists charmap print preview hr anchor pagebreak spellchecker",
@@ -56,14 +92,14 @@ if("tinymce" == _editor){
 	initMarkdownEditor();
 	initMarkdownEditor();
 }
 }
     
     
-function save(){
+function save(turnpage){
 	
 	
 	 $('#content_slug').attr('value',$("#slug_text").text());
 	 $('#content_slug').attr('value',$("#slug_text").text());
-	
+
 	if("tinymce" == _editor){
 	if("tinymce" == _editor){
 		tinymce.activeEditor.uploadImages(function(success) {
 		tinymce.activeEditor.uploadImages(function(success) {
 			tinymce.triggerSave();
 			tinymce.triggerSave();
-	 		doSubmit();
+	 		doSubmit(turnpage);
 		});
 		});
 	}else{
 	}else{
 		$("#textarea").text(simplemde.markdown(simplemde.value()));
 		$("#textarea").text(simplemde.markdown(simplemde.value()));
@@ -71,20 +107,41 @@ function save(){
 	}
 	}
 	return false;
 	return false;
  }
  }
- 
- function saveAsDraft(){
+
+function doPreview(){
+	saveAsDraft(turnPage);
+
+	/*var slug = $('#content_slug').val();
+	if("" == slug) {
+		slug = $('#title').val();
+	}*/
+
+
+
+}
+
+function turnPage(){
+	var contentId = $("#content_id").val();
+	window.location.href = "${CPATH}/admin/content/edit?id="+contentId+"&c=edit&p=uuhelper&m=uuhelper";
+}
+
+ function saveAsDraft(turnpage){
  	$("#content_status").attr("value","draft");
  	$("#content_status").attr("value","draft");
- 	save();
+ 	save(turnpage);
  }
  }
  
  
- function doSubmit(){
+ function doSubmit(turnpage){
  	$("#form").ajaxSubmit({
  	$("#form").ajaxSubmit({
 			type : "post", 
 			type : "post", 
 			dataType : "json", 
 			dataType : "json", 
-			success : function(data) { 
+			success : function(data) {
+
 				if(data.errorCode == 0){
 				if(data.errorCode == 0){
 					$("#content_id").attr("value",data.data);
 					$("#content_id").attr("value",data.data);
 					toastr.success('保存成功!','操作成功');
 					toastr.success('保存成功!','操作成功');
+					if(turnpage) {
+						turnpage();
+					}
 				}else{
 				}else{
 					toastr.error(data.message,'操作失败');
 					toastr.error(data.message,'操作失败');
 				}
 				}
@@ -161,6 +218,10 @@ $(document).ready(function(){
      $('#titleurl').on('save', function(e, params) {
      $('#titleurl').on('save', function(e, params) {
     	 $('#content_slug').attr('value',params.newValue);
     	 $('#content_slug').attr('value',params.newValue);
 	 });
 	 });
+
+	<#if content?? && "uuhelper" == content.module && ""!=content.url>
+		window.open($("#content_url").val());
+	</#if>
 });
 });
 </#macro> 
 </#macro> 
 <#macro script_import>
 <#macro script_import>
@@ -169,11 +230,15 @@ $(document).ready(function(){
 <script src="${CPATH}/static/plugins/tag/jquery.tag-editor.min.js"></script>
 <script src="${CPATH}/static/plugins/tag/jquery.tag-editor.min.js"></script>
 <script src="${CPATH}/static/plugins/editable/bootstrap-editable.min.js"></script>
 <script src="${CPATH}/static/plugins/editable/bootstrap-editable.min.js"></script>
 <script src="${CPATH}/static/simplemde/simplemde.min.js"></script>
 <script src="${CPATH}/static/simplemde/simplemde.min.js"></script>
+<script src="${CTPATH}/assets/js/jquery.imgareaselect.pack.js"></script>
+
+
 </#macro>
 </#macro>
 <#macro css_import>
 <#macro css_import>
 <link rel="stylesheet" href="${CPATH}/static/plugins/tag/jquery.tag-editor.css">
 <link rel="stylesheet" href="${CPATH}/static/plugins/tag/jquery.tag-editor.css">
 <link rel="stylesheet" href="${CPATH}/static/plugins/editable/bootstrap-editable.css">
 <link rel="stylesheet" href="${CPATH}/static/plugins/editable/bootstrap-editable.css">
 <link rel="stylesheet" href="${CPATH}/static/simplemde/simplemde.min.css">
 <link rel="stylesheet" href="${CPATH}/static/simplemde/simplemde.min.css">
+<link rel="stylesheet" type="text/css" href="${CTPATH}/assets/css/imgareaselect-default.css"/>
 </#macro>
 </#macro>
 <#macro css>
 <#macro css>
 .editable-input {
 .editable-input {

+ 29 - 0
jpress-web-admin/src/main/webapp/WEB-INF/admin/content/index.html

@@ -1,5 +1,34 @@
 <#include "../_inc/_layout.html"/> 
 <#include "../_inc/_layout.html"/> 
 <#macro script>
 <#macro script>
+function choosePushTime() {
+	var choosePushTimeSelect = $(".choosePushTime")[0];
+	var pushTime = choosePushTimeSelect.value;
+	var choosePushTimeInput = $("#choosePushTime");
+	choosePushTimeInput.attr("value",pushTime);
+	$(".form-horizontal").submit();
+}
+function chooseAuthor() {
+	var chooseAuthorSelect = $(".chooseAuthor")[0];
+	var author = chooseAuthorSelect.value;
+	var chooseAuthorInput = $("#chooseAuthor");
+	chooseAuthorInput.attr("value",author);
+	$(".form-horizontal").submit();
+}
+function chooseCopyRight() {
+	var chooseCopyRightSelect = $(".chooseCopyRight")[0];
+	var copyRight = chooseCopyRightSelect.value;
+	var chooseCopyRightInput = $("#chooseCopyRight");
+	chooseCopyRightInput.attr("value",copyRight);
+	$(".form-horizontal").submit();
+}
+function chooseTaxonomy() {
+	var chooseTaxonomySelect = $(".chooseTaxonomy")[0];
+	var taxonomy = chooseTaxonomySelect.value;
+	var chooseTaxonomyInput = $("#chooseTaxonomy");
+	chooseTaxonomyInput.attr("value",taxonomy);
+	$(".form-horizontal").submit();
+}
+
 function trash(id){
 function trash(id){
 	$.get("${CPATH}/admin/content/trash?ucode=${ucode}&id="+id, function(result){
 	$.get("${CPATH}/admin/content/trash?ucode=${ucode}&id="+id, function(result){
 		if(result.errorCode > 0){
 		if(result.errorCode > 0){

+ 10 - 4
jpress-web-core/src/main/java/io/jpress/ui/freemarker/tag/CommentPageTag.java

@@ -15,11 +15,8 @@
  */
  */
 package io.jpress.ui.freemarker.tag;
 package io.jpress.ui.freemarker.tag;
 
 
-import javax.servlet.http.HttpServletRequest;
-
 import com.jfinal.core.JFinal;
 import com.jfinal.core.JFinal;
 import com.jfinal.plugin.activerecord.Page;
 import com.jfinal.plugin.activerecord.Page;
-
 import io.jpress.core.render.freemarker.BasePaginateTag;
 import io.jpress.core.render.freemarker.BasePaginateTag;
 import io.jpress.core.render.freemarker.JTag;
 import io.jpress.core.render.freemarker.JTag;
 import io.jpress.model.Comment;
 import io.jpress.model.Comment;
@@ -27,6 +24,8 @@ import io.jpress.model.Content;
 import io.jpress.model.query.CommentQuery;
 import io.jpress.model.query.CommentQuery;
 import io.jpress.utils.StringUtils;
 import io.jpress.utils.StringUtils;
 
 
+import javax.servlet.http.HttpServletRequest;
+
 public class CommentPageTag extends JTag {
 public class CommentPageTag extends JTag {
 	
 	
 	public static final String TAG_NAME = "jp.commentPage";
 	public static final String TAG_NAME = "jp.commentPage";
@@ -45,8 +44,14 @@ public class CommentPageTag extends JTag {
 	public void onRender() {
 	public void onRender() {
 
 
 		int pageSize = getParamToInt("pageSize", 10);
 		int pageSize = getParamToInt("pageSize", 10);
+		int pageNumber = getParamToInt("pageNumber", 1);
 
 
-		Page<Comment> page = CommentQuery.me().paginateByContentId(pageNumber, pageSize, content.getId());
+		Page<Comment> page;
+		if ("uuhelper".equals(content.getModule())) {
+			page = CommentQuery.me().uuHelperPaginateByContentId(pageNumber, pageSize, content.getId(), content.getModule());
+		} else {
+			page = CommentQuery.me().paginateByContentId(pageNumber, pageSize, content.getId());
+		}
 		setVariable("page", page);
 		setVariable("page", page);
 		setVariable("comments", page.getList());
 		setVariable("comments", page.getList());
 		
 		
@@ -56,6 +61,7 @@ public class CommentPageTag extends JTag {
 		renderBody();
 		renderBody();
 	}
 	}
 
 
+
 	public static class CommentPaginateTag extends BasePaginateTag {
 	public static class CommentPaginateTag extends BasePaginateTag {
 
 
 		final Content content;
 		final Content content;

BIN
jpress-web-core/src/main/webapp/static/jpress/admin/image/dot.png


BIN
jpress-web-core/src/main/webapp/static/jpress/admin/image/hands.png


BIN
jpress-web-core/src/main/webapp/static/jpress/admin/image/loading.png


BIN
jpress-web-core/src/main/webapp/static/jpress/admin/image/pen.png


BIN
jpress-web-core/src/main/webapp/static/jpress/admin/image/support.png


BIN
jpress-web-core/src/main/webapp/static/jpress/admin/image/xiala.png


+ 174 - 7
jpress-web-front/src/main/java/io/jpress/front/controller/CommentController.java

@@ -15,22 +15,24 @@
  */
  */
 package io.jpress.front.controller;
 package io.jpress.front.controller;
 
 
-import java.math.BigInteger;
-import java.util.Date;
-
+import com.jfinal.plugin.activerecord.Page;
 import io.jpress.Consts;
 import io.jpress.Consts;
 import io.jpress.core.BaseFrontController;
 import io.jpress.core.BaseFrontController;
 import io.jpress.core.cache.ActionCacheManager;
 import io.jpress.core.cache.ActionCacheManager;
 import io.jpress.model.Comment;
 import io.jpress.model.Comment;
 import io.jpress.model.Content;
 import io.jpress.model.Content;
 import io.jpress.model.User;
 import io.jpress.model.User;
-import io.jpress.model.query.ContentQuery;
-import io.jpress.model.query.OptionQuery;
-import io.jpress.model.query.UserQuery;
+import io.jpress.model.Vote;
+import io.jpress.model.query.*;
 import io.jpress.router.RouterMapping;
 import io.jpress.router.RouterMapping;
 import io.jpress.utils.CookieUtils;
 import io.jpress.utils.CookieUtils;
 import io.jpress.utils.StringUtils;
 import io.jpress.utils.StringUtils;
 
 
+import java.math.BigInteger;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.List;
+
 @RouterMapping(url = "/comment")
 @RouterMapping(url = "/comment")
 public class CommentController extends BaseFrontController {
 public class CommentController extends BaseFrontController {
 
 
@@ -60,13 +62,16 @@ public class CommentController extends BaseFrontController {
 		}
 		}
 
 
 		BigInteger userId = StringUtils.toBigInteger(CookieUtils.get(this, Consts.COOKIE_LOGINED_USER), null);
 		BigInteger userId = StringUtils.toBigInteger(CookieUtils.get(this, Consts.COOKIE_LOGINED_USER), null);
+		userId = null;
+		BigInteger uuUserId = getParaToBigInteger("uuUserId");
 
 
 		// 允许未登录用户评论
 		// 允许未登录用户评论
 		Boolean comment_allow_not_login = OptionQuery.me().findValueAsBool("comment_allow_not_login");
 		Boolean comment_allow_not_login = OptionQuery.me().findValueAsBool("comment_allow_not_login");
 
 
 		// 允许未登录用户评论
 		// 允许未登录用户评论
 		if (comment_allow_not_login == null || comment_allow_not_login == false) {
 		if (comment_allow_not_login == null || comment_allow_not_login == false) {
-			if (userId == null) {
+			//在不允许未登录用户评论,uuhelper只能在uuId和uuUserId都为空的情况下不准评论
+			if (userId == null && uuUserId == null) {
 				String redirect = Consts.ROUTER_USER_LOGIN;
 				String redirect = Consts.ROUTER_USER_LOGIN;
 				if (StringUtils.isNotBlank(gotoUrl)) {
 				if (StringUtils.isNotBlank(gotoUrl)) {
 					redirect += "?goto=" + StringUtils.urlEncode(gotoUrl);
 					redirect += "?goto=" + StringUtils.urlEncode(gotoUrl);
@@ -105,7 +110,13 @@ public class CommentController extends BaseFrontController {
 			return;
 			return;
 		}
 		}
 
 
+		String uuUserAvatar = getPara("uuUserAvatar");
+
 		String author = getPara("author");
 		String author = getPara("author");
+		if (userId == null && uuUserId != null) {
+			author = getPara("uuUserName");
+		}
+
 		String email = getPara("email");
 		String email = getPara("email");
 
 
 		String ip = getIPAddress();
 		String ip = getIPAddress();
@@ -141,6 +152,9 @@ public class CommentController extends BaseFrontController {
 		comment.setCreated(new Date());
 		comment.setCreated(new Date());
 		comment.setParentId(parentId);
 		comment.setParentId(parentId);
 
 
+		comment.setUuUserId(uuUserId);
+		comment.setUuUserAvatar(uuUserAvatar);
+
 		if (comment.save()) {
 		if (comment.save()) {
 			ActionCacheManager.clearCache();
 			ActionCacheManager.clearCache();
 		}
 		}
@@ -168,4 +182,157 @@ public class CommentController extends BaseFrontController {
 		}
 		}
 	}
 	}
 
 
+	public void lazyLoad() {
+		Page<Comment> page = CommentQuery.me().uuHelperPaginateByContentId(getParaToInt("pagenumber"), getParaToInt("pagesize"), getParaToBigInteger("contId"), "uuhelper");
+		List<Comment> list = page.getList();
+		StringBuilder htmlBuilder = new StringBuilder();
+		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+
+		BigInteger userId = getParaToBigInteger("userId");
+		BigInteger uuUserId = getParaToBigInteger("uuUserId");
+		if ("0".equals(userId.toString())) {
+			userId = null;
+		}
+		if ("0".equals(uuUserId.toString())) {
+			uuUserId = null;
+		}
+
+		for (int i = 0; i< list.size() ;i ++) {
+			Comment comment = list.get(i);
+			htmlBuilder.append("<div class=\"message\">");
+			htmlBuilder.append("<div class=\"left\">");
+			htmlBuilder.append("<div class=\"img\">");
+			htmlBuilder.append("<img src=\"/jpress/static/jpress/admin/image/dot.png\" alt=\"用户头像\">");
+			htmlBuilder.append("</div>");
+			htmlBuilder.append("</div>");
+			htmlBuilder.append("<div class=\"right\">");
+			htmlBuilder.append("<div class=\"detail\">");
+			htmlBuilder.append("<div class=\"title\">");
+			htmlBuilder.append("<span>"+ comment.getAuthor() +"<em>" + sdf.format(comment.getCreated()) + "</em></span>");
+			htmlBuilder.append("<span><img class=\"votedUas"+comment.getId());
+
+			//如果已赞,添加class="voted"
+			String imageUrl = null;
+			if (comment.isvoted(comment.getId(), userId, uuUserId)) {
+				htmlBuilder.append(" voted\" ");
+				imageUrl = "/jpress/static/jpress/admin/image/support.png";
+			} else {
+				htmlBuilder.append("\"");
+				imageUrl = "/jpress/static/jpress/admin/image/hands.png";
+			}
+
+			htmlBuilder.append(" src="+ imageUrl + " alt=\"\" onclick=\"vote("+ comment.getId()+")\"><em class=\"em" + comment.getId() + "\">" + comment.getVoteUp() + "</em></span>");
+			htmlBuilder.append("</div>");
+			htmlBuilder.append("<p>"+comment.getText()+"</p>");
+			if (comment.getlatestSon(comment.getId()) != null) {
+				Comment sonComment = comment.getlatestSon(comment.getId());
+				htmlBuilder.append("<div class=\"title reply\">");
+				htmlBuilder.append("<span>作者回复: <em>" + sdf.format(sonComment.getCreated()) + "</em></span>");
+				htmlBuilder.append("<span><img class=\"votedUas"+sonComment.getId());
+
+				//如果已赞,添加class="voted"
+				String sonImageUrl = null;
+				if (sonComment.isvoted(sonComment.getId(), userId, uuUserId)) {
+					htmlBuilder.append(" voted\" ");
+					sonImageUrl = "/jpress/static/jpress/admin/image/support.png";
+				} else {
+					htmlBuilder.append("\"");
+					sonImageUrl = "/jpress/static/jpress/admin/image/hands.png";
+				}
+
+				htmlBuilder.append(" src="+ sonImageUrl+ " alt=\"\" onclick=\"vote("+ sonComment.getId()+")\"><em class=\"em" + sonComment.getId() + "\">" + sonComment.getVoteUp() + "</em></span>");
+				htmlBuilder.append("</div>");
+				htmlBuilder.append("<p>"+sonComment.getText()+"</p>");
+			}
+			htmlBuilder.append("</div>\n" + "</div>\n" + " </div>");
+		}
+
+		renderAjaxResultForSuccess(htmlBuilder.toString());
+	}
+
+	//新增点赞
+	private void voteUp(Comment comment,BigInteger userId,BigInteger uuUserId){
+//		BigInteger commentId = getParaToBigInteger("comment_id");
+//		Comment comment = CommentQuery.me().findById(commentId);
+//		BigInteger userId = getParaToBigInteger("user_id");
+//		BigInteger uuUserId = getParaToBigInteger("uu_user_id");
+		Vote vote = getModel(Vote.class);
+		vote.setCommentId(comment.getId());
+		vote.setUserId(userId);
+		vote.setUuUserId(uuUserId);
+		vote.setUp(true);
+		vote.setDown(null);
+		vote.setIp(getIPAddress());
+		vote.setAgent(getUserAgent());
+		vote.setStatus(Vote.STATUS_NORMAL);
+		vote.setCreated(new Date());
+
+		if (vote.save()) {
+			//更新对应评论的点赞数
+			comment.updateVoteUpCount();
+			renderAjaxResultForSuccess();
+		} else {
+			renderAjaxResultForError();
+		}
+
+	}
+
+	//取消赞
+	private void cancelVoteUp(Comment comment,Vote vote){
+//		BigInteger commentId = getParaToBigInteger("comment_id");
+//		Comment comment = CommentQuery.me().findById(commentId);
+//		BigInteger userId = getParaToBigInteger("user_id");
+//		BigInteger uuUserId = getParaToBigInteger("uu_user_id");
+		vote.setUp(null);
+		if (vote.update()) {
+			//更新对应评论的点赞数
+			comment.updateVoteUpCount();
+			renderAjaxResultForSuccess();
+		} else {
+			renderAjaxResultForError();
+		}
+	}
+
+	//再次赞
+	private void againVoteUp(Comment comment,Vote vote){
+//		BigInteger commentId = getParaToBigInteger("comment_id");
+//		Comment comment = CommentQuery.me().findById(commentId);
+//		BigInteger userId = getParaToBigInteger("user_id");
+//		BigInteger uuUserId = getParaToBigInteger("uu_user_id");
+		vote.setUp(true);
+		if (vote.update()) {
+			//更新对应评论的点赞数
+			comment.updateVoteUpCount();
+			renderAjaxResultForSuccess();
+		} else {
+			renderAjaxResultForError();
+		}
+	}
+
+	//评论点赞接口
+	public void vote() {
+		BigInteger commentId = getParaToBigInteger("comment_id");
+		Comment comment = CommentQuery.me().findById(commentId);
+		BigInteger userId = getParaToBigInteger("user_id");
+		BigInteger uuUserId = getParaToBigInteger("uu_user_id");
+		if ("0".equals(userId.toString())) {
+			userId = null;
+		}
+		if ("0".equals(uuUserId.toString())) {
+			uuUserId = null;
+		}
+
+		Vote vote = VoteQuery.me().findCommentVote(commentId,userId,uuUserId);
+		//判断此用户是否给此评论点过赞
+		if (vote != null) {
+			if (vote.getUp() == null) {
+				againVoteUp(comment,vote);
+			} else {
+				cancelVoteUp(comment,vote);
+			}
+		} else {
+			voteUp(comment,userId,uuUserId);
+		}
+	}
+
 }
 }

+ 86 - 4
jpress-web-front/src/main/java/io/jpress/front/controller/ContentController.java

@@ -15,19 +15,17 @@
  */
  */
 package io.jpress.front.controller;
 package io.jpress.front.controller;
 
 
-import java.math.BigInteger;
-import java.util.List;
-
 import com.jfinal.render.Render;
 import com.jfinal.render.Render;
-
 import io.jpress.Consts;
 import io.jpress.Consts;
 import io.jpress.core.BaseFrontController;
 import io.jpress.core.BaseFrontController;
 import io.jpress.core.addon.HookInvoker;
 import io.jpress.core.addon.HookInvoker;
 import io.jpress.core.cache.ActionCache;
 import io.jpress.core.cache.ActionCache;
 import io.jpress.model.Content;
 import io.jpress.model.Content;
 import io.jpress.model.Taxonomy;
 import io.jpress.model.Taxonomy;
+import io.jpress.model.Vote;
 import io.jpress.model.query.ContentQuery;
 import io.jpress.model.query.ContentQuery;
 import io.jpress.model.query.TaxonomyQuery;
 import io.jpress.model.query.TaxonomyQuery;
+import io.jpress.model.query.VoteQuery;
 import io.jpress.router.RouterMapping;
 import io.jpress.router.RouterMapping;
 import io.jpress.template.TemplateManager;
 import io.jpress.template.TemplateManager;
 import io.jpress.template.TplModule;
 import io.jpress.template.TplModule;
@@ -37,6 +35,10 @@ import io.jpress.ui.freemarker.tag.NextContentTag;
 import io.jpress.ui.freemarker.tag.PreviousContentTag;
 import io.jpress.ui.freemarker.tag.PreviousContentTag;
 import io.jpress.utils.StringUtils;
 import io.jpress.utils.StringUtils;
 
 
+import java.math.BigInteger;
+import java.util.Date;
+import java.util.List;
+
 @RouterMapping(url = Consts.ROUTER_CONTENT)
 @RouterMapping(url = Consts.ROUTER_CONTENT)
 public class ContentController extends BaseFrontController {
 public class ContentController extends BaseFrontController {
 
 
@@ -81,6 +83,13 @@ public class ContentController extends BaseFrontController {
 		setAttr("p", page);
 		setAttr("p", page);
 		setAttr("content", content);
 		setAttr("content", content);
 
 
+		//接收移动端发送的用户信息
+		if ("uuhelper".equals(content.getModule())) {
+			setAttr("userid", getParaToBigInteger("userid"));
+			setAttr("username", getPara("username"));
+			setAttr("iconurl", getPara("iconurl"));
+		}
+
 		setAttr(NextContentTag.TAG_NAME, new NextContentTag(content));
 		setAttr(NextContentTag.TAG_NAME, new NextContentTag(content));
 		setAttr(PreviousContentTag.TAG_NAME, new PreviousContentTag(content));
 		setAttr(PreviousContentTag.TAG_NAME, new PreviousContentTag(content));
 
 
@@ -188,4 +197,77 @@ public class ContentController extends BaseFrontController {
 		HookInvoker.contentRenderAfter(this);
 		HookInvoker.contentRenderAfter(this);
 	}
 	}
 
 
+	//文章点赞接口
+	public void vote() {
+		BigInteger contentId = getParaToBigInteger("content_id");
+		Content content = ContentQuery.me().findById(contentId);
+		BigInteger userId = getParaToBigInteger("user_id");
+		BigInteger uuUserId = getParaToBigInteger("uu_user_id");
+		if ("0".equals(userId.toString())) {
+			userId = null;
+		}
+		if ("0".equals(uuUserId.toString())) {
+			uuUserId = null;
+		}
+
+		Vote vote = VoteQuery.me().findContentVote(contentId,userId,uuUserId);
+		//判断此用户是否给此评论点过赞
+		if (vote != null) {
+			if (vote.getUp() == null) {
+				againVoteUp(content,vote);
+			} else {
+				cancelVoteUp(content,vote);
+			}
+		} else {
+			voteUp(content,userId,uuUserId);
+		}
+	}
+
+	//新增点赞
+	private void voteUp(Content content,BigInteger userId,BigInteger uuUserId){
+		Vote vote = getModel(Vote.class);
+		vote.setContentId(content.getId());
+		vote.setUserId(userId);
+		vote.setUuUserId(uuUserId);
+		vote.setUp(true);
+		vote.setDown(null);
+		vote.setIp(getIPAddress());
+		vote.setAgent(getUserAgent());
+		vote.setStatus(Vote.STATUS_NORMAL);
+		vote.setCreated(new Date());
+
+		if (vote.save()) {
+			//更新对应文章的点赞数
+			content.updateVoteUpCount("up");
+			renderAjaxResultForSuccess();
+		} else {
+			renderAjaxResultForError();
+		}
+
+	}
+
+	//取消赞
+	private void cancelVoteUp(Content content,Vote vote){
+		vote.setUp(null);
+		if (vote.update()) {
+			//更新对应评论的点赞数
+			content.updateVoteUpCount("down");
+			renderAjaxResultForSuccess();
+		} else {
+			renderAjaxResultForError();
+		}
+	}
+
+	//再次赞
+	private void againVoteUp(Content content,Vote vote){
+		vote.setUp(true);
+		if (vote.update()) {
+			//更新对应评论的点赞数
+			content.updateVoteUpCount("up");
+			renderAjaxResultForSuccess();
+		} else {
+			renderAjaxResultForError();
+		}
+	}
+
 }
 }

+ 41 - 0
jpress-web-template-usoftchina/src/main/webapp/templates/usoftchina/assets/css/imgareaselect-default.css

@@ -0,0 +1,41 @@
+/*
+ * imgAreaSelect default style
+ */
+
+.imgareaselect-border1 {
+	background: url(border-v.gif) repeat-y left top;
+}
+
+.imgareaselect-border2 {
+    background: url(border-h.gif) repeat-x left top;
+}
+
+.imgareaselect-border3 {
+    background: url(border-v.gif) repeat-y right top;
+}
+
+.imgareaselect-border4 {
+    background: url(border-h.gif) repeat-x left bottom;
+}
+
+.imgareaselect-border1, .imgareaselect-border2,
+.imgareaselect-border3, .imgareaselect-border4 {
+    filter: alpha(opacity=50);
+	opacity: 0.5;
+}
+
+.imgareaselect-handle {
+    background-color: #fff;
+    border: solid 1px #000;
+    filter: alpha(opacity=50);
+    opacity: 0.5;
+}
+
+.imgareaselect-outer {
+    background-color: #000;
+    filter: alpha(opacity=50);
+    opacity: 0.5;
+}
+
+.imgareaselect-selection {  
+}

+ 730 - 0
jpress-web-template-usoftchina/src/main/webapp/templates/usoftchina/assets/js/jquery.imgareaselect.js

@@ -0,0 +1,730 @@
+/*
+ * imgAreaSelect jQuery plugin
+ * version 0.9.10
+ *
+ * Copyright (c) 2008-2013 Michal Wojciechowski (odyniec.net)
+ *
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * http://odyniec.net/projects/imgareaselect/
+ *
+ */
+
+(function($) {
+
+var abs = Math.abs,
+    max = Math.max,
+    min = Math.min,
+    round = Math.round;
+
+function div() {
+    return $('<div/>');
+}
+
+$.imgAreaSelect = function (img, options) {
+    var
+
+        $img = $(img),
+
+        imgLoaded,
+
+        $box = div(),
+        $area = div(),
+        $border = div().add(div()).add(div()).add(div()),
+        $outer = div().add(div()).add(div()).add(div()),
+        $handles = $([]),
+
+        $areaOpera,
+
+        left, top,
+
+        imgOfs = { left: 0, top: 0 },
+
+        imgWidth, imgHeight,
+
+        $parent,
+
+        parOfs = { left: 0, top: 0 },
+
+        zIndex = 0,
+
+        position = 'absolute',
+
+        startX, startY,
+
+        scaleX, scaleY,
+
+        resize,
+
+        minWidth, minHeight, maxWidth, maxHeight,
+
+        aspectRatio,
+
+        shown,
+
+        x1, y1, x2, y2,
+
+        selection = { x1: 0, y1: 0, x2: 0, y2: 0, width: 0, height: 0 },
+
+        docElem = document.documentElement,
+
+        ua = navigator.userAgent,
+
+        $p, d, i, o, w, h, adjusted;
+
+    function viewX(x) {
+        return x + imgOfs.left - parOfs.left;
+    }
+
+    function viewY(y) {
+        return y + imgOfs.top - parOfs.top;
+    }
+
+    function selX(x) {
+        return x - imgOfs.left + parOfs.left;
+    }
+
+    function selY(y) {
+        return y - imgOfs.top + parOfs.top;
+    }
+
+    function evX(event) {
+        return event.pageX - parOfs.left;
+    }
+
+    function evY(event) {
+        return event.pageY - parOfs.top;
+    }
+
+    function getSelection(noScale) {
+        var sx = noScale || scaleX, sy = noScale || scaleY;
+
+        return { x1: round(selection.x1 * sx),
+            y1: round(selection.y1 * sy),
+            x2: round(selection.x2 * sx),
+            y2: round(selection.y2 * sy),
+            width: round(selection.x2 * sx) - round(selection.x1 * sx),
+            height: round(selection.y2 * sy) - round(selection.y1 * sy) };
+    }
+
+    function setSelection(x1, y1, x2, y2, noScale) {
+        var sx = noScale || scaleX, sy = noScale || scaleY;
+
+        selection = {
+            x1: round(x1 / sx || 0),
+            y1: round(y1 / sy || 0),
+            x2: round(x2 / sx || 0),
+            y2: round(y2 / sy || 0)
+        };
+
+        selection.width = selection.x2 - selection.x1;
+        selection.height = selection.y2 - selection.y1;
+    }
+
+    function adjust() {
+        if (!imgLoaded || !$img.width())
+            return;
+
+        imgOfs = { left: round($img.offset().left), top: round($img.offset().top) };
+
+        imgWidth = $img.innerWidth();
+        imgHeight = $img.innerHeight();
+
+        imgOfs.top += ($img.outerHeight() - imgHeight) >> 1;
+        imgOfs.left += ($img.outerWidth() - imgWidth) >> 1;
+
+        minWidth = round(options.minWidth / scaleX) || 0;
+        minHeight = round(options.minHeight / scaleY) || 0;
+        maxWidth = round(min(options.maxWidth / scaleX || 1<<24, imgWidth));
+        maxHeight = round(min(options.maxHeight / scaleY || 1<<24, imgHeight));
+
+        if ($().jquery == '1.3.2' && position == 'fixed' &&
+            !docElem['getBoundingClientRect'])
+        {
+            imgOfs.top += max(document.body.scrollTop, docElem.scrollTop);
+            imgOfs.left += max(document.body.scrollLeft, docElem.scrollLeft);
+        }
+
+        parOfs = /absolute|relative/.test($parent.css('position')) ?
+            { left: round($parent.offset().left) - $parent.scrollLeft(),
+                top: round($parent.offset().top) - $parent.scrollTop() } :
+            position == 'fixed' ?
+                { left: $(document).scrollLeft(), top: $(document).scrollTop() } :
+                { left: 0, top: 0 };
+
+        left = viewX(0);
+        top = viewY(0);
+
+        if (selection.x2 > imgWidth || selection.y2 > imgHeight)
+            doResize();
+    }
+
+    function update(resetKeyPress) {
+        if (!shown) return;
+
+        $box.css({ left: viewX(selection.x1), top: viewY(selection.y1) })
+            .add($area).width(w = selection.width).height(h = selection.height);
+
+        $area.add($border).add($handles).css({ left: 0, top: 0 });
+
+        $border
+            .width(max(w - $border.outerWidth() + $border.innerWidth(), 0))
+            .height(max(h - $border.outerHeight() + $border.innerHeight(), 0));
+
+        $($outer[0]).css({ left: left, top: top,
+            width: selection.x1, height: imgHeight });
+        $($outer[1]).css({ left: left + selection.x1, top: top,
+            width: w, height: selection.y1 });
+        $($outer[2]).css({ left: left + selection.x2, top: top,
+            width: imgWidth - selection.x2, height: imgHeight });
+        $($outer[3]).css({ left: left + selection.x1, top: top + selection.y2,
+            width: w, height: imgHeight - selection.y2 });
+
+        w -= $handles.outerWidth();
+        h -= $handles.outerHeight();
+
+        switch ($handles.length) {
+        case 8:
+            $($handles[4]).css({ left: w >> 1 });
+            $($handles[5]).css({ left: w, top: h >> 1 });
+            $($handles[6]).css({ left: w >> 1, top: h });
+            $($handles[7]).css({ top: h >> 1 });
+        case 4:
+            $handles.slice(1,3).css({ left: w });
+            $handles.slice(2,4).css({ top: h });
+        }
+
+        if (resetKeyPress !== false) {
+            if ($.imgAreaSelect.onKeyPress != docKeyPress)
+                $(document).unbind($.imgAreaSelect.keyPress,
+                    $.imgAreaSelect.onKeyPress);
+
+            if (options.keys)
+                $(document)[$.imgAreaSelect.keyPress](
+                    $.imgAreaSelect.onKeyPress = docKeyPress);
+        }
+
+        if (msie && $border.outerWidth() - $border.innerWidth() == 2) {
+            $border.css('margin', 0);
+            setTimeout(function () { $border.css('margin', 'auto'); }, 0);
+        }
+    }
+
+    function doUpdate(resetKeyPress) {
+        adjust();
+        update(resetKeyPress);
+        x1 = viewX(selection.x1); y1 = viewY(selection.y1);
+        x2 = viewX(selection.x2); y2 = viewY(selection.y2);
+    }
+
+    function hide($elem, fn) {
+        options.fadeSpeed ? $elem.fadeOut(options.fadeSpeed, fn) : $elem.hide();
+
+    }
+
+    function areaMouseMove(event) {
+        var x = selX(evX(event)) - selection.x1,
+            y = selY(evY(event)) - selection.y1;
+
+        if (!adjusted) {
+            adjust();
+            adjusted = true;
+
+            $box.one('mouseout', function () { adjusted = false; });
+        }
+
+        resize = '';
+
+        if (options.resizable) {
+            if (y <= options.resizeMargin)
+                resize = 'n';
+            else if (y >= selection.height - options.resizeMargin)
+                resize = 's';
+            if (x <= options.resizeMargin)
+                resize += 'w';
+            else if (x >= selection.width - options.resizeMargin)
+                resize += 'e';
+        }
+
+        $box.css('cursor', resize ? resize + '-resize' :
+            options.movable ? 'move' : '');
+        if ($areaOpera)
+            $areaOpera.toggle();
+    }
+
+    function docMouseUp(event) {
+        $('body').css('cursor', '');
+        if (options.autoHide || selection.width * selection.height == 0)
+            hide($box.add($outer), function () { $(this).hide(); });
+
+        $(document).unbind('mousemove', selectingMouseMove);
+        $box.mousemove(areaMouseMove);
+
+        options.onSelectEnd(img, getSelection());
+    }
+
+    function areaMouseDown(event) {
+        if (event.which != 1) return false;
+
+        adjust();
+
+        if (resize) {
+            $('body').css('cursor', resize + '-resize');
+
+            x1 = viewX(selection[/w/.test(resize) ? 'x2' : 'x1']);
+            y1 = viewY(selection[/n/.test(resize) ? 'y2' : 'y1']);
+
+            $(document).mousemove(selectingMouseMove)
+                .one('mouseup', docMouseUp);
+            $box.unbind('mousemove', areaMouseMove);
+        }
+        else if (options.movable) {
+            startX = left + selection.x1 - evX(event);
+            startY = top + selection.y1 - evY(event);
+
+            $box.unbind('mousemove', areaMouseMove);
+
+            $(document).mousemove(movingMouseMove)
+                .one('mouseup', function () {
+                    options.onSelectEnd(img, getSelection());
+
+                    $(document).unbind('mousemove', movingMouseMove);
+                    $box.mousemove(areaMouseMove);
+                });
+        }
+        else
+            $img.mousedown(event);
+
+        return false;
+    }
+
+    function fixAspectRatio(xFirst) {
+        if (aspectRatio)
+            if (xFirst) {
+                x2 = max(left, min(left + imgWidth,
+                    x1 + abs(y2 - y1) * aspectRatio * (x2 > x1 || -1)));
+
+                y2 = round(max(top, min(top + imgHeight,
+                    y1 + abs(x2 - x1) / aspectRatio * (y2 > y1 || -1))));
+                x2 = round(x2);
+            }
+            else {
+                y2 = max(top, min(top + imgHeight,
+                    y1 + abs(x2 - x1) / aspectRatio * (y2 > y1 || -1)));
+                x2 = round(max(left, min(left + imgWidth,
+                    x1 + abs(y2 - y1) * aspectRatio * (x2 > x1 || -1))));
+                y2 = round(y2);
+            }
+    }
+
+    function doResize() {
+        x1 = min(x1, left + imgWidth);
+        y1 = min(y1, top + imgHeight);
+
+        if (abs(x2 - x1) < minWidth) {
+            x2 = x1 - minWidth * (x2 < x1 || -1);
+
+            if (x2 < left)
+                x1 = left + minWidth;
+            else if (x2 > left + imgWidth)
+                x1 = left + imgWidth - minWidth;
+        }
+
+        if (abs(y2 - y1) < minHeight) {
+            y2 = y1 - minHeight * (y2 < y1 || -1);
+
+            if (y2 < top)
+                y1 = top + minHeight;
+            else if (y2 > top + imgHeight)
+                y1 = top + imgHeight - minHeight;
+        }
+
+        x2 = max(left, min(x2, left + imgWidth));
+        y2 = max(top, min(y2, top + imgHeight));
+
+        fixAspectRatio(abs(x2 - x1) < abs(y2 - y1) * aspectRatio);
+
+        if (abs(x2 - x1) > maxWidth) {
+            x2 = x1 - maxWidth * (x2 < x1 || -1);
+            fixAspectRatio();
+        }
+
+        if (abs(y2 - y1) > maxHeight) {
+            y2 = y1 - maxHeight * (y2 < y1 || -1);
+            fixAspectRatio(true);
+        }
+
+        selection = { x1: selX(min(x1, x2)), x2: selX(max(x1, x2)),
+            y1: selY(min(y1, y2)), y2: selY(max(y1, y2)),
+            width: abs(x2 - x1), height: abs(y2 - y1) };
+
+        update();
+
+        options.onSelectChange(img, getSelection());
+    }
+
+    function selectingMouseMove(event) {
+        x2 = /w|e|^$/.test(resize) || aspectRatio ? evX(event) : viewX(selection.x2);
+        y2 = /n|s|^$/.test(resize) || aspectRatio ? evY(event) : viewY(selection.y2);
+
+        doResize();
+
+        return false;
+
+    }
+
+    function doMove(newX1, newY1) {
+        x2 = (x1 = newX1) + selection.width;
+        y2 = (y1 = newY1) + selection.height;
+
+        $.extend(selection, { x1: selX(x1), y1: selY(y1), x2: selX(x2),
+            y2: selY(y2) });
+
+        update();
+
+        options.onSelectChange(img, getSelection());
+    }
+
+    function movingMouseMove(event) {
+        x1 = max(left, min(startX + evX(event), left + imgWidth - selection.width));
+        y1 = max(top, min(startY + evY(event), top + imgHeight - selection.height));
+
+        doMove(x1, y1);
+
+        event.preventDefault();
+
+        return false;
+    }
+
+    function startSelection() {
+        $(document).unbind('mousemove', startSelection);
+        adjust();
+
+        x2 = x1;
+        y2 = y1;
+
+        doResize();
+
+        resize = '';
+
+        if (!$outer.is(':visible'))
+            $box.add($outer).hide().fadeIn(options.fadeSpeed||0);
+
+        shown = true;
+
+        $(document).unbind('mouseup', cancelSelection)
+            .mousemove(selectingMouseMove).one('mouseup', docMouseUp);
+        $box.unbind('mousemove', areaMouseMove);
+
+        options.onSelectStart(img, getSelection());
+    }
+
+    function cancelSelection() {
+        $(document).unbind('mousemove', startSelection)
+            .unbind('mouseup', cancelSelection);
+        hide($box.add($outer));
+
+        setSelection(selX(x1), selY(y1), selX(x1), selY(y1));
+
+        if (!(this instanceof $.imgAreaSelect)) {
+            options.onSelectChange(img, getSelection());
+            options.onSelectEnd(img, getSelection());
+        }
+    }
+
+    function imgMouseDown(event) {
+        if (event.which != 1 || $outer.is(':animated')) return false;
+
+        adjust();
+        startX = x1 = evX(event);
+        startY = y1 = evY(event);
+
+        $(document).mousemove(startSelection).mouseup(cancelSelection);
+
+        return false;
+    }
+
+    function windowResize() {
+        doUpdate(false);
+    }
+
+    function imgLoad() {
+        imgLoaded = true;
+
+        setOptions(options = $.extend({
+            classPrefix: 'imgareaselect',
+            movable: true,
+            parent: 'body',
+            resizable: true,
+            resizeMargin: 10,
+            onInit: function () {},
+            onSelectStart: function () {},
+            onSelectChange: function () {},
+            onSelectEnd: function () {}
+        }, options));
+
+        $box.add($outer).css({ visibility: '' });
+
+        if (options.show) {
+            shown = true;
+            adjust();
+            update();
+            $box.add($outer).hide().fadeIn(options.fadeSpeed||0);
+        }
+
+        setTimeout(function () { options.onInit(img, getSelection()); }, 0);
+    }
+
+    var docKeyPress = function(event) {
+        var k = options.keys, d, t, key = event.keyCode;
+
+        d = !isNaN(k.alt) && (event.altKey || event.originalEvent.altKey) ? k.alt :
+            !isNaN(k.ctrl) && event.ctrlKey ? k.ctrl :
+            !isNaN(k.shift) && event.shiftKey ? k.shift :
+            !isNaN(k.arrows) ? k.arrows : 10;
+
+        if (k.arrows == 'resize' || (k.shift == 'resize' && event.shiftKey) ||
+            (k.ctrl == 'resize' && event.ctrlKey) ||
+            (k.alt == 'resize' && (event.altKey || event.originalEvent.altKey)))
+        {
+            switch (key) {
+            case 37:
+                d = -d;
+            case 39:
+                t = max(x1, x2);
+                x1 = min(x1, x2);
+                x2 = max(t + d, x1);
+                fixAspectRatio();
+                break;
+            case 38:
+                d = -d;
+            case 40:
+                t = max(y1, y2);
+                y1 = min(y1, y2);
+                y2 = max(t + d, y1);
+                fixAspectRatio(true);
+                break;
+            default:
+                return;
+            }
+
+            doResize();
+        }
+        else {
+            x1 = min(x1, x2);
+            y1 = min(y1, y2);
+
+            switch (key) {
+            case 37:
+                doMove(max(x1 - d, left), y1);
+                break;
+            case 38:
+                doMove(x1, max(y1 - d, top));
+                break;
+            case 39:
+                doMove(x1 + min(d, imgWidth - selX(x2)), y1);
+                break;
+            case 40:
+                doMove(x1, y1 + min(d, imgHeight - selY(y2)));
+                break;
+            default:
+                return;
+            }
+        }
+
+        return false;
+    };
+
+    function styleOptions($elem, props) {
+        for (var option in props)
+            if (options[option] !== undefined)
+                $elem.css(props[option], options[option]);
+    }
+
+    function setOptions(newOptions) {
+        if (newOptions.parent)
+            ($parent = $(newOptions.parent)).append($box.add($outer));
+
+        $.extend(options, newOptions);
+
+        adjust();
+
+        if (newOptions.handles != null) {
+            $handles.remove();
+            $handles = $([]);
+
+            i = newOptions.handles ? newOptions.handles == 'corners' ? 4 : 8 : 0;
+
+            while (i--)
+                $handles = $handles.add(div());
+
+            $handles.addClass(options.classPrefix + '-handle').css({
+                position: 'absolute',
+                fontSize: 0,
+                zIndex: zIndex + 1 || 1
+            });
+
+            if (!parseInt($handles.css('width')) >= 0)
+                $handles.width(5).height(5);
+
+            if (o = options.borderWidth)
+                $handles.css({ borderWidth: o, borderStyle: 'solid' });
+
+            styleOptions($handles, { borderColor1: 'border-color',
+                borderColor2: 'background-color',
+                borderOpacity: 'opacity' });
+        }
+
+        scaleX = options.imageWidth / imgWidth || 1;
+        scaleY = options.imageHeight / imgHeight || 1;
+
+        if (newOptions.x1 != null) {
+            setSelection(newOptions.x1, newOptions.y1, newOptions.x2,
+                newOptions.y2);
+            newOptions.show = !newOptions.hide;
+        }
+
+        if (newOptions.keys)
+            options.keys = $.extend({ shift: 1, ctrl: 'resize' },
+                newOptions.keys);
+
+        $outer.addClass(options.classPrefix + '-outer');
+        $area.addClass(options.classPrefix + '-selection');
+        for (i = 0; i++ < 4;)
+            $($border[i-1]).addClass(options.classPrefix + '-border' + i);
+
+        styleOptions($area, { selectionColor: 'background-color',
+            selectionOpacity: 'opacity' });
+        styleOptions($border, { borderOpacity: 'opacity',
+            borderWidth: 'border-width' });
+        styleOptions($outer, { outerColor: 'background-color',
+            outerOpacity: 'opacity' });
+        if (o = options.borderColor1)
+            $($border[0]).css({ borderStyle: 'solid', borderColor: o });
+        if (o = options.borderColor2)
+            $($border[1]).css({ borderStyle: 'dashed', borderColor: o });
+
+        $box.append($area.add($border).add($areaOpera)).append($handles);
+
+        if (msie) {
+            if (o = ($outer.css('filter')||'').match(/opacity=(\d+)/))
+                $outer.css('opacity', o[1]/100);
+            if (o = ($border.css('filter')||'').match(/opacity=(\d+)/))
+                $border.css('opacity', o[1]/100);
+        }
+
+        if (newOptions.hide)
+            hide($box.add($outer));
+        else if (newOptions.show && imgLoaded) {
+            shown = true;
+            $box.add($outer).fadeIn(options.fadeSpeed||0);
+            doUpdate();
+        }
+
+        aspectRatio = (d = (options.aspectRatio || '').split(/:/))[0] / d[1];
+
+        $img.add($outer).unbind('mousedown', imgMouseDown);
+
+        if (options.disable || options.enable === false) {
+            $box.unbind('mousemove', areaMouseMove).unbind('mousedown', areaMouseDown);
+            $(window).unbind('resize', windowResize);
+        }
+        else {
+            if (options.enable || options.disable === false) {
+                if (options.resizable || options.movable)
+                    $box.mousemove(areaMouseMove).mousedown(areaMouseDown);
+
+                $(window).resize(windowResize);
+            }
+
+            if (!options.persistent)
+                $img.add($outer).mousedown(imgMouseDown);
+        }
+
+        options.enable = options.disable = undefined;
+    }
+
+    this.remove = function () {
+        setOptions({ disable: true });
+        $box.add($outer).remove();
+    };
+
+    this.getOptions = function () { return options; };
+
+    this.setOptions = setOptions;
+
+    this.getSelection = getSelection;
+
+    this.setSelection = setSelection;
+
+    this.cancelSelection = cancelSelection;
+
+    this.update = doUpdate;
+
+    var msie = (/msie ([\w.]+)/i.exec(ua)||[])[1],
+        opera = /opera/i.test(ua),
+        safari = /webkit/i.test(ua) && !/chrome/i.test(ua);
+
+    $p = $img;
+
+    while ($p.length) {
+        zIndex = max(zIndex,
+            !isNaN($p.css('z-index')) ? $p.css('z-index') : zIndex);
+        if ($p.css('position') == 'fixed')
+            position = 'fixed';
+
+        $p = $p.parent(':not(body)');
+    }
+
+    zIndex = options.zIndex || zIndex;
+
+    if (msie)
+        $img.attr('unselectable', 'on');
+
+    $.imgAreaSelect.keyPress = msie || safari ? 'keydown' : 'keypress';
+
+    if (opera)
+
+        $areaOpera = div().css({ width: '100%', height: '100%',
+            position: 'absolute', zIndex: zIndex + 2 || 2 });
+
+    $box.add($outer).css({ visibility: 'hidden', position: position,
+        overflow: 'hidden', zIndex: zIndex || '0' });
+    $box.css({ zIndex: zIndex + 2 || 2 });
+    $area.add($border).css({ position: 'absolute', fontSize: 0 });
+
+    img.complete || img.readyState == 'complete' || !$img.is('img') ?
+        imgLoad() : $img.one('load', imgLoad);
+
+    if (!imgLoaded && msie && msie >= 7)
+        img.src = img.src;
+};
+
+$.fn.imgAreaSelect = function (options) {
+    options = options || {};
+
+    this.each(function () {
+        if ($(this).data('imgAreaSelect')) {
+            if (options.remove) {
+                $(this).data('imgAreaSelect').remove();
+                $(this).removeData('imgAreaSelect');
+            }
+            else
+                $(this).data('imgAreaSelect').setOptions(options);
+        }
+        else if (!options.remove) {
+            if (options.enable === undefined && options.disable === undefined)
+                options.enable = true;
+
+            $(this).data('imgAreaSelect', new $.imgAreaSelect(this, options));
+        }
+    });
+
+    if (options.instance)
+        return $(this).data('imgAreaSelect');
+
+    return this;
+};
+
+})(jQuery);

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 0 - 0
jpress-web-template-usoftchina/src/main/webapp/templates/usoftchina/assets/js/jquery.imgareaselect.min.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 0 - 0
jpress-web-template-usoftchina/src/main/webapp/templates/usoftchina/assets/js/jquery.imgareaselect.pack.js


+ 434 - 0
jpress-web-template-usoftchina/src/main/webapp/templates/usoftchina/content_uuhelper.html

@@ -0,0 +1,434 @@
+<!--手机列表页-->
+<#if USER??> <#assign userId=USER.id><#else><#assign userId=0></#if>
+<!DOCTYPE html>
+<html>
+<head lang="en">
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0,maximum-scale=1.0, user-scalable=no">
+    <script type="text/javascript" src="${CTPATH}/assets/js/jquery.min.js"></script>
+    <title></title>
+    <style>
+        .main{
+            width: 100%;
+            margin: 0 auto;
+        }
+        .main .container{
+            max-width: 640px;
+            margin: 0 auto;
+            text-align: center;
+            padding: 0 10px;
+        }
+        .main .container .header p{
+            text-align: left;
+            font-size: 18px;
+            color: #000;
+        }
+        .main .container .header div{
+            margin: 5px 0;
+            text-align: left;
+            font-size: 14px;
+            color: #8c8c8c;
+        }
+        .main .container .header div span:first-child{
+            margin-right: 10px;
+        }
+        .main .container .section div,.main .container .section p{
+            font-size: 14px;
+            color: #000;
+            text-align: left;
+        }
+        .main .container .section div.img-container{
+            text-align:center;
+            max-width: 100%;
+        }
+        .main .container .section div.img-container img{
+            max-width: 100%;
+        }
+        .main .container .section p{
+            font-size: 14px;
+            line-height: 20px;
+            color: #6c6a6b;
+            text-indent: 2em;
+            text-align: left;
+        }
+        .main .container .section div.readCount{
+            margin: 30px 0;
+            overflow: hidden;
+            color: #8c8c8c;
+        }
+        .main .container .section div.readCount div{
+            float: left;
+        }
+        .main .container .section div.readCount div span{
+            font-size: 14px;
+            margin-right: 10px;
+            cursor: pointer;
+        }
+        .main .container .section div.readCount div span em{
+            color: #5f9ac6;
+            margin-left: 5px;
+            font-style: normal;
+        }
+        .main .container .section div.readCount div span i{
+            display: inline-block;
+            font-size: 14px;
+            color: #8c8c8c;
+        }
+        .main .container .section div.readCount p{
+            float: right;
+            font-size: 14px;
+        }
+        .main .container .section div.readCount img{
+            width: 18px;
+            height: 18px;
+        }
+        .main .container .footer{
+            border-top: 1px solid #d7d5d6;
+            padding-top: 20px;
+        }
+        .main .container .footer .footer-header{
+            position: relative;
+            cursor: pointer;
+            width: 100%;
+        }
+        .main .container .footer .footer-header div.infoMessage{
+            position: absolute;
+            left: 50%;
+            margin-left: -50%;
+            top: -30px;
+            width: 100%;
+            color: #8ca8bd;
+            font-size: 14px;
+            background: #fff;
+        }
+        .main .container .footer .footer-header div.infoMessage:hover{
+            color: #000;
+        }
+        .main .container .footer .footer-header div span{
+            margin-right: 5px;
+        }
+        .main .container .footer .footer-header div img{
+            width: 15px;
+            height: 15px;
+        }
+        .main .container .footer .footer-section .message{
+            margin: 30px 0;
+            overflow: hidden ;
+        }
+        .main .container .footer .footer-section .message .left{
+            float: left;
+        }
+        .main .container .footer .footer-section .message .right{
+            float: right;
+            width: 85%;
+            padding-bottom: 20px;
+            border-bottom: 1px solid #ddd;
+        }
+        .main .container .footer .footer-section .img{
+            border: 1px solid #ddd;
+            border-radius: 5px;
+            width: 70px;
+            height: 70px;
+        }
+        .main .container .footer .footer-section .img img.imgUas{
+            max-width: 70px;
+            max-height: 70px;
+            text-align: center;
+            margin: 0 auto;
+        }
+        .main .container .footer .footer-section .detail{
+            /*overflow: hidden;*/
+        }
+        .main .container .footer .footer-section .detail .title{
+            overflow: hidden;
+            margin-bottom: 10px;
+        }
+        .main .container .footer .footer-section .detail .title img{
+            width: 17px;
+            height: 17px;
+        }
+        .main .container .footer .footer-section .detail .title span:first-child{
+            float: left;
+            color: #6c6a6b;
+            font-size: 14px;
+        }
+        .main .container .footer .footer-section .detail .title span:first-child em{
+            margin-left: 10px;
+            font-size: 14px;
+            color: #8c8c8c;
+            font-style: normal;
+        }
+        .main .container .footer .footer-section .detail .title span em{
+            font-size: 14px;
+        }
+        .main .container .footer .footer-section .detail .title span:last-child{
+            color: #8c8c8c;
+            font-size: 14px;
+            float: right;
+            cursor: pointer;
+        }
+        .main .container .footer .footer-section .detail .title span:last-child em{
+            margin-left: 10px;
+            color: #5f9ac6;
+            font-size: 14px;
+            padding-right: 5px;
+            font-style: normal;
+        }
+        .main .container .footer .footer-section .detail p{
+            text-align: left;
+            font-size: 14px;
+            color: #333;
+        }
+        .main .container .footer .footer-section .detail .reply {
+            margin-top: 10px;
+        }
+        .main .container .footer .pull{
+            margin: 40px 0;
+            font-size: 12px;
+            color: #8c8c8c;
+        }
+        .main .container .footer .loading{
+           text-align: center;
+            display: none;
+        }
+
+        @-webkit-keyframes rotate {
+            from {-webkit-transform:rotate(0deg);}
+            to {-webkit-transform:rotate(360deg);}
+        }
+        .main .container .footer .loading>img.loadingImg{
+            width: 30px;
+            height: 30px;
+            -webkit-mask-size: 30px 30px;
+            -webkit-animation-name: rotate;
+            -webkit-animation-duration: 1.5s;
+            -webkit-animation-iteration-count: infinite;
+            -webkit-animation-timing-function: linear;
+        }
+        .main .container .footer .footer-header .writeMessage{
+            display: none;
+            padding: 20px;
+            width: 80%;
+        }
+        .main .container .footer .footer-header .writeMessage textarea{
+            width: 100%;
+            height: auto;
+        }
+        .main .container .footer .footer-header .writeMessage div{
+            text-align: right;
+            margin-top: 0;
+            width: 100%;
+        }
+        .main .container .footer .footer-header .writeMessage button{
+            margin-right: 15px;
+            display: inline-block;
+            width: 65px;
+            height: 25px;
+            line-height: 25px;
+            text-align: center;
+            font-size: 14px;
+            background: #b4b5b9;
+            border-radius: 5px;
+            color: #333;
+            border: none;
+            cursor: pointer;
+        }
+        .main .container .footer .footer-header .writeMessage button:hover{
+            border: none;
+            background: #5078cb;
+            color: #fff;
+        }
+    </style>
+    <!--<#macro script>-->
+    <script>
+    </script>
+    <!--</#macro>-->
+</head>
+<body>
+<div class="main">
+    <div class="container">
+        <div class="header">
+            <p>${content.title!}</p>
+            <div><span>${(content.getMetadataByKey("push_time"))!}</span><span>${content.author!}</span></div>
+        </div>
+        <div class="section">
+            ${content.text!}
+            <div class="readCount">
+                <div>
+                    <span>阅读 <em>${content.view_count!'0'}</em></span>
+                    <span><img img class="voteContent <#if content.isvoted(content.id, userId!0, userid!0)>voted</#if>" src="/jpress/static/jpress/admin/image/hands.png" alt="" onclick="voteContent(${content.id})"><em class="voteContentCount">${content.vote_up!'0'}</em></span>
+                    <!--<span><img src="/jpress/static/jpress/admin/image/support.png" alt=""/><em>1</em></span>-->
+                </div>
+                <p>${(content.getMetadataByKey("copy_right"))!}</p>
+            </div>
+        </div>
+        <div class="footer">
+            <#if content.isCommentEnable() && !(content.isUuUserReplied(userid) || (USER?? && content.isUserReplied(USER.id))) && (USER?? || userid??)>
+                <form action="${CPATH}/comment/submit" method="post"  id="comment">
+                    <input type="hidden" name="cid" value="${(content.id)!}" >
+                    <input type="hidden" id="parent_id" name="parent_id" >
+                    <input type="hidden" name="uuUserId" value="${userid!}" >
+                    <input type="hidden" name="uuUserName" value="${username!}" >
+                    <input type="hidden" name="uuUserAvatar" value="${iconurl!}" >
+
+                    <div class="footer-header">
+                        <div class="infoMessage"><span>写留言</span><img src="/jpress/static/jpress/admin/image/pen.png" alt=""/></div>
+                        <div class="writeMessage">
+                            <textarea name="text" id="" cols="30" rows="10"></textarea>
+                            <div><button class="cancel">取消</button><button type="submit">提交</button></div>
+                        </div>
+                    </div>
+                </form>
+            </#if>
+            <div class="footer-section">
+                <@jp.commentPage pageSize="3">
+                <#if page ??>
+                    <#list page.getList() as comment>
+                        <div class="message">
+                            <div class="left">
+                                <div class="img" >
+                                    <img src="${comment.uu_user_avatar!'/jpress/static/jpress/admin/image/dot.png'}" alt="用户头像">
+                                </div>
+                            </div>
+                            <div class="right">
+                                <div class="detail">
+                                    <div class="title">
+                                        <span>${comment.author!} <em>${(comment.created?string("yyyy-MM-dd"))!}</em></span>
+                                        <span><img class="votedUas${comment.id} <#if comment.isvoted(comment.id, userId!0, userid!0)>voted</#if>" src="/jpress/static/jpress/admin/image/hands.png" alt="" onclick="vote(${comment.id})"/><em class="em${comment.id}">${(comment.vote_up)!'0'}</em></span>
+                                    </div>
+                                    <p>${comment.text!}</p>
+                                    <#if comment.qc_content ??>
+                                        <div class="title reply">
+                                            <span>作者回复: <em>${(comment.qc_created?string("yyyy-MM-dd"))!}</em></span>
+                                            <span><img class="votedUas${comment.qc_id} <#if comment.isvoted(comment.qc_id, userId!0, userid!0)>voted</#if>" src="/jpress/static/jpress/admin/image/hands.png" alt="" onclick="vote(${comment.qc_id})"/><em class="em${comment.qc_id}">${(comment.qc_vote_up)!'0'}</em></span>
+                                        </div>
+                                        <p>${comment.qc_content!}</p>
+                                    </#if>
+                                </div>
+                            </div>
+                        </div>
+                    </#list>
+
+                </#if>
+            </@jp.commentPage>
+            </div>
+            <div class="loading"><img src="/jpress/static/jpress/admin/image/loading.png" alt="" class="loadingImg"></div>
+            <div class="pull">下拉加载更多</div>
+            <!--<div class="pull"><a>没有更多数据了</a></div>-->
+        </div>
+    </div>
+</div>
+</body>
+<script>
+    jQuery('html').css('fontSize',$(window).width()/640 * 30);
+//    jQuery(window).load(function () {
+//        jQuery("img").each(function () {
+//            DrawImage(this, 300, 300);
+//        });
+//    });
+//    function DrawImage(ImgD, FitWidth, FitHeight) {
+//        var image = new Image();
+//        image.src = ImgD.src;
+//        if (image.width > 0 && image.height > 0) {
+//            if (image.width / image.height >= FitWidth / FitHeight) {
+//                if (image.width > FitWidth) {
+//                    ImgD.width = FitWidth;
+//                    ImgD.height = (image.height * FitWidth) / image.width;
+//                } else {
+//                    ImgD.width = image.width;
+//                    ImgD.height = image.height;
+//                }
+//            } else {
+//                if (image.height > FitHeight) {
+//                    ImgD.height = FitHeight;
+//                    ImgD.width = (image.width * FitHeight) / image.height;
+//                } else {
+//                    ImgD.width = image.width;
+//                    ImgD.height = image.height;
+//                }
+//            }
+//        }
+//    }
+//    写留言
+    $('.footer-header>div.infoMessage').click(function () {
+        $(this).next('.writeMessage').toggle()
+    })
+    //点击取消按钮
+    $('.cancel').click(function () {
+        $(this).parent().parent('.writeMessage').css('display','none');
+        console.log($(this).parent().parent('.writeMessage'))
+    })
+//    上拉加载更多
+    var aa = 2,
+    timers = null;
+    //加载数据
+    var LoadingDataFn = function() {
+        $.get("${CPATH}/comment/lazyLoad?contId=${(content.id)!}&pagesize=1&pagenumber="+aa+"&userId=${userId!0}&uuUserId=${userid!0}", function(result){
+            var dom = '';
+            if ("" == result.message){
+                $('.pull').text("没有更多数据了");
+                $('.loading').css('display','none');
+            }
+            dom += result.message;
+            $('.footer-section').append(dom);
+        });
+
+    };
+    //初始化
+    var userId = null;
+    var uuUserId = null;
+    $(document).ready(function() {
+        userId = "${userId!0}"
+        uuUserId = "${userid!0}";
+        $('.voted').attr("src","/jpress/static/jpress/admin/image/support.png");
+    });
+    //滚动加载方法
+    $(window).scroll(function() {
+        if (($(window).height() + $(window).scrollTop() + 60) >= $(document).height()) {
+            clearTimeout(timers);
+            timers = setTimeout(function() {
+                aa++;
+                $('.loading').css('display','block');
+                LoadingDataFn();
+            }, 300);
+        }
+    });
+
+    //点评论赞
+    var vote = function(commentid) {
+        var imgObj = $(".votedUas"+commentid);
+        var emObj = $(".em"+commentid);
+        if (imgObj.hasClass("voted")) {
+            emObj.text(""+(parseInt(emObj.text())-1));
+            imgObj.removeClass("voted");
+            imgObj.attr("src","/jpress/static/jpress/admin/image/hands.png");
+        } else {
+            emObj.text(""+(parseInt(emObj.text())+1));
+            imgObj.addClass("voted");
+            imgObj.attr("src","/jpress/static/jpress/admin/image/support.png")
+        }
+        $.get("${CPATH}/comment/vote?comment_id="+commentid+"&user_id="+userId+"&uu_user_id="+uuUserId, function(result){
+            console.log(result.message);
+        });
+    }
+
+    //点文章赞
+    var voteContent = function(contentId) {
+        var imgObj = $(".voteContent");
+        var emObj = $(".voteContentCount");
+        if (imgObj.hasClass("voted")) {
+            emObj.text(""+(parseInt(emObj.text())-1));
+            imgObj.removeClass("voted");
+            imgObj.attr("src","/jpress/static/jpress/admin/image/hands.png");
+        } else {
+            emObj.text(""+(parseInt(emObj.text())+1));
+            imgObj.addClass("voted");
+            imgObj.attr("src","/jpress/static/jpress/admin/image/support.png")
+        }
+        $.get("${CPATH}/c/vote?content_id="+contentId+"&user_id="+userId+"&uu_user_id="+uuUserId, function(result){
+            console.log(result.message);
+        });
+    }
+
+</script>
+</html>

+ 205 - 0
jpress-web-template-usoftchina/src/main/webapp/templates/usoftchina/taxonomy_uuhelper.html

@@ -0,0 +1,205 @@
+<!--手机列表页-->
+<!DOCTYPE html>
+<html>
+<head lang="en">
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0,maximum-scale=1.0, user-scalable=no">
+    <title></title>
+    <style>
+        .main{
+            width: 100%;
+            margin: 0 auto;
+
+        }
+        .main .container{
+            padding: 10px;
+            max-width: 640px;
+            margin: 0 auto;
+            text-align: center;
+            background: #ebe9ea;
+        }
+        .main .container .timeShow {
+            text-align: center;
+            width: 100%;
+            margin: 20px auto;
+        }
+        .main .container .time{
+            width: 130px;
+            line-height: 20px;
+            font-size: 12px;
+            border-radius: 10px;
+            padding: 0 5px;
+            color: #fff;
+            background: #cecece;
+            text-align: center;
+            margin: 0 auto;
+        }
+        .main .container .message{
+            text-align: center;
+            margin: 0 auto;
+            background: #fff;
+            border-radius: 5px;
+        }
+        .main .container .message .img{
+            position: relative;
+            text-align: center;
+            margin: 0 auto;
+            height: 195px;
+            overflow: hidden;
+        }
+        .main .container .message .img img{
+            max-width: 355px;
+            max-height: 195px;
+        }
+        .main .container .message .img p{
+            position: absolute;
+            left: 0;
+            bottom: 0;
+            padding: 10px;
+            text-align: left;
+            background: rgba(16,16,16,.5);
+            font-size: 14px;
+            color: #fff;
+            display: inline-block;
+            width: 100%;
+        }
+        .main .container .message .text{
+            padding: 0 16px;
+            overflow: hidden;
+            text-align: left;
+        }
+        .main .container .message .first-text{
+            border-bottom: 1px solid #e6e4e5;
+        }
+        .main .container .message .text .left{
+            margin: 10px 0;
+            width: 78%;
+            float: left;
+            font-size: 14px;
+            color: #000;
+        }
+        .main .container .message .text .right-thumb{
+            margin-top: 11px;
+            width: 55px;
+            height: 55px;
+            float: right;
+            border-radius: 5px;
+            text-align: center;
+        }
+        .main .container .message .text .right-thumb img{
+           max-width: 55px;
+            max-height: 55px;
+        }
+        .main .container .info{
+            position: relative;
+            text-align: center;
+            margin: 20px auto;
+            overflow: hidden;
+            /*width: 390px;*/
+        }
+        .main .container .info .left-thumb{
+            float: left;
+            width: 45px;
+            height: 45px;
+            border-radius: 5px;
+        }
+        .main .container .info .right-info{
+            float: left;
+            font-size: 12px;
+            text-align: left;
+            color: #545354;
+        }
+        .main .container .info .right-info span{
+            font-size: 14px;
+            color: #c1bfc0;
+        }
+        .main .container .info .right-info p{
+            background: #fff;
+            padding: 5px 10px;
+            border-radius: 5px;
+            max-width: 219px;
+            font-size: 12px;
+        }
+        .main .container .info .cart{
+            position: absolute;
+            top: 22px;
+            left: 33px;
+            width: 0;
+            height: 0;
+            vertical-align: middle;
+            border: 6px solid transparent;
+            border-right-color: #fff;
+        }
+    </style>
+</head>
+<body>
+<div class="main">
+    <div class="container">
+        <div class="timeShow">
+            <div class="time">2017-08-01 下午9:00</div>
+        </div>
+        <div class="message">
+            <div class="img">
+                <a href="">
+                    <img src="/jpress/static/jpress/admin/image/dot.png" alt="">
+                    <p>一个轻盈、智慧、便捷的企业互联网综合服务平台。</p>
+                </a>
+            </div>
+            <@jp.contents module="uuhelper" orderBy="meta:push_time">
+            <#list contents as content>
+                    <div class="text <#if content?is_first>first-text</#if>">
+                        <a href="">
+                            <p class="left">
+                                <a href="${content.url!}">${content.title!}</a>
+                            </p>
+                            <div class="right-thumb">
+                                <img src="/jpress/static/jpress/admin/image/dot.png" alt="">
+                            </div>
+                        </a>
+                    </div>
+            </#list>
+            </@jp.contents>
+                <!--<div class="text">-->
+                    <!--<a href="">-->
+                        <!--<p class="left">-->
+                            <!--u互连3.2121u互连3.2121u互连3.2121u互连3.2121u互连3.2121-->
+                        <!--</p>-->
+                        <!--<div class="right-thumb">-->
+                            <!--<img src="/jpress/static/jpress/admin/image/dot.png" alt="">-->
+                        <!--</div>-->
+                    <!--</a>-->
+                <!--</div>-->
+        </div>
+        <div class="timeShow">
+            <div class="time">星期五 下午9:00</div>
+        </div>
+        <div class="info">
+            <div class="left-thumb">
+                <img src="/jpress/static/jpress/admin/image/dot.png" alt="">
+            </div>
+            <div class="right-info">
+                <span>审批知会</span>
+                <p>您的请假单20172566未通过审批,特殊时期不允许请假</p>
+            </div>
+            <div class="cart"></div>
+        </div>
+        <div class="timeShow">
+            <div class="time">星期五 下午9:00</div>
+        </div>
+        <div class="info">
+            <div class="left-thumb">
+                <img src="/jpress/static/jpress/admin/image/dot.png" alt="">
+            </div>
+            <div class="right-info">
+                <span>审批知会</span>
+                <p>您的请假单20172566未通过审批,特殊时期不允许请假未通过审批,特殊时期不允许请假未通过审批,特殊时期不允许请假</p>
+            </div>
+            <div class="cart"></div>
+        </div>
+    </div>
+</div>
+</body>
+<script>
+    $('html').css('fontSize',$(window).width()/640 * 30);
+</script>
+</html>

+ 4 - 1
jpress-web-template-usoftchina/src/main/webapp/templates/usoftchina/tpl_config.xml

@@ -35,7 +35,10 @@
 	</module>
 	</module>
 
 
 	<module title="移动信息中心" name="uuhelper" list="软文列表" add="发布信息" comment="留言管理">
 	<module title="移动信息中心" name="uuhelper" list="软文列表" add="发布信息" comment="留言管理">
-		<taxonomy title="分类" name="category" formType="select" />
+		<taxonomy title="推送分类" name="category" formType="select" />
+		<taxonomy title="类别标签" name="tag" formType="input" />
+		<metadata dataType="input" name="push_time" title="发布时间" required="true"></metadata>
+		<metadata dataType="input" name="copy_right" title="版权"  placeholder="" required="true"></metadata>
 	</module>
 	</module>
 
 
 	<module title="常见问题" name="question" list="常见问题" add="发布问题" comment="评论">
 	<module title="常见问题" name="question" list="常见问题" add="发布问题" comment="评论">

Algunos archivos no se mostraron porque demasiados archivos cambiaron en este cambio