当前位置: 首页 > 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. 配置文件优化 关于引擎…...

Redis 的主从复制、哨兵和cluster集群

目录 一. Redis 主从复制 1. 介绍 2. 作用 3. 流程 4. 搭建 Redis 主从复制 安装redis 修改 master 的Redis配置文件 修改 slave 的Redis配置文件 验证主从效果 二. Redis 哨兵模式 1. 介绍 2. 原理 3. 哨兵模式的作用 4. 工作流程 4.1 故障转移机制 4.2 主节…...

Unity进阶之路(2)UI Toolkit

UI Toolkit是Unity内置的一个游戏UI解决方案。借鉴了web前端的设计模式。 web前端使用css&#xff0c;html&#xff0c;js。 其中css定义样式 html定义层级 js处理逻辑 UI Toolkit则是使用uss&#xff0c;uxml&#xff0c;C# 如果直接使用Unity提供的可视化UI创建工具创建…...

实现Hello Qt 程序

&#x1f40c;博主主页&#xff1a;&#x1f40c;​倔强的大蜗牛&#x1f40c;​ &#x1f4da;专栏分类&#xff1a;QT❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 目录 一、使用 "按钮" 实现 1、纯代码方式实现 2、可视化操作实现 &#xff08;1&#xff09…...

若依 ruoyi-vue 接口挂载获取Resources静态资源文件权限校验

解决小程序图片打包过大&#xff0c;放置后端&#xff0c;不引用ngnix、minio等组件&#xff0c;还能进行权限校验 package com.huida.web.controller.common.app;import com.huida.common.core.controller.BaseController; import com.huida.common.utils.file.FileUtils; imp…...

【STM32嵌入式系统设计与开发】——16InputCapture(输入捕获应用)

这里写目录标题 STM32资料包&#xff1a; 百度网盘下载链接&#xff1a;链接&#xff1a;https://pan.baidu.com/s/1mWx9Asaipk-2z9HY17wYXQ?pwd8888 提取码&#xff1a;8888 一、任务描述二、任务实施1、工程文件夹创建2、函数编辑&#xff08;1&#xff09;主函数编辑&#…...

「论文阅读」还在手写Prompt,自动Prompt搜索超越人类水平

每周论文阅读笔记&#xff0c;来自于2023LARGE LANGUAGE MODELS ARE HUMAN-LEVEL PROMPT ENGINEERS code:https://github.com/keirp/automatic_prompt_engineer 手写prompt确实很费脑筋&#xff0c;但其实本身大语言模型就是一个很好的自动prompt工具&#xff0c;APE文章提出自…...

安全测试概述和用例设计

一、安全测试概述 定义&#xff1a;安全测试是在软件产品开发基本完成时&#xff0c;验证产品是否符合安全需求定义和产品质量标准的过程。 概念&#xff1a;安全测试是检查系统对非法侵入渗透的防范能力。 准则&#xff1a;理论上来讲&#xff0c;只要有足够的时间和资源&a…...

JavaScript 超详细学习思路

JavaScript 是一种轻量级的编程语言&#xff0c;它可以在网页中嵌入&#xff0c;用来实现网页的动态效果和用户交互功能。它是 Web 开发中不可或缺的一部分&#xff0c;与 HTML 和 CSS 并称为 Web 技术的三大基石。下面我会根据您的要求&#xff0c;对每个部分进行详细的讲解。…...

LeetCode:1483. 树节点的第 K 个祖先(倍增 Java)

目录 1483. 树节点的第 K 个祖先 题目描述&#xff1a; 实现代码与解析&#xff1a; 倍增 原理思路&#xff1a; 1483. 树节点的第 K 个祖先 题目描述&#xff1a; 给你一棵树&#xff0c;树上有 n 个节点&#xff0c;按从 0 到 n-1 编号。树以父节点数组的形式给出&#…...

ConstraintLayout在复杂布局中,出现卡顿问题解决记录

ConstraintLayout在画界面的过程中&#xff0c;确实带来了不少的方便&#xff0c;随着使用的越来越多&#xff0c;也发现了一些问题&#xff0c;特此记录一下问题和解决方案。 在背景为图片&#xff0c;而背景图片宽度固定高度自适应的情况下&#xff0c;布局显示在图片固定位…...

网络安全知识/郑州专业seo哪家好

在2021世界人工智能大会中&#xff0c;达观数据与浦东青联联合举办了“未来办公 文本赋能”智能语义分析应用论坛&#xff0c;多位专家学者围绕人工智能算法、语义分析、智能办公机器人应用等话题展开了一场精彩的交流盛宴。 复旦大学教授、博士生导师 复旦大学计算机科学技术…...

网站html地图模板/灰色行业推广平台

代理对象&#xff1a;增强后的对象&#xff08;中介&#xff09; 目标对象&#xff1a;被增强的对象 &#xff08;自己&#xff09; 两种方式 静态代理 静态代理两种方式&#xff1a;继承 1.继承 我们创建在DAO层中查询数据库&#xff0c; 此时我们增强它 public class U…...

常德德山经开区建设局网站/搜一搜站长工具

数组实例的find方法&#xff0c;用于找出第一个符合条件的数组成员。它的参数是一个回调函数&#xff0c;所有数组成员依次执行该回调函数&#xff0c;直到找出第一个返回值为true的成员&#xff0c;然后返回该成员。如果没有符合条件的成员&#xff0c;则返回undefined。[1, 4…...

做图神器的网站/长沙网站推广排名优化

问题 检测到时钟偏差&#xff0c;主要是两个设备系统之间的时间上存在差距&#xff0c;导致编译失败。 解决方法 回到工作空间中&#xff0c;即build文件夹的上一级路径&#xff1a; cd ..将所有文件都重新touch一遍&#xff0c;更新到本地系统的时间&#xff0c;再make就没…...

.net网站开发实训代码/百度产品优化排名软件

最近工作中&#xff0c;要做个客户端提醒的小工具&#xff1b;winform程序自然少不了要读取和应用程序同一个目录的配置文件(不是exe.config文件)&#xff1b; 要读取当前应用程序所在目录我立马想到了System.Environment.CurrentDirectory 来获取当前工作目录。程序运行似乎一…...

六灶网站建设/自己做seo网站推广

第一、打开&#xff23;&#xff2d;&#xff24;窗口右击 第二第三、重启电脑。...