基于Springboot+Vue實(shí)現(xiàn)前后端分離進(jìn)銷存管理系統(tǒng)
項(xiàng)目編號(hào):BS-XX-144
引言:
目前整個(gè)社會(huì)已經(jīng)進(jìn)入到一個(gè)商品異常豐富的商品時(shí)代,商業(yè)化的高度發(fā)展也加速了商品流通的速度,很多的生產(chǎn)企業(yè)和商貿(mào)公司也遍地開(kāi)花似的蓬勃發(fā)展起來(lái)了。而如何去有效的管理這些琳瑯滿目的商品的采購(gòu)、銷售、庫(kù)存信息,是面臨的一大難題,傳統(tǒng)的靠人工去管理的方式即效率低下,又容易出錯(cuò),造成損耗,還無(wú)法及時(shí)統(tǒng)計(jì)信息。在當(dāng)今信息化技術(shù)普遍應(yīng)用的今天,如何利用信息化和數(shù)字化去管理商品的進(jìn)銷存信息,是一個(gè)值得研究的問(wèn)題。
本次經(jīng)過(guò)調(diào)研走訪開(kāi)發(fā)設(shè)計(jì)的這套進(jìn)銷存管理系統(tǒng),它的設(shè)計(jì)與開(kāi)發(fā)主要基于Java開(kāi)發(fā)語(yǔ)言平臺(tái),采用Spring 全家桶技術(shù)中的輕量級(jí)Springboot框架技術(shù),并結(jié)合JPA第三方持久層框架開(kāi)發(fā)實(shí)現(xiàn),前端頁(yè)面使用ElementsUI進(jìn)行頁(yè)面的開(kāi)發(fā)布局,并同時(shí)使用了Vue等前端技術(shù)進(jìn)行頁(yè)面美化和圖形報(bào)表開(kāi)發(fā)。進(jìn)銷存系統(tǒng)的業(yè)務(wù)數(shù)據(jù)存儲(chǔ)則使用MySQL8數(shù)據(jù)庫(kù)。系統(tǒng)使用Tomcat8.5.31來(lái)部署運(yùn)行。
這套進(jìn)銷存管理系統(tǒng)的開(kāi)發(fā)主要是采用產(chǎn)品設(shè)計(jì)開(kāi)發(fā)的思路去做,盡量做的功能具有普遍適用性,經(jīng)過(guò)走訪調(diào)查,得出大多數(shù)商家的基本功能需求進(jìn)而進(jìn)行抽取整合,開(kāi)發(fā)實(shí)現(xiàn)了這套進(jìn)銷存管理系統(tǒng),它具有一定的社會(huì)推廣性,對(duì)整個(gè)社會(huì)的商業(yè)化進(jìn)行有著廣泛而積極的意義。
一,項(xiàng)目簡(jiǎn)介
基于SpringBoot+Vue實(shí)現(xiàn)的一個(gè)比較全面的進(jìn)銷存管理系統(tǒng)。系統(tǒng)整體功能比較強(qiáng)大,操作人機(jī)交互性比較好,無(wú)論是從開(kāi)發(fā)模式還是易用性和技術(shù),都是比較優(yōu)秀的一個(gè)項(xiàng)目,適合有些難度或要求較高的畢業(yè)設(shè)計(jì)項(xiàng)目使用。系統(tǒng)有著完備的權(quán)限管理控制,可以自行定義角色和用戶并自由分配權(quán)限,不同的角色用戶進(jìn)入系統(tǒng)擁有的操作權(quán)限也不相同。主要完成的功能 有:
用戶注冊(cè)登陸
首頁(yè)儀表盤信息統(tǒng)計(jì)功能
圖形報(bào)表統(tǒng)計(jì)展示功能
系統(tǒng)管理模塊
部門管理
用戶管理
菜單管理
角色管理
商品分類管理
供應(yīng)商管理
客戶管理
采購(gòu)管理模塊
采購(gòu)訂單管理模塊
采購(gòu)入庫(kù)管理模塊
銷售管理模塊
銷售訂單管理模塊
銷售出庫(kù)管理模塊
庫(kù)存管理模塊
消息中心模塊
二,環(huán)境介紹
語(yǔ)言環(huán)境:Java:? jdk1.8
數(shù)據(jù)庫(kù):Mysql: mysql8?? Redis:redis5.0
應(yīng)用服務(wù)器:Tomcat:? tomcat8.5.31
開(kāi)發(fā)工具:IDEA或eclipse
后臺(tái)開(kāi)發(fā)技術(shù):Springboot+Mybatis-plus
前端開(kāi)發(fā)技術(shù):Nodejs+Vue+ElemenetUI
第三方技術(shù):七牛云
三,系統(tǒng)展示
用戶登陸

首頁(yè)統(tǒng)計(jì)


消息管理

個(gè)人消息

采購(gòu)訂單

采購(gòu)入庫(kù)

銷售訂單

銷售出庫(kù)

庫(kù)存管理

部門管理

菜單管理

角色管理

用戶管理

商品分類管理

客戶管理

供應(yīng)商管理

四,核心代碼展示
package cn.toesbieya.jxc.controller;import cn.toesbieya.jxc.model.vo.LoginParam;import cn.toesbieya.jxc.model.vo.PasswordUpdateParam;import cn.toesbieya.jxc.model.vo.RegisterParam;import cn.toesbieya.jxc.model.vo.UserVo;import cn.toesbieya.jxc.service.AccountService;import cn.toesbieya.jxc.util.SessionUtil;import cn.toesbieya.jxc.util.IpUtil;import cn.toesbieya.jxc.model.vo.R;import org.springframework.util.StringUtils;import org.springframework.web.bind.annotation.*;import javax.annotation.Resource;import javax.servlet.http.HttpServletRequest;import javax.validation.Valid;import java.io.UnsupportedEncodingException;import java.net.URLDecoder;public class AccountController { ? ?
? ?private AccountService service; ? ?
? ?public R login(HttpServletRequest request, { ? ? ? ? LoginParam param)return service.login(param, IpUtil.getIp(request));
? ?} ? ?
? ?public R logout(HttpServletRequest request) { ? ? ? ?UserVo user = SessionUtil.get(request); ? ? ? ?return service.logout(user, IpUtil.getIp(request));
? ?} ? ?
? ?public R register( { ? ? ? ? RegisterParam param)return service.register(param);
? ?} ? ?
? ?public R updatePwd( { ? ? ? ? PasswordUpdateParam param)UserVo user = SessionUtil.get();
? ? ? ?param.setId(user.getId()); ? ? ? ?String errMsg = validateUpdatePwdParam(param); ? ? ? ?if (errMsg != null) return R.fail(errMsg); ? ? ? ?return service.updatePwd(param);
? ?} ? ?
? ?public R updateAvatar( String key)throws UnsupportedEncodingException { ? ? ? ?if (StringUtils.isEmpty(key)) return R.fail("參數(shù)錯(cuò)誤"); ? ? ? ?return service.updateAvatar(SessionUtil.get(), URLDecoder.decode(key, "utf-8"));
? ?} ? ?
? ?public R validate( { ? ? ? ? String pwd)UserVo current = SessionUtil.get(); ? ? ? ?if (!pwd.equals(current.getPwd())) { ? ? ? ? ? ?return R.fail("校驗(yàn)失敗");
? ? ? ?} ? ? ? ?return R.success("校驗(yàn)通過(guò)");
? ?} ? ?
? ?public R checkLoginName( { ? ? ? ? Integer id, String name)if (StringUtils.isEmpty(name)) { ? ? ? ? ? ?return R.success();
? ? ? ?} ? ? ? ?return R.success(service.isLoginNameExist(name, id) ? "該登錄名已存在" : null);
? ?} ? ?
? ?public R checkNickName( { ? ? ? ? Integer id, String name)if (StringUtils.isEmpty(name)) { ? ? ? ? ? ?return R.success();
? ? ? ?} ? ? ? ?return R.success(service.isNickNameExist(name, id) ? "該昵稱已存在" : null);
? ?} ? ?private String validateUpdatePwdParam(PasswordUpdateParam vo) { ? ? ? ?if (vo.getId() == null) return "修改失敗,參數(shù)錯(cuò)誤"; ? ? ? ?if (StringUtils.isEmpty(vo.getOldPwd())) return "修改失敗,原密碼不能為空"; ? ? ? ?if (StringUtils.isEmpty(vo.getNewPwd())) return "修改失敗,新密碼不能為空"; ? ? ? ?if (vo.getOldPwd().equals(vo.getNewPwd())) return "修改失敗,新密碼不得與舊密碼相同"; ? ? ? ?if (vo.getNewPwd().length() != 32) return "修改失敗,密碼參數(shù)有誤"; ? ? ? ?return null;
? ?}
}
package cn.toesbieya.jxc.controller;import cn.toesbieya.jxc.model.vo.search.StockSearch;import cn.toesbieya.jxc.service.BizStockService;import cn.toesbieya.jxc.model.vo.R;import org.springframework.util.StringUtils;import org.springframework.web.bind.annotation.*;import javax.annotation.Resource;import javax.servlet.http.HttpServletResponse;public class BizStockController { ? ?
? ?private BizStockService service; ? ?
? ?public R search( { ? ? ? ? StockSearch vo)return R.success(service.search(vo));
? ?} ? ?
? ?public R getDetail( { ? ? ? ? String cids)if (StringUtils.isEmpty(cids)) return R.fail("參數(shù)錯(cuò)誤"); ? ? ? ?return R.success(service.getDetail(cids));
? ?} ? ?
? ?public R getDetailById( { ? ? ? ? String ids)if (StringUtils.isEmpty(ids)) return R.fail("參數(shù)錯(cuò)誤"); ? ? ? ?return R.success(service.getDetailById(ids));
? ?} ? ?
? ?public void export( StockSearch vo, HttpServletResponse response)throws Exception {
? ? ? ?service.export(vo, response);
? ?}
}
package cn.toesbieya.jxc.controller.sys;import cn.toesbieya.jxc.model.entity.SysCategory;import cn.toesbieya.jxc.model.vo.search.CategorySearch;import cn.toesbieya.jxc.service.sys.SysCategoryService;import cn.toesbieya.jxc.model.vo.R;import org.springframework.util.StringUtils;import org.springframework.web.bind.annotation.*;import javax.annotation.Resource;public class CategoryController { ? ?
? ?private SysCategoryService service; ? ?
? ?public R getAll() { ? ? ? ?return R.success(service.getAll());
? ?} ? ?
? ?public R search( { ? ? ? ? CategorySearch vo)return R.success(service.search(vo));
? ?} ? ?
? ?public R add( { ? ? ? ? SysCategory category)String errMsg = validateCategoryCreateParam(category); ? ? ? ?if (errMsg != null) return R.fail(errMsg);
? ? ? ?category.setId(null);
? ? ? ?category.setCtime(System.currentTimeMillis()); ? ? ? ?return service.add(category);
? ?} ? ?
? ?public R update( { ? ? ? ? SysCategory category)String errMsg = validateCategoryUpdateParam(category); ? ? ? ?if (errMsg != null) return R.fail(errMsg); ? ? ? ?return service.update(category);
? ?} ? ?
? ?public R del( { ? ? ? ? SysCategory category)if (category.getId() == null) return R.fail("刪除失敗,參數(shù)錯(cuò)誤"); ? ? ? ?return service.del(category);
? ?} ? ?private String validateCategoryCreateParam(SysCategory category) { ? ? ? ?if (category.getPid() == null) return "創(chuàng)建失敗,參數(shù)錯(cuò)誤"; ? ? ? ?if (StringUtils.isEmpty(category.getName())) return "創(chuàng)建失敗,分類名稱不能為空"; ? ? ? ?return null;
? ?} ? ?private String validateCategoryUpdateParam(SysCategory category) { ? ? ? ?if (category.getId() == null) return "修改失敗,參數(shù)錯(cuò)誤"; ? ? ? ?if (category.getPid() == null) return "創(chuàng)建失敗,參數(shù)錯(cuò)誤"; ? ? ? ?if (StringUtils.isEmpty(category.getName())) return "創(chuàng)建失敗,分類名稱不能為空"; ? ? ? ?return null;
? ?}
}
package cn.toesbieya.jxc.controller.sys;import cn.toesbieya.jxc.model.entity.SysCustomer;import cn.toesbieya.jxc.model.vo.search.CustomerSearch;import cn.toesbieya.jxc.service.sys.SysCustomerService;import cn.toesbieya.jxc.model.vo.R;import org.springframework.util.StringUtils;import org.springframework.web.bind.annotation.*;import javax.annotation.Resource;public class CustomerController { ? ?
? ?private SysCustomerService service; ? ?
? ?public R getLimitRegion() { ? ? ? ?return R.success(service.getLimitRegion());
? ?} ? ?
? ?public R search( { ? ? ? ? CustomerSearch vo)return R.success(service.search(vo));
? ?} ? ?
? ?public R add( { ? ? ? ? SysCustomer customer)String errMsg = validateCreateParam(customer); ? ? ? ?if (errMsg != null) return R.fail("創(chuàng)建失敗," + errMsg);
? ? ? ?customer.setId(null);
? ? ? ?customer.setCtime(System.currentTimeMillis()); ? ? ? ?return service.add(customer);
? ?} ? ?
? ?public R update( { ? ? ? ? SysCustomer customer)String errMsg = validateUpdateParam(customer); ? ? ? ?if (errMsg != null) return R.fail("修改失敗," + errMsg); ? ? ? ?return service.update(customer);
? ?} ? ?
? ?public R del( { ? ? ? ? SysCustomer customer)if (customer.getId() == null) return R.fail("刪除失敗,參數(shù)錯(cuò)誤"); ? ? ? ?return service.del(customer);
? ?} ? ?private String validateCreateParam(SysCustomer customer) { ? ? ? ?if (StringUtils.isEmpty(customer.getName())) return "客戶名稱不能為空"; ? ? ? ?if (StringUtils.isEmpty(customer.getRegion())) return "客戶行政區(qū)域不能為空"; ? ? ? ?if (StringUtils.isEmpty(customer.getAddress())) return "客戶地址不能為空"; ? ? ? ?if (StringUtils.isEmpty(customer.getLinkman())) return "客戶聯(lián)系人不能為空"; ? ? ? ?if (StringUtils.isEmpty(customer.getLinkphone())) return "客戶聯(lián)系電話不能為空"; ? ? ? ?return null;
? ?} ? ?private String validateUpdateParam(SysCustomer customer) { ? ? ? ?if (customer.getId() == null) return "參數(shù)錯(cuò)誤"; ? ? ? ?return validateCreateParam(customer);
? ?}
}
package cn.toesbieya.jxc.controller.sys;import cn.toesbieya.jxc.model.entity.RecUserAction;import cn.toesbieya.jxc.model.entity.SysUser;import cn.toesbieya.jxc.model.vo.search.UserSearch;import cn.toesbieya.jxc.util.ThreadUtil;import cn.toesbieya.jxc.service.sys.SysUserService;import cn.toesbieya.jxc.model.vo.R;import org.springframework.util.StringUtils;import org.springframework.web.bind.annotation.PostMapping;import org.springframework.web.bind.annotation.RequestBody;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import javax.annotation.Resource;import java.util.List;import java.util.stream.Collectors;public class UserController { ? ?
? ?private SysUserService service; ? ?
? ?public R search( { ? ? ? ? UserSearch vo)return R.success(service.search(vo));
? ?} ? ?
? ?public R add( { ? ? ? ? SysUser user)String errMsg = validateUserCreateParam(user); ? ? ? ?if (errMsg != null) { ? ? ? ? ? ?return R.fail(errMsg);
? ? ? ?} ? ? ? ?return service.add(user);
? ?} ? ?
? ?public R update( { ? ? ? ? SysUser user)String errMsg = validateUserUpdateParam(user); ? ? ? ?if (errMsg != null) { ? ? ? ? ? ?return R.fail(errMsg);
? ? ? ?} ? ? ? ?return service.update(user);
? ?} ? ?
? ?public R del( { ? ? ? ? SysUser user)if (user.getId() == null) { ? ? ? ? ? ?return R.fail("刪除失敗");
? ? ? ?} ? ? ? ?return service.del(user);
? ?} ? ?
? ?public R kick( { ? ? ? ? List<SysUser> users)if (users == null || users.isEmpty()) { ? ? ? ? ? ?return R.fail("參數(shù)錯(cuò)誤");
? ? ? ?} ? ? ? ?RecUserAction action = ThreadUtil.getAction();
? ? ? ?List<String> names = users.stream().map(SysUser::getLoginName).collect(Collectors.toList());
? ? ? ?action.setAction("踢出用戶:【" + String.join(",", names) + "】"); ? ? ? ?return service.kick(users);
? ?} ? ?
? ?public R resetPwd( { ? ? ? ? SysUser user)if (user.getId() == null || StringUtils.isEmpty(user.getLoginName())) { ? ? ? ? ? ?return R.fail("參數(shù)錯(cuò)誤");
? ? ? ?} ? ? ? ?return service.resetPwd(user);
? ?} ? ?private String validateUserCreateParam(SysUser user) { ? ? ? ?if (user.getId() != null) return "創(chuàng)建失敗,參數(shù)錯(cuò)誤"; ? ? ? ?if (StringUtils.isEmpty(user.getLoginName())
? ? ? ? ? ? ? ?||StringUtils.isEmpty(user.getNickName())) { ? ? ? ? ? ?return "創(chuàng)建失敗,用戶名稱不能為空";
? ? ? ?} ? ? ? ?if (user.getRole() == null) return "創(chuàng)建失敗,用戶角色不能為空"; ? ? ? ?return null;
? ?} ? ?private String validateUserUpdateParam(SysUser user) { ? ? ? ?if (user.getId() == null) return "修改失敗,參數(shù)錯(cuò)誤"; ? ? ? ?if (StringUtils.isEmpty(user.getLoginName())
? ? ? ? ? ? ? ?||StringUtils.isEmpty(user.getNickName())) { ? ? ? ? ? ?return "創(chuàng)建失敗,用戶名稱不能為空";
? ? ? ?} ? ? ? ?if (user.getRole() == null) return "修改失敗,用戶角色不能為空"; ? ? ? ?return null;
? ?}
}
五,項(xiàng)目總結(jié)
數(shù)字化和信息化是近年來(lái)各行業(yè)的發(fā)展趨勢(shì)。各種規(guī)模的公司正在迅速崛起。許多從事生產(chǎn)經(jīng)營(yíng)管理的企業(yè)都有自己的產(chǎn)品生產(chǎn)和銷售,其中有代表性的就是各大超市與食品工廠。這些超市和工廠的食品需要存放在倉(cāng)庫(kù)中。對(duì)于每個(gè)超市和工廠來(lái)說(shuō),隨著規(guī)模的不斷擴(kuò)大和產(chǎn)品數(shù)量的急劇增加,產(chǎn)品的種類將不斷更新和發(fā)展,關(guān)于產(chǎn)品的信息量也將成倍增長(zhǎng)。面對(duì)海量的產(chǎn)品信息,如何有效地管理庫(kù)存產(chǎn)品對(duì)這些超市和工廠來(lái)說(shuō)非常重要。倉(cāng)庫(kù)管理的重點(diǎn)是銷售信息能否及時(shí)反饋,從而保證超市和工廠的運(yùn)營(yíng)效率。在當(dāng)今的數(shù)字時(shí)代,為了加快倉(cāng)庫(kù)管理員的管理,我們必須依靠計(jì)算機(jī),使貨物數(shù)據(jù)的管理更加簡(jiǎn)單和到位?;谝陨显颍惹行枰_(kāi)發(fā)一套進(jìn)銷存管理系統(tǒng)。本文是基于計(jì)算機(jī)對(duì)倉(cāng)庫(kù)中的大量數(shù)據(jù)進(jìn)行處理和處理的研究。
進(jìn)銷存管理涉及產(chǎn)品進(jìn)出倉(cāng)庫(kù)、銷售人員和客戶等各個(gè)方面。如何管理這些信息數(shù)據(jù)是一項(xiàng)復(fù)雜的系統(tǒng)工程,它充分考驗(yàn)著倉(cāng)庫(kù)管理員的工作能力。可以想象,工作量很重。因此,需要設(shè)計(jì)出一套進(jìn)銷存管理系統(tǒng)來(lái)提高庫(kù)存管理的效率,這對(duì)于規(guī)范管理、數(shù)據(jù)統(tǒng)計(jì)、快速查詢信息、減少管理工作量、調(diào)動(dòng)員工積極性、提高生產(chǎn)效率具有重要的現(xiàn)實(shí)意義。
在我國(guó),從二十世紀(jì)七十年代計(jì)算機(jī)得以應(yīng)用后,國(guó)內(nèi)企業(yè)才逐漸配合該技術(shù)產(chǎn)生相應(yīng)進(jìn)銷存管理應(yīng)用,然而受當(dāng)時(shí)軟硬件水平局限該類系統(tǒng)也僅支持完成那些較簡(jiǎn)單性的管理操作。直到八十年代,沈陽(yáng)一家鼓風(fēng)機(jī)廠率先引進(jìn)COPICS系統(tǒng)(由IBM公司開(kāi)發(fā))才打破此種僵局,拉開(kāi)在我國(guó)畜牧業(yè)應(yīng)用MRPII系統(tǒng)的序幕[10]。
到上世紀(jì)末,受計(jì)算機(jī)技術(shù)發(fā)展及863計(jì)劃雙重影響,我國(guó)大量企業(yè)開(kāi)始引進(jìn)使用外國(guó)先進(jìn)系統(tǒng)來(lái)完善自身企業(yè)管理。
??? 本世紀(jì)以來(lái),在我國(guó)實(shí)施信息化帶動(dòng)工業(yè)化政策響應(yīng)下,更多外國(guó)先進(jìn)知名企業(yè)開(kāi)始青睞我國(guó)市場(chǎng),在我國(guó)加設(shè)辦事處。不僅增大了我國(guó)市場(chǎng)還激發(fā)了國(guó)有化產(chǎn)品的研發(fā).進(jìn)度,也給我國(guó)進(jìn)銷存管理應(yīng)用軟件行業(yè)帶來(lái)了新的契機(jī)促進(jìn)其高速發(fā)展。一時(shí)之間我國(guó)的聯(lián)想、華為等許多知名企業(yè)基于其所引進(jìn)的外國(guó)先進(jìn)軟件結(jié)合自身實(shí)際情況與市.場(chǎng)需要,開(kāi)發(fā)出了許多更加適合我國(guó)實(shí)際問(wèn)題的應(yīng)用商品,并在推出后取得極好的市場(chǎng)反映。