赞
踩
基于javaweb的商品进销存系统(java+vue+springboot+mybatis+mysql)
运行环境
Java≥8、MySQL≥5.7、Node.js≥10
开发工具
后端:eclipse/idea/myeclipse/sts等均可配置运行
前端:WebStorm/VSCode/HBuilderX等均可
适用
课程设计,大作业,毕业设计,项目练习,学习演示等
功能说明
基于javaweb+mysql的商品进销存系统(java+Vue+SpringBoot+Maven+mybatis+Mysql)
一、项目运行 环境配置:
Jdk1.8 + Tomcat8.5 + Mysql + HBuilderX(Webstorm也行)+ Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。
项目技术:
Spring + SpringBoot+ mybatis + Maven + Vue 等等组成,B/S模式 + Maven管理等等。
接口返回数据格式:
/**
接口返回数据格式
@author scott
*/
@Data
@ApiModel(value=“接口返回对象”, descriiption=“接口返回对象”)
public class Result implements Serializable {
private static final long serialVersionUID = 1L;
/**
*/
@ApiModelProperty(value = “成功标志”)
private boolean success = true;
/**
*/
@ApiModelProperty(value = “返回处理消息”)
private String message = “操作成功!”;
/**
*/
@ApiModelProperty(value = “返回代码”)
private Integer code = 0;
/**
*/
@ApiModelProperty(value = “返回数据对象”)
private T result;
/**
*/
@ApiModelProperty(value = “时间戳”)
private long timestamp = System.currentTimeMillis();
public Result() {
public Result success(String message) {
this.message = message;
this.code = CommonConstant.SC_OK_200;
this.success = true;
return this;
public static Result ok() {
Result r = new Result();
r.setSuccess(true);
r.setCode(CommonConstant.SC_OK_200);
r.setMessage(“成功”);
return r;
public static Result ok(String msg) {
Result r = new Result();
r.setSuccess(true);
r.setCode(CommonConstant.SC_OK_200);
r.setMessage(msg);
return r;
public static Result ok(Object data) {
Result r = new Result();
r.setSuccess(true);
r.setCode(CommonConstant.SC_OK_200);
r.setResult(data);
return r;
public static Result error(String msg) {
return error(CommonConstant.SC_INTERNAL_SERVER_ERROR_500, msg);
public static Result error(int code, String msg) {
Result r = new Result();
r.setCode(code);
r.setMessage(msg);
r.setSuccess(false);
return r;
public Result error500(String message) {
this.message = message;
this.code = CommonConstant.SC_INTERNAL_SERVER_ERROR_500;
this.success = false;
return this;
/**
*/
public static Result noauth(String msg) {
return error(CommonConstant.SC_JEECG_NO_AUTHZ, msg);
用户信息控制器:
/**
用户表 前端控制器
*/
@Slf4j
@RestController
@RequestMapping(“/sys/common”)
public class CommonController {
@Autowired
private ISysBaseAPI sysBaseAPI;
@Value(value = “${jeecg.path.upload}”)
private String uploadpath;
/**
*/
@Value(value=“${jeecg.uploadType}”)
private String uploadType;
/**
@Author 政辉
@return
*/
@GetMapping(“/403”)
public Result<?> noauth() {
return Result.error(“没有权限,请联系管理员授权”);
/**
文件上传统一方法
@param request
@param response
@return
*/
@PostMapping(value = “/upload”)
public Result<?> upload(HttpServletRequest request, HttpServletResponse response) {
Result<?> result = new Result<>();
String savePath = “”;
String bizPath = request.getParameter(“biz”);
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
MultipartFile file = multipartRequest.getFile(“file”);// 获取上传文件对象
if(oConvertUtils.isEmpty(bizPath)){
if(CommonConstant.UPLOAD_TYPE_OSS.equals(uploadType)){
//未指定目录,则用阿里云默认目录 upload
bizPath = “upload”;
//result.setMessage(“使用阿里云文件上传时,必须添加目录!”);
//result.setSuccess(false);
//return result;
}else{
bizPath = “”;
if(CommonConstant.UPLOAD_TYPE_LOCAL.equals(uploadType)){
//针对jeditor编辑器如何使 lcaol模式,采用 base64格式存储
String jeditor = request.getParameter(“jeditor”);
if(oConvertUtils.isNotEmpty(jeditor)){
result.setMessage(CommonConstant.UPLOAD_TYPE_LOCAL);
result.setSuccess(true);
return result;
}else{
savePath = this.uploadLocal(file,bizPath);
}else{
savePath = sysBaseAPI.upload(file,bizPath,uploadType);
if(oConvertUtils.isNotEmpty(savePath)){
result.setMessage(savePath);
result.setSuccess(true);
}else {
result.setMessage(“上传失败!”);
result.setSuccess(false);
return result;
/**
本地文件上传
@param mf 文件
@param bizPath 自定义路径
@return
*/
private String uploadLocal(MultipartFile mf,String bizPath){
try {
String ctxPath = uploadpath;
String fileName = null;
File file = new File(ctxPath + File.separator + bizPath + File.separator );
if (!file.exists()) {
file.mkdirs();// 创建文件根目录
String orgName = mf.getOriginalFilename();// 获取文件名
orgName = CommonUtils.getFileName(orgName);
if(orgName.indexOf(“.”)!=-1){
fileName = orgName.substring(0, orgName.lastIndexOf(“.”)) + “_” + System.currentTimeMillis() + orgName.substring(orgName.indexOf(“.”));
}else{
fileName = orgName+ “_” + System.currentTimeMillis();
String savePath = file.getPath() + File.separator + fileName;
File savefile = new File(savePath);
FileCopyUtils.copy(mf.getBytes(), savefile);
String dbpath = null;
if(oConvertUtils.isNotEmpty(bizPath)){
dbpath = bizPath + File.separator + fileName;
}else{
dbpath = fileName;
if (dbpath.contains(“\”)) {
dbpath = dbpath.replace(“\”, “/”);
return dbpath;
} catch (IOException e) {
log.error(e.getMessage(), e);
return “”;
// @PostMapping(value = “/upload2”)
// public Result<?> upload2(HttpServletRequest request, HttpServletResponse response) {
// Result<?> result = new Result<>();
// try {
// String ctxPath = uploadpath;
// String fileName = null;
// String bizPath = “files”;
// String tempBizPath = request.getParameter(“biz”);
// if(oConvertUtils.isNotEmpty(tempBizPath)){
// bizPath = tempBizPath;
// }
// String nowday = new SimpleDateFormat(“yyyyMMdd”).format(new Date());
// File file = new File(ctxPath + File.separator + bizPath + File.separator + nowday);
// if (!file.exists()) {
// file.mkdirs();// 创建文件根目录
// }
// MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
// MultipartFile mf = multipartRequest.getFile(“file”);// 获取上传文件对象
// String orgName = mf.getOriginalFilename();// 获取文件名
// fileName = orgName.substring(0, orgName.lastIndexOf(“.”)) + “_” + System.currentTimeMillis() + orgName.substring(orgName.indexOf(“.”));
// String savePath = file.getPath() + File.separator + fileName;
// File savefile = new File(savePath);
// FileCopyUtils.copy(mf.getBytes(), savefile);
// String dbpath = bizPath + File.separator + nowday + File.separator + fileName;
// if (dbpath.contains(“\”)) {
// dbpath = dbpath.replace(“\”, “/”);
// }
// result.setMessage(dbpath);
// result.setSuccess(true);
// } catch (IOException e) {
// result.setSuccess(false);
// result.setMessage(e.getMessage());
// log.error(e.getMessage(), e);
// }
// return result;
// }
/**
预览图片&下载文件
请求地址:http://localhost:8080/common/static/{user/20190119/e1fe9925bc315c60addea1b98eb1cb1349547719_1547866868179.jpg}
@param request
@param response
*/
@GetMapping(value = “/static/**”)
public void view(HttpServletRequest request, HttpServletResponse response) {
// ISO-8859-1 ==> UTF-8 进行编码转换
String imgPath = extractPathFromPattern(request);
if(oConvertUtils.isEmpty(imgPath) || imgPath==“null”){
return;
// 其余处理略
InputStream inputStream = null;
OutputStream outputStream = null;
try {
imgPath = imgPath.replace(“…”, “”);
if (imgPath.endsWith(“,”)) {
imgPath = imgPath.substring(0, imgPath.length() - 1);
String filePath = uploadpath + File.separator + imgPath;
File file = new File(filePath);
if(!file.exists()){
response.setStatus(404);
throw new RuntimeException(“文件不存在…”);
response.setContentType(“application/force-download”);// 设置强制下载不打开
response.addHeader(“Content-Disposition”, “attachment;fileName=” + new String(file.getName().getBytes(“UTF-8”),“iso-8859-1”));
inputStream = new BufferedInputStream(new FileInputStream(filePath));
outputStream = response.getOutputStream();
byte[] buf = new byte[1024];
int len;
while ((len = inputStream.read(buf)) > 0) {
outputStream.write(buf, 0, len);
response.flushBuffer();
} catch (IOException e) {
log.error(“预览文件失败” + e.getMessage());
response.setStatus(404);
e.printStackTrace();
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
log.error(e.getMessage(), e);
if (outputStream != null) {
try {
outputStream.close();
} catch (IOException e) {
log.error(e.getMessage(), e);
// /**
// * 下载文件
// * 请求地址:http://localhost:8080/common/download/{user/20190119/e1fe9925bc315c60addea1b98eb1cb1349547719_1547866868179.jpg}
// *
// * @param request
// * @param response
// * @throws Exception
// */
// @GetMapping(value = “/download/**”)
// public void download(HttpServletRequest request, HttpServletResponse response) throws Exception {
// // ISO-8859-1 ==> UTF-8 进行编码转换
// String filePath = extractPathFromPattern(request);
// // 其余处理略
// InputStream inputStream = null;
// OutputStream outputStream = null;
// try {
// filePath = filePath.replace(“…”, “”);
// if (filePath.endsWith(“,”)) {
// filePath = filePath.substring(0, filePath.length() - 1);
// }
// String localPath = uploadpath;
// String downloadFilePath = localPath + File.separator + filePath;
// File file = new File(downloadFilePath);
// if (file.exists()) {
// response.setContentType(“application/force-download”);// 设置强制下载不打开
// response.addHeader(“Content-Disposition”, “attachment;fileName=” + new String(file.getName().getBytes(“UTF-8”),“iso-8859-1”));
// inputStream = new BufferedInputStream(new FileInputStream(file));
// outputStream = response.getOutputStream();
// byte[] buf = new byte[1024];
// int len;
// while ((len = inputStream.read(buf)) > 0) {
// outputStream.write(buf, 0, len);
// }
// response.flushBuffer();
// }
//
// } catch (Exception e) {
// log.info(“文件下载失败” + e.getMessage());
// // e.printStackTrace();
// } finally {
// if (inputStream != null) {
// try {
// inputStream.close();
// } catch (IOException e) {
// e.printStackTrace();
// }
// }
// if (outputStream != null) {
// try {
// outputStream.close();
// } catch (IOException e) {
// e.printStackTrace();
// }
// }
// }
//
// }
/**
@功能:pdf预览Iframe
@param modelAndView
@return
*/
@RequestMapping(“/pdf/pdfPreviewIframe”)
public ModelAndView pdfPreviewIframe(ModelAndView modelAndView) {
modelAndView.setViewName(“pdfPreviewIframe”);
return modelAndView;
/**
把指定URL后的字符串全部截断当成参数
这么做是为了防止URL中包含中文或者特殊字符(/等)时,匹配不了的问题
@param request
@return
*/
private static String extractPathFromPattern(final HttpServletRequest request) {
String path = (String) request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE);
String bestMatchPattern = (String) request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE);
return new AntPathMatcher().extractPathWithinPattern(bestMatchPattern, path);
/**
中转HTTP请求,解决跨域问题
@param url 必填:请求地址
@return
*/
@RequestMapping(“/transitRESTful”)
public Result transitRESTful(@RequestParam(“url”) String url, HttpServletRequest request) {
try {
ServletServerHttpRequest httpRequest = new ServletServerHttpRequest(request);
// 中转请求method、body
HttpMethod method = httpRequest.getMethod();
JSONObject params;
try {
params = JSON.parseObject(JSON.toJSONString(httpRequest.getBody()));
} catch (Exception e) {
params = new JSONObject();
// 中转请求问号参数
JSONObject variables = JSON.parseObject(JSON.toJSONString(request.getParameterMap()));
variables.remove(“url”);
// 在 headers 里传递Token
String token = TokenUtils.getTokenByRequest(request);
HttpHeaders headers = new HttpHeaders();
headers.set(“X-Access-Token”, token);
// 发送请求
String httpURL = URLDecoder.decode(url, “UTF-8”);
ResponseEntity response = RestUtil.request(httpURL, method, headers , variables, params, String.class);
// 封装返回结果
Result result = new Result<>();
int statusCode = response.getStatusCodeValue();
result.setCode(statusCode);
result.setSuccess(statusCode == 200);
String responseBody = response.getBody();
try {
// 尝试将返回结果转为JSON
Object json = JSON.parse(responseBody);
result.setResult(json);
} catch (Exception e) {
// 转成JSON失败,直接返回原始数据
result.setResult(responseBody);
return result;
} catch (Exception e) {
log.debug(“中转HTTP请求失败”, e);
return Result.error(e.getMessage());
付款单控制层:
/**
*/
@Api(tags=“付款单”)
@RestController
@RequestMapping(“/finance/finPayment”)
@Slf4j
public class FinPaymentController {
@Autowired
private IFinPaymentService finPaymentService;
@Autowired
private IFinPaymentEntryService finPaymentEntryService;
/**
分页列表查询
@param finPayment
@param pageNo
@param pageSize
@param req
@return
*/
@AutoLog(value = “付款单-分页列表查询”)
@ApiOperation(value=“付款单-分页列表查询”, notes=“付款单-分页列表查询”)
@GetMapping(value = {“/list”, “/list/{paymentType}”}) //paymentType会传至finPayment.paymentType
public Result<?> queryPageList(FinPayment finPayment,
@RequestParam(name=“pageNo”, defaultValue=“1”) Integer pageNo,
@RequestParam(name=“pageSize”, defaultValue=“10”) Integer pageSize,
HttpServletRequest req) {
QueryWrapper queryWrapper = QueryGenerator.initQueryWrapper(finPayment, req.getParameterMap());
Page page = new Page(pageNo, pageSize);
IPage pageList = finPaymentService.page(page, queryWrapper);
return Result.ok(pageList);
@GetMapping(value = “/checkableList”)
public Result<?> queryCheckablePageList(FinPayment finPayment,
@RequestParam(name=“pageNo”, defaultValue=“1”) Integer pageNo,
@RequestParam(name=“pageSize”, defaultValue=“10”) Integer pageSize,
HttpServletRequest req) {
QueryWrapper queryWrapper = QueryGenerator.initQueryWrapper(finPayment, req.getParameterMap());
List list = new ArrayList();
list.add(“23”);
list.add(“31”);
list.add(“32”);
queryWrapper.in(“bill_proc_Status”, list);
queryWrapper.eq(“is_approved”, 1);
queryWrapper.eq(“is_closed”, 0);
queryWrapper.eq(“is_voided”, 0);
queryWrapper.apply(“amt - deducted_amt - checked_amt > 0”);
Page page = new Page(pageNo, pageSize);
IPage pageList = finPaymentService.page(page, queryWrapper);
return Result.ok(pageList);
/**
添加
@param finPaymentPage
@return
*/
@AutoLog(value = “付款单-添加”)
@ApiOperation(value=“付款单-添加”, notes=“付款单-添加”)
@PostMapping(value = “/add”)
public Result<?> add(@RequestBody FinPaymentPage finPaymentPage) {
FinPayment finPayment = new FinPayment();
BeanUtils.copyProperties(finPaymentPage, finPayment);
finPaymentService.saveMain(finPayment, finPaymentPage.getFinPaymentEntryList());
return Result.ok(“添加成功!”);
/**
编辑
@param finPaymentPage
@return
*/
@AutoLog(value = “付款单-编辑”)
@ApiOperation(value=“付款单-编辑”, notes=“付款单-编辑”)
@PutMapping(value = “/edit”)
public Result<?> edit(@RequestBody FinPaymentPage finPaymentPage) {
FinPayment finPayment = new FinPayment();
BeanUtils.copyProperties(finPaymentPage, finPayment);
FinPayment finPaymentEntity = finPaymentService.getById(finPayment.getId());
if(finPaymentEntity==null) {
return Result.error(“未找到对应数据”);
finPaymentService.updateMain(finPayment, finPaymentPage.getFinPaymentEntryList());
return Result.ok(“编辑成功!”);
/**
通过id删除
@param id
@return
*/
@AutoLog(value = “付款单-通过id删除”)
@ApiOperation(value=“付款单-通过id删除”, notes=“付款单-通过id删除”)
@DeleteMapping(value = “/delete”)
public Result<?> delete(@RequestParam(name=“id”,required=true) String id) {
finPaymentService.delMain(id);
return Result.ok(“删除成功!”);
/**
批量删除
@param ids
@return
*/
@AutoLog(value = “付款单-批量删除”)
@ApiOperation(value=“付款单-批量删除”, notes=“付款单-批量删除”)
@DeleteMapping(value = “/deleteBatch”)
public Result<?> deleteBatch(@RequestParam(name=“ids”,required=true) String ids) {
this.finPaymentService.delBatchMain(Arrays.asList(ids.split(“,”)));
return Result.ok(“批量删除成功!”);
/**
通过id查询
@param id
@return
*/
@AutoLog(value = “付款单-通过id查询”)
@ApiOperation(value=“付款单-通过id查询”, notes=“付款单-通过id查询”)
@GetMapping(value = “/queryById”)
public Result<?> queryById(@RequestParam(name=“id”,required=true) String id) {
FinPayment finPayment = finPaymentService.getById(id);
if(finPayment==null) {
return Result.error(“未找到对应数据”);
return Result.ok(finPayment);
/**
通过id查询
@param id
@return
*/
@AutoLog(value = “付款明细集合-通过id查询”)
@ApiOperation(value=“付款明细集合-通过id查询”, notes=“付款明细-通过id查询”)
@GetMapping(value = “/queryFinPaymentEntryByMainId”)
public Result<?> queryFinPaymentEntryListByMainId(@RequestParam(name=“id”,required=true) String id) {
List finPaymentEntryList = finPaymentEntryService.selectByMainId(id);
return Result.ok(finPaymentEntryList);
/**
导出excel
@param request
@param finPayment
*/
@RequestMapping(value = {“/exportXls”, “/exportXls/{paymentType}”})
public ModelAndView exportXls(HttpServletRequest request, FinPayment finPayment) {
// Step.1 组装查询条件查询数据
QueryWrapper queryWrapper = QueryGenerator.initQueryWrapper(finPayment, request.getParameterMap());
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
//Step.2 获取导出数据
List queryList = finPaymentService.list(queryWrapper);
// 过滤选中数据
String selections = request.getParameter(“selections”);
List finPaymentList = new ArrayList();
if(oConvertUtils.isEmpty(selections)) {
finPaymentList = queryList;
}else {
List selectionList = Arrays.asList(selections.split(“,”));
finPaymentList = queryList.stream().filter(item -> selectionList.contains(item.getId())).collect(Collectors.toList());
// Step.3 组装pageList
List pageList = new ArrayList();
for (FinPayment main : finPaymentList) {
FinPaymentPage vo = new FinPaymentPage();
BeanUtils.copyProperties(main, vo);
List finPaymentEntryList = finPaymentEntryService.selectByMainId(main.getId());
vo.setFinPaymentEntryList(finPaymentEntryList);
pageList.add(vo);
// Step.4 AutoPoi 导出Excel
ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
mv.addObject(NormalExcelConstants.FILE_NAME, “付款单列表”);
mv.addObject(NormalExcelConstants.CLASS, FinPaymentPage.class);
mv.addObject(NormalExcelConstants.PARAMS, new ExportParams(“付款单数据”, “导出人:”+sysUser.getRealname(), “付款单”));
mv.addObject(NormalExcelConstants.DATA_LIST, pageList);
return mv;
/**
通过excel导入数据
@param request
@param response
@return
*/
@RequestMapping(value = “/importExcel”, method = RequestMethod.POST)
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
MultipartFile file = entity.getValue();// 获取上传文件对象
ImportParams params = new ImportParams();
params.setTitleRows(2);
params.setHeadRows(1);
params.setNeedSave(true);
try {
List list = ExcelImportUtil.importExcel(file.getInputStream(), FinPaymentPage.class, params);
for (FinPaymentPage page : list) {
FinPayment po = new FinPayment();
BeanUtils.copyProperties(page, po);
finPaymentService.saveMain(po, page.getFinPaymentEntryList());
return Result.ok(“文件导入成功!数据行数:” + list.size());
} catch (Exception e) {
log.error(e.getMessage(),e);
return Result.error(“文件导入失败:”+e.getMessage());
} finally {
try {
file.getInputStream().close();
} catch (IOException e) {
e.printStackTrace();
return Result.ok(“文件导入失败!”);
@AutoLog(value = “付款单-通过id审核”)
@ApiOperation(value=“付款单-通过id审核”, notes=“付款单-通过id审核”)
@PutMapping(value = “/approve”)
public Result<?> approve(@RequestBody JSONObject json) {
finPaymentService.approve(json.getString(“id”));
return Result.ok(“审核通过!”);
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。