添加帖子是否展示的功能(一)数据保存和修改
应对可以通过路径访问,但是不在列表中展示,和机要贴有区别。
包含如下几部分
数据库
帖子表(article)
添加字段帖子是否展示 articleDisplayable, 默认展示
修改 repository.json
{
"name": "articleDisplayable",
"type": "int",
"description": "帖子是否展示,0不展示,1展示"
}
已存在的数据库手动添加列
alter table symphony_article add articleDisplayable int(11) NOT NULL DEFAULT 1 COMMENT '帖子是否展示,0不展示,1展示';
实体类
Article.java
实体类添加属性
/**
* Key of article dispalyable.
*/
public static final String ARTICLE_DISPLAYABLE = "articleDisplayable";
// articleDisplayable constants
/**
* create by: qiankunpingtai
* create time: 2019/5/14 22:42
* website:https://qiankunpingtai.cn
* description:
* 不展示false
* 展示true
*/
public static final Integer ARTICLE_DISPLAYABLE_NOT =0 ;
public static final Integer ARTICLE_DISPLAYABLE_YES = 1;
// articleDisplayable es and algolia constants
/**
* create by: qiankunpingtai
* create time: 2019/5/14 22:42
* website:https://qiankunpingtai.cn
* description:
* 0 删除
* 1 创建
* 2 更新
* 3 不操作
*/
public static final String ARTICLE_DISPLAYABLE_INDEX_OPT="articleDisplayableIndexOpt";
public static final String ARTICLE_DISPLAYABLE_INDEX_OPT_DELETE = "0";
public static final String ARTICLE_DISPLAYABLE_INDEX_OPT_ADD = "1";
public static final String ARTICLE_DISPLAYABLE_INDEX_OPT_UPDATE = "2";
public static final String ARTICLE_DISPLAYABLE_INDEX_OPT_NOTHING = "3";
页面显示文本配置
lang_zh_CN.properties 添加
displayableLabel=允许展示
lang_en_US.properties 添加
displayableLabel=Allow to display
页面
管理员界面
./skins/classic/admin/article.ftl
<div class="fn__flex">
<label>
<div>${qnaOfferPointLabel}</div>
<input type="text" name="articleQnAOfferPoint" value="${article.articleQnAOfferPoint?c}"/>
</label>
<#--添加是否列表展示的控制-->
<label class="mid">
<div>${displayableLabel}</div>
<select id="articleDisplayable" name="articleDisplayable">
<option value="1"<#if 1==article.articleDisplayable> selected</#if>>${yesLabel}</option>
<option value="0"<#if 0==article.articleDisplayable> selected</#if>>${noLabel}</option>
</select>
</label>
</div>
./skins/mobile/admin/article.ftl
<label for="articleId">${pushLabel} Email ${sortLabel}</label>
<input type="number" id="articlePushOrder" name="articlePushOrder" value="${article.articlePushOrder}" />
<#--添加是否列表展示的控制-->
<label>${displayableLabel}</label>
<select id="articleDisplayable" name="articleDisplayable">
<option value="1"<#if 1==article.articleDisplayable> selected</#if>>${yesLabel}</option>
<option value="0"<#if 0==article.articleDisplayable> selected</#if>>${noLabel}</option>
</select>
发帖界面
./skins/classic/home/post.ftl
<#if permissions["commonAddArticleAnonymous"].permissionGrant && articleType != 2 && articleType != 5>
<label class="article-anonymous">${anonymousLabel}<input<#if requisite> readonly disabled</#if>
<#if article??> disabled="disabled"<#if 1 == article.articleAnonymous> checked</#if></#if>
type="checkbox" id="articleAnonymous"></label>
</#if>
<#--添加是否列表展示的控制-->
<label class="article-anonymous"> ${displayableLabel}<input
<#if (article?? && (1==article.articleDisplayable)) || !article??> checked="checked"</#if> type="checkbox" id="articleDisplayable"></label>
./skins/mobile/home/post.ftl
<#if permissions["commonAddArticleAnonymous"].permissionGrant && articleType != 2 && articleType != 5>
<label class="article-anonymous"> ${anonymousLabel}<input
<#if article??> disabled="disabled"<#if 1 == article.articleAnonymous> checked</#if></#if>
type="checkbox" id="articleAnonymous"></label>
</#if>
<#--添加是否列表展示的控制-->
<label class="article-anonymous"> ${displayableLabel}<input
<#if (article?? && (1==article.articleDisplayable)) || !article??> checked="checked"</#if>
type="checkbox" id="articleDisplayable"></label>
add-article.js
add: function (csrfToken, it) {
......
/**
* create by: qiankunpingtai
* create time: 2019/5/14 18:11
* website:https://qiankunpingtai.cn
* description:
* 添加是否在列表中展示项
*/
var requestJSONObject = {
articleTitle: $('#articleTitle').val().replace(/(^\s*)|(\s*$)/g, ''),
articleContent: this.editor.getValue(),
articleTags: articleTags,
articleCommentable: $('#articleCommentable').prop('checked'),
articleNotifyFollowers: $('#articleNotifyFollowers').prop('checked'),
articleType: articleType,
articleDisplayable: Boolean($('#articleDisplayable').prop('checked'))?1:0
}
......
}
add-article.min.js
add: function (e, a) {
......
var r = {
articleTitle: $("#articleTitle").val().replace(/(^\s*)|(\s*$)/g, ""),
articleContent: this.editor.getValue(),
articleTags: i,
articleCommentable: $("#articleCommentable").prop("checked"),
articleNotifyFollowers: $("#articleNotifyFollowers").prop("checked"),
articleType: t,
articleDisplayable: Boolean($('#articleDisplayable').prop('checked'))?1:0
};
......
}
后台处理
保存
/admin/article/
修改AdminProcessor.java
保存方法,从 json 中获取数据
@RequestProcessing(value = "/admin/article/{articleId}", method = HttpMethod.POST)
@Before({StopwatchStartAdvice.class, PermissionCheck.class})
@After({PermissionGrant.class, StopwatchEndAdvice.class})
public void updateArticle(final RequestContext context) {
final String articleId = context.pathVar("articleId");
final HttpServletRequest request = context.getRequest();
final AbstractFreeMarkerRenderer renderer = new SkinRenderer(context, "admin/article.ftl");
final Map<String, Object> dataModel = renderer.getDataModel();
JSONObject article = articleQueryService.getArticle(articleId);
final Enumeration<String> parameterNames = request.getParameterNames();
while (parameterNames.hasMoreElements()) {
final String name = parameterNames.nextElement();
final String value = context.param(name);
/**
* create by: qiankunpingtai
* create time: 2019/5/14 22:45
* website:https://qiankunpingtai.cn
* description:
* int类型,值由字符串更新为int
*/
if (name.equals(Article.ARTICLE_REWARD_POINT)
|| name.equals(Article.ARTICLE_QNA_OFFER_POINT)
|| name.equals(Article.ARTICLE_STATUS)
|| name.equals(Article.ARTICLE_TYPE)
|| name.equals(Article.ARTICLE_THANK_CNT)
|| name.equals(Article.ARTICLE_GOOD_CNT)
|| name.equals(Article.ARTICLE_BAD_CNT)
|| name.equals(Article.ARTICLE_PERFECT)
|| name.equals(Article.ARTICLE_ANONYMOUS_VIEW)
|| name.equals(Article.ARTICLE_PUSH_ORDER)
||name.equals(Article.ARTICLE_DISPLAYABLE)) {
article.put(name, Integer.valueOf(value));
} else {
article.put(name, value);
}
}
final String articleTags = Tag.formatTags(article.optString(Article.ARTICLE_TAGS));
article.put(Article.ARTICLE_TAGS, articleTags);
articleMgmtService.updateArticleByAdmin(articleId, article);
operationMgmtService.addOperation(Operation.newOperation(request, Operation.OPERATION_CODE_C_UPDATE_ARTICLE, articleId));
article = articleQueryService.getArticle(articleId);
String title = article.optString(Article.ARTICLE_TITLE);
title = Escapes.escapeHTML(title);
article.put(Article.ARTICLE_TITLE, title);
dataModel.put(Article.ARTICLE, article);
/**
* create by: qiankunpingtai
* create time: 2019/5/15 10:45
* website:https://qiankunpingtai.cn
* description:
* 如果是不在列表中显示的帖子,直接跳过
*/
final Integer articleDisplayable = article.optInt(Article.ARTICLE_DISPLAYABLE);
if(Article.ARTICLE_DISPLAYABLE_YES.equals(articleDisplayable)){
updateArticleSearchIndex(article);
}
dataModelService.fillHeaderAndFooter(context, dataModel);
}
/article
修改ArticleProcessor.java
@RequestProcessing(value = "/article", method = HttpMethod.POST)
@Before({StopwatchStartAdvice.class, LoginCheck.class, CSRFCheck.class, ArticleAddValidation.class, PermissionCheck.class})
@After(StopwatchEndAdvice.class)
public void addArticle(final RequestContext context) {
context.renderJSON();
final HttpServletRequest request = context.getRequest();
final JSONObject requestJSONObject = context.requestJSON();
final String articleTitle = requestJSONObject.optString(Article.ARTICLE_TITLE);
String articleTags = requestJSONObject.optString(Article.ARTICLE_TAGS);
final String articleContent = requestJSONObject.optString(Article.ARTICLE_CONTENT);
final boolean articleCommentable = requestJSONObject.optBoolean(Article.ARTICLE_COMMENTABLE, true);
final int articleType = requestJSONObject.optInt(Article.ARTICLE_TYPE, Article.ARTICLE_TYPE_C_NORMAL);
final String articleRewardContent = requestJSONObject.optString(Article.ARTICLE_REWARD_CONTENT);
final int articleRewardPoint = requestJSONObject.optInt(Article.ARTICLE_REWARD_POINT);
final int articleQnAOfferPoint = requestJSONObject.optInt(Article.ARTICLE_QNA_OFFER_POINT);
final String ip = Requests.getRemoteAddr(request);
final String ua = Headers.getHeader(request, Common.USER_AGENT, "");
final boolean isAnonymous = requestJSONObject.optBoolean(Article.ARTICLE_ANONYMOUS, false);
final int articleAnonymous = isAnonymous ? Article.ARTICLE_ANONYMOUS_C_ANONYMOUS : Article.ARTICLE_ANONYMOUS_C_PUBLIC;
final boolean articleNotifyFollowers = requestJSONObject.optBoolean(Article.ARTICLE_T_NOTIFY_FOLLOWERS);
/**
* create by: qiankunpingtai
* create time: 2019/5/14 18:11
* website:https://qiankunpingtai.cn
* description:
* 添加是否在列表中展示项
*/
final Integer articleDisplayable = requestJSONObject.optInt(Article.ARTICLE_DISPLAYABLE,Article.ARTICLE_DISPLAYABLE_YES);
final JSONObject article = new JSONObject();
article.put(Article.ARTICLE_TITLE, articleTitle);
article.put(Article.ARTICLE_CONTENT, articleContent);
article.put(Article.ARTICLE_EDITOR_TYPE, 0);
article.put(Article.ARTICLE_COMMENTABLE, articleCommentable);
article.put(Article.ARTICLE_TYPE, articleType);
article.put(Article.ARTICLE_REWARD_CONTENT, articleRewardContent);
article.put(Article.ARTICLE_REWARD_POINT, articleRewardPoint);
article.put(Article.ARTICLE_QNA_OFFER_POINT, articleQnAOfferPoint);
article.put(Article.ARTICLE_IP, "");
if (StringUtils.isNotBlank(ip)) {
article.put(Article.ARTICLE_IP, ip);
}
article.put(Article.ARTICLE_UA, ua);
article.put(Article.ARTICLE_ANONYMOUS, articleAnonymous);
article.put(Article.ARTICLE_T_NOTIFY_FOLLOWERS, articleNotifyFollowers);
/**
* create by: qiankunpingtai
* create time: 2019/5/14 18:11
* website:https://qiankunpingtai.cn
* description:
* 添加是否在列表中展示项
*/
article.put(Article.ARTICLE_DISPLAYABLE, articleDisplayable);
try {
final JSONObject currentUser = Sessions.getUser();
article.put(Article.ARTICLE_AUTHOR_ID, currentUser.optString(Keys.OBJECT_ID));
if (!Role.ROLE_ID_C_ADMIN.equals(currentUser.optString(User.USER_ROLE))) {
articleTags = articleMgmtService.filterReservedTags(articleTags);
}
if (Article.ARTICLE_TYPE_C_DISCUSSION == articleType && StringUtils.isBlank(articleTags)) {
articleTags = "机要";
}
if (Article.ARTICLE_TYPE_C_THOUGHT == articleType && StringUtils.isBlank(articleTags)) {
articleTags = "思绪";
}
article.put(Article.ARTICLE_TAGS, articleTags);
final String articleId = articleMgmtService.addArticle(article);
context.renderJSONValue(Keys.STATUS_CODE, StatusCodes.SUCC);
context.renderJSONValue(Article.ARTICLE_T_ID, articleId);
} catch (final ServiceException e) {
final String msg = e.getMessage();
LOGGER.log(Level.ERROR, "Adds article [title=" + articleTitle + "] failed: {0}", e.getMessage());
context.renderMsg(msg);
context.renderJSONValue(Keys.STATUS_CODE, StatusCodes.ERR);
}
}
/article/{id}
修改ArticleProcessor.java
@RequestProcessing(value = "/article/{id}", method = HttpMethod.PUT)
@Before({StopwatchStartAdvice.class, LoginCheck.class, CSRFCheck.class, ArticleUpdateValidation.class, PermissionCheck.class})
@After(StopwatchEndAdvice.class)
public void updateArticle(final RequestContext context) {
final String id = context.pathVar("id");
final HttpServletRequest request = context.getRequest();
if (StringUtils.isBlank(id)) {
context.sendError(HttpServletResponse.SC_NOT_FOUND);
return;
}
final JSONObject oldArticle = articleQueryService.getArticleById(id);
if (null == oldArticle) {
context.sendError(HttpServletResponse.SC_NOT_FOUND);
return;
}
context.renderJSON();
if (Article.ARTICLE_STATUS_C_VALID != oldArticle.optInt(Article.ARTICLE_STATUS)) {
context.renderMsg(langPropsService.get("articleLockedLabel"));
context.renderJSONValue(Keys.STATUS_CODE, StatusCodes.ERR);
return;
}
final JSONObject requestJSONObject = context.requestJSON();
final String articleTitle = requestJSONObject.optString(Article.ARTICLE_TITLE);
String articleTags = requestJSONObject.optString(Article.ARTICLE_TAGS);
final String articleContent = requestJSONObject.optString(Article.ARTICLE_CONTENT);
final boolean articleCommentable = requestJSONObject.optBoolean(Article.ARTICLE_COMMENTABLE, true);
final int articleType = requestJSONObject.optInt(Article.ARTICLE_TYPE, Article.ARTICLE_TYPE_C_NORMAL);
final String articleRewardContent = requestJSONObject.optString(Article.ARTICLE_REWARD_CONTENT);
final int articleRewardPoint = requestJSONObject.optInt(Article.ARTICLE_REWARD_POINT);
final int articleQnAOfferPoint = requestJSONObject.optInt(Article.ARTICLE_QNA_OFFER_POINT);
final String ip = Requests.getRemoteAddr(request);
final String ua = Headers.getHeader(request, Common.USER_AGENT, "");
final boolean articleNotifyFollowers = requestJSONObject.optBoolean(Article.ARTICLE_T_NOTIFY_FOLLOWERS);
/**
* create by: qiankunpingtai
* create time: 2019/5/14 18:11
* website:https://qiankunpingtai.cn
* description:
* 添加是否在列表中展示项
*/
final Integer articleDisplayable = requestJSONObject.optInt(Article.ARTICLE_DISPLAYABLE,Article.ARTICLE_DISPLAYABLE_YES);
final JSONObject article = new JSONObject();
/**
* create by: qiankunpingtai
* create time: 2019/5/15 11:10
* website:https://qiankunpingtai.cn
* description:
* 获取文章原始是否在列表中展示标记
* 如果原始是在列表展示,现在修改为不在列表中展示,需要删除es和algolia索引
*
*/
if(Article.ARTICLE_DISPLAYABLE_YES.equals(oldArticle.optInt(Article.ARTICLE_DISPLAYABLE))){
if(Article.ARTICLE_DISPLAYABLE_YES.equals(articleDisplayable)){
//以前在列表展示,现在也在列表展示,更新索引
article.put(Article.ARTICLE_DISPLAYABLE_INDEX_OPT,Article.ARTICLE_DISPLAYABLE_INDEX_OPT_UPDATE);
}else{
//以前在列表展示,现在不在列表展示,删除索引
article.put(Article.ARTICLE_DISPLAYABLE_INDEX_OPT,Article.ARTICLE_DISPLAYABLE_INDEX_OPT_DELETE);
}
}else{
if(Article.ARTICLE_DISPLAYABLE_YES.equals(articleDisplayable)){
//以前不在列表展示,现在在列表展示,新建索引
article.put(Article.ARTICLE_DISPLAYABLE_INDEX_OPT,Article.ARTICLE_DISPLAYABLE_INDEX_OPT_ADD);
}else{
//以前不在列表展示,现在也不在列表展示,不操作索引
article.put(Article.ARTICLE_DISPLAYABLE_INDEX_OPT,Article.ARTICLE_DISPLAYABLE_INDEX_OPT_NOTHING);
}
}
article.put(Keys.OBJECT_ID, id);
article.put(Article.ARTICLE_TITLE, articleTitle);
article.put(Article.ARTICLE_CONTENT, articleContent);
article.put(Article.ARTICLE_EDITOR_TYPE, 0);
article.put(Article.ARTICLE_COMMENTABLE, articleCommentable);
article.put(Article.ARTICLE_TYPE, articleType);
article.put(Article.ARTICLE_REWARD_CONTENT, articleRewardContent);
article.put(Article.ARTICLE_REWARD_POINT, articleRewardPoint);
article.put(Article.ARTICLE_QNA_OFFER_POINT, articleQnAOfferPoint);
article.put(Article.ARTICLE_IP, "");
if (StringUtils.isNotBlank(ip)) {
article.put(Article.ARTICLE_IP, ip);
}
article.put(Article.ARTICLE_UA, ua);
article.put(Article.ARTICLE_T_NOTIFY_FOLLOWERS, articleNotifyFollowers);
/**
* create by: qiankunpingtai
* create time: 2019/5/14 18:11
* website:https://qiankunpingtai.cn
* description:
* 添加是否在列表中展示项
*/
article.put(Article.ARTICLE_DISPLAYABLE, articleDisplayable);
final JSONObject currentUser = Sessions.getUser();
if (null == currentUser
|| !currentUser.optString(Keys.OBJECT_ID).equals(oldArticle.optString(Article.ARTICLE_AUTHOR_ID))) {
context.sendError(HttpServletResponse.SC_FORBIDDEN);
return;
}
article.put(Article.ARTICLE_AUTHOR_ID, currentUser.optString(Keys.OBJECT_ID));
if (!Role.ROLE_ID_C_ADMIN.equals(currentUser.optString(User.USER_ROLE))) {
articleTags = articleMgmtService.filterReservedTags(articleTags);
}
if (Article.ARTICLE_TYPE_C_DISCUSSION == articleType && StringUtils.isBlank(articleTags)) {
articleTags = "机要";
}
if (Article.ARTICLE_TYPE_C_THOUGHT == articleType && StringUtils.isBlank(articleTags)) {
articleTags = "思绪";
}
article.put(Article.ARTICLE_TAGS, articleTags);
try {
articleMgmtService.updateArticle(article);
context.renderJSONValue(Keys.STATUS_CODE, StatusCodes.SUCC);
context.renderJSONValue(Article.ARTICLE_T_ID, id);
} catch (final ServiceException e) {
final String msg = e.getMessage();
LOGGER.log(Level.ERROR, "Adds article [title=" + articleTitle + "] failed: {0}", e.getMessage());
context.renderMsg(msg);
context.renderJSONValue(Keys.STATUS_CODE, StatusCodes.ERR);
}
}
ArticleMgmtService.java
public synchronized void updateArticle(final JSONObject requestJSONObject) throws ServiceException {
String articleTitle = requestJSONObject.optString(Article.ARTICLE_TITLE);
String articleId;
JSONObject articleToUpdate;
JSONObject oldArticle;
String authorId;
JSONObject author;
int updatePointSum;
int articleAnonymous;
try {
// check if admin allow to add article
final JSONObject option = optionRepository.get(Option.ID_C_MISC_ALLOW_ADD_ARTICLE);
if (!"0".equals(option.optString(Option.OPTION_VALUE))) {
throw new ServiceException(langPropsService.get("notAllowAddArticleLabel"));
}
articleId = requestJSONObject.optString(Keys.OBJECT_ID);
articleToUpdate = articleRepository.get(articleId);
oldArticle = JSONs.clone(articleToUpdate);
authorId = articleToUpdate.optString(Article.ARTICLE_AUTHOR_ID);
author = userRepository.get(authorId);
if (UserExt.USER_STATUS_C_VALID != author.optInt(UserExt.USER_STATUS)) {
throw new ServiceException(langPropsService.get("userStatusInvalidLabel"));
}
final long followerCnt = followQueryService.getFollowerCount(authorId, Follow.FOLLOWING_TYPE_C_USER);
int addition = (int) Math.round(Math.sqrt(followerCnt));
final long collectCnt = followQueryService.getFollowerCount(articleId, Follow.FOLLOWING_TYPE_C_ARTICLE);
final long watchCnt = followQueryService.getFollowerCount(articleId, Follow.FOLLOWING_TYPE_C_ARTICLE_WATCH);
addition += (collectCnt + watchCnt) * 2;
updatePointSum = Pointtransfer.TRANSFER_SUM_C_UPDATE_ARTICLE + addition;
articleAnonymous = articleToUpdate.optInt(Article.ARTICLE_ANONYMOUS);
if (Article.ARTICLE_ANONYMOUS_C_PUBLIC == articleAnonymous) {
final int balance = author.optInt(UserExt.USER_POINT);
if (balance - updatePointSum < 0) {
throw new ServiceException(langPropsService.get("insufficientBalanceLabel"));
}
}
final JSONObject maybeExist = articleRepository.getByTitle(articleTitle);
if (null != maybeExist) {
if (!articleToUpdate.optString(Article.ARTICLE_TITLE).equals(articleTitle)) {
final String existArticleAuthorId = maybeExist.optString(Article.ARTICLE_AUTHOR_ID);
String msg;
if (existArticleAuthorId.equals(authorId)) {
msg = langPropsService.get("duplicatedArticleTitleSelfLabel");
msg = msg.replace("{article}", "<a target='_blank' href='/article/" + maybeExist.optString(Keys.OBJECT_ID)
+ "'>" + articleTitle + "</a>");
} else {
final JSONObject existArticleAuthor = userRepository.get(existArticleAuthorId);
final String userName = existArticleAuthor.optString(User.USER_NAME);
msg = langPropsService.get("duplicatedArticleTitleLabel");
msg = msg.replace("{user}", "<a target='_blank' href='/member/" + userName + "'>" + userName + "</a>");
msg = msg.replace("{article}", "<a target='_blank' href='/article/" + maybeExist.optString(Keys.OBJECT_ID)
+ "'>" + articleTitle + "</a>");
}
throw new ServiceException(msg);
}
}
} catch (final RepositoryException e) {
throw new ServiceException(e);
}
final int qnaOfferPoint = requestJSONObject.optInt(Article.ARTICLE_QNA_OFFER_POINT, 0);
if (qnaOfferPoint < articleToUpdate.optInt(Article.ARTICLE_QNA_OFFER_POINT)) { // Increase only to prevent lowering points when adopting answer
throw new ServiceException(langPropsService.get("qnaOfferPointMustMoreThanOldLabel"));
}
articleToUpdate.put(Article.ARTICLE_QNA_OFFER_POINT, qnaOfferPoint);
final int articleType = requestJSONObject.optInt(Article.ARTICLE_TYPE, Article.ARTICLE_TYPE_C_NORMAL);
final Transaction transaction = articleRepository.beginTransaction();
try {
requestJSONObject.put(Article.ARTICLE_ANONYMOUS, articleAnonymous);
processTagsForArticleUpdate(articleToUpdate, requestJSONObject, author);
userRepository.update(author.optString(Keys.OBJECT_ID), author);
articleTitle = Emotions.toAliases(articleTitle);
articleTitle = Pangu.spacingText(articleTitle);
final String oldTitle = articleToUpdate.optString(Article.ARTICLE_TITLE);
articleToUpdate.put(Article.ARTICLE_TITLE, articleTitle);
articleToUpdate.put(Article.ARTICLE_TAGS, requestJSONObject.optString(Article.ARTICLE_TAGS));
articleToUpdate.put(Article.ARTICLE_COMMENTABLE, requestJSONObject.optBoolean(Article.ARTICLE_COMMENTABLE, true));
articleToUpdate.put(Article.ARTICLE_TYPE, articleType);
/**
* create by: qiankunpingtai
* create time: 2019/5/14 22:45
* website:https://qiankunpingtai.cn
* description:
* 添加帖子是否展示字段
*/
articleToUpdate.put(Article.ARTICLE_DISPLAYABLE,requestJSONObject.optInt(Article.ARTICLE_DISPLAYABLE, Article.ARTICLE_DISPLAYABLE_YES));
String articleContent = requestJSONObject.optString(Article.ARTICLE_CONTENT);
articleContent = Emotions.toAliases(articleContent);
//articleContent = StringUtils.trim(articleContent) + " "; https://github.com/b3log/symphony/issues/389
articleContent = articleContent.replace(langPropsService.get("uploadingLabel", Locale.SIMPLIFIED_CHINESE), "");
articleContent = articleContent.replace(langPropsService.get("uploadingLabel", Locale.US), "");
if (Article.ARTICLE_TYPE_C_THOUGHT != articleType) {
articleContent = Runes.removeControlChars(articleContent);
}
final String oldContent = articleToUpdate.optString(Article.ARTICLE_CONTENT);
articleToUpdate.put(Article.ARTICLE_CONTENT, articleContent);
final long currentTimeMillis = System.currentTimeMillis();
final long createTime = articleToUpdate.optLong(Keys.OBJECT_ID);
final boolean notIn5m = currentTimeMillis - createTime > 1000 * 60 * 5;
articleToUpdate.put(Article.ARTICLE_UPDATE_TIME, currentTimeMillis);
final int rewardPoint = requestJSONObject.optInt(Article.ARTICLE_REWARD_POINT, 0);
boolean enableReward = false;
if (0 < rewardPoint) {
if (1 > articleToUpdate.optInt(Article.ARTICLE_REWARD_POINT)) {
enableReward = true;
}
String rewardContent = requestJSONObject.optString(Article.ARTICLE_REWARD_CONTENT);
rewardContent = Emotions.toAliases(rewardContent);
rewardContent = Runes.removeControlChars(rewardContent);
articleToUpdate.put(Article.ARTICLE_REWARD_CONTENT, rewardContent);
articleToUpdate.put(Article.ARTICLE_REWARD_POINT, rewardPoint);
}
final String ip = requestJSONObject.optString(Article.ARTICLE_IP);
articleToUpdate.put(Article.ARTICLE_IP, ip);
String ua = requestJSONObject.optString(Article.ARTICLE_UA);
if (StringUtils.length(ua) > Common.MAX_LENGTH_UA) {
ua = StringUtils.substring(ua, 0, Common.MAX_LENGTH_UA);
}
articleToUpdate.put(Article.ARTICLE_UA, ua);
articleToUpdate.put(Article.ARTICLE_AUDIO_URL, ""); // 小薇语音预览更新 https://github.com/b3log/symphony/issues/791
articleRepository.update(articleId, articleToUpdate);
final boolean titleChanged = !oldTitle.replaceAll("\\s+", "").equals(articleTitle.replaceAll("\\s+", ""));
final boolean contentChanged = !oldContent.replaceAll("\\s+", "").equals(articleContent.replaceAll("\\s+", ""));
if (notIn5m && Article.ARTICLE_TYPE_C_THOUGHT != articleType
&& (titleChanged || contentChanged)) {
final JSONObject revision = new JSONObject();
revision.put(Revision.REVISION_AUTHOR_ID, authorId);
final JSONObject revisionData = new JSONObject();
revisionData.put(Article.ARTICLE_TITLE, articleTitle);
revisionData.put(Article.ARTICLE_CONTENT, articleContent);
revision.put(Revision.REVISION_DATA, revisionData.toString());
revision.put(Revision.REVISION_DATA_ID, articleId);
revision.put(Revision.REVISION_DATA_TYPE, Revision.DATA_TYPE_C_ARTICLE);
revisionRepository.add(revision);
}
transaction.commit();
try {
Thread.sleep(50); // wait for db write to avoid article duplication
} catch (final Exception e) {
}
if (Article.ARTICLE_ANONYMOUS_C_PUBLIC == articleAnonymous) {
if (notIn5m) {
pointtransferMgmtService.transfer(authorId, Pointtransfer.ID_C_SYS,
Pointtransfer.TRANSFER_TYPE_C_UPDATE_ARTICLE,
updatePointSum, articleId, System.currentTimeMillis(), "");
}
if (enableReward) {
pointtransferMgmtService.transfer(authorId, Pointtransfer.ID_C_SYS,
Pointtransfer.TRANSFER_TYPE_C_ADD_ARTICLE_REWARD,
Pointtransfer.TRANSFER_SUM_C_ADD_ARTICLE_REWARD, articleId, System.currentTimeMillis(), "");
}
}
final JSONObject eventData = new JSONObject();
/**
* create by: qiankunpingtai
* create time: 2019/5/15 11:34
* website:https://qiankunpingtai.cn
* description:
* 这里根据之前的判断,选择调用新建、删除、更新还是不操作索引
*/
String opt=requestJSONObject.optString(Article.ARTICLE_DISPLAYABLE_INDEX_OPT);
if(Article.ARTICLE_DISPLAYABLE_INDEX_OPT_DELETE.equals(opt)){
//删除
if (Symphonys.ALGOLIA_ENABLED) {
searchMgmtService.removeAlgoliaDocument(articleToUpdate);
}
if (Symphonys.ES_ENABLED) {
searchMgmtService.removeESDocument(articleToUpdate, Article.ARTICLE);
}
}else if(Article.ARTICLE_DISPLAYABLE_INDEX_OPT_ADD.equals(opt)){
//新建
eventData.put(Article.ARTICLE, articleToUpdate);
eventData.put(Article.ARTICLE_T_NOTIFY_FOLLOWERS, requestJSONObject.optBoolean(Article.ARTICLE_T_NOTIFY_FOLLOWERS));
eventManager.fireEventAsynchronously(new Event<>(EventTypes.ADD_ARTICLE, eventData));
}else if(Article.ARTICLE_DISPLAYABLE_INDEX_OPT_UPDATE.equals(opt)){
//更新
eventData.put(Article.ARTICLE, articleToUpdate);
eventData.put(Common.OLD_ARTICLE, oldArticle);
eventData.put(Article.ARTICLE_T_NOTIFY_FOLLOWERS, requestJSONObject.optBoolean(Article.ARTICLE_T_NOTIFY_FOLLOWERS));
eventManager.fireEventAsynchronously(new Event<>(EventTypes.UPDATE_ARTICLE, eventData));
}else{
//不操作
return;
}
} catch (final Exception e) {
if (transaction.isActive()) {
transaction.rollback();
}
LOGGER.log(Level.ERROR, "Updates an article failed", e);
throw new ServiceException(e);
}
}
管理员添加帖子
/admin/add-article
管理员添加的帖子默认在列表中展示,如果不需要在列表中展示,可以在帖子修改页面进行修改。
@RequestProcessing(value = "/admin/add-article", method = HttpMethod.POST)
@Before({StopwatchStartAdvice.class, PermissionCheck.class})
@After({PermissionGrant.class, StopwatchEndAdvice.class})
public void addArticle(final RequestContext context) {
final HttpServletRequest request = context.getRequest();
final String userName = context.param(User.USER_NAME);
final JSONObject author = userQueryService.getUserByName(userName);
if (null == author) {
final AbstractFreeMarkerRenderer renderer = new SkinRenderer(context, "admin/error.ftl");
final Map<String, Object> dataModel = renderer.getDataModel();
dataModel.put(Keys.MSG, langPropsService.get("notFoundUserLabel"));
dataModelService.fillHeaderAndFooter(context, dataModel);
return;
}
final String timeStr = context.param(Common.TIME);
final String articleTitle = context.param(Article.ARTICLE_TITLE);
final String articleTags = context.param(Article.ARTICLE_TAGS);
final String articleContent = context.param(Article.ARTICLE_CONTENT);
String rewardContent = context.param(Article.ARTICLE_REWARD_CONTENT);
final String rewardPoint = context.param(Article.ARTICLE_REWARD_POINT);
/**
* create by: qiankunpingtai
* create time: 2019/5/14 18:11
* website:https://qiankunpingtai.cn
* description:
* 添加是否在列表中展示项
* 管理员添加的帖子默认在列表中展示,如果不需要在列表中展示,可以在帖子修改页面进行修改。
*/
final Integer articleDisplayable = Article.ARTICLE_DISPLAYABLE_YES;
long time = System.currentTimeMillis();
try {
final Date date = DateUtils.parseDate(timeStr, new String[]{"yyyy-MM-dd'T'HH:mm"});
time = date.getTime();
final int random = RandomUtils.nextInt(9999);
time += random;
} catch (final ParseException e) {
LOGGER.log(Level.ERROR, "Parse time failed, using current time instead");
}
final JSONObject article = new JSONObject();
article.put(Article.ARTICLE_TITLE, articleTitle);
article.put(Article.ARTICLE_TAGS, articleTags);
article.put(Article.ARTICLE_CONTENT, articleContent);
article.put(Article.ARTICLE_REWARD_CONTENT, rewardContent);
article.put(Article.ARTICLE_REWARD_POINT, Integer.valueOf(rewardPoint));
article.put(User.USER_NAME, userName);
article.put(Common.TIME, time);
article.put(Article.ARTICLE_DISPLAYABLE,articleDisplayable);
try {
final String articleId = articleMgmtService.addArticleByAdmin(article);
operationMgmtService.addOperation(Operation.newOperation(request, Operation.OPERATION_CODE_C_ADD_ARTICLE, articleId));
} catch (final ServiceException e) {
final AbstractFreeMarkerRenderer renderer = new SkinRenderer(context, "admin/error.ftl");
final Map<String, Object> dataModel = renderer.getDataModel();
dataModel.put(Keys.MSG, e.getMessage());
dataModelService.fillHeaderAndFooter(context, dataModel);
return;
}
context.sendRedirect(Latkes.getServePath() + "/admin/articles");
}