Compare commits

..

10 Commits

@ -100,4 +100,3 @@
![](https://code.educoder.net/api/pcjs8mx7g/warehouse/raw/src%2Fmain%2Fresources%2Fstatic%2Fimages%2Fsales.PNG?ref=master)
商品销售退货管理
![](https://code.educoder.net/api/pcjs8mx7g/warehouse/raw/src%2Fmain%2Fresources%2Fstatic%2Fimages%2Fsalesback.PNG?ref=master)
//这是一个测试

@ -75,4 +75,5 @@ public class BusinessController {
return "business/salesback/salesbackManager";
}// 返回视图名称,跳转到商品销售退货管理页面
}
}
//git提交测试

@ -1,24 +1,25 @@
package com.yeqifu.bus.controller; // 定义包路径
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; // 导入查询包装器类
import com.baomidou.mybatisplus.core.metadata.IPage; // 导入分页接口
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; // 导入分页实现类
import com.yeqifu.bus.entity.Customer; // 导入客户实体类
import com.yeqifu.bus.service.ICustomerService; // 导入客户服务接口
import com.yeqifu.bus.vo.CustomerVo; // 导入客户视图对象
import com.yeqifu.sys.common.Constast; // 导入常量类
import com.yeqifu.sys.common.DataGridView; // 导入数据网格返回类
import com.yeqifu.sys.common.ResultObj; // 导入结果对象类
import io.swagger.annotations.ApiImplicitParam; // 导入Swagger参数注解
import io.swagger.annotations.ApiImplicitParams; // 导入Swagger参数列表注解
import io.swagger.annotations.ApiOperation; // 导入Swagger操作注解
import org.apache.commons.lang3.StringUtils; // 导入字符串工具类
import org.springframework.beans.factory.annotation.Autowired; // 导入Spring的依赖注入注解
import org.springframework.web.bind.annotation.RequestMapping; // 导入请求映射注解
import org.springframework.web.bind.annotation.RequestMethod; // 导入请求方法注解
import org.springframework.web.bind.annotation.RestController; // 导入控制器注解
import java.util.List; // 导入列表类
package com.yeqifu.bus.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yeqifu.bus.entity.Customer;
import com.yeqifu.bus.service.ICustomerService;
import com.yeqifu.bus.vo.CustomerVo;
import com.yeqifu.sys.common.Constast;
import com.yeqifu.sys.common.DataGridView;
import com.yeqifu.sys.common.ResultObj;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* <p>
@ -28,27 +29,86 @@ import java.util.List; // 导入列表类
* @author luoyi-
* @since 2019-12-05
*/
@RestController // 标注为REST控制器
@RequestMapping("/customer") // 设置请求路径为/customer
public class CustomerController {
@Autowired // 自动注入客户服务接口实现类
private ICustomerService customerService; // 定义客户服务接口实例
/*
* CustomerControllerSpring BootSpring MVCWeb
* HTTP
* JSON使@RestController
*
* @RestControllerSpring 4.0@Controller@ResponseBody
* HTTPRESTful API
* JavaJSONJSONJackson便使
*
* @RequestMapping("/customer")"/customer"
* "/customer/getById"ID"/customer/save"
* API便便
*
* @AutowiredSpringICustomerServicecustomerService
* ICustomerService
*
* CustomerController便
*
*/
@RestController
@RequestMapping("/customer")
public class CustomerController {
// 通过Spring框架提供的@Autowired注解让Spring容器自动查找并注入ICustomerService接口的实现类到此处的customerService属性
// 这是一种解耦的设计方式,使得控制器类不需要关心具体的业务逻辑实现细节,只需要调用接口定义的方法即可,方便后续的代码维护、替换业务逻辑实现类等操作。
@Autowired
private ICustomerService customerService;
/**
*
* @param customerVo
* @return
*/
@RequestMapping("loadAllCustomer") // 映射路径为/loadAllCustomer
public DataGridView loadAllCustomer(CustomerVo customerVo){ // 查询所有客户方法
IPage<Customer> page = new Page<Customer>(customerVo.getPage(),customerVo.getLimit()); // 声明分页对象
QueryWrapper<Customer> queryWrapper = new QueryWrapper<Customer>(); // 声明查询包装器
queryWrapper.like(StringUtils.isNotBlank(customerVo.getCustomername()),"customername",customerVo.getCustomername()); // 根据客户名模糊查询
queryWrapper.like(StringUtils.isNotBlank(customerVo.getConnectionpersion()),"connectionpersion",customerVo.getConnectionpersion()); // 根据联系人模糊查询
queryWrapper.like(StringUtils.isNotBlank(customerVo.getPhone()),"phone",customerVo.getPhone()); // 根据手机号模糊查询
customerService.page(page,queryWrapper); // 调用分页查询服务
return new DataGridView(page.getTotal(),page.getRecords()); // 返回分页数据
@RequestMapping("loadAllCustomer")
/*
* "loadAllCustomer"HTTPSpring MVCSpring BootWeb
* CustomerVoDataGridView
* 便
*
* CustomerVocustomerVoCustomerVo
*/
public DataGridView loadAllCustomer(CustomerVo customerVo) {
// 1. 声明分页page对象
/*
* IPage<Customer>page使CustomerVocustomerVo.getPage()customerVo.getLimit()
* IPageMyBatis-Plus
*/
IPage<Customer> page = new Page<Customer>(customerVo.getPage(), customerVo.getLimit());
// 2. 声明queryWrapper
/*
* QueryWrapper<Customer>queryWrapperQueryWrapperMyBatis-Plus
* 便
*/
QueryWrapper<Customer> queryWrapper = new QueryWrapper<Customer>();
// 根据传入的CustomerVo对象中客户姓名是否不为空StringUtils.isNotBlank用于判断字符串非空且非空白字符
// 如果不为空则添加一个模糊查询条件到queryWrapper中按照客户姓名"customername"字段进行模糊匹配查询匹配的值为customerVo.getCustomername()。
// 这样在查询数据库时,就能筛选出客户姓名包含指定关键字的客户记录,实现根据客户姓名进行模糊查询的功能。
queryWrapper.like(StringUtils.isNotBlank(customerVo.getCustomername()), "customername", customerVo.getCustomername());
// 类似地根据传入的CustomerVo对象中联系人姓名是否不为空若不为空则添加模糊查询条件按照联系人姓名"connectionpersion"字段)进行模糊匹配查询,
// 以此来筛选出联系人姓名包含指定关键字的客户记录,满足按照联系人姓名进行模糊查询的业务需求。
queryWrapper.like(StringUtils.isNotBlank(customerVo.getConnectionpersion()), "connectionpersion", customerVo.getConnectionpersion());
// 按照同样的逻辑针对传入的CustomerVo对象中的电话号码字段如果电话号码不为空就添加模糊查询条件以电话号码"phone"字段)进行模糊匹配查询,
// 便于从数据库中查找出电话号码包含指定内容的客户记录,实现根据电话号码进行模糊查询的功能。
queryWrapper.like(StringUtils.isNotBlank(customerVo.getPhone()), "phone", customerVo.getPhone());
// 调用customerService的page方法将前面创建并设置好的分页对象page和查询条件封装对象queryWrapper传入。
// customerService应该是一个实现了与客户业务逻辑相关的服务层接口例如实现了ICustomerService接口等
// 其内部的page方法会基于传入的分页和查询条件与数据库进行交互可能借助MyBatis-Plus等持久化框架执行实际的分页查询操作
// 将查询到的符合条件的客户记录填充到page对象中并同时更新page对象中的总记录数等相关属性。
customerService.page(page, queryWrapper);
// 创建一个DataGridView对象并返回将page对象中的总记录数page.getTotal()和当前页查询到的客户记录列表page.getRecords())作为参数传入。
// DataGridView对象大概率是用于向前端传递数据的一种视图模型它整合了总记录数和具体的客户数据方便前端进行分页展示、数据渲染等操作
// 从而将查询到的所有符合条件的客户信息以及总记录数等关键数据返回给前端,完成整个查询并返回数据的业务流程。
return new DataGridView(page.getTotal(), page.getRecords());
}
/**
@ -56,14 +116,33 @@ public class CustomerController {
* @param customerVo
* @return
*/
@RequestMapping("addCustomer") // 映射路径为/addCustomer
public ResultObj addCustomer(CustomerVo customerVo){ // 添加客户方法
@RequestMapping("addCustomer")
/*
* "addCustomer"Spring MVCSpring BootWebHTTP
* CustomerVo
* ResultObj
*
* CustomerVocustomerVoCustomerVo
*
*/
public ResultObj addCustomer(CustomerVo customerVo) {
try {
customerService.save(customerVo); // 保存客户数据
return ResultObj.ADD_SUCCESS; // 返回添加成功结果
// 调用customerService的save方法尝试将传入的customerVo对象所封装的客户信息保存到数据库中。
// customerService应该是一个实现了与客户业务逻辑相关的服务层接口例如实现了ICustomerService接口等
// 其内部的save方法会对传入的CustomerVo对象进行必要的处理可能包括数据校验、转换为对应的Customer实体对象等操作
// 然后借助相关的持久化框架如MyBatis、MyBatis-Plus等将客户信息持久化到数据库中完成新增客户的实际操作。
customerService.save(customerVo);
// 如果保存操作顺利完成没有抛出异常就返回ResultObj.ADD_SUCCESS表示客户信息添加成功的结果对象
// 该对象应该是一个预定义的、用于统一返回结果格式的枚举类型或者普通类实例(具体取决于项目中的实现方式),方便前端根据返回值判断操作是否成功。
return ResultObj.ADD_SUCCESS;
} catch (Exception e) {
e.printStackTrace(); // 打印异常堆栈信息
return ResultObj.ADD_ERROR; // 返回添加失败结果
// 如果在保存客户信息的过程中出现了任何异常情况(比如数据库连接异常、数据格式不符合约束条件等),
// 会进入到catch块中进行异常处理。
e.printStackTrace();
// 在这里先打印出异常的堆栈信息,方便开发人员在调试时查看具体的出错原因和出错位置,
// 然后返回ResultObj.ADD_ERROR表示客户信息添加失败的结果对象告知客户端添加操作出现了错误
// 以便前端进行相应的提示或者后续的错误处理操作。
return ResultObj.ADD_ERROR;
}
}
@ -72,32 +151,70 @@ public class CustomerController {
* @param customerVo
* @return
*/
@RequestMapping("updateCustomer") // 映射路径为/updateCustomer
public ResultObj updateCustomer(CustomerVo customerVo){ // 修改客户方法
@RequestMapping("updateCustomer")
/*
* "updateCustomer"Spring MVCSpring BootWeb
* CustomerVoID
* ResultObj
*
* CustomerVo customerVoID
*
*/
public ResultObj updateCustomer(CustomerVo customerVo) {
try {
customerService.updateById(customerVo); // 根据ID更新客户数据
return ResultObj.UPDATE_SUCCESS; // 返回更新成功结果
// 调用customerService的updateById方法尝试根据传入的CustomerVo对象所携带的信息来更新数据库中对应的客户记录。
// customerService大概率是实现了与客户业务逻辑相关的服务层接口比如ICustomerService接口等的一个具体实现类实例
// 其内部的updateById方法会先从CustomerVo对象中提取关键的更新信息以及用于定位客户记录的标识例如ID属性
// 然后借助相应的持久化框架如MyBatis、MyBatis-Plus等构建合适的更新语句例如SQL的UPDATE语句等
// 依据这些信息去数据库中查找并更新对应的客户记录将CustomerVo中包含的新的客户信息替换原记录中的旧信息完成实际的更新操作。
customerService.updateById(customerVo);
// 如果更新操作顺利完成没有抛出任何异常就返回ResultObj.UPDATE_SUCCESS表示客户信息更新成功的结果对象。
// ResultObj应该是项目中预先定义好的用于统一表示操作结果的一种数据结构可能是枚举类型或者普通类等形式方便前端开发人员依据此返回值来判断更新操作是否成功
// 进而在前端界面上做出相应的提示或者进行后续的业务处理。
return ResultObj.UPDATE_SUCCESS;
} catch (Exception e) {
e.printStackTrace(); // 打印异常堆栈信息
return ResultObj.UPDATE_ERROR; // 返回更新失败结果
// 如果在执行更新客户记录的过程中出现了任何异常情况,比如数据库连接异常、违反数据约束条件(如唯一性约束等)、数据格式错误等,
// 就会进入到catch块中进行异常处理。
e.printStackTrace();
// 在这里先打印出异常的堆栈信息,这有助于开发人员在调试阶段快速定位问题所在,查看具体是哪个环节出现了错误以及错误的详细情况,
// 然后返回ResultObj.UPDATE_ERROR表示客户信息更新失败的结果对象以便告知客户端此次更新操作出现了问题
// 使得前端可以做出相应的提示给用户或者进行其他的错误处理逻辑,比如提示用户重新尝试更新等操作。
return ResultObj.UPDATE_ERROR;
}
}
/**
*
* @param id ID
* @return
*/
@ApiOperation(value = "删除一个客户",notes = "删除一个客户") // Swagger注解描述操作内容
@ApiImplicitParams({@ApiImplicitParam(name = "id", value = "客户ID",required = true,paramType = "query",dataType = "Integer")}) // Swagger注解描述参数信息
@RequestMapping(value = "deleteCustomer",method = RequestMethod.DELETE) // 映射路径为/deleteCustomer方法为DELETE
public ResultObj deleteCustomer(Integer id){ // 删除客户方法
// 使用Swagger相关的注解@ApiOperation来描述这个接口方法的功能向使用接口文档的人员如前端开发人员、其他后端对接人员等说明此方法是用于删除一个客户的操作。
// 同时通过notes属性进一步补充说明信息这里同样强调了是执行删除一个客户的功能。
@ApiOperation(value = "删除一个客户", notes = "删除一个客户")
// @ApiImplicitParams注解用于详细定义接口方法的隐含参数信息这里使用@ApiImplicitParam注解定义了一个名为"id"的参数。
// 说明该参数代表客户ID是必须要传入的required = true参数传递方式为query即通过URL的查询参数形式传递例如?id=123这种形式
// 并且其数据类型为Integer表示该参数接收的是整型数据以此向接口文档使用者清晰展示参数的要求和相关属性。
@ApiImplicitParams({@ApiImplicitParam(name = "id", value = "客户ID", required = true, paramType = "query", dataType = "Integer")})
// 使用@RequestMapping注解来映射HTTP请求将这个方法与"deleteCustomer"这个请求路径进行关联并且指定请求方法为DELETE
// 表明此接口是用于接收并处理DELETE类型的HTTP请求符合RESTful风格的接口设计专门用于执行删除客户的操作。
@RequestMapping(value = "deleteCustomer", method = RequestMethod.DELETE)
public ResultObj deleteCustomer(Integer id) {
try {
customerService.deleteCustomerById(id); // 调用服务删除客户
return ResultObj.DELETE_SUCCESS; // 返回删除成功结果
// 调用customerService的deleteCustomerById方法尝试依据传入的客户ID参数id来删除数据库中对应的客户记录。
// customerService应该是一个实现了与客户业务逻辑相关服务的类实例其内部的deleteCustomerById方法会按照既定的业务规则和持久化机制可能借助数据库框架等
// 先根据传入的ID在数据库中查找并确认对应的客户记录然后执行删除操作比如构建SQL的DELETE语句等方式来从数据库中移除该客户记录完成实际的删除客户的业务逻辑。
customerService.deleteCustomerById(id);
// 如果删除操作顺利完成没有抛出任何异常就返回ResultObj.DELETE_SUCCESS表示客户删除成功的结果对象。
// ResultObj大概率是项目中预先定义好的用于统一表示各种操作结果的一种数据结构可能是枚举类型或者特定的类等形式
// 方便前端或其他调用此接口的地方依据返回值来判断删除操作是否成功,进而进行后续的业务处理,比如前端给出相应的提示信息告知用户客户已成功删除等。
return ResultObj.DELETE_SUCCESS;
} catch (Exception e) {
e.printStackTrace(); // 打印异常堆栈信息
return ResultObj.DELETE_ERROR; // 返回删除失败结果
// 如果在执行删除客户记录的过程中出现了任何异常情况,例如数据库连接异常、违反外键约束(若客户记录与其他数据表存在关联关系时)、权限不足等问题,
// 就会进入到catch块中进行异常处理。
e.printStackTrace();
// 在这里先打印出异常的堆栈信息,这有助于开发人员在调试阶段快速定位问题所在,查看具体是哪个环节出现了错误以及错误的详细情况,
// 然后返回ResultObj.DELETE_ERROR表示客户删除失败的结果对象以便告知客户端或者其他调用此接口的地方此次删除操作出现了问题
// 使得前端可以做出相应的提示给用户(如提示用户删除失败,请稍后再试等)或者进行其他的错误处理逻辑。
return ResultObj.DELETE_ERROR;
}
}
@ -105,12 +222,32 @@ public class CustomerController {
*
* @return
*/
@RequestMapping("loadAllCustomerForSelect") // 映射路径为/loadAllCustomerForSelect
public DataGridView loadAllCustomerForSelect(){ // 加载客户下拉列表方法
QueryWrapper<Customer> queryWrapper = new QueryWrapper<Customer>(); // 声明查询包装器
queryWrapper.eq("available", Constast.AVAILABLE_TRUE); // 查询可用客户数据
List<Customer> list = customerService.list(queryWrapper); // 获取客户列表
return new DataGridView(list); // 返回客户数据
@RequestMapping("loadAllCustomerForSelect")
/*
* "loadAllCustomerForSelect"Spring MVCSpring BootWebHTTP
* DataGridView便使
*/
public DataGridView loadAllCustomerForSelect() {
// 创建一个QueryWrapper<Customer>对象queryWrapperQueryWrapper是一种常用于构建查询条件的工具类常见于MyBatis-Plus等框架中
// 它可以通过链式调用的方式方便地添加各种查询条件,用于后续从数据库中筛选出符合特定要求的客户记录。
QueryWrapper<Customer> queryWrapper = new QueryWrapper<Customer>();
// 使用queryWrapper的eq方法添加一个相等性的查询条件即查询数据库中"available"字段值等于Constast.AVAILABLE_TRUE的客户记录。
// 这里的Constast.AVAILABLE_TRUE应该是一个常量可能在Constast类中定义代表客户处于可用状态的标识值通过这个条件可以筛选出所有可用的客户
// 过滤掉那些不可用的客户记录,满足只获取可用客户信息的业务需求。
queryWrapper.eq("available", Constast.AVAILABLE_TRUE);
// 调用customerService的list方法将构建好的查询条件封装对象queryWrapper传入。
// customerService应该是一个实现了与客户业务逻辑相关的服务层接口例如实现了ICustomerService接口等的具体实现类实例
// 其内部的list方法会依据传入的查询条件借助相关的持久化框架如MyBatis、MyBatis-Plus等与数据库进行交互执行实际的查询操作
// 从数据库中查找出所有满足条件(即"available"字段值等于指定可用状态值的客户记录并将这些客户记录封装成一个List<Customer>集合返回。
List<Customer> list = customerService.list(queryWrapper);
// 创建一个DataGridView对象并返回将查询到的包含所有可用客户信息的List<Customer>集合作为参数传入。
// DataGridView对象大概率是用于向前端传递数据的一种视图模型它接收客户数据列表方便前端进行展示、数据渲染等操作
// 从而将所有可用客户的信息以合适的格式返回给前端,完成整个查询并返回可用客户数据的业务流程。
return new DataGridView(list);
}
}
//git提交测试
}

@ -1,219 +1,317 @@
package com.yeqifu.bus.controller;
// 导入必要的类和注解
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; // 用于条件查询的封装器
import com.baomidou.mybatisplus.core.metadata.IPage; // 分页结果封装类
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; // 分页类
import com.yeqifu.bus.entity.Goods; // 商品实体类
import com.yeqifu.bus.entity.Provider; // 供应商实体类
import com.yeqifu.bus.service.IGoodsService; // 商品服务接口
import com.yeqifu.bus.service.IProviderService; // 供应商服务接口
import com.yeqifu.bus.vo.GoodsVo; // 商品视图对象
import com.yeqifu.sys.common.AppFileUtils; // 文件操作工具类
import com.yeqifu.sys.common.Constast; // 常量类
import com.yeqifu.sys.common.DataGridView; // 数据网格返回格式类
import com.yeqifu.sys.common.ResultObj; // 结果对象类
import org.apache.commons.lang3.StringUtils; // 字符串工具类
import org.springframework.beans.factory.annotation.Autowired; // 自动注入注解
import org.springframework.web.bind.annotation.RequestMapping; // 映射请求路径注解
import org.springframework.web.bind.annotation.RestController; // REST 控制器注解
import java.util.List; // Java 集合类
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yeqifu.bus.entity.Goods;
import com.yeqifu.bus.entity.Provider;
import com.yeqifu.bus.service.IGoodsService;
import com.yeqifu.bus.service.IProviderService;
import com.yeqifu.bus.vo.GoodsVo;
import com.yeqifu.sys.common.AppFileUtils;
import com.yeqifu.sys.common.Constast;
import com.yeqifu.sys.common.DataGridView;
import com.yeqifu.sys.common.ResultObj;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
*
*
* <p>
* InnoDB free: 9216 kB; (`providerid`) REFER `warehouse/bus_provider`(`id`)
* </p>
*
* @author luoyi-
* @since 2019-12-06
*/
@RestController // 标注为 REST 控制器,返回 JSON 数据
@RequestMapping("/goods") // 设置请求路径的统一前缀
@RestController
@RequestMapping("/goods")
public class GoodsController {
@Autowired // 自动注入商品服务
@Autowired
private IGoodsService goodsService;
@Autowired // 自动注入供应商服务
@Autowired
private IProviderService providerService;
/**
*
* @param goodsVo
* @return
*
* @param goodsVo
* @return
*/
@RequestMapping("loadAllGoods") // 请求映射到 /goods/loadAllGoods
public DataGridView loadAllGoods(GoodsVo goodsVo) {
// 创建分页对象,指定当前页和每页大小
IPage<Goods> page = new Page<Goods>(goodsVo.getPage(), goodsVo.getLimit());
// 构造查询条件
@RequestMapping("loadAllGoods")
public DataGridView loadAllGoods(GoodsVo goodsVo){
IPage<Goods> page = new Page<Goods>(goodsVo.getPage(),goodsVo.getLimit());
QueryWrapper<Goods> queryWrapper = new QueryWrapper<Goods>();
queryWrapper.eq(goodsVo.getProviderid() != null && goodsVo.getProviderid() != 0, "providerid", goodsVo.getProviderid()); // 按供应商 ID 查询
queryWrapper.like(StringUtils.isNotBlank(goodsVo.getGoodsname()), "goodsname", goodsVo.getGoodsname()); // 按商品名称模糊查询
queryWrapper.like(StringUtils.isNotBlank(goodsVo.getProductcode()), "productcode", goodsVo.getProductcode()); // 按商品编码模糊查询
queryWrapper.like(StringUtils.isNotBlank(goodsVo.getPromitcode()), "promitcode", goodsVo.getPromitcode()); // 按促销编码模糊查询
queryWrapper.like(StringUtils.isNotBlank(goodsVo.getDescription()), "description", goodsVo.getDescription()); // 按描述模糊查询
queryWrapper.like(StringUtils.isNotBlank(goodsVo.getSize()), "size", goodsVo.getSize()); // 按尺寸模糊查询
queryWrapper.eq(goodsVo.getProviderid()!=null&&goodsVo.getProviderid()!=0,"providerid",goodsVo.getProviderid());
queryWrapper.like(StringUtils.isNotBlank(goodsVo.getGoodsname()),"goodsname",goodsVo.getGoodsname());
queryWrapper.like(StringUtils.isNotBlank(goodsVo.getProductcode()),"productcode",goodsVo.getProductcode());
queryWrapper.like(StringUtils.isNotBlank(goodsVo.getPromitcode()),"promitcode",goodsVo.getPromitcode());
queryWrapper.like(StringUtils.isNotBlank(goodsVo.getDescription()),"description",goodsVo.getDescription());
queryWrapper.like(StringUtils.isNotBlank(goodsVo.getSize()),"size",goodsVo.getSize());
queryWrapper.orderByDesc("id"); // 按 ID 降序排序
// 执行分页查询
goodsService.page(page, queryWrapper);
// 获取查询结果
queryWrapper.orderByDesc("id");
goodsService.page(page,queryWrapper);
List<Goods> records = page.getRecords();
for (Goods goods : records) {
// 根据商品的供应商 ID 查询供应商信息,并设置供应商名称
Provider provider = providerService.getById(goods.getProviderid());
if (provider != null) {
if (null!=provider){
goods.setProvidername(provider.getProvidername());
}
}
// 返回分页数据和商品记录
return new DataGridView(page.getTotal(), page.getRecords());
return new DataGridView(page.getTotal(),page.getRecords());
}
/**
*
* @param goodsVo
* @return
* @param goodsVo
* @return
*/
@RequestMapping("addGoods") // 请求映射到 /goods/addGoods
public ResultObj addGoods(GoodsVo goodsVo) {
@RequestMapping("addGoods")
public ResultObj addGoods(GoodsVo goodsVo){
try {
System.out.println("====================================");
System.out.println(goodsVo.getGoodsimg()); // 打印上传的商品图片路径
// 如果上传的图片路径是临时文件,则重命名为正式文件
if (goodsVo.getGoodsimg() != null && goodsVo.getGoodsimg().endsWith("_temp")) {
System.out.println(goodsVo.getGoodsimg());
if (goodsVo.getGoodsimg()!=null&&goodsVo.getGoodsimg().endsWith("_temp")){
String newName = AppFileUtils.renameFile(goodsVo.getGoodsimg());
goodsVo.setGoodsimg(newName); // 更新图片路径
goodsVo.setGoodsimg(newName);
}
// 保存商品信息
goodsService.save(goodsVo);
// 返回添加成功的结果
return ResultObj.ADD_SUCCESS;
} catch (Exception e) {
e.printStackTrace(); // 打印异常堆栈信息
return ResultObj.ADD_ERROR; // 返回添加失败的结果
e.printStackTrace();
return ResultObj.ADD_ERROR;
}
}
/**
*
* @param goodsVo
* @return
* @param goodsVo
* @return
*/
@RequestMapping("updateGoods") // 请求映射到 /goods/updateGoods
public ResultObj updateGoods(GoodsVo goodsVo) {
@RequestMapping("updateGoods")
public ResultObj updateGoods(GoodsVo goodsVo){
try {
// 如果商品图片不是默认图片,则处理图片路径
if (!(goodsVo.getGoodsimg() != null && goodsVo.getGoodsimg().equals(Constast.DEFAULT_IMG_GOODS))) {
if (goodsVo.getGoodsimg().endsWith("_temp")) {
String newName = AppFileUtils.renameFile(goodsVo.getGoodsimg()); // 重命名图片文件
goodsVo.setGoodsimg(newName);
//商品图片不是默认图片
if (!(goodsVo.getGoodsimg()!=null&&goodsVo.getGoodsimg().equals(Constast.DEFAULT_IMG_GOODS))){
// 删除原先的图片文件
if (goodsVo.getGoodsimg().endsWith("_temp")){
String newName = AppFileUtils.renameFile(goodsVo.getGoodsimg());
goodsVo.setGoodsimg(newName);
//删除原先的图片
String oldPath = goodsService.getById(goodsVo.getId()).getGoodsimg();
AppFileUtils.removeFileByPath(oldPath);
}
}
// 更新商品信息
goodsService.updateById(goodsVo);
// 返回更新成功的结果
return ResultObj.UPDATE_SUCCESS;
} catch (Exception e) {
e.printStackTrace(); // 打印异常堆栈信息
return ResultObj.UPDATE_ERROR; // 返回更新失败的结果
e.printStackTrace();
return ResultObj.UPDATE_ERROR;
}
}
/**
*
* @param id ID
* @param goodsimg
* @return
* @param id id
* @return
*/
@RequestMapping("deleteGoods") // 请求映射到 /goods/deleteGoods
public ResultObj deleteGoods(Integer id, String goodsimg) {
@RequestMapping("deleteGoods")
public ResultObj deleteGoods(Integer id,String goodsimg){
try {
// 删除商品的图片文件
//删除商品的图片
AppFileUtils.removeFileByPath(goodsimg);
// 删除商品信息
// goodsService.removeById(id);
goodsService.deleteGoodsById(id);
// 返回删除成功的结果
return ResultObj.DELETE_SUCCESS;
} catch (Exception e) {
e.printStackTrace(); // 打印异常堆栈信息
return ResultObj.DELETE_ERROR; // 返回删除失败的结果
e.printStackTrace();
return ResultObj.DELETE_ERROR;
}
}
/**
*
* @return
* @return
*/
@RequestMapping("loadAllGoodsForSelect") // 请求映射到 /goods/loadAllGoodsForSelect
public DataGridView loadAllGoodsForSelect() {
// 构造查询条件,仅查询状态为可用的商品
@RequestMapping("loadAllGoodsForSelect")
public DataGridView loadAllGoodsForSelect(){
QueryWrapper<Goods> queryWrapper = new QueryWrapper<Goods>();
queryWrapper.eq("available", Constast.AVAILABLE_TRUE);
// 查询商品列表
queryWrapper.eq("available",Constast.AVAILABLE_TRUE);
List<Goods> list = goodsService.list(queryWrapper);
for (Goods goods : list) {
// 设置供应商名称
Provider provider = providerService.getById(goods.getProviderid());
if (provider != null) {
if (null!=provider){
goods.setProvidername(provider.getProvidername());
}
}
// 返回商品列表
return new DataGridView(list);
}
/**
* ID
* @param providerid ID
* @return
* ID
* @param providerid ID
* @return
*/
@RequestMapping("loadGoodsByProviderId") // 请求映射到 /goods/loadGoodsByProviderId
public DataGridView loadGoodsByProviderId(Integer providerid) {
// 构造查询条件,仅查询状态为可用的商品
@RequestMapping("loadGoodsByProviderId")
public DataGridView loadGoodsByProviderId(Integer providerid){
QueryWrapper<Goods> queryWrapper = new QueryWrapper<Goods>();
queryWrapper.eq("available", Constast.AVAILABLE_TRUE);
queryWrapper.eq(providerid != null, "providerid", providerid); // 按供应商 ID 查询
// 查询商品列表
queryWrapper.eq("available",Constast.AVAILABLE_TRUE);
queryWrapper.eq(providerid!=null,"providerid",providerid);
List<Goods> list = goodsService.list(queryWrapper);
for (Goods goods : list) {
// 设置供应商名称
Provider provider = providerService.getById(goods.getProviderid());
if (provider != null) {
if (null!=provider){
goods.setProvidername(provider.getProvidername());
}
}
// 返回商品列表
return new DataGridView(list);
}
/**
*
* @return
*/
@RequestMapping("loadAllWarningGoods") // 请求映射到 /goods/loadAllWarningGoods
public DataGridView loadAllWarningGoods() {
// 查询所有库存预警的商品
@RequestMapping("loadAllWarningGoods")
public DataGridView loadAllWarningGoods(){
List<Goods> goods = goodsService.loadAllWarning();
// 返回预警商品的数量和列表
return new DataGridView((long) goods.size(), goods);
return new DataGridView((long) goods.size(),goods);
}
}
// GoodsController类使用了@RestController注解表明它是Spring框架下用于构建RESTful API的控制器类主要负责处理与商品Goods相关的各种HTTP请求
// 并将处理结果以合适的格式如JSON返回给客户端通常是前端应用在前后端交互中起着关键的桥梁作用方便前端对商品信息进行查询、添加、修改、删除等操作。
// 通过@RequestMapping("/goods")注解,为该控制器下所有的请求映射路径设置了公共前缀"/goods",便于对商品相关的接口进行统一管理和分类,便于代码维护以及前端接口调用。
// 使用@Autowired注解自动注入IGoodsService接口的实现类对象通过这个服务对象可以调用与商品相关的核心业务逻辑方法
// 例如分页查询商品信息、添加商品、更新商品信息、删除商品以及获取库存预警商品等操作具体的业务实现细节则在IGoodsService接口对应的实现类中完成这里只是进行调用触发相应的业务逻辑流程。
// 通过@Autowired注解注入IProviderService接口的实现类对象用于获取供应商相关的业务服务。在查询商品信息、加载可用商品等操作时借助该服务根据供应商ID查询供应商的详细信息
// 以便将供应商名称等相关信息补充到商品记录中,使返回给前端的数据更加完整,方便前端展示和业务操作时能呈现更全面的供应商相关情况,让用户清楚知道商品对应的供应商是谁。
/**
*
* @param goodsVo ID
* 便
* @return DataGridView
* 便
*/
// 创建一个IPage对象用于实现分页功能通过传入从goodsVo对象中获取的当前页码goodsVo.getPage()和每页显示记录数量goodsVo.getLimit())来确定分页范围,
// 例如当页码为2且每页显示数量为10时表示要获取第2页每页显示10条商品记录的那部分数据这样可以对大量的商品记录进行分页管理提升前端展示效果以及用户查看数据的体验。
// 创建一个QueryWrapper对象用于构建查询条件它类似于构建SQL语句中的WHERE子句部分能够灵活地添加各种筛选条件从而精确地查询出符合特定要求的商品记录。
// 对供应商进行查询如果从goodsVo对象中获取的供应商IDgoodsVo.getProviderid()不为空且不等于0说明前端传入了供应商筛选条件
// 则添加一个相等性查询条件,在数据库表中对应"providerid"字段查找与传入的供应商ID相等的商品记录以此实现按供应商来筛选商品信息的功能方便查看特定供应商提供的商品情况。
// 对商品名称进行模糊查询如果从goodsVo对象中获取的商品名称goodsVo.getGoodsname()不为空字符串通过StringUtils.isNotBlank方法判断
// 则添加一个模糊查询条件,在数据库表中对应"goodsname"字段,查找包含传入商品名称的商品记录,便于根据部分商品名称来查找相关商品,满足更灵活的查询需求。
// 对产品编码进行模糊查询同理当goodsVo对象中获取的产品编码goodsVo.getProductcode())不为空字符串时,添加一个模糊查询条件,
// 在数据库表的"productcode"字段上进行模糊匹配,查找包含传入产品编码的商品记录,方便根据产品编码来定位商品。
// 对助记码进行模糊查询若goodsVo对象中获取的助记码goodsVo.getPromitcode())不为空字符串,就在"promitcode"字段添加模糊查询条件,
// 查找包含传入助记码的商品记录,有助于通过助记码快速查找特定商品,提高查询的便捷性。
// 对商品描述进行模糊查询当goodsVo对象中获取的描述信息goodsVo.getDescription())不为空字符串时,添加一个模糊查询条件,
// 在数据库表的"description"字段进行模糊匹配,查找包含传入描述内容的商品记录,方便根据商品的相关描述来查找商品。
// 对商品规格进行模糊查询类似地若goodsVo对象中获取的规格信息goodsVo.getSize())不为空字符串,就在"size"字段添加模糊查询条件,
// 查找包含传入规格的商品记录,便于根据商品规格来筛选商品,满足不同业务场景下对商品数据的查询需求。
// 通过商品的ID对查询结果进行降序排序添加一个按照"id"字段推测是商品的唯一标识符字段进行降序排序的条件使得查询返回的商品记录按照ID从大到小的顺序排列
// 这样在前端展示时,用户能先看到较新添加或更新的商品记录,更符合一般的数据查看习惯,方便查看和分析近期的商品情况。
// 调用goodsService的page方法传入构建好的分页对象page和查询条件包装器queryWrapper服务层会根据这些条件执行数据库查询操作
// 获取符合条件的商品数据并将数据填充到page对象中例如设置page对象中的总记录数、当前页的记录列表等属性以便后续返回完整的分页数据信息。
// 获取查询结果中当前页的商品记录列表,方便后续对每条记录进行补充相关信息的操作,比如添加供应商名称等,使返回给前端的数据更加丰富详细,更具业务价值。
// 遍历当前页查询到的每条商品记录,为每条记录补充供应商名称信息,使其展示的数据更加完整全面,方便前端展示以及业务查看和操作使用。
// 通过providerService的getById方法根据当前商品记录中的供应商IDgoods.getProviderid()从数据库中查询对应的供应商详细信息获取到一个Provider对象如果存在的话
// 如果查询到了对应的供应商信息将供应商的名称设置到当前商品记录goods以便前端展示商品记录时能同时显示供应商名称让数据更直观、完整便于业务人员查看商品对应的供应商情况。
// 创建一个DataGridView对象将查询得到的商品记录的总数量通过page.getTotal()获取以及当前页补充完整信息后的商品记录列表page.getRecords())进行封装,
// 最终返回给前端,使得前端能够按照分页逻辑展示商品信息,并且展示的数据包含了丰富的关联信息(供应商名称等),满足业务查看和操作的实际需求。
/**
*
* @param goodsVo ID
*
* @return ResultObjResultObjADD_SUCCESSADD_ERROR
* 便
*/
// 打印商品图片相关信息(可能用于调试查看图片相关情况,比如确认前端传入的图片路径等是否正确),此处输出只是辅助开发阶段查看相关数据情况,在正式环境可根据需求决定是否保留。
// 判断商品图片路径是否不为空且以"_temp"结尾,如果满足该条件,说明可能是临时的图片文件名,需要进行重命名处理。
// 调用AppFileUtils的renameFile方法对临时的商品图片文件名进行重命名操作得到新的文件名并将新文件名设置回goodsVo对象的"goodsimg"属性中,
// 以便后续保存商品信息时使用正确的图片文件名,保证图片存储和关联的正确性。
// 调用goodsService的save方法将包含完整商品信息已处理好图片文件名等情况的goodsVo对象传递过去触发服务层中处理添加商品的业务逻辑
// 该逻辑可能涉及到向数据库的商品表中插入一条新记录、将商品图片存储到指定的文件存储位置(如果有图片存储相关逻辑)以及其他关联业务模块的数据交互等一系列复杂操作,
// 如果整个操作过程顺利完成,不会抛出异常;若在执行过程中出现问题(比如数据库插入失败、文件存储失败、业务规则校验不通过等情况),则会抛出异常。
// 如果在添加商品的过程中出现异常,通过打印异常堆栈信息(这有助于开发人员在排查问题时了解详细的异常发生位置和原因),
// 然后返回表示添加商品失败的ResultObj.ADD_ERROR结果对象给前端使得前端能够知晓操作未成功进而采取相应的提示告知用户或者其他补救措施等。
/**
*
* @param goodsVo
// 例如修改商品名称、规格、图片等信息后,将新的值封装在这个对象中传递过来进行更新操作。
* @return ResultObjResultObjUPDATE_SUCCESSUPDATE_ERROR
* 便
*/
// 判断商品图片是否不是默认图片这里通过判断图片路径不为空且不等于默认图片路径Constast.DEFAULT_IMG_GOODS应该是项目中定义的表示默认商品图片的常量来确定
// 如果不是默认图片,说明可能需要进行图片相关的更新处理操作,比如更换了商品图片等情况。
// 进一步判断商品图片路径是否以"_temp"结尾,如果是,说明可能是新上传的临时图片文件名,需要进行重命名处理,以符合实际存储和使用的规范。
// 调用AppFileUtils的renameFile方法对临时的商品图片文件名进行重命名操作得到新的文件名并将新文件名设置回goodsVo对象的"goodsimg"属性中,
// 确保后续更新商品信息时使用正确的图片文件名进行关联。
// 获取原先商品记录中的图片路径通过调用goodsService的getById方法根据商品IDgoodsVo.getId()获取对应的商品记录再获取其图片路径getGoodsimg方法
// 以便后续删除原来的旧图片,避免图片文件冗余,保持文件存储与商品信息的一致性。
// 调用AppFileUtils的removeFileByPath方法根据获取到的旧图片路径删除原先的商品图片文件实现图片文件的更新替换操作。
// 调用goodsService的updateById方法将包含更新后商品信息的goodsVo对象传递过去服务层会根据对象中的主键信息通常是商品记录的ID
// 在数据库中找到对应的商品记录并将其他属性值更新为goodsVo对象中传入的新值实现更新商品信息的功能例如修改商品记录中的名称、规格等字段的值
// 如果更新操作顺利完成则无异常抛出,若出现问题(比如找不到对应记录、更新数据违反约束等情况)则会抛出异常。
// 如果在更新商品信息的过程中出现异常打印异常堆栈信息便于开发人员排查问题根源然后返回表示更新操作失败的ResultObj.UPDATE_ERROR结果对象给前端
// 让前端知晓更新操作未成功,以便采取相应的提示或者其他处理措施,比如告知用户更新失败,可尝试再次操作等。
/**
*
* @param id IDID
* @param goodsimg
* @return ResultObjResultObjDELETE_SUCCESSDELETE_ERROR
* 便
*/
// 调用AppFileUtils的removeFileByPath方法根据传入的商品图片路径goodsimg删除对应的商品图片文件实现删除商品图片的操作
// 避免商品记录删除后图片文件仍残留,浪费存储空间且可能导致数据不一致的问题。
// 调用goodsService的deleteGoodsById方法假设该方法用于根据商品ID删除商品记录具体实现逻辑在IGoodsService接口对应的实现类中传入要删除的商品ID
// 服务层会根据这个ID在数据库中找到对应的商品记录并执行删除操作实现删除商品记录的功能
// 如果删除操作顺利完成则无异常抛出,若出现问题(比如存在关联数据、违反数据库约束等情况)则会抛出异常。

@ -1,128 +1,267 @@
package com.yeqifu.bus.controller; // 定义包名
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; // 导入条件查询封装器
import com.baomidou.mybatisplus.core.metadata.IPage; // 导入分页结果封装类
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; // 导入分页类
import com.yeqifu.bus.entity.Goods; // 导入商品实体类
import com.yeqifu.bus.entity.Inport; // 导入商品进货实体类
import com.yeqifu.bus.entity.Provider; // 导入供应商实体类
import com.yeqifu.bus.service.IGoodsService; // 导入商品服务接口
import com.yeqifu.bus.service.IInportService; // 导入商品进货服务接口
import com.yeqifu.bus.service.IProviderService; // 导入供应商服务接口
import com.yeqifu.bus.vo.InportVo; // 导入进货视图对象
import com.yeqifu.sys.common.DataGridView; // 导入数据网格返回格式类
import com.yeqifu.sys.common.ResultObj; // 导入操作结果对象类
import com.yeqifu.sys.common.WebUtils; // 导入 Web 工具类
import com.yeqifu.sys.entity.User; // 导入用户实体类
import org.springframework.beans.factory.annotation.Autowired; // 导入自动注入注解
import org.springframework.web.bind.annotation.RequestMapping; // 导入请求映射注解
import org.springframework.web.bind.annotation.RestController; // 导入 REST 控制器注解
import java.util.Date; // 导入日期类
import java.util.List; // 导入 Java 集合类
package com.yeqifu.bus.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yeqifu.bus.entity.Goods;
import com.yeqifu.bus.entity.Inport;
import com.yeqifu.bus.entity.Provider;
import com.yeqifu.bus.service.IGoodsService;
import com.yeqifu.bus.service.IInportService;
import com.yeqifu.bus.service.IProviderService;
import com.yeqifu.bus.vo.InportVo;
import com.yeqifu.sys.common.DataGridView;
import com.yeqifu.sys.common.ResultObj;
import com.yeqifu.sys.common.WebUtils;
import com.yeqifu.sys.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Date;
import java.util.List;
/**
*
*
* <p>
* InnoDB free: 9216 kB; (`providerid`) REFER `warehouse/bus_provider`(`id`); (`goo
* </p>
*
* @author luoyi-
* @since 2019-12-18
*/
@RestController // 标注为 REST 控制器,返回 JSON 数据
@RequestMapping("inport") // 设置请求路径的统一前缀
@RestController
@RequestMapping("inport")
public class InportController {
@Autowired // 自动注入商品进货服务
@Autowired
private IInportService inportService;
@Autowired // 自动注入供应商服务
@Autowired
private IProviderService providerService;
@Autowired // 自动注入商品服务
@Autowired
private IGoodsService goodsService;
/**
*
* @param inportVo
* @return
*
* @param inportVo
* @return
*/
@RequestMapping("loadAllInport") // 请求映射到 /inport/loadAllInport
public DataGridView loadAllInport(InportVo inportVo) {
IPage<Inport> page = new Page<Inport>(inportVo.getPage(), inportVo.getLimit()); // 创建分页对象,指定当前页和每页大小
QueryWrapper<Inport> queryWrapper = new QueryWrapper<Inport>(); // 构造查询条件对象
queryWrapper.eq(inportVo.getProviderid() != null && inportVo.getProviderid() != 0, "providerid", inportVo.getProviderid()); // 按供应商 ID 查询
queryWrapper.eq(inportVo.getGoodsid() != null && inportVo.getGoodsid() != 0, "goodsid", inportVo.getGoodsid()); // 按商品 ID 查询
queryWrapper.ge(inportVo.getStartTime() != null, "inporttime", inportVo.getStartTime()); // 查询大于等于开始时间的数据
queryWrapper.le(inportVo.getEndTime() != null, "inporttime", inportVo.getEndTime()); // 查询小于等于结束时间的数据
queryWrapper.orderByDesc("inporttime"); // 按进货时间降序排序
IPage<Inport> page1 = inportService.page(page, queryWrapper); // 执行分页查询
List<Inport> records = page1.getRecords(); // 获取查询结果
for (Inport inport : records) { // 遍历查询结果
Provider provider = providerService.getById(inport.getProviderid()); // 根据供应商 ID 查询供应商信息
if (provider != null) { // 如果供应商信息存在
inport.setProvidername(provider.getProvidername()); // 设置供应商名称
@RequestMapping("loadAllInport")
public DataGridView loadAllInport(InportVo inportVo){
IPage<Inport> page = new Page<Inport>(inportVo.getPage(),inportVo.getLimit());
QueryWrapper<Inport> queryWrapper = new QueryWrapper<Inport>();
//对供应商进行查询
queryWrapper.eq(inportVo.getProviderid()!=null&&inportVo.getProviderid()!=0,"providerid",inportVo.getProviderid());
//对商品进行查询
queryWrapper.eq(inportVo.getGoodsid()!=null&&inportVo.getGoodsid()!=0,"goodsid",inportVo.getGoodsid());
//对时间进行查询要求大于开始时间小于结束时间
queryWrapper.ge(inportVo.getStartTime()!=null,"inporttime",inportVo.getStartTime());
queryWrapper.le(inportVo.getEndTime()!=null,"inporttime",inportVo.getEndTime());
//通过进货时间对商品进行排序
queryWrapper.orderByDesc("inporttime");
IPage<Inport> page1 = inportService.page(page, queryWrapper);
List<Inport> records = page1.getRecords();
for (Inport inport : records) {
Provider provider = providerService.getById(inport.getProviderid());
if (provider!=null){
//设置供应商姓名
inport.setProvidername(provider.getProvidername());
}
Goods goods = goodsService.getById(inport.getGoodsid()); // 根据商品 ID 查询商品信息
if (goods != null) { // 如果商品信息存在
inport.setGoodsname(goods.getGoodsname()); // 设置商品名称
inport.setSize(goods.getSize()); // 设置商品规格
Goods goods = goodsService.getById(inport.getGoodsid());
if (goods!=null){
//设置商品名称
inport.setGoodsname(goods.getGoodsname());
//设置商品规格
inport.setSize(goods.getSize());
}
}
return new DataGridView(page1.getTotal(), page1.getRecords()); // 返回分页数据和进货记录
return new DataGridView(page1.getTotal(),page1.getRecords());
}
/**
*
* @param inportVo
* @return
* @param inportVo
* @return
*/
@RequestMapping("addInport") // 请求映射到 /inport/addInport
public ResultObj addInport(InportVo inportVo) {
@RequestMapping("addInport")
public ResultObj addInport(InportVo inportVo){
try {
User user = (User) WebUtils.getSession().getAttribute("user"); // 获取当前登录用户
inportVo.setOperateperson(user.getName()); // 设置操作人姓名
inportVo.setInporttime(new Date()); // 设置进货时间为当前时间
inportService.save(inportVo); // 保存进货信息
return ResultObj.ADD_SUCCESS; // 返回添加成功的结果
} catch (Exception e) { // 捕获异常
e.printStackTrace(); // 打印异常堆栈信息
return ResultObj.ADD_ERROR; // 返回添加失败的结果
//获得当前系统用户
User user = (User) WebUtils.getSession().getAttribute("user");
//设置操作人
inportVo.setOperateperson(user.getName());
//设置进货时间
inportVo.setInporttime(new Date());
inportService.save(inportVo);
return ResultObj.ADD_SUCCESS;
} catch (Exception e) {
e.printStackTrace();
return ResultObj.ADD_ERROR;
}
}
/**
*
* @param inportVo
* @return
* @param inportVo
* @return
*/
@RequestMapping("updateInport") // 请求映射到 /inport/updateInport
public ResultObj updateInport(InportVo inportVo) {
@RequestMapping("updateInport")
public ResultObj updateInport(InportVo inportVo){
try {
inportService.updateById(inportVo); // 更新进货信息
return ResultObj.UPDATE_SUCCESS; // 返回更新成功的结果
} catch (Exception e) { // 捕获异常
e.printStackTrace(); // 打印异常堆栈信息
return ResultObj.UPDATE_ERROR; // 返回更新失败的结果
inportService.updateById(inportVo);
return ResultObj.UPDATE_SUCCESS;
} catch (Exception e) {
e.printStackTrace();
return ResultObj.UPDATE_ERROR;
}
}
/**
*
* @param id ID
* @return
* @param id
* @return
*/
@RequestMapping("deleteInport") // 请求映射到 /inport/deleteInport
public ResultObj deleteInport(Integer id) {
@RequestMapping("deleteInport")
public ResultObj deleteInport(Integer id){
try {
inportService.removeById(id); // 删除进货记录
return ResultObj.DELETE_SUCCESS; // 返回删除成功的结果
} catch (Exception e) { // 捕获异常
e.printStackTrace(); // 打印异常堆栈信息
return ResultObj.DELETE_ERROR; // 返回删除失败的结果
inportService.removeById(id);
return ResultObj.DELETE_SUCCESS;
} catch (Exception e) {
e.printStackTrace();
return ResultObj.DELETE_ERROR;
}
}
}
// InportController类使用了@RestController注解表明它是Spring框架下用于构建RESTful API的控制器类主要负责处理与商品进货Inport相关的HTTP请求
// 并将处理结果以合适的格式如JSON返回给客户端通常是前端应用起到了在前后端之间传递和处理商品进货业务数据的桥梁作用。同时通过@RequestMapping("inport")注解,
// 为该控制器下所有的请求映射路径设置了公共前缀"inport",便于对商品进货相关的接口进行统一管理和分类,方便前端进行接口调用以及后端进行代码维护。
// 使用@Autowired注解自动注入IInportService接口的实现类对象通过这个服务对象可以调用与商品进货相关的核心业务逻辑方法
// 比如分页查询进货记录、添加进货商品、更新进货商品信息以及删除进货商品等操作具体的业务实现细节则在IInportService接口对应的实现类中完成这里只是进行调用触发相应的业务逻辑流程。
// 通过@Autowired注解注入IProviderService接口的实现类对象用于获取供应商相关的业务服务。在查询商品进货信息时借助该服务根据供应商ID查询供应商的详细信息
// 以便将供应商姓名等相关信息补充到进货记录中,使返回给前端的数据更加完整,方便前端展示和业务操作时能呈现更全面的供应商相关情况,例如让用户清楚知道每笔进货对应的供应商是谁。
// 同样使用@Autowired注解注入IGoodsService接口的实现类对象用于获取商品相关的业务服务。在处理进货记录查询结果或者添加、更新进货商品信息时通过该服务依据商品ID查询商品详情如商品名称、规格等
// 然后将这些商品相关信息设置到进货记录中,进一步丰富返回给前端的数据内容,让前端能够展示更详细的商品相关信息,便于业务查看和分析商品进货情况,比如了解进货的具体商品是什么以及其规格特点等。
/**
*
* @param inportVo IDID
* 便
* @return DataGridView
* 便
*/
// 创建一个IPage对象用于实现分页功能通过传入从inportVo对象中获取的当前页码inportVo.getPage()和每页显示记录数量inportVo.getLimit())来确定分页范围,
// 例如当页码为2且每页显示数量为10时表示要获取第2页每页显示10条商品进货记录的那部分数据这样可以对大量的进货记录进行分页管理提升前端展示效果以及用户查看数据的体验。
// 创建一个QueryWrapper对象用于构建查询条件它类似于构建SQL语句中的WHERE子句部分能够灵活地添加各种筛选条件从而精确地查询出符合特定要求的商品进货记录。
// 对供应商进行查询如果从inportVo对象中获取的供应商IDinportVo.getProviderid()不为空且不等于0说明前端传入了供应商筛选条件
// 则添加一个相等性查询条件,在数据库表中对应"providerid"字段查找与传入的供应商ID相等的进货记录以此实现按供应商来筛选进货信息的功能方便查看特定供应商的进货情况例如查看某个供应商的历史进货记录。
// 对商品进行查询同理当inportVo对象中获取的商品IDinportVo.getGoodsid()不为空且不等于0时表明前端传入了商品筛选条件
// 就在数据库表的"goodsid"字段添加相等性查询条件查找与传入商品ID匹配的进货记录便于根据具体商品来查询其进货情况满足不同业务场景下对商品进货数据的查询需求比如查看某类商品的进货频次、数量等情况。
// 对时间进行查询要求大于开始时间小于结束时间当inportVo对象中的开始时间inportVo.getStartTime()不为空时添加一个大于等于ge的查询条件
// 在数据库表的"inporttime"字段推测是商品进货时间字段筛选出进货时间大于等于传入的开始时间的进货记录同样当结束时间inportVo.getEndTime())不为空时,
// 添加一个小于等于le的查询条件筛选出进货时间小于等于传入的结束时间的进货记录这样就能获取到处于指定时间范围内的商品进货信息方便按时间区间进行数据查询、统计分析等操作
// 例如查看某个时间段内的进货总量、不同供应商在该时间段的进货情况等。
// 通过进货时间对商品进行排序,添加一个按照"inporttime"字段(商品进货时间)进行降序排序的条件,使得查询返回的进货记录按照进货时间从近到远的顺序排列,
// 这样在前端展示时,用户能先看到较新的进货记录,更符合一般的数据查看习惯,方便查看和分析近期的进货情况,有助于及时掌握最新的进货动态、发现潜在问题等。
// 调用inportService的page方法传入构建好的分页对象page和查询条件包装器queryWrapper服务层会根据这些条件执行数据库查询操作
// 获取符合条件的商品进货数据并将数据填充到page对象中例如设置page对象中的总记录数、当前页的记录列表等属性以便后续返回完整的分页数据信息。
// 获取查询结果中当前页的进货记录列表,方便后续对每条记录进行补充相关信息的操作,比如添加供应商姓名、商品名称和规格等,使返回给前端的数据更加丰富详细,更具业务价值。
// 遍历当前页查询到的每条商品进货记录,为每条记录补充供应商姓名、商品名称和规格等信息,使其展示的数据更加完整全面,方便前端展示以及业务查看和操作使用。
// 通过providerService的getById方法根据当前进货记录中的供应商IDinport.getProviderid()从数据库中查询对应的供应商详细信息获取到一个Provider对象如果存在的话
// 如果查询到了对应的供应商信息将供应商的姓名设置到当前进货记录inport以便前端展示进货记录时能同时显示供应商姓名让数据更直观、完整便于业务人员查看相关供应商的进货情况。
// 通过goodsService的getById方法依据当前进货记录中的商品IDinport.getGoodsid()从数据库中查询对应的商品详细信息获取到一个Goods对象若存在的话
// 如果查询到了商品信息将商品的名称设置到当前进货记录inport方便前端展示进货记录时能呈现商品名称使数据更具可读性便于了解进货商品的具体情况。
// 同时将商品的规格信息也设置到当前进货记录inport进一步丰富进货记录展示的数据内容方便业务人员更详细地掌握进货商品的规格特点等信息。
// 创建一个DataGridView对象将查询得到的商品进货记录的总数量通过page1.getTotal()获取以及当前页补充完整信息后的进货记录列表page1.getRecords())进行封装,
// 最终返回给前端,使得前端能够按照分页逻辑展示商品进货信息,并且展示的数据包含了丰富的关联信息(供应商姓名、商品名称和规格等),满足业务查看和操作的实际需求。
/**
*
* @param inportVo IDID
*
* @return ResultObjResultObjADD_SUCCESSADD_ERROR
* 便
*/
// 获得当前系统用户通过从WebUtils获取当前会话HttpSession并从中获取名为"user"的属性(推测是在用户登录成功后将用户信息存储在了会话中),
// 然后将其强制转换为User类型这样就能获取到当前操作的用户对象后续可以利用该用户信息记录是谁进行了此次进货操作等相关业务逻辑。
// 设置操作人将获取到的当前用户的姓名通过user.getName()获取设置到inportVo对象中用于记录此次进货操作是由哪个用户执行的
// 这样在数据库的进货记录中就能明确体现操作人信息,方便后续进行操作记录查询、责任追溯等业务需求。
// 设置进货时间创建一个新的Date对象代表当前时间并将其设置到inportVo对象的"inporttime"属性中,以此记录此次进货业务发生的具体时间,
// 确保进货记录中的时间信息准确无误,便于后续按照时间进行数据查询、统计分析等操作。
// 调用inportService的save方法将包含完整进货信息已设置好操作人、进货时间等的inportVo对象传递过去触发服务层中处理添加进货商品的业务逻辑
// 该逻辑可能涉及到向数据库的进货表中插入一条新记录、更新库存数量(增加对应商品的库存)以及其他关联业务模块的数据交互等一系列复杂操作,
// 如果整个操作过程顺利完成,不会抛出异常;若在执行过程中出现问题(比如数据库插入失败、业务规则校验不通过等情况),则会抛出异常。
// 如果在添加进货商品的过程中出现异常,通过打印异常堆栈信息(这有助于开发人员在排查问题时了解详细的异常发生位置和原因),
// 然后返回表示添加进货商品失败的ResultObj.ADD_ERROR结果对象给前端使得前端能够知晓操作未成功进而采取相应的提示告知用户或者其他补救措施等。
/**
*
* @param inportVo
*
* @return ResultObjResultObjUPDATE_SUCCESSUPDATE_ERROR
// 方便前端根据返回结果进行相应的处理或提示用户,比如提示用户更新成功或者告知更新失败的原因等。
*/
// 调用inportService的updateById方法将包含更新后进货商品信息的inportVo对象传递过去服务层会根据对象中的主键信息通常是进货记录的ID
// 在数据库中找到对应的进货记录并将其他属性值更新为inportVo对象中传入的新值实现更新进货商品信息的功能例如修改进货记录中的数量、价格等字段的值
// 如果更新操作顺利完成则无异常抛出,若出现问题(比如找不到对应记录、更新数据违反约束等情况)则会抛出异常。
// 如果在更新进货商品信息的过程中出现异常打印异常堆栈信息便于开发人员排查问题根源然后返回表示更新操作失败的ResultObj.UPDATE_ERROR结果对象给前端
// 让前端知晓更新操作未成功,以便采取相应的提示或者其他处理措施,比如告知用户更新失败,可尝试再次操作等。
/**
*
* @param id IDID
* @return ResultObjResultObjDELETE_SUCCESSDELETE_ERROR
* 便
*/
// 调用inportService的removeById方法传入要删除的进货记录的ID服务层会根据这个ID在数据库中找到对应的进货记录并执行删除操作
// 如果删除操作顺利完成则无异常抛出,若出现问题(比如存在关联数据、违反数据库约束等情况)则会抛出异常。
// 如果在删除进货商品的过程中出现异常打印异常堆栈信息便于开发人员排查问题根源然后返回表示删除操作失败的ResultObj.DELETE_ERROR结果对象给前端
// 让前端知晓删除操作未成功,以便采取相应的提示或者其他处理措施,比如告知用户删除失败,可尝试再次操作等。

@ -1,105 +1,214 @@
package com.yeqifu.bus.controller; // 声明类所在的包
package com.yeqifu.bus.controller;
// 导入MyBatis-Plus框架相关工具类用于条件查询和分页处理
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
// 导入实体类,分别表示商品、退货记录和供应商
import com.yeqifu.bus.entity.Goods;
import com.yeqifu.bus.entity.Outport;
import com.yeqifu.bus.entity.Provider;
// 导入服务接口,用于实现业务逻辑的调用
import com.yeqifu.bus.service.IGoodsService;
import com.yeqifu.bus.service.IOutportService;
import com.yeqifu.bus.service.IProviderService;
// 导入数据传输对象和通用响应结果类
import com.yeqifu.bus.vo.OutportVo;
import com.yeqifu.sys.common.DataGridView;
import com.yeqifu.sys.common.ResultObj;
// 导入Spring框架注解
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List; // 导入Java标准库中的List接口用于处理集合
import java.util.List;
/**
* OutportControllerRESTful退
* <p>
* InnoDB free: 9216 kB
* </p>
*
* @author luoyi-
* @since 2019-12-19
*/
@RestController // 标识该类为REST风格的控制器返回结果以JSON格式序列化
@RequestMapping("/outport") // 设置基础URL路径为"/outport"
@RestController
@RequestMapping("/outport")
public class OutportController {
@Autowired // 自动注入退货服务类,用于处理退货业务逻辑
@Autowired
private IOutportService outportService;
@Autowired // 自动注入供应商服务类,用于查询供应商信息
@Autowired
private IProviderService providerService;
@Autowired // 自动注入商品服务类,用于查询商品信息
@Autowired
private IGoodsService goodsService;
/**
* 退
* @param id ID
* @param number 退
* @param remark 退
* @return
* 退
* @param id ID
* @param number 退
* @param remark
* @return
*/
@RequestMapping("addOutport") // 映射URL路径为"/outport/addOutport"
public ResultObj addOutport(Integer id, Integer number, String remark) { // 定义添加退货记录的方法
@RequestMapping("addOutport")
public ResultObj addOutport(Integer id,Integer number,String remark){
try {
outportService.addOutport(id, number, remark); // 调用服务层方法,执行添加退货逻辑
return ResultObj.BACKINPORT_SUCCESS; // 返回操作成功的结果对象
} catch (Exception e) { // 捕获异常
e.printStackTrace(); // 打印异常信息到控制台
return ResultObj.BACKINPORT_ERROR; // 返回操作失败的结果对象
outportService.addOutport(id,number,remark);
return ResultObj.BACKINPORT_SUCCESS;
} catch (Exception e) {
e.printStackTrace();
return ResultObj.BACKINPORT_ERROR;
}
}
/**
* 退
* @param outportVo
* @return 退
/**t
* 退
* @param outportVo
* @return
*/
@RequestMapping("loadAllOutport") // 映射URL路径为"/outport/loadAllOutport"
public DataGridView loadAllOuport(OutportVo outportVo) { // 定义查询退货记录的方法
IPage<Outport> page = new Page<>(outportVo.getPage(), outportVo.getLimit()); // 创建分页对象,传入当前页和每页大小
QueryWrapper<Outport> queryWrapper = new QueryWrapper<>(); // 创建条件查询封装器
queryWrapper.eq(outportVo.getProviderid() != null && outportVo.getProviderid() != 0, "providerid", outportVo.getProviderid()); // 如果供应商ID不为空且不为0添加供应商查询条件
queryWrapper.eq(outportVo.getGoodsid() != null && outportVo.getGoodsid() != 0, "goodsid", outportVo.getGoodsid()); // 如果商品ID不为空且不为0添加商品查询条件
queryWrapper.ge(outportVo.getStartTime() != null, "outputtime", outportVo.getStartTime()); // 如果开始时间不为空,添加起始时间查询条件
queryWrapper.le(outportVo.getEndTime() != null, "outputtime", outportVo.getEndTime()); // 如果结束时间不为空,添加结束时间查询条件
queryWrapper.orderByDesc("outputtime"); // 按退货时间倒序排序
IPage<Outport> page1 = outportService.page(page, queryWrapper); // 调用服务层分页查询方法
List<Outport> records = page1.getRecords(); // 获取分页查询结果中的记录列表
for (Outport ouport : records) { // 遍历每条退货记录
Provider provider = providerService.getById(ouport.getProviderid()); // 根据供应商ID查询供应商信息
if (provider != null) { // 如果供应商信息存在
ouport.setProvidername(provider.getProvidername()); // 设置退货记录中的供应商名称
@RequestMapping("loadAllOutport")
public DataGridView loadAllOuport(OutportVo outportVo){
IPage<Outport> page = new Page<Outport>(outportVo.getPage(),outportVo.getLimit());
QueryWrapper<Outport> queryWrapper = new QueryWrapper<Outport>();
//对供应商进行查询
queryWrapper.eq(outportVo.getProviderid()!=null&&outportVo.getProviderid()!=0,"providerid",outportVo.getProviderid());
//对商品进行查询
queryWrapper.eq(outportVo.getGoodsid()!=null&&outportVo.getGoodsid()!=0,"goodsid",outportVo.getGoodsid());
//对时间进行查询要求大于开始时间小于结束时间
queryWrapper.ge(outportVo.getStartTime()!=null,"outputtime",outportVo.getStartTime());
queryWrapper.le(outportVo.getEndTime()!=null,"outputtime",outportVo.getEndTime());
//通过进货时间对商品进行排序
queryWrapper.orderByDesc("outputtime");
IPage<Outport> page1 = outportService.page(page, queryWrapper);
List<Outport> records = page1.getRecords();
for (Outport ouport : records) {
Provider provider = providerService.getById(ouport.getProviderid());
if (provider!=null){
//设置供应商姓名
ouport.setProvidername(provider.getProvidername());
}
Goods goods = goodsService.getById(ouport.getGoodsid()); // 根据商品ID查询商品信息
if (goods != null) { // 如果商品信息存在
ouport.setGoodsname(goods.getGoodsname()); // 设置退货记录中的商品名称
ouport.setSize(goods.getSize()); // 设置退货记录中的商品规格
Goods goods = goodsService.getById(ouport.getGoodsid());
if (goods!=null){
//设置商品名称
ouport.setGoodsname(goods.getGoodsname());
//设置商品规格
ouport.setSize(goods.getSize());
}
}
return new DataGridView(page1.getTotal(), page1.getRecords()); // 返回分页数据和记录列表
return new DataGridView(page1.getTotal(),page1.getRecords());
}
/**
* 退
* @param id 退ID
* @return
* 退
* @param id
* @return
*/
@RequestMapping("deleteOutport") // 映射URL路径为"/outport/deleteOutport"
public ResultObj deleteOutport(Integer id) { // 定义删除退货记录的方法
@RequestMapping("deleteOutport")
public ResultObj deleteOutport(Integer id){
try {
outportService.removeById(id); // 调用服务层方法根据ID删除退货记录
return ResultObj.DELETE_SUCCESS; // 返回操作成功的结果对象
} catch (Exception e) { // 捕获异常
e.printStackTrace(); // 打印异常信息到控制台
return ResultObj.DELETE_ERROR; // 返回操作失败的结果对象
outportService.removeById(id);
return ResultObj.DELETE_SUCCESS;
} catch (Exception e) {
e.printStackTrace();
return ResultObj.DELETE_ERROR;
}
}
}
// OutportController类使用了@RestController注解表明这是一个Spring框架中的RESTful风格的控制器类
// 用于处理与商品退货Outport相关的HTTP请求并将处理结果以JSON等格式返回给客户端通常是前端页面是连接前端与后端业务逻辑的重要环节。
// 同时通过@RequestMapping("/outport")注解,为该控制器下的所有请求映射路径设置了一个公共的前缀"/outport"方便对相关的API进行统一管理和区分。
// 使用@Autowired注解自动注入IOutportService接口的实现类对象用于调用与商品退货相关的业务逻辑方法
// 例如添加退货信息、分页查询退货记录、删除退货信息等操作,具体的业务实现是在对应的服务层接口实现类中完成的,这里只是进行调用触发相应逻辑。
// 同样通过@Autowired注解注入IProviderService接口的实现类对象用于获取供应商相关的业务服务
// 在查询商品退货信息时会借助该服务根据供应商ID查询供应商详细信息以便补充到退货记录中展示更完整的数据。
// 注入IGoodsService接口的实现类对象用于获取商品相关的业务服务在查询商品退货信息时通过该服务依据商品ID查询商品详情如名称、规格等
// 然后将这些商品相关信息设置到退货记录中,使返回给前端的数据更加丰富全面,方便前端展示和业务操作。
/**
* 退
* @param id ID退
* @param number 退退退
* @param remark 退退退
* @return ResultObjResultObjBACKINPORT_SUCCESSBACKINPORT_ERROR退便
*/
// 调用outportService的addOutport方法将前端传入的进货单ID、退货数量和备注信息传递过去触发服务层的添加退货信息业务逻辑
// 该逻辑可能涉及到更新库存、在数据库中插入退货记录、处理与财务等相关模块的数据交互等一系列复杂操作,如果操作顺利完成则无异常抛出,若过程中出现问题(比如数据库操作失败、业务规则校验不通过等)则会抛出异常。
// 如果在添加退货信息过程中出现异常打印异常堆栈信息方便开发人员排查问题根源然后返回表示添加退货信息失败的ResultObj.BACKINPORT_ERROR结果对象给前端
// 使得前端能够知晓操作未成功,进而进行相应的提示告知用户或者采取其他补救措施等。
/**
* 退
* @param outportVo IDID便
* @return DataGridView退退便
*/
// 创建一个IPage对象用于实现分页功能通过传入从outportVo对象中获取的当前页码outportVo.getPage()和每页显示记录数量outportVo.getLimit())来确定分页范围,
// 例如当页码为2且每页显示数量为10时表示要获取第2页每页显示10条商品退货记录的那部分数据方便对大量退货记录进行分页展示提升前端展示和用户查看数据的体验。
// 创建一个QueryWrapper对象用于构建查询条件类似于构建SQL语句中的WHERE子句部分方便灵活地添加各种筛选条件来精确查询符合要求的商品退货记录。
// 对供应商进行查询如果outportVo对象中获取的供应商IDoutportVo.getProviderid()不为空且不等于0说明前端传入了供应商筛选条件
// 则添加一个相等性查询条件,在数据库表中对应"providerid"字段查找与传入的供应商ID相等的退货记录以此实现按供应商筛选退货信息的功能。
// 对商品进行查询同理当outportVo对象中获取的商品IDoutportVo.getGoodsid()不为空且不等于0时表明前端传入了商品筛选条件
// 就在数据库表的"goodsid"字段添加相等性查询条件查找与传入商品ID匹配的退货记录便于根据具体商品来查询其退货情况。
// 对时间进行查询要求大于开始时间小于结束时间当outportVo对象中的开始时间outportVo.getStartTime()不为空时添加一个大于等于ge的查询条件
// 在数据库表的"outputtime"字段推测是退货时间字段筛选出退货时间大于等于传入的开始时间的退货记录同样当结束时间outportVo.getEndTime())不为空时,
// 添加一个小于等于le的查询条件筛选出退货时间小于等于传入的结束时间的退货记录这样就能获取到处于指定时间范围内的商品退货信息方便按时间区间进行数据查询和统计分析等操作。
// 通过进货时间对商品进行排序,添加一个按照"outputtime"字段(退货时间)进行降序排序的条件,使得查询返回的退货记录按照退货时间从近到远的顺序排列,
// 这样在前端展示时,用户能先看到较新的退货记录,更符合一般的数据查看习惯,方便查看和分析近期的退货情况。
// 调用outportService的page方法传入构建好的分页对象page和查询条件包装器queryWrapper服务层会根据这些条件执行数据库查询操作
// 获取符合条件的商品退货数据并将数据填充到page对象中例如设置page对象中的总记录数、当前页的记录列表等属性最终返回填充好数据的page对象赋值给page1。
// 获取查询结果中当前页的退货记录列表,方便后续对每条记录进行补充相关信息的操作,比如添加供应商名称、商品名称和规格等,使返回给前端的数据更加完整详细。
// 遍历当前页查询到的每条商品退货记录,为每条记录补充供应商名称、商品名称和规格等信息,使其展示的数据更加丰富全面,方便前端展示和业务查看使用。
// 通过providerService的getById方法根据当前退货记录中的供应商IDouport.getProviderid()从数据库中查询对应的供应商详细信息获取到一个Provider对象如果存在的话
// 如果查询到了对应的供应商信息将供应商的名称设置到当前退货记录ouport以便前端展示退货记录时能同时显示供应商名称让数据更直观、完整。
// 通过goodsService的getById方法依据当前退货记录中的商品IDouport.getGoodsid()从数据库中查询对应的商品详细信息获取到一个Goods对象若存在的话
// 如果查询到了商品信息将商品的名称设置到当前退货记录ouport方便前端展示退货记录时能呈现商品名称使数据更具可读性。
// 同时将商品的规格信息也设置到当前退货记录ouport进一步丰富退货记录展示的数据内容便于业务操作和查看详细情况。
// 创建一个DataGridView对象将查询得到的商品退货记录的总数量通过page1.getTotal()获取以及当前页补充完整信息后的退货记录列表page1.getRecords())进行封装,
// 最终返回给前端,使得前端能够按照分页逻辑展示商品退货信息,并且展示的数据包含了丰富的关联信息(供应商名称、商品名称和规格等),满足业务查看和操作的需求。
/**
* 退
* @param id 退IDID退
* @return ResultObjResultObjDELETE_SUCCESSDELETE_ERROR退便
*/
// 调用outportService的removeById方法传入要删除的退货记录的ID服务层会根据这个ID在数据库中找到对应的退货记录并执行删除操作
// 如果删除操作顺利完成则无异常抛出,若出现问题(比如存在关联数据、违反数据库约束等)则会抛出异常。
// 如果在删除退货信息过程中出现异常打印异常堆栈信息便于开发人员排查问题然后返回表示删除操作失败的ResultObj.DELETE_ERROR结果对象给前端
// 让前端知晓删除操作未成功,以便采取相应的提示或其他处理措施。

@ -1,177 +1,204 @@
package com.yeqifu.bus.controller;
// 声明类所在的包
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
// 导入MyBatis-Plus的QueryWrapper类用于条件查询
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
// 导入MyBatis-Plus的IPage接口用于分页
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
// 导入MyBatis-Plus的Page类用于创建分页对象
import com.yeqifu.bus.entity.Provider;
// 导入Provider实体类表示供应商信息
import com.yeqifu.bus.service.IProviderService;
// 导入IProviderService接口用于调用供应商相关的业务逻辑
import com.yeqifu.bus.vo.ProviderVo;
// 导入ProviderVo类封装供应商查询和操作的请求参数
import com.yeqifu.sys.common.Constast;
// 导入Constast类包含通用的常量定义
import com.yeqifu.sys.common.DataGridView;
// 导入DataGridView类用于返回表格数据格式
import com.yeqifu.sys.common.ResultObj;
// 导入ResultObj类用于返回操作结果的统一格式
import org.apache.commons.lang3.StringUtils;
// 导入StringUtils工具类用于字符串判空和处理
import org.springframework.beans.factory.annotation.Autowired;
// 导入Spring框架的Autowired注解用于自动注入Bean
import org.springframework.web.bind.annotation.RequestMapping;
// 导入RequestMapping注解用于映射URL路径
import org.springframework.web.bind.annotation.RestController;
// 导入RestController注解标识为REST风格的控制器
import java.util.List;
// 导入Java的List接口用于处理集合
/**
*
* <p>
* InnoDB free: 9216 kB
* </p>
*
* @author luoyi-
* @since 2019-12-05
*/
@RestController
// 标识该类为REST风格的控制器返回JSON格式数据
@RequestMapping("/provider")
// 将该类的基础URL路径设置为"/provider"
public class ProviderController {
@Autowired
// 自动注入IProviderService接口的实现类
private IProviderService providerService;
/**
*
* @param providerVo
* @return
* @param providerVo
* @return
*/
@RequestMapping("loadAllProvider")
// 映射URL路径为"/provider/loadAllProvider"
public DataGridView loadAllProvider(ProviderVo providerVo) {
IPage<Provider> page = new Page<>(providerVo.getPage(), providerVo.getLimit());
// 创建分页对象,传入当前页和每页大小
QueryWrapper<Provider> queryWrapper = new QueryWrapper<>();
// 创建QueryWrapper对象用于构造查询条件
queryWrapper.like(StringUtils.isNotBlank(providerVo.getProvidername()), "providername", providerVo.getProvidername());
// 如果供应商名称不为空,添加模糊查询条件
queryWrapper.like(StringUtils.isNotBlank(providerVo.getConnectionperson()), "connectionperson", providerVo.getConnectionperson());
// 如果联系人名称不为空,添加模糊查询条件
queryWrapper.like(StringUtils.isNotBlank(providerVo.getPhone()), "phone", providerVo.getPhone());
// 如果联系方式不为空,添加模糊查询条件
providerService.page(page, queryWrapper);
// 调用服务层的分页查询方法
return new DataGridView(page.getTotal(), page.getRecords());
// 返回DataGridView对象包含总记录数和分页记录列表
public DataGridView loadAllProvider(ProviderVo providerVo){
//1.声明一个分页page对象
IPage<Provider> page = new Page(providerVo.getPage(),providerVo.getLimit());
//2.声明一个queryWrapper
QueryWrapper<Provider> queryWrapper = new QueryWrapper();
queryWrapper.like(StringUtils.isNotBlank(providerVo.getProvidername()),"providername",providerVo.getProvidername());
queryWrapper.like(StringUtils.isNotBlank(providerVo.getConnectionperson()),"connectionperson",providerVo.getConnectionperson());
queryWrapper.like(StringUtils.isNotBlank(providerVo.getPhone()),"phone",providerVo.getPhone());
providerService.page(page,queryWrapper);
return new DataGridView(page.getTotal(),page.getRecords());
}
/**
*
* @param providerVo
* @return
* @param providerVo
* @return
*/
@RequestMapping("addProvider")
// 映射URL路径为"/provider/addProvider"
public ResultObj addProvider(ProviderVo providerVo) {
public ResultObj addProvider(ProviderVo providerVo){
try {
providerService.save(providerVo);
// 调用服务层方法,保存供应商信息
return ResultObj.ADD_SUCCESS;
// 返回操作成功的结果对象
} catch (Exception e) {
e.printStackTrace();
// 打印异常信息
return ResultObj.ADD_ERROR;
// 返回操作失败的结果对象
}
}
/**
*
* @param providerVo
* @return
* @param providerVo
* @return
*/
@RequestMapping("updateProvider")
// 映射URL路径为"/provider/updateProvider"
public ResultObj updateProvider(ProviderVo providerVo) {
public ResultObj updateProvider(ProviderVo providerVo){
try {
providerService.updateById(providerVo);
// 调用服务层方法根据ID更新供应商信息
return ResultObj.UPDATE_SUCCESS;
// 返回操作成功的结果对象
} catch (Exception e) {
e.printStackTrace();
// 打印异常信息
return ResultObj.UPDATE_ERROR;
// 返回操作失败的结果对象
}
}
/**
*
* @param id ID
* @return
* @param id
* @return
*/
@RequestMapping("deleteProvider")
// 映射URL路径为"/provider/deleteProvider"
public ResultObj deleteProvider(Integer id) {
public ResultObj deleteProvider(Integer id){
try {
providerService.deleteProviderById(id);
// 调用服务层方法根据ID删除供应商信息
return ResultObj.DELETE_SUCCESS;
// 返回操作成功的结果对象
} catch (Exception e) {
e.printStackTrace();
// 打印异常信息
return ResultObj.DELETE_ERROR;
// 返回操作失败的结果对象
}
}
/**
*
* @return
* @return
*/
@RequestMapping("loadAllProviderForSelect")
// 映射URL路径为"/provider/loadAllProviderForSelect"
public DataGridView loadAllProviderForSelect() {
QueryWrapper<Provider> queryWrapper = new QueryWrapper<>();
// 创建QueryWrapper对象用于构造查询条件
public DataGridView loadAllProviderForSelect(){
QueryWrapper<Provider> queryWrapper = new QueryWrapper<Provider>();
queryWrapper.eq("available", Constast.AVAILABLE_TRUE);
// 查询条件为供应商状态可用
List<Provider> list = providerService.list(queryWrapper);
// 调用服务层方法,获取符合条件的供应商列表
return new DataGridView(list);
// 返回DataGridView对象包含供应商列表
}
}
// 假设所在类是一个Spring的RestController通过 @RestController 注解标识用于处理HTTP请求并返回JSON等格式的数据响应用于处理与供应商Provider相关的各种业务请求。
// 注入一个实现了IService<Provider>接口的服务层对象这里假设名为providerService用于调用服务层提供的与供应商相关的业务逻辑方法
// 虽然代码中没有显示注入的语句但在实际的Spring项目中通常会通过依赖注入的方式获取该服务对象比如使用 @Autowired 注解等方式进行注入。
// 根据传入的供应商查询条件封装在ProviderVo对象中加载所有符合条件的供应商信息并进行分页返回。
// 1. 声明一个分页page对象
// 创建一个IPage对象用于实现分页功能它接收当前页码通过providerVo.getPage()获取即从前端传入的页码信息和每页显示的记录数量通过providerVo.getLimit()获取)作为参数,
// 这样就确定了本次查询数据的分页范围例如当page为2且limit为10时表示要获取第2页每页显示10条供应商记录的那部分数据。
// 2. 声明一个queryWrapper
// 创建一个QueryWrapper对象用于构建查询条件它可以方便地通过链式调用的方式添加各种查询条件类似于构建SQL语句中的WHERE子句部分用于筛选符合特定条件的供应商记录。
// 根据供应商名称进行模糊查询如果传入的供应商名称通过providerVo.getProvidername()获取不为空字符串使用StringUtils.isNotBlank方法判断
// 则添加一个模糊查询条件,在数据库表中对应"providername"字段进行模糊匹配(匹配包含传入名称的记录),方便根据名称查找相关的供应商。
// 根据联系人名称进行模糊查询原理同上面的供应商名称查询若传入的联系人名称通过providerVo.getConnectionperson()获取)不为空,就在"connectionperson"字段上添加模糊查询条件,
// 以便筛选出符合联系人名称要求的供应商记录。
// 根据电话号码进行模糊查询同样判断传入的电话号码通过providerVo.getPhone()获取)是否不为空,若不为空,则在"phone"字段添加模糊查询条件,实现按电话号码查找供应商的功能。
// 调用服务层的page方法传入构建好的分页对象page和查询条件包装器queryWrapper服务层会根据这些条件执行数据库查询操作获取符合条件的供应商数据并将数据填充到page对象中
// 例如设置page对象中的总记录数、当前页的记录列表等属性以便后续返回分页数据。
// 创建一个DataGridView对象用于将分页查询得到的结果总记录数通过page.getTotal()获取当前页的记录列表通过page.getRecords()获取)进行封装,
// 最终返回给前端方便前端进行分页数据展示等操作DataGridView对象的具体结构和作用取决于项目中的自定义一般是将数据整理成适合前端接收和展示的格式。
/**
*
* @param providerVo
* @return ResultObjResultObjADD_SUCCESSADD_ERROR
*/
// 调用服务层的save方法将传入的包含供应商信息的providerVo对象传递给服务层服务层会将这些信息保存到数据库中实现添加供应商的功能
// 例如将供应商的基本信息插入到对应的供应商表中,如果保存成功则无异常抛出,若保存过程中出现问题(如数据库连接异常、数据格式不符合要求等)则会抛出异常。
// 如果在保存供应商信息过程中出现异常打印异常堆栈信息方便开发人员排查问题然后返回表示添加失败的ResultObj.ADD_ERROR结果对象给前端
// 让前端知道添加操作没有成功,以便进行相应的提示或处理。
/**
*
* @param providerVo
* @return ResultObjResultObjUPDATE_SUCCESSUPDATE_ERROR
*/
// 调用服务层的updateById方法将传入的包含更新后供应商信息的providerVo对象传递给服务层服务层会根据对象中的主键信息通常是供应商的ID
// 在数据库中找到对应的供应商记录并将其他属性值更新为providerVo对象中传入的新值实现修改供应商信息的功能如果更新成功则无异常抛出若出现问题如找不到对应记录、更新数据违反约束等则会抛出异常。
// 如果在更新供应商信息过程中出现异常打印异常堆栈信息方便开发人员排查问题然后返回表示修改失败的ResultObj.UPDATE_ERROR结果对象给前端
// 让前端知道修改操作没有成功,以便进行相应的提示或处理。
/**
*
* @param id IDID
* @return ResultObjResultObjDELETE_SUCCESSDELETE_ERROR
*/
/**
*
* @return DataGridView便使
*/
// 添加一个相等性查询条件,在数据库表中对应"available"字段查询其值等于Constast.AVAILABLE_TRUE这里Constast应该是项目中定义的一个常量类AVAILABLE_TRUE表示可用状态的常量值的供应商记录
// 以此获取所有处于可用状态的供应商信息。
// 调用服务层的list方法传入构建好的查询条件包装器queryWrapper服务层会根据这个条件执行数据库查询操作获取所有符合可用状态条件的供应商数据并返回一个包含这些供应商对象的列表。
// 创建一个DataGridView对象将查询得到的可用供应商列表进行封装最终返回给前端方便前端进行展示或者其他相关业务操作比如在下拉框中展示可用供应商供用户选择等

@ -1,219 +1,137 @@
package com.yeqifu.bus.controller;
// 声明类所在的包
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
// 导入QueryWrapper类用于构建查询条件
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
// 导入IPage接口用于分页功能
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
// 导入Page类用于创建分页对象
import com.yeqifu.bus.entity.Customer;
// 导入Customer实体类表示客户信息
import com.yeqifu.bus.entity.Goods;
// 导入Goods实体类表示商品信息
import com.yeqifu.bus.entity.Sales;
// 导入Sales实体类表示销售信息
import com.yeqifu.bus.service.ICustomerService;
// 导入ICustomerService接口用于处理客户业务逻辑
import com.yeqifu.bus.service.IGoodsService;
// 导入IGoodsService接口用于处理商品业务逻辑
import com.yeqifu.bus.service.ISalesService;
// 导入ISalesService接口用于处理销售信息的业务逻辑
import com.yeqifu.bus.vo.SalesVo;
// 导入SalesVo类用于封装查询参数
import com.yeqifu.sys.common.DataGridView;
// 导入DataGridView类用于返回表格数据
import com.yeqifu.sys.common.ResultObj;
// 导入ResultObj类用于统一返回操作结果
import com.yeqifu.sys.common.WebUtils;
// 导入WebUtils工具类用于处理会话信息
import com.yeqifu.sys.entity.User;
// 导入User实体类表示用户信息
import org.springframework.beans.factory.annotation.Autowired;
// 导入@Autowired注解用于自动注入服务对象
import org.springframework.web.bind.annotation.RequestMapping;
// 导入@RequestMapping注解用于映射请求路径
import org.springframework.web.bind.annotation.RestController;
// 导入@RestController注解标识该类为REST控制器
import java.util.Date;
// 导入Date类用于处理日期时间
import java.util.List;
// 导入Java集合类List用于处理列表数据
/**
*
*
* <p>
* InnoDB free: 9216 kB
* </p>
*
* @author luoyi-
* @since 2019-12-21
*/
@RestController
// 标识该类为REST风格的控制器
@RequestMapping("/sales")
// 将类的基础URL路径映射为"/sales"
public class SalesController {
@Autowired
// 自动注入ISalesService接口的实现类
private ISalesService salesService;
@Autowired
// 自动注入ICustomerService接口的实现类
private ICustomerService customerService;
@Autowired
// 自动注入IGoodsService接口的实现类
private IGoodsService goodsService;
/**
*
* @param salesVo
* @return
* @param salesVo
* @return
*/
@RequestMapping("loadAllSales")
// 映射URL路径为"/sales/loadAllSales"
public DataGridView loadAllSales(SalesVo salesVo) {
IPage<Sales> page = new Page<>(salesVo.getPage(), salesVo.getLimit());
// 创建分页对象,指定当前页和每页记录数
QueryWrapper<Sales> queryWrapper = new QueryWrapper<>();
// 创建QueryWrapper对象用于构建查询条件
queryWrapper.eq(salesVo.getCustomerid() != null && salesVo.getCustomerid() != 0, "customerid", salesVo.getCustomerid());
// 如果客户ID不为空且不为0添加客户ID的查询条件
queryWrapper.eq(salesVo.getGoodsid() != null && salesVo.getGoodsid() != 0, "goodsid", salesVo.getGoodsid());
// 如果商品ID不为空且不为0添加商品ID的查询条件
queryWrapper.ge(salesVo.getStartTime() != null, "salestime", salesVo.getStartTime());
// 如果开始时间不为空,添加大于等于开始时间的查询条件
queryWrapper.le(salesVo.getEndTime() != null, "salestime", salesVo.getEndTime());
// 如果结束时间不为空,添加小于等于结束时间的查询条件
public DataGridView loadAllSales(SalesVo salesVo){
IPage<Sales> page = new Page<>(salesVo.getPage(),salesVo.getLimit());
QueryWrapper<Sales> queryWrapper = new QueryWrapper<Sales>();
//根据客户进行模糊查询
queryWrapper.eq(salesVo.getCustomerid()!=null&&salesVo.getCustomerid()!=0,"customerid",salesVo.getCustomerid());
//根据商品模糊查询
queryWrapper.eq(salesVo.getGoodsid()!=null&&salesVo.getGoodsid()!=0,"goodsid",salesVo.getGoodsid());
//根据时间进行模糊查询
queryWrapper.ge(salesVo.getStartTime()!=null,"salestime",salesVo.getStartTime());
queryWrapper.le(salesVo.getEndTime()!=null,"salestime",salesVo.getEndTime());
IPage<Sales> page1 = salesService.page(page, queryWrapper);
// 调用服务层分页查询方法,获取分页数据
List<Sales> records = page1.getRecords();
// 获取分页记录列表
for (Sales sales : records) {
// 遍历销售信息列表
//设置客户姓名
Customer customer = customerService.getById(sales.getCustomerid());
// 根据销售信息中的客户ID查询客户信息
if (null != customer) {
if(null!=customer){
sales.setCustomername(customer.getCustomername());
// 如果客户信息存在,设置客户名称
}
//设置商品名称
Goods goods = goodsService.getById(sales.getGoodsid());
// 根据销售信息中的商品ID查询商品信息
if (null != goods) {
if (null!=goods){
//设置商品名称
sales.setGoodsname(goods.getGoodsname());
// 如果商品信息存在,设置商品名称
//设置商品规格
sales.setSize(goods.getSize());
// 设置商品规格
}
}
return new DataGridView(page1.getTotal(), page1.getRecords());
// 返回DataGridView对象包含总记录数和分页记录列表
return new DataGridView(page1.getTotal(),page1.getRecords());
}
/**
*
* @param salesVo
* @return
* @param salesVo
* @return
*/
@RequestMapping("addSales")
// 映射URL路径为"/sales/addSales"
public ResultObj addSales(SalesVo salesVo) {
public ResultObj addSales(SalesVo salesVo){
try {
//获得当前系统用户
User user = (User) WebUtils.getSession().getAttribute("user");
// 从会话中获取当前系统用户
//设置操作人
salesVo.setOperateperson(user.getName());
// 设置操作人姓名
//设置销售时间
salesVo.setSalestime(new Date());
// 设置销售时间为当前时间
salesService.save(salesVo);
// 调用服务层方法保存销售信息
return ResultObj.ADD_SUCCESS;
// 返回添加成功的结果对象
} catch (Exception e) {
}catch (Exception e) {
e.printStackTrace();
// 打印异常信息
return ResultObj.ADD_ERROR;
// 返回添加失败的结果对象
}
}
/**
*
* @param salesVo
* @return
* @param salesVo
* @return
*/
@RequestMapping("updateSales")
// 映射URL路径为"/sales/updateSales"
public ResultObj updateSales(SalesVo salesVo) {
public ResultObj updateSales(SalesVo salesVo){
try {
salesService.updateById(salesVo);
// 调用服务层方法根据ID更新销售信息
return ResultObj.UPDATE_SUCCESS;
// 返回更新成功的结果对象
} catch (Exception e) {
e.printStackTrace();
// 打印异常信息
return ResultObj.UPDATE_ERROR;
// 返回更新失败的结果对象
}
}
/**
*
* @param id ID
* @return
* @param id
* @return
*/
@RequestMapping("deleteSales")
// 映射URL路径为"/sales/deleteSales"
public ResultObj deleteSales(Integer id) {
public ResultObj deleteSales(Integer id){
try {
salesService.removeById(id);
// 调用服务层方法根据ID删除销售信息
return ResultObj.DELETE_SUCCESS;
// 返回删除成功的结果对象
} catch (Exception e) {
e.printStackTrace();
// 打印异常信息
return ResultObj.DELETE_ERROR;
// 返回删除失败的结果对象
}
}
}

@ -1,182 +1,216 @@
package com.yeqifu.bus.controller;
// 声明类所在的包
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
// 导入QueryWrapper类用于构建查询条件
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
// 导入IPage接口用于分页功能
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
// 导入Page类用于创建分页对象
import com.yeqifu.bus.entity.Customer;
// 导入Customer实体类表示客户信息
import com.yeqifu.bus.entity.Goods;
// 导入Goods实体类表示商品信息
import com.yeqifu.bus.entity.Salesback;
// 导入Salesback实体类表示销售退货信息
import com.yeqifu.bus.service.ICustomerService;
// 导入ICustomerService接口用于处理客户业务逻辑
import com.yeqifu.bus.service.IGoodsService;
// 导入IGoodsService接口用于处理商品业务逻辑
import com.yeqifu.bus.service.ISalesbackService;
// 导入ISalesbackService接口用于处理销售退货业务逻辑
import com.yeqifu.bus.vo.SalesbackVo;
// 导入SalesbackVo类用于封装查询参数
import com.yeqifu.sys.common.DataGridView;
// 导入DataGridView类用于返回表格数据
import com.yeqifu.sys.common.ResultObj;
// 导入ResultObj类用于统一返回操作结果
import org.springframework.beans.factory.annotation.Autowired;
// 导入@Autowired注解用于自动注入服务对象
import org.springframework.web.bind.annotation.RequestMapping;
// 导入@RequestMapping注解用于映射请求路径
import org.springframework.web.bind.annotation.RestController;
// 导入@RestController注解标识该类为REST控制器
import java.util.List;
// 导入Java集合类List用于处理列表数据
/**
* 退
* 退
* <p>
* InnoDB free: 9216 kB
* </p>
*
* @author luoyi-
* @since 2019-12-23
*/
@RestController
// 标识该类为REST风格的控制器
@RequestMapping("/salesback")
// 将类的基础URL路径映射为"/salesback"
public class SalesbackController {
@Autowired
// 自动注入ISalesbackService接口的实现类
private ISalesbackService salesbackService;
@Autowired
// 自动注入ICustomerService接口的实现类
private ICustomerService customerService;
@Autowired
// 自动注入IGoodsService接口的实现类
private IGoodsService goodsService;
/**
* 退
* @param id 退ID
* @param number 退
* @param remark
* @return
* @param id ID
* @param number 退
* @param remark
* @return
*/
@RequestMapping("addSalesback")
// 映射URL路径为"/salesback/addSalesback"
public ResultObj addSalesback(Integer id, Integer number, String remark) {
public ResultObj addSalesback(Integer id,Integer number,String remark){
try {
salesbackService.addSalesback(id, number, remark);
// 调用服务层方法添加退货记录
salesbackService.addSalesback(id,number,remark);
return ResultObj.BACKINPORT_SUCCESS;
// 返回退货成功的结果对象
} catch (Exception e) {
e.printStackTrace();
// 打印异常信息
return ResultObj.BACKINPORT_ERROR;
// 返回退货失败的结果对象
}
}
/**
* 退
* @param salesbackVo
* @return
* 退
* @param salesbackVo
* @return
*/
@RequestMapping("loadAllSalesback")
// 映射URL路径为"/salesback/loadAllSalesback"
public DataGridView loadAllSalesback(SalesbackVo salesbackVo) {
IPage<Salesback> page = new Page<>(salesbackVo.getPage(), salesbackVo.getLimit());
// 创建分页对象,指定当前页和每页记录数
QueryWrapper<Salesback> queryWrapper = new QueryWrapper<>();
// 创建QueryWrapper对象用于构建查询条件
queryWrapper.eq(salesbackVo.getCustomerid() != null && salesbackVo.getCustomerid() != 0, "customerid", salesbackVo.getCustomerid());
// 如果客户ID不为空且不为0添加客户ID的查询条件
queryWrapper.eq(salesbackVo.getGoodsid() != null && salesbackVo.getGoodsid() != 0, "goodsid", salesbackVo.getGoodsid());
// 如果商品ID不为空且不为0添加商品ID的查询条件
queryWrapper.ge(salesbackVo.getStartTime() != null, "salesbacktime", salesbackVo.getStartTime());
// 如果开始时间不为空,添加大于等于开始时间的查询条件
queryWrapper.le(salesbackVo.getEndTime() != null, "salesbacktime", salesbackVo.getEndTime());
// 如果结束时间不为空,添加小于等于结束时间的查询条件
public DataGridView loadAllSalesback(SalesbackVo salesbackVo){
IPage<Salesback> page = new Page<Salesback>(salesbackVo.getPage(),salesbackVo.getLimit());
QueryWrapper<Salesback> queryWrapper = new QueryWrapper<Salesback>();
//对客户进行查询
queryWrapper.eq(salesbackVo.getCustomerid()!=null&&salesbackVo.getCustomerid()!=0,"customerid",salesbackVo.getCustomerid());
//对商品进行查询
queryWrapper.eq(salesbackVo.getGoodsid()!=null&&salesbackVo.getGoodsid()!=0,"goodsid",salesbackVo.getGoodsid());
//对时间进行查询要求大于开始时间小于结束时间
queryWrapper.ge(salesbackVo.getStartTime()!=null,"salesbacktime",salesbackVo.getStartTime());
queryWrapper.le(salesbackVo.getEndTime()!=null,"salesbacktime",salesbackVo.getEndTime());
//通过商品退货时间对商品进行排序
queryWrapper.orderByDesc("salesbacktime");
// 按照退货时间降序排列
salesbackService.page(page, queryWrapper);
// 调用服务层分页查询方法,获取分页数据
List<Salesback> records = page.getRecords();
// 获取分页记录列表
for (Salesback salesback : records) {
// 遍历退货记录列表
System.out.println("============================");
Customer customer = customerService.getById(salesback.getCustomerid());
// 根据退货记录中的客户ID查询客户信息
if (customer != null) {
if (customer!=null){
//设置客户姓名
salesback.setCustomername(customer.getCustomername());
// 如果客户信息存在,设置客户名称
}
Goods goods = goodsService.getById(salesback.getGoodsid());
// 根据退货记录中的商品ID查询商品信息
if (goods != null) {
if (goods!=null){
//设置商品名称
salesback.setGoodsname(goods.getGoodsname());
// 如果商品信息存在,设置商品名称
//设置商品规格
salesback.setSize(goods.getSize());
// 设置商品规格
}
}
return new DataGridView(page.getTotal(), page.getRecords());
// 返回DataGridView对象包含总记录数和分页记录列表
return new DataGridView(page.getTotal(),page.getRecords());
}
/**
* 退
* @param id 退ID
* @return
* 退
* @param id
* @return
*/
@RequestMapping("deleteSalesback")
// 映射URL路径为"/salesback/deleteSalesback"
public ResultObj deleteSalesback(Integer id) {
public ResultObj deleteSalesback(Integer id){
try {
salesbackService.removeById(id);
// 调用服务层方法根据ID删除退货记录
return ResultObj.DELETE_SUCCESS;
// 返回删除成功的结果对象
} catch (Exception e) {
e.printStackTrace();
// 打印异常信息
return ResultObj.DELETE_ERROR;
// 返回删除失败的结果对象
}
}
}
// SalesbackController类使用了@RestController注解表明它是Spring框架下用于构建RESTful API的控制器类主要负责处理与商品销售退货Salesback相关的HTTP请求
// 并将处理结果以合适的格式如JSON返回给客户端通常是前端应用在整个项目的前后端交互中起着桥梁的作用。同时通过@RequestMapping("/salesback")注解,
// 为该控制器下所有的请求映射路径设置了公共前缀"/salesback",便于对商品销售退货相关的接口进行统一管理和分类。
// 使用@Autowired注解自动注入ISalesbackService接口的实现类对象通过这个服务对象可以调用与商品销售退货相关的核心业务逻辑方法
// 比如添加退货信息、分页查询销售退货记录以及删除销售退回信息等操作具体的业务实现细节则在ISalesbackService接口对应的实现类中完成这里只是进行调用触发相应的业务逻辑流程。
// 通过@Autowired注解注入ICustomerService接口的实现类对象用于获取客户相关的业务服务。在查询商品销售退货信息时借助该服务根据客户ID查询客户的详细信息
// 以便将客户姓名等相关信息补充到销售退货记录中,使返回给前端的数据更加完整,方便前端展示和业务操作时能呈现更全面的客户相关情况。
// 同样使用@Autowired注解注入IGoodsService接口的实现类对象用于获取商品相关的业务服务。在处理销售退货记录查询结果时通过该服务依据商品ID查询商品详情如商品名称、规格等
// 然后将这些商品相关信息设置到销售退货记录中,进一步丰富返回给前端的数据内容,让前端能够展示更详细的商品相关信息,便于业务查看和分析销售退货情况。
/**
* 退
* @param id ID退退
* @param number 退退退
* @param remark 退退退
* @return ResultObjResultObjBACKINPORT_SUCCESSBACKINPORT_ERROR退
* 便
*/
// 调用salesbackService的addSalesback方法将前端传入的进货单ID、退货数量以及备注信息传递过去以此触发服务层中处理添加销售退货信息的业务逻辑
// 该逻辑可能涉及到调整库存(将退货商品重新入库)、在数据库中插入销售退货记录、更新与销售退货相关的财务数据以及其他关联业务模块的数据交互等一系列复杂操作,
// 如果整个操作过程顺利完成,不会抛出异常;若在执行过程中出现问题(比如数据库插入失败、业务规则校验不通过等情况),则会抛出异常。
// 如果在添加销售退货信息的过程中出现异常,通过打印异常堆栈信息(这有助于开发人员在排查问题时了解详细的异常发生位置和原因),
// 然后返回表示添加销售退货信息失败的ResultObj.BACKINPORT_ERROR结果对象给前端使得前端能够知晓操作未成功进而采取相应的提示告知用户或者其他补救措施等。
/**
* 退
* @param salesbackVo IDID
* 便退
* @return DataGridView退退
* 便
*/
// 创建一个IPage对象用于实现分页功能通过传入从salesbackVo对象中获取的当前页码salesbackVo.getPage()和每页显示记录数量salesbackVo.getLimit())来确定分页范围,
// 例如当页码为2且每页显示数量为10时表示要获取第2页每页显示10条商品销售退货记录的那部分数据这样可以对大量的销售退货记录进行分页管理提升前端展示效果以及用户查看数据的体验。
// 创建一个QueryWrapper对象用于构建查询条件它类似于构建SQL语句中的WHERE子句部分能够灵活地添加各种筛选条件从而精确地查询出符合特定要求的商品销售退货记录。
// 对客户进行查询如果从salesbackVo对象中获取的客户IDsalesbackVo.getCustomerid()不为空且不等于0说明前端传入了客户筛选条件
// 则添加一个相等性查询条件,在数据库表中对应"customerid"字段查找与传入的客户ID相等的销售退货记录以此实现按客户来筛选销售退货信息的功能方便查看特定客户的销售退货情况。
// 对商品进行查询同理当salesbackVo对象中获取的商品IDsalesbackVo.getGoodsid()不为空且不等于0时表明前端传入了商品筛选条件
// 就在数据库表的"goodsid"字段添加相等性查询条件查找与传入商品ID匹配的销售退货记录便于根据具体商品来查询其销售退货情况满足不同业务场景下对商品销售退货数据的查询需求。
// 对时间进行查询要求大于开始时间小于结束时间当salesbackVo对象中的开始时间salesbackVo.getStartTime()不为空时添加一个大于等于ge的查询条件
// 在数据库表的"salesbacktime"字段推测是商品销售退货时间字段筛选出销售退货时间大于等于传入的开始时间的销售退货记录同样当结束时间salesbackVo.getEndTime())不为空时,
// 添加一个小于等于le的查询条件筛选出销售退货时间小于等于传入的结束时间的销售退货记录这样就能获取到处于指定时间范围内的商品销售退货信息方便按时间区间进行数据查询、统计分析等操作。
// 通过商品退货时间对商品进行排序,添加一个按照"salesbacktime"字段(商品销售退货时间)进行降序排序的条件,使得查询返回的销售退货记录按照退货时间从近到远的顺序排列,
// 这样在前端展示时,用户能先看到较新的销售退货记录,更符合一般的数据查看习惯,方便查看和分析近期的销售退货情况,有助于及时发现问题或者跟踪业务趋势。
// 调用salesbackService的page方法传入构建好的分页对象page和查询条件包装器queryWrapper服务层会根据这些条件执行数据库查询操作
// 获取符合条件的商品销售退货数据并将数据填充到page对象中例如设置page对象中的总记录数、当前页的记录列表等属性以便后续返回完整的分页数据信息。
// 获取查询结果中当前页的销售退货记录列表,方便后续对每条记录进行补充相关信息的操作,比如添加客户姓名、商品名称和规格等,使返回给前端的数据更加丰富详细,更具业务价值。
// 遍历当前页查询到的每条商品销售退货记录,为每条记录补充客户姓名、商品名称和规格等信息,使其展示的数据更加完整全面,方便前端展示以及业务查看和操作使用。
// 通过customerService的getById方法根据当前销售退货记录中的客户IDsalesback.getCustomerid()从数据库中查询对应的客户详细信息获取到一个Customer对象如果存在的话
// 如果查询到了对应的客户信息将客户的姓名设置到当前销售退货记录salesback以便前端展示销售退货记录时能同时显示客户姓名让数据更直观、完整便于业务人员查看相关客户的退货情况。
// 通过goodsService的getById方法依据当前销售退货记录中的商品IDsalesback.getGoodsid()从数据库中查询对应的商品详细信息获取到一个Goods对象若存在的话
// 如果查询到了商品信息将商品的名称设置到当前销售退货记录salesback方便前端展示销售退货记录时能呈现商品名称使数据更具可读性便于了解退货商品的具体情况。
// 同时将商品的规格信息也设置到当前销售退货记录salesback进一步丰富退货记录展示的数据内容方便业务人员更详细地掌握退货商品的规格特点等信息。
// 创建一个DataGridView对象将查询得到的商品销售退货记录的总数量通过page.getTotal()获取以及当前页补充完整信息后的销售退货记录列表page.getRecords())进行封装,
// 最终返回给前端,使得前端能够按照分页逻辑展示商品销售退货信息,并且展示的数据包含了丰富的关联信息(客户姓名、商品名称和规格等),满足业务查看和操作的实际需求。
/**
* 退
* @param id 退IDID退
* @return ResultObjResultObjDELETE_SUCCESSDELETE_ERROR退
* 便
*/
// 调用salesbackService的removeById方法传入要删除的销售退回记录的ID服务层会根据这个ID在数据库中找到对应的销售退回记录并执行删除操作
// 如果删除操作顺利完成则无异常抛出,若出现问题(比如存在关联数据、违反数据库约束等情况)则会抛出异常。
// 如果在删除商品销售退回信息的过程中出现异常打印异常堆栈信息便于开发人员排查问题根源然后返回表示删除操作失败的ResultObj.DELETE_ERROR结果对象给前端
// 让前端知晓删除操作未成功,以便采取相应的提示或者其他处理措施,比如告知用户删除失败,可尝试再次操作等。

@ -54,3 +54,63 @@ public class Customer implements Serializable {
}
/*
* CustomerJavaSerializable使便
*
*
* 便
*/
// 序列化版本号在Java的序列化机制中起着重要作用它用于验证在不同版本的类结构变化时反序列化操作能否正确进行这里初始化为1L
// 意味着当前版本的类结构在序列化相关操作下的一个初始标识,后续若类结构发生变更(如添加、删除成员变量等),可能需要相应地更新此版本号。
// 通过@TableId注解指定该属性为对应数据库表中的主键字段名为"id"并且采用IdType.AUTO的主键生成策略
// 也就是在向数据库插入新的客户记录时数据库会自动为其分配一个唯一的ID值这个ID作为客户在整个业务系统中的唯一标识符
// 可用于精准地定位、查询以及关联与该客户相关的所有业务数据,比如订单数据、交易记录等。
// 客户姓名,是识别客户个体的关键信息之一,在业务系统的各种界面展示、报表生成以及客户沟通等场景中都会频繁使用,
// 例如客服人员根据客户姓名查找对应的客户记录,以便提供针对性的服务。
// 邮政编码,与客户的地址信息紧密相关,有助于在物流配送、地址验证等业务环节准确地定位客户所在的地理区域,
// 像电商平台根据邮编确定包裹的大致投递范围,提高配送效率。
// 客户的详细地址,详细描述了客户所处的具体位置,是开展线下业务活动(如上门拜访、售后服务等)以及邮寄物品等操作的重要依据,
// 其格式通常包含省、市、区、街道、门牌号等具体信息,确保能准确找到客户所在地。
// 固定电话号码,虽然随着移动通讯的发展使用频率相对降低,但在部分企业客户或者特定业务场景中仍可能是重要的联系方式,
// 例如一些传统行业的企业之间通过固定电话进行业务洽谈、客服咨询等沟通活动。
// 联系人姓名,在涉及到企业客户或者有多个联系人的情况下,用于明确与业务系统对接的具体人员,
// 比如一家公司有多个采购人员,通过指定联系人姓名可以精准地找到对应的业务对接人,方便订单处理、商务沟通等操作。
// 手机号码,作为现代社会最常用的通信方式之一,是与客户进行即时沟通、发送通知(如验证码、营销信息等)的重要途径,
// 几乎所有的线上业务活动如APP登录验证、会员服务通知等都会依赖手机号码来与客户建立联系。
// 开户银行名称,反映了客户的资金账户所属的金融机构,在涉及到财务结算、转账汇款等资金相关业务操作时,
// 明确开户银行是确保资金准确、安全流转的关键信息,比如企业向客户付款时需要知道对方的开户银行才能顺利完成转账。
// 银行账号,是客户在其开户银行的唯一资金账户标识,在各种资金往来业务(如收款、付款、对账等)中起着核心作用,
// 任何一笔涉及该客户的资金交易都需要通过这个账号来准确地进行资金划转和记录。
// 电子邮箱地址,是互联网时代重要的信息交流工具,用于接收各类电子文档(如合同、账单等)、业务通知以及进行商务邮件往来等,
// 例如企业通过电子邮件向客户发送月度账单、营销活动邮件等,以实现高效的业务沟通。
// 传真号码,尽管在当今数字化办公环境下使用越来越少,但在某些特定行业(如外贸、金融等部分传统业务领域)仍可能保留一定的使用场景,
// 比如外贸企业之间通过传真传递重要的商务文件、合同等,作为一种具有法律效力的书面沟通方式。
// 可用状态标识用于标记该客户在业务系统中的可用性例如在系统中可以规定1表示客户处于正常可用状态能够进行各种业务操作
// 而0则表示客户可能因某些原因如欠费、违规等处于不可用状态无法开展正常业务通过这个标识可以方便地对客户进行筛选、管控等操作。

@ -1,15 +1,15 @@
package com.yeqifu.bus.entity; // 包名
package com.yeqifu.bus.entity;
import com.baomidou.mybatisplus.annotation.IdType; // MyBatis-Plus主键类型注解
import com.baomidou.mybatisplus.annotation.TableField; // MyBatis-Plus字段映射注解
import com.baomidou.mybatisplus.annotation.TableId; // MyBatis-Plus主键注解
import com.baomidou.mybatisplus.annotation.TableName; // MyBatis-Plus表名注解
import lombok.Data; // Lombok注解自动生成getter和setter
import lombok.EqualsAndHashCode; // Lombok注解自动生成equals和hashCode方法
import lombok.ToString; // Lombok注解自动生成toString方法
import lombok.experimental.Accessors; // Lombok注解支持链式调用
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import lombok.experimental.Accessors;
import java.io.Serializable; // 序列化接口
import java.io.Serializable;
/**
* <p>
@ -19,44 +19,71 @@ import java.io.Serializable; // 序列化接口
* @author luoyi-
* @since 2019-12-06
*/
@Data // Lombok注解自动生成getter和setter方法
@EqualsAndHashCode(callSuper = false) // Lombok注解重写equals和hashCode方法且不调用父类
@Accessors(chain = true) // Lombok注解支持链式调用
@TableName("bus_goods") // MyBatis-Plus注解指定表名为bus_goods
@ToString // Lombok注解自动生成toString方法
public class Goods implements Serializable { // 定义Goods类实现Serializable接口
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("bus_goods")
@ToString
public class Goods implements Serializable {
// 序列化版本号在Java的序列化机制中起着关键作用它用于验证在不同版本的类结构发生变化时反序列化操作能否正确进行
// 这里初始化为1L意味着当前版本的类结构在序列化相关操作下的一个初始标识后续若类结构发生变更如添加、删除成员变量等可能需要相应地更新此版本号
// 以避免反序列化失败的问题,确保数据的兼容性和稳定性
private static final long serialVersionUID = 1L; // 序列化版本号
private static final long serialVersionUID=1L;
// 通过@TableId注解指定该属性为对应数据库表中的主键字段名为"id"并且采用IdType.AUTO的主键生成策略
// 也就是在向数据库插入新的商品记录时数据库会自动为其分配一个唯一的ID值这个ID作为商品在整个业务系统中的唯一标识符
// 可用于精准地定位、查询以及关联与该商品相关的所有业务数据,比如销售记录、库存变动记录等,是整个商品数据管理的核心标识之一。
@TableId(value = "id", type = IdType.AUTO) // MyBatis-Plus注解指定主键字段id为自增类型
private Integer id; // 商品ID
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
// 商品名称,是识别商品个体的最直观关键信息,在电商平台的前端页面展示、用户搜索商品、后台商品管理等众多业务场景中都会频繁使用,
// 例如用户通过输入商品名称在搜索栏查找心仪的商品,商家在后台管理系统中根据商品名称进行商品信息的编辑、上下架等操作
private String goodsname; // 商品名称
private String goodsname;
private String produceplace; // 生产地
private String produceplace;
// 商品的产地,这一信息在很多业务场景中都有重要意义,比如对于一些具有地域特色的商品(如某地的特产茶叶、水果等),产地信息可以作为商品品质、特色的一种标识,
// 同时在质量追溯、进出口贸易(涉及产地证明等文件)等环节中,产地信息也是不可或缺的,有助于确保商品来源的合法性和质量的可靠性
private String size; // 商品规格
private String size;
private String goodspackage; // 商品包装
private String goodspackage;
// 商品的规格尺寸,其具体内容根据商品类型的不同而各异,像服装类商品的尺寸关乎穿着是否合身,电子产品的尺寸可能影响其便携性和使用场景,
// 在商品详情页展示、用户筛选商品(按尺寸范围选择合适的商品等)以及库存管理(不同尺寸可能分开统计库存等)等业务操作中,规格尺寸都是重要的参考依据。
private String productcode; // 商品编码
private String productcode;
// 商品的包装信息,它涵盖了包装的形式(如盒装、袋装、瓶装等)、包装材料(如纸质、塑料、玻璃等)等方面,
// 在商品的运输过程中,合适的包装能保护商品不受损坏;在存储时,包装形式影响仓储空间的利用;在销售展示环节,精美的包装也能吸引消费者的目光,
// 所以包装信息对于商品的整个生命周期管理都有着不可忽视的作用。
private String promitcode; // 批准文号
private String promitcode;
private String description; // 商品描述
private String description;
private Double price; // 商品价格
private Double price;
private Integer number; // 商品库存数量
private Integer number;
private Integer dangernum; // 商品警戒库存数量
private Integer dangernum;
private String goodsimg; // 商品图片地址
private String goodsimg;
private Integer available; // 商品是否可用1表示可用0表示不可用
private Integer available;
private Integer providerid;
// 供应商的ID它建立了商品与供应商之间的关联关系在采购管理、供应链溯源等业务场景中有着重要作用
@TableField(exist = false)
private String providername;
// 使用@TableField注解且设置exist = false表示该属性在数据库表中不存在对应的字段但在Java类中用于临时存储或业务逻辑处理相关的数据
private Integer providerid; // 供应商ID外键关联供应商表
@TableField(exist = false) // MyBatis-Plus注解表示此字段在数据库表中不存在
private String providername; // 供应商名称(冗余字段,用于显示)
}
/*
* GoodsJavaSerializable使便
*
* 使
*
* MyBatis-PlusJava
* 便
*/

@ -1,15 +1,15 @@
package com.yeqifu.bus.entity; // 包名
package com.yeqifu.bus.entity;
import com.baomidou.mybatisplus.annotation.IdType; // MyBatis-Plus主键类型注解
import com.baomidou.mybatisplus.annotation.TableField; // MyBatis-Plus字段映射注解
import com.baomidou.mybatisplus.annotation.TableId; // MyBatis-Plus主键注解
import com.baomidou.mybatisplus.annotation.TableName; // MyBatis-Plus表名注解
import lombok.Data; // Lombok注解自动生成getter和setter方法
import lombok.EqualsAndHashCode; // Lombok注解自动生成equals和hashCode方法
import lombok.experimental.Accessors; // Lombok注解支持链式调用
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.io.Serializable; // 序列化接口
import java.util.Date; // 日期类
import java.io.Serializable;
import java.util.Date;
/**
* <p>
@ -19,49 +19,49 @@ import java.util.Date; // 日期类
* @author luoyi-
* @since 2019-12-18
*/
@Data // Lombok注解自动生成getter和setter方法
@EqualsAndHashCode(callSuper = false) // Lombok注解重写equals和hashCode方法不调用父类
@Accessors(chain = true) // Lombok注解支持链式调用
@TableName("bus_inport") // MyBatis-Plus注解指定表名为bus_inport
public class Inport implements Serializable { // 定义Inport类实现Serializable接口
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("bus_inport")
public class Inport implements Serializable {
private static final long serialVersionUID = 1L; // 序列化版本号
private static final long serialVersionUID=1L;
@TableId(value = "id", type = IdType.AUTO) // MyBatis-Plus注解指定主键字段id为自增类型
private Integer id; // 入库单ID
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
private String paytype; // 支付类型
private String paytype;
private Date inporttime; // 入库时间
private Date inporttime;
private String operateperson; // 操作员姓名
private String operateperson;
private Integer number; // 入库数量
private Integer number;
private String remark; // 备注信息
private String remark;
private Double inportprice; // 入库价格
private Double inportprice;
private Integer providerid; // 供应商ID外键关联供应商表
private Integer providerid;
private Integer goodsid; // 商品ID外键关联商品表
private Integer goodsid;
/**
*
*/
@TableField(exist = false) // MyBatis-Plus注解表示此字段在数据库表中不存在
private String providername; // 供应商名称(冗余字段,用于显示)
@TableField(exist = false)
private String providername;
/**
*
*/
@TableField(exist = false) // MyBatis-Plus注解表示此字段在数据库表中不存在
private String goodsname; // 商品名称(冗余字段,用于显示)
@TableField(exist = false)
private String goodsname;
/**
*
*/
@TableField(exist = false) // MyBatis-Plus注解表示此字段在数据库表中不存在
private String size; // 商品规格(冗余字段,用于显示)
@TableField(exist = false)
private String size;
}

@ -1,69 +1,118 @@
package com.yeqifu.bus.entity; // 包名
package com.yeqifu.bus.entity;
import com.baomidou.mybatisplus.annotation.IdType; // MyBatis-Plus主键类型注解
import com.baomidou.mybatisplus.annotation.TableField; // MyBatis-Plus字段映射注解
import com.baomidou.mybatisplus.annotation.TableId; // MyBatis-Plus主键注解
import com.baomidou.mybatisplus.annotation.TableName; // MyBatis-Plus表名注解
import lombok.Data; // Lombok注解自动生成getter和setter方法
import lombok.EqualsAndHashCode; // Lombok注解自动生成equals和hashCode方法
import lombok.experimental.Accessors; // Lombok注解支持链式调用
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.io.Serializable; // 序列化接口
import java.util.Date; // 日期类
import java.io.Serializable;
import java.util.Date;
/**
* <p>
* InnoDB free: 9216 kB
* </p>
*
*
*
* @author luoyi-
* @since 2019-12-19
*/
@Data // Lombok注解自动生成getter和setter方法
@EqualsAndHashCode(callSuper = false) // Lombok注解重写equals和hashCode方法不调用父类
@Accessors(chain = true) // Lombok注解支持链式调用
@TableName("bus_outport") // MyBatis-Plus注解指定表名为bus_outport
public class Outport implements Serializable { // 定义Outport类实现Serializable接口
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("bus_outport")
public class Outport implements Serializable {
private static final long serialVersionUID = 1L; // 序列化版本号
private static final long serialVersionUID=1L;
@TableId(value = "id", type = IdType.AUTO) // MyBatis-Plus注解指定主键字段id为自增类型
private Integer id; // 出库单ID
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
private Integer providerid; // 供应商ID外键关联供应商表
private Integer providerid;
private String paytype; // 支付类型
private String paytype;
private Date outputtime; // 出库时间
private Date outputtime;
private String operateperson; // 操作员姓名
private String operateperson;
private Double outportprice; // 出库价格
private Double outportprice;
private Integer number; // 出库数量
private Integer number;
private String remark; // 备注信息
private String remark;
private Integer goodsid; // 商品ID外键关联商品表
private Integer goodsid;
/**
*
*/
@TableField(exist = false) // MyBatis-Plus注解表示此字段在数据库表中不存在
private String providername; // 供应商名称(冗余字段,用于显示)
@TableField(exist = false)
private String providername;
/**
*
*/
@TableField(exist = false) // MyBatis-Plus注解表示此字段在数据库表中不存在
private String goodsname; // 商品名称(冗余字段,用于显示)
@TableField(exist = false)
private String goodsname;
/**
*
*/
@TableField(exist = false) // MyBatis-Plus注解表示此字段在数据库表中不存在
private String size; // 商品规格(冗余字段,用于显示)
@TableField(exist = false)
private String size;
}
// 以下代码片段可能是一个Java类中的成员变量声明部分假设这个类用于表示某种进货相关的业务实体比如进货记录等通过这些变量来承载进货业务中涉及的各项信息。
// serialVersionUID用于控制Java对象的序列化版本在对象进行序列化和反序列化操作时通过这个版本号来确保兼容性。
// 当类的结构发生变化如新增、删除成员变量等情况如果没有正确处理这个版本号可能会导致反序列化失败。这里将其初始化为1L表示当前的初始版本。
// @TableId注解用于标记该属性为对应数据库表的主键通过设置value = "id"表明在数据库表中对应的字段名为"id"
// 而type = IdType.AUTO指定了主键的生成策略为自动增长意味着在向数据库插入新记录时数据库会自动为该字段分配一个唯一的值。
// 此id属性通常作为该业务实体在整个系统中的唯一标识符方便进行数据的查询、更新、删除等操作例如精准定位某条进货记录。
// paytype用于存储支付类型信息比如可以是"现金"、"转账"、"微信支付"、"支付宝支付"等具体的支付方式,以字符串形式记录,便于在业务中了解进货时采用的付款手段。
// inporttime用于记录进货的时间其类型为Date能够精确地保存具体的年月日时分秒等时间信息对于后续查询特定时间段内的进货情况、统计进货频率等业务操作很有帮助。
// operateperson用于存储操作进货业务的人员姓名明确是哪位工作人员进行了此次进货操作方便进行业务责任追溯以及人员绩效统计等相关工作。
// number用于记录进货的数量以整数形式表示例如进货了多少件商品等在库存管理、成本核算等业务环节中这个数量是重要的基础数据。
// remark是备注信息字段类型为字符串通常用于记录一些额外的、需要说明的关于此次进货的相关情况比如特殊的进货要求、商品质量备注等内容。
// inportprice用于存储进货价格以Double类型来精确表示价格数值可以包含小数部分比如商品单价为12.5元等情况),
// 它是计算进货成本、利润等财务相关数据的关键要素,在财务核算、价格分析等业务场景中起着重要作用。
// providerid用于存储供应商的唯一标识符通过这个ID可以关联到对应的供应商信息比如查询供应商的详细资料、联系信息等建立起进货业务与供应商之间的关联关系。
// goodsid用于存储商品的唯一标识符同样可以凭借这个ID去关联商品的详细信息例如商品的具体规格、描述等内容确定此次进货对应的具体商品是哪一种。
/**
*
* 使@TableFieldexist = false
* 便使使
*/
/**
*
* providername@TableField(exist = false)
* 便便
*/
/**
*
* 使@TableField(exist = false)
* 便使
*/

@ -1,56 +1,117 @@
package com.yeqifu.bus.entity; // 包名
package com.yeqifu.bus.entity;
import com.baomidou.mybatisplus.annotation.IdType; // MyBatis-Plus主键类型注解
import com.baomidou.mybatisplus.annotation.TableId; // MyBatis-Plus主键注解
import com.baomidou.mybatisplus.annotation.TableName; // MyBatis-Plus表名注解
import lombok.Data; // Lombok注解自动生成getter和setter方法
import lombok.EqualsAndHashCode; // Lombok注解自动生成equals和hashCode方法
import lombok.ToString; // Lombok注解自动生成toString方法
import lombok.experimental.Accessors; // Lombok注解支持链式调用
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import lombok.experimental.Accessors;
import java.io.Serializable; // 序列化接口
import java.io.Serializable;
/**
* <p>
*
* InnoDB free: 9216 kB
* </p>
*
* @author luoyi-
* @since 2019-12-05
*/
@Data // Lombok注解自动生成getter和setter方法
@EqualsAndHashCode(callSuper = false) // Lombok注解重写equals和hashCode方法不调用父类
@Accessors(chain = true) // Lombok注解支持链式调用
@TableName("bus_provider") // MyBatis-Plus注解指定表名为bus_provider
@ToString // Lombok注解自动生成toString方法
public class Provider implements Serializable { // 定义Provider类实现Serializable接口
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("bus_provider")
@ToString
public class Provider implements Serializable {
private static final long serialVersionUID = 1L; // 序列化版本号
private static final long serialVersionUID=1L;
@TableId(value = "id", type = IdType.AUTO) // MyBatis-Plus注解指定主键字段id为自增类型
private Integer id; // 供应商ID
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
private String providername; // 供应商名称
private String providername;
private String zip; // 邮政编码
private String zip;
private String address; // 供应商地址
private String address;
private String telephone; // 供应商联系电话
private String telephone;
private String connectionperson; // 联系人姓名
private String connectionperson;
private String phone; // 联系人手机号码
private String phone;
private String bank; // 开户银行
private String bank;
private String account; // 银行账号
private String account;
private String email; // 电子邮箱
private String email;
private String fax; // 传真号码
private String fax;
private Integer available;
private Integer available; // 是否可用1表示可用0表示不可用
}
// Outport类实现了Serializable接口意味着该类的对象可以被序列化和反序列化常用于数据传输比如网络传输、持久化存储如保存到文件或数据库等场景等情况
// 确保对象的状态能够完整地保存和恢复,以满足不同业务环节对数据处理的需求,在这里可能用于记录商品出货相关的业务信息。
// serialVersionUID是用于控制Java对象序列化版本的标识符在对象进行序列化与反序列化操作时会依据这个版本号来判断类结构是否匹配确保兼容性。
// 当类的结构发生变化例如添加、删除成员变量修改成员变量类型等如果不妥善处理这个版本号可能导致反序列化失败这里初始化为1L表示当前类的初始序列化版本。
// @TableId注解用于标识该属性为对应数据库表的主键通过指定value = "id"明确了在数据库表中对应的字段名为"id"
// 并且设置type = IdType.AUTO来确定主键的生成策略为自动增长也就是在向数据库插入新记录时数据库会自动为该字段分配一个唯一的整数值
// 这个id属性作为每条出货记录在系统中的唯一标识方便后续对特定出货记录进行查询、更新、删除等数据库操作例如准确查找某次出货的详细信息。
// providerid用于存储供应商的唯一标识符通过这个整数值可以关联到具体的供应商信息比如在业务系统中通过该ID查找供应商的详细资料名称、联系方式、地址等
// 它建立了出货业务与供应商之间的关联关系,在统计与某个供应商的出货情况、进行供应商相关业务分析等场景中有着重要作用。
// paytype用于记录出货时采用的支付类型其类型为字符串例如可以是"现金"、"转账"、"电子支付(如微信、支付宝等)"等具体的支付方式,方便在业务流程中了解此次出货对应的收款方式。
// outputtime用于保存出货的时间类型为Date能够精确记录具体的年月日时分秒等时间信息这对于查询特定时间段内的出货量、分析出货频率等业务操作提供了准确的时间依据。
// operateperson用于存放执行此次出货操作的人员姓名以字符串形式呈现便于进行业务操作的责任追溯比如出现问题时能快速定位到是哪位工作人员进行的出货操作
// 同时也可用于人员绩效统计等与人员相关的业务管理工作。
// outportprice用于存储出货价格以Double类型表示能够精确地记录价格数值包含小数部分如商品单价为12.5元等情况),
// 它是计算出货业务收入、利润等财务相关数据的关键要素,在财务核算、价格分析等业务场景中扮演着重要角色。
// number用于记录出货的商品数量以整数形式表示例如出货了多少件商品等在库存管理根据出货数量更新库存、销售统计等业务环节中这个数量是不可或缺的基础数据。
// remark是备注信息字段类型为字符串主要用于记录一些额外的、需要说明的关于此次出货的相关情况比如特殊的出货要求、商品质量备注、客户特殊需求等内容
// 方便后续查看出货记录时能更全面地了解当时的业务详情。
// goodsid用于存储商品的唯一标识符凭借这个ID可以关联到对应的商品详细信息例如商品的具体规格、描述、库存情况等确定此次出货对应的具体商品是哪一种
// 在商品管理、库存管理与出货业务的关联操作中起着重要的纽带作用。
/**
*
* 使@TableField(exist = false)
* 便使使便
*/
/**
*
* providername@TableField(exist = false)
* 便
*/
/**
*
* @TableField(exist = false)
* 便使便
*/

@ -1,67 +1,130 @@
package com.yeqifu.bus.entity; // 包名
package com.yeqifu.bus.entity;
import com.baomidou.mybatisplus.annotation.IdType; // MyBatis-Plus主键类型注解
import com.baomidou.mybatisplus.annotation.TableField; // MyBatis-Plus字段映射注解
import com.baomidou.mybatisplus.annotation.TableId; // MyBatis-Plus主键注解
import com.baomidou.mybatisplus.annotation.TableName; // MyBatis-Plus表名注解
import lombok.Data; // Lombok注解自动生成getter和setter方法
import lombok.EqualsAndHashCode; // Lombok注解自动生成equals和hashCode方法
import lombok.experimental.Accessors; // Lombok注解支持链式调用
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.io.Serializable; // 序列化接口
import java.util.Date; // 日期类
import java.io.Serializable;
import java.util.Date;
/**
* <p>
*
* InnoDB free: 9216 kB
* </p>
*
* @author luoyi-
* @since 2019-12-21
*/
@Data // Lombok注解自动生成getter和setter方法
@EqualsAndHashCode(callSuper = false) // Lombok注解重写equals和hashCode方法不调用父类
@Accessors(chain = true) // Lombok注解支持链式调用
@TableName("bus_sales") // MyBatis-Plus注解指定表名为bus_sales
public class Sales implements Serializable { // 定义Sales类实现Serializable接口
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("bus_sales")
public class Sales implements Serializable {
private static final long serialVersionUID = 1L; // 序列化版本号
private static final long serialVersionUID=1L;
@TableId(value = "id", type = IdType.AUTO) // MyBatis-Plus注解指定主键字段id为自增类型
private Integer id; // 销售记录ID
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
private Integer customerid; // 客户ID外键关联客户表
private Integer customerid;
private String paytype; // 支付类型
private String paytype;
private Date salestime; // 销售时间
private Date salestime;
private String operateperson; // 操作员姓名
private String operateperson;
private Integer number; // 销售数量
private Integer number;
private String remark; // 备注信息
private String remark;
private Double saleprice; // 销售价格
private Double saleprice;
private Integer goodsid; // 商品ID外键关联商品表
private Integer goodsid;
/**
*
*/
@TableField(exist = false) // MyBatis-Plus注解表示此字段在数据库表中不存在
private String customername; // 客户名称(冗余字段,用于显示)
@TableField(exist = false)
private String customername;
/**
*
*/
@TableField(exist = false) // MyBatis-Plus注解表示此字段在数据库表中不存在
private String goodsname; // 商品名称(冗余字段,用于显示)
@TableField(exist = false)
private String goodsname;
/**
*
*/
@TableField(exist = false) // MyBatis-Plus注解表示此字段在数据库表中不存在
private String size; // 商品规格(冗余字段,用于显示)
@TableField(exist = false)
private String size;
}// Sales类用于对销售业务相关的数据进行建模实现了Serializable接口这使得该类的对象能够进行序列化和反序列化操作
// 方便在诸如网络传输(例如将销售数据发送到远程服务器进行统计分析等)、持久化存储(把销售记录保存到数据库或者文件中)等场景下使用,确保销售数据的完整性和可复用性。
// 使用了多个来自相关框架如MyBatis-Plus等常用于Java持久化开发的框架的注解来配置与数据库表的映射关系以及类自身的一些行为特性。
// 序列化版本号在Java的序列化机制中起着关键作用用于确保在不同版本的类结构发生变化时反序列化操作能够正确进行。
// 这里初始化为1L表示当前版本的类结构在序列化相关操作下的一个初始标识后续若类结构发生变更如添加、删除成员变量等可能需要相应地更新此版本号
// 以避免反序列化失败的问题,保证数据的兼容性和稳定性。
// @TableId注解用于标记该属性为对应数据库表的主键通过指定value = "id"表明在数据库表中对应的字段名为"id"
// 同时设置type = IdType.AUTO来定义主键的生成策略为自动增长即当向数据库插入新的销售记录时数据库会自动为该字段分配一个唯一的整数值
// 这个id属性作为每条销售记录在整个业务系统中的唯一标识符方便后续对特定销售记录进行查询、更新、删除等数据库操作例如精准查询某一笔销售业务的详细情况。
// customerid用于存储客户的唯一标识符通过这个整数值可以关联到对应的客户信息比如在业务系统中通过该ID查找客户的详细资料客户名称、联系方式、地址等
// 它建立了销售业务与客户之间的关联关系,在统计与某个客户的销售情况、进行客户关系管理、分析客户购买行为等业务场景中有着重要作用。
// paytype用于记录销售业务中采用的支付类型其类型为字符串例如可以是"现金"、"转账"、"微信支付"、"支付宝支付"等具体的支付方式,
// 方便在业务流程中了解此次销售对应的收款方式,对于财务统计、支付方式分析等业务操作提供了必要的信息。
// salestime用于保存销售发生的时间类型为Date能够精确记录具体的年月日时分秒等时间信息这对于按时间维度查询销售数据如查询某一天、某一个月的销售额
// 分析销售趋势(不同时间段内销售情况的变化)等业务操作提供了准确的时间依据。
// operateperson用于存放执行此次销售操作的人员姓名以字符串形式呈现便于进行业务操作的责任追溯比如出现售后问题时能快速定位到是哪位工作人员进行的销售操作
// 同时也可用于人员绩效统计等与人员相关的业务管理工作。
// number用于记录销售的商品数量以整数形式表示例如销售了多少件商品等在库存管理根据销售数量更新库存、销售统计计算销售额、销售量等等业务环节中这个数量是不可或缺的基础数据。
// remark是备注信息字段类型为字符串主要用于记录一些额外的、需要说明的关于此次销售的相关情况比如客户的特殊要求、商品的特殊情况、促销活动备注等内容
// 方便后续查看销售记录时能更全面地了解当时的业务详情。
// saleprice用于存储销售价格以Double类型表示能够精确地记录价格数值包含小数部分如商品单价为12.5元等情况),
// 它是计算销售额、利润等财务相关数据的关键要素,在财务核算、价格分析等业务场景中扮演着重要角色。
// goodsid用于存储商品的唯一标识符凭借这个ID可以关联到对应的商品详细信息例如商品的具体规格、描述、库存情况等确定此次销售对应的具体商品是哪一种
// 在商品管理、库存管理与销售业务的关联操作中起着重要的纽带作用。
/**
*
* 使@TableField(exist = false)
* 便使使便
*/
/**
*
* customername@TableField(exist = false)
* 便
*/
/**
*
* @TableField(exist = false)
* 便使便
*/
}

@ -1,67 +1,133 @@
package com.yeqifu.bus.entity; // 包名
package com.yeqifu.bus.entity;
import com.baomidou.mybatisplus.annotation.IdType; // MyBatis-Plus主键类型注解
import com.baomidou.mybatisplus.annotation.TableField; // MyBatis-Plus字段映射注解
import com.baomidou.mybatisplus.annotation.TableId; // MyBatis-Plus主键注解
import com.baomidou.mybatisplus.annotation.TableName; // MyBatis-Plus表名注解
import lombok.Data; // Lombok注解自动生成getter和setter方法
import lombok.EqualsAndHashCode; // Lombok注解自动生成equals和hashCode方法
import lombok.experimental.Accessors; // Lombok注解支持链式调用
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.io.Serializable; // 序列化接口
import java.util.Date; // 日期类
import java.io.Serializable;
import java.util.Date;
/**
* <p>
* 退退
* InnoDB free: 9216 kB
* </p>
*
* @author luoyi-
* @since 2019-12-23
*/
@Data // Lombok注解自动生成getter和setter方法
@EqualsAndHashCode(callSuper = false) // Lombok注解重写equals和hashCode方法不调用父类
@Accessors(chain = true) // Lombok注解支持链式调用
@TableName("bus_salesback") // MyBatis-Plus注解指定表名为bus_salesback
public class Salesback implements Serializable { // 定义Salesback类实现Serializable接口
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("bus_salesback")
public class Salesback implements Serializable {
private static final long serialVersionUID = 1L; // 序列化版本号
private static final long serialVersionUID=1L;
@TableId(value = "id", type = IdType.AUTO) // MyBatis-Plus注解指定主键字段id为自增类型
private Integer id; // 销售退货记录ID
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
private Integer customerid; // 客户ID外键关联客户表
private Integer customerid;
private String paytype; // 支付类型
private String paytype;
private Date salesbacktime; // 退货时间
private Date salesbacktime;
private Double salebackprice; // 退货价格
private Double salebackprice;
private String operateperson; // 操作员姓名
private String operateperson;
private Integer number; // 退货数量
private Integer number;
private String remark; // 备注信息
private String remark;
private Integer goodsid; // 商品ID外键关联商品表
private Integer goodsid;
/**
*
*/
@TableField(exist = false) // MyBatis-Plus注解表示此字段在数据库表中不存在
private String customername; // 客户名称(冗余字段,用于显示)
@TableField(exist = false)
private String customername;
/**
*
*/
@TableField(exist = false) // MyBatis-Plus注解表示此字段在数据库表中不存在
private String goodsname; // 商品名称(冗余字段,用于显示)
@TableField(exist = false)
private String goodsname;
/**
*
*/
@TableField(exist = false) // MyBatis-Plus注解表示此字段在数据库表中不存在
private String size; // 商品规格(冗余字段,用于显示)
@TableField(exist = false)
private String size;
}
// Salesback类主要用于对销售退货业务相关的数据进行建模和封装实现了Serializable接口这使得该类的对象能够支持序列化与反序列化操作
// 便于在诸如将退货数据传输到其他系统(例如与财务系统对接传递退货金额等信息)、持久化存储退货记录(保存到数据库以便后续查询和统计分析)等场景下使用,
// 确保退货业务数据在不同环节的完整性和可用性。
// 同时这个类使用了多个来自常用开发框架如MyBatis-Plus等的注解来配置其与数据库表的映射关系以及定义类自身的一些便捷操作特性。
// 序列化版本号在Java的序列化机制里起着至关重要的作用用于保障在类结构随项目发展出现变化例如后续添加、删除成员变量或者修改成员变量类型等情况
// 反序列化操作依然能够正确执行避免因版本不一致而导致的数据读取失败问题。此处初始化为1L代表当前类结构在序列化方面的初始标识后续若有变更需谨慎处理该版本号。
// @TableId注解用于明确指定该属性为对应数据库表"bus_salesback"表的主键通过设定value = "id"表明在数据库表中对应的字段名为"id"
// 并且采用type = IdType.AUTO的主键生成策略意味着每当向数据库插入一条新的销售退货记录时数据库会自动为这个"id"字段分配一个唯一的整数值,
// 该"id"属性作为每条销售退货记录在整个业务系统中的唯一标识符,方便后续针对特定退货记录进行精准查询、更新、删除等数据库操作,例如查找某一次具体退货业务的详细情况。
// customerid用于存储进行退货操作的客户的唯一标识符借助这个整数值业务系统可以关联到对应的客户详细信息如客户姓名、联系方式、地址以及过往购买记录等
// 它在建立销售退货业务与客户之间的关联关系方面起着关键作用,有助于统计特定客户的退货情况、分析客户退货行为、进行客户关系维护等业务场景的操作。
// paytype用于记录此次销售退货业务中所采用的支付退款方式其类型为字符串例如可能是"现金退款"、"原支付渠道退回(如原路返回微信支付、支付宝支付的款项等)"、"转账退款"等具体的支付类型描述,
// 该信息对于财务处理退货资金流向、核对退款方式以及分析不同支付退款方式的使用频率等业务操作有着重要意义。
// salesbacktime用于保存销售退货发生的具体时间类型为Date能够精确到年月日时分秒等时间细节这为按照时间维度查询和统计退货数据比如查询某一天、某一个月内的退货量、退货金额等
// 分析退货趋势(不同时间段内退货情况的变化规律)等业务操作提供了准确可靠的时间依据。
// salebackprice用于存储此次销售退货的价格以Double类型来表示能够精确地记录包含小数部分的价格数值例如商品单价为12.5元的退货情况等),
// 它是计算退货金额、统计退货业务对财务影响(如退款总额、退货造成的利润变动等)等财务相关数据的核心要素,在财务核算、退货业务分析等场景中扮演着重要角色。
// operateperson用于存放执行此次销售退货操作的人员姓名以字符串形式呈现便于在业务流程中进行责任追溯比如当出现退货纠纷或者需要核对退货操作细节时
// 能够快速定位到是哪位工作人员负责的此次退货业务,同时也有助于进行人员绩效评估(考虑退货业务处理情况等因素)等与人员相关的业务管理工作。
// number用于记录退货的商品数量以整数形式表示例如退货了多少件商品等在库存管理根据退货数量更新库存数量将退货商品重新入库等、退货统计计算退货量、分析不同商品的退货率等等业务环节中
// 该数量是必不可少的基础数据。
// remark是备注信息字段类型为字符串主要用于记录一些额外的、需要对此次销售退货业务进行说明的相关情况比如退货原因商品质量问题、客户不满意等
// goodsid用于存储退货商品的唯一标识符通过这个ID可以关联到对应的商品详细信息例如商品的具体名称、规格、库存情况以及商品的其他属性等
// 它在将销售退货业务与商品管理相关环节进行关联操作中起到了重要的纽带作用,有助于准确处理退货商品的后续事宜(如重新入库、质量检查等)。
/**
*
* 使@TableField(exist = false)"bus_salesback"
* 便使退使便
*
*/
/**
*
* customername@TableField(exist = false)
* 便退
* 使便
*/
/**
*
* @TableField(exist = false)
* 便使
* 退便
*/

@ -14,3 +14,12 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
public interface CustomerMapper extends BaseMapper<Customer> {
}
/*
* CustomerMapperJavaMyBatisMyBatis-Plus
* BaseMapper<Customer>BaseMapperCustomer
* BaseMapperCustomerMapperselectByIdIDinsertupdateByIdIDdeleteByIdID
* SQL
* CustomerMapper
* XML使MyBatisMyBatis-PlusSQL
*
*/

@ -1,60 +1,104 @@
package com.yeqifu.bus.mapper; // 包名
package com.yeqifu.bus.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; // MyBatis-Plus核心Mapper类
import com.yeqifu.bus.entity.Goods; // 商品实体类
import org.apache.ibatis.annotations.Param; // MyBatis参数注解
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.yeqifu.bus.entity.Goods;
import org.apache.ibatis.annotations.Param;
import java.util.List; // Java集合类
import java.util.List;
/**
* <p>
* Mapper
* InnoDB free: 9216 kB; (`providerid`) REFER `warehouse/bus_provider`(`id`)
* InnoDB free: 9216 kB; (`providerid`) REFER `warehouse/bus_provider`(`id`) Mapper
* </p>
*
* @author luoyi-
* @since 2019-12-06
*/
public interface GoodsMapper extends BaseMapper<Goods> { // 继承MyBatis-Plus的BaseMapper类
public interface GoodsMapper extends BaseMapper<Goods> {
/**
* ID
* @param id1 ID
* id
* @param id1
*/
void deleteSaleByGoodsId(@Param("goodsid") Integer id1); // 自定义SQL方法传入商品ID删除相关销售信息
void deleteSaleByGoodsId(@Param("goodsid") Integer id1);
/**
* ID退
* @param id1 ID
* id退
* @param id1
*/
void deleteSaleBackByGoodsId(@Param("goodsid") Integer id1); // 自定义SQL方法传入商品ID删除相关销售退货信息
void deleteSaleBackByGoodsId(@Param("goodsid") Integer id1);
/**
* ID
* @param id ID
* id
* @param id
*/
void deleteInportByGoodsId(@Param("goodsid") Integer id); // 自定义SQL方法传入商品ID删除相关进货信息
void deleteInportByGoodsId(@Param("goodsid") Integer id);
/**
* ID退
* @param id ID
* id退
* @param id
*/
void deleteOutportByGoodsId(@Param("goodsid") Integer id); // 自定义SQL方法传入商品ID删除相关退货信息
void deleteOutportByGoodsId(@Param("goodsid") Integer id);
/**
* ID
* @param id ID
* id
* @param id id
*/
void deleteSaleByCustomerId(Integer id); // 自定义SQL方法传入客户ID删除相关销售信息
void deleteSaleByCustomerId(Integer id);
/**
* ID退
* @param id ID
* id退
* @param id id
*/
void deleteSaleBackByCustomerId(Integer id); // 自定义SQL方法传入客户ID删除相关销售退货信息
void deleteSaleBackByCustomerId(Integer id);
/**
*
* @return
*/
List<Goods> loadAllWarning(); // 自定义SQL方法返回库存预警商品列表
List<Goods> loadAllWarning();
}
// GoodsMapper接口它继承自BaseMapper<Goods>这意味着它可以复用MyBatis-Plus框架提供的基础的数据库操作方法如常见的增删改查等操作
// 同时针对商品Goods相关的特定业务逻辑定义了一些额外的数据库操作方法用于与数据库进行交互实现更贴合业务需求的持久化功能。
// 该接口对应的实现类通常由MyBatis-Plus框架自动生成或者开发人员手动实现会具体负责将这些方法映射为相应的SQL语句并执行与数据库的实际交互操作。
// 接口文档注释中的信息“InnoDB free: 9216 kB; (`providerid`) REFER `warehouse/bus_provider`(`id`)”可能是关于数据库存储引擎以及表关联相关的一些提示信息,
// 例如表明使用的是InnoDB存储引擎且有外键关联这里是`providerid`关联到`warehouse/bus_provider`表的`id`字段),不过具体要结合实际数据库表结构来深入理解其含义。
// 根据商品id删除商品销售信息
// 此方法用于从数据库中删除与指定商品相关的销售信息通过传入的参数id1使用@Param注解将其命名为"goodsid"方便在对应的SQL语句中引用这个参数
// 在数据库的商品销售相关表具体表名要根据实际数据库设计确定依据商品的唯一标识符id找到对应的销售记录并执行删除操作
// 以确保数据的一致性,例如当商品被删除或者相关业务逻辑需要清理其销售记录时调用该方法。
// 根据商品id删除商品销售退货信息
// 功能与deleteSaleByGoodsId类似不过是针对商品销售退货相关的数据进行删除操作传入的参数id1同样被命名为"goodsid"
// 根据这个商品id在数据库的商品销售退货相关表中查找并删除对应的退货记录避免冗余数据保持业务数据的准确性例如在处理商品退货记录清理等业务场景时使用。
// 根据商品id删除商品进货信息
// 用于删除与指定商品相关的进货信息传入的参数id同样通过@Param注解关联到SQL语句中的"goodsid"参数)作为依据,
// 在数据库的商品进货相关表中定位到对应的进货记录并删除,比如当商品信息变更或者不再需要某些进货历史记录时,调用该方法来清理数据。
// 根据商品id删除商品退货信息
// 按照传入的商品id在数据库的商品退货相关表可能是出库退货等相关业务对应的表具体依业务和数据库设计而定中查找并删除对应的退货记录
// 保证数据库中商品退货数据与实际业务情况相符,防止出现无效或过期的退货数据,例如在退货业务流程结束后进行数据清理时使用该方法。
// 根据客户id删除商品销售
// 该方法以传入的参数id代表客户的唯一标识符为依据从数据库的商品销售相关表中查找并删除与该客户相关的所有商品销售记录
// 例如在客户账号注销或者业务上不再需要该客户的销售历史数据等场景下,调用此方法来清理相应的数据,维护数据库数据的有效性和整洁性。
// 根据客户id删除商品销售退货信息
// 与deleteSaleByCustomerId类似不过是针对商品销售退货信息进行删除操作依据传入的客户id在数据库的商品销售退货相关表中
// 清除该客户对应的所有销售退货记录,确保数据能准确反映当前业务状态,比如在处理客户相关数据清理、业务调整等情况下使用。
// 加载所有库存预警商品
// 此方法用于从数据库中查询并返回所有符合库存预警条件的商品信息返回的是一个包含Goods对象的列表List<Goods>
// 意味着会将数据库中那些库存数量达到预警阈值或者满足其他库存预警规则(具体规则由业务逻辑和数据库查询语句确定)的商品记录查询出来,
// 方便后续在业务中进行库存预警提示、补货提醒等相关操作,让业务人员及时了解库存情况并采取相应措施。

@ -1,17 +1,29 @@
package com.yeqifu.bus.mapper; // 包名
package com.yeqifu.bus.mapper;
import com.yeqifu.bus.entity.Inport; // 导入进货实体类
import com.baomidou.mybatisplus.core.mapper.BaseMapper; // 导入MyBatis-Plus核心BaseMapper接口
import com.yeqifu.bus.entity.Inport;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* <p>
* Mapper
* InnoDB free: 9216 kB; (`providerid`) REFER `warehouse/bus_provider`(`id`)
* InnoDB free: 9216 kB; (`providerid`) REFER `warehouse/bus_provider`(`id`); (`goo Mapper
* </p>
*
* @since 2019-12-18
* @author luoyi-
* @since 2019-12-18
*/
public interface InportMapper extends BaseMapper<Inport> { // Mapper接口继承BaseMapper自动实现通用数据操作
public interface InportMapper extends BaseMapper<Inport> {
}
// InportMapper接口它继承自BaseMapper<Inport>这里的BaseMapper是MyBatis-Plus框架提供的一个基础的Mapper接口
// 通过继承它InportMapper接口可以复用BaseMapper中已经定义好的一些通用的数据库操作方法例如常见的增删改查操作方法如insert、selectById、updateById、deleteById等
// 这些方法能够方便地与数据库进行交互实现对Inport类型数据通常代表进货相关的业务实体其具体结构由Inport类定义的基本持久化功能。
// 同时,这个接口也可以作为一个扩展点,开发人员可以根据具体的进货业务逻辑需求,后续在这个接口中添加更多自定义的数据库操作方法,
// 例如根据特定条件查询进货记录、关联其他表进行复杂的进货数据统计等操作方法并且在对应的Mapper实现类一般由MyBatis-Plus框架自动生成或者手动编写实现类
// 通过编写具体的SQL语句或者利用MyBatis-Plus提供的各种查询构建器等方式来实现这些自定义方法与数据库的交互逻辑进而满足更为复杂和贴合业务实际的进货数据处理需求。
// 目前该接口没有自定义额外的方法仅继承了BaseMapper<Inport>的通用方法意味着它暂时仅具备基础的针对Inport类型数据的数据库操作能力
// 不过随着业务发展,如果有针对进货数据的特殊持久化操作需求,就可以在这里添加相应的方法定义,来完善和扩展其功能。

@ -1,17 +1,34 @@
package com.yeqifu.bus.mapper; // 包名
package com.yeqifu.bus.mapper;
import com.yeqifu.bus.entity.Outport; // 导入出货实体类
import com.baomidou.mybatisplus.core.mapper.BaseMapper; // 导入MyBatis-Plus核心BaseMapper接口
import com.yeqifu.bus.entity.Outport;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* <p>
* Mapper
* InnoDB free: 9216 kB
* InnoDB free: 9216 kB Mapper
* </p>
*
* @since 2019-12-19
* @author luoyi-
* @since 2019-12-19
*/
public interface OutportMapper extends BaseMapper<Outport> { // Mapper接口继承BaseMapper自动实现通用数据操作
public interface OutportMapper extends BaseMapper<Outport> {
}
// OutportMapper接口它在整个项目的数据持久化层中扮演着重要角色主要用于处理与出货Outport相关的数据库操作是连接业务逻辑层与数据库的关键纽带之一。
// 该接口继承自BaseMapper<Outport>BaseMapper是MyBatis-Plus框架提供的一个基础的通用Mapper接口通过这种继承关系
// OutportMapper接口能够自动获得BaseMapper中定义好的一系列通用的数据库操作方法比如常见的插入insert、根据主键查询selectById
// 根据主键更新updateById以及根据主键删除deleteById等方法这些方法基于MyBatis-Plus的强大功能能够便捷地与数据库进行交互实现对Outport类型数据通常对应着出货业务实体
// 其具体属性和结构由Outport类来定义的基础持久化操作满足了在出货业务场景下对数据进行基本的增删改查等常规需求。
// 除此之外,从扩展性角度来看,这个接口还具备很强的可扩展性。随着项目中出货业务的不断发展和变化,可能会出现一些针对出货数据的特殊操作需求,
// 例如按照特定条件(如时间范围、商品类别、供应商等)查询出货记录、关联其他相关表(如关联商品表获取商品详细信息、关联客户表查看出货对象等)进行复杂的出货数据统计分析,
// 或者执行一些涉及多个表的复杂的数据库事务操作比如出货同时更新库存和财务相关数据等等情况开发人员就可以根据这些具体的业务需求在这个OutportMapper接口中添加自定义的方法声明
// 然后在对应的Mapper实现类一般由MyBatis-Plus框架按照一定规则自动生成或者开发人员手动编写实现类通过编写合适的SQL语句、运用MyBatis-Plus提供的各种查询构建器以及事务管理机制等
// 来实现这些自定义方法与数据库之间的交互逻辑,从而进一步完善和拓展针对出货业务数据的持久化处理功能,更好地满足项目中复杂多变的出货业务操作要求。
// 当前该接口仅继承了BaseMapper<Outport>,暂时未添加额外的自定义方法,这意味着目前它仅提供了那些基础的、通用的针对出货数据的数据库操作功能,
// 不过这也为后续依据实际业务发展情况来灵活扩展其功能留下了空间,方便根据出货业务的细化需求逐步完善其持久化操作能力。

@ -1,36 +1,60 @@
package com.yeqifu.bus.mapper; // 包名
package com.yeqifu.bus.mapper;
import com.yeqifu.bus.entity.Provider; // 导入供应商实体类
import com.baomidou.mybatisplus.core.mapper.BaseMapper; // 导入MyBatis-Plus核心BaseMapper接口
import org.apache.ibatis.annotations.Param; // 导入MyBatis的参数注解
import com.yeqifu.bus.entity.Provider;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Param;
/**
* <p>
* Mapper
* InnoDB free: 9216 kB
* InnoDB free: 9216 kB Mapper
* </p>
*
* @since 2019-12-05
* @author luoyi-
* @since 2019-12-05
*/
public interface ProviderMapper extends BaseMapper<Provider> { // Mapper接口继承BaseMapper自动实现通用数据操作
public interface ProviderMapper extends BaseMapper<Provider> {
/**
* ID
* @param id ID
* id
* @param id
*/
void deleteGoodsByProviderId(@Param("pid") Integer id); // 自定义SQL方法传入供应商ID删除相关商品信息
void deleteGoodsByProviderId(@Param("pid") Integer id);
/**
* ID
* @param id ID
* id
* @param id
*/
void deleteInportByProviderId(@Param("pid") Integer id); // 自定义SQL方法传入供应商ID删除相关进货信息
void deleteInportByProviderId(@Param("pid") Integer id);
/**
* ID退
* @param id ID
* id退
* @param id
*/
void deleteOutPortByProviderId(@Param("pid") Integer id); // 自定义SQL方法传入供应商ID删除相关退货信息
void deleteOutPortByProviderId(@Param("pid") Integer id);
}
// ProviderMapper接口它在项目的数据持久化层负责处理与供应商Provider相关的数据库操作是连接业务逻辑层和数据库的重要桥梁。
// 该接口继承自BaseMapper<Provider>BaseMapper是MyBatis-Plus框架提供的基础通用Mapper接口通过继承它ProviderMapper能够复用BaseMapper中定义好的常规数据库操作方法
// 例如常见的增删改查操作像插入供应商记录、根据供应商ID查询供应商信息、更新供应商信息以及删除供应商记录等满足对供应商数据的基本持久化需求。
// 同时,针对供应商业务逻辑中的一些特定操作场景,此接口还自定义了几个额外的方法,用于处理与供应商相关联的数据的删除操作,进一步完善了在涉及供应商相关业务时的数据持久化功能。
// 根据供应商id删除商品信息
// 此方法用于从数据库中删除与指定供应商相关联的商品信息。通过传入的参数id使用@Param注解将其命名为"pid"便于在对应的SQL语句中清晰地引用该参数
// 在数据库的商品表具体表名根据实际数据库设计而定依据与供应商的关联关系通常通过外键关联比如商品表中有指向供应商表的供应商ID字段
// 找到该供应商所对应的商品记录并执行删除操作,以确保数据的一致性。例如,当某个供应商不再合作,需要清理与之相关的商品数据时,可调用该方法。
// 根据供应商id删除商品进货信息
// 其功能是依据传入的供应商id从数据库的商品进货相关表可能记录了每次进货的商品、供应商、进货时间等信息的表具体依业务和数据库设计确定
// 查找并删除与该供应商相关的所有进货记录,避免出现数据冗余或无效的进货数据关联该供应商,比如在供应商信息变更或者合作终止等情况下,用于清理对应的进货历史数据。
// 根据供应商id删除商品退货信息
// 与上述两个删除方法类似该方法根据传入的供应商id在数据库的商品退货相关表比如记录商品退货的时间、数量、退货原因以及对应的供应商等信息的表
// 定位到与该供应商相关的退货记录并进行删除操作,保证数据库中的退货数据能准确反映当前业务状态,防止出现过期或不必要的退货记录与该供应商关联,例如在整理退货数据或者更新供应商合作关系时使用。

@ -1,17 +1,38 @@
package com.yeqifu.bus.mapper; // 包名
package com.yeqifu.bus.mapper;
import com.yeqifu.bus.entity.Sales; // 导入销售实体类
import com.baomidou.mybatisplus.core.mapper.BaseMapper; // 导入MyBatis-Plus核心BaseMapper接口
import com.yeqifu.bus.entity.Sales;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* <p>
* Mapper
* InnoDB free: 9216 kB
* InnoDB free: 9216 kB Mapper
* </p>
*
* @since 2019-12-21
* @author luoyi-
* @since 2019-12-21
*/
public interface SalesMapper extends BaseMapper<Sales> { // Mapper接口继承BaseMapper自动实现通用数据操作
public interface SalesMapper extends BaseMapper<Sales> {
}
// SalesMapper接口它处于项目的数据持久化层主要负责处理与销售Sales业务相关的数据持久化操作是连接业务逻辑层与数据库的重要纽带在整个项目架构中起着关键作用。
// 该接口继承自BaseMapper<Sales>这里的BaseMapper是MyBatis-Plus框架提供的一个基础通用Mapper接口。通过这种继承关系
// SalesMapper接口能够直接复用BaseMapper中已经定义好的一系列通用的数据库操作方法像常见的插入insert方法可用于向数据库中插入新的销售记录
// 依据主键进行查询的selectById方法方便根据销售记录的唯一标识符通常是主键ID从数据库中精准获取某条销售记录的详细信息
// 基于主键更新记录的updateById方法能对数据库中已存在的销售记录进行修改操作还有通过主键删除记录的deleteById方法用于删除数据库中对应的销售记录等。
// 这些通用的数据库操作方法借助MyBatis-Plus的功能特性能够高效地与数据库进行交互实现对Sales类型的数据通常代表销售业务实体其具体的属性和结构由Sales类来定义的基本持久化功能
// 满足了在日常销售业务场景下对销售数据进行常规的增删改查等基础操作的需求,例如添加一笔新的销售业务记录、查看特定销售业务详情、修改销售记录中的部分信息或者删除不再需要的销售记录等情况。
// 从可扩展性角度来看虽然当前SalesMapper接口暂时只是继承了BaseMapper<Sales>,并没有额外自定义其他方法,但随着项目中销售业务的不断发展和变化,
// 后续极有可能会出现一些针对销售数据的特殊操作需求。例如,按照特定的条件(如销售时间范围、客户地区、商品分类等)来查询销售记录,
// 或者关联其他相关数据表(比如关联客户表获取客户的详细信息、关联商品表查看商品的具体规格等)进行更为复杂的销售数据统计分析,
// 又或者执行涉及多个表的复杂数据库事务操作(比如销售业务发生时同时更新库存表、财务相关数据表等)。一旦有这些业务需求出现,开发人员就可以根据具体的业务场景,
// 在这个SalesMapper接口中添加相应的自定义方法声明然后在对应的Mapper实现类一般由MyBatis-Plus框架按照相应规则自动生成或者开发人员手动编写实现类
// 通过编写合适的SQL语句、运用MyBatis-Plus提供的各种查询构建器以及事务管理机制等来实现这些自定义方法与数据库之间的交互逻辑
// 从而进一步完善和拓展针对销售业务数据的持久化处理功能,使其能够更好地适配项目中日益复杂和多样化的销售业务操作要求。
// 现阶段该接口仅继承了BaseMapper<Sales>所提供的通用数据库操作方法,尚未添加额外的自定义方法,这表明目前它主要提供的是基础的、常规的针对销售数据的数据库操作功能,
// 不过这也为后续依据销售业务的实际发展情况灵活扩展其功能留下了充足的空间,方便后续根据销售业务的细化需求逐步丰富其持久化操作能力,以更好地服务于整个项目的销售业务逻辑。

@ -1,17 +1,37 @@
package com.yeqifu.bus.mapper; // 包名
package com.yeqifu.bus.mapper;
import com.yeqifu.bus.entity.Salesback; // 导入销售退货实体类
import com.baomidou.mybatisplus.core.mapper.BaseMapper; // 导入MyBatis-Plus核心BaseMapper接口
import com.yeqifu.bus.entity.Salesback;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* <p>
* 退Mapper退
* InnoDB free: 9216 kB
* InnoDB free: 9216 kB Mapper
* </p>
*
* @since 2019-12-23
* @author luoyi-
* @since 2019-12-23
*/
public interface SalesbackMapper extends BaseMapper<Salesback> { // Mapper接口继承BaseMapper自动实现通用数据操作
public interface SalesbackMapper extends BaseMapper<Salesback> {
}
// SalesbackMapper接口它在整个项目的数据持久化层有着特定的作用主要聚焦于处理与销售退货Salesback相关的数据库操作是实现业务逻辑层与数据库之间交互的关键一环。
// 该接口继承自BaseMapper<Salesback>BaseMapper是MyBatis-Plus框架所提供的一个基础的通用Mapper接口。借助这种继承关系
// SalesbackMapper接口能够直接复用BaseMapper里已经定义好的一系列通用的数据库操作方法例如常见的增删改查操作方法像插入销售退货记录insert方法
// 根据销售退货记录的主键查询相应记录selectById方法、依据主键更新销售退货记录updateById方法以及通过主键删除销售退货记录deleteById方法等。
// 这些通用方法依托MyBatis-Plus的功能机制能够便捷地与数据库进行交互从而实现对Salesback类型的数据通常对应着销售退货业务实体其具体的属性和结构由Salesback类来定义进行基础的持久化操作
// 满足了在销售退货业务场景下对相关数据进行常规处理的基本需求,比如简单的添加、查询、修改以及删除单条销售退货记录等操作。
// 从可扩展性方面来看虽然当前这个接口暂时仅继承了BaseMapper<Salesback>,没有额外自定义其他方法,但随着项目中销售退货业务的不断拓展和变化,
// 后续很可能会出现一些针对销售退货数据的特殊操作需求。例如,按照特定条件(如退货时间范围、客户类别、商品种类等)来查询销售退货记录,
// 或者关联其他相关数据表(比如关联商品表获取退货商品的详细规格、关联客户表查看退货客户的更多信息等)进行更为复杂的销售退货数据统计分析,
// 亦或是执行涉及多个表的复杂数据库事务操作(比如销售退货同时更新库存、财务相关数据等情况)。当出现这些业务需求时,开发人员就可以根据具体情况,
// 在这个SalesbackMapper接口中添加自定义的方法声明然后在对应的Mapper实现类一般由MyBatis-Plus框架按照既定规则自动生成或者开发人员手动编写实现类
// 通过编写合适的SQL语句、运用MyBatis-Plus提供的各种查询构建器以及事务管理机制等手段来实现这些自定义方法与数据库之间的交互逻辑
// 进而完善和拓展针对销售退货业务数据的持久化处理功能,使其能够更好地适应项目中复杂多变的销售退货业务操作要求。
// 目前该接口仅继承了BaseMapper<Salesback>所提供的通用方法,尚未添加额外的自定义方法,这意味着现阶段它主要提供的是基础的、通用的针对销售退货数据的数据库操作功能,
// 不过这也为后续依据业务发展情况灵活扩展其功能预留了空间,方便根据销售退货业务的细化需求逐步丰富其持久化操作能力。

@ -17,5 +17,18 @@ public interface ICustomerService extends IService<Customer> {
* id
* @param id id
*/
void deleteCustomerById(Integer id);
}
// ICustomerService接口它在项目的业务逻辑层扮演着重要角色用于定义与客户Customer相关的业务操作方法规范是对外提供统一的客户业务服务的接口。
// 该接口继承自IService<Customer>IService是MyBatis-Plus框架中定义的一个通用服务层接口通过继承它ICustomerService接口可以复用IService中提供的一些通用的服务方法
// 例如常见的增删改查操作方法像保存客户信息、根据客户ID查询客户、更新客户信息等这些复用的方法能够方便地与数据持久化层进行交互实现对客户数据的基本业务处理满足常规的客户业务操作需求。
// 同时,针对客户业务逻辑中的特定需求,此接口还自定义了一个额外的方法,用于执行删除客户的操作,进一步完善了在客户管理方面的业务服务功能。
// 根据客户id删除客户
// 此方法用于在业务逻辑层面实现根据给定的客户id参数id表示客户的唯一标识符从系统中删除对应的客户信息及其相关联的数据具体关联的数据删除情况可能要依据业务规则和数据库设计而定
// 例如,在客户注销账号、不再合作或者因数据清理等业务场景下,通过调用该方法,可以触发一系列相关操作,确保客户数据在数据库以及整个业务系统中的一致性,
// 可能涉及到删除客户在其他关联表(如客户订单表、客户反馈表等)中的相关记录等操作,不过具体的实现细节会在该接口的实现类中进行处理,这里主要定义了方法的规范和功能。

@ -1,29 +1,52 @@
package com.yeqifu.bus.service; // 包名
package com.yeqifu.bus.service;
import com.baomidou.mybatisplus.extension.service.IService; // 导入MyBatis-Plus服务层通用接口
import com.yeqifu.bus.entity.Goods; // 导入商品实体类
import java.util.List; // 导入Java集合List
import com.baomidou.mybatisplus.extension.service.IService;
import com.yeqifu.bus.entity.Goods;
import java.util.List;
/**
* <p>
*
* InnoDB free: 9216 kB; (`providerid`) REFER `warehouse/bus_provider`(`id`)
* InnoDB free: 9216 kB; (`providerid`) REFER `warehouse/bus_provider`(`id`)
* </p>
*
* @since 2019-12-06
* @author luoyi-
* @since 2019-12-06
*/
public interface IGoodsService extends IService<Goods> { // IService 是 MyBatis-Plus 提供的通用服务层接口
public interface IGoodsService extends IService<Goods> {
/**
* ID
* @param id ID
* id
* @param id
*/
void deleteGoodsById(Integer id); // 自定义方法用于根据商品ID删除商品信息
void deleteGoodsById(Integer id);
/**
*
* @return
*
* @return
*/
List<Goods> loadAllWarning(); // 自定义方法,用于获取所有库存预警商品列表
List<Goods> loadAllWarning();
}
// IGoodsService接口它位于项目的业务逻辑层起着至关重要的作用主要用于定义各类与商品Goods相关的业务操作方法是对外提供统一的商品业务服务的接口方便其他层如控制层等进行调用。
// 该接口继承自IService<Goods>IService是MyBatis-Plus框架所定义的一个通用服务层接口通过继承它IGoodsService接口能够复用IService中已经定义好的一系列通用的服务方法
// 例如常见的增删改查操作方法像保存商品信息、根据商品ID查询商品详情、更新商品信息等这些复用的方法可以便捷地与数据持久化层通常是对应的Mapper接口及实现类进行交互
// 实现对商品数据的基础业务处理,满足常规的商品业务操作需求,保障了商品数据在整个业务系统中的流转和处理。
// 除此之外,针对商品业务逻辑中的特定业务场景,此接口还自定义了两个额外的方法,进一步丰富和完善了在商品管理及相关业务方面的服务功能。
// 根据商品id删除商品
// 此方法用于在业务逻辑层面依据传入的商品id参数id代表商品的唯一标识符从系统中删除对应的商品信息以及与之相关联的数据具体关联数据的删除范围要依据业务规则和数据库设计来确定
// 比如,当商品下架、库存清零且不再售卖或者因数据清理等业务情况发生时,调用该方法可以触发一系列相关操作,确保商品数据在数据库以及整个业务系统中的一致性,
// 可能涉及到删除商品在其他关联表(如商品销售表、商品进货表、商品库存表等)中的相关记录等操作,不过具体的删除逻辑实现细节会在该接口的实现类中进行处理,这里主要是定义了该删除操作的方法规范和功能要求。
// 加载所有的库存预警商品
// 该方法用于从系统中查询并获取所有满足库存预警条件的商品信息返回一个包含Goods对象的列表List<Goods>)。库存预警条件通常是由业务规则预先设定好的,
// 例如商品库存数量低于某个设定的阈值、库存周转率达到特定标准等情况,通过调用这个方法,能够方便业务人员及时了解哪些商品的库存处于需要关注的预警状态,
// 以便采取相应的措施(如及时补货、调整销售策略等),其具体的查询逻辑以及判断库存预警的实现细节同样会在接口的实现类中进行编写,这里主要定义了方法的返回值类型和功能概述。

@ -1,17 +1,36 @@
package com.yeqifu.bus.service; // 包名
package com.yeqifu.bus.service;
import com.yeqifu.bus.entity.Inport; // 导入进货实体类
import com.baomidou.mybatisplus.extension.service.IService; // 导入MyBatis-Plus提供的通用服务接口
import com.yeqifu.bus.entity.Inport;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* <p>
*
* InnoDB free: 9216 kB; (`providerid`) REFER `warehouse/bus_provider`(`id`)
* InnoDB free: 9216 kB; (`providerid`) REFER `warehouse/bus_provider`(`id`); (`goo
* </p>
*
* @since 2019-12-18
* @author luoyi-
* @since 2019-12-18
*/
public interface IInportService extends IService<Inport> { // IService 是 MyBatis-Plus 提供的通用服务接口
public interface IInportService extends IService<Inport> {
}
// IInportService接口它处于项目的业务逻辑层主要聚焦于定义与进货Inport相关的业务操作方法规范是对外提供统一的进货业务服务的接口在整个项目架构里扮演着连接控制层与数据持久化层的关键角色。
// 该接口继承自IService<Inport>IService是MyBatis-Plus框架提供的一个基础通用服务层接口。借助这种继承关系
// IInportService接口能够直接复用IService中已经定义好的一系列通用的服务方法例如常见的增删改查操作方法像保存进货记录insert方法
// 根据进货记录的主键查询相应记录selectById方法、依据主键更新进货记录updateById方法以及通过主键删除进货记录deleteById方法等。
// 这些通用的服务方法依托MyBatis-Plus的功能机制能够方便地与数据持久化层通常对应的是InportMapper及其实现类进行交互从而实现对Inport类型的数据通常对应着进货业务实体其具体的属性和结构由Inport类来定义进行基础的业务处理
// 满足了在日常进货业务场景下对进货数据进行常规的增删改查等基础操作的需求,例如添加一笔新的进货业务记录、查看特定进货业务详情、修改进货记录中的部分信息或者删除不再需要的进货记录等情况。
// 虽然当前这个接口暂时只是继承了IService<Inport>,并没有额外自定义其他方法,但随着项目中进货业务的不断拓展和变化,
// 后续很可能会出现一些针对进货数据的特殊操作需求。例如,按照特定的条件(如进货时间范围、供应商类别、商品种类等)来查询进货记录,
// 或者关联其他相关数据表(比如关联供应商表获取供应商的详细信息、关联商品表查看商品的具体规格等)进行更为复杂的进货数据统计分析,
// 又或者执行涉及多个表的复杂业务操作(比如进货同时更新库存表、财务相关数据表等)。一旦有这些业务需求出现,开发人员就可以根据具体的业务场景,
// 在这个IInportService接口中添加相应的自定义方法声明然后在对应的服务实现类一般由MyBatis-Plus框架按照既定规则自动生成或者开发人员手动编写实现类
// 通过编写合适的业务逻辑代码以及调用数据持久化层的方法等,来实现这些自定义方法与数据库及其他相关业务模块之间的交互逻辑,
// 进而完善和拓展针对进货业务数据的服务处理功能,使其能够更好地适配项目中日益复杂和多样化的进货业务操作要求。
// 现阶段该接口仅继承了IService<Inport>所提供的通用服务方法,尚未添加额外的自定义方法,这表明目前它主要提供的是基础的、常规的针对进货数据的业务服务功能,
// 不过这也为后续依据进货业务的实际发展情况灵活扩展其功能留下了充足的空间,方便后续根据进货业务的细化需求逐步丰富其服务操作能力,以更好地服务于整个项目的进货业务逻辑。

@ -1,25 +1,41 @@
package com.yeqifu.bus.service; // 包名
package com.yeqifu.bus.service;
import com.yeqifu.bus.entity.Outport; // 导入退货实体类
import com.baomidou.mybatisplus.extension.service.IService; // 导入 MyBatis-Plus 提供的通用服务接口
import com.yeqifu.bus.entity.Outport;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* <p>
* 退退
* InnoDB free: 9216 kB
* InnoDB free: 9216 kB
* </p>
*
* @since 2019-12-19
* @author luoyi-
* @since 2019-12-19
*/
public interface IOutportService extends IService<Outport> { // IService 是 MyBatis-Plus 提供的通用服务接口
public interface IOutportService extends IService<Outport> {
/**
* 退
*
* @param id ID
* @param number 退退
* @param remark 退
* @param id ID
* @param number 退
* @param remark
*/
void addOutport(Integer id, Integer number, String remark); // 自定义方法,处理退货操作
void addOutport(Integer id, Integer number, String remark);
}
// IOutportService接口它位于项目的业务逻辑层起着关键的作用主要用于定义各类与出货Outport相关的业务操作方法同时也涵盖了针对进货退货这一特定业务场景的相关操作是对外提供统一的出货及相关业务服务的接口便于其他层如控制层等进行调用。
// 该接口继承自IService<Outport>IService是MyBatis-Plus框架所定义的一个通用服务层接口通过继承它IOutportService接口能够复用IService中已经定义好的一系列通用的服务方法
// 例如常见的增删改查操作方法像保存出货记录、根据出货记录的ID查询出货详情、更新出货记录等这些复用的方法可以便捷地与数据持久化层通常是对应的OutportMapper及其实现类进行交互
// 实现对出货数据的基础业务处理,满足常规的出货业务操作需求,保障了出货数据在整个业务系统中的流转和处理。
// 除此之外,针对业务逻辑中涉及到的对商品进货进行退货处理这一特定需求,此接口还自定义了一个额外的方法,进一步丰富和完善了在出货及退货管理方面的服务功能。
// 对商品进货进行退货处理
// 此方法用于在业务逻辑层面,处理商品进货后的退货相关操作。它接收三个参数:
// - 参数id代表进货单ID用于明确是针对哪一笔进货业务进行退货操作通过这个ID可以关联到对应的进货记录确定退货操作所涉及的具体商品、供应商等相关信息它是整个退货操作定位基础数据的关键标识。
// - 参数number表示退货数量明确了此次退货的商品具体数量这对于后续更新库存数量、统计退货数据等操作至关重要确保退货数量的准确性能够维护整个业务系统中数据的一致性。
// - 参数remark代表备注信息用于记录一些额外的、需要说明的关于此次退货的相关情况比如退货原因商品质量问题、数量不符等、特殊的退货协商结果等内容方便后续查看退货记录时能更全面地了解当时的业务详情。
// 在具体实现时调用这个方法会触发一系列相关的业务逻辑操作例如根据进货单ID查找对应的进货商品信息依据退货数量更新库存减少相应的库存数量在数据库中记录此次退货的相关数据生成退货记录等
// 同时可能还会涉及到关联其他表进行相关数据的更新或记录(如财务相关表记录退货涉及的资金变动等),不过具体的详细实现逻辑会在该接口的实现类中进行处理,这里主要是定义了该退货操作方法的参数以及功能概述。

@ -1,23 +1,37 @@
package com.yeqifu.bus.service; // 包名
package com.yeqifu.bus.service;
import com.yeqifu.bus.entity.Provider; // 导入供应商实体类
import com.baomidou.mybatisplus.extension.service.IService; // 导入 MyBatis-Plus 提供的通用服务接口
import com.yeqifu.bus.entity.Provider;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* <p>
*
* InnoDB free: 9216 kB
* InnoDB free: 9216 kB
* </p>
*
* @since 2019-12-05
* @author luoyi-
* @since 2019-12-05
*/
public interface IProviderService extends IService<Provider> { // IService 是 MyBatis-Plus 提供的通用服务接口
public interface IProviderService extends IService<Provider> {
/**
* ID
*
* @param id ID
* ID
* @param id
*/
void deleteProviderById(Integer id); // 自定义方法,处理删除操作
void deleteProviderById(Integer id);
}
// IProviderService接口它处于项目的业务逻辑层主要负责定义与供应商Provider相关的业务操作方法规范是对外提供统一的供应商业务服务的接口在整个项目架构中起着连接不同业务模块以及与数据持久化层交互的重要作用。
// 该接口继承自IService<Provider>IService是MyBatis-Plus框架提供的一个通用服务层接口通过继承它IProviderService接口可以复用IService中已定义好的通用服务方法
// 例如常见的增删改查操作方法像保存供应商信息、根据供应商ID查询供应商详情、更新供应商信息等这些复用的方法能够方便地与数据持久化层通常对应的是ProviderMapper及其实现类进行交互
// 实现对供应商数据的基本业务处理,满足常规的供应商业务操作需求,保障了供应商数据在整个业务系统中的正常流转与处理。
// 同时,针对供应商业务中特定的删除操作需求,此接口自定义了一个额外的方法,进一步完善了在供应商管理方面的服务功能,使其能更精准地处理与供应商删除相关的业务逻辑。
// 根据供应商ID删除供应商
// 此方法用于在业务逻辑层面依据传入的供应商ID参数id表示供应商的唯一标识符从系统中删除对应的供应商信息以及与之相关联的数据具体关联数据的删除范围要依据业务规则和数据库设计来确定
// 例如,当供应商合作关系终止、供应商信息有误需要彻底清除或者因业务调整不再使用该供应商等场景出现时,通过调用该方法,可以触发一系列相关操作,
// 确保供应商数据在数据库以及整个业务系统中的一致性,可能涉及到删除该供应商在其他关联表(如商品进货表、商品销售表中与该供应商相关的记录等)中的相关记录等操作,
// 不过具体的删除逻辑实现细节会在该接口的实现类中进行处理这里主要是定义了该方法的功能规范明确了依据供应商ID来执行删除操作这一业务需求。

@ -1,18 +1,36 @@
package com.yeqifu.bus.service; // 包名,定义服务层的包路径
package com.yeqifu.bus.service;
import com.yeqifu.bus.entity.Sales; // 导入销售实体类
import com.baomidou.mybatisplus.extension.service.IService; // 导入 MyBatis-Plus 提供的通用服务接口
import com.yeqifu.bus.entity.Sales;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* <p>
*
* InnoDB free: 9216 kB
* InnoDB free: 9216 kB
* </p>
*
* @since 2019-12-21
* @author luoyi-
* @since 2019-12-21
*/
public interface ISalesService extends IService<Sales> { // IService 是 MyBatis-Plus 提供的通用服务接口
public interface ISalesService extends IService<Sales> {
// 由于未定义自定义方法,这里继承 IService<Sales> 后可自动具备基本的 CRUD 功能
}
// ISalesService接口它处在项目的业务逻辑层核心作用是定义与销售Sales相关的各类业务操作方法规范是对外提供统一的销售业务服务的接口在整个项目架构里充当着连接控制层与数据持久化层、协调各业务模块交互的关键角色。
// 该接口继承自IService<Sales>IService是MyBatis-Plus框架提供的一个基础通用服务层接口。借助这种继承关系
// ISalesService接口能够直接复用IService中已经定义好的一系列通用的服务方法例如常见的增删改查操作方法像保存销售记录insert方法
// 根据销售记录的主键查询相应记录selectById方法、依据主键更新销售记录updateById方法以及通过主键删除销售记录deleteById方法等。
// 这些通用的服务方法依托MyBatis-Plus的功能机制能够方便地与数据持久化层通常对应的是SalesMapper及其实现类进行交互从而实现对Sales类型的数据通常对应着销售业务实体其具体的属性和结构由Sales类来定义进行基础的业务处理
// 满足了在日常销售业务场景下对销售数据进行常规的增删改查等基础操作的需求,例如添加一笔新的销售业务记录、查看特定销售业务详情、修改销售记录中的部分信息或者删除不再需要的销售记录等情况。
// 尽管当前这个接口暂时只是继承了IService<Sales>,并没有额外自定义其他方法,但随着项目中销售业务的不断拓展和变化,
// 后续很可能会出现一些针对销售数据的特殊操作需求。例如,按照特定的条件(如销售时间范围、客户类别、商品分类等)来查询销售记录,
// 或者关联其他相关数据表(比如关联客户表获取客户的详细信息、关联商品表查看商品的具体规格等)进行更为复杂的销售数据统计分析,
// 又或者执行涉及多个表的复杂业务操作(比如销售业务发生时同时更新库存表、财务相关数据表等)。一旦有这些业务需求出现,开发人员就可以根据具体的业务场景,
// 在这个ISalesService接口中添加相应的自定义方法声明然后在对应的服务实现类一般由MyBatis-Plus框架按照既定规则自动生成或者开发人员手动编写实现类
// 通过编写合适的业务逻辑代码以及调用数据持久化层的方法等,来实现这些自定义方法与数据库及其他相关业务模块之间的交互逻辑,
// 进而完善和拓展针对销售业务数据的服务处理功能,使其能够更好地适配项目中日益复杂和多样化的销售业务操作要求。
// 现阶段该接口仅继承了IService<Sales>所提供的通用服务方法,尚未添加额外的自定义方法,这表明目前它主要提供的是基础的、常规的针对销售数据的业务服务功能,
// 不过这也为后续依据销售业务的实际发展情况灵活扩展其功能留下了充足的空间,方便后续根据销售业务的细化需求逐步丰富其服务操作能力,以更好地服务于整个项目的销售业务逻辑。

@ -1,25 +1,42 @@
package com.yeqifu.bus.service; // 包名
package com.yeqifu.bus.service;
import com.yeqifu.bus.entity.Salesback; // 导入销售退货实体类
import com.baomidou.mybatisplus.extension.service.IService; // 导入 MyBatis-Plus 提供的通用服务接口
import com.yeqifu.bus.entity.Salesback;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* <p>
* 退退
* InnoDB free: 9216 kB
* InnoDB free: 9216 kB
* </p>
*
* @since 2019-12-23
* @author luoyi-
* @since 2019-12-23
*/
public interface ISalesbackService extends IService<Salesback> { // IService 是 MyBatis-Plus 提供的通用服务接口
public interface ISalesbackService extends IService<Salesback> {
/**
* 退
*
* @param id ID退
* @param number 退退
* @param remark 退
* @param id ID
* @param number 退
* @param remark
*/
void addSalesback(Integer id, Integer number, String remark); // 自定义退货处理方法
void addSalesback(Integer id, Integer number, String remark);
}
// ISalesbackService接口它位于项目的业务逻辑层有着十分重要的作用主要用于定义与商品销售退货Salesback相关的各类业务操作方法是对外提供统一的销售退货业务服务的接口方便其他业务层比如控制层进行调用以此来驱动整个销售退货业务流程的运转。
// 该接口继承自IService<Salesback>IService是MyBatis-Plus框架所定义的一个通用服务层接口通过继承它ISalesbackService接口能够复用IService中已经定义好的一系列通用服务方法
// 例如常见的增删改查操作方法像保存销售退货记录、根据销售退货记录的主键查询对应记录、依据主键更新销售退货记录等这些复用的方法可以便捷地与数据持久化层通常对应的是SalesbackMapper及其实现类进行交互
// 实现对销售退货数据的基础业务处理,满足常规的销售退货业务操作需求,保障了销售退货数据在整个业务系统中的正常流转和处理。
// 此外,针对销售退货业务中核心的对商品销售进行退货处理这一特定业务场景,此接口还自定义了一个额外的方法,进一步完善和细化了在销售退货管理方面的服务功能,使其能精准地应对销售退货相关的业务操作需求。
// 对商品销售进行退货处理
// 此方法用于在业务逻辑层面,专门处理商品销售后的退货相关操作。它接收三个关键参数:
// - 参数id代表销售单ID这是整个退货操作的重要依据通过它可以准确关联到对应的销售记录进而确定此次退货所涉及的具体商品、客户、销售价格等基础信息是定位和追溯退货业务源头的关键标识。
// - 参数number表示退货数量明确了此次退货的商品具体数量这对于后续准确更新库存数量将退货商品重新入库、统计退货数据如计算退货金额等以及维护整个业务系统中数据的一致性都起着至关重要的作用。
// - 参数remark代表备注信息用于记录一些额外的、需要说明的关于此次退货的相关情况例如退货原因可能是商品质量问题、客户不满意、规格不符等、特殊的退货协商条件如部分退款、换货等相关约定等内容方便后续查看退货记录时能够更全面、详细地了解当时的业务详情。
// 当在业务中调用这个方法时会触发一系列复杂的业务逻辑操作比如依据销售单ID查找原始销售的详细信息根据退货数量调整库存增加相应的库存数量在数据库中记录此次销售退货的相关数据生成销售退货记录包含退货时间、操作人等信息
// 同时还可能涉及到关联其他业务表进行相关数据的更新或记录(如财务相关表记录退款金额、销售业绩表相应调整等),不过具体的这些详细实现逻辑会在该接口的实现类中进行处理,这里主要是定义了该销售退货操作方法的参数以及整体的功能概述。

@ -12,7 +12,7 @@ import org.springframework.transaction.annotation.Transactional;
import java.io.Serializable;
import java.util.Collection;
/**
/*
* <p>
* InnoDB free: 9216 kB
* </p>
@ -31,17 +31,63 @@ public class CustomerServiceImpl extends ServiceImpl<CustomerMapper, Customer> i
public boolean save(Customer entity) {
return super.save(entity);
}
/*
* ICustomerService
* savesuper.save(entity)
* entityCustomer
* save使
* SQL
* true
* false
*/
@Override
public boolean updateById(Customer entity) {
return super.updateById(entity);
}
/*
* ICustomerServiceID
* entityCustomerIDID
*
* updateByIdsuper.updateById(entity)ID
*
* SQL
* true
* false
*/
@Override
public boolean removeById(Serializable id) {
return super.removeById(id);
}
/*
* ICustomerServiceID
* idSerializable
* id
* removeByIdsuper.removeById(id)
* removeByIdMyBatisHibernate
* idSQLDELETE
*
*
*
* trueIDfalse
*/
@Override
/*
* ICustomerServiceid
* Customernull
*
* idSerializableid
*
*
* getByIdsuper.getById(id)getById
* MyBatisHibernateid
* 便Customer
* Customeridnull
*/
public Customer getById(Serializable id) {
return super.getById(id);
}
@ -64,3 +110,32 @@ public class CustomerServiceImpl extends ServiceImpl<CustomerMapper, Customer> i
this.removeById(id);
}
}
/*
* ID
*
*
* Integerid
* id
*/
// 根据客户id删除商品销售
/*
* goodsMapperdeleteSaleByCustomerIdGoodsMapper
* ID'sale'
*
*/
// 根据客户id删除商品销售退货
/*
* goodsMapperdeleteSaleBackByCustomerIdID
* 退'sale_back'退
* 退退
*/
// 调用当前类可能继承了某些基础服务类的removeById方法依据传入的客户ID
// 从存储客户基本信息的数据库表(通常名为'customer'表等)中查找并删除对应的客户记录本身,完成客户基本信息的删除操作,
// 至此,从客户基本信息到与之关联的商品销售及销售退货等相关数据都已完成删除,实现了完整的客户相关数据删除流程。

@ -1,19 +1,18 @@
package com.yeqifu.bus.vo; // 包名,定义视图层的包路径
package com.yeqifu.bus.vo;
import com.yeqifu.bus.entity.Goods; // 导入 Goods 实体类
import lombok.Data; // 导入 Lombok 提供的 @Data 注解
import lombok.EqualsAndHashCode; // 导入 Lombok 提供的 @EqualsAndHashCode 注解
import com.yeqifu.bus.entity.Goods;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* @Author: -
* @Date: 2019/12/6 22:30
*
* (VO) Goods
*/
@Data // 自动生成 getter、setter、toString 等常用方法
@EqualsAndHashCode(callSuper = false) // 生成 equals 和 hashCode 方法,且不考虑父类属性
public class GoodsVo extends Goods { // 继承 Goods 实体类
@Data
@EqualsAndHashCode(callSuper = false)
public class GoodsVo extends Goods {
private Integer page=1;
private Integer limit=10;
private Integer page = 1; // 分页查询起始页码,默认为第 1 页
private Integer limit = 10; // 分页查询的限制记录数,默认为每页 10 条数据
}

@ -1,28 +1,58 @@
package com.yeqifu.bus.vo; // 包路径,定义视图层的包路径
package com.yeqifu.bus.vo;
import com.yeqifu.bus.entity.Inport; // 导入 Inport 实体类
import lombok.Data; // 导入 Lombok 提供的 @Data 注解
import lombok.EqualsAndHashCode; // 导入 Lombok 提供的 @EqualsAndHashCode 注解
import org.springframework.format.annotation.DateTimeFormat; // 导入日期格式注解
import java.util.Date; // 导入 Date 类
import com.yeqifu.bus.entity.Inport;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
/**
* @Author: -
* @Date: 2019/12/18 10:29
*
* (VO) Inport
*/
@Data // 自动生成 getter、setter、toString 等常用方法
@EqualsAndHashCode(callSuper = false) // 生成 equals 和 hashCode 方法,且不考虑其父类属性
public class InportVo extends Inport { // 继承 Inport 实体类
@Data
@EqualsAndHashCode(callSuper = false)
public class InportVo extends Inport {
private Integer page = 1;
private Integer page = 1; // 分页查询起始页码,默认为第 1 页
private Integer limit = 10;
private Integer limit = 10; // 分页查询的限制记录数,默认为每页 10 条数据
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date startTime;
@DateTimeFormat(pattern = "yyyy-MM-dd") // 格式化日期为 yyyy-MM-dd 格式
private Date startTime; // 查询时间范围的起始时间
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date endTime;
@DateTimeFormat(pattern = "yyyy-MM-dd") // 格式化日期为 yyyy-MM-dd 格式
private Date endTime; // 查询时间范围的结束时间
}
// InportVo类它是一个Java类通过继承Inport类来扩展其功能通常用于在业务中承载更多与进货相关的数据展示、查询等操作所需的信息
// 比如用于接收前端传递过来的分页、时间范围筛选等参数,方便在后端进行相应的业务逻辑处理以及与数据库交互获取符合条件的进货数据。
// 使用了@Data注解该注解来自Lombok库假设项目中引入了Lombok它会自动为类生成常用的方法如Getter、Setter、toString、equals和hashCode等方法
// 减少了手动编写这些重复代码的工作量让代码更加简洁明了同时也遵循了Java Bean的规范便于对象属性的访问和操作。
// @EqualsAndHashCode(callSuper = false)注解同样来自Lombok库它用于重写equals和hashCode方法
// 设置callSuper = false表示在生成equals和hashCode方法时不会调用父类Inport类的相应方法而是仅基于当前类自身的属性来生成
// 这符合在一些特定业务场景下,只关注当前类新增或重写的属性来进行对象相等性判断和哈希码生成的需求。
// page属性用于存储当前请求的页码信息初始值设置为1在分页查询进货数据的业务场景中前端通常会传递需要查看的页码数
// 后端根据这个页码以及每页显示的记录数量由limit属性决定来从数据库中获取相应的数据例如当page为2且limit为10时
// 可以获取第2页的10条进货记录方便实现数据的分页展示提升用户体验避免一次性加载过多数据。
// limit属性用于指定每页显示的记录数量初始值设为10它与page属性配合使用共同确定每次分页查询时从数据库中获取的数据范围
// 可以根据实际业务需求和性能考虑来调整这个值,比如在数据量较大时适当增大每页显示数量,或者为了提高页面加载速度适当减小每页显示数量。
// startTime属性用于接收表示时间范围起始时间的日期信息通过添加@DateTimeFormat(pattern = "yyyy-MM-dd")注解,
// 可以指定前端传递过来的日期字符串的格式(这里要求为"yyyy-MM-dd"这种常见的年-月-日格式便于后端将其正确解析为Date类型
// 在查询进货数据时,这个属性可用于筛选出起始时间之后的进货记录,例如查询从某个特定日期开始的进货情况,方便进行按时间范围的数据筛选和统计分析。
// endTime属性与startTime属性类似也是用于接收日期信息同样借助@DateTimeFormat(pattern = "yyyy-MM-dd")注解来规范日期字符串的格式,
// 它用于指定时间范围的结束时间在查询进货数据时结合startTime属性可以获取在这个时间区间内包含起始时间和结束时间对应的当天的进货记录
// 比如查询某一个月内的进货情况,就可以分别设置相应的起始和结束日期,实现精准的时间范围筛选功能。

@ -1,43 +1,65 @@
package com.yeqifu.bus.vo; // 定义视图层包路径
package com.yeqifu.bus.vo;
import com.yeqifu.bus.entity.Outport; // 导入 Outport 实体类
import lombok.Data; // 导入 Lombok 提供的 @Data 注解
import lombok.EqualsAndHashCode; // 导入 Lombok 提供的 @EqualsAndHashCode 注解
import org.springframework.format.annotation.DateTimeFormat; // 导入日期格式化注解
import java.util.Date; // 导入 Date 类
import com.yeqifu.bus.entity.Outport;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
/**
* @Author: -
* @Date: 2019/12/18 10:29
*
* (VO) Outport
*
*/
@Data // 自动生成 getter、setter、toString 等常用方法
@EqualsAndHashCode(callSuper = false) // 生成 equals 和 hashCode 方法,且不考虑其父类的属性
public class OutportVo extends Outport { // 继承 Outport 实体类
@Data
@EqualsAndHashCode(callSuper = false)
public class OutportVo extends Outport {
/**
* 1
*/
private Integer page = 1;
/**
* 10
*/
private Integer limit = 10;
/**
*
* 使 @DateTimeFormat Date
*/
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date startTime;
/**
*
* 使 @DateTimeFormat Date
*/
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date endTime;
}
// OutportVo类它是一个Java类通过继承自Outport类来拓展功能主要用于在业务场景中承载更多与出货相关的数据展示及查询等操作所需的额外信息
// 常作为一种数据传输对象DTOData Transfer Object在前端与后端之间传递数据例如接收前端传来的分页、时间范围筛选等请求参数以便后端能依据这些参数进行相应的业务处理及数据库查询操作。
// 使用了@Data注解该注解通常来自于Lombok库前提是项目中引入了Lombok它的作用是自动帮我们生成一系列常规的方法像Getter获取属性值的方法、Setter设置属性值的方法
// toString将对象转换为便于查看的字符串表示形式的方法、equals用于比较两个对象是否相等的方法以及hashCode生成对象哈希码的方法
// 这样能减少大量手动编写这些重复代码的工作量让代码更加简洁直观同时也符合Java Bean的规范要求方便在程序中对类对象的属性进行操作和使用。
// @EqualsAndHashCode(callSuper = false)注解同样是由Lombok库提供它用于重写equals和hashCode方法
// 这里将callSuper设置为false表示在生成这两个方法时不会去调用父类Outport类的equals和hashCode方法逻辑而是仅仅依据当前类OutportVo类自身的属性来构建相应的比较和哈希码生成逻辑
// 这种方式在特定业务场景下是很有必要的,比如当我们只关心当前类新增或者重写的这些属性来判断对象是否相等或者生成哈希码时,就可以这样设置。
// page属性其类型为整数用于记录当前请求所对应的页码信息初始值被设定为1。在涉及出货数据分页展示和查询的业务场景中
// 前端界面通常会向后端发送想要查看的页码数而后端就依据这个page值以及每页显示的记录数量由limit属性确定从数据库中准确地获取相应的数据并返回给前端
// 例如当page为3且limit为10时后端就会查询并返回第3页的10条出货记录以此实现数据的分页管理避免一次性加载过多数据导致页面加载缓慢等问题提升用户体验。
// limit属性同样为整数类型它用于指定每页应该显示的出货记录数量初始赋值为10。这个属性和page属性协同工作共同确定了每次分页查询时从数据库中提取的数据范围
// 根据实际业务需求以及系统性能方面的考虑可以对这个limit值进行灵活调整比如如果出货数据量较少为了减少用户翻页操作可以适当增大limit值
// 若担心数据量过大影响页面加载速度则可以适当减小limit值使其更符合业务实际情况和用户体验要求。
// startTime属性类型为Date用于接收前端传递过来的表示时间范围起始时间的日期信息。通过添加@DateTimeFormat(pattern = "yyyy-MM-dd")注解,
// 明确了前端传递的日期字符串需要遵循“yyyy-MM-dd”这种常见的年-月-日格式后端在接收到这样格式的字符串后会将其正确解析并转换为Date类型进行存储和后续使用
// 在查询出货数据时该属性发挥着重要作用它可以用来筛选出起始时间之后的出货记录例如想要查询从某一特定日期开始的出货情况时就可以通过设置这个startTime属性来实现时间范围的筛选
// 方便进行基于时间维度的数据统计分析以及业务查询操作。
// endTime属性与startTime属性类似也是用来接收日期信息的类型同样为Date同样应用了@DateTimeFormat(pattern = "yyyy-MM-dd")注解来规范日期字符串的格式,
// 它的作用是指定时间范围的结束时间在进行出货数据查询时与startTime属性配合使用就能获取到处于这个时间区间内包含起始时间和结束时间对应的当天的所有出货记录
// 例如,若要查询某个月内的出货情况,只需分别设置好对应的起始和结束日期,就能精准地筛选出符合要求的出货数据,为业务分析、报表生成等操作提供准确的数据基础。

@ -1,37 +1,55 @@
package com.yeqifu.bus.vo; // 定义视图层包路径
package com.yeqifu.bus.vo;
import com.yeqifu.bus.entity.Customer; // 导入 Customer 实体类
import com.yeqifu.bus.entity.Provider; // 导入 Provider 实体类
import lombok.Data; // 导入 Lombok 提供的 @Data 注解
import lombok.EqualsAndHashCode; // 导入 Lombok 提供的 @EqualsAndHashCode 注解
import com.yeqifu.bus.entity.Customer;
import com.yeqifu.bus.entity.Provider;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* @Author: -
* @Date: 2019/12/5 9:30
*
* (VO) Provider
*
*/
@Data // 自动生成 getter、setter、toString 等常用方法
@EqualsAndHashCode(callSuper = false) // 生成 equals 和 hashCode 方法,且不考虑其父类的属性
public class ProviderVo extends Provider { // 继承 Provider 实体类
@Data
@EqualsAndHashCode(callSuper = false)
public class ProviderVo extends Provider{
/**
* -
* 1
* 10
*/
private Integer page = 1;
private Integer page=1;
private Integer limit=10;
/**
* -
* 10 10
* ID
*/
private Integer limit = 10;
private Integer[] ids;
}
// ProviderVo类它是一个Java类通过继承Provider类来扩展其功能在供应商相关的业务场景中通常用于承载更多特定业务操作所需要的额外信息
// 常作为数据传输对象DTOData Transfer Object在不同的业务层比如前端与后端之间传递数据便于根据业务需求进行相应的处理和操作。
// 使用了@Data注解该注解一般来自Lombok库假设项目中引入了Lombok它会自动为类生成一些常用的方法像获取属性值的Getter方法、设置属性值的Setter方法、
// 用于将对象转换为方便查看的字符串表示形式的toString方法、用于比较两个对象是否相等的equals方法以及生成对象哈希码的hashCode方法等
// 这样能减少手动编写这些重复代码的工作量使代码更加简洁明了同时也遵循了Java Bean的规范方便对类对象的属性进行操作和访问。
// @EqualsAndHashCode(callSuper = false)注解同样来自Lombok库用于重写equals和hashCode方法
// 这里设置callSuper为false表示在生成这两个方法时不会调用父类Provider类的equals和hashCode方法逻辑而是仅仅依据当前类ProviderVo类自身的属性来构建相应的判断对象相等和生成哈希码的逻辑
// 符合在一些业务场景下,只关注当前类新增或修改的属性来进行对象比较等操作的需求。
/**
* ID
* IDID
* 10
* 便
* page1
* limit1010
* pagelimitpage2limit10210
*/
private Integer[] ids;
}
/**
* ID
* idsID
* ID
* ID
*/

@ -1,46 +1,64 @@
package com.yeqifu.bus.vo; // 定义视图层的包路径
package com.yeqifu.bus.vo;
import com.yeqifu.bus.entity.Sales; // 导入 Sales 实体类
import lombok.Data; // 导入 Lombok 提供的 @Data 注解
import lombok.EqualsAndHashCode; // 导入 Lombok 提供的 @EqualsAndHashCode 注解
import org.springframework.format.annotation.DateTimeFormat; // 导入日期格式注解
import java.util.Date; // 导入 Date 类
import com.yeqifu.bus.entity.Sales;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
/**
* @Author: -
* @Date: 2019/12/18 10:29
*
* (VO) Sales
*
*/
@Data // 自动生成 getter、setter、toString 等常用方法
@EqualsAndHashCode(callSuper = false) // 生成 equals 和 hashCode 方法,且不考虑其父类的属性
public class SalesVo extends Sales { // 继承 Sales 实体类
/**
* -
* 1
*/
@Data
@EqualsAndHashCode(callSuper = false)
public class SalesVo extends Sales {
private Integer page = 1;
/**
* -
* 10 10
*/
private Integer limit = 10;
/**
*
*
*/
@DateTimeFormat(pattern = "yyyy-MM-dd") // 格式化日期为 yyyy-MM-dd 格式
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date startTime;
/**
*
*
*/
@DateTimeFormat(pattern = "yyyy-MM-dd") // 格式化日期为 yyyy-MM-dd 格式
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date endTime;
}
// SalesVo类它是一个Java类通过继承Sales类来进行功能扩展在销售业务相关的应用场景中常作为一种数据传输对象DTOData Transfer Object使用
// 用于在不同的业务层级(比如前端与后端之间)传递与销售业务相关的数据,同时承载了一些额外的、便于进行数据查询和展示等操作所需的信息。
// 使用了@Data注解该注解通常由Lombok库前提是项目中引入了Lombok提供支持其作用是自动为类生成多个常用的方法包含用于获取属性值的Getter方法、
// 设置属性值的Setter方法、将对象转换为易读字符串表示形式的toString方法、用于判断两个对象是否相等的equals方法以及生成对象哈希码的hashCode方法等。
// 借助@Data注解能够有效减少手动编写这些重复代码的工作量让代码结构更加简洁紧凑并且遵循Java Bean的规范方便后续在业务逻辑中对类对象的属性进行操作和处理。
// @EqualsAndHashCode(callSuper = false)注解同样来自Lombok库它主要用于重写equals和hashCode方法。在这里将callSuper设置为false表示在生成这两个方法时
// 不会去调用父类Sales类的equals和hashCode方法逻辑而是仅仅依据当前类SalesVo类自身的属性来构建相应的对象相等性判断以及哈希码生成的逻辑
// 这符合在一些特定业务场景下,更关注当前类自身新增或修改的属性对对象比较和哈希码影响的需求。
// page属性其类型为整数用于存储当前请求对应的页码信息在销售数据分页展示和查询的业务场景中有着重要作用。
// 它的初始值设定为1表示默认情况下当没有明确指定页码时代表请求查看的是第一页的数据。例如在前端展示销售记录列表时
// 如果用户未进行页码切换操作或者首次访问页面后端就会依据这个默认的page值以及每页显示的记录数量由limit属性决定从数据库中获取相应的数据返回给前端
// 通过这种分页机制,能够避免一次性加载大量销售记录导致页面加载缓慢的问题,提升用户查看数据的体验,方便用户按页浏览销售信息。
// limit属性也是整数类型用于指定每页显示的销售记录数量初始赋值为10。它与page属性协同工作共同确定每次分页查询时从数据库中获取的数据范围
// 根据实际业务需求以及系统性能状况等因素可以对limit的值进行灵活调整比如在销售数据量较少时为减少用户翻页操作可适当增大limit值
// 若数据量较大为保证页面加载速度可适当减小limit值使分页展示更贴合实际业务情况满足不同场景下的数据查看需求。
// startTime属性类型为Date主要用于接收前端传递过来的、表示时间范围起始时间的日期信息。通过添加@DateTimeFormat(pattern = "yyyy-MM-dd")注解,
// 明确了前端传递的日期字符串需要遵循“yyyy-MM-dd”这种常见的年-月-日格式后端接收到符合此格式的字符串后会将其准确地解析并转换为Date类型进行存储和后续使用
// 在查询销售数据时startTime属性可用于筛选出起始时间之后的销售记录例如若想查询从某个特定日期开始的销售情况通过设置相应的startTime值就能实现按时间范围筛选数据
// 便于进行基于时间维度的销售数据统计分析、业务查询以及生成相关报表等操作,为企业了解销售趋势、评估业务绩效等提供有力的数据依据。
// endTime属性与startTime属性类似同样是用于接收日期信息的属性类型为Date并且也添加了@DateTimeFormat(pattern = "yyyy-MM-dd")注解来规范日期字符串格式,
// 它的作用是指定时间范围的结束时间在查询销售数据时与startTime属性配合使用能够获取到处于该时间区间内包含起始时间和结束时间对应的当天的所有销售记录
// 比如,若要查询某个月内的销售情况,只需分别设置好对应的起始和结束日期,后端就能精准地筛选出该时间段内的销售数据,方便对特定时间段内的销售业务进行深入分析和总结。

@ -1,46 +1,68 @@
package com.yeqifu.bus.vo; // 定义视图层的包路径
package com.yeqifu.bus.vo;
import com.yeqifu.bus.entity.Salesback; // 导入 Salesback 实体类
import lombok.Data; // 导入 Lombok 提供的 @Data 注解
import lombok.EqualsAndHashCode; // 导入 Lombok 提供的 @EqualsAndHashCode 注解
import org.springframework.format.annotation.DateTimeFormat; // 导入日期格式注解
import java.util.Date; // 导入 Date 类
import com.yeqifu.bus.entity.Salesback;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
/**
* @Author: -
* @Date: 2019/12/18 10:29
*
* (VO) Salesback
*
*/
@Data // 自动生成 getter、setter、toString 等常用方法
@EqualsAndHashCode(callSuper = false) // 生成 equals 和 hashCode 方法,且不考虑其父类的属性
public class SalesbackVo extends Salesback { // 继承 Salesback 实体类
/**
* -
* 1
*/
@Data
@EqualsAndHashCode(callSuper = false)
public class SalesbackVo extends Salesback {
private Integer page = 1;
/**
* -
* 10 10
*/
private Integer limit = 10;
/**
*
* 退
*/
@DateTimeFormat(pattern = "yyyy-MM-dd") // 格式化日期为 yyyy-MM-dd 格式
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date startTime;
/**
*
* 退
*/
@DateTimeFormat(pattern = "yyyy-MM-dd") // 格式化日期为 yyyy-MM-dd 格式
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date endTime;
}
// SalesbackVo类它是一个Java类通过继承Salesback类实现功能的拓展主要用于在销售退货相关的业务场景中承载更多满足特定业务操作和数据展示需求的额外信息
// 通常扮演数据传输对象DTOData Transfer Object的角色负责在系统的不同层级比如前端与后端之间传递数据便于后端依据接收到的信息进行相应的业务逻辑处理以及与数据库的交互操作。
// 使用了@Data注解这个注解一般是借助Lombok库前提是项目中引入了Lombok工具来发挥作用的。它能够自动为类生成一系列常规的方法涵盖了Getter用于获取类中各个属性值的方法
// Setter用来设置属性值的方法、toString将对象转换为便于查看和理解的字符串表示形式的方法、equals用于比较两个对象是否相等的方法以及hashCode生成对象哈希码的方法等。
// 通过使用@Data注解能极大地减少手动编写这些重复代码的工作量让代码结构更加简洁清晰同时也遵循了Java Bean的规范要求方便在整个项目中对类对象的属性进行便捷的操作与访问。
// @EqualsAndHashCode(callSuper = false)注解同样来源于Lombok库它主要用于重写equals和hashCode这两个方法。
// 此处将callSuper设置为false表示在生成equals和hashCode方法的逻辑时不会去调用父类Salesback类对应的方法逻辑而是仅仅依据当前类SalesbackVo类自身所定义的属性来构建判断对象相等以及生成哈希码的逻辑
// 这在一些特定的业务场景下是很有必要的,例如当我们重点关注的是当前类新添加或者重定义的这些属性对对象相等性及哈希码的影响时,这样的设置就能满足相应需求。
// page属性其类型为整数主要用于表示当前请求所对应的页码信息在销售退货数据分页展示以及查询的业务场景中起着关键作用。
// 它的初始值被设定为1意味着在默认情况下当没有特别指定页码时系统会将其视作请求查看第一页的数据。例如在前端页面展示销售退货记录时
// 如果用户没有手动切换页码或者首次访问相关页面后端就会根据这个默认的page值也就是1以及每页显示的记录数量由limit属性确定从数据库中获取相应的数据返回给前端进行展示
// 以此实现数据的分页管理,避免一次性加载过多的销售退货记录导致页面加载缓慢、用户体验不佳等问题,使得用户能够更方便、高效地查看数据。
// limit属性同样是整数类型它用于明确指定每页应当显示的销售退货记录的数量初始赋值为10。在分页查询销售退货数据的过程中
// limit属性和page属性相互配合共同确定了每次从数据库中提取数据的范围。可以根据实际业务的具体情况以及系统性能方面的考量对这个limit值进行灵活的调整
// 比如如果销售退货记录的数据量相对较少为了减少用户翻页操作的频率提升查看效率可以适当增大limit的值相反如果数据量较大担心页面加载速度受到影响
// 则可以适当减小limit的值确保系统在不同的数据量情况下都能提供较好的用户体验满足业务操作和数据展示的实际需求。
// startTime属性类型为Date其核心作用是接收前端传递过来的、表示时间范围起始时间的日期信息。通过添加@DateTimeFormat(pattern = "yyyy-MM-dd")注解,
// 明确规定了前端传递的日期字符串必须遵循“yyyy-MM-dd”这种常见的、标准化的年-月-日格式后端在接收到符合该格式的字符串后能够准确地将其解析并转换为Date类型进行存储与后续的业务处理
// 在针对销售退货数据进行查询操作时startTime属性能够帮助筛选出起始时间之后所发生的销售退货记录例如当需要查询从某个特定日期开始的销售退货情况时
// 就可以通过设置相应的startTime值来精准地筛选出符合时间范围要求的记录从而方便进行基于时间维度的数据统计分析、业务查询以及报表生成等操作为相关业务决策提供有力的数据支持。
// endTime属性与startTime属性类似同样是用于接收日期信息的属性其类型也为Date并且同样应用了@DateTimeFormat(pattern = "yyyy-MM-dd")注解来规范前端传递日期字符串的格式,
// 它的主要用途是指定时间范围的结束时间。在查询销售退货数据时endTime属性与startTime属性协同配合二者共同确定了一个完整的时间区间后端可以依据这个时间区间
// 获取到处于该区间内(包含起始时间和结束时间所对应的当天)的所有销售退货记录,例如,若要查询某个月内的销售退货情况,只需在前端按照要求分别设置好对应的起始和结束日期,
// 后端就能准确地筛选出该月内的所有销售退货数据,为进一步深入分析销售退货趋势、原因等业务操作提供准确、详细的数据基础,助力企业更好地管理销售退货业务。

@ -14,12 +14,6 @@ import org.springframework.stereotype.Component;
import java.util.Map;
/**
*
*
*
*
* 使AOP
*
* @Author: -
* @Date: 2019/11/27 18:42
*/
@ -29,89 +23,189 @@ import java.util.Map;
public class CacheAspect {
/**
* 便
*
*/
private Log log = LogFactory.getLog(CacheAspect.class);
/**
* Map
*
*/
private Map<String, Object> CACHE_CONTAINER = CachePool.CACHE_CONTAINER;
private Map<String,Object> CACHE_CONTAINER = CachePool.CACHE_CONTAINER;
/**
*
*
*/
private static final String POINTCUT_DEPT_ADD = "execution(* com.yeqifu.sys.service.impl.DeptServiceImpl.save(..))"; // 添加部门
private static final String POINTCUT_DEPT_UPDATE = "execution(* com.yeqifu.sys.service.impl.DeptServiceImpl.updateById(..))"; // 更新部门
private static final String POINTCUT_DEPT_GET = "execution(* com.yeqifu.sys.service.impl.DeptServiceImpl.getById(..))"; // 查询部门
private static final String POINTCUT_DEPT_DELETE = "execution(* com.yeqifu.sys.service.impl.DeptServiceImpl.removeById(..))"; // 删除部门
private static final String POINTCUT_DEPT_ADD="execution(* com.yeqifu.sys.service.impl.DeptServiceImpl.save(..))";
private static final String POINTCUT_DEPT_UPDATE="execution(* com.yeqifu.sys.service.impl.DeptServiceImpl.updateById(..))";
private static final String POINTCUT_DEPT_GET="execution(* com.yeqifu.sys.service.impl.DeptServiceImpl.getById(..))";
private static final String POINTCUT_DEPT_DELETE="execution(* com.yeqifu.sys.service.impl.DeptServiceImpl.removeById(..))";
/**
*
*/
private static final String CACHE_DEPT_PROFIX = "dept:";
private static final String CACHE_DEPT_PROFIX="dept:";
/**
*
*
* @param joinPoint
* @return
* @param joinPoint
* @return
*/
@Around(value = POINTCUT_DEPT_ADD)
public Object cacheDeptAdd(ProceedingJoinPoint joinPoint) throws Throwable {
// 取出第一个参数
//取出第一个参数
Dept object = (Dept) joinPoint.getArgs()[0];
Boolean res = (Boolean) joinPoint.proceed(); // 执行原实现
if (res) {
CACHE_CONTAINER.put(CACHE_DEPT_PROFIX + object.getId(), object);
Boolean res = (Boolean) joinPoint.proceed();
if (res){
CACHE_CONTAINER.put(CACHE_DEPT_PROFIX + object.getId(),object);
}
return res;
}
/**
*
*
* @param joinPoint
* @return
* @param joinPoint
* @return
*/
@Around(value = POINTCUT_DEPT_GET)
public Object cacheDeptGet(ProceedingJoinPoint joinPoint) throws Throwable {
Integer object = (Integer) joinPoint.getArgs()[0]; // 取出第一个参数作为ID
//取出第一个参数
Integer object = (Integer) joinPoint.getArgs()[0];
//从缓存里面取
Object res1 = CACHE_CONTAINER.get(CACHE_DEPT_PROFIX + object);
if (res1 != null) {
log.info("已从缓存里面找到部门对象" + CACHE_DEPT_PROFIX + object);
return res1; // 直接返回缓存中的对象
} else {
log.info("\u672a\u4ece\u7f13\u5b58\u91CC\u627E\u5230\u90E8\u95E8\u5BF9\u8C61\uFF0C\u4ECE\u6570\u636E\u5E93\u4E2D\u67E5\u8BE2\u5E76\u653E\u5165\u7F13\u5B58");
Dept res2 = (Dept) joinPoint.proceed(); // 执行原实现
CACHE_CONTAINER.put(CACHE_DEPT_PROFIX + res2.getId(), res2);
if (res1!=null){
log.info("已从缓存里面找到部门对象"+CACHE_DEPT_PROFIX + object);
return res1;
}else {
log.info("未从缓存里面找到部门对象,从数据库中查询并放入缓存");
Dept res2 =(Dept) joinPoint.proceed();
CACHE_CONTAINER.put(CACHE_DEPT_PROFIX+res2.getId(),res2);
return res2;
}
}
/**
*
*
* @param joinPoint
* @return
* @param joinPoint
* @return
*/
@Around(value = POINTCUT_DEPT_UPDATE)
public Object cacheDeptUpdate(ProceedingJoinPoint joinPoint) throws Throwable {
//取出第一个参数
Dept deptVo = (Dept) joinPoint.getArgs()[0];
Boolean isSuccess = (Boolean) joinPoint.proceed();
if (isSuccess) {
Dept dept = (Dept) CACHE_CONTAINER.get(CACHE_DEPT_PROFIX + deptVo.getId());
if (null == dept) {
dept = new Dept();
if (isSuccess){
Dept dept =(Dept) CACHE_CONTAINER.get(CACHE_DEPT_PROFIX + deptVo.getId());
if (null==dept){
dept=new Dept();
}
BeanUtils.copyProperties(deptVo, dept);
log.info("\u90E8\u95E8\u5BF9\u8C61\u7F13\u5B58\u5DF2\u66F4\u65B0" + CACHE_DEPT_PROFIX + deptVo.getId());
CACHE_CONTAINER.put(CACHE_DEPT_PROFIX + dept.getId(), dept);
BeanUtils.copyProperties(deptVo,dept);
log.info("部门对象缓存已更新"+CACHE_DEPT_PROFIX + deptVo.getId());
CACHE_CONTAINER.put(CACHE_DEPT_PROFIX+dept.getId(),dept);
}
return isSuccess;
}
/**
*
*
* @param joinPoint
/**
*
* @param joinPoint
* @return
*/
@Around(value = POINTCUT_DEPT_DELETE)
public Object cacheDeptDelete(ProceedingJoinPoint joinPoint) throws Throwable {
//取出第一个参数
Integer id = (Integer) joinPoint.getArgs()[0];
Boolean isSuccess = (Boolean) joinPoint.proceed();
if (isSuccess){
//删除缓存
CACHE_CONTAINER.remove(CACHE_DEPT_PROFIX+id);
}
return isSuccess;
}
/**
*
*/
private static final String POINTCUT_USER_UPDATE="execution(* com.yeqifu.sys.service.impl.UserServiceImpl.updateById(..))";
private static final String POINTCUT_USER_ADD="execution(* com.yeqifu.sys.service.impl.UserServiceImpl.updateById(..))";
private static final String POINTCUT_USER_GET="execution(* com.yeqifu.sys.service.impl.UserServiceImpl.getById(..))";
private static final String POINTCUT_USER_DELETE="execution(* com.yeqifu.sys.service.impl.UserServiceImpl.removeById(..))";
private static final String CACHE_USER_PROFIX="user:";
/**
*
* @param joinPoint
* @return
*/
@Around(value = POINTCUT_USER_ADD)
public Object cacheUserAdd(ProceedingJoinPoint joinPoint) throws Throwable {
//取出第一个参数
User object = (User) joinPoint.getArgs()[0];
Boolean res = (Boolean) joinPoint.proceed();
if (res){
CACHE_CONTAINER.put(CACHE_USER_PROFIX + object.getId(),object);
}
return res;
}
/**
*
* @param joinPoint
* @return
*/
@Around(value = POINTCUT_USER_GET)
public Object cacheUserGet(ProceedingJoinPoint joinPoint) throws Throwable {
//取出第一个参数
Integer object = (Integer) joinPoint.getArgs()[0];
//从缓存里面取
Object res1 = CACHE_CONTAINER.get(CACHE_USER_PROFIX + object);
if (res1!=null){
log.info("已从缓存里面找到用户对象"+CACHE_USER_PROFIX + object);
return res1;
}else {
log.info("未从缓存里面找到用户对象,从数据库中查询并放入缓存");
User res2 =(User) joinPoint.proceed();
CACHE_CONTAINER.put(CACHE_USER_PROFIX+res2.getId(),res2);
return res2;
}
}
/**
*
* @param joinPoint
* @return
*/
@Around(value = POINTCUT_USER_UPDATE)
public Object cacheUserUpdate(ProceedingJoinPoint joinPoint) throws Throwable {
//取出第一个参数
User userVo = (User) joinPoint.getArgs()[0];
Boolean isSuccess = (Boolean) joinPoint.proceed();
if (isSuccess){
User user =(User) CACHE_CONTAINER.get(CACHE_USER_PROFIX + userVo.getId());
if (null==user){
user=new User();
}
BeanUtils.copyProperties(userVo,user);
log.info("用户对象缓存已更新"+CACHE_USER_PROFIX + userVo.getId());
CACHE_CONTAINER.put(CACHE_USER_PROFIX+user.getId(),user);
}
return isSuccess;
}
/**
*
* @param joinPoint
* @return
*/
@Around(value = POINTCUT_USER_DELETE)
public Object cacheUserDelete(ProceedingJoinPoint joinPoint) throws Throwable {
//取出第一个参数
Integer id = (Integer) joinPoint.getArgs()[0];
Boolean isSuccess = (Boolean) joinPoint.proceed();
if (isSuccess){
//删除缓存
CACHE_CONTAINER.remove(CACHE_USER_PROFIX+id);
}
return isSuccess;
}
}

@ -17,86 +17,72 @@ import java.util.List;
import java.util.Map;
/**
* CachePool Redis
*
*
*
* @Author: -
* @Date: 2019/12/20 18:05
*/
public class CachePool {
/**
*
* Redis
* CACHE_CONTAINER redis
*/
public static volatile Map<String, Object> CACHE_CONTAINER = new HashMap<>();
public static volatile Map<String,Object> CACHE_CONTAINER = new HashMap<>();
/**
*
*
* @param key
* KEY
* @param key
*/
public static void removeCacheByKey(String key) {
// 判断缓存容器中是否包含指定的键
if (CACHE_CONTAINER.containsKey(key)) {
// 删除指定键的缓存数据
public static void removeCacheByKey(String key){
if (CACHE_CONTAINER.containsKey(key)){
CACHE_CONTAINER.remove(key);
}
}
/**
*
*
*
*/
public static void removeAll() {
// 清空缓存容器
public static void removeAll(){
CACHE_CONTAINER.clear();
}
/**
*
*
*
*/
public static void syncData() {
// 同步部门数据
public static void syncData(){
//同步部门数据
DeptMapper deptMapper = SpringUtil.getBean(DeptMapper.class);
List<Dept> deptList = deptMapper.selectList(null);
for (Dept dept : deptList) {
// 将部门数据存入缓存容器
CACHE_CONTAINER.put("dept:" + dept.getId(), dept);
CACHE_CONTAINER.put("dept:"+dept.getId(),dept);
}
// 同步用户数据
//同步用户数据
UserMapper userMapper = SpringUtil.getBean(UserMapper.class);
List<User> userList = userMapper.selectList(null);
for (User user : userList) {
// 将用户数据存入缓存容器
CACHE_CONTAINER.put("user:" + user.getId(), user);
CACHE_CONTAINER.put("user:"+user.getId(),user);
}
// 同步客户数据
//同步客户数据
CustomerMapper customerMapper = SpringUtil.getBean(CustomerMapper.class);
List<Customer> customerList = customerMapper.selectList(null);
for (Customer customer : customerList) {
// 将客户数据存入缓存容器
CACHE_CONTAINER.put("customer:" + customer.getId(), customer);
CACHE_CONTAINER.put("customer:"+customer.getId(),customer);
}
// 同步供应商数据
//同步供应商数据
ProviderMapper providerMapper = SpringUtil.getBean(ProviderMapper.class);
List<Provider> providerList = providerMapper.selectList(null);
for (Provider provider : providerList) {
// 将供应商数据存入缓存容器
CACHE_CONTAINER.put("provider:" + provider.getId(), provider);
CACHE_CONTAINER.put("provider:"+provider.getId(),provider);
}
// 同步商品数据
//同步商品数据
GoodsMapper goodsMapper = SpringUtil.getBean(GoodsMapper.class);
List<Goods> goodsList = goodsMapper.selectList(null);
for (Goods goods : goodsList) {
// 将商品数据存入缓存容器
CACHE_CONTAINER.put("goods:" + goods.getId(), goods);
CACHE_CONTAINER.put("goods:"+goods.getId(),goods);
}
}
}

@ -13,111 +13,97 @@ import java.io.InputStream;
import java.util.Properties;
/**
* AppFileUtils
*
*
* @Author: -
* @Date: 2019/12/15 23:44
*/
public class AppFileUtils {
/**
* G:/upload/
*
*
*/
public static String UPLOAD_PATH = "G:/upload/";
public static String UPLOAD_PATH="G:/upload/";
// 静态代码块,初始化文件上传路径
static {
// 通过反射的方式,读取配置文件 file.properties 中的存储地址
//通过反射的方式,读取配置文件的存储地址
InputStream stream = AppFileUtils.class.getClassLoader().getResourceAsStream("file.properties");
Properties properties = new Properties();
Properties properties=new Properties();
try {
// 加载配置文件
properties.load(stream);
} catch (IOException e) {
e.printStackTrace();
}
// 获取配置文件中的文件路径,并赋值给 UPLOAD_PATH
String property = properties.getProperty("filepath");
if (property != null) {
UPLOAD_PATH = property;
if(null!=property) {
UPLOAD_PATH=property;
}
}
/**
*
* 32UUID
*
* @param oldName
* @return
*
* @param oldName
* @return 32
*/
public static String createNewFileName(String oldName) {
// 获取文件名后缀(例如 .jpg、.png
String stuff = oldName.substring(oldName.lastIndexOf("."), oldName.length());
// 使用UUID生成新的文件名并与文件后缀拼接
return IdUtil.simpleUUID().toUpperCase() + stuff;
//获取文件名后缀
String stuff=oldName.substring(oldName.lastIndexOf("."), oldName.length());
//将UUID与文件名后缀进行拼接生成新的文件名 生成的UUID为32位
return IdUtil.simpleUUID().toUpperCase()+stuff;
}
/**
*
*
*
* @param path
* @return ResponseEntity
*
* @param path
* @return
*/
public static ResponseEntity<Object> createResponseEntity(String path) {
// 1. 构造文件对象
File file = new File(UPLOAD_PATH, path);
if (file.exists()) {
// 2. 如果文件存在,将文件内容封装为字节数组
byte[] bytes = null;
//1,构造文件对象
File file=new File(UPLOAD_PATH, path);
if(file.exists()) {
//将下载的文件封装byte[]
byte[] bytes=null;
try {
bytes = FileUtil.readBytes(file);
} catch (Exception e) {
e.printStackTrace();
}
// 3. 创建响应头对象,并设置响应内容类型为 APPLICATION_OCTET_STREAM表示二进制流数据
HttpHeaders header = new HttpHeaders();
//创建封装响应头信息的对象
HttpHeaders header=new HttpHeaders();
//封装响应内容类型(APPLICATION_OCTET_STREAM 响应的内容不限定)
header.setContentType(MediaType.APPLICATION_OCTET_STREAM);
// 4. 创建并返回 ResponseEntity 对象,包含文件的字节数组、响应头和 HTTP 状态
ResponseEntity<Object> entity = new ResponseEntity<>(bytes, header, HttpStatus.CREATED);
//创建ResponseEntity对象
ResponseEntity<Object> entity= new ResponseEntity<Object>(bytes, header, HttpStatus.CREATED);
return entity;
}
return null; // 如果文件不存在,返回 null
return null;
}
/**
* "_temp"
*
* @param goodsImg
* @return
* _temp
* @param goodsImg
* @return
*/
public static String renameFile(String goodsImg) {
// 构造文件对象
File file = new File(UPLOAD_PATH, goodsImg);
// 将文件名中的 "_temp" 替换为空
String replace = goodsImg.replace("_temp", "");
// 如果文件存在,执行重命名操作
if (file.exists()) {
file.renameTo(new File(UPLOAD_PATH, replace));
File file = new File(UPLOAD_PATH,goodsImg);
String replace = goodsImg.replace("_temp","");
if (file.exists()){
file.renameTo(new File(UPLOAD_PATH,replace));
}
return replace; // 返回重命名后的文件名
return replace;
}
/**
*
*
*
* @param oldPath
*
* @param oldPath
*/
public static void removeFileByPath(String oldPath) {
// 如果旧路径不是默认商品图片的路径,则删除文件
if (!oldPath.equals(Constast.DEFAULT_IMG_GOODS)) {
File file = new File(UPLOAD_PATH, oldPath);
if (file.exists()) {
file.delete(); // 删除文件
//图片的路径不是默认图片的路径
if (!oldPath.equals(Constast.DEFAULT_IMG_GOODS)){
File file = new File(UPLOAD_PATH,oldPath);
if (file.exists()){
file.delete();
}
}
}
}

@ -7,19 +7,29 @@ import com.alibaba.fastjson.JSON;
* @Date: 2019/12/20 18:40
*/
public class CacheBean {
// 成员变量key用于存储缓存数据的唯一标识符也就是“键”。在缓存体系里通过这个键可以精准地定位和获取对应的缓存数据
// 其取值通常依据具体的业务规则和数据特点来确定,比如在缓存用户登录信息时,可能用用户名作为键;缓存商品详情时,以商品编号作为键等,
// 它的类型为String确保了键的简洁性和通用性便于在不同的缓存存储实现如内存缓存、基于Redis等的分布式缓存中进行操作
private String key;
// 成员变量value用来存放实际的缓存数据内容类型为Object这使得它具有很强的通用性能够容纳各种各样的Java对象
// 可以是简单的基础数据类型包装类对象如Integer、String等也可以是复杂的自定义业务实体对象如表示用户信息的User类对象、订单信息的Order类对象
// 甚至是包含多个元素的集合类型如List、Map等从而满足不同业务场景下多样化的缓存数据存储需求。
private Object value;
// 默认构造函数它的主要作用是提供一种创建CacheBean对象的默认方式当使用这个构造函数创建对象时
// 生成的CacheBean实例的key和value属性初始值都为null后续可以通过相应的set方法来为其赋予具体的值
// 这种方式适用于那些需要先创建对象,再根据具体业务逻辑逐步初始化键值的情况,增加了创建对象的灵活性。
public CacheBean() {
}
// 带参数的构造函数通过传入指定的字符串类型的key和任意类型的Object对象value在创建CacheBean对象的同时
// 直接将传入的参数赋值给对象的对应属性完成对键值对的初始化使得创建一个带有特定键值的CacheBean对象更加便捷高效
// 常用于已知要缓存的数据及其对应标识的场景例如明确要缓存某个商品信息就可以直接传入商品ID作为键和商品对象作为值来快速构建CacheBean对象用于缓存。
public CacheBean(String key, Object value) {
this.key = key;
this.value = value;
}
// 外部代码在需要知晓缓存数据的键时(比如在从缓存中查找、删除特定缓存项等操作时),可以调用这个方法获取对应的键信息,
// 该方法遵循Java中常规的属性访问规范保证了对私有属性key的安全访问。
public String getKey() {
return key;
}
@ -27,6 +37,10 @@ public class CacheBean {
public void setKey(String key) {
this.key = key;
}
// 获取值value的访问器方法这个方法在返回缓存数据的值时会先对存储的Object类型的value进行JSON序列化操作假设项目中引入了相应的JSON处理库如FastJSON、Jackson等
// 将其转换为JSON字符串格式后再返回。之所以这样做是因为JSON字符串具有良好的跨平台性、可读性以及便于存储和传输的特点
// 在缓存系统中无论是内存缓存还是分布式缓存将数据转换为JSON字符串形式能够更好地适配不同的存储介质并且后续在获取缓存数据后
// 也可以方便地通过JSON反序列化操作还原成原始的Java对象以便在业务逻辑中进行相应的处理符合缓存数据存储和使用的一般性要求。
public Object getValue() {
return JSON.toJSON(value).toString();
@ -36,3 +50,5 @@ public class CacheBean {
this.value = value;
}
}
// 设置值value的修改器方法用于让外部代码根据业务逻辑变化例如缓存的数据发生更新、重新缓存新的数据等情况来改变当前CacheBean对象中存储的具体缓存数据内容
// 通过调用这个方法,可以确保缓存中的数据始终与实际业务数据保持同步(在缓存有效期内),保证业务操作获取到的缓存数据是最新且准确的

@ -9,7 +9,6 @@ import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombi
/**
*
*
*
* @Author: -
* @Date: 2019/12/3 10:29
@ -17,51 +16,45 @@ import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombi
public class PinyinUtils {
/**
*
*
* @param inputString
* @return "*"
*
*/
public static String getPingYin(String inputString) {
// 设置拼音输出的格式
// 创建一个HanyuPinyinOutputFormat对象用于设置拼音输出的格式它决定了转换后的拼音在大小写、声调、特殊字符处理等方面的呈现形式。
HanyuPinyinOutputFormat format = new HanyuPinyinOutputFormat();
format.setCaseType(HanyuPinyinCaseType.LOWERCASE); // 设置拼音的大小写为小写
format.setToneType(HanyuPinyinToneType.WITHOUT_TONE); // 设置拼音不带音调
format.setVCharType(HanyuPinyinVCharType.WITH_V); // 设置拼音中的v字符使用“v”而非“u”
// 设置拼音输出的大小写格式为小写,即将转换后的拼音字母全部转换为小写形式,符合常见的拼音使用习惯。
format.setCaseType(HanyuPinyinCaseType.LOWERCASE);
// 设置拼音输出的大小写格式为小写,即将转换后的拼音字母全部转换为小写形式,符合常见的拼音使用习惯。
format.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
// 设置拼音输出对于ü这个特殊元音字符的处理方式设置为WITH_V表示将ü输出为“v”例如“绿”的拼音会输出为“lv”。
format.setVCharType(HanyuPinyinVCharType.WITH_V);
String output = "";
// 判断输入字符串是否有效
if (inputString != null && inputString.length() > 0 && !"null".equals(inputString)) {
char[] input = inputString.trim().toCharArray(); // 将输入字符串转换为字符数组
// 将输入的字符串去除首尾空白字符后转换为字符数组,方便逐个字符进行判断和处理,看其是汉字还是非汉字字符。
char[] input = inputString.trim().toCharArray();
try {
// 遍历每个字符,如果是中文字符,则转换为拼音,否则保留原字符
for (int i = 0; i < input.length; i++) {
// 判断字符是否为汉字
if (java.lang.Character.toString(input[i]).matches("[\\u4E00-\\u9FA5]+")) {
// 获取该汉字的拼音
String[] temp = PinyinHelper.toHanyuPinyinStringArray(input[i], format);
output += temp[0]; // 拼接拼音
output += temp[0];
} else {
output += java.lang.Character.toString(input[i]); // 非汉字字符直接拼接
output += java.lang.Character.toString(input[i]);
}
}
} catch (BadHanyuPinyinOutputFormatCombination e) {
e.printStackTrace(); // 处理拼音转换过程中可能发生的异常
e.printStackTrace();
}
} else {
return "*"; // 如果输入无效,返回 "*"
return "*";
}
return output;
// main方法是Java程序的入口点用于测试getPingYin方法的功能。
// 在这里调用了getPingYin方法传入字符串"落亦"作为参数进行测试,并将返回的拼音结果输出到控制台,方便查看转换效果。
}
/**
*
*
* @param args
*/
public static void main(String[] args) {
// 测试拼音转换
String s = getPingYin("落亦");
System.out.println(s); // 输出拼音luo yi
System.out.println(s);
}
}

@ -12,13 +12,22 @@ import lombok.NoArgsConstructor;
@AllArgsConstructor
@NoArgsConstructor
public class ResultObj {
// 假设这段代码位于一个名为例如ResultObj的类中此类用于统一封装操作结果相关的信息方便在整个项目中以标准化的方式返回操作结果给调用者。
// 成员变量code用于存储表示操作结果的状态码通常会依据一定的规则来设定不同的值以代表不同的结果状态
// 例如可以参考常见的HTTP状态码的思路或者项目自定义的一套状态码规范通过这个状态码调用者能快速判断操作是成功还是失败等情况。
private Integer code;
private String msg;
// 以下是一系列静态常量对象的定义它们都是ResultObj类型用于表示不同业务操作的特定结果状态方便在代码中直接引用这些预定义好的结果对象
// 保持整个项目中操作结果返回的一致性和规范性,并且使得代码的可读性更高,一看便知具体代表的是什么操作结果。
// 表示登录操作成功的静态常量对象其状态码使用了Constast类中定义的表示成功的状态码Constast.OK值为200
// 对应的提示信息为"登陆成功",在登录相关业务逻辑执行成功后,可以返回这个对象来告知调用者登录操作顺利完成。
public static final ResultObj LOGIN_SUCCESS=new ResultObj(Constast.OK,"登陆成功");
public static final ResultObj LOGIN_ERROR_PASS=new ResultObj(Constast.ERROR,"用户名或密码错误");
public static final ResultObj LOGIN_ERROR_CODE=new ResultObj(Constast.ERROR,"验证码错误");
// 表示登录操作中因用户名或密码错误导致失败的静态常量对象状态码采用Constast类中定义的表示错误的状态码Constast.ERROR值为 -1
// 提示信息为"用户名或密码错误",当登录验证时发现用户名或密码不匹配的情况,就可以返回这个对象向调用者说明登录失败的原因。
public static final ResultObj ADD_SUCCESS = new ResultObj(Constast.OK,"添加成功");
public static final ResultObj ADD_ERROR = new ResultObj(Constast.ERROR,"添加失败");
@ -44,5 +53,3 @@ public class ResultObj {
}
//测试

@ -6,20 +6,31 @@ import java.util.List;
*
* @Author: -
* @Date: 2019/11/22 16:31
*/
*/// TreeNodeBuilder类其主要作用是用于构建树形结构数据通常适用于处理具有父子层级关系的数据例如菜单结构、组织架构等场景下
// 将扁平化的节点列表转换为具有层级关系的树形结构,方便后续在前端展示或者其他需要按照树形结构处理数据的业务逻辑中使用。
public class TreeNodeBuilder {
// build静态方法是这个类的核心方法用于根据给定的扁平化的TreeNode节点列表以及顶层节点的父IDtopPid构建出树形结构的节点列表。
// 参数treeNodes是一个包含TreeNode类型元素的列表代表了所有需要构建树形结构的原始节点数据这些节点包含了自身的ID、父ID以及子节点列表等信息假设TreeNode类有相应的属性和方法来支持这些操作
// 参数topPid是一个整数类型表示顶层节点的父ID通过这个值可以筛选出树形结构的根节点进而构建整个树形结构。
public static List<TreeNode> build(List<TreeNode> treeNodes, Integer topPid) {
// 创建一个新的ArrayList<TreeNode>对象nodes用于存储最终构建好的树形结构的节点列表初始时它为空后续会不断添加符合树形结构的节点到这个列表中
List<TreeNode> nodes = new ArrayList<TreeNode>();
for (TreeNode n1 : treeNodes) {
for (TreeNode n1 : treeNodes)
{
if (n1.getPid()==topPid){
nodes.add(n1);
}
// 内层循环再次遍历原始节点列表treeNodes中的每一个节点n2这个循环的目的是为已经找到的第一层节点或后续层级的父节点寻找其直接子节点
// 并将子节点添加到对应父节点的子节点列表中通过n1.getChildren().add(n2)操作假设TreeNode类有一个名为getChildren的方法返回子节点列表并且该列表支持添加元素操作
// 以此来构建完整的树形结构,将扁平化的节点之间的父子关系在树形结构中体现出来。
for (TreeNode n2 : treeNodes) {
if (n1.getId()==n2.getPid()){
n1.getChildren().add(n2);
}
}
}
// 返回构建好的树形结构的节点列表nodes这个列表中的节点已经按照父子关系组织好了形成了一个完整的树形结构
// 可以用于后续诸如在前端以树形菜单的形式展示、按照树形结构进行数据查询或权限控制等相关业务操作。
return nodes;
}
}

@ -24,149 +24,144 @@ import javax.servlet.Filter;
import java.util.HashMap;
import java.util.Map;
@Configuration // 标注为配置类Spring 会自动扫描并加载此类的配置
@ConditionalOnWebApplication(type = Type.SERVLET) // 仅在 Servlet Web 应用中启用
@ConditionalOnClass(value = { SecurityManager.class }) // 仅在 SecurityManager 类存在时启用
@ConfigurationProperties(prefix = "shiro") // 绑定配置文件中以 "shiro" 为前缀的属性
@Data // 自动生成 getter 和 setter 方法
/**
* @Author: -
* @Date: 2019/11/21 21:01
*/
@Configuration
@ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnClass(value = { SecurityManager.class })
@ConfigurationProperties(prefix = "shiro")
@Data
public class ShiroAutoConfiguration {
private static final String SHIRO_DIALECT = "shiroDialect"; // Thymeleaf Shiro 标签名常量
private static final String SHIRO_FILTER = "shiroFilter"; // Shiro 过滤器名常量
private static final String SHIRO_DIALECT = "shiroDialect";
private static final String SHIRO_FILTER = "shiroFilter";
/**
* MD5
*
*/
private String hashAlgorithmName = "md5";
/**
*
*
*/
private int hashIterations = Constast.HASHITERATIONS;
/**
* URL
*
*/
private String loginUrl = "/index.html";
/**
* Shiro
* anonUrls - 访
* logOutUrl -
* authcUlrs -
*/
private String[] anonUrls;
private String logOutUrl;
private String[] authcUlrs;
/**
* 1.
* 使 MD5
*
*/
@Bean("credentialsMatcher")
public HashedCredentialsMatcher hashedCredentialsMatcher() {
HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();
credentialsMatcher.setHashAlgorithmName(hashAlgorithmName); // 设置加密算法
credentialsMatcher.setHashIterations(hashIterations); // 设置散列次数
credentialsMatcher.setHashAlgorithmName(hashAlgorithmName);
credentialsMatcher.setHashIterations(hashIterations);
return credentialsMatcher;
}
/**
* 2. Realm
*
* userRealm
*/
@Bean("userRealm")
public UserRealm userRealm(CredentialsMatcher credentialsMatcher) {
UserRealm userRealm = new UserRealm();
userRealm.setCredentialsMatcher(credentialsMatcher); // 注入凭证匹配器
// 注入凭证匹配器
userRealm.setCredentialsMatcher(credentialsMatcher);
return userRealm;
}
/**
* 3. SecurityManager
*
* SecurityManager
*/
@Bean("securityManager")
public SecurityManager securityManager(UserRealm userRealm) {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(userRealm); // 注入自定义 Realm
// 注入userRealm
securityManager.setRealm(userRealm);
return securityManager;
}
/**
* 4. Shiro
* ShiroFilterFactoryBean URL
* shiro
*/
@Bean(SHIRO_FILTER)
public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();
factoryBean.setSecurityManager(securityManager); // 设置安全管理器
factoryBean.setLoginUrl(loginUrl); // 设置未认证时的跳转页面
// 1. 配置过滤器链定义映射
// 设置安全管理器
factoryBean.setSecurityManager(securityManager);
// 设置未登陆的时要跳转的页面
factoryBean.setLoginUrl(loginUrl);
Map<String, String> filterChainDefinitionMap = new HashMap<>();
// 配置匿名访问路径(无需登录)
// 设置放行的路径
if (anonUrls != null && anonUrls.length > 0) {
for (String anon : anonUrls) {
filterChainDefinitionMap.put(anon, "anon");
}
}
// 配置登出路径
if (logOutUrl != null) {
// 设置登出的路径
if (null != logOutUrl) {
filterChainDefinitionMap.put(logOutUrl, "logout");
}
// 配置需要登录认证的路径
// 设置拦截的路径
if (authcUlrs != null && authcUlrs.length > 0) {
for (String authc : authcUlrs) {
filterChainDefinitionMap.put(authc, "authc");
}
}
// 2. 注入自定义过滤器(如果有)
Map<String, Filter> filters = new HashMap<>();
Map<String, Filter> filters=new HashMap<>();
// filters.put("authc", new ShiroLoginFilter());
//配置过滤器
factoryBean.setFilters(filters);
// 3. 设置过滤器链定义映射
factoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return factoryBean;
}
/**
* 5. Shiro
* Spring Boot web.xml
* shiroweb.xml
*
* @return
*/
@Bean
public FilterRegistrationBean<DelegatingFilterProxy> delegatingFilterProxy() {
FilterRegistrationBean<DelegatingFilterProxy> filterRegistrationBean = new FilterRegistrationBean<>();
FilterRegistrationBean<DelegatingFilterProxy> filterRegistrationBean = new FilterRegistrationBean<DelegatingFilterProxy>();
DelegatingFilterProxy proxy = new DelegatingFilterProxy();
proxy.setTargetFilterLifecycle(true); // 由 Spring 管理生命周期
proxy.setTargetBeanName(SHIRO_FILTER); // 关联 Shiro 过滤器
proxy.setTargetFilterLifecycle(true);
proxy.setTargetBeanName(SHIRO_FILTER);
filterRegistrationBean.setFilter(proxy);
return filterRegistrationBean;
}
/* 加入注解的使用,不加入这个注解不生效--开始 */
/**
* 6. Shiro @RequiresRoles @RequiresPermissions
*
* @param securityManager
* @return
*/
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
advisor.setSecurityManager(securityManager); // 注入 SecurityManager
return advisor;
AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
return authorizationAttributeSourceAdvisor;
}
/**
* 7.
*/
@Bean
public DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator() {
DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
advisorAutoProxyCreator.setProxyTargetClass(true); // 使用 CGLIB 代理类
advisorAutoProxyCreator.setProxyTargetClass(true);
return advisorAutoProxyCreator;
}
/* 加入注解的使用,不加入这个注解不生效--结束 */
/**
* 8. Thymeleaf Shiro
* HTML 使 Shiro shiro:hasPermission
* htmlshiro
*
* @return
*/
@Bean(name = SHIRO_DIALECT)
public ShiroDialect shiroDialect() {

@ -16,70 +16,62 @@ import java.util.Map;
import java.util.Set;
/**
*
*
*
*
* @Author: -
* @Date: 2019/12/20 18:36
*/
@Api(description = "缓存管理") // Swagger注解用于描述API功能
@RestController // 标识为Spring MVC的Rest控制器
@RequestMapping("cache") // 定义基础请求路径为 "cache"
@Api(description = "缓存管理")
@RestController
@RequestMapping("cache")
public class CacheController {
/**
*
* 使CachePool
* 使volatile线
*/
private static volatile Map<String,Object> CACHE_CONTAINER = CachePool.CACHE_CONTAINER;
private static volatile Map<String,Object> CACHE_CONTAINER= CachePool.CACHE_CONTAINER;
/**
*
* @return DataGridView
* @return
*/
@ApiOperation(value = "查询所有缓存", notes = "查询所有缓存") // Swagger注解用于描述接口的功能
@RequestMapping(value = "loadAllCache", method = RequestMethod.GET) // 映射GET请求到该方法
public DataGridView loadAllCache() {
List<CacheBean> list = new ArrayList<>(); // 用于存储缓存项的列表
@ApiOperation(value = "查询所有缓存",notes = "查询所有缓存")
@RequestMapping(value = "loadAllCache",method = RequestMethod.GET)
public DataGridView loadAllCache(){
List<CacheBean> list = new ArrayList<>();
// 遍历缓存容器的所有键值对
Set<Map.Entry<String, Object>> entrySet = CACHE_CONTAINER.entrySet();
for (Map.Entry<String, Object> entry : entrySet) {
// 将每个键值对封装为CacheBean对象并添加到列表中
list.add(new CacheBean(entry.getKey(), entry.getValue()));
list.add(new CacheBean(entry.getKey(),entry.getValue()));
}
return new DataGridView(list); // 将列表封装为DataGridView对象返回
return new DataGridView(list);
}
/**
*
* @param key
* @return ResultObj
*
* @param key
* @return
*/
@RequestMapping("deleteCache") // 映射请求路径为 "deleteCache"
public ResultObj deleteCache(String key) {
CachePool.removeCacheByKey(key); // 调用CachePool的方法删除指定缓存
return ResultObj.DELETE_SUCCESS; // 返回删除成功的结果
@RequestMapping("deleteCache")
public ResultObj deleteCache(String key){
CachePool.removeCacheByKey(key);
return ResultObj.DELETE_SUCCESS;
}
/**
*
* @return ResultObj
* @return
*/
@RequestMapping("removeAllCache") // 映射请求路径为 "removeAllCache"
public ResultObj removeAllCache() {
CachePool.removeAll(); // 调用CachePool的方法清空所有缓存
return ResultObj.DELETE_SUCCESS; // 返回清空成功的结果
@RequestMapping("removeAllCache")
public ResultObj removeAllCache(){
CachePool.removeAll();
return ResultObj.DELETE_SUCCESS;
}
/**
*
* @return ResultObj
* @return
*/
@RequestMapping("syncCache") // 映射请求路径为 "syncCache"
public ResultObj syncCache() {
CachePool.syncData(); // 调用CachePool的方法同步缓存
return ResultObj.SYNCCACHE_SUCCESS; // 返回同步成功的结果
@RequestMapping("syncCache")
public ResultObj syncCache(){
CachePool.syncData();
return ResultObj.SYNCCACHE_SUCCESS;
}
}

@ -1,5 +1,6 @@
package com.yeqifu.sys.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@ -17,144 +18,148 @@ import org.springframework.web.bind.annotation.RestController;
import java.util.*;
/**
*
* CRUD
* <p>
* InnoDB free: 9216 kB
* </p>
*
* @Author: -
* @Since: 2019-11-26
* @author luoyi-
* @since 2019-11-26
*/
@RestController // 标识为Spring MVC的Rest控制器
@RequestMapping("/dept") // 定义基础请求路径为 "/dept"
@RestController
@RequestMapping("/dept")
public class DeptController {
@Autowired
private IDeptService deptService; // 自动注入部门服务接口
private IDeptService deptService;
/**
*
* JSON
* @param deptVo
* @return DataGridView
*
* @param deptVo
* @return
*/
@RequestMapping("loadDeptManagerLeftTreeJson")
public DataGridView loadManagerLeftTreeJson(DeptVo deptVo) {
// 查询所有部门数据
public DataGridView loadManagerLeftTreeJson(DeptVo deptVo){
//查询出所有的部门存放进list中
// QueryWrapper<Dept> queryWrapper = new QueryWrapper<>();
// queryWrapper.eq('1');
List<Dept> list = deptService.list();
List<TreeNode> treeNodes = new ArrayList<>();
// 遍历部门数据,将每个部门封装为树形节点
//将部门放入treeNodes中组装成json
for (Dept dept : list) {
Boolean open = dept.getOpen() == 1; // 根据部门状态设置节点是否展开
treeNodes.add(new TreeNode(dept.getId(), dept.getPid(), dept.getName(), open));
Boolean open = dept.getOpen()==1?true:false;
treeNodes.add(new TreeNode(dept.getId(),dept.getPid(),dept.getName(),open));
}
return new DataGridView(treeNodes); // 返回树形节点数据
return new DataGridView(treeNodes);
}
/**
*
* @param deptVo
* @return DataGridView
*
* @param deptVo
* @return
*/
@RequestMapping("loadAllDept")
public DataGridView loadAllDept(DeptVo deptVo) {
IPage<Dept> page = new Page<>(deptVo.getPage(), deptVo.getLimit()); // 创建分页对象
public DataGridView loadAllDept(DeptVo deptVo){
IPage<Dept> page = new Page<>(deptVo.getPage(),deptVo.getLimit());
//进行模糊查询
QueryWrapper<Dept> queryWrapper = new QueryWrapper<>();
// 添加模糊查询条件
queryWrapper.like(StringUtils.isNotBlank(deptVo.getName()), "name", deptVo.getName());
queryWrapper.like(StringUtils.isNotBlank(deptVo.getRemark()), "remark", deptVo.getRemark());
queryWrapper.like(StringUtils.isNotBlank(deptVo.getAddress()), "address", deptVo.getAddress());
queryWrapper.eq(deptVo.getId() != null, "id", deptVo.getId())
.or().eq(deptVo.getId() != null, "pid", deptVo.getId());
queryWrapper.orderByAsc("ordernum"); // 按排序码升序排列
deptService.page(page, queryWrapper); // 执行分页查询
return new DataGridView(page.getTotal(), page.getRecords()); // 返回分页数据
queryWrapper.like(StringUtils.isNotBlank(deptVo.getName()),"name",deptVo.getName());
queryWrapper.like(StringUtils.isNotBlank(deptVo.getRemark()),"remark",deptVo.getRemark());
queryWrapper.like(StringUtils.isNotBlank(deptVo.getAddress()),"address",deptVo.getAddress());
queryWrapper.eq(deptVo.getId()!=null,"id",deptVo.getId()).or().eq(deptVo.getId()!=null,"pid",deptVo.getId());
queryWrapper.orderByAsc("ordernum");
//进行查询
deptService.page(page,queryWrapper);
//返回DataGridView
return new DataGridView(page.getTotal(),page.getRecords());
}
/**
*
* @param deptVo
* @return ResultObj
* @param deptVo
* @return
*/
@RequestMapping("addDept")
public ResultObj addDept(DeptVo deptVo) {
public ResultObj addDept(DeptVo deptVo){
try {
deptVo.setCreatetime(new Date()); // 设置创建时间
deptService.save(deptVo); // 保存部门数据
return ResultObj.ADD_SUCCESS; // 返回成功结果
deptVo.setCreatetime(new Date());
deptService.save(deptVo);
return ResultObj.ADD_SUCCESS;
} catch (Exception e) {
e.printStackTrace();
return ResultObj.ADD_ERROR; // 返回失败结果
return ResultObj.ADD_ERROR;
}
}
/**
* 1
* @return Map
*
* @return
*/
@RequestMapping("loadDeptMaxOrderNum")
public Map<String, Object> loadDeptMaxOrderNum() {
Map<String, Object> map = new HashMap<>();
public Map<String,Object> loadDeptMaxOrderNum(){
Map<String,Object> map = new HashMap<String,Object>();
QueryWrapper<Dept> queryWrapper = new QueryWrapper<>();
queryWrapper.orderByDesc("ordernum"); // 按排序码降序排列
IPage<Dept> page = new Page<>(1, 1); // 只查询一条记录
List<Dept> list = deptService.page(page, queryWrapper).getRecords();
if (list.size() > 0) {
map.put("value", list.get(0).getOrdernum() + 1); // 获取最大排序码+1
} else {
map.put("value", 1); // 如果无记录排序码为1
queryWrapper.orderByDesc("ordernum");
IPage<Dept> page = new Page<>(1,1);
List<Dept> list = deptService.page(page,queryWrapper).getRecords();
if (list.size()>0){
map.put("value",list.get(0).getOrdernum()+1);
}else {
map.put("value",1);
}
return map;
}
/**
*
* @param deptVo
* @return ResultObj
*
* @param deptVo
* @return
*/
@RequestMapping("updateDept")
public ResultObj updateDept(DeptVo deptVo) {
public ResultObj updateDept(DeptVo deptVo){
try {
deptService.updateById(deptVo); // 根据ID更新部门数据
return ResultObj.UPDATE_SUCCESS; // 返回成功结果
deptService.updateById(deptVo);
return ResultObj.UPDATE_SUCCESS;
} catch (Exception e) {
e.printStackTrace();
return ResultObj.UPDATE_ERROR; // 返回失败结果
return ResultObj.UPDATE_ERROR;
}
}
/**
*
* @param deptVo
* @return Map
* @param deptVo
* @return
*/
@RequestMapping("checkDeptHasChildrenNode")
public Map<String, Object> checkDeptHasChildrenNode(DeptVo deptVo) {
Map<String, Object> map = new HashMap<>();
public Map<String,Object> checkDeptHasChildrenNode(DeptVo deptVo){
Map<String,Object> map = new HashMap<String, Object>();
QueryWrapper<Dept> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("pid", deptVo.getId()); // 根据父ID查询
queryWrapper.eq("pid",deptVo.getId());
List<Dept> list = deptService.list(queryWrapper);
map.put("value", !list.isEmpty()); // 如果有子部门返回true否则返回false
if (list.size()>0){
map.put("value",true);
}else {
map.put("value",false);
}
return map;
}
/**
*
* @param deptVo
* @return ResultObj
* @param deptVo
* @return
*/
@RequestMapping("deleteDept")
public ResultObj deleteDept(DeptVo deptVo) {
public ResultObj deleteDept(DeptVo deptVo){
try {
deptService.removeById(deptVo.getId()); // 根据ID删除部门
return ResultObj.DELETE_SUCCESS; // 返回成功结果
deptService.removeById(deptVo.getId());
return ResultObj.DELETE_SUCCESS;
} catch (Exception e) {
e.printStackTrace();
return ResultObj.DELETE_ERROR; // 返回失败结果
return ResultObj.DELETE_ERROR;
}
}
}

@ -14,79 +14,57 @@ import java.util.HashMap;
import java.util.Map;
/**
*
*
*
* @Author: -
* @Date: 2019/12/15 23:46
*/
@RestController // 标识为Spring MVC的Rest控制器
@RequestMapping("file") // 定义基础请求路径为 "/file"
@RestController
@RequestMapping("file")
public class FileController {
/**
*
* @param mf MultipartFile
* @return Map
* @param mf
* @return
*/
@RequestMapping("uploadFile")
public Map<String, Object> uploadFile(MultipartFile mf) {
// 1. 获取原始文件名
public Map<String,Object> uploadFile(MultipartFile mf) {
//1.得到文件名
String oldName = mf.getOriginalFilename();
// 2. 生成新的文件名(避免重复文件名)
String newName = AppFileUtils.createNewFileName(oldName);
// 3. 获取当前日期并格式化为 "yyyy-MM-dd" 字符串
String dirName = DateUtil.format(new Date(), "yyyy-MM-dd");
// 4. 构造保存文件的目录
File dirFile = new File(AppFileUtils.UPLOAD_PATH, dirName);
// 5. 检查目录是否存在,若不存在则创建
if (!dirFile.exists()) {
//2.根据旧的文件名生成新的文件名
String newName=AppFileUtils.createNewFileName(oldName);
//3.得到当前日期的字符串
String dirName= DateUtil.format(new Date(), "yyyy-MM-dd");
//4.构造文件夹
File dirFile=new File(AppFileUtils.UPLOAD_PATH,dirName);
//5.判断当前文件夹是否存在
if(!dirFile.exists()) {
//如果不存在则创建新文件夹
dirFile.mkdirs();
}
// 6. 创建目标文件对象,文件名后加 "_temp" 表示临时文件
File file = new File(dirFile, newName + "_temp");
// 7. 将文件内容写入到目标文件中
//6.构造文件对象
File file=new File(dirFile, newName+"_temp");
//7.把mf里面的图片信息写入file
try {
mf.transferTo(file);
} catch (IllegalStateException | IOException e) {
e.printStackTrace(); // 打印异常信息
e.printStackTrace();
}
// 8. 返回文件的保存路径(供前端调用)
Map<String, Object> map = new HashMap<>();
map.put("path", dirName + "/" + newName + "_temp");
Map<String,Object> map=new HashMap<String, Object>();
map.put("path",dirName+"/"+newName+"_temp");
return map;
}
/**
*
*
*
* @param path
* @return ResponseEntity
*/
@RequestMapping("showImageByPath")
public ResponseEntity<byte[]> showImageByPath(String path) {
// **注意:未完成的功能,以下是解释和可能的逻辑建议**
// 1. 规范路径,防止路径穿越漏洞
// 规范路径,防止路径穿越
Path normalizedPath = Paths.get(AppFileUtils.UPLOAD_PATH, path).normalize();
// 2. 验证路径是否在允许的上传目录内
if (!normalizedPath.startsWith(AppFileUtils.UPLOAD_PATH)) {
// 如果路径越界,则返回403禁止访问状态响应
// 如果路径越界,则返回错误响应
return ResponseEntity.status(HttpStatus.FORBIDDEN).build();
}
// 3. 从路径加载文件(逻辑未完成)
// - 需要检查文件是否存在
// - 需要读取文件的字节内容
// - 使用 `ResponseEntity` 返回字节数据和适当的 Content-Type 头
}
}

@ -24,86 +24,68 @@ import java.io.IOException;
import java.util.Date;
/**
*
*
*
*
* @Author: -
* @Date: 2019/11/21 21:33
*/
@RestController // 表示该类是一个Rest风格的控制器直接返回JSON数据
@RequestMapping("login") // 定义基础请求路径为 "/login"
@RestController
@RequestMapping("login")
public class LoginController {
@Autowired
private ILoginfoService loginfoService; // 自动注入日志服务,用于记录登录日志
private ILoginfoService loginfoService;
/**
*
* @param userVo
* @param code
* @param session
* @return ResultObj
*/
@RequestMapping("login")
public ResultObj login(UserVo userVo, String code, HttpSession session) {
// 从Session中获取之前生成的验证码
String sessionCode = (String) session.getAttribute("code");
// 验证用户输入的验证码是否正确
if (code != null && sessionCode.equals(code)) {
Subject subject = SecurityUtils.getSubject(); // 获取当前用户的Shiro Subject
AuthenticationToken token = new UsernamePasswordToken(userVo.getLoginname(), userVo.getPwd()); // 创建用户认证令牌
public ResultObj login(UserVo userVo,String code,HttpSession session){
//获得存储在session中的验证码
String sessionCode = (String) session.getAttribute("code");
if (code!=null&&sessionCode.equals(code)){
Subject subject = SecurityUtils.getSubject();
AuthenticationToken token = new UsernamePasswordToken(userVo.getLoginname(),userVo.getPwd());
try {
// 执行用户认证登录
//对用户进行认证登陆
subject.login(token);
// 通过认证后获取活动用户信息
//通过subject获取以认证活动的user
ActiverUser activerUser = (ActiverUser) subject.getPrincipal();
// 将用户信息存储到Session中
WebUtils.getSession().setAttribute("user", activerUser.getUser());
// 创建登录日志对象
//将user存储到session中
WebUtils.getSession().setAttribute("user",activerUser.getUser());
//记录登陆日志
Loginfo entity = new Loginfo();
entity.setLoginname(activerUser.getUser().getName() + "-" + activerUser.getUser().getLoginname()); // 登录名称
entity.setLoginip(WebUtils.getRequest().getRemoteAddr()); // 获取用户IP地址
entity.setLogintime(new Date()); // 设置登录时间
loginfoService.save(entity); // 保存登录日志
entity.setLoginname(activerUser.getUser().getName()+"-"+activerUser.getUser().getLoginname());
entity.setLoginip(WebUtils.getRequest().getRemoteAddr());
entity.setLogintime(new Date());
loginfoService.save(entity);
return ResultObj.LOGIN_SUCCESS; // 返回登录成功结果
return ResultObj.LOGIN_SUCCESS;
} catch (AuthenticationException e) {
e.printStackTrace();
return ResultObj.LOGIN_ERROR_PASS; // 用户名或密码错误
return ResultObj.LOGIN_ERROR_PASS;
}
} else {
return ResultObj.LOGIN_ERROR_CODE; // 验证码错误
}else {
return ResultObj.LOGIN_ERROR_CODE;
}
}
/**
*
* Session
*
* @param response Http
* @param session
*
* @param response
* @param session
* @throws IOException
*/
@RequestMapping("getCode")
public void getCode(HttpServletResponse response, HttpSession session) throws IOException {
// 创建图形验证码,指定宽、高、字符数和干扰线数
LineCaptcha lineCaptcha = CaptchaUtil.createLineCaptcha(116, 36, 4, 5);
// 将验证码内容存储到Session中
session.setAttribute("code", lineCaptcha.getCode());
public void getCode(HttpServletResponse response, HttpSession session) throws IOException{
//定义图形验证码的长和宽
LineCaptcha lineCaptcha = CaptchaUtil.createLineCaptcha(116, 36,4,5);
session.setAttribute("code",lineCaptcha.getCode());
try {
// 获取响应输出流,将验证码图片写入响应
ServletOutputStream outputStream = response.getOutputStream();
lineCaptcha.write(outputStream);
outputStream.close(); // 关闭输出流
outputStream.close();
} catch (IOException e) {
e.printStackTrace(); // 捕获并打印IO异常
e.printStackTrace();
}
}
}

@ -1,8 +1,10 @@
package com.yeqifu.sys.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sun.org.apache.regexp.internal.RE;
import com.yeqifu.sys.common.DataGridView;
import com.yeqifu.sys.common.ResultObj;
import com.yeqifu.sys.entity.Loginfo;
@ -11,6 +13,7 @@ import com.yeqifu.sys.vo.LoginfoVo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.io.Serializable;
@ -18,92 +21,76 @@ import java.util.ArrayList;
import java.util.Collection;
/**
*
*
* <p>
* InnoDB free: 9216 kB
* </p>
*
* @Author: luoyi-
* @Since: 2019-11-23
* @author luoyi-
* @since 2019-11-23
*/
@RestController // 标注为Rest风格的控制器方法直接返回JSON格式数据
@RequestMapping("loginfo") // 定义基础请求路径为 "/loginfo"
@RestController
@RequestMapping("loginfo")
public class LoginfoController {
@Autowired
private ILoginfoService loginfoService; // 自动注入日志服务接口,负责日志数据的业务逻辑处理
private ILoginfoService loginfoService;
/**
*
*
*
* @param loginfoVo
* @return
*
* @param loginfoVo
* @return
*/
@RequestMapping("loadAllLoginfo")
public DataGridView loadAllLoginfo(LoginfoVo loginfoVo) {
// 创建分页对象,指定当前页和每页条数
IPage<Loginfo> page = new Page<>(loginfoVo.getPage(), loginfoVo.getLimit());
// 构造查询条件
QueryWrapper<Loginfo> queryWrapper = new QueryWrapper<>();
// 根据登录名进行模糊查询,条件为空时忽略
queryWrapper.like(StringUtils.isNotBlank(loginfoVo.getLoginname()), "loginname", loginfoVo.getLoginname());
// 根据登录IP进行模糊查询条件为空时忽略
queryWrapper.like(StringUtils.isNotBlank(loginfoVo.getLoginip()), "loginip", loginfoVo.getLoginip());
// 筛选登录时间大于等于开始时间
queryWrapper.ge(loginfoVo.getStartTime() != null, "logintime", loginfoVo.getStartTime());
// 筛选登录时间小于等于结束时间
queryWrapper.le(loginfoVo.getEndTime() != null, "logintime", loginfoVo.getEndTime());
// 按登录时间降序排列
public DataGridView loadAllLoginfo(LoginfoVo loginfoVo){
IPage<Loginfo> page = new Page<Loginfo>(loginfoVo.getPage(),loginfoVo.getLimit());
QueryWrapper<Loginfo> queryWrapper = new QueryWrapper<Loginfo>();
//进行模糊查询
queryWrapper.like(StringUtils.isNotBlank(loginfoVo.getLoginname()),"loginname",loginfoVo.getLoginname());
queryWrapper.like(StringUtils.isNotBlank(loginfoVo.getLoginip()),"loginip",loginfoVo.getLoginip());
//数据库中登陆时间要大于用户输入的开始时间且小于用户登陆的结束时间
queryWrapper.ge(loginfoVo.getStartTime()!=null,"logintime",loginfoVo.getStartTime());
queryWrapper.le(loginfoVo.getEndTime()!=null,"logintime",loginfoVo.getEndTime());
//根据登陆时间进行降序排序
queryWrapper.orderByDesc("logintime");
// 分页查询日志数据
loginfoService.page(page, queryWrapper);
// 返回包含总条数和当前页数据的结果
return new DataGridView(page.getTotal(), page.getRecords());
loginfoService.page(page,queryWrapper);
return new DataGridView(page.getTotal(),page.getRecords());
}
/**
*
* ID
*
* @param id
* @return
* @param id
* @return
*/
@RequestMapping("deleteLoginfo")
public ResultObj deleteLoginfo(Integer id) {
public ResultObj deleteLoginfo(Integer id){
try {
// 根据ID删除日志
loginfoService.removeById(id);
return ResultObj.DELETE_SUCCESS; // 返回删除成功的结果
return ResultObj.DELETE_SUCCESS;
} catch (Exception e) {
e.printStackTrace();
return ResultObj.DELETE_ERROR; // 返回删除失败的结果
return ResultObj.DELETE_ERROR;
}
}
/**
*
* ID
*
* @param loginfoVo ID
* @return
*
* @param loginfoVo
* @return
*/
@RequestMapping("batchDeleteLoginfo")
public ResultObj batchDeleteLoginfo(LoginfoVo loginfoVo) {
public ResultObj batchDeleteLoginfo(LoginfoVo loginfoVo){
try {
// 创建集合存储需要删除的日志ID
Collection<Serializable> idList = new ArrayList<>();
// 遍历日志ID数组将其添加到集合中
Collection<Serializable> idList = new ArrayList<Serializable>();
for (Integer id : loginfoVo.getIds()) {
idList.add(id);
}
// 批量删除日志
this.loginfoService.removeByIds(idList);
return ResultObj.DELETE_SUCCESS; // 返回批量删除成功的结果
return ResultObj.DELETE_SUCCESS;
} catch (Exception e) {
e.printStackTrace();
return ResultObj.DELETE_ERROR; // 返回批量删除失败的结果
return ResultObj.DELETE_ERROR;
}
}
}

@ -21,8 +21,6 @@ import org.springframework.web.bind.annotation.RestController;
import java.util.*;
/**
*
*
* @Author: -
* @Date: 2019/11/22 15:35
*/
@ -39,97 +37,119 @@ public class MenuController {
@Autowired
private IRoleService roleService;
/**
*
* @param permissionVo
* @return
*/
@RequestMapping("loadIndexLeftMenuJson")
public DataGridView loadIndexLeftMenuJson(PermissionVo permissionVo) {
// 查询所有菜单
QueryWrapper<Permission> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("type", Constast.TYPE_MENU); // 只查询菜单
queryWrapper.eq("available", Constast.AVAILABLE_TRUE); // 菜单必须可用
// 获取当前用户信息
public DataGridView loadIndexLeftMenuJson(PermissionVo permissionVo){
//查询所有菜单
QueryWrapper<Permission> queryWrapper = new QueryWrapper<Permission>();
//设置查询条件
//查询的必须是菜单不能是crud的权限
queryWrapper.eq("type",Constast.TYPE_MENU);
//菜单必须可用
queryWrapper.eq("available", Constast.AVAILABLE_TRUE);
//获得用户 判断用户的类型
User user = (User) WebUtils.getSession().getAttribute("user");
List<Permission> list;
if (user.getType().equals(Constast.USER_TYPE_SUPER)) {
// 超级管理员查询所有菜单
List<Permission> list = null;
if (user.getType().equals(Constast.USER_TYPE_SUPER)){
//用户类型为超级管理员
list = permissionService.list(queryWrapper);
} else {
// 普通用户根据角色和权限查询菜单
}else {
//用户类型为 普通用户
//根据用户ID+角色+权限去查询
Integer userId = user.getId();
List<Integer> currentUserRoleIds = roleService.queryUserRoleIdsByUid(userId); // 获取用户角色ID
//1.根据用户ID查询角色
List<Integer> currentUserRoleIds = roleService.queryUserRoleIdsByUid(userId);
//2.根据角色ID查询菜单ID和权限ID
//使用set去重
Set<Integer> pids = new HashSet<>();
for (Integer rid : currentUserRoleIds) {
pids.addAll(roleService.queryRolePermissionIdsByRid(rid)); // 根据角色ID查询权限ID
//根据角色ID查询菜单ID和权限ID
List<Integer> permissionIds = roleService.queryRolePermissionIdsByRid(rid);
//将菜单ID和权限ID放入Set中去重
pids.addAll(permissionIds);
}
if (!pids.isEmpty()) {
queryWrapper.in("id", pids); // 根据权限ID查询菜单
//3.根据角色ID查询权限
if (pids.size()>0){
queryWrapper.in("id",pids);
list = permissionService.list(queryWrapper);
} else {
list = new ArrayList<>();
}else {
list=new ArrayList<>();
}
}
// 构造树节点列表
List<TreeNode> treeNodes = new ArrayList<>();
List<TreeNode> treeNodes = new ArrayList<TreeNode>();
for (Permission p : list) {
Boolean spread = p.getOpen().equals(Constast.OPEN_TRUE);
treeNodes.add(new TreeNode(p.getId(), p.getPid(), p.getTitle(), p.getIcon(), p.getHref(), spread));
Integer id =p.getId();
Integer pid = p.getPid();
String title = p.getTitle();
String icon = p.getIcon();
String href = p.getHref();
Boolean spread = p.getOpen().equals(Constast.OPEN_TRUE)?true:false;
treeNodes.add(new TreeNode(id,pid,title,icon,href,spread));
}
// 构造层级菜单树
return new DataGridView(TreeNodeBuilder.build(treeNodes, 1));
//构造层级关系
List<TreeNode> list2 = TreeNodeBuilder.build(treeNodes,1);
return new DataGridView(list2);
}
/************************菜单管理*********************************/
/**
*
*
* @param permissionVo
* @return
* @return
*/
@RequestMapping("loadMenuManagerLeftTreeJson")
public DataGridView loadMenuManagerLeftTreeJson(PermissionVo permissionVo) {
public DataGridView loadMenuManagerLeftTreeJson(PermissionVo permissionVo){
QueryWrapper<Permission> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("type", Constast.TYPE_MENU); // 只查询菜单
List<Permission> list = permissionService.list(queryWrapper); // 查询所有菜单
queryWrapper.eq("type",Constast.TYPE_MENU);
//查询出所有的菜单存放进list中
List<Permission> list = permissionService.list(queryWrapper);
List<TreeNode> treeNodes = new ArrayList<>();
//将菜单放入treeNodes中组装成json
for (Permission menu : list) {
Boolean open = menu.getOpen() == 1; // 判断是否展开
treeNodes.add(new TreeNode(menu.getId(), menu.getPid(), menu.getTitle(), open));
Boolean open = menu.getOpen()==1?true:false;
treeNodes.add(new TreeNode(menu.getId(),menu.getPid(),menu.getTitle(),open));
}
return new DataGridView(treeNodes);
}
/**
*
*
* @param permissionVo
* @return
* @return
*/
@RequestMapping("loadAllMenu")
public DataGridView loadAllMenu(PermissionVo permissionVo) {
IPage<Permission> page = new Page<>(permissionVo.getPage(), permissionVo.getLimit());
public DataGridView loadAllMenu(PermissionVo permissionVo){
IPage<Permission> page = new Page<>(permissionVo.getPage(),permissionVo.getLimit());
//进行模糊查询
QueryWrapper<Permission> queryWrapper = new QueryWrapper<>();
queryWrapper.eq(permissionVo.getId() != null, "id", permissionVo.getId())
.or().eq(permissionVo.getId() != null, "pid", permissionVo.getId());
queryWrapper.eq("type", Constast.TYPE_MENU); // 只查询菜单
queryWrapper.like(StringUtils.isNotBlank(permissionVo.getTitle()), "title", permissionVo.getTitle());
queryWrapper.orderByAsc("ordernum"); // 根据排序码升序排列
permissionService.page(page, queryWrapper); // 分页查询
return new DataGridView(page.getTotal(), page.getRecords());
queryWrapper.eq(permissionVo.getId()!=null,"id",permissionVo.getId()).or().eq(permissionVo.getId()!=null,"pid",permissionVo.getId());
//只能查询菜单
queryWrapper.eq("type",Constast.TYPE_MENU);
queryWrapper.like(StringUtils.isNotBlank(permissionVo.getTitle()),"title",permissionVo.getTitle());
queryWrapper.orderByAsc("ordernum");
//进行查询
permissionService.page(page,queryWrapper);
//返回DataGridView
return new DataGridView(page.getTotal(),page.getRecords());
}
/**
*
* @param permissionVo
* @return
* @return
*/
@RequestMapping("addMenu")
public ResultObj addMenu(PermissionVo permissionVo) {
public ResultObj addMenu(PermissionVo permissionVo){
try {
permissionVo.setType(Constast.TYPE_MENU); // 设置类型为菜单
//设置添加类型为 menu
permissionVo.setType(Constast.TYPE_MENU);
permissionService.save(permissionVo);
return ResultObj.ADD_SUCCESS;
} catch (Exception e) {
@ -139,27 +159,31 @@ public class MenuController {
}
/**
*
* @return
*
* @return
*/
@RequestMapping("loadMenuMaxOrderNum")
public Map<String, Object> loadMenuMaxOrderNum() {
Map<String, Object> map = new HashMap<>();
public Map<String,Object> loadMenuMaxOrderNum(){
Map<String,Object> map = new HashMap<String,Object>();
QueryWrapper<Permission> queryWrapper = new QueryWrapper<>();
queryWrapper.orderByDesc("ordernum");
IPage<Permission> page = new Page<>(1, 1);
List<Permission> list = permissionService.page(page, queryWrapper).getRecords();
map.put("value", list.isEmpty() ? 1 : list.get(0).getOrdernum() + 1);
IPage<Permission> page = new Page<>(1,1);
List<Permission> list = permissionService.page(page,queryWrapper).getRecords();
if (list.size()>0){
map.put("value",list.get(0).getOrdernum()+1);
}else {
map.put("value",1);
}
return map;
}
/**
*
* @param permissionVo
* @return
* @return
*/
@RequestMapping("updateMenu")
public ResultObj updateMenu(PermissionVo permissionVo) {
public ResultObj updateMenu(PermissionVo permissionVo){
try {
permissionService.updateById(permissionVo);
return ResultObj.UPDATE_SUCCESS;
@ -170,26 +194,31 @@ public class MenuController {
}
/**
*
*
* @param permissionVo
* @return
* @return
*/
@RequestMapping("checkMenuHasChildrenNode")
public Map<String, Object> checkMenuHasChildrenNode(PermissionVo permissionVo) {
Map<String, Object> map = new HashMap<>();
public Map<String,Object> checkMenuHasChildrenNode(PermissionVo permissionVo){
Map<String,Object> map = new HashMap<String, Object>();
QueryWrapper<Permission> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("pid", permissionVo.getId()); // 查询是否有子菜单
map.put("value", !permissionService.list(queryWrapper).isEmpty());
queryWrapper.eq("pid",permissionVo.getId());
List<Permission> list = permissionService.list(queryWrapper);
if (list.size()>0){
map.put("value",true);
}else {
map.put("value",false);
}
return map;
}
/**
*
* @param permissionVo
* @return
* @return
*/
@RequestMapping("deleteMenu")
public ResultObj deleteMenu(PermissionVo permissionVo) {
public ResultObj deleteMenu(PermissionVo permissionVo){
try {
permissionService.removeById(permissionVo.getId());
return ResultObj.DELETE_SUCCESS;
@ -198,4 +227,6 @@ public class MenuController {
return ResultObj.DELETE_ERROR;
}
}
}

@ -37,51 +37,48 @@ public class NoticeController {
private INoticeService noticeService;
/**
*
*
*
* @param noticeVo
* @return DataGridView
*
* @param noticeVo
* @return
*/
@RequestMapping("loadAllNotice")
public DataGridView loadAllNotice(NoticeVo noticeVo) {
// 分页和条件查询
IPage<Notice> page = new Page<>(noticeVo.getPage(), noticeVo.getLimit());
QueryWrapper<Notice> queryWrapper = new QueryWrapper<>();
queryWrapper.like(StringUtils.isNotBlank(noticeVo.getTitle()), "title", noticeVo.getTitle());
queryWrapper.like(StringUtils.isNotBlank(noticeVo.getOpername()), "opername", noticeVo.getOpername());
queryWrapper.ge(noticeVo.getStartTime() != null, "createtime", noticeVo.getStartTime());
queryWrapper.le(noticeVo.getEndTime() != null, "createtime", noticeVo.getEndTime());
public DataGridView loadAllNotice(NoticeVo noticeVo){
IPage<Notice> page = new Page<Notice>(noticeVo.getPage(),noticeVo.getLimit());
QueryWrapper<Notice> queryWrapper = new QueryWrapper<Notice>();
//进行模糊查询
queryWrapper.like(StringUtils.isNotBlank(noticeVo.getTitle()),"title",noticeVo.getTitle());
queryWrapper.like(StringUtils.isNotBlank(noticeVo.getOpername()),"opername",noticeVo.getOpername());
//公告创建时间应该大于搜索开始时间小于搜索结束时间
queryWrapper.ge(noticeVo.getStartTime()!=null,"createtime",noticeVo.getStartTime());
queryWrapper.le(noticeVo.getEndTime()!=null,"createtime",noticeVo.getEndTime());
//根据公告创建时间进行排序
queryWrapper.orderByDesc("createtime");
noticeService.page(page, queryWrapper);
return new DataGridView(page.getTotal(), page.getRecords());
noticeService.page(page,queryWrapper);
return new DataGridView(page.getTotal(),page.getRecords());
}
/**
* ID
*
* @param id ID
* @return DataGridView
* ID
* @param id ID
* @return
*/
@RequestMapping("loadNoticeById")
public DataGridView loadNoticeById(Integer id) {
public DataGridView loadNoticeById(Integer id){
Notice notice = noticeService.getById(id);
return new DataGridView(notice);
}
/**
*
*
*
* @param noticeVo
* @return
* @param noticeVo
* @return
*/
@RequestMapping("addNotice")
public ResultObj addNotice(NoticeVo noticeVo) {
public ResultObj addNotice(NoticeVo noticeVo){
try {
noticeVo.setCreatetime(new Date()); // 设置创建时间
noticeVo.setCreatetime(new Date());
User user = (User) WebUtils.getSession().getAttribute("user");
noticeVo.setOpername(user.getName()); // 设置操作人
noticeVo.setOpername(user.getName());
noticeService.save(noticeVo);
return ResultObj.ADD_SUCCESS;
} catch (Exception e) {
@ -92,12 +89,11 @@ public class NoticeController {
/**
*
*
* @param noticeVo
* @return
* @param noticeVo
* @return
*/
@RequestMapping("updateNotice")
public ResultObj updateNotice(NoticeVo noticeVo) {
public ResultObj updateNotice(NoticeVo noticeVo){
try {
noticeService.updateById(noticeVo);
return ResultObj.UPDATE_SUCCESS;
@ -108,13 +104,12 @@ public class NoticeController {
}
/**
*
*
* @param noticeVo ID
* @return
*
* @param noticeVo
* @return
*/
@RequestMapping("deleteNotice")
public ResultObj deleteNotice(NoticeVo noticeVo) {
public ResultObj deleteNotice(NoticeVo noticeVo){
try {
noticeService.removeById(noticeVo);
return ResultObj.DELETE_SUCCESS;
@ -126,22 +121,24 @@ public class NoticeController {
/**
*
*
* @param noticeVo ID
* @return
* @param noticeVo
* @return
*/
@RequestMapping("batchDeleteNotice")
public ResultObj batchDeleteNotice(NoticeVo noticeVo) {
public ResultObj batchDeleteNotice(NoticeVo noticeVo){
try {
Collection<Serializable> idList = new ArrayList<>();
for (Integer id : noticeVo.getIds()) {
idList.add(id); // 将ID加入集合
idList.add(id);
}
noticeService.removeByIds(idList); // 批量删除
noticeService.removeByIds(idList);
return ResultObj.DELETE_SUCCESS;
} catch (Exception e) {
e.printStackTrace();
return ResultObj.DELETE_ERROR;
}
}
}

@ -22,66 +22,74 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
/@RestController
/**
* <p>
* InnoDB free: 9216 kB
* </p>
*
* @author luoyi-
* @since 2019-11-22
*/
@RestController
@RequestMapping("permission")
public class PermissionController {
@Autowired
private IPermissionService permissionService;
/**
*
*
*
* @param permissionVo
* @return DataGridView
*
* @param permissionVo
* @return
*/
@RequestMapping("loadPermissionManagerLeftTreeJson")
public DataGridView loadPermissionManagerLeftTreeJson(PermissionVo permissionVo) {
QueryWrapper<Permission> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("type", Constast.TYPE_MENU); // 查询类型为菜单的权限
List<Permission> list = permissionService.list(queryWrapper); // 查询权限列表
List<TreeNode> treeNodes = new ArrayList<>();
public DataGridView loadPermissionManagerLeftTreeJson(PermissionVo permissionVo){
QueryWrapper<Permission> queryWrapper = new QueryWrapper<Permission>();
queryWrapper.eq("type", Constast.TYPE_MENU);
//查询出所有的权限存放进list中
List<Permission> list = permissionService.list(queryWrapper);
List<TreeNode> treeNodes = new ArrayList<TreeNode>();
//将权限放入treeNodes中组装成json
for (Permission permission : list) {
// 创建树节点,设置是否展开
Boolean open = permission.getOpen() == 1 ? true : false;
treeNodes.add(new TreeNode(permission.getId(), permission.getPid(), permission.getTitle(), open));
Boolean open = permission.getOpen()==1?true:false;
treeNodes.add(new TreeNode(permission.getId(),permission.getPid(),permission.getTitle(),open));
}
return new DataGridView(treeNodes);
}
/**
*
* ID
*
* @param permissionVo
* @return DataGridView
* @param permissionVo
* @return
*/
@RequestMapping("loadAllPermission")
public DataGridView loadAllPermission(PermissionVo permissionVo) {
IPage<Permission> page = new Page<>(permissionVo.getPage(), permissionVo.getLimit());
public DataGridView loadAllPermission(PermissionVo permissionVo){
IPage<Permission> page = new Page<>(permissionVo.getPage(),permissionVo.getLimit());
//进行模糊查询
QueryWrapper<Permission> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("type", Constast.TYPE_PERMISSION); // 仅查询权限类型
queryWrapper.like(StringUtils.isNotBlank(permissionVo.getTitle()), "title", permissionVo.getTitle());
queryWrapper.like(StringUtils.isNotBlank(permissionVo.getPercode()), "percode", permissionVo.getPercode());
queryWrapper.eq(permissionVo.getId() != null, "pid", permissionVo.getId());
queryWrapper.orderByAsc("ordernum"); // 按排序号升序排序
permissionService.page(page, queryWrapper); // 执行分页查询
return new DataGridView(page.getTotal(), page.getRecords());
//只能查询权限
queryWrapper.eq("type",Constast.TYPE_PERMISSION);
queryWrapper.like(StringUtils.isNotBlank(permissionVo.getTitle()),"title",permissionVo.getTitle());
queryWrapper.like(StringUtils.isNotBlank(permissionVo.getPercode()),"percode",permissionVo.getPercode());
queryWrapper.eq(permissionVo.getId()!=null,"pid",permissionVo.getId());
queryWrapper.orderByAsc("ordernum");
//进行查询
permissionService.page(page,queryWrapper);
//返回DataGridView
return new DataGridView(page.getTotal(),page.getRecords());
}
/**
*
*
*
* @param permissionVo
* @return
* @param permissionVo
* @return
*/
@RequestMapping("addPermission")
public ResultObj addPermission(PermissionVo permissionVo) {
public ResultObj addPermission(PermissionVo permissionVo){
try {
permissionVo.setType(Constast.TYPE_PERMISSION); // 设置类型为权限
permissionService.save(permissionVo); // 保存权限
//设置添加类型为 permission
permissionVo.setType(Constast.TYPE_PERMISSION);
permissionService.save(permissionVo);
return ResultObj.ADD_SUCCESS;
} catch (Exception e) {
e.printStackTrace();
@ -90,37 +98,33 @@ public class PermissionController {
}
/**
*
* +1
*
* @return Map
*
* @return
*/
@RequestMapping("loadPermissionMaxOrderNum")
public Map<String, Object> loadPermissionMaxOrderNum() {
Map<String, Object> map = new HashMap<>();
public Map<String,Object> loadPermissionMaxOrderNum(){
Map<String,Object> map = new HashMap<String,Object>();
QueryWrapper<Permission> queryWrapper = new QueryWrapper<>();
queryWrapper.orderByDesc("ordernum"); // 按排序号降序查询
IPage<Permission> page = new Page<>(1, 1); // 查询第一页的第一条记录
List<Permission> list = permissionService.page(page, queryWrapper).getRecords();
if (list.size() > 0) {
map.put("value", list.get(0).getOrdernum() + 1); // 最大排序号+1
} else {
map.put("value", 1); // 如果没有记录设置排序号为1
queryWrapper.orderByDesc("ordernum");
IPage<Permission> page = new Page<>(1,1);
List<Permission> list = permissionService.page(page,queryWrapper).getRecords();
if (list.size()>0){
map.put("value",list.get(0).getOrdernum()+1);
}else {
map.put("value",1);
}
return map;
}
/**
*
* ID
*
* @param permissionVo
* @return
* @param permissionVo
* @return
*/
@RequestMapping("updatePermission")
public ResultObj updatePermission(PermissionVo permissionVo) {
public ResultObj updatePermission(PermissionVo permissionVo){
try {
permissionService.updateById(permissionVo); // 根据ID更新权限
permissionService.updateById(permissionVo);
return ResultObj.UPDATE_SUCCESS;
} catch (Exception e) {
e.printStackTrace();
@ -129,37 +133,40 @@ public class PermissionController {
}
/**
*
* IDtruefalse
*
* @param permissionVo ID
* @return Map
*
* @param permissionVo
* @return
*/
@RequestMapping("checkPermissionHasChildrenNode")
public Map<String, Object> checkPermissionHasChildrenNode(PermissionVo permissionVo) {
Map<String, Object> map = new HashMap<>();
public Map<String,Object> checkPermissionHasChildrenNode(PermissionVo permissionVo){
Map<String,Object> map = new HashMap<String, Object>();
QueryWrapper<Permission> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("pid", permissionVo.getId()); // 根据父ID查询
queryWrapper.eq("pid",permissionVo.getId());
List<Permission> list = permissionService.list(queryWrapper);
map.put("value", !list.isEmpty()); // 如果有子权限返回true否则返回false
if (list.size()>0){
map.put("value",true);
}else {
map.put("value",false);
}
return map;
}
/**
*
* ID
*
* @param permissionVo ID
* @return
* @param permissionVo
* @return
*/
@RequestMapping("deletePermission")
public ResultObj deletePermission(PermissionVo permissionVo) {
public ResultObj deletePermission(PermissionVo permissionVo){
try {
permissionService.removeById(permissionVo.getId()); // 根据ID删除权限
permissionService.removeById(permissionVo.getId());
return ResultObj.DELETE_SUCCESS;
} catch (Exception e) {
e.printStackTrace();
return ResultObj.DELETE_ERROR;
}
}
}

@ -18,30 +18,49 @@ import java.io.Serializable;
* @author luoyi-
* @since 2019-11-26
*/
// DeptServiceImpl类它是一个服务层Service Layer的实现类主要负责处理与部门Dept相关的业务逻辑操作
// 并与数据持久化层进行交互,实现对部门数据的增删改查等功能。
// 使用@Service注解将这个类标记为Spring框架中的一个服务组件意味着Spring容器会对其进行管理自动创建实例并处理依赖注入等相关操作方便在其他组件中进行调用。
// 同时添加了@Transactional注解用于开启事务管理功能保证在这个类中执行的多个数据库操作如涉及到多个增删改操作的业务方法要么全部成功提交要么全部失败回滚
// 以此确保数据的一致性和完整性,常用于处理复杂的业务逻辑场景中涉及到多个数据持久化操作的情况。
@Service
@Transactional
public class DeptServiceImpl extends ServiceImpl<DeptMapper, Dept> implements IDeptService {
// 重写了IDeptService接口假设存在该接口用于定义部门相关业务逻辑方法的规范中的getById方法
// 此方法的功能是根据给定的唯一标识符id实现了Serializable接口通常对应数据库表中部门记录的主键值
// 从数据库中获取对应的部门信息并以Dept对象的形式返回。
// 在这个实现中直接调用了父类ServiceImpl<DeptMapper, Dept>的getById方法利用了MyBatis-Plus框架提供的通用数据持久化操作功能来执行实际的查询操作
// 从对应的数据库表中查找并返回符合条件的部门记录如果未找到则返回null。
@Override
public Dept getById(Serializable id) {
return super.getById(id);
}
// 重写了IDeptService接口中的update方法该方法用于根据给定的部门实体对象entity以及更新条件封装对象updateWrapper用于构建复杂的更新条件
// 对数据库中的部门记录进行更新操作,比如修改部门的名称、负责人等信息。
// 在这里同样是调用了父类的update方法借助MyBatis-Plus框架提供的机制依据传入的参数构建合适的SQL更新语句
// 然后与数据库进行交互执行更新操作并返回一个布尔值表示更新操作是否成功true表示成功false表示失败例如未找到符合条件的记录等情况
@Override
public boolean update(Dept entity, Wrapper<Dept> updateWrapper){
return super.update(entity,updateWrapper);
}
// 重写IDeptService接口中的updateById方法其功能是根据传入的部门实体对象entity的主键值通常是部门ID
// 对数据库中对应的部门记录进行更新操作该方法相对update方法来说更新条件更简单直接就是依据实体对象自身携带的主键来定位记录进行更新。
// 实现中也是依赖父类的同名方法利用MyBatis-Plus的功能生成相应的SQL更新语句并与数据库交互最后返回更新操作是否成功的布尔值结果。
@Override
public boolean updateById(Dept entity){
return super.updateById(entity);
}
// 重写IDeptService接口中的removeById方法用于根据给定的唯一标识符id从数据库中删除对应的部门记录
// 调用父类的removeById方法通过MyBatis-Plus框架来构建并执行SQL删除语句实现从数据库表中移除相应部门数据的操作
// 同样返回一个布尔值来表示删除操作是否成功成功返回true失败如未找到对应记录等原因返回false。
@Override
public boolean removeById(Serializable id){
return super.removeById(id);
}
// 重写IDeptService接口中的save方法其核心功能是将传入的部门实体对象entity保存到数据库中
// 如果实体对象的主键值如部门ID为空或者不存在会执行插入操作例如新增一个部门记录若主键值已存在则执行更新操作覆盖原有记录
// 这里通过调用父类的save方法借助MyBatis-Plus框架的功能来自动判断并执行相应的数据库持久化操作最后返回表示操作是否成功的布尔值结果。
@Override
public boolean save(Dept entity) {
return super.save(entity);

@ -20,3 +20,19 @@ import org.springframework.transaction.annotation.Transactional;
public class LoginfoServiceImpl extends ServiceImpl<LoginfoMapper, Loginfo> implements ILoginfoService {
}
// 在整个项目架构里起着承上启下的作用一方面承接来自控制层如Controller的业务请求另一方面与数据持久化层通过LoginfoMapper交互实现对日志信息的各种操作。
// 使用@Service注解将该类标记为Spring框架下的一个服务组件这意味着Spring容器会对其进行管理自动创建类的实例并处理依赖注入等相关操作
// 方便在项目的其他组件(比如其他服务类、控制器类等)中进行调用,确保各个组件之间可以低耦合地协同工作。
// 同时添加了@Transactional注解用于开启事务管理功能。在处理日志信息相关业务时可能会涉及到多个数据库操作例如同时插入多条关联的日志记录、更新日志状态等情况
// 这个注解能保证这些相关的数据库操作作为一个整体,要么全部成功提交到数据库,要么在出现任何异常情况时全部失败回滚,从而确保了数据库中日志数据的一致性和完整性,
// 是保障数据可靠处理的重要机制,尤其适用于复杂的日志业务逻辑场景。
// 此类继承自ServiceImpl<LoginfoMapper, Loginfo>意味着它复用了MyBatis-Plus框架提供的通用服务层实现的功能比如常见的增删改查等基础数据库操作方法都可以直接调用或者按需重写
// 同时又实现了ILoginfoService接口假设存在该接口用于规范定义日志信息相关的业务逻辑方法这表明它遵循该接口所约定的方法签名
// 为外部调用提供了统一的、符合业务需求的日志信息处理方法,方便进行诸如根据条件查询日志、保存新的日志记录、更新日志详情等操作。
// 虽然当前类中暂时没有重写任何来自ILoginfoService接口或者父类ServiceImpl的方法但按照常规的业务扩展逻辑
// 后续可以根据具体的日志信息业务需求在这里重写相应的方法例如添加一些特定的业务验证逻辑在保存日志记录前重写save方法
// 或者自定义复杂的查询条件来获取特定的日志信息(重写查询相关方法等),以此来完善针对日志信息的个性化业务处理功能。

@ -15,8 +15,30 @@ import org.springframework.transaction.annotation.Transactional;
* @author luoyi-
* @since 2019-11-25
*/
// NoticeServiceImpl类它在项目的服务层Service Layer中承担着处理通知Notice相关业务逻辑的重要职责
// 作为连接控制层例如接收前端请求的Controller层与数据持久化层通过NoticeMapper与数据库交互的关键纽带实现对通知信息的各种操作与管理
// 像是创建新通知、更新通知内容、删除通知以及查询通知详情等业务功能,都可以在这个类中通过相应的方法来完成。
// @Service注解将该类标识为Spring框架下的一个服务组件这一标记使得Spring容器能够识别并管理这个类
// Spring会自动为其创建实例并且处理依赖注入等操作从而方便其他组件比如控制器类、其他服务类等在需要时对它进行调用
// 保证了整个项目中各个组件之间可以以一种低耦合、易于维护和扩展的方式协同工作。
// @Transactional注解在此处开启了事务管理功能考虑到通知相关业务逻辑可能涉及到多个数据库操作步骤例如在发布一个新通知时
// 可能需要同时向数据库中插入通知主体内容、关联相关的接收对象信息以及记录发布记录等多个操作,使用该注解能够确保这些操作作为一个整体,
// 要么全部成功提交到数据库中,维持数据的一致性和完整性;要么在出现任何异常情况时全部回滚,避免出现部分操作成功、部分操作失败而导致的数据不一致问题,
// 这对于保障通知业务逻辑的可靠性和数据准确性起着至关重要的作用,特别是在复杂的业务场景下尤为关键。
// 此类继承自ServiceImpl<NoticeMapper, Notice>这意味着它可以利用MyBatis-Plus框架提供的通用服务层实现功能
// 例如已经内置的一些基础的增删改查方法,能直接调用这些方法来与数据库进行交互,完成常规的通知数据操作,减少了重复编写数据库操作代码的工作量。
// 同时它还实现了INoticeService接口假设存在这个接口用于规范定义通知相关的业务逻辑方法集合
// 通过实现该接口NoticeServiceImpl类对外提供了统一的、符合业务需求的通知业务处理方法方便其他层如控制层按照接口约定的方法签名来调用相应的服务
// 确保整个项目在处理通知业务时接口的一致性和规范性,便于后续的代码维护与功能扩展
@Service
@Transactional
public class NoticeServiceImpl extends ServiceImpl<NoticeMapper, Notice> implements INoticeService {
}
// 尽管当前代码中没有显式地重写INoticeService接口或者父类ServiceImpl中的方法但从业务扩展的角度来看
// 后续可以根据具体的通知业务场景需求在这里重写相关方法来添加特定的业务逻辑比如在保存通知时进行一些数据合法性验证重写save方法
// 或者定制复杂的查询条件来获取满足特定要求的通知列表(重写查询相关方法)等,以此来完善和细化针对通知信息的个性化业务处理功能,
// 更好地满足项目中不断变化的通知业务操作需求。

@ -20,7 +20,10 @@ import java.io.Serializable;
@Service
@Transactional
public class PermissionServiceImpl extends ServiceImpl<PermissionMapper, Permission> implements IPermissionService {
// getBaseMapper()方法通常由继承的框架相关类提供比如MyBatis-Plus框架下的ServiceImpl类提供此方法会返回对应的Mapper接口实例
// 用于与数据库进行交互操作。在这里获取到PermissionMapper实例后就可以调用它定义的deleteRolePermissionByPid方法
// 其目的是依据传入的id权限ID或菜单ID具体依业务而定从sys_role_permission表中删除与之相关的关联数据
// 例如在权限管理系统中,可能存在角色与权限之间的关联关系存储在该表中,当删除某个权限或者菜单时,需要先清理与之关联的角色权限记录,避免数据不一致或冗余
@Override
public boolean removeById(Serializable id) {
@ -28,6 +31,11 @@ public class PermissionServiceImpl extends ServiceImpl<PermissionMapper, Permiss
PermissionMapper permissionMapper = this.getBaseMapper();
permissionMapper.deleteRolePermissionByPid(id);
//删除权限表中的数据
// 删除权限表中的数据
// 调用父类的removeById方法super.removeById(id)),借助父类(可能是继承自通用服务层实现类)中已经实现的删除逻辑,
// 根据传入的id去对应的权限表具体对应哪个表由继承关系和配置决定通常与当前业务实体对应的表相关中删除主体数据记录
// 例如删除权限记录本身最终返回一个布尔值表示这次删除主体权限数据操作是否成功同时整个重写的removeById方法也会将这个布尔值作为最终结果返回
// 告知调用者此次包含关联数据清理和主体数据删除的整个删除操作是否成功完成。
return super.removeById(id);
}
}

@ -1,63 +1,59 @@
<!DOCTYPE html> <!-- HTML5 -->
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
xmlns:shiro="http://www.pollix.at/thymeleaf/shiro"> <!-- thymeleafshiro -->
xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
<head>
<meta charset="UTF-8"> <!-- UTF-8 -->
<title>Right</title> <!-- "Right" -->
<meta name="renderer" content="webkit"> <!-- 使webkit -->
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <!-- IE使 -->
<meta http-equiv="Access-Control-Allow-Origin" content="*"> <!-- 访*访 -->
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"> <!-- 使 -->
<meta name="apple-mobile-web-app-status-bar-style" content="black"> <!-- -->
<meta name="apple-mobile-web-app-capable" content="yes"> <!-- iOSWebApp -->
<meta name="format-detection" content="telephone=no"> <!-- -->
<link rel="icon" href="/resources/favicon.ico"> <!-- -->
<!-- layuiCSS -->
<meta charset="UTF-8">
<title>Right</title>
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta http-equiv="Access-Control-Allow-Origin" content="*">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="format-detection" content="telephone=no">
<link rel="icon" href="/resources/favicon.ico">
<link rel="stylesheet" href="resources/layui/css/layui.css" th:href="@{/resources/layui/css/layui.css}" media="all"/>
<!-- CSS -->
<link rel="stylesheet" th:href="@{/resources/css/public.css}" media="all"/>
<!-- -->
<link rel="stylesheet" th:href="@{/resources/layui_ext/dtree/dtree.css}" media="all"/>
<!-- -->
<link rel="stylesheet" th:href="@{/resources/layui_ext/dtree/font/dtreefont.css}" media="all"/>
<style>
/* 定义搜索框样式,使其有圆角和统一高度 */
input#search_provideridTree_select_input_id,
input#provideridTree_select_input_id,
input#leaderprovideridTree_select_input_id,
input#search_provideridTree_select_input_id {
border-radius: 10px;
height: 30px;
margin-top: 4px;
}
input#provideridTree_select_input_id {
border-radius: 10px;
height: 30px;
margin-top: 4px;
}
input#leaderprovideridTree_select_input_id {
border-radius: 10px;
height: 30px;
margin-top: 4px;
}
input.layui-input.layui-unselect {
border-radius: 10px; /* 设置圆角为10px */
height: 30px; /* 设置输入框高度为30px */
margin-top: 4px; /* 设置输入框的上边距为4px */
border-radius: 10px;
height: 30px;
margin-top: 4px;
}
</style>
</head>
<body>
<!-- -->
<!---->
<fieldset class="layui-elem-field layui-field-title" style="margin-top: 15px;">
<legend></legend> <!-- -->
<legend></legend>
</fieldset>
<!-- -->
<form action="" method="post" id="searchFrm" lay-filter="searchFrm" class="layui-form">
<div class="layui-form-item">
<!-- -->
<div class="layui-inline">
<label class="layui-form-label"></label>
<div class="layui-input-inline">
<select name="providerid" id="select_providerid">
<option value="0"></option> <!-- -->
<option value="0"></option>
</select>
</div>
</div>
<!-- -->
<div class="layui-inline">
<label class="layui-form-label"></label>
<div class="layui-input-inline">
@ -65,16 +61,12 @@
placeholder="请输入商品名称">
</div>
</div>
<!-- -->
<div class="layui-inline">
<label class="layui-form-label"></label>
<div class="layui-input-inline">
<input type="text" name="productcode" id="productcode" class="layui-input input-radius" placeholder="请输入生产批号">
</div>
</div>
<!-- -->
<div class="layui-inline">
<label class="layui-form-label"></label>
<div class="layui-input-inline">
@ -82,9 +74,8 @@
</div>
</div>
</div>
<div class="layui-form-item">
<!-- -->
<div class="layui-inline">
<label class="layui-form-label"></label>
<div class="layui-input-inline">
@ -92,72 +83,364 @@
placeholder="请输入商品描述">
</div>
</div>
<!-- -->
<div class="layui-inline">
<label class="layui-form-label"></label>
<div class="layui-input-inline">
<input type="text" name="size" id="size" class="layui-input input-radius" placeholder="请输入商品规格">
</div>
</div>
<!-- -->
<div class="layui-inline" style="padding-left: 3%">
<button type="button" class="layui-btn layui-btn-sm layui-btn-radius" lay-submit="" lay-filter="doSearch">
<i class="layui-icon layui-icon-search layui-icon-normal"></i>
<button type="button" class="layui-btn layui-btn-sm layui-btn-radius" lay-submit="" lay-filter="doSearch"><i
class="layui-icon layui-icon-search layui-icon-normal"></i>
</button>
<button type="reset" class="layui-btn layui-btn-sm layui-btn-radius layui-btn-warm">
<i class="layui-icon layui-icon-refresh"></i><span></span>
<button type="reset" class="layui-btn layui-btn-sm layui-btn-radius layui-btn-warm"><i
class="layui-icon layui-icon-refresh"></i><span></span>
</button>
</div>
</div>
</form>
<!-- -->
<!---->
<div>
<table class="layui-hide" id="goodsTable" lay-filter="goodsTable"></table> <!-- -->
<!-- -->
<table class="layui-hide" id="goodsTable" lay-filter="goodsTable"></table>
<div id="goodsToolBar" style="display: none">
<button type="button" lay-event="add" shiro:hasPermission="goods:create" class="layui-btn layui-btn-sm layui-btn-normal layui-btn-radius">
<i class="layui-icon layui-icon-add-1"></i>
</button>
</div>
<div id="goodsRowBar" style="display: none;">
<button type="button" lay-event="update" shiro:hasPermission="goods:update" class="layui-btn layui-btn-sm layui-btn-radius"><i
class="layui-icon layui-icon-edit"></i>
</button>
<button type="button" lay-event="delete" shiro:hasPermission="goods:delete" class="layui-btn layui-btn-sm layui-btn-danger layui-btn-radius"><i
class="layui-icon layui-icon-delete"></i>
</button>
</div>
</div>
<!---->
<div id="addOrUpdateDiv" style="display: none;padding: 10px;padding-right: 5%">
<form action="" method="post" class="layui-form" id="dataFrm" lay-filter="dataFrm">
<div class="layui-col-md12 layui-col-xs12">
<div class="layui-row layui-col-space10">
<div class="layui-col-md9 layui-col-xs7">
<div class="layui-form-item magt3">
<label class="layui-form-label"></label>
<div class="layui-input-block">
<select name="providerid" id="providerid">
<option value="0"></option>
</select>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label"></label>
<div class="layui-input-block">
<input type="hidden" name="id">
<input type="text" class="layui-input input-radius" name="goodsname" lay-verify="required" placeholder="请输入商品名称">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label"></label>
<div class="layui-input-block">
<input type="text" class="layui-input input-radius" name="description" lay-verify="required" placeholder="请输入商品描述">
</div>
</div>
</div>
<div class="layui-col-md3 layui-col-xs5">
<div class="layui-upload-list thumbBox mag0 magt3">
<input type="hidden" name="goodsimg" id="goodsimg" value="images/noDefaultImage.jpg">
<img class="layui-upload-img thumbImg" src="/file/showImageByPath?path=images/noDefaultImage.jpg">
</div>
</div>
</div>
<div class="layui-form-item magb0">
<div class="layui-inline">
<label class="layui-form-label"></label>
<div class="layui-input-inline">
<input type="text" class="layui-input input-radius" name="produceplace" lay-verify="required" placeholder="请输入商品产地">
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label"></label>
<div class="layui-input-inline">
<input type="text" class="layui-input input-radius" name="goodspackage" lay-verify="required" placeholder="请输入商品包装">
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label"></label>
<div class="layui-input-inline">
<input type="text" class="layui-input input-radius" name="size" lay-verify="required" placeholder="请输入商品规格">
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label"></label>
<div class="layui-input-inline">
<input type="text" class="layui-input input-radius" name="productcode" lay-verify="required" placeholder="请输入商品生产批号">
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label"></label>
<div class="layui-input-inline">
<input type="text" class="layui-input input-radius" name="promitcode" lay-verify="required" placeholder="请输入商品批准文号">
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label"></label>
<div class="layui-input-inline">
<input type="text" class="layui-input input-radius" name="price" lay-verify="required|number" placeholder="请输入商品销售价格">
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label"></label>
<div class="layui-input-inline">
<input type="text" class="layui-input input-radius" name="number" lay-verify="required|number" placeholder="请输入商品库存量">
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label"></label>
<div class="layui-input-inline">
<input type="text" class="layui-input input-radius" name="dangernum" lay-verify="required|number" placeholder="请输入商品预警值">
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label"></label>
<div class="layui-input-inline">
<input type="radio" name="available" value="1" title="可用" checked="">
<input type="radio" name="available" value="0" title="不可用" >
</div>
</div>
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block" style="text-align: center;padding-right: 7%">
<button type="button" class="layui-btn layui-btn-radius" lay-submit="" lay-filter="doSubmit" id="doSubmit"><i
class="layui-icon layui-icon-search layui-icon-normal"></i>
</button>
<button type="reset" class="layui-btn layui-btn-radius layui-btn-warm"><i
class="layui-icon layui-icon-refresh"></i><span></span>
</button>
</div>
</div>
</form>
</div>
<!-- layuiJS -->
<script type="text/javascript" src="/resources/layui/layui.js"></script>
<script type="text/javascript">
layui.use(['jquery', 'form', 'layer', 'table', 'upload'], function () {
//提升数据表格的作用域因为底下还有一个reloadTable方法
var tableIns;
layui.use(['jquery', 'form', 'layer', 'table','upload'], function () {
var $ = layui.jquery;
var form = layui.form;
var layer = layui.layer;
var table = layui.table;
var upload = layui.upload;
// 渲染数据表格
//初始化表格 加载数据
tableIns = table.render({
elem: "#goodsTable",
title: "商品数据表格",
url: "/goods/loadAllGoods",
toolbar: "#goodsToolBar",
page: true,
cols: [[
{field: 'id', title: 'ID', align: 'center'},
{field: 'goodsname', title: '', align: 'center'},
{field: 'providername', title: '', align: 'center'}
]]
height: "full-180",
cols: [ [
{field: 'id', title: 'ID', align: 'center',width:'50'},
{field: 'goodsname', title: '', align: 'center',width:'150'},
{field: 'providername', title: '', align: 'center',width:'150'},
{field: 'produceplace', title: '', align: 'center',width:'150'},
{field: 'description', title: '', align: 'center',width:'150'},
{field: 'price', title: '', align: 'center',width:'90'},
{field: 'number', title: '', align: 'center',width:'90'},
{field: 'dangernum', title: '', align: 'center',width:'100'},
{field: 'goodsimg', title: '', align: 'center',width:'150', templet:function(d){
return '<img width=40 height=40 src=/file/showImageByPath?path='+d.goodsimg+ ' />';
}},
{field: 'size', title: '', align: 'center',width:'120'},
{field: 'goodspackage', title: '', align: 'center',width:'120'},
{field: 'productcode', title: '', align: 'center',width:'130'},
{field: 'promitcode', title: '', align: 'center',width:'130'},
{field: 'available', title: '', align: 'center',width:'100',templet:function (d) {
return d.available==1?'<font color="blue"></font>':'<font color="red"></font>';
}},
{fixed: 'right', title: '', toolbar: '#goodsRowBar', align: 'center',width:'180'}
] ],
done: function (data, curr, count) {
//不是第一页时如果当前返回的数据为0那么就返回上一页
if (data.data.length == 0 && curr != 1) {
tableIns.reload({
page: {
curr: curr - 1
}
})
}
}
});
//初始化查询条件的下拉列表
$.get("/provider/loadAllProviderForSelect",function (res) {
var data = res.data;
var dom = $("#select_providerid");
var html = '<option value="0"></option>';
$.each(data,function (index, item) {
html += '<option value="'+item.id+'">'+item.providername+'</option>';
})
dom.html(html);
//重新渲染下拉列表
form.render("select");
});
// 表单提交事件处理
//监控模糊查询按钮事件
form.on("submit(doSearch)", function (data) {
tableIns.reload({
where: data.field,
page: { curr: 1 }
page: {
curr: 1
}
});
return false;
});
//监控工具条事件
table.on("toolbar(goodsTable)", function (obj) {
switch (obj.event) {
case 'add':
openAddLayer();
break;
case 'deleteBatch':
batchDeleteGoods();
break;
};
});
//监控行工具条事件
table.on("tool(goodsTable)", function (obj) {
//获取当前行数据
var data = obj.data;
switch (obj.event) {
case 'delete':
deleteGoods(data);
break;
case 'update':
updateGoods(data);
break;
};
});
//文件上传
upload.render({
elem: '.thumbBox',
url: '/file/uploadFile',
acceptMime:'image/*',
field:'mf',
method : "post",
done: function(res, index, upload){
var path=res.path;
$('.thumbImg').attr('src','/file/showImageByPath?path='+path);
$('.thumbBox').css("background","#fff");
//给隐藏域赋值
$("#goodsimg").val(path);
}
});
var mainIndex;
var url;
//打开添加弹出层
function openAddLayer() {
mainIndex = layer.open({
type:1,
content:$("#addOrUpdateDiv"),
area:['700px','500px'],
title:'',
success:function () {
$("#dataFrm")[0].reset();
url="/goods/addGoods";
$.get("/provider/loadAllProviderForSelect",function(res){
var data=res.data;
var dom=$("#providerid");
var html='<option value="0"></option>'
$.each(data,function(index,item){
html+='<option value="'+item.id+'">'+item.providername+'</option>'
});
dom.html(html);
form.render("select");
});
//设置默认为无图片
$(".thumbImg").attr("src",'/file/showImageByPath?path=images/noDefaultImage.jpg');
$("#goodsimg").val('/images/noDefaultImage.jpg');
}
});
}
//打开修改的弹出层
function updateGoods(data) {
mainIndex = layer.open({
type:1,
content:$("#addOrUpdateDiv"),
area:['700px','500px'],
title:'',
success:function () {
//清空原有的数据
$("#dataFrm")[0].reset();
//装载新的数据
form.val("dataFrm",data);
//图片进行回显
$(".thumbImg").attr("src",'/file/showImageByPath?path='+data.goodsimg);
//下拉列表的回显
$.get("/provider/loadAllProviderForSelect",function(res){
var redata=res.data;
var dom=$("#providerid");
var html='<option value="0"></option>'
$.each(redata,function(index,item){
if (data.providerid===item.id){
html+='<option value="'+item.id+'" selected>'+item.providername+'</option>'
}else {
html+='<option value="'+item.id+'">'+item.providername+'</option>'
}
});
dom.html(html);
form.render("select");
});
url="/goods/updateGoods";
}
});
}
form.on("submit(doSubmit)",function (data) {
$.post(url,data.field,function (res) {
if (res.code==200){
tableIns.reload();
}
layer.msg(res.msg);
layer.close(mainIndex);
});
return false;
});
//删除
function deleteGoods(data) {
layer.confirm('' + data.goodsname + '退退', {icon: 3, title: ''}, function (index) {
$.post("/goods/deleteGoods", {id: data.id,goodsimg:data.goodsimg},function (res) {
if (res.code == 200) {
tableIns.reload({
where:"",
});
}
layer.msg(res.msg);
});
layer.close(index);
});
}
});
</script>
</body>
</html>
</html>

@ -1,52 +1,71 @@
<!DOCTYPE html> <!-- HTML5 -->
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
xmlns:shiro="http://www.pollix.at/thymeleaf/shiro"> <!-- ThymeleafShiro -->
xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
<head>
<meta charset="UTF-8"> <!-- UTF-8 -->
<title>Right</title> <!-- -->
<meta name="renderer" content="webkit"> <!-- 使webkit -->
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <!-- IE -->
<meta http-equiv="Access-Control-Allow-Origin" content="*"> <!-- 访 -->
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"> <!-- -->
<meta name="apple-mobile-web-app-status-bar-style" content="black"> <!-- -->
<meta name="apple-mobile-web-app-capable" content="yes"> <!-- -->
<meta name="format-detection" content="telephone=no"> <!-- -->
<link rel="icon" href="/resources/favicon.ico"> <!-- -->
<!-- layui -->
<meta charset="UTF-8">
<title>Right</title>
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta http-equiv="Access-Control-Allow-Origin" content="*">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="format-detection" content="telephone=no">
<link rel="icon" href="/resources/favicon.ico">
<link rel="stylesheet" href="resources/layui/css/layui.css" th:href="@{/resources/layui/css/layui.css}" media="all"/>
<!-- -->
<link rel="stylesheet" th:href="@{/resources/css/public.css}" media="all"/>
<!-- -->
<link rel="stylesheet" th:href="@{/resources/layui_ext/dtree/dtree.css}" media="all"/>
<link rel="stylesheet" th:href="@{/resources/layui_ext/dtree/font/dtreefont.css}" media="all"/>
<style>
/* 输入框样式设置 */
input#search_provideridTree_select_input_id,
input#provideridTree_select_input_id,
input#leaderprovideridTree_select_input_id,
input.layui-input.layui-unselect,
input#search_goodsidTree_select_input_id,
input#goodsidTree_select_input_id,
input#search_provideridTree_select_input_id {
border-radius: 10px;
height: 30px;
margin-top: 4px;
}
input#provideridTree_select_input_id {
border-radius: 10px;
height: 30px;
margin-top: 4px;
}
input#leaderprovideridTree_select_input_id {
border-radius: 10px;
height: 30px;
margin-top: 4px;
}
input.layui-input.layui-unselect {
border-radius: 10px;
height: 30px;
margin-top: 4px;
}
input#search_goodsidTree_select_input_id {
border-radius: 10px;
height: 30px;
margin-top: 4px;
}
input#goodsidTree_select_input_id {
border-radius: 10px;
height: 30px;
margin-top: 4px;
}
input#leadergoodsidTree_select_input_id {
border-radius: 10px; /* 设置圆角 */
height: 30px; /* 设置输入框高度 */
margin-top: 4px; /* 设置顶部外边距 */
border-radius: 10px;
height: 30px;
margin-top: 4px;
}
input.layui-input.layui-unselect {
border-radius: 10px;
height: 30px;
margin-top: 4px;
}
</style>
</head>
<body>
<!-- -->
<!---->
<fieldset class="layui-elem-field layui-field-title" style="margin-top: 15px;">
<legend></legend> <!-- -->
<legend></legend>
</fieldset>
<!-- -->
<form action="" method="post" id="searchFrm" lay-filter="searchFrm" class="layui-form">
<div class="layui-form-item">
<!-- -->
<div class="layui-inline">
<label class="layui-form-label"></label>
<div class="layui-input-inline">
@ -55,8 +74,6 @@
</select>
</div>
</div>
<!-- -->
<div class="layui-inline">
<label class="layui-form-label"></label>
<div class="layui-input-inline">
@ -65,8 +82,6 @@
</select>
</div>
</div>
<!-- -->
<div class="layui-inline">
<label class="layui-form-label"></label>
<div class="layui-input-inline">
@ -74,8 +89,6 @@
class="layui-input input-radius">
</div>
</div>
<!-- -->
<div class="layui-inline">
<label class="layui-form-label"></label>
<div class="layui-input-inline">
@ -84,21 +97,19 @@
</div>
</div>
</div>
<!-- -->
<div class="layui-form-item">
<div class="layui-input-block" style="text-align: center;padding-right: 15%;">
<button type="button" class="layui-btn layui-btn-sm layui-btn-radius" lay-submit="" lay-filter="doSearch">
<i class="layui-icon layui-icon-search layui-icon-normal"></i>
<button type="button" class="layui-btn layui-btn-sm layui-btn-radius" lay-submit="" lay-filter="doSearch"><i
class="layui-icon layui-icon-search layui-icon-normal"></i>
</button>
<button type="reset" class="layui-btn layui-btn-sm layui-btn-radius layui-btn-warm">
<i class="layui-icon layui-icon-refresh"></i><span></span>
<button type="reset" class="layui-btn layui-btn-sm layui-btn-radius layui-btn-warm"><i
class="layui-icon layui-icon-refresh"></i><span></span>
</button>
</div>
</div>
</form>
<!-- -->
<!---->
<div>
<table class="layui-hide" id="inportTable" lay-filter="inportTable"></table>
<div id="inportToolBar" style="display: none">
@ -106,231 +117,102 @@
<i class="layui-icon layui-icon-add-1"></i>
</button>
</div>
</div>
<!-- / -->
<div id="addOrUpdateDiv" style="display: none;padding: 10px;padding-right: 5%">
<form action="" method="post" class="layui-form" id="dataFrm" lay-filter="dataFrm">
<div class="layui-form-item">
<label class="layui-form-label"></label>
<div class="layui-input-inline">
<select name="providerid" id="providerid" lay-filter="providerid">
<option value="0"></option>
</select>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label"></label>
<div class="layui-input-inline">
<select name="goodsid" id="goodsid">
<option value="0"></option>
</select>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label"></label>
<div class="layui-input-block">
<input type="text" name="number" lay-verify="required|number" autocomplete="off" class="layui-input input-radius" placeholder="请输入进货数量">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label"></label>
<div class="layui-input-block">
<textarea name="remark" placeholder="请输入进货备注" class="layui-textarea"></textarea>
</div>
</div>
<!-- -->
<div class="layui-form-item">
<div class="layui-input-block" style="text-align: center;padding-right: 7%">
<button type="button" class="layui-btn layui-btn-radius" lay-submit="" lay-filter="doSubmit">
<i class="layui-icon layui-icon-search layui-icon-normal"></i>
</button>
<button type="reset" class="layui-btn layui-btn-radius layui-btn-warm">
<i class="layui-icon layui-icon-refresh"></i><span></span>
</button>
</div>
</div>
</form>
</div><!DOCTYPE html> <!-- HTML5 -->
<html xmlns:th="http://www.thymeleaf.org"
xmlns:shiro="http://www.pollix.at/thymeleaf/shiro"> <!-- ThymeleafShiro -->
<head>
<meta charset="UTF-8"> <!-- UTF-8 -->
<title>Right</title> <!-- -->
<meta name="renderer" content="webkit"> <!-- 使webkit -->
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <!-- IE -->
<meta http-equiv="Access-Control-Allow-Origin" content="*"> <!-- 访 -->
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"> <!-- -->
<meta name="apple-mobile-web-app-status-bar-style" content="black"> <!-- -->
<meta name="apple-mobile-web-app-capable" content="yes"> <!-- -->
<meta name="format-detection" content="telephone=no"> <!-- -->
<link rel="icon" href="/resources/favicon.ico"> <!-- -->
<!-- layui -->
<link rel="stylesheet" href="resources/layui/css/layui.css" th:href="@{/resources/layui/css/layui.css}" media="all"/>
<!-- -->
<link rel="stylesheet" th:href="@{/resources/css/public.css}" media="all"/>
<!-- -->
<link rel="stylesheet" th:href="@{/resources/layui_ext/dtree/dtree.css}" media="all"/>
<link rel="stylesheet" th:href="@{/resources/layui_ext/dtree/font/dtreefont.css}" media="all"/>
<style>
/* 输入框样式设置 */
input#search_provideridTree_select_input_id,
input#provideridTree_select_input_id,
input#leaderprovideridTree_select_input_id,
input.layui-input.layui-unselect,
input#search_goodsidTree_select_input_id,
input#goodsidTree_select_input_id,
input#leadergoodsidTree_select_input_id {
border-radius: 10px; /* 设置圆角 */
height: 30px; /* 设置输入框高度 */
margin-top: 4px; /* 设置顶部外边距 */
}
</style>
</head>
<body>
<!-- -->
<fieldset class="layui-elem-field layui-field-title" style="margin-top: 15px;">
<legend></legend> <!-- -->
</fieldset>
<!-- -->
<form action="" method="post" id="searchFrm" lay-filter="searchFrm" class="layui-form">
<div class="layui-form-item">
<!-- -->
<div class="layui-inline">
<label class="layui-form-label"></label>
<div class="layui-input-inline">
<select name="providerid" id="select_providerid">
<option value="0"></option>
</select>
</div>
</div>
<!-- -->
<div class="layui-inline">
<label class="layui-form-label"></label>
<div class="layui-input-inline">
<select name="goodsid" id="select_goodsid">
<option value="0"></option>
</select>
</div>
</div>
<!-- -->
<div class="layui-inline">
<label class="layui-form-label"></label>
<div class="layui-input-inline">
<input type="text" name="startTime" id="startTime" readonly="readonly" placeholder="yyyy-MM-dd"
class="layui-input input-radius">
</div>
</div>
<!-- -->
<div class="layui-inline">
<label class="layui-form-label"></label>
<div class="layui-input-inline">
<input type="text" name="endTime" id="endTime" readonly="readonly" placeholder="yyyy-MM-dd"
class="layui-input input-radius">
</div>
</div>
</div>
<!-- -->
<div class="layui-form-item">
<div class="layui-input-block" style="text-align: center;padding-right: 15%;">
<button type="button" class="layui-btn layui-btn-sm layui-btn-radius" lay-submit="" lay-filter="doSearch">
<i class="layui-icon layui-icon-search layui-icon-normal"></i>
</button>
<button type="reset" class="layui-btn layui-btn-sm layui-btn-radius layui-btn-warm">
<i class="layui-icon layui-icon-refresh"></i><span></span>
</button>
</div>
</div>
</form>
<!-- -->
<div>
<table class="layui-hide" id="inportTable" lay-filter="inportTable"></table>
<div id="inportToolBar" style="display: none">
<button type="button" lay-event="add" shiro:hasPermission="inport:create" class="layui-btn layui-btn-sm layui-btn-normal layui-btn-radius">
<i class="layui-icon layui-icon-add-1"></i>
<div id="inportRowBar" style="display: none;">
<button type="button" lay-event="update" shiro:hasPermission="inport:update" class="layui-btn layui-btn-sm layui-btn-radius"><i
class="layui-icon layui-icon-edit"></i>
</button>
<button type="button" lay-event="delete" shiro:hasPermission="inport:delete" class="layui-btn layui-btn-sm layui-btn-danger layui-btn-radius"><i
class="layui-icon layui-icon-delete"></i>
</button>
<button type="button" lay-event="back" shiro:hasPermission="inport:back" class="layui-btn layui-btn-sm layui-btn-warm layui-btn-radius"><i
class="layui-icon layui-icon-delete"></i>退
</button>
</div>
</div>
<!-- / -->
<!---->
<div id="addOrUpdateDiv" style="display: none;padding: 10px;padding-right: 5%">
<form action="" method="post" class="layui-form" id="dataFrm" lay-filter="dataFrm">
<div class="layui-form-item">
<label class="layui-form-label"></label>
<div class="layui-input-inline">
<select name="providerid" id="providerid" lay-filter="providerid">
<option value="0"></option>
</select>
<div class="layui-inline">
<label class="layui-form-label"></label>
<div class="layui-input-inline">
<select name="providerid" id="providerid" lay-filter="providerid">
<option value="0"></option>
</select>
<div class="mydiv" title="不可修改" style="position:absolute;width:100%;height:100%;left:0px;top:0px;background:#fff;opacity:0;filter:alpha(opacity=0)"> </div>
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label"></label>
<div class="layui-input-inline">
<select name="goodsid" id="goodsid">
<option value="0"></option>
</select>
</div>
<div class="mydiv" title="不可修改" style="position:absolute;width:100%;height:100%;left:0px;top:0px;background:#fff;opacity:0;filter:alpha(opacity=0)"> </div>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label"></label>
<div class="layui-input-inline">
<select name="goodsid" id="goodsid">
<option value="0"></option>
</select>
<div class="layui-inline">
<label class="layui-form-label"></label>
<div class="layui-input-block">
<input type="hidden" name="id">
<input type="text" name="number" lay-verify="required|number" autocomplete="off" class="layui-input input-radius" placeholder="请输入进货数量">
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label"></label>
<div class="layui-input-block">
<input type="text" name="inportprice" lay-verify="required|number" autocomplete="off" class="layui-input input-radius" placeholder="请输入进货价格">
</div>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label"></label>
<div class="layui-input-block">
<input type="text" name="number" lay-verify="required|number" autocomplete="off" class="layui-input input-radius" placeholder="请输入进货数量">
<div class="layui-inline">
<label class="layui-form-label"></label>
<div class="layui-input-block">
<input type="radio" name="paytype" value="微信" title="微信">
<input type="radio" name="paytype" value="支付宝" title="支付宝" checked>
<input type="radio" name="paytype" value="银联" title="银联">
</div>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label"></label>
<div class="layui-input-block">
<textarea name="remark" placeholder="请输入进货备注" class="layui-textarea"></textarea>
<div class="layui-inline">
<label class="layui-form-label"></label>
<div class="layui-input-block">
<textarea name="remark" placeholder="请输入进货备注" class="layui-textarea" cols="200" rows="8"></textarea>
</div>
</div>
</div>
<!-- -->
<div class="layui-form-item">
<div class="layui-input-block" style="text-align: center;padding-right: 7%">
<button type="button" class="layui-btn layui-btn-radius" lay-submit="" lay-filter="doSubmit">
<i class="layui-icon layui-icon-search layui-icon-normal"></i>
<button type="button" class="layui-btn layui-btn-radius" lay-submit="" lay-filter="doSubmit" id="doSubmit"><i
class="layui-icon layui-icon-search layui-icon-normal"></i>
</button>
<button type="reset" class="layui-btn layui-btn-radius layui-btn-warm">
<i class="layui-icon layui-icon-refresh"></i><span></span>
<button type="reset" class="layui-btn layui-btn-radius layui-btn-warm"><i
class="layui-icon layui-icon-refresh"></i><span></span>
</button>
</div>
</div>
</form>
</div>
<!-- 退退 -->
<!--退-->
<div id="backGoodsDiv" style="display: none;padding-right: 3%">
<form action="" method="post" class="layui-form" id="dataFrmBack" lay-filter="dataFrmBack">
<!-- 退 -->
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label">退</label>
<div class="layui-input-block">
<input type="hidden" name="id"> <!-- 退ID -->
<input type="hidden" name="currentNumber" id="currentNumber"> <!-- -->
<input type="hidden" name="id"> <!-- ID -->
<input type="hidden" name="currentNumber" id="currentNumber"> <!-- -->
<input type="text" name="number" lay-verify="required|checkNumber" autocomplete="off" class="layui-input input-radius" placeholder="请输入退货数量">
</div>
</div>
</div>
<!-- 退 -->
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label">退</label>
@ -339,17 +221,13 @@
</div>
</div>
</div>
<!-- -->
<div class="layui-form-item">
<div class="layui-input-block" style="text-align: center;padding-right: 7%">
<!-- 退 -->
<button type="button" class="layui-btn layui-btn-radius" lay-submit="" lay-filter="doBackSubmit" id="doBackSubmit">
<i class="layui-icon layui-icon-search layui-icon-normal"></i>
<button type="button" class="layui-btn layui-btn-radius" lay-submit="" lay-filter="doBackSubmit" id="doBackSubmit"><i
class="layui-icon layui-icon-search layui-icon-normal"></i>
</button>
<!-- 退 -->
<button type="reset" class="layui-btn layui-btn-radius layui-btn-warm">
<i class="layui-icon layui-icon-refresh"></i><span></span>
<button type="reset" class="layui-btn layui-btn-radius layui-btn-warm"><i
class="layui-icon layui-icon-refresh"></i><span></span>
</button>
</div>
</div>
@ -357,7 +235,6 @@
</div>
<script type="text/javascript" src="/resources/layui/layui.js"></script>
<script type="text/javascript">
@ -571,7 +448,7 @@
form.render("select");
});
}
form.on("submit(doSubmit)",function (data) {
$.post(url,data.field,function (res) {

@ -1,46 +1,70 @@
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
<!-- HTMLThymeleafShiro -->
<html xmlns:th="http://www.thymeleaf.org"
xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
<head>
<meta charset="UTF-8">
<!-- UTF-8 -->
<title>Right</title>
<!-- -->
<meta name="renderer" content="webkit">
<!-- 使WebKit -->
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<!-- 使 -->
<meta http-equiv="Access-Control-Allow-Origin" content="*">
<!-- -->
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<!-- -->
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<!-- iOS -->
<meta name="apple-mobile-web-app-capable" content="yes">
<!-- iOS -->
<meta name="format-detection" content="telephone=no">
<!-- -->
<link rel="icon" href="/resources/favicon.ico">
<!-- -->
<link rel="stylesheet" href="resources/layui/css/layui.css" th:href="@{/resources/layui/css/layui.css}" media="all"/>
<!-- layui -->
<link rel="stylesheet" th:href="@{/resources/css/public.css}" media="all"/>
<!-- -->
<link rel="stylesheet" th:href="@{/resources/layui_ext/dtree/dtree.css}" media="all"/>
<!-- -->
<link rel="stylesheet" th:href="@{/resources/layui_ext/dtree/font/dtreefont.css}" media="all"/>
<!-- -->
<style>
input#search_provideridTree_select_input_id {
border-radius: 10px;
height: 30px;
margin-top: 4px;
}
input#provideridTree_select_input_id {
border-radius: 10px;
height: 30px;
margin-top: 4px;
}
input#leaderprovideridTree_select_input_id {
border-radius: 10px;
height: 30px;
margin-top: 4px;
}
input.layui-input.layui-unselect {
border-radius: 10px;
height: 30px;
margin-top: 4px;
}
input#search_goodsidTree_select_input_id {
border-radius: 10px;
height: 30px;
margin-top: 4px;
}
input#goodsidTree_select_input_id {
border-radius: 10px;
height: 30px;
margin-top: 4px;
}
input#leadergoodsidTree_select_input_id {
border-radius: 10px;
height: 30px;
margin-top: 4px;
}
input.layui-input.layui-unselect {
border-radius: 10px;
height: 30px;
margin-top: 4px;
}
</style>
</head>
<body>
<!-- -->
<!-- -->
<!---->
<fieldset class="layui-elem-field layui-field-title" style="margin-top: 15px;">
<legend></legend>
</fieldset>
<form action="" method="post" id="searchFrm" lay-filter="searchFrm" class="layui-form">
<!-- -->
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label"></label>
@ -48,7 +72,6 @@
<select name="providerid" id="select_providerid">
<option value="0"></option>
</select>
<!-- -->
</div>
</div>
<div class="layui-inline">
@ -57,7 +80,6 @@
<select name="goodsid" id="select_goodsid">
<option value="0"></option>
</select>
<!-- -->
</div>
</div>
<div class="layui-inline">
@ -65,7 +87,6 @@
<div class="layui-input-inline">
<input type="text" name="startTime" id="startTime" readonly="readonly" placeholder="yyyy-MM-dd"
class="layui-input input-radius">
<!-- -->
</div>
</div>
<div class="layui-inline">
@ -73,41 +94,37 @@
<div class="layui-input-inline">
<input type="text" name="endTime" id="endTime" readonly="readonly" placeholder="yyyy-MM-dd"
class="layui-input input-radius">
<!-- -->
</div>
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block" style="text-align: center;padding-right: 15%;">
<button type="button" class="layui-btn layui-btn-sm layui-btn-radius" lay-submit="" lay-filter="doSearch">
<i class="layui-icon layui-icon-search layui-icon-normal"></i>
<button type="button" class="layui-btn layui-btn-sm layui-btn-radius" lay-submit="" lay-filter="doSearch"><i
class="layui-icon layui-icon-search layui-icon-normal"></i>
</button>
<!-- -->
<button type="reset" class="layui-btn layui-btn-sm layui-btn-radius layui-btn-warm">
<i class="layui-icon layui-icon-refresh"></i><span></span>
<button type="reset" class="layui-btn layui-btn-sm layui-btn-radius layui-btn-warm"><i
class="layui-icon layui-icon-refresh"></i><span></span>
</button>
<!-- -->
</div>
</div>
</form>
<!-- -->
<!---->
<div>
<table class="layui-hide" id="outportTable" lay-filter="outportTable"></table>
<div id="outportRowBar" style="display: none;">
<button type="button" lay-event="delete" shiro:hasPermission="outport:delete" class="layui-btn layui-btn-sm layui-btn-danger layui-btn-radius">
<i class="layui-icon layui-icon-delete"></i>
<button type="button" lay-event="delete" shiro:hasPermission="outport:delete" class="layui-btn layui-btn-sm layui-btn-danger layui-btn-radius"><i
class="layui-icon layui-icon-delete"></i>
</button>
<!-- 退 -->
</div>
</div>
<!-- layuiJS -->
<script type="text/javascript" src="/resources/layui/layui.js"></script>
<script type="text/javascript">
// 提升数据表格的作用域
//提升数据表格的作用域因为底下还有一个reloadTable方法
var tableIns;
layui.use(['jquery', 'form', 'layer', 'table', 'laydate'], function () {
@ -117,7 +134,7 @@
var table = layui.table;
var laydate = layui.laydate;
// 渲染时间选择器
//初始化时间选择器
laydate.render({
elem: '#startTime',
type: 'datetime'
@ -125,24 +142,42 @@
laydate.render({
elem: '#endTime',
type: 'datetime'
});
})
// 渲染数据表格
//初始化表格 加载数据
tableIns = table.render({
elem: "#outportTable",
title: "进货数据表格",
url: "/outport/loadAllOutport",
toolbar: true,
page: true,
height: "full-180",
cols: [[
cols: [ [
{field: 'id', title: 'ID', align: 'center'},
{field: 'providername', title: '', align: 'center'},
{field: 'goodsname', title: '', align: 'center'},
{field: 'paytype', title: '', align: 'center'},
{field: 'outputtime', title: '退', align: 'center'}
]]
{field: 'providername', title: '', align: 'center',width:'130'},
{field: 'goodsname', title: '', align: 'center',width:'150'},
{field: 'paytype', title: '', align: 'center',width:'90'},
{field: 'outputtime', title: '退', align: 'center',width:'170'},
{field: 'operateperson', title: '', align: 'center',width:'130'},
{field: 'number', title: '退', align: 'center',width:'100'},
{field: 'outportprice', title: '退', align: 'center',width:'120'},
{field: 'remark', title: '', align: 'center',width:'130'},
{field: 'size', title: '', align: 'center',width:'100'},
{fixed: 'right', title: '', toolbar: '#outportRowBar', align: 'center',width:'130'}
] ],
done: function (data, curr, count) {
//不是第一页时如果当前返回的数据为0那么就返回上一页
if (data.data.length == 0 && curr != 1) {
tableIns.reload({
page: {
curr: curr - 1
}
})
}
}
});
// 查询按钮点击事件
//监控模糊查询按钮事件
form.on("submit(doSearch)", function (data) {
tableIns.reload({
where: data.field,
@ -152,7 +187,63 @@
});
return false;
});
//监控行工具条事件
table.on("tool(outportTable)", function (obj) {
//获取当前行数据
var data = obj.data;
switch (obj.event) {
case 'delete':
deleteOutport(data);
break;
};
});
//初始化供应商名称的下拉列表
$.get("/provider/loadAllProviderForSelect",function (res) {
var data = res.data;
var dom = $("#select_providerid");
var html = '<option value="0"></option>';
$.each(data,function (index, item) {
html += '<option value="'+item.id+'">'+item.providername+'</option>';
})
dom.html(html);
//重新渲染下拉列表
form.render("select");
});
//初始化商品名称的下拉列表
$.get("/goods/loadAllGoodsForSelect",function (res) {
var data = res.data;
var dom = $("#select_goodsid");
var html = '<option value="0"></option>';
$.each(data,function (index, item) {
html += '<option value="'+item.id+'">'+item.goodsname+'-['+item.size+']-'+'['+item.providername+']'+'</option>';
});
dom.html(html);
//重新渲染下拉列表
form.render("select");
});
//删除退货信息
function deleteOutport(data) {
layer.confirm('退', {icon: 3, title: ''}, function (index) {
$.post("/outport/deleteOutport", {id: data.id},function (res) {
if (res.code == 200) {
tableIns.reload({
where:"",
});
}
layer.msg(res.msg);
});
layer.close(index);
});
}
});
</script>
</body>
</html>
</html>

@ -99,3 +99,117 @@ public class CodeGenerator {
}
// 这个类假设所在类有合适的类名包含了代码生成相关的逻辑通过配置MyBatis-Plus的代码生成器根据给定的各种参数生成相应的代码文件
// 比如实体类、Mapper接口、Service层、Controller层等代码方便快速搭建项目的基础代码结构减少手动编写重复代码的工作量。
// scanner方法用于从控制台获取用户输入的信息并且进行简单的验证如果输入为空则抛出异常提示用户重新输入。
// 参数tip用于提示用户需要输入的内容类型在控制台输出相应的提示信息引导用户输入。
// 创建一个Scanner对象用于读取用户从控制台输入的内容它会关联到标准输入流System.in以便获取用户输入的文本信息。
// 构建一个包含提示信息的字符串,告知用户需要输入什么内容,例如提示"请输入模块名:"等,方便用户明白输入的要求。
// 获取用户输入的字符串内容如果用户有输入的话将其赋值给ipt变量。
// 使用StringUtils工具类假设来自MyBatis-Plus的工具包或者项目自定义的工具类用于字符串相关的操作判断输入的字符串是否不为空
// 如果不为空,则将该输入的字符串返回,作为有效的用户输入内容。
// 如果用户没有输入内容即输入为空字符串或者没有输入任何东西则抛出一个MybatisPlusException异常
// 异常信息会提示用户需要输入正确的相应内容,引导用户重新进行输入操作。
// 代码生成器
// 创建一个AutoGenerator对象它是MyBatis-Plus提供的代码生成器的核心类通过配置它的各种属性能够自动生成项目所需的多种代码文件。
// 全局配置
// 创建一个GlobalConfig对象用于配置代码生成的一些全局属性例如生成代码的输出目录、作者信息、生成代码后是否自动打开文件夹等。
// 获取当前项目的根目录路径通过System.getProperty("user.dir")方法可以获取到项目所在的磁盘路径,方便后续设置代码生成的输出位置。
// 设置生成的代码文件输出目录将代码输出到项目的src/main/java目录下这是Java项目中存放主要源代码的常见位置符合Java项目的代码结构规范。
// 设置代码的作者信息,这里设置为"luoyi-",在生成的代码文件中,会在相应的位置(比如类的注释头部等)添加作者标识,方便后续代码维护时知道代码的编写者。
// 设置当代码生成完成之后是否打开代码所在的文件夹这里设置为false表示生成代码后不会自动打开文件夹可根据实际需求选择是否开启该功能。
// gc.setSwagger2(true); 实体属性 Swagger2 注解
// 如果取消注释上面这行代码会在生成的实体类属性上添加Swagger2注解用于在使用Swagger进行接口文档生成和展示时能更好地展示实体类的属性信息方便接口调试和文档查阅。
// 数据源配置
// 创建一个DataSourceConfig对象用于配置代码生成时连接数据库的相关信息使得代码生成器能够获取数据库中的表结构信息从而根据表结构生成相应的代码。
// 设置数据库的连接URL这里配置的是连接本地MySQL数据库localhost:3306中的warehouse数据库同时设置了一些连接参数
// 如使用Unicode编码、不使用SSL加密以及设置字符编码为utf8确保与数据库的正确连接以及数据的正确读取和处理。
// dsc.setSchemaName("public");
// 如果数据库有指定的模式名对于某些数据库如PostgreSQL等有模式概念可以通过这行代码设置在这里MySQL中一般可不设置所以注释掉了。
// 设置数据库驱动的名称这里配置的是MySQL数据库的JDBC驱动名称不过需要确保项目的依赖中已经添加了对应的MySQL驱动包才能正确连接数据库。
// 设置连接数据库的用户名,这里设置为"root"通常是MySQL数据库默认的超级管理员用户名根据实际数据库的配置情况进行相应修改。
// 设置连接数据库的密码,这里设置为"123456",同样要根据实际数据库的密码进行填写,确保能够成功连接到数据库获取表结构信息。
// 包配置
// 创建一个PackageConfig对象用于配置生成代码的包名相关信息决定了代码文件在项目中的包结构便于代码的组织和管理。
// 通过调用scanner方法从控制台获取用户输入的模块名这个模块名会用于后续代码文件的包名构建以及表名前缀等相关配置
// 比如可以根据不同的业务模块来生成不同包名下的代码,使代码结构更加清晰,符合业务模块划分的需求。
// 设置生成代码的顶级包名,这里设置为"com.yeqifu",表示生成的代码文件会放在这个包及其子包下,可根据项目的实际包名规范进行修改。
// 设置Mapper接口对应的XML文件的存放位置这里设置为"mapper.xml"意味着生成的Mapper XML文件会放在相应的目录下方便后续进行数据库操作的SQL语句配置。
// 策略配置
// 创建一个StrategyConfig对象用于配置代码生成的具体策略比如命名规则、是否使用某些框架特性、生成哪些表的代码等决定了生成代码的具体形式和内容。
// 设置字段名和表名是否把下划线换成驼峰命名规则这里设置为将下划线命名转换为驼峰命名符合Java中常见的命名规范使生成的代码变量名和类名等更加规范、易读。
// 设置生成的实体类继承的父类
// strategy.setSuperEntityClass("com.baomidou.ant.common.BaseEntity");
// 如果取消注释上面这行代码,可以指定生成的实体类继承自特定的父类(这里示例是"com.baomidou.ant.common.BaseEntity"
// 这样可以复用父类中的一些通用属性和方法,便于统一管理实体类的公共行为和属性,可根据项目实际需求进行设置。
// 是否启用lombok
// 设置为true表示在生成的实体类中启用Lombok框架的特性Lombok会自动为实体类生成Getter、Setter、构造函数、toString等方法
// 减少手动编写这些重复代码的工作量使实体类代码更加简洁前提是项目中已经引入了Lombok依赖。
// 是否生成restController
// 设置为true表示生成的Controller层代码会采用RESTful风格的控制器符合现代Web开发中常见的接口设计风格方便前后端分离开发以及接口的调用和管理。
// 公共父类
// strategy.setSuperControllerClass("com.baomidou.ant.common.BaseController");
// 如果取消注释上面这行代码可以指定生成的Controller类继承自一个公共的父类这里示例是"com.baomidou.ant.common.BaseController"
// 以便复用父类中的一些通用的控制器相关方法和逻辑,可根据项目中控制器层的设计需求进行设置。
// 写于父类中的公共字段
// strategy.setSuperEntityColumns("id");
// 如果取消注释上面这行代码,可以指定在生成的实体类中,哪些字段是作为公共字段继承自父类的,这里示例是将"id"字段作为公共字段,
// 通常用于一些具有统一主键等情况的实体类设计,根据实际项目的实体类结构特点进行相应设置。
// 设置要生成哪些表 如果不设置就是生成所有的表
// 通过调用scanner方法获取用户输入的表名信息要求用户以英文逗号分割多个表名输入然后将输入的字符串按逗号分割为数组
// 代码生成器会根据这个数组中的表名,只生成对应表的相关代码,若不设置这行代码,则会生成数据库中所有表的相关代码,方便根据实际需求灵活控制生成的代码范围。
// 设置Controller层的映射路径采用连字符风格例如对于一个名为"user_info"的表生成的Controller中对应的请求映射路径可能会类似"/user-info"
// 使接口路径更符合RESTful风格以及常见的URL命名习惯便于接口的访问和识别。
// strategy.setTablePrefix("sys_");
// 设置表名前缀这里可以根据模块名动态设置表名前缀通过pc.getModuleName()获取模块名并添加下划线),也可以使用固定的前缀(如注释中的"sys_"
// 这样在生成代码时会根据设置的前缀来识别和处理表名例如在生成实体类名、Mapper接口名等时会依据表名和前缀进行相应的转换和命名方便代码与表结构的对应和管理。
// 将配置好的策略信息设置到代码生成器AutoGenerator对象中使得代码生成器按照设定的策略来生成代码。
// 调用代码生成器的execute方法启动代码生成的流程根据前面配置好的全局配置、数据源配置、包配置以及策略配置等信息
// 自动生成相应的代码文件包括实体类、Mapper接口、Service层、Controller层等代码快速搭建项目的代码结构。

Loading…
Cancel
Save