Commit 86bd7489 authored by Liang Ding's avatar Liang Ding

Fixed #269

parent d20c6e4f
...@@ -30,7 +30,6 @@ import org.b3log.latke.logging.Level; ...@@ -30,7 +30,6 @@ import org.b3log.latke.logging.Level;
import org.b3log.latke.logging.Logger; import org.b3log.latke.logging.Logger;
import org.b3log.latke.plugin.PluginManager; import org.b3log.latke.plugin.PluginManager;
import org.b3log.latke.plugin.ViewLoadEventHandler; import org.b3log.latke.plugin.ViewLoadEventHandler;
import org.b3log.latke.repository.RepositoryException;
import org.b3log.latke.repository.Transaction; import org.b3log.latke.repository.Transaction;
import org.b3log.latke.servlet.AbstractServletListener; import org.b3log.latke.servlet.AbstractServletListener;
import org.b3log.latke.util.Requests; import org.b3log.latke.util.Requests;
...@@ -50,7 +49,6 @@ import org.b3log.solo.model.Preference; ...@@ -50,7 +49,6 @@ import org.b3log.solo.model.Preference;
import org.b3log.solo.model.Skin; import org.b3log.solo.model.Skin;
import org.b3log.solo.repository.PreferenceRepository; import org.b3log.solo.repository.PreferenceRepository;
import org.b3log.solo.repository.impl.PreferenceRepositoryImpl; import org.b3log.solo.repository.impl.PreferenceRepositoryImpl;
import org.b3log.solo.repository.impl.UserRepositoryImpl;
import org.b3log.solo.service.PreferenceMgmtService; import org.b3log.solo.service.PreferenceMgmtService;
import org.b3log.solo.service.StatisticMgmtService; import org.b3log.solo.service.StatisticMgmtService;
import org.b3log.solo.util.Skins; import org.b3log.solo.util.Skins;
...@@ -61,7 +59,7 @@ import org.json.JSONObject; ...@@ -61,7 +59,7 @@ import org.json.JSONObject;
* B3log Solo servlet listener. * B3log Solo servlet listener.
* *
* @author <a href="mailto:DL88250@gmail.com">Liang Ding</a> * @author <a href="mailto:DL88250@gmail.com">Liang Ding</a>
* @version 1.0.9.9, Apr 26, 2013 * @version 1.1.0.0, Jun 28, 2013
* @since 0.3.1 * @since 0.3.1
*/ */
public final class SoloServletListener extends AbstractServletListener { public final class SoloServletListener extends AbstractServletListener {
...@@ -96,6 +94,11 @@ public final class SoloServletListener extends AbstractServletListener { ...@@ -96,6 +94,11 @@ public final class SoloServletListener extends AbstractServletListener {
*/ */
public static final String B3LOG_SYMPHONY_SERVE_PATH; public static final String B3LOG_SYMPHONY_SERVE_PATH;
/**
* Bean manager.
*/
private LatkeBeanManager beanManager;
static { static {
final ResourceBundle b3log = ResourceBundle.getBundle("b3log"); final ResourceBundle b3log = ResourceBundle.getBundle("b3log");
...@@ -106,13 +109,15 @@ public final class SoloServletListener extends AbstractServletListener { ...@@ -106,13 +109,15 @@ public final class SoloServletListener extends AbstractServletListener {
@Override @Override
public void contextInitialized(final ServletContextEvent servletContextEvent) { public void contextInitialized(final ServletContextEvent servletContextEvent) {
super.contextInitialized(servletContextEvent); super.contextInitialized(servletContextEvent);
beanManager = Lifecycle.getBeanManager();
Stopwatchs.start("Context Initialized"); Stopwatchs.start("Context Initialized");
// Default to skin "ease", loads from preference later // Default to skin "ease", loads from preference later
Skins.setDirectoryForTemplateLoading("ease"); Skins.setDirectoryForTemplateLoading("ease");
final PreferenceRepository preferenceRepository = new PreferenceRepositoryImpl(); final PreferenceRepository preferenceRepository = beanManager.getReference(PreferenceRepositoryImpl.class);
final Transaction transaction = preferenceRepository.beginTransaction(); final Transaction transaction = preferenceRepository.beginTransaction();
...@@ -137,7 +142,7 @@ public final class SoloServletListener extends AbstractServletListener { ...@@ -137,7 +142,7 @@ public final class SoloServletListener extends AbstractServletListener {
LOGGER.info("Initialized the context"); LOGGER.info("Initialized the context");
Stopwatchs.end(); Stopwatchs.end();
LOGGER.log(Level.DEBUG, "Stopwatch: {0}{1}", new Object[] {Strings.LINE_SEPARATOR, Stopwatchs.getTimingStat()}); LOGGER.log(Level.DEBUG, "Stopwatch: {0}{1}", Strings.LINE_SEPARATOR, Stopwatchs.getTimingStat());
} }
@Override @Override
...@@ -168,10 +173,9 @@ public final class SoloServletListener extends AbstractServletListener { ...@@ -168,10 +173,9 @@ public final class SoloServletListener extends AbstractServletListener {
// Gets the session of this request // Gets the session of this request
final HttpSession session = httpServletRequest.getSession(); final HttpSession session = httpServletRequest.getSession();
LOGGER.log(Level.DEBUG, "Gets a session[id={0}, remoteAddr={1}, User-Agent={2}, isNew={3}]", new Object[] { LOGGER.log(Level.DEBUG, "Gets a session[id={0}, remoteAddr={1}, User-Agent={2}, isNew={3}]", session.getId(),
session.getId(), httpServletRequest.getRemoteAddr(), httpServletRequest.getHeader("User-Agent"), session.isNew()}); httpServletRequest.getRemoteAddr(), httpServletRequest.getHeader("User-Agent"), session.isNew());
// Online visitor count // Online visitor count
final LatkeBeanManager beanManager = Lifecycle.getBeanManager();
final StatisticMgmtService statisticMgmtService = beanManager.getReference(StatisticMgmtService.class); final StatisticMgmtService statisticMgmtService = beanManager.getReference(StatisticMgmtService.class);
statisticMgmtService.onlineVisitorCount(httpServletRequest); statisticMgmtService.onlineVisitorCount(httpServletRequest);
...@@ -184,7 +188,7 @@ public final class SoloServletListener extends AbstractServletListener { ...@@ -184,7 +188,7 @@ public final class SoloServletListener extends AbstractServletListener {
public void requestDestroyed(final ServletRequestEvent servletRequestEvent) { public void requestDestroyed(final ServletRequestEvent servletRequestEvent) {
Stopwatchs.end(); Stopwatchs.end();
LOGGER.log(Level.DEBUG, "Stopwatch: {0}{1}", new Object[] {Strings.LINE_SEPARATOR, Stopwatchs.getTimingStat()}); LOGGER.log(Level.DEBUG, "Stopwatch: {0}{1}", Strings.LINE_SEPARATOR, Stopwatchs.getTimingStat());
Stopwatchs.release(); Stopwatchs.release();
super.requestDestroyed(servletRequestEvent); super.requestDestroyed(servletRequestEvent);
...@@ -210,7 +214,7 @@ public final class SoloServletListener extends AbstractServletListener { ...@@ -210,7 +214,7 @@ public final class SoloServletListener extends AbstractServletListener {
LOGGER.info("Loading preference...."); LOGGER.info("Loading preference....");
final PreferenceRepository preferenceRepository = new PreferenceRepositoryImpl(); final PreferenceRepository preferenceRepository = beanManager.getReference(PreferenceRepositoryImpl.class);
JSONObject preference; JSONObject preference;
try { try {
...@@ -220,7 +224,9 @@ public final class SoloServletListener extends AbstractServletListener { ...@@ -220,7 +224,9 @@ public final class SoloServletListener extends AbstractServletListener {
return; return;
} }
new PreferenceMgmtService().loadSkins(preference); final PreferenceMgmtService preferenceMgmtService = beanManager.getReference(PreferenceMgmtService.class);
preferenceMgmtService.loadSkins(preference);
final boolean pageCacheEnabled = preference.getBoolean(Preference.PAGE_CACHE_ENABLED); final boolean pageCacheEnabled = preference.getBoolean(Preference.PAGE_CACHE_ENABLED);
...@@ -234,23 +240,6 @@ public final class SoloServletListener extends AbstractServletListener { ...@@ -234,23 +240,6 @@ public final class SoloServletListener extends AbstractServletListener {
Stopwatchs.end(); Stopwatchs.end();
} }
/**
* Determines Solo had been initialized.
*
* @return {@code true} if it had been initialized, {@code false} otherwise
*/
// XXX: to find a better way (isInited)?
public static boolean isInited() {
try {
final JSONObject admin = new UserRepositoryImpl().getAdmin();
return null != admin;
} catch (final RepositoryException e) {
LOGGER.log(Level.WARN, "B3log Solo has not been initialized");
return false;
}
}
/** /**
* Register event processors. * Register event processors.
*/ */
...@@ -293,7 +282,7 @@ public final class SoloServletListener extends AbstractServletListener { ...@@ -293,7 +282,7 @@ public final class SoloServletListener extends AbstractServletListener {
*/ */
private void resolveSkinDir(final HttpServletRequest httpServletRequest) { private void resolveSkinDir(final HttpServletRequest httpServletRequest) {
try { try {
final PreferenceRepository preferenceRepository = new PreferenceRepositoryImpl(); final PreferenceRepository preferenceRepository = beanManager.getReference(PreferenceRepositoryImpl.class);
final JSONObject preference = preferenceRepository.get(Preference.PREFERENCE); final JSONObject preference = preferenceRepository.get(Preference.PREFERENCE);
if (null == preference) { // Did not initialize yet if (null == preference) { // Did not initialize yet
......
...@@ -35,7 +35,7 @@ import org.b3log.latke.service.ServiceException; ...@@ -35,7 +35,7 @@ import org.b3log.latke.service.ServiceException;
import org.b3log.latke.servlet.HTTPRequestContext; import org.b3log.latke.servlet.HTTPRequestContext;
import org.b3log.latke.servlet.HTTPRequestDispatcher; import org.b3log.latke.servlet.HTTPRequestDispatcher;
import org.b3log.latke.servlet.HTTPRequestMethod; import org.b3log.latke.servlet.HTTPRequestMethod;
import org.b3log.solo.SoloServletListener; import org.b3log.solo.service.InitService;
import org.b3log.solo.service.PreferenceQueryService; import org.b3log.solo.service.PreferenceQueryService;
import org.json.JSONObject; import org.json.JSONObject;
...@@ -44,7 +44,7 @@ import org.json.JSONObject; ...@@ -44,7 +44,7 @@ import org.json.JSONObject;
* Checks initialization filter. * Checks initialization filter.
* *
* @author <a href="mailto:DL88250@gmail.com">Liang Ding</a> * @author <a href="mailto:DL88250@gmail.com">Liang Ding</a>
* @version 1.0.0.9, May 17, 2012 * @version 1.0.1.0, Jun 28, 2013
* @since 0.3.1 * @since 0.3.1
*/ */
public final class InitCheckFilter implements Filter { public final class InitCheckFilter implements Filter {
...@@ -81,8 +81,11 @@ public final class InitCheckFilter implements Filter { ...@@ -81,8 +81,11 @@ public final class InitCheckFilter implements Filter {
return; return;
} }
final LatkeBeanManager beanManager = Lifecycle.getBeanManager();
final InitService initService = beanManager.getReference(InitService.class);
try { try {
if (SoloServletListener.isInited()) { if (initService.isInited()) {
chain.doFilter(request, response); chain.doFilter(request, response);
return; return;
...@@ -95,7 +98,6 @@ public final class InitCheckFilter implements Filter { ...@@ -95,7 +98,6 @@ public final class InitCheckFilter implements Filter {
return; return;
} }
final LatkeBeanManager beanManager = Lifecycle.getBeanManager();
final PreferenceQueryService preferenceQueryService = beanManager.getReference(PreferenceQueryService.class); final PreferenceQueryService preferenceQueryService = beanManager.getReference(PreferenceQueryService.class);
LOGGER.debug("Try to get preference to confirm whether the preference exixts"); LOGGER.debug("Try to get preference to confirm whether the preference exixts");
......
...@@ -345,7 +345,7 @@ public final class ArticleProcessor { ...@@ -345,7 +345,7 @@ public final class ArticleProcessor {
if (Strings.isEmptyOrNull(articleId)) { if (Strings.isEmptyOrNull(articleId)) {
return; return;
} }
final TextHTMLRenderer renderer = new TextHTMLRenderer(); final TextHTMLRenderer renderer = new TextHTMLRenderer();
context.setRenderer(renderer); context.setRenderer(renderer);
...@@ -353,7 +353,7 @@ public final class ArticleProcessor { ...@@ -353,7 +353,7 @@ public final class ArticleProcessor {
String content; String content;
try { try {
content = articleQueryService.getArticleContent(articleId); content = articleQueryService.getArticleContent(request, articleId);
} catch (final ServiceException e) { } catch (final ServiceException e) {
LOGGER.log(Level.ERROR, "Can not get article content", e); LOGGER.log(Level.ERROR, "Can not get article content", e);
return; return;
......
...@@ -52,7 +52,7 @@ import org.json.JSONObject; ...@@ -52,7 +52,7 @@ import org.json.JSONObject;
* B3log Solo initialization service. * B3log Solo initialization service.
* *
* @author <a href="mailto:DL88250@gmail.com">Liang Ding</a> * @author <a href="mailto:DL88250@gmail.com">Liang Ding</a>
* @version 1.0.0.5, Sep 6, 2012 * @version 1.0.0.6, Jun 28, 2013
* @since 0.4.0 * @since 0.4.0
*/ */
@RequestProcessor @RequestProcessor
...@@ -92,7 +92,7 @@ public final class InitProcessor { ...@@ -92,7 +92,7 @@ public final class InitProcessor {
@RequestProcessing(value = "/init", method = HTTPRequestMethod.GET) @RequestProcessing(value = "/init", method = HTTPRequestMethod.GET)
public void showInit(final HTTPRequestContext context, final HttpServletRequest request, final HttpServletResponse response) public void showInit(final HTTPRequestContext context, final HttpServletRequest request, final HttpServletResponse response)
throws Exception { throws Exception {
if (SoloServletListener.isInited()) { if (initService.isInited()) {
response.sendRedirect("/"); response.sendRedirect("/");
return; return;
...@@ -136,7 +136,7 @@ public final class InitProcessor { ...@@ -136,7 +136,7 @@ public final class InitProcessor {
@RequestProcessing(value = "/init", method = HTTPRequestMethod.POST) @RequestProcessing(value = "/init", method = HTTPRequestMethod.POST)
public void initB3logSolo(final HTTPRequestContext context, final HttpServletRequest request, public void initB3logSolo(final HTTPRequestContext context, final HttpServletRequest request,
final HttpServletResponse response) throws Exception { final HttpServletResponse response) throws Exception {
if (SoloServletListener.isInited()) { if (initService.isInited()) {
response.sendRedirect("/"); response.sendRedirect("/");
return; return;
......
...@@ -33,6 +33,7 @@ import org.b3log.latke.logging.Logger; ...@@ -33,6 +33,7 @@ import org.b3log.latke.logging.Logger;
import org.b3log.latke.model.Pagination; import org.b3log.latke.model.Pagination;
import org.b3log.latke.model.User; import org.b3log.latke.model.User;
import org.b3log.latke.repository.*; import org.b3log.latke.repository.*;
import org.b3log.latke.service.LangPropsService;
import org.b3log.latke.service.ServiceException; import org.b3log.latke.service.ServiceException;
import org.b3log.latke.service.annotation.Service; import org.b3log.latke.service.annotation.Service;
import org.b3log.latke.user.UserService; import org.b3log.latke.user.UserService;
...@@ -128,6 +129,12 @@ public final class ArticleQueryService { ...@@ -128,6 +129,12 @@ public final class ArticleQueryService {
@Inject @Inject
private StatisticQueryService statisticQueryService; private StatisticQueryService statisticQueryService;
/**
* Language service.
*/
@Inject
private LangPropsService langPropsService;
/** /**
* Can the current user access an article specified by the given article id? * Can the current user access an article specified by the given article id?
* *
...@@ -178,6 +185,10 @@ public final class ArticleQueryService { ...@@ -178,6 +185,10 @@ public final class ArticleQueryService {
return false; return false;
} }
if (null == request) {
return true;
}
final HttpSession session = request.getSession(false); final HttpSession session = request.getSession(false);
if (null != session) { if (null != session) {
...@@ -920,11 +931,12 @@ public final class ArticleQueryService { ...@@ -920,11 +931,12 @@ public final class ArticleQueryService {
* Invoking this method dose not effect on article view count. * Invoking this method dose not effect on article view count.
* </p> * </p>
* *
* @param request the specified HTTP servlet request
* @param articleId the specified article id * @param articleId the specified article id
* @return article contents, returns {@code null} if not found * @return article contents, returns {@code null} if not found
* @throws ServiceException service exception * @throws ServiceException service exception
*/ */
public String getArticleContent(final String articleId) throws ServiceException { public String getArticleContent(final HttpServletRequest request, final String articleId) throws ServiceException {
if (Strings.isEmptyOrNull(articleId)) { if (Strings.isEmptyOrNull(articleId)) {
return null; return null;
} }
...@@ -936,8 +948,12 @@ public final class ArticleQueryService { ...@@ -936,8 +948,12 @@ public final class ArticleQueryService {
return null; return null;
} }
// Markdown to HTML for content and abstract if (needViewPwd(request, article)) {
if ("CodeMirror-Markdown".equals(article.optString(ARTICLE_EDITOR_TYPE))) { final String content = langPropsService.get("articleContentPwd");
article.put(ARTICLE_CONTENT, content);
} else if ("CodeMirror-Markdown".equals(article.optString(ARTICLE_EDITOR_TYPE))) {
// Markdown to HTML for content and abstract
Stopwatchs.start("Get Article Content [Markdown]"); Stopwatchs.start("Get Article Content [Markdown]");
final String content = article.optString(ARTICLE_CONTENT); final String content = article.optString(ARTICLE_CONTENT);
......
...@@ -60,7 +60,7 @@ import org.json.JSONObject; ...@@ -60,7 +60,7 @@ import org.json.JSONObject;
* B3log Solo initialization service. * B3log Solo initialization service.
* *
* @author <a href="mailto:DL88250@gmail.com">Liang Ding</a> * @author <a href="mailto:DL88250@gmail.com">Liang Ding</a>
* @version 1.0.1.6, May 17, 2013 * @version 1.0.1.7, Jun 28, 2013
* @since 0.4.0 * @since 0.4.0
*/ */
@Service @Service
...@@ -141,6 +141,23 @@ public final class InitService { ...@@ -141,6 +141,23 @@ public final class InitService {
@Inject @Inject
private LangPropsService langPropsService; private LangPropsService langPropsService;
/**
* Determines Solo had been initialized.
*
* @return {@code true} if it had been initialized, {@code false} otherwise
*/
// XXX: to find a better way (isInited)?
public boolean isInited() {
try {
final JSONObject admin = userRepository.getAdmin();
return null != admin;
} catch (final RepositoryException e) {
LOGGER.log(Level.WARN, "B3log Solo has not been initialized");
return false;
}
}
/** /**
* Initializes B3log Solo. * Initializes B3log Solo.
* *
...@@ -172,7 +189,7 @@ public final class InitService { ...@@ -172,7 +189,7 @@ public final class InitService {
* @throws ServiceException service exception * @throws ServiceException service exception
*/ */
public void init(final JSONObject requestJSONObject) throws ServiceException { public void init(final JSONObject requestJSONObject) throws ServiceException {
if (SoloServletListener.isInited()) { if (isInited()) {
return; return;
} }
......
...@@ -344,7 +344,7 @@ public final class StatisticMgmtService { ...@@ -344,7 +344,7 @@ public final class StatisticMgmtService {
* *
* @param request the specified request * @param request the specified request
*/ */
public static void onlineVisitorCount(final HttpServletRequest request) { public void onlineVisitorCount(final HttpServletRequest request) {
final String remoteAddr = Requests.getRemoteAddr(request); final String remoteAddr = Requests.getRemoteAddr(request);
LOGGER.log(Level.DEBUG, "Current request [IP={0}]", remoteAddr); LOGGER.log(Level.DEBUG, "Current request [IP={0}]", remoteAddr);
......
...@@ -29,7 +29,7 @@ import org.testng.annotations.Test; ...@@ -29,7 +29,7 @@ import org.testng.annotations.Test;
* {@link ArticleQueryService} test case. * {@link ArticleQueryService} test case.
* *
* @author <a href="mailto:DL88250@gmail.com">Liang Ding</a> * @author <a href="mailto:DL88250@gmail.com">Liang Ding</a>
* @version 1.0.0.1, Sep 11, 2012 * @version 1.0.0.2, Jun 28, 2013
*/ */
@Test(suiteName = "service") @Test(suiteName = "service")
public class ArticleQueryServiceTestCase extends AbstractTestCase { public class ArticleQueryServiceTestCase extends AbstractTestCase {
...@@ -120,7 +120,7 @@ public class ArticleQueryServiceTestCase extends AbstractTestCase { ...@@ -120,7 +120,7 @@ public class ArticleQueryServiceTestCase extends AbstractTestCase {
final String articleId = articles.get(0).getString(Keys.OBJECT_ID); final String articleId = articles.get(0).getString(Keys.OBJECT_ID);
Assert.assertNotNull(articleQueryService.getArticleContent(articleId)); Assert.assertNotNull(articleQueryService.getArticleContent(null, articleId));
} }
/** /**
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
# #
# Description: B3log Solo language configurations(en_US). # Description: B3log Solo language configurations(en_US).
# Version: 2.1.0.9, May 17, 2013 # Version: 2.1.1.0, Jun 28, 2013
# Author: Liang Ding # Author: Liang Ding
# Author: Liyuan Li # Author: Liyuan Li
# Author: Dongxu Wang # Author: Dongxu Wang
...@@ -377,4 +377,5 @@ helloWorld.content=<p>Welcome to \ ...@@ -377,4 +377,5 @@ helloWorld.content=<p>Welcome to \
<span style="color: blue;">G</span> \ <span style="color: blue;">G</span> \
<span style="color: orangered; font-weight: bold;">Solo</span></a>\ <span style="color: orangered; font-weight: bold;">Solo</span></a>\
. This is your first post. Edit or delete it, then start blogging!</p> . This is your first post. Edit or delete it, then start blogging!</p>
helloWorld.comment.content=Hi, this is a comment. _esc_enter_88250_To delete a comment, just log in and view the post's comments. There you will have the option to delete them. helloWorld.comment.content=Hi, this is a comment. _esc_enter_88250_To delete a comment, just log in and view the post's comments. There you will have the option to delete them.
\ No newline at end of file articleContentPwd=This article need password to view.
\ No newline at end of file
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
# #
# Description: B3log Solo default language configurations(zh_CN). # Description: B3log Solo default language configurations(zh_CN).
# Version: 2.1.1.6, May 17, 2013 # Version: 2.1.1.7, Jun 28, 2013
# Author: Liang Ding # Author: Liang Ding
# Author: Liyuan Li # Author: Liyuan Li
# Author: Dongxu Wang # Author: Dongxu Wang
...@@ -377,4 +377,5 @@ helloWorld.content=<p>\u6b22\u8fce\u4f7f\u7528 \ ...@@ -377,4 +377,5 @@ helloWorld.content=<p>\u6b22\u8fce\u4f7f\u7528 \
<span style="color: blue;">G</span> \ <span style="color: blue;">G</span> \
<span style="color: orangered; font-weight: bold;">Solo</span></a>\ <span style="color: orangered; font-weight: bold;">Solo</span></a>\
\u3002\u8fd9\u662f\u7cfb\u7edf\u81ea\u52a8\u751f\u6210\u7684\u6f14\u793a\u6587\u7ae0\u3002\u7f16\u8f91\u6216\u8005\u5220\u9664\u5b83\uff0c\u7136\u540e\u5f00\u59cb\u60a8\u7684\u535a\u5ba2\uff01</p> \u3002\u8fd9\u662f\u7cfb\u7edf\u81ea\u52a8\u751f\u6210\u7684\u6f14\u793a\u6587\u7ae0\u3002\u7f16\u8f91\u6216\u8005\u5220\u9664\u5b83\uff0c\u7136\u540e\u5f00\u59cb\u60a8\u7684\u535a\u5ba2\uff01</p>
helloWorld.comment.content=\u60a8\u597d\uff0c\u8fd9\u662f\u4e00\u6761\u8bc4\u8bba\u3002_esc_enter_88250_\u8981\u5220\u9664\u8bc4\u8bba\uff0c\u8bf7\u5148\u767b\u5f55\uff0c\u7136\u540e\u518d\u67e5\u770b\u8fd9\u7bc7\u6587\u7ae0\u7684\u8bc4\u8bba\u3002\u5728\u90a3\u91cc\uff0c\u60a8\u53ef\u4ee5\u770b\u5230\u7f16\u8f91\u6216\u8005\u5220\u9664\u8bc4\u8bba\u7684\u9009\u9879\u3002 helloWorld.comment.content=\u60a8\u597d\uff0c\u8fd9\u662f\u4e00\u6761\u8bc4\u8bba\u3002_esc_enter_88250_\u8981\u5220\u9664\u8bc4\u8bba\uff0c\u8bf7\u5148\u767b\u5f55\uff0c\u7136\u540e\u518d\u67e5\u770b\u8fd9\u7bc7\u6587\u7ae0\u7684\u8bc4\u8bba\u3002\u5728\u90a3\u91cc\uff0c\u60a8\u53ef\u4ee5\u770b\u5230\u7f16\u8f91\u6216\u8005\u5220\u9664\u8bc4\u8bba\u7684\u9009\u9879\u3002
\ No newline at end of file articleContentPwd=\u8be5\u6587\u7ae0\u5df2\u7ecf\u52a0\u5bc6\u3002
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment