mirror of
https://gitee.com/liweiyi/ChestnutCMS.git
synced 2025-12-06 16:38:24 +08:00
版本更新:v1.5.1
This commit is contained in:
parent
29537b2388
commit
bd42862278
18
NOTICE
18
NOTICE
@ -13,15 +13,7 @@ Copyright 2002-2024 The Apache Software Foundation
|
|||||||
This product includes software developed at
|
This product includes software developed at
|
||||||
The Apache Software Foundation (https://www.apache.org/).
|
The Apache Software Foundation (https://www.apache.org/).
|
||||||
-----------------------------------------------------------------------
|
-----------------------------------------------------------------------
|
||||||
This product contains code from the redisson Project:
|
This product contains code from the Apache Commons Text Project:
|
||||||
|
|
||||||
Apache Commons Text
|
|
||||||
Copyright 2014-2024 The Apache Software Foundation
|
|
||||||
|
|
||||||
This product includes software developed at
|
|
||||||
The Apache Software Foundation (https://www.apache.org/).
|
|
||||||
-----------------------------------------------------------------------
|
|
||||||
This product contains code from the redisson Project:
|
|
||||||
|
|
||||||
Apache Commons Text
|
Apache Commons Text
|
||||||
Copyright 2014-2024 The Apache Software Foundation
|
Copyright 2014-2024 The Apache Software Foundation
|
||||||
@ -41,3 +33,11 @@ The files
|
|||||||
- velocity-engine-scripting/src/main/java/org/apache/velocity/script/VelocityScriptEngine.java
|
- velocity-engine-scripting/src/main/java/org/apache/velocity/script/VelocityScriptEngine.java
|
||||||
- velocity-engine-scripting/src/main/java/org/apache/velocity/script/VelocityScriptEngineFactory.java
|
- velocity-engine-scripting/src/main/java/org/apache/velocity/script/VelocityScriptEngineFactory.java
|
||||||
are Copyright 2006 Sun Microsystems, Inc., and licenced under a BSD-like licence.
|
are Copyright 2006 Sun Microsystems, Inc., and licenced under a BSD-like licence.
|
||||||
|
-----------------------------------------------------------------------
|
||||||
|
This product contains code from the flexmark-java Project:
|
||||||
|
|
||||||
|
Copyright (c) 2015-2016, Atlassian Pty Ltd
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Copyright (c) 2016-2018, Vladimir Schneider,
|
||||||
|
All rights reserved.
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
# ChestnutCMS v1.5.0
|
# ChestnutCMS v1.5.1
|
||||||
|
|
||||||
### 系统简介
|
### 系统简介
|
||||||
|
|
||||||
@ -10,9 +10,9 @@ ChestnutCMS是前后端分离的企业级内容管理系统。项目基于[RuoYi
|
|||||||
|
|
||||||
账号:demo / a123456
|
账号:demo / a123456
|
||||||
|
|
||||||
企业站演示地址:<http://swikoon.1000mz.com>
|
企业站演示地址:<https://swikoon.1000mz.com>
|
||||||
|
|
||||||
资讯站演示地址:<http://news.1000mz.com>(会员演示账号:xxx333@126.com / a123456)
|
资讯站演示地址:<https://news.1000mz.com>(会员演示账号:xxx333@126.com / a123456)
|
||||||
|
|
||||||
图片站演示地址:PC端:<http://tpz.1000mz.com> 移动端:<http://mtpz.1000mz.com>
|
图片站演示地址:PC端:<http://tpz.1000mz.com> 移动端:<http://mtpz.1000mz.com>
|
||||||
|
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>chestnut</artifactId>
|
<artifactId>chestnut</artifactId>
|
||||||
<groupId>com.chestnut</groupId>
|
<groupId>com.chestnut</groupId>
|
||||||
<version>1.5.0</version>
|
<version>1.5.1</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|||||||
@ -5,7 +5,7 @@ chestnut:
|
|||||||
# 代号
|
# 代号
|
||||||
alias: ChestnutCMS
|
alias: ChestnutCMS
|
||||||
# 版本
|
# 版本
|
||||||
version: 1.5.0
|
version: 1.5.1
|
||||||
# 版权年份
|
# 版权年份
|
||||||
copyrightYear: 2022-2024
|
copyrightYear: 2022-2024
|
||||||
system:
|
system:
|
||||||
@ -191,10 +191,8 @@ spring:
|
|||||||
|
|
||||||
# Actuator 监控端点的配置项
|
# Actuator 监控端点的配置项
|
||||||
management:
|
management:
|
||||||
trace:
|
|
||||||
http:
|
|
||||||
enabled: true
|
|
||||||
endpoints:
|
endpoints:
|
||||||
|
enabled-by-default: false
|
||||||
web:
|
web:
|
||||||
exposure:
|
exposure:
|
||||||
include: '*'
|
include: '*'
|
||||||
@ -203,6 +201,9 @@ management:
|
|||||||
show-details: ALWAYS
|
show-details: ALWAYS
|
||||||
logfile:
|
logfile:
|
||||||
external-file: ./logs/client.log
|
external-file: ./logs/client.log
|
||||||
|
httpexchanges:
|
||||||
|
recording:
|
||||||
|
enabled: true
|
||||||
|
|
||||||
sa-token:
|
sa-token:
|
||||||
# token名称 (同时也是cookie名称)
|
# token名称 (同时也是cookie名称)
|
||||||
@ -237,6 +238,9 @@ mybatis-plus:
|
|||||||
xss:
|
xss:
|
||||||
# 过滤开关
|
# 过滤开关
|
||||||
enabled: true
|
enabled: true
|
||||||
|
# 过滤链接
|
||||||
|
urlPatterns:
|
||||||
|
- /*
|
||||||
|
|
||||||
xxl:
|
xxl:
|
||||||
job:
|
job:
|
||||||
|
|||||||
@ -5,7 +5,7 @@ chestnut:
|
|||||||
# 代号
|
# 代号
|
||||||
alias: ChestnutCMS
|
alias: ChestnutCMS
|
||||||
# 版本
|
# 版本
|
||||||
version: 1.5.0
|
version: 1.5.1
|
||||||
# 版权年份
|
# 版权年份
|
||||||
copyrightYear: 2022-2024
|
copyrightYear: 2022-2024
|
||||||
system:
|
system:
|
||||||
@ -195,7 +195,7 @@ sa-token:
|
|||||||
# token有效期,单位s 默认30天, -1代表永不过期
|
# token有效期,单位s 默认30天, -1代表永不过期
|
||||||
timeout: 2592000
|
timeout: 2592000
|
||||||
# token临时有效期 (指定时间内无操作就视为token过期) 单位: 秒
|
# token临时有效期 (指定时间内无操作就视为token过期) 单位: 秒
|
||||||
active-timeout: -1
|
active-timeout: 1800
|
||||||
# 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录)
|
# 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录)
|
||||||
is-concurrent: true
|
is-concurrent: true
|
||||||
# 在多人登录同一账号时,是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token)
|
# 在多人登录同一账号时,是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token)
|
||||||
|
|||||||
@ -5,7 +5,7 @@ chestnut:
|
|||||||
# 代号
|
# 代号
|
||||||
alias: ChestnutCMS
|
alias: ChestnutCMS
|
||||||
# 版本
|
# 版本
|
||||||
version: 1.5.0
|
version: 1.5.1
|
||||||
# 版权年份
|
# 版权年份
|
||||||
copyrightYear: 2022-2024
|
copyrightYear: 2022-2024
|
||||||
system:
|
system:
|
||||||
|
|||||||
@ -4,9 +4,6 @@ ALTER TABLE cms_image DROP COLUMN deleted;
|
|||||||
ALTER TABLE cms_audio DROP COLUMN deleted;
|
ALTER TABLE cms_audio DROP COLUMN deleted;
|
||||||
ALTER TABLE cms_video DROP COLUMN deleted;
|
ALTER TABLE cms_video DROP COLUMN deleted;
|
||||||
|
|
||||||
-- ----------------------------
|
|
||||||
-- Table structure for b_cms_content
|
|
||||||
-- ----------------------------
|
|
||||||
CREATE TABLE `b_cms_content` (
|
CREATE TABLE `b_cms_content` (
|
||||||
`content_id` bigint NOT NULL COMMENT '主键ID',
|
`content_id` bigint NOT NULL COMMENT '主键ID',
|
||||||
`site_id` bigint NOT NULL COMMENT '所属站点ID',
|
`site_id` bigint NOT NULL COMMENT '所属站点ID',
|
||||||
@ -69,9 +66,7 @@ CREATE TABLE `b_cms_content` (
|
|||||||
`backup_remark` varchar(100) COLLATE utf8mb4_general_ci DEFAULT NULL,
|
`backup_remark` varchar(100) COLLATE utf8mb4_general_ci DEFAULT NULL,
|
||||||
PRIMARY KEY (`backup_id`) USING BTREE
|
PRIMARY KEY (`backup_id`) USING BTREE
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC;
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC;
|
||||||
-- ----------------------------
|
|
||||||
-- Table structure for b_cms_article_detail
|
|
||||||
-- ----------------------------
|
|
||||||
CREATE TABLE `b_cms_article_detail` (
|
CREATE TABLE `b_cms_article_detail` (
|
||||||
`content_id` bigint NOT NULL COMMENT 'ID',
|
`content_id` bigint NOT NULL COMMENT 'ID',
|
||||||
`site_id` bigint NOT NULL,
|
`site_id` bigint NOT NULL,
|
||||||
@ -85,9 +80,7 @@ CREATE TABLE `b_cms_article_detail` (
|
|||||||
`backup_remark` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
|
`backup_remark` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
|
||||||
PRIMARY KEY (`backup_id`) USING BTREE
|
PRIMARY KEY (`backup_id`) USING BTREE
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC;
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC;
|
||||||
-- ----------------------------
|
|
||||||
-- Table structure for b_cms_image
|
|
||||||
-- ----------------------------
|
|
||||||
CREATE TABLE `b_cms_image` (
|
CREATE TABLE `b_cms_image` (
|
||||||
`image_id` bigint NOT NULL COMMENT '主键ID',
|
`image_id` bigint NOT NULL COMMENT '主键ID',
|
||||||
`site_id` bigint DEFAULT NULL,
|
`site_id` bigint DEFAULT NULL,
|
||||||
@ -114,9 +107,7 @@ CREATE TABLE `b_cms_image` (
|
|||||||
`backup_remark` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
|
`backup_remark` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
|
||||||
PRIMARY KEY (`backup_id`) USING BTREE
|
PRIMARY KEY (`backup_id`) USING BTREE
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC;
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC;
|
||||||
-- ----------------------------
|
|
||||||
-- Table structure for b_cms_audio
|
|
||||||
-- ----------------------------
|
|
||||||
CREATE TABLE `b_cms_audio` (
|
CREATE TABLE `b_cms_audio` (
|
||||||
`audio_id` bigint NOT NULL COMMENT 'ID',
|
`audio_id` bigint NOT NULL COMMENT 'ID',
|
||||||
`content_id` bigint NOT NULL COMMENT '所属内容ID',
|
`content_id` bigint NOT NULL COMMENT '所属内容ID',
|
||||||
@ -145,9 +136,7 @@ CREATE TABLE `b_cms_audio` (
|
|||||||
`backup_remark` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
|
`backup_remark` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
|
||||||
PRIMARY KEY (`backup_id`) USING BTREE
|
PRIMARY KEY (`backup_id`) USING BTREE
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC;
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC;
|
||||||
-- ----------------------------
|
|
||||||
-- Table structure for b_cms_video
|
|
||||||
-- ----------------------------
|
|
||||||
CREATE TABLE `b_cms_video` (
|
CREATE TABLE `b_cms_video` (
|
||||||
`video_id` bigint NOT NULL,
|
`video_id` bigint NOT NULL,
|
||||||
`content_id` bigint NOT NULL COMMENT '所属内容ID',
|
`content_id` bigint NOT NULL COMMENT '所属内容ID',
|
||||||
@ -179,9 +168,6 @@ CREATE TABLE `b_cms_video` (
|
|||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC;
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC;
|
||||||
|
|
||||||
-- __CC_IGNORE__
|
-- __CC_IGNORE__
|
||||||
-- ----------------------------
|
|
||||||
-- Table structure for cms_book
|
|
||||||
-- ----------------------------
|
|
||||||
CREATE TABLE `cms_book` (
|
CREATE TABLE `cms_book` (
|
||||||
`content_id` bigint NOT NULL COMMENT 'ID',
|
`content_id` bigint NOT NULL COMMENT 'ID',
|
||||||
`site_id` bigint NOT NULL COMMENT '所属站点ID',
|
`site_id` bigint NOT NULL COMMENT '所属站点ID',
|
||||||
@ -199,9 +185,7 @@ CREATE TABLE `cms_book` (
|
|||||||
`completed` varchar(1) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '是否完结',
|
`completed` varchar(1) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '是否完结',
|
||||||
PRIMARY KEY (`content_id`)
|
PRIMARY KEY (`content_id`)
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||||
-- ----------------------------
|
|
||||||
-- Table structure for b_cms_book
|
|
||||||
-- ----------------------------
|
|
||||||
CREATE TABLE `b_cms_book` (
|
CREATE TABLE `b_cms_book` (
|
||||||
`content_id` bigint NOT NULL COMMENT 'ID',
|
`content_id` bigint NOT NULL COMMENT 'ID',
|
||||||
`site_id` bigint NOT NULL COMMENT '所属站点ID',
|
`site_id` bigint NOT NULL COMMENT '所属站点ID',
|
||||||
@ -223,9 +207,7 @@ CREATE TABLE `b_cms_book` (
|
|||||||
`backup_remark` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
|
`backup_remark` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
|
||||||
PRIMARY KEY (`backup_id`) USING BTREE
|
PRIMARY KEY (`backup_id`) USING BTREE
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||||
-- ----------------------------
|
|
||||||
-- Table structure for cms_book_chapter
|
|
||||||
-- ----------------------------
|
|
||||||
CREATE TABLE `cms_book_chapter` (
|
CREATE TABLE `cms_book_chapter` (
|
||||||
`chapter_id` bigint NOT NULL COMMENT 'ID',
|
`chapter_id` bigint NOT NULL COMMENT 'ID',
|
||||||
`site_id` bigint NOT NULL COMMENT '所属站点ID',
|
`site_id` bigint NOT NULL COMMENT '所属站点ID',
|
||||||
@ -243,9 +225,7 @@ CREATE TABLE `cms_book_chapter` (
|
|||||||
`remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '备注',
|
`remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '备注',
|
||||||
PRIMARY KEY (`chapter_id`)
|
PRIMARY KEY (`chapter_id`)
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||||
-- ----------------------------
|
|
||||||
-- Table structure for b_cms_book_chapter
|
|
||||||
-- ----------------------------
|
|
||||||
CREATE TABLE `b_cms_book_chapter` (
|
CREATE TABLE `b_cms_book_chapter` (
|
||||||
`chapter_id` bigint NOT NULL COMMENT 'ID',
|
`chapter_id` bigint NOT NULL COMMENT 'ID',
|
||||||
`site_id` bigint NOT NULL COMMENT '所属站点ID',
|
`site_id` bigint NOT NULL COMMENT '所属站点ID',
|
||||||
|
|||||||
@ -0,0 +1,83 @@
|
|||||||
|
UPDATE cms_content SET `link_flag` = 'N' WHERE link_flag is null;
|
||||||
|
ALTER TABLE cms_content MODIFY COLUMN `link_flag` varchar(1) DEFAULT 'N';
|
||||||
|
UPDATE cms_content SET `is_lock` = 'N' WHERE is_lock is null;
|
||||||
|
ALTER TABLE cms_content MODIFY COLUMN `is_lock` varchar(1) DEFAULT 'N';
|
||||||
|
|
||||||
|
ALTER TABLE cms_video MODIFY COLUMN `path` varchar(1000);
|
||||||
|
ALTER TABLE b_cms_video MODIFY COLUMN `path` varchar(1000);
|
||||||
|
|
||||||
|
ALTER TABLE cms_content ADD COLUMN `images` varchar(500);
|
||||||
|
UPDATE cms_content SET images = CASE WHEN logo IS NOT NULL AND logo != '' THEN CONCAT('["', logo, '"]') ELSE '[]' END;
|
||||||
|
ALTER TABLE cms_content DROP COLUMN logo;
|
||||||
|
|
||||||
|
ALTER TABLE cms_article_detail DROP COLUMN content_json;
|
||||||
|
ALTER TABLE cms_article_detail ADD COLUMN `format` varchar(10);
|
||||||
|
UPDATE cms_article_detail SET format = 'RichText';
|
||||||
|
|
||||||
|
CREATE TABLE `cms_content_op_log` (
|
||||||
|
`log_id` bigint NOT NULL COMMENT 'ID',
|
||||||
|
`site_id` bigint NOT NULL COMMENT '站点ID',
|
||||||
|
`content_id` bigint NOT NULL COMMENT '内容ID',
|
||||||
|
`type` varchar(20) COLLATE utf8mb4_general_ci NOT NULL COMMENT '操作方式',
|
||||||
|
`details` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '操作明细',
|
||||||
|
`operator_type` varchar(20) COLLATE utf8mb4_general_ci NOT NULL COMMENT '操作人类型',
|
||||||
|
`operator` varchar(50) COLLATE utf8mb4_general_ci NOT NULL COMMENT '操作人',
|
||||||
|
`log_time` datetime NOT NULL COMMENT '日志时间',
|
||||||
|
PRIMARY KEY (`log_id`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||||
|
|
||||||
|
/* __CC_IGNORE__ */
|
||||||
|
CREATE TABLE `cc_check_latest_version_log` (
|
||||||
|
`log_id` bigint NOT NULL COMMENT 'ID',
|
||||||
|
`from` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '来源',
|
||||||
|
`referer` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT 'Referer',
|
||||||
|
`create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '创建者',
|
||||||
|
`create_time` datetime NOT NULL COMMENT '创建时间',
|
||||||
|
`update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '更新者',
|
||||||
|
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
|
||||||
|
`remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '备注',
|
||||||
|
PRIMARY KEY (`log_id`) USING BTREE
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC;
|
||||||
|
|
||||||
|
CREATE TABLE `cc_certificate` (
|
||||||
|
`cert_id` bigint NOT NULL COMMENT 'ID',
|
||||||
|
`issuer` varchar(50) COLLATE utf8mb4_general_ci NOT NULL COMMENT '签发者类型',
|
||||||
|
`domain` varchar(100) COLLATE utf8mb4_general_ci NOT NULL COMMENT '域名',
|
||||||
|
`acme_account_id` bigint DEFAULT NULL COMMENT '关联ACME账号ID',
|
||||||
|
`issue_time` bigint DEFAULT NULL COMMENT '证书签发时间',
|
||||||
|
`expire_time` bigint DEFAULT NULL COMMENT '证书过期时间',
|
||||||
|
`key_path` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '证书Key路径',
|
||||||
|
`crt_path` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '证书路径',
|
||||||
|
`crt_country` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '证书信息:国家',
|
||||||
|
`crt_state` varchar(100) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '证书信息:省',
|
||||||
|
`crt_locality` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '证书信息:地区',
|
||||||
|
`crt_organization` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '证书信息:组织机构',
|
||||||
|
`status` varchar(20) COLLATE utf8mb4_general_ci NOT NULL COMMENT '状态',
|
||||||
|
`config_props` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '配置参数',
|
||||||
|
`create_by` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '创建人',
|
||||||
|
`create_time` datetime NOT NULL COMMENT '创建时间',
|
||||||
|
`update_by` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '最后修改人',
|
||||||
|
`update_time` datetime DEFAULT NULL COMMENT '最后修改时间',
|
||||||
|
`remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '备注',
|
||||||
|
PRIMARY KEY (`cert_id`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='域名证书表';
|
||||||
|
|
||||||
|
CREATE TABLE `cc_acme_account` (
|
||||||
|
`account_id` bigint NOT NULL,
|
||||||
|
`issuer` varchar(50) COLLATE utf8mb4_general_ci NOT NULL,
|
||||||
|
`key_pair_path` varchar(255) COLLATE utf8mb4_general_ci NOT NULL,
|
||||||
|
`location_url` varchar(500) COLLATE utf8mb4_general_ci DEFAULT NULL,
|
||||||
|
`domain_num` int NOT NULL,
|
||||||
|
`contact` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL,
|
||||||
|
`create_by` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '创建人',
|
||||||
|
`create_time` datetime NOT NULL COMMENT '创建时间',
|
||||||
|
`update_by` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '最后修改人',
|
||||||
|
`update_time` datetime DEFAULT NULL COMMENT '最后修改时间',
|
||||||
|
`remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '备注',
|
||||||
|
PRIMARY KEY (`account_id`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='ACME账号表';
|
||||||
|
INSERT INTO `sys_menu` VALUES (2082, '域名证书', 3, 5, 'deploy/certificate', 'deploy/certificate/index', '', 'N', 'Y', 'C', 'Y', '0', 'deploy:cert:view', 'skill', 'admin', '2025-01-14 00:00:00', '', NULL, '');
|
||||||
|
INSERT INTO `sys_i18n_dict` VALUES (632978182307909, 'zh-CN', 'MENU.NAME.2082', '证书管理');
|
||||||
|
INSERT INTO `sys_i18n_dict` VALUES (633640198516805, 'en', 'MENU.NAME.2082', 'Domain Cert');
|
||||||
|
INSERT INTO `sys_i18n_dict` VALUES (633640198524997, 'zh-TW', 'MENU.NAME.2082', '證書管理');
|
||||||
|
/* __CC_IGNORE_END__ */
|
||||||
@ -1,28 +0,0 @@
|
|||||||
package com.chestnut.member;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.boot.test.context.SpringBootTest;
|
|
||||||
|
|
||||||
import com.chestnut.member.domain.Member;
|
|
||||||
import com.chestnut.member.service.IMemberExpConfigService;
|
|
||||||
import com.chestnut.member.service.IMemberService;
|
|
||||||
|
|
||||||
@SpringBootTest
|
|
||||||
public class MemberTest {
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private IMemberService memberService;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private IMemberExpConfigService expConfigService;
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testMemberSignIn() {
|
|
||||||
Member member = this.memberService.getById(398339741712453L);
|
|
||||||
|
|
||||||
expConfigService.list().forEach(expConfig -> {
|
|
||||||
|
|
||||||
expConfigService.triggerExpOperation(expConfig.getOpType(), member.getMemberId());
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -7,7 +7,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>com.chestnut</groupId>
|
<groupId>com.chestnut</groupId>
|
||||||
<artifactId>chestnut-cms</artifactId>
|
<artifactId>chestnut-cms</artifactId>
|
||||||
<version>1.5.0</version>
|
<version>1.5.1</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>chestnut-cms-advertisement</artifactId>
|
<artifactId>chestnut-cms-advertisement</artifactId>
|
||||||
|
|||||||
@ -29,7 +29,6 @@ import org.springframework.stereotype.Component;
|
|||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.logging.Logger;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 广告页面部件内容核心数据处理器
|
* 广告页面部件内容核心数据处理器
|
||||||
@ -61,6 +60,7 @@ public class AdCoreDataHandler implements ICoreDataHandler {
|
|||||||
files.forEach(f -> {
|
files.forEach(f -> {
|
||||||
List<CmsAdvertisement> list = JacksonUtils.fromList(f, CmsAdvertisement.class);
|
List<CmsAdvertisement> list = JacksonUtils.fromList(f, CmsAdvertisement.class);
|
||||||
for (CmsAdvertisement data : list) {
|
for (CmsAdvertisement data : list) {
|
||||||
|
Long oldAdvertisementId = data.getAdvertisementId();
|
||||||
try {
|
try {
|
||||||
data.setAdvertisementId(IdUtils.getSnowflakeId());
|
data.setAdvertisementId(IdUtils.getSnowflakeId());
|
||||||
data.setSiteId(context.getSite().getSiteId());
|
data.setSiteId(context.getSite().getSiteId());
|
||||||
@ -70,8 +70,7 @@ public class AdCoreDataHandler implements ICoreDataHandler {
|
|||||||
data.setRedirectUrl(context.dealInternalUrl(data.getRedirectUrl()));
|
data.setRedirectUrl(context.dealInternalUrl(data.getRedirectUrl()));
|
||||||
advertisementService.save(data);
|
advertisementService.save(data);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
AsyncTaskManager.addErrMessage("导入广告数据失败:" + data.getName()
|
AsyncTaskManager.addErrMessage("导入广告数据`" + oldAdvertisementId + "`失败:" + e.getMessage());
|
||||||
+ "[" + data.getAdvertisementId() + "]");
|
|
||||||
log.error("Import advertisement failed: {}", data.getAdvertisementId(), e);
|
log.error("Import advertisement failed: {}", data.getAdvertisementId(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,70 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2022-2024 兮玥(190785909@qq.com)
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.chestnut.advertisement.cache;
|
||||||
|
|
||||||
|
import com.chestnut.common.redis.IMonitoredCache;
|
||||||
|
import com.chestnut.common.redis.RedisCache;
|
||||||
|
import com.chestnut.contentcore.config.CMSConfig;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AdMonitoredCache
|
||||||
|
*
|
||||||
|
* @author 兮玥
|
||||||
|
* @email 190785909@qq.com
|
||||||
|
*/
|
||||||
|
@Component(IMonitoredCache.BEAN_PREFIX + AdMonitoredCache.ID)
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class AdMonitoredCache implements IMonitoredCache<Map<String, String>> {
|
||||||
|
|
||||||
|
public static final String ID = "AD";
|
||||||
|
|
||||||
|
private static final String CACHE_PREFIX = CMSConfig.CachePrefix + "adv-ids";
|
||||||
|
|
||||||
|
private final RedisCache redisCache;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getId() {
|
||||||
|
return ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getCacheName() {
|
||||||
|
return "{MONITORED.CACHE.AD}";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getCacheKey() {
|
||||||
|
return CACHE_PREFIX;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, String> getCache(String cacheKey) {
|
||||||
|
return redisCache.getCacheMap(cacheKey, String.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, String> getCache(Supplier<Map<String, String>> supplier) {
|
||||||
|
return redisCache.getCacheMap(CACHE_PREFIX, String.class, supplier);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clear() {
|
||||||
|
this.redisCache.deleteObject(CACHE_PREFIX);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -15,16 +15,16 @@
|
|||||||
*/
|
*/
|
||||||
package com.chestnut.advertisement.pojo.vo;
|
package com.chestnut.advertisement.pojo.vo;
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
|
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
|
||||||
import com.chestnut.advertisement.domain.CmsAdvertisement;
|
import com.chestnut.advertisement.domain.CmsAdvertisement;
|
||||||
|
import com.chestnut.common.annotation.XComment;
|
||||||
import com.chestnut.contentcore.util.InternalUrlUtils;
|
import com.chestnut.contentcore.util.InternalUrlUtils;
|
||||||
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 广告数据VO
|
* 广告数据VO
|
||||||
*
|
*
|
||||||
@ -36,79 +36,49 @@ import lombok.Setter;
|
|||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
public class AdvertisementVO {
|
public class AdvertisementVO {
|
||||||
|
|
||||||
/**
|
@XComment("广告ID")
|
||||||
* 广告ID
|
|
||||||
*/
|
|
||||||
private Long advertisementId;
|
private Long advertisementId;
|
||||||
|
|
||||||
/**
|
@XComment("所属广告版本(页面部件)ID")
|
||||||
* 所属广告位ID
|
|
||||||
*/
|
|
||||||
private Long adSpaceId;
|
private Long adSpaceId;
|
||||||
|
|
||||||
/**
|
@XComment("类型")
|
||||||
* 类型
|
|
||||||
*/
|
|
||||||
private String type;
|
private String type;
|
||||||
|
|
||||||
/**
|
@XComment("名称")
|
||||||
* 名称
|
|
||||||
*/
|
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
/**
|
@XComment("权重")
|
||||||
* 权重
|
|
||||||
*/
|
|
||||||
private Integer weight;
|
private Integer weight;
|
||||||
|
|
||||||
/**
|
@XComment("关键词")
|
||||||
* 关键词
|
|
||||||
*/
|
|
||||||
private String keywords;
|
private String keywords;
|
||||||
|
|
||||||
/**
|
@XComment("状态")
|
||||||
* 状态
|
|
||||||
*/
|
|
||||||
private String state;
|
private String state;
|
||||||
|
|
||||||
/**
|
@XComment("上线时间")
|
||||||
* 上线时间
|
|
||||||
*/
|
|
||||||
private LocalDateTime onlineDate;
|
private LocalDateTime onlineDate;
|
||||||
|
|
||||||
/**
|
@XComment("下线时间")
|
||||||
* 下线时间
|
|
||||||
*/
|
|
||||||
private LocalDateTime offlineDate;
|
private LocalDateTime offlineDate;
|
||||||
|
|
||||||
/**
|
@XComment("原始跳转链接")
|
||||||
* 跳转链接
|
|
||||||
*/
|
|
||||||
private String redirectUrl;
|
private String redirectUrl;
|
||||||
|
|
||||||
/**
|
@XComment("实际跳转链接(可设置为中转地址)")
|
||||||
* 跳转链接(可设置为中转地址)
|
|
||||||
*/
|
|
||||||
private String link;
|
private String link;
|
||||||
|
|
||||||
/**
|
@XComment("素材路径")
|
||||||
* 素材链接
|
|
||||||
*/
|
|
||||||
private String resourcePath;
|
private String resourcePath;
|
||||||
|
|
||||||
/**
|
@XComment("素材访问链接")
|
||||||
* 素材真实地址
|
|
||||||
*/
|
|
||||||
private String resourceSrc;
|
private String resourceSrc;
|
||||||
|
|
||||||
/**
|
@XComment("创建人")
|
||||||
* 创建人
|
|
||||||
*/
|
|
||||||
private String createBy;
|
private String createBy;
|
||||||
|
|
||||||
/**
|
@XComment("创建时间")
|
||||||
* 创建时间
|
|
||||||
*/
|
|
||||||
private LocalDateTime createTime;
|
private LocalDateTime createTime;
|
||||||
|
|
||||||
public AdvertisementVO(CmsAdvertisement ad) {
|
public AdvertisementVO(CmsAdvertisement ad) {
|
||||||
|
|||||||
@ -15,35 +15,41 @@
|
|||||||
*/
|
*/
|
||||||
package com.chestnut.advertisement.service.impl;
|
package com.chestnut.advertisement.service.impl;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
import com.chestnut.advertisement.AdSpacePageWidgetType;
|
||||||
|
import com.chestnut.advertisement.IAdvertisementType;
|
||||||
|
import com.chestnut.advertisement.cache.AdMonitoredCache;
|
||||||
|
import com.chestnut.advertisement.domain.CmsAdvertisement;
|
||||||
|
import com.chestnut.advertisement.mapper.CmsAdvertisementMapper;
|
||||||
|
import com.chestnut.advertisement.pojo.dto.AdvertisementDTO;
|
||||||
|
import com.chestnut.advertisement.service.IAdvertisementService;
|
||||||
|
import com.chestnut.common.async.AsyncTaskManager;
|
||||||
|
import com.chestnut.common.exception.CommonErrorCode;
|
||||||
|
import com.chestnut.common.utils.Assert;
|
||||||
|
import com.chestnut.common.utils.IdUtils;
|
||||||
|
import com.chestnut.contentcore.core.IPageWidget;
|
||||||
|
import com.chestnut.contentcore.core.IPageWidgetType;
|
||||||
|
import com.chestnut.contentcore.domain.CmsPageWidget;
|
||||||
|
import com.chestnut.contentcore.domain.CmsSite;
|
||||||
|
import com.chestnut.contentcore.properties.SiteApiUrlProperty;
|
||||||
|
import com.chestnut.contentcore.publish.IStaticizeType;
|
||||||
|
import com.chestnut.contentcore.service.IPageWidgetService;
|
||||||
|
import com.chestnut.contentcore.service.ISiteService;
|
||||||
|
import com.chestnut.system.fixed.dict.EnableOrDisable;
|
||||||
|
import com.chestnut.system.security.StpAdminUtil;
|
||||||
|
import freemarker.template.TemplateException;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.beans.BeanUtils;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.net.URLEncoder;
|
import java.net.URLEncoder;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import com.chestnut.contentcore.domain.CmsSite;
|
|
||||||
import com.chestnut.contentcore.properties.SiteApiUrlProperty;
|
|
||||||
import com.chestnut.contentcore.service.ISiteService;
|
|
||||||
import org.springframework.beans.BeanUtils;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
||||||
import com.chestnut.advertisement.IAdvertisementType;
|
|
||||||
import com.chestnut.advertisement.domain.CmsAdvertisement;
|
|
||||||
import com.chestnut.advertisement.mapper.CmsAdvertisementMapper;
|
|
||||||
import com.chestnut.advertisement.pojo.dto.AdvertisementDTO;
|
|
||||||
import com.chestnut.advertisement.service.IAdvertisementService;
|
|
||||||
import com.chestnut.common.exception.CommonErrorCode;
|
|
||||||
import com.chestnut.common.redis.RedisCache;
|
|
||||||
import com.chestnut.common.utils.Assert;
|
|
||||||
import com.chestnut.common.utils.IdUtils;
|
|
||||||
import com.chestnut.contentcore.config.CMSConfig;
|
|
||||||
import com.chestnut.contentcore.domain.CmsPageWidget;
|
|
||||||
import com.chestnut.contentcore.service.IPageWidgetService;
|
|
||||||
import com.chestnut.system.fixed.dict.EnableOrDisable;
|
|
||||||
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
* 广告数据服务实现类
|
* 广告数据服务实现类
|
||||||
@ -57,9 +63,7 @@ import lombok.RequiredArgsConstructor;
|
|||||||
public class AdvertisementServiceImpl extends ServiceImpl<CmsAdvertisementMapper, CmsAdvertisement>
|
public class AdvertisementServiceImpl extends ServiceImpl<CmsAdvertisementMapper, CmsAdvertisement>
|
||||||
implements IAdvertisementService {
|
implements IAdvertisementService {
|
||||||
|
|
||||||
private static final String CACHE_KEY_ADV_IDS = CMSConfig.CachePrefix + "adv-ids";
|
private final AdMonitoredCache adCache;
|
||||||
|
|
||||||
private final RedisCache redisCache;
|
|
||||||
|
|
||||||
private final Map<String, IAdvertisementType> advertisementTypes;
|
private final Map<String, IAdvertisementType> advertisementTypes;
|
||||||
|
|
||||||
@ -67,6 +71,8 @@ public class AdvertisementServiceImpl extends ServiceImpl<CmsAdvertisementMapper
|
|||||||
|
|
||||||
private final ISiteService siteService;
|
private final ISiteService siteService;
|
||||||
|
|
||||||
|
private final AsyncTaskManager asyncTaskManager;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IAdvertisementType getAdvertisementType(String typeId) {
|
public IAdvertisementType getAdvertisementType(String typeId) {
|
||||||
return this.advertisementTypes.get(IAdvertisementType.BEAN_NAME_PREFIX + typeId);
|
return this.advertisementTypes.get(IAdvertisementType.BEAN_NAME_PREFIX + typeId);
|
||||||
@ -79,10 +85,12 @@ public class AdvertisementServiceImpl extends ServiceImpl<CmsAdvertisementMapper
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, String> getAdvertisementMap() {
|
public Map<String, String> getAdvertisementMap() {
|
||||||
return this.redisCache.getCacheMap(CACHE_KEY_ADV_IDS,
|
return adCache.getCache(() -> {
|
||||||
() -> this.lambdaQuery().select(List.of(CmsAdvertisement::getAdvertisementId, CmsAdvertisement::getName)).list()
|
return this.lambdaQuery()
|
||||||
.stream().collect(
|
.select(List.of(CmsAdvertisement::getAdvertisementId, CmsAdvertisement::getName))
|
||||||
Collectors.toMap(ad -> ad.getAdvertisementId().toString(), CmsAdvertisement::getName)));
|
.list().stream()
|
||||||
|
.collect(Collectors.toMap(ad -> ad.getAdvertisementId().toString(), CmsAdvertisement::getName));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -99,7 +107,7 @@ public class AdvertisementServiceImpl extends ServiceImpl<CmsAdvertisementMapper
|
|||||||
advertisement.createBy(dto.getOperator().getUsername());
|
advertisement.createBy(dto.getOperator().getUsername());
|
||||||
this.save(advertisement);
|
this.save(advertisement);
|
||||||
|
|
||||||
this.redisCache.deleteObject(CACHE_KEY_ADV_IDS);
|
this.adCache.clear();
|
||||||
return advertisement;
|
return advertisement;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,12 +124,14 @@ public class AdvertisementServiceImpl extends ServiceImpl<CmsAdvertisementMapper
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public void deleteAdvertisement(List<Long> advertisementIds) {
|
public void deleteAdvertisement(List<Long> advertisementIds) {
|
||||||
this.removeByIds(advertisementIds);
|
this.removeByIds(advertisementIds);
|
||||||
this.redisCache.deleteObject(CACHE_KEY_ADV_IDS);
|
this.adCache.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public void enableAdvertisement(List<Long> advertisementIds, String operator) {
|
public void enableAdvertisement(List<Long> advertisementIds, String operator) {
|
||||||
List<CmsAdvertisement> list = this.listByIds(advertisementIds);
|
List<CmsAdvertisement> list = this.listByIds(advertisementIds);
|
||||||
for (CmsAdvertisement ad : list) {
|
for (CmsAdvertisement ad : list) {
|
||||||
@ -134,6 +144,7 @@ public class AdvertisementServiceImpl extends ServiceImpl<CmsAdvertisementMapper
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public void disableAdvertisement(List<Long> advertisementIds, String operator) {
|
public void disableAdvertisement(List<Long> advertisementIds, String operator) {
|
||||||
List<CmsAdvertisement> list = this.listByIds(advertisementIds);
|
List<CmsAdvertisement> list = this.listByIds(advertisementIds);
|
||||||
for (CmsAdvertisement ad : list) {
|
for (CmsAdvertisement ad : list) {
|
||||||
@ -143,7 +154,14 @@ public class AdvertisementServiceImpl extends ServiceImpl<CmsAdvertisementMapper
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.updateBatchById(list);
|
this.updateBatchById(list);
|
||||||
// todo 重新发布
|
// 重新发布
|
||||||
|
asyncTaskManager.execute(() -> {
|
||||||
|
CmsPageWidget pageWidget = this.pageWidgetService.getById(list.get(0).getAdSpaceId());
|
||||||
|
IPageWidgetType pwt = pageWidgetService.getPageWidgetType(AdSpacePageWidgetType.ID);
|
||||||
|
IPageWidget pw = pwt.loadPageWidget(pageWidget);
|
||||||
|
pw.setOperator(StpAdminUtil.getLoginUser());
|
||||||
|
pw.publish();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@ -45,11 +45,15 @@ import java.util.Map;
|
|||||||
public class CmsAdvertisementTag extends AbstractListTag {
|
public class CmsAdvertisementTag extends AbstractListTag {
|
||||||
|
|
||||||
public final static String TAG_NAME = "cms_advertisement";
|
public final static String TAG_NAME = "cms_advertisement";
|
||||||
public final static String NAME = "{FREEMARKER.TAG.NAME." + TAG_NAME + "}";
|
public final static String NAME = "{FREEMARKER.TAG." + TAG_NAME + ".NAME}";
|
||||||
public final static String DESC = "{FREEMARKER.TAG.DESC." + TAG_NAME + "}";
|
public final static String DESC = "{FREEMARKER.TAG." + TAG_NAME + ".DESC}";
|
||||||
|
public final static String ATTR_USAGE_CODE = "{FREEMARKER.TAG." + TAG_NAME + ".code}";
|
||||||
|
public final static String ATTR_USAGE_TYPE = "{FREEMARKER.TAG." + TAG_NAME + ".type}";
|
||||||
|
public final static String ATTR_OPTION_TYPE_NONE = "{FREEMARKER.TAG." + TAG_NAME + ".type.None}";
|
||||||
|
public final static String ATTR_OPTION_TYPE_STAT = "{FREEMARKER.TAG." + TAG_NAME + ".type.Stat}";
|
||||||
|
|
||||||
final static String TagAttr_Code = "code";
|
final static String ATTR_CODE = "code";
|
||||||
final static String TagAttr_RedirectType = "type";
|
final static String ATTR_TYPE = "type";
|
||||||
|
|
||||||
private final IAdvertisementService advertisementService;
|
private final IAdvertisementService advertisementService;
|
||||||
|
|
||||||
@ -58,23 +62,23 @@ public class CmsAdvertisementTag extends AbstractListTag {
|
|||||||
@Override
|
@Override
|
||||||
public List<TagAttr> getTagAttrs() {
|
public List<TagAttr> getTagAttrs() {
|
||||||
List<TagAttr> tagAttrs = super.getTagAttrs();
|
List<TagAttr> tagAttrs = super.getTagAttrs();
|
||||||
tagAttrs.add(new TagAttr(TagAttr_Code, true, TagAttrDataType.STRING, "广告位编码"));
|
tagAttrs.add(new TagAttr(ATTR_CODE, true, TagAttrDataType.STRING, ATTR_USAGE_CODE));
|
||||||
tagAttrs.add(new TagAttr(TagAttr_RedirectType, false, TagAttrDataType.STRING, "广告跳转方式",
|
tagAttrs.add(new TagAttr(ATTR_TYPE, false, TagAttrDataType.STRING, ATTR_USAGE_TYPE,
|
||||||
RedirectType.toTagAttrOptions(), RedirectType.None.name()));
|
RedirectType.toTagAttrOptions(), RedirectType.None.name()));
|
||||||
return tagAttrs;
|
return tagAttrs;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TagPageData prepareData(Environment env, Map<String, String> attrs, boolean page, int size, int pageIndex) throws TemplateException {
|
public TagPageData prepareData(Environment env, Map<String, String> attrs, boolean page, int size, int pageIndex) throws TemplateException {
|
||||||
String code = MapUtils.getString(attrs, TagAttr_Code);
|
String code = MapUtils.getString(attrs, ATTR_CODE);
|
||||||
String redirectType = MapUtils.getString(attrs, TagAttr_RedirectType, RedirectType.None.name());
|
String redirectType = MapUtils.getString(attrs, ATTR_TYPE, RedirectType.None.name());
|
||||||
|
|
||||||
Long siteId = TemplateUtils.evalSiteId(env);
|
Long siteId = TemplateUtils.evalSiteId(env);
|
||||||
CmsPageWidget adSpace = this.pageWidgetService.getOne(new LambdaQueryWrapper<CmsPageWidget>()
|
CmsPageWidget adSpace = this.pageWidgetService.getOne(new LambdaQueryWrapper<CmsPageWidget>()
|
||||||
.eq(CmsPageWidget::getSiteId, siteId)
|
.eq(CmsPageWidget::getSiteId, siteId)
|
||||||
.eq(CmsPageWidget::getCode, code));
|
.eq(CmsPageWidget::getCode, code));
|
||||||
if (adSpace == null) {
|
if (adSpace == null) {
|
||||||
throw new TemplateException(StringUtils.messageFormat("<@{0}>AD place `{1}` not exists.", this.getTagName(), code), env) ;
|
throw new TemplateException(StringUtils.messageFormat("Advertising space `{0}` not exists.", code), env) ;
|
||||||
}
|
}
|
||||||
String condition = MapUtils.getString(attrs, TagAttr.AttrName_Condition);
|
String condition = MapUtils.getString(attrs, TagAttr.AttrName_Condition);
|
||||||
|
|
||||||
@ -83,9 +87,6 @@ public class CmsAdvertisementTag extends AbstractListTag {
|
|||||||
.eq(CmsAdvertisement::getState, EnableOrDisable.ENABLE);
|
.eq(CmsAdvertisement::getState, EnableOrDisable.ENABLE);
|
||||||
q.apply(StringUtils.isNotEmpty(condition), condition);
|
q.apply(StringUtils.isNotEmpty(condition), condition);
|
||||||
Page<CmsAdvertisement> pageResult = this.advertisementService.page(new Page<>(pageIndex, size, page), q);
|
Page<CmsAdvertisement> pageResult = this.advertisementService.page(new Page<>(pageIndex, size, page), q);
|
||||||
if (pageIndex > 1 & pageResult.getRecords().isEmpty()) {
|
|
||||||
throw new TemplateException(StringUtils.messageFormat("Page data empty: pageIndex = {0}", pageIndex), env) ;
|
|
||||||
}
|
|
||||||
TemplateContext context = FreeMarkerUtils.getTemplateContext(env);
|
TemplateContext context = FreeMarkerUtils.getTemplateContext(env);
|
||||||
List<AdvertisementVO> list = pageResult.getRecords().stream().map(ad ->{
|
List<AdvertisementVO> list = pageResult.getRecords().stream().map(ad ->{
|
||||||
AdvertisementVO vo = new AdvertisementVO(ad);
|
AdvertisementVO vo = new AdvertisementVO(ad);
|
||||||
@ -99,6 +100,11 @@ public class CmsAdvertisementTag extends AbstractListTag {
|
|||||||
return TagPageData.of(list, pageResult.getTotal());
|
return TagPageData.of(list, pageResult.getTotal());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<AdvertisementVO> getDataClass() {
|
||||||
|
return AdvertisementVO.class;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getTagName() {
|
public String getTagName() {
|
||||||
return TAG_NAME;
|
return TAG_NAME;
|
||||||
@ -115,8 +121,8 @@ public class CmsAdvertisementTag extends AbstractListTag {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private enum RedirectType {
|
private enum RedirectType {
|
||||||
None("原始链接"),
|
None(ATTR_OPTION_TYPE_NONE),
|
||||||
Stat("统计链接");
|
Stat(ATTR_OPTION_TYPE_STAT);
|
||||||
|
|
||||||
private final String desc;
|
private final String desc;
|
||||||
|
|
||||||
|
|||||||
@ -5,8 +5,12 @@ CMS.CONTENCORE.PAGEWIDGET.ads=广告位
|
|||||||
ADVERTISEMENT.TYPE.image=图片
|
ADVERTISEMENT.TYPE.image=图片
|
||||||
|
|
||||||
# 模板freemarker
|
# 模板freemarker
|
||||||
FREEMARKER.TAG.NAME.cms_advertisement=广告列表标签
|
FREEMARKER.TAG.cms_advertisement.NAME=广告列表标签
|
||||||
FREEMARKER.TAG.DESC.cms_advertisement=获取广告数据列表,内嵌<#list DataList as ad>${ad.name}</#list>遍历数据
|
FREEMARKER.TAG.cms_advertisement.DESC=获取广告数据列表,内嵌`<#list DataList as ad>${ad.name}</#list>`遍历数据
|
||||||
|
FREEMARKER.TAG.cms_advertisement.code=广告位编码
|
||||||
|
FREEMARKER.TAG.cms_advertisement.type=广告链接类型
|
||||||
|
FREEMARKER.TAG.cms_advertisement.type.None=原始链接
|
||||||
|
FREEMARKER.TAG.cms_advertisement.type.Stat=统计链接
|
||||||
|
|
||||||
# 统计菜单
|
# 统计菜单
|
||||||
STAT.MENU.CmsAdv=广告数据统计
|
STAT.MENU.CmsAdv=广告数据统计
|
||||||
@ -17,3 +21,5 @@ STAT.MENU.CmsAdViewLog=广告展现日志
|
|||||||
# 定时任务
|
# 定时任务
|
||||||
SCHEDULED_TASK.AdvertisementStatJob=广告统计任务
|
SCHEDULED_TASK.AdvertisementStatJob=广告统计任务
|
||||||
SCHEDULED_TASK.AdvertisementPublishJob=广告定时发布下线任务
|
SCHEDULED_TASK.AdvertisementPublishJob=广告定时发布下线任务
|
||||||
|
|
||||||
|
MONITORED.CACHE.AD=广告
|
||||||
@ -5,8 +5,12 @@ CMS.CONTENCORE.PAGEWIDGET.ads=AD
|
|||||||
ADVERTISEMENT.TYPE.image=Image
|
ADVERTISEMENT.TYPE.image=Image
|
||||||
|
|
||||||
# 模板freemarker
|
# 模板freemarker
|
||||||
FREEMARKER.TAG.NAME.cms_advertisement=Advertisement list tag
|
FREEMARKER.TAG.cms_advertisement.NAME=Advertisement list tag
|
||||||
FREEMARKER.TAG.DESC.cms_advertisement=Fetch advertising data list, use <#list> in tag like "<#list DataList as ad>${ad.name}</#list>" to walk through the list of ad.
|
FREEMARKER.TAG.cms_advertisement.DESC=Fetch advertising data list, use `<#list>` in tag like `<#list DataList as ad>${ad.name}</#list>` to walk through the list of ad.
|
||||||
|
FREEMARKER.TAG.cms_advertisement.code=Advertisement code
|
||||||
|
FREEMARKER.TAG.cms_advertisement.type=Redirect type
|
||||||
|
FREEMARKER.TAG.cms_advertisement.type.None=Source link
|
||||||
|
FREEMARKER.TAG.cms_advertisement.type.Stat=Statistics link
|
||||||
|
|
||||||
# 统计菜单
|
# 统计菜单
|
||||||
STAT.MENU.CmsAdv=Advertising Statistics
|
STAT.MENU.CmsAdv=Advertising Statistics
|
||||||
@ -17,3 +21,5 @@ STAT.MENU.CmsAdViewLog=View Logs
|
|||||||
# 定时任务
|
# 定时任务
|
||||||
SCHEDULED_TASK.AdvertisementStatJob=AD Statistics Task
|
SCHEDULED_TASK.AdvertisementStatJob=AD Statistics Task
|
||||||
SCHEDULED_TASK.AdvertisementPublishJob=AD Publish/Offline Task
|
SCHEDULED_TASK.AdvertisementPublishJob=AD Publish/Offline Task
|
||||||
|
|
||||||
|
MONITORED.CACHE.AD=Advertisement
|
||||||
@ -5,8 +5,12 @@ CMS.CONTENCORE.PAGEWIDGET.ads=廣告位
|
|||||||
ADVERTISEMENT.TYPE.image=圖片
|
ADVERTISEMENT.TYPE.image=圖片
|
||||||
|
|
||||||
# 模板freemarker
|
# 模板freemarker
|
||||||
FREEMARKER.TAG.NAME.cms_advertisement=廣告列表標籤
|
FREEMARKER.TAG.cms_advertisement.NAME=廣告列表標籤
|
||||||
FREEMARKER.TAG.DESC.cms_advertisement=獲取廣告數據列表,內嵌<#list DataList as ad>${ad.name}</#list>遍曆數據
|
FREEMARKER.TAG.cms_advertisement.DESC=獲取廣告數據列表,內嵌`<#list DataList as ad>${ad.name}</#list>`遍曆數據
|
||||||
|
FREEMARKER.TAG.cms_advertisement.code=廣告位編碼
|
||||||
|
FREEMARKER.TAG.cms_advertisement.type=廣告鏈接類型
|
||||||
|
FREEMARKER.TAG.cms_advertisement.type.None=原始鏈接
|
||||||
|
FREEMARKER.TAG.cms_advertisement.type.Stat=統計鏈接
|
||||||
|
|
||||||
# 統計菜單
|
# 統計菜單
|
||||||
STAT.MENU.CmsAdv=廣告數據統計
|
STAT.MENU.CmsAdv=廣告數據統計
|
||||||
@ -17,3 +21,5 @@ STAT.MENU.CmsAdViewLog=廣告展現日誌
|
|||||||
# 定時任務
|
# 定時任務
|
||||||
SCHEDULED_TASK.AdvertisementStatJob=廣告統計任務
|
SCHEDULED_TASK.AdvertisementStatJob=廣告統計任務
|
||||||
SCHEDULED_TASK.AdvertisementPublishJob=廣告定時發布下線任務
|
SCHEDULED_TASK.AdvertisementPublishJob=廣告定時發布下線任務
|
||||||
|
|
||||||
|
MONITORED.CACHE.AD=廣告
|
||||||
|
|||||||
@ -7,7 +7,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>com.chestnut</groupId>
|
<groupId>com.chestnut</groupId>
|
||||||
<artifactId>chestnut-cms</artifactId>
|
<artifactId>chestnut-cms</artifactId>
|
||||||
<version>1.5.0</version>
|
<version>1.5.1</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>chestnut-cms-article</artifactId>
|
<artifactId>chestnut-cms-article</artifactId>
|
||||||
|
|||||||
@ -23,7 +23,6 @@ import com.chestnut.common.utils.HtmlUtils;
|
|||||||
import com.chestnut.common.utils.SpringUtils;
|
import com.chestnut.common.utils.SpringUtils;
|
||||||
import com.chestnut.common.utils.StringUtils;
|
import com.chestnut.common.utils.StringUtils;
|
||||||
import com.chestnut.contentcore.core.AbstractContent;
|
import com.chestnut.contentcore.core.AbstractContent;
|
||||||
import com.chestnut.contentcore.domain.CmsCatalog;
|
|
||||||
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.IResourceService;
|
import com.chestnut.contentcore.service.IResourceService;
|
||||||
@ -31,6 +30,7 @@ import com.chestnut.contentcore.util.ResourceUtils;
|
|||||||
import com.chestnut.system.fixed.dict.YesOrNo;
|
import com.chestnut.system.fixed.dict.YesOrNo;
|
||||||
import org.springframework.beans.BeanUtils;
|
import org.springframework.beans.BeanUtils;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
|
|
||||||
@ -41,11 +41,9 @@ public class ArticleContent extends AbstractContent<CmsArticleDetail> {
|
|||||||
private IResourceService resourceService;
|
private IResourceService resourceService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Long add() {
|
protected void add0() {
|
||||||
super.add();
|
|
||||||
if (!this.hasExtendEntity()) {
|
if (!this.hasExtendEntity()) {
|
||||||
this.getContentService().dao().save(this.getContentEntity());
|
return;
|
||||||
return this.getContentEntity().getContentId();
|
|
||||||
}
|
}
|
||||||
CmsArticleDetail articleDetail = this.getExtendEntity();
|
CmsArticleDetail articleDetail = this.getExtendEntity();
|
||||||
articleDetail.setContentId(this.getContentEntity().getContentId());
|
articleDetail.setContentId(this.getContentEntity().getContentId());
|
||||||
@ -60,23 +58,22 @@ public class ArticleContent extends AbstractContent<CmsArticleDetail> {
|
|||||||
}
|
}
|
||||||
articleDetail.setContentHtml(contentHtml);
|
articleDetail.setContentHtml(contentHtml);
|
||||||
// 正文首图作为logo
|
// 正文首图作为logo
|
||||||
if (StringUtils.isEmpty(this.getContentEntity().getLogo())
|
if (StringUtils.isEmpty(this.getContentEntity().getImages())
|
||||||
&& AutoArticleLogo.getValue(this.getSite().getConfigProps())) {
|
&& AutoArticleLogo.getValue(this.getSite().getConfigProps())) {
|
||||||
this.getContentEntity().setLogo(this.getFirstImage(articleDetail.getContentHtml()));
|
String firstImage = this.getFirstImage(articleDetail.getContentHtml());
|
||||||
|
if (Objects.nonNull(firstImage)) {
|
||||||
|
this.getContentEntity().setImages(List.of(firstImage));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
this.getContentService().dao().save(this.getContentEntity());
|
|
||||||
this.getArticleService().dao().save(articleDetail);
|
this.getArticleService().dao().save(articleDetail);
|
||||||
return this.getContentEntity().getContentId();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Long save() {
|
protected void save0() {
|
||||||
super.save();
|
|
||||||
// 非映射内容或标题内容修改文章详情
|
// 非映射内容或标题内容修改文章详情
|
||||||
if (!this.hasExtendEntity()) {
|
if (!this.hasExtendEntity()) {
|
||||||
this.getContentService().dao().updateById(this.getContentEntity());
|
|
||||||
this.getArticleService().dao().removeById(this.getContentEntity().getContentId());
|
this.getArticleService().dao().removeById(this.getContentEntity().getContentId());
|
||||||
return this.getContentEntity().getContentId();
|
return;
|
||||||
}
|
}
|
||||||
CmsArticleDetail articleDetail = this.getExtendEntity();
|
CmsArticleDetail articleDetail = this.getExtendEntity();
|
||||||
// 处理内部链接
|
// 处理内部链接
|
||||||
@ -89,13 +86,14 @@ public class ArticleContent extends AbstractContent<CmsArticleDetail> {
|
|||||||
}
|
}
|
||||||
articleDetail.setContentHtml(contentHtml);
|
articleDetail.setContentHtml(contentHtml);
|
||||||
// 正文首图作为logo
|
// 正文首图作为logo
|
||||||
if (StringUtils.isEmpty(this.getContentEntity().getLogo())
|
if (StringUtils.isEmpty(this.getContentEntity().getImages())
|
||||||
&& AutoArticleLogo.getValue(this.getSite().getConfigProps())) {
|
&& AutoArticleLogo.getValue(this.getSite().getConfigProps())) {
|
||||||
this.getContentEntity().setLogo(this.getFirstImage(articleDetail.getContentHtml()));
|
String firstImage = this.getFirstImage(articleDetail.getContentHtml());
|
||||||
|
if (Objects.nonNull(firstImage)) {
|
||||||
|
this.getContentEntity().setImages(List.of(firstImage));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
this.getContentService().dao().updateById(this.getContentEntity());
|
|
||||||
this.getArticleService().dao().saveOrUpdate(articleDetail);
|
this.getArticleService().dao().saveOrUpdate(articleDetail);
|
||||||
return this.getContentEntity().getContentId();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -116,8 +114,7 @@ public class ArticleContent extends AbstractContent<CmsArticleDetail> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void delete() {
|
protected void delete0() {
|
||||||
super.delete();
|
|
||||||
if (this.hasExtendEntity()) {
|
if (this.hasExtendEntity()) {
|
||||||
this.getArticleService().dao()
|
this.getArticleService().dao()
|
||||||
.deleteByIdAndBackup(this.getExtendEntity(), this.getOperatorUName());
|
.deleteByIdAndBackup(this.getExtendEntity(), this.getOperatorUName());
|
||||||
@ -125,16 +122,13 @@ public class ArticleContent extends AbstractContent<CmsArticleDetail> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CmsContent copyTo(CmsCatalog toCatalog, Integer copyType) {
|
public void copyTo0(CmsContent newContent, Integer copyType) {
|
||||||
CmsContent copyContent = super.copyTo(toCatalog, copyType);
|
|
||||||
if (this.hasExtendEntity() && ContentCopyType.isIndependency(copyType)) {
|
if (this.hasExtendEntity() && ContentCopyType.isIndependency(copyType)) {
|
||||||
Long newContentId = (Long) this.getParams().get("NewContentId");
|
|
||||||
CmsArticleDetail newArticleDetail = new CmsArticleDetail();
|
CmsArticleDetail newArticleDetail = new CmsArticleDetail();
|
||||||
BeanUtils.copyProperties(this.getExtendEntity(), newArticleDetail, "contentId");
|
BeanUtils.copyProperties(this.getExtendEntity(), newArticleDetail, "contentId");
|
||||||
newArticleDetail.setContentId(newContentId);
|
newArticleDetail.setContentId(newContent.getContentId());
|
||||||
this.getArticleService().dao().save(newArticleDetail);
|
this.getArticleService().dao().save(newArticleDetail);
|
||||||
}
|
}
|
||||||
return copyContent;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@ -35,23 +35,19 @@ import com.chestnut.contentcore.domain.*;
|
|||||||
import com.chestnut.contentcore.domain.dto.PublishPipeProp;
|
import com.chestnut.contentcore.domain.dto.PublishPipeProp;
|
||||||
import com.chestnut.contentcore.domain.vo.ContentVO;
|
import com.chestnut.contentcore.domain.vo.ContentVO;
|
||||||
import com.chestnut.contentcore.enums.ContentCopyType;
|
import com.chestnut.contentcore.enums.ContentCopyType;
|
||||||
import com.chestnut.contentcore.enums.ContentOpType;
|
import com.chestnut.contentcore.fixed.dict.ContentOpType;
|
||||||
import com.chestnut.contentcore.fixed.dict.ContentAttribute;
|
|
||||||
import com.chestnut.contentcore.service.ICatalogService;
|
import com.chestnut.contentcore.service.ICatalogService;
|
||||||
import com.chestnut.contentcore.service.IContentService;
|
import com.chestnut.contentcore.service.IContentService;
|
||||||
import com.chestnut.contentcore.service.IPublishPipeService;
|
import com.chestnut.contentcore.service.IPublishPipeService;
|
||||||
import com.chestnut.contentcore.service.ISiteService;
|
import com.chestnut.contentcore.service.ISiteService;
|
||||||
import com.chestnut.contentcore.util.InternalUrlUtils;
|
|
||||||
import com.chestnut.system.fixed.dict.YesOrNo;
|
import com.chestnut.system.fixed.dict.YesOrNo;
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.beans.BeanUtils;
|
import org.springframework.beans.BeanUtils;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.InputStream;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Optional;
|
||||||
|
|
||||||
@Component(IContentType.BEAN_NAME_PREFIX + ArticleContentType.ID)
|
@Component(IContentType.BEAN_NAME_PREFIX + ArticleContentType.ID)
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
@ -101,29 +97,22 @@ public class ArticleContentType implements IContentType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IContent<?> readRequest(HttpServletRequest request) throws IOException {
|
public IContent<?> readFrom(InputStream is) {
|
||||||
ArticleDTO dto = JacksonUtils.from(request.getInputStream(), ArticleDTO.class);
|
ArticleDTO dto = JacksonUtils.from(is, ArticleDTO.class);
|
||||||
|
return readFrom0(dto);
|
||||||
CmsContent contentEntity;
|
|
||||||
if (dto.getOpType() == ContentOpType.UPDATE) {
|
|
||||||
contentEntity = this.contentService.dao().getById(dto.getContentId());
|
|
||||||
Assert.notNull(contentEntity,
|
|
||||||
() -> CommonErrorCode.DATA_NOT_FOUND_BY_ID.exception("contentId", dto.getContentId()));
|
|
||||||
} else {
|
|
||||||
contentEntity = new CmsContent();
|
|
||||||
}
|
}
|
||||||
BeanUtils.copyProperties(dto, contentEntity);
|
|
||||||
CmsCatalog catalog = this.catalogService.getCatalog(dto.getCatalogId());
|
|
||||||
contentEntity.setSiteId(catalog.getSiteId());
|
|
||||||
contentEntity.setAttributes(ContentAttribute.convertInt(dto.getAttributes()));
|
|
||||||
// 发布通道配置
|
|
||||||
Map<String, Map<String, Object>> publishPipProps = new HashMap<>();
|
|
||||||
dto.getPublishPipeProps().forEach(prop -> {
|
|
||||||
publishPipProps.put(prop.getPipeCode(), prop.getProps());
|
|
||||||
});
|
|
||||||
contentEntity.setPublishPipeProps(publishPipProps);
|
|
||||||
|
|
||||||
|
private ArticleContent readFrom0(ArticleDTO dto) {
|
||||||
|
// 内容基础信息
|
||||||
|
CmsContent contentEntity = dto.convertToContentEntity(this.catalogService, this.contentService);
|
||||||
|
// 文章扩展信息
|
||||||
CmsArticleDetail extendEntity = new CmsArticleDetail();
|
CmsArticleDetail extendEntity = new CmsArticleDetail();
|
||||||
|
if (ContentOpType.UPDATE.equals(dto.getOpType())) {
|
||||||
|
Optional<CmsArticleDetail> opt = this.articleService.dao().getOptById(contentEntity.getContentId());
|
||||||
|
if (opt.isPresent()) {
|
||||||
|
extendEntity = opt.get();
|
||||||
|
}
|
||||||
|
}
|
||||||
BeanUtils.copyProperties(dto, extendEntity);
|
BeanUtils.copyProperties(dto, extendEntity);
|
||||||
|
|
||||||
ArticleContent content = new ArticleContent();
|
ArticleContent content = new ArticleContent();
|
||||||
@ -148,9 +137,6 @@ public class ArticleContentType implements IContentType {
|
|||||||
|
|
||||||
CmsArticleDetail extendEntity = this.articleService.dao().getById(contentId);
|
CmsArticleDetail extendEntity = this.articleService.dao().getById(contentId);
|
||||||
vo = ArticleVO.newInstance(contentEntity, extendEntity);
|
vo = ArticleVO.newInstance(contentEntity, extendEntity);
|
||||||
if (StringUtils.isNotEmpty(vo.getLogo())) {
|
|
||||||
vo.setLogoSrc(InternalUrlUtils.getActualPreviewUrl(vo.getLogo()));
|
|
||||||
}
|
|
||||||
// 发布通道模板数据
|
// 发布通道模板数据
|
||||||
List<PublishPipeProp> publishPipeProps = this.publishPipeService.getPublishPipeProps(catalog.getSiteId(),
|
List<PublishPipeProp> publishPipeProps = this.publishPipeService.getPublishPipeProps(catalog.getSiteId(),
|
||||||
PublishPipePropUseType.Content, contentEntity.getPublishPipeProps());
|
PublishPipePropUseType.Content, contentEntity.getPublishPipeProps());
|
||||||
|
|||||||
@ -103,7 +103,7 @@ public class ArticleCoreDataHandler implements ICoreDataHandler {
|
|||||||
data.setContentHtml(html.toString());
|
data.setContentHtml(html.toString());
|
||||||
articleService.dao().save(data);
|
articleService.dao().save(data);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
AsyncTaskManager.addErrMessage("导入文章数据失败:" + oldContentId);
|
AsyncTaskManager.addErrMessage("导入文章数据`" + oldContentId + "`失败:" + e.getMessage());
|
||||||
log.error("Import article detail failed: {}", oldContentId, e);
|
log.error("Import article detail failed: {}", oldContentId, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -13,32 +13,37 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package com.chestnut.common.storage;
|
package com.chestnut.article;
|
||||||
|
|
||||||
import java.util.List;
|
/**
|
||||||
|
* 文正正文文档格式
|
||||||
|
*
|
||||||
|
* @author 兮玥
|
||||||
|
* @email 190785909@qq.com
|
||||||
|
*/
|
||||||
|
public interface IArticleBodyFormat {
|
||||||
|
|
||||||
public class StorageListResult<T> {
|
String BEAN_PREFIX = "ArticleBodyFormat_";
|
||||||
|
|
||||||
private List<T> objects;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 列举文件使用的continuationToken
|
* ID
|
||||||
*/
|
*/
|
||||||
private String nextContinuationToken ;
|
String getId();
|
||||||
|
|
||||||
public String getNextContinuationToken() {
|
/**
|
||||||
return nextContinuationToken;
|
* 名称
|
||||||
|
*/
|
||||||
|
String getName();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编辑器内容初始化处理
|
||||||
|
*/
|
||||||
|
default String initEditor(String contentHtml) {
|
||||||
|
return contentHtml;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setNextContinuationToken(String nextContinuationToken) {
|
/**
|
||||||
this.nextContinuationToken = nextContinuationToken;
|
* 文章正文内容发布预览处理
|
||||||
}
|
*/
|
||||||
|
String deal(String contentHtml, String publishPipeCode, boolean isPreview);
|
||||||
public List<T> getObjects() {
|
|
||||||
return objects;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setObjects(List<T> objects) {
|
|
||||||
this.objects = objects;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@ -16,8 +16,10 @@
|
|||||||
package com.chestnut.article.controller;
|
package com.chestnut.article.controller;
|
||||||
|
|
||||||
|
|
||||||
|
import com.chestnut.article.IArticleBodyFormat;
|
||||||
import com.chestnut.article.PublishPipeProp_UEditorCss;
|
import com.chestnut.article.PublishPipeProp_UEditorCss;
|
||||||
import com.chestnut.common.domain.R;
|
import com.chestnut.common.domain.R;
|
||||||
|
import com.chestnut.common.i18n.I18nUtils;
|
||||||
import com.chestnut.common.security.anno.Priv;
|
import com.chestnut.common.security.anno.Priv;
|
||||||
import com.chestnut.common.security.web.BaseRestController;
|
import com.chestnut.common.security.web.BaseRestController;
|
||||||
import com.chestnut.common.utils.StringUtils;
|
import com.chestnut.common.utils.StringUtils;
|
||||||
@ -28,13 +30,16 @@ import com.chestnut.contentcore.service.ICatalogService;
|
|||||||
import com.chestnut.contentcore.service.IPublishPipeService;
|
import com.chestnut.contentcore.service.IPublishPipeService;
|
||||||
import com.chestnut.contentcore.service.ISiteService;
|
import com.chestnut.contentcore.service.ISiteService;
|
||||||
import com.chestnut.system.security.AdminUserType;
|
import com.chestnut.system.security.AdminUserType;
|
||||||
|
import lombok.Getter;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.Setter;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -57,6 +62,8 @@ public class ArticleController extends BaseRestController {
|
|||||||
|
|
||||||
private final IPublishPipeService publishPipeService;
|
private final IPublishPipeService publishPipeService;
|
||||||
|
|
||||||
|
private final List<IArticleBodyFormat> articleBodyFormatList;
|
||||||
|
|
||||||
@GetMapping("/ueditor_css")
|
@GetMapping("/ueditor_css")
|
||||||
public R<?> getUEditorCss(@RequestParam Long catalogId) {
|
public R<?> getUEditorCss(@RequestParam Long catalogId) {
|
||||||
CmsCatalog catalog = catalogService.getCatalog(catalogId);
|
CmsCatalog catalog = catalogService.getCatalog(catalogId);
|
||||||
@ -73,5 +80,24 @@ public class ArticleController extends BaseRestController {
|
|||||||
});
|
});
|
||||||
return R.ok(data);
|
return R.ok(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping("/formats")
|
||||||
|
public R<?> getArticleBodyFormats() {
|
||||||
|
List<ArticleBodyFormat> list = this.articleBodyFormatList.stream().map(item -> {
|
||||||
|
ArticleBodyFormat format = new ArticleBodyFormat();
|
||||||
|
format.setId(item.getId());
|
||||||
|
format.setName(I18nUtils.get(item.getName()));
|
||||||
|
return format;
|
||||||
|
}).toList();
|
||||||
|
I18nUtils.replaceI18nFields(list);
|
||||||
|
return R.ok(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
static class ArticleBodyFormat {
|
||||||
|
private String id;
|
||||||
|
private String name;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -113,27 +113,24 @@ public class ArticleApiController extends BaseRestController {
|
|||||||
return R.ok(List.of());
|
return R.ok(List.of());
|
||||||
}
|
}
|
||||||
List<Long> contentIds = pageResult.getRecords().stream().map(CmsContent::getContentId).toList();
|
List<Long> contentIds = pageResult.getRecords().stream().map(CmsContent::getContentId).toList();
|
||||||
Map<Long, CmsArticleDetail> articleDetails = this.articleService.dao().listByIds(contentIds)
|
Map<Long, CmsArticleDetail> articleDetails = new HashMap<>();
|
||||||
.stream().collect(Collectors.toMap(CmsArticleDetail::getContentId, c -> c));
|
if (text) {
|
||||||
|
articleDetails.putAll(this.articleService.dao().listByIds(contentIds)
|
||||||
|
.stream().collect(Collectors.toMap(CmsArticleDetail::getContentId, c -> c)));
|
||||||
|
}
|
||||||
|
|
||||||
Map<Long, CmsCatalog> loadedCatalogs = new HashMap<>();
|
|
||||||
List<ArticleApiVO> list = new ArrayList<>();
|
List<ArticleApiVO> list = new ArrayList<>();
|
||||||
pageResult.getRecords().forEach(c -> {
|
pageResult.getRecords().forEach(c -> {
|
||||||
ArticleApiVO dto = ArticleApiVO.newInstance(c);
|
ArticleApiVO vo = ArticleApiVO.newInstance(c, null);
|
||||||
CmsCatalog catalog = loadedCatalogs.get(c.getCatalogId());
|
CmsCatalog catalog = this.catalogService.getCatalog(c.getCatalogId());
|
||||||
if (Objects.isNull(catalog)) {
|
vo.setCatalogName(catalog.getName());
|
||||||
catalog = this.catalogService.getCatalog(c.getCatalogId());
|
vo.setCatalogLink(catalogService.getCatalogLink(catalog, 1, publishPipeCode, preview));
|
||||||
loadedCatalogs.put(catalog.getCatalogId(), catalog);
|
vo.setLink(this.contentService.getContentLink(c, 1, publishPipeCode, preview));
|
||||||
|
vo.setLogoSrc(InternalUrlUtils.getActualUrl(c.getLogo(), publishPipeCode, preview));
|
||||||
|
if (text && articleDetails.containsKey(c.getContentId())) {
|
||||||
|
vo.setContentHtml(articleDetails.get(c.getContentId()).getContentHtml());
|
||||||
}
|
}
|
||||||
dto.setCatalogName(catalog.getName());
|
list.add(vo);
|
||||||
dto.setCatalogLink(catalogService.getCatalogLink(catalog, 1, publishPipeCode, preview));
|
|
||||||
dto.setLink(this.contentService.getContentLink(c, 1, publishPipeCode, preview));
|
|
||||||
dto.setLogoSrc(InternalUrlUtils.getActualUrl(c.getLogo(), publishPipeCode, preview));
|
|
||||||
CmsArticleDetail articleDetail = articleDetails.get(c.getContentId());
|
|
||||||
if (Objects.nonNull(articleDetail)) {
|
|
||||||
dto.setContentHtml(articleDetail.getContentHtml());
|
|
||||||
}
|
|
||||||
list.add(dto);
|
|
||||||
});
|
});
|
||||||
return R.ok(list);
|
return R.ok(list);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -47,11 +47,6 @@ public class CmsArticleDetail implements IBackupable<BCmsArticleDetail> {
|
|||||||
*/
|
*/
|
||||||
private Long siteId;
|
private Long siteId;
|
||||||
|
|
||||||
/**
|
|
||||||
* 正文详情(json)
|
|
||||||
*/
|
|
||||||
private String contentJson;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 正文详情(html)
|
* 正文详情(html)
|
||||||
*/
|
*/
|
||||||
@ -67,6 +62,11 @@ public class CmsArticleDetail implements IBackupable<BCmsArticleDetail> {
|
|||||||
*/
|
*/
|
||||||
private String downloadRemoteImage;
|
private String downloadRemoteImage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 正文格式(图文混排,MARKDOWN)
|
||||||
|
*/
|
||||||
|
private String format;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BCmsArticleDetail toBackupEntity() {
|
public BCmsArticleDetail toBackupEntity() {
|
||||||
BCmsArticleDetail backupEntity = new BCmsArticleDetail();
|
BCmsArticleDetail backupEntity = new BCmsArticleDetail();
|
||||||
|
|||||||
@ -15,17 +15,12 @@
|
|||||||
*/
|
*/
|
||||||
package com.chestnut.article.domain.dto;
|
package com.chestnut.article.domain.dto;
|
||||||
|
|
||||||
import org.springframework.beans.BeanUtils;
|
|
||||||
|
|
||||||
import com.chestnut.article.domain.CmsArticleDetail;
|
import com.chestnut.article.domain.CmsArticleDetail;
|
||||||
import com.chestnut.common.utils.StringUtils;
|
|
||||||
import com.chestnut.contentcore.domain.CmsContent;
|
import com.chestnut.contentcore.domain.CmsContent;
|
||||||
import com.chestnut.contentcore.domain.dto.ContentDTO;
|
import com.chestnut.contentcore.domain.dto.ContentDTO;
|
||||||
import com.chestnut.contentcore.fixed.dict.ContentAttribute;
|
|
||||||
import com.chestnut.contentcore.util.InternalUrlUtils;
|
|
||||||
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
import org.springframework.beans.BeanUtils;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
@ -46,13 +41,14 @@ public class ArticleDTO extends ContentDTO {
|
|||||||
*/
|
*/
|
||||||
private String pageTitles;
|
private String pageTitles;
|
||||||
|
|
||||||
public static ArticleDTO newInstance(CmsContent content, CmsArticleDetail articleDetail) {
|
/**
|
||||||
|
* 文档格式
|
||||||
|
*/
|
||||||
|
private String format;
|
||||||
|
|
||||||
|
public static ArticleDTO newInstance(CmsContent content, CmsArticleDetail articleDetail, boolean preview) {
|
||||||
ArticleDTO dto = new ArticleDTO();
|
ArticleDTO dto = new ArticleDTO();
|
||||||
BeanUtils.copyProperties(content, dto);
|
dto.initByContent(content, preview);
|
||||||
dto.setAttributes(ContentAttribute.convertStr(content.getAttributes()));
|
|
||||||
if (StringUtils.isNotEmpty(dto.getLogo())) {
|
|
||||||
dto.setLogoSrc(InternalUrlUtils.getActualPreviewUrl(dto.getLogo()));
|
|
||||||
}
|
|
||||||
BeanUtils.copyProperties(articleDetail, dto);
|
BeanUtils.copyProperties(articleDetail, dto);
|
||||||
return dto;
|
return dto;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,11 +15,14 @@
|
|||||||
*/
|
*/
|
||||||
package com.chestnut.article.domain.vo;
|
package com.chestnut.article.domain.vo;
|
||||||
|
|
||||||
|
import com.chestnut.article.domain.CmsArticleDetail;
|
||||||
import com.chestnut.contentcore.domain.CmsContent;
|
import com.chestnut.contentcore.domain.CmsContent;
|
||||||
import com.chestnut.contentcore.domain.vo.ContentApiVO;
|
import com.chestnut.contentcore.domain.vo.ContentApiVO;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <TODO description class purpose>
|
* <TODO description class purpose>
|
||||||
*
|
*
|
||||||
@ -32,9 +35,12 @@ public class ArticleApiVO extends ContentApiVO {
|
|||||||
|
|
||||||
private String contentHtml;
|
private String contentHtml;
|
||||||
|
|
||||||
public static ArticleApiVO newInstance(CmsContent cmsContent) {
|
public static ArticleApiVO newInstance(CmsContent cmsContent, CmsArticleDetail articleDetail) {
|
||||||
ArticleApiVO vo = new ArticleApiVO();
|
ArticleApiVO vo = new ArticleApiVO();
|
||||||
vo.copyProperties(cmsContent);
|
vo.initByContent(cmsContent, false);
|
||||||
|
if (Objects.nonNull(articleDetail)) {
|
||||||
|
vo.setContentHtml(articleDetail.getContentHtml());
|
||||||
|
}
|
||||||
return vo;
|
return vo;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,20 +15,14 @@
|
|||||||
*/
|
*/
|
||||||
package com.chestnut.article.domain.vo;
|
package com.chestnut.article.domain.vo;
|
||||||
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
import org.springframework.beans.BeanUtils;
|
|
||||||
|
|
||||||
import com.chestnut.article.domain.CmsArticleDetail;
|
import com.chestnut.article.domain.CmsArticleDetail;
|
||||||
import com.chestnut.common.utils.StringUtils;
|
|
||||||
import com.chestnut.contentcore.domain.CmsContent;
|
import com.chestnut.contentcore.domain.CmsContent;
|
||||||
import com.chestnut.contentcore.domain.vo.ContentVO;
|
import com.chestnut.contentcore.domain.vo.ContentVO;
|
||||||
import com.chestnut.contentcore.fixed.dict.ContentAttribute;
|
|
||||||
import com.chestnut.contentcore.util.InternalUrlUtils;
|
|
||||||
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
public class ArticleVO extends ContentVO {
|
public class ArticleVO extends ContentVO {
|
||||||
@ -48,16 +42,20 @@ public class ArticleVO extends ContentVO {
|
|||||||
*/
|
*/
|
||||||
private String pageTitles;
|
private String pageTitles;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文档格式
|
||||||
|
*/
|
||||||
|
private String format;
|
||||||
|
|
||||||
public static ArticleVO newInstance(CmsContent content, CmsArticleDetail articleDetail) {
|
public static ArticleVO newInstance(CmsContent content, CmsArticleDetail articleDetail) {
|
||||||
ArticleVO dto = new ArticleVO();
|
ArticleVO vo = new ArticleVO();
|
||||||
BeanUtils.copyProperties(content, dto);
|
vo.initByContent(content, true);
|
||||||
dto.setAttributes(ContentAttribute.convertStr(content.getAttributes()));
|
|
||||||
if (StringUtils.isNotEmpty(dto.getLogo())) {
|
|
||||||
dto.setLogoSrc(InternalUrlUtils.getActualPreviewUrl(dto.getLogo()));
|
|
||||||
}
|
|
||||||
if (Objects.nonNull(articleDetail)) {
|
if (Objects.nonNull(articleDetail)) {
|
||||||
BeanUtils.copyProperties(articleDetail, dto);
|
vo.setContentHtml(articleDetail.getContentHtml());
|
||||||
|
vo.setDownloadRemoteImage(articleDetail.getDownloadRemoteImage());
|
||||||
|
vo.setPageTitles(articleDetail.getPageTitles());
|
||||||
|
vo.setFormat(articleDetail.getFormat());
|
||||||
}
|
}
|
||||||
return dto;
|
return vo;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2022-2024 兮玥(190785909@qq.com)
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.chestnut.article.format;
|
||||||
|
|
||||||
|
import com.chestnut.article.ArticleUtils;
|
||||||
|
import com.chestnut.article.IArticleBodyFormat;
|
||||||
|
import com.chestnut.contentcore.util.InternalUrlUtils;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文章正文文档格式:富文本
|
||||||
|
*
|
||||||
|
* @author 兮玥
|
||||||
|
* @email 190785909@qq.com
|
||||||
|
*/
|
||||||
|
@Component(IArticleBodyFormat.BEAN_PREFIX + ArticleBodyFormat_RichText.ID)
|
||||||
|
public class ArticleBodyFormat_RichText implements IArticleBodyFormat {
|
||||||
|
|
||||||
|
public static final String ID = "RichText";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getId() {
|
||||||
|
return ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "{ArticleBodyFormat.RichText}";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String initEditor(String contentHtml) {
|
||||||
|
return InternalUrlUtils.dealResourceInternalUrl(contentHtml);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String deal(String contentHtml, String publishPipeCode, boolean isPreview) {
|
||||||
|
// 处理内容扩展模板占位符
|
||||||
|
contentHtml = ArticleUtils.dealContentEx(contentHtml, publishPipeCode, isPreview);
|
||||||
|
// 处理正文内部链接
|
||||||
|
contentHtml = InternalUrlUtils.dealInternalUrl(contentHtml, publishPipeCode, isPreview);
|
||||||
|
return contentHtml;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -16,6 +16,7 @@
|
|||||||
package com.chestnut.article.listener;
|
package com.chestnut.article.listener;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import com.chestnut.article.IArticleBodyFormat;
|
||||||
import com.chestnut.article.domain.BCmsArticleDetail;
|
import com.chestnut.article.domain.BCmsArticleDetail;
|
||||||
import com.chestnut.article.domain.CmsArticleDetail;
|
import com.chestnut.article.domain.CmsArticleDetail;
|
||||||
import com.chestnut.article.domain.vo.ArticleVO;
|
import com.chestnut.article.domain.vo.ArticleVO;
|
||||||
@ -24,13 +25,13 @@ import com.chestnut.common.async.AsyncTaskManager;
|
|||||||
import com.chestnut.contentcore.domain.CmsSite;
|
import com.chestnut.contentcore.domain.CmsSite;
|
||||||
import com.chestnut.contentcore.listener.event.AfterContentEditorInitEvent;
|
import com.chestnut.contentcore.listener.event.AfterContentEditorInitEvent;
|
||||||
import com.chestnut.contentcore.listener.event.BeforeSiteDeleteEvent;
|
import com.chestnut.contentcore.listener.event.BeforeSiteDeleteEvent;
|
||||||
import com.chestnut.contentcore.util.InternalUrlUtils;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.context.event.EventListener;
|
import org.springframework.context.event.EventListener;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Component
|
@Component
|
||||||
@ -81,7 +82,12 @@ public class ArticleListener {
|
|||||||
@EventListener
|
@EventListener
|
||||||
public void afterContentEditorInit(AfterContentEditorInitEvent event) {
|
public void afterContentEditorInit(AfterContentEditorInitEvent event) {
|
||||||
if (event.getContentVO() instanceof ArticleVO vo) {
|
if (event.getContentVO() instanceof ArticleVO vo) {
|
||||||
vo.setContentHtml(InternalUrlUtils.dealResourceInternalUrl(vo.getContentHtml()));
|
IArticleBodyFormat articleBodyFormat = articleService.getArticleBodyFormat(vo.getFormat());
|
||||||
|
if (Objects.nonNull(articleBodyFormat)) {
|
||||||
|
vo.setContentHtml(articleBodyFormat.initEditor(vo.getContentHtml()));
|
||||||
|
} else {
|
||||||
|
log.warn("Unsupported article body format: " + vo.getFormat());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package com.chestnut.article.service;
|
package com.chestnut.article.service;
|
||||||
|
|
||||||
|
import com.chestnut.article.IArticleBodyFormat;
|
||||||
import com.chestnut.article.dao.CmsArticleDetailDAO;
|
import com.chestnut.article.dao.CmsArticleDetailDAO;
|
||||||
import com.chestnut.common.db.mybatisplus.HasDAO;
|
import com.chestnut.common.db.mybatisplus.HasDAO;
|
||||||
|
|
||||||
@ -25,4 +26,5 @@ import com.chestnut.common.db.mybatisplus.HasDAO;
|
|||||||
* @email 190785909@qq.com
|
* @email 190785909@qq.com
|
||||||
*/
|
*/
|
||||||
public interface IArticleService extends HasDAO<CmsArticleDetailDAO> {
|
public interface IArticleService extends HasDAO<CmsArticleDetailDAO> {
|
||||||
|
IArticleBodyFormat getArticleBodyFormat(String format);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,12 +15,15 @@
|
|||||||
*/
|
*/
|
||||||
package com.chestnut.article.service.impl;
|
package com.chestnut.article.service.impl;
|
||||||
|
|
||||||
|
import com.chestnut.article.IArticleBodyFormat;
|
||||||
import com.chestnut.article.dao.CmsArticleDetailDAO;
|
import com.chestnut.article.dao.CmsArticleDetailDAO;
|
||||||
import com.chestnut.article.service.IArticleService;
|
import com.chestnut.article.service.IArticleService;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Service
|
@Service
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
@ -28,8 +31,17 @@ public class ArticleServiceImpl implements IArticleService {
|
|||||||
|
|
||||||
private final CmsArticleDetailDAO dao;
|
private final CmsArticleDetailDAO dao;
|
||||||
|
|
||||||
|
|
||||||
|
private final Map<String, IArticleBodyFormat> articleBodyFormatMap;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CmsArticleDetailDAO dao() {
|
public CmsArticleDetailDAO dao() {
|
||||||
return this.dao;
|
return this.dao;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IArticleBodyFormat getArticleBodyFormat(String format) {
|
||||||
|
return articleBodyFormatMap.get(IArticleBodyFormat.BEAN_PREFIX + format);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,12 +15,14 @@
|
|||||||
*/
|
*/
|
||||||
package com.chestnut.article.template.func;
|
package com.chestnut.article.template.func;
|
||||||
|
|
||||||
import com.chestnut.article.ArticleUtils;
|
import com.chestnut.article.IArticleBodyFormat;
|
||||||
|
import com.chestnut.article.format.ArticleBodyFormat_RichText;
|
||||||
|
import com.chestnut.article.service.IArticleService;
|
||||||
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.func.AbstractFunc;
|
import com.chestnut.common.staticize.func.AbstractFunc;
|
||||||
|
import com.chestnut.common.utils.Assert;
|
||||||
import com.chestnut.common.utils.StringUtils;
|
import com.chestnut.common.utils.StringUtils;
|
||||||
import com.chestnut.contentcore.util.InternalUrlUtils;
|
|
||||||
import freemarker.core.Environment;
|
import freemarker.core.Environment;
|
||||||
import freemarker.template.SimpleScalar;
|
import freemarker.template.SimpleScalar;
|
||||||
import freemarker.template.TemplateModelException;
|
import freemarker.template.TemplateModelException;
|
||||||
@ -28,6 +30,7 @@ import lombok.RequiredArgsConstructor;
|
|||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Freemarker模板自定义函数:处理Html文本内容中的内部链接
|
* Freemarker模板自定义函数:处理Html文本内容中的内部链接
|
||||||
@ -38,7 +41,13 @@ public class dealArticleBodyFunction extends AbstractFunc {
|
|||||||
|
|
||||||
static final String FUNC_NAME = "dealArticleBody";
|
static final String FUNC_NAME = "dealArticleBody";
|
||||||
|
|
||||||
private static final String DESC = "{FREEMARKER.FUNC.DESC." + FUNC_NAME + "}";
|
private static final String DESC = "{FREEMARKER.FUNC." + FUNC_NAME + ".DESC}";
|
||||||
|
|
||||||
|
private static final String ARG1_NAME = "{FREEMARKER.FUNC." + FUNC_NAME + ".Arg1.Name}";
|
||||||
|
|
||||||
|
private static final String ARG2_NAME = "{FREEMARKER.FUNC." + FUNC_NAME + ".Arg2.Name}";
|
||||||
|
|
||||||
|
private final IArticleService articleService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getFuncName() {
|
public String getFuncName() {
|
||||||
@ -55,18 +64,33 @@ public class dealArticleBodyFunction extends AbstractFunc {
|
|||||||
if (args.length < 1) {
|
if (args.length < 1) {
|
||||||
return StringUtils.EMPTY;
|
return StringUtils.EMPTY;
|
||||||
}
|
}
|
||||||
|
String format;
|
||||||
|
if (args.length > 1) {
|
||||||
|
String _format = ((SimpleScalar) args[1]).getAsString();
|
||||||
|
if (StringUtils.isEmpty(_format)) {
|
||||||
|
_format = ArticleBodyFormat_RichText.ID;
|
||||||
|
}
|
||||||
|
format = _format;
|
||||||
|
} else {
|
||||||
|
format = ArticleBodyFormat_RichText.ID;
|
||||||
|
}
|
||||||
TemplateContext context = FreeMarkerUtils.getTemplateContext(Environment.getCurrentEnvironment());
|
TemplateContext context = FreeMarkerUtils.getTemplateContext(Environment.getCurrentEnvironment());
|
||||||
SimpleScalar simpleScalar = (SimpleScalar) args[0];
|
SimpleScalar simpleScalar = (SimpleScalar) args[0];
|
||||||
String contentHtml = simpleScalar.getAsString();
|
String contentHtml = simpleScalar.getAsString();
|
||||||
// 处理内容扩展模板占位符
|
IArticleBodyFormat articleBodyFormat = articleService.getArticleBodyFormat(format);
|
||||||
contentHtml = ArticleUtils.dealContentEx(contentHtml, context.getPublishPipeCode(), context.isPreview());
|
Assert.notNull(articleBodyFormat, () -> new TemplateModelException("Unsupported article body format: " + format));
|
||||||
// 处理正文内部链接
|
if (Objects.isNull(articleBodyFormat)) {
|
||||||
contentHtml = InternalUrlUtils.dealInternalUrl(contentHtml, context.getPublishPipeCode(), context.isPreview());
|
articleBodyFormat = articleService.getArticleBodyFormat(ArticleBodyFormat_RichText.ID);
|
||||||
|
}
|
||||||
|
contentHtml = articleBodyFormat.deal(contentHtml, context.getPublishPipeCode(), context.isPreview());
|
||||||
return contentHtml;
|
return contentHtml;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<FuncArg> getFuncArgs() {
|
public List<FuncArg> getFuncArgs() {
|
||||||
return List.of(new FuncArg("HTML文章正文内容", FuncArgType.String, true, null));
|
return List.of(
|
||||||
|
new FuncArg(ARG1_NAME, FuncArgType.String, true, null),
|
||||||
|
new FuncArg(ARG2_NAME, FuncArgType.String, false, null, ArticleBodyFormat_RichText.ID)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,10 +17,13 @@ package com.chestnut.article.template.tag;
|
|||||||
|
|
||||||
import com.chestnut.article.domain.CmsArticleDetail;
|
import com.chestnut.article.domain.CmsArticleDetail;
|
||||||
import com.chestnut.article.mapper.CmsArticleDetailMapper;
|
import com.chestnut.article.mapper.CmsArticleDetailMapper;
|
||||||
|
import com.chestnut.common.annotation.XComment;
|
||||||
import com.chestnut.common.staticize.FreeMarkerUtils;
|
import com.chestnut.common.staticize.FreeMarkerUtils;
|
||||||
import com.chestnut.common.staticize.StaticizeConstants;
|
import com.chestnut.common.staticize.StaticizeConstants;
|
||||||
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.exception.DuplicatePageFlagException;
|
||||||
|
import com.chestnut.common.staticize.exception.PageIndexOutOfBoundsException;
|
||||||
import com.chestnut.common.staticize.tag.AbstractTag;
|
import com.chestnut.common.staticize.tag.AbstractTag;
|
||||||
import com.chestnut.common.staticize.tag.TagAttr;
|
import com.chestnut.common.staticize.tag.TagAttr;
|
||||||
import com.chestnut.common.utils.StringUtils;
|
import com.chestnut.common.utils.StringUtils;
|
||||||
@ -30,35 +33,36 @@ import com.chestnut.contentcore.mapper.CmsContentMapper;
|
|||||||
import freemarker.core.Environment;
|
import freemarker.core.Environment;
|
||||||
import freemarker.template.TemplateException;
|
import freemarker.template.TemplateException;
|
||||||
import freemarker.template.TemplateModel;
|
import freemarker.template.TemplateModel;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.Setter;
|
||||||
import org.apache.commons.collections4.MapUtils;
|
import org.apache.commons.collections4.MapUtils;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
@Component
|
@Component
|
||||||
|
@RequiredArgsConstructor
|
||||||
public class CmsArticleTag extends AbstractTag {
|
public class CmsArticleTag extends AbstractTag {
|
||||||
|
|
||||||
public static final String TAG_NAME = "cms_article";
|
public static final String TAG_NAME = "cms_article";
|
||||||
public final static String NAME = "{FREEMARKER.TAG.NAME." + TAG_NAME + "}";
|
public final static String NAME = "{FREEMARKER.TAG." + TAG_NAME + ".NAME}";
|
||||||
public final static String DESC = "{FREEMARKER.TAG.DESC." + TAG_NAME + "}";
|
public final static String DESC = "{FREEMARKER.TAG." + TAG_NAME + ".DESC}";
|
||||||
|
public final static String ATTR_USAGE_CONTENT_ID = "{FREEMARKER.TAG." + TAG_NAME + ".contentId}";
|
||||||
|
public final static String ATTR_USAGE_PAGE = "{FREEMARKER.TAG." + TAG_NAME + ".page}";
|
||||||
|
|
||||||
public static final String TagAttr_ContentId = "contentId";
|
public static final String ATTR_CONTENT_ID = "contentId";
|
||||||
|
public static final String ATTR_PAGE = "page";
|
||||||
public static final String TagAttr_Page = "page";
|
|
||||||
|
|
||||||
public static final String TemplateVariable_ArticleContent = "ArticleContent";
|
public static final String TemplateVariable_ArticleContent = "ArticleContent";
|
||||||
|
|
||||||
// CKEditor5: <div class="page-break" style="page-break-after:always;"><span style="display:none;"> </span></div>
|
|
||||||
// private static final String PAGE_BREAK_SPLITER = "<div[^>]+class=['\"]page-break['\"].*?</div>";
|
// private static final String PAGE_BREAK_SPLITER = "<div[^>]+class=['\"]page-break['\"].*?</div>";
|
||||||
private static final String PAGE_BREAK_SPLITER = "__XY_UEDITOR_PAGE_BREAK__";
|
private static final String PAGE_BREAK_SPLITER = "__XY_UEDITOR_PAGE_BREAK__";
|
||||||
|
|
||||||
|
|
||||||
private final CmsContentMapper contentMapper;
|
private final CmsContentMapper contentMapper;
|
||||||
|
|
||||||
private final CmsArticleDetailMapper articleMapper;
|
private final CmsArticleDetailMapper articleMapper;
|
||||||
@ -66,16 +70,16 @@ public class CmsArticleTag extends AbstractTag {
|
|||||||
@Override
|
@Override
|
||||||
public List<TagAttr> getTagAttrs() {
|
public List<TagAttr> getTagAttrs() {
|
||||||
List<TagAttr> tagAttrs = new ArrayList<>();
|
List<TagAttr> tagAttrs = new ArrayList<>();
|
||||||
tagAttrs.add(new TagAttr(TagAttr_ContentId, true, TagAttrDataType.INTEGER, "文章内容ID"));
|
tagAttrs.add(new TagAttr(ATTR_CONTENT_ID, true, TagAttrDataType.INTEGER, ATTR_USAGE_CONTENT_ID));
|
||||||
tagAttrs.add(new TagAttr(TagAttr_Page, false, TagAttrDataType.BOOLEAN, "是否分页,默认false"));
|
tagAttrs.add(new TagAttr(ATTR_PAGE, false, TagAttrDataType.BOOLEAN, ATTR_USAGE_PAGE, Boolean.FALSE.toString()));
|
||||||
return tagAttrs;
|
return tagAttrs;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, TemplateModel> execute0(Environment env, Map<String, String> attrs)
|
public Map<String, TemplateModel> execute0(Environment env, Map<String, String> attrs)
|
||||||
throws TemplateException, IOException {
|
throws TemplateException {
|
||||||
String contentHtml = null;
|
String contentHtml;
|
||||||
long contentId = MapUtils.getLongValue(attrs, TagAttr_ContentId, 0);
|
long contentId = MapUtils.getLongValue(attrs, ATTR_CONTENT_ID, 0);
|
||||||
if (contentId <= 0) {
|
if (contentId <= 0) {
|
||||||
throw new TemplateException("Invalid contentId: " + contentId, env);
|
throw new TemplateException("Invalid contentId: " + contentId, env);
|
||||||
}
|
}
|
||||||
@ -92,24 +96,32 @@ public class CmsArticleTag extends AbstractTag {
|
|||||||
}
|
}
|
||||||
contentHtml = articleDetail.getContentHtml();
|
contentHtml = articleDetail.getContentHtml();
|
||||||
TemplateContext context = FreeMarkerUtils.getTemplateContext(env);
|
TemplateContext context = FreeMarkerUtils.getTemplateContext(env);
|
||||||
boolean page = MapUtils.getBooleanValue(attrs, TagAttr_Page, false);
|
boolean page = MapUtils.getBooleanValue(attrs, ATTR_PAGE, false);
|
||||||
if (page) {
|
if (page) {
|
||||||
if (context.isPaged()) {
|
if (context.isPaged()) {
|
||||||
throw new TemplateException("分页标识已被其他标签激活", env);
|
throw new DuplicatePageFlagException(env);
|
||||||
}
|
}
|
||||||
context.setPaged(true);
|
context.setPaged(true);
|
||||||
|
|
||||||
String[] pageContents = contentHtml.split(PAGE_BREAK_SPLITER);
|
String[] pageContents = contentHtml.split(PAGE_BREAK_SPLITER);
|
||||||
if (context.getPageIndex() > pageContents.length) {
|
if (context.getPageIndex() > pageContents.length) {
|
||||||
throw new TemplateException(StringUtils.messageFormat("文章内容分页越界:{0}, 最大页码:{1}。", context.getPageIndex(),
|
throw new PageIndexOutOfBoundsException(context.getPageIndex(), pageContents.length, env);
|
||||||
pageContents.length), env);
|
|
||||||
}
|
}
|
||||||
context.setPageTotal(pageContents.length);
|
context.setPageTotal(pageContents.length);
|
||||||
env.setGlobalVariable(StaticizeConstants.TemplateVariable_PageTotal,
|
env.setGlobalVariable(StaticizeConstants.TemplateVariable_PageTotal,
|
||||||
this.wrap(env, context.getPageTotal()));
|
this.wrap(env, context.getPageTotal()));
|
||||||
contentHtml = pageContents[context.getPageIndex() - 1];
|
contentHtml = pageContents[context.getPageIndex() - 1];
|
||||||
}
|
}
|
||||||
return Map.of(TemplateVariable_ArticleContent, this.wrap(env, contentHtml));
|
ArticleTagData data = new ArticleTagData(articleDetail.getFormat(), contentHtml);
|
||||||
|
return Map.of(
|
||||||
|
TemplateVariable_ArticleContent, this.wrap(env, contentHtml), // 兼容历史版本保留ArticleContent
|
||||||
|
StaticizeConstants.TemplateVariable_Data, this.wrap(env, data)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<ArticleTagData> getDataClass() {
|
||||||
|
return ArticleTagData.class;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -126,4 +138,21 @@ public class CmsArticleTag extends AbstractTag {
|
|||||||
public String getDescription() {
|
public String getDescription() {
|
||||||
return DESC;
|
return DESC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@NoArgsConstructor
|
||||||
|
public static class ArticleTagData {
|
||||||
|
|
||||||
|
@XComment("文章正文格式")
|
||||||
|
private String Format;
|
||||||
|
|
||||||
|
@XComment("文章正文")
|
||||||
|
private String ArticleContent;
|
||||||
|
|
||||||
|
public ArticleTagData(String format, String articleContent) {
|
||||||
|
this.Format = format;
|
||||||
|
this.ArticleContent = articleContent;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,6 +2,13 @@
|
|||||||
CMS.CONTENTCORE.CONTENT_TYPE.article=文章
|
CMS.CONTENTCORE.CONTENT_TYPE.article=文章
|
||||||
|
|
||||||
# 模板freemarker
|
# 模板freemarker
|
||||||
FREEMARKER.TAG.NAME.cms_article=文章正文数据标签
|
FREEMARKER.TAG.cms_article.NAME=文章正文数据标签
|
||||||
FREEMARKER.TAG.DESC.cms_article=获取文章正文数据,标签内使用${ArticleContent}获取正文详情
|
FREEMARKER.TAG.cms_article.DESC=获取文章正文数据,标签内使用`${ArticleContent}`获取正文详情
|
||||||
FREEMARKER.FUNC.DESC.dealArticleBody=文章正文处理函数,主要用来处理文章内容中的内部链接和扩展模板占位符
|
FREEMARKER.TAG.cms_article.contentId=文章ID
|
||||||
|
FREEMARKER.TAG.cms_article.page=是否分頁
|
||||||
|
FREEMARKER.FUNC.dealArticleBody.DESC=文章正文处理函数,主要用来处理文章内容中的内部链接和扩展模板占位符
|
||||||
|
FREEMARKER.FUNC.dealArticleBody.Arg1.Name=文章正文内容
|
||||||
|
FREEMARKER.FUNC.dealArticleBody.Arg2.Name=文章正文格式
|
||||||
|
|
||||||
|
# 固定字典项
|
||||||
|
ArticleBodyFormat.RichText=富文本
|
||||||
@ -2,6 +2,12 @@
|
|||||||
CMS.CONTENTCORE.CONTENT_TYPE.article=Article
|
CMS.CONTENTCORE.CONTENT_TYPE.article=Article
|
||||||
|
|
||||||
# 模板freemarker
|
# 模板freemarker
|
||||||
FREEMARKER.TAG.NAME.cms_article=Article body tag
|
FREEMARKER.TAG.cms_article.NAME=Article body tag
|
||||||
FREEMARKER.TAG.DESC.cms_article=Fetch article body details, use "${ArticleContent}" in tag to get body text.
|
FREEMARKER.TAG.cms_article.DESC=Fetch article body details, use `${ArticleContent}` in tag to get body text.
|
||||||
FREEMARKER.FUNC.DESC.dealArticleBody=Article body deal function
|
FREEMARKER.TAG.cms_article.contentId=Article content id.
|
||||||
|
FREEMARKER.TAG.cms_article.page=Pageable
|
||||||
|
FREEMARKER.FUNC.dealArticleBody.DESC=Article body deal function
|
||||||
|
FREEMARKER.FUNC.dealArticleBody.Arg1.Name=Article body text
|
||||||
|
FREEMARKER.FUNC.dealArticleBody.Arg2.Name=Article body format
|
||||||
|
|
||||||
|
ArticleBodyFormat.RichText=Rich Text
|
||||||
@ -2,6 +2,12 @@
|
|||||||
CMS.CONTENTCORE.CONTENT_TYPE.article=文章
|
CMS.CONTENTCORE.CONTENT_TYPE.article=文章
|
||||||
|
|
||||||
# 模板freemarker
|
# 模板freemarker
|
||||||
FREEMARKER.TAG.NAME.cms_article=文章正文數據標籤
|
FREEMARKER.TAG.cms_article.NAME=文章正文數據標籤
|
||||||
FREEMARKER.TAG.DESC.cms_article=獲取文章正文數據,標籤內使用${ArticleContent}獲取正文詳情
|
FREEMARKER.TAG.cms_article.DESC=獲取文章正文數據,標籤內使用`${ArticleContent}`獲取正文詳情
|
||||||
FREEMARKER.FUNC.DESC.dealArticleBody=文章正文處理函數,主要用來處理文章內容中的內部連結和擴展模板佔位符
|
FREEMARKER.TAG.cms_article.contentId=文章ID
|
||||||
|
FREEMARKER.TAG.cms_article.page=是否分頁
|
||||||
|
FREEMARKER.FUNC.dealArticleBody.DESC=文章正文處理函數,主要用來處理文章內容中的內部連結和擴展模板佔位符
|
||||||
|
FREEMARKER.FUNC.dealArticleBody.Arg1.Name=文章正文內容
|
||||||
|
FREEMARKER.FUNC.dealArticleBody.Arg2.Name=文章正文格式
|
||||||
|
|
||||||
|
ArticleBodyFormat.RichText=富文本
|
||||||
|
|||||||
@ -7,7 +7,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>com.chestnut</groupId>
|
<groupId>com.chestnut</groupId>
|
||||||
<artifactId>chestnut-cms</artifactId>
|
<artifactId>chestnut-cms</artifactId>
|
||||||
<version>1.5.0</version>
|
<version>1.5.1</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>chestnut-cms-block</artifactId>
|
<artifactId>chestnut-cms-block</artifactId>
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>com.chestnut</groupId>
|
<groupId>com.chestnut</groupId>
|
||||||
<artifactId>chestnut-cms</artifactId>
|
<artifactId>chestnut-cms</artifactId>
|
||||||
<version>1.5.0</version>
|
<version>1.5.1</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>chestnut-cms-comment</artifactId>
|
<artifactId>chestnut-cms-comment</artifactId>
|
||||||
|
|||||||
@ -42,8 +42,14 @@ import java.util.stream.Collectors;
|
|||||||
public class CmsCommentTag extends AbstractListTag {
|
public class CmsCommentTag extends AbstractListTag {
|
||||||
|
|
||||||
public final static String TAG_NAME = "cms_comment";
|
public final static String TAG_NAME = "cms_comment";
|
||||||
public final static String NAME = "{FREEMARKER.TAG.NAME." + TAG_NAME + "}";
|
public final static String NAME = "{FREEMARKER.TAG." + TAG_NAME + ".NAME}";
|
||||||
public final static String DESC = "{FREEMARKER.TAG.DESC." + TAG_NAME + "}";
|
public final static String DESC = "{FREEMARKER.TAG." + TAG_NAME + ".DESC}";
|
||||||
|
public final static String ATTR_USAGE_UID = "{FREEMARKER.TAG." + TAG_NAME + ".uid}";
|
||||||
|
public final static String ATTR_USAGE_TYPE = "{FREEMARKER.TAG." + TAG_NAME + ".type}";
|
||||||
|
|
||||||
|
public final static String ATTR_UID = "uid";
|
||||||
|
public final static String ATTR_TYPE = "type";
|
||||||
|
|
||||||
|
|
||||||
private final ICommentService commentService;
|
private final ICommentService commentService;
|
||||||
|
|
||||||
@ -52,15 +58,15 @@ public class CmsCommentTag extends AbstractListTag {
|
|||||||
@Override
|
@Override
|
||||||
public List<TagAttr> getTagAttrs() {
|
public List<TagAttr> getTagAttrs() {
|
||||||
List<TagAttr> tagAttrs = super.getTagAttrs();
|
List<TagAttr> tagAttrs = super.getTagAttrs();
|
||||||
tagAttrs.add(new TagAttr("uid", true, TagAttrDataType.INTEGER, "用户ID"));
|
tagAttrs.add(new TagAttr(ATTR_UID, true, TagAttrDataType.INTEGER, ATTR_USAGE_UID));
|
||||||
tagAttrs.add(new TagAttr("type", false, TagAttrDataType.STRING, "来源类型", CommentConsts.COMMENT_SOURCE_TYPE));
|
tagAttrs.add(new TagAttr(ATTR_TYPE, false, TagAttrDataType.STRING, ATTR_USAGE_TYPE, CommentConsts.COMMENT_SOURCE_TYPE));
|
||||||
return tagAttrs;
|
return tagAttrs;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TagPageData prepareData(Environment env, Map<String, String> attrs, boolean page, int size, int pageIndex) throws TemplateException {
|
public TagPageData prepareData(Environment env, Map<String, String> attrs, boolean page, int size, int pageIndex) throws TemplateException {
|
||||||
long uid = MapUtils.getLongValue(attrs, "uid");
|
long uid = MapUtils.getLongValue(attrs, ATTR_UID);
|
||||||
String sourceType = attrs.get("type");
|
String sourceType = attrs.get(ATTR_TYPE);
|
||||||
|
|
||||||
Page<Comment> pageResult = this.commentService.lambdaQuery()
|
Page<Comment> pageResult = this.commentService.lambdaQuery()
|
||||||
.eq(Comment::getSourceType, sourceType)
|
.eq(Comment::getSourceType, sourceType)
|
||||||
@ -87,6 +93,11 @@ public class CmsCommentTag extends AbstractListTag {
|
|||||||
return TagPageData.of(pageResult.getRecords(), pageResult.getTotal());
|
return TagPageData.of(pageResult.getRecords(), pageResult.getTotal());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<Comment> getDataClass() {
|
||||||
|
return Comment.class;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getTagName() {
|
public String getTagName() {
|
||||||
return TAG_NAME;
|
return TAG_NAME;
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
# freemarker模板标签
|
# freemarker模板标签
|
||||||
FREEMARKER.TAG.NAME.cms_comment=评论列表标签
|
FREEMARKER.TAG.cms_comment.NAME=评论列表标签
|
||||||
FREEMARKER.TAG.DESC.cms_comment=获取评论数据列表,内嵌<#list DataList as comment>${comment.name}</#list>遍历数据
|
FREEMARKER.TAG.cms_comment.DESC=获取评论数据列表,内嵌`<#list DataList as comment>${comment.name}</#list>`遍历数据
|
||||||
|
FREEMARKER.TAG.cms_comment.uid=用户ID
|
||||||
|
FREEMARKER.TAG.cms_comment.type=来源类型
|
||||||
@ -1,3 +1,5 @@
|
|||||||
# freemarker模板标签
|
# freemarker模板标签
|
||||||
FREEMARKER.TAG.NAME.cms_comment=Comment list tag
|
FREEMARKER.TAG.cms_comment.NAME=Comment list tag
|
||||||
FREEMARKER.TAG.DESC.cms_comment=Fetch comment list, use <#list> in tag like "<#list DataList as comment>${comment.title}</#list>" to walk through the list of comments.
|
FREEMARKER.TAG.cms_comment.DESC=Fetch comment list, use `<#list>` in tag like `<#list DataList as comment>${comment.title}</#list>` to walk through the list of comments.
|
||||||
|
FREEMARKER.TAG.cms_comment.uid=User id
|
||||||
|
FREEMARKER.TAG.cms_comment.type=Owner type
|
||||||
@ -1,3 +1,5 @@
|
|||||||
# freemarker模板標籤
|
# freemarker模板標籤
|
||||||
FREEMARKER.TAG.NAME.cms_comment=評論列表標籤
|
FREEMARKER.TAG.cms_comment.NAME=評論列表標籤
|
||||||
FREEMARKER.TAG.DESC.cms_comment=獲取評論數據列表,內嵌<#list DataList as comment>${comment.name}</#list>遍曆數據
|
FREEMARKER.TAG.cms_comment.DESC=獲取評論數據列表,內嵌`<#list DataList as comment>${comment.name}</#list>`遍曆數據
|
||||||
|
FREEMARKER.TAG.cms_comment.uid=用戶ID
|
||||||
|
FREEMARKER.TAG.cms_comment.type=來源類型
|
||||||
|
|||||||
@ -7,19 +7,13 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>com.chestnut</groupId>
|
<groupId>com.chestnut</groupId>
|
||||||
<artifactId>chestnut-cms</artifactId>
|
<artifactId>chestnut-cms</artifactId>
|
||||||
<version>1.5.0</version>
|
<version>1.5.1</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>chestnut-cms-contentcore</artifactId>
|
<artifactId>chestnut-cms-contentcore</artifactId>
|
||||||
<description>内容核心</description>
|
<description>内容核心</description>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<!-- 图片处理工具库 -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>net.coobird</groupId>
|
|
||||||
<artifactId>thumbnailator</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.chestnut</groupId>
|
<groupId>com.chestnut</groupId>
|
||||||
<artifactId>chestnut-search</artifactId>
|
<artifactId>chestnut-search</artifactId>
|
||||||
|
|||||||
@ -0,0 +1,91 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2022-2024 兮玥(190785909@qq.com)
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.chestnut.contentcore.cache;
|
||||||
|
|
||||||
|
import com.chestnut.common.redis.IMonitoredCache;
|
||||||
|
import com.chestnut.common.redis.RedisCache;
|
||||||
|
import com.chestnut.contentcore.config.CMSConfig;
|
||||||
|
import com.chestnut.contentcore.domain.CmsCatalog;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CatalogMonitoredCache
|
||||||
|
*
|
||||||
|
* @author 兮玥
|
||||||
|
* @email 190785909@qq.com
|
||||||
|
*/
|
||||||
|
@Component(IMonitoredCache.BEAN_PREFIX + CatalogMonitoredCache.ID)
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class CatalogMonitoredCache implements IMonitoredCache<CmsCatalog> {
|
||||||
|
|
||||||
|
public static final String ID = "Catalog";
|
||||||
|
|
||||||
|
private static final String CACHE_PREFIX = CMSConfig.CachePrefix + "catalog:";
|
||||||
|
|
||||||
|
private final RedisCache redisCache;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getId() {
|
||||||
|
return ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getCacheName() {
|
||||||
|
return "{MONITORED.CACHE.CATALOG}";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getCacheKey() {
|
||||||
|
return CACHE_PREFIX;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CmsCatalog getCache(String cacheKey) {
|
||||||
|
return redisCache.getCacheObject(cacheKey, CmsCatalog.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String cacheKeyById(Long catalogId) {
|
||||||
|
return CACHE_PREFIX + "id:" + catalogId;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String cacheKeyByAlias(Long siteId, String alias) {
|
||||||
|
return CACHE_PREFIX + "alias:" + siteId + ":" + alias;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CmsCatalog getCacheById(Long catalogId) {
|
||||||
|
return redisCache.getCacheObject(cacheKeyById(catalogId), CmsCatalog.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CmsCatalog getCacheById(Long catalogId, Supplier<CmsCatalog> supplier) {
|
||||||
|
return redisCache.getCacheObject(cacheKeyById(catalogId), CmsCatalog.class, supplier);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CmsCatalog getCacheByAlias(Long siteId, String alias) {
|
||||||
|
return redisCache.getCacheObject(cacheKeyByAlias(siteId, alias), CmsCatalog.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CmsCatalog getCacheByAlias(Long siteId, String alias, Supplier<CmsCatalog> supplier) {
|
||||||
|
return redisCache.getCacheObject(cacheKeyByAlias(siteId, alias), CmsCatalog.class, supplier);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clear(CmsCatalog catalog) {
|
||||||
|
this.redisCache.deleteObject(cacheKeyById(catalog.getCatalogId()));
|
||||||
|
this.redisCache.deleteObject(cacheKeyByAlias(catalog.getSiteId(), catalog.getAlias()));
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,70 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2022-2024 兮玥(190785909@qq.com)
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.chestnut.contentcore.cache;
|
||||||
|
|
||||||
|
import com.chestnut.common.redis.IMonitoredCache;
|
||||||
|
import com.chestnut.common.redis.RedisCache;
|
||||||
|
import com.chestnut.contentcore.config.CMSConfig;
|
||||||
|
import com.chestnut.contentcore.domain.CmsPageWidget;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PageWidgetMonitoredCache
|
||||||
|
*
|
||||||
|
* @author 兮玥
|
||||||
|
* @email 190785909@qq.com
|
||||||
|
*/
|
||||||
|
@Component(IMonitoredCache.BEAN_PREFIX + PageWidgetMonitoredCache.ID)
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class PageWidgetMonitoredCache implements IMonitoredCache<CmsPageWidget> {
|
||||||
|
|
||||||
|
public static final String ID = "PageWidget";
|
||||||
|
|
||||||
|
private static final String CACHE_PREFIX = CMSConfig.CachePrefix + "pagewidget:";
|
||||||
|
|
||||||
|
private final RedisCache redisCache;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getId() {
|
||||||
|
return ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getCacheName() {
|
||||||
|
return "{MONITORED.CACHE.PAGE_WIDGET}";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CmsPageWidget getCache(String cacheKey) {
|
||||||
|
return redisCache.getCacheObject(cacheKey, CmsPageWidget.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getCacheKey() {
|
||||||
|
return CACHE_PREFIX;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CmsPageWidget getCache(Long siteId, String code, Supplier<CmsPageWidget> supplier) {
|
||||||
|
return redisCache.getCacheObject(CACHE_PREFIX + siteId + ":" + code, CmsPageWidget.class, supplier);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clear(CmsPageWidget pageWidget) {
|
||||||
|
this.redisCache.deleteObject(CACHE_PREFIX + pageWidget.getSiteId() + ":" + pageWidget.getCode());
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,70 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2022-2024 兮玥(190785909@qq.com)
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.chestnut.contentcore.cache;
|
||||||
|
|
||||||
|
import com.chestnut.common.redis.IMonitoredCache;
|
||||||
|
import com.chestnut.common.redis.RedisCache;
|
||||||
|
import com.chestnut.contentcore.config.CMSConfig;
|
||||||
|
import com.chestnut.contentcore.domain.CmsSite;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SiteMonitoredCache
|
||||||
|
*
|
||||||
|
* @author 兮玥
|
||||||
|
* @email 190785909@qq.com
|
||||||
|
*/
|
||||||
|
@Component(IMonitoredCache.BEAN_PREFIX + SiteMonitoredCache.ID)
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class SiteMonitoredCache implements IMonitoredCache<CmsSite> {
|
||||||
|
|
||||||
|
public static final String ID = "Site";
|
||||||
|
|
||||||
|
private static final String CACHE_PREFIX = CMSConfig.CachePrefix + "site:";
|
||||||
|
|
||||||
|
private final RedisCache redisCache;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getId() {
|
||||||
|
return ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getCacheName() {
|
||||||
|
return "{MONITORED.CACHE.SITE}";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CmsSite getCache(String cacheKey) {
|
||||||
|
return redisCache.getCacheObject(cacheKey, CmsSite.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getCacheKey() {
|
||||||
|
return CACHE_PREFIX;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CmsSite getCache(Long siteId, Supplier<CmsSite> supplier) {
|
||||||
|
return redisCache.getCacheObject(CACHE_PREFIX + siteId, CmsSite.class, supplier);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clear(long siteId) {
|
||||||
|
this.redisCache.deleteObject(CACHE_PREFIX + siteId);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,74 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2022-2024 兮玥(190785909@qq.com)
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.chestnut.contentcore.cache;
|
||||||
|
|
||||||
|
import com.chestnut.common.redis.IMonitoredCache;
|
||||||
|
import com.chestnut.common.redis.RedisCache;
|
||||||
|
import com.chestnut.contentcore.config.CMSConfig;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TemplateMonitoredCache
|
||||||
|
*
|
||||||
|
* @author 兮玥
|
||||||
|
* @email 190785909@qq.com
|
||||||
|
*/
|
||||||
|
@Component(IMonitoredCache.BEAN_PREFIX + TemplateMonitoredCache.ID)
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class TemplateMonitoredCache implements IMonitoredCache<String> {
|
||||||
|
|
||||||
|
public static final String ID = "Template";
|
||||||
|
|
||||||
|
private static final String CACHE_PREFIX = CMSConfig.CachePrefix + "template:";
|
||||||
|
|
||||||
|
private final RedisCache redisCache;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getId() {
|
||||||
|
return ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getCacheName() {
|
||||||
|
return "{MONITORED.CACHE.TEMPLATE}";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getCache(String cacheKey) {
|
||||||
|
return redisCache.getCacheObject(cacheKey, String.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getCacheKey() {
|
||||||
|
return CACHE_PREFIX;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCache(String templateKey, Supplier<String> supplier) {
|
||||||
|
return redisCache.getCacheObject(CACHE_PREFIX + templateKey, String.class, supplier);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clear(String templateKey) {
|
||||||
|
this.redisCache.deleteObject(CACHE_PREFIX + templateKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCache(String templateKey, String staticContent, int timeout, TimeUnit timeUnit) {
|
||||||
|
redisCache.setCacheObject(CACHE_PREFIX + templateKey, staticContent, timeout, timeUnit);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -69,10 +69,7 @@ public class CMSConfig implements WebMvcConfigurer {
|
|||||||
if (StringUtils.isEmpty(RESOURCE_ROOT)) {
|
if (StringUtils.isEmpty(RESOURCE_ROOT)) {
|
||||||
RESOURCE_ROOT = SpringUtils.getAppParentDirectory() + "/wwwroot_release/";
|
RESOURCE_ROOT = SpringUtils.getAppParentDirectory() + "/wwwroot_release/";
|
||||||
}
|
}
|
||||||
RESOURCE_ROOT = FileExUtils.normalizePath(RESOURCE_ROOT);
|
RESOURCE_ROOT = StringUtils.appendIfMissing(FileExUtils.normalizePath(RESOURCE_ROOT), "/");
|
||||||
if (!RESOURCE_ROOT.endsWith("/")) {
|
|
||||||
RESOURCE_ROOT += "/";
|
|
||||||
}
|
|
||||||
FileExUtils.mkdirs(RESOURCE_ROOT);
|
FileExUtils.mkdirs(RESOURCE_ROOT);
|
||||||
properties.setResourceRoot(RESOURCE_ROOT);
|
properties.setResourceRoot(RESOURCE_ROOT);
|
||||||
log.info("ResourceRoot: " + RESOURCE_ROOT);
|
log.info("ResourceRoot: " + RESOURCE_ROOT);
|
||||||
@ -116,7 +113,7 @@ public class CMSConfig implements WebMvcConfigurer {
|
|||||||
public void resetCache() {
|
public void resetCache() {
|
||||||
if (this.properties.getResetCache()) {
|
if (this.properties.getResetCache()) {
|
||||||
Collection<String> keys = this.redisCache.keys(this.properties.getCacheName() + "*");
|
Collection<String> keys = this.redisCache.keys(this.properties.getCacheName() + "*");
|
||||||
this.redisCache.deleteObject(keys);
|
this.redisCache.deleteObjects(keys);
|
||||||
log.info("Clear redis caches with prefix `{}`", this.properties.getCacheName());
|
log.info("Clear redis caches with prefix `{}`", this.properties.getCacheName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,11 +16,13 @@
|
|||||||
package com.chestnut.contentcore.controller;
|
package com.chestnut.contentcore.controller;
|
||||||
|
|
||||||
import cn.dev33.satoken.annotation.SaMode;
|
import cn.dev33.satoken.annotation.SaMode;
|
||||||
|
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
|
||||||
import com.chestnut.common.async.AsyncTask;
|
import com.chestnut.common.async.AsyncTask;
|
||||||
import com.chestnut.common.async.AsyncTaskManager;
|
import com.chestnut.common.async.AsyncTaskManager;
|
||||||
import com.chestnut.common.domain.R;
|
import com.chestnut.common.domain.R;
|
||||||
import com.chestnut.common.domain.TreeNode;
|
import com.chestnut.common.domain.TreeNode;
|
||||||
import com.chestnut.common.exception.CommonErrorCode;
|
import com.chestnut.common.exception.CommonErrorCode;
|
||||||
|
import com.chestnut.common.extend.annotation.XssIgnore;
|
||||||
import com.chestnut.common.i18n.I18nUtils;
|
import com.chestnut.common.i18n.I18nUtils;
|
||||||
import com.chestnut.common.log.annotation.Log;
|
import com.chestnut.common.log.annotation.Log;
|
||||||
import com.chestnut.common.log.enums.BusinessType;
|
import com.chestnut.common.log.enums.BusinessType;
|
||||||
@ -52,6 +54,7 @@ import com.chestnut.contentcore.util.SiteUtils;
|
|||||||
import com.chestnut.system.security.AdminUserType;
|
import com.chestnut.system.security.AdminUserType;
|
||||||
import com.chestnut.system.security.StpAdminUtil;
|
import com.chestnut.system.security.StpAdminUtil;
|
||||||
import com.chestnut.system.validator.LongId;
|
import com.chestnut.system.validator.LongId;
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import jakarta.validation.constraints.Min;
|
import jakarta.validation.constraints.Min;
|
||||||
import jakarta.validation.constraints.NotNull;
|
import jakarta.validation.constraints.NotNull;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
@ -177,14 +180,13 @@ public class CatalogController extends BaseRestController {
|
|||||||
@DeleteMapping("/{catalogId}")
|
@DeleteMapping("/{catalogId}")
|
||||||
public R<String> deleteCatalog(@PathVariable("catalogId") @LongId Long catalogId) {
|
public R<String> deleteCatalog(@PathVariable("catalogId") @LongId Long catalogId) {
|
||||||
LoginUser operator = StpAdminUtil.getLoginUser();
|
LoginUser operator = StpAdminUtil.getLoginUser();
|
||||||
AsyncTask task = new AsyncTask() {
|
AsyncTask task = new AsyncTask("Catalog-" + catalogId) {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run0() {
|
public void run0() {
|
||||||
catalogService.deleteCatalog(catalogId, operator);
|
catalogService.deleteCatalog(catalogId, operator);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
task.setTaskId("DeleteCatalog_" + catalogId);
|
|
||||||
this.asyncTaskManager.execute(task);
|
this.asyncTaskManager.execute(task);
|
||||||
return R.ok(task.getTaskId());
|
return R.ok(task.getTaskId());
|
||||||
}
|
}
|
||||||
@ -282,6 +284,7 @@ public class CatalogController extends BaseRestController {
|
|||||||
/**
|
/**
|
||||||
* 保存栏目扩展配置
|
* 保存栏目扩展配置
|
||||||
*/
|
*/
|
||||||
|
@XssIgnore
|
||||||
@Priv(type = AdminUserType.TYPE, value = "Catalog:Edit:${#catalogId}")
|
@Priv(type = AdminUserType.TYPE, value = "Catalog:Edit:${#catalogId}")
|
||||||
@Log(title = "栏目扩展", businessType = BusinessType.UPDATE, isSaveRequestData = false)
|
@Log(title = "栏目扩展", businessType = BusinessType.UPDATE, isSaveRequestData = false)
|
||||||
@PutMapping("/extends/{catalogId}")
|
@PutMapping("/extends/{catalogId}")
|
||||||
@ -376,4 +379,48 @@ public class CatalogController extends BaseRestController {
|
|||||||
}
|
}
|
||||||
return R.ok(Map.of("alias", alias, "path", path));
|
return R.ok(Map.of("alias", alias, "path", path));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Priv(type = AdminUserType.TYPE)
|
||||||
|
@GetMapping("/tree")
|
||||||
|
public R<String> getCatalogTree(@RequestParam Long catalogId, HttpServletRequest request) {
|
||||||
|
CmsSite site = siteService.getCurrentSite(request);
|
||||||
|
CmsCatalog parent = null;
|
||||||
|
if (IdUtils.validate(catalogId)) {
|
||||||
|
parent = catalogService.getCatalog(catalogId);
|
||||||
|
}
|
||||||
|
LambdaQueryChainWrapper<CmsCatalog> q = catalogService.lambdaQuery()
|
||||||
|
.select(CmsCatalog::getName, CmsCatalog::getAncestors, CmsCatalog::getTreeLevel)
|
||||||
|
.eq(CmsCatalog::getSiteId, site.getSiteId());
|
||||||
|
if (Objects.nonNull(parent)) {
|
||||||
|
q.likeRight(CmsCatalog::getAncestors, parent.getAncestors());
|
||||||
|
}
|
||||||
|
List<CmsCatalog> list = q.list();
|
||||||
|
list.sort(Comparator.comparing(CmsCatalog::getAncestors));
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
list.forEach(catalog -> {
|
||||||
|
String prefix = StringUtils.leftPad("", (catalog.getTreeLevel() -1) * 2);
|
||||||
|
sb.append(prefix).append(catalog.getName()).append(StringUtils.LF);
|
||||||
|
});
|
||||||
|
return R.ok(sb.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Priv(type = AdminUserType.TYPE, value = "Catalog:Edit:${#catalogId}")
|
||||||
|
@Log(title = "清空", businessType = BusinessType.UPDATE)
|
||||||
|
@PostMapping("/clear")
|
||||||
|
public R<String> clearCatalog(@RequestBody ClearCatalogDTO dto) {
|
||||||
|
LoginUser operator = StpAdminUtil.getLoginUser();
|
||||||
|
dto.setOperator(operator);
|
||||||
|
AsyncTask task = catalogService.clearCatalog(dto);
|
||||||
|
return R.ok(task.getTaskId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Priv(type = AdminUserType.TYPE, value = "Catalog:Edit:${#catalogId}")
|
||||||
|
@Log(title = "合并", businessType = BusinessType.UPDATE)
|
||||||
|
@PostMapping("/merge")
|
||||||
|
public R<String> mergeCatalog(@RequestBody MergeCatalogDTO dto) {
|
||||||
|
LoginUser operator = StpAdminUtil.getLoginUser();
|
||||||
|
dto.setOperator(operator);
|
||||||
|
AsyncTask task = catalogService.mergeCatalogs(dto);
|
||||||
|
return R.ok(task.getTaskId());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -32,7 +32,6 @@ import com.chestnut.common.utils.ServletUtils;
|
|||||||
import com.chestnut.common.utils.StringUtils;
|
import com.chestnut.common.utils.StringUtils;
|
||||||
import com.chestnut.contentcore.core.IContent;
|
import com.chestnut.contentcore.core.IContent;
|
||||||
import com.chestnut.contentcore.core.IContentType;
|
import com.chestnut.contentcore.core.IContentType;
|
||||||
import com.chestnut.contentcore.core.impl.InternalDataType_Content;
|
|
||||||
import com.chestnut.contentcore.domain.CmsCatalog;
|
import com.chestnut.contentcore.domain.CmsCatalog;
|
||||||
import com.chestnut.contentcore.domain.CmsContent;
|
import com.chestnut.contentcore.domain.CmsContent;
|
||||||
import com.chestnut.contentcore.domain.CmsSite;
|
import com.chestnut.contentcore.domain.CmsSite;
|
||||||
@ -50,7 +49,6 @@ import com.chestnut.contentcore.user.preference.IncludeChildContentPreference;
|
|||||||
import com.chestnut.contentcore.user.preference.ShowContentSubTitlePreference;
|
import com.chestnut.contentcore.user.preference.ShowContentSubTitlePreference;
|
||||||
import com.chestnut.contentcore.util.CmsPrivUtils;
|
import com.chestnut.contentcore.util.CmsPrivUtils;
|
||||||
import com.chestnut.contentcore.util.ContentCoreUtils;
|
import com.chestnut.contentcore.util.ContentCoreUtils;
|
||||||
import com.chestnut.contentcore.util.InternalUrlUtils;
|
|
||||||
import com.chestnut.system.permission.PermissionUtils;
|
import com.chestnut.system.permission.PermissionUtils;
|
||||||
import com.chestnut.system.security.AdminUserType;
|
import com.chestnut.system.security.AdminUserType;
|
||||||
import com.chestnut.system.security.StpAdminUtil;
|
import com.chestnut.system.security.StpAdminUtil;
|
||||||
@ -59,7 +57,6 @@ import freemarker.template.TemplateException;
|
|||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import jakarta.validation.constraints.NotEmpty;
|
import jakarta.validation.constraints.NotEmpty;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.beans.BeanUtils;
|
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
import org.springframework.data.domain.Sort.Direction;
|
import org.springframework.data.domain.Sort.Direction;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
@ -67,7 +64,6 @@ import org.springframework.web.bind.annotation.*;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
@ -137,15 +133,7 @@ public class ContentController extends BaseRestController {
|
|||||||
q.orderByDesc(CmsContent::getTopFlag).orderByDesc(CmsContent::getSortFlag);
|
q.orderByDesc(CmsContent::getTopFlag).orderByDesc(CmsContent::getSortFlag);
|
||||||
}
|
}
|
||||||
Page<CmsContent> page = q.page(new Page<>(pr.getPageNumber(), pr.getPageSize(), true));
|
Page<CmsContent> page = q.page(new Page<>(pr.getPageNumber(), pr.getPageSize(), true));
|
||||||
List<ListContentVO> list = new ArrayList<>();
|
List<ListContentVO> list = page.getRecords().stream().map(ListContentVO::newInstance).toList();
|
||||||
page.getRecords().forEach(content -> {
|
|
||||||
ListContentVO vo = new ListContentVO();
|
|
||||||
BeanUtils.copyProperties(content, vo);
|
|
||||||
vo.setLogoSrc(InternalUrlUtils.getActualPreviewUrl(content.getLogo()));
|
|
||||||
vo.setAttributes(ContentAttribute.convertStr(content.getAttributes()));
|
|
||||||
vo.setInternalUrl(InternalUrlUtils.getInternalUrl(InternalDataType_Content.ID, content.getContentId()));
|
|
||||||
list.add(vo);
|
|
||||||
});
|
|
||||||
return this.bindDataTable(list, (int) page.getTotal());
|
return this.bindDataTable(list, (int) page.getTotal());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -171,7 +159,7 @@ public class ContentController extends BaseRestController {
|
|||||||
throws IOException {
|
throws IOException {
|
||||||
IContentType ct = ContentCoreUtils.getContentType(contentType);
|
IContentType ct = ContentCoreUtils.getContentType(contentType);
|
||||||
|
|
||||||
IContent<?> content = ct.readRequest(request);
|
IContent<?> content = ct.readFrom(request.getInputStream());
|
||||||
content.setOperator(StpAdminUtil.getLoginUser());
|
content.setOperator(StpAdminUtil.getLoginUser());
|
||||||
PermissionUtils.checkPermission(CatalogPrivItem.AddContent.getPermissionKey(content.getCatalogId()),
|
PermissionUtils.checkPermission(CatalogPrivItem.AddContent.getPermissionKey(content.getCatalogId()),
|
||||||
content.getOperator());
|
content.getOperator());
|
||||||
@ -187,7 +175,7 @@ public class ContentController extends BaseRestController {
|
|||||||
throws IOException {
|
throws IOException {
|
||||||
IContentType ct = ContentCoreUtils.getContentType(contentType);
|
IContentType ct = ContentCoreUtils.getContentType(contentType);
|
||||||
|
|
||||||
IContent<?> content = ct.readRequest(request);
|
IContent<?> content = ct.readFrom(request.getInputStream());
|
||||||
content.setOperator(StpAdminUtil.getLoginUser());
|
content.setOperator(StpAdminUtil.getLoginUser());
|
||||||
PermissionUtils.checkPermission(CatalogPrivItem.EditContent.getPermissionKey(content.getCatalogId()),
|
PermissionUtils.checkPermission(CatalogPrivItem.EditContent.getPermissionKey(content.getCatalogId()),
|
||||||
content.getOperator());
|
content.getOperator());
|
||||||
|
|||||||
@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2022-2024 兮玥(190785909@qq.com)
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.chestnut.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.security.web.PageRequest;
|
||||||
|
import com.chestnut.common.utils.StringUtils;
|
||||||
|
import com.chestnut.contentcore.domain.CmsContentOpLog;
|
||||||
|
import com.chestnut.contentcore.service.IContentOpLogService;
|
||||||
|
import com.chestnut.system.security.AdminUserType;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 内容操作日志管理
|
||||||
|
*
|
||||||
|
* @author 兮玥
|
||||||
|
* @email 190785909@qq.com
|
||||||
|
*/
|
||||||
|
@Priv(type = AdminUserType.TYPE)
|
||||||
|
@RestController
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@RequestMapping("/cms/content/log")
|
||||||
|
public class ContentOpLogController extends BaseRestController {
|
||||||
|
|
||||||
|
private final IContentOpLogService contentOpLogService;
|
||||||
|
|
||||||
|
@GetMapping
|
||||||
|
public R<?> getContentOpLogPageList(@RequestParam Long contentId,
|
||||||
|
@RequestParam(required = false) String type,
|
||||||
|
@RequestParam(required = false) String operator) {
|
||||||
|
PageRequest pr = this.getPageRequest();
|
||||||
|
LambdaQueryWrapper<CmsContentOpLog> q = new LambdaQueryWrapper<CmsContentOpLog>()
|
||||||
|
.eq(CmsContentOpLog::getContentId, contentId)
|
||||||
|
.eq(StringUtils.isNotEmpty(type), CmsContentOpLog::getType, type)
|
||||||
|
.eq(StringUtils.isNotEmpty(operator), CmsContentOpLog::getOperator, operator)
|
||||||
|
.orderByDesc(CmsContentOpLog::getLogId);
|
||||||
|
Page<CmsContentOpLog> pageResult = contentOpLogService.page(
|
||||||
|
new Page<>(pr.getPageNumber(), pr.getPageSize(), true), q
|
||||||
|
);
|
||||||
|
return this.bindDataTable(pageResult);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -25,6 +25,7 @@ import com.chestnut.common.utils.Assert;
|
|||||||
import com.chestnut.common.utils.ServletUtils;
|
import com.chestnut.common.utils.ServletUtils;
|
||||||
import com.chestnut.contentcore.core.IInternalDataType;
|
import com.chestnut.contentcore.core.IInternalDataType;
|
||||||
import com.chestnut.contentcore.domain.CmsSite;
|
import com.chestnut.contentcore.domain.CmsSite;
|
||||||
|
import com.chestnut.contentcore.domain.vo.ContentPathRuleVO;
|
||||||
import com.chestnut.contentcore.domain.vo.DynamicPageTypeVO;
|
import com.chestnut.contentcore.domain.vo.DynamicPageTypeVO;
|
||||||
import com.chestnut.contentcore.exception.ContentCoreErrorCode;
|
import com.chestnut.contentcore.exception.ContentCoreErrorCode;
|
||||||
import com.chestnut.contentcore.service.ISiteService;
|
import com.chestnut.contentcore.service.ISiteService;
|
||||||
@ -126,7 +127,6 @@ public class CoreController extends BaseRestController {
|
|||||||
@RequestParam(value = "pi", required = false, defaultValue = "1") Integer pageIndex,
|
@RequestParam(value = "pi", required = false, defaultValue = "1") Integer pageIndex,
|
||||||
@RequestParam Map<String, Object> params) {
|
@RequestParam Map<String, Object> params) {
|
||||||
try {
|
try {
|
||||||
// TODO 缓存
|
|
||||||
long s = System.currentTimeMillis();
|
long s = System.currentTimeMillis();
|
||||||
CmsSite site = this.siteService.getSite(siteId);
|
CmsSite site = this.siteService.getSite(siteId);
|
||||||
// 模板ID = 通道:站点目录:模板文件名
|
// 模板ID = 通道:站点目录:模板文件名
|
||||||
@ -164,9 +164,25 @@ public class CoreController extends BaseRestController {
|
|||||||
public R<?> getDynamicPageTypes() {
|
public R<?> getDynamicPageTypes() {
|
||||||
List<DynamicPageTypeVO> list = ContentCoreUtils.getDynamicPageTypes().stream()
|
List<DynamicPageTypeVO> list = ContentCoreUtils.getDynamicPageTypes().stream()
|
||||||
.map(DynamicPageTypeVO::newInstance).toList();
|
.map(DynamicPageTypeVO::newInstance).toList();
|
||||||
list.forEach( vo ->
|
list.forEach( vo -> {
|
||||||
vo.setName(I18nUtils.get(vo.getName()))
|
vo.setName(I18nUtils.get(vo.getName()));
|
||||||
);
|
vo.setDesc(I18nUtils.get(vo.getDesc()));
|
||||||
|
vo.getRequestArgs().forEach(requestArg -> {
|
||||||
|
requestArg.setName(I18nUtils.get(requestArg.getName()));
|
||||||
|
requestArg.setDesc(I18nUtils.get(requestArg.getDesc()));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return R.ok(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Priv(type = AdminUserType.TYPE)
|
||||||
|
@GetMapping("/cms/contentPathRules")
|
||||||
|
public R<?> getContentPathRules() {
|
||||||
|
List<ContentPathRuleVO> list = ContentCoreUtils.getContentPathRules().stream()
|
||||||
|
.map(ContentPathRuleVO::newInstance).toList();
|
||||||
|
list.forEach( vo -> {
|
||||||
|
vo.setName(I18nUtils.get(vo.getName()));
|
||||||
|
});
|
||||||
return R.ok(list);
|
return R.ok(list);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,84 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2022-2024 兮玥(190785909@qq.com)
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.chestnut.contentcore.controller;
|
||||||
|
|
||||||
|
import cn.dev33.satoken.annotation.SaMode;
|
||||||
|
import com.chestnut.common.domain.R;
|
||||||
|
import com.chestnut.common.log.annotation.Log;
|
||||||
|
import com.chestnut.common.log.enums.BusinessType;
|
||||||
|
import com.chestnut.common.security.anno.Priv;
|
||||||
|
import com.chestnut.common.security.web.BaseRestController;
|
||||||
|
import com.chestnut.contentcore.domain.dto.ImageCropDTO;
|
||||||
|
import com.chestnut.contentcore.domain.dto.ImageRotateDTO;
|
||||||
|
import com.chestnut.contentcore.perms.ContentCorePriv;
|
||||||
|
import com.chestnut.contentcore.service.IImageProcessService;
|
||||||
|
import com.chestnut.contentcore.util.CmsPrivUtils;
|
||||||
|
import com.chestnut.system.security.AdminUserType;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 图片资源处理控制器
|
||||||
|
*
|
||||||
|
* @author 兮玥
|
||||||
|
* @email 190785909@qq.com
|
||||||
|
*/
|
||||||
|
@Priv(
|
||||||
|
type = AdminUserType.TYPE,
|
||||||
|
value = { ContentCorePriv.ResourceView, CmsPrivUtils.PRIV_SITE_VIEW_PLACEHOLDER},
|
||||||
|
mode = SaMode.AND
|
||||||
|
)
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/cms/process/image")
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class ImageProcessController extends BaseRestController {
|
||||||
|
|
||||||
|
private final IImageProcessService imageProcessService;
|
||||||
|
|
||||||
|
@Log(title = "图片裁剪", businessType = BusinessType.UPDATE)
|
||||||
|
@PostMapping("/crop")
|
||||||
|
public R<?> cropImage(@RequestBody @Validated ImageCropDTO dto) throws IOException {
|
||||||
|
this.imageProcessService.cropImage(dto);
|
||||||
|
return R.ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Log(title = "旋转缩放", businessType = BusinessType.UPDATE)
|
||||||
|
@PostMapping("/rotate")
|
||||||
|
public R<?> rotateImage(@RequestBody @Validated ImageRotateDTO dto) throws IOException {
|
||||||
|
this.imageProcessService.rotateImage(dto);
|
||||||
|
return R.ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Log(title = "文字水印", businessType = BusinessType.UPDATE)
|
||||||
|
@PostMapping("/image/textWatermark")
|
||||||
|
public R<?> textWatermark(@RequestBody @Validated ImageCropDTO dto) throws IOException {
|
||||||
|
|
||||||
|
return R.ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Log(title = "图片水印", businessType = BusinessType.UPDATE)
|
||||||
|
@PostMapping("/image/imageWatermark")
|
||||||
|
public R<?> imageWatermark(@RequestBody @Validated ImageCropDTO dto) throws IOException {
|
||||||
|
|
||||||
|
return R.ok();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -34,7 +34,6 @@ import com.chestnut.contentcore.core.IResourceType;
|
|||||||
import com.chestnut.contentcore.core.impl.InternalDataType_Resource;
|
import com.chestnut.contentcore.core.impl.InternalDataType_Resource;
|
||||||
import com.chestnut.contentcore.domain.CmsResource;
|
import com.chestnut.contentcore.domain.CmsResource;
|
||||||
import com.chestnut.contentcore.domain.CmsSite;
|
import com.chestnut.contentcore.domain.CmsSite;
|
||||||
import com.chestnut.contentcore.domain.dto.ImageCropDTO;
|
|
||||||
import com.chestnut.contentcore.domain.dto.ResourceUploadDTO;
|
import com.chestnut.contentcore.domain.dto.ResourceUploadDTO;
|
||||||
import com.chestnut.contentcore.exception.ContentCoreErrorCode;
|
import com.chestnut.contentcore.exception.ContentCoreErrorCode;
|
||||||
import com.chestnut.contentcore.fixed.config.ResourceUploadAcceptSize;
|
import com.chestnut.contentcore.fixed.config.ResourceUploadAcceptSize;
|
||||||
@ -52,7 +51,6 @@ import jakarta.validation.constraints.NotEmpty;
|
|||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.apache.commons.io.FileUtils;
|
import org.apache.commons.io.FileUtils;
|
||||||
import org.springframework.format.annotation.DateTimeFormat;
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
import org.springframework.validation.annotation.Validated;
|
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
@ -198,11 +196,4 @@ public class ResourceController extends BaseRestController {
|
|||||||
Assert.notNull(resource, () -> CommonErrorCode.DATA_NOT_FOUND_BY_ID.exception("resourceId", resourceId));
|
Assert.notNull(resource, () -> CommonErrorCode.DATA_NOT_FOUND_BY_ID.exception("resourceId", resourceId));
|
||||||
this.resourceService.downloadResource(resource, response);
|
this.resourceService.downloadResource(resource, response);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Log(title = "图片裁剪", businessType = BusinessType.UPDATE)
|
|
||||||
@PostMapping("/image/cut")
|
|
||||||
public R<?> cutImage(@RequestBody @Validated ImageCropDTO imageCutDTO) {
|
|
||||||
// TODO
|
|
||||||
return R.fail("TODO");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@ -21,6 +21,7 @@ import com.chestnut.common.async.AsyncTask;
|
|||||||
import com.chestnut.common.async.AsyncTaskManager;
|
import com.chestnut.common.async.AsyncTaskManager;
|
||||||
import com.chestnut.common.domain.R;
|
import com.chestnut.common.domain.R;
|
||||||
import com.chestnut.common.exception.CommonErrorCode;
|
import com.chestnut.common.exception.CommonErrorCode;
|
||||||
|
import com.chestnut.common.extend.annotation.XssIgnore;
|
||||||
import com.chestnut.common.log.annotation.Log;
|
import com.chestnut.common.log.annotation.Log;
|
||||||
import com.chestnut.common.log.enums.BusinessType;
|
import com.chestnut.common.log.enums.BusinessType;
|
||||||
import com.chestnut.common.security.anno.Priv;
|
import com.chestnut.common.security.anno.Priv;
|
||||||
@ -264,6 +265,7 @@ public class SiteController extends BaseRestController {
|
|||||||
* @param siteId 站点ID
|
* @param siteId 站点ID
|
||||||
* @param configs 扩展配置数据
|
* @param configs 扩展配置数据
|
||||||
*/
|
*/
|
||||||
|
@XssIgnore
|
||||||
@Priv(type = AdminUserType.TYPE, value = "Site:Edit:${#siteId}")
|
@Priv(type = AdminUserType.TYPE, value = "Site:Edit:${#siteId}")
|
||||||
@Log(title = "站点扩展", businessType = BusinessType.UPDATE, isSaveRequestData = false)
|
@Log(title = "站点扩展", businessType = BusinessType.UPDATE, isSaveRequestData = false)
|
||||||
@PostMapping("/extends/{siteId}")
|
@PostMapping("/extends/{siteId}")
|
||||||
|
|||||||
@ -15,24 +15,23 @@
|
|||||||
*/
|
*/
|
||||||
package com.chestnut.contentcore.controller;
|
package com.chestnut.contentcore.controller;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
import com.chestnut.common.domain.R;
|
import com.chestnut.common.domain.R;
|
||||||
import com.chestnut.common.i18n.I18nUtils;
|
import com.chestnut.common.i18n.I18nUtils;
|
||||||
import com.chestnut.common.security.anno.Priv;
|
import com.chestnut.common.security.anno.Priv;
|
||||||
import com.chestnut.common.security.web.BaseRestController;
|
import com.chestnut.common.security.web.BaseRestController;
|
||||||
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.StringUtils;
|
||||||
import com.chestnut.contentcore.domain.vo.TemplateFuncVO;
|
import com.chestnut.contentcore.domain.vo.TemplateFuncVO;
|
||||||
import com.chestnut.contentcore.domain.vo.TemplateTagVO;
|
import com.chestnut.contentcore.domain.vo.TemplateTagVO;
|
||||||
import com.chestnut.contentcore.perms.ContentCorePriv;
|
import com.chestnut.contentcore.perms.ContentCorePriv;
|
||||||
import com.chestnut.system.security.AdminUserType;
|
import com.chestnut.system.security.AdminUserType;
|
||||||
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 静态化管理
|
* 静态化管理
|
||||||
@ -56,11 +55,22 @@ public class StaticizeController extends BaseRestController {
|
|||||||
@GetMapping("/tags")
|
@GetMapping("/tags")
|
||||||
public R<?> getTemplateTags() {
|
public R<?> getTemplateTags() {
|
||||||
List<TemplateTagVO> list = this.tags.stream().map(tag -> {
|
List<TemplateTagVO> list = this.tags.stream().map(tag -> {
|
||||||
TemplateTagVO vo = TemplateTagVO.builder().name(I18nUtils.get(tag.getName())).tagName(tag.getTagName())
|
TemplateTagVO vo = TemplateTagVO.builder()
|
||||||
.description(I18nUtils.get(tag.getDescription())).tagAttrs(tag.getTagAttrs()).build();
|
.name(I18nUtils.get(tag.getName()))
|
||||||
|
.tagName(tag.getTagName())
|
||||||
|
.description(I18nUtils.get(tag.getDescription()))
|
||||||
|
.tagAttrs(tag.getTagAttrs())
|
||||||
|
.demoLink("https://www.1000mz.com/docs/template/tags/" + tag.getTagName())
|
||||||
|
.build();
|
||||||
vo.getTagAttrs().forEach(attr -> {
|
vo.getTagAttrs().forEach(attr -> {
|
||||||
attr.setName(I18nUtils.get(attr.getName()));
|
attr.setName(I18nUtils.get(attr.getName()));
|
||||||
attr.setUsage(I18nUtils.get(attr.getUsage()));
|
attr.setUsage(I18nUtils.get(attr.getUsage()));
|
||||||
|
attr.setDefaultValue(I18nUtils.get(attr.getDefaultValue()));
|
||||||
|
if (StringUtils.isNotEmpty(attr.getOptions())) {
|
||||||
|
attr.getOptions().forEach(option -> {
|
||||||
|
option.setDesc(I18nUtils.get(option.getDesc()));
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
return vo;
|
return vo;
|
||||||
}).toList();
|
}).toList();
|
||||||
@ -73,8 +83,12 @@ public class StaticizeController extends BaseRestController {
|
|||||||
@GetMapping("/functions")
|
@GetMapping("/functions")
|
||||||
public R<?> getTemplateFunctions() {
|
public R<?> getTemplateFunctions() {
|
||||||
List<TemplateFuncVO> list = this.functions.stream().map(func -> {
|
List<TemplateFuncVO> list = this.functions.stream().map(func -> {
|
||||||
TemplateFuncVO vo = TemplateFuncVO.builder().funcName(func.getFuncName())
|
TemplateFuncVO vo = TemplateFuncVO.builder()
|
||||||
.desc(I18nUtils.get(func.getDesc())).funcArgs(func.getFuncArgs()).build();
|
.funcName(func.getFuncName())
|
||||||
|
.desc(I18nUtils.get(func.getDesc()))
|
||||||
|
.funcArgs(func.getFuncArgs())
|
||||||
|
.demoLink("https://www.1000mz.com/docs/template/functions/" + func.getFuncName())
|
||||||
|
.build();
|
||||||
vo.getFuncArgs().forEach(arg -> {
|
vo.getFuncArgs().forEach(arg -> {
|
||||||
arg.setName(I18nUtils.get(arg.getName()));
|
arg.setName(I18nUtils.get(arg.getName()));
|
||||||
arg.setDesc(I18nUtils.get(arg.getDesc()));
|
arg.setDesc(I18nUtils.get(arg.getDesc()));
|
||||||
|
|||||||
@ -39,7 +39,10 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
|||||||
import org.springframework.web.bind.annotation.RequestParam;
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -128,15 +131,10 @@ public class ContentApiController extends BaseRestController {
|
|||||||
if (pageResult.getRecords().isEmpty()) {
|
if (pageResult.getRecords().isEmpty()) {
|
||||||
return R.ok(List.of());
|
return R.ok(List.of());
|
||||||
}
|
}
|
||||||
Map<Long, CmsCatalog> loadedCatalogs = new HashMap<>();
|
|
||||||
List<ContentApiVO> list = new ArrayList<>();
|
List<ContentApiVO> list = new ArrayList<>();
|
||||||
pageResult.getRecords().forEach(c -> {
|
pageResult.getRecords().forEach(c -> {
|
||||||
ContentApiVO dto = ContentApiVO.newInstance(c);
|
ContentApiVO dto = ContentApiVO.newInstance(c);
|
||||||
CmsCatalog catalog = loadedCatalogs.get(c.getCatalogId());
|
CmsCatalog catalog = this.catalogService.getCatalog(c.getCatalogId());
|
||||||
if (catalog == null) {
|
|
||||||
catalog = this.catalogService.getCatalog(c.getCatalogId());
|
|
||||||
loadedCatalogs.put(catalog.getCatalogId(), catalog);
|
|
||||||
}
|
|
||||||
dto.setCatalogName(catalog.getName());
|
dto.setCatalogName(catalog.getName());
|
||||||
dto.setCatalogLink(catalogService.getCatalogLink(catalog, 1, publishPipeCode, preview));
|
dto.setCatalogLink(catalogService.getCatalogLink(catalog, 1, publishPipeCode, preview));
|
||||||
dto.setLink(this.contentService.getContentLink(c, 1, publishPipeCode, preview));
|
dto.setLink(this.contentService.getContentLink(c, 1, publishPipeCode, preview));
|
||||||
|
|||||||
@ -24,7 +24,9 @@ import com.chestnut.contentcore.domain.CmsContent;
|
|||||||
import com.chestnut.contentcore.domain.CmsSite;
|
import com.chestnut.contentcore.domain.CmsSite;
|
||||||
import com.chestnut.contentcore.enums.ContentCopyType;
|
import com.chestnut.contentcore.enums.ContentCopyType;
|
||||||
import com.chestnut.contentcore.exception.ContentCoreErrorCode;
|
import com.chestnut.contentcore.exception.ContentCoreErrorCode;
|
||||||
|
import com.chestnut.contentcore.fixed.dict.ContentOpType;
|
||||||
import com.chestnut.contentcore.fixed.dict.ContentStatus;
|
import com.chestnut.contentcore.fixed.dict.ContentStatus;
|
||||||
|
import com.chestnut.contentcore.listener.event.*;
|
||||||
import com.chestnut.contentcore.properties.PublishedContentEditProperty;
|
import com.chestnut.contentcore.properties.PublishedContentEditProperty;
|
||||||
import com.chestnut.contentcore.service.ICatalogService;
|
import com.chestnut.contentcore.service.ICatalogService;
|
||||||
import com.chestnut.contentcore.service.IContentService;
|
import com.chestnut.contentcore.service.IContentService;
|
||||||
@ -32,6 +34,7 @@ import com.chestnut.contentcore.service.IPublishService;
|
|||||||
import com.chestnut.contentcore.service.ISiteService;
|
import com.chestnut.contentcore.service.ISiteService;
|
||||||
import com.chestnut.contentcore.util.CatalogUtils;
|
import com.chestnut.contentcore.util.CatalogUtils;
|
||||||
import com.chestnut.contentcore.util.ContentCoreUtils;
|
import com.chestnut.contentcore.util.ContentCoreUtils;
|
||||||
|
import com.chestnut.contentcore.util.ContentLogUtils;
|
||||||
import com.chestnut.contentcore.util.InternalUrlUtils;
|
import com.chestnut.contentcore.util.InternalUrlUtils;
|
||||||
import com.chestnut.system.fixed.dict.YesOrNo;
|
import com.chestnut.system.fixed.dict.YesOrNo;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
@ -141,6 +144,8 @@ public abstract class AbstractContent<T> implements IContent<T> {
|
|||||||
throw ContentCoreErrorCode.TITLE_REPLEAT.exception();
|
throw ContentCoreErrorCode.TITLE_REPLEAT.exception();
|
||||||
}
|
}
|
||||||
checkRedirectUrl();
|
checkRedirectUrl();
|
||||||
|
|
||||||
|
SpringUtils.publishEvent(new BeforeContentSaveEvent(this, this, true));
|
||||||
content.setSiteId(catalog.getSiteId());
|
content.setSiteId(catalog.getSiteId());
|
||||||
content.setCatalogAncestors(catalog.getAncestors());
|
content.setCatalogAncestors(catalog.getAncestors());
|
||||||
content.setTopCatalog(CatalogUtils.getTopCatalog(catalog));
|
content.setTopCatalog(CatalogUtils.getTopCatalog(catalog));
|
||||||
@ -150,13 +155,24 @@ public abstract class AbstractContent<T> implements IContent<T> {
|
|||||||
content.setStatus(ContentStatus.DRAFT);
|
content.setStatus(ContentStatus.DRAFT);
|
||||||
content.setSortFlag(SortUtils.getDefaultSortValue());
|
content.setSortFlag(SortUtils.getDefaultSortValue());
|
||||||
content.setIsLock(YesOrNo.NO);
|
content.setIsLock(YesOrNo.NO);
|
||||||
|
if (StringUtils.isEmpty(content.getLinkFlag())) {
|
||||||
|
content.setLinkFlag(YesOrNo.NO);
|
||||||
|
}
|
||||||
|
if (Objects.isNull(content.getCopyType())) {
|
||||||
|
content.setCopyType(ContentCopyType.NONE);
|
||||||
|
}
|
||||||
content.createBy(this.getOperatorUName());
|
content.createBy(this.getOperatorUName());
|
||||||
|
this.getContentService().dao().save(this.getContentEntity());
|
||||||
|
this.add0();
|
||||||
// 栏目内容数+1
|
// 栏目内容数+1
|
||||||
this.getCatalogService().changeContentCount(catalog.getCatalogId(), 1);
|
this.getCatalogService().changeContentCount(catalog.getCatalogId(), 1);
|
||||||
|
ContentLogUtils.addLog(ContentOpType.ADD, this.getContentEntity(), this.getOperator());
|
||||||
|
SpringUtils.publishEvent(new AfterContentSaveEvent(this, this, true));
|
||||||
return this.getContentEntity().getContentId();
|
return this.getContentEntity().getContentId();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected abstract void add0();
|
||||||
|
|
||||||
void checkLock() {
|
void checkLock() {
|
||||||
boolean lockContent = content.isLock() && StringUtils.isNotEmpty(content.getLockUser())
|
boolean lockContent = content.isLock() && StringUtils.isNotEmpty(content.getLockUser())
|
||||||
&& !content.getLockUser().equals(this.getOperatorUName());
|
&& !content.getLockUser().equals(this.getOperatorUName());
|
||||||
@ -190,26 +206,39 @@ public abstract class AbstractContent<T> implements IContent<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
checkRedirectUrl();
|
checkRedirectUrl();
|
||||||
|
SpringUtils.publishEvent(new BeforeContentSaveEvent(this, this, false));
|
||||||
if (ContentStatus.isToPublishOrPublished(content.getStatus())) {
|
if (ContentStatus.isToPublishOrPublished(content.getStatus())) {
|
||||||
content.setStatus(ContentStatus.EDITING);
|
content.setStatus(ContentStatus.EDITING);
|
||||||
}
|
}
|
||||||
content.updateBy(this.getOperatorUName());
|
content.updateBy(this.getOperatorUName());
|
||||||
|
contentService.dao().updateById(this.getContentEntity());
|
||||||
|
this.save0();
|
||||||
|
ContentLogUtils.addLog(ContentOpType.UPDATE, this.getContentEntity(), this.getOperator());
|
||||||
|
SpringUtils.publishEvent(new AfterContentSaveEvent(this, this, false));
|
||||||
return this.getContentEntity().getContentId();
|
return this.getContentEntity().getContentId();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected abstract void save0();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void delete() {
|
public void delete() {
|
||||||
this.checkLock();
|
this.checkLock();
|
||||||
// 删除到备份表
|
// 删除到备份表
|
||||||
this.getContentService().dao().deleteByIdAndBackup(this.getContentEntity(), getOperatorUName());
|
this.getContentService().dao().deleteByIdAndBackup(this.getContentEntity(), getOperatorUName());
|
||||||
|
this.delete0();
|
||||||
// 直接删除站内映射内容
|
// 直接删除站内映射内容
|
||||||
this.getContentService().dao().remove(new LambdaQueryWrapper<CmsContent>()
|
this.getContentService().dao().remove(new LambdaQueryWrapper<CmsContent>()
|
||||||
.eq(CmsContent::getCopyType, ContentCopyType.Mapping)
|
.eq(CmsContent::getCopyType, ContentCopyType.Mapping)
|
||||||
.eq(CmsContent::getCopyId, this.getContentEntity().getContentId()));
|
.eq(CmsContent::getCopyId, this.getContentEntity().getContentId()));
|
||||||
// 栏目内容数-1
|
// 栏目内容数-1
|
||||||
this.getCatalogService().changeContentCount(getCatalogId(), -1);
|
this.getCatalogService().changeContentCount(getCatalogId(), -1);
|
||||||
|
ContentLogUtils.addLog(ContentOpType.DELETE, this.getContentEntity(), this.getOperator());
|
||||||
|
|
||||||
|
SpringUtils.publishEvent(new AfterContentDeleteEvent(this, this));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected abstract void delete0();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean publish() {
|
public boolean publish() {
|
||||||
checkLock();
|
checkLock();
|
||||||
@ -227,6 +256,7 @@ public abstract class AbstractContent<T> implements IContent<T> {
|
|||||||
}
|
}
|
||||||
if (update) {
|
if (update) {
|
||||||
this.getContentService().dao().updateById(content);
|
this.getContentService().dao().updateById(content);
|
||||||
|
ContentLogUtils.addLog(ContentOpType.PUBLISH, this.getContentEntity(), this.getOperator());
|
||||||
}
|
}
|
||||||
// 静态化
|
// 静态化
|
||||||
this.getPublishService().asyncPublishContent(this);
|
this.getPublishService().asyncPublishContent(this);
|
||||||
@ -263,12 +293,16 @@ public abstract class AbstractContent<T> implements IContent<T> {
|
|||||||
newContent.setOfflineDate(null);
|
newContent.setOfflineDate(null);
|
||||||
}
|
}
|
||||||
this.getContentService().dao().save(newContent);
|
this.getContentService().dao().save(newContent);
|
||||||
this.getParams().put("NewContentId", newContent.getContentId());
|
copyTo0(newContent, copyType);
|
||||||
// 栏目内容数+1
|
// 栏目内容数+1
|
||||||
this.getCatalogService().changeContentCount(toCatalog.getCatalogId(), 1);
|
this.getCatalogService().changeContentCount(toCatalog.getCatalogId(), 1);
|
||||||
|
|
||||||
|
SpringUtils.publishEvent(new AfterContentCopyEvent(this, this.getContentEntity(), newContent));
|
||||||
return newContent;
|
return newContent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected abstract void copyTo0(CmsContent newContent, Integer copyType);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void moveTo(CmsCatalog toCatalog) {
|
public void moveTo(CmsCatalog toCatalog) {
|
||||||
checkLock();
|
checkLock();
|
||||||
@ -308,24 +342,26 @@ public abstract class AbstractContent<T> implements IContent<T> {
|
|||||||
if (ContentStatus.isPublished(this.getContentEntity().getStatus())) {
|
if (ContentStatus.isPublished(this.getContentEntity().getStatus())) {
|
||||||
this.getPublishService().publishContent(List.of(content.getContentId()), getOperator());
|
this.getPublishService().publishContent(List.of(content.getContentId()), getOperator());
|
||||||
}
|
}
|
||||||
|
ContentLogUtils.addLog(ContentOpType.TOP, this.getContentEntity(), this.getOperator());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void cancelTop() {
|
public void cancelTop() {
|
||||||
content.setTopFlag(0L);
|
if (content.getTopFlag() > 0L) {
|
||||||
content.setTopDate(null);
|
return;
|
||||||
content.updateBy(this.getOperatorUName());
|
}
|
||||||
this.getContentService().dao().updateById(content);
|
this.getContentService().dao().updateById(content);
|
||||||
// 重新发布内容
|
// 重新发布内容
|
||||||
if (ContentStatus.isPublished(this.getContentEntity().getStatus())) {
|
if (ContentStatus.isPublished(this.getContentEntity().getStatus())) {
|
||||||
this.getPublishService().publishContent(List.of(content.getContentId()), getOperator());
|
this.getPublishService().publishContent(List.of(content.getContentId()), getOperator());
|
||||||
}
|
}
|
||||||
|
ContentLogUtils.addLog(ContentOpType.CANCEL_TOP, this.getContentEntity(), this.getOperator());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sort(Long targetContentId) {
|
public void sort(Long targetContentId) {
|
||||||
if (targetContentId.equals(this.getContentEntity().getContentId())) {
|
if (targetContentId.equals(this.getContentEntity().getContentId())) {
|
||||||
return; // 排序目标是自己直接返回
|
return;
|
||||||
}
|
}
|
||||||
checkLock();
|
checkLock();
|
||||||
CmsContent next = this.getContentService().dao().getById(targetContentId);
|
CmsContent next = this.getContentService().dao().getById(targetContentId);
|
||||||
@ -346,15 +382,17 @@ public abstract class AbstractContent<T> implements IContent<T> {
|
|||||||
}
|
}
|
||||||
this.getContentEntity().updateBy(this.getOperatorUName());
|
this.getContentEntity().updateBy(this.getOperatorUName());
|
||||||
this.getContentService().dao().updateById(content);
|
this.getContentService().dao().updateById(content);
|
||||||
|
ContentLogUtils.addLog(ContentOpType.SORT, this.getContentEntity(), this.getOperator());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void offline() {
|
public void offline() {
|
||||||
String status = this.getContentEntity().getStatus();
|
String status = this.getContentEntity().getStatus();
|
||||||
|
if (!ContentStatus.isOffline(status)) {
|
||||||
this.getContentEntity().setStatus(ContentStatus.OFFLINE);
|
this.getContentEntity().setStatus(ContentStatus.OFFLINE);
|
||||||
this.getContentEntity().updateBy(this.getOperatorUName());
|
this.getContentEntity().updateBy(this.getOperatorUName());
|
||||||
this.getContentService().dao().updateById(this.getContentEntity());
|
this.getContentService().dao().updateById(this.getContentEntity());
|
||||||
|
}
|
||||||
if (ContentStatus.isPublished(status)) {
|
if (ContentStatus.isPublished(status)) {
|
||||||
// 已发布内容删除静态页面
|
// 已发布内容删除静态页面
|
||||||
this.getContentService().deleteStaticFiles(this.getContentEntity());
|
this.getContentService().deleteStaticFiles(this.getContentEntity());
|
||||||
@ -366,14 +404,20 @@ public abstract class AbstractContent<T> implements IContent<T> {
|
|||||||
false, false, null, this.getOperator());
|
false, false, null, this.getOperator());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ContentLogUtils.addLog(ContentOpType.OFFLINE, this.getContentEntity(), this.getOperator());
|
||||||
|
SpringUtils.publishEvent(new AfterContentOfflineEvent(this, this));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void toPublish() {
|
public void toPublish() {
|
||||||
|
if (!ContentStatus.isToPublish(this.getContentEntity().getStatus())) {
|
||||||
this.getContentEntity().setStatus(ContentStatus.TO_PUBLISHED);
|
this.getContentEntity().setStatus(ContentStatus.TO_PUBLISHED);
|
||||||
this.getContentEntity().updateBy(this.getOperatorUName());
|
this.getContentEntity().updateBy(this.getOperatorUName());
|
||||||
this.getContentService().dao().updateById(this.getContentEntity());
|
this.getContentService().dao().updateById(this.getContentEntity());
|
||||||
}
|
}
|
||||||
|
ContentLogUtils.addLog(ContentOpType.TO_PUBLISH, this.getContentEntity(), this.getOperator());
|
||||||
|
SpringUtils.publishEvent(new AfterContentToPublishEvent(this, this));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void archive() {
|
public void archive() {
|
||||||
|
|||||||
@ -105,7 +105,7 @@ public abstract class AbstractPageWidget implements IPageWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void publish() throws TemplateException, IOException {
|
public void publish() {
|
||||||
CmsPageWidget pageWidgetEntity = this.getPageWidgetEntity();
|
CmsPageWidget pageWidgetEntity = this.getPageWidgetEntity();
|
||||||
pageWidgetEntity.setState(PageWidgetStatus.PUBLISHED);
|
pageWidgetEntity.setState(PageWidgetStatus.PUBLISHED);
|
||||||
pageWidgetEntity.updateBy(this.getOperator().getUsername());
|
pageWidgetEntity.updateBy(this.getOperator().getUsername());
|
||||||
|
|||||||
@ -18,9 +18,8 @@ package com.chestnut.contentcore.core;
|
|||||||
import com.chestnut.contentcore.domain.BCmsContent;
|
import com.chestnut.contentcore.domain.BCmsContent;
|
||||||
import com.chestnut.contentcore.domain.CmsContent;
|
import com.chestnut.contentcore.domain.CmsContent;
|
||||||
import com.chestnut.contentcore.domain.vo.ContentVO;
|
import com.chestnut.contentcore.domain.vo.ContentVO;
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.InputStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 内容类型
|
* 内容类型
|
||||||
@ -79,11 +78,11 @@ public interface IContentType extends Comparable<IContentType> {
|
|||||||
IContent<?> loadContent(CmsContent xContent);
|
IContent<?> loadContent(CmsContent xContent);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 从请求读取内容数据
|
* 从输入流读取内容数据
|
||||||
*
|
*
|
||||||
* @param request
|
* @param is 输入流
|
||||||
*/
|
*/
|
||||||
IContent<?> readRequest(HttpServletRequest request) throws IOException;
|
IContent<?> readFrom(InputStream is);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 初始化内容编辑页面数据
|
* 初始化内容编辑页面数据
|
||||||
|
|||||||
@ -17,6 +17,8 @@ package com.chestnut.contentcore.core;
|
|||||||
|
|
||||||
import com.chestnut.common.staticize.core.TemplateContext;
|
import com.chestnut.common.staticize.core.TemplateContext;
|
||||||
import com.chestnut.common.utils.StringUtils;
|
import com.chestnut.common.utils.StringUtils;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -31,9 +33,9 @@ public interface IDynamicPageType {
|
|||||||
|
|
||||||
String BEAN_PREFIX = "DynamicPageType_";
|
String BEAN_PREFIX = "DynamicPageType_";
|
||||||
|
|
||||||
RequestArg REQUEST_ARG_SITE_ID = new RequestArg("sid", "站点ID", RequestArgType.Parameter, true, null);
|
RequestArg REQUEST_ARG_SITE_ID = new RequestArg("sid", "{DYNAMIC_PAGE_TYPE.ARG.sid}", RequestArgType.Parameter, true);
|
||||||
RequestArg REQUEST_ARG_PUBLISHPIPE_CODE = new RequestArg("pp", "发布通道编码", RequestArgType.Parameter, true, null);
|
RequestArg REQUEST_ARG_PUBLISHPIPE_CODE = new RequestArg("pp", "{DYNAMIC_PAGE_TYPE.ARG.pp}", RequestArgType.Parameter, true);
|
||||||
RequestArg REQUEST_ARG_PREVIEW = new RequestArg("preview", "是否预览模式", RequestArgType.Parameter, false, "false");
|
RequestArg REQUEST_ARG_PREVIEW = new RequestArg("preview", "{DYNAMIC_PAGE_TYPE.ARG.preview}", RequestArgType.Parameter, false, "false");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 类型
|
* 类型
|
||||||
@ -89,17 +91,27 @@ public interface IDynamicPageType {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
record RequestArg(
|
@Getter
|
||||||
String name, // 参数名
|
@Setter
|
||||||
|
class RequestArg {
|
||||||
|
private String name;
|
||||||
|
private String desc;
|
||||||
|
private RequestArgType type;
|
||||||
|
private boolean mandatory;
|
||||||
|
private String defValue;
|
||||||
|
|
||||||
String desc, // 参数说明
|
public RequestArg(String name, String desc, RequestArgType type, boolean mandatory) {
|
||||||
|
this(name, desc, type, mandatory, null);
|
||||||
|
}
|
||||||
|
|
||||||
RequestArgType type, // 类型:parameter, path
|
public RequestArg(String name, String desc, RequestArgType type, boolean mandatory, String defValue) {
|
||||||
|
this.name = name;
|
||||||
boolean mandatory, // 是否必填
|
this.desc = desc;
|
||||||
|
this.type = type;
|
||||||
String defaultValue // 默认值
|
this.mandatory = mandatory;
|
||||||
){}
|
this.defValue = defValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
enum RequestArgType {
|
enum RequestArgType {
|
||||||
Parameter, Path
|
Parameter, Path
|
||||||
|
|||||||
@ -15,13 +15,9 @@
|
|||||||
*/
|
*/
|
||||||
package com.chestnut.contentcore.core;
|
package com.chestnut.contentcore.core;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import com.chestnut.common.security.domain.LoginUser;
|
import com.chestnut.common.security.domain.LoginUser;
|
||||||
import com.chestnut.contentcore.domain.CmsPageWidget;
|
import com.chestnut.contentcore.domain.CmsPageWidget;
|
||||||
|
|
||||||
import freemarker.template.TemplateException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 页面部件
|
* 页面部件
|
||||||
*
|
*
|
||||||
@ -59,5 +55,5 @@ public interface IPageWidget {
|
|||||||
|
|
||||||
void delete();
|
void delete();
|
||||||
|
|
||||||
void publish() throws TemplateException, IOException;
|
void publish();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -79,4 +79,8 @@ public interface IResourceType {
|
|||||||
resource.setFileSize((long) bytes.length);
|
resource.setFileSize((long) bytes.length);
|
||||||
return bytes;
|
return bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
default void afterProcess(CmsResource resource) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,17 +15,16 @@
|
|||||||
*/
|
*/
|
||||||
package com.chestnut.contentcore.core;
|
package com.chestnut.contentcore.core;
|
||||||
|
|
||||||
|
import com.chestnut.common.utils.StringUtils;
|
||||||
|
import com.chestnut.contentcore.exception.InternalUrlParseException;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
import org.springframework.web.util.HtmlUtils;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
import org.springframework.web.util.HtmlUtils;
|
|
||||||
|
|
||||||
import com.chestnut.common.utils.StringUtils;
|
|
||||||
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 内部数据自定义URL<br/>
|
* 内部数据自定义URL<br/>
|
||||||
* 内部数据包括:内容、栏目、站点、资源等<br/>
|
* 内部数据包括:内容、栏目、站点、资源等<br/>
|
||||||
@ -107,6 +106,9 @@ public class InternalURL {
|
|||||||
url = HtmlUtils.htmlUnescape(url);
|
url = HtmlUtils.htmlUnescape(url);
|
||||||
String content = url.substring(IURLProtocol.length());
|
String content = url.substring(IURLProtocol.length());
|
||||||
int i = content.lastIndexOf("?");
|
int i = content.lastIndexOf("?");
|
||||||
|
if (i < 0) {
|
||||||
|
throw new InternalUrlParseException("Invalid iurl: missing parameters.");
|
||||||
|
}
|
||||||
// 默认iurl的路径部分就是内部数据类型,如果参数中含有type则使用参数type,路径部分作为path
|
// 默认iurl的路径部分就是内部数据类型,如果参数中含有type则使用参数type,路径部分作为path
|
||||||
String type = content.substring(0, i);
|
String type = content.substring(0, i);
|
||||||
iurl.setType(type);
|
iurl.setType(type);
|
||||||
|
|||||||
@ -112,7 +112,7 @@ public class SiteImportContext implements ISiteThemeContext {
|
|||||||
if (IdUtils.validate(id)) {
|
if (IdUtils.validate(id)) {
|
||||||
internalURL.setId(id);
|
internalURL.setId(id);
|
||||||
if (InternalDataType_Resource.ID.equals(internalURL.getType())) {
|
if (InternalDataType_Resource.ID.equals(internalURL.getType())) {
|
||||||
internalURL.setParams(Map.of("sid", site.getSiteId().toString()));
|
internalURL.getParams().put("sid", site.getSiteId().toString());
|
||||||
}
|
}
|
||||||
return internalURL.toIUrl();
|
return internalURL.toIUrl();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -64,11 +64,13 @@ public class ContentCoreResourceStat implements IResourceStat {
|
|||||||
*/
|
*/
|
||||||
private Set<Long> contentLogo() {
|
private Set<Long> contentLogo() {
|
||||||
Set<Long> resourceIds = new HashSet<>();
|
Set<Long> resourceIds = new HashSet<>();
|
||||||
this.contentService.dao().lambdaQuery().select(List.of(CmsContent::getLogo)).list().forEach(content -> {
|
this.contentService.dao().lambdaQuery().select(List.of(CmsContent::getImages)).list().forEach(content -> {
|
||||||
|
if (Objects.nonNull(content.getImages())) {
|
||||||
InternalURL internalURL = InternalUrlUtils.parseInternalUrl(content.getLogo());
|
InternalURL internalURL = InternalUrlUtils.parseInternalUrl(content.getLogo());
|
||||||
if (Objects.nonNull(internalURL)) {
|
if (Objects.nonNull(internalURL)) {
|
||||||
resourceIds.add(internalURL.getId());
|
resourceIds.add(internalURL.getId());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
return resourceIds;
|
return resourceIds;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -53,7 +53,7 @@ public class InternalDataType_Catalog implements IInternalDataType {
|
|||||||
public String getPageData(RequestData requestData) throws IOException, TemplateException {
|
public String getPageData(RequestData requestData) throws IOException, TemplateException {
|
||||||
CmsCatalog catalog = catalogService.getCatalog(requestData.getDataId());
|
CmsCatalog catalog = catalogService.getCatalog(requestData.getDataId());
|
||||||
boolean listFlag = YesOrNo.isYes(requestData.getParams().get("list"));
|
boolean listFlag = YesOrNo.isYes(requestData.getParams().get("list"));
|
||||||
return this.publishService.getCatalogPageData(catalog, requestData.getPageIndex(), listFlag, requestData.getPublishPipeCode(), requestData.isPreview());
|
return this.publishService.getCatalogPageData(catalog, requestData, listFlag);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@ -55,7 +55,7 @@ public class InternalDataType_Content implements IInternalDataType {
|
|||||||
CmsContent content = contentService.dao().getById(requestData.getDataId());
|
CmsContent content = contentService.dao().getById(requestData.getDataId());
|
||||||
Assert.notNull(content, () -> CommonErrorCode.DATA_NOT_FOUND_BY_ID.exception("contentId", requestData.getDataId()));
|
Assert.notNull(content, () -> CommonErrorCode.DATA_NOT_FOUND_BY_ID.exception("contentId", requestData.getDataId()));
|
||||||
|
|
||||||
return this.publishService.getContentPageData(content, requestData.getPageIndex(), requestData.getPublishPipeCode(), requestData.isPreview());
|
return this.publishService.getContentPageData(content, requestData);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@ -15,19 +15,17 @@
|
|||||||
*/
|
*/
|
||||||
package com.chestnut.contentcore.core.impl;
|
package com.chestnut.contentcore.core.impl;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import com.chestnut.contentcore.core.IInternalDataType;
|
import com.chestnut.contentcore.core.IInternalDataType;
|
||||||
import com.chestnut.contentcore.core.InternalURL;
|
import com.chestnut.contentcore.core.InternalURL;
|
||||||
import com.chestnut.contentcore.domain.CmsSite;
|
import com.chestnut.contentcore.domain.CmsSite;
|
||||||
import com.chestnut.contentcore.service.IPublishService;
|
import com.chestnut.contentcore.service.IPublishService;
|
||||||
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 freemarker.template.TemplateException;
|
import freemarker.template.TemplateException;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 内部数据类型:站点
|
* 内部数据类型:站点
|
||||||
@ -53,7 +51,7 @@ public class InternalDataType_Site implements IInternalDataType {
|
|||||||
@Override
|
@Override
|
||||||
public String getPageData(RequestData requestData) throws IOException, TemplateException {
|
public String getPageData(RequestData requestData) throws IOException, TemplateException {
|
||||||
CmsSite site = siteService.getSite(requestData.getDataId());
|
CmsSite site = siteService.getSite(requestData.getDataId());
|
||||||
return this.publishService.getSitePageData(site, requestData.getPublishPipeCode(), requestData.isPreview());
|
return this.publishService.getSitePageData(site, requestData);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@ -15,38 +15,31 @@
|
|||||||
*/
|
*/
|
||||||
package com.chestnut.contentcore.core.impl;
|
package com.chestnut.contentcore.core.impl;
|
||||||
|
|
||||||
import java.awt.image.BufferedImage;
|
import com.chestnut.common.storage.IFileStorageType;
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
import javax.imageio.ImageIO;
|
|
||||||
|
|
||||||
import com.chestnut.common.utils.file.ImageUtils;
|
|
||||||
import com.chestnut.contentcore.properties.ThumbnailHeightProperty;
|
|
||||||
import com.chestnut.contentcore.properties.ThumbnailWidthProperty;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import net.coobird.thumbnailator.Thumbnailator;
|
|
||||||
import net.coobird.thumbnailator.util.ThumbnailatorUtils;
|
|
||||||
import org.apache.commons.compress.utils.FileNameUtils;
|
|
||||||
import org.apache.commons.lang3.ArrayUtils;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import com.chestnut.common.utils.StringUtils;
|
import com.chestnut.common.utils.StringUtils;
|
||||||
|
import com.chestnut.common.utils.image.ImageHelper;
|
||||||
|
import com.chestnut.common.utils.image.ImageUtils;
|
||||||
|
import com.chestnut.common.utils.image.WatermarkPosition;
|
||||||
import com.chestnut.contentcore.core.IResourceType;
|
import com.chestnut.contentcore.core.IResourceType;
|
||||||
import com.chestnut.contentcore.domain.CmsResource;
|
import com.chestnut.contentcore.domain.CmsResource;
|
||||||
import com.chestnut.contentcore.domain.CmsSite;
|
import com.chestnut.contentcore.domain.CmsSite;
|
||||||
import com.chestnut.contentcore.enums.WatermarkerPosition;
|
import com.chestnut.contentcore.properties.*;
|
||||||
import com.chestnut.contentcore.properties.ImageWatermarkArgsProperty;
|
|
||||||
import com.chestnut.contentcore.properties.ImageWatermarkArgsProperty.ImageWatermarkArgs;
|
import com.chestnut.contentcore.properties.ImageWatermarkArgsProperty.ImageWatermarkArgs;
|
||||||
import com.chestnut.contentcore.properties.ImageWatermarkProperty;
|
|
||||||
import com.chestnut.contentcore.service.ISiteService;
|
import com.chestnut.contentcore.service.ISiteService;
|
||||||
|
import com.chestnut.contentcore.util.FileStorageHelper;
|
||||||
import com.chestnut.contentcore.util.SiteUtils;
|
import com.chestnut.contentcore.util.SiteUtils;
|
||||||
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import net.coobird.thumbnailator.Thumbnails;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.commons.compress.utils.FileNameUtils;
|
||||||
|
import org.apache.commons.io.FilenameUtils;
|
||||||
|
import org.apache.commons.lang3.ArrayUtils;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.io.*;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 资源类型:图片
|
* 资源类型:图片
|
||||||
@ -67,6 +60,8 @@ public class ResourceType_Image implements IResourceType {
|
|||||||
|
|
||||||
private final ISiteService siteService;
|
private final ISiteService siteService;
|
||||||
|
|
||||||
|
private final Map<String, IFileStorageType> fileStorageTypeMap;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getId() {
|
public String getId() {
|
||||||
return ID;
|
return ID;
|
||||||
@ -90,49 +85,71 @@ public class ResourceType_Image implements IResourceType {
|
|||||||
@Override
|
@Override
|
||||||
public byte[] process(CmsResource resource, byte[] bytes) throws IOException {
|
public byte[] process(CmsResource resource, byte[] bytes) throws IOException {
|
||||||
CmsSite site = siteService.getSite(resource.getSiteId());
|
CmsSite site = siteService.getSite(resource.getSiteId());
|
||||||
// 提取图片宽高属性
|
|
||||||
try (ByteArrayInputStream is = new ByteArrayInputStream(bytes)) {
|
try (ByteArrayInputStream is = new ByteArrayInputStream(bytes)) {
|
||||||
|
// 提取图片宽高属性
|
||||||
BufferedImage bi = ImageIO.read(is);
|
BufferedImage bi = ImageIO.read(is);
|
||||||
resource.setWidth(bi.getWidth());
|
resource.setWidth(bi.getWidth());
|
||||||
resource.setHeight(bi.getHeight());
|
resource.setHeight(bi.getHeight());
|
||||||
// 默认缩略图处理
|
|
||||||
int w = ThumbnailWidthProperty.getValue(site.getConfigProps());
|
|
||||||
int h = ThumbnailHeightProperty.getValue(site.getConfigProps());
|
|
||||||
if (w > 0 && h > 0) {
|
|
||||||
String siteResourceRoot = SiteUtils.getSiteResourceRoot(site);
|
|
||||||
Thumbnails.of(bi).size(w, h).toFile(siteResourceRoot + ImageUtils.getThumbnailFileName(resource.getPath(), w, h));
|
|
||||||
}
|
|
||||||
// 添加水印
|
// 添加水印
|
||||||
if (ImageWatermarkProperty.getValue(site.getConfigProps())
|
if (ImageWatermarkProperty.getValue(site.getConfigProps())) {
|
||||||
&& !"webp".equalsIgnoreCase(resource.getSuffix())) {
|
|
||||||
// TODO webp水印支持
|
|
||||||
ImageWatermarkArgs args = ImageWatermarkArgsProperty.getValue(site.getConfigProps());
|
ImageWatermarkArgs args = ImageWatermarkArgsProperty.getValue(site.getConfigProps());
|
||||||
if (StringUtils.isNotEmpty(args.getImage())) {
|
if (StringUtils.isNotEmpty(args.getImage())) {
|
||||||
// 水印图片占比大小调整
|
|
||||||
String siteResourceRoot = SiteUtils.getSiteResourceRoot(site);
|
String siteResourceRoot = SiteUtils.getSiteResourceRoot(site);
|
||||||
File file = new File(siteResourceRoot + args.getImage());
|
File file = new File(siteResourceRoot + args.getImage());
|
||||||
if (file.exists()) {
|
if (file.exists()) {
|
||||||
float waterremakImageWidth = bi.getWidth() * args.getRatio() * 0.01f;
|
|
||||||
BufferedImage biWatermarkImage = ImageIO.read(file);
|
BufferedImage biWatermarkImage = ImageIO.read(file);
|
||||||
biWatermarkImage = Thumbnails.of(biWatermarkImage)
|
|
||||||
.scale(waterremakImageWidth / biWatermarkImage.getWidth()).asBufferedImage();
|
|
||||||
try (ByteArrayOutputStream os = new ByteArrayOutputStream()) {
|
try (ByteArrayOutputStream os = new ByteArrayOutputStream()) {
|
||||||
// 添加水印
|
String ext = FilenameUtils.getExtension(resource.getFileName());
|
||||||
Thumbnails.of(bi)
|
ImageHelper.of(bi).format(ext).watermark(
|
||||||
.watermark(WatermarkerPosition.valueOf(args.getPosition()).position(),
|
biWatermarkImage,
|
||||||
biWatermarkImage, args.getOpacity())
|
args.getRatio() * 0.01f,
|
||||||
.scale(1f).outputFormat(resource.getSuffix()).toOutputStream(os);
|
args.getOpacity(),
|
||||||
|
WatermarkPosition.str2Position(args.getPosition())
|
||||||
|
).to(os);
|
||||||
bytes = os.toByteArray();
|
bytes = os.toByteArray();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (IOException e) {
|
||||||
log.error("图片处理失败:", e);
|
log.error("Read image failed: " + resource.getPath(), e);
|
||||||
resource.setWidth(0);
|
resource.setWidth(0);
|
||||||
resource.setHeight(0);
|
resource.setHeight(0);
|
||||||
}
|
}
|
||||||
resource.setFileSize((long) bytes.length);
|
resource.setFileSize((long) bytes.length);
|
||||||
return bytes;
|
return bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterProcess(CmsResource resource) {
|
||||||
|
CmsSite site = siteService.getSite(resource.getSiteId());
|
||||||
|
int w = ThumbnailWidthProperty.getValue(site.getConfigProps());
|
||||||
|
int h = ThumbnailHeightProperty.getValue(site.getConfigProps());
|
||||||
|
if (w > 0 && h > 0) {
|
||||||
|
// 读取存储配置
|
||||||
|
String fileStorageType = FileStorageTypeProperty.getValue(site.getConfigProps());
|
||||||
|
IFileStorageType fst = fileStorageTypeMap.get(IFileStorageType.BEAN_NAME_PREIFX + fileStorageType);
|
||||||
|
FileStorageHelper fileStorageHelper = FileStorageHelper.of(fst, site);
|
||||||
|
// 生成默认缩略图
|
||||||
|
String ext = FilenameUtils.getExtension(resource.getFileName());
|
||||||
|
String thumbnailPath = ImageUtils.getThumbnailFileName(resource.getPath(), w, h);
|
||||||
|
InputStream read = fileStorageHelper.read(resource.getPath());
|
||||||
|
try (ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
|
||||||
|
ImageHelper.of(read).format(ext).resize(w, h).to(bos);
|
||||||
|
fileStorageHelper.write(thumbnailPath, bos.toByteArray());
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.warn("Generate default thumbnail image failed: " + resource.getPath(), e);
|
||||||
|
// 生成缩略图失败直接使用源图作为缩略图
|
||||||
|
fileStorageHelper.write(thumbnailPath, read);
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
if (Objects.nonNull(read)) {
|
||||||
|
read.close();
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.warn("Input stream close err!", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,9 +15,6 @@
|
|||||||
*/
|
*/
|
||||||
package com.chestnut.contentcore.domain;
|
package com.chestnut.contentcore.domain;
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.annotation.IdType;
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
import com.baomidou.mybatisplus.annotation.TableField;
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
import com.baomidou.mybatisplus.annotation.TableId;
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
@ -28,10 +25,12 @@ import com.chestnut.contentcore.core.impl.PublishPipeProp_IndexTemplate;
|
|||||||
import com.chestnut.contentcore.core.impl.PublishPipeProp_ListTemplate;
|
import com.chestnut.contentcore.core.impl.PublishPipeProp_ListTemplate;
|
||||||
import com.chestnut.system.fixed.dict.EnableOrDisable;
|
import com.chestnut.system.fixed.dict.EnableOrDisable;
|
||||||
import com.chestnut.system.fixed.dict.YesOrNo;
|
import com.chestnut.system.fixed.dict.YesOrNo;
|
||||||
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 栏目表对象 [cms_catalog]
|
* 栏目表对象 [cms_catalog]
|
||||||
*
|
*
|
||||||
@ -230,12 +229,7 @@ public class CmsCatalog extends BaseEntity {
|
|||||||
if (this.publishPipeProps == null) {
|
if (this.publishPipeProps == null) {
|
||||||
this.publishPipeProps = new HashMap<>();
|
this.publishPipeProps = new HashMap<>();
|
||||||
}
|
}
|
||||||
Map<String, Object> map = this.publishPipeProps.get(publishPipeCode);
|
return this.publishPipeProps.computeIfAbsent(publishPipeCode, k -> new HashMap<>());
|
||||||
if (map == null) {
|
|
||||||
map = new HashMap<>();
|
|
||||||
this.publishPipeProps.put(publishPipeCode, map);
|
|
||||||
}
|
|
||||||
return map;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getIndexTemplate(String publishPipeCode) {
|
public String getIndexTemplate(String publishPipeCode) {
|
||||||
|
|||||||
@ -30,6 +30,7 @@ import org.springframework.beans.BeanUtils;
|
|||||||
|
|
||||||
import java.io.Serial;
|
import java.io.Serial;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -119,10 +120,17 @@ public class CmsContent extends BaseEntity implements IBackupable<BCmsContent> {
|
|||||||
private String titleStyle;
|
private String titleStyle;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* logo
|
* 封面图
|
||||||
*/
|
*/
|
||||||
|
@TableField(exist = false)
|
||||||
private String logo;
|
private String logo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新封面图字段
|
||||||
|
*/
|
||||||
|
@TableField(typeHandler = JacksonTypeHandler.class)
|
||||||
|
private List<String> images;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 来源
|
* 来源
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -0,0 +1,69 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2022-2024 兮玥(190785909@qq.com)
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.chestnut.contentcore.domain;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import com.chestnut.common.annotation.XComment;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 内容操作记录 [cms_content_op_log]
|
||||||
|
*
|
||||||
|
* @author 兮玥
|
||||||
|
* @email 190785909@qq.com
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@TableName(CmsContentOpLog.TABLE_NAME)
|
||||||
|
public class CmsContentOpLog implements Serializable {
|
||||||
|
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
public static final String TABLE_NAME = "cms_content_op_log";
|
||||||
|
|
||||||
|
@TableId(value = "log_id", type = IdType.INPUT)
|
||||||
|
@XComment("ID")
|
||||||
|
private Long logId;
|
||||||
|
|
||||||
|
@XComment("所属站点ID")
|
||||||
|
private Long siteId;
|
||||||
|
|
||||||
|
@XComment("所属内容ID")
|
||||||
|
private Long contentId;
|
||||||
|
|
||||||
|
@XComment("操作类型")
|
||||||
|
private String type;
|
||||||
|
|
||||||
|
@XComment("操作明细")
|
||||||
|
private String details;
|
||||||
|
|
||||||
|
@XComment("操作人类型")
|
||||||
|
private String operatorType;
|
||||||
|
|
||||||
|
@XComment("操作人用户名")
|
||||||
|
private String operator;
|
||||||
|
|
||||||
|
@XComment("日志时间")
|
||||||
|
private LocalDateTime logTime;
|
||||||
|
}
|
||||||
@ -140,12 +140,7 @@ public class CmsSite extends BaseEntity {
|
|||||||
if (this.publishPipeProps == null) {
|
if (this.publishPipeProps == null) {
|
||||||
this.publishPipeProps = new HashMap<>();
|
this.publishPipeProps = new HashMap<>();
|
||||||
}
|
}
|
||||||
Map<String, Object> map = this.publishPipeProps.get(publishPipeCode);
|
return this.publishPipeProps.computeIfAbsent(publishPipeCode, k -> new HashMap<>());
|
||||||
if (map == null) {
|
|
||||||
map = new HashMap<>();
|
|
||||||
this.publishPipeProps.put(publishPipeCode, map);
|
|
||||||
}
|
|
||||||
return map;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getIndexTemplate(String publishPipeCode) {
|
public String getIndexTemplate(String publishPipeCode) {
|
||||||
@ -158,9 +153,7 @@ public class CmsSite extends BaseEntity {
|
|||||||
|
|
||||||
public String getUrl(String publishPipeCode) {
|
public String getUrl(String publishPipeCode) {
|
||||||
String ppUrl = PublishPipeProp_SiteUrl.getValue(publishPipeCode, this.publishPipeProps);
|
String ppUrl = PublishPipeProp_SiteUrl.getValue(publishPipeCode, this.publishPipeProps);
|
||||||
if (ppUrl != null && !ppUrl.endsWith("/")) {
|
ppUrl = StringUtils.appendIfMissing(ppUrl, "/");
|
||||||
ppUrl += "/";
|
|
||||||
}
|
|
||||||
return Objects.requireNonNullElse(ppUrl, StringUtils.EMPTY);
|
return Objects.requireNonNullElse(ppUrl, StringUtils.EMPTY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -18,8 +18,8 @@ package com.chestnut.contentcore.domain;
|
|||||||
import com.baomidou.mybatisplus.annotation.IdType;
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
import com.baomidou.mybatisplus.annotation.TableId;
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import com.chestnut.common.annotation.XComment;
|
||||||
import com.chestnut.common.db.domain.BaseEntity;
|
import com.chestnut.common.db.domain.BaseEntity;
|
||||||
|
|
||||||
import jakarta.validation.constraints.NotBlank;
|
import jakarta.validation.constraints.NotBlank;
|
||||||
import jakarta.validation.constraints.Pattern;
|
import jakarta.validation.constraints.Pattern;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
@ -40,31 +40,21 @@ public class CmsSiteProperty extends BaseEntity {
|
|||||||
|
|
||||||
public static final String TABLE_NAME = "cms_site_property";
|
public static final String TABLE_NAME = "cms_site_property";
|
||||||
|
|
||||||
/**
|
|
||||||
* 属性ID-主键
|
|
||||||
*/
|
|
||||||
@TableId(value = "property_id", type = IdType.INPUT)
|
@TableId(value = "property_id", type = IdType.INPUT)
|
||||||
|
@XComment("ID")
|
||||||
private Long propertyId;
|
private Long propertyId;
|
||||||
|
|
||||||
/**
|
@XComment("所属站点ID")
|
||||||
* 所属站点ID
|
|
||||||
*/
|
|
||||||
private Long siteId;
|
private Long siteId;
|
||||||
|
|
||||||
/**
|
@XComment("属性名称")
|
||||||
* 属性名称
|
|
||||||
*/
|
|
||||||
@NotBlank
|
@NotBlank
|
||||||
private String propName;
|
private String propName;
|
||||||
|
|
||||||
/**
|
@XComment("属性编码")
|
||||||
* 属性代码
|
@Pattern(regexp = "[A-Za-z0-9_]+", message = "{VALIDATOR.CMS.SITE_PROPERTY.REGEXP_ERR}")
|
||||||
*/
|
|
||||||
@Pattern(regexp = "[A-Za-z0-9_]+")
|
|
||||||
private String propCode;
|
private String propCode;
|
||||||
|
|
||||||
/**
|
@XComment("属性值")
|
||||||
* 属性值
|
|
||||||
*/
|
|
||||||
private String propValue;
|
private String propValue;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2022-2024 兮玥(190785909@qq.com)
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.chestnut.contentcore.domain;
|
||||||
|
|
||||||
|
import com.chestnut.common.utils.StringUtils;
|
||||||
|
import com.chestnut.contentcore.fixed.dict.ContentAttribute;
|
||||||
|
import com.chestnut.contentcore.util.InternalUrlUtils;
|
||||||
|
import org.springframework.beans.BeanUtils;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public interface InitByContent {
|
||||||
|
|
||||||
|
void setAttributes(String[] attributes);
|
||||||
|
|
||||||
|
void setLogo(String logo);
|
||||||
|
|
||||||
|
void setLogoSrc(String logoSrc);
|
||||||
|
|
||||||
|
void setImages(List<String> images);
|
||||||
|
|
||||||
|
void setImagesSrc(List<String> imagesSrc);
|
||||||
|
|
||||||
|
default void initByContent(CmsContent content, boolean preview) {
|
||||||
|
BeanUtils.copyProperties(content, this);
|
||||||
|
this.setAttributes(ContentAttribute.convertStr(content.getAttributes()));
|
||||||
|
if (StringUtils.isNotEmpty(content.getImages())) {
|
||||||
|
this.setLogo(content.getImages().get(0));
|
||||||
|
if (preview) {
|
||||||
|
this.setImagesSrc(content.getImages().stream().map(InternalUrlUtils::getActualPreviewUrl).toList());
|
||||||
|
this.setLogoSrc(InternalUrlUtils.getActualPreviewUrl(content.getLogo()));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.setImages(List.of());
|
||||||
|
this.setImagesSrc(List.of());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -21,7 +21,6 @@ import com.chestnut.system.validator.Dict;
|
|||||||
import com.chestnut.system.validator.LongId;
|
import com.chestnut.system.validator.LongId;
|
||||||
import jakarta.validation.constraints.NotBlank;
|
import jakarta.validation.constraints.NotBlank;
|
||||||
import jakarta.validation.constraints.NotEmpty;
|
import jakarta.validation.constraints.NotEmpty;
|
||||||
import jakarta.validation.constraints.NotNull;
|
|
||||||
import jakarta.validation.constraints.Pattern;
|
import jakarta.validation.constraints.Pattern;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
@ -92,6 +91,11 @@ public class CatalogUpdateDTO extends BaseDTO {
|
|||||||
*/
|
*/
|
||||||
private String redirectUrl;
|
private String redirectUrl;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 内容路径规则
|
||||||
|
*/
|
||||||
|
private String detailNameRule;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* SEO关键词
|
* SEO关键词
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -13,25 +13,22 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package com.chestnut.cms.stat.baidu.vo;
|
package com.chestnut.contentcore.domain.dto;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
|
import com.chestnut.common.security.domain.BaseDTO;
|
||||||
|
import com.chestnut.system.validator.LongId;
|
||||||
|
import jakarta.validation.constraints.NotNull;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
public class LineChartVO {
|
public class ClearCatalogDTO extends BaseDTO {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* x轴
|
* 栏目ID
|
||||||
*/
|
*/
|
||||||
private List<String> xAxisDatas;
|
@NotNull
|
||||||
|
@LongId
|
||||||
/**
|
public Long catalogId;
|
||||||
* y轴数据
|
|
||||||
*/
|
|
||||||
private Map<String, List<Object>> datas;
|
|
||||||
}
|
}
|
||||||
@ -15,11 +15,15 @@
|
|||||||
*/
|
*/
|
||||||
package com.chestnut.contentcore.domain.dto;
|
package com.chestnut.contentcore.domain.dto;
|
||||||
|
|
||||||
import com.chestnut.common.utils.StringUtils;
|
import com.chestnut.common.exception.CommonErrorCode;
|
||||||
|
import com.chestnut.common.utils.Assert;
|
||||||
|
import com.chestnut.contentcore.domain.CmsCatalog;
|
||||||
import com.chestnut.contentcore.domain.CmsContent;
|
import com.chestnut.contentcore.domain.CmsContent;
|
||||||
import com.chestnut.contentcore.enums.ContentOpType;
|
import com.chestnut.contentcore.domain.InitByContent;
|
||||||
import com.chestnut.contentcore.fixed.dict.ContentAttribute;
|
import com.chestnut.contentcore.fixed.dict.ContentAttribute;
|
||||||
import com.chestnut.contentcore.util.InternalUrlUtils;
|
import com.chestnut.contentcore.fixed.dict.ContentOpType;
|
||||||
|
import com.chestnut.contentcore.service.ICatalogService;
|
||||||
|
import com.chestnut.contentcore.service.IContentService;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import org.springframework.beans.BeanUtils;
|
import org.springframework.beans.BeanUtils;
|
||||||
@ -31,12 +35,12 @@ import java.util.Map;
|
|||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
public class ContentDTO {
|
public class ContentDTO implements InitByContent {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 操作类型
|
* 操作类型
|
||||||
*/
|
*/
|
||||||
private ContentOpType opType;
|
private String opType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 内容ID
|
* 内容ID
|
||||||
@ -74,15 +78,25 @@ public class ContentDTO {
|
|||||||
private String titleStyle;
|
private String titleStyle;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 引导图
|
* 封面图
|
||||||
*/
|
*/
|
||||||
private String logo;
|
private String logo;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 引导图预览路径
|
* 封面图预览路径
|
||||||
*/
|
*/
|
||||||
private String logoSrc;
|
private String logoSrc;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 其他图片
|
||||||
|
*/
|
||||||
|
private List<String> images = List.of();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 其他图片预览路径
|
||||||
|
*/
|
||||||
|
private List<String> imagesSrc = List.of();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 发布链接
|
* 发布链接
|
||||||
*/
|
*/
|
||||||
@ -258,13 +272,32 @@ public class ContentDTO {
|
|||||||
*/
|
*/
|
||||||
private String prop4;
|
private String prop4;
|
||||||
|
|
||||||
|
public CmsContent convertToContentEntity(ICatalogService catalogService, IContentService contentService) {
|
||||||
|
CmsContent contentEntity;
|
||||||
|
if (ContentOpType.UPDATE.equals(this.getOpType())) {
|
||||||
|
contentEntity = contentService.dao().getById(this.getContentId());
|
||||||
|
Assert.notNull(contentEntity,
|
||||||
|
() -> CommonErrorCode.DATA_NOT_FOUND_BY_ID.exception("contentId", this.getContentId()));
|
||||||
|
} else {
|
||||||
|
contentEntity = new CmsContent();
|
||||||
|
}
|
||||||
|
BeanUtils.copyProperties(this, contentEntity);
|
||||||
|
// 所属站点
|
||||||
|
CmsCatalog catalog = catalogService.getCatalog(this.getCatalogId());
|
||||||
|
contentEntity.setSiteId(catalog.getSiteId());
|
||||||
|
contentEntity.setAttributes(ContentAttribute.convertInt(this.getAttributes()));
|
||||||
|
// 发布通道配置
|
||||||
|
Map<String, Map<String, Object>> publishPipProps = new HashMap<>();
|
||||||
|
this.getPublishPipeProps().forEach(prop -> {
|
||||||
|
publishPipProps.put(prop.getPipeCode(), prop.getProps());
|
||||||
|
});
|
||||||
|
contentEntity.setPublishPipeProps(publishPipProps);
|
||||||
|
return contentEntity;
|
||||||
|
}
|
||||||
|
|
||||||
public static ContentDTO newInstance(CmsContent cmsContent) {
|
public static ContentDTO newInstance(CmsContent cmsContent) {
|
||||||
ContentDTO dto = new ContentDTO();
|
ContentDTO dto = new ContentDTO();
|
||||||
BeanUtils.copyProperties(cmsContent, dto);
|
dto.initByContent(cmsContent, false);
|
||||||
dto.setAttributes(ContentAttribute.convertStr(cmsContent.getAttributes()));
|
|
||||||
if (StringUtils.isNotEmpty(dto.getLogo())) {
|
|
||||||
dto.setLogoSrc(InternalUrlUtils.getActualPreviewUrl(dto.getLogo()));
|
|
||||||
}
|
|
||||||
return dto;
|
return dto;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -22,4 +22,13 @@ import lombok.Setter;
|
|||||||
@Setter
|
@Setter
|
||||||
public class ImageCropDTO {
|
public class ImageCropDTO {
|
||||||
|
|
||||||
|
private Long resourceId;
|
||||||
|
|
||||||
|
private Integer x;
|
||||||
|
|
||||||
|
private Integer y;
|
||||||
|
|
||||||
|
private Integer width;
|
||||||
|
|
||||||
|
private Integer height;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2022-2024 兮玥(190785909@qq.com)
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.chestnut.contentcore.domain.dto;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class ImageRotateDTO {
|
||||||
|
|
||||||
|
private Long resourceId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 缩略图宽度
|
||||||
|
*/
|
||||||
|
private Integer width;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 缩略图高度
|
||||||
|
*/
|
||||||
|
private Integer height;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 旋转角度
|
||||||
|
*/
|
||||||
|
private Integer rotate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 水平翻转
|
||||||
|
*/
|
||||||
|
private Boolean flipX;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 垂直翻转
|
||||||
|
*/
|
||||||
|
private Boolean flipY;
|
||||||
|
}
|
||||||
@ -13,42 +13,31 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package com.chestnut.cms.stat.baidu.vo;
|
package com.chestnut.contentcore.domain.dto;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
|
import com.chestnut.common.security.domain.BaseDTO;
|
||||||
|
import com.chestnut.system.validator.LongId;
|
||||||
|
import jakarta.validation.constraints.NotEmpty;
|
||||||
|
import jakarta.validation.constraints.NotNull;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
public class BaiduTimeTrendVO extends LineChartVO {
|
public class MergeCatalogDTO extends BaseDTO {
|
||||||
|
|
||||||
private Integer offset;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 时间范围
|
* 栏目ID
|
||||||
*/
|
*/
|
||||||
private String timeSpan;
|
@NotNull
|
||||||
|
@LongId
|
||||||
|
public Long catalogId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 指标字段
|
* 被合并栏目IDs
|
||||||
*/
|
*/
|
||||||
private List<String> fields;
|
@NotEmpty
|
||||||
|
public List<Long> mergeCatalogIds;
|
||||||
/**
|
|
||||||
* 总数
|
|
||||||
*/
|
|
||||||
private Integer total;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 指标合计
|
|
||||||
*/
|
|
||||||
private Map<String, Object> sum;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
private Map<String, Object> pageSum;
|
|
||||||
}
|
}
|
||||||
@ -16,15 +16,15 @@
|
|||||||
package com.chestnut.contentcore.domain.vo;
|
package com.chestnut.contentcore.domain.vo;
|
||||||
|
|
||||||
import com.chestnut.contentcore.domain.CmsContent;
|
import com.chestnut.contentcore.domain.CmsContent;
|
||||||
import com.chestnut.contentcore.fixed.dict.ContentAttribute;
|
import com.chestnut.contentcore.domain.InitByContent;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
|
||||||
import java.time.ZoneOffset;
|
import java.util.List;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
public class ContentApiVO {
|
public class ContentApiVO implements InitByContent {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 内容ID
|
* 内容ID
|
||||||
@ -72,15 +72,25 @@ public class ContentApiVO {
|
|||||||
private String titleStyle;
|
private String titleStyle;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 引导图
|
* 封面图
|
||||||
*/
|
*/
|
||||||
private String logo;
|
private String logo;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 引导图预览路径
|
* 封面图预览路径
|
||||||
*/
|
*/
|
||||||
private String logoSrc;
|
private String logoSrc;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 其他图片
|
||||||
|
*/
|
||||||
|
private List<String> images = List.of();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 其他图片预览路径
|
||||||
|
*/
|
||||||
|
private List<String> imagesSrc = List.of();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 发布链接
|
* 发布链接
|
||||||
*/
|
*/
|
||||||
@ -161,35 +171,9 @@ public class ContentApiVO {
|
|||||||
*/
|
*/
|
||||||
private Long viewCount;
|
private Long viewCount;
|
||||||
|
|
||||||
protected void copyProperties(CmsContent content) {
|
|
||||||
this.setAuthor(content.getAuthor());
|
|
||||||
this.setCatalogId(content.getCatalogId());
|
|
||||||
this.setContentId(content.getContentId());
|
|
||||||
this.setContentType(content.getContentType());
|
|
||||||
this.setEditor(content.getEditor());
|
|
||||||
this.setKeywords(content.getKeywords());
|
|
||||||
this.setLogo(content.getLogo());
|
|
||||||
this.setOriginal(content.getOriginal());
|
|
||||||
this.setPublishDate(content.getPublishDate().toInstant(ZoneOffset.UTC).toEpochMilli());
|
|
||||||
this.setShortTitle(content.getShortTitle());
|
|
||||||
this.setSubTitle(content.getSubTitle());
|
|
||||||
this.setTitle(content.getTitle());
|
|
||||||
this.setSource(content.getSource());
|
|
||||||
this.setSourceUrl(content.getSourceUrl());
|
|
||||||
this.setSummary(content.getSummary());
|
|
||||||
this.setTags(content.getTags());
|
|
||||||
this.setTitleStyle(content.getTitleStyle());
|
|
||||||
this.setTopFlag(content.getTopFlag());
|
|
||||||
this.setAttributes(ContentAttribute.convertStr(content.getAttributes()));
|
|
||||||
this.setViewCount(content.getViewCount());
|
|
||||||
this.setLikeCount(content.getLikeCount());
|
|
||||||
this.setCommentCount(content.getCommentCount());
|
|
||||||
this.setFavoriteCount(content.getFavoriteCount());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ContentApiVO newInstance(CmsContent content) {
|
public static ContentApiVO newInstance(CmsContent content) {
|
||||||
ContentApiVO vo = new ContentApiVO();
|
ContentApiVO vo = new ContentApiVO();
|
||||||
vo.copyProperties(content);
|
vo.initByContent(content, false);
|
||||||
return vo;
|
return vo;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -13,31 +13,24 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package com.chestnut.common.redis;
|
package com.chestnut.contentcore.domain.vo;
|
||||||
|
|
||||||
|
import com.chestnut.contentcore.publish.IContentPathRule;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
|
||||||
/**
|
|
||||||
* 被监控的Redis缓存数据
|
|
||||||
*/
|
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
public class MonitoredCache {
|
public class ContentPathRuleVO {
|
||||||
|
|
||||||
|
private String id;
|
||||||
|
|
||||||
/**
|
private String name;
|
||||||
* 缓存名称
|
|
||||||
*/
|
|
||||||
private String cacheName = "";
|
|
||||||
|
|
||||||
/**
|
public static ContentPathRuleVO newInstance(IContentPathRule contentPathRule) {
|
||||||
* 缓存键名
|
ContentPathRuleVO vo = new ContentPathRuleVO();
|
||||||
*/
|
vo.setId(contentPathRule.getId());
|
||||||
private String cacheKey = "";
|
vo.setName(contentPathRule.getName());
|
||||||
|
return vo;
|
||||||
public MonitoredCache(String cacheName, String cacheKey) {
|
|
||||||
this.cacheName = cacheName;
|
|
||||||
this.cacheKey = cacheKey;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -15,26 +15,20 @@
|
|||||||
*/
|
*/
|
||||||
package com.chestnut.contentcore.domain.vo;
|
package com.chestnut.contentcore.domain.vo;
|
||||||
|
|
||||||
|
import com.chestnut.contentcore.domain.InitByContent;
|
||||||
|
import com.chestnut.contentcore.domain.dto.PublishPipeProp;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.springframework.beans.BeanUtils;
|
|
||||||
|
|
||||||
import com.chestnut.common.utils.StringUtils;
|
|
||||||
import com.chestnut.contentcore.domain.CmsContent;
|
|
||||||
import com.chestnut.contentcore.domain.dto.PublishPipeProp;
|
|
||||||
import com.chestnut.contentcore.fixed.dict.ContentAttribute;
|
|
||||||
import com.chestnut.contentcore.util.InternalUrlUtils;
|
|
||||||
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
public class ContentVO {
|
public class ContentVO implements InitByContent {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 内容ID
|
* 内容ID
|
||||||
@ -82,15 +76,25 @@ public class ContentVO {
|
|||||||
private String showSubTitle;
|
private String showSubTitle;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 引导图
|
* 封面图
|
||||||
*/
|
*/
|
||||||
private String logo;
|
private String logo;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 引导图预览路径
|
* 封面图预览路径
|
||||||
*/
|
*/
|
||||||
private String logoSrc;
|
private String logoSrc;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新多图封面字段
|
||||||
|
*/
|
||||||
|
private List<String> images = List.of();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新多图封面预览路径
|
||||||
|
*/
|
||||||
|
private List<String> imagesSrc = List.of();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 发布链接
|
* 发布链接
|
||||||
*/
|
*/
|
||||||
@ -265,14 +269,4 @@ public class ContentVO {
|
|||||||
* 自定义参数
|
* 自定义参数
|
||||||
*/
|
*/
|
||||||
private Map<String, Object> params;
|
private Map<String, Object> params;
|
||||||
|
|
||||||
public static ContentVO newInstance(CmsContent cmsContent) {
|
|
||||||
ContentVO dto = new ContentVO();
|
|
||||||
BeanUtils.copyProperties(cmsContent, dto);
|
|
||||||
dto.setAttributes(ContentAttribute.convertStr(cmsContent.getAttributes()));
|
|
||||||
if (StringUtils.isNotEmpty(dto.getLogo())) {
|
|
||||||
dto.setLogoSrc(InternalUrlUtils.getActualPreviewUrl(dto.getLogo()));
|
|
||||||
}
|
|
||||||
return dto;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,17 +15,20 @@
|
|||||||
*/
|
*/
|
||||||
package com.chestnut.contentcore.domain.vo;
|
package com.chestnut.contentcore.domain.vo;
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
import com.chestnut.contentcore.core.impl.InternalDataType_Content;
|
||||||
import java.util.Date;
|
import com.chestnut.contentcore.domain.CmsContent;
|
||||||
|
import com.chestnut.contentcore.domain.InitByContent;
|
||||||
import com.baomidou.mybatisplus.annotation.TableField;
|
import com.chestnut.contentcore.util.InternalUrlUtils;
|
||||||
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
public class ListContentVO {
|
public class ListContentVO implements InitByContent {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 内容ID
|
* 内容ID
|
||||||
@ -72,6 +75,16 @@ public class ListContentVO {
|
|||||||
*/
|
*/
|
||||||
private String logoSrc;
|
private String logoSrc;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 引导图
|
||||||
|
*/
|
||||||
|
private List<String> images;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 引导图预览路径
|
||||||
|
*/
|
||||||
|
private List<String> imagesSrc;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 内部链接
|
* 内部链接
|
||||||
*/
|
*/
|
||||||
@ -166,4 +179,11 @@ public class ListContentVO {
|
|||||||
* 创建时间
|
* 创建时间
|
||||||
*/
|
*/
|
||||||
private LocalDateTime createTime;
|
private LocalDateTime createTime;
|
||||||
|
|
||||||
|
public static ListContentVO newInstance(CmsContent content) {
|
||||||
|
ListContentVO vo = new ListContentVO();
|
||||||
|
vo.initByContent(content, true);
|
||||||
|
vo.setInternalUrl(InternalUrlUtils.getInternalUrl(InternalDataType_Content.ID, content.getContentId()));
|
||||||
|
return vo;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,48 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2022-2024 兮玥(190785909@qq.com)
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.chestnut.contentcore.domain.vo;
|
||||||
|
|
||||||
|
import com.chestnut.common.annotation.XComment;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TagBaseVO
|
||||||
|
*
|
||||||
|
* @author 兮玥
|
||||||
|
* @email 190785909@qq.com
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class TagBaseVO {
|
||||||
|
|
||||||
|
@XComment("创建者")
|
||||||
|
private String createBy;
|
||||||
|
|
||||||
|
@XComment("创建时间")
|
||||||
|
private LocalDateTime createTime;
|
||||||
|
|
||||||
|
@XComment("更新者")
|
||||||
|
private String updateBy;
|
||||||
|
|
||||||
|
@XComment("更新时间")
|
||||||
|
private LocalDateTime updateTime;
|
||||||
|
|
||||||
|
@XComment("备注")
|
||||||
|
private String remark;
|
||||||
|
}
|
||||||
@ -0,0 +1,124 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2022-2024 兮玥(190785909@qq.com)
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.chestnut.contentcore.domain.vo;
|
||||||
|
|
||||||
|
import com.chestnut.common.annotation.XComment;
|
||||||
|
import com.chestnut.common.utils.StringUtils;
|
||||||
|
import com.chestnut.contentcore.domain.CmsCatalog;
|
||||||
|
import com.chestnut.contentcore.util.InternalUrlUtils;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
import org.springframework.beans.BeanUtils;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 栏目标签数据对象
|
||||||
|
*
|
||||||
|
* @author 兮玥
|
||||||
|
* @email 190785909@qq.com
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class TagCatalogVO extends TagBaseVO {
|
||||||
|
|
||||||
|
@XComment("栏目ID")
|
||||||
|
private Long catalogId;
|
||||||
|
|
||||||
|
@XComment("站点ID")
|
||||||
|
private Long siteId;
|
||||||
|
|
||||||
|
@XComment("父级栏目ID")
|
||||||
|
private Long parentId;
|
||||||
|
|
||||||
|
@XComment("祖级栏目IDs")
|
||||||
|
private String ancestors;
|
||||||
|
|
||||||
|
@XComment("栏目名称")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@XComment("栏目引导图")
|
||||||
|
private String logo;
|
||||||
|
|
||||||
|
@XComment(value = "栏目引导图访问路径", deprecated = true, forRemoval = "1.6.0")
|
||||||
|
private String logoSrc;
|
||||||
|
|
||||||
|
@XComment("栏目别名")
|
||||||
|
private String alias;
|
||||||
|
|
||||||
|
@XComment("栏目简介")
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
@XComment("所属部门编码")
|
||||||
|
private String deptCode;
|
||||||
|
|
||||||
|
@XComment("栏目类型")
|
||||||
|
private String catalogType;
|
||||||
|
|
||||||
|
@XComment("栏目目录")
|
||||||
|
private String path;
|
||||||
|
|
||||||
|
@XComment("标题栏目跳转地址")
|
||||||
|
private String redirectUrl;
|
||||||
|
|
||||||
|
@XComment("排序值")
|
||||||
|
private Long sortFlag;
|
||||||
|
|
||||||
|
@XComment("栏目层级")
|
||||||
|
private Integer treeLevel;
|
||||||
|
|
||||||
|
@XComment("子栏目数")
|
||||||
|
private Integer childCount;
|
||||||
|
|
||||||
|
@XComment("内容数量")
|
||||||
|
private Integer contentCount;
|
||||||
|
|
||||||
|
@XComment("SEO关键词")
|
||||||
|
private String seoKeywords;
|
||||||
|
|
||||||
|
@XComment("SEO描述")
|
||||||
|
private String seoDescription;
|
||||||
|
|
||||||
|
@XComment("SEO标题")
|
||||||
|
private String seoTitle;
|
||||||
|
|
||||||
|
@XComment("扩展配置")
|
||||||
|
private Map<String, String> configProps;
|
||||||
|
|
||||||
|
@XComment("栏目链接")
|
||||||
|
private String link;
|
||||||
|
|
||||||
|
@XComment("列表页链接(无首页模板时与link一致)")
|
||||||
|
private String listLink;
|
||||||
|
|
||||||
|
public static TagCatalogVO newInstance(CmsCatalog catalog, String publishPipeCode, boolean preview) {
|
||||||
|
TagCatalogVO vo = new TagCatalogVO();
|
||||||
|
BeanUtils.copyProperties(catalog, vo);
|
||||||
|
if (StringUtils.isNotEmpty(catalog.getLogo())) {
|
||||||
|
// 兼容历史版本
|
||||||
|
vo.setLogoSrc(InternalUrlUtils.getActualUrl(catalog.getLogo(), publishPipeCode, preview));
|
||||||
|
}
|
||||||
|
return vo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, String> getConfigProps() {
|
||||||
|
if (this.configProps == null) {
|
||||||
|
this.configProps = new HashMap<>();
|
||||||
|
}
|
||||||
|
return configProps;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,180 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2022-2024 兮玥(190785909@qq.com)
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.chestnut.contentcore.domain.vo;
|
||||||
|
|
||||||
|
import com.chestnut.common.annotation.XComment;
|
||||||
|
import com.chestnut.common.utils.StringUtils;
|
||||||
|
import com.chestnut.contentcore.domain.CmsContent;
|
||||||
|
import com.chestnut.contentcore.fixed.dict.ContentAttribute;
|
||||||
|
import com.chestnut.contentcore.util.InternalUrlUtils;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
import org.springframework.beans.BeanUtils;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 内容标签数据对象
|
||||||
|
*
|
||||||
|
* @author 兮玥
|
||||||
|
* @email 190785909@qq.com
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class TagContentVO extends TagBaseVO {
|
||||||
|
|
||||||
|
@XComment("内容ID")
|
||||||
|
private Long contentId;
|
||||||
|
|
||||||
|
@XComment("所属站点ID")
|
||||||
|
private Long siteId;
|
||||||
|
|
||||||
|
@XComment("所属栏目ID")
|
||||||
|
private Long catalogId;
|
||||||
|
|
||||||
|
@XComment("所属栏目祖级IDs")
|
||||||
|
private String catalogAncestors;
|
||||||
|
|
||||||
|
@XComment("所属顶级栏目")
|
||||||
|
private Long topCatalog;
|
||||||
|
|
||||||
|
@XComment("所属部门ID")
|
||||||
|
private Long deptId;
|
||||||
|
|
||||||
|
@XComment("所属部门编码")
|
||||||
|
private String deptCode;
|
||||||
|
|
||||||
|
@XComment("内容类型")
|
||||||
|
private String contentType;
|
||||||
|
|
||||||
|
@XComment("标题")
|
||||||
|
private String title;
|
||||||
|
|
||||||
|
@XComment("副标题")
|
||||||
|
private String subTitle;
|
||||||
|
|
||||||
|
@XComment("短标题")
|
||||||
|
private String shortTitle;
|
||||||
|
|
||||||
|
@XComment("标题样式")
|
||||||
|
private String titleStyle;
|
||||||
|
|
||||||
|
@XComment(value = "封面图", deprecated = true, forRemoval = "1.6.0")
|
||||||
|
private String logo;
|
||||||
|
|
||||||
|
@XComment(value = "封面图访问路径", deprecated = true, forRemoval = "1.6.0")
|
||||||
|
private String logoSrc;
|
||||||
|
|
||||||
|
@XComment("封面图列表")
|
||||||
|
private List<String> images;
|
||||||
|
|
||||||
|
@XComment("来源")
|
||||||
|
private String source;
|
||||||
|
|
||||||
|
@XComment("来源URL")
|
||||||
|
private String sourceUrl;
|
||||||
|
|
||||||
|
@XComment("是否原创")
|
||||||
|
private String original;
|
||||||
|
|
||||||
|
@XComment("作者")
|
||||||
|
private String author;
|
||||||
|
|
||||||
|
@XComment("编辑")
|
||||||
|
private String editor;
|
||||||
|
|
||||||
|
@XComment("投稿用户ID")
|
||||||
|
private Long contributorId;
|
||||||
|
|
||||||
|
@XComment("摘要")
|
||||||
|
private String summary;
|
||||||
|
|
||||||
|
@XComment("内容属性标识列表")
|
||||||
|
private String[] attributes;
|
||||||
|
|
||||||
|
@XComment("是否链接内容")
|
||||||
|
private String linkFlag;
|
||||||
|
|
||||||
|
@XComment("跳转链接(linkFlag==Y)")
|
||||||
|
private String redirectUrl;
|
||||||
|
|
||||||
|
@XComment("置顶标识")
|
||||||
|
private Long topFlag;
|
||||||
|
|
||||||
|
@XComment("置顶结束时间")
|
||||||
|
private LocalDateTime topDate;
|
||||||
|
|
||||||
|
@XComment("排序值")
|
||||||
|
private Long sortFlag;
|
||||||
|
|
||||||
|
@XComment("关键词")
|
||||||
|
private String[] keywords;
|
||||||
|
|
||||||
|
@XComment("TAGs")
|
||||||
|
private String[] tags;
|
||||||
|
|
||||||
|
@XComment("发布时间")
|
||||||
|
private LocalDateTime publishDate;
|
||||||
|
|
||||||
|
@XComment("SEO标题")
|
||||||
|
private String seoTitle;
|
||||||
|
|
||||||
|
@XComment("SEO关键词")
|
||||||
|
private String seoKeywords;
|
||||||
|
|
||||||
|
@XComment("SEO描述")
|
||||||
|
private String seoDescription;
|
||||||
|
|
||||||
|
@XComment("点赞数(非实时)")
|
||||||
|
private Long likeCount;
|
||||||
|
|
||||||
|
@XComment("评论数(非实时)")
|
||||||
|
private Long commentCount;
|
||||||
|
|
||||||
|
@XComment("收藏数(非实时)")
|
||||||
|
private Long favoriteCount;
|
||||||
|
|
||||||
|
@XComment("文章浏览数(非实时)")
|
||||||
|
private Long viewCount;
|
||||||
|
|
||||||
|
@XComment("备用字段1")
|
||||||
|
private String prop1;
|
||||||
|
|
||||||
|
@XComment("备用字段2")
|
||||||
|
private String prop2;
|
||||||
|
|
||||||
|
@XComment("备用字段3")
|
||||||
|
private String prop3;
|
||||||
|
|
||||||
|
@XComment("备用字段4")
|
||||||
|
private String prop4;
|
||||||
|
|
||||||
|
@XComment("内容链接")
|
||||||
|
private String link;
|
||||||
|
|
||||||
|
public static TagContentVO newInstance(CmsContent content, String publishPipeCode, boolean preview) {
|
||||||
|
TagContentVO vo = new TagContentVO();
|
||||||
|
BeanUtils.copyProperties(content, vo);
|
||||||
|
vo.setAttributes(ContentAttribute.convertStr(content.getAttributes()));
|
||||||
|
if (StringUtils.isNotEmpty(content.getImages())) {
|
||||||
|
// 兼容历史版本
|
||||||
|
vo.setLogo(content.getImages().get(0));
|
||||||
|
vo.setLogoSrc(InternalUrlUtils.getActualUrl(content.getLogo(), publishPipeCode, preview));
|
||||||
|
}
|
||||||
|
return vo;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,66 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2022-2024 兮玥(190785909@qq.com)
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.chestnut.contentcore.domain.vo;
|
||||||
|
|
||||||
|
import com.chestnut.common.annotation.XComment;
|
||||||
|
import com.chestnut.contentcore.domain.CmsPageWidget;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
import org.springframework.beans.BeanUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 栏目标签数据对象
|
||||||
|
*
|
||||||
|
* @author 兮玥
|
||||||
|
* @email 190785909@qq.com
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class TagPageWidgetVO {
|
||||||
|
|
||||||
|
@XComment("页面部件ID")
|
||||||
|
private Long pageWidgetId;
|
||||||
|
|
||||||
|
@XComment("所属站点ID")
|
||||||
|
private Long siteId;
|
||||||
|
|
||||||
|
@XComment("所属栏目ID")
|
||||||
|
private Long catalogId;
|
||||||
|
|
||||||
|
@XComment("所属栏目祖级IDs")
|
||||||
|
private String catalogAncestors;
|
||||||
|
|
||||||
|
@XComment("类型")
|
||||||
|
private String type;
|
||||||
|
|
||||||
|
@XComment("名称")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@XComment("编码")
|
||||||
|
private String code;
|
||||||
|
|
||||||
|
@XComment("发布通道")
|
||||||
|
private String publishPipeCode;
|
||||||
|
|
||||||
|
@XComment("页面部件扩展数据")
|
||||||
|
private Object contentObj;
|
||||||
|
|
||||||
|
public static TagPageWidgetVO newInstance(CmsPageWidget pageWidget) {
|
||||||
|
TagPageWidgetVO vo = new TagPageWidgetVO();
|
||||||
|
BeanUtils.copyProperties(pageWidget, vo);
|
||||||
|
return vo;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,100 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2022-2024 兮玥(190785909@qq.com)
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.chestnut.contentcore.domain.vo;
|
||||||
|
|
||||||
|
import com.chestnut.common.annotation.XComment;
|
||||||
|
import com.chestnut.common.utils.StringUtils;
|
||||||
|
import com.chestnut.contentcore.domain.CmsSite;
|
||||||
|
import com.chestnut.contentcore.util.InternalUrlUtils;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
import org.springframework.beans.BeanUtils;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 站点标签数据对象
|
||||||
|
*
|
||||||
|
* @author 兮玥
|
||||||
|
* @email 190785909@qq.com
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class TagSiteVO extends TagBaseVO {
|
||||||
|
|
||||||
|
@XComment("站点ID")
|
||||||
|
private Long siteId;
|
||||||
|
|
||||||
|
@XComment("父级站点ID")
|
||||||
|
private Long parentId;
|
||||||
|
|
||||||
|
@XComment("站点名称")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@XComment("站点描述")
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
@XComment("站点LOGO")
|
||||||
|
private String logo;
|
||||||
|
|
||||||
|
@XComment(value = "站点LOGO访问地址", deprecated = true, forRemoval = "1.6.0")
|
||||||
|
private String logoSrc;
|
||||||
|
|
||||||
|
@XComment("站点目录")
|
||||||
|
private String path;
|
||||||
|
|
||||||
|
@XComment("站点资源访问域名")
|
||||||
|
private String resourceUrl;
|
||||||
|
|
||||||
|
@XComment("所属部门编码")
|
||||||
|
private String deptCode;
|
||||||
|
|
||||||
|
@XComment("排序值")
|
||||||
|
private Long sortFlag;
|
||||||
|
|
||||||
|
@XComment("SEO关键词")
|
||||||
|
private String seoKeywords;
|
||||||
|
|
||||||
|
@XComment("SEO描述")
|
||||||
|
private String seoDescription;
|
||||||
|
|
||||||
|
@XComment("SEO标题")
|
||||||
|
private String seoTitle;
|
||||||
|
|
||||||
|
@XComment("扩展属性配置")
|
||||||
|
private Map<String, String> configProps;
|
||||||
|
|
||||||
|
@XComment("站点访问地址")
|
||||||
|
private String link;
|
||||||
|
|
||||||
|
public static TagSiteVO newInstance(CmsSite site, String publishPipeCode, boolean preview) {
|
||||||
|
TagSiteVO vo = new TagSiteVO();
|
||||||
|
BeanUtils.copyProperties(site, vo);
|
||||||
|
if (StringUtils.isNotEmpty(site.getLogo())) {
|
||||||
|
// 兼容历史版本
|
||||||
|
vo.setLogoSrc(InternalUrlUtils.getActualUrl(site.getLogo(), publishPipeCode, preview));
|
||||||
|
}
|
||||||
|
return vo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, String> getConfigProps() {
|
||||||
|
if (this.configProps == null) {
|
||||||
|
this.configProps = new HashMap<>();
|
||||||
|
}
|
||||||
|
return configProps;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -15,14 +15,13 @@
|
|||||||
*/
|
*/
|
||||||
package com.chestnut.contentcore.domain.vo;
|
package com.chestnut.contentcore.domain.vo;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import com.chestnut.common.staticize.func.IFunction.FuncArg;
|
import com.chestnut.common.staticize.func.IFunction.FuncArg;
|
||||||
|
|
||||||
import lombok.Builder;
|
import lombok.Builder;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
@Builder
|
@Builder
|
||||||
@ -35,4 +34,6 @@ public class TemplateFuncVO {
|
|||||||
private String desc;
|
private String desc;
|
||||||
|
|
||||||
private List<FuncArg> funcArgs;
|
private List<FuncArg> funcArgs;
|
||||||
|
|
||||||
|
private String demoLink;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,14 +15,13 @@
|
|||||||
*/
|
*/
|
||||||
package com.chestnut.contentcore.domain.vo;
|
package com.chestnut.contentcore.domain.vo;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import com.chestnut.common.staticize.tag.TagAttr;
|
import com.chestnut.common.staticize.tag.TagAttr;
|
||||||
|
|
||||||
import lombok.Builder;
|
import lombok.Builder;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
@Builder
|
@Builder
|
||||||
@ -35,4 +34,6 @@ public class TemplateTagVO {
|
|||||||
private String description;
|
private String description;
|
||||||
|
|
||||||
private List<TagAttr> tagAttrs;
|
private List<TagAttr> tagAttrs;
|
||||||
|
|
||||||
|
private String demoLink;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -20,9 +20,13 @@ import java.util.Objects;
|
|||||||
/**
|
/**
|
||||||
* 内容复制方式
|
* 内容复制方式
|
||||||
*
|
*
|
||||||
|
* @author 兮玥
|
||||||
|
* @email 190785909@qq.com
|
||||||
*/
|
*/
|
||||||
public class ContentCopyType {
|
public class ContentCopyType {
|
||||||
|
|
||||||
|
public static final int NONE = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 独立复制,完整拷贝内容所有信息,拷贝的内容变更与源内容无关,仅仅记录来源
|
* 独立复制,完整拷贝内容所有信息,拷贝的内容变更与源内容无关,仅仅记录来源
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -1,50 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2022-2024 兮玥(190785909@qq.com)
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package com.chestnut.contentcore.enums;
|
|
||||||
|
|
||||||
import net.coobird.thumbnailator.geometry.Position;
|
|
||||||
import net.coobird.thumbnailator.geometry.Positions;
|
|
||||||
|
|
||||||
public enum WatermarkerPosition {
|
|
||||||
|
|
||||||
TOP_LEFT(Positions.TOP_LEFT), // 左上
|
|
||||||
|
|
||||||
TOP_CENTER(Positions.TOP_CENTER), // 上
|
|
||||||
|
|
||||||
TOP_RIGHT(Positions.TOP_RIGHT), // 右上
|
|
||||||
|
|
||||||
CENTER_LEFT(Positions.CENTER_LEFT), // 左
|
|
||||||
|
|
||||||
CENTER(Positions.CENTER), // 中
|
|
||||||
|
|
||||||
CENTER_RIGHT(Positions.CENTER_RIGHT), // 右
|
|
||||||
|
|
||||||
BOTTOM_LEFT(Positions.BOTTOM_LEFT), // 左下
|
|
||||||
|
|
||||||
BOTTOM_CENTER(Positions.BOTTOM_CENTER), // 下
|
|
||||||
|
|
||||||
BOTTOM_RIGHT(Positions.BOTTOM_RIGHT); // 右下
|
|
||||||
|
|
||||||
private Position position;
|
|
||||||
|
|
||||||
WatermarkerPosition(Position position) {
|
|
||||||
this.position = position;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Position position() {
|
|
||||||
return position;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -15,6 +15,12 @@
|
|||||||
*/
|
*/
|
||||||
package com.chestnut.contentcore.enums;
|
package com.chestnut.contentcore.enums;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 水印类型
|
||||||
|
*
|
||||||
|
* @author 兮玥
|
||||||
|
* @email 190785909@qq.com
|
||||||
|
*/
|
||||||
public enum WatermarkerType {
|
public enum WatermarkerType {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -23,7 +29,7 @@ public enum WatermarkerType {
|
|||||||
NONE,
|
NONE,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 图片谁赢
|
* 图片水印
|
||||||
*/
|
*/
|
||||||
IMAGE,
|
IMAGE,
|
||||||
|
|
||||||
|
|||||||
@ -69,6 +69,11 @@ public enum ContentCoreErrorCode implements ErrorCode {
|
|||||||
*/
|
*/
|
||||||
UNSUPPORTED_DYNAMIC_PAGE_TYPE,
|
UNSUPPORTED_DYNAMIC_PAGE_TYPE,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 不支持的内容详情页路径规则:{0}
|
||||||
|
*/
|
||||||
|
UNSUPPORTED_CONTENT_PATH_RULE,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 请先删除子栏目
|
* 请先删除子栏目
|
||||||
*/
|
*/
|
||||||
@ -177,7 +182,27 @@ public enum ContentCoreErrorCode implements ErrorCode {
|
|||||||
/**
|
/**
|
||||||
* 上传文件超过限制
|
* 上传文件超过限制
|
||||||
*/
|
*/
|
||||||
RESOURCE_ACCEPT_SIZE_LIMIT;
|
RESOURCE_ACCEPT_SIZE_LIMIT,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 不能处理非图片资源
|
||||||
|
*/
|
||||||
|
ONLY_SUPPORT_IMAGE,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 资源存储方式与站点配置不一致
|
||||||
|
*/
|
||||||
|
UNSUPPORTED_RESOURCE_STORAGE,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 被合并栏目不能为空
|
||||||
|
*/
|
||||||
|
MERGE_CATALOG_IS_EMPTY,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 不能合并包含子栏目的栏目
|
||||||
|
*/
|
||||||
|
MERGE_CATALOG_NOT_LEAF;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String value() {
|
public String value() {
|
||||||
|
|||||||
@ -23,6 +23,10 @@ package com.chestnut.contentcore.exception;
|
|||||||
*/
|
*/
|
||||||
public class InternalUrlParseException extends RuntimeException {
|
public class InternalUrlParseException extends RuntimeException {
|
||||||
|
|
||||||
|
public InternalUrlParseException(String message) {
|
||||||
|
super("Parse iurl failed: " + message);
|
||||||
|
}
|
||||||
|
|
||||||
public InternalUrlParseException(String message, Exception e) {
|
public InternalUrlParseException(String message, Exception e) {
|
||||||
super("Parse iurl failed: " + message, e);
|
super("Parse iurl failed: " + message, e);
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user