一、商品管理
1.商品列表
1>分页查询商品
查询所有仓库。
com.pn.entity.Store.java:
package com.pn.entity;
/** * 仓库表store表对应的实体类: */ @Data @NoArgsConstructor @AllArgsConstructor @ToString public class Store implements Serializable {
private Integer storeId;//仓库id
private String storeName;//仓库名称
private String storeNum;//仓库编码
private String storeAddress;//仓库地址
private String concat;//仓库联系人
private String phone;//仓库联系电话 } |
com.pn.mapper.StoreMapper.java:
package com.pn.mapper;
public interface StoreMapper {
//查询所有仓库的方法 public List<Store> findAllStore(); } |
resources/mapper/StoreMapper.xml:
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.pn.mapper.StoreMapper">
<!-- //查询所有仓库的方法 public List<Store> findAllStore() --> <select id="findAllStore" resultType="com.pn.entity.Store"> select * from store </select>
</mapper> |
com.pn.service.StoreService.java:
package com.pn.service;
public interface StoreService {
//查询所有仓库的业务方法 public List<Store> queryAllStore(); } |
启动类com.pn.WarehouseApplication.java:
package com.pn;
//开启redis注解版缓存 @EnableCaching @MapperScan(basePackages = {"com.pn.mapper", "com.pn.utils"}) @SpringBootApplication public class WarehouseApplication {
public static void main(String[] args) { SpringApplication.run(WarehouseApplication.class, args); }
} |
com.pn.service.impl.StoreServiceImpl.java:
package com.pn.service.impl;
//指定缓存的名称即键的前缀,一般是@CacheConfig标注的类的全类名 @CacheConfig(cacheNames = "com.pn.service.impl.StoreServiceImpl") @Service public class StoreServiceImpl implements StoreService {
//注入StoreMapper @Autowired private StoreMapper storeMapper;
/* 查询所有仓库的业务方法 */ //对查询到的所有仓库进行缓存,缓存到redis的键为all:store @Cacheable(key = "'all:store'") @Override public List<Store> queryAllStore() { //查询所有仓库 return storeMapper.findAllStore(); } } |
com.pn.controller.ProductController.java:
package com.pn.controller;
@RequestMapping("/product") @RestController public class ProductController {
//注入StoreService @Autowired private StoreService storeService;
/** * 查询所有仓库的url接口/product/store-list * * 返回值Result对象给客户端响应查询到的List<Store>; */ @RequestMapping("/store-list") public Result storeList(){ //执行业务 List<Store> storeList = storeService.queryAllStore(); //响应 return Result.ok(storeList); } } |
查询所有品牌。
com.pn.entity.Brand.java:
package com.pn.entity;
/** * 品牌表brand表对应的实体类: */ @Data @NoArgsConstructor @AllArgsConstructor @ToString public class Brand implements Serializable {
private Integer brandId;//品牌id
private String brandName;//品牌名称
private String brandLeter;//品牌首字母
private String brandDesc;//品牌描述 } |
com.pn.mapper.BrandMapper.java:
package com.pn.mapper;
public interface BrandMapper {
//查询所有品牌的方法 public List<Brand> findAllBrand(); } |
resources/mapper/BrandMapper.xml:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.pn.mapper.BrandMapper">
<!-- //查询所有品牌的方法 public List<Brand> findAllBrand() --> <select id="findAllBrand" resultType="com.pn.entity.Brand"> select * from brand </select>
</mapper> |
com.pn.service.BrandService.java:
package com.pn.service; public interface BrandService {
//查询所有品牌的业务方法 public List<Brand> queryAllBrand(); } |
com.pn.service.impl.BrandServiceImpl.java:
package com.pn.service.impl;
//指定缓存的名称即键的前缀,一般是@CacheConfig标注的类的全类名 @CacheConfig(cacheNames = "com.pn.service.impl.BrandServiceImpl") @Service public class BrandServiceImpl implements BrandService {
//注入BrandMapper @Autowired private BrandMapper brandMapper;
/* 查询所有品牌的业务方法 */ //对查询到的所有品牌进行缓存,缓存到redis的键为all:brand @Cacheable(key = "'all:brand'") @Override public List<Brand> queryAllBrand() { //查询所有品牌 return brandMapper.findAllBrand(); } } |
com.pn.controller.ProductController.java:
package com.pn.controller;
@RequestMapping("/product") @RestController public class ProductController {
//注入BrandService @Autowired private BrandService brandService;
/** * 查询所有品牌的url接口/product/brand-list * * 返回值Result对象给客户端响应查询到的List<Brand>; */ @RequestMapping("/brand-list") public Result brandList(){ //执行业务 List<Brand> brandList = brandService.queryAllBrand(); //响应 return Result.ok(brandList); } } |
查询所有商品分类树 -- 添加商品需要。
com.pn.entity.ProductType.java:
package com.pn.entity;
/** * 商品分类表product_type表对应的实体类: */ @Data @NoArgsConstructor @AllArgsConstructor @ToString public class ProductType implements Serializable {
private Integer typeId;//分类id
private Integer parentId;//上级分类id
private String typeCode;//分类代码
private String typeName;//分类名称
private String typeDesc;//分类描述
//自定义List<ProductType>集合属性,用于存储当前分类的所有子级分类 private List<ProductType> childProductCategory; } |
com.pn.mapper.ProductTypeMapper.java:
package com.pn.mapper;
public interface ProductTypeMapper {
//查询所有商品分类的方法 public List<ProductType> findAllProductType(); } |
resources/mapper/ProductTypeMapper.xml:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.pn.mapper.ProductTypeMapper">
<!-- //查询所有商品分类的方法 public List<ProductType> findAllProductType() --> <select id="findAllProductType" resultType="com.pn.entity.ProductType"> select * from product_type </select>
</mapper> |
com.pn.service.ProductTypeService.java:
package com.pn.service;
public interface ProductTypeService {
//查询所有商品分类树的业务方法 public List<ProductType> allProductTypeTree(); } |
com.pn.service.impl.ProductTypeServiceImpl.java:
package com.pn.service.impl;
//指定缓存的名称即键的前缀,一般是@CacheConfig标注的类的全类名 @CacheConfig(cacheNames = "com.pn.service.impl.productTypeServiceImpl") @Service public class productTypeServiceImpl implements ProductTypeService {
//注入ProductTypeMapper @Autowired private ProductTypeMapper productTypeMapper;
/* 查询所有商品分类树的业务方法 */ //对查询到的所有商品分类树进行缓存,缓存到redis的键为all:typeTree @Cacheable(key = "'all:typeTree'") @Override public List<ProductType> allProductTypeTree() { //查询所有商品分类 List<ProductType> allTypeList = productTypeMapper.findAllProductType(); //将所有商品分类List<ProductType>转成商品分类树List<ProductType> List<ProductType> typeTreeList = allTypeToTypeTree(allTypeList, 0); //返回商品分类树List<ProductType> return typeTreeList; }
//将查询到的所有商品分类List<ProductType>转成商品分类树List<ProductType>的算法 private List<ProductType> allTypeToTypeTree(List<ProductType> allTypeList, Integer parentId){
List<ProductType> typeList = new ArrayList<>(); for (ProductType productType : allTypeList) { if(productType.getParentId().equals(parentId)){ typeList.add(productType); } }
for (ProductType productType : typeList) { List<ProductType> childTypeList = allTypeToTypeTree(allTypeList, productType.getTypeId()); productType.setChildProductCategory(childTypeList); }
return typeList; } } |
com.pn.controller.ProductController.java:
package com.pn.controller;
@RequestMapping("/product") @RestController public class ProductController {
//注入ProductTypeService @Autowired private ProductTypeService productTypeService;
/** * 查询所有商品分类树的url接口/product/category-tree * * 返回值Result对象给客户端响应查询到的所有商品分类树List<ProductType>; */ @RequestMapping("/category-tree") public Result categoryTree(){ //执行业务 List<ProductType> typeTreeList = productTypeService.allProductTypeTree(); //响应 return Result.ok(typeTreeList); } } |
查询所有供应商 -- 添加商品需要。
com.pn.entity.Supply.java:
package com.pn.entity;
/** * 供应商表supply表对应的实体类: */ @Data @NoArgsConstructor @AllArgsConstructor @ToString public class Supply implements Serializable {
private Integer supplyId;//供应商id
private String supplyNum;//供应商代码
private String supplyName;//供应商名称
private String supplyIntroduce;//供应商介绍
private String concat;//供应商联系人
private String phone;//供应商联系电话
private String address;//供应商地址
private String isDelete;//是否删除状态,0未删除,1删除 } |
com.pn.mapper.SupplyMapper.java:
package com.pn.mapper;
public interface SupplyMapper {
//查询所有供应商的方法 public List<Supply> findAllSupply(); } |
resources/mapper/SupplyMapper.xml:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.pn.mapper.SupplyMapper">
<!-- //查询所有供应商的方法 public List<Supply> findAllSupply() --> <select id="findAllSupply" resultType="com.pn.entity.Supply"> select * from supply </select>
</mapper> |
com.pn.service.SupplyService.java:
package com.pn.service;
public interface SupplyService {
//查询所有供应商的业务方法 public List<Supply> queryAllSupply(); } |
com.pn.service.impl.SupplyServiceImpl.java:
package com.pn.service.impl;
//指定缓存的名称即键的前缀,一般是@CacheConfig标注的类的全类名 @CacheConfig(cacheNames = "com.pn.service.impl.SupplyServiceImpl") @Service public class SupplyServiceImpl implements SupplyService {
//注入SupplyMapper @Autowired private SupplyMapper supplyMapper;
/* 查询所有供应商的业务方法 */ //对查询到的所有供应商进行缓存,缓存到redis的键为all:supply @Cacheable(key = "'all:supply'") @Override public List<Supply> queryAllSupply() { //查询所有供应商 return supplyMapper.findAllSupply(); } } |
com.pn.controller.ProductController.java:
package com.pn.controller;
@RequestMapping("/product") @RestController public class ProductController {
//注入SupplyService @Autowired private SupplyService supplyService;
/** * 查询所有供应商的url接口/product/supply-list * * 返回值Result对象给客户端响应查询到的List<Supply>; */ @RequestMapping("/supply-list") public Result supplyList(){ //执行业务 List<Supply> supplyList = supplyService.queryAllSupply(); //响应 return Result.ok(supplyList); } } |
查询所有产地 -- 添加商品需要。
com.pn.entity.Place.java:
package com.pn.entity;
/** * 产地表place表对应的实体类: */ @Data @NoArgsConstructor @AllArgsConstructor @ToString public class Place implements Serializable {
private Integer placeId;//产地id
private String placeName;//产地名称
private String placeNum;//产地代码
private String introduce;//产地介绍
private String isDelete;//是否删除状态,0未删除,1删除 } |
com.pn.mapper.PlaceMapper.java:
package com.pn.mapper; public interface PlaceMapper {
//查询所有产地 public List<Place> findAllPlace(); } |
resources/mapper/PlaceMapper.xml:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.pn.mapper.PlaceMapper">
<!-- //查询所有产地 public List<Place> findAllPlace() --> <select id="findAllPlace" resultType="com.pn.entity.Place"> select * from place </select>
</mapper> |
com.pn.service.PlaceService.java:
package com.pn.service;
public interface PlaceService {
//查询所有产地的业务方法 public List<Place> queryAllPlace(); } |
com.pn.service.impl.PlaceServiceImpl.java:
package com.pn.service.impl;
//指定缓存的名称即键的前缀,一般是@CacheConfig标注的类的全类名 @CacheConfig(cacheNames = "com.pn.service.impl.PlaceServiceImpl") @Service public class PlaceServiceImpl implements PlaceService {
//注入PlaceMapper @Autowired private PlaceMapper placeMapper;
/* 查询所有产地的业务方法 */ //对查询到的所有产地进行缓存,缓存到redis的键为all:place @Cacheable(key = "'all:place'") @Override public List<Place> queryAllPlace() { //查询所有产地 return placeMapper.findAllPlace(); } } |
com.pn.controller.ProductController.java:
package com.pn.controller;
@RequestMapping("/product") @RestController public class ProductController {
//注入PlaceService @Autowired private PlaceService placeService;
/** * 查询所有产地的url接口/product/place-list * * 返回值Result对象给客户端响应查询到的List<Place>; */ @RequestMapping("/place-list") public Result placeList(){ //执行业务 List<Place> placeList = placeService.queryAllPlace(); //响应 return Result.ok(placeList); } } |
查询所有单位 -- 添加商品需要。
com.pn.entity.Unit.java:
package com.pn.entity;
/** * 单位表unit表对应的实体类: */ @Data @NoArgsConstructor @AllArgsConstructor @ToString public class Unit implements Serializable {
private Integer unitId;//单位id
private String unitName;//单位
private String unitDesc;//单位描述 } |
com.pn.mapper.UnitMapper.java:
package com.pn.mapper;
public interface UnitMapper {
//查询所有单位的方法 public List<Unit> findAllUnit(); } |
resources/mapper/UnitMapper.xml:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.pn.mapper.UnitMapper">
<!-- //查询所有单位的方法 public List<Unit> findAllUnit() --> <select id="findAllUnit" resultType="com.pn.entity.Unit"> select * from unit </select>
</mapper> |
com.pn.service.UnitService.java:
package com.pn.service;
public interface UnitService {
//查询所有单位的业务方法 public List<Unit> queryAllUnit(); } |
com.pn.service.impl.UnitServiceImpl.java:
package com.pn.service.impl;
//指定缓存的名称即键的前缀,一般是@CacheConfig标注的类的全类名 @CacheConfig(cacheNames = "com.pn.service.impl.UnitServiceImpl") @Service public class UnitServiceImpl implements UnitService {
//注入UnitMapper @Autowired private UnitMapper unitMapper;
/* 查询所有单位的业务方法 */ //对查询到的所有单位进行缓存,缓存到redis的键为all:unit @Cacheable(key = "'all:unit'") @Override public List<Unit> queryAllUnit() { //查询所有单位 return unitMapper.findAllUnit(); } } |
com.pn.controller.ProductController.java:
package com.pn.controller;
@RequestMapping("/product") @RestController public class ProductController {
//注入UnitService @Autowired private UnitService unitService;
/** * 查询所有单位的url接口/product/unit-list * * 返回值Result对象给客户端响应查询到的List<Unit>; */ @RequestMapping("/unit-list") public Result unitList(){ //执行业务 List<Unit> unitList = unitService.queryAllUnit(); //响应 return Result.ok(unitList); } } |
查询所有商品并分页,或者根据仓库、商品名称、品牌、类型、供应商、产地、是否上架、是否过期查询商品并分页。
com.pn.entity.Product.java:
package com.pn.entity;
/** * 商品表product表对应的实体类: */ @Data @NoArgsConstructor @AllArgsConstructor @ToString public class Product {
private Integer productId;//商品id
private Integer storeId;//商品所在仓库id private String storeName;//非表中字段 --商品所在仓库名称
private Integer brandId;//商品所属品牌id private String brandName;//非表中字段 -- 商品所属品牌名称
private String productName;//商品名称
private String productNum;//商品编码
private Integer productInvent;//商品库存
private Integer typeId;//商品所属分类id private String typeName;//非表中字段 -- 商品所属分类名称
private Integer supplyId;//商品供应商id private String supplyName;//非表中字段 -- 商品供应商名称
private Integer placeId;//商品产地id private String placeName;//非表中字段 -- 商品产地名称
private Integer unitId;//商品单位id private String unitName;//非表中字段 -- 商品单位名称
private String introduce;//商品介绍
private String upDownState;//商品上下架状态,1.上架,0.下架
private Double inPrice;//商品进价
private Double salePrice;//商品售价
private Double memPrice;//商品会员价 @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") private Date createTime;//商品的创建时间 @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") private Date updateTime;//商品的修改时间
private Integer createBy;//创建商品的用户id
private Integer updateBy;//修改商品的用户id
private String imgs;//商品的图片地址
@JsonFormat(pattern="yyyy-MM-dd") private Date productDate;//商品的生产日期
@JsonFormat(pattern="yyyy-MM-dd") private Date suppDate;//商品的保质期
private String isOverDate;//非表中字段 -- 商品是否过期,0未过期,1已过期 } |
com.pn.mapper.ProductMapper.java:
package com.pn.mapper;
public interface ProductMapper {
//查询商品总行数的方法 public int selectProductCount(Product product);
//分页查询商品的方法 public List<Product> selectProductPage(@Param("page") Page page, @Param("product") Product product); } |
resources/mapper/ProductMapper.xml:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.pn.mapper.ProductMapper">
<!-- //查询商品总行数的方法 public int selectProductCount(Product product) --> <select id="selectProductCount" resultType="integer"> select count(*) from product t1, store t2, brand t3, product_type t4, supply t5, place t6, unit t7 where t1.store_id = t2.store_id and t1.brand_id = t3.brand_id and t1.type_id = t4.type_id and t1.supply_id = t5.supply_id and t1.place_id = t6.place_id and t1.unit_id = t7.unit_id <if test="storeId != null"> and t1.store_id = #{storeId} </if> <if test="productName != null and productName != ''"> and t1.product_name like concat('%',#{productName},'%') </if> <if test="brandName != null and brandName != ''"> and t3.brand_name like concat('%', #{brandName}, '%') </if> <if test="typeName != null and typeName != ''"> and t4.type_name like concat('%', #{typeName}, '%') </if> <if test="supplyName != null and supplyName != ''"> and t5.supply_name like concat('%', #{supplyName}, '%') </if> <if test="placeName != null and placeName != ''"> and t6.place_name like concat('%', #{placeName}, '%') </if> <if test="upDownState != null and upDownState != ''"> and t1.up_down_state = #{upDownState} </if> <!-- 如果方法参数Product对象的isOverDate属性值为1(查询已过期商品),则查询 当前时间大于product表中supp_date列的时间的商品; 反之如果方法参数Product对象的isOverDate属性值为0(查询未过期商品),则 查询当前时间小于product表中supp_date列的时间的商品; --> <if test="isOverDate != null and isOverDate != '' and isOverDate==1"> and date_format(now(), '%y-%m-%d') > t1.supp_date </if> <if test="isOverDate != null and isOverDate != '' and isOverDate==0"> and date_format(now(), '%y-%m-%d') < t1.supp_date </if> </select>
<!-- //分页查询商品的方法 public List<Product> selectProductPage(@Param("page") Page page, @Param("product") Product product) --> <select id="selectProductPage" resultType="com.pn.entity.Product"> select t1.*, t2.store_name, t3.brand_name, t4.type_name, t5.supply_name, t6.place_name, t7.unit_name from product t1, store t2, brand t3, product_type t4, supply t5, place t6, unit t7 where t1.store_id = t2.store_id and t1.brand_id = t3.brand_id and t1.type_id = t4.type_id and t1.supply_id = t5.supply_id and t1.place_id = t6.place_id and t1.unit_id = t7.unit_id <if test="product.storeId != null"> and t1.store_id = #{product.storeId} </if> <if test="product.productName != null and product.productName != ''"> and t1.product_name like concat('%',#{product.productName},'%') </if> <if test="product.brandName != null and product.brandName != ''"> and t3.brand_name like concat('%', #{product.brandName}, '%') </if> <if test="product.typeName != null and product.typeName != ''"> and t4.type_name like concat('%', #{product.typeName}, '%') </if> <if test="product.supplyName != null and product.supplyName != ''"> and t5.supply_name like concat('%', #{product.supplyName}, '%') </if> <if test="product.placeName != null and product.placeName != ''"> and t6.place_name like concat('%', #{product.placeName}, '%') </if> <if test="product.upDownState != null and product.upDownState != ''"> and t1.up_down_state = #{product.upDownState} </if> <if test="product.isOverDate != null and product.isOverDate != '' and product.isOverDate==1"> and date_format(now(), '%y-%m-%d') > t1.supp_date </if> <if test="product.isOverDate != null and product.isOverDate != '' and product.isOverDate==0"> and date_format(now(), '%y-%m-%d') < t1.supp_date </if> order by t1.create_time limit #{page.limitIndex}, #{page.pageSize} </select> </mapper> |
com.pn.service.ProductService.java:
package com.pn.service;
public interface ProductService {
//分页查询商品的业务方法 public Page queryProductPage(Page page, Product product); } |
com.pn.service.impl.ProductServiceImpl.java:
package com.pn.service.impl;
@Service public class ProductServiceImpl implements ProductService {
//注入ProductMapper @Autowired private ProductMapper productMapper;
//分页查询商品的业务方法 @Override public Page queryProductPage(Page page, Product product) {
//查询商品总行数 int productCount = productMapper.selectProductCount(product);
//分页查询商品 List<Product> productList = productMapper.selectProductPage(page, product);
//将查询到的总行数和当前页数据组装到Page对象 page.setTotalNum(productCount); page.setResultList(productList);
return page; } } |
com.pn.controller.ProductController.java:
package com.pn.controller;
@RequestMapping("/product") @RestController public class ProductController {
//注入ProductService @Autowired private ProductService productService;
/** * 分页查询商品的url接口/product/product-page-list * * 参数Page对象用于接收请求参数页码pageNum、每页行数pageSize; * 参数Product对象用于接收请求参数仓库id storeId、商品名称productName、 * 品牌名称brandName、分类名称typeName、供应商名称supplyName、产地名称 * placeName、上下架状态upDownState、是否过期isOverDate; * * 返回值Result对象向客户端响应组装了所有分页信息的Page对象; */ @RequestMapping("/product-page-list") public Result productPageList(Page page, Product product){ //执行业务 page = productService.queryProductPage(page, product); //响应 return Result.ok(page); } } |
com.pn.filter.SecurityFilter.java:
package com.pn.filter;
/** * 登录限制过滤器: */ public class SecurityFilter implements Filter {
//将redis模板定义为其成员变量 private StringRedisTemplate redisTemplate;
//成员变量redis模板的set方法 public void setRedisTemplate(StringRedisTemplate redisTemplate) { this.redisTemplate = redisTemplate; }
/** * 过滤器拦截到请求执行的方法: */ @Override public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest)req; HttpServletResponse response = (HttpServletResponse)resp;
//获取请求url接口 String path = request.getServletPath(); /* 白名单请求都直接放行: */ List<String> urlList = new ArrayList<>(); urlList.add("/captcha/captchaImage"); urlList.add("/login"); urlList.add("/logout"); //对static下的/img/upload中的静态资源图片的访问直接放行 if(urlList.contains(path)||path.contains("/img/upload")){ chain.doFilter(request, response); return; }
/* 其它请求都校验token: */ //拿到前端归还的token String clientToken = request.getHeader(WarehouseConstants.HEADER_TOKEN_NAME); //校验token,校验通过请求放行 if(StringUtils.hasText(clientToken)&&redisTemplate.hasKey(clientToken)){ chain.doFilter(request, response); return; } //校验失败,向前端响应失败的Result对象转成的json串 Result result = Result.err(Result.CODE_ERR_UNLOGINED, "请登录!"); String jsonStr = JSON.toJSONString(result); response.setContentType("application/json;charset=UTF-8"); PrintWriter out = response.getWriter(); out.print(jsonStr); out.flush(); out.close(); }
} |
2>添加商品
1)上传图片
com.pn.controller.ProductController.java:
package com.pn.controller;
@RequestMapping("/product") @RestController public class ProductController {
/** * 将配置文件的file.upload-path属性值注入给控制器的uploadPath属性, * 其为图片上传到项目的目录路径(类路径classes即resources下的static/img/upload); */ @Value("${file.upload-path}") private String uploadPath;
/** * 上传图片的url接口/product/img-upload * * 参数MultipartFile file对象封装了上传的图片; * * @CrossOrigin表示该url接口允许跨域请求; */ @CrossOrigin @PostMapping("/img-upload") public Result uploadImg(MultipartFile file){
try { //拿到图片上传到的目录(类路径classes下的static/img/upload)的File对象 File uploadDirFile = ResourceUtils.getFile(uploadPath); //拿到图片上传到的目录的磁盘路径 String uploadDirPath = uploadDirFile.getAbsolutePath(); //拿到图片保存到的磁盘路径 String fileUploadPath = uploadDirPath + "\\" + file.getOriginalFilename(); //保存图片 file.transferTo(new File(fileUploadPath)); //成功响应 return Result.ok("图片上传成功!"); } catch (IOException e) { //失败响应 return Result.err(Result.CODE_ERR_BUSINESS, "图片上传失败!"); } } } |
com.pn.filter.SecurityFilter.java:
package com.pn.filter;
/** * 登录限制过滤器: */ public class SecurityFilter implements Filter {
//将redis模板定义为其成员变量 private StringRedisTemplate redisTemplate;
//成员变量redis模板的set方法 public void setRedisTemplate(StringRedisTemplate redisTemplate) { this.redisTemplate = redisTemplate; }
/** * 过滤器拦截到请求执行的方法: */ @Override public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest)req; HttpServletResponse response = (HttpServletResponse)resp;
//获取请求url接口 String path = request.getServletPath(); /* 白名单请求都直接放行: */ List<String> urlList = new ArrayList<>(); urlList.add("/captcha/captchaImage"); urlList.add("/login"); urlList.add("/logout"); //对上传图片的url接口/product/img-upload的请求直接放行 urlList.add("/product/img-upload"); //对static下的/img/upload中的静态资源图片的访问直接放行 if(urlList.contains(path)||path.contains("/img/upload")){ chain.doFilter(request, response); return; }
/* 其它请求都校验token: */ //拿到前端归还的token String clientToken = request.getHeader(WarehouseConstants.HEADER_TOKEN_NAME); //校验token,校验通过请求放行 if(StringUtils.hasText(clientToken)&&redisTemplate.hasKey(clientToken)){ chain.doFilter(request, response); return; } //校验失败,向前端响应失败的Result对象转成的json串 Result result = Result.err(Result.CODE_ERR_UNLOGINED, "请登录!"); String jsonStr = JSON.toJSONString(result); response.setContentType("application/json;charset=UTF-8"); PrintWriter out = response.getWriter(); out.print(jsonStr); out.flush(); out.close(); }
} |
2)添加商品
com.pn.mapper.ProductMapper.java:
package com.pn.mapper;
public interface ProductMapper {
//添加商品的方法 public int insertProduct(Product product); } |
resources/mapper/ProductMapper.xml:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.pn.mapper.ProductMapper">
<!-- //添加商品的方法 public int insertProduct(Product product) --> <insert id="insertProduct"> insert into product values ( null, #{storeId}, #{brandId}, #{productName}, #{productNum}, #{productInvent}, #{typeId}, #{supplyId}, #{placeId}, #{unitId}, #{introduce}, 0, #{inPrice}, #{salePrice}, #{memPrice}, now(), null, #{createBy}, null, #{imgs}, #{productDate}, #{suppDate} ) </insert> </mapper> |
com.pn.service.ProductService.java:
package com.pn.service;
public interface ProductService { //添加商品的业务方法 public Result saveProduct(Product product); } |
com.pn.service.impl.ProductServiceImpl.java:
package com.pn.service.impl;
@Service public class ProductServiceImpl implements ProductService {
//注入ProductMapper @Autowired private ProductMapper productMapper;
/* 将配置文件的file.access-path属性值注入给service的accessPath属性, * 其为上传的图片保存到数据库中的访问地址的目录路径/img/upload/; */ @Value("${file.access-path}") private String accessPath;
//添加商品的业务方法 @Override public Result saveProduct(Product product) {
//处理上传的图片的访问地址 -- /img/upload/图片名称 product.setImgs(accessPath+product.getImgs());
//添加商品 int i = productMapper.insertProduct(product);
if(i>0){ return Result.ok("添加商品成功!"); }
return Result.err(Result.CODE_ERR_BUSINESS, "添加商品失败!"); } } |
com.pn.controller.ProductController.java:
package com.pn.controller;
@RequestMapping("/product") @RestController public class ProductController {
//注入ProductService @Autowired private ProductService productService;
//注入TokenUtils @Autowired private TokenUtils tokenUtils;
/** * 添加商品的url接口/product/product-add * * @RequestBody Product product将添加的商品信息的json串数据封装到参数Product对象; * @RequestHeader(WarehouseConstants.HEADER_TOKEN_NAME) String token * 将请求头Token的值即客户端归还的token赋值给参数变量token; */ @RequestMapping("/product-add") public Result addProduct(@RequestBody Product product, @RequestHeader(WarehouseConstants.HEADER_TOKEN_NAME) String token){
//获取当前登录的用户 CurrentUser currentUser = tokenUtils.getCurrentUser(token); //获取当前登录的用户id,即添加商品的用户id int createBy = currentUser.getUserId(); product.setCreateBy(createBy);
//执行业务 Result result = productService.saveProduct(product);
//响应 return result; } } |
3>修改商品上下架状态
新添加的商品默认是下架状态,需要设置商品上架。
com.pn.mapper.ProductMapper.java:
package com.pn.mapper;
public interface ProductMapper {
//根据商品id修改商品的上下架状态 public int updateStateById(Product product); } |
resources/mapper/ProductMapper.xml:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.pn.mapper.ProductMapper">
<!-- //根据商品id修改商品的上下架状态 public int updateStateById(Product product) --> <update id="updateStateById"> update product set up_down_state = #{upDownState} where product_id = #{productId} </update> </mapper> |
com.pn.service.ProductService.java:
package com.pn.service;
public interface ProductService {
//修改商品上下架状态的业务方法 public Result updateProductState(Product product); } |
com.pn.service.impl.ProductServiceImpl.java:
package com.pn.service.impl;
@Service public class ProductServiceImpl implements ProductService {
//注入ProductMapper @Autowired private ProductMapper productMapper;
//修改商品上下架状态的业务方法 @Override public Result updateProductState(Product product) { //根据商品id修改商品上下架状态 int i = productMapper.updateStateById(product); if(i>0){ return Result.ok("修改成功!"); } return Result.err(Result.CODE_ERR_BUSINESS, "修改失败!"); } } |
com.pn.controller.ProductController.java:
package com.pn.controller;
@RequestMapping("/product") @RestController public class ProductController {
//注入ProductService @Autowired private ProductService productService; /** * 修改商品上下架状态的url接口/product/state-change * * @RequestBody Product product用于接收并封装请求json数据; */ @RequestMapping("/state-change") public Result changeProductState(@RequestBody Product product){ //执行业务 Result result = productService.updateProductState(product); //响应 return result; } } |
4>删除商品
com.pn.mapper.ProductMapper.java:
package com.pn.mapper;
public interface ProductMapper {
//根据商品id删除商品的方法 public int deleteProductById(Integer productId); } |
resources/mapper/ProductMapper.xml:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.pn.mapper.ProductMapper">
<!-- //根据商品id删除商品的方法 public int deleteProductById(Integer productId) --> <delete id="deleteProductById"> delete from product where product_id = #{productId} </delete>
</mapper> |
com.pn.service.ProductService.java:
package com.pn.service;
public interface ProductService {
//删除商品的业务方法 public Result deleteProduct(Integer productId); } |
com.pn.service.impl.ProductServiceImpl.java:
package com.pn.service.impl;
@Service public class ProductServiceImpl implements ProductService {
//注入ProductMapper @Autowired private ProductMapper productMapper;
//删除商品的业务方法 @Override public Result deleteProduct(Integer productId) { //根据商品id删除商品 int i = productMapper.deleteProductById(productId); if(i>0){ return Result.ok("商品删除成功!"); } return Result.err(Result.CODE_ERR_BUSINESS, "商品删除失败!"); } } |
com.pn.controller.ProductController.java:
package com.pn.controller;
@RequestMapping("/product") @RestController public class ProductController {
//注入ProductService @Autowired private ProductService productService; /** * 删除商品的url接口/product/product-delete/{productId} */ @RequestMapping("/product-delete/{productId}") public Result deleteProduct(@PathVariable Integer productId){ //执行业务 Result result = productService.deleteProduct(productId); //响应 return result; } } |
5>修改商品
com.pn.mapper.ProductMapper.java:
package com.pn.mapper;
public interface ProductMapper {
//根据商品id修改商品的方法 public int updateProductById(Product product); } |
resources/mapper/ProductMapper.xml:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.pn.mapper.ProductMapper">
<!-- //根据商品id修改商品的方法 public int updateProductById(Product product) --> <update id="updateProductById"> <!--商品上下架状态、创建时间、创建者字段值不用改--> update product set store_id = #{storeId}, brand_id = #{brandId}, product_name = #{productName}, product_num = #{productNum}, product_invent = #{productInvent}, type_id = #{typeId}, supply_id = #{supplyId}, place_id = #{placeId}, unit_id = #{unitId}, introduce = #{introduce}, in_price = #{inPrice}, sale_price = #{salePrice}, mem_price = #{memPrice}, update_time = now(), update_by = #{updateBy}, imgs = #{imgs}, product_date = #{productDate}, supp_date = #{suppDate} where product_id = #{productId} </update>
</mapper> |
com.pn.service.ProductService.java:
package com.pn.service;
public interface ProductService {
//修改商品的业务方法 public Result updateProduct(Product product); } |
com.pn.service.impl.ProductServiceImpl.java:
package com.pn.service.impl;
@Service public class ProductServiceImpl implements ProductService {
//注入ProductMapper @Autowired private ProductMapper productMapper;
/* 将配置文件的file.access-path属性值注入给service的accessPath属性, * 其为上传的图片保存到数据库中的访问地址的目录路径/img/upload/; */ @Value("${file.access-path}") private String accessPath;
//修改商品的业务方法 @Override public Result updateProduct(Product product) {
/* 处理商品上传的图片的访问地址: 如果product对象的imgs属性值没有以/img/upload/开始,说明商品的图片 被修改了即上传了新的图片,那么product对象的imgs属性值只是图片的名称, 则给图片名称前拼接/img/upload构成商品新上传的图片的访问地址; */ if(!product.getImgs().startsWith(accessPath)){ product.setImgs(accessPath+product.getImgs()); } //根据商品id修改商品信息 int i = productMapper.updateProductById(product); if(i>0){ return Result.ok("商品修改成功!"); } return Result.err(Result.CODE_ERR_BUSINESS,"商品修改失败!"); } } |
com.pn.controller.ProductController.java:
package com.pn.controller;
@RequestMapping("/product") @RestController public class ProductController {
//注入ProductService @Autowired private ProductService productService;
/** * 修改商品的url接口/product/product-update * * @RequestBody Product product将请求传递的json数据封装到参数Product对象; * @RequestHeader(WarehouseConstants.HEADER_TOKEN_NAME) String token * 将请求头Token的值即客户端归还的token赋值给参数变量token; */ @RequestMapping("/product-update") public Result updateProduct(@RequestBody Product product, @RequestHeader(WarehouseConstants.HEADER_TOKEN_NAME) String token){
//获取当前登录的用户 CurrentUser currentUser = tokenUtils.getCurrentUser(token); //获取当前登录的用户id,即修改商品的用户id int updateBy = currentUser.getUserId(); product.setUpdateBy(updateBy);
//执行业务 Result result = productService.updateProduct(product);
//响应 return result; } } |
6>添加采购单
com.pn.entity.Purchase.java:
package com.pn.entity;
/** * 采购单表buy_list表的实体类: */ @Data @NoArgsConstructor @AllArgsConstructor @ToString public class Purchase {
private Integer buyId;//采购单id
private Integer productId;//采购单采购的商品id
private Integer storeId;//采购单采购的商品所在仓库id
private Integer buyNum;//预计采购的商品数量
private Integer factBuyNum;//实际采购的商品数量
@JsonFormat(pattern = "yyyy-MM-dd") private Date buyTime;//采购时间
private Integer supplyId;//采购单采购的商品的供应商id
private Integer placeId;//采购单采购的商品的产地id
private String buyUser;//采购人
private String phone;//采购人联系电话
private String isIn;//是否生成入库单,1.是,0.否 } |
com.pn.mapper.PurchaseMapper.java:
package com.pn.mapper;
public interface PurchaseMapper {
//添加采购单的方法 public int insertPurchase(Purchase purchase); } |
resources/mapper/PurchaseMapper.xml:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.pn.mapper.PurchaseMapper">
<!-- //添加采购单的方法 public int insertPurchase(Purchase purchase) --> <insert id="insertPurchase"> insert into buy_list values( null, #{productId}, #{storeId}, #{buyNum}, null, now(), #{supplyId}, #{placeId}, #{buyUser}, #{phone}, 0 ) </insert>
</mapper> |
com.pn.service.PurchaseService.java:
package com.pn.service;
public interface PurchaseService {
//添加采购单的业务方法 public Result savePurchase(Purchase purchase); } |
com.pn.service.impl.PurchaseServiceImpl.java:
package com.pn.service.impl;
@Service public class PurchaseServiceImpl implements PurchaseService {
//注入PurchaseMapper @Autowired private PurchaseMapper purchaseMapper;
//添加采购单的业务方法 @Override public Result savePurchase(Purchase purchase) { //添加采购单 int i = purchaseMapper.insertPurchase(purchase); if(i>0){ return Result.ok("采购单添加成功!"); } return Result.err(Result.CODE_ERR_BUSINESS, "采购单添加失败!"); } } |
com.pn.controller.PurchaseController.java:
package com.pn.controller;
@RequestMapping("/purchase") @RestController public class PurchaseController {
//注入PurchaseService @Autowired private PurchaseService purchaseService;
/** * 添加采购单的url接口/purchase/purchase-add */ @RequestMapping("/purchase-add") public Result addPurchase(@RequestBody Purchase purchase){ //执行业务 Result result = purchaseService.savePurchase(purchase); //响应 return result; } } |
7>添加出库单
com.pn.entity.OutStore.java:
package com.pn.entity;
/** * 出库单表out_store表的实体类: */ @Data @NoArgsConstructor @AllArgsConstructor @ToString public class OutStore {
private Integer outsId;//出库单id
private Integer productId;//出库单出库的商品id
private Integer storeId;//出库单出库的商品所在仓库id
private Integer tallyId;//理货员id
private Double outPrice;//商品的出库价格
private Integer outNum;//出库的商品数量
private Integer createBy;//创建出库单的用户id
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") private Date createTime;//创建出库单的时间
private String isOut;//是否出库,0.未出库,1.已出库 } |
com.pn.mapper.OutStoreMapper.java:
package com.pn.mapper;
public interface OutStoreMapper {
//添加出库单的方法 public int insertOutStore(OutStore outStore); } |
resources/mapper/OutStoreMapper.xml:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.pn.mapper.OutStoreMapper">
<!-- //添加出库单的方法 public int insertOutStore(OutStore outStore) --> <insert id="insertOutStore"> insert into out_store values( null, #{productId}, #{storeId}, null, null, #{outNum}, #{createBy}, now(), 0 ) </insert>
</mapper> |
com.pn.service.OutStoreService.java:
package com.pn.service;
public interface OutStoreService {
//添加出库单的业务方法 public Result saveOutStore(OutStore outStore); } |
com.pn.service.impl.OutStoreServiceImpl.java:
package com.pn.service.impl;
@Service public class OutStoreServiceImpl implements OutStoreService {
//注入OutStoreMapper @Autowired private OutStoreMapper outStoreMapper;
//添加出库单的业务方法 @Override public Result saveOutStore(OutStore outStore) { //添加出库单 int i = outStoreMapper.insertOutStore(outStore); if(i>0){ return Result.ok("添加出库单成功!"); } return Result.err(Result.CODE_ERR_BUSINESS, "添加出库单失败!"); } } |
com.pn.controller.OutStoreController.java:
package com.pn.controller;
@RequestMapping("/outstore") @RestController public class OutStoreController {
//注入OutStoreService @Autowired private OutStoreService outStoreService;
//注入TokenUtils @Autowired private TokenUtils tokenUtils;
/** * 添加出库单的url接口/outstore/outstore-add * * @RequestBody OutStore outStore将添加的出库单信息的json数据封装到参数OutStore对象; * @RequestHeader(WarehouseConstants.HEADER_TOKEN_NAME) String token * 将请求头Token的值即客户端归还的token赋值给参数变量token; */ @RequestMapping("/outstore-add") public Result addOutStore(@RequestBody OutStore outStore, @RequestHeader(WarehouseConstants.HEADER_TOKEN_NAME) String token){
//获取当前登录的用户 CurrentUser currentUser = tokenUtils.getCurrentUser(token); //获取当前登录的用户id,即添加出库单的用户id int createBy = currentUser.getUserId(); outStore.setCreateBy(createBy);
//执行业务 Result result = outStoreService.saveOutStore(outStore);
//响应 return result; } } |
2.商品分类
1>查询商品分类树
com.pn.controller.ProductTypeController.java:
package com.pn.controller;
@RequestMapping("/productCategory") @RestController public class ProductTypeController {
//注入ProductTypeService @Autowired private ProductTypeService productTypeService;
/** * 查询商品分类树的url接口/productCategory/product-category-tree * * 返回值Result对象给客户端响应查询到的所有商品分类树List<ProductType>; */ @RequestMapping("/product-category-tree") public Result productCategoryTree(){ //执行业务 List<ProductType> productTypeList = productTypeService.allProductTypeTree(); //响应 return Result.ok(productTypeList); }
} |
2>添加商品分类
校验分类编码是否已存在。
com.pn.mapper.ProductTypeMapper.java:
package com.pn.mapper;
public interface ProductTypeMapper {
//根据分类编码查询商品分类的方法 public ProductType findTypeByCode(String typeCode); } |
resources/mapper/ProductTypeMapper.xml:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.pn.mapper.ProductTypeMapper">
<!-- //根据分类编码查询商品分类的方法 public ProductType findTypeByCode(String typeCode) --> <select id="findTypeByCode" resultType="com.pn.entity.ProductType"> select * from product_type where type_code = #{typeCode} </select>
</mapper> |
com.pn.service.ProductTypeService.java:
package com.pn.service;
public interface ProductTypeService {
//校验分类编码是否已存在的业务方法 public Result queryTypeByCode(String typeCode); } |
com.pn.service.impl.ProductTypeServiceImpl.java:
package com.pn.service.impl;
//指定缓存的名称即键的前缀,一般是@CacheConfig标注的类的全类名 @CacheConfig(cacheNames = "com.pn.service.impl.productTypeServiceImpl") @Service public class productTypeServiceImpl implements ProductTypeService {
//注入ProductTypeMapper @Autowired private ProductTypeMapper productTypeMapper;
//校验分类编码是否已存在的业务方法 @Override public Result queryTypeByCode(String typeCode) {
//根据分类编码查询商品分类 ProductType productType = productTypeMapper.findTypeByCode(typeCode);
return Result.ok(productType==null); } } |
com.pn.controller.ProductTypeController.java:
package com.pn.controller;
@RequestMapping("/productCategory") @RestController public class ProductTypeController {
//注入ProductTypeService @Autowired private ProductTypeService productTypeService;
/** * 校验分类编码是否已存在的url接口/productCategory/verify-type-code */ @RequestMapping("/verify-type-code") public Result checkTypeCode(String typeCode){ //执行业务 Result result = productTypeService.queryTypeByCode(typeCode); //响应 return result; } } |
com.pn.mapper.ProductTypeMapper.java:
package com.pn.mapper;
public interface ProductTypeMapper {
//添加商品分类的方法 public int insertProductType(ProductType productType); } |
resources/mapper/ProductTypeMapper.xml:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.pn.mapper.ProductTypeMapper">
<!-- //添加商品分类的方法 public int insertProductType(ProductType productType) --> <insert id="insertProductType"> insert into product_type values( null, #{parentId}, #{typeCode}, #{typeName}, #{typeDesc} ) </insert> </mapper> |
com.pn.service.ProductTypeService.java:
package com.pn.service;
public interface ProductTypeService {
//添加商品分类的业务方法 public Result saveProductType(ProductType productType); } |
com.pn.service.impl.ProductTypeServiceImpl.java:
package com.pn.service.impl;
//指定缓存的名称即键的前缀,一般是@CacheConfig标注的类的全类名 @CacheConfig(cacheNames = "com.pn.service.impl.productTypeServiceImpl") @Service public class productTypeServiceImpl implements ProductTypeService {
//注入ProductTypeMapper @Autowired private ProductTypeMapper productTypeMapper;
/* 添加商品分类的业务方法
@CacheEvict(key = "'all:typeTree'")清除所有商品分类树的缓存; */ @CacheEvict(key = "'all:typeTree'") @Override public Result saveProductType(ProductType productType) { //添加商品分类 int i = productTypeMapper.insertProductType(productType); if(i>0){ return Result.ok("分类添加成功!"); } return Result.err(Result.CODE_ERR_BUSINESS, "分类添加失败!"); } } |
com.pn.controller.ProductTypeController.java:
package com.pn.controller;
@RequestMapping("/productCategory") @RestController public class ProductTypeController {
//注入ProductTypeService @Autowired private ProductTypeService productTypeService;
/** * 添加商品分类的url接口/productCategory/type-add * * @RequestBody ProductType productType将请求传递的json数据封装到参数ProductType对象; */ @RequestMapping("/type-add") public Result addProductType(@RequestBody ProductType productType){ //执行业务 Result result = productTypeService.saveProductType(productType); //响应 return result; } } |
3>删除商品分类
com.pn.mapper.ProductTypeMapper.java:
package com.pn.mapper;
public interface ProductTypeMapper {
//根据分类id删除分类及其所有子级分类的方法 public int deleteProductType(Integer typeId); } |
resources/mapper/ProductTypeMapper.xml:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.pn.mapper.ProductTypeMapper">
<!-- //根据分类id删除分类及其所有子级分类的方法 public int deleteProductType(Integer typeId) --> <delete id="deleteProductType"> delete from product_type where type_id = #{typeId} or parent_id = #{typeId} </delete>
</mapper> |
com.pn.service.ProductTypeService.java:
package com.pn.service;
public interface ProductTypeService {
//删除商品分类的业务方法 public Result removeProductType(Integer typeId); } |
com.pn.service.impl.ProductTypeServiceImpl.java:
package com.pn.service.impl;
//指定缓存的名称即键的前缀,一般是@CacheConfig标注的类的全类名 @CacheConfig(cacheNames = "com.pn.service.impl.productTypeServiceImpl") @Service public class productTypeServiceImpl implements ProductTypeService {
//注入ProductTypeMapper @Autowired private ProductTypeMapper productTypeMapper;
/* 删除商品分类的业务方法
@CacheEvict(key = "'all:typeTree'")清除所有商品分类树的缓存; */ @CacheEvict(key = "'all:typeTree'") @Override public Result removeProductType(Integer typeId) { //根据分类id删除分类及其所有子级分类 int i = productTypeMapper.deleteProductType(typeId); if(i>0){ return Result.ok("分类删除成功!"); } return Result.err(Result.CODE_ERR_BUSINESS, "分类删除失败!"); } } |
com.pn.controller.ProductTypeController.java:
package com.pn.controller;
@RequestMapping("/productCategory") @RestController public class ProductTypeController {
//注入ProductTypeService @Autowired private ProductTypeService productTypeService;
/** * 删除商品分类的url接口/productCategory/type-delete/{typeId} * * @PathVariable Integer typeId将路径占位符typeId的值赋值给参数变量typeId; */ @RequestMapping("/type-delete/{typeId}") public Result deleteType(@PathVariable Integer typeId){ //执行业务 Result result = productTypeService.removeProductType(typeId); //响应 return result; } } |
4>修改商品分类
com.pn.mapper.ProductTypeMapper.java:
package com.pn.mapper;
public interface ProductTypeMapper {
//根据分类id修改分类的方法 public int updateTypeById(ProductType productType); } |
resources/mapper/ProductTypeMapper.xml:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.pn.mapper.ProductTypeMapper">
<!-- //根据分类id修改分类的方法 public int updateTypeById(ProductType productType) --> <update id="updateTypeById"> update product_type set type_name = #{typeName}, type_desc = #{typeDesc} where type_id = #{typeId} </update>
</mapper> |
com.pn.service.ProductTypeService.java:
package com.pn.service;
public interface ProductTypeService {
//修改商品分类的业务方法 public Result updateProductType(ProductType productType); } |
com.pn.service.impl.ProductTypeServiceImpl.java:
package com.pn.service.impl;
//指定缓存的名称即键的前缀,一般是@CacheConfig标注的类的全类名 @CacheConfig(cacheNames = "com.pn.service.impl.productTypeServiceImpl") @Service public class productTypeServiceImpl implements ProductTypeService {
//注入ProductTypeMapper @Autowired private ProductTypeMapper productTypeMapper;
/* 修改商品分类的业务方法
@CacheEvict(key = "'all:typeTree'")清除所有商品分类树的缓存; */ @CacheEvict(key = "'all:typeTree'") @Override public Result updateProductType(ProductType productType) { //根据分类id修改分类 int i = productTypeMapper.updateTypeById(productType); if(i>0){ return Result.ok("分类修改成功!"); } return Result.err(Result.CODE_ERR_BUSINESS, "分类修改失败!"); } } |
com.pn.controller.ProductTypeController.java:
package com.pn.controller;
@RequestMapping("/productCategory") @RestController public class ProductTypeController {
//注入ProductTypeService @Autowired private ProductTypeService productTypeService;
/** * 修改商品分类的url接口/productCategory/type-update * * @RequestBody ProductType productType将请求传递的json数据封装到参数ProductType对象; */ @RequestMapping("/type-update") public Result updateType(@RequestBody ProductType productType){ //执行业务 Result result = productTypeService.updateProductType(productType); //响应 return result; } } |
二、采购管理
1.采购列表
查询所有仓库。
com.pn.controller.PurchaseController.java:
package com.pn.controller;
@RequestMapping("/purchase") @RestController public class PurchaseController {
//注入StoreService @Autowired private StoreService storeService;
/** * 查询所有仓库的url接口/purchase/store-list */ @RequestMapping("/store-list") public Result storeList(){ //执行业务 List<Store> storeList = storeService.queryAllStore(); //响应 return Result.ok(storeList); } } |
查询所有采购单并分页,或者根据仓库、商品名称、采购人、是否生成入库单、起止时间查询采购单并分页。
com.pn.entity.Purchase.java:
package com.pn.entity;
/** * 采购单表buy_list表的实体类: */ @Data @NoArgsConstructor @AllArgsConstructor @ToString public class Purchase {
private Integer buyId;//采购单id
private Integer productId;//采购单采购的商品id
private Integer storeId;//采购单采购的商品所在仓库id
private Integer buyNum;//预计采购的商品数量
private Integer factBuyNum;//实际采购的商品数量
@JsonFormat(pattern = "yyyy-MM-dd") private Date buyTime;//采购时间
private Integer supplyId;//采购单采购的商品的供应商id
private Integer placeId;//采购单采购的商品的产地id
private String buyUser;//采购人
private String phone;//采购人联系电话
private String isIn;//是否生成入库单,1.是,0.否
//---------------追加属性---------------------------
private String productName;//商品名称
private String storeName;//仓库名称
private String startTime;//搜索起始时间
private String endTime;//搜索结束时间 } |
com.pn.mapper.PurchaseMapper.java:
package com.pn.mapper;
public interface PurchaseMapper {
//查询采购单总行数的方法 public int selectPurchaseCount(Purchase purchase);
//分页查询采购单的方法 public List<Purchase> selectPurchasePage(@Param("page") Page page, @Param("purchase") Purchase purchase); } |
resources/mapper/PurchaseMapper.xml:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.pn.mapper.PurchaseMapper">
<!-- //查询采购单总行数的方法 public int selectPurchaseCount(Purchase purchase) --> <select id="selectPurchaseCount" resultType="integer"> select count(*) from buy_list t1, product t2, store t3 where t1.product_id = t2.product_id and t1.store_id = t3.store_id <if test="storeId != null"> and t1.store_id = #{storeId} </if> <if test="productName != null and productName != ''"> and t2.product_name like concat('%', #{productName}, '%') </if> <if test="buyUser != null and buyUser != ''"> and t1.buy_user like concat('%', #{buyUser}, '%') </if> <if test="isIn != null and isIn != ''"> and t1.is_in = #{isIn} </if> <if test="startTime != null and startTime != ''"> and t1.buy_time >= #{startTime} </if> <if test="endTime != null and endTime != ''"> and t1.buy_time <= #{endTime} </if> </select>
<!-- //分页查询采购单的方法 public List<Purchase> selectPurchasePage(@Param("page") Page page, @Param("purchase") Purchase purchase) --> <select id="selectPurchasePage" resultType="com.pn.entity.Purchase"> select t1.*, t2.product_name, t3.store_name from buy_list t1, product t2, store t3 where t1.product_id = t2.product_id and t1.store_id = t3.store_id <if test="purchase.storeId != null"> and t1.store_id = #{purchase.storeId} </if> <if test="purchase.productName != null and purchase.productName != ''"> and t2.product_name like concat('%', #{purchase.productName}, '%') </if> <if test="purchase.buyUser != null and purchase.buyUser != ''"> and t1.buy_user like concat('%', #{purchase.buyUser}, '%') </if> <if test="purchase.isIn != null and purchase.isIn != ''"> and t1.is_in = #{purchase.isIn} </if> <if test="purchase.startTime != null and purchase.startTime != ''"> and t1.buy_time >= #{purchase.startTime} </if> <if test="purchase.endTime != null and purchase.endTime != ''"> and t1.buy_time <= #{purchase.endTime} </if> order by t1.buy_time desc limit #{page.limitIndex}, #{page.pageSize} </select> </mapper> |
com.pn.service.PurchaseService.java:
package com.pn.service;
public interface PurchaseService {
//分页查询采购单的业务方法 public Page queryPurchasePage(Page page, Purchase purchase); } |
com.pn.service.impl.PurchaseServiceImpl.java:
package com.pn.service.impl;
@Service public class PurchaseServiceImpl implements PurchaseService {
//注入PurchaseMapper @Autowired private PurchaseMapper purchaseMapper;
//分页查询采购单的业务方法 @Override public Page queryPurchasePage(Page page, Purchase purchase) {
//查询采购单总行数 int purchaseCount = purchaseMapper.selectPurchaseCount(purchase);
//分页查询采购单 List<Purchase> purchaseList = purchaseMapper.selectPurchasePage(page, purchase);
//将查询到的总行数和当前页数据组装到Page对象 page.setTotalNum(purchaseCount); page.setResultList(purchaseList);
return page; } } |
com.pn.controller.PurchaseController.java:
package com.pn.controller;
@RequestMapping("/purchase") @RestController public class PurchaseController {
//注入PurchaseService @Autowired private PurchaseService purchaseService;
/** * 分页查询采购单的url接口/purchase/purchase-page-list * * 参数Page对象用于接收请求参数页码pageNum、每页行数pageSize; * 参数Purchase对象用于接收请求参数仓库id storeId、商品名称productName、 * 采购人buyUser、是否生成入库单isIn、起止时间startTime和endTime; * * 返回值Result对象向客户端响应组装了所有分页信息的Page对象; */ @RequestMapping("/purchase-page-list") public Result purchasePageList(Page page, Purchase purchase){ //执行业务 page = purchaseService.queryPurchasePage(page, purchase); //响应 return Result.ok(page); } } |
2.删除采购单
com.pn.mapper.PurchaseMapper.java:
package com.pn.mapper;
public interface PurchaseMapper {
//根据id删除采购单的方法 public int deletePurchaseById(Integer buyId); } |
resources/mapper/PurchaseMapper.xml:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.pn.mapper.PurchaseMapper">
<!-- //根据id删除采购单的方法 public int deletePurchaseById(Integer buyId) --> <delete id="deletePurchaseById"> delete from buy_list where buy_id = #{buyId} </delete>
</mapper> |
com.pn.service.PurchaseService.java:
package com.pn.service;
public interface PurchaseService {
//删除采购单的业务方法 public Result deletePurchase(Integer buyId); } |
com.pn.service.impl.PurchaseServiceImpl.java:
package com.pn.service.impl;
@Service public class PurchaseServiceImpl implements PurchaseService {
//注入PurchaseMapper @Autowired private PurchaseMapper purchaseMapper;
//删除采购单的业务方法 @Override public Result deletePurchase(Integer buyId) { //根据id删除采购单 int i = purchaseMapper.deletePurchaseById(buyId); if(i>0){ return Result.ok("采购单删除成功!"); } return Result.err(Result.CODE_ERR_BUSINESS, "采购单删除失败!"); } } |
com.pn.controller.PurchaseController.java:
package com.pn.controller;
@RequestMapping("/purchase") @RestController public class PurchaseController {
//注入PurchaseService @Autowired private PurchaseService purchaseService;
/** * 删除采购单的url接口/purchase/purchase-delete/{buyId} * * @PathVariable Integer buyId将路径占位符buyId的值赋值给参数变量buyId; */ @RequestMapping("/purchase-delete/{buyId}") public Result deletePurchase(@PathVariable Integer buyId){ //执行业务 Result result = purchaseService.deletePurchase(buyId); //响应 return result; } } |
3.修改采购单
com.pn.mapper.PurchaseMapper.java:
package com.pn.mapper;
public interface PurchaseMapper {
//根据id修改采购单的方法 public int updatePurchaseById(Purchase purchase); } |
resources/mapper/PurchaseMapper.xml:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.pn.mapper.PurchaseMapper">
<!-- //根据id修改采购单的方法 public int updatePurchaseById(Purchase purchase) --> <update id="updatePurchaseById"> update buy_list set buy_num = #{buyNum}, fact_buy_num = #{factBuyNum} where buy_id = #{buyId} </update>
</mapper> |
com.pn.service.PurchaseService.java:
package com.pn.service;
public interface PurchaseService {
//修改采购单的业务方法 public Result updatePurchase(Purchase purchase); } |
com.pn.service.impl.PurchaseServiceImpl.java:
package com.pn.service.impl;
@Service public class PurchaseServiceImpl implements PurchaseService {
//注入PurchaseMapper @Autowired private PurchaseMapper purchaseMapper;
//修改采购单的业务方法 @Override public Result updatePurchase(Purchase purchase) { //根据id修改采购单 int i = purchaseMapper.updatePurchaseById(purchase); if(i>0){ return Result.ok("采购单修改成功!"); } return Result.err(Result.CODE_ERR_BUSINESS, "采购单修改失败!"); } } |
com.pn.controller.PurchaseController.java:
package com.pn.controller;
@RequestMapping("/purchase") @RestController public class PurchaseController {
//注入PurchaseService @Autowired private PurchaseService purchaseService;
/** * 修改采购单的url接口/purchase/purchase-update * * @RequestBody Purchase purchase将请求传递的json数据封装到参数Purchase对象; */ @RequestMapping("/purchase-update") public Result updatePurchase(@RequestBody Purchase purchase){ //执行业务 Result result = purchaseService.updatePurchase(purchase); //响应 return result; } } |
4.生成入库单
com.pn.entity.InStore.java:
package com.pn.entity;
/** * 入库单表in_store表的实体类: */ @Data @NoArgsConstructor @AllArgsConstructor public class InStore {
private Integer insId;//入库单id
private Integer storeId;//仓库id
private Integer productId;//商品id
private Integer inNum;//入库数量
private Integer createBy;//创建入库单的用户id
@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss") private Date createTime;//创建时间
private Integer isIn;//是否入库,1.是,0.否 } |
com.pn.mapper.InStoreMapper.java:
package com.pn.mapper;
public interface InStoreMapper {
//添加入库单的方法 public int insertInStore(InStore inStore); } |
resources/mapper/InStoreMapper.xml:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.pn.mapper.InStoreMapper">
<!-- //添加入库单的方法 public int insertInStore(InStore inStore) --> <insert id="insertInStore"> insert into in_store values( null, #{storeId}, #{productId}, #{inNum}, #{createBy}, now(), 0 ) </insert>
</mapper> |
com.pn.mapper.PurchaseMapper.java:
package com.pn.mapper;
public interface PurchaseMapper {
//根据id将采购单状态改为已入库的方法 public int updateIsInById(Integer buyId); } |
resources/mapper/PurchaseMapper.xml:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.pn.mapper.PurchaseMapper">
<!-- //根据id将采购单状态改为已入库的方法 public int updateIsInById(Integer buyId) --> <update id="updateIsInById"> update buy_list set is_in = 1 where buy_id = #{buyId} </update>
</mapper> |
com.pn.service.InStoreService.java:
package com.pn.service;
public interface InStoreService {
//添加入库单的业务方法 public Result saveInStore(InStore inStore, Integer buyId); } |
com.pn.service.impl.InStoreServiceImpl.java:
package com.pn.service.impl;
@Service public class InStoreServiceImpl implements InStoreService {
//注入InStoreMapper @Autowired private InStoreMapper inStoreMapper;
//注入PurchaseMapper @Autowired private PurchaseMapper purchaseMapper;
//添加入库单的业务方法 @Transactional//事务处理 @Override public Result saveInStore(InStore inStore, Integer buyId) { //添加入库单 int i = inStoreMapper.insertInStore(inStore); if(i>0){ //根据id将采购单状态改为已入库 int j = purchaseMapper.updateIsInById(buyId); if(j>0){ return Result.ok("入库单添加成功!"); } return Result.err(Result.CODE_ERR_BUSINESS, "入库单添加失败!"); } return Result.err(Result.CODE_ERR_BUSINESS, "入库单添加失败!"); } } |
com.pn.controller.PurchaseController.java:
package com.pn.controller;
@RequestMapping("/purchase") @RestController public class PurchaseController {
//注入TokenUtils @Autowired private TokenUtils tokenUtils;
//注入InStoreService @Autowired private InStoreService inStoreService;
/** * 添加入库单的url接口/purchase/in-warehouse-record-add * * @RequestBody Purchase purchase将请求传递的json数据封装到参数Purchase对象; * @RequestHeader(WarehouseConstants.HEADER_TOKEN_NAME) String token * 将请求头Token的值即客户端归还的token赋值给参数变量token; */ @RequestMapping("/in-warehouse-record-add") public Result addInStore(@RequestBody Purchase purchase, @RequestHeader(WarehouseConstants.HEADER_TOKEN_NAME) String token){ //获取当前登录的用户 CurrentUser currentUser = tokenUtils.getCurrentUser(token); //获取当前登录的用户id -- 创建入库单的用户id int createBy = currentUser.getUserId();
//创建InStore对象封装添加的入库单的信息 InStore inStore = new InStore(); inStore.setStoreId(purchase.getStoreId()); inStore.setProductId(purchase.getProductId()); inStore.setInNum(purchase.getFactBuyNum()); inStore.setCreateBy(createBy);
//执行业务 Result result = inStoreService.saveInStore(inStore, purchase.getBuyId());
//响应 return result; } } |
三、入库管理
1.入库列表
查询所有仓库。
com.pn.controller.InStoreController.java:
package com.pn.controller;
@RequestMapping("/instore") @RestController public class InStoreController {
//注入StoreService @Autowired private StoreService StoreService;
/** * 查询所有仓库的url接口/instore/store-list */ @RequestMapping("/store-list") public Result storeList(){ //执行业务 List<Store> storeList = StoreService.queryAllStore(); //响应 return Result.ok(storeList); } } |
查询所有入库单并分页,或者根据仓库、商品名称、起止时间查询入库单并分页。
com.pn.entity.InStore.java:
package com.pn.entity;
/** * 入库单表in_store表的实体类: */ @Data @NoArgsConstructor @AllArgsConstructor public class InStore {
private Integer insId;//入库单id
private Integer storeId;//仓库id
private Integer productId;//商品id
private Integer inNum;//入库数量
private Integer createBy;//创建入库单的用户id
@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss") private Date createTime;//创建时间
private Integer isIn;//是否入库,1.是,0.否
//-----------------追加的属性--------------------
private String productName;//商品名称
private String startTime;//起始时间
private String endTime;//结束时间
private String storeName;//仓库名称
private String userCode;//创建入库单的用户的名称
private BigDecimal inPrice;//商品入库价格 } |
com.pn.mapper.InStoreMapper.java:
package com.pn.mapper;
public interface InStoreMapper {
//查询入库单总行数的方法 public int selectInStoreCount(InStore inStore);
//分页查询入库单的方法 public List<InStore> selectInStorePage(@Param("page") Page page, @Param("inStore") InStore inStore); } |
resources/mapper/InStoreMapper.xml:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.pn.mapper.InStoreMapper">
<!-- //查询入库单总行数的方法 public int selectInStoreCount(InStore inStore) --> <select id="selectInStoreCount" resultType="integer"> select count(*) from in_store t1, store t2, product t3, user_info t4 where t1.store_id = t2.store_id and t1.product_id = t3.product_id and t1.create_by = t4.user_id
<if test="storeId != null"> and t1.store_id = #{storeId} </if> <if test="productName != null and productName != ''"> and t3.product_name like concat('%', #{productName}, '%') </if> <if test="startTime != null and startTime != ''"> and t1.create_time >= #{startTime} </if> <if test="endTime != null and endTime != ''"> and t1.create_time <= #{endTime} </if> </select>
<!-- //分页查询入库单的方法 public List<InStore> selectInStorePage(@Param("page") Page page, @Param("inStore") InStore inStore) --> <select id="selectInStorePage" resultType="com.pn.entity.InStore"> select t1.*, t2.store_name, t3.product_name, t3.in_price, t4.user_code from in_store t1, store t2, product t3, user_info t4 where t1.store_id = t2.store_id and t1.product_id = t3.product_id and t1.create_by = t4.user_id
<if test="inStore.storeId != null"> and t1.store_id = #{inStore.storeId} </if> <if test="inStore.productName != null and inStore.productName != ''"> and t3.product_name like concat('%', #{inStore.productName}, '%') </if> <if test="inStore.startTime != null and inStore.startTime != ''"> and t1.create_time >= #{inStore.startTime} </if> <if test="inStore.endTime != null and inStore.endTime != ''"> and t1.create_time <= #{inStore.endTime} </if>
order by t1.create_time desc limit #{page.limitIndex}, #{page.pageSize} </select> </mapper> |
com.pn.service.InStoreService.java:
package com.pn.service;
public interface InStoreService {
//分页查询入库单的业务方法 public Page queryInStorePage(Page page, InStore inStore); } |
com.pn.service.impl.InStoreServiceImpl.java:
package com.pn.service.impl;
@Service public class InStoreServiceImpl implements InStoreService {
//注入InStoreMapper @Autowired private InStoreMapper inStoreMapper;
//分页查询入库单的业务方法 @Override public Page queryInStorePage(Page page, InStore inStore) {
//查询入库单总行数 int inStoreCount = inStoreMapper.selectInStoreCount(inStore);
//分页查询入库单 List<InStore> inStoreList = inStoreMapper.selectInStorePage(page, inStore);
//将查询到的总行数和当前页数据封装到Page对象 page.setTotalNum(inStoreCount); page.setResultList(inStoreList);
return page; } } |
com.pn.controller.InStoreController.java:
package com.pn.controller;
@RequestMapping("/instore") @RestController public class InStoreController {
//注入InStoreService @Autowired private InStoreService inStoreService;
/** * 分页查询入库单的url接口/instore/instore-page-list * * 参数Page对象用于接收请求参数页码pageNum、每页行数pageSize; * 参数InStore对象用于接收请求参数仓库id storeId、商品名称productName、 * 起止时间startTime和endTime; * * 返回值Result对象向客户端响应组装了所有分页信息的Page对象; */ @RequestMapping("/instore-page-list") public Result inStorePageList(Page page, InStore inStore){ //执行业务 page = inStoreService.queryInStorePage(page, inStore); //响应 return Result.ok(page); } } |
2.确定入库
com.pn.mapper.ProductMapper.java:
package com.pn.mapper;
public interface ProductMapper {
//根据商品id增加商品库存的方法 public int addInventById(Integer productId, Integer invent); } |
resources/mapper/ProductMapper.xml:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.pn.mapper.ProductMapper">
<!-- //根据商品id增加商品库存的方法 public int addInventById(Integer productId, Integer invent) --> <update id="addInventById"> update product set product_invent = product_invent + #{param2} where product_id = #{param1} </update>
</mapper> |
com.pn.mapper.InStoreMapper.java:
package com.pn.mapper;
public interface InStoreMapper {
//根据id将入库单状态改为已入库的方法 public int updateIsInById(Integer insId); } |
resources/mapper/InStoreMapper.xml:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.pn.mapper.InStoreMapper">
<!-- //根据id将入库单状态改为已入库的方法 public int updateIsInById(Integer insId) --> <update id="updateIsInById"> update in_store set is_in = 1 where ins_id = #{insId} </update>
</mapper> |
com.pn.service.InStoreService.java:
package com.pn.service;
public interface InStoreService {
//确定入库的业务方法 public Result confirmInStore(InStore inStore); } |
com.pn.service.impl.InStoreServiceImpl.java:
package com.pn.service.impl;
@Service public class InStoreServiceImpl implements InStoreService {
//注入InStoreMapper @Autowired private InStoreMapper inStoreMapper;
//注入ProductMapper @Autowired private ProductMapper productMapper;
//确定入库的业务方法 @Transactional//事务处理 @Override public Result confirmInStore(InStore inStore) {
//根据id将入库单状态改为已入库 int i = inStoreMapper.updateIsInById(inStore.getInsId()); if(i>0){ //根据商品id增加商品库存 int j = productMapper.addInventById(inStore.getProductId(), inStore.getInNum()); if(j>0){ return Result.ok("入库成功!"); } return Result.err(Result.CODE_ERR_BUSINESS, "入库失败!"); } return Result.err(Result.CODE_ERR_BUSINESS, "入库失败!"); } } |
com.pn.controller.InStoreController.java:
package com.pn.controller;
@RequestMapping("/instore") @RestController public class InStoreController {
//注入InStoreService @Autowired private InStoreService inStoreService;
/** * 确定入库的url接口/instore/instore-confirm * * @RequestBody InStore inStore将请求传递的json数据封装到参数InStore对象; */ @RequestMapping("/instore-confirm") public Result confirmInStore(@RequestBody InStore inStore){ //执行业务 Result result = inStoreService.confirmInStore(inStore); //响应 return result; } } |
四、出库管理
1.出库列表
查询所有仓库。
com.pn.controller.OutStoreController.java:
package com.pn.controller;
@RequestMapping("/outstore") @RestController public class OutStoreController {
//注入StoreService @Autowired private StoreService storeService;
/** * 查询所有仓库的url接口/outstore/store-list */ @RequestMapping("/store-list") public Result storeList(){ //执行业务 List<Store> storeList = storeService.queryAllStore(); //响应 return Result.ok(storeList); } } |
查询所有出库单并分页,或者根据仓库、商品名称、是否出库、起止时间查询出库单并分页。
com.pn.entity.OutStore.java:
package com.pn.entity;
/** * 出库单表out_store表的实体类: */ @Data @NoArgsConstructor @AllArgsConstructor @ToString public class OutStore {
private Integer outsId;//出库单id
private Integer productId;//出库单出库的商品id
private Integer storeId;//出库单出库的商品所在仓库id
private Integer tallyId;//理货员id
private Double outPrice;//商品的出库价格
private Integer outNum;//出库的商品数量
private Integer createBy;//创建出库单的用户id
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") private Date createTime;//创建出库单的时间
private String isOut;//是否出库,0.未出库,1.已出库
//------------------追加的属性-------------------------
private String productName;//商品名称
private String startTime;//起始时间
private String endTime;//结束时间
private String storeName;//仓库名称
private String userCode;//创建出库单的用户的名称 } |
com.pn.mapper.OutStoreMapper.java:
package com.pn.mapper;
public interface OutStoreMapper {
//查询出库单总行数的方法 public int outStoreCount(OutStore outStore);
//分页查询出库单的方法 public List<OutStore> outStorePage(@Param("page") Page page, @Param("outStore") OutStore outStore); } |
resources/mapper/OutStoreMapper.xml:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.pn.mapper.OutStoreMapper">
<!-- //查询出库单总行数的方法 public int outStoreCount(OutStore outStore); --> <select id="outStoreCount" resultType="integer"> select count(*) from out_store t1, store t2, product t3, user_info t4 where t1.store_id = t2.store_id and t1.product_id = t3.product_id and t1.create_by = t4.user_id
<if test="storeId != null"> and t1.store_id = #{storeId} </if> <if test="productName != null and productName != ''"> and t3.product_name like concat('%', #{productName}, '%') </if> <if test="isOut != null and isOut != ''"> and t1.is_out = #{isOut} </if> <if test="startTime != null and startTime != ''"> and t1.create_time >= #{startTime} </if> <if test="endTime != null and endTime != ''"> and t1.create_time <= #{endTime} </if> </select>
<!-- //分页查询出库单的方法 public List<OutStore> outStorePage(@Param("page") Page page, @Param("outStore") OutStore outStore); --> <select id="outStorePage" resultType="com.pn.entity.OutStore"> select t1.*, t2.store_name, t3.product_name, t4.user_code from out_store t1, store t2, product t3, user_info t4 where t1.store_id = t2.store_id and t1.product_id = t3.product_id and t1.create_by = t4.user_id
<if test="outStore.storeId != null"> and t1.store_id = #{outStore.storeId} </if> <if test="outStore.productName != null and outStore.productName != ''"> and t3.product_name like concat('%', #{outStore.productName}, '%') </if> <if test="outStore.isOut != null and outStore.isOut != ''"> and t1.is_out = #{outStore.isOut} </if> <if test="outStore.startTime != null and outStore.startTime != ''"> and t1.create_time >= #{outStore.startTime} </if> <if test="outStore.endTime != null and outStore.endTime != ''"> and t1.create_time <= #{outStore.endTime} </if>
order by t1.create_time desc limit #{page.limitIndex}, #{page.pageSize} </select> </mapper> |
com.pn.service.OutStoreService.java:
package com.pn.service;
public interface OutStoreService {
//分页查询出库单的业务方法 public Page outStorePage(Page page, OutStore outStore); } |
com.pn.service.impl.OutStoreServiceImpl.java:
package com.pn.service.impl;
@Service public class OutStoreServiceImpl implements OutStoreService {
//注入OutStoreMapper @Autowired private OutStoreMapper outStoreMapper;
//分页查询出库单的业务方法 @Override public Page outStorePage(Page page, OutStore outStore) {
//查询出库单总行数 int outStoreCount = outStoreMapper.outStoreCount(outStore);
//分页查询出库单 List<OutStore> outStoreList = outStoreMapper.outStorePage(page, outStore);
//将查询到的总行数和当前页数据封装到Page对象 page.setTotalNum(outStoreCount); page.setResultList(outStoreList);
return page; } } |
com.pn.controller.OutStoreController.java:
package com.pn.controller;
@RequestMapping("/outstore") @RestController public class OutStoreController {
//注入OutStoreService @Autowired private OutStoreService outStoreService;
/** * 分页查询出库单的url接口/outstore/outstore-page-list * * 参数Page对象用于接收请求参数页码pageNum、每页行数pageSize; * 参数OutStore对象用于接收请求参数仓库id storeId、商品名称productName、 * 是否出库isOut、起止时间startTime和endTime; * * 返回值Result对象向客户端响应组装了所有分页信息的Page对象; */ @RequestMapping("/outstore-page-list") public Result outStorePageList(Page page, OutStore outStore){ //执行业务 page = outStoreService.outStorePage(page, outStore); //响应 return Result.ok(page); } } |
2.确定出库
com.pn.mapper.ProductMapper.java:
package com.pn.mapper;
public interface ProductMapper {
//根据商品id增加商品库存的方法 public int addInventById(Integer productId, Integer invent);
//根据商品id查询商品的方法 public Product selectProductById(Integer productId); } |
resources/mapper/ProductMapper.xml:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.pn.mapper.ProductMapper">
<!-- //根据商品id增加商品库存的方法 public int addInventById(Integer productId, Integer invent) --> <update id="addInventById"> update product set product_invent = product_invent + #{param2} where product_id = #{param1} </update>
<!-- //根据商品id查询商品的方法 public Product selectProductById(Integer productId) --> <select id="selectProductById" resultType="com.pn.entity.Product"> select * from product where product_id = #{productId} </select>
</mapper> |
com.pn.mapper.OutStoreMapper.java:
package com.pn.mapper;
public interface OutStoreMapper {
//根据id将出库单状态改为已出库的方法 public int updateIsOutById(Integer outsId); } |
resources/mapper/OutStoreMapper.xml:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.pn.mapper.OutStoreMapper">
<!-- //根据id将出库单状态改为已出库的方法 public int updateIsOutById(Integer outsId) --> <update id="updateIsOutById"> update out_store set is_out = 1 where outs_id = #{outsId} </update>
</mapper> |
com.pn.service.OutStoreService.java:
package com.pn.service;
public interface OutStoreService {
//确定出库的业务方法 public Result confirmOutStore(OutStore outStore); } |
com.pn.service.impl.OutStoreServiceImpl.java:
package com.pn.service.impl;
@Service public class OutStoreServiceImpl implements OutStoreService {
//注入OutStoreMapper @Autowired private OutStoreMapper outStoreMapper;
//注入ProductMapper @Autowired private ProductMapper productMapper;
//确定出库的业务方法 @Transactional//事务处理 @Override public Result confirmOutStore(OutStore outStore) {
//根据商品id查询商品 Product product = productMapper.selectProductById(outStore.getProductId()); if(outStore.getOutNum()>product.getProductInvent()){ return Result.err(Result.CODE_ERR_BUSINESS, "商品库存不足"); }
//根据id将出库单状态改为已出库 int i = outStoreMapper.updateIsOutById(outStore.getOutsId()); if(i>0){ //根据商品id减商品库存 int j = productMapper.addInventById(outStore.getProductId(), -outStore.getOutNum()); if(j>0){ return Result.ok("出库成功!"); } return Result.err(Result.CODE_ERR_BUSINESS, "出库失败!"); } return Result.err(Result.CODE_ERR_BUSINESS, "出库失败!"); } } |
com.pn.controller.OutStoreController.java:
package com.pn.controller;
@RequestMapping("/outstore") @RestController public class OutStoreController {
//注入OutStoreService @Autowired private OutStoreService outStoreService;
/** * 确定出库的url接口/outstore/outstore-confirm * * @RequestBody OutStore outStore将请求传递的json数据封装到参数OutStore对象; */ @RequestMapping("/outstore-confirm") public Result confirmOutStore(@RequestBody OutStore outStore){ //执行业务 Result result = outStoreService.confirmOutStore(outStore); //响应 return result; } } |
五、统计查询
统计报表
查询各个仓库的商品库存数量。
com.pn.entity.Statistics.java:
package com.pn.entity;
/** * 统计实体类: */ @Data @NoArgsConstructor @AllArgsConstructor public class Statistics {
private Integer storeId;//仓库id
private String storeName;//仓库名称
private Integer totalInvent;//仓库商品库存数 } |
com.pn.mapper.StatisticsMapper.java:
package com.pn.mapper;
public interface StatisticsMapper {
//统计各个仓库商品库存数量的方法 public List<Statistics> statisticsStoreInvent(); } |
resources/mapper/StatisticsMapper.xml:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.pn.mapper.StatisticsMapper">
<!-- //统计各个仓库商品库存数量的方法 public List<Statistics> statisticsStoreInvent() --> <select id="statisticsStoreInvent" resultType="com.pn.entity.Statistics"> select t1.store_id, t2.store_name, ifnull(sum(t1.product_invent),0) totalInvent from product t1, store t2 where t1.store_id = t2.store_id group by t1.store_id, t2.store_name </select>
</mapper> |
com.pn.service.StatisticsService.java:
package com.pn.service;
public interface StatisticsService {
//统计各个仓库商品库存数量的业务方法 public List<Statistics> statisticsStoreInvent(); } |
com.pn.service.impl.StatisticsServiceImpl.java:
package com.pn.service.impl;
@Service public class StatisticsServiceImpl implements StatisticsService {
//注入StatisticsMapper @Autowired private StatisticsMapper statisticsMapper;
//统计各个仓库商品库存数量的业务方法 @Override public List<Statistics> statisticsStoreInvent() { return statisticsMapper.statisticsStoreInvent(); } } |
com.pn.controller.StatisticsController.java:
package com.pn.controller;
@RequestMapping("/statistics") @RestController public class StatisticsController {
//注入StatisticsService @Autowired private StatisticsService statisticsService;
/** * 统计各个仓库商品库存数量的url接口/statistics/store-invent */ @RequestMapping("/store-invent") public Result statisticsStoreInvent(){ //执行业务 List<Statistics> statisticsList = statisticsService.statisticsStoreInvent(); //响应 return Result.ok(statisticsList); } } |
六、仓库管理
1.仓库列表
查询所有仓库并分页,或者根据仓库名称、仓库地址、联系人、电话查询仓库并分页。
com.pn.mapper.StoreMapper.java:
package com.pn.mapper;
public interface StoreMapper {
//查询仓库总行数的方法 public int selectStoreCount(Store store);
//分页查询仓库的方法 public List<Store> selectStorePage(@Param("page") Page page, @Param("store") Store store); } |
resources/mapper/StoreMapper.xml:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.pn.mapper.StoreMapper">
<!-- //查询仓库总行数的方法 public int selectStoreCount(Store store); --> <select id="selectStoreCount" resultType="integer"> select count(*) from store <where> <if test="storeName != null and storeName != ''"> and store_name like concat('%', #{storeName}, '%') </if> <if test="storeAddress != null and storeAddress != ''"> and store_address like concat('%', #{storeAddress}, '%') </if> <if test="concat != null and concat != ''"> and concat like concat('%', #{concat}, '%') </if> <if test="phone != null and phone != ''"> and phone like concat('%', #{phone}, '%') </if> </where> </select>
<!-- //分页查询仓库的方法 public List<Store> selectStorePage(@Param("page") Page page, @Param("store") Store store); --> <select id="selectStorePage" resultType="com.pn.entity.Store"> select * from store <where> <if test="store.storeName != null and store.storeName != ''"> and store_name like concat('%', #{store.storeName}, '%') </if> <if test="store.storeAddress != null and store.storeAddress != ''"> and store_address like concat('%', #{store.storeAddress}, '%') </if> <if test="store.concat != null and store.concat != ''"> and concat like concat('%', #{store.concat}, '%') </if> <if test="store.phone != null and store.phone != ''"> and phone like concat('%', #{store.phone}, '%') </if> </where> limit #{page.limitIndex}, #{page.pageSize} </select> </mapper> |
com.pn.service.StoreService.java:
package com.pn.service;
public interface StoreService {
//分页查询仓库的业务方法 public Page queryStorePage(Page page, Store store); } |
com.pn.service.impl.StoreServiceImpl.java:
package com.pn.service.impl;
//指定缓存的名称即键的前缀,一般是@CacheConfig标注的类的全类名 @CacheConfig(cacheNames = "com.pn.service.impl.StoreServiceImpl") @Service public class StoreServiceImpl implements StoreService {
//注入StoreMapper @Autowired private StoreMapper storeMapper;
//分页查询仓库的业务方法 @Override public Page queryStorePage(Page page, Store store) {
//查询仓库总行数 int storeCount = storeMapper.selectStoreCount(store);
//分页查询仓库 List<Store> storeList = storeMapper.selectStorePage(page, store);
//将查到的总行数和当前页数据封装到Page对象 page.setTotalNum(storeCount); page.setResultList(storeList);
return page; } } |
com.pn.controller.StoreController.java:
package com.pn.controller;
@RequestMapping("/store") @RestController public class StoreController {
//注入StoreService @Autowired private StoreService storeService;
/** * 分页查询仓库的url接口/store/store-page-list * * 参数Page对象用于接收请求参数页码pageNum、每页行数pageSize; * 参数Store对象用于接收请求参数仓库名称storeName、仓库地址storeAddress、 * 联系人concat、联系电话phone; * * 返回值Result对象向客户端响应组装了所有分页信息的Page对象; */ @RequestMapping("/store-page-list") public Result storePageList(Page page, Store store){ //执行业务 page = storeService.queryStorePage(page, store); //响应 return Result.ok(page); } } |
2.添加仓库
校验仓库编号是否已存在。
com.pn.mapper.StoreMapper.java:
package com.pn.mapper; public interface StoreMapper {
//添加仓库的方法 public int insertStore(Store store); } |
resources/mapper/StoreMapper.xml:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.pn.mapper.StoreMapper">
<!-- //添加仓库的方法 public int insertStore(Store store) --> <insert id="insertStore"> insert into store values( null, #{storeName}, #{storeNum}, #{storeAddress}, #{concat}, #{phone} ) </insert> </mapper> |
com.pn.service.StoreService.java:
package com.pn.service;
public interface StoreService {
//添加仓库的业务方法 public Result saveStore(Store store); } |
com.pn.service.impl.StoreServiceImpl.java:
package com.pn.service.impl;
//指定缓存的名称即键的前缀,一般是@CacheConfig标注的类的全类名 @CacheConfig(cacheNames = "com.pn.service.impl.StoreServiceImpl") @Service public class StoreServiceImpl implements StoreService {
//注入StoreMapper @Autowired private StoreMapper storeMapper; //添加仓库的业务方法 @Override public Result saveStore(Store store) { //添加仓库 int i = storeMapper.insertStore(store); if(i>0){ return Result.ok("仓库添加成功!"); } return Result.err(Result.CODE_ERR_BUSINESS, "仓库添加失败!"); } } |
com.pn.controller.StoreController.java:
package com.pn.controller;
@RequestMapping("/store") @RestController public class StoreController {
//注入StoreService @Autowired private StoreService storeService;
/** * 添加仓库的url接口/store/store-add * * @RequestBody Store store将请求传递的json数据封装到参数Store对象; */ @RequestMapping("/store-add") public Result addStore(@RequestBody Store store){ //执行业务 Result result = storeService.saveStore(store); //响应 return result; } } |
3.修改仓库
com.pn.mapper.StoreMapper.java:
package com.pn.mapper;
public interface StoreMapper {
//根据仓库id修改仓库的方法 public int updateStoreById(Store store); } |
resources/mapper/StoreMapper.xml:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.pn.mapper.StoreMapper">
<!-- //根据仓库id修改仓库的方法 public int updateStoreById(Store store) --> <update id="updateStoreById"> update store set store_name = #{storeName}, store_address = #{storeAddress}, concat = #{concat}, phone = #{phone} where store_id = #{storeId} </update>
</mapper> |
com.pn.service.StoreService.java:
package com.pn.service;
public interface StoreService {
//修改仓库的业务方法 public Result updateStore(Store store); } |
com.pn.service.impl.StoreServiceImpl.java:
package com.pn.service.impl;
//指定缓存的名称即键的前缀,一般是@CacheConfig标注的类的全类名 @CacheConfig(cacheNames = "com.pn.service.impl.StoreServiceImpl") @Service public class StoreServiceImpl implements StoreService {
//注入StoreMapper @Autowired private StoreMapper storeMapper;
//修改仓库的业务方法 @Override public Result updateStore(Store store) { //根据仓库id修改仓库 int i = storeMapper.updateStoreById(store); if(i>0){ return Result.ok("仓库修改成功!"); } return Result.err(Result.CODE_ERR_BUSINESS, "仓库修改失败!"); } } |
com.pn.controller.StoreController.java:
package com.pn.controller;
@RequestMapping("/store") @RestController public class StoreController {
//注入StoreService @Autowired private StoreService storeService;
/** * 修改仓库的url接口/store/store-update * * @RequestBody Store store将请求传递的json数据封装到参数Store对象; */ @RequestMapping("/store-update") public Result updateStore(@RequestBody Store store){ //执行业务 Result result = storeService.updateStore(store); //响应 return result; } } |
4.删除仓库
com.pn.mapper.StoreMapper.java:
package com.pn.mapper; public interface StoreMapper {
//根据仓库id删除仓库的方法 public int deleteStoreById(Integer storeId); } |
resources/mapper/StoreMapper.xml:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.pn.mapper.StoreMapper">
<!-- //根据仓库id删除仓库的方法 public int deleteStoreById(Integer storeId) --> <delete id="deleteStoreById"> delete from store where store_id = #{storeId} </delete>
</mapper> |
com.pn.service.StoreService.java:
package com.pn.service;
public interface StoreService {
//删除仓库的业务方法 public Result deleteStore(Integer storeId); } |
com.pn.service.impl.StoreServiceImpl.java:
package com.pn.service.impl;
//指定缓存的名称即键的前缀,一般是@CacheConfig标注的类的全类名 @CacheConfig(cacheNames = "com.pn.service.impl.StoreServiceImpl") @Service public class StoreServiceImpl implements StoreService {
//注入StoreMapper @Autowired private StoreMapper storeMapper;
//删除仓库的业务方法 @Override public Result deleteStore(Integer storeId) { //根据仓库id删除仓库 int i = storeMapper.deleteStoreById(storeId); if(i>0){ return Result.ok("仓库删除成功!"); } return Result.err(Result.CODE_ERR_BUSINESS, "仓库删除失败!"); } } |
com.pn.controller.StoreController.java:
package com.pn.controller;
@RequestMapping("/store") @RestController public class StoreController {
//注入StoreService @Autowired private StoreService storeService;
/** * 删除仓库的url接口/store/store-delete/{storeId} * * @PathVariable Integer storeId将路径占位符storeId的值赋值给参数变量storeId; */ @RequestMapping("/store-delete/{storeId}") public Result deleteStore(@PathVariable Integer storeId){ //执行业务 Result result = storeService.deleteStore(storeId); //响应 return result; } } |
5.导出数据
导出当前页数据。
com.pn.controller.StoreController.java:
package com.pn.controller;
@RequestMapping("/store") @RestController public class StoreController {
//注入StoreService @Autowired private StoreService storeService;
/** * 导出数据的url接口/store/exportTable * * 参数Page对象用于接收请求参数页码pageNum、每页行数pageSize; * 参数Store对象用于接收请求参数仓库名称storeName、仓库地址storeAddress、 * 联系人concat、联系电话phone; * * 返回值Result对象向客户端响应组装了当前页数据的List; */ @RequestMapping("/exportTable") public Result exportTable(Page page, Store store){ //分页查询仓库 page = storeService.queryStorePage(page, store); //拿到当前页数据 List<?> resultList = page.getResultList(); //响应 return Result.ok(resultList); } } |