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

news2024/11/27 18:43:57

原文地址:前后端开发之——文章分类管理 - 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 {
    @Autowired
    private CategoryService categoryService;
    @PostMapping
    public Result add(@RequestBody @Validated(Category.Add.class) Category category){
        categoryService.add(category);
        return Result.success();
    }

    @GetMapping
    public 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);
    }

    @PutMapping
    public Result update(@RequestBody @Validated(Category.Update.class) Category category){
        categoryService.update(category);
        return Result.success();
    }

    @DeleteMapping
    public 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 {
    @Autowired
    private CategoryMapper categoryMapper;
    @Override
    public 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);
    }
    @Override
    public List<Category> list(){
        Map<String,Object> map = ThreadLocalUtil.get();
        Integer userId = (Integer) map.get("id");
        return categoryMapper.list(userId);
    }
    @Override
    public Category findById(Integer id) {
        Category c = categoryMapper.findById(id);
        return c;
    }
    @Override
    public void update(Category category){
        category.setUpdateTime(LocalDateTime.now());
        categoryMapper.update(category);
    }
    @Override
    public 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.coloradmin.cn/o/1562789.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Windows提权—数据库提权-mysql提权mssql提权Oracle数据库提权

目录 Windows 提权—数据库提权一、mysql提权1.1 udf提权1.1.2 操作方法一 、MSF自动化--UDF提权--漏洞利用1.1.3 操作方法二、 手工导出sqlmap中的dll1.1.4 操作方法三、 moon.php大马利用 1.2 mof提权1.3 启动项提权1.4 反弹shell 二、MSSQL提权MSSQL提权方法1.使用xp_cmdshe…

项目管理工具的魔力:团队合作的秘诀大揭秘!

我们知道项目的成败往往取决于人。假如一个项目团队组织不善&#xff0c;即使项目经理能力很强也无法力挽狂澜&#xff0c;甚至被团队束缚。创建更好的项目团队可以从多方面下手其中项目管理工具就是重要的一项&#xff0c;如何利用项目管理工具组建更好的项目团队&#xff1f;…

中国主要河流水系数据

在我国&#xff0c;水系等级划分主要依据流域面积、流量和河流长度等因素。根据《中华人民共和国水资源》的相关规定&#xff0c;我国水系等级大致可以分为以下几类&#xff1a; 一级水系&#xff1a;主要是指国内的大型河流&#xff0c;如长江、黄河、珠江等。这些河流的流域…

java入门-分支与循环

分支结构 分支结构是解决程序选取分支走不同的路线&#xff0c;增加了程序开发的灵活性。java的分支主要由if和switch这两种结构实现。 if 语句 if是分支中最常用的语法&#xff0c;它从形式上有三种形态&#xff1a; if 结构 结构 语法 if(表达式){ //代码块 } 程序案例 i…

基于java+SpringBoot+Vue的学生考勤管理系统设计与实现

基于javaSpringBootVue的学生考勤管理系统设计与实现 开发语言: Java 数据库: MySQL技术: SpringBoot MyBatis工具: IDEA/Eclipse、Navicat、Maven 系统展示 前台展示 登录注册&#xff1a;支持学生、教师和管理员登录和注册。 个人中心&#xff1a;用户可以查看和更新个…

C语言-冒泡排序算法

题目描述 设计一个程序&#xff0c;实现冒泡排序算法&#xff0c;并输出{9,8,7,6,5,4,3,2,1,0} 的排序过程。 输出 每个排序过程输出一行&#xff0c;直到排序完成。 样例输出 Expected 9 8 7 6 5 4 3 2 1 0 0 9 8 7 6 5 4 3 2 1 0 1 9 …

C#学习笔记7:C#面向对象编程方法(1)

今日继续我的C#学习笔记 主要用实际代码编程来学习研究C#面向对象的编程方法&#xff1a;直接看代码及注释即可&#xff1a; 目录 1、对类与对象概念的快速认知&#xff1a; 2、类和对象成员访问控制&#xff1a; 3、类的构造函数和析构函数&#xff1a; 4、类的属性&#xff…

GaussDB云数据库极简版安装与使用-新手指南

一、前言 作为一款领先的企业级数据库管理系统&#xff0c;GaussDB 提供了强大的性能、高度可靠性和丰富的功能&#xff0c;是企业构建可靠、高性能的数据库解决方案的理想选择。 本文主要针对高校和个人测试环境&#xff0c;介绍极简版安装和使用过程&#xff0c;更加适合高…

git 修改历史 commit message

目录 1&#xff0c;修改当前的2&#xff0c;修改历史的1&#xff0c;先查看 log2&#xff0c;开始修改 3&#xff0c;其他注意点1&#xff0c;中途不想修改了2&#xff0c;commit ID 会发生变化3&#xff0c;推送远程4&#xff0c;精准定位 1&#xff0c;修改当前的 直接使用下…

Netty核心原理剖析与RPC实践11-15

Netty核心原理剖析与RPC实践11-15 11 另起炉灶&#xff1a;Netty 数据传输载体 ByteBuf 详解 在学习编解码章节的过程中&#xff0c;我们看到 Netty 大量使用了自己实现的 ByteBuf 工具类&#xff0c;ByteBuf 是 Netty 的数据容器&#xff0c;所有网络通信中字节流的传输都是…

哥哥张国荣逝世21年,唐唐继续发文怀念

一代巨星张国荣&#xff08;哥哥&#xff09;在21年前的愚人节&#xff08;2003年4月1日&#xff09;从香港文华东方酒店一跃而下&#xff0c;终年46岁&#xff0c;当年他的离开令很多歌迷影迷都感到悲痛&#xff0c;当中亦包括了他…… 他就是唐鹤德&#xff08;唐唐&#xff…

FPGA高端图像处理开发板-->鲲叔4EV:12G-SDI、4K HDMI2.0、MIPI等接口谁敢与我争锋?

目录 前言鲲叔4EV----高端FPGA图像处理开发板核心板描述底板描述配套例程源码描述配套服务描述开发板测试视频演示开发板获取 前言 在CSDN写博客传播FPGA开发经验已经一年多了&#xff0c;帮助了不少人&#xff0c;也得罪了不少人&#xff0c;有的人用我的代码赢得了某些比赛、…

SpringBoot整合Netty整合WebSocket-带参认证

文章目录 一. VectorNettyApplication启动类配置二.WebSocketServerBoot初始化服务端Netty三. WebsocketServerChannelInitializer初始化服务端Netty读写处理器四.initParamHandler处理器-去参websocket识别五.MessageHandler核心业务处理类-采用工厂策略模式5.1 策略上下文 六…

【C语言】联合和枚举

个人主页点这里~ 联合和枚举 一、联合体1、联合体类型的声明2、联合体成员的特点3、与结构体对比4、计算联合体大小 二、枚举1、枚举的声明2、枚举的优点3、枚举类型的使用 一、联合体 1、联合体类型的声明 联合体的定义与结构体相似&#xff0c;但是联合体往往会节省更多的空…

分布式光伏电力监控系统解决方案

安科瑞薛瑶瑶18701709087 分布式光伏现状 自发自用、余电上网模式 完全自发自用&#xff08;防逆流&#xff09;模式 全额上网模式 0.4kV并网系统 此图为车间新建屋顶分布式光伏发电项目&#xff0c;建设装机容量为1103.46kWp。组件采用单晶硅功率515Wp及550Wp组件&#xff…

文献学习-25-综合学习和适应性教学:用于病理性胶质瘤分级的多模态知识蒸馏

Comprehensive learning and adaptive teaching: Distilling multi-modal knowledge for pathological glioma grading Authors: Xiaohan Xing , Meilu Zhu , Zhen Chen , Yixuan Yuan Source: Medical Image Analysis 91 (2024) 102990 Key words: 知识蒸馏、模态缺失、胶质瘤…

js实现简单的添加移除水印效果

一、实现场景 在做某些内部管理系统时&#xff0c;需求可能要求增加水印&#xff0c;水印内容通常可能是logo或者用户名手机号。实现效果如图&#xff1a; 以下步骤可实现简单添加或者移除水印&#xff0c;并且可以自定义样式、旋转角度等。 二、实现方式 1、先新建一个js…

期权定价模型有哪些?

常见的期权定价模型有BSM模型、二叉树模型以及蒙特卡洛定价模型。 BS模型 在一系列的假设条件下&#xff0c;该模型将期权的价值表示成为标的资产价格、行权价格、无风险利率、期权剩余期限和标的资产波动率的函数。即一旦定量的给出上述5个影响因子的数值&#xff0c;就可以…

鸿蒙OS开发实例:【ArkTS类库多线程CPU密集型任务TaskPool】

CPU密集型任务是指需要占用系统资源处理大量计算能力的任务&#xff0c;需要长时间运行&#xff0c;这段时间会阻塞线程其它事件的处理&#xff0c;不适宜放在主线程进行。例如图像处理、视频编码、数据分析等。 基于多线程并发机制处理CPU密集型任务可以提高CPU利用率&#x…

【PFA树脂交换柱】实验室高纯PFA材质过滤柱耐受电子级氢氟酸含氟树脂层析柱

PFA离子交换柱&#xff0c;也叫PFA层析柱、PFA过滤柱等&#xff0c;其原理是利用吸附剂对不同化合物有不同吸附作用和不同化合物在溶剂中的不同溶解度&#xff0c;用适应溶剂使混合物在填有吸附剂的柱内通过&#xff0c;使复杂的混合物达到分离和提纯的目的。 柱体为透明PFA材…