前后端开发之——文章分类管理

2024-04-03 08:36
文章标签 开发 文章 分类管理

本文主要是介绍前后端开发之——文章分类管理,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

原文地址:前后端开发之——文章分类管理 - Pleasure的博客

下面是正文内容:

前言

上回书说到

文章管理系统之添加文章分类。就是通过点击“新建文章分类”按钮从而在服务端数据库中增加一个文章分类。

对于文章分类这个对象,增删改查属于配套的基础操作。这篇博文就主要聚焦于“增”之外的“删改查”配套操作。这里的查不是指搜索,而是指查询数据库信息用于前端显示。

前端使用语言:Vue,后端使用语言:SpringBoot

正文

前端思路分析

当用户点击界面上的按钮后跳出之前的弹窗,

修改完相关信息后点击确认触发按钮绑定的updateCategory函数向后端发送表单,

updateCategory函数在开头的script部分进行了声明是调用后端修改文章分类接口的异步函数

updateCategory函数中的articleCategoryUpdateService服务在api文件夹下的article.js文件中进行了定义,以put的方式向后端“/category”发送id,categoryName,categoryAlias的值用来修改数据库中的记录。

“删”同理,点击按钮触发deleteCategory函数。

函数,弹窗,表单,接口都有自己对应的代码

后端思路分析

后端文件结构需要查看专栏之前的文章,这里就不重复进行申明了

数据访问层CategoryMapper.java,定义CategoryMapper函数用于向数据库添加数据,

服务层CategoryService.java中先声明接口,然后在CategoryServiceImpl.java中定义CategoryService函数通过调用ControllerMapper函数实现添加,(不要忘记在pojo文件夹下声明Category类)

请求层CategoryController.java,调用服务层的函数categoryService.add(category)通过post/get/put等不同的方式实现添加。

需要注意的是:

由于新增文章分类的时候向后端发送的json文件不携带id字段,是由数据库中的id主键自动生成,而更新和删除操作向后端发送的json文件则需要携带,所以在pojo文件夹下声明Category类时需要进行注解分组校验。

页面展示

实现代码

部分项目结构和代码需要参考专栏之前的文章

前端Vue

categorys和categoryModel的声明略

采用了element-plus的UI交互组件,官方参考文档:Overview 组件总览 | Element Plus

根据自己的需要自行拼接

api文件夹下的article.js(接口,删除操作相对于新增需要额外携带id字段作为区别)

import request from '@/utils/request.js'
export const articleCategoryListService = ()=>{return request.get('/category')
}
//文章分类添加
export const articleCategoryAddService = (categoryData)=>{return request.post('/category',categoryData)
}
//文章分类修改
export const articleCategoryUpdateService = (categoryData)=>{return request.put('/category',categoryData)
}
//文章分类删除
export const articleCategoryDeleteService = (id)=>{return request.delete('/category?id='+id)
}

声明要用到的异步函数(放在script部分)

/声明一个异步的函数
import { articleCategoryListService, articleCategoryAddService, articleCategoryUpdateService, articleCategoryDeleteService } from '@/api/article.js'
const articleCategoryList = async () => {let result = await articleCategoryListService();categorys.value = result.data;}
articleCategoryList();

显示文章分类的函数(放在script部分)

//定义变量,控制标题的展示
const title = ref('')const showDialog = (row) => {dialogVisible.value = true; title.value = '编辑分类'//数据拷贝categoryModel.value.categoryName = row.categoryName;categoryModel.value.categoryAlias = row.categoryAlias;//扩展id属性,将来需要传递给后台,完成分类的修改categoryModel.value.id = row.id
}

编辑文章分类的函数(放在script部分)

//编辑分类
const updateCategory = async () => {//调用接口let result = await articleCategoryUpdateService(categoryModel.value);ElMessage.success(result.msg ? result.msg : '编辑成功')//调用获取所有文章分类的函数articleCategoryList();dialogVisible.value = false;
}

删除文章分类的弹窗和函数(放在script部分)

import { ElMessageBox } from 'element-plus'
const deleteCategory = (row) => {ElMessageBox.confirm('确认删除当前文章分类?','Warning',{confirmButtonText: 'OK',cancelButtonText: 'Cancel',type: 'warning',}).then(async () => {//调用接口let result = await articleCategoryDeleteService(row.id);ElMessage({type: 'success',message: 'Delete completed',})articleCategoryList();}).catch(() => {ElMessage({type: 'info',message: 'Delete canceled',})})
}

页面显示部分(即template部分,包括了弹窗和表格)

<template><el-page-header :icon="null"><template #content><div class="flex items-center"><el-avatar :size="32" class="mr-3"src="https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png" /><span class="text-large font-600 mr-3"> 文章分类列表</span></div></template><template #extra><el-button type="primary" @click="dialogVisible = true; title = '新建文章分类'; clearData()">新建文章分类</el-button><el-dialog v-model="dialogVisible" :title="title" width="30%"><el-form :model="categoryModel" :rules="rules" label-width="100px" style="padding-right: 30px"><el-form-item label="文章分类名" prop="categoryName"><el-input v-model="categoryModel.categoryName" minlength="1" maxlength="10"></el-input></el-form-item><el-form-item label="备注和说明" prop="categoryAlias"><el-input v-model="categoryModel.categoryAlias" minlength="1" maxlength="15"></el-input></el-form-item></el-form><template #footer><span class="dialog-footer"><el-button @click="dialogVisible = false">取消</el-button><el-button type="primary" @click="title == '新建文章分类' ? addCategory() : updateCategory()"> 确认 </el-button></span></template></el-dialog></template></el-page-header><el-divider></el-divider><el-table :data="categorys" style="width: 100%"><el-table-column label="id" prop="id" /><el-table-column label="分类名称" prop="categoryName"></el-table-column><el-table-column label="分类别名" prop="categoryAlias"></el-table-column><el-table-column label="操作" width="100"><template #default="{ row }"><el-button :icon="Edit" circle plain type="primary" @click="showDialog(row)"></el-button><el-button :icon="Delete" circle plain type="danger" @click="deleteCategory(row)"></el-button></template></el-table-column><template #empty><el-empty description="没有数据" /></template></el-table>
</template>

后端SpringBoot

增删改查的操作上大体相同,所以就合并进行展示了。

实体类(Category.java)

package org.example.pojo;import com.fasterxml.jackson.annotation.JsonFormat;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.groups.Default;
import lombok.Data;
import org.apache.ibatis.annotations.Update;
import java.time.LocalDateTime;@Data
public class Category {@NotNull(groups = Update.class)private Integer id;//主键ID@NotEmpty/*(groups = {Add.class, Update.class})*/private String categoryName;//分类名称@NotEmpty/*(groups = {Add.class, Update.class})*/private String categoryAlias;//分类别名private Integer createUser;//创建人ID@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")private LocalDateTime createTime;//创建时间@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")private LocalDateTime updateTime;//更新时间public interface Add extends Default {}public interface Update extends Default{}
}

请求层(CategoryController.java)

package org.example.controller;import org.apache.ibatis.annotations.Mapper;
import org.example.pojo.Result;
import org.example.pojo.Category;
import org.example.service.CategoryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;import java.util.List;@RestController
@RequestMapping("/category")
public class CategoryController {@Autowiredprivate CategoryService categoryService;@PostMappingpublic Result add(@RequestBody @Validated(Category.Add.class) Category category){categoryService.add(category);return Result.success();}@GetMappingpublic Result<List<Category>> list(){List<Category> cs = categoryService.list();return Result.success(cs);}@GetMapping("/detail")public  Result<Category> detail(Integer id){Category c = categoryService.findById(id);return Result.success(c);}@PutMappingpublic Result update(@RequestBody @Validated(Category.Update.class) Category category){categoryService.update(category);return Result.success();}@DeleteMappingpublic Result delete(Integer id){categoryService.deleteById(id);return Result.success();}
}

服务层(CategoryServiceImpl.java,CategoryService.java只需进行声明函数略)

package org.example.service.impl;import org.example.mapper.CategoryMapper;
import org.example.pojo.Category;
import org.example.service.CategoryService;
import org.example.utils.ThreadLocalUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;@Service
public class CategoryServiceImpl implements CategoryService {@Autowiredprivate CategoryMapper categoryMapper;@Overridepublic void add(Category category){category.setCreateTime(LocalDateTime.now());category.setUpdateTime(LocalDateTime.now());Map<String,Object> map = ThreadLocalUtil.get();Integer userId = (Integer) map.get("id");category.setCreateUser(userId);categoryMapper.add(category);}@Overridepublic List<Category> list(){Map<String,Object> map = ThreadLocalUtil.get();Integer userId = (Integer) map.get("id");return categoryMapper.list(userId);}@Overridepublic Category findById(Integer id) {Category c = categoryMapper.findById(id);return c;}@Overridepublic void update(Category category){category.setUpdateTime(LocalDateTime.now());categoryMapper.update(category);}@Overridepublic void deleteById(Integer id){categoryMapper.deleteById(id);}
}

数据访问层(CategoryMapper.java)

package org.example.mapper;
import org.apache.ibatis.annotations.*;
import org.example.pojo.Category;
import java.util.List;
@Mapper
public interface CategoryMapper {@Insert("insert into category(category_name,category_alias,create_user,create_time,update_time)" +"values (#{categoryName},#{categoryAlias},#{createUser},#{createTime},#{updateTime})")void add(Category category);@Select("select * from category where create_user = #{userId}")List<Category> list(Integer userId);@Select("select * from category where id = #{id}")Category findById(Integer id);@Update("update category set category_name=#{categoryName},category_alias=#{categoryAlias},update_time=now() where id=#{id}")void update(Category category);@Delete("delete from category where id=#{id}")void deleteById(Integer id);
}

尾声

一周一码,后面就是文章管理的部分了。

这篇关于前后端开发之——文章分类管理的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/872416

相关文章

VSCode开发中有哪些好用的插件和快捷键

《VSCode开发中有哪些好用的插件和快捷键》作为全球最受欢迎的编程工具,VSCode的快捷键体系是提升开发效率的核心密码,:本文主要介绍VSCode开发中有哪些好用的插件和快捷键的相关资料,文中... 目录前言1、vscode插件1.1 Live-server1.2 Auto Rename Tag1.3

Agent开发核心技术解析以及现代Agent架构设计

《Agent开发核心技术解析以及现代Agent架构设计》在人工智能领域,Agent并非一个全新的概念,但在大模型时代,它被赋予了全新的生命力,简单来说,Agent是一个能够自主感知环境、理解任务、制定... 目录一、回归本源:到底什么是Agent?二、核心链路拆解:Agent的"大脑"与"四肢"1. 规划模

一篇文章让你彻底搞懂Java中VO、DTO、BO、DO、PO

《一篇文章让你彻底搞懂Java中VO、DTO、BO、DO、PO》在java编程中我们常常需要做数据交换,那么在数据交换过程中就需要使用到实体对象,这就不可避免的使用到vo、dto、po等实体对象,这篇... 目录深入浅出讲解各层对象区别+实战应用+代码对比,告别概念混淆,设计出更优雅的系统架构!一、 为什么

Python+wxPython开发一个文件属性比对工具

《Python+wxPython开发一个文件属性比对工具》在日常的文件管理工作中,我们经常会遇到同一个文件存在多个版本,或者需要验证备份文件与源文件是否一致,下面我们就来看看如何使用wxPython模... 目录引言项目背景与需求应用场景核心需求运行结果技术选型程序设计界面布局核心功能模块关键代码解析文件大

C++多线程开发环境配置方法

《C++多线程开发环境配置方法》文章详细介绍了如何在Windows上安装MinGW-w64和VSCode,并配置环境变量和编译任务,使用VSCode创建一个C++多线程测试项目,并通过配置tasks.... 目录下载安装 MinGW-w64下载安装VS code创建测试项目配置编译任务创建 tasks.js

一篇文章彻底搞懂macOS如何决定java环境

《一篇文章彻底搞懂macOS如何决定java环境》MacOS作为一个功能强大的操作系统,为开发者提供了丰富的开发工具和框架,下面:本文主要介绍macOS如何决定java环境的相关资料,文中通过代码... 目录方法一:使用 which命令方法二:使用 Java_home工具(Apple 官方推荐)那问题来了,

一文详解Python如何开发游戏

《一文详解Python如何开发游戏》Python是一种非常流行的编程语言,也可以用来开发游戏模组,:本文主要介绍Python如何开发游戏的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下... 目录一、python简介二、Python 开发 2D 游戏的优劣势优势缺点三、Python 开发 3D

基于Python开发Windows自动更新控制工具

《基于Python开发Windows自动更新控制工具》在当今数字化时代,操作系统更新已成为计算机维护的重要组成部分,本文介绍一款基于Python和PyQt5的Windows自动更新控制工具,有需要的可... 目录设计原理与技术实现系统架构概述数学建模工具界面完整代码实现技术深度分析多层级控制理论服务层控制注

Java中的分布式系统开发基于 Zookeeper 与 Dubbo 的应用案例解析

《Java中的分布式系统开发基于Zookeeper与Dubbo的应用案例解析》本文将通过实际案例,带你走进基于Zookeeper与Dubbo的分布式系统开发,本文通过实例代码给大家介绍的非常详... 目录Java 中的分布式系统开发基于 Zookeeper 与 Dubbo 的应用案例一、分布式系统中的挑战二

基于Go语言开发一个 IP 归属地查询接口工具

《基于Go语言开发一个IP归属地查询接口工具》在日常开发中,IP地址归属地查询是一个常见需求,本文将带大家使用Go语言快速开发一个IP归属地查询接口服务,有需要的小伙伴可以了解下... 目录功能目标技术栈项目结构核心代码(main.go)使用方法扩展功能总结在日常开发中,IP 地址归属地查询是一个常见需求: