版本更新到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://tpz.1000mz.com>
图片站演示地址:PC端<http://tpz.1000mz.com> 移动端:<http://mtpz.1000mz.com>
游戏站演示地址PC端<http://game.1000mz.com> 移动端:<http://mgame.1000mz.com>
### 开发环境
- JDK 17

View File

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

View File

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

View File

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

View File

@ -3,7 +3,7 @@ chestnut:
# 名称
name: ChestnutCMS
# 版本
version: 1.3.21
version: 1.3.23
# 版权年份
copyrightYear: 2023
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>
<groupId>com.chestnut</groupId>
<artifactId>chestnut-cms</artifactId>
<version>1.3.21</version>
<version>1.3.23</version>
</parent>
<artifactId>chestnut-cms-advertisement</artifactId>

View File

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

View File

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

View File

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

View File

@ -7,7 +7,7 @@
<parent>
<groupId>com.chestnut</groupId>
<artifactId>chestnut-cms</artifactId>
<version>1.3.21</version>
<version>1.3.23</version>
</parent>
<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.util.Date;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
import lombok.Getter;
import lombok.Setter;
@ -75,6 +77,21 @@ public class ListContentVO {
*/
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 com.chestnut.common.utils.StringUtils;
import org.springframework.stereotype.Component;
import com.chestnut.contentcore.core.IProperty;
@ -36,6 +37,10 @@ public class PublishedContentEditProperty implements IProperty {
}
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属性值的任意标签匹配
*/
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);

View File

@ -88,6 +88,8 @@ FREEMARKER.TAG.NAME.cms_pagewidget_data=页面部件数据标签
FREEMARKER.TAG.DESC.cms_pagewidget_data=页面部件数据标签,标签体内可使用${Data.name}获取数据
FREEMARKER.TAG.NAME.cms_content_closest=内容前后篇标签
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.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.dict=获取字典数据列表,例如:${dict('YesOrNo', 'Y')}
FREEMARKER.FUNC.DESC.sysConfig=获取系统参数配置值,例如:${sysConfig('SiteApiUrl')}
FREEMARKER.FUNC.DESC.listHtmlInternalUrl=获取html文本中的iurl列表例如${listHtmlInternalUrl(ArticleContent)}
# 校验规则
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.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.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.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.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.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.

View File

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

View File

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

View File

@ -7,7 +7,7 @@
<parent>
<groupId>com.chestnut</groupId>
<artifactId>chestnut-cms</artifactId>
<version>1.3.21</version>
<version>1.3.23</version>
</parent>
<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);
q.apply(StringUtils.isNotEmpty(condition), condition);
q.orderByAsc(CmsImage::getSortFlag);
Page<CmsImage> pageResult = this.imageService.page(new Page<>(pageIndex, size, page), q);
if (pageIndex > 1 & pageResult.getRecords().size() == 0) {
throw new TemplateException("内容列表页码超出上限:" + pageIndex, env);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -7,7 +7,7 @@
<parent>
<groupId>com.chestnut</groupId>
<artifactId>chestnut-cms</artifactId>
<version>1.3.21</version>
<version>1.3.23</version>
</parent>
<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.FUNC.DESC.replaceHotWord=替换热词链接,例如:${replaceHotWord(content, 'default', '[a href='\{0\}' target='\{2\}']\{1\}[/a]')}
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.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.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>
<groupId>com.chestnut</groupId>
<artifactId>chestnut-cms</artifactId>
<version>1.3.21</version>
<version>1.3.23</version>
</parent>
<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.util.SiteUtils;
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_SitemapUrlLimit;
import com.chestnut.system.fixed.dict.YesOrNo;
@ -88,7 +89,10 @@ public class BaiduSitemapService {
}
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);
}

View File

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

View File

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

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>chestnut-common</artifactId>
<groupId>com.chestnut</groupId>
<version>1.3.21</version>
<version>1.3.23</version>
</parent>
<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.utils.Assert;
import com.chestnut.common.utils.StringUtils;
import com.google.common.collect.ImmutableSortedMap;
import java.util.*;
import java.util.stream.Stream;
@ -313,18 +314,18 @@ public class SqlBuilder {
}
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,
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,
String field2, boolean isAsc2,
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>
<artifactId>chestnut-common</artifactId>
<groupId>com.chestnut</groupId>
<version>1.3.21</version>
<version>1.3.23</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

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

View File

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

View File

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

View File

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

View File

@ -1,26 +1,18 @@
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.HashMap;
import java.util.Iterator;
import java.util.Map;
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 {
/**
@ -40,6 +32,8 @@ public class FreeMarkerUtils {
env.getObjectWrapper().wrap(context.getFirstFileName()));
env.setGlobalVariable(StaticizeConstants.TemplateVariable_OtherPage,
env.getObjectWrapper().wrap(context.getOtherFileName()));
env.setGlobalVariable(StaticizeConstants.TemplateVariable_TimeMillis,
env.getObjectWrapper().wrap(context.getTimeMillis()));
}
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_TimeMillis = "TimeMillis";
}

View File

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

View File

@ -1,14 +1,13 @@
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.file.FileExUtils;
import lombok.Getter;
import lombok.Setter;
import java.util.HashMap;
import java.util.Map;
/**
* 模板上下文
*/
@ -81,6 +80,11 @@ public class TemplateContext {
*/
private boolean paged;
/**
* 模板处理时间
*/
private Long timeMillis;
public TemplateContext(String templateId, boolean preview, String publishPipeCode) {
this.templateId = templateId;
this.preview = preview;

View File

@ -91,7 +91,8 @@ public class PageBarTag extends AbstractTag {
private String generatePageBar(String target, String firstPage, String lastPage, boolean withFirstAndLast, Environment env)
throws TemplateException {
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 endPage = 7;
if (context.getPageIndex() > 4) {
@ -106,7 +107,7 @@ public class PageBarTag extends AbstractTag {
StringBuilder sb = new StringBuilder();
sb.append("<div class=\"pagination\">");
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>");
}
for (int i = startPage; i <= endPage; i++) {
@ -120,7 +121,7 @@ public class PageBarTag extends AbstractTag {
}
if (withFirstAndLast && endPage < pageCount) {
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>");
return sb.toString();

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,6 +1,6 @@
{
"name": "ChestnutCMS",
"version": "1.3.21",
"version": "1.3.23",
"description": "ChestnutCMS[栗子内容管理系统]",
"author": "",
"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;
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 操作权限处理
* Copyright (c) 2023 兮玥190785909@qq.com
*
* 1非el-button标签的按钮权限需要给对应控件添加class="btn-permi"
* 2表格操作列的多个按钮需要给按钮添加一个<span class="btn-cell-wrap"></span>
*/
import store from '@/store'
@ -18,27 +21,15 @@ function fn (el, binding) {
})
if (!hasPermissions) {
if (el.cacheParentElement && el.cacheParentElement.className.split(' ').indexOf('el-dropdown') > -1) {
el.cacheParentElement.parentNode.removeChild(el.cacheParentElement)
el.cacheParentElement.parentNode.style.display = 'none';
} 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) {
if (el.classList.contains('el-button') || el.classList.contains("btn-permi")) {
el.cacheParentElement && el.cacheParentElement.removeChild(el)
} else if (el.classList.contains('el-dropdown-menu__item')) {
el.cacheElement.style.display = 'none';
}
} else {
if (el.cacheParentElement && el.cacheParentElement.className.split(' ').indexOf('el-dropdown') > -1) {
el.cacheParentElement.parentNode.appendChild(el.cacheElement.parentNode)
el.cacheParentElement.parentNode.style.display = '';
} 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.classList.contains('el-button') || el.classList.contains("btn-permi")) {
el.cacheParentElement && el.cacheParentElement.appendChild(el.cacheElement)
} else if (el.classList.contains('el-dropdown-menu__item')) {
if (el.cacheElement) {
el.cacheElement.style.display = '';
}

View File

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

View File

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

View File

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

View File

@ -1,6 +1,7 @@
<template>
<div class="catalog-extend-container">
<el-row class="mb12">
<el-col :span="1.5">
<el-button
plain
type="success"
@ -9,6 +10,8 @@
:disabled="!this.catalogId"
v-hasPermi="[ $p('Catalog:Edit:{0}', [ catalogId ]) ]"
@click="handleSaveExtends">{{ $t("Common.Save") }}</el-button>
</el-col>
<el-col :span="1.5">
<el-button
plain
type="primary"
@ -17,8 +20,10 @@
:disabled="!this.catalogId"
v-hasPermi="[ $p('Catalog:Edit:{0}', [ catalogId ]) ]"
@click="handleApplyAllToCatalog()">{{ $t('CMS.Catalog.ApplyToChildren') }}</el-button>
</el-col>
</el-row>
<el-form
class="catalog-extend-form"
ref="form_extend"
:model="form_extend"
v-loading="loading"
@ -242,22 +247,22 @@ export default {
}
};
</script>
<style>
.catalog-extend-container .el-form-item {
<style scoped>
.catalog-extend-form .el-form-item {
margin-bottom: 12px;
width: 700px;
}
.catalog-extend-container .el-card {
.catalog-extend-form .el-card {
margin-bottom: 10px;
}
.catalog-extend-container .el-input, .el-select,
.catalog-extend-container .el-input-number {
.catalog-extend-form .el-input, .el-select,
.catalog-extend-form .el-input-number {
width: 301.5px;
}
.catalog-extend-container .el-upload-list {
.catalog-extend-form .el-upload-list {
width: 300px;
}
.catalog-extend-container .btn-apply-child {
.catalog-extend-form .btn-apply-child {
padding: 10px;
}
</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>
</el-col>
<el-col :span="1.5">
<el-dropdown>
<el-dropdown class="btn-permi" v-hasPermi="[ $p('Catalog:Publish:{0}', [ catalogId ]) ]">
<el-button
plain
size="mini"
type="primary"
icon="el-icon-s-promotion"
:disabled="!this.catalogId"
v-hasPermi="[ $p('Catalog:Publish:{0}', [ catalogId ]) ]"
@click="handlePublish(-1)">
{{ $t('CMS.ContentCore.Publish') }}<i class="el-icon-arrow-down el-icon--right"></i>
</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
v-for="dict in dict.type.CMSContentStatus"
:key="dict.value"
@ -65,6 +64,7 @@
<el-popover
width="226"
:disabled="!this.catalogId"
class="btn-permi"
v-hasPermi="[ $p('Catalog:Sort:{0}', [ catalogId ]) ]"
v-model="showSortPop">
<el-input-number v-model="sortValue" size="small" style="width:200px;" />
@ -85,14 +85,13 @@
</el-popover>
</el-col>
<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
type="danger"
icon="el-icon-delete"
size="mini"
plain
:disabled="!this.catalogId"
v-hasPermi="[ $p('Catalog:Delete:{0}', [ catalogId ]) ]"
slot="reference">{{ $t("Common.Delete") }}</el-button>
</el-popconfirm>
</el-col>

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="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" 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-else plain type="warning" size="mini" icon="el-icon-back" @click="handleGoBack">{{ $t('CMS.Content.BackToList') }}</el-button>
</div>
@ -229,6 +230,7 @@
:open="openContentSelector"
@ok="handleContentSelectorOk"
@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>
</div>
@ -246,6 +248,7 @@ import CMSLogoView from '@/views/cms/components/LogoView';
import CMSResourceDialog from "@/views/cms/contentcore/resourceDialog";
import CMSCatalogSelector from "@/views/cms/contentcore/catalogSelector";
import CMSContentSelector from "@/views/cms/contentcore/contentSelector";
import CMSContrentRelaDialog from '@/views/cms/contentcore/contentRelaDialog';
import CMSTemplateSelector from '@/views/cms/contentcore/templateSelector';
import CMSEXModelEditor from '@/views/cms/components/EXModelEditor';
import CMSTagEditor from '@/views/cms/components/TagEditor';
@ -269,6 +272,7 @@ export default {
"cms-logo-view": CMSLogoView,
'cms-catalog-selector': CMSCatalogSelector,
'cms-content-selector': CMSContentSelector,
'cms-content-rela-dialog': CMSContrentRelaDialog,
"cms-exmodel-editor": CMSEXModelEditor,
"cms-tag-editor": CMSTagEditor,
// "ckeditor": CKEditor5
@ -324,6 +328,7 @@ export default {
selectExTemplate: false,
publishAfterSave: false,
toPublishAfterSave: false,
openRelaContentDialog: false,
};
},
created() {
@ -594,6 +599,28 @@ export default {
handleContentSelectorOk(contents) {
if (contents && contents.length > 0) {
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;
} else {
this.$modal.msgWarning(this.$t('Common.SelectFirst'));
@ -601,6 +628,12 @@ export default {
},
handleContentSelectorClose() {
this.openContentSelector = false;
},
handleRelaContent() {
this.openRelaContentDialog = true;
},
handleRelaContentClose() {
this.openRelaContentDialog = false;
}
}
};

View File

@ -2,7 +2,7 @@
<div class="cms-content-list">
<el-row :gutter="10" class="mb12">
<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-radio-group v-model="addContentType">
<el-radio-button
@ -35,6 +35,7 @@
icon="el-icon-delete"
size="mini"
:disabled="multiple"
v-hasPermi="[ $p('Catalog:DeleteContent:{0}', [ catalogId ]) ]"
@click="handleDelete">{{ $t("Common.Delete") }}
</el-button>
</el-col>
@ -45,6 +46,7 @@
icon="el-icon-timer"
size="mini"
:disabled="multiple"
v-hasPermi="[ $p('Catalog:EditContent:{0}', [ catalogId ]) ]"
@click="handleToPublish">{{ $t("CMS.ContentCore.ToPublish") }}
</el-button>
</el-col>
@ -55,6 +57,7 @@
icon="el-icon-s-promotion"
size="mini"
:disabled="multiple"
v-hasPermi="[ $p('Catalog:EditContent:{0}', [ catalogId ]) ]"
@click="handlePublish">{{ $t("CMS.ContentCore.Publish") }}
</el-button>
</el-col>
@ -65,6 +68,7 @@
icon="el-icon-download"
size="mini"
:disabled="multiple"
v-hasPermi="[ $p('Catalog:EditContent:{0}', [ catalogId ]) ]"
@click="handleOffline">{{ $t("CMS.Content.Offline") }}
</el-button>
</el-col>
@ -89,7 +93,7 @@
</el-button>
</el-col>
<el-col :span="1.5">
<el-dropdown>
<el-dropdown class="btn-permi" v-hasPermi="[ $p('Catalog:EditContent:{0}', [ catalogId ]) ]">
<el-button
plain
size="mini"
@ -104,7 +108,7 @@
</el-dropdown>
</el-col>
<el-col :span="1.5">
<el-dropdown>
<el-dropdown class="btn-permi" v-hasPermi="[ $p('Catalog:EditContent:{0}', [ catalogId ]) ]">
<el-button
plain
size="mini"
@ -231,32 +235,40 @@
width="220"
class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
size="small"
type="text"
icon="el-icon-s-promotion"
@click="handlePublish(scope.row)">{{ $t('CMS.ContentCore.Publish') }}</el-button>
<span class="btn-cell-wrap">
<el-button
size="small"
type="text"
icon="el-icon-view"
@click="handlePreview(scope.row)">{{ $t('CMS.ContentCore.Preview') }}</el-button>
</span>
<span class="btn-cell-wrap">
<el-button
size="small"
type="text"
icon="el-icon-s-promotion"
v-hasPermi="[ $p('Catalog:EditContent:{0}', [ scope.row.catalogId ]) ]"
@click="handlePublish(scope.row)">{{ $t('CMS.ContentCore.Publish') }}</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-link :underline="false" class="row-more-btn" icon="el-icon-more"></el-link>
<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-delete" @click.native="handleDelete(scope.row)">{{ $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 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-bottom" @click.native="handleCancelTop(scope.row)">{{ $t('CMS.Content.CancelTop') }}</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)" 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)" 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)" 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)" 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-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-search" @click.native="handleCreateIndex(scope.row)">{{ $t('CMS.Content.GenIndex') }}</el-dropdown-item>
</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;
}
},
computed: {
okBtnDisabled() {
return this.selectedTemplate == undefined;
}
},
data () {
return {
loading: false,

View File

@ -2,8 +2,6 @@
<div class="pagewidget-container">
<el-row :gutter="24" class="mb12">
<el-col :span="8">
<el-row :gutter="10">
<el-col :span="1.5">
<el-button
plain
type="primary"
@ -12,8 +10,6 @@
v-hasPermi="[ $p('Site:AddPageWidget:{0}', [ siteId ]) ]"
@click="handleAdd">{{ $t("Common.Add") }}</el-button>
</el-col>
</el-row>
</el-col>
<el-col :span="16" style="text-align: right;">
<el-select
v-model="queryParams.type" size="mini"
@ -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('Common.Operation')" align="left" width="200" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-row :gutter="10">
<el-col :span="1.5">
<span class="btn-cell-wrap">
<el-button
size="mini"
type="text"
icon="el-icon-s-promotion"
v-hasPermi="[ $p('PageWidget:Publish:{0}', [ scope.row.pageWidgetId ]) ]"
@click="handlePublish(scope.row)">{{ $t('CMS.ContentCore.Publish') }}</el-button>
</el-col>
<el-col :span="1.5">
</span>
<span class="btn-cell-wrap">
<el-button
size="mini"
type="text"
icon="el-icon-view"
@click="handlePreview(scope.row)">{{ $t('CMS.ContentCore.Preview') }}</el-button>
</el-col>
<el-col :span="1.5">
</span>
<span class="btn-cell-wrap">
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleEdit(scope.row)">{{ $t('Common.Edit') }}</el-button>
</el-col>
<el-col :span="1.5">
</span>
<span class="btn-cell-wrap">
<el-button
size="mini"
type="text"
icon="el-icon-delete"
v-hasPermi="[ $p('PageWidget:Delete:{0}', [ scope.row.pageWidgetId ]) ]"
@click="handleDelete(scope.row)">{{ $t("Common.Delete") }}</el-button>
</el-col>
</el-row>
</span>
</template>
</el-table-column>
</el-table>

View File

@ -111,7 +111,7 @@
</el-form-item>
</el-form>
</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-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" />
@ -436,7 +436,7 @@ export default {
padding: 0 4px;
}
.resource-dialog .el-card {
width: 150px;
width: 148px;
text-align: center;
float: left;
border: none;

View File

@ -48,25 +48,36 @@
<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">
<template slot-scope="scope">
<el-button
type="text"
icon="el-icon-s-promotion"
size="small"
@click="handlePublish(scope.row)">{{ $t('CMS.Site.PublishHome') }}</el-button>
<span class="btn-cell-wrap">
<el-button
type="text"
size="small"
@click="handlePreview(scope.row)"><svg-icon icon-class="eye-open" class="mr2"></svg-icon>{{ $t('CMS.ContentCore.Preview') }}</el-button>
</span>
<span class="btn-cell-wrap">
<el-button
type="text"
icon="el-icon-s-promotion"
size="small"
v-hasPermi="[ $p('Site:Publish:{0}', [ scope.row.siteId ]) ]"
@click="handlePublish(scope.row)">{{ $t('CMS.Site.PublishHome') }}</el-button>
</span>
<span class="btn-cell-wrap">
<el-button
type="text"
icon="el-icon-edit"
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>
</el-table-column>
</el-table>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -106,6 +106,7 @@
<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">
<template slot-scope="scope">
<span class="btn-cell-wrap">
<el-button
size="small"
type="text"
@ -113,6 +114,8 @@
@click="handleUpdate(scope.row)"
v-hasPermi="['system:i18ndict:edit']"
>{{ $t('Common.Edit') }}</el-button>
</span>
<span class="btn-cell-wrap">
<el-button
size="small"
type="text"
@ -120,6 +123,7 @@
@click="handleDelete(scope.row)"
v-hasPermi="['system:i18ndict:remove']"
>{{ $t('Common.Delete') }}</el-button>
</span>
</template>
</el-table-column>
</el-table>

View File

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

View File

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

View File

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

View File

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

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