> props);
/**
* 获取发布通道属性值
diff --git a/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/service/IPublishService.java b/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/service/IPublishService.java
index faa3b743..a991461e 100644
--- a/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/service/IPublishService.java
+++ b/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/service/IPublishService.java
@@ -32,14 +32,12 @@ import java.util.List;
public interface IPublishService {
/**
- * 发布站点首页
- *
+ * 发布站点首页
* 此方法供API发布站点首页调用,做基础校验
*
- * @param site
- * @return
- * @throws IOException
- * @throws TemplateException
+ * @param site 站点
+ * @throws IOException e1
+ * @throws TemplateException e2
*/
void publishSiteIndex(CmsSite site) throws IOException, TemplateException;
@@ -48,20 +46,20 @@ public interface IPublishService {
*
* 发布站点下所有栏目及指定状态内容
*
- * @param site
- * @param contentStatus
- * @return
+ * @param site 站点
+ * @param contentStatus 内容状态
+ * @return 结果
*/
AsyncTask publishAll(CmsSite site, final String contentStatus, final LoginUser operator);
/**
* 站点首页页面内容
*
- * @param site
- * @param requestData
- * @return
- * @throws IOException
- * @throws TemplateException
+ * @param site 站点
+ * @param requestData 请求数据
+ * @return 结果
+ * @throws IOException e1
+ * @throws TemplateException e2
*/
String getSitePageData(CmsSite site, IInternalDataType.RequestData requestData)
throws IOException, TemplateException;
@@ -69,12 +67,12 @@ public interface IPublishService {
/**
* 获取栏目模板页面内容
*
- * @param catalog
- * @param requestData
- * @param listFlag
- * @return
- * @throws IOException
- * @throws TemplateException
+ * @param catalog 栏目
+ * @param requestData 请求数据
+ * @param listFlag 是否分页
+ * @return 结果
+ * @throws IOException e1
+ * @throws TemplateException e2
*/
String getCatalogPageData(CmsCatalog catalog, IInternalDataType.RequestData requestData, boolean listFlag)
throws IOException, TemplateException;
@@ -82,11 +80,11 @@ public interface IPublishService {
/**
* 发布栏目,异步任务
*
- * @param catalog
+ * @param catalog 栏目
* @param publishChild 是否发布子栏目
* @param publishDetail 是否发布详情页
* @param publishStatus 指定发布内容状态
- * @return
+ * @return 结果
*/
AsyncTask publishCatalog(CmsCatalog catalog, boolean publishChild, boolean publishDetail,
String publishStatus, final LoginUser operator);
@@ -94,11 +92,11 @@ public interface IPublishService {
/**
* 获取内容模板页面结果
*
- * @param content
- * @param requestData
- * @return
- * @throws IOException
- * @throws TemplateException
+ * @param content 内容
+ * @param requestData 请求数据
+ * @return 结果
+ * @throws IOException e1
+ * @throws TemplateException e2
*/
String getContentPageData(CmsContent content, IInternalDataType.RequestData requestData)
throws IOException, TemplateException;
@@ -106,29 +104,27 @@ public interface IPublishService {
/**
* 发布内容,创建异步任务发布
*
- * @param content
+ * @param content 内容
*/
void asyncPublishContent(IContent> content);
/**
* 发布内容
*
- * @param contentIds
- * @return
- * @throws IOException
- * @throws TemplateException
+ * @param contentIds 内容ID列表
+ * @param operator 操作人
*/
void publishContent(List contentIds, LoginUser operator) ;
/**
* 获取内容扩展模板解析内容
*
- * @param content
- * @param publishPipeCode
- * @param isPreview
- * @return
- * @throws IOException
- * @throws TemplateException
+ * @param content 内容
+ * @param publishPipeCode 发布通道编码
+ * @param isPreview 是否预览
+ * @return 结果
+ * @throws IOException e1
+ * @throws TemplateException e2
*/
String getContentExPageData(CmsContent content, String publishPipeCode, boolean isPreview)
throws IOException, TemplateException;
@@ -136,18 +132,19 @@ public interface IPublishService {
/**
* 获取页面部件模板解析内容
*
- * @param pageWidget
- * @param isPreview
- * @return
- * @throws IOException
- * @throws TemplateException
+ * @param pageWidget 页面部件
+ * @param publishPipeCode 发布通道编码
+ * @param isPreview 是否预览
+ * @return 结果
+ * @throws IOException e1
+ * @throws TemplateException e2
*/
- String getPageWidgetPageData(CmsPageWidget pageWidget, boolean isPreview) throws IOException, TemplateException;
+ String getPageWidgetPageData(CmsPageWidget pageWidget, String publishPipeCode, boolean isPreview) throws IOException, TemplateException;
/**
* 页面部件静态化
*
- * @param pageWidget
+ * @param pageWidget 页面部件
*/
void pageWidgetStaticize(IPageWidget pageWidget);
}
diff --git a/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/service/IResourceService.java b/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/service/IResourceService.java
index fc832a78..25254454 100644
--- a/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/service/IResourceService.java
+++ b/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/service/IResourceService.java
@@ -16,8 +16,8 @@
package com.chestnut.contentcore.service;
import com.baomidou.mybatisplus.extension.service.IService;
-import com.chestnut.common.storage.IFileStorageType;
import com.chestnut.contentcore.core.IResourceType;
+import com.chestnut.contentcore.core.InternalURL;
import com.chestnut.contentcore.domain.CmsResource;
import com.chestnut.contentcore.domain.CmsSite;
import com.chestnut.contentcore.domain.dto.ResourceUploadDTO;
@@ -26,14 +26,10 @@ import jakarta.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.util.List;
+import java.util.function.Consumer;
public interface IResourceService extends IService {
- /**
- * 获取存储方式
- */
- IFileStorageType getFileStorageType(String type);
-
/**
* 上传资源
*/
@@ -102,4 +98,31 @@ public interface IResourceService extends IService {
* @param operator 操作人
*/
String downloadRemoteImages(String html, CmsSite site, String operator);
+
+ /**
+ * 检查图片资源缩略图,如果不存在则生成
+ *
+ * @param internalURL 内部链接
+ * @param width 缩略图宽度
+ * @param height 缩略图高度
+ */
+ void createThumbnailIfNotExists(InternalURL internalURL, int width, int height) throws IOException;
+
+ /**
+ * 处理默认缩略图
+ *
+ * @param site 站点
+ * @param images 源图列表
+ * @param thumbnailsConsumer 缩略图消费者
+ */
+ void dealDefaultThumbnail(CmsSite site, List images, Consumer> thumbnailsConsumer);
+
+ /**
+ * 处理内容引导图缩略图
+ *
+ * @param site 站点
+ * @param imageSrc 源图列表
+ * @param thumbnailConsumer 缩略图消费者
+ */
+ void dealDefaultThumbnail(CmsSite site, String imageSrc, Consumer thumbnailConsumer);
}
diff --git a/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/service/impl/CatalogServiceImpl.java b/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/service/impl/CatalogServiceImpl.java
index b984d457..9a0ec4b3 100644
--- a/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/service/impl/CatalogServiceImpl.java
+++ b/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/service/impl/CatalogServiceImpl.java
@@ -39,6 +39,7 @@ import com.chestnut.contentcore.domain.CmsCatalog;
import com.chestnut.contentcore.domain.CmsContent;
import com.chestnut.contentcore.domain.CmsSite;
import com.chestnut.contentcore.domain.dto.*;
+import com.chestnut.contentcore.domain.pojo.PublishPipeProps;
import com.chestnut.contentcore.exception.ContentCoreErrorCode;
import com.chestnut.contentcore.listener.event.*;
import com.chestnut.contentcore.mapper.CmsCatalogMapper;
@@ -279,7 +280,7 @@ public class CatalogServiceImpl extends ServiceImpl> publishPipeProps = dto.getPublishPipeDatas().stream()
- .collect(Collectors.toMap(PublishPipeProp::getPipeCode, PublishPipeProp::getProps));
+ .collect(Collectors.toMap(PublishPipeProps::getPipeCode, PublishPipeProps::getProps));
catalog.setPublishPipeProps(publishPipeProps);
catalog.updateBy(dto.getOperator().getUsername());
this.updateById(catalog);
@@ -303,8 +304,7 @@ public class CatalogServiceImpl extends ServiceImpl toCatalogs = this.list(q);
if (!toCatalogs.isEmpty()) {
for (CmsCatalog toCatalog : toCatalogs) {
- List publishPipeProps = dto.getPublishPipeProps();
- for (PublishPipeProp publishPipeProp : publishPipeProps) {
+ List publishPipeProps = dto.getPublishPipeProps();
+ for (PublishPipeProps publishPipeProp : publishPipeProps) {
Map sitePublishPipeProp = site.getPublishPipeProps()
.get(publishPipeProp.getPipeCode());
Map catalogPublishPipeProp = toCatalog
@@ -604,6 +603,9 @@ public class CatalogServiceImpl extends ServiceImpl icontent = contentType.loadContent(content);
icontent.setOperator(operator);
+ icontent.getParams().put(IContent.PARAM_IS_DELETE_BY_CATALOG, true);
icontent.delete();
});
}
diff --git a/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/service/impl/FileServiceImpl.java b/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/service/impl/FileServiceImpl.java
index 24fa6902..a2fbd7b5 100644
--- a/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/service/impl/FileServiceImpl.java
+++ b/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/service/impl/FileServiceImpl.java
@@ -33,12 +33,15 @@ import com.chestnut.contentcore.service.IPublishPipeService;
import com.chestnut.contentcore.util.SiteUtils;
import lombok.RequiredArgsConstructor;
import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.FilenameUtils;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
@@ -149,27 +152,28 @@ public class FileServiceImpl implements IFileService {
@Override
public void renameFile(CmsSite site, String filePath, String rename) throws IOException {
- this.checkFileType(rename);
-
+ String ext = FilenameUtils.getExtension(rename);
+ if (StringUtils.isNotEmpty(ext)) {
+ this.checkFileType(rename);
+ }
String path = FileExUtils.normalizePath(filePath);
if (path.startsWith("/")) {
path = path.substring(1);
}
- this.checkSiteDirectory(site, filePath);
-
+ this.checkSiteDirectory(site, path);
+
String root = CMSConfig.getResourceRoot();
File file = new File(root + path);
Assert.isTrue(file.exists(), ContentCoreErrorCode.FILE_NOT_EXIST::exception);
-
- String dest = root + StringUtils.substringBeforeLast(path, "/") + "/" + rename;
- File destFile = new File(dest);
- Assert.isFalse(destFile.exists(), ContentCoreErrorCode.FILE_ALREADY_EXISTS::exception);
+
+ Path dest = Path.of(file.getParent(), rename);
+ Assert.isFalse(Files.exists(dest), ContentCoreErrorCode.FILE_ALREADY_EXISTS::exception);
if (file.isDirectory()) {
- FileUtils.moveDirectory(file, destFile);
+ FileUtils.moveDirectory(file, dest.toFile());
} else {
this.checkFileType(rename);
- FileUtils.moveFile(file, destFile);
+ FileUtils.moveFile(file, dest.toFile());
}
}
@@ -205,7 +209,8 @@ public class FileServiceImpl implements IFileService {
path = path.substring(1);
}
this.checkSiteDirectory(site, path);
- if (!EDITABLE_FILE_TYPE.contains(FileExUtils.getExtension(path))) {
+ String ext = FilenameUtils.getExtension(path);
+ if (!EDITABLE_FILE_TYPE.contains(ext)) {
throw ContentCoreErrorCode.NOT_EDITABLE_FILE.exception();
}
String root = CMSConfig.getResourceRoot();
diff --git a/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/service/impl/PublishPipeServiceImpl.java b/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/service/impl/PublishPipeServiceImpl.java
index ca5b05c8..665a0307 100644
--- a/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/service/impl/PublishPipeServiceImpl.java
+++ b/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/service/impl/PublishPipeServiceImpl.java
@@ -29,7 +29,7 @@ import com.chestnut.contentcore.core.IPublishPipeProp.PublishPipePropUseType;
import com.chestnut.contentcore.core.impl.PublishPipeProp_IndexTemplate;
import com.chestnut.contentcore.domain.CmsPublishPipe;
import com.chestnut.contentcore.domain.CmsSite;
-import com.chestnut.contentcore.domain.dto.PublishPipeProp;
+import com.chestnut.contentcore.domain.pojo.PublishPipeProps;
import com.chestnut.contentcore.fixed.config.TemplateSuffix;
import com.chestnut.contentcore.mapper.CmsPublishPipeMapper;
import com.chestnut.contentcore.properties.EnableSiteDeleteBackupProperty;
@@ -65,13 +65,13 @@ public class PublishPipeServiceImpl extends ServiceImpl publishPipeProps;
@Override
- public List getPublishPipeProps(Long siteId, PublishPipePropUseType useType,
- Map> props) {
+ public List getPublishPipeProps(Long siteId, PublishPipePropUseType useType,
+ Map> props) {
List list = this.publishPipeProps.stream()
.filter(p -> p.getUseTypes().contains(useType))
.toList();
return this.getPublishPipes(siteId).stream().map(pp -> {
- PublishPipeProp prop = PublishPipeProp.newInstance(pp.getCode(), pp.getName(),
+ PublishPipeProps prop = PublishPipeProps.newInstance(pp.getCode(), pp.getName(),
Objects.isNull(props) ? null : props.get(pp.getCode()));
list.forEach(p -> {
if (!prop.getProps().containsKey(p.getKey())) {
diff --git a/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/service/impl/PublishServiceImpl.java b/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/service/impl/PublishServiceImpl.java
index 5f8f83cf..7b5198bb 100644
--- a/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/service/impl/PublishServiceImpl.java
+++ b/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/service/impl/PublishServiceImpl.java
@@ -46,6 +46,7 @@ import com.chestnut.contentcore.util.*;
import com.chestnut.system.fixed.dict.YesOrNo;
import freemarker.template.TemplateException;
import lombok.RequiredArgsConstructor;
+import org.apache.commons.collections4.MapUtils;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -106,7 +107,7 @@ public class PublishServiceImpl implements IPublishService, ApplicationContextAw
this.staticizeService.process(context, writer);
return writer.toString();
} finally {
- logger.debug("[{}]首页模板解析:{}\t耗时:{}ms", requestData.getPublishPipeCode(), site.getName(), System.currentTimeMillis() - s);
+ logger.debug("[{}]Parse index template: {}\t, cost: {}ms", requestData.getPublishPipeCode(), site.getName(), System.currentTimeMillis() - s);
}
}
@@ -229,7 +230,7 @@ public class PublishServiceImpl implements IPublishService, ApplicationContextAw
if (listFlag) {
String catalogLink = this.catalogService.getCatalogListLink(catalog, 1, requestData.getPublishPipeCode(), requestData.isPreview());
templateContext.setFirstFileName(catalogLink);
- templateContext.setOtherFileName(catalogLink + "&pi=" + TemplateContext.PlaceHolder_PageNo);
+ templateContext.setOtherFileName(TemplateUtils.appendPageIndexParam(catalogLink, TemplateContext.PlaceHolder_PageNo));
}
try (StringWriter writer = new StringWriter()) {
this.staticizeService.process(templateContext, writer);
@@ -372,7 +373,7 @@ public class PublishServiceImpl implements IPublishService, ApplicationContextAw
// 分页链接
String contentLink = this.contentService.getContentLink(content, 1, requestData.getPublishPipeCode(), requestData.isPreview());
templateContext.setFirstFileName(contentLink);
- templateContext.setOtherFileName(contentLink + "&pi=" + TemplateContext.PlaceHolder_PageNo);
+ templateContext.setOtherFileName(TemplateUtils.appendPageIndexParam(contentLink, TemplateContext.PlaceHolder_PageNo));
// staticize
this.staticizeService.process(templateContext, writer);
logger.debug("[{}][{}]内容模板解析:{},耗时:{}", requestData.getPublishPipeCode(), contentType.getId(), content.getTitle(),
@@ -484,22 +485,20 @@ public class PublishServiceImpl implements IPublishService, ApplicationContextAw
}
@Override
- public String getPageWidgetPageData(CmsPageWidget pageWidget, boolean isPreview)
+ public String getPageWidgetPageData(CmsPageWidget pageWidget, String publishPipeCode, boolean isPreview)
throws IOException, TemplateException {
CmsSite site = this.siteService.getById(pageWidget.getSiteId());
- File templateFile = this.templateService.findTemplateFile(site, pageWidget.getTemplate(),
- pageWidget.getPublishPipeCode());
- Assert.notNull(templateFile,
- () -> ContentCoreErrorCode.TEMPLATE_EMPTY.exception(pageWidget.getName(), pageWidget.getCode()));
+ String template = MapUtils.getString(pageWidget.getTemplates(), publishPipeCode, "");
+ File templateFile = this.templateService.findTemplateFile(site, template,
+ publishPipeCode);
+ Assert.notNull(templateFile, () -> ContentCoreErrorCode.TEMPLATE_EMPTY.exception(template));
// 生成静态页面
try (StringWriter writer = new StringWriter()) {
long s = System.currentTimeMillis();
// 模板ID = 通道:站点目录:模板文件名
- String templateKey = SiteUtils.getTemplateKey(site, pageWidget.getPublishPipeCode(),
- pageWidget.getTemplate());
- TemplateContext templateContext = new TemplateContext(templateKey, isPreview,
- pageWidget.getPublishPipeCode());
+ String templateKey = SiteUtils.getTemplateKey(site, publishPipeCode, template);
+ TemplateContext templateContext = new TemplateContext(templateKey, isPreview, publishPipeCode);
// init template global variables
TemplateUtils.initGlobalVariables(site, templateContext);
templateContext.getVariables().put(TemplateUtils.TemplateVariable_PageWidget, pageWidget);
@@ -508,7 +507,7 @@ public class PublishServiceImpl implements IPublishService, ApplicationContextAw
templateType.initTemplateData(site.getSiteId(), templateContext);
// staticize
this.staticizeService.process(templateContext, writer);
- logger.debug("[{}]页面部件【{}#{}】模板解析耗时:{}ms", pageWidget.getPublishPipeCode(), pageWidget.getName(),
+ logger.debug("[{}]页面部件【{}#{}】模板解析耗时:{}ms", publishPipeCode, pageWidget.getName(),
pageWidget.getCode(), System.currentTimeMillis() - s);
return writer.toString();
}
@@ -516,23 +515,35 @@ public class PublishServiceImpl implements IPublishService, ApplicationContextAw
@Override
public void pageWidgetStaticize(IPageWidget pageWidget) {
- long s = System.currentTimeMillis();
CmsPageWidget pw = pageWidget.getPageWidgetEntity();
- CmsSite site = this.siteService.getSite(pw.getSiteId());
- File templateFile = this.templateService.findTemplateFile(site, pw.getTemplate(), pw.getPublishPipeCode());
- if (Objects.isNull(templateFile)) {
- logger.warn(StringUtils.messageFormat("页面部件【{0}%s#{1}%s】模板未配置或文件不存在", pw.getName(), pw.getCode()));
+ if (StringUtils.isEmpty(pw.getTemplates())) {
+ logger.warn("页面部件【{}#{}】未配置模板", pw.getName(), pw.getCode());
return;
}
+ CmsSite site = this.siteService.getSite(pw.getSiteId());
+ List allPublishPipes = this.publishPipeService.getAllPublishPipes(pw.getSiteId());
+ for (CmsPublishPipe publishPipe : allPublishPipes) {
+ String template = pw.getTemplate(publishPipe.getCode());
+ File templateFile = this.templateService.findTemplateFile(site, template, publishPipe.getCode());
+ if (Objects.nonNull(templateFile)) {
+ pageWidgetStaticize0(site, pw, publishPipe.getCode(), template);
+ } else {
+ logger.warn("页面部件【{}#{}】模板未配置或文件不存在", pw.getName(), pw.getCode());
+ }
+ }
+ }
+
+ private void pageWidgetStaticize0(CmsSite site, CmsPageWidget pw, String publishPipeCode, String template) {
+ long s = System.currentTimeMillis();
try {
// 静态化目录
- String dirPath = SiteUtils.getSiteRoot(site, pw.getPublishPipeCode()) + pw.getPath();
+ String dirPath = SiteUtils.getSiteRoot(site, publishPipeCode) + pw.getPath();
FileExUtils.mkdirs(dirPath);
// 自定义模板上下文
- String templateKey = SiteUtils.getTemplateKey(site, pw.getPublishPipeCode(), pw.getTemplate());
- TemplateContext templateContext = new TemplateContext(templateKey, false, pw.getPublishPipeCode());
+ String templateKey = SiteUtils.getTemplateKey(site, publishPipeCode, template);
+ TemplateContext templateContext = new TemplateContext(templateKey, false, publishPipeCode);
templateContext.setDirectory(dirPath);
- String staticFileName = PageWidgetUtils.getStaticFileName(pw, site.getStaticSuffix(pw.getPublishPipeCode()));
+ String staticFileName = PageWidgetUtils.getStaticFileName(pw, site.getStaticSuffix(publishPipeCode));
templateContext.setFirstFileName(staticFileName);
// init template datamode
TemplateUtils.initGlobalVariables(site, templateContext);
@@ -542,10 +553,10 @@ public class PublishServiceImpl implements IPublishService, ApplicationContextAw
templateType.initTemplateData(site.getSiteId(), templateContext);
// staticize
this.staticizeService.process(templateContext);
- logger.debug("[{}]页面部件模板解析:{},耗时:{}ms", pw.getPublishPipeCode(), pw.getCode(), System.currentTimeMillis() - s);
+ logger.debug("[{}]页面部件模板解析:{},耗时:{}ms", publishPipeCode, pw.getCode(), System.currentTimeMillis() - s);
} catch (TemplateException | IOException e) {
logger.error(AsyncTaskManager.addErrMessage(StringUtils.messageFormat("[{0}]页面部件模板解析失败:{1}#{2}",
- pw.getPublishPipeCode(), pw.getName(), pw.getCode())), e);
+ publishPipeCode, pw.getName(), pw.getCode())), e);
}
}
diff --git a/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/service/impl/ResourceServiceImpl.java b/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/service/impl/ResourceServiceImpl.java
index 7e899562..09d79c28 100644
--- a/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/service/impl/ResourceServiceImpl.java
+++ b/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/service/impl/ResourceServiceImpl.java
@@ -18,15 +18,15 @@ package com.chestnut.contentcore.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.chestnut.common.async.AsyncTaskManager;
import com.chestnut.common.exception.CommonErrorCode;
+import com.chestnut.common.storage.FileStorageService;
import com.chestnut.common.storage.IFileStorageType;
-import com.chestnut.common.storage.StorageReadArgs;
-import com.chestnut.common.storage.StorageReadArgs.StorageReadArgsBuilder;
-import com.chestnut.common.storage.exception.StorageErrorCode;
import com.chestnut.common.utils.*;
import com.chestnut.common.utils.file.FileExUtils;
+import com.chestnut.common.utils.image.ImageHelper;
import com.chestnut.common.utils.image.ImageUtils;
import com.chestnut.contentcore.core.IResourceStat;
import com.chestnut.contentcore.core.IResourceType;
+import com.chestnut.contentcore.core.InternalURL;
import com.chestnut.contentcore.core.impl.InternalDataType_Resource;
import com.chestnut.contentcore.core.impl.ResourceType_Image;
import com.chestnut.contentcore.domain.CmsResource;
@@ -34,32 +34,35 @@ import com.chestnut.contentcore.domain.CmsSite;
import com.chestnut.contentcore.domain.dto.ResourceUploadDTO;
import com.chestnut.contentcore.exception.ContentCoreErrorCode;
import com.chestnut.contentcore.mapper.CmsResourceMapper;
-import com.chestnut.contentcore.properties.FileStorageArgsProperty;
-import com.chestnut.contentcore.properties.FileStorageArgsProperty.FileStorageArgs;
import com.chestnut.contentcore.properties.FileStorageTypeProperty;
+import com.chestnut.contentcore.properties.ThumbnailHeightProperty;
+import com.chestnut.contentcore.properties.ThumbnailWidthProperty;
import com.chestnut.contentcore.service.IResourceService;
import com.chestnut.contentcore.service.ISiteService;
import com.chestnut.contentcore.util.*;
import com.chestnut.system.fixed.dict.EnableOrDisable;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
+import org.apache.commons.collections4.MapUtils;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.springframework.stereotype.Service;
+import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
+import java.util.function.Consumer;
import java.util.regex.Matcher;
@Service
@RequiredArgsConstructor
public class ResourceServiceImpl extends ServiceImpl implements IResourceService {
- private final Map fileStorageTypes;
+ private final FileStorageService fileStorageService;
private final List resourceStats;
@@ -144,23 +147,42 @@ public class ResourceServiceImpl extends ServiceImpl CommonErrorCode.DATA_NOT_FOUND_BY_ID.exception("resourceId", dto.getResourceId()));
+ String oldResourceType = resource.getResourceType();
+ String oldPath = resource.getPath();
+
resource.setResourceType(resourceType.getId());
resource.setFileName(dto.getFile().getOriginalFilename());
resource.setName(StringUtils.isEmpty(dto.getName()) ? dto.getFile().getOriginalFilename() : dto.getName());
resource.setSuffix(suffix);
-
String fileName = resource.getResourceId() + StringUtils.DOT + suffix;
- String path = StringUtils.substringBeforeLast(resource.getPath(), "/") + fileName;
-
+ String path = StringUtils.substringBeforeLast(resource.getPath(), "/") + "/" + fileName;
resource.setPath(path);
resource.updateBy(dto.getOperator().getUsername());
resource.setRemark(dto.getRemark());
+ // 删除原文件
+ if (!resource.getPath().equals(oldPath)) {
+ String fileStorageType = FileStorageTypeProperty.getValue(dto.getSite().getConfigProps());
+ IFileStorageType fst = fileStorageService.getFileStorageType(fileStorageType);
+ FileStorageHelper fileStorageHelper = FileStorageHelper.of(fst, dto.getSite());
+ deleteResource(oldPath, oldResourceType, fileStorageHelper);
+ }
// 处理资源
this.processResource(resource, resourceType, dto.getSite(), dto.getFile().getBytes());
this.updateById(resource);
return resource;
}
+ private void deleteResource(String path, String resourceType, FileStorageHelper fileStorageHelper) {
+ fileStorageHelper.remove(path);
+ // 删除图片缩略图
+ if (ResourceType_Image.ID.equals(resourceType)) {
+ String fileName = StringUtils.substringAfterLast(path, "/");
+ final String fileNamePrefix = StringUtils.substringBeforeLast(fileName, ".") + "_";
+ path = StringUtils.substringBeforeLast(path, "/") + "/" + fileNamePrefix;
+ fileStorageHelper.removeByPrefix(path);
+ }
+ }
+
@Override
public CmsResource addBase64Image(CmsSite site, String operator, String base64Data) throws IOException {
if (!ImageUtils.isBase64Image(base64Data)) {
@@ -234,17 +256,36 @@ public class ResourceServiceImpl extends ServiceImpl processed = resourceType.process(resource, tempFile);
+ try {
+ // 读取存储配置
+ String fileStorageType = FileStorageTypeProperty.getValue(site.getConfigProps());
+ IFileStorageType fst = fileStorageService.getFileStorageType(fileStorageType);
+ FileStorageHelper fileStorageHelper = FileStorageHelper.of(fst, site);
+ // 写入磁盘/OSS
+ fileStorageHelper.write(resource.getPath(), tempFile);
+ if (!processed.isEmpty()) {
+ String prefix = StringUtils.substringBeforeLast(resource.getPath(), "/") + "/";
+ for (File f : processed) {
+ fileStorageHelper.write(prefix + f.getName(), f);
+ }
+ }
+ // 设置资源参数
+ resource.setStorageType(fileStorageType);
+ resource.setInternalUrl(InternalDataType_Resource.getInternalUrl(resource));
+ // 异步后续处理
+ resourceType.asyncProcess(resource);
+ } finally {
+ // 删除临时文件
+ FileUtils.delete(tempFile);
+ for (File file : processed) {
+ FileUtils.delete(file);
+ }
+ }
}
@Override
@@ -252,26 +293,13 @@ public class ResourceServiceImpl extends ServiceImpl resources = this.listByIds(resourceIds);
if (!resources.isEmpty()) {
CmsSite site = siteService.getSite(resources.get(0).getSiteId());
- String siteRoot = SiteUtils.getSiteResourceRoot(site);
+ String fileStorageType = FileStorageTypeProperty.getValue(site.getConfigProps());
+ IFileStorageType fst = fileStorageService.getFileStorageType(fileStorageType);
+ FileStorageHelper fileStorageHelper = FileStorageHelper.of(fst, site);
resources.forEach(r -> {
- // 删除资源文件
- try {
- File file = new File(siteRoot + r.getPath());
- FileUtils.delete(file);
- final String fileNamePrefix = StringUtils.substringBeforeLast(file.getName(), ".");
- // 删除图片缩略图
- File[] others = file.getParentFile().listFiles(
- (dir, name) -> name.startsWith(fileNamePrefix)
- );
- if (Objects.nonNull(others)) {
- for (File f : others) {
- FileUtils.delete(f);
- }
- }
- } catch (IOException e) {
- log.error("Delete resource file failed: " + r.getPath());
- }
- // 删除数据库记录
+ // 删除文件
+ deleteResource(r.getPath(), r.getResourceType(), fileStorageHelper);
+ // 删除数据库记录
this.removeById(r.getResourceId());
});
}
@@ -287,31 +315,15 @@ public class ResourceServiceImpl extends ServiceImpl StorageErrorCode.UNSUPPORTED_STORAGE_TYPE.exception(type));
- return fileStorageType;
- }
-
/**
* 解析html中的图片标签,如果是远程地址图片则下载到资源库中并将图片标签的src替换为资源内部链接
*
@@ -359,13 +371,83 @@ public class ResourceServiceImpl extends ServiceImpl internalUrls, Consumer> consumer) {
+ if (internalUrls.isEmpty()) {
+ return;
+ }
+ int w = ThumbnailWidthProperty.getValue(site.getConfigProps());
+ int h = ThumbnailHeightProperty.getValue(site.getConfigProps());
+ if (w > 0 && h > 0) {
+ List thumbnails = dealThumbnails(internalUrls, w, h);
+ consumer.accept(thumbnails);
+ }
+ }
+
+ @Override
+ public void dealDefaultThumbnail(CmsSite site, String internalUrl, Consumer consumer) {
+ if (StringUtils.isEmpty(internalUrl)) {
+ return;
+ }
+ dealDefaultThumbnail(site, List.of(internalUrl), thumbnails -> consumer.accept(thumbnails.get(0)));
+ }
+
+ private List dealThumbnails(List internalUrls, int w, int h) {
+ return internalUrls.stream().map(iurl -> {
+ try {
+ InternalURL internalURL = InternalUrlUtils.parseInternalUrl(iurl);
+ if (Objects.nonNull(internalURL)) {
+ // 先检查是否存在缩略图,如果不存在需要生成
+ createThumbnailIfNotExists(internalURL, w, h);
+ // 返回缩略图路径
+ return ImageUtils.getThumbnailFileName(InternalUrlUtils.getActualPreviewUrl(internalURL), w, h);
+ }
+ // 非内部链接返回原路径
+ return iurl;
+ } catch (Exception e) {
+ log.error("Generate thumbnail fail: " + iurl, e);
+ return iurl;
+ }
+ }).toList();
+ }
+
/**
* 统计资源引用
*/
public void statResourceUsage(Long siteId) throws InterruptedException {
Map quotedResources = new HashMap<>();
for (IResourceStat resourceStat : this.resourceStats) {
- resourceStat.statQuotedResource(siteId, quotedResources);
+ resourceStat.statQuotedResource(siteId, quotedResources);
}
}
}
diff --git a/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/service/impl/SiteServiceImpl.java b/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/service/impl/SiteServiceImpl.java
index f17fa9c4..769a9875 100644
--- a/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/service/impl/SiteServiceImpl.java
+++ b/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/service/impl/SiteServiceImpl.java
@@ -19,6 +19,8 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.chestnut.common.async.AsyncTaskManager;
import com.chestnut.common.exception.CommonErrorCode;
import com.chestnut.common.security.domain.LoginUser;
+import com.chestnut.common.storage.FileStorageService;
+import com.chestnut.common.storage.IFileStorageType;
import com.chestnut.common.utils.*;
import com.chestnut.common.utils.file.FileExUtils;
import com.chestnut.contentcore.ContentCoreConsts;
@@ -27,7 +29,7 @@ import com.chestnut.contentcore.config.CMSConfig;
import com.chestnut.contentcore.core.IProperty;
import com.chestnut.contentcore.core.IPublishPipeProp;
import com.chestnut.contentcore.domain.CmsSite;
-import com.chestnut.contentcore.domain.dto.PublishPipeProp;
+import com.chestnut.contentcore.domain.pojo.PublishPipeProps;
import com.chestnut.contentcore.domain.dto.SiteDTO;
import com.chestnut.contentcore.domain.dto.SiteDefaultTemplateDTO;
import com.chestnut.contentcore.exception.ContentCoreErrorCode;
@@ -39,9 +41,11 @@ import com.chestnut.contentcore.mapper.CmsSiteMapper;
import com.chestnut.contentcore.perms.SitePermissionType;
import com.chestnut.contentcore.perms.SitePermissionType.SitePrivItem;
import com.chestnut.contentcore.properties.EnableSiteDeleteBackupProperty;
+import com.chestnut.contentcore.properties.FileStorageTypeProperty;
import com.chestnut.contentcore.service.ISiteService;
import com.chestnut.contentcore.util.CmsPrivUtils;
import com.chestnut.contentcore.util.ConfigPropertyUtils;
+import com.chestnut.contentcore.util.FileStorageHelper;
import com.chestnut.contentcore.util.SiteUtils;
import com.chestnut.system.security.StpAdminUtil;
import com.chestnut.system.service.ISysPermissionService;
@@ -77,6 +81,10 @@ public class SiteServiceImpl extends ServiceImpl impleme
private final SiteMonitoredCache siteCache;
+ private final FileStorageService fileStorageService;
+
+ private final AsyncTaskManager asyncTaskManager;
+
@Override
public CmsSite getSite(Long siteId) {
CmsSite site = siteCache.getCache(siteId, () -> this.getById(siteId));
@@ -165,7 +173,7 @@ public class SiteServiceImpl extends ServiceImpl impleme
prop.getProps().entrySet().removeIf(e -> !publishPipeProps.containsKey(IPublishPipeProp.BEAN_PREFIX + e.getKey()));
});
Map> publishPipeProps = dto.getPublishPipeDatas().stream()
- .collect(Collectors.toMap(PublishPipeProp::getPipeCode, PublishPipeProp::getProps));
+ .collect(Collectors.toMap(PublishPipeProps::getPipeCode, PublishPipeProps::getProps));
site.setPublishPipeProps(publishPipeProps);
site.updateBy(dto.getOperator().getUsername());
this.updateById(site);
@@ -226,8 +234,8 @@ public class SiteServiceImpl extends ServiceImpl impleme
@Override
public void saveSiteDefaultTemplate(SiteDefaultTemplateDTO dto) {
CmsSite site = this.getSite(dto.getSiteId());
- List publishPipeProps = dto.getPublishPipeProps();
- for (PublishPipeProp ppp : publishPipeProps) {
+ List publishPipeProps = dto.getPublishPipeProps();
+ for (PublishPipeProps ppp : publishPipeProps) {
Map sitePublishPipeProps = site.getPublishPipeProps(ppp.getPipeCode());
sitePublishPipeProps.putAll(ppp.getProps());
}
@@ -245,6 +253,13 @@ public class SiteServiceImpl extends ServiceImpl impleme
site.updateBy(operator);
this.updateById(site);
this.clearCache(site.getSiteId());
+ // 重新加载StorageClient
+ asyncTaskManager.execute(() -> {
+ String fileStorageType = FileStorageTypeProperty.getValue(site.getConfigProps());
+ IFileStorageType fst = fileStorageService.getFileStorageType(fileStorageType);
+ FileStorageHelper fileStorageHelper = FileStorageHelper.of(fst, site);
+ fileStorageHelper.reloadClient();
+ });
}
@Override
diff --git a/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/service/impl/SiteThemeService.java b/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/service/impl/SiteThemeService.java
index fa454b4b..5aae2024 100644
--- a/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/service/impl/SiteThemeService.java
+++ b/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/service/impl/SiteThemeService.java
@@ -308,6 +308,9 @@ public class SiteThemeService {
} finally {
FileUtils.deleteDirectory(new File(destDir));
this.setProgressInfo(100, "导入完成");
+ if (log.isDebugEnabled() && StringUtils.isNotEmpty(this.getErrMessages())) {
+ this.getErrMessages().forEach(log::debug);
+ }
}
}
};
diff --git a/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/template/func/FileExtractorFunction.java b/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/template/func/FileExtractorFunction.java
index c5035a92..6bced778 100644
--- a/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/template/func/FileExtractorFunction.java
+++ b/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/template/func/FileExtractorFunction.java
@@ -65,7 +65,7 @@ public class FileExtractorFunction extends AbstractFunc {
@Override
public Object exec0(Object... args) throws TemplateModelException {
if (args.length < 1) {
- return StringUtils.EMPTY;
+ return List.of();
}
List suffixArray = List.of();
if (args.length == 2 && Objects.nonNull(args[1])) {
diff --git a/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/template/func/ImageSizeFunction.java b/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/template/func/ImageSizeFunction.java
index 60520617..23bd8793 100644
--- a/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/template/func/ImageSizeFunction.java
+++ b/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/template/func/ImageSizeFunction.java
@@ -18,14 +18,10 @@ package com.chestnut.contentcore.template.func;
import com.chestnut.common.staticize.FreeMarkerUtils;
import com.chestnut.common.staticize.core.TemplateContext;
import com.chestnut.common.staticize.func.AbstractFunc;
-import com.chestnut.common.storage.local.LocalFileStorageType;
import com.chestnut.common.utils.ObjectUtils;
import com.chestnut.common.utils.StringUtils;
-import com.chestnut.common.utils.file.FileExUtils;
-import com.chestnut.common.utils.image.ImageHelper;
import com.chestnut.contentcore.core.InternalURL;
import com.chestnut.contentcore.core.impl.InternalDataType_Resource;
-import com.chestnut.contentcore.domain.CmsResource;
import com.chestnut.contentcore.service.IResourceService;
import com.chestnut.contentcore.service.ISiteService;
import com.chestnut.contentcore.util.InternalUrlUtils;
@@ -33,15 +29,11 @@ import com.chestnut.contentcore.util.SiteUtils;
import freemarker.core.Environment;
import freemarker.template.SimpleNumber;
import freemarker.template.SimpleScalar;
-import freemarker.template.TemplateBooleanModel;
import freemarker.template.TemplateModelException;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
@@ -67,8 +59,6 @@ public class ImageSizeFunction extends AbstractFunc {
private static final String ARG3_NAME = "{FREEMARKER.FUNC." + FUNC_NAME + ".Arg3.Name}";
- private static final String ARG4_NAME = "{FREEMARKER.FUNC." + FUNC_NAME + ".Arg4.Name}";
-
private final ISiteService siteService;
private final IResourceService resourceService;
@@ -97,48 +87,27 @@ public class ImageSizeFunction extends AbstractFunc {
if (!InternalUrlUtils.isInternalUrl(iurl)) {
return iurl; // 非内部链接直接返回
}
- boolean crop = false; // 是否在缩放后进行居中裁剪,默认:false
- if (args.length == 4) {
- crop = ((TemplateBooleanModel) args[3]).getAsBoolean();
- }
TemplateContext context = FreeMarkerUtils.getTemplateContext(Environment.getCurrentEnvironment());
InternalURL internalUrl = InternalUrlUtils.parseInternalUrl(iurl);
if (Objects.isNull(internalUrl) || !InternalDataType_Resource.ID.equals(internalUrl.getType())) {
return iurl;
}
- String actualUrl = InternalUrlUtils.getActualUrl(internalUrl, context.getPublishPipeCode(),
- context.isPreview());
+ String originalUrl = InternalUrlUtils.getActualUrl(internalUrl, context.getPublishPipeCode(), context.isPreview());
String siteResourceRoot = SiteUtils.getSiteResourceRoot(siteService.getSite(Long.valueOf(internalUrl.getParams().get("sid"))));
String destPath = StringUtils.substringBeforeLast(internalUrl.getPath(), ".") + "_" + width + "x" + height
+ "." + StringUtils.substringAfterLast(internalUrl.getPath(), ".");
+ String thumbnailUrl = StringUtils.substringBeforeLast(originalUrl, ".") + "_" + width + "x" + height + "."
+ + StringUtils.substringAfterLast(originalUrl, ".");
if (Files.exists(Path.of(siteResourceRoot + destPath))) {
- return StringUtils.substringBeforeLast(actualUrl, ".") + "_" + width + "x" + height + "."
- + StringUtils.substringAfterLast(actualUrl, ".");
+ return thumbnailUrl;
}
try {
- CmsResource resource = this.resourceService.getById(internalUrl.getId());
- if (Objects.nonNull(resource) && LocalFileStorageType.TYPE.equals(resource.getStorageType())) {
- if (crop) {
- String ext = FileExUtils.getExtension(resource.getPath());
- File file = new File(siteResourceRoot + resource.getPath());
- try (ByteArrayOutputStream os = new ByteArrayOutputStream()) {
- try (FileInputStream is = new FileInputStream(file)) {
- ImageHelper.of(is).format(ext).centerCropAndResize(width, height).to(os);
- }
- Files.write(file.toPath(), os.toByteArray());
- }
- } else {
- ImageHelper.of(new File(siteResourceRoot + resource.getPath()))
- .resize(width, height)
- .toFile(new File(siteResourceRoot + destPath));
- }
- actualUrl = StringUtils.substringBeforeLast(actualUrl, ".") + "_" + width + "x" + height + "."
- + StringUtils.substringAfterLast(actualUrl, ".");
- }
+ resourceService.createThumbnailIfNotExists(internalUrl, width, height);
+ return thumbnailUrl;
} catch (Exception e) {
- log.warn("Generate thumbnail failed: " + actualUrl, e);
+ log.warn("Generate thumbnail failed: " + originalUrl, e);
}
- return actualUrl;
+ return originalUrl;
}
@Override
@@ -146,8 +115,7 @@ public class ImageSizeFunction extends AbstractFunc {
return List.of(
new FuncArg(ARG1_NAME, FuncArgType.String, true, ARG1_DESC),
new FuncArg(ARG2_NAME, FuncArgType.Int, true),
- new FuncArg(ARG3_NAME, FuncArgType.Int, true),
- new FuncArg(ARG4_NAME, FuncArgType.Boolean, false)
+ new FuncArg(ARG3_NAME, FuncArgType.Int, true)
);
}
}
diff --git a/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/template/tag/CmsPageWidgetTag.java b/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/template/tag/CmsPageWidgetTag.java
index 2823cb97..891231f4 100644
--- a/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/template/tag/CmsPageWidgetTag.java
+++ b/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/template/tag/CmsPageWidgetTag.java
@@ -111,17 +111,18 @@ public class CmsPageWidgetTag extends AbstractTag {
if (!PageWidgetStatus.PUBLISHED.equals(pw.getState())) {
return null;
}
+ String template = pw.getTemplate(context.getPublishPipeCode());
CmsSite site = this.siteService.getSite(siteId);
- File templateFile = this.templateService.findTemplateFile(site, pw.getTemplate(), context.getPublishPipeCode());
- Assert.notNull(templateFile, () -> new IncludeTemplateNotFoundException(pw.getTemplate(), env));
+ File templateFile = this.templateService.findTemplateFile(site, template, context.getPublishPipeCode());
+ Assert.notNull(templateFile, () -> new IncludeTemplateNotFoundException(template, env));
boolean ssi = MapUtils.getBoolean(attrs, ATTR_SSI, EnableSSIProperty.getValue(site.getConfigProps()));
- String templateKey = SiteUtils.getTemplateKey(site, pw.getPublishPipeCode(), pw.getTemplate());
+ String templateKey = SiteUtils.getTemplateKey(site, context.getPublishPipeCode(), template);
if (context.isPreview()) {
env.getOut().write(this.processTemplate(env, pw, templateKey));
} else {
String siteRoot = SiteUtils.getSiteRoot(site, context.getPublishPipeCode());
- String staticFileName = PageWidgetUtils.getStaticFileName(pw, site.getStaticSuffix(pw.getPublishPipeCode()));
+ String staticFileName = PageWidgetUtils.getStaticFileName(pw, site.getStaticSuffix(context.getPublishPipeCode()));
String staticFilePath = pw.getPath() + staticFileName;
if (ssi) {
// 读取页面部件静态化内容
diff --git a/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/util/ConfigPropertyUtils.java b/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/util/ConfigPropertyUtils.java
index 9de78af2..5bd35dfc 100644
--- a/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/util/ConfigPropertyUtils.java
+++ b/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/util/ConfigPropertyUtils.java
@@ -15,21 +15,17 @@
*/
package com.chestnut.contentcore.util;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.stream.Collectors;
-
-import org.apache.commons.collections4.MapUtils;
-
import com.chestnut.common.utils.NumberUtils;
import com.chestnut.common.utils.SpringUtils;
import com.chestnut.common.utils.StringUtils;
import com.chestnut.contentcore.core.IProperty;
import com.chestnut.contentcore.core.IProperty.UseType;
import com.chestnut.contentcore.exception.ContentCoreErrorCode;
+import org.apache.commons.collections4.MapUtils;
+
+import java.util.*;
+import java.util.Map.Entry;
+import java.util.stream.Collectors;
public class ConfigPropertyUtils {
@@ -120,9 +116,28 @@ public class ConfigPropertyUtils {
String v = null;
if (prop != null) {
v = MapUtils.getString(firstProps, prop.getId());
- if (StringUtils.isEmpty(v)) {
+ if (Objects.isNull(v) && Objects.nonNull(secondProps)) {
v = MapUtils.getString(secondProps, prop.getId());
}
+ if (Objects.isNull(v)) {
+ v = prop.defaultValue().toString();
+ }
+ }
+ return v;
+ }
+
+ public static Object getValue(String propertyKey, Map firstProps,
+ Map secondProps) {
+ IProperty prop = getConfigProperty(propertyKey);
+ Object v = null;
+ if (prop != null) {
+ v = MapUtils.getObject(firstProps, prop.getId());
+ if (Objects.isNull(v) && Objects.nonNull(secondProps)) {
+ v = MapUtils.getObject(secondProps, prop.getId());
+ }
+ if (Objects.isNull(v)) {
+ v = prop.defaultValue();
+ }
}
return v;
}
@@ -151,12 +166,20 @@ public class ConfigPropertyUtils {
int intV = 0;
if (prop != null) {
String v = MapUtils.getString(firstProps, prop.getId());
+ if (Objects.isNull(v) && Objects.nonNull(secondProps)) {
+ v = MapUtils.getString(secondProps, prop.getId());
+ }
if (NumberUtils.isCreatable(v)) {
intV = NumberUtils.toInt(v);
} else {
- v = MapUtils.getString(secondProps, prop.getId());
- if (NumberUtils.isCreatable(v)) {
- intV = NumberUtils.toInt(v);
+ Object defaultV = prop.defaultValue();
+ if (defaultV instanceof Integer defaultIntV) {
+ intV = defaultIntV;
+ } else {
+ v = defaultV.toString();
+ if (NumberUtils.isCreatable(v)) {
+ intV = NumberUtils.toInt(v);
+ }
}
}
}
diff --git a/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/util/FileStorageHelper.java b/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/util/FileStorageHelper.java
index c5a00641..43baa303 100644
--- a/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/util/FileStorageHelper.java
+++ b/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/util/FileStorageHelper.java
@@ -15,19 +15,16 @@
*/
package com.chestnut.contentcore.util;
-import com.chestnut.common.storage.IFileStorageType;
-import com.chestnut.common.storage.StorageListArgs;
-import com.chestnut.common.storage.StorageReadArgs;
-import com.chestnut.common.storage.StorageWriteArgs;
+import com.chestnut.common.exception.CommonErrorCode;
+import com.chestnut.common.storage.*;
import com.chestnut.common.storage.local.LocalFileStorageType;
+import com.chestnut.common.utils.StringUtils;
import com.chestnut.contentcore.domain.CmsSite;
import com.chestnut.contentcore.properties.FileStorageArgsProperty;
import com.chestnut.contentcore.properties.FileStorageTypeProperty;
import lombok.Getter;
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
+import java.io.*;
import java.util.List;
/**
@@ -48,6 +45,8 @@ public class FileStorageHelper {
private String endpoint;
+ private String region;
+
private String pipeline;
@Getter
@@ -66,36 +65,87 @@ public class FileStorageHelper {
helper.accessSecret = args.getAccessSecret();
helper.bucket = args.getBucket();
helper.endpoint = args.getEndpoint();
+ helper.region = args.getRegion();
helper.pipeline = args.getPipeline();
helper.domain = args.getDomain();
+ helper.validate();
return helper;
}
+ private void validate() {
+ if (LocalFileStorageType.TYPE.equals(this.fileStorage.getType())) {
+ return; // 本地存储不需要校验
+ }
+ if (StringUtils.isEmpty(this.accessKey)) {
+ throw CommonErrorCode.NOT_EMPTY.exception("fileStorage.accessKey");
+ }
+ if (StringUtils.isEmpty(this.accessSecret)) {
+ throw CommonErrorCode.NOT_EMPTY.exception("fileStorage.accessSecret");
+ }
+ if (StringUtils.isEmpty(this.endpoint)) {
+ throw CommonErrorCode.NOT_EMPTY.exception("fileStorage.endpoint");
+ }
+ if (StringUtils.isEmpty(this.region)) {
+ throw CommonErrorCode.NOT_EMPTY.exception("fileStorage.region");
+ }
+ if (StringUtils.isEmpty(this.bucket)) {
+ throw CommonErrorCode.NOT_EMPTY.exception("fileStorage.bucket");
+ }
+ if (StringUtils.isEmpty(this.domain)) {
+ throw CommonErrorCode.NOT_EMPTY.exception("fileStorage.domain");
+ }
+ }
+
+ public void reloadClient() {
+ fileStorage.reloadClient(this.endpoint, this.region, this.accessKey, this.accessSecret);
+ }
+
+ public boolean exists(String thumbnailPath) {
+ StorageExistArgs args = StorageExistArgs.builder()
+ .accessKey(this.accessKey)
+ .accessSecret(this.accessSecret)
+ .bucket(this.bucket)
+ .endpoint(this.endpoint)
+ .region(this.region)
+ .path(thumbnailPath)
+ .build();
+ return fileStorage.exists(args);
+ }
+
public InputStream read(String path) {
StorageReadArgs storageReadArgs = StorageReadArgs.builder()
.accessKey(this.accessKey)
.accessSecret(this.accessSecret)
.bucket(this.bucket)
.endpoint(this.endpoint)
+ .region(this.region)
.path(path)
.build();
return fileStorage.read(storageReadArgs);
}
- public void write(String path, byte[] bytes) throws IOException {
- try (ByteArrayInputStream is = new ByteArrayInputStream(bytes)) {
- write(path, is);
+ public void write(String path, File file) throws IOException {
+ try (FileInputStream is = new FileInputStream(file)) {
+ write(path, is, file.length());
}
}
- public void write(String path, InputStream is) {
+ public void write(String path, byte[] bytes) throws IOException {
+ try (ByteArrayInputStream is = new ByteArrayInputStream(bytes)) {
+ write(path, is, bytes.length);
+ }
+ }
+
+ public void write(String path, InputStream is, long length) {
StorageWriteArgs args = StorageWriteArgs.builder()
.accessKey(this.accessKey)
.accessSecret(this.accessSecret)
.bucket(this.bucket)
.endpoint(this.endpoint)
+ .region(this.region)
.path(path)
.inputStream(is)
+ .length(length)
.build();
this.fileStorage.write(args);
}
@@ -110,9 +160,46 @@ public class FileStorageHelper {
.accessSecret(this.accessSecret)
.bucket(this.bucket)
.endpoint(this.endpoint)
+ .region(this.region)
.prefix(prefix)
.maxKeys(count)
.build();
return this.fileStorage.list(storageListArgs);
}
+
+ public void remove(String path) {
+ StorageRemoveArgs args = StorageRemoveArgs.builder()
+ .accessKey(this.accessKey)
+ .accessSecret(this.accessSecret)
+ .bucket(this.bucket)
+ .endpoint(this.endpoint)
+ .region(this.region)
+ .path(path)
+ .build();
+ this.fileStorage.remove(args);
+ }
+
+ public void removeByPrefix(String prefix) {
+ StorageListArgs storageListArgs = StorageListArgs.builder()
+ .accessKey(this.accessKey)
+ .accessSecret(this.accessSecret)
+ .bucket(this.bucket)
+ .endpoint(this.endpoint)
+ .region(this.region)
+ .prefix(prefix)
+ .maxKeys(100)
+ .build();
+ List list = this.fileStorage.list(storageListArgs);
+ for (String path : list) {
+ StorageRemoveArgs args = StorageRemoveArgs.builder()
+ .accessKey(this.accessKey)
+ .accessSecret(this.accessSecret)
+ .bucket(this.bucket)
+ .endpoint(this.endpoint)
+ .region(this.region)
+ .path(path)
+ .build();
+ this.fileStorage.remove(args);
+ }
+ }
}
diff --git a/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/util/InternalUrlUtils.java b/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/util/InternalUrlUtils.java
index 3a0d4572..dd64ed32 100644
--- a/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/util/InternalUrlUtils.java
+++ b/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/util/InternalUrlUtils.java
@@ -94,6 +94,10 @@ public class InternalUrlUtils {
return getActualUrl(iurl, null, true);
}
+ public static String getActualPreviewUrl(InternalURL internalURL) {
+ return getActualUrl(internalURL, null, true);
+ }
+
/**
* 判断是否是内部资源URL
*/
diff --git a/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/util/TemplateUtils.java b/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/util/TemplateUtils.java
index 7e56e730..433a56d6 100644
--- a/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/util/TemplateUtils.java
+++ b/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/util/TemplateUtils.java
@@ -17,6 +17,7 @@ package com.chestnut.contentcore.util;
import cn.dev33.satoken.config.SaTokenConfig;
import com.chestnut.common.staticize.FreeMarkerUtils;
+import com.chestnut.common.staticize.StaticizeConstants;
import com.chestnut.common.staticize.core.TemplateContext;
import com.chestnut.common.utils.ReflectASMUtils;
import com.chestnut.common.utils.StringUtils;
@@ -44,7 +45,7 @@ public class TemplateUtils {
/**
* 模板变量:请求参数
*/
- public final static String TemplateVariable_Request = "Request";
+ public final static String TemplateVariable_Request = StaticizeConstants.TemplateVariable_Request;
/**
* 模板变量:<@cms_include>标签file属性请求参数,下个大版本移除
@@ -252,33 +253,6 @@ public class TemplateUtils {
}
}
- public static String appendTokenParameter(String url, Environment env) throws TemplateModelException {
- if (StringUtils.isEmpty(url)) {
- return url;
- }
- String tokenName = FreeMarkerUtils.getStringVariable(env, TemplateUtils.TemplateVariable_TokenName);
- String token = FreeMarkerUtils.getStringVariable(env, TemplateUtils.TemplateVariable_Token);
- if (url.contains("?")) {
- return url + "&" + tokenName + "=" + token;
- }
- return url + "?" + token + "=" + token;
- }
-
- public static String appendTokenParameter(String url) {
- if (StringUtils.isEmpty(url)) {
- return url;
- }
- SaTokenConfig config = StpAdminUtil.getStpLogic().getConfigOrGlobal();
- String token = StpAdminUtil.getTokenValue();
- if (StringUtils.isNotEmpty(config.getTokenPrefix())) {
- token = config.getTokenPrefix() + " " + token;
- }
- if (url.contains("?")) {
- return url + "&" + config.getTokenName() + "=" + token;
- }
- return url + "?" + config.getTokenName() + "=" + token;
- }
-
/**
* 页面区块静态文件相对路径
@@ -293,4 +267,36 @@ public class TemplateUtils {
includeTemplateName.length() - TemplateSuffix.getValue().length())
+ "." + site.getStaticSuffix(publishPipeCode);
}
+
+ public static String appendParam(String path, String name, String value) {
+ if (path.contains("?")) {
+ return path + "&" + name + "=" + value;
+ }
+ return path + "?" + name + "=" + value;
+ }
+
+ public static String appendPageIndexParam(String path, String pageIndex) {
+ return appendParam(path, StaticizeConstants.TemplateParam_PageIndex, pageIndex);
+ }
+
+ public static String appendTokenParameter(String url, Environment env) throws TemplateModelException {
+ if (StringUtils.isEmpty(url)) {
+ return url;
+ }
+ String tokenName = FreeMarkerUtils.getStringVariable(env, TemplateUtils.TemplateVariable_TokenName);
+ String token = FreeMarkerUtils.getStringVariable(env, TemplateUtils.TemplateVariable_Token);
+ return appendParam(url, tokenName, token);
+ }
+
+ public static String appendTokenParameter(String url) {
+ if (StringUtils.isEmpty(url)) {
+ return url;
+ }
+ SaTokenConfig config = StpAdminUtil.getStpLogic().getConfigOrGlobal();
+ String token = StpAdminUtil.getTokenValue();
+ if (StringUtils.isNotEmpty(config.getTokenPrefix())) {
+ token = config.getTokenPrefix() + " " + token;
+ }
+ return appendParam(url, config.getTokenName(), token);
+ }
}
diff --git a/chestnut-cms/chestnut-cms-contentcore/src/main/resources/i18n/messages.properties b/chestnut-cms/chestnut-cms-contentcore/src/main/resources/i18n/messages.properties
index 832655e8..9a6e30bb 100644
--- a/chestnut-cms/chestnut-cms-contentcore/src/main/resources/i18n/messages.properties
+++ b/chestnut-cms/chestnut-cms-contentcore/src/main/resources/i18n/messages.properties
@@ -88,6 +88,7 @@ ERRCODE.CMS.CONTENTCORE.RESOURCE_ACCEPT_SIZE_LIMIT=上传文件大小超过限
ERRCODE.CMS.CONTENTCORE.UNSUPPORTED_RESOURCE_STORAGE=资源存储方式与当前站点配置不一致
ERRCODE.CMS.CONTENTCORE.MERGE_CATALOG_IS_EMPTY=被合并栏目不存在
ERRCODE.CMS.CONTENTCORE.MERGE_CATALOG_NOT_LEAF=被合并栏目不能包含子栏目
+ERRCODE.CMS.CONTENTCORE.DENY_LINK_TO_LINK_INTERNAL_DATA=不能链接到链接内容或栏目
# freemarker模板标签
FREEMARKER.TAG.cms_site.NAME=站点列表标签
@@ -161,9 +162,8 @@ FREEMARKER.FUNC.imageSize.Arg1.Name=图片资源内部路径(iurl://)
FREEMARKER.FUNC.imageSize.Arg1.Desc=仅支持处理内部资源图片(iurl://)
FREEMARKER.FUNC.imageSize.Arg2.Name=宽度
FREEMARKER.FUNC.imageSize.Arg3.Name=高度
-FREEMARKER.FUNC.imageSize.Arg4.Name=是否居中裁剪
FREEMARKER.FUNC.internalUrl.DESC=将内部链接“iurl://”解析为正常http(s)访问地址,例如:`${internalUrl(content.redirectUrl)}`
-FREEMARKER.FUNC.internalUrl.Arg1.Name=內部鏈接(iurl://)
+FREEMARKER.FUNC.internalUrl.Arg1.Name=内部链接(iurl://)
FREEMARKER.FUNC.siteUrl.DESC=获取站点指定发布通道访问链接,例如:`${siteUrl(Site.siteId, 'h5')}`
FREEMARKER.FUNC.siteUrl.Arg1.Name=站点ID
FREEMARKER.FUNC.siteUrl.Arg2.Name=发布通道编码
@@ -198,6 +198,7 @@ FREEMARKER.FUNC.fileExtractor.Arg2.Name=文件类型/后缀
# 校验规则
VALIDATOR.CMS.SITE.PUBLISH_PIPE_PROPS_EMPTY=发布通道配置不能为空
VALIDATOR.CMS.SITE_PROPERTY.REGEXP_ERR=属性编码只能使用大小写字母、数字和下划线
+VALIDATOR.CMS.FILE_NAME.REGEXP_ERR=文件名不能包含斜杠或反斜杠
# 定时任务
SCHEDULED_TASK.RecycleExpireJobHandler=回收站过期内容删除任务
diff --git a/chestnut-cms/chestnut-cms-contentcore/src/main/resources/i18n/messages_en.properties b/chestnut-cms/chestnut-cms-contentcore/src/main/resources/i18n/messages_en.properties
index ae0fbd7d..6de492c8 100644
--- a/chestnut-cms/chestnut-cms-contentcore/src/main/resources/i18n/messages_en.properties
+++ b/chestnut-cms/chestnut-cms-contentcore/src/main/resources/i18n/messages_en.properties
@@ -88,6 +88,7 @@ ERRCODE.CMS.CONTENTCORE.RESOURCE_ACCEPT_SIZE_LIMIT=Upload file size exceeded.
ERRCODE.CMS.CONTENTCORE.UNSUPPORTED_RESOURCE_STORAGE=The resource storage type is inconsistent with the site configuration.
ERRCODE.CMS.CONTENTCORE.MERGE_CATALOG_IS_EMPTY=Merge catalog not exists.
ERRCODE.CMS.CONTENTCORE.MERGE_CATALOG_NOT_LEAF=Cannot merge catalog which has children.
+ERRCODE.CMS.CONTENTCORE.DENY_LINK_TO_LINK_INTERNAL_DATA=Cannot link to link-catalog or link-content.
# 模板freemarker
FREEMARKER.TAG.cms_site.NAME=Site list tag
@@ -161,7 +162,6 @@ FREEMARKER.FUNC.imageSize.Arg1.Name=Internal image resource link (iurl://)
FREEMARKER.FUNC.imageSize.Arg1.Desc=Only supports internal resource images with prefix "iurl://".
FREEMARKER.FUNC.imageSize.Arg2.Name=Width
FREEMARKER.FUNC.imageSize.Arg3.Name=Height
-FREEMARKER.FUNC.imageSize.Arg4.Name=Center cutting
FREEMARKER.FUNC.internalUrl.DESC=Use `${internalUrl(site.logo)}` in template to parse "iurl://xx" to http(s) link.
FREEMARKER.FUNC.internalUrl.Arg1.Name=Internal resource url(iurl://)
FREEMARKER.FUNC.siteUrl.DESC=Use `${siteUrl(Site.siteId,'h5')}` in template to get the site publishpipe url.
@@ -198,6 +198,7 @@ FREEMARKER.FUNC.fileExtractor.Arg2.Name=File type or suffix
# 校验规则
VALIDATOR.CMS.SITE.PUBLISH_PIPE_PROPS_EMPTY=The site publish pipe props cannot be empty.
VALIDATOR.CMS.SITE_PROPERTY.REGEXP_ERR=The code can only use uppercase/lowercase letters, numbers and underscores.
+VALIDATOR.CMS.FILE_NAME.REGEXP_ERR=The file name cannot contain slashes or backslashes.
# 定时任务
SCHEDULED_TASK.RecycleExpireJobHandler=Recycle Content Expired Task
diff --git a/chestnut-cms/chestnut-cms-contentcore/src/main/resources/i18n/messages_zh_TW.properties b/chestnut-cms/chestnut-cms-contentcore/src/main/resources/i18n/messages_zh_TW.properties
index f2b0b0c8..ecb8c5ae 100644
--- a/chestnut-cms/chestnut-cms-contentcore/src/main/resources/i18n/messages_zh_TW.properties
+++ b/chestnut-cms/chestnut-cms-contentcore/src/main/resources/i18n/messages_zh_TW.properties
@@ -88,6 +88,7 @@ ERRCODE.CMS.CONTENTCORE.RESOURCE_ACCEPT_SIZE_LIMIT=上傳文件大小超過限
ERRCODE.CMS.CONTENTCORE.UNSUPPORTED_RESOURCE_STORAGE=資源存儲方式與當前站點配置不一致
ERRCODE.CMS.CONTENTCORE.MERGE_CATALOG_IS_EMPTY=被合並欄目不存在
ERRCODE.CMS.CONTENTCORE.MERGE_CATALOG_NOT_LEAF=被合並欄目不能包含子欄目
+ERRCODE.CMS.CONTENTCORE.DENY_LINK_TO_LINK_INTERNAL_DATA=不能链接到链接内容或栏目
# freemarker模板標籤
FREEMARKER.TAG.cms_site.NAME=站點列表標籤
@@ -161,7 +162,6 @@ FREEMARKER.FUNC.imageSize.Arg1.Name=圖片資源內部路徑(iurl://)
FREEMARKER.FUNC.imageSize.Arg1.Desc=僅支持處理內部資源圖片(iurl://)
FREEMARKER.FUNC.imageSize.Arg2.Name=寬度
FREEMARKER.FUNC.imageSize.Arg3.Name=高度
-FREEMARKER.FUNC.imageSize.Arg4.Name=是否居中裁剪
FREEMARKER.FUNC.internalUrl.DESC=將內部連結“iurl://”解析為正常http(s)訪問地址,例如:`${internalUrl(content.redirectUrl)}`
FREEMARKER.FUNC.internalUrl.Arg1.Name=內部鏈接(iurl://)
FREEMARKER.FUNC.siteUrl.DESC=獲取站點指定發布通道訪問連結,例如:`${siteUrl(Site.siteId, 'h5')}`
@@ -198,6 +198,7 @@ FREEMARKER.FUNC.fileExtractor.Arg2.Name=文件類型/後綴
# 校驗規則
VALIDATOR.CMS.SITE.PUBLISH_PIPE_PROPS_EMPTY=發布通道配置不能為空
VALIDATOR.CMS.SITE_PROPERTY.REGEXP_ERR=屬性編碼只能使用大小寫字母、數字和下劃線
+VALIDATOR.CMS.FILE_NAME.REGEXP_ERR=文件名不能包含斜杠或反斜杠
# 定時任務
SCHEDULED_TASK.RecycleExpireJobHandler=資源回收筒過期內容刪除任務
diff --git a/chestnut-cms/chestnut-cms-customform/pom.xml b/chestnut-cms/chestnut-cms-customform/pom.xml
index e8a59746..7c954da9 100644
--- a/chestnut-cms/chestnut-cms-customform/pom.xml
+++ b/chestnut-cms/chestnut-cms-customform/pom.xml
@@ -7,7 +7,7 @@
com.chestnut
chestnut-cms
- 1.5.5
+ 1.5.6
chestnut-cms-customform
diff --git a/chestnut-cms/chestnut-cms-customform/src/main/java/com/chestnut/customform/cache/CustomFormCaptchaMonitoredCache.java b/chestnut-cms/chestnut-cms-customform/src/main/java/com/chestnut/customform/cache/CustomFormCaptchaMonitoredCache.java
deleted file mode 100644
index 4ff8d8ca..00000000
--- a/chestnut-cms/chestnut-cms-customform/src/main/java/com/chestnut/customform/cache/CustomFormCaptchaMonitoredCache.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright 2022-2025 兮玥(190785909@qq.com)
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.chestnut.customform.cache;
-
-import com.chestnut.common.redis.IMonitoredCache;
-import com.chestnut.common.redis.RedisCache;
-import com.chestnut.system.SysConstants;
-import lombok.RequiredArgsConstructor;
-import org.springframework.stereotype.Component;
-
-import java.util.concurrent.TimeUnit;
-
-/**
- * CustomFormCaptchaMonitoredCache
- *
- * @author 兮玥
- * @email 190785909@qq.com
- */
-@Component(IMonitoredCache.BEAN_PREFIX + CustomFormCaptchaMonitoredCache.ID)
-@RequiredArgsConstructor
-public class CustomFormCaptchaMonitoredCache implements IMonitoredCache {
-
- public static final String ID = "CustomFormCaptcha";
-
- public static final String CACHE_PREFIX = "cms:customform:captcha:";
-
- private final RedisCache redisCache;
-
- @Override
- public String getId() {
- return ID;
- }
-
- @Override
- public String getCacheName() {
- return "{MONITORED.CACHE.CUSTOM_FORM_CAPTCHA}";
- }
-
- @Override
- public String getCacheKey() {
- return CACHE_PREFIX;
- }
-
- @Override
- public String getCache(String cacheKey) {
- return redisCache.getCacheObject(cacheKey, String.class);
- }
-
- public void deleteCache(String cacheKey) {
- this.redisCache.deleteObject(cacheKey);
- }
-
- public void setCache(String cacheKey, String code, Integer captchaExpiration, TimeUnit timeUnit) {
- this.redisCache.setCacheObject(cacheKey, code, captchaExpiration, timeUnit);
- }
-}
diff --git a/chestnut-cms/chestnut-cms-customform/src/main/java/com/chestnut/customform/controller/CustomFormController.java b/chestnut-cms/chestnut-cms-customform/src/main/java/com/chestnut/customform/controller/CustomFormController.java
index 96ddc68b..00d83ebb 100644
--- a/chestnut-cms/chestnut-cms-customform/src/main/java/com/chestnut/customform/controller/CustomFormController.java
+++ b/chestnut-cms/chestnut-cms-customform/src/main/java/com/chestnut/customform/controller/CustomFormController.java
@@ -27,6 +27,7 @@ import com.chestnut.common.utils.Assert;
import com.chestnut.common.utils.ServletUtils;
import com.chestnut.common.utils.StringUtils;
import com.chestnut.contentcore.domain.CmsSite;
+import com.chestnut.contentcore.domain.pojo.PublishPipeTemplate;
import com.chestnut.contentcore.service.IPublishPipeService;
import com.chestnut.contentcore.service.ISiteService;
import com.chestnut.customform.domain.CmsCustomForm;
@@ -46,7 +47,6 @@ import org.springframework.web.bind.annotation.*;
import java.io.IOException;
import java.util.List;
-import java.util.Map;
/**
*
@@ -96,12 +96,12 @@ public class CustomFormController extends BaseRestController {
Assert.notNull(form, () -> CommonErrorCode.DATA_NOT_FOUND_BY_ID.exception("formId", formId));
CustomFormVO vo = CustomFormVO.from(form);
- List