当前位置: 首页 > news >正文

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

原文地址:前后端开发之——文章分类管理 - 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);
}

尾声

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

相关文章:

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

原文地址&#xff1a;前后端开发之——文章分类管理 - Pleasure的博客 下面是正文内容&#xff1a; 前言 上回书说到 文章管理系统之添加文章分类。就是通过点击“新建文章分类”按钮从而在服务端数据库中增加一个文章分类。 对于文章分类这个对象&#xff0c;增删改查属于配…...

第12届蓝桥杯省赛 ---- C/C++ C组

文章目录 1. ASC2. 空间3. 卡片4. 相乘5. 路径6.时间显示7.最少砝码8. 杨辉三角形9. 左孩子右兄弟 第12届蓝桥杯省赛&#xff0c;C/C C组真题&#xff0c;第10题不是很清楚&#xff0c;题解不敢乱放&#x1f601;&#x1f601;&#x1f601; 1. ASC 额。。。。 #include <i…...

IVS模型解释

核心思路 【Implied volatility surface predictability: The case of commodity markets】 半参数化模型&#xff1a;利用各种参数(或者因子)对隐含波动率进行降维&#xff08;静态参数化因子模型&#xff09;&#xff0c;对参数化因子的时间序列进行间接的建模 基于非对称…...

通用开发技能系列:Git

云原生学习路线导航页&#xff08;持续更新中&#xff09; 本文是 通用开发技能系列 文章&#xff0c;主要对编程通用技能Git进行学习 1.为什么使用版本控制系统 版本控制系统可以解决的问题 代码备份很重要版本控制很重要协同工作很重要责任追溯很重要 常见的版本控制系统 Gi…...

最新怎么订阅OnlyFans上喜欢的博主,详细教程

大家好&#xff0c;本文教大家如何用虚拟信用卡在 Onlyfans 订阅&#xff0c;链接在浏览器打开地址https://bewildcard.com/i/GPT310&#xff0c;虚拟卡开好之后&#xff0c;用支付宝充值就可以进行订阅OnlyFans平台的博主了。 什么是OnlyFans&#xff1f; OnlyFans 是一个提…...

Mysql故障和优化

一、MySQL故障 二、MySQL优化 1.硬件优化&#xff1a; 2.数据库设计与规划 1.提前估计数据量&#xff0c;使用什么存储引擎 2.数据库服务器专机专用&#xff0c;避免额外的服务可能导致的性能下降和不稳定性 3.增加多台服务器&#xff0c;以达到稳定、高效的效果。主从同步、…...

Windows系统C盘空间优化进阶:磁盘清理与Docker日志管理

Windows系统C盘空间优化进阶&#xff1a;磁盘清理与Docker日志管理 文章目录 Windows系统C盘空间优化进阶&#xff1a;磁盘清理与Docker日志管理磁盘清理工具 使用“运行”命令访问磁盘清理利用存储感知自动管理空间清理WinSxS文件夹结合手动清理策略 小结删除临时文件总结&…...

14届蓝桥杯 C/C++ B组 T7 子串简写 (字符串)

采用存储目标字符下标的方法&#xff0c;此题的想法比较新奇&#xff0c;故予以记录。 存好下标之后&#xff0c;可以先定位好启始的字符&#xff0c;然后去搜结尾字符符合长度k并且最靠近启始字符的下标&#xff0c;找到之后可以直接取到这个下标之后的所有下标&#xff0c;因…...

Android 系统大致启动流程

Android启动流程大体为&#xff1a;BootRom -> BootLoader -> Kernel -> Init -> Zygote -> SystemServer ->Launcher 1、Loader层 1.1、Boot ROM 电源按下&#xff0c;引导芯片代码开始从预定义的地方&#xff08;固化在ROM&#xff09;开始执行&#xff0…...

【Web】2024红明谷CTF初赛个人wp(2/4)

目录 ezphp playground 时间原因只打了2个小时&#xff0c;出了2道&#xff0c;简单记录一下 ezphp 参考文章 PHP filter chains: file read from error-based oracle https://github.com/synacktiv/php_filter_chains_oracle_exploit 用上面的脚本爆出部分源码&#xff…...

stable-diffusion-webui安装教程

现在AI开始进入绘画领域,并且能自动根据文本来创建图片出来,这是一个划时代的进步。 这时候,我也不能落后,要紧跟上时代的步伐,那么也来学习一下stable-diffusion的使用,这样也算多一项对技术的认识,提高对AI的认知。 从网上看到很多stable-diffusion-webui的安装,其…...

如何魔改 diffusers 中的 pipelines

如何魔改 diffusers 中的 pipelines 整个 Stable Diffusion 及其 pipeline 长得就很适合 hack 的样子。不管是通过简单地调整采样过程中的一些参数&#xff0c;还是直接魔改 pipeline 内部甚至 UNet 内部的 Attention&#xff0c;都可以实现很多有趣的功能或采样生图结果。 本…...

解放办公室的利器!让证卡打印机轻松应对繁忙工作场景

在现代办公室中&#xff0c;证卡打印机已经成为不可或缺的工作利器。但是&#xff0c;在繁忙的工作场景中&#xff0c;我们经常忽视了它的保养和清洁。然而&#xff0c;正确的清洁和维护不仅可以延长打印机的寿命&#xff0c;还可以提高工作效率&#xff0c;确保每一次打印都是…...

2012年认证杯SPSSPRO杯数学建模A题(第二阶段)蜘蛛网全过程文档及程序

2012年认证杯SPSSPRO杯数学建模 A题 蜘蛛网 原题再现&#xff1a; 第二阶段问题   现在我们假设一个具体的环境。假设有一个凸多边形的区域&#xff0c;蜘蛛准备在这个区域&#xff08;或其一部分&#xff09;上结一张网。   问题一&#xff1a; 在区域的边界上安置有若干…...

ES学习日记(七)-------Kibana安装和简易使用

前言 首先明确一点&#xff0c;Kibana是一个软件&#xff0c;不是插件。 Kibana 是一款开源的数据分析和可视化平台&#xff0c;它是 Elastic stack 成员之一&#xff0c;设计用于和Elasticsearch 协作。您可以使用 Kibana 对 Elasticsearch 索引中的数据进行搜索&#xff0c;…...

react 父子组件的渲染机制 | 优化手段

文章目录 父子组件的渲染机制优化手段与实践写法父组件&#xff1a;下发stateprops.children 传递无状态组件props传递组件 React.memo缓存子组件与useCallback结合 父子组件的渲染机制 渲染分初次渲染和重新渲染 React组件会在两种情况下发生重新渲染 当组件自身的state发生…...

elementPlus el-table动态列扩展及二维表格

1、循环列数据源&#xff0c;动态生成列 <template><div><el-table ref"table" :data"pageData.tableData" stripe style"width: 100%"><el-table-column v-for"column in pageData.columns" :key"column.p…...

vitepress系列-04-规整sideBar左侧菜单导航

规整左侧菜单导航 新建navConfig.ts 文件用来管理左侧导航菜单&#xff1a; 将于其他的配置分开&#xff0c;避免config.mts太大 在config目录下&#xff0c;新建 sidebarModules文件目录用来左侧导航菜单 按模块进行分类&#xff1a; 在config下新建sidebarConfig.ts文件&…...

golang slice总结

目录 概述 一、什么是slice 二、slice的声明 三、slice的初始化、创建 make方式创建 创建一个包含指定长度的切片 创建一个指定长度和容量的切片 创建一个空切片 创建一个长度和容量都为 0 的切片 new方式创建 短声明初始化切片 通过一个数组来创建切片 声明一个 …...

MySQL 数据库的优化

目录 一. 常见故障 单实例常见故障 1. 故障一 2. 故障二 3.故障三 4. 故障四 5. 故障五 6.故障六 7.故障七 8.故障八 主从环境常见故障 1.故障一 2. 故障二 3. 故障三 二. 优化 1.硬件方面 1.1 关于CPU 1.2 关于内存 1.3 关于磁盘 2. 配置文件优化 关于引擎…...

uniapp 对接腾讯云IM群组成员管理(增删改查)

UniApp 实战&#xff1a;腾讯云IM群组成员管理&#xff08;增删改查&#xff09; 一、前言 在社交类App开发中&#xff0c;群组成员管理是核心功能之一。本文将基于UniApp框架&#xff0c;结合腾讯云IM SDK&#xff0c;详细讲解如何实现群组成员的增删改查全流程。 权限校验…...

Zustand 状态管理库:极简而强大的解决方案

Zustand 是一个轻量级、快速和可扩展的状态管理库&#xff0c;特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...

django filter 统计数量 按属性去重

在Django中&#xff0c;如果你想要根据某个属性对查询集进行去重并统计数量&#xff0c;你可以使用values()方法配合annotate()方法来实现。这里有两种常见的方法来完成这个需求&#xff1a; 方法1&#xff1a;使用annotate()和Count 假设你有一个模型Item&#xff0c;并且你想…...

全球首个30米分辨率湿地数据集(2000—2022)

数据简介 今天我们分享的数据是全球30米分辨率湿地数据集&#xff0c;包含8种湿地亚类&#xff0c;该数据以0.5X0.5的瓦片存储&#xff0c;我们整理了所有属于中国的瓦片名称与其对应省份&#xff0c;方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...

Java多线程实现之Callable接口深度解析

Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...

【HTML-16】深入理解HTML中的块元素与行内元素

HTML元素根据其显示特性可以分为两大类&#xff1a;块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...

SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)

上一章用到了V2 的概念&#xff0c;其实 Fiori当中还有 V4&#xff0c;咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务)&#xff0c;代理中间件&#xff08;ui5-middleware-simpleproxy&#xff09;-CSDN博客…...

MacOS下Homebrew国内镜像加速指南(2025最新国内镜像加速)

macos brew国内镜像加速方法 brew install 加速formula.jws.json下载慢加速 &#x1f37a; 最新版brew安装慢到怀疑人生&#xff1f;别怕&#xff0c;教你轻松起飞&#xff01; 最近Homebrew更新至最新版&#xff0c;每次执行 brew 命令时都会自动从官方地址 https://formulae.…...

毫米波雷达基础理论(3D+4D)

3D、4D毫米波雷达基础知识及厂商选型 PreView : https://mp.weixin.qq.com/s/bQkju4r6med7I3TBGJI_bQ 1. FMCW毫米波雷达基础知识 主要参考博文&#xff1a; 一文入门汽车毫米波雷达基本原理 &#xff1a;https://mp.weixin.qq.com/s/_EN7A5lKcz2Eh8dLnjE19w 毫米波雷达基础…...

【把数组变成一棵树】有序数组秒变平衡BST,原来可以这么优雅!

【把数组变成一棵树】有序数组秒变平衡BST,原来可以这么优雅! 🌱 前言:一棵树的浪漫,从数组开始说起 程序员的世界里,数组是最常见的基本结构之一,几乎每种语言、每种算法都少不了它。可你有没有想过,一组看似“线性排列”的有序数组,竟然可以**“长”成一棵平衡的二…...