后端SpringBoot+前端Vue前后端分离的项目(二)

前言:完成一个列表,实现表头的切换,字段的筛选,排序,分页功能。

目录

一、数据库表的设计

​编辑二、后端实现

环境配置

model层

mapper层

service层

service层单元测试

controller层

三、前端实现

interface接口

接口api层

主体代码

效果展示


一、数据库表的设计

二、后端实现

环境配置

引入mybatis-plus依赖

java 复制代码
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.3</version>
        </dependency>

model层

java 复制代码
package com.mrjj.java.model;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
@TableName("merchandise_details")
public class MerchandiseDetails {
    @TableId(type= IdType.AUTO)
    public int id;
    public String salesPlatform;
    public String merchandiseName;
    public int freightCharge;
    public String notes;
}

mapper层

java 复制代码
package com.mrjj.java.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.mrjj.java.model.MerchandiseDetails;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface MerchandiseDetailsMapper extends BaseMapper<MerchandiseDetails> {
}

service层

MerchandiseDetailsService文件

java 复制代码
package com.mrjj.java.service;

import com.baomidou.mybatisplus.extension.service.IService;
import com.mrjj.java.model.MerchandiseDetails;

public interface MerchandiseDetailsService extends IService<MerchandiseDetails> {
}
java 复制代码
package com.mrjj.java.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mrjj.java.mapper.MerchandiseDetailsMapper;
import com.mrjj.java.model.MerchandiseDetails;
import com.mrjj.java.service.MerchandiseDetailsService;
import org.springframework.stereotype.Service;

@Service("MerchandiseDetailsService")
public class MerchandiseDetailsServiceImpl extends ServiceImpl<MerchandiseDetailsMapper, MerchandiseDetails> implements MerchandiseDetailsService {
}

service层单元测试

java 复制代码
package com.mrjj.java.service;

import com.mrjj.java.model.MerchandiseDetails;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;

@SpringBootTest
@Transactional
public class MerchandiseDetailsServiceTest {
    @Resource
    MerchandiseDetailsService merchandiseDetailsService;

    @Test
    public void getAll() {
        List<MerchandiseDetails> list = merchandiseDetailsService.list();
        System.out.println(list);

    }

    @Test
    public void update() {
        MerchandiseDetails change = new MerchandiseDetails(30, "淘宝", "天堂伞", 16, "质量好");
        merchandiseDetailsService.updateById(change);
    }
}

controller层

java 复制代码
package com.mrjj.java.controller;

import com.mrjj.java.model.MerchandiseDetails;
import com.mrjj.java.model.Result;
import com.mrjj.java.service.MerchandiseDetailsService;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.List;

@RestController
@RequestMapping("/MerchandiseDetails")
public class MerchandiseDetailsController {
    @Resource
    MerchandiseDetailsService merchandiseDetailsService;

    @GetMapping
    public Result<List<MerchandiseDetails>> listMerchandiseDetails() {
        return Result.success(merchandiseDetailsService.list());
    }

    @PutMapping
    public Result updateMerchandiseDetails(@RequestBody MerchandiseDetails merchandiseDetails) {
        boolean result = merchandiseDetailsService.updateById(merchandiseDetails);
        if (result) {
            return Result.success("更新商品详细信息成功!");
        } else {
            return Result.fail(210, "更新商品详细信息失败", merchandiseDetails);
        }

    }
}

三、前端实现

interface接口

javascript 复制代码
export interface MerchandiseDetails {
    id: number;
    salesPlatform: string;
    merchandiseName: string;
    freightCharge: number;
    notes: string;
}

接口api层

javascript 复制代码
import request from '../request'
import axios, { type AxiosPromise } from 'axios'
import type { MerchandiseDetails } from '@/types/merchandises_details/types'
const instance = axios.create({
    baseURL: '/merchandiseDetails',
    timeout: 30000,
    headers: { 'Content-Type': 'application/json;charset=utf-8' }
  })
  export default instance

export function listMerchandiseDetailsApi(): AxiosPromise<MerchandiseDetails[]> {
  return request({
    url: '/merchandiseDetails',
    method: 'get',
  })
}

export function updateMerchandiseDetailsApi(data: MerchandiseDetails) {
  return request({
    url: '/merchandiseDetails',
    method: 'put',
    data: data,
  })
}

主要代码

java 复制代码
<template>
<main>
  <el-dialog title="修改商品名称" v-model="isUpdateName">
    <el-input v-model="changeRow.merchandiseName" size="default" clearable></el-input>
    <template #footer>
      <span>
        <el-button @click="isUpdateName = false">取消</el-button>
        <el-button type="primary" @click="updateMerchandiseName">确认</el-button>
      </span>
    </template>
  </el-dialog>
  <el-row>
    <el-col :span="12" :offset="0"> 
  <el-radio-group v-model="filterType" size="default">
    <el-radio-button label="all">全部</el-radio-button>
    <el-radio-button label="京东" />
    <el-radio-button label="唯品会" />
    <el-radio-button label="淘宝" />
    <el-radio-button label="亚马逊" />
    <el-radio-button label="拼多多" />
    <el-radio-button label="当当" />
    <el-radio-button label="天猫" />
  </el-radio-group>

    </el-col>
    <el-col >
      <el-input
        v-model="searchText"
        placeholder="请输入内容进行搜索"
        size="default"
        clearable
        :suffix-icon="Search"
        ><template #prepend
          ><el-button type="primary" size="default" :icon="Search"></el-button>
        </template>
      </el-input>
    </el-col>
  </el-row>

  <el-table :data="showMerchandiseList" style="width: 50%" height="540" border stripe>
    <el-table-column label="商品名称" fixed prop="merchandiseName" width="200px" />
    <el-table-column label="销售平台" prop="salesPlatform" width="100px" />
    <el-table-column label="邮费" prop="freightCharge" width="100px" />
    <el-table-column label="详细信息" prop="notes" width="200px" />
    <el-table-column label="操作" width="200px">
      <template #default="{ row }">
        <el-button
          type="primary"
          size="default"
          @click="
            isUpdateName = true;
            changeRow = { ...row };
          "
          >修改商品名称</el-button
        ></template
      >
    </el-table-column>
  </el-table>
  <el-pagination
    background
    v-model:current-page="currentPage"
    v-model:page-size="pageSize"
    :page-sizes="[10, 20, 50]"
    layout="total, prev,sizes, pager, next,jumper"
    :total="filterMerchandiseList.length"
    @size-change="handleSizeChange"
    @current-change="handleCurrentChange"
  />
  </main>
</template>
<script setup lang="ts">
import { MerchandiseName } from '../types/merchandises_details/types'
import { listMerchandiseDetailsApi, updateMerchandiseDetailsApi } from '../api/merchandise_details'
import { computed, onMounted, ref } from 'vue'
import { Search } from '@element-plus/icons-vue'
import { ElMessage } from 'element-plus'
let merchandiseDetailsList = ref<MerchandiseName[]>([])
let filterMerchandiseList = computed(() => {
  let platformMerchandise = merchandiseDetailsList.value
    .filter((key) => {
      return filterType.value === 'all' || key.salesPlatform === filterType.value
    })
    .filter((merchandise) => {
      return (
        merchandise.merchandiseName.indexOf(searchText.value) !== -1 ||
        merchandise.notes.indexOf(searchText.value) !== -1
      )
    })
  return platformMerchandise
})
onMounted(() => {
  ListMerchandiseDetails()
})

const searchText = ref('')
const filterType = ref('all')

let changeRow = ref<MerchandiseName>()
let isUpdateName = ref(false)

let currentPage = ref(1)
let pageSize = ref(10)

let showMerchandiseList = computed(() => {
  let startIndex = (currentPage.value - 1) * pageSize.value
  let endIndex = currentPage.value * pageSize.value - 1
  let index = -1
  let currentPageData = filterMerchandiseList.value.filter((merchandiseName) => {
    index += 1
    return index <= endIndex && index >= startIndex
  })
  return currentPageData
})

function ListMerchandiseDetails() {
  listMerchandiseDetailsApi().then(({ data }) => {
    merchandiseDetailsList.value = data
  })
}
function updateMerchandiseName() {
  // ElMessage.info(JSON.stringify(changeRow.value))
  isUpdateName.value = false
  updateMerchandiseDetailsApi(changeRow.value!).then(({ data }) => {
    ElMessage.success(data)
    ListMerchandiseDetails()
  })
}
function handleSizeChange(size: number) {
  console.log('当前页面大小是:', size)
  pageSize.value = size
}
const handleCurrentChange = (page: number) => {
  console.log('当前的页数是:', page)
  currentPage.value = page
}
</script>

<style scoped>
.el-input{
width: 30%;
}
</style>

效果展示

固定表头,每页展示50条数据,分页功能

搜索功能

过滤+搜索功能

修改商品名称

数据库merchandise_name字段值发生改变

相关推荐
Victor3563 分钟前
MongoDB(2)MongoDB与传统关系型数据库的主要区别是什么?
后端
JaguarJack4 分钟前
PHP 应用遭遇 DDoS 攻击时会发生什么 从入门到进阶的防护指南
后端·php·服务端
BingoGo4 分钟前
PHP 应用遭遇 DDoS 攻击时会发生什么 从入门到进阶的防护指南
后端
Victor3566 分钟前
MongoDB(3)什么是文档(Document)?
后端
恋猫de小郭1 小时前
Flutter Zero 是什么?它的出现有什么意义?为什么你需要了解下?
android·前端·flutter
牛奔2 小时前
Go 如何避免频繁抢占?
开发语言·后端·golang
想用offer打牌7 小时前
MCP (Model Context Protocol) 技术理解 - 第二篇
后端·aigc·mcp
崔庆才丨静觅8 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60618 小时前
完成前端时间处理的另一块版图
前端·github·web components
KYGALYX8 小时前
服务异步通信
开发语言·后端·微服务·ruby