fix bug
This commit is contained in:
@@ -31,6 +31,7 @@ import jakarta.servlet.http.HttpServletResponse;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.springblade.core.boot.ctrl.BladeController;
|
||||
import org.springblade.core.excel.util.ExcelUtil;
|
||||
import org.springblade.common.excel.ImportFailureExcelUtil;
|
||||
import org.springblade.core.mp.support.Condition;
|
||||
import org.springblade.core.mp.support.Query;
|
||||
import org.springblade.core.secure.annotation.PreAuth;
|
||||
@@ -38,6 +39,7 @@ import org.springblade.core.tool.api.R;
|
||||
import org.springblade.core.tool.utils.DateUtil;
|
||||
import org.springblade.core.tool.utils.Func;
|
||||
import org.springblade.transport.excel.ShippingTemplateExcel;
|
||||
import org.springblade.transport.excel.ShippingTemplateGoodsExcel;
|
||||
import org.springblade.transport.pojo.entity.ShippingTemplate;
|
||||
import org.springblade.transport.pojo.vo.BusinessRemoveResultVO;
|
||||
import org.springblade.transport.pojo.vo.ShippingTemplateVO;
|
||||
@@ -48,6 +50,7 @@ import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -116,4 +119,22 @@ public class ShippingTemplateController extends BladeController {
|
||||
return R.data(shippingTemplateService.copy(id));
|
||||
}
|
||||
|
||||
@PostMapping("/import-goods")
|
||||
@Operation(summary = "导入发货模板货物")
|
||||
public R<List<ShippingTemplateGoodsExcel>> importGoods(MultipartFile file, HttpServletResponse response) {
|
||||
List<ShippingTemplateGoodsExcel> data = ExcelUtil.read(file, ShippingTemplateGoodsExcel.class);
|
||||
List<ShippingTemplateGoodsExcel> failures = shippingTemplateService.importGoods(data);
|
||||
if (Func.isNotEmpty(failures)) {
|
||||
ImportFailureExcelUtil.export(response, "发货模板货物导入失败明细" + DateUtil.time(), "导入失败明细", failures, ShippingTemplateGoodsExcel.class);
|
||||
return null;
|
||||
}
|
||||
return R.data(data);
|
||||
}
|
||||
|
||||
@GetMapping("/export-goods-template")
|
||||
@Operation(summary = "导出发货模板货物导入模板")
|
||||
public void exportGoodsTemplate(HttpServletResponse response) {
|
||||
ExcelUtil.export(response, "发货模板货物导入模板", "货物信息", new ArrayList<ShippingTemplateGoodsExcel>(), ShippingTemplateGoodsExcel.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
package org.springblade.transport.excel;
|
||||
|
||||
import cn.idev.excel.annotation.ExcelIgnore;
|
||||
import cn.idev.excel.annotation.ExcelProperty;
|
||||
import cn.idev.excel.annotation.write.style.ColumnWidth;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
/** 发货模板货物导入 Excel。 */
|
||||
@Data
|
||||
@ColumnWidth(20)
|
||||
public class ShippingTemplateGoodsExcel implements Serializable {
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
@ExcelProperty("*货物名称") private String cargoName;
|
||||
@ExcelProperty("*货物类型") private String cargoType;
|
||||
@ExcelProperty("数量") private String quantity;
|
||||
@ExcelProperty("数量单位") private String quantityUnit;
|
||||
@ExcelProperty("包装") private String packageType;
|
||||
@ExcelProperty("品牌") private String brand;
|
||||
@ExcelProperty("规格") private String specification;
|
||||
@ExcelProperty("型号") private String model;
|
||||
@ExcelProperty("物料编码") private String materialCode;
|
||||
@ExcelProperty("设备编码") private String deviceCode;
|
||||
@ExcelProperty("备注") private String remark;
|
||||
@ExcelIgnore private String errorMessage;
|
||||
}
|
||||
@@ -25,6 +25,7 @@ package org.springblade.transport.service;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import org.springblade.core.mp.base.BaseService;
|
||||
import org.springblade.transport.excel.ShippingTemplateExcel;
|
||||
import org.springblade.transport.excel.ShippingTemplateGoodsExcel;
|
||||
import org.springblade.transport.pojo.entity.ShippingTemplate;
|
||||
import org.springblade.transport.pojo.vo.BusinessRemoveResultVO;
|
||||
import org.springblade.transport.pojo.vo.ShippingTemplateVO;
|
||||
@@ -45,5 +46,6 @@ public interface IShippingTemplateService extends BaseService<ShippingTemplate>
|
||||
BusinessRemoveResultVO removeShippingTemplate(String ids);
|
||||
List<ShippingTemplateExcel> exportShippingTemplate(ShippingTemplateVO shippingTemplate, String ids);
|
||||
ShippingTemplateVO copy(Long id);
|
||||
List<ShippingTemplateGoodsExcel> importGoods(List<ShippingTemplateGoodsExcel> data);
|
||||
|
||||
}
|
||||
|
||||
@@ -294,6 +294,13 @@ public class CustomerArchiveServiceImpl extends BaseServiceImpl<CustomerArchiveM
|
||||
customer.setLegalPerson(trimToEmpty(customer.getLegalPerson()));
|
||||
customer.setContactPhone(trimToEmpty(customer.getContactPhone()));
|
||||
customer.setDeptIds(trimToNull(customer.getDeptIds()));
|
||||
if (Func.isNotEmpty(customer.getDeptIds())) {
|
||||
List<Long> deptIdList = Func.toLongList(customer.getDeptIds());
|
||||
if (Func.isEmpty(deptIdList)) {
|
||||
throw new ServiceException("所属组织不正确");
|
||||
}
|
||||
customer.setDeptId(deptIdList.get(0));
|
||||
}
|
||||
customer.setDeptName(trimToEmpty(customer.getDeptName()));
|
||||
customer.setAccessType(Func.isEmpty(customer.getAccessType()) ? ACCESS_TEMPORARY : customer.getAccessType());
|
||||
customer.setApprovalStatus(Func.isEmpty(customer.getApprovalStatus()) ? APPROVAL_DRAFT : customer.getApprovalStatus());
|
||||
|
||||
@@ -22,6 +22,9 @@
|
||||
*/
|
||||
package org.springblade.transport.service.impl;
|
||||
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.alibaba.fastjson2.JSONArray;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
@@ -29,11 +32,14 @@ import org.springblade.core.log.exception.ServiceException;
|
||||
import org.springblade.core.mp.base.BaseServiceImpl;
|
||||
import org.springblade.core.tool.utils.BeanUtil;
|
||||
import org.springblade.core.tool.utils.Func;
|
||||
import org.springblade.core.tool.utils.StringUtil;
|
||||
import org.springblade.system.cache.UserCache;
|
||||
import org.springblade.system.pojo.entity.Dept;
|
||||
import org.springblade.transport.excel.ShippingTemplateExcel;
|
||||
import org.springblade.transport.excel.ShippingTemplateGoodsExcel;
|
||||
import java.time.LocalDate;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.math.BigDecimal;
|
||||
import org.springblade.transport.mapper.ShippingTemplateMapper;
|
||||
import org.springblade.transport.pojo.entity.ShippingTemplate;
|
||||
import org.springblade.transport.pojo.vo.BusinessRemoveResultVO;
|
||||
@@ -164,6 +170,27 @@ public class ShippingTemplateServiceImpl extends BaseServiceImpl<ShippingTemplat
|
||||
return detail(target.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ShippingTemplateGoodsExcel> importGoods(List<ShippingTemplateGoodsExcel> data) {
|
||||
if (Func.isEmpty(data)) {
|
||||
throw new ServiceException("导入数据不能为空");
|
||||
}
|
||||
List<ShippingTemplateGoodsExcel> failures = new ArrayList<>();
|
||||
for (int index = 0; index < data.size(); index++) {
|
||||
ShippingTemplateGoodsExcel item = data.get(index);
|
||||
try {
|
||||
if (Func.isEmpty(TransportBusinessSupport.trimToNull(item.getCargoName()))) throw new ServiceException("货物名称不能为空");
|
||||
if (Func.isEmpty(TransportBusinessSupport.trimToNull(item.getCargoType()))) throw new ServiceException("货物类型不能为空");
|
||||
if (StringUtil.isNotBlank(item.getQuantity()) && !item.getQuantity().trim().matches("^\\d+(\\.\\d{1,3})?$")) throw new ServiceException("数量只能输入非负数字,最多保留3位小数");
|
||||
if (StringUtil.isNotBlank(item.getRemark()) && item.getRemark().trim().length() > 200) throw new ServiceException("备注不能超过200个字符");
|
||||
} catch (Exception e) {
|
||||
item.setErrorMessage("第" + (index + 2) + "行:" + e.getMessage());
|
||||
failures.add(item);
|
||||
}
|
||||
}
|
||||
return failures;
|
||||
}
|
||||
|
||||
private LambdaQueryWrapper<ShippingTemplate> buildQuery(ShippingTemplateVO shippingTemplate) {
|
||||
TransportBusinessSupport.validateAllDept(shippingTemplate.getAllDept(), "发货模板");
|
||||
LambdaQueryWrapper<ShippingTemplate> queryWrapper = Wrappers.<ShippingTemplate>lambdaQuery().eq(ShippingTemplate::getIsDeleted, 0);
|
||||
@@ -273,11 +300,110 @@ public class ShippingTemplateServiceImpl extends BaseServiceImpl<ShippingTemplat
|
||||
TransportBusinessSupport.validateLength(shippingTemplate.getArrivalPhone(), 255, "收货联系方式不能超过255字");
|
||||
TransportBusinessSupport.validateLength(shippingTemplate.getGoodsJson(), 8000, "货物信息不能超过8000字");
|
||||
TransportBusinessSupport.validateLength(shippingTemplate.getFreightJson(), 8000, "运费信息不能超过8000字");
|
||||
validateFreight(shippingTemplate);
|
||||
TransportBusinessSupport.validateLength(shippingTemplate.getAttachmentsJson(), 8000, "附件不能超过8000字");
|
||||
TransportBusinessSupport.validateLength(shippingTemplate.getDeptName(), 255, "所属组织不能超过255字");
|
||||
TransportBusinessSupport.validateLength(shippingTemplate.getRemark(), 500, "备注不能超过500字");
|
||||
}
|
||||
|
||||
private void validateFreight(ShippingTemplate shippingTemplate) {
|
||||
if (!"运单".equals(shippingTemplate.getTemplateType())) {
|
||||
shippingTemplate.setFreightJson(null);
|
||||
return;
|
||||
}
|
||||
if (StringUtil.isBlank(shippingTemplate.getFreightJson())) {
|
||||
throw new ServiceException("运单模板的运费信息不能为空");
|
||||
}
|
||||
final JSONObject freight;
|
||||
final JSONArray goods;
|
||||
try {
|
||||
freight = JSON.parseObject(shippingTemplate.getFreightJson());
|
||||
goods = StringUtil.isBlank(shippingTemplate.getGoodsJson())
|
||||
? new JSONArray()
|
||||
: JSON.parseArray(shippingTemplate.getGoodsJson());
|
||||
} catch (Exception e) {
|
||||
throw new ServiceException("运费信息或货物信息格式不正确");
|
||||
}
|
||||
if (freight == null) {
|
||||
throw new ServiceException("运费信息格式不正确");
|
||||
}
|
||||
String currency = TransportBusinessSupport.trimToNull(freight.getString("currency"));
|
||||
if (StringUtil.isBlank(currency)) {
|
||||
throw new ServiceException("运费信息的币种不能为空");
|
||||
}
|
||||
freight.put("currency", currency);
|
||||
freight.put("otherFreightAmount", amountText(freight.get("otherFreightAmount"), "其他运费合计"));
|
||||
|
||||
if (isRoadTransport(shippingTemplate.getTransportType())) {
|
||||
JSONArray freightItems = freight.getJSONArray("freightItems");
|
||||
if (freightItems == null || freightItems.size() != goods.size()) {
|
||||
throw new ServiceException("公路运输的运费明细必须与货物信息一一对应");
|
||||
}
|
||||
BigDecimal totalFreightAmount = BigDecimal.ZERO;
|
||||
for (int index = 0; index < freightItems.size(); index++) {
|
||||
JSONObject freightItem = freightItems.getJSONObject(index);
|
||||
if (freightItem == null) {
|
||||
throw new ServiceException("第" + (index + 1) + "条运费明细格式不正确");
|
||||
}
|
||||
BigDecimal unitPrice = amountValue(freightItem.get("unitPrice"), "第" + (index + 1) + "条货物单价");
|
||||
String priceUnit = TransportBusinessSupport.trimToNull(freightItem.getString("priceUnit"));
|
||||
if (StringUtil.isBlank(priceUnit)) {
|
||||
throw new ServiceException("第" + (index + 1) + "条货物计价单位不能为空");
|
||||
}
|
||||
JSONObject goodsItem = goods.getJSONObject(index);
|
||||
BigDecimal quantity = amountValue(goodsItem == null ? null : goodsItem.get("quantity"), "第" + (index + 1) + "条货物数量");
|
||||
BigDecimal freightAmount = unitPrice.multiply(quantity);
|
||||
freightItem.put("cargoIndex", index);
|
||||
freightItem.put("unitPrice", decimalText(unitPrice));
|
||||
freightItem.put("priceUnit", priceUnit);
|
||||
freightItem.put("quantity", decimalText(quantity));
|
||||
freightItem.put("freightAmount", decimalText(freightAmount));
|
||||
totalFreightAmount = totalFreightAmount.add(freightAmount);
|
||||
}
|
||||
freight.put("totalFreightAmount", decimalText(totalFreightAmount));
|
||||
freight.remove("freightAmount");
|
||||
freight.remove("quantity");
|
||||
} else {
|
||||
BigDecimal quantity = goods.stream()
|
||||
.map(item -> item instanceof JSONObject ? (JSONObject) item : null)
|
||||
.map(item -> amountValue(item == null ? null : item.get("quantity"), "货物数量"))
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
freight.put("quantity", decimalText(quantity));
|
||||
freight.put("freightAmount", amountText(freight.get("freightAmount"), "运费"));
|
||||
freight.remove("freightItems");
|
||||
freight.remove("totalFreightAmount");
|
||||
}
|
||||
shippingTemplate.setFreightJson(freight.toJSONString());
|
||||
}
|
||||
|
||||
private boolean isRoadTransport(String transportType) {
|
||||
String value = transportType == null ? "" : transportType.toLowerCase();
|
||||
return value.contains("公路") || value.contains("道路") || value.contains("road") || "gl".equals(value);
|
||||
}
|
||||
|
||||
private String amountText(Object value, String fieldName) {
|
||||
return decimalText(amountValue(value, fieldName));
|
||||
}
|
||||
|
||||
private BigDecimal amountValue(Object value, String fieldName) {
|
||||
if (value == null || StringUtil.isBlank(String.valueOf(value))) {
|
||||
return BigDecimal.ZERO;
|
||||
}
|
||||
try {
|
||||
BigDecimal amount = new BigDecimal(String.valueOf(value));
|
||||
if (amount.compareTo(BigDecimal.ZERO) < 0) {
|
||||
throw new ServiceException(fieldName + "不能小于0");
|
||||
}
|
||||
return amount;
|
||||
} catch (NumberFormatException e) {
|
||||
throw new ServiceException(fieldName + "必须为非负数字");
|
||||
}
|
||||
}
|
||||
|
||||
private String decimalText(BigDecimal value) {
|
||||
return value.stripTrailingZeros().toPlainString();
|
||||
}
|
||||
|
||||
private ShippingTemplate loadEditable(Long id, boolean checkDept) {
|
||||
if (Func.isEmpty(id)) {
|
||||
throw new ServiceException("主键不能为空");
|
||||
|
||||
@@ -88,7 +88,7 @@ public class TransportPlanServiceImpl extends BaseServiceImpl<TransportPlanMappe
|
||||
transportPlan.setDeptName(oldRecord.getDeptName());
|
||||
}
|
||||
prepare(transportPlan);
|
||||
if (created && Func.isEmpty(transportPlan.getPlanNo())) {
|
||||
if (created) {
|
||||
transportPlan.setPlanNo(nextCode());
|
||||
}
|
||||
validate(transportPlan);
|
||||
@@ -490,7 +490,7 @@ public class TransportPlanServiceImpl extends BaseServiceImpl<TransportPlanMappe
|
||||
}
|
||||
|
||||
private synchronized String nextCode() {
|
||||
String prefix = "JH" + LocalDate.now().format(DateTimeFormatter.BASIC_ISO_DATE);
|
||||
String prefix = "JH-" + LocalDate.now().format(DateTimeFormatter.BASIC_ISO_DATE);
|
||||
List<TransportPlan> latestList = list(Wrappers.<TransportPlan>lambdaQuery()
|
||||
.select(TransportPlan::getPlanNo)
|
||||
.likeRight(TransportPlan::getPlanNo, prefix)
|
||||
|
||||
Reference in New Issue
Block a user