版本更新到1.3.23

This commit is contained in:
兮玥 2023-11-10 19:04:25 +08:00
parent 5abcb601e1
commit 4d84c3de19
106 changed files with 1376 additions and 581 deletions

View File

@ -1,4 +1,4 @@
# ChestnutCMS v1.3.21 # ChestnutCMS v1.3.23
### 系统简介 ### 系统简介
@ -16,8 +16,9 @@ ChestnutCMS是前后端分离的企业级内容管理系统。项目基于[RuoYi
资讯站演示地址:<http://news.1000mz.com>会员演示账号xxx333@126.com / a123456 资讯站演示地址:<http://news.1000mz.com>会员演示账号xxx333@126.com / a123456
图片站演示地址:<http://tpz.1000mz.com> 图片站演示地址:PC端<http://tpz.1000mz.com> 移动端:<http://mtpz.1000mz.com>
游戏站演示地址PC端<http://game.1000mz.com> 移动端:<http://mgame.1000mz.com>
### 开发环境 ### 开发环境
- JDK 17 - JDK 17

View File

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

View File

@ -3,7 +3,7 @@ chestnut:
# 名称 # 名称
name: ChestnutCMS name: ChestnutCMS
# 版本 # 版本
version: 1.3.21 version: 1.3.23
# 版权年份 # 版权年份
copyrightYear: 2023 copyrightYear: 2023
system: system:

View File

@ -3,7 +3,7 @@ chestnut:
# 名称 # 名称
name: ChestnutCMS name: ChestnutCMS
# 版本 # 版本
version: 1.3.21 version: 1.3.23
# 版权年份 # 版权年份
copyrightYear: 2023 copyrightYear: 2023
system: system:

View File

@ -3,7 +3,7 @@ chestnut:
# 名称 # 名称
name: ChestnutCMS name: ChestnutCMS
# 版本 # 版本
version: 1.3.21 version: 1.3.23
# 版权年份 # 版权年份
copyrightYear: 2023 copyrightYear: 2023
system: system:

View File

@ -0,0 +1,11 @@
CREATE TABLE `cms_content_rela` (
`rela_id` bigint NOT NULL COMMENT 'ID',
`content_id` bigint NOT NULL COMMENT '内容ID',
`rela_content_id` bigint NOT NULL COMMENT '关联内容ID',
`create_by` varchar(64) NOT NULL DEFAULT '' COMMENT '创建者',
`create_time` datetime NOT NULL COMMENT '创建时间',
`update_by` varchar(64) DEFAULT '' COMMENT '更新者',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
`remark` varchar(500) DEFAULT NULL COMMENT '备注',
PRIMARY KEY (`rela_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,73 @@
package com.chestnut.contentcore.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
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.IdUtils;
import com.chestnut.contentcore.domain.CmsContent;
import com.chestnut.contentcore.domain.CmsContentRela;
import com.chestnut.contentcore.mapper.CmsContentRelaMapper;
import com.chestnut.contentcore.service.IContentRelaService;
import com.chestnut.system.security.AdminUserType;
import com.chestnut.system.security.StpAdminUtil;
import jakarta.validation.constraints.NotEmpty;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.PageRequest;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 关联内容管理
*
* @author 兮玥
* @email 190785909@qq.com
*/
@Priv(type = AdminUserType.TYPE)
@RestController
@RequiredArgsConstructor
@RequestMapping("/cms/content/rela")
public class ContentRelaController extends BaseRestController {
private final IContentRelaService contentRelaService;
private final CmsContentRelaMapper contentRelaMapper;
@GetMapping
public R<?> getRelaContents(@RequestParam Long contentId, @RequestParam(required = false) String title) {
PageRequest pr = this.getPageRequest();
Page<CmsContent> page = contentRelaMapper.selectRelaContents(new Page<>(pr.getPageNumber(), pr.getPageSize(), true),
contentId, title);
return this.bindDataTable(page);
}
@PostMapping
public R<?> addRelaContents(@RequestParam Long contentId, @RequestBody List<Long> relaContentIds) {
List<Long> contentIds = contentRelaMapper.selectList(new LambdaQueryWrapper<CmsContentRela>()
.eq(CmsContentRela::getContentId, contentId))
.stream().map(CmsContentRela::getRelaContentId).toList();
String operator = StpAdminUtil.getLoginUser().getUsername();
List<CmsContentRela> relaContents = relaContentIds.stream()
.filter(id -> !contentIds.contains(id))
.map(relaContentId -> {
CmsContentRela rela = new CmsContentRela();
rela.setRelaId(IdUtils.getSnowflakeId());
rela.setContentId(contentId);
rela.setRelaContentId(relaContentId);
rela.createBy(operator);
return rela;
}).toList();
this.contentRelaService.saveBatch(relaContents);
return R.ok();
}
@DeleteMapping
public R<?> deleteRelaContents(@RequestParam Long contentId, @RequestBody @NotEmpty List<Long> relaContentIds) {
this.contentRelaService.remove(new LambdaQueryWrapper<CmsContentRela>()
.eq(CmsContentRela::getContentId, contentId)
.in(CmsContentRela::getRelaContentId, relaContentIds));
return R.ok();
}
}

View File

@ -0,0 +1,39 @@
package com.chestnut.contentcore.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.chestnut.common.db.domain.BaseEntity;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
/**
* 关联内容表对象 [cms_content_rela]
*
* @author 兮玥
* @email 190785909@qq.com
*/
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@TableName(CmsContentRela.TABLE_NAME)
public class CmsContentRela extends BaseEntity {
public static final String TABLE_NAME = "cms_content_rela";
@TableId(value = "rela_id", type = IdType.INPUT)
private Long relaId;
/**
* 内容ID
*/
private Long contentId;
/**
* 关联内容ID
*/
private Long relaContentId;
}

View File

@ -3,6 +3,8 @@ package com.chestnut.contentcore.domain.vo;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.Date; import java.util.Date;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
@ -75,6 +77,21 @@ public class ListContentVO {
*/ */
private String[] attributes; private String[] attributes;
/*
* 关键词
*/
private String[] keywords;
/*
* TAGs
*/
private String[] tags;
/*
* 摘要
*/
private String summary;
/* /*
* 置顶标识 * 置顶标识
*/ */

View File

@ -0,0 +1,23 @@
package com.chestnut.contentcore.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.chestnut.contentcore.domain.CmsContent;
import com.chestnut.contentcore.domain.CmsContentRela;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
public interface CmsContentRelaMapper extends BaseMapper<CmsContentRela> {
@Select("""
<script>
SELECT c.* FROM cms_content_rela a right join cms_content c on a.rela_content_id = c.content_id
WHERE a.content_id = #{contentId}
<if test=' title != null and title != "" '> AND c.title like concat('%', #{title}, '%') </if>
ORDER BY a.create_time DESC
</script>
""")
Page<CmsContent> selectRelaContents(IPage<CmsContent> page, @Param("contentId") Long contentId, @Param("title") String title);
}

View File

@ -2,6 +2,7 @@ package com.chestnut.contentcore.properties;
import java.util.Map; import java.util.Map;
import com.chestnut.common.utils.StringUtils;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import com.chestnut.contentcore.core.IProperty; import com.chestnut.contentcore.core.IProperty;
@ -36,6 +37,10 @@ public class PublishedContentEditProperty implements IProperty {
} }
public static boolean getValue(Map<String, String> props) { public static boolean getValue(Map<String, String> props) {
return YesOrNo.isYes(ConfigPropertyUtils.getStringValue(ID, props)); String value = ConfigPropertyUtils.getStringValue(ID, props);
if (StringUtils.isEmpty(value)) {
return true;
}
return YesOrNo.isYes(value);
} }
} }

View File

@ -0,0 +1,8 @@
package com.chestnut.contentcore.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.chestnut.contentcore.domain.CmsContentRela;
public interface IContentRelaService extends IService<CmsContentRela> {
}

View File

@ -0,0 +1,14 @@
package com.chestnut.contentcore.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.chestnut.contentcore.domain.CmsContentRela;
import com.chestnut.contentcore.mapper.CmsContentRelaMapper;
import com.chestnut.contentcore.service.IContentRelaService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
@Service
@RequiredArgsConstructor
public class ContentRelaServiceImpl extends ServiceImpl<CmsContentRelaMapper, CmsContentRela>
implements IContentRelaService {
}

View File

@ -0,0 +1,60 @@
package com.chestnut.contentcore.template.func;
import com.chestnut.common.staticize.FreeMarkerUtils;
import com.chestnut.common.staticize.core.TemplateContext;
import com.chestnut.common.staticize.func.AbstractFunc;
import com.chestnut.common.utils.StringUtils;
import com.chestnut.contentcore.util.InternalUrlUtils;
import freemarker.core.Environment;
import freemarker.template.TemplateModelException;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
/**
* Freemarker模板自定义函数处理Html文本内容中的内部链接
*/
@Component
@RequiredArgsConstructor
public class ListHtmlInternalUrlFunction extends AbstractFunc {
static final String FUNC_NAME = "listHtmlInternalUrl";
private static final String DESC = "{FREEMARKER.FUNC.DESC." + FUNC_NAME + "}";
@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;
}
TemplateContext context = FreeMarkerUtils.getTemplateContext(Environment.getCurrentEnvironment());
String html = args[0].toString();
Matcher matcher = InternalUrlUtils.InternalUrlTagPattern.matcher(html);
List<String> list = new ArrayList<>();
while (matcher.find()) {
String iurl = matcher.group(1);
String actualUrl = InternalUrlUtils.getActualUrl(iurl, context.getPublishPipeCode(), context.isPreview());
list.add(actualUrl);
}
return list;
}
@Override
public List<FuncArg> getFuncArgs() {
return List.of(new FuncArg("HTML文本内容", FuncArgType.String, true, null));
}
}

View File

@ -0,0 +1,63 @@
package com.chestnut.contentcore.template.tag;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.chestnut.common.staticize.enums.TagAttrDataType;
import com.chestnut.common.staticize.tag.AbstractListTag;
import com.chestnut.common.staticize.tag.TagAttr;
import com.chestnut.contentcore.domain.CmsContent;
import com.chestnut.contentcore.mapper.CmsContentRelaMapper;
import freemarker.core.Environment;
import freemarker.template.TemplateException;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections4.MapUtils;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Map;
@Component
@RequiredArgsConstructor
public class CmsContentRelaTag extends AbstractListTag {
public final static String TAG_NAME = "cms_content_rela";
public final static String NAME = "{FREEMARKER.TAG.NAME." + TAG_NAME + "}";
public final static String DESC = "{FREEMARKER.TAG.DESC." + TAG_NAME + "}";
public final static String TagAttr_ContentId = "contentid";
private final CmsContentRelaMapper contentRelaMapper;
@Override
public List<TagAttr> getTagAttrs() {
List<TagAttr> tagAttrs = super.getTagAttrs();
tagAttrs.add(new TagAttr(TagAttr_ContentId, true, TagAttrDataType.INTEGER, "内容ID"));
return tagAttrs;
}
@Override
public TagPageData prepareData(Environment env, Map<String, String> attrs, boolean page, int size, int pageIndex)
throws TemplateException {
long contentId = MapUtils.getLongValue(attrs, TagAttr_ContentId);
if (contentId <= 0) {
throw new TemplateException("内容ID错误" + contentId, env);
}
Page<CmsContent> pageResult = contentRelaMapper
.selectRelaContents(new Page<>(pageIndex, size, page), contentId, null);
return TagPageData.of(pageResult.getRecords(), pageResult.getTotal());
}
@Override
public String getTagName() {
return TAG_NAME;
}
@Override
public String getName() {
return NAME;
}
@Override
public String getDescription() {
return DESC;
}
}

View File

@ -20,7 +20,7 @@ public class InternalUrlUtils {
/** /**
* 带iurl属性值的任意标签匹配 * 带iurl属性值的任意标签匹配
*/ */
private static final Pattern InternalUrlTagPattern = Pattern.compile("<[^>]+=\\s*['\"](iurl://[^'\"]+)['\"][^>]*>", public static final Pattern InternalUrlTagPattern = Pattern.compile("<[^>]+=\\s*['\"](iurl://[^'\"]+)['\"][^>]*>",
Pattern.CASE_INSENSITIVE | Pattern.DOTALL | Pattern.MULTILINE); Pattern.CASE_INSENSITIVE | Pattern.DOTALL | Pattern.MULTILINE);

View File

@ -88,6 +88,8 @@ FREEMARKER.TAG.NAME.cms_pagewidget_data=页面部件数据标签
FREEMARKER.TAG.DESC.cms_pagewidget_data=页面部件数据标签,标签体内可使用${Data.name}获取数据 FREEMARKER.TAG.DESC.cms_pagewidget_data=页面部件数据标签,标签体内可使用${Data.name}获取数据
FREEMARKER.TAG.NAME.cms_content_closest=内容前后篇标签 FREEMARKER.TAG.NAME.cms_content_closest=内容前后篇标签
FREEMARKER.TAG.DESC.cms_content_closest=内容前后篇标签,仅支持指定内容当前栏目列表,标签体内可使用${Data.title}获取数据 FREEMARKER.TAG.DESC.cms_content_closest=内容前后篇标签,仅支持指定内容当前栏目列表,标签体内可使用${Data.title}获取数据
FREEMARKER.TAG.NAME.cms_content_rela=相关内容标签
FREEMARKER.TAG.DESC.cms_content_rela=相关内容标签,内嵌<#list DataList as content>${content.name}</#list>遍历数据
# freemarker模板函数 # freemarker模板函数
FREEMARKER.FUNC.DESC.clearHtmlTag=清除Html标签例如${clearHtmlTag(ArticleContent)} FREEMARKER.FUNC.DESC.clearHtmlTag=清除Html标签例如${clearHtmlTag(ArticleContent)}
@ -103,6 +105,7 @@ FREEMARKER.FUNC.DESC.ifElse=三元表达式函数,例如:${ifElse(content.lo
FREEMARKER.FUNC.DESC.dynamicPageLink=动态页面链接获取函数,例如:${dynamicPageLink('Search')} FREEMARKER.FUNC.DESC.dynamicPageLink=动态页面链接获取函数,例如:${dynamicPageLink('Search')}
FREEMARKER.FUNC.DESC.dict=获取字典数据列表,例如:${dict('YesOrNo', 'Y')} FREEMARKER.FUNC.DESC.dict=获取字典数据列表,例如:${dict('YesOrNo', 'Y')}
FREEMARKER.FUNC.DESC.sysConfig=获取系统参数配置值,例如:${sysConfig('SiteApiUrl')} FREEMARKER.FUNC.DESC.sysConfig=获取系统参数配置值,例如:${sysConfig('SiteApiUrl')}
FREEMARKER.FUNC.DESC.listHtmlInternalUrl=获取html文本中的iurl列表例如${listHtmlInternalUrl(ArticleContent)}
# 校验规则 # 校验规则
VALIDATOR.CMS.SITE.PUBLISH_PIPE_PROPS_EMPTY=发布通道配置不能为空 VALIDATOR.CMS.SITE.PUBLISH_PIPE_PROPS_EMPTY=发布通道配置不能为空

View File

@ -88,6 +88,8 @@ FREEMARKER.TAG.NAME.cms_pagewidget_data=Pagewidget data tag
FREEMARKER.TAG.DESC.cms_pagewidget_data=Fetch pagewidget data and use "${Data.name}" to show in template. FREEMARKER.TAG.DESC.cms_pagewidget_data=Fetch pagewidget data and use "${Data.name}" to show in template.
FREEMARKER.TAG.NAME.cms_content_closest=Content closest tag FREEMARKER.TAG.NAME.cms_content_closest=Content closest tag
FREEMARKER.TAG.DESC.cms_content_closest=Only support the content's catalog to fetch data, use <#list> in tag like "<#list DataList as content>${content.title}</#list>" to walk through the list of contents. FREEMARKER.TAG.DESC.cms_content_closest=Only support the content's catalog to fetch data, use <#list> in tag like "<#list DataList as content>${content.title}</#list>" to walk through the list of contents.
FREEMARKER.TAG.NAME.cms_content_rela=Related content tag
FREEMARKER.TAG.DESC.cms_content_rela=Fetch related contents by contentId, use <#list> in tag like "<#list DataList as content>${content.title}</#list>" to walk through the list of contents.
# freemarker模板函数 # freemarker模板函数
FREEMARKER.FUNC.DESC.clearHtmlTag=Use ${clearHtmlTag(ArticleContent)} in template to clear html tag. FREEMARKER.FUNC.DESC.clearHtmlTag=Use ${clearHtmlTag(ArticleContent)} in template to clear html tag.
@ -103,6 +105,7 @@ FREEMARKER.FUNC.DESC.ifElse=Use ${ifElse(Site.siteId!='','1','2')} in template t
FREEMARKER.FUNC.DESC.dynamicPageLink=Use ${dynamicPageLink('Search')} in template to get the dynamic page link. FREEMARKER.FUNC.DESC.dynamicPageLink=Use ${dynamicPageLink('Search')} in template to get the dynamic page link.
FREEMARKER.FUNC.DESC.dict=Use ${dict(content.linkFlag, 'YesOrNo')} in template to get the dict data label. FREEMARKER.FUNC.DESC.dict=Use ${dict(content.linkFlag, 'YesOrNo')} in template to get the dict data label.
FREEMARKER.FUNC.DESC.sysConfig=Use ${sysConfig('SiteApiUrl')} in template to get the system config value. FREEMARKER.FUNC.DESC.sysConfig=Use ${sysConfig('SiteApiUrl')} in template to get the system config value.
FREEMARKER.FUNC.DESC.listHtmlInternalUrl=Use ${listHtmlInternalUrl(ArticleContent)} in template to get the iurl list.
# 校验规则 # 校验规则
VALIDATOR.CMS.SITE.PUBLISH_PIPE_PROPS_EMPTY=The site publish pipe props cannot be empty. VALIDATOR.CMS.SITE.PUBLISH_PIPE_PROPS_EMPTY=The site publish pipe props cannot be empty.

View File

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

View File

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

View File

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

View File

@ -59,6 +59,7 @@ public class CmsImageTag extends AbstractListTag {
LambdaQueryWrapper<CmsImage> q = new LambdaQueryWrapper<CmsImage>().eq(CmsImage::getContentId, contentId); LambdaQueryWrapper<CmsImage> q = new LambdaQueryWrapper<CmsImage>().eq(CmsImage::getContentId, contentId);
q.apply(StringUtils.isNotEmpty(condition), condition); q.apply(StringUtils.isNotEmpty(condition), condition);
q.orderByAsc(CmsImage::getSortFlag);
Page<CmsImage> pageResult = this.imageService.page(new Page<>(pageIndex, size, page), q); Page<CmsImage> pageResult = this.imageService.page(new Page<>(pageIndex, size, page), q);
if (pageIndex > 1 & pageResult.getRecords().size() == 0) { if (pageIndex > 1 & pageResult.getRecords().size() == 0) {
throw new TemplateException("内容列表页码超出上限:" + pageIndex, env); throw new TemplateException("内容列表页码超出上限:" + pageIndex, env);

View File

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

View File

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

View File

@ -1,29 +1,27 @@
package com.chestnut.media.template.tag; package com.chestnut.media.template.tag;
import java.util.List;
import java.util.Map;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.chestnut.common.utils.StringUtils;
import org.apache.commons.collections4.MapUtils;
import org.springframework.stereotype.Component;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.chestnut.common.staticize.FreeMarkerUtils; import com.chestnut.common.staticize.FreeMarkerUtils;
import com.chestnut.common.staticize.core.TemplateContext; import com.chestnut.common.staticize.core.TemplateContext;
import com.chestnut.common.staticize.enums.TagAttrDataType; import com.chestnut.common.staticize.enums.TagAttrDataType;
import com.chestnut.common.staticize.tag.AbstractListTag; import com.chestnut.common.staticize.tag.AbstractListTag;
import com.chestnut.common.staticize.tag.TagAttr; import com.chestnut.common.staticize.tag.TagAttr;
import com.chestnut.common.utils.StringUtils;
import com.chestnut.contentcore.domain.CmsContent; import com.chestnut.contentcore.domain.CmsContent;
import com.chestnut.contentcore.enums.ContentCopyType; import com.chestnut.contentcore.enums.ContentCopyType;
import com.chestnut.contentcore.service.IContentService; import com.chestnut.contentcore.service.IContentService;
import com.chestnut.contentcore.util.InternalUrlUtils; import com.chestnut.contentcore.util.InternalUrlUtils;
import com.chestnut.media.domain.CmsAudio; import com.chestnut.media.domain.CmsAudio;
import com.chestnut.media.service.IAudioService; import com.chestnut.media.service.IAudioService;
import freemarker.core.Environment; import freemarker.core.Environment;
import freemarker.template.TemplateException; import freemarker.template.TemplateException;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.apache.commons.collections4.MapUtils;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Map;
@RequiredArgsConstructor @RequiredArgsConstructor
@Component @Component
@ -58,6 +56,7 @@ public class CmsAudioTag extends AbstractListTag {
String condition = MapUtils.getString(attrs, TagAttr.AttrName_Condition); String condition = MapUtils.getString(attrs, TagAttr.AttrName_Condition);
LambdaQueryWrapper<CmsAudio> q = new LambdaQueryWrapper<CmsAudio>().eq(CmsAudio::getContentId, contentId); LambdaQueryWrapper<CmsAudio> q = new LambdaQueryWrapper<CmsAudio>().eq(CmsAudio::getContentId, contentId);
q.apply(StringUtils.isNotEmpty(condition), condition); q.apply(StringUtils.isNotEmpty(condition), condition);
q.orderByAsc(CmsAudio::getSortFlag);
Page<CmsAudio> pageResult = this.audioService.page(new Page<>(pageIndex, size, page), q); Page<CmsAudio> pageResult = this.audioService.page(new Page<>(pageIndex, size, page), q);
if (pageIndex > 1 & pageResult.getRecords().size() == 0) { if (pageIndex > 1 & pageResult.getRecords().size() == 0) {
throw new TemplateException("内容列表页码超出上限:" + pageIndex, env); throw new TemplateException("内容列表页码超出上限:" + pageIndex, env);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,75 @@
package com.chestnut.cms.word.template.tag;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.chestnut.common.staticize.enums.TagAttrDataType;
import com.chestnut.common.staticize.tag.AbstractListTag;
import com.chestnut.common.staticize.tag.TagAttr;
import com.chestnut.common.utils.StringUtils;
import com.chestnut.word.domain.TagWord;
import com.chestnut.word.domain.TagWordGroup;
import com.chestnut.word.service.ITagWordGroupService;
import com.chestnut.word.service.ITagWordService;
import freemarker.core.Environment;
import freemarker.template.TemplateException;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections4.MapUtils;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Map;
import java.util.Optional;
@Component
@RequiredArgsConstructor
public class CmsTagWordTag extends AbstractListTag {
public final static String TAG_NAME = "cms_tag_word";
public final static String NAME = "{FREEMARKER.TAG.NAME." + TAG_NAME + "}";
public final static String DESC = "{FREEMARKER.TAG.DESC." + TAG_NAME + "}";
private final ITagWordGroupService tagWordGroupService;
private final ITagWordService tagWordService;
@Override
public List<TagAttr> getTagAttrs() {
List<TagAttr> tagAttrs = super.getTagAttrs();
tagAttrs.add(new TagAttr("group", false, TagAttrDataType.STRING, "TAG词分组编码") );
return tagAttrs;
}
@Override
public TagPageData prepareData(Environment env, Map<String, String> attrs, boolean page, int size, int pageIndex) throws TemplateException {
String group = MapUtils.getString(attrs, "group");
Optional<TagWordGroup> opt = tagWordGroupService.lambdaQuery().eq(TagWordGroup::getCode, group).oneOpt();
if (opt.isEmpty()) {
throw new TemplateException("Tag word group not found: " + group, env);
}
TagWordGroup tagWordGroup = opt.get();
LambdaQueryWrapper<TagWord> q = new LambdaQueryWrapper<TagWord>()
.eq(TagWord::getGroupId, tagWordGroup.getGroupId());
String condition = MapUtils.getString(attrs, TagAttr.AttrName_Condition);
q.apply(StringUtils.isNotEmpty(condition), condition);
q.orderByAsc(TagWord::getSortFlag);
Page<TagWord> pageResult = this.tagWordService.page(new Page<>(pageIndex, size, page), q);
return TagPageData.of(pageResult.getRecords(), pageResult.getTotal());
}
@Override
public String getTagName() {
return TAG_NAME;
}
@Override
public String getName() {
return NAME;
}
@Override
public String getDescription() {
return DESC;
}
}

View File

@ -1,3 +1,7 @@
# freemarker模板函数 # freemarker模板函数
FREEMARKER.FUNC.DESC.replaceHotWord=替换热词链接,例如:${replaceHotWord(content, 'default', '[a href='\{0\}' target='\{2\}']\{1\}[/a]')} FREEMARKER.FUNC.DESC.replaceHotWord=替换热词链接,例如:${replaceHotWord(content, 'default', '[a href='\{0\}' target='\{2\}']\{1\}[/a]')}
FREEMARKER.FUNC.DESC.replaceSensitiveWord=替换敏感词,例如:${replaceSensitiveWord(content, 'xxx')} FREEMARKER.FUNC.DESC.replaceSensitiveWord=替换敏感词,例如:${replaceSensitiveWord(content, 'xxx')}
# freemarker模板标签
FREEMARKER.TAG.NAME.cms_tag_word=TAG词列表标签
FREEMARKER.TAG.DESC.cms_tag_word=根据TAG词分组编码获取TAG词列表内嵌<#list DataList as tag>${tag.word}</#list>遍历数据

View File

@ -1,3 +1,6 @@
# freemarker模板函数 # freemarker模板函数
FREEMARKER.FUNC.DESC.replaceHotWord=Replace hot word in content argument, eg: ${replaceHotWord(content, 'default', '[a href='\{0\}' target='\{2\}']\{1\}[/a]')} FREEMARKER.FUNC.DESC.replaceHotWord=Replace hot word in content argument, eg: ${replaceHotWord(content, 'default', '[a href='\{0\}' target='\{2\}']\{1\}[/a]')}
FREEMARKER.FUNC.DESC.replaceSensitiveWord=Replace sensitive word in content argument, eg: ${replaceSensitiveWord(content, 'xxx')} FREEMARKER.FUNC.DESC.replaceSensitiveWord=Replace sensitive word in content argument, eg: ${replaceSensitiveWord(content, 'xxx')}
FREEMARKER.TAG.NAME.cms_link=TAG Word List Tag
FREEMARKER.TAG.DESC.cms_link=Fetch tag-word list, use <#list> in tag like "<#list DataList as tag>${tag.word}</#list>" to walk through the list of tag-words.

View File

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

View File

@ -18,6 +18,7 @@ import com.chestnut.contentcore.service.IPublishPipeService;
import com.chestnut.contentcore.service.ISiteService; import com.chestnut.contentcore.service.ISiteService;
import com.chestnut.contentcore.util.SiteUtils; import com.chestnut.contentcore.util.SiteUtils;
import com.chestnut.seo.fixed.dict.SitemapPageType; import com.chestnut.seo.fixed.dict.SitemapPageType;
import com.chestnut.seo.publishpipe.PublishPipeProp_EnableSitemap;
import com.chestnut.seo.publishpipe.PublishPipeProp_SitemapPageType; import com.chestnut.seo.publishpipe.PublishPipeProp_SitemapPageType;
import com.chestnut.seo.publishpipe.PublishPipeProp_SitemapUrlLimit; import com.chestnut.seo.publishpipe.PublishPipeProp_SitemapUrlLimit;
import com.chestnut.system.fixed.dict.YesOrNo; import com.chestnut.system.fixed.dict.YesOrNo;
@ -88,7 +89,10 @@ public class BaiduSitemapService {
} }
public void generateSitemapXml(CmsSite site) { public void generateSitemapXml(CmsSite site) {
List<CmsPublishPipe> publishPipes = this.publishPipeService.getPublishPipes(site.getSiteId()); List<CmsPublishPipe> publishPipes = this.publishPipeService.getPublishPipes(site.getSiteId())
.stream().filter(pp ->
PublishPipeProp_EnableSitemap.getValue(pp.getCode(), site.getPublishPipeProps())
).toList();
generateSitemapXml(site, publishPipes); generateSitemapXml(site, publishPipes);
} }

View File

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

View File

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

View File

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

View File

@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.extension.toolkit.SqlRunner;
import com.chestnut.common.db.DBErrorCode; import com.chestnut.common.db.DBErrorCode;
import com.chestnut.common.utils.Assert; import com.chestnut.common.utils.Assert;
import com.chestnut.common.utils.StringUtils; import com.chestnut.common.utils.StringUtils;
import com.google.common.collect.ImmutableSortedMap;
import java.util.*; import java.util.*;
import java.util.stream.Stream; import java.util.stream.Stream;
@ -313,18 +314,18 @@ public class SqlBuilder {
} }
public SqlBuilder orderBy(String field, boolean isAsc) { public SqlBuilder orderBy(String field, boolean isAsc) {
return this.orderBy(Map.of(field, isAsc)); return this.orderBy(ImmutableSortedMap.of(field, isAsc));
} }
public SqlBuilder orderBy(String field1, boolean isAsc1, public SqlBuilder orderBy(String field1, boolean isAsc1,
String field2, boolean isAsc2) { String field2, boolean isAsc2) {
return this.orderBy(Map.of(field1, isAsc1, field2, isAsc2)); return this.orderBy(ImmutableSortedMap.of(field1, isAsc1, field2, isAsc2));
} }
public SqlBuilder orderBy(String field1, boolean isAsc1, public SqlBuilder orderBy(String field1, boolean isAsc1,
String field2, boolean isAsc2, String field2, boolean isAsc2,
String field3, boolean isAsc3) { String field3, boolean isAsc3) {
return this.orderBy(Map.of(field1, isAsc1, field2, isAsc2, field3, isAsc3)); return this.orderBy(ImmutableSortedMap.of(field1, isAsc1, field2, isAsc2, field3, isAsc3));
} }
/** /**

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,26 +1,18 @@
package com.chestnut.common.staticize; package com.chestnut.common.staticize;
import com.chestnut.common.staticize.core.TemplateContext;
import com.chestnut.common.utils.DateUtils;
import com.chestnut.common.utils.NumberUtils;
import com.chestnut.common.utils.StringUtils;
import freemarker.core.Environment;
import freemarker.template.*;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import com.chestnut.common.staticize.core.TemplateContext;
import com.chestnut.common.utils.DateUtils;
import com.chestnut.common.utils.NumberUtils;
import com.chestnut.common.utils.StringUtils;
import freemarker.core.Environment;
import freemarker.template.AdapterTemplateModel;
import freemarker.template.TemplateBooleanModel;
import freemarker.template.TemplateDateModel;
import freemarker.template.TemplateHashModel;
import freemarker.template.TemplateModel;
import freemarker.template.TemplateModelException;
import freemarker.template.TemplateNumberModel;
import freemarker.template.TemplateScalarModel;
public class FreeMarkerUtils { public class FreeMarkerUtils {
/** /**
@ -40,6 +32,8 @@ public class FreeMarkerUtils {
env.getObjectWrapper().wrap(context.getFirstFileName())); env.getObjectWrapper().wrap(context.getFirstFileName()));
env.setGlobalVariable(StaticizeConstants.TemplateVariable_OtherPage, env.setGlobalVariable(StaticizeConstants.TemplateVariable_OtherPage,
env.getObjectWrapper().wrap(context.getOtherFileName())); env.getObjectWrapper().wrap(context.getOtherFileName()));
env.setGlobalVariable(StaticizeConstants.TemplateVariable_TimeMillis,
env.getObjectWrapper().wrap(context.getTimeMillis()));
} }
public static TemplateContext getTemplateContext(Environment env) throws TemplateModelException { public static TemplateContext getTemplateContext(Environment env) throws TemplateModelException {

View File

@ -41,4 +41,9 @@ public class StaticizeConstants {
* 模板变量自定义上下文 * 模板变量自定义上下文
*/ */
public static final String TemplateVariable_TemplateContext = "TemplateContext"; public static final String TemplateVariable_TemplateContext = "TemplateContext";
/**
* 模板解析时间
*/
public static final String TemplateVariable_TimeMillis = "TimeMillis";
} }

View File

@ -1,24 +1,22 @@
package com.chestnut.common.staticize; package com.chestnut.common.staticize;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.List;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import com.chestnut.common.staticize.core.TemplateContext; import com.chestnut.common.staticize.core.TemplateContext;
import com.chestnut.common.staticize.func.IFunction; import com.chestnut.common.staticize.func.IFunction;
import com.chestnut.common.staticize.tag.ITag; import com.chestnut.common.staticize.tag.ITag;
import com.chestnut.common.utils.Assert; import com.chestnut.common.utils.Assert;
import freemarker.core.Environment; import freemarker.core.Environment;
import freemarker.template.Configuration; import freemarker.template.Configuration;
import freemarker.template.Template; import freemarker.template.Template;
import freemarker.template.TemplateException; import freemarker.template.TemplateException;
import freemarker.template.TemplateModelException; import freemarker.template.TemplateModelException;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.List;
@Slf4j @Slf4j
@Service @Service
@ -29,8 +27,8 @@ public class StaticizeService {
public StaticizeService(@Qualifier("staticizeConfiguration") Configuration cfg, List<ITag> tags, public StaticizeService(@Qualifier("staticizeConfiguration") Configuration cfg, List<ITag> tags,
List<IFunction> functions) { List<IFunction> functions) {
this.cfg = cfg; this.cfg = cfg;
tags.forEach(this::registTag); tags.forEach(this::registerTag);
functions.forEach(this::registFunction); functions.forEach(this::registerFunction);
} }
/** /**
@ -40,7 +38,7 @@ public class StaticizeService {
* 此方法只返回TemplateContext中制定页码的静态化结果 * 此方法只返回TemplateContext中制定页码的静态化结果
* </p> * </p>
* *
* @param templateContext * @param context
* @param writer * @param writer
* @throws TemplateException * @throws TemplateException
* @throws IOException * @throws IOException
@ -50,6 +48,7 @@ public class StaticizeService {
Template template = cfg.getTemplate(context.getTemplateId()); Template template = cfg.getTemplate(context.getTemplateId());
// 处理模板 // 处理模板
long s = System.currentTimeMillis(); long s = System.currentTimeMillis();
context.setTimeMillis(s);
Environment env = template.createProcessingEnvironment(context.getVariables(), writer); Environment env = template.createProcessingEnvironment(context.getVariables(), writer);
FreeMarkerUtils.addGlobalVariables(env, context); FreeMarkerUtils.addGlobalVariables(env, context);
env.process(); env.process();
@ -60,7 +59,7 @@ public class StaticizeService {
/** /**
* 生成静态化文件自动处理分页 * 生成静态化文件自动处理分页
* *
* @param templateContext * @param context
* @throws TemplateException * @throws TemplateException
* @throws IOException * @throws IOException
*/ */
@ -69,6 +68,7 @@ public class StaticizeService {
Template template = cfg.getTemplate(context.getTemplateId()); Template template = cfg.getTemplate(context.getTemplateId());
// 处理模板 // 处理模板
long s = System.currentTimeMillis(); long s = System.currentTimeMillis();
context.setTimeMillis(s);
Environment env = null; Environment env = null;
String filePath = context.getStaticizeFilePath(context.getPageIndex()); String filePath = context.getStaticizeFilePath(context.getPageIndex());
try (FileWriter writer = new FileWriter(filePath)) { try (FileWriter writer = new FileWriter(filePath)) {
@ -102,27 +102,27 @@ public class StaticizeService {
cfg.clearTemplateCache(); cfg.clearTemplateCache();
} }
public void registTag(ITag tag) { public void registerTag(ITag tag) {
// 注册模板标签 // 注册模板标签
try { try {
Assert.isNull(cfg.getSharedVariable(tag.getTagName()), Assert.isNull(cfg.getSharedVariable(tag.getTagName()),
() -> new IllegalArgumentException("Freemarker directive conflict: " + tag.getTagName())); () -> new IllegalArgumentException("Freemarker directive conflict: " + tag.getTagName()));
cfg.setSharedVariable(tag.getTagName(), tag); cfg.setSharedVariable(tag.getTagName(), tag);
} catch (TemplateModelException e) { } catch (TemplateModelException e) {
log.error("Freemarker directive '<@{}>' regist failed.", tag.getTagName()); log.error("Freemarker directive '<@{}>' register failed.", tag.getTagName());
throw new IllegalArgumentException(e); throw new IllegalArgumentException(e);
} }
log.info("Freemarker directive: <@{}>", tag.getTagName()); log.info("Freemarker directive: <@{}>", tag.getTagName());
} }
public void registFunction(IFunction func) { public void registerFunction(IFunction func) {
// 注册模板函数 // 注册模板函数
try { try {
Assert.isNull(cfg.getSharedVariable(func.getFuncName()), Assert.isNull(cfg.getSharedVariable(func.getFuncName()),
() -> new IllegalArgumentException("Freemarker function conflict: " + func.getFuncName())); () -> new IllegalArgumentException("Freemarker function conflict: " + func.getFuncName()));
cfg.setSharedVariable(func.getFuncName(), func); cfg.setSharedVariable(func.getFuncName(), func);
} catch (TemplateModelException e) { } catch (TemplateModelException e) {
log.error("Freemarker function '{}' regist failed.", func.getFuncName()); log.error("Freemarker function '{}' register failed.", func.getFuncName());
throw new IllegalArgumentException(e); throw new IllegalArgumentException(e);
} }
log.info("Freemarker function: {}", func.getFuncName()); log.info("Freemarker function: {}", func.getFuncName());

View File

@ -1,14 +1,13 @@
package com.chestnut.common.staticize.core; package com.chestnut.common.staticize.core;
import java.util.HashMap;
import java.util.Map;
import com.chestnut.common.utils.StringUtils; import com.chestnut.common.utils.StringUtils;
import com.chestnut.common.utils.file.FileExUtils; import com.chestnut.common.utils.file.FileExUtils;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import java.util.HashMap;
import java.util.Map;
/** /**
* 模板上下文 * 模板上下文
*/ */
@ -80,6 +79,11 @@ public class TemplateContext {
* 注意需要生成多页面的模板中只能有一个page=true的列表标签存在多个会覆盖掉分页属性 * 注意需要生成多页面的模板中只能有一个page=true的列表标签存在多个会覆盖掉分页属性
*/ */
private boolean paged; private boolean paged;
/**
* 模板处理时间
*/
private Long timeMillis;
public TemplateContext(String templateId, boolean preview, String publishPipeCode) { public TemplateContext(String templateId, boolean preview, String publishPipeCode) {
this.templateId = templateId; this.templateId = templateId;

View File

@ -91,7 +91,8 @@ public class PageBarTag extends AbstractTag {
private String generatePageBar(String target, String firstPage, String lastPage, boolean withFirstAndLast, Environment env) private String generatePageBar(String target, String firstPage, String lastPage, boolean withFirstAndLast, Environment env)
throws TemplateException { throws TemplateException {
TemplateContext context = FreeMarkerUtils.getTemplateContext(env); TemplateContext context = FreeMarkerUtils.getTemplateContext(env);
int pageCount = Long.valueOf((context.getPageTotal() + context.getPageSize() - 1 ) / context.getPageSize()).intValue(); int pageSize = context.getPageSize() == 0 ? 20 : context.getPageSize();
int pageCount = Long.valueOf((context.getPageTotal() + pageSize - 1 ) / pageSize).intValue();
int startPage = 1; int startPage = 1;
int endPage = 7; int endPage = 7;
if (context.getPageIndex() > 4) { if (context.getPageIndex() > 4) {
@ -106,7 +107,7 @@ public class PageBarTag extends AbstractTag {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append("<div class=\"pagination\">"); sb.append("<div class=\"pagination\">");
if (withFirstAndLast && startPage > 1) { if (withFirstAndLast && startPage > 1) {
sb.append(StringUtils.messageFormat(temp, firstPageLink, "", target, firstPage)); sb.append(StringUtils.messageFormat(temp, firstPageLink, " page_first", target, firstPage));
sb.append("<a href=\"javascript:;\" class=\"page_white\">...</a>"); sb.append("<a href=\"javascript:;\" class=\"page_white\">...</a>");
} }
for (int i = startPage; i <= endPage; i++) { for (int i = startPage; i <= endPage; i++) {
@ -120,7 +121,7 @@ public class PageBarTag extends AbstractTag {
} }
if (withFirstAndLast && endPage < pageCount) { if (withFirstAndLast && endPage < pageCount) {
sb.append("<a href=\"javascript:;\" class=\"page_white\">...</a>"); sb.append("<a href=\"javascript:;\" class=\"page_white\">...</a>");
sb.append(StringUtils.messageFormat(temp, StringUtils.messageFormat(otherPageLink, pageCount), "", target, lastPage)); sb.append(StringUtils.messageFormat(temp, StringUtils.messageFormat(otherPageLink, pageCount), " page_last", target, lastPage));
} }
sb.append("</div>"); sb.append("</div>");
return sb.toString(); return sb.toString();

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,6 +1,6 @@
{ {
"name": "ChestnutCMS", "name": "ChestnutCMS",
"version": "1.3.21", "version": "1.3.23",
"description": "ChestnutCMS[栗子内容管理系统]", "description": "ChestnutCMS[栗子内容管理系统]",
"author": "", "author": "",
"license": "Apache-2.0", "license": "Apache-2.0",

View File

@ -0,0 +1,25 @@
import request from '@/utils/request'
export function getRelaContentList(query) {
return request({
url: '/cms/content/rela',
method: 'get',
params: query
})
}
export function addRelaContents(data) {
return request({
url: '/cms/content/rela?contentId=' + data.contentId,
method: 'post',
data: data.relaContentIds
})
}
export function delRelaContents(data) {
return request({
url: '/cms/content/rela?contentId=' + data.contentId,
method: 'delete',
data: data.relaContentIds
})
}

View File

@ -97,3 +97,10 @@
font-size: 14px; font-size: 14px;
border-radius: 4px; border-radius: 4px;
} }
.btn-cell-wrap + .btn-cell-wrap {
margin-left: 10px;
}
.btn-cell-wrap:empty {
margin-left: 0;
}

View File

@ -1,6 +1,9 @@
/** /**
* v-hasPermi 操作权限处理 * v-hasPermi 操作权限处理
* Copyright (c) 2023 兮玥190785909@qq.com * Copyright (c) 2023 兮玥190785909@qq.com
*
* 1非el-button标签的按钮权限需要给对应控件添加class="btn-permi"
* 2表格操作列的多个按钮需要给按钮添加一个<span class="btn-cell-wrap"></span>
*/ */
import store from '@/store' import store from '@/store'
@ -18,27 +21,15 @@ function fn (el, binding) {
}) })
if (!hasPermissions) { if (!hasPermissions) {
if (el.cacheParentElement && el.cacheParentElement.className.split(' ').indexOf('el-dropdown') > -1) { if (el.classList.contains('el-button') || el.classList.contains("btn-permi")) {
el.cacheParentElement.parentNode.removeChild(el.cacheParentElement) el.cacheParentElement && el.cacheParentElement.removeChild(el)
el.cacheParentElement.parentNode.style.display = 'none'; } else if (el.classList.contains('el-dropdown-menu__item')) {
} else if (el.className.indexOf('el-button') > -1) {
el.parentNode && el.parentNode.removeChild(el)
if (el.cacheParentElement != null) {
el.cacheParentElement.style.display = 'none';
}
} else if (el.className.indexOf('el-dropdown-menu__item') > -1) {
el.cacheElement.style.display = 'none'; el.cacheElement.style.display = 'none';
} }
} else { } else {
if (el.cacheParentElement && el.cacheParentElement.className.split(' ').indexOf('el-dropdown') > -1) { if (el.classList.contains('el-button') || el.classList.contains("btn-permi")) {
el.cacheParentElement.parentNode.appendChild(el.cacheElement.parentNode) el.cacheParentElement && el.cacheParentElement.appendChild(el.cacheElement)
el.cacheParentElement.parentNode.style.display = ''; } else if (el.classList.contains('el-dropdown-menu__item')) {
} else if (el.className.indexOf('el-button') > -1) {
if (el.cacheParentElement) {
el.cacheParentElement.appendChild(el.cacheElement)
el.cacheParentElement.style.display = '';
}
} else if (el.className.indexOf('el-dropdown-menu__item') > -1) {
if (el.cacheElement) { if (el.cacheElement) {
el.cacheElement.style.display = ''; el.cacheElement.style.display = '';
} }

View File

@ -1128,7 +1128,8 @@ export default {
ViewCount: "Views", ViewCount: "Views",
FavoriteCount: "Favorities", FavoriteCount: "Favorities",
LikeCount: "Likes", LikeCount: "Likes",
CommentCount: "Comments" CommentCount: "Comments",
RelaContent: "Related contents"
}, },
Image: { Image: {
Title: "Title", Title: "Title",

View File

@ -1128,7 +1128,8 @@ export default {
ViewCount: "浏览量", ViewCount: "浏览量",
FavoriteCount: "收藏数", FavoriteCount: "收藏数",
LikeCount: "点赞数", LikeCount: "点赞数",
CommentCount: "评论数" CommentCount: "评论数",
RelaContent: "相关内容"
}, },
Image: { Image: {
Title: "标题", Title: "标题",

View File

@ -2,19 +2,25 @@
<div class="app-container adv-editor-container" v-loading="loading"> <div class="app-container adv-editor-container" v-loading="loading">
<el-container> <el-container>
<el-header height="40px"> <el-header height="40px">
<el-button <el-row :gutter="10" class="btn-row">
plain <el-col :span="1.5">
type="info" <el-button
icon="el-icon-back" plain
size="mini" type="info"
@click="handleGoBack">{{ $t('CMS.Adv.GoBack') }}</el-button> icon="el-icon-back"
<el-button size="mini"
plain @click="handleGoBack">{{ $t('CMS.Adv.GoBack') }}</el-button>
type="success" </el-col>
icon="el-icon-edit" <el-col :span="1.5">
size="mini" <el-button
v-hasPermi="[ $p('PageWidget:Edit:{0}', [ adSpaceId ]) ]" plain
@click="handleSave">{{ $t("Common.Save") }}</el-button> type="success"
icon="el-icon-edit"
size="mini"
v-hasPermi="[ $p('PageWidget:Edit:{0}', [ adSpaceId ]) ]"
@click="handleSave">{{ $t("Common.Save") }}</el-button>
</el-col>
</el-row>
</el-header> </el-header>
<el-form <el-form
ref="form" ref="form"

View File

@ -1,24 +1,29 @@
<template> <template>
<div class="catalog-extend-container"> <div class="catalog-extend-container">
<el-row class="mb12"> <el-row class="mb12">
<el-button <el-col :span="1.5">
plain <el-button
type="success" plain
icon="el-icon-edit" type="success"
size="mini" icon="el-icon-edit"
:disabled="!this.catalogId" size="mini"
v-hasPermi="[ $p('Catalog:Edit:{0}', [ catalogId ]) ]" :disabled="!this.catalogId"
@click="handleSaveExtends">{{ $t("Common.Save") }}</el-button> v-hasPermi="[ $p('Catalog:Edit:{0}', [ catalogId ]) ]"
<el-button @click="handleSaveExtends">{{ $t("Common.Save") }}</el-button>
plain </el-col>
type="primary" <el-col :span="1.5">
icon="el-icon-bottom-right" <el-button
size="mini" plain
:disabled="!this.catalogId" type="primary"
v-hasPermi="[ $p('Catalog:Edit:{0}', [ catalogId ]) ]" icon="el-icon-bottom-right"
@click="handleApplyAllToCatalog()">{{ $t('CMS.Catalog.ApplyToChildren') }}</el-button> size="mini"
:disabled="!this.catalogId"
v-hasPermi="[ $p('Catalog:Edit:{0}', [ catalogId ]) ]"
@click="handleApplyAllToCatalog()">{{ $t('CMS.Catalog.ApplyToChildren') }}</el-button>
</el-col>
</el-row> </el-row>
<el-form <el-form
class="catalog-extend-form"
ref="form_extend" ref="form_extend"
:model="form_extend" :model="form_extend"
v-loading="loading" v-loading="loading"
@ -242,22 +247,22 @@ export default {
} }
}; };
</script> </script>
<style> <style scoped>
.catalog-extend-container .el-form-item { .catalog-extend-form .el-form-item {
margin-bottom: 12px; margin-bottom: 12px;
width: 700px; width: 700px;
} }
.catalog-extend-container .el-card { .catalog-extend-form .el-card {
margin-bottom: 10px; margin-bottom: 10px;
} }
.catalog-extend-container .el-input, .el-select, .catalog-extend-form .el-input, .el-select,
.catalog-extend-container .el-input-number { .catalog-extend-form .el-input-number {
width: 301.5px; width: 301.5px;
} }
.catalog-extend-container .el-upload-list { .catalog-extend-form .el-upload-list {
width: 300px; width: 300px;
} }
.catalog-extend-container .btn-apply-child { .catalog-extend-form .btn-apply-child {
padding: 10px; padding: 10px;
} }
</style> </style>

View File

@ -20,18 +20,17 @@
@click="handlePreview"><svg-icon icon-class="eye-open" class="mr5"></svg-icon>{{ $t('CMS.ContentCore.Preview') }}</el-button> @click="handlePreview"><svg-icon icon-class="eye-open" class="mr5"></svg-icon>{{ $t('CMS.ContentCore.Preview') }}</el-button>
</el-col> </el-col>
<el-col :span="1.5"> <el-col :span="1.5">
<el-dropdown> <el-dropdown class="btn-permi" v-hasPermi="[ $p('Catalog:Publish:{0}', [ catalogId ]) ]">
<el-button <el-button
plain plain
size="mini" size="mini"
type="primary" type="primary"
icon="el-icon-s-promotion" icon="el-icon-s-promotion"
:disabled="!this.catalogId" :disabled="!this.catalogId"
v-hasPermi="[ $p('Catalog:Publish:{0}', [ catalogId ]) ]"
@click="handlePublish(-1)"> @click="handlePublish(-1)">
{{ $t('CMS.ContentCore.Publish') }}<i class="el-icon-arrow-down el-icon--right"></i> {{ $t('CMS.ContentCore.Publish') }}<i class="el-icon-arrow-down el-icon--right"></i>
</el-button> </el-button>
<el-dropdown-menu slot="dropdown" :key="'btn-publish2-' + catalogId" v-hasPermi="[ $p('Catalog:Publish:{0}', [ catalogId ]) ]"> <el-dropdown-menu slot="dropdown" :key="'btn-publish2-' + catalogId">
<el-dropdown-item <el-dropdown-item
v-for="dict in dict.type.CMSContentStatus" v-for="dict in dict.type.CMSContentStatus"
:key="dict.value" :key="dict.value"
@ -65,6 +64,7 @@
<el-popover <el-popover
width="226" width="226"
:disabled="!this.catalogId" :disabled="!this.catalogId"
class="btn-permi"
v-hasPermi="[ $p('Catalog:Sort:{0}', [ catalogId ]) ]" v-hasPermi="[ $p('Catalog:Sort:{0}', [ catalogId ]) ]"
v-model="showSortPop"> v-model="showSortPop">
<el-input-number v-model="sortValue" size="small" style="width:200px;" /> <el-input-number v-model="sortValue" size="small" style="width:200px;" />
@ -85,16 +85,15 @@
</el-popover> </el-popover>
</el-col> </el-col>
<el-col :span="1.5"> <el-col :span="1.5">
<el-popconfirm :title="$t('CMS.Catalog.DeleteTip')" @confirm="handleDelete"> <el-popconfirm :title="$t('CMS.Catalog.DeleteTip')" @confirm="handleDelete" class="btn-permi" v-hasPermi="[ $p('Catalog:Delete:{0}', [ catalogId ]) ]">
<el-button <el-button
type="danger" type="danger"
icon="el-icon-delete" icon="el-icon-delete"
size="mini" size="mini"
plain plain
:disabled="!this.catalogId" :disabled="!this.catalogId"
v-hasPermi="[ $p('Catalog:Delete:{0}', [ catalogId ]) ]" slot="reference">{{ $t("Common.Delete") }}</el-button>
slot="reference">{{ $t("Common.Delete") }}</el-button> </el-popconfirm>
</el-popconfirm>
</el-col> </el-col>
</el-row> </el-row>
<el-form <el-form

View File

@ -9,6 +9,7 @@
<el-button plain type="primary" size="mini" @click="handlePreview"><svg-icon icon-class="eye-open" class="mr5"></svg-icon>{{ $t('CMS.ContentCore.Preview') }}</el-button> <el-button plain type="primary" size="mini" @click="handlePreview"><svg-icon icon-class="eye-open" class="mr5"></svg-icon>{{ $t('CMS.ContentCore.Preview') }}</el-button>
<el-button plain type="warning" v-if="isLock" size="mini" icon="el-icon-unlock" @click="handleChangeLockState">{{ $t('CMS.Content.Unlock') }}</el-button> <el-button plain type="warning" v-if="isLock" size="mini" icon="el-icon-unlock" @click="handleChangeLockState">{{ $t('CMS.Content.Unlock') }}</el-button>
<el-button plain type="primary" v-else size="mini" icon="el-icon-lock" @click="handleChangeLockState">{{ $t('CMS.Content.Lock') }}</el-button> <el-button plain type="primary" v-else size="mini" icon="el-icon-lock" @click="handleChangeLockState">{{ $t('CMS.Content.Lock') }}</el-button>
<el-button plain type="primary" size="mini" icon="el-icon-share" @click="handleRelaContent">{{ $t('CMS.Content.RelaContent') }}</el-button>
<el-button v-if="openEditorW" plain type="warning" size="mini" icon="el-icon-close" @click="handleClose">{{ $t('Common.Close') }}</el-button> <el-button v-if="openEditorW" plain type="warning" size="mini" icon="el-icon-close" @click="handleClose">{{ $t('Common.Close') }}</el-button>
<el-button v-else plain type="warning" size="mini" icon="el-icon-back" @click="handleGoBack">{{ $t('CMS.Content.BackToList') }}</el-button> <el-button v-else plain type="warning" size="mini" icon="el-icon-back" @click="handleGoBack">{{ $t('CMS.Content.BackToList') }}</el-button>
</div> </div>
@ -229,6 +230,7 @@
:open="openContentSelector" :open="openContentSelector"
@ok="handleContentSelectorOk" @ok="handleContentSelectorOk"
@close="handleContentSelectorClose"></cms-content-selector> @close="handleContentSelectorClose"></cms-content-selector>
<cms-content-rela-dialog :cid="contentId" :open="openRelaContentDialog" @close="handleRelaContentClose"></cms-content-rela-dialog>
<!-- 进度条 --> <!-- 进度条 -->
<cms-progress :title="progressTitle" :open.sync="openProgress" :taskId="taskId" @close="handleProgressClose"></cms-progress> <cms-progress :title="progressTitle" :open.sync="openProgress" :taskId="taskId" @close="handleProgressClose"></cms-progress>
</div> </div>
@ -246,6 +248,7 @@ import CMSLogoView from '@/views/cms/components/LogoView';
import CMSResourceDialog from "@/views/cms/contentcore/resourceDialog"; import CMSResourceDialog from "@/views/cms/contentcore/resourceDialog";
import CMSCatalogSelector from "@/views/cms/contentcore/catalogSelector"; import CMSCatalogSelector from "@/views/cms/contentcore/catalogSelector";
import CMSContentSelector from "@/views/cms/contentcore/contentSelector"; import CMSContentSelector from "@/views/cms/contentcore/contentSelector";
import CMSContrentRelaDialog from '@/views/cms/contentcore/contentRelaDialog';
import CMSTemplateSelector from '@/views/cms/contentcore/templateSelector'; import CMSTemplateSelector from '@/views/cms/contentcore/templateSelector';
import CMSEXModelEditor from '@/views/cms/components/EXModelEditor'; import CMSEXModelEditor from '@/views/cms/components/EXModelEditor';
import CMSTagEditor from '@/views/cms/components/TagEditor'; import CMSTagEditor from '@/views/cms/components/TagEditor';
@ -269,6 +272,7 @@ export default {
"cms-logo-view": CMSLogoView, "cms-logo-view": CMSLogoView,
'cms-catalog-selector': CMSCatalogSelector, 'cms-catalog-selector': CMSCatalogSelector,
'cms-content-selector': CMSContentSelector, 'cms-content-selector': CMSContentSelector,
'cms-content-rela-dialog': CMSContrentRelaDialog,
"cms-exmodel-editor": CMSEXModelEditor, "cms-exmodel-editor": CMSEXModelEditor,
"cms-tag-editor": CMSTagEditor, "cms-tag-editor": CMSTagEditor,
// "ckeditor": CKEditor5 // "ckeditor": CKEditor5
@ -324,6 +328,7 @@ export default {
selectExTemplate: false, selectExTemplate: false,
publishAfterSave: false, publishAfterSave: false,
toPublishAfterSave: false, toPublishAfterSave: false,
openRelaContentDialog: false,
}; };
}, },
created() { created() {
@ -594,6 +599,28 @@ export default {
handleContentSelectorOk(contents) { handleContentSelectorOk(contents) {
if (contents && contents.length > 0) { if (contents && contents.length > 0) {
this.form.redirectUrl = contents[0].internalUrl; this.form.redirectUrl = contents[0].internalUrl;
if (!this.form.logo || this.form.logo.length == 0) {
this.form.logo = contents[0].logo;
this.form.logoSrc = contents[0].logoSrc;
}
if (!this.form.title || this.form.title.length == 0) {
this.form.title = contents[0].title;
}
if (!this.form.author || this.form.author.length == 0) {
this.form.author = contents[0].author;
}
if (!this.form.editor || this.form.editor.length == 0) {
this.form.editor = contents[0].editor;
}
if (!this.form.tags || this.form.tags.length == 0) {
this.form.tags = contents[0].tags;
}
if (!this.form.keywords || this.form.keywords.length == 0) {
this.form.keywords = contents[0].keywords;
}
if (!this.form.summary || this.form.summary.length == 0) {
this.form.summary = contents[0].summary;
}
this.openContentSelector = false; this.openContentSelector = false;
} else { } else {
this.$modal.msgWarning(this.$t('Common.SelectFirst')); this.$modal.msgWarning(this.$t('Common.SelectFirst'));
@ -601,6 +628,12 @@ export default {
}, },
handleContentSelectorClose() { handleContentSelectorClose() {
this.openContentSelector = false; this.openContentSelector = false;
},
handleRelaContent() {
this.openRelaContentDialog = true;
},
handleRelaContentClose() {
this.openRelaContentDialog = false;
} }
} }
}; };

View File

@ -2,7 +2,7 @@
<div class="cms-content-list"> <div class="cms-content-list">
<el-row :gutter="10" class="mb12"> <el-row :gutter="10" class="mb12">
<el-col :span="1.5"> <el-col :span="1.5">
<el-popover placement="bottom-start" :width="350" trigger="click"> <el-popover class="btn-permi" placement="bottom-start" :width="350" trigger="click" v-hasPermi="[ $p('Catalog:AddContent:{0}', [ catalogId ]) ]">
<el-row style="margin-bottom:20px;text-align:right;"> <el-row style="margin-bottom:20px;text-align:right;">
<el-radio-group v-model="addContentType"> <el-radio-group v-model="addContentType">
<el-radio-button <el-radio-button
@ -35,6 +35,7 @@
icon="el-icon-delete" icon="el-icon-delete"
size="mini" size="mini"
:disabled="multiple" :disabled="multiple"
v-hasPermi="[ $p('Catalog:DeleteContent:{0}', [ catalogId ]) ]"
@click="handleDelete">{{ $t("Common.Delete") }} @click="handleDelete">{{ $t("Common.Delete") }}
</el-button> </el-button>
</el-col> </el-col>
@ -45,6 +46,7 @@
icon="el-icon-timer" icon="el-icon-timer"
size="mini" size="mini"
:disabled="multiple" :disabled="multiple"
v-hasPermi="[ $p('Catalog:EditContent:{0}', [ catalogId ]) ]"
@click="handleToPublish">{{ $t("CMS.ContentCore.ToPublish") }} @click="handleToPublish">{{ $t("CMS.ContentCore.ToPublish") }}
</el-button> </el-button>
</el-col> </el-col>
@ -55,6 +57,7 @@
icon="el-icon-s-promotion" icon="el-icon-s-promotion"
size="mini" size="mini"
:disabled="multiple" :disabled="multiple"
v-hasPermi="[ $p('Catalog:EditContent:{0}', [ catalogId ]) ]"
@click="handlePublish">{{ $t("CMS.ContentCore.Publish") }} @click="handlePublish">{{ $t("CMS.ContentCore.Publish") }}
</el-button> </el-button>
</el-col> </el-col>
@ -65,6 +68,7 @@
icon="el-icon-download" icon="el-icon-download"
size="mini" size="mini"
:disabled="multiple" :disabled="multiple"
v-hasPermi="[ $p('Catalog:EditContent:{0}', [ catalogId ]) ]"
@click="handleOffline">{{ $t("CMS.Content.Offline") }} @click="handleOffline">{{ $t("CMS.Content.Offline") }}
</el-button> </el-button>
</el-col> </el-col>
@ -89,7 +93,7 @@
</el-button> </el-button>
</el-col> </el-col>
<el-col :span="1.5"> <el-col :span="1.5">
<el-dropdown> <el-dropdown class="btn-permi" v-hasPermi="[ $p('Catalog:EditContent:{0}', [ catalogId ]) ]">
<el-button <el-button
plain plain
size="mini" size="mini"
@ -104,7 +108,7 @@
</el-dropdown> </el-dropdown>
</el-col> </el-col>
<el-col :span="1.5"> <el-col :span="1.5">
<el-dropdown> <el-dropdown class="btn-permi" v-hasPermi="[ $p('Catalog:EditContent:{0}', [ catalogId ]) ]">
<el-button <el-button
plain plain
size="mini" size="mini"
@ -231,32 +235,40 @@
width="220" width="220"
class-name="small-padding fixed-width"> class-name="small-padding fixed-width">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button <span class="btn-cell-wrap">
size="small" <el-button
type="text" size="small"
icon="el-icon-s-promotion" type="text"
@click="handlePublish(scope.row)">{{ $t('CMS.ContentCore.Publish') }}</el-button> icon="el-icon-view"
<el-button @click="handlePreview(scope.row)">{{ $t('CMS.ContentCore.Preview') }}</el-button>
size="small" </span>
type="text" <span class="btn-cell-wrap">
icon="el-icon-view" <el-button
@click="handlePreview(scope.row)">{{ $t('CMS.ContentCore.Preview') }}</el-button> size="small"
<el-button type="text"
size="small" icon="el-icon-s-promotion"
type="text" v-hasPermi="[ $p('Catalog:EditContent:{0}', [ scope.row.catalogId ]) ]"
icon="el-icon-timer" @click="handlePublish(scope.row)">{{ $t('CMS.ContentCore.Publish') }}</el-button>
@click="handleToPublish(scope.row)">{{ $t('CMS.ContentCore.ToPublish') }}</el-button> </span>
<span class="btn-cell-wrap">
<el-button
size="small"
type="text"
icon="el-icon-timer"
v-hasPermi="[ $p('Catalog:EditContent:{0}', [ scope.row.catalogId ]) ]"
@click="handleToPublish(scope.row)">{{ $t('CMS.ContentCore.ToPublish') }}</el-button>
</span>
<el-dropdown size="small"> <el-dropdown size="small">
<el-link :underline="false" class="row-more-btn" icon="el-icon-more"></el-link> <el-link :underline="false" class="row-more-btn" icon="el-icon-more"></el-link>
<el-dropdown-menu slot="dropdown"> <el-dropdown-menu slot="dropdown">
<el-dropdown-item icon="el-icon-edit" @click.native="handleEdit(scope.row)">{{ $t('Common.Edit') }}</el-dropdown-item> <el-dropdown-item icon="el-icon-edit" @click.native="handleEdit(scope.row)" v-hasPermi="[ $p('Catalog:EditContent:{0}', [ scope.row.catalogId ]) ]">{{ $t('Common.Edit') }}</el-dropdown-item>
<el-dropdown-item icon="el-icon-delete" @click.native="handleDelete(scope.row)">{{ $t('Common.Delete') }}</el-dropdown-item> <el-dropdown-item icon="el-icon-delete" @click.native="handleDelete(scope.row)" v-hasPermi="[ $p('Catalog:DeleteContent:{0}', [ scope.row.catalogId ]) ]">{{ $t('Common.Delete') }}</el-dropdown-item>
<el-dropdown-item icon="el-icon-sort" @click.native="handleSort(scope.row)">{{ $t('Common.Sort') }}</el-dropdown-item> <el-dropdown-item icon="el-icon-sort" @click.native="handleSort(scope.row)" v-hasPermi="[ $p('Catalog:EditContent:{0}', [ scope.row.catalogId ]) ]">{{ $t('Common.Sort') }}</el-dropdown-item>
<el-dropdown-item v-show="scope.row.topFlag<=0" icon="el-icon-top" @click.native="handleSetTop(scope.row)">{{ $t('CMS.Content.SetTop') }}</el-dropdown-item> <el-dropdown-item v-show="scope.row.topFlag<=0" icon="el-icon-top" @click.native="handleSetTop(scope.row)" v-hasPermi="[ $p('Catalog:EditContent:{0}', [ scope.row.catalogId ]) ]">{{ $t('CMS.Content.SetTop') }}</el-dropdown-item>
<el-dropdown-item v-show="scope.row.topFlag>0" icon="el-icon-bottom" @click.native="handleCancelTop(scope.row)">{{ $t('CMS.Content.CancelTop') }}</el-dropdown-item> <el-dropdown-item v-show="scope.row.topFlag>0" icon="el-icon-bottom" @click.native="handleCancelTop(scope.row)" v-hasPermi="[ $p('Catalog:EditContent:{0}', [ scope.row.catalogId ]) ]">{{ $t('CMS.Content.CancelTop') }}</el-dropdown-item>
<el-dropdown-item icon="el-icon-document-copy" @click.native="handleCopy(scope.row)">{{ $t('Common.Copy') }}</el-dropdown-item> <el-dropdown-item icon="el-icon-document-copy" @click.native="handleCopy(scope.row)">{{ $t('Common.Copy') }}</el-dropdown-item>
<el-dropdown-item icon="el-icon-right" @click.native="handleMove(scope.row)">{{ $t('Common.Move') }}</el-dropdown-item> <el-dropdown-item icon="el-icon-right" @click.native="handleMove(scope.row)">{{ $t('Common.Move') }}</el-dropdown-item>
<el-dropdown-item icon="el-icon-download" @click.native="handleOffline(scope.row)">{{ $t('CMS.Content.Offline') }}</el-dropdown-item> <el-dropdown-item icon="el-icon-download" @click.native="handleOffline(scope.row)" v-hasPermi="[ $p('Catalog:EditContent:{0}', [ scope.row.catalogId ]) ]">{{ $t('CMS.Content.Offline') }}</el-dropdown-item>
<!-- <el-dropdown-item icon="el-icon-document" @click.native="handleArchive(scope.row)">{{ $t('CMS.Content.Archive') }}</el-dropdown-item> --> <!-- <el-dropdown-item icon="el-icon-document" @click.native="handleArchive(scope.row)">{{ $t('CMS.Content.Archive') }}</el-dropdown-item> -->
<el-dropdown-item icon="el-icon-search" @click.native="handleCreateIndex(scope.row)">{{ $t('CMS.Content.GenIndex') }}</el-dropdown-item> <el-dropdown-item icon="el-icon-search" @click.native="handleCreateIndex(scope.row)">{{ $t('CMS.Content.GenIndex') }}</el-dropdown-item>
</el-dropdown-menu> </el-dropdown-menu>

View File

@ -0,0 +1,210 @@
<template>
<div class="app-container-content-sort">
<el-dialog
:title="$t('CMS.Content.RelaContent')"
:visible.sync="visible"
width="800px"
:close-on-click-modal="false"
append-to-body>
<el-row>
<el-col>
<el-button
plain
type="primary"
icon="el-icon-add"
size="mini"
@click="handleAdd">{{ $t("Common.Add") }}
</el-button>
<el-button
plain
type="danger"
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete">{{ $t("Common.Delete") }}
</el-button>
</el-col>
<el-col>
<el-form
:model="queryParams"
ref="queryForm"
:inline="true"
size="small"
@submit.native.prevent
class="el-form-search mt10 mb10"
style="text-align:left">
<el-form-item label="" prop="title">
<el-input
v-model="queryParams.title"
:placeholder="$t('CMS.Content.Placeholder.Title')"
@keyup.enter.native="handleQuery">
</el-input>
</el-form-item>
<el-form-item>
<el-button-group>
<el-button type="primary" icon="el-icon-search" @click="handleQuery">{{ $t("Common.Search") }}</el-button>
<el-button icon="el-icon-refresh" @click="resetQuery">{{ $t("Common.Reset") }}</el-button>
</el-button-group>
</el-form-item>
</el-form>
</el-col>
</el-row>
<el-table
v-loading="loading"
:data="relaContentList"
size="mini"
highlight-current-row
@selection-change="handleSelectionChange">
<el-table-column type="selection" width="50" align="center" />
<el-table-column type="index" :label="$t('Common.RowNo')" align="center" width="50" />
<el-table-column :label="$t('CMS.Content.Title')" align="left" prop="title">
<template slot-scope="scope">
<span><i v-if="scope.row.topFlag>0" class="el-icon-top top-icon" :title="$t('CMS.Content.SetTop')"></i> {{ scope.row.title }}</span>
</template>
</el-table-column>
<el-table-column :label="$t('CMS.Content.Status')" align="center" prop="status">
<template slot-scope="scope">
<dict-tag :options="dict.type.CMSContentStatus" :value="scope.row.status"/>
</template>
</el-table-column>
<el-table-column :label="$t('CMS.Content.PublishDate')" align="center" prop="publishDate" width="160">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.publishDate) }}</span>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="loadRelaContentList" />
<div slot="footer" class="dialog-footer">
<el-button @click="handleClose">{{ $t("Common.Cancel") }}</el-button>
</div>
</el-dialog>
<!-- 内容选择组件 -->
<cms-content-selector
:open="openContentSelector"
@ok="handleContentSelectorOk"
@close="handleContentSelectorClose"></cms-content-selector>
</div>
</template>
<script>
import { getRelaContentList, addRelaContents, delRelaContents } from "@/api/contentcore/rela";
import CMSContentSelector from "@/views/cms/contentcore/contentSelector";
export default {
name: "CMSContentRelaDialog",
dicts: ['CMSContentStatus'],
components: {
'cms-content-selector': CMSContentSelector
},
props: {
open: {
type: Boolean,
default: false,
required: true
},
cid: {
type: String,
default: undefined,
required: false
}
},
watch: {
open () {
this.visible = this.open;
},
visible (newVal) {
if (!newVal) {
this.handleClose();
} else {
this.loadRelaContentList();
}
},
cid () {
this.queryParams.catalogId = this.cid;
}
},
data () {
return {
loading: false,
visible: this.open,
selectedContents: [],
relaContentList: [],
multiple: true,
total: 0,
queryParams: {
pageNum: 1,
pageSize: 10,
contentId: this.cid,
title: undefined
},
openContentSelector: false,
};
},
methods: {
loadRelaContentList () {
if (!this.visible) {
return;
}
this.loading = true;
getRelaContentList(this.queryParams).then(response => {
this.relaContentList = response.data.rows;
this.total = parseInt(response.data.total);
this.selectedContents = [];
this.loading = false;
});
},
handleSelectionChange (selection) {
this.selectedContents = selection;
this.multiple = !selection.length;
},
handleAdd () {
this.openContentSelector = true;
},
handleContentSelectorOk(contents) {
if (contents && contents.length > 0) {
const data = { contentId: this.cid, relaContentIds: contents.map(c => c.contentId) }
addRelaContents(data).then(response => {
this.openContentSelector = false;
this.$modal.msgSuccess(this.$t('Common.AddSuccess'));
this.handleQuery();
});
} else {
this.$modal.msgWarning(this.$t('Common.SelectFirst'));
}
},
handleContentSelectorClose() {
this.openContentSelector = false;
},
handleDelete () {
if (this.selectedContents.length == 0) {
this.$modal.msgWarning(this.$t('Common.SelectFirst'));
return;
}
const data = { contentId: this.cid, relaContentIds: this.selectedContents.map(c => c.contentId) }
delRelaContents(data).then(response => {
this.$modal.msgSuccess(this.$t('Common.DeleteSuccess'));
this.handleQuery();
});
},
handleClose () {
this.$emit("close");
this.resetForm("queryForm");
this.selectedContents = [];
this.relaContentList = [];
},
handleQuery () {
this.loadRelaContentList();
},
resetQuery () {
this.resetForm("queryForm");
this.handleQuery();
}
}
};
</script>

View File

@ -101,11 +101,6 @@ export default {
this.queryParams.catalogId = this.cid; this.queryParams.catalogId = this.cid;
} }
}, },
computed: {
okBtnDisabled() {
return this.selectedTemplate == undefined;
}
},
data () { data () {
return { return {
loading: false, loading: false,

View File

@ -2,17 +2,13 @@
<div class="pagewidget-container"> <div class="pagewidget-container">
<el-row :gutter="24" class="mb12"> <el-row :gutter="24" class="mb12">
<el-col :span="8"> <el-col :span="8">
<el-row :gutter="10"> <el-button
<el-col :span="1.5"> plain
<el-button type="primary"
plain icon="el-icon-plus"
type="primary" size="mini"
icon="el-icon-plus" v-hasPermi="[ $p('Site:AddPageWidget:{0}', [ siteId ]) ]"
size="mini" @click="handleAdd">{{ $t("Common.Add") }}</el-button>
v-hasPermi="[ $p('Site:AddPageWidget:{0}', [ siteId ]) ]"
@click="handleAdd">{{ $t("Common.Add") }}</el-button>
</el-col>
</el-row>
</el-col> </el-col>
<el-col :span="16" style="text-align: right;"> <el-col :span="16" style="text-align: right;">
<el-select <el-select
@ -59,38 +55,36 @@
<el-table-column :label="$t('CMS.PageWidget.Path')" align="left" width="180" prop="path" :show-overflow-tooltip="true" /> <el-table-column :label="$t('CMS.PageWidget.Path')" align="left" width="180" prop="path" :show-overflow-tooltip="true" />
<el-table-column :label="$t('Common.Operation')" align="left" width="200" class-name="small-padding fixed-width"> <el-table-column :label="$t('Common.Operation')" align="left" width="200" class-name="small-padding fixed-width">
<template slot-scope="scope"> <template slot-scope="scope">
<el-row :gutter="10"> <span class="btn-cell-wrap">
<el-col :span="1.5">
<el-button <el-button
size="mini" size="mini"
type="text" type="text"
icon="el-icon-s-promotion" icon="el-icon-s-promotion"
v-hasPermi="[ $p('PageWidget:Publish:{0}', [ scope.row.pageWidgetId ]) ]" v-hasPermi="[ $p('PageWidget:Publish:{0}', [ scope.row.pageWidgetId ]) ]"
@click="handlePublish(scope.row)">{{ $t('CMS.ContentCore.Publish') }}</el-button> @click="handlePublish(scope.row)">{{ $t('CMS.ContentCore.Publish') }}</el-button>
</el-col> </span>
<el-col :span="1.5"> <span class="btn-cell-wrap">
<el-button <el-button
size="mini" size="mini"
type="text" type="text"
icon="el-icon-view" icon="el-icon-view"
@click="handlePreview(scope.row)">{{ $t('CMS.ContentCore.Preview') }}</el-button> @click="handlePreview(scope.row)">{{ $t('CMS.ContentCore.Preview') }}</el-button>
</el-col> </span>
<el-col :span="1.5"> <span class="btn-cell-wrap">
<el-button <el-button
size="mini" size="mini"
type="text" type="text"
icon="el-icon-edit" icon="el-icon-edit"
@click="handleEdit(scope.row)">{{ $t('Common.Edit') }}</el-button> @click="handleEdit(scope.row)">{{ $t('Common.Edit') }}</el-button>
</el-col> </span>
<el-col :span="1.5"> <span class="btn-cell-wrap">
<el-button <el-button
size="mini" size="mini"
type="text" type="text"
icon="el-icon-delete" icon="el-icon-delete"
v-hasPermi="[ $p('PageWidget:Delete:{0}', [ scope.row.pageWidgetId ]) ]" v-hasPermi="[ $p('PageWidget:Delete:{0}', [ scope.row.pageWidgetId ]) ]"
@click="handleDelete(scope.row)">{{ $t("Common.Delete") }}</el-button> @click="handleDelete(scope.row)">{{ $t("Common.Delete") }}</el-button>
</el-col> </span>
</el-row>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>

View File

@ -111,7 +111,7 @@
</el-form-item> </el-form-item>
</el-form> </el-form>
</el-header> </el-header>
<el-main v-loading="loadingList"> <el-main v-loading="loadingList" style="overflow-y: scroll;">
<el-card shadow="never" v-for="(r, index) in resourceList" :key="r.resourceId"> <el-card shadow="never" v-for="(r, index) in resourceList" :key="r.resourceId">
<el-image v-if="isImageResource(r.src)" class="item-img" fit="scale-down" :src="r.src" @click="handleResourceChecked(index)"></el-image> <el-image v-if="isImageResource(r.src)" class="item-img" fit="scale-down" :src="r.src" @click="handleResourceChecked(index)"></el-image>
<svg-icon v-else :icon-class="getResourceFileIconClass(r.path)" class="item-svg" /> <svg-icon v-else :icon-class="getResourceFileIconClass(r.path)" class="item-svg" />
@ -436,7 +436,7 @@ export default {
padding: 0 4px; padding: 0 4px;
} }
.resource-dialog .el-card { .resource-dialog .el-card {
width: 150px; width: 148px;
text-align: center; text-align: center;
float: left; float: left;
border: none; border: none;

View File

@ -48,25 +48,36 @@
<el-table-column :label="$t('CMS.Site.Path')" prop="path" /> <el-table-column :label="$t('CMS.Site.Path')" prop="path" />
<el-table-column :label="$t('Common.Operation')" align="center" width="310" class-name="small-padding fixed-width"> <el-table-column :label="$t('Common.Operation')" align="center" width="310" class-name="small-padding fixed-width">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button <span class="btn-cell-wrap">
type="text" <el-button
icon="el-icon-s-promotion" type="text"
size="small" size="small"
@click="handlePublish(scope.row)">{{ $t('CMS.Site.PublishHome') }}</el-button> @click="handlePreview(scope.row)"><svg-icon icon-class="eye-open" class="mr2"></svg-icon>{{ $t('CMS.ContentCore.Preview') }}</el-button>
<el-button </span>
type="text" <span class="btn-cell-wrap">
size="small" <el-button
@click="handlePreview(scope.row)"><svg-icon icon-class="eye-open" class="mr2"></svg-icon>{{ $t('CMS.ContentCore.Preview') }}</el-button> type="text"
<el-button icon="el-icon-s-promotion"
type="text" size="small"
icon="el-icon-edit" v-hasPermi="[ $p('Site:Publish:{0}', [ scope.row.siteId ]) ]"
size="small" @click="handlePublish(scope.row)">{{ $t('CMS.Site.PublishHome') }}</el-button>
@click="handleEdit(scope.row)">{{ $t("Common.Edit") }}</el-button> </span>
<el-button <span class="btn-cell-wrap">
type="text" <el-button
icon="el-icon-delete" type="text"
size="small" icon="el-icon-edit"
@click="handleDelete(scope.row)">{{ $t("Common.Delete") }}</el-button> size="small"
v-hasPermi="[ $p('Site:Edit:{0}', [ scope.row.siteId ]) ]"
@click="handleEdit(scope.row)">{{ $t("Common.Edit") }}</el-button>
</span>
<span class="btn-cell-wrap">
<el-button
type="text"
icon="el-icon-delete"
size="small"
v-hasPermi="[ $p('Site:Delete:{0}', [ scope.row.siteId ]) ]"
@click="handleDelete(scope.row)">{{ $t("Common.Delete") }}</el-button>
</span>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>

View File

@ -276,13 +276,14 @@
:label="$t('CMS.Site.Extend.BaiduAccessToken')" :label="$t('CMS.Site.Extend.BaiduAccessToken')"
prop="BaiduTjAccessToken"> prop="BaiduTjAccessToken">
<el-input v-model="form_extend.BaiduTjAccessToken"></el-input> <el-input v-model="form_extend.BaiduTjAccessToken"></el-input>
<el-button <span class="btn-cell-wrap ml5">
class="ml5" <el-button
type="primary" type="primary"
icon="el-icon-refresh" icon="el-icon-refresh"
:disabled="!this.siteId" :disabled="!this.siteId"
v-hasPermi="[ $p('Site:Edit:{0}', [ siteId ]) ]" v-hasPermi="[ $p('Site:Edit:{0}', [ siteId ]) ]"
@click="handleRefreshBdTongjiToken">{{ $t("Common.Refresh") }}</el-button> @click="handleRefreshBdTongjiToken">{{ $t("Common.Refresh") }}</el-button>
</span>
</el-form-item> </el-form-item>
<el-form-item <el-form-item
:label="$t('CMS.Site.Extend.BaiduDomain')" :label="$t('CMS.Site.Extend.BaiduDomain')"

View File

@ -32,14 +32,13 @@
@click="handlePublish">{{ $t("CMS.Site.PublishHome") }}</el-button> @click="handlePublish">{{ $t("CMS.Site.PublishHome") }}</el-button>
</el-col> </el-col>
<el-col :span="1.5"> <el-col :span="1.5">
<el-dropdown> <el-dropdown class="btn-permi" v-hasPermi="[ $p('Site:Publish:{0}', [ siteId ]) ]">
<el-button <el-button
split-button split-button
plain plain
size="mini" size="mini"
type="primary" type="primary"
icon="el-icon-s-promotion" icon="el-icon-s-promotion"
v-hasPermi="[ $p('Site:Publish:{0}', [ siteId ]) ]"
:disabled="!this.siteId"> :disabled="!this.siteId">
{{ $t("CMS.Site.PublishAll") }}<i class="el-icon-arrow-down el-icon--right"></i> {{ $t("CMS.Site.PublishAll") }}<i class="el-icon-arrow-down el-icon--right"></i>
</el-button> </el-button>

View File

@ -2,22 +2,26 @@
<div class=""> <div class="">
<el-row :gutter="24" class="mb12"> <el-row :gutter="24" class="mb12">
<el-col :span="12"> <el-col :span="12">
<el-row> <el-row :gutter="10">
<el-button <el-col :span="1.5">
plain <el-button
type="primary" plain
icon="el-icon-plus" type="primary"
size="mini" icon="el-icon-plus"
v-hasPermi="[ $p('Site:Edit:{0}', [ site ]) ]" size="mini"
@click="handleAdd">{{ $t("Common.Add") }}</el-button> v-hasPermi="[ $p('Site:Edit:{0}', [ site ]) ]"
<el-button @click="handleAdd">{{ $t("Common.Add") }}</el-button>
plain </el-col>
type="danger" <el-col :span="1.5">
icon="el-icon-delete" <el-button
size="mini" plain
:disabled="multiple" type="danger"
v-hasPermi="[ $p('Site:Edit:{0}', [ site ]) ]" icon="el-icon-delete"
@click="handleDelete">{{ $t("Common.Delete") }}</el-button> size="mini"
:disabled="multiple"
v-hasPermi="[ $p('Site:Edit:{0}', [ site ]) ]"
@click="handleDelete">{{ $t("Common.Delete") }}</el-button>
</el-col>
</el-row> </el-row>
</el-col> </el-col>
<el-col :span="12" style="text-align:right"> <el-col :span="12" style="text-align:right">

View File

@ -96,18 +96,22 @@
</el-table-column> </el-table-column>
<el-table-column :label="$t('Common.Operation')" align="center" width="180" class-name="small-padding fixed-width"> <el-table-column :label="$t('Common.Operation')" align="center" width="180" class-name="small-padding fixed-width">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button <span class="btn-cell-wrap">
type="text" <el-button
icon="el-icon-edit" type="text"
size="small" icon="el-icon-edit"
v-hasPermi="[ 'cms:friendlink:add', 'cms:friendlink:edit' ]" size="small"
@click="handleEdit(scope.row)">{{ $t('Common.Edit') }}</el-button> v-hasPermi="[ 'cms:friendlink:add', 'cms:friendlink:edit' ]"
<el-button @click="handleEdit(scope.row)">{{ $t('Common.Edit') }}</el-button>
type="text" </span>
icon="el-icon-delete" <span class="btn-cell-wrap">
size="small" <el-button
v-hasPermi="[ 'cms:friendlink:delete' ]" type="text"
@click="handleDelete(scope.row)">{{ $t("Common.Delete") }}</el-button> icon="el-icon-delete"
size="small"
v-hasPermi="[ 'cms:friendlink:delete' ]"
@click="handleDelete(scope.row)">{{ $t("Common.Delete") }}</el-button>
</span>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>

View File

@ -81,18 +81,22 @@
</el-table-column> </el-table-column>
<el-table-column :label="$t('Common.Operation')" align="center" width="180" class-name="small-padding fixed-width"> <el-table-column :label="$t('Common.Operation')" align="center" width="180" class-name="small-padding fixed-width">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button <span class="btn-cell-wrap">
type="text" <el-button
icon="el-icon-edit" type="text"
size="small" icon="el-icon-edit"
v-hasPermi="[ 'cms:friendlink:add', 'cms:friendlink:edit' ]" size="small"
@click="handleEdit(scope.row)">{{ $t('Common.Edit') }}</el-button> v-hasPermi="[ 'cms:friendlink:add', 'cms:friendlink:edit' ]"
<el-button @click="handleEdit(scope.row)">{{ $t('Common.Edit') }}</el-button>
type="text" </span>
icon="el-icon-delete" <span class="btn-cell-wrap">
size="small" <el-button
v-hasPermi="[ 'cms:friendlink:delete' ]" type="text"
@click="handleDelete(scope.row)">{{ $t("Common.Delete") }}</el-button> icon="el-icon-delete"
size="small"
v-hasPermi="[ 'cms:friendlink:delete' ]"
@click="handleDelete(scope.row)">{{ $t("Common.Delete") }}</el-button>
</span>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>

View File

@ -113,21 +113,25 @@
</el-table-column> </el-table-column>
<el-table-column :label="$t('Common.Operation')" align="center" class-name="small-padding fixed-width"> <el-table-column :label="$t('Common.Operation')" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button <span class="btn-cell-wrap">
size="small" <el-button
type="text" size="small"
icon="el-icon-edit" type="text"
@click="handleUpdate(scope.row)" icon="el-icon-edit"
v-hasPermi="['monitor:job:edit']" @click="handleUpdate(scope.row)"
>{{ $t('Common.Edit') }}</el-button> v-hasPermi="['monitor:job:edit']"
<el-button >{{ $t('Common.Edit') }}</el-button>
size="small" </span>
type="text" <span class="btn-cell-wrap">
icon="el-icon-delete" <el-button
@click="handleDelete(scope.row)" size="small"
v-hasPermi="['monitor:job:remove']" type="text"
>{{ $t('Common.Delete') }}</el-button> icon="el-icon-delete"
<el-dropdown size="small" @command="(command) => handleCommand(command, scope.row)" v-hasPermi="['monitor:job:changeStatus', 'monitor:job:query']"> @click="handleDelete(scope.row)"
v-hasPermi="['monitor:job:remove']"
>{{ $t('Common.Delete') }}</el-button>
</span>
<el-dropdown size="small" @command="(command) => handleCommand(command, scope.row)">
<el-button size="small" type="text" icon="el-icon-d-arrow-right">{{ $t('Common.More') }}</el-button> <el-button size="small" type="text" icon="el-icon-d-arrow-right">{{ $t('Common.More') }}</el-button>
<el-dropdown-menu slot="dropdown"> <el-dropdown-menu slot="dropdown">
<el-dropdown-item command="handleRun" icon="el-icon-caret-right" <el-dropdown-item command="handleRun" icon="el-icon-caret-right"

View File

@ -121,13 +121,15 @@
</el-table-column> </el-table-column>
<el-table-column :label="$t('Common.Operation')" align="center" class-name="small-padding fixed-width"> <el-table-column :label="$t('Common.Operation')" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button <span class="btn-cell-wrap">
size="small" <el-button
type="text" size="small"
icon="el-icon-view" type="text"
@click="handleView(scope.row)" icon="el-icon-view"
v-hasPermi="['monitor:job:query']" @click="handleView(scope.row)"
>{{ $t('Monitor.Job.LogDetails') }}</el-button> v-hasPermi="['monitor:job:query']"
>{{ $t('Monitor.Job.LogDetails') }}</el-button>
</span>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>

View File

@ -46,13 +46,15 @@
</el-table-column> </el-table-column>
<el-table-column :label="$t('Common.Operation')" align="center" class-name="small-padding fixed-width" width="80"> <el-table-column :label="$t('Common.Operation')" align="center" class-name="small-padding fixed-width" width="80">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button <span class="btn-cell-wrap">
size="small" <el-button
type="text" size="small"
icon="el-icon-delete" type="text"
@click="handleForceLogout(scope.row)" icon="el-icon-delete"
v-hasPermi="['monitor:online:forceLogout']" @click="handleForceLogout(scope.row)"
>{{ $t('Monitor.Online.ForceExit') }}</el-button> v-hasPermi="['monitor:online:forceLogout']"
>{{ $t('Monitor.Online.ForceExit') }}</el-button>
</span>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>

View File

@ -103,20 +103,24 @@
</el-table-column> </el-table-column>
<el-table-column :label="$t('Common.Operation')" align="center" class-name="small-padding fixed-width"> <el-table-column :label="$t('Common.Operation')" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button <span class="btn-cell-wrap">
size="small" <el-button
type="text" size="small"
icon="el-icon-edit" type="text"
@click="handleUpdate(scope.row)" icon="el-icon-edit"
v-hasPermi="['system:config:edit']" @click="handleUpdate(scope.row)"
>{{ $t('Common.Edit') }}</el-button> v-hasPermi="['system:config:edit']"
<el-button >{{ $t('Common.Edit') }}</el-button>
size="small" </span>
type="text" <span class="btn-cell-wrap">
icon="el-icon-delete" <el-button
@click="handleDelete(scope.row)" size="small"
v-hasPermi="['system:config:remove']" type="text"
>{{ $t('Common.Delete') }}</el-button> icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['system:config:remove']"
>{{ $t('Common.Delete') }}</el-button>
</span>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>

View File

@ -73,28 +73,34 @@
</el-table-column> </el-table-column>
<el-table-column :label="$t('Common.Operation')" width="300" class-name="small-padding fixed-width"> <el-table-column :label="$t('Common.Operation')" width="300" class-name="small-padding fixed-width">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button <span class="btn-cell-wrap">
size="small" <el-button
type="text" size="small"
icon="el-icon-edit" type="text"
@click="handleUpdate(scope.row)" icon="el-icon-edit"
v-hasPermi="['system:dept:edit']" @click="handleUpdate(scope.row)"
>{{ $t('Common.Edit') }}</el-button> v-hasPermi="['system:dept:edit']"
<el-button >{{ $t('Common.Edit') }}</el-button>
size="small" </span>
type="text" <span class="btn-cell-wrap">
icon="el-icon-plus" <el-button
@click="handleAdd(scope.row)" size="small"
v-hasPermi="['system:dept:add']" type="text"
>{{ $t('Common.Add') }}</el-button> icon="el-icon-plus"
<el-button @click="handleAdd(scope.row)"
v-if="scope.row.parentId != 0" v-hasPermi="['system:dept:add']"
size="small" >{{ $t('Common.Add') }}</el-button>
type="text" </span>
icon="el-icon-delete" <span class="btn-cell-wrap">
@click="handleDelete(scope.row)" <el-button
v-hasPermi="['system:dept:remove']" v-if="scope.row.parentId != 0"
>{{ $t('Common.Delete') }}</el-button> size="small"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['system:dept:remove']"
>{{ $t('Common.Delete') }}</el-button>
</span>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>

View File

@ -112,20 +112,24 @@
</el-table-column> </el-table-column>
<el-table-column :label="$t('Common.Operation')" align="center" class-name="small-padding fixed-width"> <el-table-column :label="$t('Common.Operation')" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button <span class="btn-cell-wrap">
size="small" <el-button
type="text" size="small"
icon="el-icon-edit" type="text"
@click="handleUpdate(scope.row)" icon="el-icon-edit"
v-hasPermi="['system:dict:edit']" @click="handleUpdate(scope.row)"
>{{ $t('Common.Edit') }}</el-button> v-hasPermi="['system:dict:edit']"
<el-button >{{ $t('Common.Edit') }}</el-button>
size="small" <span class="btn-cell-wrap">
type="text" </span>
icon="el-icon-delete" <el-button
@click="handleDelete(scope.row)" size="small"
v-hasPermi="['system:dict:remove']" type="text"
>{{ $t('Common.Delete') }}</el-button> icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['system:dict:remove']"
>{{ $t('Common.Delete') }}</el-button>
</span>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>

View File

@ -113,20 +113,24 @@
</el-table-column> </el-table-column>
<el-table-column :label="$t('Common.Operation')" align="center" class-name="small-padding fixed-width"> <el-table-column :label="$t('Common.Operation')" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button <span class="btn-cell-wrap">
size="small" <el-button
type="text" size="small"
icon="el-icon-edit" type="text"
@click="handleUpdate(scope.row)" icon="el-icon-edit"
v-hasPermi="['system:dict:edit']" @click="handleUpdate(scope.row)"
>{{ $t('Common.Edit') }}</el-button> v-hasPermi="['system:dict:edit']"
<el-button >{{ $t('Common.Edit') }}</el-button>
size="small" </span>
type="text" <span class="btn-cell-wrap">
icon="el-icon-delete" <el-button
@click="handleDelete(scope.row)" size="small"
v-hasPermi="['system:dict:remove']" type="text"
>{{ $t('Common.Delete') }}</el-button> icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['system:dict:remove']"
>{{ $t('Common.Delete') }}</el-button>
</span>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>

View File

@ -106,20 +106,24 @@
<el-table-column :label="$t('System.I18n.LangValue')" align="left" prop="langValue" :show-overflow-tooltip="true" /> <el-table-column :label="$t('System.I18n.LangValue')" align="left" prop="langValue" :show-overflow-tooltip="true" />
<el-table-column :label="$t('Common.Operation')" align="center" class-name="small-padding fixed-width"> <el-table-column :label="$t('Common.Operation')" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button <span class="btn-cell-wrap">
size="small" <el-button
type="text" size="small"
icon="el-icon-edit" type="text"
@click="handleUpdate(scope.row)" icon="el-icon-edit"
v-hasPermi="['system:i18ndict:edit']" @click="handleUpdate(scope.row)"
>{{ $t('Common.Edit') }}</el-button> v-hasPermi="['system:i18ndict:edit']"
<el-button >{{ $t('Common.Edit') }}</el-button>
size="small" </span>
type="text" <span class="btn-cell-wrap">
icon="el-icon-delete" <el-button
@click="handleDelete(scope.row)" size="small"
v-hasPermi="['system:i18ndict:remove']" type="text"
>{{ $t('Common.Delete') }}</el-button> icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['system:i18ndict:remove']"
>{{ $t('Common.Delete') }}</el-button>
</span>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>

View File

@ -85,27 +85,33 @@
</el-table-column> </el-table-column>
<el-table-column :label="$t('Common.Operation')" align="center" class-name="small-padding fixed-width"> <el-table-column :label="$t('Common.Operation')" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button <span class="btn-cell-wrap">
size="small" <el-button
type="text" size="small"
icon="el-icon-edit" type="text"
@click="handleUpdate(scope.row)" icon="el-icon-edit"
v-hasPermi="['system:menu:edit']" @click="handleUpdate(scope.row)"
>{{ $t('Common.Edit') }}</el-button> v-hasPermi="['system:menu:edit']"
<el-button >{{ $t('Common.Edit') }}</el-button>
size="small" </span>
type="text" <span class="btn-cell-wrap">
icon="el-icon-plus" <el-button
@click="handleAdd(scope.row)" size="small"
v-hasPermi="['system:menu:add']" type="text"
>{{ $t('Common.Add') }}</el-button> icon="el-icon-plus"
<el-button @click="handleAdd(scope.row)"
size="small" v-hasPermi="['system:menu:add']"
type="text" >{{ $t('Common.Add') }}</el-button>
icon="el-icon-delete" </span>
@click="handleDelete(scope.row)" <span class="btn-cell-wrap">
v-hasPermi="['system:menu:remove']" <el-button
>{{ $t('Common.Delete') }}</el-button> size="small"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['system:menu:remove']"
>{{ $t('Common.Delete') }}</el-button>
</span>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>

View File

@ -99,20 +99,24 @@
</el-table-column> </el-table-column>
<el-table-column :label="$t('Common.Operation')" align="center" class-name="small-padding fixed-width"> <el-table-column :label="$t('Common.Operation')" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button <span class="btn-cell-wrap">
size="small" <el-button
type="text" size="small"
icon="el-icon-edit" type="text"
@click="handleUpdate(scope.row)" icon="el-icon-edit"
v-hasPermi="['system:notice:edit']" @click="handleUpdate(scope.row)"
>{{ $t('Common.Edit') }}</el-button> v-hasPermi="['system:notice:edit']"
<el-button >{{ $t('Common.Edit') }}</el-button>
size="small" </span>
type="text" <span class="btn-cell-wrap">
icon="el-icon-delete" <el-button
@click="handleDelete(scope.row)" size="small"
v-hasPermi="['system:notice:remove']" type="text"
>{{ $t('Common.Delete') }}</el-button> icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['system:notice:remove']"
>{{ $t('Common.Delete') }}</el-button>
</span>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>

View File

@ -100,20 +100,24 @@
</el-table-column> </el-table-column>
<el-table-column :label="$t('Common.Operation')" align="center" class-name="small-padding fixed-width"> <el-table-column :label="$t('Common.Operation')" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button <span class="btn-cell-wrap">
size="small" <el-button
type="text" size="small"
icon="el-icon-edit" type="text"
@click="handleUpdate(scope.row)" icon="el-icon-edit"
v-hasPermi="['system:post:edit']" @click="handleUpdate(scope.row)"
>{{ $t('Common.Edit') }}</el-button> v-hasPermi="['system:post:edit']"
<el-button >{{ $t('Common.Edit') }}</el-button>
size="small" </span>
type="text" <span class="btn-cell-wrap">
icon="el-icon-delete" <el-button
@click="handleDelete(scope.row)" size="small"
v-hasPermi="['system:post:remove']" type="text"
>{{ $t('Common.Delete') }}</el-button> icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['system:post:remove']"
>{{ $t('Common.Delete') }}</el-button>
</span>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>

View File

@ -78,13 +78,15 @@
</el-table-column> </el-table-column>
<el-table-column :label="$t('Common.Operation')" align="center" class-name="small-padding fixed-width"> <el-table-column :label="$t('Common.Operation')" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button <span class="btn-cell-wrap">
size="small" <el-button
type="text" size="small"
icon="el-icon-circle-close" type="text"
@click="cancelAuthUser(scope.row)" icon="el-icon-circle-close"
v-hasPermi="['system:role:remove']" @click="cancelAuthUser(scope.row)"
>{{ $t('Common.Remove') }}</el-button> v-hasPermi="['system:role:remove']"
>{{ $t('Common.Remove') }}</el-button>
</span>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>

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