文章新增、修改待完成

This commit is contained in:
xiao-fajia 2024-07-24 17:24:35 +08:00
parent 8d500a947b
commit 67ea39901c
18 changed files with 439 additions and 140 deletions

View File

@ -2,8 +2,14 @@ package com.ruoyi.cms.config;
import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.IdUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
/**
* 新增工具Config
@ -15,11 +21,31 @@ import org.springframework.context.annotation.Configuration;
public class AppConfig {
/**
* 用雪花算法算成ID需要在实体类用到的字段上加上@JsonSerialize(using = ToStringSerializer.class)注解不然会丢失精度
* 用雪花算法算成ID
* @return
*/
@Bean
public Snowflake snowflake(){
return IdUtil.getSnowflake(1,1);
}
/**
* 解决雪花ID精度丢失问题
* @param builder
* @return
*/
@Bean
@Primary
@ConditionalOnMissingBean(ObjectMapper.class)
public ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder)
{
ObjectMapper objectMapper = builder.createXmlMapper(false).build();
// 全局配置序列化返回 JSON 处理
SimpleModule simpleModule = new SimpleModule();
//JSON Long ==> String
simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
objectMapper.registerModule(simpleModule);
return objectMapper;
}
}

View File

@ -127,4 +127,12 @@ public class CmsCategoryController extends BaseController
}
return toAjax(cmsCategoryService.deleteCmsCategoryById(id));
}
/**
* 根据栏目ID查其所有的文章
*/
@GetMapping("/content/{id}")
public AjaxResult getContentByCategoryId(@PathVariable Long id){
return success(cmsCategoryService.getContentById(id));
}
}

View File

@ -1,11 +1,13 @@
package com.ruoyi.cms.controller;
import java.security.Principal;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import com.ruoyi.cms.domain.CmsCategory;
import com.ruoyi.cms.service.ICmsCategoryService;
import com.ruoyi.common.core.domain.entity.SysDept;
import org.apache.ibatis.annotations.Delete;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
@ -104,9 +106,9 @@ public class CmsContentController extends BaseController
@PreAuthorize("@ss.hasPermi('cms:content:remove')")
@Log(title = "文章", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public AjaxResult remove(@PathVariable Long[] ids)
public AjaxResult remove(@PathVariable Long[] ids, Principal principal)
{
return toAjax(cmsContentService.deleteCmsContentByIds(ids));
return toAjax(cmsContentService.deleteCmsContentByIds(ids, principal.getName()));
}
/**
@ -118,4 +120,26 @@ public class CmsContentController extends BaseController
{
return success(cmsCategoryService.selectCmsCategoryTreeList(category));
}
/**
* 恢复记录
*/
@Log(title = "文章", businessType = BusinessType.DELETE)
@PutMapping("/{ids}")
public AjaxResult recoverContentByIds(@PathVariable Long[] ids, Principal principal)
{
return toAjax(cmsContentService.recoverContentByIds(ids, principal.getName()));
}
/**
* 发布文章改变文章状态时用
* @param ids
* @param principal
* @return
*/
@Log(title = "文章", businessType = BusinessType.UPDATE)
@PutMapping("/changeStatus/{ids}")
public AjaxResult changeContentByIds(@PathVariable Long[] ids, Principal principal){
return toAjax(cmsContentService.changeContentByIds(ids, principal.getName()));
}
}

View File

@ -1,6 +1,8 @@
package com.ruoyi.cms.domain;
import com.alibaba.fastjson2.annotation.JSONField;
import com.baomidou.mybatisplus.annotation.TableField;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import lombok.Data;
@ -21,7 +23,6 @@ public class CmsCategory extends BaseEntity
{
private static final long serialVersionUID = 1L;
@JsonSerialize(using = ToStringSerializer.class)
/** 栏目ID */
private Long id;
@ -37,7 +38,6 @@ public class CmsCategory extends BaseEntity
@Excel(name = "栏目路径")
private String categoryUrl;
@JsonSerialize(using = ToStringSerializer.class)
/** 父栏目ID */
@Excel(name = "父栏目ID")
private Long parentId;

View File

@ -1,5 +1,6 @@
package com.ruoyi.cms.domain;
import com.alibaba.fastjson2.annotation.JSONField;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
@ -22,11 +23,9 @@ public class CmsContent extends BaseEntity
{
private static final long serialVersionUID = 1L;
@JsonSerialize(using = ToStringSerializer.class)
/** 主键ID */
private Long id;
@JsonSerialize(using = ToStringSerializer.class)
/** 所属栏目ID */
@Excel(name = "所属栏目ID")
private Long categoryId;

View File

@ -4,6 +4,7 @@ import java.util.List;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ruoyi.cms.domain.CmsContent;
import org.apache.ibatis.annotations.Param;
/**
* 文章Mapper接口

View File

@ -51,7 +51,7 @@ public interface ICmsContentService extends IService<CmsContent>
* @param ids 需要删除的文章主键集合
* @return 结果
*/
public int deleteCmsContentByIds(Long[] ids);
public int deleteCmsContentByIds(Long[] ids, String username);
/**
* 删除文章信息
@ -60,4 +60,16 @@ public interface ICmsContentService extends IService<CmsContent>
* @return 结果
*/
public int deleteCmsContentById(Long id);
/**
* 恢复记录
*/
int recoverContentByIds(Long[] ids, String username);
/**
* 发布文章改变文章状态时用
* @param ids
* @return
*/
int changeContentByIds(Long[] ids, String username);
}

View File

@ -30,13 +30,12 @@ import javax.annotation.Resource;
/**
* 栏目Service业务层处理
*
*
* @author 点亮信息
* @date 2024-07-18
*/
@Service
public class CmsCategoryServiceImpl extends ServiceImpl<CmsCategoryMapper, CmsCategory> implements ICmsCategoryService
{
public class CmsCategoryServiceImpl extends ServiceImpl<CmsCategoryMapper, CmsCategory> implements ICmsCategoryService {
@Autowired
private Snowflake snowflake;
@ -45,37 +44,34 @@ public class CmsCategoryServiceImpl extends ServiceImpl<CmsCategoryMapper, CmsCa
/**
* 查询栏目
*
*
* @param id 栏目主键
* @return 栏目
*/
@Override
public CmsCategory selectCmsCategoryById(Long id)
{
public CmsCategory selectCmsCategoryById(Long id) {
return baseMapper.selectCmsCategoryById(id);
}
/**
* 查询栏目列表
*
*
* @param cmsCategory 栏目
* @return 栏目
*/
@Override
public List<CmsCategory> selectCmsCategoryList(CmsCategory cmsCategory)
{
public List<CmsCategory> selectCmsCategoryList(CmsCategory cmsCategory) {
return baseMapper.selectCmsCategoryList(cmsCategory);
}
/**
* 新增栏目
*
*
* @param cmsCategory 栏目
* @return 结果
*/
@Override
public int insertCmsCategory(CmsCategory cmsCategory)
{
public int insertCmsCategory(CmsCategory cmsCategory) {
cmsCategory.setId(snowflake.nextId());
cmsCategory.setCreateTime(DateUtils.getNowDate());
return baseMapper.insertCmsCategory(cmsCategory);
@ -83,26 +79,24 @@ public class CmsCategoryServiceImpl extends ServiceImpl<CmsCategoryMapper, CmsCa
/**
* 修改栏目
*
*
* @param cmsCategory 栏目
* @return 结果
*/
@Override
public int updateCmsCategory(CmsCategory cmsCategory)
{
public int updateCmsCategory(CmsCategory cmsCategory) {
cmsCategory.setUpdateTime(DateUtils.getNowDate());
return baseMapper.updateCmsCategory(cmsCategory);
}
/**
* 删除栏目信息
*
*
* @param id 栏目主键
* @return 结果
*/
@Override
public int deleteCmsCategoryById(Long id)
{
public int deleteCmsCategoryById(Long id) {
return baseMapper.deleteCmsCategoryById(id);
}
@ -113,12 +107,10 @@ public class CmsCategoryServiceImpl extends ServiceImpl<CmsCategoryMapper, CmsCa
* @return 结果
*/
@Override
public boolean checkCmsCategoryNameUnique(CmsCategory category)
{
public boolean checkCmsCategoryNameUnique(CmsCategory category) {
Long menuId = StringUtils.isNull(category.getId()) ? -1L : category.getId();
CmsCategory info = baseMapper.checkCategoryNameUnique(category.getCategoryName(), category.getParentId());
if (StringUtils.isNotNull(info) && info.getId().longValue() != menuId.longValue())
{
if (StringUtils.isNotNull(info) && info.getId().longValue() != menuId.longValue()) {
return UserConstants.NOT_UNIQUE;
}
return UserConstants.UNIQUE;
@ -131,8 +123,7 @@ public class CmsCategoryServiceImpl extends ServiceImpl<CmsCategoryMapper, CmsCa
* @return 结果
*/
@Override
public boolean hasChildByCategoryId(Long id)
{
public boolean hasChildByCategoryId(Long id) {
int result = baseMapper.hasChildByCategoryId(id);
return result > 0;
}
@ -144,8 +135,7 @@ public class CmsCategoryServiceImpl extends ServiceImpl<CmsCategoryMapper, CmsCa
* @return 栏目树信息集合
*/
@Override
public List<TreeSelect> selectCmsCategoryTreeList(CmsCategory category)
{
public List<TreeSelect> selectCmsCategoryTreeList(CmsCategory category) {
List<CmsCategory> categorys = SpringUtils.getAopProxy(this).selectCmsCategoryList(category);
return buildCmsCategoryTreeSelect(categorys);
}
@ -157,20 +147,17 @@ public class CmsCategoryServiceImpl extends ServiceImpl<CmsCategoryMapper, CmsCa
* @return 树结构列表
*/
@Override
public List<CmsCategory> buildCmsCategoryTree(List<CmsCategory> categorys){
public List<CmsCategory> buildCmsCategoryTree(List<CmsCategory> categorys) {
List<CmsCategory> returnList = new ArrayList<CmsCategory>();
List<Long> tempList = categorys.stream().map(CmsCategory::getId).collect(Collectors.toList());
for (CmsCategory category : categorys)
{
for (CmsCategory category : categorys) {
// 如果是顶级节点, 遍历该父节点的所有子节点
if (!tempList.contains(category.getParentId()))
{
if (!tempList.contains(category.getParentId())) {
recursionFn(categorys, category);
returnList.add(category);
}
}
if (returnList.isEmpty())
{
if (returnList.isEmpty()) {
returnList = categorys;
}
return returnList;
@ -183,7 +170,7 @@ public class CmsCategoryServiceImpl extends ServiceImpl<CmsCategoryMapper, CmsCa
* @return 下拉树结构列表
*/
@Override
public List<TreeSelect> buildCmsCategoryTreeSelect(List<CmsCategory> categorys){
public List<TreeSelect> buildCmsCategoryTreeSelect(List<CmsCategory> categorys) {
List<CmsCategory> categoryTrees = buildCmsCategoryTree(categorys);
return categoryTrees.stream().map(NewTreeSelect::new).collect(Collectors.toList());
}
@ -191,15 +178,12 @@ public class CmsCategoryServiceImpl extends ServiceImpl<CmsCategoryMapper, CmsCa
/**
* 递归列表
*/
private void recursionFn(List<CmsCategory> list, CmsCategory t)
{
private void recursionFn(List<CmsCategory> list, CmsCategory t) {
// 得到子节点列表
List<CmsCategory> childList = getChildList(list, t);
t.setChildren(childList);
for (CmsCategory tChild : childList)
{
if (hasChild(list, tChild))
{
for (CmsCategory tChild : childList) {
if (hasChild(list, tChild)) {
recursionFn(list, tChild);
}
}
@ -208,15 +192,12 @@ public class CmsCategoryServiceImpl extends ServiceImpl<CmsCategoryMapper, CmsCa
/**
* 得到子节点列表
*/
private List<CmsCategory> getChildList(List<CmsCategory> list, CmsCategory t)
{
private List<CmsCategory> getChildList(List<CmsCategory> list, CmsCategory t) {
List<CmsCategory> tlist = new ArrayList<CmsCategory>();
Iterator<CmsCategory> it = list.iterator();
while (it.hasNext())
{
while (it.hasNext()) {
CmsCategory n = (CmsCategory) it.next();
if (StringUtils.isNotNull(n.getParentId()) && n.getParentId().longValue() == t.getId().longValue())
{
if (StringUtils.isNotNull(n.getParentId()) && n.getParentId().longValue() == t.getId().longValue()) {
tlist.add(n);
}
}
@ -226,46 +207,53 @@ public class CmsCategoryServiceImpl extends ServiceImpl<CmsCategoryMapper, CmsCa
/**
* 判断是否有子节点
*/
private boolean hasChild(List<CmsCategory> list, CmsCategory t)
{
private boolean hasChild(List<CmsCategory> list, CmsCategory t) {
return getChildList(list, t).size() > 0;
}
/**
* 获取栏目下的子栏目及文章
*
* @param id 顶层栏目ID
*/
@Override
public List<CMSCategoryVo> selectCmsCategoryAndContentTreeList(Long id) {
List<CmsCategory> categories = baseMapper.selectList(new QueryWrapper<CmsCategory>().eq("parent_id", id));
List<CMSCategoryVo> categoryVoList = new ArrayList<>();
for (CmsCategory category : categories){
List<CMSCategoryVo> categoryVoList = categories.stream().map(category -> {
CMSCategoryVo categoryVo = new CMSCategoryVo();
BeanUtil.copyProperties(category, categoryVo);
categoryVo.setChildren(getContentById(category.getId()));
categoryVoList.add(categoryVo);
}
return categoryVo;
}).collect(Collectors.toList());
return categoryVoList;
}
/**
* 按ID查文章
*
* @param id
* @return
*/
@Override
public PageInfo<CmsContent> getContentById(Long id){
public PageInfo<CmsContent> getContentById(Long id) {
PageHelper.startPage(1, 10);
List<CmsContent> contents = contentMapper.selectList(new QueryWrapper<CmsContent>().eq("category_id", id));
List<CmsContent> contents = contentMapper.selectList(new QueryWrapper<CmsContent>()
.and(item -> {
item.eq("category_id", id)
.eq("status", "1");
})
.orderByDesc("create_time")
);
return new PageInfo<CmsContent>(contents);
}
/**
* 获取所有的叶子节点
*
* @return
*/
@Override
public List<CmsCategory> getLeavesCategoryList(){
public List<CmsCategory> getLeavesCategoryList() {
return baseMapper.selectList(new QueryWrapper<CmsCategory>().ne("parent_id", 0));
}
}

View File

@ -1,10 +1,13 @@
package com.ruoyi.cms.service.impl;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import cn.hutool.core.lang.Snowflake;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.utils.DateUtils;
import io.swagger.models.auth.In;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.cms.mapper.CmsContentMapper;
@ -81,8 +84,21 @@ public class CmsContentServiceImpl extends ServiceImpl<CmsContentMapper, CmsCont
* @return 结果
*/
@Override
public int deleteCmsContentByIds(Long[] ids)
public int deleteCmsContentByIds(Long[] ids, String username)
{
/** 如果是第一次删除,就标记删除,移到回收站 */
if (baseMapper.selectCmsContentById(ids[0]).getDelFlag() == 0){
Integer result = 0;
for (Long id : ids){
CmsContent content = new CmsContent();
content.setId(id);
content.setDelFlag(1);
content.setUpdateBy(username);
content.setUpdateTime(new Date());
result += baseMapper.updateById(content);
}
return result;
}
return baseMapper.deleteCmsContentByIds(ids);
}
@ -97,4 +113,54 @@ public class CmsContentServiceImpl extends ServiceImpl<CmsContentMapper, CmsCont
{
return baseMapper.deleteCmsContentById(id);
}
/**
* 恢复记录
*/
@Override
public int recoverContentByIds(Long[] ids, String username){
Integer result = 0;
for (Long id : ids) {
CmsContent content = new CmsContent();
content.setId(id);
content.setDelFlag(0);
content.setUpdateBy(username);
content.setUpdateTime(new Date());
result += baseMapper.updateById(content);
}
return result;
}
/**
* 发布文章改变文章状态时用
* @param ids
* @return
*/
@Override
public int changeContentByIds(Long[] ids, String username){
// 下线
if (baseMapper.selectCmsContentById(ids[0]).getStatus().equals("1")){
Integer result = 0;
for (Long id : ids) {
CmsContent content = new CmsContent();
content.setId(id);
content.setUpdateBy(username);
content.setUpdateTime(new Date());
content.setStatus("2");
result += baseMapper.updateById(content);
}
return result;
}
// 发布
Integer result = 0;
for (Long id : ids) {
CmsContent content = new CmsContent();
content.setId(id);
content.setUpdateBy(username);
content.setUpdateTime(new Date());
content.setStatus("1");
result += baseMapper.updateById(content);
}
return result;
}
}

View File

@ -7,7 +7,7 @@
"imageCompressEnable": true, /* ,true */
"imageCompressBorder": 1600, /* */
"imageInsertAlign": "none", /* */
"imageUrlPrefix": "http://localhost:8080/", /* 访 */
"imageUrlPrefix": "http://localhost:8080", /* 访 */
"imagePathFormat": "image/{yyyy}{mm}{dd}/{time}{rand:6}", /* , */
/* {filename} , */
/* {rand:6} , */
@ -43,7 +43,7 @@
"videoActionName": "uploadvideo", /* action */
"videoFieldName": "upfile", /* */
"videoPathFormat": "video/{yyyy}{mm}{dd}/{time}{rand:6}", /* , */
"videoUrlPrefix": "http://localhost:8080/", /* 访 */
"videoUrlPrefix": "http://localhost:8080", /* 访 */
"videoMaxSize": 102400000, /* B100MB */
"videoAllowFiles": [ ".flv", ".swf", ".mkv", ".avi", ".rm", ".rmvb", ".mpeg", ".mpg", ".ogg", ".ogv", ".mov", ".wmv", ".mp4", ".webm", ".mp3", ".wav", ".mid"], /* */
/* */

View File

@ -33,7 +33,7 @@
</resultMap>
<sql id="selectCmsContentVo">
select id, category_id, content_type,image_url, video_url content_title, content_img, content_detail, source, source_url, original, author, editor, summary, status, publish_date, offline_date, is_accessory, accessory_url, remark, del_flag, create_time, create_by, update_time, update_by from cms_content
select id, category_id, content_type,image_url, video_url, content_title, content_img, content_detail, source, source_url, original, author, editor, summary, status, publish_date, offline_date, is_accessory, accessory_url, remark, del_flag, create_time, create_by, update_time, update_by from cms_content
</sql>
<select id="selectCmsContentList" parameterType="CmsContent" resultMap="CmsContentResult">
@ -41,7 +41,7 @@
<where>
<if test="categoryId != null "> and category_id = #{categoryId}</if>
<if test="contentType != null "> and content_type = #{contentType}</if>
<if test="contentTitle != null and contentTitle != ''"> and content_title = #{contentTitle}</if>
<if test="contentTitle != null and contentTitle != ''"> and content_title like concat('%', #{contentTitle}, '%')</if>
<if test="contentImg != null and contentImg != ''"> and content_img = #{contentImg}</if>
<if test="contentDetail != null and contentDetail != ''"> and content_detail = #{contentDetail}</if>
<if test="source != null and source != ''"> and source = #{source}</if>
@ -55,6 +55,7 @@
<if test="offlineDate != null "> and offline_date = #{offlineDate}</if>
<if test="isAccessory != null "> and is_accessory = #{isAccessory}</if>
<if test="accessoryUrl != null and accessoryUrl != ''"> and accessory_url = #{accessoryUrl}</if>
<if test="delFlag != null"> and del_flag = #{delFlag}</if>
</where>
</select>
@ -146,6 +147,7 @@
where id = #{id}
</update>
<delete id="deleteCmsContentById" parameterType="Long">
delete from cms_content where id = #{id}
</delete>

View File

@ -50,3 +50,19 @@ export function categoryTreeSelect() {
method: 'get'
})
}
// 恢复文章
export function recoverContentByIds(id) {
return request({
url: "/cms/content/" + id,
method: "put"
})
}
// 发布文章
export function changeContentByIds(id) {
return request({
url: "/cms/content/changeStatus/" + id,
method: "put"
})
}

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path fill="none" d="M0 0h24v24H0z"/><path d="M4.828 21l-.02.02-.021-.02H2.992A.993.993 0 0 1 2 20.007V3.993A1 1 0 0 1 2.992 3h18.016c.548 0 .992.445.992.993v16.014a1 1 0 0 1-.992.993H4.828zM20 15V5H4v14L14 9l6 6zm0 2.828l-6-6L6.828 19H20v-1.172zM8 11a2 2 0 1 1 0-4 2 2 0 0 1 0 4z"/></svg>

After

Width:  |  Height:  |  Size: 372 B

View File

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1662634780886" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2402" xmlns:xlink="http://www.w3.org/1999/xlink" width="16" height="16"><path d="M416 704c-6.4 0-9.6 0-16-3.2C390.4 694.4 384 684.8 384 672L384 352c0-12.8 6.4-22.4 16-28.8 9.6-6.4 22.4-6.4 32 0l256 166.4c9.6 6.4 16 16 16 28.8 0 9.6-6.4 22.4-16 25.6l-256 156.8C428.8 704 422.4 704 416 704zM448 409.6l0 204.8 163.2-99.2L448 409.6z" p-id="2403"></path><path d="M512 960C265.6 960 64 758.4 64 512S265.6 64 512 64s448 201.6 448 448S758.4 960 512 960zM512 128C300.8 128 128 300.8 128 512c0 211.2 172.8 384 384 384 211.2 0 384-172.8 384-384C896 300.8 723.2 128 512 128z" p-id="2404"></path></svg>

After

Width:  |  Height:  |  Size: 839 B

View File

@ -52,7 +52,8 @@
</el-col>
</el-row>
<el-row>
<el-form :model="queryParams" ref="queryForm" size="small" class="el-form-search" style="text-align:left;" :inline="true">
<el-form :model="queryParams" ref="queryForm" size="small" class="el-form-search" style="text-align:left;"
:inline="true">
<div class="mb12">
<el-form-item prop="contentTitle">
<el-input
@ -60,7 +61,7 @@
placeholder="请输入文章标题"
clearable
style="width: 200px"
@keyup.enter.native="handleQuery" />
@keyup.enter.native="handleQuery"/>
</el-form-item>
<el-form-item prop="contentType">
<el-select
@ -86,7 +87,7 @@
v-for="dict in dict.type.cms_content_status"
:key="dict.value"
:label="dict.label"
:value="dict.value" />
:value="dict.value"/>
</el-select>
</el-form-item>
<el-form-item>
@ -97,24 +98,30 @@
</el-form-item>
</div>
</el-form>
</el-row>
<el-table
v-loading="loading"
ref="tableContentList"
:data="contentList"
size="small"
@row-click="handleRowClick"
@cell-dblclick="handleEdit"
@selection-change="handleSelectionChange">
<el-table-column type="selection" width="50" align="center" />
<el-table-column label="文章标题" align="center" prop="contentTitle" />
<el-table-column label="缩略图" align="center" prop="contentImg" />
<el-table-column label="文章类型" align="center" prop="contentType" />
<el-table-column label="状态" align="center" prop="status" />
<el-table-column type="selection" width="50" align="center"/>
<el-table-column label="文章标题" align="center" prop="contentTitle"/>
<el-table-column label="文章类型" align="center" prop="contentType">
<template slot-scope="scope">
<dict-tag :options="dict.type.cms_content_type" :value="scope.row.contentType"/>
</template>
</el-table-column>
<el-table-column label="状态" align="center" prop="status">
<template slot-scope="scope">
<dict-tag :options="dict.type.cms_content_status" :value="scope.row.status"/>
</template>
</el-table-column>
<el-table-column label="创建时间" align="center" prop="createTime" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d}') }}</span>
<span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d} {h}:{m}:{s}') }}</span>
</template>
</el-table-column>
<el-table-column
@ -128,6 +135,7 @@
size="small"
type="text"
icon="el-icon-s-promotion"
:disabled="scope.row.status === '1'"
@click="handlePublish(scope.row)">发布</el-button>
</span>
<span class="btn-cell-wrap">
@ -135,15 +143,16 @@
size="small"
type="text"
icon="el-icon-download"
:disabled="scope.row.status !== '1'"
@click="handleOffline(scope.row)">下线</el-button>
</span>
<el-dropdown size="small">
<el-link :underline="false" class="row-more-btn" icon="el-icon-more"></el-link>
<el-dropdown-menu slot="dropdown">
<!-- 修改-->
<el-dropdown-item icon="el-icon-edit" @click.native="handleEdit(scope.row)" >修改</el-dropdown-item>
<el-dropdown-item icon="el-icon-edit" @click.native="handleEdit(scope.row)">修改</el-dropdown-item>
<!-- 删除-->
<el-dropdown-item icon="el-icon-delete" @click.native="handleDelete(scope.row)" >删除</el-dropdown-item>
<el-dropdown-item icon="el-icon-delete" @click.native="handleDelete(scope.row)">删除</el-dropdown-item>
<!-- 下线-->
</el-dropdown-menu>
</el-dropdown>
@ -155,15 +164,22 @@
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList" />
@pagination="getList"/>
</div>
</template>
<script>
import {delContent, getContent, listContent} from "@/api/cms/content";
import {changeContentByIds, delContent, getContent, listContent} from "@/api/cms/content";
export default {
name: "CMSContentList",
dicts: ['cms_content_type', 'cms_content_status'],
props: {
cid: {
type: String,
defaultValue: undefined,
required: false
}
},
data() {
return {
//
@ -176,21 +192,40 @@ export default {
contentTitle: undefined,
contentType: undefined,
status: undefined,
catalogId: undefined,
sorts: ''
categoryId: "0",
delFlag: "0",
},
total: 0,
}
},
watch: {
cid(newVal) {
this.queryParams = {
pageNum: 1,
pageSize: 10,
categoryId: newVal,
delFlag: "0"
}
this.getList()
}
},
created() {
if (this.cid === "") {
this.queryParams.categoryId = "0"
} else {
this.queryParams.categoryId = this.cid.toString()
}
this.getList();
},
methods: {
/** 新增按钮操作 */
handleAdd() {
this.$router.push({path: '/content/editor'})
this.$router.push({path: '/content/editor', query: {"categoryId": this.queryParams.categoryId}})
},
/** 删除按钮操作 */
handleDelete(row) {
const ids = row.id || this.ids;
this.$modal.confirm('是否确认删除文章编号为"' + ids + '"的数据项?').then(function () {
const ids = row.id ? [row.id] : this.selectedRows.map(row => row.id);
this.$modal.confirm('是否确认删除所选文章?').then(function () {
return delContent(ids);
}).then(() => {
this.getList();
@ -198,7 +233,7 @@ export default {
}).catch(() => {
});
},
handleSelectionChange (selection) {
handleSelectionChange(selection) {
this.selectedRows = selection;
this.single = selection.length != 1;
this.multiple = !selection.length;
@ -215,13 +250,38 @@ export default {
},
//
handlePublish(row) {
const statues = row.status ? [row.status] : this.selectedRows.map(row => row.status)
if (statues.includes("1")) {
this.$modal.msgError("所选文章已发布!!!");
} else {
const ids = row.id ? [row.id] : this.selectedRows.map(row => row.id);
this.$modal.confirm('是否确认下线所选文章?').then(function () {
return changeContentByIds(ids);
}).then(() => {
this.getList();
this.$modal.msgSuccess("下线成功");
}).catch(() => {
});
}
},
// 线
handleOffline(row) {
const statues = row.status ? [row.status] : this.selectedRows.map(row => row.status)
if (!statues.includes("1")) {
this.$modal.msgError("所选文章为初稿或已下线文章,不能下线!!!");
} else {
const ids = row.id ? [row.id] : this.selectedRows.map(row => row.id);
this.$modal.confirm('是否确认下线所选文章?').then(function () {
return changeContentByIds(ids);
}).then(() => {
this.getList();
this.$modal.msgSuccess("下线成功");
}).catch(() => {
});
}
},
//
handleQuery () {
handleQuery() {
this.queryParams.page = 1;
this.getList();
},
@ -235,17 +295,17 @@ export default {
});
},
//
resetQuery () {
resetQuery() {
this.resetForm("queryForm");
this.handleQuery();
},
//
handleRowClick (currentRow) {
handleRowClick(currentRow) {
this.toggleAllCheckedRows();
this.$refs.tableContentList.toggleRowSelection(currentRow);
},
//
handleEdit (row) {
handleEdit(row) {
// this.handleAdd(row.catalogId, row.contentId, row.contentType);
},
toggleAllCheckedRows() {
@ -261,27 +321,34 @@ export default {
.cms-content-list .head-container .el-select .el-input {
width: 110px;
}
.cms-content-list .el-divider {
margin-top: 10px;
}
.cms-content-list .el-tabs__header {
margin-bottom: 10px;
}
.cms-content-list .pagination-container {
height: 30px;
}
.cms-content-list .row-more-btn {
padding-left: 10px;
}
.cms-content-list .top-icon {
font-weight: bold;
font-size: 12px;
color:green;
color: green;
}
.cms-content-list .content_attr {
margin-left: 2px;
}
.mb12{
.mb12 {
margin-bottom: 12px;
}
</style>

View File

@ -92,11 +92,19 @@
width="50"
align="center" />
<el-table-column label="文章标题" :show-overflow-tooltip="true" prop="contentTitle" />
<el-table-column label="文章类型" align="center" prop="contentType" />
<el-table-column label="删除前状态" align="center" prop="status" />
<el-table-column label="文章类型" align="center" prop="contentType">
<template slot-scope="scope">
<dict-tag :options="dict.type.cms_content_type" :value="scope.row.contentType"/>
</template>
</el-table-column>
<el-table-column label="删除前状态" align="center" prop="status">
<template slot-scope="scope">
<dict-tag :options="dict.type.cms_content_status" :value="scope.row.status"/>
</template>
</el-table-column>
<el-table-column label="删除时间" align="center" prop="updateTime" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.updateTime, '{y}-{m}-{d}') }}</span>
<span>{{ parseTime(scope.row.updateTime, '{y}-{m}-{d} {h}:{m}:{s}') }}</span>
</template>
</el-table-column>
<el-table-column label="操作人" align="center" :show-overflow-tooltip="true" prop="updateBy" width="140" />
@ -110,7 +118,7 @@
size="small"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)">删除</el-button>
@click="handleDelete(scope.row)">彻底删除</el-button>
</template>
</el-table-column>
</el-table>
@ -124,9 +132,18 @@
</template>
<script>
import {delContent, listContent, recoverContentByIds} from "@/api/cms/content";
export default {
name: "CMSContentRecycleList",
dicts: ['cms_content_type', 'cms_content_status'],
props:{
cid:{
type: String,
defaultValue: undefined,
required: false
}
},
data() {
return {
//
@ -139,16 +156,51 @@ export default {
contentTitle: undefined,
contentType: undefined,
status: undefined,
catalogId: undefined,
categoryId: "0",
delFlag: "1"
},
total: 0,
}
},
watch:{
cid(newVal){
this.queryParams = {
pageNum: 1,
pageSize: 10,
categoryId: newVal,
delFlag: "1"
}
this.getRecycleList()
}
},
created() {
if (this.cid === ""){
this.queryParams.categoryId = "0"
}else {
this.queryParams.categoryId = this.cid.toString()
}
this.getRecycleList()
},
methods: {
//
getRecycleList() {},
getRecycleList() {
this.loading = true;
listContent(this.queryParams).then(response => {
this.contentRecycleList = response.rows;
this.total = response.total;
this.loading = false;
});
},
//
handleRecover(row) {
const ids = row.id ? [ row.id ] : this.selectedRows.map(row => row.id);
this.$modal.confirm('是否确认恢复所选文章?').then(function () {
return recoverContentByIds(ids);
}).then(() => {
this.getRecycleList();
this.$modal.msgSuccess("恢复成功");
}).catch(() => {
});
},
//
handleDelete(row) {

View File

@ -30,11 +30,11 @@
<el-tabs v-model="activeName" @tab-click="handleTabClick">
<!-- 内容列表-->
<el-tab-pane label="内容列表" name="contentList">
<cms-content-list v-if="activeName==='contentList'"></cms-content-list>
<cms-content-list v-if="activeName==='contentList'" :cid="selectCategoryId"></cms-content-list>
</el-tab-pane>
<!-- 回收站-->
<el-tab-pane label="回收站" name="recycle">
<cms-recycle-list v-if="activeName==='recycle'"></cms-recycle-list>
<cms-recycle-list v-if="activeName==='recycle'" :cid="selectCategoryId"></cms-recycle-list>
</el-tab-pane>
</el-tabs>
</el-row>
@ -54,6 +54,7 @@ export default {
dicts: ['cms_category_disable', "cms_content_type"],
data() {
return {
selectCategoryId: '',
activeName: "contentList",
//
contentList: null,
@ -159,8 +160,7 @@ export default {
},
//
handleNodeClick(data) {
this.queryParams.deptId = data.id;
this.handleQuery();
this.selectCategoryId = data.id;
},
/** 查询栏目下拉树结构 */
getCategoryTree() {
@ -180,6 +180,7 @@ export default {
this.multiple = !selection.length
},
handleTabClick (tab, event) {
},
}
};

View File

@ -24,9 +24,9 @@
</el-form-item>
</div>
<div class="art-title bg-purple-white">
<el-form-item label="文章描述" prop="contentDescription">
<el-form-item label="文章描述" prop="summary">
<el-input
v-model="form.contentDescription"
v-model="form.summary"
maxlength="360"
show-word-limit>
</el-input>
@ -59,16 +59,16 @@
/>
</div>
<div v-if="isType === '1'" class="content bg-purple-white">
<el-upload limit="1"
action="https://jsonplaceholder.typicode.com/posts/"
list-type="picture-card"
:on-preview="handlePictureCardPreview"
:on-remove="handleRemove">
<i class="el-icon-plus"></i>
</el-upload>
<el-dialog :visible.sync="dialogVisible">
<img width="100%" :src="dialogImageUrl" alt="">
</el-dialog>
<div class="btn-add-image bg-purple-white" @click="addImage">
<svg-icon icon-class="image" style="width:60px;height:60px;"></svg-icon>
<div>添加图片</div>
</div>
</div>
<div v-if="isType === '2'" class="content bg-purple-white">
<div class="btn-add bg-purple-white" @click="addItem">
<svg-icon icon-class="video" style="width:60px;height:60px;"></svg-icon>
<div>添加视频</div>
</div>
</div>
</el-card>
</el-col>
@ -79,8 +79,8 @@
<el-card shadow="always">
<el-tabs v-model="activeName">
<el-tab-pane label="文章属性" name="basic">
<el-form-item label="所属栏目" prop="catalogId">
<el-select v-model="form.categoryId" placeholder="">
<el-form-item label="所属栏目" prop="categoryId">
<el-select v-model="form.categoryId" placeholder="所属栏目">
<el-option
v-for="item in categoryList"
:key="item.id"
@ -89,9 +89,10 @@
</el-option>
</el-select>
</el-form-item>
<el-form-item label="封面" prop="logo">
<!-- <cms-logo-view v-model="form.logo" :src="form.logoSrc"-->
<!-- :width="210" :height="150"></cms-logo-view>-->
<el-form-item label="缩略图" prop="logo" >
<div class="no-picture" style="width: 200px;height: 140px;font-size: 145px">
<svg-icon icon-class="upload" @click="handleEdit"></svg-icon>
</div>
</el-form-item>
<el-form-item label="作者" prop="author">
<el-input v-model="form.author" />
@ -102,13 +103,10 @@
<el-form-item label="原创" prop="original">
<el-switch
v-model="form.original"
active-value="Y"
inactive-value="N"
active-value="0"
inactive-value="1"
></el-switch>
</el-form-item>
<el-form-item label="摘要" prop="summary">
<el-input type="textarea" v-model="form.summary" :autosize="summaryInputSize" maxlength="500" show-word-limit />
</el-form-item>
<el-form-item label="来源" prop="source">
<el-input v-model="form.source" />
</el-form-item>
@ -146,11 +144,12 @@ export default {
},
data() {
return {
uploadLimit: 1,
openResourceDialog: false,
imgUploadUrl: process.env.VUE_APP_BASE_API + "/ueditor/config?action=uploadimage",
isType: "0",
activeName: "basic",
summaryInputSize: { minRows: 3, maxRows: 6 },
dialogImageUrl: '',
dialogVisible: false,
//
form: {
contentType: "0",
@ -158,14 +157,15 @@ export default {
contentJson: [],
contentHtml: "",
downloadRemoteImage: "Y",
original: "N",
original: "0",
publishPipe: [],
imageList: [],
tags:[],
keywords:[]
},
rules: {
contentTitle: [{ required: true, message: "文章标题不能为空", trigger: "blur" }]
contentTitle: [{ required: true, message: "文章标题不能为空", trigger: "blur" }],
categoryId: [{required: true, methods: "所属栏目不能为空", trigger: "blur"}]
},
editorConfig: {
initialFrameHeight: 1000, //
@ -193,17 +193,52 @@ export default {
handleChangeType(){
this.isType = this.form.contentType
},
handleRemove(file, fileList) {
console.log(file, fileList);
addImage () {
this.editIndex = -1;
this.uploadLimit = 1;
this.openResourceDialog = true;
},
addItem () {
this.editIndex = -1;
this.uploadLimit = 1;
this.resourceType = 'video';
this.openResourceDialog = true;
},
handleEdit () {
this.openResourceDialog = true;
},
handlePictureCardPreview(file) {
this.dialogImageUrl = file.url;
this.dialogVisible = true;
}
}
}
</script>
<style scoped>
<style lang="scss" scoped>
.btn-add-image {
width: 100%;
text-align: center;
display: inline-block;
cursor: pointer;
fill: #5a5e66;
}
.btn-add-image:hover {
color:#1890ff;
}
.btn-add {
width: 100%;
text-align: center;
display: inline-block;
cursor: pointer;
fill: #5a5e66;
}
.btn-add:hover {
color:#1890ff;
}
.no-picture {
border: 3px dashed #a7a7a7;
text-align: center;
color: #777;
cursor: pointer;
}
.no-picture:hover {
color: #409EFF;
}
</style>