Web 毕设篇-适合小白、初级入门练手的 Spring Boot Web 毕业设计项目:药品进销存信息管理系统(前后端源码 + 数据库 sql 脚本)

🔥博客主页: 【小扳_-CSDN博客】**
❤感谢大家点赞👍收藏⭐评论✍**

文章目录

[](#1.0 项目介绍)[1.0 项目介绍](#1.0 项目介绍)

[1.1 项目功能](#1.1 项目功能)

[](#2.0 用户登录功能)[2.0 用户登录功能](#2.0 用户登录功能)

[](#3.0 首页界面)[3.0 首页界面](#3.0 首页界面)

[](#4.0 供应商管理功能)[4.0 供应商管理功能](#4.0 供应商管理功能)

[](#5.0 药品管理功能)[5.0 药品管理功能](#5.0 药品管理功能)

[](#6.0 采购记录管理功能)[6.0 采购记录管理功能](#6.0 采购记录管理功能)

[](#7.0 销售记录管理功能)[7.0 销售记录管理功能](#7.0 销售记录管理功能)

[](#8.0 退货记录管理功能)[8.0 退货记录管理功能](#8.0 退货记录管理功能)

[](#9.0 库存变动管理功能)[9.0 库存变动管理功能](#9.0 库存变动管理功能)

[](#10.0 SQL 数据库设计)[10.0 SQL 数据库设计](#10.0 SQL 数据库设计)


1.0 项目介绍

开发工具:IDEA、VScode

服务器:Tomcat, JDK 17

项目构建:maven

数据库:mysql 8.0

系统用户前台和管理后台两部分,项目采用前后端分离

前端技术:vue3 + elementUI

服务端技术:springboot + mybatis + redis + mysql

1.1 项目功能

后台功能:

1)登录、退出系统、首页

2)供应商信息管理

(1) 供应商信息管理:添加、修改、删除、查询等功能。

3)药品管理

(1) 药品管理:添加、修改、删除、查询等功能。

4)采购登记管理

(1) 采购登记管理:添加、修改、删除、查询等功能。

5)销售记录管理

(1) 销售记录管理:添加、修改、删除、查询等功能。

6)退货记录管理

(1) 退货记录管理:添加、修改、删除、查询等功能。

7)库存变动管理

(1) 库存变动管理:添加、修改、删除、查询等功能。

8)系统管理

用户信息管理

(1)用户信息管理:添加、修改、删除、查询等功能。

角色管理

(2)角色信息管理:添加、修改、删除、查询等功能。

菜单管理

(3)菜单信息管理:添加、修改、删除、查询等功能。

日志管理

(4)日志信息管理:添加、修改、删除、查询等功能。

9)系统监控

查看在先用户、设置定时任务、数据监控、缓存监控、查看缓存列表等。

10)权限管理

(1) 角色信息管理:添加、修改、删除、分配权限等功能。

(2) 资源信息管理:添加、修改、删除等功能。

注意:不一定非要完全符合开发环境,有稍微的差别也是可以开发的。

若需要项目完整源码,可以在 CSDN 私信给我,我每天都有查看消息的,感谢大家支持,希望可以帮助到大家!

2.0 用户登录功能

用户根据正确的用户名、密码且通过正确的校验码进行登录。

实现了登录校验,还有用户注册功能:

用到了 Spring Security 框架来实现登录、校验、验证等功能。

相关的部分源码:

java 复制代码
@RestController
public class SysLoginController
{
    @Autowired
    private SysLoginService loginService;
 
    @Autowired
    private ISysMenuService menuService;
 
    @Autowired
    private SysPermissionService permissionService;
 
    /**
     * 登录方法
     * 
     * @param loginBody 登录信息
     * @return 结果
     */
    @PostMapping("/login")
    public AjaxResult login(@RequestBody LoginBody loginBody)
    {
        AjaxResult ajax = AjaxResult.success();
        // 生成令牌
        String token = loginService.login(loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(),
                loginBody.getUuid());
        ajax.put(Constants.TOKEN, token);
        return ajax;
    }
 
    /**
     * 获取用户信息
     * 
     * @return 用户信息
     */
    @GetMapping("getInfo")
    public AjaxResult getInfo()
    {
        SysUser user = SecurityUtils.getLoginUser().getUser();
        // 角色集合
        Set<String> roles = permissionService.getRolePermission(user);
        // 权限集合
        Set<String> permissions = permissionService.getMenuPermission(user);
        AjaxResult ajax = AjaxResult.success();
        ajax.put("user", user);
        ajax.put("roles", roles);
        ajax.put("permissions", permissions);
        return ajax;
    }
 
    /**
     * 获取路由信息
     * 
     * @return 路由信息
     */
    @GetMapping("getRouters")
    public AjaxResult getRouters()
    {
        Long userId = SecurityUtils.getUserId();
        List<SysMenu> menus = menuService.selectMenuTreeByUserId(userId);
        return AjaxResult.success(menuService.buildMenus(menus));
    }
}
java 复制代码
    public String login(String username, String password, String code, String uuid)
    {
        // 验证码校验
        validateCaptcha(username, code, uuid);
        // 登录前置校验
        loginPreCheck(username, password);
        // 用户验证
        Authentication authentication = null;
        try
        {
            UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username, password);
            AuthenticationContextHolder.setContext(authenticationToken);
            // 该方法会去调用UserDetailsServiceImpl.loadUserByUsername
            authentication = authenticationManager.authenticate(authenticationToken);
        }
        catch (Exception e)
        {
            if (e instanceof BadCredentialsException)
            {
                AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
                throw new UserPasswordNotMatchException();
            }
            else
            {
                AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, e.getMessage()));
                throw new ServiceException(e.getMessage());
            }
        }
        finally
        {
            AuthenticationContextHolder.clearContext();
        }
        AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
        LoginUser loginUser = (LoginUser) authentication.getPrincipal();
        recordLoginInfo(loginUser.getUserId());
        // 生成token
        return tokenService.createToken(loginUser);
    }

3.0 首页界面

统计相关药品的信息,使用柱状图和圆饼图等展示出来,会更加直观。


相关的前端源码:

javascript 复制代码
<template>
  <div class="statistics">
    <!-- <h2 class="title">药品进销存统计信息</h2> -->
    <div class="chart-container">
      <div ref="barChart" class="chart"></div>
      <div ref="pieChart" class="chart"></div>
      <div ref="lineChart" class="chart"></div>
      <div ref="radarChart" class="chart"></div>
    </div>
  </div>
</template>

<script setup>
import * as echarts from 'echarts';
import { onMounted, ref } from 'vue';

const barChart = ref(null);
const pieChart = ref(null);
const lineChart = ref(null);
const radarChart = ref(null);

onMounted(() => {
  fetchAndInitCharts();
});

async function fetchAndInitCharts() {
  const salesData = {
    categories: ['阿司匹林', '布洛芬', '对乙酰氨基酚', '盐酸昂丹司琼注射液', '盐酸昂丹司琼注射液'],
    values: [120, 200, 150, 80, 70]
  };

  const inventoryData = [
    { value: 335, name: '阿司匹林' },
    { value: 310, name: '布洛芬' },
    { value: 234, name: '对乙酰氨基酚' },
    { value: 135, name: '盐酸昂丹司琼注射液' },
    { value: 1548, name: '盐酸昂丹司琼注射液' }
  ];

  const trendData = {
    categories: ['1月', '2月', '3月', '4月', '5月', '6月'],
    values: [120, 200, 150, 80, 70, 100]
  };

  const radarData = {
    indicators: [
      { name: '质量', max: 100 },
      { name: '价格', max: 100 },
      { name: '销量', max: 100 },
      { name: '库存', max: 100 },
      { name: '满意度', max: 100 }
    ],
    series: [
      {
        value: [80, 60, 70, 50, 90],
        name: '阿司匹林'
      }
    ]
  };

  initBarChart(salesData);
  initPieChart(inventoryData);
  initLineChart(trendData);
  initRadarChart(radarData);
}

function initBarChart(data) {
  const chart = echarts.init(barChart.value);
  const option = {
    title: {
      text: '药品销售量统计',
      left: 'center',
      textStyle: {
        color: '#111711', // 修改字体颜色
        fontSize: 24
      }
    },
    tooltip: {
      trigger: 'axis',
      axisPointer: {
        type: 'shadow'
      }
    },
    xAxis: {
      type: 'category',
      data: data.categories,
      axisLabel: {
        interval: 0,
        rotate: 30,
        color: '#111711' // 修改字体颜色
      },
      axisLine: {
        lineStyle: {
          color: '#fff'
        }
      }
    },
    yAxis: {
      type: 'value',
      axisLabel: {
        color: '#111711' // 修改字体颜色
      },
      axisLine: {
        lineStyle: {
          color: '#fff'
        }
      }
    },
    series: [{
      data: data.values,
      type: 'bar',
      itemStyle: {
        color: '#6A5ACD' // 更改颜色为更深的紫色
      }
    }],
    backgroundColor: 'transparent' // 设置背景色为透明
  };
  chart.setOption(option);
}

function initPieChart(data) {
  const chart = echarts.init(pieChart.value);
  const option = {
    title: {
      text: '药品库存比例',
      left: 'center',
      textStyle: {
        color: '#111711', // 修改字体颜色
        fontSize: 24
      }
    },
    tooltip: {
      trigger: 'item'
    },
    legend: {
      orient: 'vertical',
      left: 'left',
      textStyle: {
        color: '#111711' // 修改字体颜色
      }
    },
    series: [{
      name: '药品库存',
      type: 'pie',
      radius: '50%',
      data: data,
      emphasis: {
        itemStyle: {
          shadowBlur: 10,
          shadowOffsetX: 0,
          shadowColor: 'rgba(0, 0, 0, 0.5)'
        }
      },
      itemStyle: {
        color: (params) => {
          const colorList = ['#FF69B4', '#FFD700', '#32CD32', '#1E90FF', '#FF6347']; // 更改颜色为更青春的色调
          return colorList[params.dataIndex];
        }
      }
    }],
    backgroundColor: 'transparent' // 设置背景色为透明
  };
  chart.setOption(option);
}

function initLineChart(data) {
  const chart = echarts.init(lineChart.value);
  const option = {
    title: {
      text: '药品销售趋势',
      left: 'center',
      textStyle: {
        color: '#111711', // 修改字体颜色
        fontSize: 24
      }
    },
    tooltip: {
      trigger: 'axis'
    },
    xAxis: {
      type: 'category',
      data: data.categories,
      axisLabel: {
        color: '#111711' // 修改字体颜色
      },
      axisLine: {
        lineStyle: {
          color: '#fff'
        }
      }
    },
    yAxis: {
      type: 'value',
      axisLabel: {
        color: '#111711' // 修改字体颜色
      },
      axisLine: {
        lineStyle: {
          color: '#fff'
        }
      }
    },
    series: [{
      data: data.values,
      type: 'line',
      smooth: true,
      itemStyle: {
        color: '#FF69B4' // 更改颜色为粉红
      }
    }],
    backgroundColor: 'transparent' // 设置背景色为透明
  };
  chart.setOption(option);
}

function initRadarChart(data) {
  const chart = echarts.init(radarChart.value);
  const option = {
    title: {
      text: '药品综合评价',
      left: 'center',
      textStyle: {
        color: '#111711', // 修改字体颜色
        fontSize: 24
      }
    },
    tooltip: {
      trigger: 'item'
    },
    radar: {
      indicator: data.indicators,
      axisName: {
        color: '#111711' // 修改字体颜色
      },
      splitArea: {
        areaStyle: {
          color: ['#17273B', '#233B56']
        }
      }
    },
    series: [{
      name: '药品综合评价',
      type: 'radar',
      data: data.series,
      itemStyle: {
        color: '#FF69B4' // 更改颜色为粉红
      }
    }],
    backgroundColor: 'transparent' // 设置背景色为透明
  };
  chart.setOption(option);
}
</script>

<style scoped>
.statistics {
  padding: 40px;
  display: flex;
  flex-direction: column;
  align-items: center;
  background-color: #4DA3D4;
  background-image: url('../../assets/images/4.jpg'); /* 设置背景图 */
  background-size: cover; /* 使背景图覆盖整个容器 */
  background-position: center; /* 背景图居中 */
  color: #111711; /* 修改字体颜色 */
  min-height: 100vh;
}

.title {
  font-size: 36px;
  margin-bottom: 40px;
  color: #111711; /* 修改字体颜色 */
}

.chart-container {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));
  gap: 40px;
  width: 100%;
  max-width: 1400px;
}

.chart {
  width: 100%;
  height: 500px;
  border: 1px solid #ddd;
  box-shadow: 0 4px 8px rgba(0, 0, 0, 1);
  border-radius: 12px;
  overflow: hidden;
  background-color: transparent; /* 设置背景色为透明 */
}
</style>

4.0 供应商管理功能



上传图片使用了第三方接口:x-File-Storage 框架。

相关源码:

java 复制代码
@RestController
@RequestMapping("/manage/suppliers")
public class SuppliersController extends BaseController
{
    @Autowired
    private ISuppliersService suppliersService;

    /**
     * 查询供应商信息列表
     */
    @PreAuthorize("@ss.hasPermi('manage:suppliers:list')")
    @GetMapping("/list")
    public TableDataInfo list(Suppliers suppliers)
    {
        startPage();
        List<Suppliers> list = suppliersService.selectSuppliersList(suppliers);
        return getDataTable(list);
    }

    /**
     * 导出供应商信息列表
     */
    @PreAuthorize("@ss.hasPermi('manage:suppliers:export')")
    @Log(title = "供应商信息", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, Suppliers suppliers)
    {
        List<Suppliers> list = suppliersService.selectSuppliersList(suppliers);
        ExcelUtil<Suppliers> util = new ExcelUtil<Suppliers>(Suppliers.class);
        util.exportExcel(response, list, "供应商信息数据");
    }

    /**
     * 获取供应商信息详细信息
     */
    @PreAuthorize("@ss.hasPermi('manage:suppliers:query')")
    @GetMapping(value = "/{supplierId}")
    public AjaxResult getInfo(@PathVariable("supplierId") Long supplierId)
    {
        return success(suppliersService.selectSuppliersBySupplierId(supplierId));
    }

    /**
     * 新增供应商信息
     */
    @PreAuthorize("@ss.hasPermi('manage:suppliers:add')")
    @Log(title = "供应商信息", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody Suppliers suppliers)
    {
        return toAjax(suppliersService.insertSuppliers(suppliers));
    }

    /**
     * 修改供应商信息
     */
    @PreAuthorize("@ss.hasPermi('manage:suppliers:edit')")
    @Log(title = "供应商信息", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody Suppliers suppliers)
    {
        return toAjax(suppliersService.updateSuppliers(suppliers));
    }

    /**
     * 删除供应商信息
     */
    @PreAuthorize("@ss.hasPermi('manage:suppliers:remove')")
    @Log(title = "供应商信息", businessType = BusinessType.DELETE)
	@DeleteMapping("/{supplierIds}")
    public AjaxResult remove(@PathVariable Long[] supplierIds)
    {
        return toAjax(suppliersService.deleteSuppliersBySupplierIds(supplierIds));
    }
}

5.0 药品管理功能




相关源码:

java 复制代码
@RestController
@RequestMapping("/manage/medicines")
public class MedicinesController extends BaseController
{
    @Autowired
    private IMedicinesService medicinesService;

    /**
     * 查询药品信息列表
     */
    @PreAuthorize("@ss.hasPermi('manage:medicines:list')")
    @GetMapping("/list")
    public TableDataInfo list(Medicines medicines)
    {
        startPage();
        List<Medicines> list = medicinesService.selectMedicinesList(medicines);
        return getDataTable(list);
    }

    /**
     * 导出药品信息列表
     */
    @PreAuthorize("@ss.hasPermi('manage:medicines:export')")
    @Log(title = "药品信息", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, Medicines medicines)
    {
        List<Medicines> list = medicinesService.selectMedicinesList(medicines);
        ExcelUtil<Medicines> util = new ExcelUtil<Medicines>(Medicines.class);
        util.exportExcel(response, list, "药品信息数据");
    }

    /**
     * 获取药品信息详细信息
     */
    @PreAuthorize("@ss.hasPermi('manage:medicines:query')")
    @GetMapping(value = "/{medicineId}")
    public AjaxResult getInfo(@PathVariable("medicineId") Long medicineId)
    {
        return success(medicinesService.selectMedicinesByMedicineId(medicineId));
    }

    /**
     * 新增药品信息
     */
    @PreAuthorize("@ss.hasPermi('manage:medicines:add')")
    @Log(title = "药品信息", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody Medicines medicines)
    {
        return toAjax(medicinesService.insertMedicines(medicines));
    }

    /**
     * 修改药品信息
     */
    @PreAuthorize("@ss.hasPermi('manage:medicines:edit')")
    @Log(title = "药品信息", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody Medicines medicines)
    {
        return toAjax(medicinesService.updateMedicines(medicines));
    }

    /**
     * 删除药品信息
     */
    @PreAuthorize("@ss.hasPermi('manage:medicines:remove')")
    @Log(title = "药品信息", businessType = BusinessType.DELETE)
	@DeleteMapping("/{medicineIds}")
    public AjaxResult remove(@PathVariable Long[] medicineIds)
    {
        return toAjax(medicinesService.deleteMedicinesByMedicineIds(medicineIds));
    }
}

6.0 采购记录管理功能

对药品进行采购。



相关源码:

java 复制代码
@RestController
@RequestMapping("/manage/purchases")
public class PurchasesController extends BaseController
{
    @Autowired
    private IPurchasesService purchasesService;

    /**
     * 查询采购记录列表
     */
    @PreAuthorize("@ss.hasPermi('manage:purchases:list')")
    @GetMapping("/list")
    public TableDataInfo list(Purchases purchases)
    {
        startPage();
        List<Purchases> list = purchasesService.selectPurchasesList(purchases);
        return getDataTable(list);
    }

    /**
     * 导出采购记录列表
     */
    @PreAuthorize("@ss.hasPermi('manage:purchases:export')")
    @Log(title = "采购记录", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, Purchases purchases)
    {
        List<Purchases> list = purchasesService.selectPurchasesList(purchases);
        ExcelUtil<Purchases> util = new ExcelUtil<Purchases>(Purchases.class);
        util.exportExcel(response, list, "采购记录数据");
    }

    /**
     * 获取采购记录详细信息
     */
    @PreAuthorize("@ss.hasPermi('manage:purchases:query')")
    @GetMapping(value = "/{purchaseId}")
    public AjaxResult getInfo(@PathVariable("purchaseId") Long purchaseId)
    {
        return success(purchasesService.selectPurchasesByPurchaseId(purchaseId));
    }

    /**
     * 新增采购记录
     */
    @PreAuthorize("@ss.hasPermi('manage:purchases:add')")
    @Log(title = "采购记录", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody Purchases purchases)
    {
        return toAjax(purchasesService.insertPurchases(purchases));
    }

    /**
     * 修改采购记录
     */
    @PreAuthorize("@ss.hasPermi('manage:purchases:edit')")
    @Log(title = "采购记录", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody Purchases purchases)
    {
        return toAjax(purchasesService.updatePurchases(purchases));
    }

    /**
     * 删除采购记录
     */
    @PreAuthorize("@ss.hasPermi('manage:purchases:remove')")
    @Log(title = "采购记录", businessType = BusinessType.DELETE)
	@DeleteMapping("/{purchaseIds}")
    public AjaxResult remove(@PathVariable Long[] purchaseIds)
    {
        return toAjax(purchasesService.deletePurchasesByPurchaseIds(purchaseIds));
    }
}

7.0 销售记录管理功能

对药品进行销售、销毁处理等操作。



相关源码:

java 复制代码
@RestController
@RequestMapping("/manage/sales")
public class SalesController extends BaseController
{
    @Autowired
    private ISalesService salesService;

    /**
     * 查询销售记录列表
     */
    @PreAuthorize("@ss.hasPermi('manage:sales:list')")
    @GetMapping("/list")
    public TableDataInfo list(Sales sales)
    {
        startPage();
        List<Sales> list = salesService.selectSalesList(sales);
        return getDataTable(list);
    }

    /**
     * 导出销售记录列表
     */
    @PreAuthorize("@ss.hasPermi('manage:sales:export')")
    @Log(title = "销售记录", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, Sales sales)
    {
        List<Sales> list = salesService.selectSalesList(sales);
        ExcelUtil<Sales> util = new ExcelUtil<Sales>(Sales.class);
        util.exportExcel(response, list, "销售记录数据");
    }

    /**
     * 获取销售记录详细信息
     */
    @PreAuthorize("@ss.hasPermi('manage:sales:query')")
    @GetMapping(value = "/{saleId}")
    public AjaxResult getInfo(@PathVariable("saleId") Long saleId)
    {
        return success(salesService.selectSalesBySaleId(saleId));
    }

    /**
     * 新增销售记录
     */
    @PreAuthorize("@ss.hasPermi('manage:sales:add')")
    @Log(title = "销售记录", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody Sales sales)
    {
        return toAjax(salesService.insertSales(sales));
    }

    /**
     * 修改销售记录
     */
    @PreAuthorize("@ss.hasPermi('manage:sales:edit')")
    @Log(title = "销售记录", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody Sales sales)
    {
        return toAjax(salesService.updateSales(sales));
    }

    /**
     * 删除销售记录
     */
    @PreAuthorize("@ss.hasPermi('manage:sales:remove')")
    @Log(title = "销售记录", businessType = BusinessType.DELETE)
	@DeleteMapping("/{saleIds}")
    public AjaxResult remove(@PathVariable Long[] saleIds)
    {
        return toAjax(salesService.deleteSalesBySaleIds(saleIds));
    }
}

8.0 退货记录管理功能

药品进行合理的退货,需要对库存进行同步的调整。



相关源码:

java 复制代码
@RestController
@RequestMapping("/manage/returns")
public class ReturnsController extends BaseController
{
    @Autowired
    private IReturnsService returnsService;

    /**
     * 查询退货记录列表
     */
    @PreAuthorize("@ss.hasPermi('manage:returns:list')")
    @GetMapping("/list")
    public TableDataInfo list(Returns returns)
    {
        startPage();
        List<Returns> list = returnsService.selectReturnsList(returns);
        return getDataTable(list);
    }

    /**
     * 导出退货记录列表
     */
    @PreAuthorize("@ss.hasPermi('manage:returns:export')")
    @Log(title = "退货记录", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, Returns returns)
    {
        List<Returns> list = returnsService.selectReturnsList(returns);
        ExcelUtil<Returns> util = new ExcelUtil<Returns>(Returns.class);
        util.exportExcel(response, list, "退货记录数据");
    }

    /**
     * 获取退货记录详细信息
     */
    @PreAuthorize("@ss.hasPermi('manage:returns:query')")
    @GetMapping(value = "/{returnId}")
    public AjaxResult getInfo(@PathVariable("returnId") Long returnId)
    {
        return success(returnsService.selectReturnsByReturnId(returnId));
    }

    /**
     * 新增退货记录
     */
    @PreAuthorize("@ss.hasPermi('manage:returns:add')")
    @Log(title = "退货记录", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody Returns returns)
    {
        return toAjax(returnsService.insertReturns(returns));
    }

    /**
     * 修改退货记录
     */
    @PreAuthorize("@ss.hasPermi('manage:returns:edit')")
    @Log(title = "退货记录", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody Returns returns)
    {
        return toAjax(returnsService.updateReturns(returns));
    }

    /**
     * 删除退货记录
     */
    @PreAuthorize("@ss.hasPermi('manage:returns:remove')")
    @Log(title = "退货记录", businessType = BusinessType.DELETE)
	@DeleteMapping("/{returnIds}")
    public AjaxResult remove(@PathVariable Long[] returnIds)
    {
        return toAjax(returnsService.deleteReturnsByReturnIds(returnIds));
    }
}

9.0 库存变动管理功能

对药品进行采购、销售、调整都会进行记录。



相关源码:

java 复制代码
@RestController
@RequestMapping("/manage/movements")
public class InventoryMovementsController extends BaseController
{
    @Autowired
    private IInventoryMovementsService inventoryMovementsService;

    /**
     * 查询库存变动记录列表
     */
    @PreAuthorize("@ss.hasPermi('manage:movements:list')")
    @GetMapping("/list")
    public TableDataInfo list(InventoryMovements inventoryMovements)
    {
        startPage();
        List<InventoryMovements> list = inventoryMovementsService.selectInventoryMovementsList(inventoryMovements);
        return getDataTable(list);
    }

    /**
     * 导出库存变动记录列表
     */
    @PreAuthorize("@ss.hasPermi('manage:movements:export')")
    @Log(title = "库存变动记录", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, InventoryMovements inventoryMovements)
    {
        List<InventoryMovements> list = inventoryMovementsService.selectInventoryMovementsList(inventoryMovements);
        ExcelUtil<InventoryMovements> util = new ExcelUtil<InventoryMovements>(InventoryMovements.class);
        util.exportExcel(response, list, "库存变动记录数据");
    }

    /**
     * 获取库存变动记录详细信息
     */
    @PreAuthorize("@ss.hasPermi('manage:movements:query')")
    @GetMapping(value = "/{movementId}")
    public AjaxResult getInfo(@PathVariable("movementId") Long movementId)
    {
        return success(inventoryMovementsService.selectInventoryMovementsByMovementId(movementId));
    }

    /**
     * 新增库存变动记录
     */
    @PreAuthorize("@ss.hasPermi('manage:movements:add')")
    @Log(title = "库存变动记录", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody InventoryMovements inventoryMovements)
    {
        return toAjax(inventoryMovementsService.insertInventoryMovements(inventoryMovements));
    }

    /**
     * 修改库存变动记录
     */
    @PreAuthorize("@ss.hasPermi('manage:movements:edit')")
    @Log(title = "库存变动记录", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody InventoryMovements inventoryMovements)
    {
        return toAjax(inventoryMovementsService.updateInventoryMovements(inventoryMovements));
    }

    /**
     * 删除库存变动记录
     */
    @PreAuthorize("@ss.hasPermi('manage:movements:remove')")
    @Log(title = "库存变动记录", businessType = BusinessType.DELETE)
	@DeleteMapping("/{movementIds}")
    public AjaxResult remove(@PathVariable Long[] movementIds)
    {
        return toAjax(inventoryMovementsService.deleteInventoryMovementsByMovementIds(movementIds));
    }
}

10.0 SQL 数据库设计

sql 复制代码
create database pharmaceuticals;

-- 创建供应商表
CREATE TABLE suppliers (
    supplier_id INT AUTO_INCREMENT PRIMARY KEY COMMENT '供应商ID',
    img varchar(100) comment '照片',
    name VARCHAR(100) NOT NULL COMMENT '供应商名称',
    contact_person VARCHAR(100) COMMENT '联系人',
    phone VARCHAR(20) COMMENT '联系电话',
    email VARCHAR(100) COMMENT '电子邮箱',
    address TEXT COMMENT '地址',
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
    updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间'
) COMMENT='供应商信息表';


-- 创建药品表
CREATE TABLE medicines (
    medicine_id INT AUTO_INCREMENT PRIMARY KEY COMMENT '药品ID',
    name VARCHAR(100) NOT NULL COMMENT '药品名称',
    img varchar(100) comment '照片',
    generic_name VARCHAR(100) COMMENT '通用名',
    form tinyint COMMENT '剂型(如固体等)',
    expiration_date DATE COMMENT '有效期至',
    purchase_price DECIMAL(10, 2) COMMENT '进货价',
    sale_price DECIMAL(10, 2) COMMENT '售价',
    stock_quantity INT DEFAULT 0 COMMENT '库存数量',
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
    updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间'
) COMMENT='药品信息表';



-- 创建采购记录表
CREATE TABLE purchases (
    purchase_id INT AUTO_INCREMENT PRIMARY KEY COMMENT '采购ID',
    supplier_id INT NOT NULL COMMENT '供应商ID(逻辑外键关联suppliers表的supplier_id)',
    medicine_id INT NOT NULL COMMENT '药品ID(逻辑外键关联medicines表的medicine_id)',
    quantity INT NOT NULL COMMENT '数量',
    unit_price DECIMAL(10, 2) NOT NULL COMMENT '单价',
    purchase_date DATE NOT NULL COMMENT '采购日期',
    total_amount DECIMAL(10, 2) NOT NULL COMMENT '总金额',
    user_id INT NOT NULL COMMENT '创建人(逻辑外键关联users表的user_id)',
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
    updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间'
) COMMENT='采购记录表';

insert into purchases(supplier_id, medicine_id, quantity, unit_price, purchase_date, total_amount, user_id) values (1,1,10,30,now(),300,1);


-- 创建销售记录表
CREATE TABLE sales (
    sale_id INT AUTO_INCREMENT PRIMARY KEY COMMENT '销售ID',
    sale_date DATE NOT NULL COMMENT '销售日期',
    customer_name VARCHAR(100) COMMENT '客户姓名',
    customer_phone VARCHAR(20) COMMENT '客户电话',
    supplier_id INT NOT NULL COMMENT '供应商ID(逻辑外键关联suppliers表的supplier_id)',
    medicine_id INT NOT NULL COMMENT '药品ID(逻辑外键关联medicines表的medicine_id)',
    quantity INT NOT NULL COMMENT '数量',
    unit_price DECIMAL(10, 2) NOT NULL COMMENT '单价',
    total_amount DECIMAL(10, 2) NOT NULL COMMENT '总金额',
    user_id INT NOT NULL COMMENT '负责人(逻辑外键关联users表的user_id)',
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
    updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间'
) COMMENT='销售记录表';

insert into sales(sale_date, customer_name, customer_phone, supplier_id, medicine_id, quantity, unit_price, total_amount, user_id) VALUES
                  (now(),'小扳手','11789332791',1,1,1,40,40,1);


use pharmaceuticals;

-- 创建退货记录表
CREATE TABLE returns (
    return_id INT AUTO_INCREMENT PRIMARY KEY COMMENT '退货ID',
    customer_name VARCHAR(100) COMMENT '客户姓名',
    customer_phone VARCHAR(20) COMMENT '客户电话',
    medicine_id INT NOT NULL COMMENT '药品ID(逻辑外键关联medicines表的medicine_id)',
    supplier_id INT NOT NULL COMMENT '供应商ID(逻辑外键关联suppliers表的supplier_id)',
    sale_date DATE NOT NULL COMMENT '销售日期',
    sale_id INT NOT NULL COMMENT '销售ID(逻辑外键关联sales表的sale_id)',
    return_date DATE NOT NULL COMMENT '退货日期',
    total_amount DECIMAL(10, 2) NOT NULL COMMENT '退货总金额',
    reason TEXT COMMENT '退货原因',
    user_id INT NOT NULL COMMENT '处理人(逻辑外键关联users表的user_id)',
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
    updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间'
) COMMENT='退货记录表';

-- 创建库存变动记录表
CREATE TABLE inventory_movements (
    movement_id INT AUTO_INCREMENT PRIMARY KEY COMMENT '变动ID',
    supplier_id INT NOT NULL COMMENT '供应商ID(逻辑外键关联suppliers表的supplier_id)',
    medicine_id INT NOT NULL COMMENT '药品ID(逻辑外键关联medicines表的medicine_id)',
    movement_type INT NOT NULL COMMENT '变动类型:1.进货、2.销售、3.调整',
    quantity INT NOT NULL COMMENT '变动数量',
    movement_date DATE NOT NULL COMMENT '变动日期',
    reference_id INT COMMENT '参考ID(例如采购单ID或销售单ID)',
    note TEXT COMMENT '备注',
    user_id INT NOT NULL COMMENT '负责人(逻辑外键关联users表的user_id)',
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
    updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间'
) COMMENT='库存变动记录表';

若需要项目完整源码,可以在 CSDN 私信给我,我每天都有查看消息的,感谢大家支持,希望可以帮助到大家!

相关推荐
weixin199701080161 天前
开山网商品详情页前端性能优化实战
java·前端·python
HelloReader1 天前
Flutter 状态管理实战搭建维基百科阅读器项目
前端
掘金者阿豪1 天前
Joplin笔记告别局域网高效办公就靠cpolar
前端·后端
i建模1 天前
npm国内镜像源加速
前端·npm·node.js
恋猫de小郭1 天前
Cursor 自己做了模型 PK ,Cursor 里哪个模型性价比最高?
前端·人工智能·ai编程
张一凡931 天前
告别 Redux 的繁琐,试试这个基于类模型的 React 状态管理库:easy-model
前端·react.js
巫山老妖1 天前
OpenClaw 心跳机制实战:让 AI Agent 24 小时不停自主运行
java·前端
前端付豪1 天前
实现学习报告统计面板
前端·python·llm
opbr1 天前
Vite 插件实战:如何优雅地将构建时间注入到 HTML 中?
前端·开源
方也_arkling1 天前
基于脚手架创建Vue2工程
前端·javascript·vue.js