refactor(controller): 移除冗余的service注入,使用BeanContext统一管理

feat(sales-order): 补充SalesOrderVo缺失字段并完善相关功能
feat(sales-order): 添加客户、税率等字段到销售订单界面
refactor(tab-skin): 重构TabSkin基类,统一bean获取方式
fix(fxml): 修正controller包路径和字段绑定
feat(repository): 添加findAllByOrder方法优化查询
This commit is contained in:
2025-10-15 00:40:02 +08:00
parent 1c1ff678a5
commit d2e0dc4555
25 changed files with 485 additions and 137 deletions

View File

@@ -160,9 +160,7 @@ public class SalesBillVoucherCtx extends AbstractYongYouU8Ctx {
public void syncBySalesOrder(SalesOrder order, MessageHolder holder) {
var voucherService = getSalesBillVoucherService();
var voucherItemService = getSalesBillVoucherItemService();
List<SalesBillVoucher> vouchers = voucherService.findAll((root, q, cb) -> {
return cb.equal(root.get("order"), order);
}, Sort.unsorted());
List<SalesBillVoucher> vouchers = voucherService.findAllByOrder(order);
holder.debug("查找到 " + vouchers.size() + " 条专用发票记录在数据库中");
Map<Integer, SalesBillVoucher> voucherMap = vouchers.stream()
.collect(Collectors.toMap(SalesBillVoucher::getRefId, item -> item));

View File

@@ -11,11 +11,16 @@ import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import com.ecep.contract.ds.company.model.Company;
import com.ecep.contract.ds.company.service.CompanyService;
import com.ecep.contract.ds.contract.service.ContractItemService;
import com.ecep.contract.ds.contract.service.ContractService;
import com.ecep.contract.vo.ContractVo;
import org.springframework.data.domain.Sort;
import org.springframework.util.StringUtils;
import com.ecep.contract.MessageHolder;
import com.ecep.contract.constant.CloudServiceConstant;
@@ -24,6 +29,8 @@ import com.ecep.contract.ds.contract.service.SalesOrderItemService;
import com.ecep.contract.ds.contract.model.Contract;
import com.ecep.contract.ds.customer.model.SalesOrder;
import com.ecep.contract.ds.customer.model.SalesOrderItem;
import com.ecep.contract.ds.customer.service.CompanyCustomerEntityService;
import com.ecep.contract.ds.customer.service.CustomerService;
import com.ecep.contract.util.NumberUtils;
import lombok.Setter;
@@ -42,6 +49,69 @@ public class SalesOrderCtx extends AbstractYongYouU8Ctx {
return saleOrdersService;
}
/**
* 更新客户信息
*
* @param getter 获取当前客户的函数
* @param setter 设置客户的函数
* @param code 客户代码
* @param name 客户名称
* @param holder 消息持有者
* @param fieldName 字段名称
* @return 是否发生了修改
*/
private boolean updateCustomer(Supplier<Company> getter,
java.util.function.Consumer<Company> setter,
String code,
String name,
MessageHolder holder,
String fieldName) {
Company current = getter.get();
CompanyService companyService = getBean(CompanyService.class);
if (StringUtils.hasText(code)) {
var customerEntity = getCachedBean(CompanyCustomerEntityService.class).findByCustomerCode(code);
if (customerEntity == null) {
holder.warn("未找到客户:" + name + " (代码: " + code + ")");
} else {
var customer = getCachedBean(CustomerService.class).findById(customerEntity.getCustomerId());
if (customer == null) {
holder.warn("未找到客户:" + name + " (代码: " + code + ")");
} else {
var companyId = customer.getCompanyId();
if (current == null) {
var updated = companyService.getById(companyId);
setter.accept(updated);
holder.info(fieldName + " 更新为 " + updated.getName());
return true;
}
if (!Objects.equals(current.getId(), companyId)) {
var updated = companyService.getById(companyId);
setter.accept(updated);
holder.info(fieldName + " 更新为 " + updated.getName());
return true;
}
}
}
}
// 尝试通过名称或简称查找公司
Company updated = companyService.findAndRemoveDuplicateCompanyByNameOrAbbName(name, null);
if (updated == null) {
holder.warn("未找到客户:" + name + " (代码: " + code + ")");
return false;
}
if (!Objects.equals(current, updated)) {
setter.accept(updated);
holder.info(fieldName + " 更新为 " + updated.getName());
return true;
}
return false;
}
SalesOrderItemService getOrderItemService() {
if (orderItemService == null) {
orderItemService = getBean(SalesOrderItemService.class);
@@ -49,22 +119,20 @@ public class SalesOrderCtx extends AbstractYongYouU8Ctx {
return orderItemService;
}
public List<SalesOrder> syncByContract(ContractVo contract, MessageHolder holder) {
SaleOrdersService saleOrdersService = getSaleOrdersService();
SalesOrderItemService orderItemService = getOrderItemService();
List<SalesOrder> orders = saleOrdersService.findAllByContract(contract);
holder.debug("查找到 " + orders.size() + " 条销售订单记录在数据库中");
Map<String, SalesOrder> ordersMap = orders.stream().collect(Collectors.toMap(SalesOrder::getCode, item -> item));
Map<String, SalesOrder> ordersMap = orders.stream()
.collect(Collectors.toMap(SalesOrder::getCode, item -> item));
// 按 order 分组
Map<SalesOrder, Map<String, SalesOrderItem>> itemMap = orders.stream()
.collect(
Collectors.toMap(Function.identity(), order -> orderItemService.findAllBySaleOrder(order).stream().collect(
Collectors.toMap(SalesOrderItem::getCode, item -> item)
))
);
Collectors.toMap(Function.identity(),
order -> orderItemService.findAllBySaleOrder(order).stream().collect(
Collectors.toMap(SalesOrderItem::getCode, item -> item))));
// 查询 U8 数据库
List<Map<String, Object>> ds = repository.findAllSalesOrderItemByContractCode(contract.getCode());
@@ -161,8 +229,23 @@ public class SalesOrderCtx extends AbstractYongYouU8Ctx {
private boolean applySalesOrderDetail(SalesOrder order, Map<String, Object> map, MessageHolder holder) {
String code = (String) map.get("cSOCode");
String employeeCode = (String) map.get("cPersonCode");
String cCloser = (String) map.get("cCloser");
String customerCode = (String) map.get("cCusCode");
String customerName = (String) map.get("cCusName");
String customerAddress = (String) map.get("cCusOAddress");
String makerName = (String) map.get("cMaker");
Timestamp makerDate = (Timestamp) map.get("dcreatesystime");
String verifierName = (String) map.get("cVerifier");
Timestamp verifierDate = (Timestamp) map.get("dverifysystime");
String modifierName = (String) map.get("cmodifier");
Timestamp modifierDate = (Timestamp) map.get("dmodifysystime");
String closerName = (String) map.get("cCloser");
Timestamp closerDate = (Timestamp) map.get("dclosesystime");
float taxRate = Optional.ofNullable(map.get("iTaxRate"))
.map(obj -> obj instanceof Number ? ((Number) obj).floatValue() : null).orElse(0f);
String memo = (String) map.get("cMemo");
@@ -174,20 +257,48 @@ public class SalesOrderCtx extends AbstractYongYouU8Ctx {
modified = true;
}
if (updateEmployeeByCode(order::getEmployee, order::setEmployee, (String) map.get("cPersonCode"), holder, "业务员")) {
if (updateEmployeeByCode(order::getEmployee, order::setEmployee, employeeCode, holder, "业务员")) {
modified = true;
}
if (updateEmployeeByName(order::getMaker, order::setMaker, (String) map.get("cMaker"), holder, "制单人")) {
if (updateEmployeeByName(order::getMaker, order::setMaker, makerName, holder, "制单人")) {
modified = true;
}
if (updateEmployeeByName(order::getVerifier, order::setVerifier, (String) map.get("cVerifier"), holder, "审核人")) {
if (updateEmployeeByName(order::getVerifier, order::setVerifier, verifierName, holder, "审核人")) {
modified = true;
}
if (updateEmployeeByName(order::getModifier, order::setModifier, modifierName, holder, "修改人")) {
modified = true;
}
if (updateEmployeeByName(order::getCloser, order::setCloser, closerName, holder, "关闭人")) {
modified = true;
}
if (updateLocalDate(order::getMakerDate, order::setMakerDate, (Timestamp) map.get("dcreatesystime"), holder, "制单日期")) {
if (updateLocalDate(order::getMakerDate, order::setMakerDate, makerDate, holder, "制单日期")) {
modified = true;
}
if (updateLocalDate(order::getVerifierDate, order::setVerifierDate, (Timestamp) map.get("dverifysystime"), holder, "审核日期")) {
if (updateLocalDate(order::getVerifierDate, order::setVerifierDate, verifierDate, holder, "审核日期")) {
modified = true;
}
if (updateLocalDate(order::getModifierDate, order::setModifierDate, modifierDate, holder, "修改日期")) {
modified = true;
}
if (updateLocalDate(order::getCloserDate, order::setCloserDate, closerDate, holder, "关闭日期")) {
modified = true;
}
if (!NumberUtils.equals(order.getTaxRate(), taxRate)) {
order.setTaxRate(taxRate);
holder.info("税率修改为: " + taxRate);
modified = true;
}
if (updateCustomer(order::getCustomer, order::setCustomer, customerCode, customerName, holder, "客户")) {
modified = true;
}
if (!Objects.equals(order.getCustomerAddress(), customerAddress)) {
order.setCustomerAddress(customerAddress);
holder.info("客户地址修改为: " + customerAddress);
modified = true;
}
@@ -200,11 +311,11 @@ public class SalesOrderCtx extends AbstractYongYouU8Ctx {
return modified;
}
private boolean applySaleOrderItemDetail(SalesOrderItem item, Map<String, Object> map, MessageHolder holder) {
String code = String.valueOf(map.get("iSOsID"));
String spec = (String) map.get("cInvName");
String title = (String) map.get("cInvName");
String contractItemRowId = (String) map.get("cContractRowGuid");
double quantity = (double) map.get("iQuantity");
double taxRate = (double) map.get("iTaxRate");
double taxPrice = (double) map.get("iTaxUnitPrice");
@@ -217,7 +328,6 @@ public class SalesOrderCtx extends AbstractYongYouU8Ctx {
holder.debug("条目:" + title + " x " + amount);
if (!Objects.equals(item.getCode(), code)) {
item.setCode(code);
holder.info("代码修改为: " + code);
@@ -255,6 +365,13 @@ public class SalesOrderCtx extends AbstractYongYouU8Ctx {
modified = true;
}
var contractItem = getCachedBean(ContractItemService.class).findByRowId(contractItemRowId);
if (!Objects.equals(item.getContractItem(), contractItem)) {
item.setContractItem(contractItem);
holder.info("合同条目修改为: #" + contractItem.getId());
modified = true;
}
if (!Objects.equals(item.getDescription(), memo)) {
item.setDescription(memo);
modified = true;

View File

@@ -1,7 +1,9 @@
package com.ecep.contract.ds.contract.repository;
import java.util.List;
import java.util.Optional;
import com.ecep.contract.ds.customer.model.SalesOrder;
import org.springframework.stereotype.Repository;
import com.ecep.contract.ds.MyRepository;
@@ -12,4 +14,5 @@ public interface SalesBillVoucherRepository extends MyRepository<SalesBillVouche
Optional<SalesBillVoucher> findByCode(String code);
List<SalesBillVoucher> findAllByOrder(SalesOrder order);
}

View File

@@ -20,6 +20,7 @@ import com.ecep.contract.QueryService;
import com.ecep.contract.SpringApp;
import com.ecep.contract.ds.contract.repository.SalesOrderRepository;
import com.ecep.contract.ds.other.service.EmployeeService;
import com.ecep.contract.ds.company.service.CompanyService;
import com.ecep.contract.ds.contract.model.Contract;
import com.ecep.contract.ds.customer.model.SalesOrder;
import com.ecep.contract.service.VoableService;
@@ -112,6 +113,11 @@ public class SaleOrdersService extends EntityService<SalesOrder, SalesOrderVo, I
model.setMakerDate(vo.getMakerDate());
model.setVerifierDate(vo.getVerifierDate());
model.setDescription(vo.getDescription());
model.setRefId(vo.getRefId());
model.setTaxRate(vo.getTaxRate());
model.setCustomerAddress(vo.getCustomerAddress());
model.setModifierDate(vo.getModifierDate());
model.setCloserDate(vo.getCloserDate());
// 处理关联对象
if (vo.getContractId() == null) {
@@ -138,6 +144,24 @@ public class SaleOrdersService extends EntityService<SalesOrder, SalesOrderVo, I
model.setVerifier(SpringApp.getBean(EmployeeService.class).getById(vo.getVerifierId()));
}
if (vo.getCustomerId() == null) {
model.setCustomer(null);
} else {
model.setCustomer(SpringApp.getBean(CompanyService.class).getById(vo.getCustomerId()));
}
if (vo.getModifierId() == null) {
model.setModifier(null);
} else {
model.setModifier(SpringApp.getBean(EmployeeService.class).getById(vo.getModifierId()));
}
if (vo.getCloserId() == null) {
model.setCloser(null);
} else {
model.setCloser(SpringApp.getBean(EmployeeService.class).getById(vo.getCloserId()));
}
// active字段在SalesOrder实体类中不存在不需要设置
}

View File

@@ -1,5 +1,6 @@
package com.ecep.contract.ds.contract.service;
import com.ecep.contract.ds.customer.model.SalesOrder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@@ -24,6 +25,8 @@ import com.ecep.contract.util.SpecificationUtils;
import com.ecep.contract.vo.SalesBillVoucherVo;
import com.fasterxml.jackson.databind.JsonNode;
import java.util.List;
/**
* 采购账单凭证服务
*/
@@ -141,4 +144,8 @@ public class SalesBillVoucherService extends EntityService<SalesBillVoucher, Sal
model.setVerifier(employeeService.getById(vo.getVerifierId()));
}
}
public List<SalesBillVoucher> findAllByOrder(SalesOrder order) {
return salesBillVoucherRepository.findAllByOrder(order);
}
}

View File

@@ -3,6 +3,7 @@ package com.ecep.contract.ds.customer.model;
import java.time.LocalDate;
import java.util.Objects;
import com.ecep.contract.ds.company.model.Company;
import com.ecep.contract.ds.contract.model.Contract;
import com.ecep.contract.ds.contract.model.ContractBasedEntity;
import com.ecep.contract.model.BasedEntity;
@@ -53,9 +54,35 @@ public class SalesOrder implements IdentityEntity, BasedEntity, ContractBasedEnt
@ToString.Exclude
private Employee employee;
/**
* 单据编号
*/
@Column(name = "CODE")
private String code;
@Column(name = "REF_ID")
private int refId;
/**
* 税率
*/
@Column(name = "TAX_RATE")
private float taxRate;
/**
* 客户
*/
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "CUSTOMER_ID")
@ToString.Exclude
private Company customer;
/**
* 客户地址
*/
@Column(name = "CUSTOMER_ADDRESS")
private String customerAddress;
/**
* 制单人
*/
@@ -79,8 +106,27 @@ public class SalesOrder implements IdentityEntity, BasedEntity, ContractBasedEnt
/**
* 审核日期
*/
@Column(name = "VERIFIER_DATE")
@Column(name = "VERIFIED_DATE")
private LocalDate verifierDate;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "MODIFIER_ID")
@ToString.Exclude
private Employee modifier;
@Column(name = "MODIFIED_DATE")
private LocalDate modifierDate;
/**
* 关闭人
*/
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "CLOSER_ID")
@ToString.Exclude
private Employee closer;
@Column(name = "CLOSED_DATE")
private LocalDate closerDate;
/**
* 备注
*/
@@ -113,23 +159,40 @@ public class SalesOrder implements IdentityEntity, BasedEntity, ContractBasedEnt
@Override
public SalesOrderVo toVo() {
SalesOrderVo vo = new SalesOrderVo();
// 基本字段映射
vo.setId(id);
vo.setCode(code);
vo.setRefId(refId);
vo.setTaxRate(taxRate);
vo.setCustomerAddress(customerAddress);
vo.setMakerDate(makerDate);
vo.setVerifierDate(verifierDate);
vo.setModifierDate(modifierDate);
vo.setCloserDate(closerDate);
vo.setDescription(description);
// 关联对象ID映射
if (contract != null) {
vo.setContractId(contract.getId());
}
vo.setCode(code);
if (employee != null) {
vo.setEmployeeId(employee.getId());
}
if (maker != null) {
vo.setMakerId(maker.getId());
}
vo.setMakerDate(makerDate);
if (verifier != null) {
vo.setVerifierId(verifier.getId());
}
vo.setVerifierDate(verifierDate);
vo.setDescription(description);
if (customer != null) {
vo.setCustomerId(customer.getId());
}
if (modifier != null) {
vo.setModifierId(modifier.getId());
}
if (closer != null) {
vo.setCloserId(closer.getId());
}
// active字段默认为false在SalesOrderVo类中已经设置
return vo;

View File

@@ -3,6 +3,7 @@ package com.ecep.contract.ds.customer.model;
import java.time.LocalDate;
import java.util.Objects;
import com.ecep.contract.ds.contract.model.ContractItem;
import com.ecep.contract.model.BasedEntity;
import com.ecep.contract.model.IdentityEntity;
import com.ecep.contract.model.Voable;
@@ -69,6 +70,11 @@ public class SalesOrderItem implements IdentityEntity, BasedEntity, Voable<Sales
@Column(name = "EX_TAX_PRICE")
private double exclusiveTaxPrice;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "CONTRACT_ITEM_ID")
@ToString.Exclude
private ContractItem contractItem;
@Column(name = "START_DATE")
private LocalDate startDate;