Browse Source

Merge remote-tracking branch 'origin/dev' into dev

lazhaoqian 3 years ago
parent
commit
677747cdd1
26 changed files with 1674 additions and 62 deletions
  1. 3 0
      blade-service-api/blade-land-api/src/main/java/org/springblade/land/entity/OrderItem.java
  2. 34 0
      blade-service-api/trade-purchase-api/src/main/java/com/trade/purchase/office/dto/StockDTO.java
  3. 153 0
      blade-service-api/trade-purchase-api/src/main/java/com/trade/purchase/office/entity/Stock.java
  4. 49 0
      blade-service-api/trade-purchase-api/src/main/java/com/trade/purchase/office/feign/IOfficeOrderClient.java
  5. 44 0
      blade-service-api/trade-purchase-api/src/main/java/com/trade/purchase/office/vo/StockVO.java
  6. 38 1
      blade-service-api/trade-purchase-api/src/main/java/com/trade/purchase/order/entity/Order.java
  7. 14 0
      blade-service-api/trade-purchase-api/src/main/java/com/trade/purchase/order/entity/OrderItems.java
  8. 27 0
      blade-service-api/trade-purchase-api/src/main/java/com/trade/purchase/order/vo/OrderVO.java
  9. 5 5
      blade-service/blade-check/pom.xml
  10. 2 0
      blade-service/blade-check/src/main/java/org/springblade/check/CheckApplication.java
  11. 11 6
      blade-service/blade-check/src/main/java/org/springblade/check/controller/AuditProecessController.java
  12. 2 0
      blade-service/blade-check/src/main/java/org/springblade/check/service/IAuditProecessService.java
  13. 229 47
      blade-service/blade-check/src/main/java/org/springblade/check/service/impl/AuditProecessServiceImpl.java
  14. 10 3
      blade-service/blade-land/src/main/java/org/springblade/land/service/impl/OrderItemServiceImpl.java
  15. 6 0
      blade-service/trade-purchase/pom.xml
  16. 131 0
      blade-service/trade-purchase/src/main/java/com/trade/purchase/office/controller/OfficeOrderController.java
  17. 40 0
      blade-service/trade-purchase/src/main/java/com/trade/purchase/office/controller/OfficeOrderItemController.java
  18. 125 0
      blade-service/trade-purchase/src/main/java/com/trade/purchase/office/controller/StockController.java
  19. 42 0
      blade-service/trade-purchase/src/main/java/com/trade/purchase/office/mapper/StockMapper.java
  20. 33 0
      blade-service/trade-purchase/src/main/java/com/trade/purchase/office/mapper/StockMapper.xml
  21. 8 0
      blade-service/trade-purchase/src/main/java/com/trade/purchase/office/service/IOfficeOrderItemService.java
  22. 81 0
      blade-service/trade-purchase/src/main/java/com/trade/purchase/office/service/IOfficeOrderService.java
  23. 51 0
      blade-service/trade-purchase/src/main/java/com/trade/purchase/office/service/IStockService.java
  24. 14 0
      blade-service/trade-purchase/src/main/java/com/trade/purchase/office/service/impl/OfficeOrderItemServiceImpl.java
  25. 411 0
      blade-service/trade-purchase/src/main/java/com/trade/purchase/office/service/impl/OfficeOrderServiceImpl.java
  26. 111 0
      blade-service/trade-purchase/src/main/java/com/trade/purchase/office/service/impl/StockServiceImpl.java

+ 3 - 0
blade-service-api/blade-land-api/src/main/java/org/springblade/land/entity/OrderItem.java

@@ -290,6 +290,9 @@ public class OrderItem implements Serializable {
 	private Integer isDeleted;
 
 	@TableField(exist = false)
+	private String corpName;
+
+	@TableField(exist = false)
 	private String fleetName;
 
 	@TableField(exist = false)

+ 34 - 0
blade-service-api/trade-purchase-api/src/main/java/com/trade/purchase/office/dto/StockDTO.java

@@ -0,0 +1,34 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package com.trade.purchase.office.dto;
+
+import com.trade.purchase.office.entity.Stock;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 办公用品库存账数据传输对象实体类
+ *
+ * @author BladeX
+ * @since 2022-04-02
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class StockDTO extends Stock {
+	private static final long serialVersionUID = 1L;
+
+}

+ 153 - 0
blade-service-api/trade-purchase-api/src/main/java/com/trade/purchase/office/entity/Stock.java

@@ -0,0 +1,153 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package com.trade.purchase.office.entity;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * 办公用品库存账实体类
+ *
+ * @author BladeX
+ * @since 2022-04-02
+ */
+@Data
+@TableName("office_stock")
+@ApiModel(value = "Stock对象", description = "办公用品库存账")
+public class Stock implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * 主键
+	 */
+	@ApiModelProperty(value = "主键")
+	@TableId
+	private Long id;
+	/**
+	 * 仓库/库区id
+	 */
+	@ApiModelProperty(value = "仓库/库区id")
+	private Long storageId;
+	/**
+	 * 商品id
+	 */
+	@ApiModelProperty(value = "商品id")
+	private Long goodsId;
+	/**
+	 * 期初
+	 */
+	@ApiModelProperty(value = "期初")
+	private BigDecimal opening;
+	/**
+	 * 入库数量
+	 */
+	@ApiModelProperty(value = "入库数量")
+	private BigDecimal inQuantity;
+	/**
+	 * 出库数量
+	 */
+	@ApiModelProperty(value = "出库数量")
+	private BigDecimal outQuantity;
+	/**
+	 * 结余数量
+	 */
+	@ApiModelProperty(value = "结余数量")
+	private BigDecimal balanceQuantity;
+	/**
+	 * 单价
+	 */
+	@ApiModelProperty(value = "单价")
+	private BigDecimal unitPrice;
+	/**
+	 * 金额
+	 */
+	@ApiModelProperty(value = "金额")
+	private BigDecimal amount;
+	/**
+	 * 类型
+	 */
+	@ApiModelProperty(value = "类型")
+	private String tradeType;
+	/**
+	 * 备注
+	 */
+	@ApiModelProperty(value = "备注")
+	private String remarks;
+	/**
+	 * 入库日期
+	 */
+	@ApiModelProperty(value = "入库日期")
+	@DateTimeFormat(pattern = "yyyy-MM")
+	@JsonFormat(pattern = "yyyy-MM")
+	private Date inDate;
+	/**
+	 * 租户id
+	 */
+	@ApiModelProperty(value = "租户id")
+	private String tenantId;
+	/**
+	 * 创建人
+	 */
+	@ApiModelProperty(value = "创建人")
+	private Long createUser;
+	/**
+	 * 创建部门
+	 */
+	@ApiModelProperty(value = "创建部门")
+	private Long createDept;
+	/**
+	 * 创建时间
+	 */
+	@ApiModelProperty(value = "创建时间")
+	@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+	private Date createTime;
+	/**
+	 * 修改人
+	 */
+	@ApiModelProperty(value = "修改人")
+	private Long updateUser;
+	/**
+	 * 修改时间
+	 */
+	@ApiModelProperty(value = "修改时间")
+	@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+	private Date updateTime;
+	/**
+	 * 状态
+	 */
+	@ApiModelProperty(value = "状态")
+	private Integer status;
+	/**
+	 * 是否已删除(0 否 1是)
+	 */
+	@ApiModelProperty(value = "是否已删除(0 否 1是)")
+	private Integer isDeleted;
+
+
+}

+ 49 - 0
blade-service-api/trade-purchase-api/src/main/java/com/trade/purchase/office/feign/IOfficeOrderClient.java

@@ -0,0 +1,49 @@
+package com.trade.purchase.office.feign;
+
+import org.springblade.core.tool.api.R;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+
+/**
+ * @author caifc
+ * @date 2021-10-21 22:28
+ */
+@FeignClient(
+	value = "trade-purchase"
+)
+public interface IOfficeOrderClient {
+
+	String API_PREFIX = "/office-order";
+	String PASS_CHECK = API_PREFIX + "/pass-check";
+	String PASS_CANCEL = API_PREFIX + "/pass-cancel";
+	String UNDER_REVIEW = API_PREFIX + "/under-review";
+
+	/**
+	 * 审核通过
+	 *
+	 * @param id
+	 * @return
+	 */
+	@PostMapping(PASS_CHECK)
+	R passCheck(@RequestParam("id") Long id);
+
+	/**
+	 * 审核不通过
+	 *
+	 * @param id
+	 * @return
+	 */
+	@PostMapping(PASS_CANCEL)
+	R passCancel(@RequestParam("id") Long id);
+
+	/**
+	 * 审核中
+	 *
+	 * @param id
+	 * @return
+	 */
+	@PostMapping(UNDER_REVIEW)
+	R underReview(@RequestParam("id") Long id);
+
+}

+ 44 - 0
blade-service-api/trade-purchase-api/src/main/java/com/trade/purchase/office/vo/StockVO.java

@@ -0,0 +1,44 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package com.trade.purchase.office.vo;
+
+import com.trade.purchase.office.entity.Stock;
+import io.swagger.annotations.ApiModel;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 办公用品库存账视图实体类
+ *
+ * @author BladeX
+ * @since 2022-04-02
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ApiModel(value = "StockVO对象", description = "办公用品库存账")
+public class StockVO extends Stock {
+	private static final long serialVersionUID = 1L;
+
+	private String cname;
+
+	private String code;
+
+	private String beginInDate;
+
+	private String endInDate;
+
+}

+ 38 - 1
blade-service-api/trade-purchase-api/src/main/java/com/trade/purchase/order/entity/Order.java

@@ -1,14 +1,16 @@
 package com.trade.purchase.order.entity;
 
 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 com.trade.purchase.order.common.entity.OrderBase;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
 
-import java.io.Serializable;
 import java.math.BigDecimal;
 import java.util.Date;
 
@@ -656,4 +658,39 @@ public class Order extends OrderBase {
 	@ApiModelProperty(value = "批次号")
 	private String lotNo;
 
+	/**
+	 * 申请人
+	 */
+	@ApiModelProperty(value = "申请人")
+	private Long applyUser;
+	/**
+	 * 申请部门
+	 */
+	@ApiModelProperty(value = "申请部门")
+	private Long applyDept;
+	/**
+	 * 申请时间
+	 */
+	@ApiModelProperty(value = "申请时间")
+	@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+	private Date applyTime;
+	/**
+	 * 库管员
+	 */
+	@ApiModelProperty(value = "库管员")
+	private Long stockUser;
+	/**
+	 * 库管部门
+	 */
+	@ApiModelProperty(value = "库管部门")
+	private Long stockDept;
+	/**
+	 * 入库时间
+	 */
+	@ApiModelProperty(value = "入库时间")
+	@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+	private Date stockTime;
+
 }

+ 14 - 0
blade-service-api/trade-purchase-api/src/main/java/com/trade/purchase/order/entity/OrderItems.java

@@ -52,6 +52,11 @@ public class OrderItems extends OrderBase {
 	@ApiModelProperty(value = "价格类别")
 	private String priceType;
 	/**
+	 * 库区id
+	 */
+	@ApiModelProperty(value = "库区id")
+	private Long storageId;
+	/**
 	 * 货物id
 	 */
 	@ApiModelProperty(value = "货物id")
@@ -440,4 +445,13 @@ public class OrderItems extends OrderBase {
 	 */
 	@ApiModelProperty(value = "最新价格时间")
 	private Date newDate;
+
+	@TableField(exist = false)
+	private String storageName;
+
+	@TableField(exist = false)
+	private String createUserName;
+
+	@TableField(exist = false)
+	private String updateUserName;
 }

+ 27 - 0
blade-service-api/trade-purchase-api/src/main/java/com/trade/purchase/order/vo/OrderVO.java

@@ -172,4 +172,31 @@ public class OrderVO extends Order {
 	@ApiModelProperty(value = "计划交货日期结束")
 	private String plannedDeliveryEnd;
 
+	/**
+	 * 申请人中文名
+	 */
+	@ApiModelProperty(value = "申请人中文名")
+	private String applyUserName;
+	/**
+	 * 申请部门中文名
+	 */
+	@ApiModelProperty(value = "申请部门中文名")
+	private String applyDeptName;
+	/**
+	 * 库管员中文名
+	 */
+	@ApiModelProperty(value = "库管员中文名")
+	private String stockUserName;
+
+	/**
+	 * 库管部门中文名
+	 */
+	@ApiModelProperty(value = "库管部门中文名")
+	private String stockDeptName;
+
+	private Integer checkFlag;
+	private String checkType;
+	private String url;
+	private String pageStatus;
+	private String pageLabel;
 }

+ 5 - 5
blade-service/blade-check/pom.xml

@@ -48,11 +48,6 @@
             <groupId>org.springblade</groupId>
             <artifactId>blade-core-boot</artifactId>
         </dependency>
-
-        <dependency>
-            <groupId>org.springblade</groupId>
-            <artifactId>blade-starter-swagger</artifactId>
-        </dependency>
         <dependency>
             <groupId>org.springblade</groupId>
             <artifactId>blade-client-api</artifactId>
@@ -105,6 +100,11 @@
             <version>2.8.2.RELEASE</version>
             <scope>compile</scope>
         </dependency>
+        <dependency>
+            <groupId>org.springblade</groupId>
+            <artifactId>trade-purchase-api</artifactId>
+            <version>2.8.2.RELEASE</version>
+        </dependency>
     </dependencies>
 
 

+ 2 - 0
blade-service/blade-check/src/main/java/org/springblade/check/CheckApplication.java

@@ -20,6 +20,7 @@ import org.springblade.core.cloud.feign.EnableBladeFeign;
 import org.springblade.core.launch.BladeApplication;
 import org.springblade.core.transaction.annotation.SeataCloudApplication;
 import org.springframework.cloud.client.SpringCloudApplication;
+import org.springframework.cloud.openfeign.EnableFeignClients;
 
 /**
  * 用户启动器
@@ -27,6 +28,7 @@ import org.springframework.cloud.client.SpringCloudApplication;
  * @author Chill
  */
 @EnableBladeFeign
+@EnableFeignClients({"org.springblade", "com.trade.purchase"})
 @SpringCloudApplication
 @SeataCloudApplication
 public class CheckApplication {

+ 11 - 6
blade-service/blade-check/src/main/java/org/springblade/check/controller/AuditProecessController.java

@@ -203,16 +203,21 @@ public class AuditProecessController extends BladeController {
 		if (StringUtils.isBlank(proecess.getCheckType())) {
 			throw new SecurityException("审核失败,未填写审批类型");
 		}
-		//付费申请请核
-		if (proecess.getCheckType().equals("ffsq")) {
+		// 付费申请请核
+		if ("ffsq".equals(proecess.getCheckType())) {
 			auditProecessService.operationFinanceProcess(auditProecess);
 		}
-		//采购 或者 销售 订单请核
-		else if (proecess.getCheckType().equals("xsqh") || proecess.getCheckType().equals("cgqh")) {
+		// 采购 或者 销售 订单请核
+		else if ("xsqh".equals(proecess.getCheckType()) || "cgqh".equals(proecess.getCheckType())) {
 			auditProecessService.orderCheckProcess(auditProecess);
-		} else if (proecess.getCheckType().equals("xsgz") || proecess.getCheckType().equals("czgz") //通济学校 小学 初中 高中 后勤工资审核
-		|| proecess.getCheckType().equals("gzgz") ||proecess.getCheckType().equals("hqgz")) {
+		}
+		// 通济学校 小学 初中 高中 后勤工资审核
+		else if ("xsgz".equals(proecess.getCheckType()) || "czgz".equals(proecess.getCheckType()) || "gzgz".equals(proecess.getCheckType()) || "hqgz".equals(proecess.getCheckType())) {
 			auditProecessService.salaryCheck(auditProecess);
+		}
+		// 办公用品采购
+		else if ("ocg".equals(proecess.getCheckType()) || "oly".equals(proecess.getCheckType())) {
+			auditProecessService.officeCheck(auditProecess);
 		} else {
 			throw new SecurityException("此审批类型未查到相关审批类型");
 		}

+ 2 - 0
blade-service/blade-check/src/main/java/org/springblade/check/service/IAuditProecessService.java

@@ -57,4 +57,6 @@ public interface IAuditProecessService extends IService<AuditProecess> {
 
 	void salaryCheck(AuditProecess auditProecess);
 
+	void officeCheck(AuditProecess auditProecess);
+
 }

+ 229 - 47
blade-service/blade-check/src/main/java/org/springblade/check/service/impl/AuditProecessServiceImpl.java

@@ -20,6 +20,7 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.trade.purchase.office.feign.IOfficeOrderClient;
 import io.seata.spring.annotation.GlobalTransactional;
 import lombok.AllArgsConstructor;
 import org.springblade.check.dto.AuditProecessDTO;
@@ -41,7 +42,6 @@ import org.springblade.finance.feign.IFinanceClient;
 import org.springblade.finance.vojo.Settlement;
 import org.springblade.project.entity.ServiceProject;
 import org.springblade.project.feign.IProjectClient;
-import org.springblade.project.feign.IProjectItemClient;
 import org.springblade.purchase.sales.entity.Order;
 import org.springblade.purchase.sales.feign.IOrderCheckClient;
 import org.springblade.purchase.sales.feign.IOrderDescClient;
@@ -65,35 +65,35 @@ import java.util.stream.Collectors;
 @AllArgsConstructor
 public class AuditProecessServiceImpl extends ServiceImpl<AuditProecessMapper, AuditProecess> implements IAuditProecessService {
 
-	private AuditPathsActsMapper auditPathsActsMapper;
+	private final AuditPathsActsMapper auditPathsActsMapper;
 
-	private IFinanceClient financeClient;
+	private final IFinanceClient financeClient;
 
-	private IMessageClient messageClient;
+	private final IMessageClient messageClient;
 
-	private IOrderDescClient orderDescClient;
+	private final IOrderDescClient orderDescClient;
 
-	private IProjectItemClient iProjectItemClient;
+	private final IProjectClient iProjectClient;
 
-	private IProjectClient iProjectClient;
+	private final IOrderCheckClient orderCheckClient;
 
-	private IOrderCheckClient orderCheckClient;
-
-	private ICorpsDescClient iCorpsDescClient;
+	private final ICorpsDescClient iCorpsDescClient;
 
 	private final ISalaryClient salaryClient;
 
+	private final IOfficeOrderClient officeOrderClient;
+
 	@Override
 	public IPage<AuditProecessVO> selectAuditProecessPage(IPage<AuditProecessVO> page, AuditProecessVO auditProecess) {
 		return page.setRecords(baseMapper.selectAuditProecessPage(page, auditProecess));
 	}
 
 	@Override
-	@Transactional
-	@GlobalTransactional
+	@Transactional(rollbackFor = Exception.class)
+	@GlobalTransactional(rollbackFor = Exception.class)
 	public void createFinanceProcess(AuditProecessDTO auditProecessDTO) {
 		//查询最大批次号
-		int current = 0;
+		int current;
 		LambdaQueryWrapper<AuditProecess> auditProecessLambdaQueryWrapper = new LambdaQueryWrapper<>();
 		auditProecessLambdaQueryWrapper.eq(AuditProecess::getSrcBillId, auditProecessDTO.getSrcBillId());
 		List<AuditProecess> auditProecesses = baseMapper.selectList(auditProecessLambdaQueryWrapper);
@@ -181,21 +181,28 @@ public class AuditProecessServiceImpl extends ServiceImpl<AuditProecessMapper, A
 					message.setMessageBody("您有小学部工资审核,请审核,"
 						+ " 提交人:" + auditProecessDTO.getSendName() + "  " + "提交时间" + simpleDateFormat.format(auditProecessDTO.getSendTime())
 					);
-				}else if ("初中部工资审批".equals(auditProecessDTO.getProcessType())) {
+				} else if ("初中部工资审批".equals(auditProecessDTO.getProcessType())) {
 					message.setMessageBody("您有初中部工资审核,请审核,"
 						+ " 提交人:" + auditProecessDTO.getSendName() + "  " + "提交时间" + simpleDateFormat.format(auditProecessDTO.getSendTime())
 					);
-				}else if ("高中部工资审批".equals(auditProecessDTO.getProcessType())) {
+				} else if ("高中部工资审批".equals(auditProecessDTO.getProcessType())) {
 					message.setMessageBody("您有高中部工资审核,请审核,"
 						+ " 提交人:" + auditProecessDTO.getSendName() + "  " + "提交时间" + simpleDateFormat.format(auditProecessDTO.getSendTime())
 					);
-				}else if ("后勤部工资审批".equals(auditProecessDTO.getProcessType())) {
+				} else if ("后勤部工资审批".equals(auditProecessDTO.getProcessType())) {
 					message.setMessageBody("您有后勤部工资审核,请审核,"
 						+ " 提交人:" + auditProecessDTO.getSendName() + "  " + "提交时间" + simpleDateFormat.format(auditProecessDTO.getSendTime())
 					);
+				} else if ("办公用品采购审批".equals(auditProecessDTO.getProcessType())) {
+					message.setMessageBody("您有办公用品采购审核,请审核,"
+						+ " 提交人:" + auditProecessDTO.getSendName() + "  " + "提交时间" + simpleDateFormat.format(auditProecessDTO.getSendTime())
+					);
+				} else if ("办公用品领用审批".equals(auditProecessDTO.getProcessType())) {
+					message.setMessageBody("您有办公用品领用审核,请审核,"
+						+ " 提交人:" + auditProecessDTO.getSendName() + "  " + "提交时间" + simpleDateFormat.format(auditProecessDTO.getSendTime())
+					);
 				}
 
-
 				message.setUrl("/approveData/index");
 				R save = messageClient.save(message);
 				if (!save.isSuccess()) {
@@ -223,8 +230,8 @@ public class AuditProecessServiceImpl extends ServiceImpl<AuditProecessMapper, A
 	}
 
 	@Override
-	@Transactional
-	@GlobalTransactional
+	@Transactional(rollbackFor = Exception.class)
+	@GlobalTransactional(rollbackFor = Exception.class)
 	public void operationFinanceProcess(AuditProecess auditProecess) {
 
 		//查看最新操作记录,防止重复提交
@@ -403,8 +410,8 @@ public class AuditProecessServiceImpl extends ServiceImpl<AuditProecessMapper, A
 	}
 
 	@Override
-	@Transactional
-	@GlobalTransactional
+	@Transactional(rollbackFor = Exception.class)
+	@GlobalTransactional(rollbackFor = Exception.class)
 	public void serverProcess(AuditProecess auditProecess) {
 
 		//查看最新操作记录,防止重复提交
@@ -560,8 +567,8 @@ public class AuditProecessServiceImpl extends ServiceImpl<AuditProecessMapper, A
 	}
 
 	@Override
-	@Transactional
-	@GlobalTransactional
+	@Transactional(rollbackFor = Exception.class)
+	@GlobalTransactional(rollbackFor = Exception.class)
 	public void orderCheckProcess(AuditProecess auditProecess) {
 		//查看最新操作记录,防止重复提交
 		AuditProecess auditProecess1 = baseMapper.selectById(auditProecess.getId());
@@ -764,8 +771,8 @@ public class AuditProecessServiceImpl extends ServiceImpl<AuditProecessMapper, A
 	}
 
 	@Override
-	@Transactional
-	@GlobalTransactional
+	@Transactional(rollbackFor = Exception.class)
+	@GlobalTransactional(rollbackFor = Exception.class)
 	public void batchOperation(List<AuditProecess> processLis, Integer operate, String auditMsg) {
 		processLis.forEach(e -> {
 			e.setOperate(operate);
@@ -782,8 +789,8 @@ public class AuditProecessServiceImpl extends ServiceImpl<AuditProecessMapper, A
 	}
 
 	@Override
-	@Transactional
-	@GlobalTransactional
+	@Transactional(rollbackFor = Exception.class)
+	@GlobalTransactional(rollbackFor = Exception.class)
 	public void changeAuditUser(AuditProecess auditProecess) {
 		baseMapper.updateById(auditProecess);
 
@@ -840,8 +847,8 @@ public class AuditProecessServiceImpl extends ServiceImpl<AuditProecessMapper, A
 	}
 
 	@Override
-	@Transactional
-	@GlobalTransactional
+	@Transactional(rollbackFor = Exception.class)
+	@GlobalTransactional(rollbackFor = Exception.class)
 	public void cancelCheck(Long srcBillId) {
 		//查询最大批次号
 		LambdaQueryWrapper<AuditProecess> countMaxWrapper = new LambdaQueryWrapper<>();
@@ -886,8 +893,8 @@ public class AuditProecessServiceImpl extends ServiceImpl<AuditProecessMapper, A
 	 * @param auditProecess
 	 */
 	@Override
-	@Transactional
-	@GlobalTransactional
+	@Transactional(rollbackFor = Exception.class)
+	@GlobalTransactional(rollbackFor = Exception.class)
 	public void salaryCheck(AuditProecess auditProecess) {
 		//查看最新操作记录,防止重复提交
 		AuditProecess auditProecess1 = baseMapper.selectById(auditProecess.getId());
@@ -973,19 +980,19 @@ public class AuditProecessServiceImpl extends ServiceImpl<AuditProecessMapper, A
 				message.setToUserId(Long.valueOf(proecess.getAuditUserId()));
 				message.setMessageType(1);
 				message.setTenantId(AuthUtil.getTenantId());
-				if (auditProecess1.getCheckType().equals("xsgz")){
+				if (auditProecess1.getCheckType().equals("xsgz")) {
 					message.setMessageBody("您有小学部工资审核请审核。"
 						+ "提交人:" + auditProecess1.getSendName() + "  " + "提交时间" + simpleDateFormat.format(auditProecess1.getSendTime())
 					);
-				}else if (auditProecess1.getCheckType().equals("czgz")){
+				} else if (auditProecess1.getCheckType().equals("czgz")) {
 					message.setMessageBody("您有初中部工资审核请审核。"
 						+ "提交人:" + auditProecess1.getSendName() + "  " + "提交时间" + simpleDateFormat.format(auditProecess1.getSendTime())
 					);
-				}else if (auditProecess1.getCheckType().equals("gzgz")){
+				} else if (auditProecess1.getCheckType().equals("gzgz")) {
 					message.setMessageBody("您有高中部工资审核请审核。"
 						+ "提交人:" + auditProecess1.getSendName() + "  " + "提交时间" + simpleDateFormat.format(auditProecess1.getSendTime())
 					);
-				}else if (auditProecess1.getCheckType().equals("hqgz")){
+				} else if (auditProecess1.getCheckType().equals("hqgz")) {
 					message.setMessageBody("您有后勤部工资审核请审核。"
 						+ "提交人:" + auditProecess1.getSendName() + "  " + "提交时间" + simpleDateFormat.format(auditProecess1.getSendTime())
 					);
@@ -1007,13 +1014,13 @@ public class AuditProecessServiceImpl extends ServiceImpl<AuditProecessMapper, A
 				if (!r.isSuccess()) {
 					throw new SecurityException("修改原数据失败");
 				}
-				if (auditProecess1.getCheckType().equals("xsgz")){
+				if (auditProecess1.getCheckType().equals("xsgz")) {
 					sendMessage.setMessageBody("您的小学部工资请核未通过,驳回原因:" + auditProecess.getAuditMsg());
-				}else if (auditProecess1.getCheckType().equals("czgz")){
+				} else if (auditProecess1.getCheckType().equals("czgz")) {
 					sendMessage.setMessageBody("您的初中部工资请核未通过,驳回原因:" + auditProecess.getAuditMsg());
-				}else if (auditProecess1.getCheckType().equals("gzgz")){
+				} else if (auditProecess1.getCheckType().equals("gzgz")) {
 					sendMessage.setMessageBody("您的高中部工资请核未通过,驳回原因:" + auditProecess.getAuditMsg());
-				}else if (auditProecess1.getCheckType().equals("hqgz")){
+				} else if (auditProecess1.getCheckType().equals("hqgz")) {
 					sendMessage.setMessageBody("您的后勤部工资请核未通过,驳回原因:" + auditProecess.getAuditMsg());
 				}
 				R save = messageClient.save(sendMessage);
@@ -1033,13 +1040,13 @@ public class AuditProecessServiceImpl extends ServiceImpl<AuditProecessMapper, A
 				if (!r.isSuccess()) {
 					throw new SecurityException(r.getMsg());
 				}
-				if (auditProecess1.getCheckType().equals("xsgz")){
+				if (auditProecess1.getCheckType().equals("xsgz")) {
 					sendMessage.setMessageBody("您的小学部工资请核已通过,请继续操作");
-				}else if (auditProecess1.getCheckType().equals("czgz")){
+				} else if (auditProecess1.getCheckType().equals("czgz")) {
 					sendMessage.setMessageBody("您的初中部工资请核已通过,请继续操作");
-				}else if (auditProecess1.getCheckType().equals("gzgz")){
+				} else if (auditProecess1.getCheckType().equals("gzgz")) {
 					sendMessage.setMessageBody("您的高中部工资请核已通过,请继续操作");
-				}else if (auditProecess1.getCheckType().equals("hqgz")){
+				} else if (auditProecess1.getCheckType().equals("hqgz")) {
 					sendMessage.setMessageBody("您的后勤部工资请核已通过,请继续操作");
 				}
 				R save = messageClient.save(sendMessage);
@@ -1055,13 +1062,13 @@ public class AuditProecessServiceImpl extends ServiceImpl<AuditProecessMapper, A
 				if (!r.isSuccess()) {
 					throw new SecurityException("修改原数据失败");
 				}
-				if (auditProecess1.getCheckType().equals("xsgz")){
+				if (auditProecess1.getCheckType().equals("xsgz")) {
 					sendMessage.setMessageBody("您的小学部工资请核未通过,驳回原因:" + auditProecess.getAuditMsg());
-				}else if (auditProecess1.getCheckType().equals("czgz")){
+				} else if (auditProecess1.getCheckType().equals("czgz")) {
 					sendMessage.setMessageBody("您的初中部工资请核未通过,驳回原因:" + auditProecess.getAuditMsg());
-				}else if (auditProecess1.getCheckType().equals("gzgz")){
+				} else if (auditProecess1.getCheckType().equals("gzgz")) {
 					sendMessage.setMessageBody("您的高中部工资请核未通过,驳回原因:" + auditProecess.getAuditMsg());
-				}else if (auditProecess1.getCheckType().equals("hqgz")){
+				} else if (auditProecess1.getCheckType().equals("hqgz")) {
 					sendMessage.setMessageBody("您的后勤部工资请核未通过,驳回原因:" + auditProecess.getAuditMsg());
 				}
 				R save = messageClient.save(sendMessage);
@@ -1078,4 +1085,179 @@ public class AuditProecessServiceImpl extends ServiceImpl<AuditProecessMapper, A
 		baseMapper.updateById(auditProecess);
 	}
 
+	/**
+	 * 办公用品采购审核
+	 *
+	 * @param auditProecess
+	 */
+	@Override
+	@Transactional(rollbackFor = Exception.class)
+	@GlobalTransactional(rollbackFor = Exception.class)
+	public void officeCheck(AuditProecess auditProecess) {
+		// 查看最新操作记录,防止重复提交
+		AuditProecess auditProecess1 = baseMapper.selectById(auditProecess.getId());
+		if (auditProecess1 == null) {
+			throw new SecurityException("未查到此审批记录,禁止操作");
+		}
+		if ("A".equals(auditProecess1.getAuditStatus()) || "B".equals(auditProecess1.getAuditStatus())) {
+			throw new SecurityException("当前记录已经完成审批,禁止重复操作");
+		}
+
+		if (auditProecess.getAuditStatus() == null || !"S".equals(auditProecess.getAuditStatus())) {
+			throw new SecurityException("审批状态非待审,禁止操作");
+		}
+		// 信息
+		Message sendMessage = new Message();
+		sendMessage.setParameter(String.valueOf(auditProecess.getBillId()));
+		sendMessage.setUserName(AuthUtil.getUserName());
+		sendMessage.setUserId(AuthUtil.getUserId());
+		sendMessage.setToUserId(auditProecess.getSendUserId());
+		sendMessage.setToUserName(auditProecess.getSendName());
+		sendMessage.setMessageType(1);
+		sendMessage.setTenantId(AuthUtil.getTenantId());
+		sendMessage.setCreateUser(AuthUtil.getUserId());
+		sendMessage.setCreateTime(new Date());
+		sendMessage.setUrl(auditProecess.getUrl());
+		sendMessage.setPageLabel(auditProecess.getPageLabel());
+		sendMessage.setPageStatus(auditProecess.getPageStatus());
+
+		// 用户操作 1.通过  2.驳回
+		Integer operate = auditProecess.getOperate();
+		// 查看当前审批是否为最后一级
+		String iffinalItem = auditProecess.getIffinalItem();
+		// 审批人
+		auditProecess.setAuditUserId(String.valueOf(AuthUtil.getUserId()));
+		// 审批时间
+		auditProecess.setAuditOpTime(new Date());
+		// 不是最后一级
+		if ("F".equals(iffinalItem)) {
+
+			// 通过
+			if (operate == 1) {
+				// 如果是第一级, 则修改状态为审批中
+				if (auditProecess.getLevelId() == 1) {
+					R submit = officeOrderClient.underReview(auditProecess.getSrcBillId());
+					if (!submit.isSuccess()) {
+						throw new SecurityException("审批开始修改审核状态失败");
+					}
+				}
+
+				auditProecess.setAuditStatus("A");
+				// 查询下一级,开启待审
+				LambdaQueryWrapper<AuditProecess> auditProecessLambdaQueryWrapper = new LambdaQueryWrapper<>();
+				auditProecessLambdaQueryWrapper
+					.eq(AuditProecess::getBatchNo, auditProecess.getBatchNo())
+					.eq(AuditProecess::getSrcBillId, auditProecess.getSrcBillId())
+					.eq(AuditProecess::getIsDelete, 0)
+					.eq(AuditProecess::getActId, auditProecess.getActId())
+					.eq(AuditProecess::getBillId, auditProecess.getBillId())
+					.eq(AuditProecess::getBillNo, auditProecess.getBillNo())
+					.eq(AuditProecess::getTenantId, AuthUtil.getTenantId())
+					.eq(AuditProecess::getLevelId, auditProecess.getLevelId() + 1);
+				Integer count = baseMapper.selectCount(auditProecessLambdaQueryWrapper);
+				if (count != null && count > 1) {
+					throw new SecurityException("审核失败,获取下一级信息失败");
+				}
+				AuditProecess proecess = baseMapper.selectOne(auditProecessLambdaQueryWrapper);
+				if (proecess == null) {
+					throw new SecurityException("审批通过=>获取下一级信息失败");
+				}
+				proecess.setAuditStatus("S");
+				baseMapper.updateById(proecess);
+
+
+				SimpleDateFormat simpleDateFormat = new SimpleDateFormat();
+				Message message = new Message();
+				message.setParameter(String.valueOf(auditProecess.getBillId()));
+				message.setUserName(AuthUtil.getUserName());
+				message.setUserId(AuthUtil.getUserId());
+				//消息通知下一级
+				message.setToUserId(Long.valueOf(proecess.getAuditUserId()));
+				message.setMessageType(1);
+				message.setTenantId(AuthUtil.getTenantId());
+				if ("ocg".equals(auditProecess1.getCheckType())) {
+					message.setMessageBody("您有办公用品采购审核请审核。"
+						+ "提交人:" + auditProecess1.getSendName() + "  提交时间" + simpleDateFormat.format(auditProecess1.getSendTime())
+					);
+				} else if ("oly".equals(auditProecess1.getCheckType())) {
+					message.setMessageBody("您有办公用品领用审核请审核。"
+						+ "提交人:" + auditProecess1.getSendName() + "  提交时间" + simpleDateFormat.format(auditProecess1.getSendTime())
+					);
+				}
+				message.setCreateUser(AuthUtil.getUserId());
+				message.setUrl("/approveData/index");
+				message.setCreateTime(new Date());
+
+				R save = messageClient.save(message);
+				if (!save.isSuccess()) {
+					throw new SecurityException("发送消息失败");
+				}
+			}
+			// 不通过
+			else if (operate == 2) {
+				auditProecess.setAuditStatus("B");
+				R r = officeOrderClient.passCancel(auditProecess.getSrcBillId());
+				if (!r.isSuccess()) {
+					throw new SecurityException("修改原数据失败");
+				}
+
+				if ("ocg".equals(auditProecess1.getCheckType())) {
+					sendMessage.setMessageBody("您的办公用品采购请核未通过,驳回原因:" + auditProecess.getAuditMsg());
+				} else if ("oly".equals(auditProecess1.getCheckType())) {
+					sendMessage.setMessageBody("您的办公用品领用请核未通过,驳回原因:" + auditProecess.getAuditMsg());
+				}
+				R save = messageClient.save(sendMessage);
+				if (!save.isSuccess()) {
+					throw new SecurityException("发送消息失败");
+				}
+			}
+
+		}
+		// 是最后一级
+		else if ("T".equals(iffinalItem)) {
+			// 通过
+			if (operate == 1) {
+				auditProecess.setAuditStatus("A");
+				R r = officeOrderClient.passCheck(auditProecess.getSrcBillId());
+				if (!r.isSuccess()) {
+					throw new SecurityException(r.getMsg());
+				}
+
+				if ("ocg".equals(auditProecess1.getCheckType())) {
+					sendMessage.setMessageBody("您的办公用品采购请核已通过,请继续操作");
+				} else if ("oly".equals(auditProecess1.getCheckType())) {
+					sendMessage.setMessageBody("您的办公用品领用请核已通过,请继续操作");
+				}
+				R save = messageClient.save(sendMessage);
+				if (!save.isSuccess()) {
+					throw new SecurityException("发送消息失败");
+				}
+			}
+			// 不通过
+			else if (operate == 2) {
+				auditProecess.setAuditStatus("B");
+				R r = officeOrderClient.passCancel(auditProecess.getSrcBillId());
+				if (!r.isSuccess()) {
+					throw new SecurityException("修改原数据失败");
+				}
+
+				if ("ocg".equals(auditProecess1.getCheckType())) {
+					sendMessage.setMessageBody("您的办公用品采购请核未通过,驳回原因:" + auditProecess.getAuditMsg());
+				} else if ("oly".equals(auditProecess1.getCheckType())) {
+					sendMessage.setMessageBody("您的办公用品领用请核未通过,驳回原因:" + auditProecess.getAuditMsg());
+				}
+				R save = messageClient.save(sendMessage);
+				if (!save.isSuccess()) {
+					throw new SecurityException("发送消息失败");
+				}
+			}
+		} else {
+			throw new SecurityException("审批异常,请联系管理员");
+		}
+		//保存操作记录
+		auditProecess.setAuditMsg(auditProecess.getAuditMsg());
+		auditProecess.setAuditItem(new Date());
+		baseMapper.updateById(auditProecess);
+	}
+
 }

+ 10 - 3
blade-service/blade-land/src/main/java/org/springblade/land/service/impl/OrderItemServiceImpl.java

@@ -128,10 +128,17 @@ public class OrderItemServiceImpl extends ServiceImpl<OrderItemMapper, OrderItem
 			record.setArrivalTime(order.getArrivalTime());
 			record.setAddressDetail(order.getAddressDetail());
 
+			if (ObjectUtil.isNotEmpty(order.getCorpId())) {
+				R<CorpsDesc> corp = corpsDescClient.getCorpMessage(order.getCorpId());
+				if (corp.isSuccess() && corp.getData() != null) {
+					record.setCorpName(corp.getData().getCname());
+				}
+			}
+
 			if (ObjectUtil.isNotEmpty(record.getFleetId())) {
-				R<CorpsDesc> corpMessage = corpsDescClient.getCorpMessage(record.getFleetId());
-				if (corpMessage.isSuccess() && corpMessage.getData() != null) {
-					record.setFleetName(corpMessage.getData().getCname());
+				R<CorpsDesc> fleet = corpsDescClient.getCorpMessage(record.getFleetId());
+				if (fleet.isSuccess() && fleet.getData() != null) {
+					record.setFleetName(fleet.getData().getCname());
 				}
 			}
 

+ 6 - 0
blade-service/trade-purchase/pom.xml

@@ -87,6 +87,12 @@
             <version>2.8.2.RELEASE</version>
             <scope>compile</scope>
         </dependency>
+        <dependency>
+            <groupId>org.springblade</groupId>
+            <artifactId>blade-check-api</artifactId>
+            <version>2.8.2.RELEASE</version>
+            <scope>compile</scope>
+        </dependency>
 
     </dependencies>
 

+ 131 - 0
blade-service/trade-purchase/src/main/java/com/trade/purchase/office/controller/OfficeOrderController.java

@@ -0,0 +1,131 @@
+package com.trade.purchase.office.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
+import com.trade.purchase.office.service.IOfficeOrderService;
+import com.trade.purchase.order.entity.Order;
+import com.trade.purchase.order.vo.OrderVO;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import lombok.AllArgsConstructor;
+import org.springblade.core.mp.support.Query;
+import org.springblade.core.tool.api.R;
+import org.springblade.core.tool.utils.Func;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.Valid;
+
+/**
+ * 进口采购订单表 控制器
+ *
+ * @author BladeX
+ * @since 2021-09-26
+ */
+@RestController
+@AllArgsConstructor
+@RequestMapping("/office-order")
+@Api(value = "办公用品采购订单", tags = "办公用品采购订单")
+public class OfficeOrderController {
+
+	private final IOfficeOrderService officeOrderService;
+
+	/**
+	 * 详情
+	 */
+	@GetMapping("/{id}")
+	@ApiOperationSupport(order = 1)
+	@ApiOperation(value = "详情", notes = "传入order")
+	public R<Order> detail(Order order) {
+		return R.data(officeOrderService.getDetail(order));
+	}
+
+	/**
+	 * 分页 采购订单表
+	 */
+	@GetMapping("/list")
+	@ApiOperationSupport(order = 2)
+	@ApiOperation(value = "分页 列表", notes = "传入order")
+	public R<IPage<OrderVO>> list(Order order, Query query) {
+		return R.data(officeOrderService.getList(order, query));
+	}
+
+	/**
+	 * 新增 采购订单表
+	 */
+	@PostMapping("/save")
+	@ApiOperationSupport(order = 3)
+	@ApiOperation(value = "新增", notes = "传入order")
+	public R save(@Valid @RequestBody OrderVO orderVO) {
+		return R.data(officeOrderService.saveOrder(orderVO));
+	}
+
+	/**
+	 * 提交 入库确认
+	 */
+	@PostMapping("/submit")
+	@ApiOperationSupport(order = 4)
+	@ApiOperation(value = "提交", notes = "传入order")
+	public R submit(@Valid @RequestBody OrderVO orderVO) {
+		return R.status(officeOrderService.submitOrder(orderVO));
+	}
+
+	/**
+	 * 撤销 入库确认
+	 */
+	@PostMapping("/revoke")
+	@ApiOperationSupport(order = 5)
+	@ApiOperation(value = "撤销", notes = "传入order")
+	public R revoke(@Valid @RequestBody OrderVO orderVO) {
+		return R.status(officeOrderService.revokeOrder(orderVO));
+	}
+
+	/**
+	 * 删除 采购订单表
+	 */
+	@PostMapping("/remove")
+	@ApiOperationSupport(order = 6)
+	@ApiOperation(value = "删除", notes = "传入ids")
+	public R remove(@ApiParam(value = "主键集合", required = true) @RequestParam String ids) {
+		return R.status(officeOrderService.removeByIds(Func.toLongList(ids)));
+	}
+
+	/**
+	 * 审核 采购订单表
+	 */
+	@PostMapping("check-order")
+	@ApiOperationSupport(order = 7)
+	@ApiOperation(value = "审核", notes = "传入order")
+	public R checkOrder(@RequestBody OrderVO orderVO) {
+		officeOrderService.checkOrder(orderVO);
+		return R.data("操作成功");
+	}
+
+	/**
+	 * 审核通过
+	 */
+	@PostMapping("/pass-check")
+	public R passCheck(@ApiParam(value = "主表id", required = true) @RequestParam Long id) {
+		officeOrderService.passCheck(id);
+		return R.success("操作成功");
+	}
+
+	/**
+	 * 审核不通过
+	 */
+	@PostMapping("/pass-cancel")
+	public R passCancel(@ApiParam(value = "主表id", required = true) @RequestParam Long id) {
+		officeOrderService.passCancel(id);
+		return R.success("操作成功");
+	}
+
+	/**
+	 * 审核中
+	 */
+	@PostMapping("/under-review")
+	public R underReview(@ApiParam(value = "主表id", required = true) @RequestParam Long id) {
+		officeOrderService.underReview(id);
+		return R.success("操作成功");
+	}
+
+}

+ 40 - 0
blade-service/trade-purchase/src/main/java/com/trade/purchase/office/controller/OfficeOrderItemController.java

@@ -0,0 +1,40 @@
+package com.trade.purchase.office.controller;
+
+import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
+import com.trade.purchase.office.service.IOfficeOrderItemService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import lombok.AllArgsConstructor;
+import org.springblade.core.tool.api.R;
+import org.springblade.core.tool.utils.Func;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * 进口采购订单表 控制器
+ *
+ * @author BladeX
+ * @since 2021-09-26
+ */
+@RestController
+@AllArgsConstructor
+@RequestMapping("/office-order-item")
+@Api(value = "办公用品采购订单明细", tags = "办公用品采购订单明细")
+public class OfficeOrderItemController {
+
+	private final IOfficeOrderItemService officeOrderItemService;
+
+	/**
+	 * 删除 采购订单明细表
+	 */
+	@PostMapping("/remove")
+	@ApiOperationSupport(order = 1)
+	@ApiOperation(value = "删除", notes = "传入ids")
+	public R remove(@ApiParam(value = "主键集合", required = true) @RequestParam String ids) {
+		return R.status(officeOrderItemService.removeByIds(Func.toLongList(ids)));
+	}
+
+}

+ 125 - 0
blade-service/trade-purchase/src/main/java/com/trade/purchase/office/controller/StockController.java

@@ -0,0 +1,125 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package com.trade.purchase.office.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
+import com.trade.purchase.office.entity.Stock;
+import com.trade.purchase.office.service.IStockService;
+import com.trade.purchase.office.vo.StockVO;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import lombok.AllArgsConstructor;
+import org.springblade.core.boot.ctrl.BladeController;
+import org.springblade.core.mp.support.Condition;
+import org.springblade.core.mp.support.Query;
+import org.springblade.core.tool.api.R;
+import org.springblade.core.tool.utils.Func;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.Valid;
+
+/**
+ * 办公用品库存账 控制器
+ *
+ * @author BladeX
+ * @since 2022-04-02
+ */
+@RestController
+@AllArgsConstructor
+@RequestMapping("/stock")
+@Api(value = "办公用品库存账", tags = "办公用品库存账接口")
+public class StockController extends BladeController {
+
+	private final IStockService stockService;
+
+	/**
+	 * 详情
+	 */
+	@GetMapping("/detail")
+	@ApiOperationSupport(order = 1)
+	@ApiOperation(value = "详情", notes = "传入stock")
+	public R<Stock> detail(Stock stock) {
+		Stock detail = stockService.getOne(Condition.getQueryWrapper(stock));
+		return R.data(detail);
+	}
+
+	/**
+	 * 分页 办公用品库存账
+	 */
+	@GetMapping("/list")
+	@ApiOperationSupport(order = 2)
+	@ApiOperation(value = "分页", notes = "传入stock")
+	public R<IPage<StockVO>> list(StockVO stockVO, Query query) {
+		return R.data(stockService.getList(stockVO, query));
+	}
+
+	/**
+	 * 自定义分页 办公用品库存账
+	 */
+	@GetMapping("/page")
+	@ApiOperationSupport(order = 3)
+	@ApiOperation(value = "分页", notes = "传入stock")
+	public R<IPage<StockVO>> page(StockVO stock, Query query) {
+		IPage<StockVO> pages = stockService.selectStockPage(Condition.getPage(query), stock);
+		return R.data(pages);
+	}
+
+	/**
+	 * 新增 办公用品库存账
+	 */
+	@PostMapping("/save")
+	@ApiOperationSupport(order = 4)
+	@ApiOperation(value = "新增", notes = "传入stock")
+	public R save(@Valid @RequestBody Stock stock) {
+		return R.status(stockService.save(stock));
+	}
+
+	/**
+	 * 修改 办公用品库存账
+	 */
+	@PostMapping("/update")
+	@ApiOperationSupport(order = 5)
+	@ApiOperation(value = "修改", notes = "传入stock")
+	public R update(@Valid @RequestBody Stock stock) {
+		return R.status(stockService.updateById(stock));
+	}
+
+	/**
+	 * 新增或修改 办公用品库存账
+	 */
+	@PostMapping("/submit")
+	@ApiOperationSupport(order = 6)
+	@ApiOperation(value = "新增或修改", notes = "传入stock")
+	public R submit(@Valid @RequestBody Stock stock) {
+		return R.status(stockService.saveOrUpdate(stock));
+	}
+
+
+	/**
+	 * 删除 办公用品库存账
+	 */
+	@PostMapping("/remove")
+	@ApiOperationSupport(order = 8)
+	@ApiOperation(value = "删除", notes = "传入ids")
+	public R remove(@ApiParam(value = "主键集合", required = true) @RequestParam String ids) {
+		return R.status(stockService.removeByIds(Func.toLongList(ids)));
+	}
+
+
+}

+ 42 - 0
blade-service/trade-purchase/src/main/java/com/trade/purchase/office/mapper/StockMapper.java

@@ -0,0 +1,42 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package com.trade.purchase.office.mapper;
+
+import com.trade.purchase.office.entity.Stock;
+import com.trade.purchase.office.vo.StockVO;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import java.util.List;
+
+/**
+ * 办公用品库存账 Mapper 接口
+ *
+ * @author BladeX
+ * @since 2022-04-02
+ */
+public interface StockMapper extends BaseMapper<Stock> {
+
+	/**
+	 * 自定义分页
+	 *
+	 * @param page
+	 * @param stock
+	 * @return
+	 */
+	List<StockVO> selectStockPage(IPage page, StockVO stock);
+
+}

+ 33 - 0
blade-service/trade-purchase/src/main/java/com/trade/purchase/office/mapper/StockMapper.xml

@@ -0,0 +1,33 @@
+<?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.trade.purchase.office.mapper.StockMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="stockResultMap" type="com.trade.purchase.office.entity.Stock">
+        <id column="id" property="id"/>
+        <result column="storage_id" property="storageId"/>
+        <result column="goods_id" property="goodsId"/>
+        <result column="opening" property="opening"/>
+        <result column="in_quantity" property="inQuantity"/>
+        <result column="out_quantity" property="outQuantity"/>
+        <result column="balance_quantity" property="balanceQuantity"/>
+        <result column="unit_price" property="unitPrice"/>
+        <result column="amount" property="amount"/>
+        <result column="trade_type" property="tradeType"/>
+        <result column="remarks" property="remarks"/>
+        <result column="in_date" property="inDate"/>
+        <result column="create_user" property="createUser"/>
+        <result column="create_dept" property="createDept"/>
+        <result column="create_time" property="createTime"/>
+        <result column="update_user" property="updateUser"/>
+        <result column="update_time" property="updateTime"/>
+        <result column="status" property="status"/>
+        <result column="is_deleted" property="isDeleted"/>
+    </resultMap>
+
+
+    <select id="selectStockPage" resultMap="stockResultMap">
+        select * from office_stock where is_deleted = 0
+    </select>
+
+</mapper>

+ 8 - 0
blade-service/trade-purchase/src/main/java/com/trade/purchase/office/service/IOfficeOrderItemService.java

@@ -0,0 +1,8 @@
+package com.trade.purchase.office.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.trade.purchase.order.entity.OrderItems;
+
+public interface IOfficeOrderItemService extends IService<OrderItems> {
+
+}

+ 81 - 0
blade-service/trade-purchase/src/main/java/com/trade/purchase/office/service/IOfficeOrderService.java

@@ -0,0 +1,81 @@
+package com.trade.purchase.office.service;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.trade.purchase.order.entity.Order;
+import com.trade.purchase.order.vo.OrderVO;
+import org.springblade.core.mp.support.Query;
+
+public interface IOfficeOrderService extends IService<Order> {
+
+	/**
+	 * 详情
+	 *
+	 * @param order
+	 * @return
+	 */
+	Order getDetail(Order order);
+
+	/**
+	 * 列表 分页
+	 *
+	 * @param order
+	 * @param query
+	 * @return
+	 */
+	IPage<OrderVO> getList(Order order, Query query);
+
+	/**
+	 * 保存订单
+	 *
+	 * @param orderVO
+	 * @return
+	 */
+	Long saveOrder(OrderVO orderVO);
+
+	/**
+	 * 提交订单
+	 *
+	 * @param orderVO
+	 * @return
+	 */
+	boolean submitOrder(OrderVO orderVO);
+
+	/**
+	 * 撤销订单
+	 *
+	 * @param orderVO
+	 * @return
+	 */
+	boolean revokeOrder(OrderVO orderVO);
+
+	/**
+	 * 审核订单
+	 *
+	 * @param orderVO
+	 * @return
+	 */
+	void checkOrder(OrderVO orderVO);
+
+	/**
+	 * 审核通过
+	 *
+	 * @param id
+	 */
+	void passCheck(Long id);
+
+	/**
+	 * 审核不通过
+	 *
+	 * @param id
+	 */
+	void passCancel(Long id);
+
+	/**
+	 * 审核中
+	 *
+	 * @param id
+	 */
+	void underReview(Long id);
+
+}

+ 51 - 0
blade-service/trade-purchase/src/main/java/com/trade/purchase/office/service/IStockService.java

@@ -0,0 +1,51 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package com.trade.purchase.office.service;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.trade.purchase.office.entity.Stock;
+import com.trade.purchase.office.vo.StockVO;
+import org.springblade.core.mp.support.Query;
+
+/**
+ * 办公用品库存账 服务类
+ *
+ * @author BladeX
+ * @since 2022-04-02
+ */
+public interface IStockService extends IService<Stock> {
+
+	/**
+	 * 自定义分页
+	 *
+	 * @param page
+	 * @param stock
+	 * @return
+	 */
+	IPage<StockVO> selectStockPage(IPage<StockVO> page, StockVO stock);
+
+	/**
+	 * 列表 分页
+	 *
+	 * @param stockVO
+	 * @param query
+	 * @return
+	 */
+	IPage<StockVO> getList(StockVO stockVO, Query query);
+
+}

+ 14 - 0
blade-service/trade-purchase/src/main/java/com/trade/purchase/office/service/impl/OfficeOrderItemServiceImpl.java

@@ -0,0 +1,14 @@
+package com.trade.purchase.office.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.trade.purchase.office.service.IOfficeOrderItemService;
+import com.trade.purchase.order.entity.OrderItems;
+import com.trade.purchase.order.mapper.OrderItemsMapper;
+import lombok.AllArgsConstructor;
+import org.springframework.stereotype.Service;
+
+@Service
+@AllArgsConstructor
+public class OfficeOrderItemServiceImpl extends ServiceImpl<OrderItemsMapper, OrderItems> implements IOfficeOrderItemService {
+
+}

+ 411 - 0
blade-service/trade-purchase/src/main/java/com/trade/purchase/office/service/impl/OfficeOrderServiceImpl.java

@@ -0,0 +1,411 @@
+package com.trade.purchase.office.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.trade.purchase.office.entity.Stock;
+import com.trade.purchase.office.mapper.StockMapper;
+import com.trade.purchase.office.service.IOfficeOrderService;
+import com.trade.purchase.order.entity.Order;
+import com.trade.purchase.order.entity.OrderItems;
+import com.trade.purchase.order.mapper.OrderItemsMapper;
+import com.trade.purchase.order.mapper.OrderMapper;
+import com.trade.purchase.order.vo.OrderVO;
+import lombok.AllArgsConstructor;
+import org.springblade.check.dto.AuditProecessDTO;
+import org.springblade.check.entity.AuditPathsActs;
+import org.springblade.check.entity.AuditPathsLevels;
+import org.springblade.check.feign.ICheckClient;
+import org.springblade.client.entity.StorageDesc;
+import org.springblade.client.feign.IGoodsDescClient;
+import org.springblade.client.feign.ISerialClient;
+import org.springblade.client.feign.IStorageClient;
+import org.springblade.client.vo.GoodsDescVO;
+import org.springblade.core.mp.support.Condition;
+import org.springblade.core.mp.support.Query;
+import org.springblade.core.secure.utils.AuthUtil;
+import org.springblade.core.tool.api.R;
+import org.springblade.core.tool.utils.BeanUtil;
+import org.springblade.core.tool.utils.ObjectUtil;
+import org.springblade.system.entity.Dept;
+import org.springblade.system.feign.ISysClient;
+import org.springblade.system.user.entity.User;
+import org.springblade.system.user.feign.IUserClient;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.transaction.interceptor.TransactionAspectSupport;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.util.Date;
+import java.util.List;
+
+@Service
+@AllArgsConstructor
+public class OfficeOrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements IOfficeOrderService {
+
+	private final OrderItemsMapper orderItemsMapper;
+
+	private final StockMapper stockMapper;
+
+	private final IUserClient userClient;
+
+	private final ISysClient sysClient;
+
+	private final ISerialClient serialClient;
+
+	private final IGoodsDescClient goodsDescClient;
+
+	private final ICheckClient checkClient;
+
+	private final IStorageClient storageClient;
+
+	@Override
+	public OrderVO getDetail(Order order) {
+		OrderVO detail = BeanUtil.copy(baseMapper.selectById(order.getId()), OrderVO.class);
+		if (!ObjectUtil.isEmpty(detail)) {
+			List<OrderItems> items = orderItemsMapper.selectList(new LambdaQueryWrapper<OrderItems>()
+				.eq(OrderItems::getPid, detail.getId())
+				.eq(OrderItems::getIsDeleted, 0)
+			);
+			items.forEach(item -> {
+				if (ObjectUtil.isNotEmpty(item.getItemId())) {
+					R<GoodsDescVO> goods = goodsDescClient.selectGoodsMessage(item.getItemId());
+					if (goods.isSuccess() && ObjectUtil.isNotEmpty(goods.getData())) {
+						item.setCode(goods.getData().getCode());
+						item.setCname(goods.getData().getCname());
+					}
+				}
+				if (ObjectUtil.isNotEmpty(item.getCreateUser())) {
+					item.setCreateUserName(getUserName(item.getCreateUser()));
+				}
+				if (ObjectUtil.isNotEmpty(item.getUpdateUser())) {
+					item.setUpdateUserName(getUserName(item.getUpdateUser()));
+				}
+				if (ObjectUtil.isNotEmpty(item.getStorageId())) {
+					StorageDesc storage = storageClient.findById(item.getStorageId());
+					if (ObjectUtil.isNotEmpty(storage)) {
+						item.setStorageName(storage.getCname());
+					}
+				}
+			});
+			detail.setOrderItemsList(items);
+		}
+		return detail;
+	}
+
+	@Override
+	public IPage<OrderVO> getList(Order order, Query query) {
+		IPage<Order> orderPages = baseMapper.selectPage(Condition.getPage(query), Condition.getQueryWrapper(order));
+		IPage<OrderVO> pages = Condition.getPage(query);
+		List<OrderVO> records = BeanUtil.copy(orderPages.getRecords(), OrderVO.class);
+		records.forEach(record -> {
+			if (ObjectUtil.isNotEmpty(record.getApplyUser())) {
+				record.setApplyUserName(getUserName(record.getApplyUser()));
+			}
+			if (ObjectUtil.isNotEmpty(record.getApplyDept())) {
+				record.setApplyDeptName(getDeptName(record.getApplyDept()));
+			}
+
+			if (ObjectUtil.isNotEmpty(record.getStockUser())) {
+				record.setStockUserName(getUserName(record.getStockUser()));
+			}
+			if (ObjectUtil.isNotEmpty(record.getStockDept())) {
+				record.setStockDeptName(getDeptName(record.getStockDept()));
+			}
+		});
+		pages.setRecords(records);
+		return pages;
+	}
+
+	@Override
+	@Transactional(rollbackFor = Exception.class)
+	public Long saveOrder(OrderVO orderVO) {
+		Order order = BeanUtil.copy(orderVO, Order.class);
+		if (ObjectUtil.isEmpty(order)) {
+			throw new SecurityException("传入数据为空");
+		}
+
+		if (ObjectUtil.isEmpty(order.getId())) {
+			// 生成系统编号
+			R sysNo = serialClient.getBillNo(order.getTradeType(), order.getTradeType(), order.getTradeType());
+			if (!sysNo.isSuccess()) {
+				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
+				throw new SecurityException("生成系统编号失败");
+			}
+			order.setSysNo((String) sysNo.getData());
+			order.setBusinesDate(new Date());
+			order.setTenantId(AuthUtil.getTenantId());
+			order.setCreateUser(AuthUtil.getUserId());
+			order.setCreateTime(new Date());
+			baseMapper.insert(order);
+		} else {
+			order.setUpdateUser(AuthUtil.getUserId());
+			order.setUpdateTime(new Date());
+			baseMapper.updateById(order);
+		}
+
+		long orderId = order.getId();
+		orderVO.getOrderItemsList().forEach(item -> {
+			if (ObjectUtil.isEmpty(item.getId())) {
+				item.setPid(orderId);
+				item.setTenantId(AuthUtil.getTenantId());
+				item.setCreateUser(AuthUtil.getUserId());
+				item.setCreateTime(new Date());
+				orderItemsMapper.insert(item);
+			} else {
+				item.setUpdateUser(AuthUtil.getUserId());
+				item.setUpdateTime(new Date());
+				orderItemsMapper.updateById(item);
+			}
+		});
+		return orderId;
+	}
+
+	@Override
+	@Transactional(rollbackFor = Exception.class)
+	public boolean submitOrder(OrderVO orderVO) {
+		Order order = baseMapper.selectById(orderVO.getId());
+		order.setStatus(4);
+		order.setUpdateUser(AuthUtil.getUserId());
+		order.setUpdateTime(new Date());
+		baseMapper.updateById(order);
+
+		orderVO.getOrderItemsList().forEach(orderItem -> {
+			OrderItems item = orderItemsMapper.selectById(orderItem.getId());
+			item.setStatus(4);
+			item.setUpdateUser(AuthUtil.getUserId());
+			item.setUpdateTime(new Date());
+			orderItemsMapper.updateById(item);
+
+			Stock stock = stockMapper.selectOne(new LambdaQueryWrapper<Stock>()
+				.eq(Stock::getGoodsId, item.getItemId())
+				.eq(Stock::getTenantId, AuthUtil.getTenantId())
+				.eq(Stock::getIsDeleted, 0)
+			);
+			if (ObjectUtil.isEmpty(stock)) {
+				Stock stockTemp = new Stock();
+				stockTemp.setStorageId(item.getStorageId());
+				stockTemp.setGoodsId(item.getItemId());
+				stockTemp.setInQuantity(item.getOrderQuantity());
+				stockTemp.setBalanceQuantity(item.getOrderQuantity());
+				stockTemp.setUnitPrice(item.getPrice());
+				stockTemp.setAmount(item.getAmount());
+				stockTemp.setTradeType("BGYP");
+				stockTemp.setTenantId(AuthUtil.getTenantId());
+				stockTemp.setInDate(new Date());
+				stockTemp.setCreateUser(AuthUtil.getUserId());
+				stockTemp.setCreateTime(new Date());
+				stockMapper.insert(stockTemp);
+			} else {
+				stock.setInQuantity(stock.getInQuantity().add(item.getOrderQuantity()));
+				stock.setAmount(stock.getAmount().add(item.getAmount()));
+				stock.setUnitPrice(stock.getAmount().divide(stock.getInQuantity(), RoundingMode.HALF_UP));
+				stockMapper.updateById(stock);
+			}
+		});
+		return true;
+	}
+
+	@Override
+	@Transactional(rollbackFor = Exception.class)
+	public boolean revokeOrder(OrderVO orderVO) {
+		Order order = baseMapper.selectById(orderVO.getId());
+		order.setStatus(3);
+		order.setUpdateUser(AuthUtil.getUserId());
+		order.setUpdateTime(new Date());
+		baseMapper.updateById(order);
+
+		orderVO.getOrderItemsList().forEach(orderItem -> {
+			OrderItems item = orderItemsMapper.selectById(orderItem.getId());
+			item.setStatus(3);
+			item.setUpdateUser(AuthUtil.getUserId());
+			item.setUpdateTime(new Date());
+			orderItemsMapper.updateById(item);
+
+			Stock stock = stockMapper.selectOne(new LambdaQueryWrapper<Stock>()
+				.eq(Stock::getGoodsId, item.getItemId())
+				.eq(Stock::getTenantId, AuthUtil.getTenantId())
+				.eq(Stock::getIsDeleted, 0)
+			);
+
+			BigDecimal balanceQuantity = stock.getBalanceQuantity();
+			if (balanceQuantity.compareTo(item.getOrderQuantity()) < 0) {
+				throw new SecurityException("库存结余数量不足,禁止撤销");
+			}
+
+			BigDecimal inQuantity = stock.getInQuantity().subtract(item.getOrderQuantity());
+
+			if (inQuantity.compareTo(BigDecimal.ZERO) > 0) {
+				stock.setInQuantity(inQuantity);
+				stock.setBalanceQuantity(balanceQuantity.subtract(item.getOrderQuantity()));
+				stock.setAmount(stock.getAmount().add(item.getAmount()));
+				stock.setUnitPrice(stock.getAmount().divide(stock.getInQuantity(), RoundingMode.HALF_UP));
+				stockMapper.updateById(stock);
+			} else {
+				stockMapper.deleteById(stock.getId());
+			}
+		});
+		return true;
+	}
+
+	@Override
+	@Transactional(rollbackFor = Exception.class)
+	public void checkOrder(OrderVO orderVO) {
+		Order order = baseMapper.selectById(orderVO.getId());
+		Integer checkFlag = orderVO.getCheckFlag();
+		// 判断是否有审批流,如果审批流已开启就进入审批流,否则直接走申请通过
+		AuditPathsActs pathsActs;
+
+		//判断是采购审批 还是 销售审批
+		if (checkFlag == 2) {
+			pathsActs = checkClient.getActsByActId(10, "status");
+		} else if (checkFlag == 1) {
+			pathsActs = checkClient.getActsByActId(9, "status");
+		} else {
+			throw new SecurityException("请核失败:请核标识设置不正确");
+		}
+
+		// 没开启审批流直接走,通过流程
+		if (pathsActs == null || pathsActs.getIsEnable() == 2) {
+			throw new SecurityException("当前租户未查询到审批流配置");
+		} else {
+			order.setStatus(1);
+			baseMapper.updateById(order);
+			editItemStatus(order.getId(), 1);
+
+			// 获取审批级次
+			List<AuditPathsLevels> auditPathsLevels;
+			if (checkFlag == 2) {
+				auditPathsLevels = checkClient.listLevelsByActId(10, "status");
+			} else {
+				auditPathsLevels = checkClient.listLevelsByActId(9, "status");
+			}
+			if (CollectionUtils.isEmpty(auditPathsLevels)) {
+				throw new SecurityException("开启审批失败:未查询到审批信息");
+			}
+
+			AuditProecessDTO auditProecessDTO = new AuditProecessDTO();
+			// 绑定审核类型
+			auditProecessDTO.setCheckType(orderVO.getCheckType());
+			// 追加跳转路由url
+			auditProecessDTO.setUrl(orderVO.getUrl());
+			auditProecessDTO.setPageStatus(orderVO.getPageStatus());
+			auditProecessDTO.setPageLabel(orderVO.getPageLabel());
+			// 增加审批类型
+			if (checkFlag == 2) {
+				auditProecessDTO.setProcessType("办公用品领用审批");
+				auditProecessDTO.setActId(10);
+			} else {
+				auditProecessDTO.setProcessType("办公用品采购审批");
+				auditProecessDTO.setActId(9);
+			}
+			auditProecessDTO.setPathsLevelsList(auditPathsLevels);
+			auditProecessDTO.setSrcBillId(order.getId());
+			auditProecessDTO.setBillId(order.getId());
+			auditProecessDTO.setBillNo(order.getSysNo());
+			auditProecessDTO.setSendUserId(AuthUtil.getUserId());
+			auditProecessDTO.setSendName(AuthUtil.getUserName());
+			auditProecessDTO.setSendTime(new Date());
+			R financeProcess = checkClient.createFinanceProcess(auditProecessDTO);
+			if (!financeProcess.isSuccess()) {
+				throw new SecurityException("操作失败,请联系管理员");
+			}
+
+		}
+	}
+
+	@Override
+	@Transactional(rollbackFor = Exception.class)
+	public void passCheck(Long id) {
+		Order order = baseMapper.selectById(id);
+		if (ObjectUtil.isEmpty(order)) {
+			throw new SecurityException("审批失败");
+		}
+		order.setStatus(3);
+		baseMapper.updateById(order);
+		editItemStatus(id, 3);
+
+		List<OrderItems> itemList = orderItemsMapper.selectList(new LambdaQueryWrapper<OrderItems>()
+			.eq(OrderItems::getPid, id)
+			.eq(OrderItems::getIsDeleted, 0)
+		);
+		if ("OCG".equals(order.getTradeType())) {
+			order.setId(null);
+			order.setSrcId(id);
+			order.setBillType("ORK");
+			order.setTradeType("ORK");
+			baseMapper.insert(order);
+
+			itemList.forEach(item -> {
+				item.setId(null);
+				item.setPid(order.getId());
+				orderItemsMapper.insert(item);
+			});
+		}
+		if ("OLY".equals(order.getTradeType())) {
+			itemList.forEach(item -> {
+				Stock stock = stockMapper.selectOne(new LambdaQueryWrapper<Stock>()
+					.eq(Stock::getGoodsId, item.getItemId())
+					.eq(Stock::getTenantId, AuthUtil.getTenantId())
+					.eq(Stock::getIsDeleted, 0)
+				);
+
+				stock.setOutQuantity(stock.getOutQuantity().add(item.getOrderQuantity()));
+				stock.setBalanceQuantity(stock.getInQuantity().subtract(stock.getOutQuantity()));
+				stockMapper.updateById(stock);
+			});
+		}
+	}
+
+	@Override
+	@Transactional(rollbackFor = Exception.class)
+	public void passCancel(Long id) {
+		Order order = baseMapper.selectById(id);
+		if (ObjectUtil.isEmpty(order)) {
+			throw new SecurityException("审批失败");
+		}
+		order.setStatus(0);
+		baseMapper.updateById(order);
+		editItemStatus(id, 0);
+	}
+
+	@Override
+	@Transactional(rollbackFor = Exception.class)
+	public void underReview(Long id) {
+		Order order = baseMapper.selectById(id);
+		if (ObjectUtil.isEmpty(order)) {
+			throw new SecurityException("审批失败");
+		}
+		order.setStatus(2);
+		baseMapper.updateById(order);
+		editItemStatus(id, 2);
+	}
+
+	private void editItemStatus(Long pid, Integer status) {
+		OrderItems items = new OrderItems();
+		items.setStatus(status);
+		orderItemsMapper.update(items, new LambdaQueryWrapper<OrderItems>()
+			.eq(OrderItems::getPid, pid)
+			.eq(OrderItems::getIsDeleted, 0)
+		);
+	}
+
+	private String getUserName(Long userId) {
+		R<User> user = userClient.userInfoById(userId);
+		if (user.isSuccess() && ObjectUtil.isNotEmpty(user.getData())) {
+			return user.getData().getRealName();
+		}
+		return null;
+	}
+
+	private String getDeptName(Long deptId) {
+		R<Dept> dept = sysClient.getDept(deptId);
+		if (dept.isSuccess() && ObjectUtil.isNotEmpty(dept.getData())) {
+			return dept.getData().getDeptName();
+		}
+		return null;
+	}
+
+}

+ 111 - 0
blade-service/trade-purchase/src/main/java/com/trade/purchase/office/service/impl/StockServiceImpl.java

@@ -0,0 +1,111 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package com.trade.purchase.office.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.trade.purchase.office.entity.Stock;
+import com.trade.purchase.office.mapper.StockMapper;
+import com.trade.purchase.office.service.IStockService;
+import com.trade.purchase.office.vo.StockVO;
+import lombok.AllArgsConstructor;
+import org.springblade.client.feign.IGoodsDescClient;
+import org.springblade.client.vo.GoodsDescVO;
+import org.springblade.core.mp.support.Condition;
+import org.springblade.core.mp.support.Query;
+import org.springblade.core.secure.utils.AuthUtil;
+import org.springblade.core.tool.api.R;
+import org.springblade.core.tool.utils.BeanUtil;
+import org.springblade.core.tool.utils.ObjectUtil;
+import org.springblade.core.tool.utils.StringUtil;
+import org.springframework.stereotype.Service;
+
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.List;
+
+/**
+ * 办公用品库存账 服务实现类
+ *
+ * @author BladeX
+ * @since 2022-04-02
+ */
+@Service
+@AllArgsConstructor
+public class StockServiceImpl extends ServiceImpl<StockMapper, Stock> implements IStockService {
+
+	private final IGoodsDescClient goodsDescClient;
+
+	@Override
+	public IPage<StockVO> selectStockPage(IPage<StockVO> page, StockVO stock) {
+		return page.setRecords(baseMapper.selectStockPage(page, stock));
+	}
+
+	@Override
+	public IPage<StockVO> getList(StockVO stockVO, Query query) {
+		LambdaQueryWrapper<Stock> stockQueryWrapper = new LambdaQueryWrapper<>();
+		stockQueryWrapper.eq(ObjectUtil.isNotEmpty(stockVO.getGoodsId()), Stock::getGoodsId, stockVO.getGoodsId())
+			.between(StringUtil.isNotBlank(stockVO.getBeginInDate()) && StringUtil.isNotBlank(stockVO.getEndInDate()),
+				Stock::getInDate, getFirstTimeOfMonth(stockVO.getBeginInDate()), getLastTimeOfMonth(stockVO.getEndInDate()))
+			.eq(Stock::getIsDeleted, 0)
+			.eq(Stock::getTenantId, AuthUtil.getTenantId());
+
+		IPage<Stock> stockPages = baseMapper.selectPage(Condition.getPage(query), stockQueryWrapper);
+
+		IPage<StockVO> pages = Condition.getPage(query);
+		List<StockVO> records = BeanUtil.copy(stockPages.getRecords(), StockVO.class);
+		records.forEach(record -> {
+			if (ObjectUtil.isNotEmpty(record.getGoodsId())) {
+				R<GoodsDescVO> goods = goodsDescClient.selectGoodsMessage(record.getGoodsId());
+				if (goods.isSuccess() && ObjectUtil.isNotEmpty(goods.getData())) {
+					record.setCode(goods.getData().getCode());
+					record.setCname(goods.getData().getCname());
+				}
+			}
+		});
+		pages.setRecords(records);
+		return pages;
+	}
+
+	private String getFirstTimeOfMonth(String date) {
+		return getTimeOfMonth(date, true);
+	}
+
+	private String getLastTimeOfMonth(String date) {
+		return getTimeOfMonth(date, false);
+	}
+
+	private String getTimeOfMonth(String date, boolean minimum) {
+		if (StringUtil.isBlank(date)) {
+			return date;
+		}
+		String[] array = date.split("-");
+
+		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+		Calendar calendar = Calendar.getInstance();
+		calendar.set(Calendar.YEAR, Integer.parseInt(array[0]));
+		calendar.set(Calendar.MONTH, Integer.parseInt(array[1]) - 1);
+		if (minimum) {
+			calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMinimum(Calendar.DAY_OF_MONTH));
+			return sdf.format(calendar.getTime()) + " 00:00:00";
+		}
+		calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
+		return sdf.format(calendar.getTime()) + " 23:59:59";
+	}
+
+}