初步完成屠宰场管理

This commit is contained in:
xuqiuyun
2025-12-09 17:34:29 +08:00
parent 620975c04d
commit 980ffb39b9
30 changed files with 3428 additions and 522 deletions

View File

@@ -0,0 +1,99 @@
package com.aiotagro.cattletrade.business.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import com.aiotagro.cattletrade.business.dto.SlaughterEntryCreateDto;
import com.aiotagro.cattletrade.business.dto.SlaughterEntryDto;
import com.aiotagro.cattletrade.business.dto.SlaughterEntryEditDto;
import com.aiotagro.cattletrade.business.entity.SlaughterEntry;
import com.aiotagro.cattletrade.business.service.ISlaughterEntryService;
import com.aiotagro.common.core.web.domain.AjaxResult;
import com.aiotagro.common.core.web.domain.PageResultResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
/**
* 屠宰场进场管理控制器
*
* @author System
* @date 2025-12-09
*/
@RestController
@RequestMapping("/slaughter/entry")
public class SlaughterEntryController {
@Autowired
private ISlaughterEntryService slaughterEntryService;
/**
* 分页查询进场记录
*/
@SaCheckPermission("slaughterEntry:query")
@PostMapping("/list")
public AjaxResult list(@RequestBody SlaughterEntryDto dto) {
try {
PageResultResponse<SlaughterEntry> result = slaughterEntryService.pageQuery(dto);
return AjaxResult.success(result);
} catch (Exception e) {
e.printStackTrace();
return AjaxResult.error("查询进场记录失败:" + e.getMessage());
}
}
/**
* 新增进场记录
*/
@SaCheckPermission("slaughterEntry:add")
@PostMapping("/add")
public AjaxResult add(@Validated @RequestBody SlaughterEntryCreateDto dto) {
try {
return slaughterEntryService.addEntry(dto);
} catch (Exception e) {
e.printStackTrace();
return AjaxResult.error("新增进场记录失败:" + e.getMessage());
}
}
/**
* 编辑进场记录
*/
@SaCheckPermission("slaughterEntry:edit")
@PostMapping("/edit")
public AjaxResult edit(@Validated @RequestBody SlaughterEntryEditDto dto) {
try {
return slaughterEntryService.updateEntry(dto);
} catch (Exception e) {
e.printStackTrace();
return AjaxResult.error("编辑进场记录失败:" + e.getMessage());
}
}
/**
* 删除进场记录
*/
@SaCheckPermission("slaughterEntry:delete")
@GetMapping("/delete")
public AjaxResult delete(@RequestParam Integer id) {
try {
return slaughterEntryService.deleteEntry(id);
} catch (Exception e) {
e.printStackTrace();
return AjaxResult.error("删除进场记录失败:" + e.getMessage());
}
}
/**
* 详情
*/
@SaCheckPermission("slaughterEntry:query")
@GetMapping("/detail")
public AjaxResult detail(@RequestParam Integer id) {
try {
return slaughterEntryService.detail(id);
} catch (Exception e) {
e.printStackTrace();
return AjaxResult.error("查询进场记录详情失败:" + e.getMessage());
}
}
}

View File

@@ -0,0 +1,115 @@
package com.aiotagro.cattletrade.business.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import com.aiotagro.cattletrade.business.dto.SlaughterHouseCreateDto;
import com.aiotagro.cattletrade.business.dto.SlaughterHouseDto;
import com.aiotagro.cattletrade.business.dto.SlaughterHouseEditDto;
import com.aiotagro.cattletrade.business.entity.SlaughterHouse;
import com.aiotagro.cattletrade.business.service.ISlaughterHouseService;
import com.aiotagro.common.core.web.domain.AjaxResult;
import com.aiotagro.common.core.web.domain.PageResultResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 屠宰场管理控制器
*
* @author System
* @date 2025-12-09
*/
@RestController
@RequestMapping("/slaughter/house")
public class SlaughterHouseController {
@Autowired
private ISlaughterHouseService slaughterHouseService;
/**
* 分页查询屠宰场
*/
@SaCheckPermission("slaughterHouse:query")
@PostMapping("/list")
public AjaxResult list(@RequestBody SlaughterHouseDto dto) {
try {
PageResultResponse<SlaughterHouse> result = slaughterHouseService.pageQuery(dto);
return AjaxResult.success(result);
} catch (Exception e) {
e.printStackTrace();
return AjaxResult.error("查询屠宰场列表失败:" + e.getMessage());
}
}
/**
* 新增屠宰场
*/
@SaCheckPermission("slaughterHouse:add")
@PostMapping("/add")
public AjaxResult add(@Validated @RequestBody SlaughterHouseCreateDto dto) {
try {
return slaughterHouseService.addHouse(dto);
} catch (Exception e) {
e.printStackTrace();
return AjaxResult.error("新增屠宰场失败:" + e.getMessage());
}
}
/**
* 编辑屠宰场
*/
@SaCheckPermission("slaughterHouse:edit")
@PostMapping("/edit")
public AjaxResult edit(@Validated @RequestBody SlaughterHouseEditDto dto) {
try {
return slaughterHouseService.updateHouse(dto);
} catch (Exception e) {
e.printStackTrace();
return AjaxResult.error("编辑屠宰场失败:" + e.getMessage());
}
}
/**
* 删除屠宰场
*/
@SaCheckPermission("slaughterHouse:delete")
@GetMapping("/delete")
public AjaxResult delete(@RequestParam Integer id) {
try {
return slaughterHouseService.deleteHouse(id);
} catch (Exception e) {
e.printStackTrace();
return AjaxResult.error("删除屠宰场失败:" + e.getMessage());
}
}
/**
* 详情
*/
@SaCheckPermission("slaughterHouse:query")
@GetMapping("/detail")
public AjaxResult detail(@RequestParam Integer id) {
try {
return slaughterHouseService.detail(id);
} catch (Exception e) {
e.printStackTrace();
return AjaxResult.error("查询屠宰场详情失败:" + e.getMessage());
}
}
/**
* 启用列表(下拉)
*/
@GetMapping("/all")
public AjaxResult allEnabled() {
try {
List<SlaughterHouse> list = slaughterHouseService.getAllEnabled();
return AjaxResult.success("查询成功", list);
} catch (Exception e) {
e.printStackTrace();
return AjaxResult.error("查询屠宰场列表失败:" + e.getMessage());
}
}
}

View File

@@ -0,0 +1,89 @@
package com.aiotagro.cattletrade.business.dto;
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
/**
* 进场记录创建DTO
*
* @author System
* @date 2025-12-09
*/
@Data
public class SlaughterEntryCreateDto {
/**
* 屠宰场ID
*/
@NotNull(message = "屠宰场ID不能为空")
private Integer slaughterHouseId;
/**
* 运送清单ID
*/
@NotNull(message = "运送清单ID不能为空")
private Integer deliveryId;
/**
* 订单ID
*/
private Integer orderId;
/**
* 起始地
*/
private String startLocation;
/**
* 起始经度
*/
private String startLon;
/**
* 起始纬度
*/
private String startLat;
/**
* 目的地
*/
private String endLocation;
/**
* 目的地经度
*/
private String endLon;
/**
* 目的地纬度
*/
private String endLat;
/**
* 司机姓名
*/
private String driverName;
/**
* 联系方式
*/
private String driverMobile;
/**
* 车牌号
*/
private String licensePlate;
/**
* 出肉率(%
*/
private BigDecimal yieldRate;
/**
* 备注
*/
private String remark;
}

View File

@@ -0,0 +1,31 @@
package com.aiotagro.cattletrade.business.dto;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* 进场记录查询DTO
*
* @author System
* @date 2025-12-09
*/
@Data
@EqualsAndHashCode(callSuper = false)
public class SlaughterEntryDto extends BaseDto {
/**
* 屠宰场ID
*/
private Integer slaughterHouseId;
/**
* 运送清单ID
*/
private Integer deliveryId;
/**
* 订单ID
*/
private Integer orderId;
}

View File

@@ -0,0 +1,95 @@
package com.aiotagro.cattletrade.business.dto;
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
/**
* 进场记录编辑DTO
*
* @author System
* @date 2025-12-09
*/
@Data
public class SlaughterEntryEditDto {
/**
* 主键ID
*/
@NotNull(message = "主键ID不能为空")
private Integer id;
/**
* 屠宰场ID
*/
@NotNull(message = "屠宰场ID不能为空")
private Integer slaughterHouseId;
/**
* 运送清单ID
*/
@NotNull(message = "运送清单ID不能为空")
private Integer deliveryId;
/**
* 订单ID
*/
private Integer orderId;
/**
* 起始地
*/
private String startLocation;
/**
* 起始经度
*/
private String startLon;
/**
* 起始纬度
*/
private String startLat;
/**
* 目的地
*/
private String endLocation;
/**
* 目的地经度
*/
private String endLon;
/**
* 目的地纬度
*/
private String endLat;
/**
* 司机姓名
*/
private String driverName;
/**
* 联系方式
*/
private String driverMobile;
/**
* 车牌号
*/
private String licensePlate;
/**
* 出肉率(%
*/
private BigDecimal yieldRate;
/**
* 备注
*/
private String remark;
}

View File

@@ -0,0 +1,70 @@
package com.aiotagro.cattletrade.business.dto;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
/**
* 屠宰场创建DTO
*
* @author System
* @date 2025-12-09
*/
@Data
public class SlaughterHouseCreateDto {
/**
* 屠宰场名称
*/
@NotBlank(message = "屠宰场名称不能为空")
private String houseName;
/**
* 屠宰场编码(为空时自动生成)
*/
private String slaughterCode;
/**
* 容量(头数)
*/
@NotNull(message = "容量不能为空")
private Integer capacity;
/**
* 负责人
*/
private String person;
/**
* 联系电话
*/
private String phone;
/**
* 地址
*/
@NotBlank(message = "地址不能为空")
private String address;
/**
* 经度
*/
private String longitude;
/**
* 纬度
*/
private String latitude;
/**
* 状态1-启用0-禁用
*/
private Integer status;
/**
* 备注
*/
private String remark;
}

View File

@@ -0,0 +1,31 @@
package com.aiotagro.cattletrade.business.dto;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* 屠宰场查询DTO
*
* @author System
* @date 2025-12-09
*/
@Data
@EqualsAndHashCode(callSuper = false)
public class SlaughterHouseDto extends BaseDto {
/**
* 屠宰场名称
*/
private String houseName;
/**
* 屠宰场编码
*/
private String slaughterCode;
/**
* 状态1-启用0-禁用
*/
private Integer status;
}

View File

@@ -0,0 +1,77 @@
package com.aiotagro.cattletrade.business.dto;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
/**
* 屠宰场编辑DTO
*
* @author System
* @date 2025-12-09
*/
@Data
public class SlaughterHouseEditDto {
/**
* 主键ID
*/
@NotNull(message = "主键ID不能为空")
private Integer id;
/**
* 屠宰场名称
*/
@NotBlank(message = "屠宰场名称不能为空")
private String houseName;
/**
* 屠宰场编码
*/
@NotBlank(message = "屠宰场编码不能为空")
private String slaughterCode;
/**
* 容量(头数)
*/
@NotNull(message = "容量不能为空")
private Integer capacity;
/**
* 负责人
*/
private String person;
/**
* 联系电话
*/
private String phone;
/**
* 地址
*/
@NotBlank(message = "地址不能为空")
private String address;
/**
* 经度
*/
private String longitude;
/**
* 纬度
*/
private String latitude;
/**
* 状态1-启用0-禁用
*/
private Integer status;
/**
* 备注
*/
private String remark;
}

View File

@@ -0,0 +1,150 @@
package com.aiotagro.cattletrade.business.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
/**
* 屠宰场进场记录实体
*
* @author System
* @date 2025-12-09
*/
@Data
@TableName("slaughter_entry")
public class SlaughterEntry implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键ID
*/
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
/**
* 屠宰场ID
*/
@TableField("slaughter_house_id")
private Integer slaughterHouseId;
/**
* 运送清单ID
*/
@TableField("delivery_id")
private Integer deliveryId;
/**
* 订单ID
*/
@TableField("order_id")
private Integer orderId;
/**
* 起始地
*/
@TableField("start_location")
private String startLocation;
/**
* 起始经度
*/
@TableField("start_lon")
private String startLon;
/**
* 起始纬度
*/
@TableField("start_lat")
private String startLat;
/**
* 目的地
*/
@TableField("end_location")
private String endLocation;
/**
* 目的地经度
*/
@TableField("end_lon")
private String endLon;
/**
* 目的地纬度
*/
@TableField("end_lat")
private String endLat;
/**
* 司机姓名
*/
@TableField("driver_name")
private String driverName;
/**
* 联系方式
*/
@TableField("driver_mobile")
private String driverMobile;
/**
* 车牌号
*/
@TableField("license_plate")
private String licensePlate;
/**
* 出肉率(%
*/
@TableField("yield_rate")
private BigDecimal yieldRate;
/**
* 备注
*/
@TableField("remark")
private String remark;
/**
* 逻辑删除标记(0-正常,1-已删除)
*/
@TableLogic(value = "0", delval = "1")
@TableField("is_delete")
private Integer isDelete;
/**
* 创建时间
*/
@TableField("create_time")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date createTime;
/**
* 创建人ID
*/
@TableField("created_by")
private Integer createdBy;
/**
* 更新时间
*/
@TableField("update_time")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date updateTime;
/**
* 更新人ID
*/
@TableField("updated_by")
private Integer updatedBy;
}

View File

@@ -0,0 +1,125 @@
package com.aiotagro.cattletrade.business.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
/**
* 屠宰场实体
*
* @author System
* @date 2025-12-09
*/
@Data
@TableName("slaughter_house")
public class SlaughterHouse implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键ID
*/
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
/**
* 屠宰场名称
*/
@TableField("house_name")
private String houseName;
/**
* 屠宰场编码
*/
@TableField("slaughter_code")
private String slaughterCode;
/**
* 容量(头数)
*/
@TableField("capacity")
private Integer capacity;
/**
* 负责人
*/
@TableField("person")
private String person;
/**
* 联系电话
*/
@TableField("phone")
private String phone;
/**
* 地址
*/
@TableField("address")
private String address;
/**
* 经度
*/
@TableField("longitude")
private String longitude;
/**
* 纬度
*/
@TableField("latitude")
private String latitude;
/**
* 状态1-启用0-禁用
*/
@TableField("status")
private Integer status;
/**
* 备注
*/
@TableField("remark")
private String remark;
/**
* 逻辑删除标记(0-正常,1-已删除)
*/
@TableLogic(value = "0", delval = "1")
@TableField("is_delete")
private Integer isDelete;
/**
* 创建时间
*/
@TableField("create_time")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date createTime;
/**
* 创建人ID
*/
@TableField("created_by")
private Integer createdBy;
/**
* 更新时间
*/
@TableField("update_time")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date updateTime;
/**
* 更新人ID
*/
@TableField("updated_by")
private Integer updatedBy;
}

View File

@@ -0,0 +1,16 @@
package com.aiotagro.cattletrade.business.mapper;
import com.aiotagro.cattletrade.business.entity.SlaughterEntry;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
* 进场记录 Mapper
*
* @author System
* @date 2025-12-09
*/
@Mapper
public interface SlaughterEntryMapper extends BaseMapper<SlaughterEntry> {
}

View File

@@ -0,0 +1,38 @@
package com.aiotagro.cattletrade.business.mapper;
import com.aiotagro.cattletrade.business.entity.SlaughterHouse;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import java.util.List;
/**
* 屠宰场管理 Mapper
*
* @author System
* @date 2025-12-09
*/
@Mapper
public interface SlaughterHouseMapper extends BaseMapper<SlaughterHouse> {
/**
* 根据编码查询
*/
@Select("SELECT * FROM slaughter_house WHERE slaughter_code = #{slaughterCode} AND is_delete = 0")
SlaughterHouse selectByCode(@Param("slaughterCode") String slaughterCode);
/**
* 查询指定前缀下的最新编码
*/
@Select("SELECT * FROM slaughter_house WHERE slaughter_code LIKE #{prefixPattern} AND is_delete = 0 ORDER BY slaughter_code DESC LIMIT 1")
SlaughterHouse selectLastCode(@Param("prefixPattern") String prefixPattern);
/**
* 查询所有启用的屠宰场
*/
@Select("SELECT id, house_name, slaughter_code FROM slaughter_house WHERE status = 1 AND is_delete = 0 ORDER BY create_time DESC")
List<SlaughterHouse> selectAllEnabled();
}

View File

@@ -0,0 +1,44 @@
package com.aiotagro.cattletrade.business.service;
import com.aiotagro.cattletrade.business.dto.SlaughterEntryCreateDto;
import com.aiotagro.cattletrade.business.dto.SlaughterEntryDto;
import com.aiotagro.cattletrade.business.dto.SlaughterEntryEditDto;
import com.aiotagro.cattletrade.business.entity.SlaughterEntry;
import com.aiotagro.common.core.web.domain.AjaxResult;
import com.aiotagro.common.core.web.domain.PageResultResponse;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* 进场管理服务接口
*
* @author System
* @date 2025-12-09
*/
public interface ISlaughterEntryService extends IService<SlaughterEntry> {
/**
* 分页查询
*/
PageResultResponse<SlaughterEntry> pageQuery(SlaughterEntryDto dto);
/**
* 新增进场记录
*/
AjaxResult addEntry(SlaughterEntryCreateDto dto);
/**
* 编辑进场记录
*/
AjaxResult updateEntry(SlaughterEntryEditDto dto);
/**
* 删除进场记录(逻辑删除)
*/
AjaxResult deleteEntry(Integer id);
/**
* 获取详情
*/
AjaxResult detail(Integer id);
}

View File

@@ -0,0 +1,51 @@
package com.aiotagro.cattletrade.business.service;
import com.aiotagro.cattletrade.business.dto.SlaughterHouseCreateDto;
import com.aiotagro.cattletrade.business.dto.SlaughterHouseDto;
import com.aiotagro.cattletrade.business.dto.SlaughterHouseEditDto;
import com.aiotagro.cattletrade.business.entity.SlaughterHouse;
import com.aiotagro.common.core.web.domain.AjaxResult;
import com.aiotagro.common.core.web.domain.PageResultResponse;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
/**
* 屠宰场管理服务接口
*
* @author System
* @date 2025-12-09
*/
public interface ISlaughterHouseService extends IService<SlaughterHouse> {
/**
* 分页查询
*/
PageResultResponse<SlaughterHouse> pageQuery(SlaughterHouseDto dto);
/**
* 新增
*/
AjaxResult addHouse(SlaughterHouseCreateDto dto);
/**
* 编辑
*/
AjaxResult updateHouse(SlaughterHouseEditDto dto);
/**
* 删除(逻辑)
*/
AjaxResult deleteHouse(Integer id);
/**
* 详情
*/
AjaxResult detail(Integer id);
/**
* 下拉列表
*/
List<SlaughterHouse> getAllEnabled();
}

View File

@@ -0,0 +1,178 @@
package com.aiotagro.cattletrade.business.service.impl;
import com.aiotagro.cattletrade.business.dto.SlaughterEntryCreateDto;
import com.aiotagro.cattletrade.business.dto.SlaughterEntryDto;
import com.aiotagro.cattletrade.business.dto.SlaughterEntryEditDto;
import com.aiotagro.cattletrade.business.entity.Delivery;
import com.aiotagro.cattletrade.business.entity.Order;
import com.aiotagro.cattletrade.business.entity.SlaughterEntry;
import com.aiotagro.cattletrade.business.entity.SlaughterHouse;
import com.aiotagro.cattletrade.business.mapper.DeliveryMapper;
import com.aiotagro.cattletrade.business.mapper.OrderMapper;
import com.aiotagro.cattletrade.business.mapper.SlaughterEntryMapper;
import com.aiotagro.cattletrade.business.mapper.SlaughterHouseMapper;
import com.aiotagro.cattletrade.business.service.ISlaughterEntryService;
import com.aiotagro.common.core.utils.SecurityUtil;
import com.aiotagro.common.core.utils.bean.BeanUtils;
import com.aiotagro.common.core.web.domain.AjaxResult;
import com.aiotagro.common.core.web.domain.PageResultResponse;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date;
import java.util.List;
/**
* 进场管理服务实现
*
* @author System
* @date 2025-12-09
*/
@Service
public class SlaughterEntryServiceImpl extends ServiceImpl<SlaughterEntryMapper, SlaughterEntry> implements ISlaughterEntryService {
@Autowired
private SlaughterEntryMapper slaughterEntryMapper;
@Autowired
private SlaughterHouseMapper slaughterHouseMapper;
@Autowired
private DeliveryMapper deliveryMapper;
@Autowired
private OrderMapper orderMapper;
@Override
public PageResultResponse<SlaughterEntry> pageQuery(SlaughterEntryDto dto) {
Integer pageNum = dto.getPageNum() != null ? dto.getPageNum() : 1;
Integer pageSize = dto.getPageSize() != null ? dto.getPageSize() : 10;
Page<SlaughterEntry> page = PageHelper.startPage(pageNum, pageSize);
LambdaQueryWrapper<SlaughterEntry> wrapper = new LambdaQueryWrapper<>();
wrapper.and(q -> q.eq(SlaughterEntry::getIsDelete, 0).or().isNull(SlaughterEntry::getIsDelete));
if (dto.getSlaughterHouseId() != null) {
wrapper.eq(SlaughterEntry::getSlaughterHouseId, dto.getSlaughterHouseId());
}
if (dto.getDeliveryId() != null) {
wrapper.eq(SlaughterEntry::getDeliveryId, dto.getDeliveryId());
}
if (dto.getOrderId() != null) {
wrapper.eq(SlaughterEntry::getOrderId, dto.getOrderId());
}
wrapper.orderByDesc(SlaughterEntry::getCreateTime);
List<SlaughterEntry> list = slaughterEntryMapper.selectList(wrapper);
return new PageResultResponse<>(page.getTotal(), list);
}
@Override
@Transactional
public AjaxResult addEntry(SlaughterEntryCreateDto dto) {
AjaxResult validateResult = validateRelation(dto.getSlaughterHouseId(), dto.getDeliveryId(), dto.getOrderId());
if (validateResult != null) {
return validateResult;
}
SlaughterEntry entry = new SlaughterEntry();
BeanUtils.copyProperties(dto, entry);
Integer userId = SecurityUtil.getCurrentUserId();
entry.setCreatedBy(userId);
entry.setCreateTime(new Date());
int inserted = slaughterEntryMapper.insert(entry);
return inserted > 0 ? AjaxResult.success("新增进场记录成功") : AjaxResult.error("新增进场记录失败");
}
@Override
@Transactional
public AjaxResult updateEntry(SlaughterEntryEditDto dto) {
if (dto.getId() == null) {
return AjaxResult.error("进场记录ID不能为空");
}
SlaughterEntry existing = slaughterEntryMapper.selectById(dto.getId());
if (existing == null || (existing.getIsDelete() != null && existing.getIsDelete() == 1)) {
return AjaxResult.error("进场记录不存在");
}
AjaxResult validateResult = validateRelation(dto.getSlaughterHouseId(), dto.getDeliveryId(), dto.getOrderId());
if (validateResult != null) {
return validateResult;
}
SlaughterEntry entry = new SlaughterEntry();
BeanUtils.copyProperties(dto, entry);
Integer userId = SecurityUtil.getCurrentUserId();
entry.setUpdatedBy(userId);
entry.setUpdateTime(new Date());
int updated = slaughterEntryMapper.updateById(entry);
return updated > 0 ? AjaxResult.success("更新进场记录成功") : AjaxResult.error("更新进场记录失败");
}
@Override
@Transactional
public AjaxResult deleteEntry(Integer id) {
if (id == null) {
return AjaxResult.error("进场记录ID不能为空");
}
SlaughterEntry entry = slaughterEntryMapper.selectById(id);
if (entry == null || (entry.getIsDelete() != null && entry.getIsDelete() == 1)) {
return AjaxResult.error("进场记录不存在");
}
Integer userId = SecurityUtil.getCurrentUserId();
UpdateWrapper<SlaughterEntry> wrapper = new UpdateWrapper<>();
wrapper.eq("id", id).eq("is_delete", 0)
.set("is_delete", 1)
.set("updated_by", userId)
.set("update_time", new Date());
int result = slaughterEntryMapper.update(null, wrapper);
return result > 0 ? AjaxResult.success("删除进场记录成功") : AjaxResult.error("删除进场记录失败");
}
@Override
public AjaxResult detail(Integer id) {
if (id == null) {
return AjaxResult.error("进场记录ID不能为空");
}
SlaughterEntry entry = slaughterEntryMapper.selectById(id);
if (entry == null || (entry.getIsDelete() != null && entry.getIsDelete() == 1)) {
return AjaxResult.error("进场记录不存在");
}
return AjaxResult.success("查询成功", entry);
}
/**
* 校验关联的屠宰场、运送清单、订单是否存在
*/
private AjaxResult validateRelation(Integer houseId, Integer deliveryId, Integer orderId) {
SlaughterHouse house = slaughterHouseMapper.selectById(houseId);
if (house == null || (house.getIsDelete() != null && house.getIsDelete() == 1)) {
return AjaxResult.error("屠宰场不存在");
}
Delivery delivery = deliveryMapper.selectById(deliveryId);
if (delivery == null) {
return AjaxResult.error("运送清单不存在");
}
if (orderId != null) {
Order order = orderMapper.selectById(orderId);
if (order == null || (order.getIsDelete() != null && order.getIsDelete() == 1)) {
return AjaxResult.error("订单不存在");
}
}
return null;
}
}

View File

@@ -0,0 +1,198 @@
package com.aiotagro.cattletrade.business.service.impl;
import com.aiotagro.cattletrade.business.dto.SlaughterHouseCreateDto;
import com.aiotagro.cattletrade.business.dto.SlaughterHouseDto;
import com.aiotagro.cattletrade.business.dto.SlaughterHouseEditDto;
import com.aiotagro.cattletrade.business.entity.SlaughterHouse;
import com.aiotagro.cattletrade.business.mapper.SlaughterHouseMapper;
import com.aiotagro.cattletrade.business.service.ISlaughterHouseService;
import com.aiotagro.common.core.utils.SecurityUtil;
import com.aiotagro.common.core.utils.bean.BeanUtils;
import com.aiotagro.common.core.web.domain.AjaxResult;
import com.aiotagro.common.core.web.domain.PageResultResponse;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
/**
* 屠宰场管理服务实现
*
* @author System
* @date 2025-12-09
*/
@Service
public class SlaughterHouseServiceImpl extends ServiceImpl<SlaughterHouseMapper, SlaughterHouse> implements ISlaughterHouseService {
@Autowired
private SlaughterHouseMapper slaughterHouseMapper;
@Override
public PageResultResponse<SlaughterHouse> pageQuery(SlaughterHouseDto dto) {
Integer pageNum = dto.getPageNum() != null ? dto.getPageNum() : 1;
Integer pageSize = dto.getPageSize() != null ? dto.getPageSize() : 10;
Page<SlaughterHouse> page = PageHelper.startPage(pageNum, pageSize);
LambdaQueryWrapper<SlaughterHouse> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.and(wrapper -> wrapper.eq(SlaughterHouse::getIsDelete, 0).or().isNull(SlaughterHouse::getIsDelete));
if (StringUtils.hasText(dto.getHouseName())) {
queryWrapper.like(SlaughterHouse::getHouseName, dto.getHouseName());
}
if (StringUtils.hasText(dto.getSlaughterCode())) {
queryWrapper.like(SlaughterHouse::getSlaughterCode, dto.getSlaughterCode());
}
if (dto.getStatus() != null) {
queryWrapper.eq(SlaughterHouse::getStatus, dto.getStatus());
}
queryWrapper.orderByDesc(SlaughterHouse::getCreateTime);
List<SlaughterHouse> list = slaughterHouseMapper.selectList(queryWrapper);
return new PageResultResponse<>(page.getTotal(), list);
}
@Override
@Transactional
public AjaxResult addHouse(SlaughterHouseCreateDto dto) {
String code = dto.getSlaughterCode();
if (!StringUtils.hasText(code)) {
code = generateSlaughterCode();
} else {
SlaughterHouse exist = slaughterHouseMapper.selectByCode(code);
if (exist != null) {
return AjaxResult.error("屠宰场编码已存在");
}
}
SlaughterHouse house = new SlaughterHouse();
BeanUtils.copyProperties(dto, house);
house.setSlaughterCode(code);
if (house.getStatus() == null) {
house.setStatus(1);
}
Integer userId = SecurityUtil.getCurrentUserId();
house.setCreatedBy(userId);
house.setCreateTime(new Date());
try {
int inserted = slaughterHouseMapper.insert(house);
return inserted > 0 ? AjaxResult.success("新增屠宰场成功") : AjaxResult.error("新增屠宰场失败");
} catch (DuplicateKeyException e) {
return AjaxResult.error("屠宰场编码已存在,请使用其他编码");
} catch (Exception e) {
e.printStackTrace();
return AjaxResult.error("新增屠宰场失败:" + e.getMessage());
}
}
@Override
@Transactional
public AjaxResult updateHouse(SlaughterHouseEditDto dto) {
if (dto.getId() == null) {
return AjaxResult.error("屠宰场ID不能为空");
}
SlaughterHouse exist = slaughterHouseMapper.selectById(dto.getId());
if (exist == null || (exist.getIsDelete() != null && exist.getIsDelete() == 1)) {
return AjaxResult.error("屠宰场不存在");
}
SlaughterHouse codeHouse = slaughterHouseMapper.selectByCode(dto.getSlaughterCode());
if (codeHouse != null && !codeHouse.getId().equals(dto.getId())) {
return AjaxResult.error("屠宰场编码已存在");
}
SlaughterHouse house = new SlaughterHouse();
BeanUtils.copyProperties(dto, house);
Integer userId = SecurityUtil.getCurrentUserId();
house.setUpdatedBy(userId);
house.setUpdateTime(new Date());
try {
int updated = slaughterHouseMapper.updateById(house);
return updated > 0 ? AjaxResult.success("更新屠宰场成功") : AjaxResult.error("更新屠宰场失败");
} catch (DuplicateKeyException e) {
return AjaxResult.error("屠宰场编码已存在,请使用其他编码");
} catch (Exception e) {
e.printStackTrace();
return AjaxResult.error("更新屠宰场失败:" + e.getMessage());
}
}
@Override
@Transactional
public AjaxResult deleteHouse(Integer id) {
if (id == null) {
return AjaxResult.error("屠宰场ID不能为空");
}
SlaughterHouse house = slaughterHouseMapper.selectById(id);
if (house == null || (house.getIsDelete() != null && house.getIsDelete() == 1)) {
return AjaxResult.error("屠宰场不存在");
}
Integer userId = SecurityUtil.getCurrentUserId();
UpdateWrapper<SlaughterHouse> updateWrapper = new UpdateWrapper<>();
updateWrapper.eq("id", id).eq("is_delete", 0)
.set("is_delete", 1)
.set("updated_by", userId)
.set("update_time", new Date());
int result = slaughterHouseMapper.update(null, updateWrapper);
return result > 0 ? AjaxResult.success("删除成功") : AjaxResult.error("删除失败");
}
@Override
public AjaxResult detail(Integer id) {
if (id == null) {
return AjaxResult.error("屠宰场ID不能为空");
}
SlaughterHouse house = slaughterHouseMapper.selectById(id);
if (house == null || (house.getIsDelete() != null && house.getIsDelete() == 1)) {
return AjaxResult.error("屠宰场不存在");
}
return AjaxResult.success("查询成功", house);
}
@Override
public List<SlaughterHouse> getAllEnabled() {
return slaughterHouseMapper.selectAllEnabled();
}
/**
* 生成屠宰场编码SLyyyyMMdd + 4位流水
*/
private String generateSlaughterCode() {
String dateStr = new SimpleDateFormat("yyyyMMdd").format(new Date());
String prefix = "SL" + dateStr;
SlaughterHouse last = slaughterHouseMapper.selectLastCode(prefix + "%");
int next = 1;
if (last != null && StringUtils.hasText(last.getSlaughterCode())) {
String lastCode = last.getSlaughterCode();
if (lastCode.startsWith(prefix)) {
String seq = lastCode.substring(prefix.length());
try {
next = Integer.parseInt(seq) + 1;
} catch (NumberFormatException ignored) {
next = 1;
}
}
}
return String.format("%s%04d", prefix, next);
}
}

View File

@@ -0,0 +1,68 @@
USE cattletrade;
-- 创建屠宰场管理相关表
-- 1. 屠宰场表slaughter_house
-- 2. 进场表slaughter_entry
-- ============================================
-- 1. 屠宰场表slaughter_house
-- ============================================
CREATE TABLE IF NOT EXISTS `slaughter_house` (
`id` INT(11) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`house_name` VARCHAR(100) NOT NULL COMMENT '屠宰场名称',
`slaughter_code` VARCHAR(50) NOT NULL COMMENT '屠宰场编码格式SLyyyyMMddXXXX',
`capacity` INT(11) DEFAULT NULL COMMENT '容量(头数)',
`address` VARCHAR(255) DEFAULT NULL COMMENT '地址',
`longitude` VARCHAR(50) DEFAULT NULL COMMENT '经度',
`latitude` VARCHAR(50) DEFAULT NULL COMMENT '纬度',
`status` TINYINT(1) DEFAULT 1 COMMENT '状态1-启用0-禁用',
`remark` TEXT COMMENT '备注',
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`created_by` INT(11) DEFAULT NULL COMMENT '创建人ID',
`updated_by` INT(11) DEFAULT NULL COMMENT '更新人ID',
`is_delete` TINYINT(1) DEFAULT 0 COMMENT '逻辑删除0-未删除1-已删除',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_slaughter_code` (`slaughter_code`),
KEY `idx_house_name` (`house_name`),
KEY `idx_status` (`status`),
KEY `idx_is_delete` (`is_delete`),
KEY `idx_create_time` (`create_time`),
KEY `idx_status_is_delete` (`status`, `is_delete`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='屠宰场表';
-- ============================================
-- 2. 进场表slaughter_entry
-- ============================================
CREATE TABLE IF NOT EXISTS `slaughter_entry` (
`id` INT(11) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`slaughter_house_id` INT(11) NOT NULL COMMENT '屠宰场ID',
`delivery_id` INT(11) NOT NULL COMMENT '运送清单ID关联delivery表',
`order_id` INT(11) DEFAULT NULL COMMENT '订单ID关联order表',
`start_location` VARCHAR(255) DEFAULT NULL COMMENT '起始地',
`start_lon` VARCHAR(50) DEFAULT NULL COMMENT '起始经度',
`start_lat` VARCHAR(50) DEFAULT NULL COMMENT '起始纬度',
`end_location` VARCHAR(255) DEFAULT NULL COMMENT '目的地',
`end_lon` VARCHAR(50) DEFAULT NULL COMMENT '目的地经度',
`end_lat` VARCHAR(50) DEFAULT NULL COMMENT '目的地纬度',
`driver_name` VARCHAR(50) DEFAULT NULL COMMENT '司机姓名',
`driver_mobile` VARCHAR(20) DEFAULT NULL COMMENT '联系方式',
`license_plate` VARCHAR(20) DEFAULT NULL COMMENT '车牌号',
`yield_rate` DECIMAL(5,2) DEFAULT NULL COMMENT '出肉率(%',
`remark` TEXT COMMENT '备注',
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`created_by` INT(11) DEFAULT NULL COMMENT '创建人ID',
`updated_by` INT(11) DEFAULT NULL COMMENT '更新人ID',
`is_delete` TINYINT(1) DEFAULT 0 COMMENT '逻辑删除0-未删除1-已删除',
PRIMARY KEY (`id`),
KEY `idx_slaughter_house_id` (`slaughter_house_id`),
KEY `idx_delivery_id` (`delivery_id`),
KEY `idx_order_id` (`order_id`),
KEY `idx_is_delete` (`is_delete`),
KEY `idx_create_time` (`create_time`),
CONSTRAINT `fk_slaughter_entry_house` FOREIGN KEY (`slaughter_house_id`) REFERENCES `slaughter_house` (`id`) ON DELETE RESTRICT ON UPDATE CASCADE,
CONSTRAINT `fk_slaughter_entry_delivery` FOREIGN KEY (`delivery_id`) REFERENCES `delivery` (`id`) ON DELETE RESTRICT ON UPDATE CASCADE,
CONSTRAINT `fk_slaughter_entry_order` FOREIGN KEY (`order_id`) REFERENCES `order` (`id`) ON DELETE SET NULL ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='屠宰场进场表';

View File

@@ -0,0 +1,74 @@
USE cattletrade;
-- 插入屠宰场管理菜单(一级目录 + 两个二级菜单 + 按钮权限)
-- 菜单类型0-目录1-菜单2-按钮
-- 1) 一级菜单:屠宰场管理
INSERT INTO sys_menu (parent_id, type, icon, name, sort, route_url, page_url, org_type, authority, create_time, update_time, is_delete)
VALUES (
0,
0,
'el-icon-knife-fork',
'屠宰场管理',
70,
NULL,
NULL,
2,
NULL,
NOW(),
NOW(),
0
);
SET @slaughter_parent_id = LAST_INSERT_ID();
-- 2) 二级菜单:屠宰场管理(列表页)
INSERT INTO sys_menu (parent_id, type, icon, name, sort, route_url, page_url, org_type, authority, create_time, update_time, is_delete)
VALUES (
@slaughter_parent_id,
1,
'el-icon-office-building',
'屠宰场管理',
1,
'house',
'slaughter/house',
2,
'slaughterHouse:list',
NOW(),
NOW(),
0
);
SET @slaughter_house_menu_id = LAST_INSERT_ID();
INSERT INTO sys_menu (parent_id, type, icon, name, sort, route_url, page_url, org_type, authority, create_time, update_time, is_delete)
VALUES
(@slaughter_house_menu_id, 2, NULL, '新增', 1, NULL, NULL, 2, 'slaughterHouse:add', NOW(), NOW(), 0),
(@slaughter_house_menu_id, 2, NULL, '编辑', 2, NULL, NULL, 2, 'slaughterHouse:edit', NOW(), NOW(), 0),
(@slaughter_house_menu_id, 2, NULL, '删除', 3, NULL, NULL, 2, 'slaughterHouse:delete', NOW(), NOW(), 0),
(@slaughter_house_menu_id, 2, NULL, '查询', 4, NULL, NULL, 2, 'slaughterHouse:query', NOW(), NOW(), 0);
-- 3) 二级菜单:进场管理
INSERT INTO sys_menu (parent_id, type, icon, name, sort, route_url, page_url, org_type, authority, create_time, update_time, is_delete)
VALUES (
@slaughter_parent_id,
1,
'el-icon-truck',
'进场管理',
2,
'entry',
'slaughter/entry',
2,
'slaughterEntry:list',
NOW(),
NOW(),
0
);
SET @slaughter_entry_menu_id = LAST_INSERT_ID();
INSERT INTO sys_menu (parent_id, type, icon, name, sort, route_url, page_url, org_type, authority, create_time, update_time, is_delete)
VALUES
(@slaughter_entry_menu_id, 2, NULL, '新增', 1, NULL, NULL, 2, 'slaughterEntry:add', NOW(), NOW(), 0),
(@slaughter_entry_menu_id, 2, NULL, '编辑', 2, NULL, NULL, 2, 'slaughterEntry:edit', NOW(), NOW(), 0),
(@slaughter_entry_menu_id, 2, NULL, '删除', 3, NULL, NULL, 2, 'slaughterEntry:delete', NOW(), NOW(), 0),
(@slaughter_entry_menu_id, 2, NULL, '查询', 4, NULL, NULL, 2, 'slaughterEntry:query', NOW(), NOW(), 0);