版本升级:V1.5.2

This commit is contained in:
liweiyi 2025-02-22 20:20:38 +08:00
parent 0e7b319498
commit 802a86abf6
82 changed files with 669 additions and 113 deletions

View File

@ -1,4 +1,4 @@
# ChestnutCMS v1.5.1
# ChestnutCMS v1.5.2
### 系统简介

View File

@ -3,7 +3,7 @@
<parent>
<artifactId>chestnut</artifactId>
<groupId>com.chestnut</groupId>
<version>1.5.1</version>
<version>1.5.2</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<packaging>jar</packaging>

View File

@ -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

View File

@ -5,7 +5,7 @@ chestnut:
# 代号
alias: ChestnutCMS
# 版本
version: 1.5.1
version: 1.5.2
# 版权年份
copyrightYear: 2022-2024
system:

View File

@ -5,7 +5,7 @@ chestnut:
# 代号
alias: ChestnutCMS
# 版本
version: 1.5.1
version: 1.5.2
# 版权年份
copyrightYear: 2022-2024
system:

View File

@ -0,0 +1,2 @@
ALTER TABLE cms_catalog MODIFY COLUMN `path` varchar(255);
ALTER TABLE cms_content MODIFY COLUMN `images` varchar(1000);

View File

@ -7,7 +7,7 @@
<parent>
<groupId>com.chestnut</groupId>
<artifactId>chestnut-cms</artifactId>
<version>1.5.1</version>
<version>1.5.2</version>
</parent>
<artifactId>chestnut-cms-advertisement</artifactId>

View File

@ -7,7 +7,7 @@
<parent>
<groupId>com.chestnut</groupId>
<artifactId>chestnut-cms</artifactId>
<version>1.5.1</version>
<version>1.5.2</version>
</parent>
<artifactId>chestnut-cms-article</artifactId>

View File

@ -7,7 +7,7 @@
<parent>
<groupId>com.chestnut</groupId>
<artifactId>chestnut-cms</artifactId>
<version>1.5.1</version>
<version>1.5.2</version>
</parent>
<artifactId>chestnut-cms-block</artifactId>

View File

@ -6,7 +6,7 @@
<parent>
<groupId>com.chestnut</groupId>
<artifactId>chestnut-cms</artifactId>
<version>1.5.1</version>
<version>1.5.2</version>
</parent>
<artifactId>chestnut-cms-comment</artifactId>

View File

@ -7,7 +7,7 @@
<parent>
<groupId>com.chestnut</groupId>
<artifactId>chestnut-cms</artifactId>
<version>1.5.1</version>
<version>1.5.2</version>
</parent>
<artifactId>chestnut-cms-contentcore</artifactId>

View File

@ -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<PublishPipePropUseType> getUseTypes() {
return List.of(PublishPipePropUseType.Site);
}
@Override
public String getDefaultValue() {
return SitePrefixMode.Absolute;
}
public static String getValue(String publishPipeCode, Map<String, Map<String, Object>> publishPipeProps) {
if (Objects.nonNull(publishPipeProps)) {
return MapUtils.getString(publishPipeProps.get(publishPipeCode), KEY);
}
return SitePrefixMode.Absolute;
}
}

View File

@ -153,7 +153,9 @@ public class CmsSite extends BaseEntity {
public String getUrl(String publishPipeCode) {
String ppUrl = PublishPipeProp_SiteUrl.getValue(publishPipeCode, this.publishPipeProps);
if (StringUtils.isNotBlank(ppUrl)) {
ppUrl = StringUtils.appendIfMissing(ppUrl, "/");
}
return Objects.requireNonNullElse(ppUrl, StringUtils.EMPTY);
}
}

View File

@ -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);
}
}

View File

@ -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();

View File

@ -75,7 +75,9 @@ public class SiteApiUrlProperty implements IProperty {
if (StringUtils.isEmpty(apiUrl)) {
apiUrl = site.getUrl(publishPipeCode);
}
if (StringUtils.isNotEmpty(apiUrl)) {
apiUrl = StringUtils.appendIfMissing(apiUrl, "/");
}
return apiUrl;
}
}

View File

@ -20,4 +20,5 @@ import com.chestnut.contentcore.domain.CmsContentRela;
public interface IContentRelaService extends IService<CmsContentRela> {
void onContentDelete(Long contentId);
}

View File

@ -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<CmsContentRelaMapper, CmsContentRela>
implements IContentRelaService {
@Override
public void onContentDelete(Long contentId) {
this.remove(new LambdaQueryWrapper<CmsContentRela>()
.eq(CmsContentRela::getContentId, contentId).or().eq(CmsContentRela::getRelaContentId, contentId));
}
}

View File

@ -119,7 +119,9 @@ public class SiteServiceImpl extends ServiceImpl<CmsSiteMapper, CmsSite> impleme
CmsSite site = new CmsSite();
site.setSiteId(IdUtils.getSnowflakeId());
BeanUtils.copyProperties(dto, site, "siteId");
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<CmsSiteMapper, CmsSite> impleme
CmsSite site = this.getById(dto.getSiteId());
BeanUtils.copyProperties(dto, site, "path");
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()));

View File

@ -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());

View File

@ -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);
}

View File

@ -7,7 +7,7 @@
<parent>
<groupId>com.chestnut</groupId>
<artifactId>chestnut-cms</artifactId>
<version>1.5.1</version>
<version>1.5.2</version>
</parent>
<artifactId>chestnut-cms-customform</artifactId>

View File

@ -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 <T> void decode(List<T> list, Function<T, String> getter, BiConsumer<T, String> setter) {

View File

@ -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);

View File

@ -7,7 +7,7 @@
<parent>
<groupId>com.chestnut</groupId>
<artifactId>chestnut-cms</artifactId>
<version>1.5.1</version>
<version>1.5.2</version>
</parent>
<artifactId>chestnut-cms-dynamic</artifactId>

View File

@ -7,7 +7,7 @@
<parent>
<groupId>com.chestnut</groupId>
<artifactId>chestnut-cms</artifactId>
<version>1.5.1</version>
<version>1.5.2</version>
</parent>
<artifactId>chestnut-cms-exmodel</artifactId>

View File

@ -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<String, IMetaControlType> controlTypeMap;
@Override
public List<TagAttr> 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));
}

View File

@ -7,7 +7,7 @@
<parent>
<groupId>com.chestnut</groupId>
<artifactId>chestnut-cms</artifactId>
<version>1.5.1</version>
<version>1.5.2</version>
</parent>
<artifactId>chestnut-cms-image</artifactId>

View File

@ -7,7 +7,7 @@
<parent>
<groupId>com.chestnut</groupId>
<artifactId>chestnut-cms</artifactId>
<version>1.5.1</version>
<version>1.5.2</version>
</parent>
<artifactId>chestnut-cms-link</artifactId>

View File

@ -7,7 +7,7 @@
<parent>
<groupId>com.chestnut</groupId>
<artifactId>chestnut-cms</artifactId>
<version>1.5.1</version>
<version>1.5.2</version>
</parent>
<artifactId>chestnut-cms-media</artifactId>

View File

@ -6,7 +6,7 @@
<parent>
<groupId>com.chestnut</groupId>
<artifactId>chestnut-cms</artifactId>
<version>1.5.1</version>
<version>1.5.2</version>
</parent>
<artifactId>chestnut-cms-member</artifactId>

View File

@ -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;
}
}

View File

@ -7,7 +7,7 @@
<parent>
<groupId>com.chestnut</groupId>
<artifactId>chestnut-cms</artifactId>
<version>1.5.1</version>
<version>1.5.2</version>
</parent>
<artifactId>chestnut-cms-search</artifactId>

View File

@ -7,7 +7,7 @@
<parent>
<groupId>com.chestnut</groupId>
<artifactId>chestnut-cms</artifactId>
<version>1.5.1</version>
<version>1.5.2</version>
</parent>
<artifactId>chestnut-cms-seo</artifactId>

View File

@ -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) {

View File

@ -7,7 +7,7 @@
<parent>
<groupId>com.chestnut</groupId>
<artifactId>chestnut-cms</artifactId>
<version>1.5.1</version>
<version>1.5.2</version>
</parent>
<artifactId>chestnut-cms-stat</artifactId>

View File

@ -7,7 +7,7 @@
<parent>
<groupId>com.chestnut</groupId>
<artifactId>chestnut-cms</artifactId>
<version>1.5.1</version>
<version>1.5.2</version>
</parent>
<artifactId>chestnut-cms-vote</artifactId>

View File

@ -7,7 +7,7 @@
<parent>
<groupId>com.chestnut</groupId>
<artifactId>chestnut-cms</artifactId>
<version>1.5.1</version>
<version>1.5.2</version>
</parent>
<artifactId>chestnut-cms-word</artifactId>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>com.chestnut</groupId>
<artifactId>chestnut</artifactId>
<version>1.5.1</version>
<version>1.5.2</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>chestnut-common</artifactId>
<groupId>com.chestnut</groupId>
<version>1.5.1</version>
<version>1.5.2</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -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<String, List<Map<String, ?>>> groupBy(List<Map<String, ?>> list, String groupBy) {
Map<String, List<Map<String, ?>>> map = new HashMap<>();
list.forEach(obj -> {
String key = obj.get(groupBy).toString();
List<Map<String, ?>> groupList = map.get(key);
if (Objects.isNull(groupList)) {
groupList = new ArrayList<>();
map.put(key, groupList);
}
groupList.add(obj);
});
return map;
}
public static <T> Map<String, List<T>> groupBy(List<T> list, Function<T, String> getter) {
Map<String, List<T>> map = new HashMap<>();
list.forEach(obj -> {
String key = getter.apply(obj);
List<T> groupList = map.get(key);
if (Objects.isNull(groupList)) {
groupList = new ArrayList<>();
map.put(key, groupList);
}
groupList.add(obj);
});
return map;
}
}

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>chestnut-common</artifactId>
<groupId>com.chestnut</groupId>
<version>1.5.1</version>
<version>1.5.2</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>chestnut-common</artifactId>
<groupId>com.chestnut</groupId>
<version>1.5.1</version>
<version>1.5.2</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>chestnut-common</artifactId>
<groupId>com.chestnut</groupId>
<version>1.5.1</version>
<version>1.5.2</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>chestnut-common</artifactId>
<groupId>com.chestnut</groupId>
<version>1.5.1</version>
<version>1.5.2</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>chestnut-common</artifactId>
<groupId>com.chestnut</groupId>
<version>1.5.1</version>
<version>1.5.2</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>chestnut-common</artifactId>
<groupId>com.chestnut</groupId>
<version>1.5.1</version>
<version>1.5.2</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -48,7 +48,7 @@ public class FreeMarkerConfig {
* </p>
*
* @param properties
* @param fileTemplateLoader
* @param templateLoaders
* @return
* @throws TemplateException
*/

View File

@ -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);
}
}

View File

@ -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<FuncArg> 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()));
}
}

View File

@ -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<FuncArg> getFuncArgs() {
return List.of(new FuncArg("URL", FuncArgType.String, true, null));
}
}

View File

@ -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<String, List<TemplateModel>> groupBy(TemplateSequenceModel list, String groupBy) throws TemplateModelException {
Map<String, List<TemplateModel>> 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<TemplateModel> groupList = map.get(key);
if (Objects.isNull(groupList)) {
groupList = new ArrayList<>();
map.put(key, groupList);
}
groupList.add(itemModel);
}
}
return map;
}
@Override
public List<FuncArg> getFuncArgs() {
return List.of(
new FuncArg(ARG1_NAME, FuncArgType.Array, true, ARG1_DESC),
new FuncArg(ARG2_NAME, FuncArgType.String, true, ARG2_DESC)
);
}
}

View File

@ -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}。
@ -43,3 +48,4 @@ FREEMARKER.ERR.INVALID_ATTR_VALUE2=标签 <@{0}> 属性值 `{1}` = `{2}` 无效
FREEMARKER.ERR.DUPLICATE_PAGE_FLAG=标签分页属性`page`不能被多次设置为true。
FREEMARKER.ERR.PAGE_INDEX_OUT_OF_BOUNDS=分页页码`{0}`超出最大页码`{1}`。
FREEMARKER.ERR.INVALID_FUNC_ARGUMENT=函数`{0}()`第{1}个参数错误:{2}。
FREEMARKER.ERR.IncludeTemplateNotFound=引用模板`{0}`不存在。

View File

@ -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}.
@ -43,3 +48,4 @@ FREEMARKER.ERR.INVALID_ATTR_VALUE2=The tag <@{0}> attribute value `{1}` = `{2}`
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}。
FREEMARKER.ERR.IncludeTemplateNotFound=Include template `{0}` not found.。

View File

@ -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}。
@ -43,3 +48,4 @@ FREEMARKER.ERR.INVALID_ATTR_VALUE2=標籤 <@{0}> 屬性值 `{1}` = `{2}` 无效
FREEMARKER.ERR.DUPLICATE_PAGE_FLAG=標籤分頁屬性`page`不能被多次設置為true。
FREEMARKER.ERR.PAGE_INDEX_OUT_OF_BOUNDS=分頁頁碼`{0}`超出最大頁碼`{1}`。
FREEMARKER.ERR.INVALID_FUNC_ARGUMENT=函數`{0}()`第{1}個參數錯誤:{2}。
FREEMARKER.ERR.IncludeTemplateNotFound=引用模板`{0}`不存在。

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>chestnut-common</artifactId>
<groupId>com.chestnut</groupId>
<version>1.5.1</version>
<version>1.5.2</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>com.chestnut</groupId>
<artifactId>chestnut</artifactId>
<version>1.5.1</version>
<version>1.5.2</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -3,7 +3,7 @@
<parent>
<artifactId>chestnut-modules</artifactId>
<groupId>com.chestnut</groupId>
<version>1.5.1</version>
<version>1.5.2</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>chestnut-modules</artifactId>
<groupId>com.chestnut</groupId>
<version>1.5.1</version>
<version>1.5.2</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -3,7 +3,7 @@
<parent>
<artifactId>chestnut-modules</artifactId>
<groupId>com.chestnut</groupId>
<version>1.5.1</version>
<version>1.5.2</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -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;
}

View File

@ -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;
}
}

View File

@ -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<MemberLevelConfigM
private final Map<String, ILevelType> levelTypes;
private Map<String, LevelManager> levelManagerMap = new HashMap<>();
private static final Map<String, LevelManager> levelManagerMap = new HashMap<>();
@Override
public void addLevelConfig(LevelConfigDTO dto) {
@ -87,9 +86,10 @@ public class MemberLevelConfigServiceImpl extends ServiceImpl<MemberLevelConfigM
}
@Override
@Transactional(rollbackFor = Exception.class)
public void deleteLevelConfig(List<Long> configIds) {
List<MemberLevelConfig> 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<MemberLevelConfigM
List<MemberLevelConfig> 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<MemberLevelConfigM
}
private LevelManager getLevelManager(ILevelType levelType) {
LevelManager levelManager = this.levelManagerMap.get(levelType.getId());
LevelManager levelManager = levelManagerMap.get(levelType.getId());
if (levelManager == null) {
levelManager = new LevelManager();
levelManager.setLevelType(levelType);
this.levelManagerMap.put(levelType.getId(), levelManager);
levelManagerMap.put(levelType.getId(), levelManager);
}
return levelManager;
}
@ -137,6 +137,6 @@ public class MemberLevelConfigServiceImpl extends ServiceImpl<MemberLevelConfigM
@Override
public void run(String... args) throws Exception {
levelTypes.values().forEach(levelType -> onLevelConfigChange(levelType));
levelTypes.values().forEach(this::onLevelConfigChange);
}
}

View File

@ -6,7 +6,7 @@
<parent>
<artifactId>chestnut-modules</artifactId>
<groupId>com.chestnut</groupId>
<version>1.5.1</version>
<version>1.5.2</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -6,7 +6,7 @@
<parent>
<groupId>com.chestnut</groupId>
<artifactId>chestnut-modules</artifactId>
<version>1.5.1</version>
<version>1.5.2</version>
</parent>
<artifactId>chestnut-monitor</artifactId>

View File

@ -3,7 +3,7 @@
<parent>
<artifactId>chestnut-modules</artifactId>
<groupId>com.chestnut</groupId>
<version>1.5.1</version>
<version>1.5.2</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -6,7 +6,7 @@
<parent>
<artifactId>chestnut-modules</artifactId>
<groupId>com.chestnut</groupId>
<version>1.5.1</version>
<version>1.5.2</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>chestnut-modules</artifactId>
<groupId>com.chestnut</groupId>
<version>1.5.1</version>
<version>1.5.2</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -3,7 +3,7 @@
<parent>
<artifactId>chestnut-modules</artifactId>
<groupId>com.chestnut</groupId>
<version>1.5.1</version>
<version>1.5.2</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -6,7 +6,7 @@
<parent>
<artifactId>chestnut-modules</artifactId>
<groupId>com.chestnut</groupId>
<version>1.5.1</version>
<version>1.5.2</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>com.chestnut</groupId>
<artifactId>chestnut</artifactId>
<version>1.5.1</version>
<version>1.5.2</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -1,6 +1,6 @@
{
"name": "ChestnutCMS",
"version": "1.5.1",
"version": "1.5.2",
"description": "ChestnutCMS[栗子内容管理系统]",
"author": "兮玥 - 190785909@qq.com",
"license": "Apache-2.0",

View File

@ -35,7 +35,7 @@
@row-dblclick="handleRowDblclick"
style="width:100%;line-height: normal;">
<el-table-column type="index" :label="$t('Common.RowNo')" width="50" />
<el-table-column :label="$t('CMS.Site.Name')" align="center" prop="name">
<el-table-column :label="$t('CMS.Site.Name')" prop="name">
<template slot-scope="scope">
<div slot="reference" class="name-wrapper">
<el-tag v-if="scope.row.siteId==currentSite" size="medium">{{ scope.row.name }}</el-tag>
@ -43,7 +43,7 @@
</div>
</template>
</el-table-column>
<el-table-column label="URL" align="center" width="300" prop="url" />
<el-table-column :label="$t('CMS.Site.Path')" width="260" prop="path" />
</el-table>
<pagination
v-show="total>0"

View File

@ -935,6 +935,9 @@ export default {
SitemapProgressTitle: "Generate sitemap task",
Domain: "URL",
UEditorCss: "UEditor CSS",
PrefixMode: "Prefix Mode",
PrefixMode_Absolute: "Absolute",
PrefixMode_Relative: "Relative",
Tab: {
Basic: "Basic Information",
Extend: "Extend Config",
@ -1003,7 +1006,8 @@ export default {
SEO: "SEO Configuration",
BaiduPushAccessSecret: "Baidu Push API Secret",
DownloadRemoteImage: "Enable Download Remote Image",
EnableSiteDeleteBackup: "Enable Site Delete Backup"
EnableSiteDeleteBackup: "Enable Site Delete Backup",
MemberResourceUrl: "Member Resource Domain",
},
Property: {
QueryPlaceholder: "Input name/code",
@ -1826,7 +1830,10 @@ export default {
Location: "Location",
Source: "Source",
ClientType: "Client Type",
LogTime: "Time"
LogTime: "Time",
Placeholder: {
Word: "Input search word"
}
},
WordStat: {
TabName: "Query Statistics",
@ -1908,9 +1915,36 @@ export default {
ConfirmApply: "Are you sure to apply for the certificate?",
Applying: "Waiting for certificate application...",
Authroizating: "Authorizating...",
Servers: "Synchronize to server",
Placeholder: {
Domain: "Input domain..."
}
},
ServerMachine: {
Name: "Server Name",
RemoteAddress: "Remote Addr.",
Host: "Host",
Port: "Port",
UserName: "Username",
KeyFile: "Login Key",
Passphrase: "Passphrase",
AddTitle: "Add Server",
EditTitle: "Eidt Server",
TestConnection: "Test Connection",
ConnectionSuccess: "Connect Success",
TestConnectionLoading: "Connecting...",
},
NginxConfig: {
Name: "Name",
Code: "Code",
Type: "Type",
ConfigText: "Configure",
Status: "Status",
Sync: "Synchronize to server",
ConfirmSync: "Are you sure to sync the config `{0}` to deploy servers?",
NginxNode: "Deploy Servers",
AddTitle: "Add nginx config",
EditTitle: "Edit nginx config",
}
}
};

View File

@ -935,6 +935,9 @@ export default {
SitemapProgressTitle: "生成Sitemap任务",
Domain: "站点域名",
UEditorCss: "文章编辑器CSS",
PrefixMode: "路径模式",
PrefixMode_Absolute: "绝对路径",
PrefixMode_Relative: "相对路径",
Tab: {
Basic: "基础信息",
Extend: "扩展配置",
@ -1003,7 +1006,8 @@ export default {
SEO: "搜索引擎优化配置",
BaiduPushAccessSecret: "百度收录API秘钥",
DownloadRemoteImage: "开启文章远程图片下载",
EnableSiteDeleteBackup: "开启站点删除备份"
EnableSiteDeleteBackup: "开启站点删除备份",
MemberResourceUrl: "会员资源访问域名",
},
Property: {
QueryPlaceholder: "输入名称/编码查询",
@ -1911,9 +1915,36 @@ export default {
ConfirmApply: "确认发起证书申请吗?",
Applying: "正在提交证书申请,请稍等...",
Authroizating: "正在验证,请稍等...",
Servers: "同步服务器",
Placeholder: {
Domain: "输入域名查询"
}
},
ServerMachine: {
Name: "服务器名称",
RemoteAddress: "服务器地址",
Host: "域名/IP地址",
Port: "端口",
UserName: "登录用户名",
KeyFile: "登录秘钥",
Passphrase: "秘钥密码",
AddTitle: "添加服务器信息",
EditTitle: "编辑服务器信息",
TestConnection: "测试连接",
ConnectionSuccess: "连接成功",
TestConnectionLoading: "正在尝试链接..."
},
NginxConfig: {
Name: "名称",
Code: "编码",
Type: "类型",
ConfigText: "自定义配置",
Status: "状态",
Sync: "同步配置",
ConfirmSync: "确认将配置`{0}`同步到关联服务器节点吗?",
NginxNode: "部署节点",
AddTitle: "添加配置",
EditTitle: "编辑配置信息",
}
}
};

View File

@ -935,6 +935,9 @@ export default {
SitemapProgressTitle: "生成Sitemap任務",
Domain: "站點域名",
UEditorCss: "文章編輯器CSS",
PrefixMode: "路徑模式",
PrefixMode_Absolute: "絕對路徑",
PrefixMode_Relative: "相對路徑",
Tab: {
Basic: "基礎資訊",
Extend: "擴展配置",
@ -1003,7 +1006,8 @@ export default {
SEO: "搜索引擎優化配置",
BaiduPushAccessSecret: "百度收錄API秘鑰",
DownloadRemoteImage: "開啟文章遠程圖片下載",
EnableSiteDeleteBackup: "開啟站點刪除備份"
EnableSiteDeleteBackup: "開啟站點刪除備份",
MemberResourceUrl: "會員資源訪問域名",
},
Property: {
QueryPlaceholder: "輸入名稱/編碼查詢",
@ -1827,6 +1831,9 @@ export default {
Source: "來源",
ClientType: "客戶端",
LogTime: "搜索時間",
Placeholder: {
Word: "輸入搜索詞查詢"
}
},
WordStat: {
TabName: "搜索詞",
@ -1908,9 +1915,36 @@ export default {
ConfirmApply: "確認發起證書申請嗎?",
Applying: "正在提交證書申請,請稍等...",
Authroizating: "正在驗證,請稍等...",
Servers: "同步服務器",
Placeholder: {
Domain: "輸入域名查詢"
}
},
ServerMachine: {
Name: "服务器名称",
RemoteAddress: "服务器地址",
Host: "域名/IP地址",
Port: "端口",
UserName: "登录用户名",
KeyFile: "登录秘钥",
Passphrase: "秘钥密码",
AddTitle: "添加服务器信息",
EditTitle: "编辑服务器信息",
TestConnection: "测试连接",
ConnectionSuccess: "连接成功",
TestConnectionLoading: "正在尝试链接...",
},
NginxConfig: {
Name: "名稱",
Code: "編碼",
Type: "類型",
ConfigText: "自定義配置",
Status: "狀態",
Sync: "同步配置",
ConfirmSync: "確認將配置`{0}`同步到關聯服務器節點嗎?",
NginxNode: "部署節點",
AddTitle: "添加配置",
EditTitle: "編輯配置信息",
}
}
};

View File

@ -177,7 +177,7 @@
</el-input>
</el-form-item>
<el-form-item :label="$t('CMS.Catalog.Desc')" prop="description">
<el-input v-model="form_info.description" type="textarea" maxlength="100" />
<el-input v-model="form_info.description" type="textarea" maxlength="250" />
</el-form-item>
<el-form-item :label="$t('CMS.Catalog.ContentPathRule')" prop="detailNameRule">
<el-select v-model="form_info.detailNameRule" :placeholder="$t('CMS.Catalog.ContentPathRule')">

View File

@ -80,7 +80,7 @@
<el-col class="pr10">
<el-card shadow="always" class="card-title">
<div class="art-title bg-purple-white">
<el-form-item :label="$t('CMS.Content.Title')" prop="title">
<el-form-item :label="$t('CMS.Content.Title')" prop="title" style="margin-bottom: 18px;">
<el-input
v-model="form.title"
maxlength="360"

View File

@ -85,6 +85,9 @@
<el-form-item :label="$t('CMS.Site.Extend.SiteApiUrl')" prop="SiteApiUrl">
<el-input v-model="form_extend.SiteApiUrl" placeholder="http(s)://"></el-input>
</el-form-item>
<el-form-item :label="$t('CMS.Site.Extend.MemberResourceUrl')" prop="MemberResourceUrl">
<el-input v-model="form_extend.MemberResourceUrl" placeholder="http(s)://"></el-input>
</el-form-item>
</el-card>
<el-card shadow="hover">
<div slot="header" class="clearfix">

View File

@ -177,6 +177,12 @@
>{{ $t("Common.Select") }}</el-button>
</el-input>
</el-form-item>
<el-form-item :label="$t('CMS.Site.PrefixMode')">
<el-radio-group v-model="pp.props.PrefixMode">
<el-radio-button label="absolute">{{ $t('CMS.Site.PrefixMode_Absolute') }}</el-radio-button>
<el-radio-button label="relative">{{ $t('CMS.Site.PrefixMode_Relative') }}</el-radio-button>
</el-radio-group>
</el-form-item>
</el-tab-pane>
</el-tabs>
<div v-else style="background-color: #f4f4f5;color: #909399;font-size:12px;line-height: 30px;padding-left:10px;">

View File

@ -100,7 +100,7 @@
<el-table-column
:label="$t('Common.Operation')"
align="right"
width="350"
width="380"
class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
@ -167,7 +167,7 @@
</el-option>
</el-select>
</el-form-item>
<el-form-item :label="$t('CMS.CustomForm.NeedCaptcha')" prop="needCaptcha">
<!-- <el-form-item :label="$t('CMS.CustomForm.NeedCaptcha')" prop="needCaptcha">
<el-switch
v-model="form.needCaptcha"
active-value="Y"
@ -180,7 +180,7 @@
active-value="Y"
inactive-value="N"
></el-switch>
</el-form-item>
</el-form-item> -->
<el-form-item v-if="form.needLogin=='N'" :label="$t('CMS.CustomForm.RuleLimit')" prop="ruleLimit">
<el-select v-model="form.ruleLimit">
<el-option

View File

@ -4,14 +4,14 @@
<groupId>com.chestnut</groupId>
<artifactId>chestnut</artifactId>
<version>1.5.1</version>
<version>1.5.2</version>
<packaging>pom</packaging>
<name>ChestnutCMS</name>
<description>栗子内容管理系统</description>
<properties>
<chestnut.version>1.5.1</chestnut.version>
<chestnut.version>1.5.2</chestnut.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>17</java.version>