mirror of
https://gitee.com/liweiyi/ChestnutCMS.git
synced 2025-12-08 01:18:24 +08:00
新增分页条模板标签<@page_bar>,异步任务优化
This commit is contained in:
parent
322ec7e856
commit
d4c14db946
@ -157,7 +157,7 @@ public class CatalogController extends BaseRestController {
|
|||||||
AsyncTask task = new AsyncTask() {
|
AsyncTask task = new AsyncTask() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run0() throws Exception {
|
public void run0() {
|
||||||
catalogService.deleteCatalog(catalogId, operator);
|
catalogService.deleteCatalog(catalogId, operator);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@ -181,38 +181,33 @@ public class ContentCoreListener {
|
|||||||
public void afterContentOffline(AfterContentOfflineEvent event) {
|
public void afterContentOffline(AfterContentOfflineEvent event) {
|
||||||
final Long contentId = event.getContent().getContentEntity().getContentId();
|
final Long contentId = event.getContent().getContentEntity().getContentId();
|
||||||
final String operator = event.getContent().getOperator().getUsername();
|
final String operator = event.getContent().getOperator().getUsername();
|
||||||
AsyncTask task = new AsyncTask() {
|
asyncTaskManager.execute(() -> {
|
||||||
|
// 映射关联内容同步下线
|
||||||
@Override
|
List<CmsContent> mappingList = contentService.lambdaQuery()
|
||||||
public void run0() throws Exception {
|
.gt(CmsContent::getCopyType, ContentCopyType.Mapping)
|
||||||
// 映射关联内容同步下线
|
.eq(CmsContent::getCopyId, contentId).list();
|
||||||
List<CmsContent> mappingList = contentService.lambdaQuery()
|
for (CmsContent c : mappingList) {
|
||||||
.gt(CmsContent::getCopyType, ContentCopyType.Mapping)
|
if (ContentStatus.PUBLISHED == c.getStatus()) {
|
||||||
.eq(CmsContent::getCopyId, contentId).list();
|
try {
|
||||||
for (CmsContent c : mappingList) {
|
contentService.deleteStaticFiles(c);
|
||||||
if (ContentStatus.PUBLISHED == c.getStatus()) {
|
} catch (IOException e) {
|
||||||
try {
|
e.printStackTrace();
|
||||||
contentService.deleteStaticFiles(c);
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
c.setStatus(ContentStatus.OFFLINE);
|
|
||||||
c.updateBy(operator);
|
|
||||||
}
|
}
|
||||||
contentService.updateBatchById(mappingList);
|
c.setStatus(ContentStatus.OFFLINE);
|
||||||
// 标题内容同步下线
|
c.updateBy(operator);
|
||||||
String internalUrl = InternalUrlUtils.getInternalUrl(InternalDataType_Content.ID, contentId);
|
|
||||||
List<CmsContent> linkList = contentService.lambdaQuery().eq(CmsContent::getLinkFlag, YesOrNo.YES)
|
|
||||||
.eq(CmsContent::getRedirectUrl, internalUrl).list();
|
|
||||||
for (CmsContent c : linkList) {
|
|
||||||
c.setStatus(ContentStatus.OFFLINE);
|
|
||||||
c.updateBy(operator);
|
|
||||||
}
|
|
||||||
mappingList.addAll(linkList);
|
|
||||||
contentService.updateBatchById(mappingList);
|
|
||||||
}
|
}
|
||||||
};
|
contentService.updateBatchById(mappingList);
|
||||||
this.asyncTaskManager.execute(task);
|
// 标题内容同步下线
|
||||||
|
String internalUrl = InternalUrlUtils.getInternalUrl(InternalDataType_Content.ID, contentId);
|
||||||
|
List<CmsContent> linkList = contentService.lambdaQuery().eq(CmsContent::getLinkFlag, YesOrNo.YES)
|
||||||
|
.eq(CmsContent::getRedirectUrl, internalUrl).list();
|
||||||
|
for (CmsContent c : linkList) {
|
||||||
|
c.setStatus(ContentStatus.OFFLINE);
|
||||||
|
c.updateBy(operator);
|
||||||
|
}
|
||||||
|
mappingList.addAll(linkList);
|
||||||
|
contentService.updateBatchById(mappingList);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -202,7 +202,7 @@ public class ContentServiceImpl extends ServiceImpl<CmsContentMapper, CmsContent
|
|||||||
aopProxy.addContent0(content);
|
aopProxy.addContent0(content);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
task.setType("SaveContent");
|
task.setType("SaveContent-" + content.getContentEntity().getContentId());
|
||||||
asyncTaskManager.execute(task);
|
asyncTaskManager.execute(task);
|
||||||
return task;
|
return task;
|
||||||
}
|
}
|
||||||
@ -224,7 +224,7 @@ public class ContentServiceImpl extends ServiceImpl<CmsContentMapper, CmsContent
|
|||||||
saveContent0(content);
|
saveContent0(content);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
task.setType("SaveContent");
|
task.setType("SaveContent-" + content.getContentEntity().getContentId());
|
||||||
asyncTaskManager.execute(task);
|
asyncTaskManager.execute(task);
|
||||||
return task;
|
return task;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -99,7 +99,6 @@ public class PublishServiceImpl implements IPublishService, ApplicationContextAw
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AsyncTask publishAll(CmsSite site, final String contentStatus, final LoginUser operator) {
|
public AsyncTask publishAll(CmsSite site, final String contentStatus, final LoginUser operator) {
|
||||||
String taskId = "Publish-Site-" + site.getSiteId();
|
|
||||||
AsyncTask asyncTask = new AsyncTask() {
|
AsyncTask asyncTask = new AsyncTask() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -164,7 +163,8 @@ public class PublishServiceImpl implements IPublishService, ApplicationContextAw
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
asyncTask.setType("Publish");
|
asyncTask.setType("Publish");
|
||||||
asyncTask.setTaskId(taskId);
|
asyncTask.setTaskId("Publish-Site-" + site.getSiteId());
|
||||||
|
asyncTask.setInterruptible(true);
|
||||||
this.asyncTaskManager.execute(asyncTask);
|
this.asyncTaskManager.execute(asyncTask);
|
||||||
return asyncTask;
|
return asyncTask;
|
||||||
}
|
}
|
||||||
@ -335,6 +335,7 @@ public class PublishServiceImpl implements IPublishService, ApplicationContextAw
|
|||||||
};
|
};
|
||||||
asyncTask.setType("Publish");
|
asyncTask.setType("Publish");
|
||||||
asyncTask.setTaskId("Publish-Catalog-" + catalog.getCatalogId());
|
asyncTask.setTaskId("Publish-Catalog-" + catalog.getCatalogId());
|
||||||
|
asyncTask.setInterruptible(true);
|
||||||
this.asyncTaskManager.execute(asyncTask);
|
this.asyncTaskManager.execute(asyncTask);
|
||||||
return asyncTask;
|
return asyncTask;
|
||||||
}
|
}
|
||||||
@ -459,16 +460,6 @@ public class PublishServiceImpl implements IPublishService, ApplicationContextAw
|
|||||||
return detailTemplate;
|
return detailTemplate;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getContentExTemplate(CmsSite site, CmsCatalog catalog, CmsContent content, String publishPipeCode) {
|
|
||||||
String exTemplate = PublishPipeProp_ContentExTemplate.getValue(publishPipeCode,
|
|
||||||
content.getPublishPipeProps());
|
|
||||||
if (StringUtils.isEmpty(exTemplate)) {
|
|
||||||
// 无内容独立扩展模板取栏目配置
|
|
||||||
exTemplate = PublishPipeProp_ContentExTemplate.getValue(publishPipeCode, catalog.getPublishPipeProps());
|
|
||||||
}
|
|
||||||
return exTemplate;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getContentPageData(CmsContent content, int pageIndex, String publishPipeCode, boolean isPreview)
|
public String getContentPageData(CmsContent content, int pageIndex, String publishPipeCode, boolean isPreview)
|
||||||
throws IOException, TemplateException {
|
throws IOException, TemplateException {
|
||||||
@ -517,46 +508,39 @@ public class PublishServiceImpl implements IPublishService, ApplicationContextAw
|
|||||||
if (list.isEmpty()) {
|
if (list.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
AsyncTask asyncTask = new AsyncTask() {
|
asyncTaskManager.execute(() -> {
|
||||||
|
// 发布内容
|
||||||
|
Set<Long> catalogIds = new HashSet<>();
|
||||||
|
for (CmsContent cmsContent : list) {
|
||||||
|
IContentType contentType = ContentCoreUtils.getContentType(cmsContent.getContentType());
|
||||||
|
IContent<?> content = contentType.loadContent(cmsContent);
|
||||||
|
content.setOperator(operator);
|
||||||
|
|
||||||
@Override
|
catalogIds.add(cmsContent.getCatalogId());
|
||||||
public void run0() {
|
if (content.publish()) {
|
||||||
// 发布内容
|
applicationContext.publishEvent(new AfterContentPublishEvent(contentType, content));
|
||||||
Set<Long> catalogIds = new HashSet<>();
|
|
||||||
for (CmsContent cmsContent : list) {
|
|
||||||
IContentType contentType = ContentCoreUtils.getContentType(cmsContent.getContentType());
|
|
||||||
IContent<?> content = contentType.loadContent(cmsContent);
|
|
||||||
content.setOperator(operator);
|
|
||||||
|
|
||||||
catalogIds.add(cmsContent.getCatalogId());
|
|
||||||
if (content.publish()) {
|
|
||||||
applicationContext.publishEvent(new AfterContentPublishEvent(contentType, content));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// 发布关联栏目:内容所属栏目及其所有父级栏目
|
|
||||||
Map<Long, CmsCatalog> catalogMap = new HashMap<>();
|
|
||||||
catalogIds.forEach(catalogId -> {
|
|
||||||
CmsCatalog catalog = catalogService.getCatalog(catalogId);
|
|
||||||
catalogMap.put(catalog.getCatalogId(), catalog);
|
|
||||||
long parentId = catalog.getParentId();
|
|
||||||
while (parentId > 0) {
|
|
||||||
CmsCatalog parent = catalogService.getCatalog(parentId);
|
|
||||||
if (parent == null) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
catalogMap.put(parent.getCatalogId(), parent);
|
|
||||||
parentId = parent.getParentId();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
CmsSite site = siteService.getSite(list.get(0).getSiteId());
|
|
||||||
catalogMap.values().forEach(c -> asyncPublishCatalog(c));
|
|
||||||
// 发布站点首页
|
|
||||||
asyncPublishSite(site);
|
|
||||||
}
|
}
|
||||||
};
|
// 发布关联栏目:内容所属栏目及其所有父级栏目
|
||||||
asyncTask.setType("Publish");
|
Map<Long, CmsCatalog> catalogMap = new HashMap<>();
|
||||||
asyncTask.setTaskId("Publish-Content");
|
catalogIds.forEach(catalogId -> {
|
||||||
this.asyncTaskManager.execute(asyncTask);
|
CmsCatalog catalog = catalogService.getCatalog(catalogId);
|
||||||
|
catalogMap.put(catalog.getCatalogId(), catalog);
|
||||||
|
long parentId = catalog.getParentId();
|
||||||
|
while (parentId > 0) {
|
||||||
|
CmsCatalog parent = catalogService.getCatalog(parentId);
|
||||||
|
if (parent == null) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
catalogMap.put(parent.getCatalogId(), parent);
|
||||||
|
parentId = parent.getParentId();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
CmsSite site = siteService.getSite(list.get(0).getSiteId());
|
||||||
|
catalogMap.values().forEach(this::asyncPublishCatalog);
|
||||||
|
// 发布站点首页
|
||||||
|
asyncPublishSite(site);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -792,7 +776,7 @@ public class PublishServiceImpl implements IPublishService, ApplicationContextAw
|
|||||||
templateType.initTemplateData(site.getSiteId(), templateContext);
|
templateType.initTemplateData(site.getSiteId(), templateContext);
|
||||||
// staticize
|
// staticize
|
||||||
this.staticizeService.process(templateContext);
|
this.staticizeService.process(templateContext);
|
||||||
logger.debug("[{0}]页面部件模板解析:{1},耗时:{2}ms", pw.getPublishPipeCode(), pw.getCode(), System.currentTimeMillis() - s);
|
logger.debug("[{}]页面部件模板解析:{},耗时:{}ms", pw.getPublishPipeCode(), pw.getCode(), System.currentTimeMillis() - s);
|
||||||
} catch (TemplateException | IOException e) {
|
} catch (TemplateException | IOException e) {
|
||||||
logger.error(AsyncTaskManager.addErrMessage(StringUtils.messageFormat("[{0}]页面部件模板解析失败:{1}#{2}",
|
logger.error(AsyncTaskManager.addErrMessage(StringUtils.messageFormat("[{0}]页面部件模板解析失败:{1}#{2}",
|
||||||
pw.getPublishPipeCode(), pw.getName(), pw.getCode())), e);
|
pw.getPublishPipeCode(), pw.getName(), pw.getCode())), e);
|
||||||
|
|||||||
@ -67,16 +67,6 @@ public class SiteThemeService implements ApplicationContextAware {
|
|||||||
private final IPageWidgetService pageWidgetService;
|
private final IPageWidgetService pageWidgetService;
|
||||||
|
|
||||||
public AsyncTask importSiteTheme(CmsSite site, final File zipFile, LoginUser operator) throws IOException {
|
public AsyncTask importSiteTheme(CmsSite site, final File zipFile, LoginUser operator) throws IOException {
|
||||||
String taskId = "SiteThemeImport-" + site.getPath();
|
|
||||||
AsyncTask task = asyncTaskManager.getTask(taskId);
|
|
||||||
if (task != null) {
|
|
||||||
if (!task.isAlive()) {
|
|
||||||
asyncTaskManager.removeById(task.getTaskId());
|
|
||||||
} else {
|
|
||||||
throw ContentCoreErrorCode.SITE_EXPORT_TASK_EXISTS.exception();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
AsyncTask asyncTask = new AsyncTask() {
|
AsyncTask asyncTask = new AsyncTask() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -178,8 +168,8 @@ public class SiteThemeService implements ApplicationContextAware {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
asyncTask.setTaskId(taskId);
|
asyncTask.setType("SiteTheme");
|
||||||
asyncTask.setType("SiteThemeImport");
|
asyncTask.setTaskId("SiteThemeImport-" + site.getSiteId());
|
||||||
this.asyncTaskManager.execute(asyncTask);
|
this.asyncTaskManager.execute(asyncTask);
|
||||||
return asyncTask;
|
return asyncTask;
|
||||||
}
|
}
|
||||||
@ -187,16 +177,6 @@ public class SiteThemeService implements ApplicationContextAware {
|
|||||||
public static final String ThemeFileName = "SiteTheme.zip";
|
public static final String ThemeFileName = "SiteTheme.zip";
|
||||||
|
|
||||||
public AsyncTask exportSiteTheme(CmsSite site, final List<String> directories) {
|
public AsyncTask exportSiteTheme(CmsSite site, final List<String> directories) {
|
||||||
String taskId = "SiteExportTheme-" + site.getPath();
|
|
||||||
AsyncTask task = asyncTaskManager.getTask(taskId);
|
|
||||||
if (task != null) {
|
|
||||||
if (!task.isAlive()) {
|
|
||||||
asyncTaskManager.removeById(task.getTaskId());
|
|
||||||
} else {
|
|
||||||
throw ContentCoreErrorCode.SITE_EXPORT_TASK_EXISTS.exception();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
AsyncTask asyncTask = new AsyncTask() {
|
AsyncTask asyncTask = new AsyncTask() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -256,8 +236,8 @@ public class SiteThemeService implements ApplicationContextAware {
|
|||||||
AsyncTaskManager.setTaskProgressInfo(100, "导出成功");
|
AsyncTaskManager.setTaskProgressInfo(100, "导出成功");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
asyncTask.setTaskId(taskId);
|
asyncTask.setType("SiteTheme");
|
||||||
asyncTask.setType("SiteExportTheme");
|
asyncTask.setTaskId("SiteThemeExport-" + site.getSiteId());
|
||||||
this.asyncTaskManager.execute(asyncTask);
|
this.asyncTaskManager.execute(asyncTask);
|
||||||
return asyncTask;
|
return asyncTask;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -223,6 +223,7 @@ public class ContentIndexService implements CommandLineRunner {
|
|||||||
};
|
};
|
||||||
asyncTask.setTaskId("RebuildAllContentIndex");
|
asyncTask.setTaskId("RebuildAllContentIndex");
|
||||||
asyncTask.setType("ContentCore");
|
asyncTask.setType("ContentCore");
|
||||||
|
asyncTask.setInterruptible(true);
|
||||||
this.asyncTaskManager.execute(asyncTask);
|
this.asyncTaskManager.execute(asyncTask);
|
||||||
return asyncTask;
|
return asyncTask;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,7 +5,6 @@ import com.chestnut.cms.stat.domain.CmsUserContentStat;
|
|||||||
import com.chestnut.cms.stat.domain.vo.ContentStatusTotal;
|
import com.chestnut.cms.stat.domain.vo.ContentStatusTotal;
|
||||||
import com.chestnut.cms.stat.mapper.CmsCatalogContentStatMapper;
|
import com.chestnut.cms.stat.mapper.CmsCatalogContentStatMapper;
|
||||||
import com.chestnut.cms.stat.mapper.CmsUserContentStatMapper;
|
import com.chestnut.cms.stat.mapper.CmsUserContentStatMapper;
|
||||||
import com.chestnut.common.async.AsyncTask;
|
|
||||||
import com.chestnut.common.async.AsyncTaskManager;
|
import com.chestnut.common.async.AsyncTaskManager;
|
||||||
import com.chestnut.common.utils.IdUtils;
|
import com.chestnut.common.utils.IdUtils;
|
||||||
import com.chestnut.contentcore.fixed.dict.ContentStatus;
|
import com.chestnut.contentcore.fixed.dict.ContentStatus;
|
||||||
@ -13,7 +12,6 @@ import com.chestnut.contentcore.listener.event.*;
|
|||||||
import com.chestnut.system.domain.SysUser;
|
import com.chestnut.system.domain.SysUser;
|
||||||
import com.chestnut.system.service.ISysUserService;
|
import com.chestnut.system.service.ISysUserService;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.context.event.EventListener;
|
import org.springframework.context.event.EventListener;
|
||||||
@ -94,73 +92,63 @@ public class CmsStatEventListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void updateCatalogContentStat(Long siteId, Long catalogId) {
|
private void updateCatalogContentStat(Long siteId, Long catalogId) {
|
||||||
AsyncTask task = new AsyncTask() {
|
asyncTaskManager.execute(() -> {
|
||||||
@Override
|
long s = System.currentTimeMillis();
|
||||||
public void run0() {
|
Map<String, Integer> dataMap = catalogContentStatMapper.statContentByStatus(catalogId)
|
||||||
long s = System.currentTimeMillis();
|
.stream().collect(Collectors.toMap(ContentStatusTotal::getStatus, ContentStatusTotal::getTotal));
|
||||||
Map<String, Integer> dataMap = catalogContentStatMapper.statContentByStatus(catalogId)
|
|
||||||
.stream().collect(Collectors.toMap(ContentStatusTotal::getStatus, ContentStatusTotal::getTotal));
|
|
||||||
|
|
||||||
CmsCatalogContentStat stat = catalogContentStatMapper.selectById(catalogId);
|
CmsCatalogContentStat stat = catalogContentStatMapper.selectById(catalogId);
|
||||||
if (Objects.isNull(stat)) {
|
if (Objects.isNull(stat)) {
|
||||||
stat = new CmsCatalogContentStat();
|
stat = new CmsCatalogContentStat();
|
||||||
stat.setCatalogId(catalogId);
|
stat.setCatalogId(catalogId);
|
||||||
stat.setSiteId(siteId);
|
stat.setSiteId(siteId);
|
||||||
stat.setDraftTotal(dataMap.get(ContentStatus.DRAFT));
|
stat.setDraftTotal(dataMap.get(ContentStatus.DRAFT));
|
||||||
stat.setToPublishTotal(dataMap.get(ContentStatus.TO_PUBLISHED));
|
stat.setToPublishTotal(dataMap.get(ContentStatus.TO_PUBLISHED));
|
||||||
stat.setPublishedTotal(dataMap.get(ContentStatus.PUBLISHED));
|
stat.setPublishedTotal(dataMap.get(ContentStatus.PUBLISHED));
|
||||||
stat.setOfflineTotal(dataMap.get(ContentStatus.OFFLINE));
|
stat.setOfflineTotal(dataMap.get(ContentStatus.OFFLINE));
|
||||||
stat.setEditingTotal(dataMap.get(ContentStatus.EDITING));
|
stat.setEditingTotal(dataMap.get(ContentStatus.EDITING));
|
||||||
catalogContentStatMapper.insert(stat);
|
catalogContentStatMapper.insert(stat);
|
||||||
} else {
|
} else {
|
||||||
stat.setDraftTotal(dataMap.get(ContentStatus.DRAFT));
|
stat.setDraftTotal(dataMap.get(ContentStatus.DRAFT));
|
||||||
stat.setToPublishTotal(dataMap.get(ContentStatus.TO_PUBLISHED));
|
stat.setToPublishTotal(dataMap.get(ContentStatus.TO_PUBLISHED));
|
||||||
stat.setPublishedTotal(dataMap.get(ContentStatus.PUBLISHED));
|
stat.setPublishedTotal(dataMap.get(ContentStatus.PUBLISHED));
|
||||||
stat.setOfflineTotal(dataMap.get(ContentStatus.OFFLINE));
|
stat.setOfflineTotal(dataMap.get(ContentStatus.OFFLINE));
|
||||||
stat.setEditingTotal(dataMap.get(ContentStatus.EDITING));
|
stat.setEditingTotal(dataMap.get(ContentStatus.EDITING));
|
||||||
catalogContentStatMapper.updateById(stat);
|
catalogContentStatMapper.updateById(stat);
|
||||||
}
|
|
||||||
logger.info("Stat catalog content by status cost: " + (System.currentTimeMillis() - s) + " ms");
|
|
||||||
}
|
}
|
||||||
};
|
logger.info("Stat catalog content by status cost: " + (System.currentTimeMillis() - s) + " ms");
|
||||||
task.setTaskId("UpdateCatalogContentStat");
|
});
|
||||||
this.asyncTaskManager.executeIgnoreIfExists(task);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateUserContentStat(Long siteId, SysUser user) {
|
private void updateUserContentStat(Long siteId, SysUser user) {
|
||||||
AsyncTask task = new AsyncTask() {
|
asyncTaskManager.execute(() -> {
|
||||||
@Override
|
long s = System.currentTimeMillis();
|
||||||
public void run0() {
|
Map<String, Integer> dataMap = userContentStatMapper.statContentByStatus(siteId, user.getUserName())
|
||||||
long s = System.currentTimeMillis();
|
.stream().collect(Collectors.toMap(ContentStatusTotal::getStatus, ContentStatusTotal::getTotal));
|
||||||
Map<String, Integer> dataMap = userContentStatMapper.statContentByStatus(siteId, user.getUserName())
|
|
||||||
.stream().collect(Collectors.toMap(ContentStatusTotal::getStatus, ContentStatusTotal::getTotal));
|
|
||||||
|
|
||||||
String statId = siteId + "-" + user.getUserId();
|
String statId = siteId + "-" + user.getUserId();
|
||||||
CmsUserContentStat stat = userContentStatMapper.selectById(statId);
|
CmsUserContentStat stat = userContentStatMapper.selectById(statId);
|
||||||
if (Objects.isNull(stat)) {
|
if (Objects.isNull(stat)) {
|
||||||
stat = new CmsUserContentStat();
|
stat = new CmsUserContentStat();
|
||||||
stat.setId(statId);
|
stat.setId(statId);
|
||||||
stat.setUserId(user.getUserId());
|
stat.setUserId(user.getUserId());
|
||||||
stat.setUserName(user.getUserName());
|
stat.setUserName(user.getUserName());
|
||||||
stat.setSiteId(siteId);
|
stat.setSiteId(siteId);
|
||||||
stat.setDraftTotal(dataMap.get(ContentStatus.DRAFT));
|
stat.setDraftTotal(dataMap.get(ContentStatus.DRAFT));
|
||||||
stat.setToPublishTotal(dataMap.get(ContentStatus.TO_PUBLISHED));
|
stat.setToPublishTotal(dataMap.get(ContentStatus.TO_PUBLISHED));
|
||||||
stat.setPublishedTotal(dataMap.get(ContentStatus.PUBLISHED));
|
stat.setPublishedTotal(dataMap.get(ContentStatus.PUBLISHED));
|
||||||
stat.setOfflineTotal(dataMap.get(ContentStatus.OFFLINE));
|
stat.setOfflineTotal(dataMap.get(ContentStatus.OFFLINE));
|
||||||
stat.setEditingTotal(dataMap.get(ContentStatus.EDITING));
|
stat.setEditingTotal(dataMap.get(ContentStatus.EDITING));
|
||||||
userContentStatMapper.insert(stat);
|
userContentStatMapper.insert(stat);
|
||||||
} else {
|
} else {
|
||||||
stat.setDraftTotal(dataMap.get(ContentStatus.DRAFT));
|
stat.setDraftTotal(dataMap.get(ContentStatus.DRAFT));
|
||||||
stat.setToPublishTotal(dataMap.get(ContentStatus.TO_PUBLISHED));
|
stat.setToPublishTotal(dataMap.get(ContentStatus.TO_PUBLISHED));
|
||||||
stat.setPublishedTotal(dataMap.get(ContentStatus.PUBLISHED));
|
stat.setPublishedTotal(dataMap.get(ContentStatus.PUBLISHED));
|
||||||
stat.setOfflineTotal(dataMap.get(ContentStatus.OFFLINE));
|
stat.setOfflineTotal(dataMap.get(ContentStatus.OFFLINE));
|
||||||
stat.setEditingTotal(dataMap.get(ContentStatus.EDITING));
|
stat.setEditingTotal(dataMap.get(ContentStatus.EDITING));
|
||||||
userContentStatMapper.updateById(stat);
|
userContentStatMapper.updateById(stat);
|
||||||
}
|
|
||||||
logger.info("Stat user content by status cost: " + (System.currentTimeMillis() - s) + " ms");
|
|
||||||
}
|
}
|
||||||
};
|
logger.info("Stat user content by status cost: " + (System.currentTimeMillis() - s) + " ms");
|
||||||
task.setTaskId("UpdateUserContentStat");
|
});
|
||||||
this.asyncTaskManager.executeIgnoreIfExists(task);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -81,6 +81,11 @@ public abstract class AsyncTask implements Runnable {
|
|||||||
*/
|
*/
|
||||||
private boolean interrupt = false;
|
private boolean interrupt = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否可被中断
|
||||||
|
*/
|
||||||
|
private boolean interruptible = false;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
@ -103,6 +108,7 @@ public abstract class AsyncTask implements Runnable {
|
|||||||
this.setPercent(100);
|
this.setPercent(100);
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
} finally {
|
} finally {
|
||||||
|
this.setEndTime(LocalDateTime.now());
|
||||||
AsyncTaskManager.removeCurrent();
|
AsyncTaskManager.removeCurrent();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -131,28 +137,24 @@ public abstract class AsyncTask implements Runnable {
|
|||||||
* 任务完成
|
* 任务完成
|
||||||
*/
|
*/
|
||||||
void completed() {
|
void completed() {
|
||||||
if (this.getStatus() == TaskStatus.INTERRUPTED) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
log.debug("[{}]Task completed: {}", Thread.currentThread().getName(), this.getTaskId());
|
|
||||||
this.setStatus(TaskStatus.SUCCESS);
|
this.setStatus(TaskStatus.SUCCESS);
|
||||||
this.setEndTime(LocalDateTime.now());
|
|
||||||
this.setPercent(100);
|
this.setPercent(100);
|
||||||
if (this.getCallback() != null) {
|
if (this.getCallback() != null) {
|
||||||
this.getCallback().complete(this);
|
this.getCallback().complete(this);
|
||||||
}
|
}
|
||||||
|
log.debug("[{}]Task completed: {}", Thread.currentThread().getName(), this.getTaskId());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 执行中断,设置中断标识
|
* 执行中断,设置中断标识
|
||||||
*/
|
*/
|
||||||
public void interrupt() {
|
public void interrupt() {
|
||||||
log.debug("[{}]Task interrupted: {}", Thread.currentThread().getName(), this.getTaskId());
|
|
||||||
if (this.interrupt) {
|
if (this.interrupt) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.interrupt = true;
|
this.interrupt = true;
|
||||||
this.setInterruptTime(LocalDateTime.now());
|
this.setInterruptTime(LocalDateTime.now());
|
||||||
|
log.debug("[{}]Task interrupted: {}", Thread.currentThread().getName(), this.getTaskId());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -164,6 +166,10 @@ public abstract class AsyncTask implements Runnable {
|
|||||||
Assert.isFalse(this.interrupt, () -> new InterruptedException("The task is interrupted: " + this.taskId));
|
Assert.isFalse(this.interrupt, () -> new InterruptedException("The task is interrupted: " + this.taskId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isExpired(long expireSeconds) {
|
||||||
|
return this.isEnd() && this.endTime.plusSeconds(expireSeconds).isBefore(LocalDateTime.now());
|
||||||
|
}
|
||||||
|
|
||||||
public String getTaskId() {
|
public String getTaskId() {
|
||||||
return taskId;
|
return taskId;
|
||||||
}
|
}
|
||||||
@ -274,4 +280,12 @@ public abstract class AsyncTask implements Runnable {
|
|||||||
public void setInterruptTime(LocalDateTime interruptTime) {
|
public void setInterruptTime(LocalDateTime interruptTime) {
|
||||||
this.interruptTime = interruptTime;
|
this.interruptTime = interruptTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isInterruptible() {
|
||||||
|
return interruptible;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setInterruptible(boolean interruptible) {
|
||||||
|
this.interruptible = interruptible;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -1,95 +1,83 @@
|
|||||||
package com.chestnut.common.async;
|
package com.chestnut.common.async;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
|
|
||||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import com.chestnut.common.async.enums.TaskStatus;
|
import com.chestnut.common.async.enums.TaskStatus;
|
||||||
import com.chestnut.common.config.AsyncConfig;
|
import com.chestnut.common.config.AsyncConfig;
|
||||||
import com.chestnut.common.exception.CommonErrorCode;
|
import com.chestnut.common.exception.CommonErrorCode;
|
||||||
import com.chestnut.common.utils.Assert;
|
import com.chestnut.common.utils.Assert;
|
||||||
import com.chestnut.common.utils.IdUtils;
|
import com.chestnut.common.utils.IdUtils;
|
||||||
import com.chestnut.common.utils.StringUtils;
|
import com.chestnut.common.utils.StringUtils;
|
||||||
|
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
import lombok.RequiredArgsConstructor;
|
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 异步任务管理器
|
* 异步任务管理器
|
||||||
*/
|
*/
|
||||||
@RequiredArgsConstructor
|
|
||||||
@Component
|
@Component
|
||||||
public class AsyncTaskManager {
|
public class AsyncTaskManager {
|
||||||
|
|
||||||
|
private final long ExpireSeconds = 60;
|
||||||
|
|
||||||
private static final ThreadLocal<AsyncTask> CURRENT = new ThreadLocal<>();
|
private static final ThreadLocal<AsyncTask> CURRENT = new ThreadLocal<>();
|
||||||
|
|
||||||
private ConcurrentHashMap<String, AsyncTask> asyncTaskMap = new ConcurrentHashMap<>();
|
private static final ConcurrentHashMap<String, AsyncTask> asyncTaskMap = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
@Resource(name = AsyncConfig.COMMON_EXECUTOR_BEAN)
|
@Resource(name = AsyncConfig.COMMON_EXECUTOR_BEAN)
|
||||||
private ThreadPoolTaskExecutor taskExecutor;
|
private ThreadPoolTaskExecutor taskExecutor;
|
||||||
|
|
||||||
|
AsyncTaskManager() {
|
||||||
public void execute(AsyncTask asyncTask) {
|
Executors.newScheduledThreadPool(1).scheduleAtFixedRate(() -> {
|
||||||
execute(asyncTask, false);
|
asyncTaskMap.entrySet().removeIf(next -> next.getValue().isExpired(ExpireSeconds));
|
||||||
}
|
}, ExpireSeconds, ExpireSeconds, TimeUnit.SECONDS);
|
||||||
|
|
||||||
public void executeIgnoreIfExists(AsyncTask asyncTask) {
|
|
||||||
this.execute(asyncTask, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 提交异步任务
|
* 提交异步任务,提供任务进度监控,中断操作
|
||||||
*
|
*/
|
||||||
* @param asyncTask 异步任务构造器
|
public synchronized void execute(AsyncTask asyncTask) {
|
||||||
* @return taskInfo
|
if (StringUtils.isEmpty(asyncTask.getTaskId())) {
|
||||||
*/
|
asyncTask.setTaskId(this.generateTaskId());
|
||||||
public synchronized void execute(AsyncTask asyncTask, boolean ignoreExists) {
|
}
|
||||||
if (StringUtils.isEmpty(asyncTask.getTaskId())) {
|
AsyncTask task = asyncTaskMap.get(asyncTask.getTaskId());
|
||||||
asyncTask.setTaskId(this.generateTaskId());
|
if (task != null && task.isAlive()) {
|
||||||
}
|
throw CommonErrorCode.ASYNC_TASK_RUNNING.exception(asyncTask.getTaskId());
|
||||||
AsyncTask task = this.asyncTaskMap.get(asyncTask.getTaskId());
|
}
|
||||||
if (task != null && task.isAlive()) {
|
asyncTaskMap.put(asyncTask.getTaskId(), asyncTask);
|
||||||
if (ignoreExists) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
throw CommonErrorCode.ASYNC_TASK_RUNNING.exception(asyncTask.getTaskId());
|
|
||||||
}
|
|
||||||
this.asyncTaskMap.put(asyncTask.getTaskId(), asyncTask);
|
|
||||||
asyncTask.ready();
|
asyncTask.ready();
|
||||||
|
|
||||||
this.taskExecutor.execute(asyncTask);
|
this.taskExecutor.execute(asyncTask);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void execute(Runnable runnable) {
|
/**
|
||||||
this.execute(new AsyncTask() {
|
* 提交异步任务
|
||||||
|
*/
|
||||||
@Override
|
public void execute(Runnable runnable) {
|
||||||
public void run0() throws Exception {
|
this.taskExecutor.execute(runnable);
|
||||||
runnable.run();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取任务信息
|
* 获取任务信息
|
||||||
*
|
*
|
||||||
* @param taskId 任务ID
|
* @param taskId 任务ID
|
||||||
* @return
|
* @return AsyncTask
|
||||||
*/
|
*/
|
||||||
public AsyncTask getTask(String taskId) {
|
public AsyncTask getTask(String taskId) {
|
||||||
return this.asyncTaskMap.get(taskId);
|
return asyncTaskMap.get(taskId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取任务列表
|
* 获取任务列表
|
||||||
* @return
|
*
|
||||||
|
* @return taskList
|
||||||
*/
|
*/
|
||||||
public List<AsyncTask> getTaskList() {
|
public List<AsyncTask> getTaskList() {
|
||||||
return new ArrayList<>(this.asyncTaskMap.values());
|
return new ArrayList<>(asyncTaskMap.values());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -109,11 +97,11 @@ public class AsyncTaskManager {
|
|||||||
boolean isRunning = task.getStatus() == TaskStatus.RUNNING || task.getStatus() == TaskStatus.READY;
|
boolean isRunning = task.getStatus() == TaskStatus.RUNNING || task.getStatus() == TaskStatus.READY;
|
||||||
Assert.isFalse(isRunning, () -> CommonErrorCode.ASYNC_TASK_RUNNING.exception(taskId));
|
Assert.isFalse(isRunning, () -> CommonErrorCode.ASYNC_TASK_RUNNING.exception(taskId));
|
||||||
|
|
||||||
this.asyncTaskMap.remove(taskId);
|
asyncTaskMap.remove(taskId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void cancel(String taskId) {
|
public synchronized void cancel(String taskId) {
|
||||||
AsyncTask task = this.asyncTaskMap.get(taskId);
|
AsyncTask task = asyncTaskMap.get(taskId);
|
||||||
if (Objects.nonNull(task)) {
|
if (Objects.nonNull(task)) {
|
||||||
task.interrupt();
|
task.interrupt();
|
||||||
}
|
}
|
||||||
@ -123,51 +111,51 @@ public class AsyncTaskManager {
|
|||||||
* 获取线程池信息
|
* 获取线程池信息
|
||||||
*/
|
*/
|
||||||
public ThreadPoolTaskExecutor getThreadPool() {
|
public ThreadPoolTaskExecutor getThreadPool() {
|
||||||
return this.taskExecutor;
|
return this.taskExecutor;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static void setCurrent(AsyncTask task) {
|
protected static void setCurrent(AsyncTask task) {
|
||||||
CURRENT.set(task);
|
CURRENT.set(task);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static void removeCurrent() {
|
protected static void removeCurrent() {
|
||||||
CURRENT.remove();
|
CURRENT.remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void checkInterrupt() throws InterruptedException {
|
public static void checkInterrupt() throws InterruptedException {
|
||||||
AsyncTask task = CURRENT.get();
|
AsyncTask task = CURRENT.get();
|
||||||
if (Objects.nonNull(task)) {
|
if (Objects.nonNull(task)) {
|
||||||
task.checkInterrupt();
|
task.checkInterrupt();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String addErrMessage(String message) {
|
public static String addErrMessage(String message) {
|
||||||
AsyncTask task = CURRENT.get();
|
AsyncTask task = CURRENT.get();
|
||||||
if (Objects.nonNull(task)) {
|
if (Objects.nonNull(task)) {
|
||||||
task.addErrorMessage(message);
|
task.addErrorMessage(message);
|
||||||
}
|
}
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void setTaskPercent(int percent) {
|
public static void setTaskPercent(int percent) {
|
||||||
AsyncTask task = CURRENT.get();
|
AsyncTask task = CURRENT.get();
|
||||||
if (Objects.nonNull(task)) {
|
if (Objects.nonNull(task)) {
|
||||||
task.setPercent(percent);
|
task.setPercent(percent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void setTaskMessage(String msg) {
|
public static void setTaskMessage(String msg) {
|
||||||
AsyncTask task = CURRENT.get();
|
AsyncTask task = CURRENT.get();
|
||||||
if (Objects.nonNull(task)) {
|
if (Objects.nonNull(task)) {
|
||||||
task.setProgressMessage(msg);
|
task.setProgressMessage(msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void setTaskProgressInfo(int percent, String msg) {
|
public static void setTaskProgressInfo(int percent, String msg) {
|
||||||
AsyncTask task = CURRENT.get();
|
AsyncTask task = CURRENT.get();
|
||||||
if (Objects.nonNull(task)) {
|
if (Objects.nonNull(task)) {
|
||||||
task.setProgressInfo(percent, msg);
|
task.setProgressInfo(percent, msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getTaskProgressPercent() {
|
public static int getTaskProgressPercent() {
|
||||||
|
|||||||
@ -1,11 +1,9 @@
|
|||||||
package com.chestnut.common.config;
|
package com.chestnut.common.config;
|
||||||
|
|
||||||
import java.util.concurrent.Executor;
|
import com.chestnut.common.config.properties.AsyncProperties;
|
||||||
import java.util.concurrent.ThreadPoolExecutor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
|
|
||||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
@ -13,10 +11,8 @@ import org.springframework.scheduling.annotation.AsyncConfigurer;
|
|||||||
import org.springframework.scheduling.annotation.EnableAsync;
|
import org.springframework.scheduling.annotation.EnableAsync;
|
||||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||||
|
|
||||||
import com.chestnut.common.async.AsyncTaskExceptionHandler;
|
import java.util.concurrent.Executor;
|
||||||
import com.chestnut.common.config.properties.AsyncProperties;
|
import java.util.concurrent.ThreadPoolExecutor;
|
||||||
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 异步任务线程池配置
|
* 异步任务线程池配置
|
||||||
@ -66,9 +62,4 @@ public class AsyncConfig implements AsyncConfigurer {
|
|||||||
executor.initialize();
|
executor.initialize();
|
||||||
return executor;
|
return executor;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
|
|
||||||
return new AsyncTaskExceptionHandler();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@ -0,0 +1,160 @@
|
|||||||
|
package com.chestnut.common.staticize.tag.impl;
|
||||||
|
|
||||||
|
import com.chestnut.common.staticize.FreeMarkerUtils;
|
||||||
|
import com.chestnut.common.staticize.StaticizeConstants;
|
||||||
|
import com.chestnut.common.staticize.core.TemplateContext;
|
||||||
|
import com.chestnut.common.staticize.enums.TagAttrDataType;
|
||||||
|
import com.chestnut.common.staticize.tag.AbstractTag;
|
||||||
|
import com.chestnut.common.staticize.tag.TagAttr;
|
||||||
|
import com.chestnut.common.staticize.tag.TagAttrOption;
|
||||||
|
import com.chestnut.common.utils.StringUtils;
|
||||||
|
import freemarker.core.Environment;
|
||||||
|
import freemarker.template.TemplateException;
|
||||||
|
import freemarker.template.TemplateModel;
|
||||||
|
import org.apache.commons.collections4.MapUtils;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class PageBarTag extends AbstractTag {
|
||||||
|
|
||||||
|
public final static String TAG_NAME = "page_bar";
|
||||||
|
public final static String NAME = "{FREEMARKER.TAG.NAME." + TAG_NAME + "}";
|
||||||
|
public final static String DESC = "{FREEMARKER.TAG.DESC." + TAG_NAME + "}";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTagName() {
|
||||||
|
return TAG_NAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return NAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getDescription() {
|
||||||
|
return DESC;
|
||||||
|
}
|
||||||
|
|
||||||
|
final static String TagAttr_Type = "type";
|
||||||
|
final static String TagAttr_Target = "target";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<TagAttr> getTagAttrs() {
|
||||||
|
List<TagAttr> tagAttrs = new ArrayList<>();
|
||||||
|
tagAttrs.add(new TagAttr(TagAttr_Type, false, TagAttrDataType.STRING, "类型",
|
||||||
|
PageBarType.toTagAttrOptions(), PageBarType.Simple.name()));
|
||||||
|
tagAttrs.add(new TagAttr(TagAttr_Target, false, TagAttrDataType.STRING, "链接打开方式",
|
||||||
|
LinkTarget.toTagAttrOptions(), LinkTarget._self.name()));
|
||||||
|
return tagAttrs;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, TemplateModel> execute0(Environment env, Map<String, String> attrs)
|
||||||
|
throws TemplateException, IOException {
|
||||||
|
String type = MapUtils.getString(attrs, TagAttr_Type, PageBarType.Simple.name());
|
||||||
|
String target = MapUtils.getString(attrs, TagAttr_Target, LinkTarget._self.name());
|
||||||
|
|
||||||
|
env.getOut().write(switch (PageBarType.valueOf(type)) {
|
||||||
|
case Mini -> generateMinPageBar(target, env);
|
||||||
|
case Simple -> generateSimplePageBar(target, env);
|
||||||
|
});
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String generateMinPageBar(String target, Environment env)
|
||||||
|
throws TemplateException {
|
||||||
|
return generatePageBar(target, false, env);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String generateSimplePageBar(String target, Environment env)
|
||||||
|
throws TemplateException {
|
||||||
|
return generatePageBar(target, true, env);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <a href="#" class="page_link page_active" target="_blank">1</a>
|
||||||
|
* [首页]...[2][3][4] 5 [6][7][8]...[末页]
|
||||||
|
* 最多显示7个页码,当前页前后各三个
|
||||||
|
*/
|
||||||
|
private String generatePageBar(String target, boolean withFirstAndLast, Environment env)
|
||||||
|
throws TemplateException {
|
||||||
|
TemplateContext context = FreeMarkerUtils.getTemplateContext(env);
|
||||||
|
int pageCount = Long.valueOf((context.getPageTotal() + context.getPageSize() - 1 ) / context.getPageSize()).intValue();
|
||||||
|
int startPage = 1;
|
||||||
|
int endPage = 7;
|
||||||
|
if (context.getPageIndex() > 4) {
|
||||||
|
int maxMove = Math.max(pageCount - endPage, 0);
|
||||||
|
startPage += Math.min(context.getPageIndex() - 4, maxMove);
|
||||||
|
}
|
||||||
|
endPage = Math.min(startPage + 6, pageCount);
|
||||||
|
|
||||||
|
String firstPageLink = FreeMarkerUtils.evalStringVariable(env, StaticizeConstants.TemplateVariable_FirstPage);
|
||||||
|
String otherPageLink = FreeMarkerUtils.evalStringVariable(env, StaticizeConstants.TemplateVariable_OtherPage);
|
||||||
|
String temp = "<a href=\"{0}\" class=\"page_link{1}\" target=\"{2}\">{3}</a>";
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append("<div class=\"pagination\">");
|
||||||
|
if (withFirstAndLast && startPage > 1) {
|
||||||
|
sb.append(StringUtils.messageFormat(temp, firstPageLink, "", target, "首页"));
|
||||||
|
sb.append("<a href=\"javascript:;\" class=\"page_white\">...</a>");
|
||||||
|
}
|
||||||
|
for (int i = startPage; i <= endPage; i++) {
|
||||||
|
String pageLink = "javascript:;";
|
||||||
|
String active = " page_active";
|
||||||
|
if (i != context.getPageIndex()) {
|
||||||
|
pageLink = i > 1 ? StringUtils.messageFormat(otherPageLink, i) : firstPageLink;
|
||||||
|
active = "";
|
||||||
|
}
|
||||||
|
sb.append(StringUtils.messageFormat(temp, pageLink, active, target, i));
|
||||||
|
}
|
||||||
|
if (withFirstAndLast && endPage < pageCount) {
|
||||||
|
sb.append("<a href=\"javascript:;\" class=\"page_white\">...</a>");
|
||||||
|
sb.append(StringUtils.messageFormat(temp, StringUtils.messageFormat(otherPageLink, pageCount), "", target, "末页"));
|
||||||
|
}
|
||||||
|
sb.append("</div>");
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum PageBarType {
|
||||||
|
|
||||||
|
Mini("极简(页码)"),
|
||||||
|
Simple("简单(页码+首末页)");
|
||||||
|
|
||||||
|
private final String desc;
|
||||||
|
|
||||||
|
PageBarType(String desc) {
|
||||||
|
this.desc = desc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static List<TagAttrOption> toTagAttrOptions() {
|
||||||
|
return List.of(
|
||||||
|
new TagAttrOption(Mini.name(), Mini.desc),
|
||||||
|
new TagAttrOption(Simple.name(), Simple.desc)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum LinkTarget {
|
||||||
|
|
||||||
|
_blank("新标签页打开"),
|
||||||
|
_self("当前页打开");
|
||||||
|
|
||||||
|
private final String desc;
|
||||||
|
|
||||||
|
LinkTarget(String desc) {
|
||||||
|
this.desc = desc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static List<TagAttrOption> toTagAttrOptions() {
|
||||||
|
return List.of(
|
||||||
|
new TagAttrOption(_blank.name(), _blank.desc),
|
||||||
|
new TagAttrOption(_self.name(), _self.desc)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,3 +1,8 @@
|
|||||||
FREEMARKER.TAG_ATTR.PAGE=是否分页获取数据
|
FREEMARKER.TAG_ATTR.PAGE=是否分页获取数据
|
||||||
FREEMARKER.TAG_ATTR.PAGE_SIZE=分页数据条数,默认:20
|
FREEMARKER.TAG_ATTR.PAGE_SIZE=分页数据条数,默认:20
|
||||||
FREEMARKER.TAG_ATTR.CONDITION=扩展sql条件语句,例如:title like 'a%'
|
FREEMARKER.TAG_ATTR.CONDITION=扩展sql条件语句,例如:title like 'a%'
|
||||||
|
|
||||||
|
FREEMARKER.TAG.NAME.page_bar=分页条标签
|
||||||
|
FREEMARKER.TAG.DESC.page_bar=生成固定格式的分页条html代码,样式由模板样式决定
|
||||||
|
FREEMARKER.TAG.FIRST_PAGE=首页
|
||||||
|
FREEMARKER.TAG.LAST_PAGE=末页
|
||||||
|
|||||||
@ -1,3 +1,8 @@
|
|||||||
FREEMARKER.TAG_ATTR.PAGE=Pageable
|
FREEMARKER.TAG_ATTR.PAGE=Pageable
|
||||||
FREEMARKER.TAG_ATTR.PAGE_SIZE=Page size, default is: 20.
|
FREEMARKER.TAG_ATTR.PAGE_SIZE=Page size, default is: 20.
|
||||||
FREEMARKER.TAG_ATTR.CONDITION=Extend sql condition, eg: title like 'a%'
|
FREEMARKER.TAG_ATTR.CONDITION=Extend sql condition, eg: title like 'a%'
|
||||||
|
|
||||||
|
FREEMARKER.TAG.NAME.page_bar=Pagination bar tag
|
||||||
|
FREEMARKER.TAG.DESC.page_bar=Generate pagination bar html code, the style is determined by the template style.
|
||||||
|
FREEMARKER.TAG.FIRST_PAGE=First Page
|
||||||
|
FREEMARKER.TAG.LAST_PAGE=Last Page
|
||||||
|
|||||||
@ -122,9 +122,9 @@ public class MemberLoginApiController extends BaseRestController {
|
|||||||
if (StpMemberUtil.isLogin()) {
|
if (StpMemberUtil.isLogin()) {
|
||||||
LoginUser loginUser = StpMemberUtil.getLoginUser();
|
LoginUser loginUser = StpMemberUtil.getLoginUser();
|
||||||
StpMemberUtil.logout();
|
StpMemberUtil.logout();
|
||||||
asyncTaskManager.execute(this.logininforService.recordLogininfor(loginUser.getUserType(),
|
this.logininforService.recordLogininfor(loginUser.getUserType(),
|
||||||
loginUser.getUserId(), loginUser.getUsername(), LoginLogType.LOGOUT, SuccessOrFail.SUCCESS,
|
loginUser.getUserId(), loginUser.getUsername(), LoginLogType.LOGOUT, SuccessOrFail.SUCCESS,
|
||||||
StringUtils.EMPTY));
|
StringUtils.EMPTY);
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,26 +1,19 @@
|
|||||||
package com.chestnut.member.security;
|
package com.chestnut.member.security;
|
||||||
|
|
||||||
import java.time.Instant;
|
import cn.dev33.satoken.session.SaSession;
|
||||||
import java.time.LocalDateTime;
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.chestnut.common.exception.GlobalException;
|
import com.chestnut.common.exception.GlobalException;
|
||||||
import com.chestnut.common.utils.IdUtils;
|
|
||||||
import com.chestnut.member.domain.dto.MemberLoginDTO;
|
|
||||||
import com.chestnut.member.domain.dto.MemberRegisterDTO;
|
|
||||||
import com.chestnut.member.fixed.dict.MemberStatus;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import com.chestnut.common.async.AsyncTaskManager;
|
|
||||||
import com.chestnut.common.security.SecurityUtils;
|
import com.chestnut.common.security.SecurityUtils;
|
||||||
import com.chestnut.common.security.domain.LoginUser;
|
import com.chestnut.common.security.domain.LoginUser;
|
||||||
import com.chestnut.common.security.enums.DeviceType;
|
import com.chestnut.common.security.enums.DeviceType;
|
||||||
import com.chestnut.common.utils.IP2RegionUtils;
|
import com.chestnut.common.utils.IP2RegionUtils;
|
||||||
import com.chestnut.common.utils.ServletUtils;
|
import com.chestnut.common.utils.IdUtils;
|
||||||
import com.chestnut.common.utils.StringUtils;
|
import com.chestnut.common.utils.StringUtils;
|
||||||
import com.chestnut.member.domain.Member;
|
import com.chestnut.member.domain.Member;
|
||||||
|
import com.chestnut.member.domain.dto.MemberLoginDTO;
|
||||||
|
import com.chestnut.member.domain.dto.MemberRegisterDTO;
|
||||||
import com.chestnut.member.exception.MemberErrorCode;
|
import com.chestnut.member.exception.MemberErrorCode;
|
||||||
|
import com.chestnut.member.fixed.dict.MemberStatus;
|
||||||
import com.chestnut.member.service.IMemberService;
|
import com.chestnut.member.service.IMemberService;
|
||||||
import com.chestnut.system.exception.SysErrorCode;
|
import com.chestnut.system.exception.SysErrorCode;
|
||||||
import com.chestnut.system.fixed.dict.LoginLogType;
|
import com.chestnut.system.fixed.dict.LoginLogType;
|
||||||
@ -28,10 +21,13 @@ import com.chestnut.system.fixed.dict.SuccessOrFail;
|
|||||||
import com.chestnut.system.fixed.dict.UserStatus;
|
import com.chestnut.system.fixed.dict.UserStatus;
|
||||||
import com.chestnut.system.service.ISecurityConfigService;
|
import com.chestnut.system.service.ISecurityConfigService;
|
||||||
import com.chestnut.system.service.ISysLogininforService;
|
import com.chestnut.system.service.ISysLogininforService;
|
||||||
|
|
||||||
import cn.dev33.satoken.session.SaSession;
|
|
||||||
import eu.bitwalker.useragentutils.UserAgent;
|
import eu.bitwalker.useragentutils.UserAgent;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 会员登录校验方法
|
* 会员登录校验方法
|
||||||
@ -49,8 +45,6 @@ public class MemberLoginService {
|
|||||||
|
|
||||||
private final ISecurityConfigService securityConfigService;
|
private final ISecurityConfigService securityConfigService;
|
||||||
|
|
||||||
private final AsyncTaskManager asyncTaskManager;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 登录验证
|
* 登录验证
|
||||||
*
|
*
|
||||||
@ -74,8 +68,8 @@ public class MemberLoginService {
|
|||||||
// 密码错误处理策略
|
// 密码错误处理策略
|
||||||
this.securityConfigService.processLoginPasswordError(member);
|
this.securityConfigService.processLoginPasswordError(member);
|
||||||
// 记录日志
|
// 记录日志
|
||||||
asyncTaskManager.execute(this.logininfoService.recordLogininfor(MemberUserType.TYPE, member.getMemberId(),
|
this.logininfoService.recordLogininfor(MemberUserType.TYPE, member.getMemberId(),
|
||||||
member.getUserName(), LoginLogType.LOGIN, SuccessOrFail.FAIL, "Invalid password."));
|
member.getUserName(), LoginLogType.LOGIN, SuccessOrFail.FAIL, "Invalid password.");
|
||||||
throw SysErrorCode.PASSWORD_ERROR.exception();
|
throw SysErrorCode.PASSWORD_ERROR.exception();
|
||||||
}
|
}
|
||||||
this.securityConfigService.onLoginSuccess(member);
|
this.securityConfigService.onLoginSuccess(member);
|
||||||
@ -89,8 +83,8 @@ public class MemberLoginService {
|
|||||||
loginUser.setToken(StpMemberUtil.getTokenValueByLoginId(member.getUserId()));
|
loginUser.setToken(StpMemberUtil.getTokenValueByLoginId(member.getUserId()));
|
||||||
StpMemberUtil.getTokenSession().set(SaSession.USER, loginUser);
|
StpMemberUtil.getTokenSession().set(SaSession.USER, loginUser);
|
||||||
// 日志
|
// 日志
|
||||||
asyncTaskManager.execute(this.logininfoService.recordLogininfor(MemberUserType.TYPE, member.getUserId(),
|
this.logininfoService.recordLogininfor(MemberUserType.TYPE, member.getUserId(),
|
||||||
loginUser.getUsername(), LoginLogType.LOGIN, SuccessOrFail.SUCCESS, StringUtils.EMPTY));
|
loginUser.getUsername(), LoginLogType.LOGIN, SuccessOrFail.SUCCESS, StringUtils.EMPTY);
|
||||||
return StpMemberUtil.getTokenValue();
|
return StpMemberUtil.getTokenValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
package com.chestnut.system.controller;
|
package com.chestnut.system.controller;
|
||||||
|
|
||||||
import com.chestnut.common.async.AsyncTaskManager;
|
|
||||||
import com.chestnut.common.domain.R;
|
import com.chestnut.common.domain.R;
|
||||||
import com.chestnut.common.i18n.I18nUtils;
|
import com.chestnut.common.i18n.I18nUtils;
|
||||||
import com.chestnut.common.security.anno.Priv;
|
import com.chestnut.common.security.anno.Priv;
|
||||||
@ -47,12 +46,8 @@ public class SysLoginController extends BaseRestController {
|
|||||||
|
|
||||||
private final ISysRoleService roleService;
|
private final ISysRoleService roleService;
|
||||||
|
|
||||||
private final ISysPermissionService permissionService;
|
|
||||||
|
|
||||||
private final ISysLogininforService logininfoService;
|
private final ISysLogininforService logininfoService;
|
||||||
|
|
||||||
private final AsyncTaskManager asyncTaskManager;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 登录方法
|
* 登录方法
|
||||||
*
|
*
|
||||||
@ -73,9 +68,9 @@ public class SysLoginController extends BaseRestController {
|
|||||||
if (StpAdminUtil.isLogin()) {
|
if (StpAdminUtil.isLogin()) {
|
||||||
LoginUser loginUser = StpAdminUtil.getLoginUser();
|
LoginUser loginUser = StpAdminUtil.getLoginUser();
|
||||||
StpAdminUtil.logout();
|
StpAdminUtil.logout();
|
||||||
asyncTaskManager.execute(this.logininfoService.recordLogininfor(loginUser.getUserType(),
|
this.logininfoService.recordLogininfor(loginUser.getUserType(),
|
||||||
loginUser.getUserId(), loginUser.getUsername(), LoginLogType.LOGOUT, SuccessOrFail.SUCCESS,
|
loginUser.getUserId(), loginUser.getUsername(), LoginLogType.LOGOUT, SuccessOrFail.SUCCESS,
|
||||||
StringUtils.EMPTY));
|
StringUtils.EMPTY);
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
|
||||||
|
|||||||
@ -72,7 +72,7 @@ public class SysLogHandler implements ILogHandler {
|
|||||||
operLog.setOperTime(logDetail.getLogTime());
|
operLog.setOperTime(logDetail.getLogTime());
|
||||||
operLog.setCost(logDetail.getCost());
|
operLog.setCost(logDetail.getCost());
|
||||||
// 保存数据库
|
// 保存数据库
|
||||||
asyncTaskManager.execute(operLogService.recordOper(operLog));
|
operLogService.recordOper(operLog);
|
||||||
} catch (Exception exp) {
|
} catch (Exception exp) {
|
||||||
// 记录本地异常日志
|
// 记录本地异常日志
|
||||||
logger.error("异常信息:{}", exp.getMessage());
|
logger.error("异常信息:{}", exp.getMessage());
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
package com.chestnut.system.security;
|
package com.chestnut.system.security;
|
||||||
|
|
||||||
import cn.dev33.satoken.session.SaSession;
|
import cn.dev33.satoken.session.SaSession;
|
||||||
import com.chestnut.common.async.AsyncTaskManager;
|
|
||||||
import com.chestnut.common.redis.RedisCache;
|
import com.chestnut.common.redis.RedisCache;
|
||||||
import com.chestnut.common.security.SecurityUtils;
|
import com.chestnut.common.security.SecurityUtils;
|
||||||
import com.chestnut.common.security.domain.LoginUser;
|
import com.chestnut.common.security.domain.LoginUser;
|
||||||
@ -49,8 +48,6 @@ public class SysLoginService {
|
|||||||
|
|
||||||
private final ISysPermissionService permissionService;
|
private final ISysPermissionService permissionService;
|
||||||
|
|
||||||
private final AsyncTaskManager asyncTaskManager;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 登录验证
|
* 登录验证
|
||||||
*
|
*
|
||||||
@ -84,8 +81,8 @@ public class SysLoginService {
|
|||||||
this.userService.updateById(user);
|
this.userService.updateById(user);
|
||||||
}
|
}
|
||||||
// 记录日志
|
// 记录日志
|
||||||
asyncTaskManager.execute(this.logininfoService.recordLogininfor(AdminUserType.TYPE, user.getUserId(),
|
this.logininfoService.recordLogininfor(AdminUserType.TYPE, user.getUserId(),
|
||||||
user.getUserName(), LoginLogType.LOGIN, SuccessOrFail.FAIL, "Invalid password."));
|
user.getUserName(), LoginLogType.LOGIN, SuccessOrFail.FAIL, "Invalid password.");
|
||||||
throw SysErrorCode.PASSWORD_ERROR.exception();
|
throw SysErrorCode.PASSWORD_ERROR.exception();
|
||||||
}
|
}
|
||||||
this.securityConfigService.onLoginSuccess(user);
|
this.securityConfigService.onLoginSuccess(user);
|
||||||
@ -100,8 +97,8 @@ public class SysLoginService {
|
|||||||
loginUser.setToken(StpAdminUtil.getTokenValueByLoginId(user.getUserId()));
|
loginUser.setToken(StpAdminUtil.getTokenValueByLoginId(user.getUserId()));
|
||||||
StpAdminUtil.getTokenSession().set(SaSession.USER, loginUser);
|
StpAdminUtil.getTokenSession().set(SaSession.USER, loginUser);
|
||||||
// 日志
|
// 日志
|
||||||
asyncTaskManager.execute(this.logininfoService.recordLogininfor(AdminUserType.TYPE, user.getUserId(),
|
this.logininfoService.recordLogininfor(AdminUserType.TYPE, user.getUserId(),
|
||||||
loginUser.getUsername(), LoginLogType.LOGIN, SuccessOrFail.SUCCESS, StringUtils.EMPTY));
|
loginUser.getUsername(), LoginLogType.LOGIN, SuccessOrFail.SUCCESS, StringUtils.EMPTY);
|
||||||
return StpAdminUtil.getTokenValue();
|
return StpAdminUtil.getTokenValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,25 +127,24 @@ public class SysLoginService {
|
|||||||
* @param username 用户名
|
* @param username 用户名
|
||||||
* @param code 验证码
|
* @param code 验证码
|
||||||
* @param uuid 唯一标识
|
* @param uuid 唯一标识
|
||||||
* @return 结果
|
|
||||||
*/
|
*/
|
||||||
public void validateCaptcha(String username, String code, String uuid) {
|
public void validateCaptcha(String username, String code, String uuid) {
|
||||||
Assert.notEmpty(uuid, () -> SysErrorCode.CAPTCHA_ERR.exception());
|
Assert.notEmpty(uuid, SysErrorCode.CAPTCHA_ERR::exception);
|
||||||
|
|
||||||
String verifyKey = SysConstants.CAPTCHA_CODE_KEY + StringUtils.nvl(uuid, StringUtils.EMPTY);
|
String verifyKey = SysConstants.CAPTCHA_CODE_KEY + StringUtils.nvl(uuid, StringUtils.EMPTY);
|
||||||
String captcha = redisCache.getCacheObject(verifyKey);
|
String captcha = redisCache.getCacheObject(verifyKey);
|
||||||
// 过期判断
|
// 过期判断
|
||||||
Assert.notNull(captcha, () -> {
|
Assert.notNull(captcha, () -> {
|
||||||
asyncTaskManager.execute(this.logininfoService.recordLogininfor(AdminUserType.TYPE, null, username,
|
this.logininfoService.recordLogininfor(AdminUserType.TYPE, null, username,
|
||||||
LoginLogType.LOGIN, SuccessOrFail.FAIL, SysErrorCode.CAPTCHA_EXPIRED.name()));
|
LoginLogType.LOGIN, SuccessOrFail.FAIL, SysErrorCode.CAPTCHA_EXPIRED.name());
|
||||||
return SysErrorCode.CAPTCHA_EXPIRED.exception();
|
return SysErrorCode.CAPTCHA_EXPIRED.exception();
|
||||||
});
|
});
|
||||||
// 未过期移除缓存
|
// 未过期移除缓存
|
||||||
redisCache.deleteObject(verifyKey);
|
redisCache.deleteObject(verifyKey);
|
||||||
// 判断是否与输入验证码一致
|
// 判断是否与输入验证码一致
|
||||||
Assert.isTrue(StringUtils.equals(code, captcha), () -> {
|
Assert.isTrue(StringUtils.equals(code, captcha), () -> {
|
||||||
asyncTaskManager.execute(this.logininfoService.recordLogininfor(AdminUserType.TYPE, null, username,
|
this.logininfoService.recordLogininfor(AdminUserType.TYPE, null, username,
|
||||||
LoginLogType.LOGIN, SuccessOrFail.FAIL, SysErrorCode.CAPTCHA_ERR.name()));
|
LoginLogType.LOGIN, SuccessOrFail.FAIL, SysErrorCode.CAPTCHA_ERR.name());
|
||||||
return SysErrorCode.CAPTCHA_ERR.exception();
|
return SysErrorCode.CAPTCHA_ERR.exception();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@ -53,8 +53,8 @@ public class SysRegisterService {
|
|||||||
user.setPassword(registerBody.getPassword());
|
user.setPassword(registerBody.getPassword());
|
||||||
user.setNickName(registerBody.getUsername());
|
user.setNickName(registerBody.getUsername());
|
||||||
userService.registerUser(user);
|
userService.registerUser(user);
|
||||||
asyncTaskManager.execute(this.logininfoService.recordLogininfor(AdminUserType.TYPE, user.getUserId(),
|
this.logininfoService.recordLogininfor(AdminUserType.TYPE, user.getUserId(),
|
||||||
user.getUserName(), LoginLogType.REGIST, SuccessOrFail.SUCCESS, StringUtils.EMPTY));
|
user.getUserName(), LoginLogType.REGIST, SuccessOrFail.SUCCESS, StringUtils.EMPTY);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
package com.chestnut.system.service;
|
package com.chestnut.system.service;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.extension.service.IService;
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
import com.chestnut.common.async.AsyncTask;
|
|
||||||
import com.chestnut.system.domain.SysLogininfor;
|
import com.chestnut.system.domain.SysLogininfor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -12,18 +11,17 @@ public interface ISysLogininforService extends IService<SysLogininfor> {
|
|||||||
/**
|
/**
|
||||||
* 清空系统登录日志
|
* 清空系统登录日志
|
||||||
*/
|
*/
|
||||||
public void cleanLogininfor();
|
void cleanLogininfor();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 记录登录日志任务
|
* 记录登录日志任务
|
||||||
*
|
*
|
||||||
* @param userType
|
* @param userType 用户类型
|
||||||
* @param userId
|
* @param userId 用户ID
|
||||||
* @param username
|
* @param username 用户名
|
||||||
* @param logType
|
* @param logType 日志类型
|
||||||
* @param message
|
* @param message 日志详情
|
||||||
* @param args
|
* @param args 参数
|
||||||
* @return
|
|
||||||
*/
|
*/
|
||||||
AsyncTask recordLogininfor(String userType, Object userId, String username, String logType, String status, String message, Object... args);
|
void recordLogininfor(String userType, Object userId, String username, String logType, String status, String message, Object... args);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
package com.chestnut.system.service;
|
package com.chestnut.system.service;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.extension.service.IService;
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
import com.chestnut.common.async.AsyncTask;
|
|
||||||
import com.chestnut.system.domain.SysOperLog;
|
import com.chestnut.system.domain.SysOperLog;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -15,14 +14,12 @@ public interface ISysOperLogService extends IService<SysOperLog> {
|
|||||||
/**
|
/**
|
||||||
* 清空操作日志
|
* 清空操作日志
|
||||||
*/
|
*/
|
||||||
public void cleanOperLog();
|
void cleanOperLog();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 操作日志记录
|
* 操作日志记录
|
||||||
*
|
*
|
||||||
* @param operLog
|
* @param operLog 操作日志信息
|
||||||
* 操作日志信息
|
|
||||||
* @return 任务task
|
|
||||||
*/
|
*/
|
||||||
public AsyncTask recordOper(SysOperLog operLog);
|
void recordOper(SysOperLog operLog);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,12 +2,12 @@ package com.chestnut.system.service.impl;
|
|||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
import com.chestnut.common.async.AsyncTaskManager;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
import com.chestnut.common.async.AsyncTask;
|
|
||||||
import com.chestnut.common.utils.ConvertUtils;
|
import com.chestnut.common.utils.ConvertUtils;
|
||||||
import com.chestnut.common.utils.IP2RegionUtils;
|
import com.chestnut.common.utils.IP2RegionUtils;
|
||||||
import com.chestnut.common.utils.ServletUtils;
|
import com.chestnut.common.utils.ServletUtils;
|
||||||
@ -32,6 +32,8 @@ public class SysLogininforServiceImpl extends ServiceImpl<SysLogininforMapper, S
|
|||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(SysLogininforServiceImpl.class);
|
private static final Logger logger = LoggerFactory.getLogger(SysLogininforServiceImpl.class);
|
||||||
|
|
||||||
|
private final AsyncTaskManager asyncTaskManager;
|
||||||
|
|
||||||
private final SysLogininforMapper logininforMapper;
|
private final SysLogininforMapper logininforMapper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -43,50 +45,41 @@ public class SysLogininforServiceImpl extends ServiceImpl<SysLogininforMapper, S
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AsyncTask recordLogininfor(String userType, Object userId, String username, String logType, String status, String message, Object... args) {
|
public void recordLogininfor(String userType, Object userId, String username, String logType, String status, String message, Object... args) {
|
||||||
final UserAgent userAgent = UserAgent.parseUserAgentString(ServletUtils.getUserAgent());
|
final UserAgent userAgent = UserAgent.parseUserAgentString(ServletUtils.getUserAgent());
|
||||||
final String ip = ServletUtils.getIpAddr(ServletUtils.getRequest());
|
final String ip = ServletUtils.getIpAddr(ServletUtils.getRequest());
|
||||||
return new AsyncTask() {
|
asyncTaskManager.execute(() -> {
|
||||||
|
// 打印信息到日志
|
||||||
@Override
|
StringBuilder s = new StringBuilder();
|
||||||
public String getType() {
|
s.append("[").append(ip).append("]");
|
||||||
return "LoginLog";
|
s.append("[type:").append(userType).append("]");
|
||||||
|
s.append("[uid:").append(userId).append("]");
|
||||||
|
s.append("[uname:").append(username).append("]");
|
||||||
|
s.append("[").append(logType).append("]");
|
||||||
|
s.append("[").append(status).append("]");
|
||||||
|
s.append("[").append(message).append("]");
|
||||||
|
logger.info(s.toString(), args);
|
||||||
|
// 获取客户端操作系统
|
||||||
|
String os = userAgent.getOperatingSystem().getName();
|
||||||
|
// 获取客户端浏览器
|
||||||
|
String browser = userAgent.getBrowser().getName();
|
||||||
|
// 封装对象
|
||||||
|
SysLogininfor logininfor = new SysLogininfor();
|
||||||
|
logininfor.setUserType(userType);
|
||||||
|
logininfor.setUserId(ConvertUtils.toStr(userId));
|
||||||
|
logininfor.setUserName(username);
|
||||||
|
logininfor.setLoginTime(LocalDateTime.now());
|
||||||
|
logininfor.setIpaddr(ip);
|
||||||
|
logininfor.setLoginLocation(IP2RegionUtils.ip2Region(ip));
|
||||||
|
logininfor.setBrowser(browser);
|
||||||
|
logininfor.setOs(os);
|
||||||
|
if (StringUtils.isNotBlank(message)) {
|
||||||
|
logininfor.setMsg(message.length() > 2000 ? message.substring(0, 2000) : message);
|
||||||
}
|
}
|
||||||
|
logininfor.setLogType(logType);
|
||||||
@Override
|
// 日志状态
|
||||||
public void run0() {
|
logininfor.setStatus(status);
|
||||||
// 打印信息到日志
|
save(logininfor);
|
||||||
StringBuilder s = new StringBuilder();
|
});
|
||||||
s.append("[").append(ip).append("]");
|
|
||||||
s.append("[type:").append(userType).append("]");
|
|
||||||
s.append("[uid:").append(userId).append("]");
|
|
||||||
s.append("[uname:").append(username).append("]");
|
|
||||||
s.append("[").append(logType).append("]");
|
|
||||||
s.append("[").append(status).append("]");
|
|
||||||
s.append("[").append(message).append("]");
|
|
||||||
logger.info(s.toString(), args);
|
|
||||||
// 获取客户端操作系统
|
|
||||||
String os = userAgent.getOperatingSystem().getName();
|
|
||||||
// 获取客户端浏览器
|
|
||||||
String browser = userAgent.getBrowser().getName();
|
|
||||||
// 封装对象
|
|
||||||
SysLogininfor logininfor = new SysLogininfor();
|
|
||||||
logininfor.setUserType(userType);
|
|
||||||
logininfor.setUserId(ConvertUtils.toStr(userId));
|
|
||||||
logininfor.setUserName(username);
|
|
||||||
logininfor.setLoginTime(LocalDateTime.now());
|
|
||||||
logininfor.setIpaddr(ip);
|
|
||||||
logininfor.setLoginLocation(IP2RegionUtils.ip2Region(ip));
|
|
||||||
logininfor.setBrowser(browser);
|
|
||||||
logininfor.setOs(os);
|
|
||||||
if (StringUtils.isNotBlank(message)) {
|
|
||||||
logininfor.setMsg(message.length() > 2000 ? message.substring(0, 2000) : message);
|
|
||||||
}
|
|
||||||
logininfor.setLogType(logType);
|
|
||||||
// 日志状态
|
|
||||||
logininfor.setStatus(status);
|
|
||||||
save(logininfor);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
package com.chestnut.system.service.impl;
|
package com.chestnut.system.service.impl;
|
||||||
|
|
||||||
|
import com.chestnut.common.async.AsyncTaskManager;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
import com.chestnut.common.async.AsyncTask;
|
|
||||||
import com.chestnut.common.utils.IP2RegionUtils;
|
import com.chestnut.common.utils.IP2RegionUtils;
|
||||||
import com.chestnut.system.domain.SysOperLog;
|
import com.chestnut.system.domain.SysOperLog;
|
||||||
import com.chestnut.system.mapper.SysOperLogMapper;
|
import com.chestnut.system.mapper.SysOperLogMapper;
|
||||||
@ -20,6 +20,8 @@ public class SysOperLogServiceImpl extends ServiceImpl<SysOperLogMapper, SysOper
|
|||||||
|
|
||||||
private final SysOperLogMapper operLogMapper;
|
private final SysOperLogMapper operLogMapper;
|
||||||
|
|
||||||
|
private final AsyncTaskManager asyncTaskManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 清空操作日志
|
* 清空操作日志
|
||||||
*/
|
*/
|
||||||
@ -30,26 +32,14 @@ public class SysOperLogServiceImpl extends ServiceImpl<SysOperLogMapper, SysOper
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 操作日志记录
|
* 操作日志记录
|
||||||
*
|
*
|
||||||
* @param operLog
|
* @param operLog 操作日志信息
|
||||||
* 操作日志信息
|
|
||||||
* @return 任务task
|
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public AsyncTask recordOper(final SysOperLog operLog) {
|
public void recordOper(final SysOperLog operLog) {
|
||||||
return new AsyncTask() {
|
asyncTaskManager.execute(() -> {
|
||||||
|
operLog.setOperLocation(IP2RegionUtils.ip2Region(operLog.getOperIp()));
|
||||||
@Override
|
save(operLog);
|
||||||
public String getType() {
|
});
|
||||||
return "OpLog";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run0() {
|
|
||||||
// 远程查询操作地点
|
|
||||||
operLog.setOperLocation(IP2RegionUtils.ip2Region(operLog.getOperIp()));
|
|
||||||
save(operLog);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user