后端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字段值发生改变

相关推荐
ss27320 分钟前
基于Springboot + vue实现的中医院问诊系统
java·spring boot·后端
同志3271332 分钟前
用HTML+CSS做了一个网易云音乐客户端首页
前端·css
小猪欧巴哟34 分钟前
pnpm install 安装项目依赖遇到 illegal operation on a directory, symlink 问题
前端·vue.js
独角仙梦境34 分钟前
🚀🚀🚀学习这个思路,你也能手撸自己的专属vip脚手架🚀🚀🚀
前端
CJWbiu37 分钟前
Github Action + docker 实现自动化部署
前端·自动化运维
关山38 分钟前
在TS中如何在子进程中动态实例化一个类
前端
吃瓜群众i38 分钟前
兼容IE8浏览器的8个实用知识点
前端·javascript
前端烨42 分钟前
vue3子传父——v-model辅助值传递
前端·vue3·组件传值
Mintopia1 小时前
Three.js 在数字孪生中的应用场景教学
前端·javascript·three.js
左灯右行的爱情1 小时前
Redis 缓存并发问题深度解析:击穿、雪崩与穿透防治指南
java·数据库·redis·后端·缓存