diff --git a/README.md b/README.md index b727e7c2..b347e5b5 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# ChestnutCMS v1.5.1 +# ChestnutCMS v1.5.2 ### 系统简介 diff --git a/chestnut-admin/pom.xml b/chestnut-admin/pom.xml index 50860ad3..d2871d47 100644 --- a/chestnut-admin/pom.xml +++ b/chestnut-admin/pom.xml @@ -3,7 +3,7 @@ chestnut com.chestnut - 1.5.1 + 1.5.2 4.0.0 jar diff --git a/chestnut-admin/src/main/resources/application-dev.yml b/chestnut-admin/src/main/resources/application-dev.yml index 3ab8ae43..f938a0f0 100644 --- a/chestnut-admin/src/main/resources/application-dev.yml +++ b/chestnut-admin/src/main/resources/application-dev.yml @@ -5,7 +5,7 @@ chestnut: # 代号 alias: ChestnutCMS # 版本 - version: 1.5.1 + version: 1.5.2 # 版权年份 copyrightYear: 2022-2024 system: @@ -19,6 +19,7 @@ chestnut: uploadPath: 'E:/dev/workspace_chestnut/_xy_member/' cms: publish: + strategy: ThreadPool pool: threadNamePrefix: "CMS-PUBLISH-" queueCapacity: 10000 diff --git a/chestnut-admin/src/main/resources/application-prod.yml b/chestnut-admin/src/main/resources/application-prod.yml index 1486dca7..4ed261ab 100644 --- a/chestnut-admin/src/main/resources/application-prod.yml +++ b/chestnut-admin/src/main/resources/application-prod.yml @@ -5,7 +5,7 @@ chestnut: # 代号 alias: ChestnutCMS # 版本 - version: 1.5.1 + version: 1.5.2 # 版权年份 copyrightYear: 2022-2024 system: diff --git a/chestnut-admin/src/main/resources/application-test.yml b/chestnut-admin/src/main/resources/application-test.yml index af6bf6f8..eff1020c 100644 --- a/chestnut-admin/src/main/resources/application-test.yml +++ b/chestnut-admin/src/main/resources/application-test.yml @@ -5,7 +5,7 @@ chestnut: # 代号 alias: ChestnutCMS # 版本 - version: 1.5.1 + version: 1.5.2 # 版权年份 copyrightYear: 2022-2024 system: diff --git a/chestnut-admin/src/main/resources/db/migration/mysql/V1.5.2__update.sql b/chestnut-admin/src/main/resources/db/migration/mysql/V1.5.2__update.sql new file mode 100644 index 00000000..237e7b4f --- /dev/null +++ b/chestnut-admin/src/main/resources/db/migration/mysql/V1.5.2__update.sql @@ -0,0 +1,2 @@ +ALTER TABLE cms_catalog MODIFY COLUMN `path` varchar(255); +ALTER TABLE cms_content MODIFY COLUMN `images` varchar(1000); \ No newline at end of file diff --git a/chestnut-cms/chestnut-cms-advertisement/pom.xml b/chestnut-cms/chestnut-cms-advertisement/pom.xml index 28afb769..d333f5f9 100644 --- a/chestnut-cms/chestnut-cms-advertisement/pom.xml +++ b/chestnut-cms/chestnut-cms-advertisement/pom.xml @@ -7,7 +7,7 @@ com.chestnut chestnut-cms - 1.5.1 + 1.5.2 chestnut-cms-advertisement diff --git a/chestnut-cms/chestnut-cms-article/pom.xml b/chestnut-cms/chestnut-cms-article/pom.xml index 4323a7b2..d8c1f598 100644 --- a/chestnut-cms/chestnut-cms-article/pom.xml +++ b/chestnut-cms/chestnut-cms-article/pom.xml @@ -7,7 +7,7 @@ com.chestnut chestnut-cms - 1.5.1 + 1.5.2 chestnut-cms-article diff --git a/chestnut-cms/chestnut-cms-block/pom.xml b/chestnut-cms/chestnut-cms-block/pom.xml index 6692b137..5d61a483 100644 --- a/chestnut-cms/chestnut-cms-block/pom.xml +++ b/chestnut-cms/chestnut-cms-block/pom.xml @@ -7,7 +7,7 @@ com.chestnut chestnut-cms - 1.5.1 + 1.5.2 chestnut-cms-block diff --git a/chestnut-cms/chestnut-cms-comment/pom.xml b/chestnut-cms/chestnut-cms-comment/pom.xml index b2581412..64bcf8e8 100644 --- a/chestnut-cms/chestnut-cms-comment/pom.xml +++ b/chestnut-cms/chestnut-cms-comment/pom.xml @@ -6,7 +6,7 @@ com.chestnut chestnut-cms - 1.5.1 + 1.5.2 chestnut-cms-comment diff --git a/chestnut-cms/chestnut-cms-contentcore/pom.xml b/chestnut-cms/chestnut-cms-contentcore/pom.xml index 1715543a..549adfab 100644 --- a/chestnut-cms/chestnut-cms-contentcore/pom.xml +++ b/chestnut-cms/chestnut-cms-contentcore/pom.xml @@ -7,7 +7,7 @@ com.chestnut chestnut-cms - 1.5.1 + 1.5.2 chestnut-cms-contentcore diff --git a/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/core/impl/PublishPipeProp_PrefixMode.java b/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/core/impl/PublishPipeProp_PrefixMode.java new file mode 100644 index 00000000..f027e3b8 --- /dev/null +++ b/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/core/impl/PublishPipeProp_PrefixMode.java @@ -0,0 +1,64 @@ +/* + * Copyright 2022-2024 兮玥(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.contentcore.core.impl; + +import com.chestnut.contentcore.core.IPublishPipeProp; +import com.chestnut.contentcore.enums.SitePrefixMode; +import org.apache.commons.collections4.MapUtils; +import org.springframework.stereotype.Component; + +import java.util.List; +import java.util.Map; +import java.util.Objects; + +/** + * 发布通道属性:站点路径模式 + * + * @author 兮玥 + * @email 190785909@qq.com + */ +@Component(IPublishPipeProp.BEAN_PREFIX + PublishPipeProp_PrefixMode.KEY) +public class PublishPipeProp_PrefixMode implements IPublishPipeProp { + + public static final String KEY = "PrefixMode"; + + @Override + public String getKey() { + return KEY; + } + + @Override + public String getName() { + return "站点路径模式"; + } + + @Override + public List getUseTypes() { + return List.of(PublishPipePropUseType.Site); + } + + @Override + public String getDefaultValue() { + return SitePrefixMode.Absolute; + } + + public static String getValue(String publishPipeCode, Map> publishPipeProps) { + if (Objects.nonNull(publishPipeProps)) { + return MapUtils.getString(publishPipeProps.get(publishPipeCode), KEY); + } + return SitePrefixMode.Absolute; + } +} diff --git a/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/domain/CmsSite.java b/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/domain/CmsSite.java index 9d6b9c64..d7030528 100644 --- a/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/domain/CmsSite.java +++ b/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/domain/CmsSite.java @@ -153,7 +153,9 @@ public class CmsSite extends BaseEntity { public String getUrl(String publishPipeCode) { String ppUrl = PublishPipeProp_SiteUrl.getValue(publishPipeCode, this.publishPipeProps); - ppUrl = StringUtils.appendIfMissing(ppUrl, "/"); + if (StringUtils.isNotBlank(ppUrl)) { + ppUrl = StringUtils.appendIfMissing(ppUrl, "/"); + } return Objects.requireNonNullElse(ppUrl, StringUtils.EMPTY); } } diff --git a/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/enums/SitePrefixMode.java b/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/enums/SitePrefixMode.java new file mode 100644 index 00000000..14944870 --- /dev/null +++ b/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/enums/SitePrefixMode.java @@ -0,0 +1,43 @@ +/* + * Copyright 2022-2024 兮玥(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.contentcore.enums; + +/** + * 站点路径模式,决定模板上下文${Prefix}取值 + * + * @author 兮玥 + * @email 190785909@qq.com + */ +public class SitePrefixMode { + + /** + * 相对路径,Prefix = "/" + */ + public static final String Relative = "relative"; + + /** + * 绝对路径, Prefix = "SiteUrl" + */ + public static final String Absolute = "absolute"; + + public static boolean isRelative(String v) { + return Relative.equals(v); + } + + public static boolean isAbsolute(String v) { + return Absolute.equals(v); + } +} diff --git a/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/listener/ContentCoreListener.java b/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/listener/ContentCoreListener.java index 6cf8f15b..cf0973fc 100644 --- a/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/listener/ContentCoreListener.java +++ b/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/listener/ContentCoreListener.java @@ -235,6 +235,11 @@ public class ContentCoreListener { }); } + @EventListener + public void afterContentDelete(AfterContentDeleteEvent event) { + contentRelaService.onContentDelete(event.getContent().getContentEntity().getContentId()); + } + @EventListener public void onCatalogClear(OnCatalogClearEvent event) { CmsCatalog catalog = event.getCatalog(); diff --git a/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/properties/SiteApiUrlProperty.java b/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/properties/SiteApiUrlProperty.java index c7050398..03ef3834 100644 --- a/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/properties/SiteApiUrlProperty.java +++ b/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/properties/SiteApiUrlProperty.java @@ -75,7 +75,9 @@ public class SiteApiUrlProperty implements IProperty { if (StringUtils.isEmpty(apiUrl)) { apiUrl = site.getUrl(publishPipeCode); } - apiUrl = StringUtils.appendIfMissing(apiUrl, "/"); + if (StringUtils.isNotEmpty(apiUrl)) { + apiUrl = StringUtils.appendIfMissing(apiUrl, "/"); + } return apiUrl; } } diff --git a/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/service/IContentRelaService.java b/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/service/IContentRelaService.java index d253a9f4..da9cabf1 100644 --- a/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/service/IContentRelaService.java +++ b/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/service/IContentRelaService.java @@ -20,4 +20,5 @@ import com.chestnut.contentcore.domain.CmsContentRela; public interface IContentRelaService extends IService { + void onContentDelete(Long contentId); } diff --git a/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/service/impl/ContentRelaServiceImpl.java b/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/service/impl/ContentRelaServiceImpl.java index 5bd18af7..7becd065 100644 --- a/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/service/impl/ContentRelaServiceImpl.java +++ b/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/service/impl/ContentRelaServiceImpl.java @@ -15,6 +15,7 @@ */ package com.chestnut.contentcore.service.impl; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.chestnut.contentcore.domain.CmsContentRela; import com.chestnut.contentcore.mapper.CmsContentRelaMapper; @@ -26,4 +27,10 @@ import org.springframework.stereotype.Service; @RequiredArgsConstructor public class ContentRelaServiceImpl extends ServiceImpl implements IContentRelaService { + + @Override + public void onContentDelete(Long contentId) { + this.remove(new LambdaQueryWrapper() + .eq(CmsContentRela::getContentId, contentId).or().eq(CmsContentRela::getRelaContentId, contentId)); + } } 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 a21c19fe..d9b14e41 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 @@ -119,7 +119,9 @@ public class SiteServiceImpl extends ServiceImpl impleme CmsSite site = new CmsSite(); site.setSiteId(IdUtils.getSnowflakeId()); BeanUtils.copyProperties(dto, site, "siteId"); - site.setResourceUrl(StringUtils.appendIfMissing(site.getResourceUrl(), "/")); + if (StringUtils.isNotBlank(site.getResourceUrl())) { + site.setResourceUrl(StringUtils.appendIfMissing(site.getResourceUrl(), "/")); + } site.setSortFlag(SortUtils.getDefaultSortValue()); site.createBy(dto.getOperator().getUsername()); this.save(site); @@ -143,7 +145,9 @@ public class SiteServiceImpl extends ServiceImpl impleme CmsSite site = this.getById(dto.getSiteId()); BeanUtils.copyProperties(dto, site, "path"); - site.setResourceUrl(StringUtils.appendIfMissing(site.getResourceUrl(), "/")); + if (StringUtils.isNotBlank(site.getResourceUrl())) { + site.setResourceUrl(StringUtils.appendIfMissing(site.getResourceUrl(), "/")); + } // 发布通道数据处理 dto.getPublishPipeDatas().forEach(prop -> { prop.getProps().entrySet().removeIf(e -> !publishPipeProps.containsKey(IPublishPipeProp.BEAN_PREFIX + e.getKey())); 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 96c62f68..39d25b29 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 @@ -18,6 +18,7 @@ package com.chestnut.contentcore.template.tag; import com.chestnut.common.staticize.FreeMarkerUtils; import com.chestnut.common.staticize.core.TemplateContext; import com.chestnut.common.staticize.enums.TagAttrDataType; +import com.chestnut.common.staticize.exception.IncludeTemplateNotFoundException; import com.chestnut.common.staticize.tag.AbstractTag; import com.chestnut.common.staticize.tag.TagAttr; import com.chestnut.common.utils.Assert; @@ -36,7 +37,6 @@ import freemarker.core.Environment; import freemarker.template.Template; import freemarker.template.TemplateException; import freemarker.template.TemplateModel; -import freemarker.template.TemplateNotFoundException; import lombok.RequiredArgsConstructor; import org.apache.commons.collections4.MapUtils; import org.apache.commons.io.FileUtils; @@ -113,7 +113,7 @@ public class CmsPageWidgetTag extends AbstractTag { } CmsSite site = this.siteService.getSite(siteId); File templateFile = this.templateService.findTemplateFile(site, pw.getTemplate(), context.getPublishPipeCode()); - Assert.notNull(templateFile, () -> new TemplateNotFoundException(pw.getTemplate(), null, null)); + Assert.notNull(templateFile, () -> new IncludeTemplateNotFoundException(pw.getTemplate(), env)); boolean ssi = MapUtils.getBoolean(attrs, ATTR_SSI, EnableSSIProperty.getValue(site.getConfigProps())); String templateKey = SiteUtils.getTemplateKey(site, pw.getPublishPipeCode(), pw.getTemplate()); diff --git a/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/util/SiteUtils.java b/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/util/SiteUtils.java index 4efd37c1..20313f03 100644 --- a/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/util/SiteUtils.java +++ b/chestnut-cms/chestnut-cms-contentcore/src/main/java/com/chestnut/contentcore/util/SiteUtils.java @@ -20,7 +20,9 @@ import com.chestnut.contentcore.ContentCoreConsts; import com.chestnut.contentcore.config.CMSConfig; import com.chestnut.contentcore.core.IInternalDataType; import com.chestnut.contentcore.core.impl.InternalDataType_Site; +import com.chestnut.contentcore.core.impl.PublishPipeProp_PrefixMode; import com.chestnut.contentcore.domain.CmsSite; +import com.chestnut.contentcore.enums.SitePrefixMode; import com.chestnut.system.fixed.config.BackendContext; public class SiteUtils { @@ -44,6 +46,10 @@ public class SiteUtils { return CMSConfig.getResourcePreviewPrefix() + getSitePublishPipePath(site.getPath(), publishPipeCode); } + String pathMode = PublishPipeProp_PrefixMode.getValue(publishPipeCode, site.getPublishPipeProps()); + if (SitePrefixMode.isRelative(pathMode)) { + return "/"; + } return site.getUrl(publishPipeCode); } diff --git a/chestnut-cms/chestnut-cms-customform/pom.xml b/chestnut-cms/chestnut-cms-customform/pom.xml index 24504901..775848e0 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.1 + 1.5.2 chestnut-cms-customform diff --git a/chestnut-cms/chestnut-cms-customform/src/main/java/com/chestnut/customform/fixed/dict/CustomFormRule.java b/chestnut-cms/chestnut-cms-customform/src/main/java/com/chestnut/customform/fixed/dict/CustomFormRule.java index 72a2e649..9fe9cff6 100644 --- a/chestnut-cms/chestnut-cms-customform/src/main/java/com/chestnut/customform/fixed/dict/CustomFormRule.java +++ b/chestnut-cms/chestnut-cms-customform/src/main/java/com/chestnut/customform/fixed/dict/CustomFormRule.java @@ -34,9 +34,9 @@ public class CustomFormRule extends FixedDictType { public static final String Unlimited = "0"; // 无限制 - public static final String IP = "1"; // IP +// public static final String IP = "1"; // IP - public static final String BrowserFingerprint = "2"; // 浏览器指纹 +// public static final String BrowserFingerprint = "2"; // 浏览器指纹 private static final ISysDictTypeService dictTypeService = SpringUtils.getBean(ISysDictTypeService.class); @@ -44,8 +44,8 @@ public class CustomFormRule extends FixedDictType { public CustomFormRule() { super(TYPE, "{DICT." + TYPE + "}"); super.addDictData("{DICT." + TYPE + "." + Unlimited + "}", Unlimited, 1); - super.addDictData("{DICT." + TYPE + "." + IP + "}", IP, 2); - super.addDictData("{DICT." + TYPE + "." + BrowserFingerprint + "}", BrowserFingerprint, 3); +// super.addDictData("{DICT." + TYPE + "." + IP + "}", IP, 2); +// super.addDictData("{DICT." + TYPE + "." + BrowserFingerprint + "}", BrowserFingerprint, 3); } public static void decode(List list, Function getter, BiConsumer setter) { diff --git a/chestnut-cms/chestnut-cms-customform/src/main/java/com/chestnut/customform/template/tag/CmsCustomFormTag.java b/chestnut-cms/chestnut-cms-customform/src/main/java/com/chestnut/customform/template/tag/CmsCustomFormTag.java index 3cb03634..e62f1778 100644 --- a/chestnut-cms/chestnut-cms-customform/src/main/java/com/chestnut/customform/template/tag/CmsCustomFormTag.java +++ b/chestnut-cms/chestnut-cms-customform/src/main/java/com/chestnut/customform/template/tag/CmsCustomFormTag.java @@ -19,6 +19,7 @@ import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapp import com.chestnut.common.staticize.FreeMarkerUtils; import com.chestnut.common.staticize.core.TemplateContext; import com.chestnut.common.staticize.enums.TagAttrDataType; +import com.chestnut.common.staticize.exception.IncludeTemplateNotFoundException; import com.chestnut.common.staticize.tag.AbstractTag; import com.chestnut.common.staticize.tag.TagAttr; import com.chestnut.common.utils.Assert; @@ -39,7 +40,6 @@ import freemarker.core.Environment; import freemarker.template.Template; import freemarker.template.TemplateException; import freemarker.template.TemplateModel; -import freemarker.template.TemplateNotFoundException; import lombok.RequiredArgsConstructor; import org.apache.commons.collections4.MapUtils; import org.apache.commons.io.FileUtils; @@ -104,7 +104,7 @@ public class CmsCustomFormTag extends AbstractTag { String template = form.getTemplates().getOrDefault(context.getPublishPipeCode(), PublishPipeProp_CustomFormTemplate.getValue(context.getPublishPipeCode(), site.getPublishPipeProps())); File templateFile = this.templateService.findTemplateFile(site, template, context.getPublishPipeCode()); - Assert.notNull(templateFile, () -> new TemplateNotFoundException(template, null, null)); + Assert.notNull(templateFile, () -> new IncludeTemplateNotFoundException(template, env)); boolean ssi = MapUtils.getBoolean(attrs, ATTR_SSI, EnableSSIProperty.getValue(site.getConfigProps())); String templateKey = SiteUtils.getTemplateKey(site, context.getPublishPipeCode(), template); diff --git a/chestnut-cms/chestnut-cms-dynamic/pom.xml b/chestnut-cms/chestnut-cms-dynamic/pom.xml index c88167da..d929807d 100644 --- a/chestnut-cms/chestnut-cms-dynamic/pom.xml +++ b/chestnut-cms/chestnut-cms-dynamic/pom.xml @@ -7,7 +7,7 @@ com.chestnut chestnut-cms - 1.5.1 + 1.5.2 chestnut-cms-dynamic diff --git a/chestnut-cms/chestnut-cms-exmodel/pom.xml b/chestnut-cms/chestnut-cms-exmodel/pom.xml index c9bf2673..8ef423f4 100644 --- a/chestnut-cms/chestnut-cms-exmodel/pom.xml +++ b/chestnut-cms/chestnut-cms-exmodel/pom.xml @@ -7,7 +7,7 @@ com.chestnut chestnut-cms - 1.5.1 + 1.5.2 chestnut-cms-exmodel diff --git a/chestnut-cms/chestnut-cms-exmodel/src/main/java/com/chestnut/exmodel/template/tag/CmsXModelDataTag.java b/chestnut-cms/chestnut-cms-exmodel/src/main/java/com/chestnut/exmodel/template/tag/CmsXModelDataTag.java index ab4abd48..abc9ed76 100644 --- a/chestnut-cms/chestnut-cms-exmodel/src/main/java/com/chestnut/exmodel/template/tag/CmsXModelDataTag.java +++ b/chestnut-cms/chestnut-cms-exmodel/src/main/java/com/chestnut/exmodel/template/tag/CmsXModelDataTag.java @@ -21,9 +21,13 @@ import com.chestnut.common.staticize.exception.InvalidTagAttrValueException; 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.ConvertUtils; import com.chestnut.common.utils.IdUtils; import com.chestnut.exmodel.CmsExtendMetaModelType; +import com.chestnut.xmodel.core.IMetaControlType; +import com.chestnut.xmodel.core.MetaModel; import com.chestnut.xmodel.service.IModelDataService; +import com.chestnut.xmodel.service.IModelService; import freemarker.core.Environment; import freemarker.template.TemplateException; import freemarker.template.TemplateModel; @@ -53,7 +57,9 @@ public class CmsXModelDataTag extends AbstractTag { public final static String ATTR_DATA_TYPE = "dataType"; public final static String ATTR_DATA_ID = "dataId"; + private final IModelService modelService; private final IModelDataService modelDataService; + private final Map controlTypeMap; @Override public List getTagAttrs() { @@ -79,6 +85,17 @@ public class CmsXModelDataTag extends AbstractTag { CmsExtendMetaModelType.FIELD_DATA_TYPE.getCode(), dataType, CmsExtendMetaModelType.FIELD_DATA_ID.getCode(), dataId )); + MetaModel model = this.modelService.getMetaModel(modelId); + modelData.entrySet().forEach(entry -> { + model.getFields().stream().filter(field -> field.getCode().equals(entry.getKey())) + .findFirst().ifPresent(field -> { + IMetaControlType controlType = controlTypeMap.get(IMetaControlType.BEAN_PREFIX + field.getControlType()); + if (controlType != null) { + Object v = controlType.stringAsValue(ConvertUtils.toStr(entry.getValue())); + entry.setValue(v); + } + }); + }); return Map.of(StaticizeConstants.TemplateVariable_Data, this.wrap(env, modelData)); } diff --git a/chestnut-cms/chestnut-cms-image/pom.xml b/chestnut-cms/chestnut-cms-image/pom.xml index 6f6ba21a..33142c98 100644 --- a/chestnut-cms/chestnut-cms-image/pom.xml +++ b/chestnut-cms/chestnut-cms-image/pom.xml @@ -7,7 +7,7 @@ com.chestnut chestnut-cms - 1.5.1 + 1.5.2 chestnut-cms-image diff --git a/chestnut-cms/chestnut-cms-link/pom.xml b/chestnut-cms/chestnut-cms-link/pom.xml index 66c831c6..5d2840a7 100644 --- a/chestnut-cms/chestnut-cms-link/pom.xml +++ b/chestnut-cms/chestnut-cms-link/pom.xml @@ -7,7 +7,7 @@ com.chestnut chestnut-cms - 1.5.1 + 1.5.2 chestnut-cms-link diff --git a/chestnut-cms/chestnut-cms-media/pom.xml b/chestnut-cms/chestnut-cms-media/pom.xml index 1f64ea97..d746951e 100644 --- a/chestnut-cms/chestnut-cms-media/pom.xml +++ b/chestnut-cms/chestnut-cms-media/pom.xml @@ -7,7 +7,7 @@ com.chestnut chestnut-cms - 1.5.1 + 1.5.2 chestnut-cms-media diff --git a/chestnut-cms/chestnut-cms-member/pom.xml b/chestnut-cms/chestnut-cms-member/pom.xml index 607a13a5..3b8ccd2c 100644 --- a/chestnut-cms/chestnut-cms-member/pom.xml +++ b/chestnut-cms/chestnut-cms-member/pom.xml @@ -6,7 +6,7 @@ com.chestnut chestnut-cms - 1.5.1 + 1.5.2 chestnut-cms-member diff --git a/chestnut-cms/chestnut-cms-member/src/main/java/com/chestnut/cms/member/properties/MemberResourceUrlProperty.java b/chestnut-cms/chestnut-cms-member/src/main/java/com/chestnut/cms/member/properties/MemberResourceUrlProperty.java new file mode 100644 index 00000000..49e36783 --- /dev/null +++ b/chestnut-cms/chestnut-cms-member/src/main/java/com/chestnut/cms/member/properties/MemberResourceUrlProperty.java @@ -0,0 +1,59 @@ +/* + * Copyright 2022-2024 兮玥(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.cms.member.properties; + +import com.chestnut.common.utils.StringUtils; +import com.chestnut.contentcore.core.IProperty; +import com.chestnut.contentcore.domain.CmsSite; +import com.chestnut.contentcore.util.ConfigPropertyUtils; +import org.springframework.stereotype.Component; + +/** + * 会员资源访问域名 + * + * @author 兮玥 + * @email 190785909@qq.com + */ +@Component(IProperty.BEAN_NAME_PREFIX + MemberResourceUrlProperty.ID) +public class MemberResourceUrlProperty implements IProperty { + + public final static String ID = "MemberResourceUrl"; + + static UseType[] UseTypes = new UseType[] { UseType.Site }; + + @Override + public UseType[] getUseTypes() { + return UseTypes; + } + + @Override + public String getId() { + return ID; + } + + @Override + public String getName() { + return "会员资源访问域名"; + } + + public static String getValue(CmsSite site) { + String value = ConfigPropertyUtils.getStringValue(ID, site.getConfigProps()); + if (StringUtils.isNotEmpty(value)) { + return StringUtils.appendIfMissing(value, "/"); + } + return StringUtils.EMPTY; + } +} diff --git a/chestnut-cms/chestnut-cms-search/pom.xml b/chestnut-cms/chestnut-cms-search/pom.xml index aebcf78b..96c5ddbb 100644 --- a/chestnut-cms/chestnut-cms-search/pom.xml +++ b/chestnut-cms/chestnut-cms-search/pom.xml @@ -7,7 +7,7 @@ com.chestnut chestnut-cms - 1.5.1 + 1.5.2 chestnut-cms-search diff --git a/chestnut-cms/chestnut-cms-seo/pom.xml b/chestnut-cms/chestnut-cms-seo/pom.xml index 527c96c2..fa2c392e 100644 --- a/chestnut-cms/chestnut-cms-seo/pom.xml +++ b/chestnut-cms/chestnut-cms-seo/pom.xml @@ -7,7 +7,7 @@ com.chestnut chestnut-cms - 1.5.1 + 1.5.2 chestnut-cms-seo diff --git a/chestnut-cms/chestnut-cms-seo/src/main/java/com/chestnut/seo/service/BaiduSitemapService.java b/chestnut-cms/chestnut-cms-seo/src/main/java/com/chestnut/seo/service/BaiduSitemapService.java index e767b99d..e7a810b9 100644 --- a/chestnut-cms/chestnut-cms-seo/src/main/java/com/chestnut/seo/service/BaiduSitemapService.java +++ b/chestnut-cms/chestnut-cms-seo/src/main/java/com/chestnut/seo/service/BaiduSitemapService.java @@ -195,7 +195,6 @@ public class BaiduSitemapService { */ public void generateSitemapIndexXml(CmsSite site, String publishPipeCode) throws IOException { String siteUrl = site.getUrl(publishPipeCode); - siteUrl = StringUtils.appendIfMissing(siteUrl, "/"); String siteRoot = SiteUtils.getSiteRoot(site, publishPipeCode); File[] files = new File(siteRoot).listFiles(f -> f.getName().startsWith(SitemapFileNamePrefix)); if (files != null) { diff --git a/chestnut-cms/chestnut-cms-stat/pom.xml b/chestnut-cms/chestnut-cms-stat/pom.xml index ab3da0ce..de319a5f 100644 --- a/chestnut-cms/chestnut-cms-stat/pom.xml +++ b/chestnut-cms/chestnut-cms-stat/pom.xml @@ -7,7 +7,7 @@ com.chestnut chestnut-cms - 1.5.1 + 1.5.2 chestnut-cms-stat diff --git a/chestnut-cms/chestnut-cms-vote/pom.xml b/chestnut-cms/chestnut-cms-vote/pom.xml index ce9c13f8..82461475 100644 --- a/chestnut-cms/chestnut-cms-vote/pom.xml +++ b/chestnut-cms/chestnut-cms-vote/pom.xml @@ -7,7 +7,7 @@ com.chestnut chestnut-cms - 1.5.1 + 1.5.2 chestnut-cms-vote diff --git a/chestnut-cms/chestnut-cms-word/pom.xml b/chestnut-cms/chestnut-cms-word/pom.xml index 349783d4..105b7b95 100644 --- a/chestnut-cms/chestnut-cms-word/pom.xml +++ b/chestnut-cms/chestnut-cms-word/pom.xml @@ -7,7 +7,7 @@ com.chestnut chestnut-cms - 1.5.1 + 1.5.2 chestnut-cms-word diff --git a/chestnut-cms/pom.xml b/chestnut-cms/pom.xml index 1105cb44..183eeca7 100644 --- a/chestnut-cms/pom.xml +++ b/chestnut-cms/pom.xml @@ -5,7 +5,7 @@ com.chestnut chestnut - 1.5.1 + 1.5.2 4.0.0 diff --git a/chestnut-common/chestnut-common-core/pom.xml b/chestnut-common/chestnut-common-core/pom.xml index 5d1644f9..696fed63 100644 --- a/chestnut-common/chestnut-common-core/pom.xml +++ b/chestnut-common/chestnut-common-core/pom.xml @@ -5,7 +5,7 @@ chestnut-common com.chestnut - 1.5.1 + 1.5.2 4.0.0 diff --git a/chestnut-common/chestnut-common-core/src/main/java/com/chestnut/common/utils/ArrayUtils.java b/chestnut-common/chestnut-common-core/src/main/java/com/chestnut/common/utils/ArrayUtils.java index bcc57750..573cd832 100644 --- a/chestnut-common/chestnut-common-core/src/main/java/com/chestnut/common/utils/ArrayUtils.java +++ b/chestnut-common/chestnut-common-core/src/main/java/com/chestnut/common/utils/ArrayUtils.java @@ -15,8 +15,8 @@ */ package com.chestnut.common.utils; -import java.util.Collection; -import java.util.Objects; +import java.util.*; +import java.util.function.Function; import java.util.function.Predicate; public class ArrayUtils { @@ -84,4 +84,32 @@ public class ArrayUtils { } return defaultV; } + + public static Map>> groupBy(List> list, String groupBy) { + Map>> map = new HashMap<>(); + list.forEach(obj -> { + String key = obj.get(groupBy).toString(); + List> groupList = map.get(key); + if (Objects.isNull(groupList)) { + groupList = new ArrayList<>(); + map.put(key, groupList); + } + groupList.add(obj); + }); + return map; + } + + public static Map> groupBy(List list, Function getter) { + Map> map = new HashMap<>(); + list.forEach(obj -> { + String key = getter.apply(obj); + List groupList = map.get(key); + if (Objects.isNull(groupList)) { + groupList = new ArrayList<>(); + map.put(key, groupList); + } + groupList.add(obj); + }); + return map; + } } diff --git a/chestnut-common/chestnut-common-datasource/pom.xml b/chestnut-common/chestnut-common-datasource/pom.xml index 6564b6af..e596f1fe 100644 --- a/chestnut-common/chestnut-common-datasource/pom.xml +++ b/chestnut-common/chestnut-common-datasource/pom.xml @@ -5,7 +5,7 @@ chestnut-common com.chestnut - 1.5.1 + 1.5.2 4.0.0 diff --git a/chestnut-common/chestnut-common-extend/pom.xml b/chestnut-common/chestnut-common-extend/pom.xml index e13ae992..03bf73b0 100644 --- a/chestnut-common/chestnut-common-extend/pom.xml +++ b/chestnut-common/chestnut-common-extend/pom.xml @@ -5,7 +5,7 @@ chestnut-common com.chestnut - 1.5.1 + 1.5.2 4.0.0 diff --git a/chestnut-common/chestnut-common-log/pom.xml b/chestnut-common/chestnut-common-log/pom.xml index 09fec9ce..11cacc98 100644 --- a/chestnut-common/chestnut-common-log/pom.xml +++ b/chestnut-common/chestnut-common-log/pom.xml @@ -5,7 +5,7 @@ chestnut-common com.chestnut - 1.5.1 + 1.5.2 4.0.0 diff --git a/chestnut-common/chestnut-common-redis/pom.xml b/chestnut-common/chestnut-common-redis/pom.xml index a14f2a13..8966eab5 100644 --- a/chestnut-common/chestnut-common-redis/pom.xml +++ b/chestnut-common/chestnut-common-redis/pom.xml @@ -5,7 +5,7 @@ chestnut-common com.chestnut - 1.5.1 + 1.5.2 4.0.0 diff --git a/chestnut-common/chestnut-common-security/pom.xml b/chestnut-common/chestnut-common-security/pom.xml index 6aa9da59..52c40143 100644 --- a/chestnut-common/chestnut-common-security/pom.xml +++ b/chestnut-common/chestnut-common-security/pom.xml @@ -5,7 +5,7 @@ chestnut-common com.chestnut - 1.5.1 + 1.5.2 4.0.0 diff --git a/chestnut-common/chestnut-common-staticize/pom.xml b/chestnut-common/chestnut-common-staticize/pom.xml index cf2aaa14..a986c590 100644 --- a/chestnut-common/chestnut-common-staticize/pom.xml +++ b/chestnut-common/chestnut-common-staticize/pom.xml @@ -5,7 +5,7 @@ chestnut-common com.chestnut - 1.5.1 + 1.5.2 4.0.0 diff --git a/chestnut-common/chestnut-common-staticize/src/main/java/com/chestnut/common/staticize/config/FreeMarkerConfig.java b/chestnut-common/chestnut-common-staticize/src/main/java/com/chestnut/common/staticize/config/FreeMarkerConfig.java index c4487385..a7aebfdf 100644 --- a/chestnut-common/chestnut-common-staticize/src/main/java/com/chestnut/common/staticize/config/FreeMarkerConfig.java +++ b/chestnut-common/chestnut-common-staticize/src/main/java/com/chestnut/common/staticize/config/FreeMarkerConfig.java @@ -48,7 +48,7 @@ public class FreeMarkerConfig { *

* * @param properties - * @param fileTemplateLoader + * @param templateLoaders * @return * @throws TemplateException */ diff --git a/chestnut-common/chestnut-common-staticize/src/main/java/com/chestnut/common/staticize/exception/IncludeTemplateNotFoundException.java b/chestnut-common/chestnut-common-staticize/src/main/java/com/chestnut/common/staticize/exception/IncludeTemplateNotFoundException.java new file mode 100644 index 00000000..3731b7da --- /dev/null +++ b/chestnut-common/chestnut-common-staticize/src/main/java/com/chestnut/common/staticize/exception/IncludeTemplateNotFoundException.java @@ -0,0 +1,33 @@ +/* + * Copyright 2022-2024 兮玥(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.common.staticize.exception; + +import com.chestnut.common.i18n.I18nUtils; +import freemarker.core.Environment; +import freemarker.template.TemplateException; + +/** + * IncludeTemplateNotFoundException + * + * @author 兮玥 + * @email 190785909@qq.com + */ +public class IncludeTemplateNotFoundException extends TemplateException { + + public IncludeTemplateNotFoundException(String templateKey, Environment env) { + super(I18nUtils.get("{FREEMARKER.ERR.IncludeTemplateNotFound}", templateKey), env); + } +} diff --git a/chestnut-common/chestnut-common-staticize/src/main/java/com/chestnut/common/staticize/func/impl/DateFormatFunction.java b/chestnut-common/chestnut-common-staticize/src/main/java/com/chestnut/common/staticize/func/impl/DateFormatFunction.java index 4fad52f2..652d7b2d 100644 --- a/chestnut-common/chestnut-common-staticize/src/main/java/com/chestnut/common/staticize/func/impl/DateFormatFunction.java +++ b/chestnut-common/chestnut-common-staticize/src/main/java/com/chestnut/common/staticize/func/impl/DateFormatFunction.java @@ -16,10 +16,7 @@ package com.chestnut.common.staticize.func.impl; import com.chestnut.common.staticize.func.AbstractFunc; -import com.chestnut.common.utils.ConvertUtils; -import com.chestnut.common.utils.DateUtils; -import com.chestnut.common.utils.NumberUtils; -import com.chestnut.common.utils.StringUtils; +import com.chestnut.common.utils.*; import freemarker.ext.beans.BeanModel; import freemarker.template.SimpleNumber; import freemarker.template.SimpleScalar; @@ -30,11 +27,11 @@ import org.springframework.stereotype.Component; import java.text.SimpleDateFormat; import java.time.Instant; import java.time.LocalDateTime; -import java.time.ZoneId; import java.time.format.DateTimeFormatter; import java.time.temporal.TemporalAccessor; import java.util.Date; import java.util.List; +import java.util.Locale; import java.util.Objects; /** @@ -52,8 +49,7 @@ public class DateFormatFunction extends AbstractFunc { private static final String ARG2_NAME = "{FREEMARKER.FUNC." + FUNC_NAME + ".Arg2.Name}"; - private static final SimpleDateFormat DEFAULT_SIMPLE_DATE_FORMAT = new SimpleDateFormat( - DateUtils.YYYY_MM_DD_HH_MM_SS); + private static final String ARG3_NAME = "{FREEMARKER.FUNC." + FUNC_NAME + ".Arg3.Name}"; @Override public String getFuncName() { @@ -70,35 +66,35 @@ public class DateFormatFunction extends AbstractFunc { if (args.length < 1 || Objects.isNull(args[0])) { return StringUtils.EMPTY; } + Locale locale = args.length == 3 ? Locale.forLanguageTag(args[2].toString()) : Locale.getDefault(); if (args[0] instanceof BeanModel model) { Object obj = model.getWrappedObject(); - if (obj instanceof TemporalAccessor t) { if (args.length > 1) { - return DateTimeFormatter.ofPattern(args[1].toString()).format(t); + return DateTimeFormatter.ofPattern(args[1].toString(), locale).format(t); } else { - return DateTimeFormatter.ISO_LOCAL_DATE_TIME.format(t); + return DateTimeFormatter.ofPattern(DateUtils.YYYY_MM_DD_HH_MM_SS, locale).format(t); } } else if (obj instanceof Date d) { if (args.length > 1) { String formatStr = ConvertUtils.toStr(args[1], DateUtils.YYYY_MM_DD_HH_MM_SS); - return DateUtils.parseDateToStr(formatStr, d); + SimpleDateFormat format = new SimpleDateFormat(formatStr, locale); + return format.format(d); } else { - return DEFAULT_SIMPLE_DATE_FORMAT.format(d); + SimpleDateFormat format = new SimpleDateFormat(DateUtils.YYYY_MM_DD_HH_MM_SS, locale); + return format.format(d); } } } else if (args[0] instanceof SimpleScalar s) { String value = s.getAsString(); if (NumberUtils.isCreatable(value)) { - LocalDateTime dateTime = Instant.ofEpochMilli(ConvertUtils.toLong(value)) - .atZone(ZoneId.systemDefault()).toLocalDateTime(); - return DateTimeFormatter.ofPattern(args[1].toString()).format(dateTime); + LocalDateTime dateTime = TimeUtils.toLocalDateTime(Instant.ofEpochMilli(ConvertUtils.toLong(value))); + return DateTimeFormatter.ofPattern(args[1].toString(), locale).format(dateTime); } } else if (args[0] instanceof SimpleNumber s) { long value = s.getAsNumber().longValue(); - LocalDateTime dateTime = Instant.ofEpochMilli(value) - .atZone(ZoneId.systemDefault()).toLocalDateTime(); - return DateTimeFormatter.ofPattern(args[1].toString()).format(dateTime); + LocalDateTime dateTime = TimeUtils.toLocalDateTime(Instant.ofEpochMilli(value)); + return DateTimeFormatter.ofPattern(args[1].toString(), locale).format(dateTime); } return args[0].toString(); } @@ -106,6 +102,7 @@ public class DateFormatFunction extends AbstractFunc { @Override public List getFuncArgs() { return List.of(new FuncArg(ARG1_NAME, FuncArgType.DateTime, true), - new FuncArg(ARG2_NAME, FuncArgType.String, false, null, "yyyy-MM-dd HH:mm:ss")); + new FuncArg(ARG2_NAME, FuncArgType.String, false, null, "yyyy-MM-dd HH:mm:ss"), + new FuncArg(ARG3_NAME, FuncArgType.String, false, null, Locale.getDefault().toLanguageTag())); } } diff --git a/chestnut-common/chestnut-common-staticize/src/main/java/com/chestnut/common/staticize/func/impl/GetDomainFunction.java b/chestnut-common/chestnut-common-staticize/src/main/java/com/chestnut/common/staticize/func/impl/GetDomainFunction.java new file mode 100644 index 00000000..1d151d58 --- /dev/null +++ b/chestnut-common/chestnut-common-staticize/src/main/java/com/chestnut/common/staticize/func/impl/GetDomainFunction.java @@ -0,0 +1,63 @@ +/* + * Copyright 2022-2024 兮玥(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.common.staticize.func.impl; + +import com.chestnut.common.staticize.func.AbstractFunc; +import com.chestnut.common.utils.StringUtils; +import freemarker.template.TemplateModelException; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * Freemarker模板自定义函数:提取URL域名 + */ +@Component +@RequiredArgsConstructor +public class GetDomainFunction extends AbstractFunc { + + static final String FUNC_NAME = "getDomain"; + + private static final String DESC = "{FREEMARKER.FUNC." + FUNC_NAME + ".DESC}"; + + @Override + public String getFuncName() { + return FUNC_NAME; + } + + @Override + public String getDesc() { + return DESC; + } + + @Override + public Object exec0(Object... args) throws TemplateModelException { + if (args.length < 1) { + return StringUtils.EMPTY; + } + String str = args[0].toString(); + if (StringUtils.isBlank(str)) { + return StringUtils.EMPTY; + } + return StringUtils.substringBefore(StringUtils.substringAfter(str, "://"), "/"); + } + + @Override + public List getFuncArgs() { + return List.of(new FuncArg("URL", FuncArgType.String, true, null)); + } +} diff --git a/chestnut-common/chestnut-common-staticize/src/main/java/com/chestnut/common/staticize/func/impl/GroupByFunction.java b/chestnut-common/chestnut-common-staticize/src/main/java/com/chestnut/common/staticize/func/impl/GroupByFunction.java new file mode 100644 index 00000000..7d5c8081 --- /dev/null +++ b/chestnut-common/chestnut-common-staticize/src/main/java/com/chestnut/common/staticize/func/impl/GroupByFunction.java @@ -0,0 +1,94 @@ +/* + * Copyright 2022-2024 兮玥(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.common.staticize.func.impl; + +import com.chestnut.common.staticize.func.AbstractFunc; +import com.chestnut.common.utils.StringUtils; +import freemarker.template.TemplateHashModel; +import freemarker.template.TemplateModel; +import freemarker.template.TemplateModelException; +import freemarker.template.TemplateSequenceModel; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; + +import java.util.*; + +/** + * Freemarker模板自定义函数:列表分组 + */ +@Component +@RequiredArgsConstructor +public class GroupByFunction extends AbstractFunc { + + static final String FUNC_NAME = "groupBy"; + + private static final String DESC = "{FREEMARKER.FUNC." + FUNC_NAME + ".DESC}"; + + private static final String ARG1_NAME = "{FREEMARKER.FUNC." + FUNC_NAME + ".Arg1.Name}"; + + private static final String ARG1_DESC = "{FREEMARKER.FUNC." + FUNC_NAME + ".Arg1.Desc}"; + + private static final String ARG2_NAME = "{FREEMARKER.FUNC." + FUNC_NAME + ".Arg2.Name}"; + + private static final String ARG2_DESC = "{FREEMARKER.FUNC." + FUNC_NAME + ".Arg2.Desc}"; + + @Override + public String getFuncName() { + return FUNC_NAME; + } + + @Override + public String getDesc() { + return DESC; + } + + @Override + public Object exec0(Object... args) throws TemplateModelException { + if (StringUtils.isEmpty(args)) { + return StringUtils.EMPTY; + } + String groupBy = args[1].toString(); + if (args[0] instanceof TemplateSequenceModel dataList) { + return groupBy(dataList, groupBy); + } + return Map.of(); + } + + public static Map> groupBy(TemplateSequenceModel list, String groupBy) throws TemplateModelException { + Map> map = new HashMap<>(); + for (int i = 0; i < list.size(); i++) { + TemplateModel itemModel = list.get(i); + if (itemModel instanceof TemplateHashModel model) { + String key = model.get(groupBy).toString(); + List groupList = map.get(key); + if (Objects.isNull(groupList)) { + groupList = new ArrayList<>(); + map.put(key, groupList); + } + groupList.add(itemModel); + } + } + return map; + } + + @Override + public List getFuncArgs() { + return List.of( + new FuncArg(ARG1_NAME, FuncArgType.Array, true, ARG1_DESC), + new FuncArg(ARG2_NAME, FuncArgType.String, true, ARG2_DESC) + ); + } +} diff --git a/chestnut-common/chestnut-common-staticize/src/main/resources/i18n/messages.properties b/chestnut-common/chestnut-common-staticize/src/main/resources/i18n/messages.properties index 68ee2599..66642e44 100644 --- a/chestnut-common/chestnut-common-staticize/src/main/resources/i18n/messages.properties +++ b/chestnut-common/chestnut-common-staticize/src/main/resources/i18n/messages.properties @@ -33,8 +33,13 @@ FREEMARKER.FUNC.randomInt.Arg2.Name=随机数范围最大值 FREEMARKER.FUNC.dateFormat.DESC=日期格式化,例如:`${dateFormat(content.publishDate,'yyyy-MM')}` FREEMARKER.FUNC.dateFormat.Arg1.Name=日期时间 FREEMARKER.FUNC.dateFormat.Arg2.Name=格式化字符串 +FREEMARKER.FUNC.dateFormat.Arg3.Name=地区 FREEMARKER.FUNC.clearHtmlTag.DESC=清除Html标签,例如:`${clearHtmlTag(ArticleContent)}` FREEMARKER.FUNC.clearHtmlTag.Arg1.Name=Html字符串 +FREEMARKER.FUNC.getDomain.DESC=提取URL的域名 +FREEMARKER.FUNC.groupBy.DESC=将列表数据按列表项指定字段分组 +FREEMARKER.FUNC.groupBy.Arg1.Name=列表数据 +FREEMARKER.FUNC.groupBy.Arg2.Name=列表项字段名 FREEMARKER.ERR.MISSING_ATTR=标签 <@{0}> 缺少必填属性:{1}。 FREEMARKER.ERR.INVALID_ATTR_TYPE=标签 <@{0}> 属性 `{1}` 类型必须是:{2}, 当前是:{3}。 @@ -42,4 +47,5 @@ FREEMARKER.ERR.INVALID_ATTR_VALUE=标签 <@{0}> 属性值 `{1}` = `{2}` 数据 FREEMARKER.ERR.INVALID_ATTR_VALUE2=标签 <@{0}> 属性值 `{1}` = `{2}` 无效,可选项:{3}。 FREEMARKER.ERR.DUPLICATE_PAGE_FLAG=标签分页属性`page`不能被多次设置为true。 FREEMARKER.ERR.PAGE_INDEX_OUT_OF_BOUNDS=分页页码`{0}`超出最大页码`{1}`。 -FREEMARKER.ERR.INVALID_FUNC_ARGUMENT=函数`{0}()`第{1}个参数错误:{2}。 \ No newline at end of file +FREEMARKER.ERR.INVALID_FUNC_ARGUMENT=函数`{0}()`第{1}个参数错误:{2}。 +FREEMARKER.ERR.IncludeTemplateNotFound=引用模板`{0}`不存在。 \ No newline at end of file diff --git a/chestnut-common/chestnut-common-staticize/src/main/resources/i18n/messages_en.properties b/chestnut-common/chestnut-common-staticize/src/main/resources/i18n/messages_en.properties index 96ac93e0..ccc7e486 100644 --- a/chestnut-common/chestnut-common-staticize/src/main/resources/i18n/messages_en.properties +++ b/chestnut-common/chestnut-common-staticize/src/main/resources/i18n/messages_en.properties @@ -33,8 +33,13 @@ FREEMARKER.FUNC.randomInt.Arg2.Name=Maximum value FREEMARKER.FUNC.dateFormat.DESC=Use `${dateFormat(site.publishDate,'yyyy-MM')}` in template to format the date. FREEMARKER.FUNC.dateFormat.Arg1.Name=Date time FREEMARKER.FUNC.dateFormat.Arg2.Name=Format string +FREEMARKER.FUNC.dateFormat.Arg3.Name=Locale FREEMARKER.FUNC.clearHtmlTag.DESC=Use `${clearHtmlTag(ArticleContent)}` in template to clear html tag. FREEMARKER.FUNC.clearHtmlTag.Arg1.Name=Html text +FREEMARKER.FUNC.getDomain.DESC=Get domain from url. +FREEMARKER.FUNC.groupBy.DESC=Group the list by the specified field of the list item. +FREEMARKER.FUNC.groupBy.Arg1.Name=List +FREEMARKER.FUNC.groupBy.Arg2.Name=The list item field name FREEMARKER.ERR.MISSING_ATTR=The tag <@{0}> missing required attribute: {1}. FREEMARKER.ERR.INVALID_ATTR_TYPE=The tag <@{0}> attribute `{1}` must be {2}, but is: {3}. @@ -42,4 +47,5 @@ FREEMARKER.ERR.INVALID_ATTR_VALUE=The tag <@{0}> attribute value `{1}` = `{2}` i FREEMARKER.ERR.INVALID_ATTR_VALUE2=The tag <@{0}> attribute value `{1}` = `{2}` is invalid, options: {3}. FREEMARKER.ERR.DUPLICATE_PAGE_FLAG=Template page flag is already activated. FREEMARKER.ERR.PAGE_INDEX_OUT_OF_BOUNDS=The page number `{0}` is out of bounds `{1}`. -FREEMARKER.ERR.INVALID_FUNC_ARGUMENT=Invalid arg[{1}] of function '{0}()' is invalid: {2}。 \ No newline at end of file +FREEMARKER.ERR.INVALID_FUNC_ARGUMENT=Invalid arg[{1}] of function '{0}()' is invalid: {2}。 +FREEMARKER.ERR.IncludeTemplateNotFound=Include template `{0}` not found.。 \ No newline at end of file diff --git a/chestnut-common/chestnut-common-staticize/src/main/resources/i18n/messages_zh_TW.properties b/chestnut-common/chestnut-common-staticize/src/main/resources/i18n/messages_zh_TW.properties index d2bd256a..9db47032 100644 --- a/chestnut-common/chestnut-common-staticize/src/main/resources/i18n/messages_zh_TW.properties +++ b/chestnut-common/chestnut-common-staticize/src/main/resources/i18n/messages_zh_TW.properties @@ -33,8 +33,13 @@ FREEMARKER.FUNC.randomInt.Arg2.Name=隨機數範圍最大值 FREEMARKER.FUNC.dateFormat.DESC=日期格式化,例如:`${dateFormat(content.publishDate,'yyyy-MM')}` FREEMARKER.FUNC.dateFormat.Arg1.Name=日期時間 FREEMARKER.FUNC.dateFormat.Arg2.Name=格式化字符串 +FREEMARKER.FUNC.dateFormat.Arg3.Name=地區 FREEMARKER.FUNC.clearHtmlTag.DESC=清除Html標籤,例如:`${clearHtmlTag(ArticleContent)}` FREEMARKER.FUNC.clearHtmlTag.Arg1.Name=待處理字符串 +FREEMARKER.FUNC.getDomain.DESC=提取URL的域名 +FREEMARKER.FUNC.groupBy.DESC=將列表數據按列表項指定字段分組 +FREEMARKER.FUNC.groupBy.Arg1.Name=列表數據 +FREEMARKER.FUNC.groupBy.Arg2.Name=列表項字段名 FREEMARKER.ERR.MISSING_ATTR=標籤 <@{0}> 缺少必填屬性:{1}。 FREEMARKER.ERR.INVALID_ATTR_TYPE=標籤 <@{0}> 屬性 `{1}` 類型必須是:{2}, 當前是: {3}。 @@ -42,4 +47,5 @@ FREEMARKER.ERR.INVALID_ATTR_VALUE=標籤 <@{0}> 屬性值 `{1}` = `{2}` 錯誤 FREEMARKER.ERR.INVALID_ATTR_VALUE2=標籤 <@{0}> 屬性值 `{1}` = `{2}` 无效,可选项:{3}。 FREEMARKER.ERR.DUPLICATE_PAGE_FLAG=標籤分頁屬性`page`不能被多次設置為true。 FREEMARKER.ERR.PAGE_INDEX_OUT_OF_BOUNDS=分頁頁碼`{0}`超出最大頁碼`{1}`。 -FREEMARKER.ERR.INVALID_FUNC_ARGUMENT=函數`{0}()`第{1}個參數錯誤:{2}。 \ No newline at end of file +FREEMARKER.ERR.INVALID_FUNC_ARGUMENT=函數`{0}()`第{1}個參數錯誤:{2}。 +FREEMARKER.ERR.IncludeTemplateNotFound=引用模板`{0}`不存在。 \ No newline at end of file diff --git a/chestnut-common/chestnut-common-storage/pom.xml b/chestnut-common/chestnut-common-storage/pom.xml index 55ec65d9..f793ee97 100644 --- a/chestnut-common/chestnut-common-storage/pom.xml +++ b/chestnut-common/chestnut-common-storage/pom.xml @@ -5,7 +5,7 @@ chestnut-common com.chestnut - 1.5.1 + 1.5.2 4.0.0 diff --git a/chestnut-common/pom.xml b/chestnut-common/pom.xml index 39f70abf..9cceea11 100644 --- a/chestnut-common/pom.xml +++ b/chestnut-common/pom.xml @@ -5,7 +5,7 @@ com.chestnut chestnut - 1.5.1 + 1.5.2 4.0.0 diff --git a/chestnut-modules/chestnut-comment/pom.xml b/chestnut-modules/chestnut-comment/pom.xml index 9d4d92c3..8c3cb869 100644 --- a/chestnut-modules/chestnut-comment/pom.xml +++ b/chestnut-modules/chestnut-comment/pom.xml @@ -3,7 +3,7 @@ chestnut-modules com.chestnut - 1.5.1 + 1.5.2 4.0.0 diff --git a/chestnut-modules/chestnut-generator/pom.xml b/chestnut-modules/chestnut-generator/pom.xml index 37198ed0..db900f2c 100644 --- a/chestnut-modules/chestnut-generator/pom.xml +++ b/chestnut-modules/chestnut-generator/pom.xml @@ -5,7 +5,7 @@ chestnut-modules com.chestnut - 1.5.1 + 1.5.2 4.0.0 diff --git a/chestnut-modules/chestnut-member/pom.xml b/chestnut-modules/chestnut-member/pom.xml index 2e952468..eef8ad2b 100644 --- a/chestnut-modules/chestnut-member/pom.xml +++ b/chestnut-modules/chestnut-member/pom.xml @@ -3,7 +3,7 @@ chestnut-modules com.chestnut - 1.5.1 + 1.5.2 4.0.0 diff --git a/chestnut-modules/chestnut-member/src/main/java/com/chestnut/member/config/MemberConfig.java b/chestnut-modules/chestnut-member/src/main/java/com/chestnut/member/config/MemberConfig.java index d07c8783..0eaef980 100644 --- a/chestnut-modules/chestnut-member/src/main/java/com/chestnut/member/config/MemberConfig.java +++ b/chestnut-modules/chestnut-member/src/main/java/com/chestnut/member/config/MemberConfig.java @@ -39,7 +39,7 @@ public class MemberConfig implements WebMvcConfigurer { private final MemberProperties properties; - public MemberConfig(MemberProperties properties) throws FileNotFoundException { + public MemberConfig(MemberProperties properties) { UPLOAD_DIRECTORY = properties.getUploadPath(); if (StringUtils.isEmpty(UPLOAD_DIRECTORY)) { UPLOAD_DIRECTORY = SpringUtils.getAppParentDirectory() + "/_xy_member/"; @@ -47,7 +47,7 @@ public class MemberConfig implements WebMvcConfigurer { UPLOAD_DIRECTORY = StringUtils.appendIfMissing(FileExUtils.normalizePath(UPLOAD_DIRECTORY), "/"); FileExUtils.mkdirs(UPLOAD_DIRECTORY); properties.setUploadPath(UPLOAD_DIRECTORY); - log.info("Member upload directory: " + UPLOAD_DIRECTORY); + log.info("Member upload directory: {}", UPLOAD_DIRECTORY); this.properties = properties; } diff --git a/chestnut-modules/chestnut-member/src/main/java/com/chestnut/member/fixed/config/MemberResourcePrefix.java b/chestnut-modules/chestnut-member/src/main/java/com/chestnut/member/fixed/config/MemberResourcePrefix.java index 37ce6cb1..8f8d84e0 100644 --- a/chestnut-modules/chestnut-member/src/main/java/com/chestnut/member/fixed/config/MemberResourcePrefix.java +++ b/chestnut-modules/chestnut-member/src/main/java/com/chestnut/member/fixed/config/MemberResourcePrefix.java @@ -39,6 +39,9 @@ public class MemberResourcePrefix extends FixedConfig { if (StringUtils.isEmpty(configValue)) { return BackendContext.getValue() + MemberConfig.getResourcePrefix(); } - return StringUtils.appendIfMissing(configValue, "/"); + if (StringUtils.isEmpty(configValue)) { + configValue = StringUtils.appendIfMissing(configValue, "/"); + } + return configValue; } } diff --git a/chestnut-modules/chestnut-member/src/main/java/com/chestnut/member/service/impl/MemberLevelConfigServiceImpl.java b/chestnut-modules/chestnut-member/src/main/java/com/chestnut/member/service/impl/MemberLevelConfigServiceImpl.java index 0ecf43d4..a26f6c36 100644 --- a/chestnut-modules/chestnut-member/src/main/java/com/chestnut/member/service/impl/MemberLevelConfigServiceImpl.java +++ b/chestnut-modules/chestnut-member/src/main/java/com/chestnut/member/service/impl/MemberLevelConfigServiceImpl.java @@ -15,14 +15,6 @@ */ package com.chestnut.member.service.impl; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - -import org.springframework.boot.CommandLineRunner; -import org.springframework.stereotype.Service; - import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.chestnut.common.exception.CommonErrorCode; import com.chestnut.common.utils.Assert; @@ -34,8 +26,15 @@ import com.chestnut.member.level.ILevelType; import com.chestnut.member.level.LevelManager; import com.chestnut.member.mapper.MemberLevelConfigMapper; import com.chestnut.member.service.IMemberLevelConfigService; - import lombok.RequiredArgsConstructor; +import org.springframework.boot.CommandLineRunner; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; @RequiredArgsConstructor @Service @@ -44,7 +43,7 @@ public class MemberLevelConfigServiceImpl extends ServiceImpl levelTypes; - private Map levelManagerMap = new HashMap<>(); + private static final Map levelManagerMap = new HashMap<>(); @Override public void addLevelConfig(LevelConfigDTO dto) { @@ -87,9 +86,10 @@ public class MemberLevelConfigServiceImpl extends ServiceImpl configIds) { List list = this.listByIds(configIds); - if (list.size() > 0) { + if (!list.isEmpty()) { this.removeByIds(list); ILevelType levelType = this.getLevelType(list.get(0).getLevelType()); @@ -101,7 +101,7 @@ public class MemberLevelConfigServiceImpl extends ServiceImpl list = this.lambdaQuery().eq(MemberLevelConfig::getLevelType, levelType.getId()) .orderByAsc(MemberLevelConfig::getLevel).list(); LevelManager levelManager = this.getLevelManager(levelType); - if (list.size() > 0) { + if (!list.isEmpty()) { levelManager.resetLevelConfigs( list.stream().collect(Collectors.toMap(MemberLevelConfig::getLevel, conf -> conf))); } @@ -114,11 +114,11 @@ public class MemberLevelConfigServiceImpl extends ServiceImpl onLevelConfigChange(levelType)); + levelTypes.values().forEach(this::onLevelConfigChange); } } diff --git a/chestnut-modules/chestnut-meta/pom.xml b/chestnut-modules/chestnut-meta/pom.xml index 68b696d1..1d34d3f7 100644 --- a/chestnut-modules/chestnut-meta/pom.xml +++ b/chestnut-modules/chestnut-meta/pom.xml @@ -6,7 +6,7 @@ chestnut-modules com.chestnut - 1.5.1 + 1.5.2 4.0.0 diff --git a/chestnut-modules/chestnut-monitor/pom.xml b/chestnut-modules/chestnut-monitor/pom.xml index 6c1d006b..abe6f15d 100644 --- a/chestnut-modules/chestnut-monitor/pom.xml +++ b/chestnut-modules/chestnut-monitor/pom.xml @@ -6,7 +6,7 @@ com.chestnut chestnut-modules - 1.5.1 + 1.5.2 chestnut-monitor diff --git a/chestnut-modules/chestnut-search/pom.xml b/chestnut-modules/chestnut-search/pom.xml index 1f5ed356..c618acdf 100644 --- a/chestnut-modules/chestnut-search/pom.xml +++ b/chestnut-modules/chestnut-search/pom.xml @@ -3,7 +3,7 @@ chestnut-modules com.chestnut - 1.5.1 + 1.5.2 4.0.0 diff --git a/chestnut-modules/chestnut-stat/pom.xml b/chestnut-modules/chestnut-stat/pom.xml index f93b85a3..93ce1661 100644 --- a/chestnut-modules/chestnut-stat/pom.xml +++ b/chestnut-modules/chestnut-stat/pom.xml @@ -6,7 +6,7 @@ chestnut-modules com.chestnut - 1.5.1 + 1.5.2 4.0.0 diff --git a/chestnut-modules/chestnut-system/pom.xml b/chestnut-modules/chestnut-system/pom.xml index a5d825d7..343f18d7 100644 --- a/chestnut-modules/chestnut-system/pom.xml +++ b/chestnut-modules/chestnut-system/pom.xml @@ -5,7 +5,7 @@ chestnut-modules com.chestnut - 1.5.1 + 1.5.2 4.0.0 diff --git a/chestnut-modules/chestnut-vote/pom.xml b/chestnut-modules/chestnut-vote/pom.xml index 00bf6b07..3a75a8e2 100644 --- a/chestnut-modules/chestnut-vote/pom.xml +++ b/chestnut-modules/chestnut-vote/pom.xml @@ -3,7 +3,7 @@ chestnut-modules com.chestnut - 1.5.1 + 1.5.2 4.0.0 diff --git a/chestnut-modules/chestnut-word/pom.xml b/chestnut-modules/chestnut-word/pom.xml index a4d4dddf..4126bf11 100644 --- a/chestnut-modules/chestnut-word/pom.xml +++ b/chestnut-modules/chestnut-word/pom.xml @@ -6,7 +6,7 @@ chestnut-modules com.chestnut - 1.5.1 + 1.5.2 4.0.0 diff --git a/chestnut-modules/pom.xml b/chestnut-modules/pom.xml index 64d5a7fe..079db553 100644 --- a/chestnut-modules/pom.xml +++ b/chestnut-modules/pom.xml @@ -5,7 +5,7 @@ com.chestnut chestnut - 1.5.1 + 1.5.2 4.0.0 diff --git a/chestnut-ui/package.json b/chestnut-ui/package.json index 89f62079..45295396 100644 --- a/chestnut-ui/package.json +++ b/chestnut-ui/package.json @@ -1,6 +1,6 @@ { "name": "ChestnutCMS", - "version": "1.5.1", + "version": "1.5.2", "description": "ChestnutCMS[栗子内容管理系统]", "author": "兮玥 - 190785909@qq.com", "license": "Apache-2.0", diff --git a/chestnut-ui/src/components/CurrentSite/index.vue b/chestnut-ui/src/components/CurrentSite/index.vue index fb32bbf8..7da05fe1 100644 --- a/chestnut-ui/src/components/CurrentSite/index.vue +++ b/chestnut-ui/src/components/CurrentSite/index.vue @@ -35,7 +35,7 @@ @row-dblclick="handleRowDblclick" style="width:100%;line-height: normal;"> - + - + - + diff --git a/chestnut-ui/src/views/cms/contentcore/contentEditor.vue b/chestnut-ui/src/views/cms/contentcore/contentEditor.vue index 4baf2d0c..c1ab2e14 100644 --- a/chestnut-ui/src/views/cms/contentcore/contentEditor.vue +++ b/chestnut-ui/src/views/cms/contentcore/contentEditor.vue @@ -80,7 +80,7 @@
- + + + +
diff --git a/chestnut-ui/src/views/cms/contentcore/siteInfo.vue b/chestnut-ui/src/views/cms/contentcore/siteInfo.vue index 8632646d..b41b7bcb 100644 --- a/chestnut-ui/src/views/cms/contentcore/siteInfo.vue +++ b/chestnut-ui/src/views/cms/contentcore/siteInfo.vue @@ -177,6 +177,12 @@ >{{ $t("Common.Select") }} + + + {{ $t('CMS.Site.PrefixMode_Absolute') }} + {{ $t('CMS.Site.PrefixMode_Relative') }} + +
diff --git a/chestnut-ui/src/views/cms/customform/index.vue b/chestnut-ui/src/views/cms/customform/index.vue index 2eac1e88..3e78c8e1 100644 --- a/chestnut-ui/src/views/cms/customform/index.vue +++ b/chestnut-ui/src/views/cms/customform/index.vue @@ -100,7 +100,7 @@