feat(content): 添加多语言支持和Excel导入功能

- 在CmsContent实体类中增加英文标题、描述、介绍和内容字段
- 实现根据语言类型查询内容的功能,支持中英文切换
- 添加从Excel文件批量导入内容数据的功能
- 实现上传技能压缩包并解析生成技能内容的功能
- 优化分页查询逻辑,支持按标签过滤和内存分页
- 修改数据库映射配置以支持多语言字段存储
- 重构点赞功能的安全检查逻辑
This commit is contained in:
wangzhiwei 2026-03-11 15:36:48 +08:00
parent 1b0d102ef9
commit 6398b0495e
10 changed files with 517 additions and 28 deletions

View File

@ -10,8 +10,10 @@ import com.kexue.skills.service.CmsContentService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import java.io.IOException;
/**
* (CmsContent)表控制层
@ -261,4 +263,25 @@ public class CmsContentController {
public CommonResult<PageInfo<CmsContent>> getUserCreated(@RequestBody CmsContentDto queryDto) {
return CommonResult.success(cmsContentService.getPageListByUserCreated(queryDto));
}
/**
* 导入Excel数据到CmsContent
*
* @param file Excel文件
* @param createBy 创建人
* @return 导入结果
*/
@PostMapping("/importFromExcel")
@Operation(summary = "导入Excel数据", description = "从Excel文件导入数据到CmsContent")
@RequireAuth
public CommonResult<Integer> importFromExcel(@RequestParam("file") MultipartFile file, @RequestParam("createBy") String createBy) {
try {
byte[] fileBytes = file.getBytes();
int successCount = cmsContentService.importFromExcel(fileBytes, createBy);
return CommonResult.success(successCount);
} catch (IOException e) {
e.printStackTrace();
return CommonResult.failed("导入失败:" + e.getMessage());
}
}
}

View File

@ -80,4 +80,16 @@ public class SkillGenController {
public CommonResult<String> genIntroduce(@RequestBody GenIntroduceRequest request) {
return CommonResult.success(skillGenService.genIntroduce(request.getContent()));
}
/**
* 上传技能压缩包
*
* @param skillUrl 技能压缩包URL
* @return 生成的技能内容
*/
@PostMapping("/uploadSkill")
@Operation(summary = "上传技能压缩包", description = "上传技能压缩包并生成技能")
public CommonResult<CmsContent> uploadSkill(@RequestBody String skillUrl) {
return CommonResult.success(skillGenService.uploadSkill(skillUrl));
}
}

View File

@ -27,6 +27,9 @@ public class CmsContent extends BaseEntity implements Serializable {
@Schema(description ="标题")
private String title;
@Schema(description ="英文标题")
private String titleEn;
@Schema(description ="是否是官方0否1是")
private Boolean isOfficial;
@ -45,12 +48,18 @@ public class CmsContent extends BaseEntity implements Serializable {
@Schema(description ="详细描述")
private String description;
@Schema(description ="英文描述")
private String descriptionEn;
@Schema(description ="需求说明")
private String requirement;
@Schema(description ="介绍信息")
private String introduce;
@Schema(description ="英文介绍")
private String introduceEn;
@Schema(description ="分享数量")
private Integer shareCount;
@ -70,6 +79,9 @@ public class CmsContent extends BaseEntity implements Serializable {
@Schema(description ="内容详情")
private String content;
@Schema(description ="英文内容")
private String contentEn;
@Schema(description ="封面图片")
private String coverImage;

View File

@ -20,12 +20,6 @@ public class CmsContentDto extends BaseQueryDto {
private Integer contentType;
private String categoryIds;
private Long categoryId;
private List<String> categoryIdList;
private Boolean isOfficial;
private Integer shareCount;
@ -51,9 +45,14 @@ public class CmsContentDto extends BaseQueryDto {
*/
private List<Long> tagIdList;
/**
* 语言类型0 中文1 英文
*/
private Integer languageType;
/**
* 搜索关键字同时搜索 titledescriptiontags
*/
private String keyword;
}

View File

@ -56,6 +56,14 @@ public interface CmsContentMapper {
* @return 实例对象
*/
CmsContent queryById(Long contentId);
/**
* 通过ID和语言类型查询单条数据
*
* @param queryDto 筛选条件
* @return 实例对象
*/
CmsContent queryByIdWithLanguage(CmsContentDto queryDto);
/**
* 新增数据
@ -64,6 +72,14 @@ public interface CmsContentMapper {
* @return 影响行数
*/
int insert(CmsContent cmsContent);
/**
* 批量新增数据
*
* @param cmsContentList 实例对象列表
* @return 影响行数
*/
int batchInsert(@Param("cmsContentList") List<CmsContent> cmsContentList);
/**
* 更新数据

View File

@ -165,4 +165,13 @@ public interface CmsContentService extends BaseService {
* @return 查询结果
*/
PageInfo<CmsContent> getPageListByUserCreated(CmsContentDto queryDto);
/**
* 导入Excel数据到CmsContent
*
* @param fileBytes Excel文件字节数组
* @param createBy 创建人
* @return 导入结果
*/
int importFromExcel(byte[] fileBytes, String createBy);
}

View File

@ -43,4 +43,12 @@ public interface SkillGenService {
* @return 技能介绍
*/
String genIntroduce(String content);
/**
* 上传技能压缩包并生成技能
*
* @param skillUrl 技能压缩包URL
* @return 生成的技能内容
*/
CmsContent uploadSkill(String skillUrl);
}

View File

@ -2,6 +2,7 @@ package com.kexue.skills.service.impl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.github.pagehelper.util.StringUtil;
import com.kexue.skills.common.LoginUserCacheUtil;
import com.kexue.skills.entity.CmsContent;
import com.kexue.skills.entity.CmsContentView;
@ -12,10 +13,15 @@ import com.kexue.skills.mapper.CmsContentMapper;
import com.kexue.skills.mapper.CmsContentViewMapper;
import com.kexue.skills.mapper.CmsContentLikeMapper;
import com.kexue.skills.service.CmsContentService;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;
@ -60,12 +66,15 @@ public class CmsContentServiceImpl implements CmsContentService {
// 使用 PageHelper 进行分页
PageHelper.startPage(queryDto.getPageNum(), queryDto.getPageSize());
// 设置默认语言类型为中文
if (queryDto.getLanguageType() == null) {
queryDto.setLanguageType(0);
}
List<CmsContent> list = this.cmsContentMapper.getPageList(queryDto);
PageInfo<CmsContent> pageInfo = new PageInfo<>(list);
// 如果使用了 keyword 搜索且返回结果小于等于 3 则根据第一个 skill 的标签查询相关 skill
if (queryDto.getKeyword() != null && !queryDto.getKeyword().trim().isEmpty()
&& list.size() <= 3 && !list.isEmpty()) {
if (queryDto.getTitle() != null && !queryDto.getTitle().trim().isEmpty() && list.size() <= 3 && !list.isEmpty()) {
// 获取第一个 skill 的标签
CmsContent firstSkill = list.get(0);
String tagsStr = firstSkill.getTags();
@ -86,6 +95,11 @@ public class CmsContentServiceImpl implements CmsContentService {
}
}
//如果传入的tagId不为空则添加到tagIdSet中
if (queryDto.getTagId() != null) {
tagIdSet.add(queryDto.getTagId());
}
// 如果有有效的标签 ID查询相关内容
if (!tagIdSet.isEmpty()) {
// 排除已返回的 contentId
@ -100,22 +114,29 @@ public class CmsContentServiceImpl implements CmsContentService {
tagQueryDto.setTagIdList(new ArrayList<>(tagIdSet));
tagQueryDto.setPageNum(1);
tagQueryDto.setPageSize(1000);
// 查询包含这些标签的所有 skill
List<CmsContent> taggedContents = this.cmsContentMapper.getPageList(tagQueryDto);
// 过滤掉已返回的内容
List<CmsContent> relatedContents = taggedContents.stream()
.filter(content -> !existingIds.contains(content.getContentId()))
.collect(Collectors.toList());
// List<CmsContent> relatedContents = taggedContents.stream()
// .filter(content -> !existingIds.contains(content.getContentId()))
// .collect(Collectors.toList());
//如果tag传参则根据tag再次过滤
if (queryDto.getTagId() != null) {
taggedContents = taggedContents.stream().filter(content -> content.getTags().contains(queryDto.getTagId().toString())).toList() ;
}
List<CmsContent> finalList = new ArrayList<>(taggedContents);
// 如果有相关 skill添加到结果中
if (!relatedContents.isEmpty()) {
if (!finalList.isEmpty()) {
// sort create_time 排序
relatedContents.sort((a, b) -> {
finalList.sort((a, b) -> {
int sortCompare = Integer.compare(
a.getSort() != null ? a.getSort() : 0,
b.getSort() != null ? b.getSort() : 0);
a.getViewCount() != null ? a.getViewCount() : 0,
b.getViewCount() != null ? b.getViewCount() : 0);
if (sortCompare != 0) {
return sortCompare;
}
@ -125,10 +146,10 @@ public class CmsContentServiceImpl implements CmsContentService {
return b.getCreateTime().compareTo(a.getCreateTime());
});
list.addAll(relatedContents);
// 重新构建 PageInfo
pageInfo = new PageInfo<>(list);
pageInfo.setTotal(list.size());
// 计算需要添加的数量确保总数量不超过 pageSize
PageInfo<CmsContent> newPageInfo = new PageInfo<>(memoryPagination(finalList, queryDto.getPageNum(), queryDto.getPageSize()));
newPageInfo.setTotal(finalList.size());
pageInfo = newPageInfo;
}
}
}
@ -138,6 +159,42 @@ public class CmsContentServiceImpl implements CmsContentService {
return pageInfo;
}
/**
* 内存分页方法
*
* @param list 原始数据列表
* @param pageNum 页码
* @param pageSize 每页大小
* @return 当前页的 list对应的页码没有数据则返回空 list
*/
private List<CmsContent> memoryPagination(List<CmsContent> list, int pageNum, int pageSize) {
// 参数校验
if (list == null) {
return new ArrayList<>();
}
if (pageNum < 1) {
pageNum = 1;
}
if (pageSize < 1) {
pageSize = 10;
}
// 计算总记录数
int total = list.size();
// 计算分页参数
int startIndex = (pageNum - 1) * pageSize;
int endIndex = Math.min(startIndex + pageSize, total);
// 截取分页数据
List<CmsContent> pageList = new ArrayList<>();
if (startIndex < total) {
pageList = list.subList(startIndex, endIndex);
}
return pageList;
}
/**
* 查询列表
*
@ -146,6 +203,10 @@ public class CmsContentServiceImpl implements CmsContentService {
*/
@Override
public List<CmsContent> getList(CmsContentDto queryDto) {
// 设置默认语言类型为中文
if (queryDto.getLanguageType() == null) {
queryDto.setLanguageType(0);
}
return this.cmsContentMapper.getList(queryDto);
}
@ -374,7 +435,7 @@ public class CmsContentServiceImpl implements CmsContentService {
result = cmsContentLikeMapper.deleteById(existingLike.getLikeId());
// 减少内容的点赞数
if (content.getLikeCount() > 0) {
if (content != null && content.getLikeCount() > 0) {
content.setLikeCount(content.getLikeCount() - 1);
this.cmsContentMapper.update(content);
}
@ -648,4 +709,195 @@ public class CmsContentServiceImpl implements CmsContentService {
return pageInfo;
}
@Override
public int importFromExcel(byte[] fileBytes, String createBy) {
int successCount = 0;
final int BATCH_SIZE = 100; // 批量处理大小
try (InputStream inputStream = new ByteArrayInputStream(fileBytes);
ExcelReader reader = ExcelUtil.getReader(inputStream)) {
// 获取总行数包括标题行
int totalRows = reader.getRowCount();
if (totalRows <= 1) {
// 只有标题行或空文件
return 0;
}
Date now = new Date();
List<CmsContent> batchList = new ArrayList<>(BATCH_SIZE);
// 读取标题行
List<Object> headerObjList = reader.readRow(0);
if (headerObjList == null || headerObjList.isEmpty()) {
return 0;
}
// 转换为List<String>
List<String> headerList = new ArrayList<>();
for (Object obj : headerObjList) {
headerList.add(obj != null ? obj.toString() : "");
}
// 从第二行开始读取数据第一行为标题行
for (int rowIndex = 1; rowIndex < totalRows; rowIndex++) {
List<Object> rowList = reader.readRow(rowIndex);
if (rowList == null || rowList.isEmpty()) {
continue;
}
// 转换为Map<String, Object>
Map<String, Object> row = new HashMap<>();
for (int i = 0; i < headerList.size() && i < rowList.size(); i++) {
row.put(headerList.get(i), rowList.get(i));
}
if (row.isEmpty()) {
continue;
}
CmsContent cmsContent = new CmsContent();
// 设置创建时间和更新时间
cmsContent.setCreateTime(now);
cmsContent.setUpdateTime(now);
cmsContent.setCreateBy(createBy);
cmsContent.setUpdateBy(createBy);
// 设置默认值
cmsContent.setDeleteFlag(0);
cmsContent.setAuditStatus(1); // 默认草稿状态
cmsContent.setPublishStatus(1); // 默认未发布状态
cmsContent.setViewCount(0);
cmsContent.setLikeCount(0);
cmsContent.setCommentCount(0);
cmsContent.setSort(0);
// 读取Excel中的字段
// content_id - 数据库自动生成不需要读取
cmsContent.setTitle(getStringValue(row, "title"));
cmsContent.setTitleEn(getStringValue(row, "title_en"));
cmsContent.setOrigin(getStringValue(row, "origin"));
cmsContent.setTags(Objects.requireNonNull(getStringValue(row, "tags")).replaceAll(" ",""));
cmsContent.setIcon(getStringValue(row, "icon"));
cmsContent.setIsOfficial(getBooleanValue(row, "is_official"));
cmsContent.setPrice(getBigDecimalValue(row, "price"));
cmsContent.setLikeCount(getIntegerValue(row, "like_count"));
cmsContent.setShareCount(getIntegerValue(row, "share_count"));
cmsContent.setContentType(getIntegerValue(row, "content_type"));
cmsContent.setContent(getStringValue(row, "content"));
cmsContent.setContentEn(getStringValue(row, "content_en"));
cmsContent.setAuditStatus(getIntegerValue(row, "audit_status"));
cmsContent.setPublishStatus(getIntegerValue(row, "publish_status"));
cmsContent.setPublishTime(getDateValue(row, "publish_time"));
cmsContent.setViewCount(getIntegerValue(row, "view_count"));
cmsContent.setCommentCount(getIntegerValue(row, "comment_count"));
cmsContent.setIsPaid(getIntegerValue(row, "is_paid"));
cmsContent.setSupportPointsPay(getIntegerValue(row, "support_points_pay"));
cmsContent.setDescription(getStringValue(row, "description"));
cmsContent.setDescriptionEn(getStringValue(row, "description_en"));
cmsContent.setIntroduce(getStringValue(row, "introduce"));
cmsContent.setIntroduceEn(getStringValue(row, "introduce_en"));
// create_time - 由系统生成不需要读取
// update_time - 由系统生成不需要读取
cmsContent.setDeleteFlag(getIntegerValue(row, "delete_flag"));
batchList.add(cmsContent);
// 达到批量大小或最后一行时执行批量插入
if (batchList.size() >= BATCH_SIZE || rowIndex == totalRows - 1) {
if (!batchList.isEmpty()) {
// 执行批量插入
this.cmsContentMapper.batchInsert(batchList);
successCount += batchList.size();
batchList.clear(); // 清空批次
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return successCount;
}
/**
* 从Map中获取字符串值
*/
private String getStringValue(Map<String, Object> row, String key) {
Object value = row.get(key);
return value != null ? value.toString() : null;
}
/**
* 从Map中获取布尔值
*/
private Boolean getBooleanValue(Map<String, Object> row, String key) {
Object value = row.get(key);
if (value == null) {
return null;
}
if (value instanceof Boolean) {
return (Boolean) value;
}
if (value instanceof String) {
return Boolean.parseBoolean((String) value);
}
return null;
}
/**
* 从Map中获取整数值
*/
private Integer getIntegerValue(Map<String, Object> row, String key) {
Object value = row.get(key);
if (value == null) {
return null;
}
if (value instanceof Number) {
return ((Number) value).intValue();
}
if (value instanceof String) {
try {
return Integer.parseInt((String) value);
} catch (NumberFormatException e) {
return null;
}
}
return null;
}
/**
* 从Map中获取BigDecimal值
*/
private BigDecimal getBigDecimalValue(Map<String, Object> row, String key) {
Object value = row.get(key);
if (value == null) {
return null;
}
if (value instanceof Number) {
return BigDecimal.valueOf(((Number) value).doubleValue());
}
if (value instanceof String) {
try {
return new BigDecimal((String) value);
} catch (NumberFormatException e) {
return null;
}
}
return null;
}
/**
* 从Map中获取日期值
*/
private Date getDateValue(Map<String, Object> row, String key) {
Object value = row.get(key);
if (value == null) {
return null;
}
if (value instanceof Date) {
return (Date) value;
}
return null;
}
}

View File

@ -310,4 +310,91 @@ public class SkillGenServiceImpl implements SkillGenService {
return null;
}
@Override
public CmsContent uploadSkill(String skillUrl) {
log.info("上传技能压缩包请求: {}", skillUrl);
String url = deepSeekConfig.getBaseUrl() + "/v1/chat/completions";
// 从数据库中读取cms_tag表的标签信息
CmsTagDto tagDto = new CmsTagDto();
tagDto.setDeleteFlag(0);
tagDto.setStatus(1);
List<CmsTag> tags = cmsTagService.getList(tagDto);
// 将标签名称拼接成逗号分隔的字符串
StringBuilder tagsList = new StringBuilder();
for (int i = 0; i < tags.size(); i++) {
CmsTag tag = tags.get(i);
tagsList.append(tag.getTagId()+"."+tag.getTagName());
if (i < tags.size() - 1) {
tagsList.append("");
}
}
// 构建系统消息内容
String systemContent = """
你是一位专业的AI技能包解析助手需完成以下任务
1. 我会提供一个技能包压缩包格式包含zip/rar的URL你需解析该压缩包根目录下的SKILL.md文件; 或者提供一个在线的SKILL.md文件的url
2. 基于SKILL.md内容提炼出
- skill的核心描述description
- 详细功能介绍introduce
- 从指定标签列表中选取至少3个适配标签tagList标签范围TAG_LIST
- 选择标签的时候只需要输出对应的标签编号
3. 生成content字段基于技能包的名称描述标签按照skills目录结构输出完整的技能包YAML内容包含skills.md本体scripts目录脚本等需遵循以下严格规范
- 包含技能包必需的文件和目录
- 多行内容使用|字面块表示
- 所有内容从行首开始无前置空格
- 空目录标注为children: []
- 文件内容需具备实际使用价值
- YAML文档需完整核心概要包含nameversiondescriptionauthorcreatedtags等属性
- 核心节点为structure用于描述技能包文件目录结构structure下每个节点需包含基础属性nametypepathformatdescriptioncontent和children为互选属性type为file时content字段填写文件内容type为directory时children数组填写子目录/文件节点
请将最终结果以JSON格式输出JSON结构必须包含description技能描述introduce功能介绍tagList标签列表content完整YAML格式技能包内容无需额外说明仅输出符合要求的JSON内容
""";
systemContent = systemContent.replace("TAG_LIST", tagsList.toString());
// 构建用户消息内容
String userContent = skillUrl;
// 创建技能请求
SkillRequest skillRequest = new SkillRequest(true, deepSeekConfig.getChat().getModel(), systemContent, userContent, 0.5, 8192, "json_object");
try {
// 发送HTTP请求到DeepSeek API
String deepseekResponse = HttpUtil.sendPostRequest(url, skillRequest, deepSeekConfig.getApiKey(), null);
log.info("Deepseek API响应: {}", deepseekResponse);
// 解析返回结果
JSONObject responseJson = JSON.parseObject(deepseekResponse);
List<JSONObject> choices = responseJson.getJSONArray("choices").toJavaList(JSONObject.class);
if (choices != null && !choices.isEmpty()) {
// 获取最新的choice
JSONObject latestChoice = choices.get(0);
JSONObject message = latestChoice.getJSONObject("message");
String content = message.getString("content");
// 解析content中的JSON
JSONObject skillJson = JSON.parseObject(content);
// 构建技能生成请求
SkillGenRequest request = new SkillGenRequest();
request.setName(skillJson.getString("name"));
request.setDescription(skillJson.getString("description"));
request.setRequirement(skillJson.getString("introduce"));
request.setTags(skillJson.getJSONArray("tagList").toJavaList(String.class));
// 生成CmsContent对象
CmsContent cmsContent = getCmsContent(request, skillJson.getString("content"), StpUtil.getLoginIdAsLong(), "");
// 保存到数据库
cmsContentMapper.insert(cmsContent);
return cmsContent;
}
} catch (Exception e) {
log.error("调用Deepseek API失败: {}", e.getMessage(), e);
}
return null;
}
}

View File

@ -5,13 +5,17 @@
<resultMap type="com.kexue.skills.entity.CmsContent" id="CmsContentMap">
<result property="contentId" column="content_id" jdbcType="BIGINT"/>
<result property="title" column="title" jdbcType="VARCHAR"/>
<result property="titleEn" column="title_en" jdbcType="VARCHAR"/>
<result property="subtitle" column="subtitle" jdbcType="VARCHAR"/>
<result property="contentType" column="content_type" jdbcType="INTEGER"/>
<result property="summary" column="summary" jdbcType="VARCHAR"/>
<result property="description" column="description" jdbcType="LONGVARCHAR"/>
<result property="descriptionEn" column="description_en" jdbcType="LONGVARCHAR"/>
<result property="requirement" column="requirement" jdbcType="LONGVARCHAR"/>
<result property="introduce" column="introduce" jdbcType="LONGVARCHAR"/>
<result property="introduceEn" column="introduce_en" jdbcType="LONGVARCHAR"/>
<result property="content" column="content" jdbcType="LONGVARCHAR"/>
<result property="contentEn" column="content_en" jdbcType="LONGVARCHAR"/>
<result property="coverImage" column="cover_image" jdbcType="VARCHAR"/>
<result property="authorId" column="author_id" jdbcType="BIGINT"/>
<result property="authorName" column="author_name" jdbcType="VARCHAR"/>
@ -52,11 +56,37 @@
from cms_content
where content_id = #{contentId}
</select>
<!--查询单个带语言类型-->
<select id="queryByIdWithLanguage" resultMap="CmsContentMap">
select
content_id,
case when #{languageType} = 1 then title_en else title end as title,
subtitle,
content_type, summary,
case when #{languageType} = 1 then description_en else description end as description,
requirement,
case when #{languageType} = 1 then introduce_en else introduce end as introduce,
case when #{languageType} = 1 then content_en else content end as content,
cover_image, author_id, author_name,
reviewer_id, reviewer_name, audit_status, audit_comment, publish_status, publish_time,
view_count, like_count, comment_count, sort, is_paid, price, required_points, support_points_pay, is_official, share_count, file_url, icon, background, origin, tags, create_time, update_time, create_by, update_by, delete_flag
from cms_content
where content_id = #{contentId}
</select>
<!--查询分页列表-->
<select id="getPageList" resultMap="CmsContentMap">
select
content_id, title, subtitle, content_type, summary, description, requirement, introduce, content, cover_image, author_id, author_name,
content_id,
case when #{languageType} = 1 then title_en else title end as title,
subtitle,
content_type, summary,
case when #{languageType} = 1 then description_en else description end as description,
requirement,
case when #{languageType} = 1 then introduce_en else introduce end as introduce,
case when #{languageType} = 1 then content_en else content end as content,
cover_image, author_id, author_name,
reviewer_id, reviewer_name, audit_status, audit_comment, publish_status, publish_time,
view_count, like_count, comment_count, sort, is_paid, price, required_points, support_points_pay, is_official, share_count, file_url, icon, background, origin, tags, create_time, update_time, create_by, update_by, delete_flag
from cms_content
@ -113,7 +143,15 @@
<!--带分页的查询-->
<select id="getPageListWithPagination" resultMap="CmsContentMap">
select
content_id, title, subtitle, content_type, summary, description, requirement, introduce, content, cover_image, author_id, author_name,
content_id,
case when #{queryDto.languageType} = 1 then title_en else title end as title,
subtitle,
content_type, summary,
case when #{queryDto.languageType} = 1 then description_en else description end as description,
requirement,
case when #{queryDto.languageType} = 1 then introduce_en else introduce end as introduce,
case when #{queryDto.languageType} = 1 then content_en else content end as content,
cover_image, author_id, author_name,
reviewer_id, reviewer_name, audit_status, audit_comment, publish_status, publish_time,
view_count, like_count, comment_count, sort, is_paid, price, required_points, support_points_pay, is_official, share_count, file_url, icon, background, origin, tags, create_time, update_time, create_by, update_by, delete_flag
from cms_content
@ -217,7 +255,15 @@
<!--查询列表-->
<select id="getList" resultMap="CmsContentMap">
select
content_id, title, subtitle, content_type, summary, description, requirement, introduce, content, cover_image, author_id, author_name,
content_id,
case when #{languageType} = 1 then title_en else title end as title,
subtitle,
content_type, summary,
case when #{languageType} = 1 then description_en else description end as description,
requirement,
case when #{languageType} = 1 then introduce_en else introduce end as introduce,
case when #{languageType} = 1 then content_en else content end as content,
cover_image, author_id, author_name,
reviewer_id, reviewer_name, audit_status, audit_comment, publish_status, publish_time,
view_count, like_count, comment_count, sort, is_paid, price, required_points, support_points_pay, is_official, share_count, file_url, icon, background, origin, tags, create_time, update_time, create_by, update_by, delete_flag
from cms_content
@ -267,13 +313,26 @@
<!--新增所有列-->
<insert id="insert" keyProperty="contentId" useGeneratedKeys="true">
insert into cms_content(title, subtitle, content_type, summary, description, requirement, introduce, content, cover_image, author_id, author_name,
insert into cms_content(title, title_en, subtitle, content_type, summary, description, description_en, requirement, introduce, introduce_en, content, content_en, cover_image, author_id, author_name,
reviewer_id, reviewer_name, audit_status, audit_comment, publish_status, publish_time,
view_count, like_count, comment_count, sort, is_paid, price, required_points, support_points_pay, is_official, share_count, file_url, icon, background, origin, tags, create_time, update_time, create_by, update_by, delete_flag)
values (#{title}, #{subtitle}, #{contentType}, #{summary}, #{description}, #{requirement}, #{introduce}, #{content}, #{coverImage}, #{authorId}, #{authorName},
values (#{title}, #{titleEn}, #{subtitle}, #{contentType}, #{summary}, #{description}, #{descriptionEn}, #{requirement}, #{introduce}, #{introduceEn}, #{content}, #{contentEn}, #{coverImage}, #{authorId}, #{authorName},
#{reviewerId}, #{reviewerName}, #{auditStatus}, #{auditComment}, #{publishStatus}, #{publishTime},
#{viewCount}, #{likeCount}, #{commentCount}, #{sort}, #{isPaid}, #{price}, #{requiredPoints}, #{supportPointsPay}, #{isOfficial}, #{shareCount}, #{fileUrl}, #{icon}, #{background}, #{origin}, #{tags}, #{createTime}, #{updateTime}, #{createBy}, #{updateBy}, #{deleteFlag})
</insert>
<!--批量新增数据-->
<insert id="batchInsert" useGeneratedKeys="true" keyProperty="contentId">
insert into cms_content(title, title_en, subtitle, content_type, summary, description, description_en, requirement, introduce, introduce_en, content, content_en, cover_image, author_id, author_name,
reviewer_id, reviewer_name, audit_status, audit_comment, publish_status, publish_time,
view_count, like_count, comment_count, sort, is_paid, price, required_points, support_points_pay, is_official, share_count, file_url, icon, background, origin, tags, create_time, update_time, create_by, update_by, delete_flag)
values
<foreach collection="cmsContentList" item="item" separator=",">
(#{item.title}, #{item.titleEn}, #{item.subtitle}, #{item.contentType}, #{item.summary}, #{item.description}, #{item.descriptionEn}, #{item.requirement}, #{item.introduce}, #{item.introduceEn}, #{item.content}, #{item.contentEn}, #{item.coverImage}, #{item.authorId}, #{item.authorName},
#{item.reviewerId}, #{item.reviewerName}, #{item.auditStatus}, #{item.auditComment}, #{item.publishStatus}, #{item.publishTime},
#{item.viewCount}, #{item.likeCount}, #{item.commentCount}, #{item.sort}, #{item.isPaid}, #{item.price}, #{item.requiredPoints}, #{item.supportPointsPay}, #{item.isOfficial}, #{item.shareCount}, #{item.fileUrl}, #{item.icon}, #{item.background}, #{item.origin}, #{item.tags}, #{item.createTime}, #{item.updateTime}, #{item.createBy}, #{item.updateBy}, #{item.deleteFlag})
</foreach>
</insert>
<!--通过主键修改数据-->
<update id="update">
@ -282,6 +341,9 @@
<if test="title != null and title != ''">
title = #{title},
</if>
<if test="titleEn != null and titleEn != ''">
title_en = #{titleEn},
</if>
<if test="subtitle != null">
subtitle = #{subtitle},
</if>
@ -294,15 +356,24 @@
<if test="description != null">
description = #{description},
</if>
<if test="descriptionEn != null">
description_en = #{descriptionEn},
</if>
<if test="requirement != null">
requirement = #{requirement},
</if>
<if test="introduce != null">
introduce = #{introduce},
</if>
<if test="introduceEn != null">
introduce_en = #{introduceEn},
</if>
<if test="content != null">
content = #{content},
</if>
<if test="contentEn != null">
content_en = #{contentEn},
</if>
<if test="coverImage != null">
cover_image = #{coverImage},
</if>