版本更新:v1.4.3

This commit is contained in:
liweiyi 2024-03-25 12:03:05 +08:00
parent 175c582608
commit 0e19d56afd
146 changed files with 1226 additions and 801 deletions

View File

@ -1,4 +1,4 @@
# ChestnutCMS v1.4.2
# ChestnutCMS v1.4.3
### 系统简介
@ -12,8 +12,6 @@ ChestnutCMS是前后端分离的企业级内容管理系统。项目基于[RuoYi
企业站演示地址:<http://swikoon.1000mz.com>
> 企业演示站的静态资源已提交到仓库[chestnut-cms-wwwroot](https://gitee.com/liweiyi/chestnut-cms-wwwroot)。
资讯站演示地址:<http://news.1000mz.com>会员演示账号xxx333@126.com / a123456
图片站演示地址PC端<http://tpz.1000mz.com> 移动端:<http://mtpz.1000mz.com>
@ -27,6 +25,7 @@ ChestnutCMS是前后端分离的企业级内容管理系统。项目基于[RuoYi
- Maven 3.8+
- MySQL 8.0+
- Redis 5.x+
- NodeJS 16.20.2
### 主要技术框架

View File

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

View File

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

View File

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

View File

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

View File

@ -10,3 +10,5 @@ ALTER TABLE cc_hot_word_group ADD COLUMN owner VARCHAR(100);
ALTER TABLE cc_hot_word_group ADD COLUMN word_total bigint DEFAULT 0;
ALTER TABLE cc_hot_word ADD COLUMN owner VARCHAR(100);
UPDATE cc_hot_word_group SET word_total = (SELECT count(*) FROM cc_hot_word WHERE cc_hot_word.group_id=cc_hot_word_group.group_id);
UPDATE sys_memu set component = 'cms/word/word' WHERE menu_id = '2039';

View File

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

View File

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

View File

@ -131,6 +131,9 @@ public class ArticleContent extends AbstractContent<CmsArticleDetail> {
@Override
public String getFullText() {
if (this.getContentEntity().isLinkContent()) {
return super.getFullText();
}
return super.getFullText() + StringUtils.SPACE + HtmlUtils.clean(this.getExtendEntity().getContentHtml());
}

View File

@ -15,13 +15,12 @@
*/
package com.chestnut.article;
import java.util.List;
import com.chestnut.contentcore.core.IPublishPipeProp;
import org.springframework.stereotype.Component;
import com.chestnut.contentcore.core.IPublishPipeProp;
import java.util.List;
@Component
@Component(IPublishPipeProp.BEAN_PREFIX + PublishPipeProp_ArticleDetailTemplate.KEY)
public class PublishPipeProp_ArticleDetailTemplate implements IPublishPipeProp {
public static final String KEY = DetailTemplatePropPrefix + ArticleContentType.ID;

View File

@ -15,13 +15,12 @@
*/
package com.chestnut.article;
import java.util.List;
import com.chestnut.contentcore.core.IPublishPipeProp;
import org.springframework.stereotype.Component;
import com.chestnut.contentcore.core.IPublishPipeProp;
import java.util.List;
@Component
@Component(IPublishPipeProp.BEAN_PREFIX + PublishPipeProp_DefaultArticleDetailTemplate.KEY)
public class PublishPipeProp_DefaultArticleDetailTemplate implements IPublishPipeProp {
public static final String KEY = DefaultDetailTemplatePropPrefix + ArticleContentType.ID;

View File

@ -0,0 +1,67 @@
/*
* 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.article;
import com.alibaba.excel.util.StringUtils;
import com.chestnut.contentcore.core.IPublishPipeProp;
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_UEditorCss.KEY)
public class PublishPipeProp_UEditorCss implements IPublishPipeProp {
public static final String KEY = "ueditorCss";
@Override
public String getKey() {
return KEY;
}
@Override
public String getName() {
return "文章编辑器自定义样式";
}
@Override
public List<PublishPipePropUseType> getUseTypes() {
return List.of(PublishPipePropUseType.Site, PublishPipePropUseType.Catalog);
}
public static String getValue(
String publishPipeCode,
Map<String, Map<String, Object>> firstPublishPipeProps,
Map<String, Map<String, Object>> secondPublishPipeProps
) {
String v = StringUtils.EMPTY;
if (Objects.nonNull(firstPublishPipeProps)) {
v = MapUtils.getString(firstPublishPipeProps.get(publishPipeCode), KEY, StringUtils.EMPTY);
if (StringUtils.isEmpty(v) && Objects.nonNull(secondPublishPipeProps)) {
v = MapUtils.getString(secondPublishPipeProps.get(publishPipeCode), KEY, StringUtils.EMPTY);
}
}
return v;
}
}

View File

@ -16,15 +16,30 @@
package com.chestnut.article.controller;
import com.chestnut.article.PublishPipeProp_UEditorCss;
import com.chestnut.common.domain.R;
import com.chestnut.common.security.anno.Priv;
import com.chestnut.common.security.web.BaseRestController;
import com.chestnut.common.utils.StringUtils;
import com.chestnut.contentcore.config.CMSConfig;
import com.chestnut.contentcore.domain.CmsCatalog;
import com.chestnut.contentcore.domain.CmsSite;
import com.chestnut.contentcore.service.ICatalogService;
import com.chestnut.contentcore.service.IPublishPipeService;
import com.chestnut.contentcore.service.ISiteService;
import com.chestnut.system.security.AdminUserType;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;
/**
* <p>
* 前端控制器
* 文章前端控制器
* </p>
*
* @author 兮玥
@ -32,8 +47,31 @@ import org.springframework.web.bind.annotation.RestController;
*/
@Priv(type = AdminUserType.TYPE)
@RestController
@RequiredArgsConstructor
@RequestMapping("/cms/article")
public class ArticleController extends BaseRestController {
private final ISiteService siteService;
private final ICatalogService catalogService;
private final IPublishPipeService publishPipeService;
@GetMapping("/ueditor_css")
public R<?> getUEditorCss(@RequestParam Long catalogId) {
CmsCatalog catalog = catalogService.getCatalog(catalogId);
CmsSite site = siteService.getSite(catalog.getSiteId());
Map<String, String> data = new HashMap<>();
publishPipeService.getPublishPipes(site.getSiteId()).forEach(pp -> {
String value = PublishPipeProp_UEditorCss.getValue(pp.getCode(),
catalog.getPublishPipeProps(), site.getPublishPipeProps());
if (StringUtils.isNotEmpty(value)) {
value = CMSConfig.getResourcePreviewPrefix() + value;
}
data.put(pp.getCode(), value);
});
return R.ok(data);
}
}

View File

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

View File

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

View File

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

View File

@ -21,7 +21,6 @@ import com.chestnut.common.security.anno.Priv;
import com.chestnut.common.security.web.BaseRestController;
import com.chestnut.common.utils.Assert;
import com.chestnut.common.utils.IdUtils;
import com.chestnut.common.utils.ServletUtils;
import com.chestnut.common.utils.StringUtils;
import com.chestnut.contentcore.domain.CmsCatalog;
import com.chestnut.contentcore.domain.CmsPageWidget;
@ -41,7 +40,6 @@ import com.chestnut.contentcore.perms.SitePermissionType.SitePrivItem;
import com.chestnut.contentcore.service.ICatalogService;
import com.chestnut.contentcore.service.IPageWidgetService;
import com.chestnut.contentcore.service.ISiteService;
import com.chestnut.contentcore.util.CmsPrivUtils;
import com.chestnut.system.domain.SysPermission;
import com.chestnut.system.security.AdminUserType;
import com.chestnut.system.security.StpAdminUtil;
@ -130,20 +128,21 @@ public class CmsPermissionController extends BaseRestController {
@GetMapping("/site/options")
public R<?> getSiteOptions(@RequestParam String ownerType, @RequestParam String owner) {
SysPermission permissions = this.permissionService.getPermission(ownerType, owner);
Set<String> sitePermissionKeys = sitePermissionType.deserialize(permissions.getPermissions().get(sitePermissionType.getId()));
List<CmsSite> list = this.siteService.lambdaQuery()
.select(List.of(CmsSite::getSiteId, CmsSite::getName))
.list();
Set<String> permissionKeys = this.permissionService.getPermissionKeys(ownerType, owner, SitePermissionType.ID);
Set<String> inheritedPermissionKeys = this.permissionService.getInheritedPermissionKeys(ownerType, owner, SitePermissionType.ID);
sitePermissionKeys.addAll(inheritedPermissionKeys);
List<Map<String, Object>> list = this.siteService.lambdaQuery().select(List.of(CmsSite::getSiteId, CmsSite::getName))
.list().stream()
.filter(site -> sitePermissionKeys.contains(SitePrivItem.View.getPermissionKey(site.getSiteId())))
permissionKeys.addAll(inheritedPermissionKeys);
List<Map<String, Object>> data = list.stream()
.filter(site -> permissionKeys.contains(SitePrivItem.View.getPermissionKey(site.getSiteId())))
.map(site -> {
Map<String, Object> map = new HashMap<>();
map.put("id", site.getSiteId());
map.put("name", site.getName());
return map;
}).toList();
return this.bindDataTable(list);
return this.bindDataTable(data);
}
@GetMapping("/catalog")

View File

@ -66,6 +66,7 @@ import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@ -97,10 +98,12 @@ public class ContentController extends BaseRestController {
* 内容列表
*/
@GetMapping("/list")
public R<?> listData(@RequestParam(name = "catalogId", required = false) Long catalogId,
@RequestParam(name = "title", required = false, defaultValue = "") String title,
@RequestParam(name = "contentType", required = false, defaultValue = "") String contentType,
@RequestParam(name = "status", required = false) String status) {
public R<?> listData(@RequestParam(required = false) Long catalogId,
@RequestParam(required = false) String title,
@RequestParam(required = false) String contentType,
@RequestParam(required = false) String status,
@RequestParam(required = false) LocalDateTime beginTime,
@RequestParam(required = false) LocalDateTime endTime) {
LoginUser loginUser = StpAdminUtil.getLoginUser();
if (!IdUtils.validate(catalogId)
|| !loginUser.hasPermission(CatalogPrivItem.View.getPermissionKey(catalogId))) {
@ -114,7 +117,9 @@ public class ContentController extends BaseRestController {
.eq(CmsContent::getSiteId, site.getSiteId())
.eq(StringUtils.isNotEmpty(contentType), CmsContent::getContentType, contentType)
.like(StringUtils.isNotEmpty(title), CmsContent::getTitle, title)
.eq(StringUtils.isNotEmpty(status), CmsContent::getStatus, status);
.eq(StringUtils.isNotEmpty(status), CmsContent::getStatus, status)
.ge(Objects.nonNull(beginTime), CmsContent::getCreateTime, beginTime)
.le(Objects.nonNull(endTime), CmsContent::getCreateTime, endTime);
if (includeChild) {
CmsCatalog catalog = this.catalogService.getCatalog(catalogId);
q.like(CmsContent::getCatalogAncestors, catalog.getAncestors());

View File

@ -15,22 +15,7 @@
*/
package com.chestnut.contentcore.controller;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import cn.dev33.satoken.annotation.SaMode;
import com.chestnut.contentcore.config.CMSConfig;
import com.chestnut.contentcore.util.CmsPrivUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import com.chestnut.common.domain.R;
import com.chestnut.common.domain.TreeNode;
import com.chestnut.common.exception.CommonErrorCode;
@ -40,16 +25,24 @@ import com.chestnut.common.security.anno.Priv;
import com.chestnut.common.security.web.BaseRestController;
import com.chestnut.common.utils.Assert;
import com.chestnut.common.utils.ServletUtils;
import com.chestnut.contentcore.config.CMSConfig;
import com.chestnut.contentcore.domain.CmsSite;
import com.chestnut.contentcore.domain.dto.FileAddDTO;
import com.chestnut.contentcore.domain.dto.FileOperateDTO;
import com.chestnut.contentcore.perms.ContentCorePriv;
import com.chestnut.contentcore.service.IFileService;
import com.chestnut.contentcore.service.ISiteService;
import com.chestnut.contentcore.util.CmsPrivUtils;
import com.chestnut.system.security.AdminUserType;
import jakarta.validation.constraints.NotEmpty;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.util.List;
import java.util.Map;
/**
* 文件管理
@ -74,21 +67,18 @@ public class FileController extends BaseRestController {
/**
* 查询文件列表
*
* @param filePath
* @param filename
* @return
* @param filePath 文件目录路径
* @param fileName 文件名
*/
@GetMapping("/list")
public R<?> getFileList(@RequestParam("filePath") @NotEmpty String filePath,
@RequestParam("fileName") String filename) {
public R<?> getFileList(@RequestParam @NotEmpty String filePath,
@RequestParam(required = false, defaultValue = "") String fileName) {
CmsSite site = this.siteService.getCurrentSite(ServletUtils.getRequest());
return this.fileService.getSiteFileList(site, filePath, filename);
return this.fileService.getSiteFileList(site, filePath, fileName);
}
/**
* 获取目录树数据
*
* @return
*/
@GetMapping("/directoryTreeData")
public R<?> getDirectoryTree() {
@ -151,7 +141,7 @@ public class FileController extends BaseRestController {
* @return
* @throws IOException
*/
@Log(title = "读取文", businessType = BusinessType.OTHER)
@Log(title = "读取文", businessType = BusinessType.OTHER)
@PostMapping("/read")
public R<?> readFile(@RequestBody @Validated FileOperateDTO dto) throws IOException {
CmsSite site = this.siteService.getCurrentSite(ServletUtils.getRequest());

View File

@ -27,6 +27,8 @@ import com.chestnut.common.utils.StringUtils;
*/
public interface IPublishPipeProp {
String BEAN_PREFIX = "PublishPipeProp_";
String DetailTemplatePropPrefix = "detailTemplate_";
String DefaultDetailTemplatePropPrefix = "defaultDetailTemplate_";

View File

@ -35,7 +35,7 @@ import java.util.Objects;
* @author 兮玥
* @email 190785909@qq.com
*/
@Component
@Component(IPublishPipeProp.BEAN_PREFIX + PublishPipeProp_ContentExTemplate.KEY)
public class PublishPipeProp_ContentExTemplate implements IPublishPipeProp {
public static final String KEY = "contentExTemplate";

View File

@ -15,14 +15,13 @@
*/
package com.chestnut.contentcore.core.impl;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import com.chestnut.contentcore.core.IPublishPipeProp;
import org.apache.commons.collections4.MapUtils;
import org.springframework.stereotype.Component;
import com.chestnut.contentcore.core.IPublishPipeProp;
import java.util.List;
import java.util.Map;
import java.util.Objects;
/**
* 发布通道属性内容自定义模板
@ -30,7 +29,7 @@ import com.chestnut.contentcore.core.IPublishPipeProp;
* @author 兮玥
* @email 190785909@qq.com
*/
@Component
@Component(IPublishPipeProp.BEAN_PREFIX + PublishPipeProp_ContentTemplate.KEY)
public class PublishPipeProp_ContentTemplate implements IPublishPipeProp {
public static final String KEY = "template";

View File

@ -15,14 +15,13 @@
*/
package com.chestnut.contentcore.core.impl;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import com.chestnut.contentcore.core.IPublishPipeProp;
import org.apache.commons.collections4.MapUtils;
import org.springframework.stereotype.Component;
import com.chestnut.contentcore.core.IPublishPipeProp;
import java.util.List;
import java.util.Map;
import java.util.Objects;
/**
* 发布通道属性栏目列表页默认模板
@ -30,7 +29,7 @@ import com.chestnut.contentcore.core.IPublishPipeProp;
* @author 兮玥
* @email 190785909@qq.com
*/
@Component
@Component(IPublishPipeProp.BEAN_PREFIX + PublishPipeProp_DefaultListTemplate.KEY)
public class PublishPipeProp_DefaultListTemplate implements IPublishPipeProp {
public static final String KEY = "defaultListTemplate";

View File

@ -15,14 +15,13 @@
*/
package com.chestnut.contentcore.core.impl;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import com.chestnut.contentcore.core.IPublishPipeProp;
import org.apache.commons.collections4.MapUtils;
import org.springframework.stereotype.Component;
import com.chestnut.contentcore.core.IPublishPipeProp;
import java.util.List;
import java.util.Map;
import java.util.Objects;
/**
* 发布通道属性首页模板
@ -30,7 +29,7 @@ import com.chestnut.contentcore.core.IPublishPipeProp;
* @author 兮玥
* @email 190785909@qq.com
*/
@Component
@Component(IPublishPipeProp.BEAN_PREFIX + PublishPipeProp_IndexTemplate.KEY)
public class PublishPipeProp_IndexTemplate implements IPublishPipeProp {
public static final String KEY = "indexTemplate";

View File

@ -15,14 +15,13 @@
*/
package com.chestnut.contentcore.core.impl;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import com.chestnut.contentcore.core.IPublishPipeProp;
import org.apache.commons.collections4.MapUtils;
import org.springframework.stereotype.Component;
import com.chestnut.contentcore.core.IPublishPipeProp;
import java.util.List;
import java.util.Map;
import java.util.Objects;
/**
* 发布通道属性栏目列表页模板
@ -30,7 +29,7 @@ import com.chestnut.contentcore.core.IPublishPipeProp;
* @author 兮玥
* @email 190785909@qq.com
*/
@Component
@Component(IPublishPipeProp.BEAN_PREFIX + PublishPipeProp_ListTemplate.KEY)
public class PublishPipeProp_ListTemplate implements IPublishPipeProp {
public static final String KEY = "listTemplate";

View File

@ -15,14 +15,13 @@
*/
package com.chestnut.contentcore.core.impl;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import com.chestnut.contentcore.core.IPublishPipeProp;
import org.apache.commons.collections4.MapUtils;
import org.springframework.stereotype.Component;
import com.chestnut.contentcore.core.IPublishPipeProp;
import java.util.List;
import java.util.Map;
import java.util.Objects;
/**
* 发布通道属性站点域名
@ -30,7 +29,7 @@ import com.chestnut.contentcore.core.IPublishPipeProp;
* @author 兮玥
* @email 190785909@qq.com
*/
@Component
@Component(IPublishPipeProp.BEAN_PREFIX + PublishPipeProp_SiteUrl.KEY)
public class PublishPipeProp_SiteUrl implements IPublishPipeProp {
public static final String KEY = "url";

View File

@ -15,15 +15,14 @@
*/
package com.chestnut.contentcore.core.impl;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import com.chestnut.contentcore.core.IPublishPipeProp;
import com.chestnut.contentcore.fixed.dict.StaticSuffix;
import org.apache.commons.collections4.MapUtils;
import org.springframework.stereotype.Component;
import com.chestnut.contentcore.core.IPublishPipeProp;
import com.chestnut.contentcore.fixed.dict.StaticSuffix;
import java.util.List;
import java.util.Map;
import java.util.Objects;
/**
* 发布通道属性静态文件类型
@ -31,7 +30,7 @@ import com.chestnut.contentcore.fixed.dict.StaticSuffix;
* @author 兮玥
* @email 190785909@qq.com
*/
@Component
@Component(IPublishPipeProp.BEAN_PREFIX + PublishPipeProp_StaticSuffix.KEY)
public class PublishPipeProp_StaticSuffix implements IPublishPipeProp {
public static final String KEY = "staticSuffix";

View File

@ -222,6 +222,26 @@ public class ContentDTO {
private String status;
/**
* 备用字段1
*/
private String prop1;
/**
* 备用字段2
*/
private String prop2;
/**
* 备用字段3
*/
private String prop3;
/**
* 备用字段4
*/
private String prop4;
public static ContentDTO newInstance(CmsContent cmsContent) {
ContentDTO dto = new ContentDTO();
BeanUtils.copyProperties(cmsContent, dto);

View File

@ -15,71 +15,69 @@
*/
package com.chestnut.contentcore.service;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import com.baomidou.mybatisplus.extension.service.IService;
import com.chestnut.contentcore.core.IPublishPipeProp.PublishPipePropUseType;
import com.chestnut.contentcore.domain.CmsPublishPipe;
import com.chestnut.contentcore.domain.CmsSite;
import com.chestnut.contentcore.domain.dto.PublishPipeProp;
import java.io.IOException;
import java.util.List;
import java.util.Map;
public interface IPublishPipeService extends IService<CmsPublishPipe> {
/**
* 新增发布通道数据
*
* @param publishPipe
* @throws IOException
* @param publishPipe 发布通道信息
*/
public void addPublishPipe(CmsPublishPipe publishPipe) throws IOException;
void addPublishPipe(CmsPublishPipe publishPipe) throws IOException;
/**
* 修改发布通道数据
*
* @param publishPipe
* @throws IOException
* @param publishPipe 发布通道信息
*/
public void savePublishPipe(CmsPublishPipe publishPipe) throws IOException;
void savePublishPipe(CmsPublishPipe publishPipe) throws IOException;
/**
* 删除发布通道
*
* @param publishPipeId
* @throws IOException
* @param publishPipeId 发布通道ID
*/
public void deletePublishPipe(List<Long> publishPipeId);
void deletePublishPipe(List<Long> publishPipeId);
/**
* 删除指定站点发布通道
*
* @param site
* @throws IOException
* @param site 站点信息
*/
public void deletePublishPipeBySite(CmsSite site);
void deletePublishPipeBySite(CmsSite site);
/**
* 获取指定站点可用发布通道
*
* @param siteId
* @param siteId 站点ID
* @return 结果列表
*/
public List<CmsPublishPipe> getPublishPipes(Long siteId);
List<CmsPublishPipe> getPublishPipes(Long siteId);
/**
* 获取指定站点所有发布通道
*
* @param siteId
* @param siteId 站点ID
* @return 结果列表
*/
public List<CmsPublishPipe> getAllPublishPipes(Long siteId);
List<CmsPublishPipe> getAllPublishPipes(Long siteId);
/**
* 获取站点下指定使用场景的发布通道数据列表
*
* @param siteId
* @param useType
* @param props
* @return
* @param siteId 站点ID
* @param useType 使用方式
* @param props 数据集合
* @return 结果列表
*/
List<PublishPipeProp> getPublishPipeProps(Long siteId, PublishPipePropUseType useType,
Map<String, Map<String, Object>> props);
@ -87,10 +85,10 @@ public interface IPublishPipeService extends IService<CmsPublishPipe> {
/**
* 获取发布通道属性值
*
* @param propKey
* @param publishPipeCode
* @param props
* @return
* @param propKey 发布通道属性唯一标识
* @param publishPipeCode 发布通道编码
* @param props 数据集合
* @return 属性值
*/
String getPublishPipePropValue(String propKey, String publishPipeCode, Map<String, Map<String, Object>> props);
}

View File

@ -66,15 +66,16 @@ public class PublishPipeServiceImpl extends ServiceImpl<CmsPublishPipeMapper, Cm
/**
* 获取站点下指定使用场景的发布通道数据列表
*
* @param siteId
* @param useType
* @param props
* @return
* @param siteId 站点ID
* @param useType 使用类型
* @param props 数据集合
* @return 结果
*/
@Override
public List<PublishPipeProp> getPublishPipeProps(Long siteId, PublishPipePropUseType useType,
Map<String, Map<String, Object>> props) {
List<IPublishPipeProp> list = this.publishPipeProps.stream().filter(p -> p.getUseTypes().contains(useType))
List<IPublishPipeProp> list = this.publishPipeProps.stream()
.filter(p -> p.getUseTypes().contains(useType))
.toList();
return this.getPublishPipes(siteId).stream().map(pp -> {
PublishPipeProp prop = PublishPipeProp.newInstance(pp.getCode(), pp.getName(),
@ -98,7 +99,8 @@ public class PublishPipeServiceImpl extends ServiceImpl<CmsPublishPipeMapper, Cm
return value;
}
}
Optional<IPublishPipeProp> opt = this.publishPipeProps.stream().filter(p -> p.getKey().equals(propKey)).findFirst();
Optional<IPublishPipeProp> opt = this.publishPipeProps.stream()
.filter(p -> p.getKey().equals(propKey)).findFirst();
if (opt.isPresent()) {
return opt.get().getDefaultValue();
} else {
@ -128,7 +130,7 @@ public class PublishPipeServiceImpl extends ServiceImpl<CmsPublishPipeMapper, Cm
private static final String DEFAULT_INDEX_TEMPLATE_CONTENT = """
<html>
<head>
<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>${Site.name}</title>
</head>
<body>

View File

@ -89,7 +89,19 @@ public class PublishServiceImpl implements IPublishService, ApplicationContextAw
@Override
public String getSitePageData(CmsSite site, String publishPipeCode, boolean isPreview)
throws IOException, TemplateException {
TemplateContext context = this.generateSiteTemplateContext(site, publishPipeCode, isPreview);
String indexTemplate = site.getIndexTemplate(publishPipeCode);
File templateFile = this.templateService.findTemplateFile(site, indexTemplate, publishPipeCode);
if (Objects.isNull(templateFile)) {
throw ContentCoreErrorCode.TEMPLATE_EMPTY.exception(publishPipeCode, indexTemplate);
}
// 模板ID = 通道:站点目录:模板文件名
String templateKey = SiteUtils.getTemplateKey(site, publishPipeCode, indexTemplate);
TemplateContext context = new TemplateContext(templateKey, isPreview, publishPipeCode);
// init template datamode
TemplateUtils.initGlobalVariables(site, context);
// init templateType data to datamode
ITemplateType templateType = templateService.getTemplateType(SiteTemplateType.TypeId);
templateType.initTemplateData(site.getSiteId(), context);
long s = System.currentTimeMillis();
try (StringWriter writer = new StringWriter()) {
@ -201,12 +213,27 @@ public class PublishServiceImpl implements IPublishService, ApplicationContextAw
try {
AsyncTaskManager
.setTaskMessage(StringUtils.messageFormat("[{0}]正在发布站点首页:{1}", publishPipeCode, site.getName()));
TemplateContext templateContext = this.generateSiteTemplateContext(site, publishPipeCode, false);
String indexTemplate = site.getIndexTemplate(publishPipeCode);
File templateFile = this.templateService.findTemplateFile(site, indexTemplate, publishPipeCode);
if (Objects.isNull(templateFile)) {
logger.warn(AsyncTaskManager.addErrMessage(StringUtils.messageFormat("[{0}]站点首页模板未配置或不存在:{1}",
publishPipeCode, site.getSiteId() + "#" + site.getName())));
return;
}
// 模板ID = 通道:站点目录:模板文件名
String templateKey = SiteUtils.getTemplateKey(site, publishPipeCode, indexTemplate);
TemplateContext context = new TemplateContext(templateKey, false, publishPipeCode);
// init template datamode
TemplateUtils.initGlobalVariables(site, context);
// init templateType data to datamode
ITemplateType templateType = templateService.getTemplateType(SiteTemplateType.TypeId);
templateType.initTemplateData(site.getSiteId(), context);
long s = System.currentTimeMillis();
templateContext.setDirectory(SiteUtils.getSiteRoot(site, publishPipeCode));
templateContext.setFirstFileName("index" + StringUtils.DOT + site.getStaticSuffix(publishPipeCode));
this.staticizeService.process(templateContext);
context.setDirectory(SiteUtils.getSiteRoot(site, publishPipeCode));
context.setFirstFileName("index" + StringUtils.DOT + site.getStaticSuffix(publishPipeCode));
this.staticizeService.process(context);
logger.debug("[{}]首页模板解析:{},耗时:{}ms", publishPipeCode, site.getName(), (System.currentTimeMillis() - s));
} catch (Exception e) {
logger.error(AsyncTaskManager.addErrMessage(StringUtils.messageFormat("[{0}][{1}]站点首页解析失败:{2}",
@ -214,23 +241,6 @@ public class PublishServiceImpl implements IPublishService, ApplicationContextAw
}
}
private TemplateContext generateSiteTemplateContext(CmsSite site, String publishPipeCode, boolean isPreview) {
String indexTemplate = site.getIndexTemplate(publishPipeCode);
File templateFile = this.templateService.findTemplateFile(site, indexTemplate, publishPipeCode);
Assert.notNull(templateFile,
() -> ContentCoreErrorCode.TEMPLATE_EMPTY.exception(publishPipeCode, indexTemplate));
// 模板ID = 通道:站点目录:模板文件名
String templateKey = SiteUtils.getTemplateKey(site, publishPipeCode, indexTemplate);
TemplateContext templateContext = new TemplateContext(templateKey, isPreview, publishPipeCode);
// init template datamode
TemplateUtils.initGlobalVariables(site, templateContext);
// init templateType data to datamode
ITemplateType templateType = templateService.getTemplateType(SiteTemplateType.TypeId);
templateType.initTemplateData(site.getSiteId(), templateContext);
return templateContext;
}
@Override
public String getCatalogPageData(CmsCatalog catalog, int pageIndex, boolean listFlag, String publishPipeCode, boolean isPreview)
throws IOException, TemplateException {
@ -712,7 +722,7 @@ public class PublishServiceImpl implements IPublishService, ApplicationContextAw
}
File templateFile = this.templateService.findTemplateFile(site, exTemplate, publishPipeCode);
if (templateFile == null) {
logger.warn("[{}]栏目[{}#{}]扩展模板未设置或文件不存在", publishPipeCode, catalog.getName(), content.getTitle());
logger.warn("[{}]内容[{}#{}]扩展模板未设置或文件不存在", publishPipeCode, catalog.getName(), content.getTitle());
return;
}
try {
@ -775,8 +785,10 @@ public class PublishServiceImpl implements IPublishService, ApplicationContextAw
CmsPageWidget pw = pageWidget.getPageWidgetEntity();
CmsSite site = this.siteService.getSite(pw.getSiteId());
File templateFile = this.templateService.findTemplateFile(site, pw.getTemplate(), pw.getPublishPipeCode());
Assert.notNull(templateFile, () -> new RuntimeException(
StringUtils.messageFormat("页面部件【{0}%s#{1}%s】模板未配置或文件不存在", pw.getName(), pw.getCode())));
if (Objects.isNull(templateFile)) {
logger.warn(StringUtils.messageFormat("页面部件【{0}%s#{1}%s】模板未配置或文件不存在", pw.getName(), pw.getCode()));
return;
}
try {
// 静态化目录
String dirPath = SiteUtils.getSiteRoot(site, pw.getPublishPipeCode()) + pw.getPath();

View File

@ -25,6 +25,7 @@ import com.chestnut.common.utils.file.FileExUtils;
import com.chestnut.contentcore.ContentCoreConsts;
import com.chestnut.contentcore.config.CMSConfig;
import com.chestnut.contentcore.core.IProperty;
import com.chestnut.contentcore.core.IPublishPipeProp;
import com.chestnut.contentcore.domain.CmsSite;
import com.chestnut.contentcore.domain.dto.PublishPipeProp;
import com.chestnut.contentcore.domain.dto.SiteDTO;
@ -69,6 +70,8 @@ public class SiteServiceImpl extends ServiceImpl<CmsSiteMapper, CmsSite> impleme
private final ISysPermissionService permissionService;
private final Map<String, IPublishPipeProp> publishPipeProps;
private final RedisCache redisCache;
@Override
@ -146,6 +149,9 @@ public class SiteServiceImpl extends ServiceImpl<CmsSiteMapper, CmsSite> impleme
site.setResourceUrl(site.getResourceUrl() + "/");
}
// 发布通道数据处理
dto.getPublishPipeDatas().forEach(prop -> {
prop.getProps().entrySet().removeIf(e -> !publishPipeProps.containsKey(IPublishPipeProp.BEAN_PREFIX + e.getKey()));
});
Map<String, Map<String, Object>> publishPipeProps = dto.getPublishPipeDatas().stream()
.collect(Collectors.toMap(PublishPipeProp::getPipeCode, PublishPipeProp::getProps));
site.setPublishPipeProps(publishPipeProps);

View File

@ -69,4 +69,9 @@ public class InternalUrlFunction extends AbstractFunc {
public List<FuncArg> getFuncArgs() {
return List.of(new FuncArg("内部链接", FuncArgType.String, true, null));
}
@Override
public List<String> getAliases() {
return List.of("iurl");
}
}

View File

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

View File

@ -29,7 +29,7 @@ import java.util.Objects;
* @author 兮玥
* @email 190785909@qq.com
*/
@Component
@Component(IPublishPipeProp.BEAN_PREFIX + PublishPipeProp_CustomFormTemplate.KEY)
public class PublishPipeProp_CustomFormTemplate implements IPublishPipeProp {
public static final String KEY = "defaultCustomFormTemplate";

View File

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

View File

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

View File

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

View File

@ -15,13 +15,12 @@
*/
package com.chestnut.cms.image;
import java.util.List;
import com.chestnut.contentcore.core.IPublishPipeProp;
import org.springframework.stereotype.Component;
import com.chestnut.contentcore.core.IPublishPipeProp;
import java.util.List;
@Component
@Component(IPublishPipeProp.BEAN_PREFIX + PublishPipeProp_DefaultImageDetailTemplate.KEY)
public class PublishPipeProp_DefaultImageDetailTemplate implements IPublishPipeProp {
public static final String KEY = DefaultDetailTemplatePropPrefix + ImageContentType.ID;

View File

@ -15,13 +15,12 @@
*/
package com.chestnut.cms.image;
import java.util.List;
import com.chestnut.contentcore.core.IPublishPipeProp;
import org.springframework.stereotype.Component;
import com.chestnut.contentcore.core.IPublishPipeProp;
import java.util.List;
@Component
@Component(IPublishPipeProp.BEAN_PREFIX + PublishPipeProp_ImageDetailTemplate.KEY)
public class PublishPipeProp_ImageDetailTemplate implements IPublishPipeProp {
public static final String KEY = DetailTemplatePropPrefix + ImageContentType.ID;

View File

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

View File

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

View File

@ -15,14 +15,13 @@
*/
package com.chestnut.media.publishpipe.prop;
import java.util.List;
import org.springframework.stereotype.Component;
import com.chestnut.contentcore.core.IPublishPipeProp;
import com.chestnut.media.AudioContentType;
import org.springframework.stereotype.Component;
@Component
import java.util.List;
@Component(IPublishPipeProp.BEAN_PREFIX + PublishPipeProp_AudioDetailTemplate.KEY)
public class PublishPipeProp_AudioDetailTemplate implements IPublishPipeProp {
public static final String KEY = DetailTemplatePropPrefix + AudioContentType.ID;

View File

@ -15,14 +15,13 @@
*/
package com.chestnut.media.publishpipe.prop;
import java.util.List;
import org.springframework.stereotype.Component;
import com.chestnut.contentcore.core.IPublishPipeProp;
import com.chestnut.media.AudioContentType;
import org.springframework.stereotype.Component;
@Component
import java.util.List;
@Component(IPublishPipeProp.BEAN_PREFIX + PublishPipeProp_DefaultAudioDetailTemplate.KEY)
public class PublishPipeProp_DefaultAudioDetailTemplate implements IPublishPipeProp {
public static final String KEY = DefaultDetailTemplatePropPrefix + AudioContentType.ID;

View File

@ -15,14 +15,13 @@
*/
package com.chestnut.media.publishpipe.prop;
import java.util.List;
import org.springframework.stereotype.Component;
import com.chestnut.contentcore.core.IPublishPipeProp;
import com.chestnut.media.VideoContentType;
import org.springframework.stereotype.Component;
@Component
import java.util.List;
@Component(IPublishPipeProp.BEAN_PREFIX + PublishPipeProp_DefaultVideoDetailTemplate.KEY)
public class PublishPipeProp_DefaultVideoDetailTemplate implements IPublishPipeProp {
public static final String KEY = DefaultDetailTemplatePropPrefix + VideoContentType.ID;

View File

@ -15,14 +15,13 @@
*/
package com.chestnut.media.publishpipe.prop;
import java.util.List;
import org.springframework.stereotype.Component;
import com.chestnut.contentcore.core.IPublishPipeProp;
import com.chestnut.media.VideoContentType;
import org.springframework.stereotype.Component;
@Component
import java.util.List;
@Component(IPublishPipeProp.BEAN_PREFIX + PublishPipeProp_VideoDetailTemplate.KEY)
public class PublishPipeProp_VideoDetailTemplate implements IPublishPipeProp {
public static final String KEY = DetailTemplatePropPrefix + VideoContentType.ID;

View File

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

View File

@ -23,7 +23,7 @@ import java.util.List;
import java.util.Map;
import java.util.Objects;
@Component
@Component(IPublishPipeProp.BEAN_PREFIX + PublishPipeProp_AccountCentreTemplate.KEY)
public class PublishPipeProp_AccountCentreTemplate implements IPublishPipeProp {
public static final String KEY = "accountCentreTemplate";

View File

@ -23,7 +23,7 @@ import java.util.List;
import java.util.Map;
import java.util.Objects;
@Component
@Component(IPublishPipeProp.BEAN_PREFIX + PublishPipeProp_MemberBindEmailTemplate.KEY)
public class PublishPipeProp_MemberBindEmailTemplate implements IPublishPipeProp {
public static final String KEY = "memberBindEmailTemplate";

View File

@ -23,7 +23,7 @@ import java.util.List;
import java.util.Map;
import java.util.Objects;
@Component
@Component(IPublishPipeProp.BEAN_PREFIX + PublishPipeProp_MemberContributeTemplate.KEY)
public class PublishPipeProp_MemberContributeTemplate implements IPublishPipeProp {
public static final String KEY = "memberContributeTemplate";

View File

@ -23,7 +23,7 @@ import java.util.List;
import java.util.Map;
import java.util.Objects;
@Component
@Component(IPublishPipeProp.BEAN_PREFIX + PublishPipeProp_MemberForgetPasswordTemplate.KEY)
public class PublishPipeProp_MemberForgetPasswordTemplate implements IPublishPipeProp {
public static final String KEY = "memberForgetPasswordTemplate";

View File

@ -23,7 +23,7 @@ import java.util.List;
import java.util.Map;
import java.util.Objects;
@Component
@Component(IPublishPipeProp.BEAN_PREFIX + PublishPipeProp_MemberLoginTemplate.KEY)
public class PublishPipeProp_MemberLoginTemplate implements IPublishPipeProp {
public static final String KEY = "memberLoginTemplate";

View File

@ -23,7 +23,7 @@ import java.util.List;
import java.util.Map;
import java.util.Objects;
@Component
@Component(IPublishPipeProp.BEAN_PREFIX + PublishPipeProp_MemberPasswordTemplate.KEY)
public class PublishPipeProp_MemberPasswordTemplate implements IPublishPipeProp {
public static final String KEY = "memberPasswordTemplate";

View File

@ -23,7 +23,7 @@ import java.util.List;
import java.util.Map;
import java.util.Objects;
@Component
@Component(IPublishPipeProp.BEAN_PREFIX + PublishPipeProp_MemberRegisterTemplate.KEY)
public class PublishPipeProp_MemberRegisterTemplate implements IPublishPipeProp {
public static final String KEY = "memberRegisterTemplate";

View File

@ -23,7 +23,7 @@ import java.util.List;
import java.util.Map;
import java.util.Objects;
@Component
@Component(IPublishPipeProp.BEAN_PREFIX + PublishPipeProp_MemberSettingTemplate.KEY)
public class PublishPipeProp_MemberSettingTemplate implements IPublishPipeProp {
public static final String KEY = "memberSettingTemplate";

View File

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

View File

@ -48,6 +48,7 @@ import com.chestnut.search.SearchConsts;
import com.chestnut.search.exception.SearchErrorCode;
import com.chestnut.system.security.AdminUserType;
import com.chestnut.system.validator.LongId;
import com.chestnut.xmodel.core.IMetaModelType;
import com.fasterxml.jackson.databind.node.ObjectNode;
import jakarta.validation.constraints.NotEmpty;
import lombok.RequiredArgsConstructor;
@ -131,6 +132,11 @@ public class ContentIndexController extends BaseRestController {
List<ESContentVO> list = sr.hits().hits().stream().map(hit -> {
ObjectNode source = hit.source();
ESContentVO vo = JacksonUtils.getObjectMapper().convertValue(source, ESContentVO.class);
source.fieldNames().forEachRemaining(fieldName -> {
if (fieldName.startsWith(IMetaModelType.DATA_FIELD_PREFIX)) {
vo.getExtendData().put(fieldName, source.get(fieldName).asText());
}
});
vo.setHitScore(hit.score());
vo.setPublishDateInstance(LocalDateTime.ofEpochSecond(vo.getPublishDate(), 0, ZoneOffset.UTC));
vo.setCreateTimeInstance(LocalDateTime.ofEpochSecond(vo.getCreateTime(), 0, ZoneOffset.UTC));
@ -138,11 +144,11 @@ public class ContentIndexController extends BaseRestController {
if (Objects.nonNull(catalog)) {
vo.setCatalogName(catalog.getName());
}
hit.highlight().entrySet().forEach(e -> {
if (e.getKey().equals("fullText")) {
vo.setFullText(StringUtils.join(e.getValue().toArray(String[]::new)));
} else if (e.getKey().equals("title")) {
vo.setTitle(StringUtils.join(e.getValue().toArray(String[]::new)));
hit.highlight().forEach((key, value) -> {
if (key.equals("fullText")) {
vo.setFullText(StringUtils.join(value.toArray(String[]::new)));
} else if (key.equals("title")) {
vo.setTitle(StringUtils.join(value.toArray(String[]::new)));
}
});
return vo;

View File

@ -128,6 +128,8 @@ public class SearchApiController extends BaseRestController {
if (Objects.nonNull(catalog)) {
vo.setCatalogName(catalog.getName());
}
vo.setLink(InternalUrlUtils.getActualUrl(vo.getLink(), publishPipeCode, preview));
vo.setLogo(InternalUrlUtils.getActualUrl(vo.getLogo(), publishPipeCode, preview));
hit.highlight().forEach((key, value) -> {
try {
if (key.equals("fullText")) {
@ -135,8 +137,6 @@ public class SearchApiController extends BaseRestController {
} else if (key.equals("title")) {
vo.setTitle(StringUtils.join(value.toArray(String[]::new)));
}
vo.setLink(InternalUrlUtils.getActualUrl(vo.getLink(), publishPipeCode, preview));
vo.setLogo(InternalUrlUtils.getActualUrl(vo.getLogo(), publishPipeCode, preview));
} catch (Exception ex) {
log.warn("Search api row parse failed: ", ex);
}

View File

@ -23,7 +23,7 @@ import java.util.List;
import java.util.Map;
import java.util.Objects;
@Component
@Component(IPublishPipeProp.BEAN_PREFIX + PublishPipeProp_SearchTemplate.KEY)
public class PublishPipeProp_SearchTemplate implements IPublishPipeProp {
public static final String KEY = "searchTemplate";

View File

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

View File

@ -30,7 +30,7 @@ import java.util.Objects;
* @author 兮玥
* @email 190785909@qq.com
*/
@Component
@Component(IPublishPipeProp.BEAN_PREFIX + PublishPipeProp_EnableSitemap.KEY)
public class PublishPipeProp_EnableSitemap implements IPublishPipeProp {
public static final String KEY = "enableSitemap";

View File

@ -30,7 +30,7 @@ import java.util.Objects;
* @author 兮玥
* @email 190785909@qq.com
*/
@Component
@Component(IPublishPipeProp.BEAN_PREFIX + PublishPipeProp_SitemapPageType.KEY)
public class PublishPipeProp_SitemapPageType implements IPublishPipeProp {
public static final String KEY = "sitemapPageType";

View File

@ -30,7 +30,7 @@ import java.util.Objects;
* @author 兮玥
* @email 190785909@qq.com
*/
@Component
@Component(IPublishPipeProp.BEAN_PREFIX + PublishPipeProp_SitemapUrlLimit.KEY)
public class PublishPipeProp_SitemapUrlLimit implements IPublishPipeProp {
public static final String KEY = "sitemapUrlLimit";

View File

@ -15,6 +15,8 @@
*/
package com.chestnut.seo.service;
import com.chestnut.common.exception.GlobalException;
import com.chestnut.common.utils.Assert;
import com.chestnut.common.utils.HttpUtils;
import com.chestnut.common.utils.JacksonUtils;
import com.chestnut.common.utils.StringUtils;
@ -52,9 +54,8 @@ public class BaiduPushService {
public List<BaiduPushResult> pushContents(CmsSite site, List<Long> contentIds) {
String secret = BaiduPushAccessSecretProperty.getValue(site.getConfigProps());
if (StringUtils.isEmpty(secret)) {
return List.of();
}
Assert.notEmpty(secret, () -> new GlobalException("Baidu push access secret not configured."));
List<CmsPublishPipe> publishPipes = publishPipeService.getPublishPipes(site.getSiteId());
List<BaiduPushResult> results = new ArrayList<>(publishPipes.size());
publishPipes.forEach(pp -> {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -50,4 +50,14 @@ public class ObjectUtils {
}
return Objects.nonNull(objects[index]);
}
/**
* 指定对象是否为null或者转成string后为空字符串
*
* @param obj
* @return
*/
public static boolean isNullOrEmptyStr(Object obj) {
return Objects.isNull(obj) || StringUtils.isEmpty(obj.toString());
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -136,6 +136,13 @@ public class StaticizeService {
Assert.isNull(cfg.getSharedVariable(func.getFuncName()),
() -> new IllegalArgumentException("Freemarker function conflict: " + func.getFuncName()));
cfg.setSharedVariable(func.getFuncName(), func);
if (!func.getAliases().isEmpty()) {
for (String alias : func.getAliases()) {
Assert.isNull(cfg.getSharedVariable(alias),
() -> new IllegalArgumentException("Freemarker function alias conflict: " + alias));
cfg.setSharedVariable(alias, func);
}
}
} catch (TemplateModelException e) {
log.error("Freemarker function '{}' register failed.", func.getFuncName());
throw new IllegalArgumentException(e);

View File

@ -28,28 +28,35 @@ public interface IFunction {
*
* @return
*/
public String getFuncName();
String getFuncName();
/**
* 描述
*
* @return
*/
public String getDesc();
String getDesc();
/**
* 获取函数参数定义列表
*
* @return
*/
public List<FuncArg> getFuncArgs();
List<FuncArg> getFuncArgs();
/**
* 函数别名
*/
default List<String> getAliases() {
return List.of();
}
/**
* 模板函数参数
*/
@Getter
@Setter
public class FuncArg {
class FuncArg {
private String name;
@ -67,7 +74,7 @@ public interface IFunction {
}
}
public enum FuncArgType {
enum FuncArgType {
String, Int, Long, Float, Double, DateTime, Boolean
}
}

View File

@ -17,11 +17,12 @@ package com.chestnut.common.staticize.func.impl;
import com.chestnut.common.staticize.func.AbstractFunc;
import com.chestnut.common.utils.StringUtils;
import freemarker.template.SimpleNumber;
import freemarker.template.TemplateModelException;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
/**
@ -50,14 +51,8 @@ public class MaxFunction extends AbstractFunc {
if (StringUtils.isEmpty(args)) {
return StringUtils.EMPTY;
}
SimpleNumber max = (SimpleNumber) args[0];
for (int i = 1; i < args.length; i++) {
SimpleNumber simpleNumber = (SimpleNumber) args[i];
if (simpleNumber.getAsNumber().doubleValue() > max.getAsNumber().doubleValue()) {
max = simpleNumber;
}
}
return max;
List<Number> numbers = MinFunction.readNumbers(args);
return Collections.max(numbers, Comparator.comparing(Number::doubleValue));
}
@Override

View File

@ -17,11 +17,13 @@ package com.chestnut.common.staticize.func.impl;
import com.chestnut.common.staticize.func.AbstractFunc;
import com.chestnut.common.utils.StringUtils;
import freemarker.template.SimpleNumber;
import freemarker.template.TemplateModelException;
import freemarker.template.*;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
/**
@ -50,14 +52,32 @@ public class MinFunction extends AbstractFunc {
if (StringUtils.isEmpty(args)) {
return StringUtils.EMPTY;
}
SimpleNumber min = (SimpleNumber) args[0];
for (int i = 1; i < args.length; i++) {
SimpleNumber simpleNumber = (SimpleNumber) args[i];
if (simpleNumber.getAsNumber().doubleValue() < min.getAsNumber().doubleValue()) {
min = simpleNumber;
List<Number> numbers = readNumbers(args);
return Collections.min(numbers, Comparator.comparing(Number::doubleValue));
}
static List<Number> readNumbers(Object... args) throws TemplateModelException {
ArrayList<Number> numbers = new ArrayList<>();
for (Object arg : args) {
if (arg instanceof SimpleNumber simpleNumber) {
numbers.add(simpleNumber.getAsNumber());
} else if (arg instanceof SimpleSequence simpleSequence) {
for (int j = 0; j < simpleSequence.size(); j++) {
if (simpleSequence.get(j) instanceof SimpleNumber simpleNumber) {
numbers.add(simpleNumber.getAsNumber());
}
}
return min;
} else if (arg instanceof SimpleCollection simpleCollection) {
TemplateModelIterator iterator = simpleCollection.iterator();
while (iterator.hasNext()) {
TemplateModel next = iterator.next();
if (next instanceof SimpleNumber simpleNumber) {
numbers.add(simpleNumber.getAsNumber());
}
}
}
}
return numbers;
}
@Override

View File

@ -24,24 +24,24 @@ public interface ITag {
*
* <@value></@value>
*/
public String getTagName();
String getTagName();
/**
* 标签名称
*/
public String getName();
String getName();
/**
* 标签描述
*/
default public String getDescription() {
default String getDescription() {
return "";
}
/**
* 标签属性定义
*/
default public List<TagAttr> getTagAttrs() {
default List<TagAttr> getTagAttrs() {
return null;
}
}

View File

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

View File

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

View File

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

View File

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

View File

@ -1,8 +1,12 @@
package ${packageName}.controller;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.access.prepost.PreAuthorize;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.chestnut.common.security.web.PageRequest;
import com.chestnut.common.utils.IdUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
@ -12,17 +16,13 @@ import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.chestnut.common.annotation.Log;
import com.chestnut.common.core.controller.BaseController;
import com.chestnut.common.core.domain.AjaxResult;
import com.chestnut.common.enums.BusinessType;
import com.chestnut.common.security.web.BaseRestController;
import ${packageName}.domain.${ClassName};
import ${packageName}.service.I${ClassName}Service;
import com.chestnut.common.utils.poi.ExcelUtil;
#if($table.crud || $table.sub)
import com.chestnut.common.core.page.TableDataInfo;
#elseif($table.tree)
#end
import com.chestnut.common.security.anno.Priv;
import com.chestnut.system.security.AdminUserType;
import lombok.RequiredArgsConstructor;
import com.chestnut.common.domain.R;
/**
* ${functionName}Controller
@ -30,86 +30,119 @@ import com.chestnut.common.core.page.TableDataInfo;
* @author ${author}
* @date ${datetime}
*/
@RequiredArgsConstructor
@RestController
@RequestMapping("/${moduleName}/${businessName}")
public class ${ClassName}Controller extends BaseController
{
public class ${ClassName}Controller extends BaseRestController {
@Autowired
private I${ClassName}Service ${className}Service;
/**
* 查询${functionName}列表
*/
@PreAuthorize("@ss.hasPermi('${permissionPrefix}:list')")
@Priv
@GetMapping("/list")
#if($table.crud || $table.sub)
public TableDataInfo list(${ClassName} ${className})
public R<?> list(${ClassName} ${className})
{
startPage();
List<${ClassName}> list = ${className}Service.select${ClassName}List(${className});
return getDataTable(list);
PageRequest pr = this.getPageRequest();
LambdaQueryChainWrapper<CcProducts> wrapper = this.ccProductsService.lambdaQuery();
#foreach($column in $columns)
#set($queryType=$column.queryType)
#set($javaField=$column.javaField)
#set($javaType=$column.javaType)
#set($columnName=$column.columnName)
#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
#if($column.query)
#if($column.queryType == "EQ")
if (${className}.get${AttrName}() != null) {
wrapper.eq(${ClassName}::get${AttrName},${className}.get${AttrName}());
}
#elseif($queryType == "NE")
if (${className}.get${AttrName}() != null) {
wrapper.ne(${ClassName}::get${AttrName},${className}.get${AttrName}());
}
#elseif($queryType == "GT")
if (${className}.get${AttrName}() != null) {
wrapper.gt(${ClassName}::get${AttrName},${className}.get${AttrName}());
}
#elseif($queryType == "GTE")
if (${className}.get${AttrName}() != null) {
wrapper.gte(${ClassName}::get${AttrName},${className}.get${AttrName}());
}
#elseif($queryType == "LT")
if (${className}.get${AttrName}() != null) {
wrapper.lt(${ClassName}::get${AttrName},${className}.get${AttrName}());
}
#elseif($queryType == "LTE")
if (${className}.get${AttrName}() != null) {
wrapper.lte(${ClassName}::get${AttrName},${className}.get${AttrName}());
}
#elseif($queryType == "LIKE")
if (${className}.get${AttrName}() != null) {
wrapper.like(${ClassName}::get${AttrName},${className}.get${AttrName}());
}
#end
#end
#end
Page<CcProducts> page = wrapper
.page(new Page<>(pr.getPageNumber(), pr.getPageSize(), true));
return this.bindDataTable(page);
}
#elseif($table.tree)
public AjaxResult list(${ClassName} ${className})
public R<?> list(${ClassName} ${className})
{
List<${ClassName}> list = ${className}Service.select${ClassName}List(${className});
return success(list);
return R.ok(list);
}
#end
/**
* 导出${functionName}列表
*/
@PreAuthorize("@ss.hasPermi('${permissionPrefix}:export')")
@Log(title = "${functionName}", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, ${ClassName} ${className})
{
List<${ClassName}> list = ${className}Service.select${ClassName}List(${className});
ExcelUtil<${ClassName}> util = new ExcelUtil<${ClassName}>(${ClassName}.class);
util.exportExcel(response, list, "${functionName}数据");
}
/**
* 获取${functionName}详细信息
*/
@PreAuthorize("@ss.hasPermi('${permissionPrefix}:query')")
@GetMapping(value = "/{${pkColumn.javaField}}")
public AjaxResult getInfo(@PathVariable("${pkColumn.javaField}") ${pkColumn.javaType} ${pkColumn.javaField})
public R<?> getInfo(@PathVariable("${pkColumn.javaField}") ${pkColumn.javaType} ${pkColumn.javaField})
{
return success(${className}Service.select${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaField}));
return R.ok(this.${className}Service.getById(id));
}
/**
* 新增${functionName}
*/
@PreAuthorize("@ss.hasPermi('${permissionPrefix}:add')")
@Priv
@Log(title = "${functionName}", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody ${ClassName} ${className})
public R<?> add(@RequestBody ${ClassName} ${className})
{
return toAjax(${className}Service.insert${ClassName}(${className}));
this.${className}Service.save(${className});
return R.ok();
}
/**
* 修改${functionName}
*/
@PreAuthorize("@ss.hasPermi('${permissionPrefix}:edit')")
@Priv
@Log(title = "${functionName}", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody ${ClassName} ${className})
public R<?> edit(@RequestBody ${ClassName} ${className})
{
return toAjax(${className}Service.update${ClassName}(${className}));
this.${className}Service.updateById(${className});
return R.ok();
}
/**
* 删除${functionName}
*/
@PreAuthorize("@ss.hasPermi('${permissionPrefix}:remove')")
@Priv
@Log(title = "${functionName}", businessType = BusinessType.DELETE)
@DeleteMapping("/{${pkColumn.javaField}s}")
public AjaxResult remove(@PathVariable ${pkColumn.javaType}[] ${pkColumn.javaField}s)
public R<?> remove(@PathVariable ${pkColumn.javaType}[] ${pkColumn.javaField}s)
{
return toAjax(${className}Service.delete${ClassName}By${pkColumn.capJavaField}s(${pkColumn.javaField}s));
this.${className}Service.removeBatchByIds(List.of(${pkColumn.javaField}s));
return R.ok();
}
}

View File

@ -3,14 +3,10 @@ package ${packageName}.domain;
#foreach ($import in $importList)
import ${import};
#end
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.chestnut.common.annotation.Excel;
#if($table.crud || $table.sub)
import com.chestnut.common.core.domain.BaseEntity;
#elseif($table.tree)
import com.chestnut.common.core.domain.TreeEntity;
#end
import java.io.Serializable;
import lombok.Getter;
import lombok.Setter;
import com.baomidou.mybatisplus.annotation.TableName;
/**
* ${functionName}对象 ${tableName}
@ -23,10 +19,15 @@ import com.chestnut.common.core.domain.TreeEntity;
#elseif($table.tree)
#set($Entity="TreeEntity")
#end
public class ${ClassName} extends ${Entity}
{
@Getter
@Setter
@TableName(value = ${ClassName}.TABLE_NAME)
public class ${ClassName} implements Serializable {
private static final long serialVersionUID = 1L;
public static final String TABLE_NAME = "${tableName}";
#foreach ($column in $columns)
#if(!$table.isSuperColumn($column.javaField))
/** $column.columnComment */
@ -38,12 +39,8 @@ public class ${ClassName} extends ${Entity}
#set($comment=$column.columnComment)
#end
#if($parentheseIndex != -1)
@Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()")
#elseif($column.javaType == 'Date')
@JsonFormat(pattern = "yyyy-MM-dd")
@Excel(name = "${comment}", width = 30, dateFormat = "yyyy-MM-dd")
#else
@Excel(name = "${comment}")
#end
#end
private $column.javaType $column.javaField;
@ -55,24 +52,6 @@ public class ${ClassName} extends ${Entity}
private List<${subClassName}> ${subclassName}List;
#end
#foreach ($column in $columns)
#if(!$table.isSuperColumn($column.javaField))
#if($column.javaField.length() > 2 && $column.javaField.substring(1,2).matches("[A-Z]"))
#set($AttrName=$column.javaField)
#else
#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
#end
public void set${AttrName}($column.javaType $column.javaField)
{
this.$column.javaField = $column.javaField;
}
public $column.javaType get${AttrName}()
{
return $column.javaField;
}
#end
#end
#if($table.sub)
public List<${subClassName}> get${subClassName}List()
@ -84,22 +63,5 @@ public class ${ClassName} extends ${Entity}
{
this.${subclassName}List = ${subclassName}List;
}
#end
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
#foreach ($column in $columns)
#if($column.javaField.length() > 2 && $column.javaField.substring(1,2).matches("[A-Z]"))
#set($AttrName=$column.javaField)
#else
#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
#end
.append("${column.javaField}", get${AttrName}())
#end
#if($table.sub)
.append("${subclassName}List", get${subClassName}List())
#end
.toString();
}
}

View File

@ -1,10 +1,7 @@
package ${packageName}.mapper;
import java.util.List;
import ${packageName}.domain.${ClassName};
#if($table.sub)
import ${packageName}.domain.${subClassName};
#end
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* ${functionName}Mapper接口
@ -12,80 +9,5 @@ import ${packageName}.domain.${subClassName};
* @author ${author}
* @date ${datetime}
*/
public interface ${ClassName}Mapper
{
/**
* 查询${functionName}
*
* @param ${pkColumn.javaField} ${functionName}主键
* @return ${functionName}
*/
public ${ClassName} select${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaType} ${pkColumn.javaField});
/**
* 查询${functionName}列表
*
* @param ${className} ${functionName}
* @return ${functionName}集合
*/
public List<${ClassName}> select${ClassName}List(${ClassName} ${className});
/**
* 新增${functionName}
*
* @param ${className} ${functionName}
* @return 结果
*/
public int insert${ClassName}(${ClassName} ${className});
/**
* 修改${functionName}
*
* @param ${className} ${functionName}
* @return 结果
*/
public int update${ClassName}(${ClassName} ${className});
/**
* 删除${functionName}
*
* @param ${pkColumn.javaField} ${functionName}主键
* @return 结果
*/
public int delete${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaType} ${pkColumn.javaField});
/**
* 批量删除${functionName}
*
* @param ${pkColumn.javaField}s 需要删除的数据主键集合
* @return 结果
*/
public int delete${ClassName}By${pkColumn.capJavaField}s(${pkColumn.javaType}[] ${pkColumn.javaField}s);
#if($table.sub)
/**
* 批量删除${subTable.functionName}
*
* @param ${pkColumn.javaField}s 需要删除的数据主键集合
* @return 结果
*/
public int delete${subClassName}By${subTableFkClassName}s(${pkColumn.javaType}[] ${pkColumn.javaField}s);
/**
* 批量新增${subTable.functionName}
*
* @param ${subclassName}List ${subTable.functionName}列表
* @return 结果
*/
public int batch${subClassName}(List<${subClassName}> ${subclassName}List);
/**
* 通过${functionName}主键删除${subTable.functionName}信息
*
* @param ${pkColumn.javaField} ${functionName}ID
* @return 结果
*/
public int delete${subClassName}By${subTableFkClassName}(${pkColumn.javaType} ${pkColumn.javaField});
#end
public interface ${ClassName}Mapper extends BaseMapper<${ClassName}> {
}

View File

@ -1,6 +1,6 @@
package ${packageName}.service;
import java.util.List;
import com.baomidou.mybatisplus.extension.service.IService;
import ${packageName}.domain.${ClassName};
/**
@ -9,53 +9,5 @@ import ${packageName}.domain.${ClassName};
* @author ${author}
* @date ${datetime}
*/
public interface I${ClassName}Service
{
/**
* 查询${functionName}
*
* @param ${pkColumn.javaField} ${functionName}主键
* @return ${functionName}
*/
public ${ClassName} select${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaType} ${pkColumn.javaField});
/**
* 查询${functionName}列表
*
* @param ${className} ${functionName}
* @return ${functionName}集合
*/
public List<${ClassName}> select${ClassName}List(${ClassName} ${className});
/**
* 新增${functionName}
*
* @param ${className} ${functionName}
* @return 结果
*/
public int insert${ClassName}(${ClassName} ${className});
/**
* 修改${functionName}
*
* @param ${className} ${functionName}
* @return 结果
*/
public int update${ClassName}(${ClassName} ${className});
/**
* 批量删除${functionName}
*
* @param ${pkColumn.javaField}s 需要删除的${functionName}主键集合
* @return 结果
*/
public int delete${ClassName}By${pkColumn.capJavaField}s(${pkColumn.javaType}[] ${pkColumn.javaField}s);
/**
* 删除${functionName}信息
*
* @param ${pkColumn.javaField} ${functionName}主键
* @return 结果
*/
public int delete${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaType} ${pkColumn.javaField});
public interface I${ClassName}Service extends IService<${ClassName}> {
}

View File

@ -1,6 +1,6 @@
package ${packageName}.service.impl;
import java.util.List;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
#foreach ($column in $columns)
#if($column.javaField == 'createTime' || $column.javaField == 'updateTime')
import com.chestnut.common.utils.DateUtils;
@ -26,144 +26,9 @@ import ${packageName}.service.I${ClassName}Service;
* @date ${datetime}
*/
@Service
public class ${ClassName}ServiceImpl implements I${ClassName}Service
{
public class ${ClassName}ServiceImpl extends ServiceImpl<${ClassName}Mapper, ${ClassName}> implements I${ClassName}Service {
@Autowired
private ${ClassName}Mapper ${className}Mapper;
/**
* 查询${functionName}
*
* @param ${pkColumn.javaField} ${functionName}主键
* @return ${functionName}
*/
@Override
public ${ClassName} select${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaType} ${pkColumn.javaField})
{
return ${className}Mapper.select${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaField});
}
/**
* 查询${functionName}列表
*
* @param ${className} ${functionName}
* @return ${functionName}
*/
@Override
public List<${ClassName}> select${ClassName}List(${ClassName} ${className})
{
return ${className}Mapper.select${ClassName}List(${className});
}
/**
* 新增${functionName}
*
* @param ${className} ${functionName}
* @return 结果
*/
#if($table.sub)
@Transactional
#end
@Override
public int insert${ClassName}(${ClassName} ${className})
{
#foreach ($column in $columns)
#if($column.javaField == 'createTime')
${className}.setCreateTime(DateUtils.getNowDate());
#end
#end
#if($table.sub)
int rows = ${className}Mapper.insert${ClassName}(${className});
insert${subClassName}(${className});
return rows;
#else
return ${className}Mapper.insert${ClassName}(${className});
#end
}
/**
* 修改${functionName}
*
* @param ${className} ${functionName}
* @return 结果
*/
#if($table.sub)
@Transactional
#end
@Override
public int update${ClassName}(${ClassName} ${className})
{
#foreach ($column in $columns)
#if($column.javaField == 'updateTime')
${className}.setUpdateTime(DateUtils.getNowDate());
#end
#end
#if($table.sub)
${className}Mapper.delete${subClassName}By${subTableFkClassName}(${className}.get${pkColumn.capJavaField}());
insert${subClassName}(${className});
#end
return ${className}Mapper.update${ClassName}(${className});
}
/**
* 批量删除${functionName}
*
* @param ${pkColumn.javaField}s 需要删除的${functionName}主键
* @return 结果
*/
#if($table.sub)
@Transactional
#end
@Override
public int delete${ClassName}By${pkColumn.capJavaField}s(${pkColumn.javaType}[] ${pkColumn.javaField}s)
{
#if($table.sub)
${className}Mapper.delete${subClassName}By${subTableFkClassName}s(${pkColumn.javaField}s);
#end
return ${className}Mapper.delete${ClassName}By${pkColumn.capJavaField}s(${pkColumn.javaField}s);
}
/**
* 删除${functionName}信息
*
* @param ${pkColumn.javaField} ${functionName}主键
* @return 结果
*/
#if($table.sub)
@Transactional
#end
@Override
public int delete${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaType} ${pkColumn.javaField})
{
#if($table.sub)
${className}Mapper.delete${subClassName}By${subTableFkClassName}(${pkColumn.javaField});
#end
return ${className}Mapper.delete${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaField});
}
#if($table.sub)
/**
* 新增${subTable.functionName}信息
*
* @param ${className} ${functionName}对象
*/
public void insert${subClassName}(${ClassName} ${className})
{
List<${subClassName}> ${subclassName}List = ${className}.get${subClassName}List();
${pkColumn.javaType} ${pkColumn.javaField} = ${className}.get${pkColumn.capJavaField}();
if (StringUtils.isNotNull(${subclassName}List))
{
List<${subClassName}> list = new ArrayList<${subClassName}>();
for (${subClassName} ${subclassName} : ${subclassName}List)
{
${subclassName}.set${subTableFkClassName}(${pkColumn.javaField});
list.add(${subclassName});
}
if (list.size() > 0)
{
${className}Mapper.batch${subClassName}(list);
}
}
}
#end
}

View File

@ -1,6 +1,6 @@
-- 菜单 SQL
insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
values('${functionName}', '${parentMenuId}', '1', '${businessName}', '${moduleName}/${businessName}/index', 1, 0, 'C', '0', '0', '${permissionPrefix}:list', '#', 'admin', sysdate(), '', null, '${functionName}菜单');
values('${functionName}', '0', '1', '${businessName}', '${moduleName}/${businessName}/index', 'N', 'Y', 'C', 'Y', '0', '${permissionPrefix}:list', '#', 'admin', sysdate(), '', null, '${functionName}菜单');
-- 按钮父菜单ID
SELECT @parentId := LAST_INSERT_ID();

View File

@ -442,8 +442,8 @@ export default {
#end
#end
list${BusinessName}(this.queryParams).then(response => {
this.${businessName}List = response.rows;
this.total = response.total;
this.${businessName}List = response.data.rows;
this.total = response.data.total;
this.loading = false;
});
},

View File

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

View File

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

View File

@ -15,9 +15,14 @@
*/
package com.chestnut.xmodel.core.impl;
import com.chestnut.common.utils.DateUtils;
import com.chestnut.xmodel.core.IMetaControlType;
import com.chestnut.xmodel.dto.XModelFieldDataDTO;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
import java.util.Objects;
/**
* 元数据模型字段类型日期选择框
*
@ -38,4 +43,12 @@ public class MetaControlType_Date implements IMetaControlType {
public String getName() {
return "{META.CONTROL_TYPE." + TYPE + "}";
}
@Override
public void parseFieldValue(XModelFieldDataDTO fieldData) {
Object value = fieldData.getValue();
if (Objects.nonNull(value) && value instanceof LocalDateTime ldt) {
fieldData.setValue(ldt.format(DateUtils.FORMAT_YYYY_MM_DD));
}
}
}

View File

@ -16,8 +16,13 @@
package com.chestnut.xmodel.core.impl;
import com.chestnut.xmodel.core.IMetaControlType;
import com.chestnut.xmodel.dto.XModelFieldDataDTO;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Objects;
/**
* 元数据模型字段类型时间选择框
*
@ -29,6 +34,8 @@ public class MetaControlType_Time implements IMetaControlType {
public static final String TYPE = "time";
public static DateTimeFormatter HH_MM_SS = DateTimeFormatter.ofPattern("HH:mm:ss");
@Override
public String getType() {
return TYPE;
@ -38,4 +45,12 @@ public class MetaControlType_Time implements IMetaControlType {
public String getName() {
return "{META.CONTROL_TYPE." + TYPE + "}";
}
@Override
public void parseFieldValue(XModelFieldDataDTO fieldData) {
Object value = fieldData.getValue();
if (Objects.nonNull(value) && value instanceof LocalDateTime ldt) {
fieldData.setValue(ldt.format(HH_MM_SS));
}
}
}

View File

@ -15,6 +15,7 @@
*/
package com.chestnut.xmodel.core.impl;
import com.chestnut.common.utils.ObjectUtils;
import com.chestnut.xmodel.core.IMetaFieldValidation;
import org.springframework.stereotype.Component;
@ -42,7 +43,7 @@ public class MetaFieldValidation_Date implements IMetaFieldValidation {
}
public boolean validate(Object fieldValue, Map<String, Object> args) {
if (fieldValue == null) {
if (ObjectUtils.isNullOrEmptyStr(fieldValue)) {
return true;
}
try {

View File

@ -15,6 +15,7 @@
*/
package com.chestnut.xmodel.core.impl;
import com.chestnut.common.utils.ObjectUtils;
import com.chestnut.xmodel.core.IMetaFieldValidation;
import org.springframework.stereotype.Component;
@ -43,7 +44,7 @@ public class MetaFieldValidation_DateTime implements IMetaFieldValidation {
@Override
public boolean validate(Object fieldValue, Map<String, Object> args) {
if (fieldValue == null) {
if (ObjectUtils.isNullOrEmptyStr(fieldValue)) {
return true;
}
try {

View File

@ -15,6 +15,7 @@
*/
package com.chestnut.xmodel.core.impl;
import com.chestnut.common.utils.ObjectUtils;
import com.chestnut.xmodel.core.IMetaFieldValidation;
import org.springframework.stereotype.Component;
@ -41,7 +42,7 @@ public class MetaFieldValidation_Email implements IMetaFieldValidation {
@Override
public boolean validate(Object fieldValue, Map<String, Object> args) {
if (fieldValue == null) {
if (ObjectUtils.isNullOrEmptyStr(fieldValue)) {
return true;
}
return Pattern.matches(EmailPattern, fieldValue.toString());

View File

@ -16,11 +16,11 @@
package com.chestnut.xmodel.core.impl;
import com.chestnut.common.utils.NumberUtils;
import com.chestnut.common.utils.ObjectUtils;
import com.chestnut.xmodel.core.IMetaFieldValidation;
import org.springframework.stereotype.Component;
import java.util.Map;
import java.util.Objects;
/**
* 整数校验
@ -40,6 +40,6 @@ public class MetaFieldValidation_Int implements IMetaFieldValidation {
@Override
public boolean validate(Object fieldValue, Map<String, Object> args) {
return Objects.isNull(fieldValue) || NumberUtils.isDigits(fieldValue.toString());
return ObjectUtils.isNullOrEmptyStr(fieldValue) || NumberUtils.isDigits(fieldValue.toString());
}
}

Some files were not shown because too many files have changed in this diff Show More