From 88291b1d46d25c6634b1b77864d3a89fa42a89e7 Mon Sep 17 00:00:00 2001 From: zhangjf Date: Wed, 18 Feb 2026 08:19:13 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E8=A1=A5=E5=85=85=E5=90=8E=E7=AB=AF?= =?UTF-8?q?=E7=BC=BA=E5=A4=B1=E6=8E=A5=E5=8F=A3=E5=B9=B6=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?API=E8=B7=AF=E5=BE=84=E4=B8=8D=E4=B8=80=E8=87=B4=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新增接口: - fund-sys: 登出、刷新Token、获取角色菜单 - fund-cust: 联系人管理完整CRUD - fund-receipt: 获取应收款收款记录列表 修复问题: - 支出类型更新接口路径改为 PUT /{id} - 支出更新接口路径改为 PUT /{id} - 应收款更新接口路径改为 PUT /{id} - FundReceipt实体添加receivableId字段 --- .../cust/controller/ContactController.java | 82 +++++++++ .../cust/data/entity/CustomerContact.java | 117 +++++++++++++ .../data/mapper/CustomerContactMapper.java | 12 ++ .../service/CustomerContactDataService.java | 10 ++ .../impl/CustomerContactDataServiceImpl.java | 14 ++ .../com/fundplatform/cust/dto/ContactDTO.java | 126 ++++++++++++++ .../cust/service/ContactService.java | 41 +++++ .../cust/service/impl/ContactServiceImpl.java | 148 ++++++++++++++++ .../com/fundplatform/cust/vo/ContactVO.java | 162 ++++++++++++++++++ .../exp/controller/ExpenseTypeController.java | 5 +- .../exp/controller/FundExpenseController.java | 5 +- .../controller/ReceivableController.java | 15 +- .../receipt/data/entity/FundReceipt.java | 5 + .../receipt/service/FundReceiptService.java | 7 + .../receipt/service/ReceivableService.java | 7 + .../service/impl/FundReceiptServiceImpl.java | 11 ++ .../service/impl/ReceivableServiceImpl.java | 12 +- .../receipt/vo/FundReceiptVO.java | 3 + .../sys/controller/AuthController.java | 18 ++ .../sys/controller/RoleController.java | 14 +- .../fundplatform/sys/service/AuthService.java | 10 ++ .../fundplatform/sys/service/RoleService.java | 5 + .../sys/service/impl/AuthServiceImpl.java | 24 +++ .../sys/service/impl/RoleServiceImpl.java | 8 + 24 files changed, 853 insertions(+), 8 deletions(-) create mode 100644 fund-cust/src/main/java/com/fundplatform/cust/controller/ContactController.java create mode 100644 fund-cust/src/main/java/com/fundplatform/cust/data/entity/CustomerContact.java create mode 100644 fund-cust/src/main/java/com/fundplatform/cust/data/mapper/CustomerContactMapper.java create mode 100644 fund-cust/src/main/java/com/fundplatform/cust/data/service/CustomerContactDataService.java create mode 100644 fund-cust/src/main/java/com/fundplatform/cust/data/service/impl/CustomerContactDataServiceImpl.java create mode 100644 fund-cust/src/main/java/com/fundplatform/cust/dto/ContactDTO.java create mode 100644 fund-cust/src/main/java/com/fundplatform/cust/service/ContactService.java create mode 100644 fund-cust/src/main/java/com/fundplatform/cust/service/impl/ContactServiceImpl.java create mode 100644 fund-cust/src/main/java/com/fundplatform/cust/vo/ContactVO.java diff --git a/fund-cust/src/main/java/com/fundplatform/cust/controller/ContactController.java b/fund-cust/src/main/java/com/fundplatform/cust/controller/ContactController.java new file mode 100644 index 0000000..2df7c05 --- /dev/null +++ b/fund-cust/src/main/java/com/fundplatform/cust/controller/ContactController.java @@ -0,0 +1,82 @@ +package com.fundplatform.cust.controller; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.fundplatform.common.core.Result; +import com.fundplatform.cust.dto.ContactDTO; +import com.fundplatform.cust.service.ContactService; +import com.fundplatform.cust.vo.ContactVO; +import jakarta.validation.Valid; +import org.springframework.web.bind.annotation.*; + +/** + * 联系人管理Controller + */ +@RestController +@RequestMapping("/api/v1/customer/contact") +public class ContactController { + + private final ContactService contactService; + + public ContactController(ContactService contactService) { + this.contactService = contactService; + } + + /** + * 创建联系人 + */ + @PostMapping + public Result create(@Valid @RequestBody ContactDTO dto) { + Long id = contactService.createContact(dto); + return Result.success(id); + } + + /** + * 更新联系人 + */ + @PutMapping("/{id}") + public Result update(@PathVariable Long id, @Valid @RequestBody ContactDTO dto) { + boolean result = contactService.updateContact(id, dto); + return Result.success(result); + } + + /** + * 根据ID查询联系人 + */ + @GetMapping("/{id}") + public Result getById(@PathVariable Long id) { + ContactVO vo = contactService.getContactById(id); + return Result.success(vo); + } + + /** + * 分页查询联系人 + */ + @GetMapping("/page") + public Result> page( + @RequestParam(defaultValue = "1") int pageNum, + @RequestParam(defaultValue = "10") int pageSize, + @RequestParam(required = false) Long customerId) { + Page page = contactService.pageContacts(pageNum, pageSize, customerId); + return Result.success(page); + } + + /** + * 删除联系人 + */ + @DeleteMapping("/{id}") + public Result delete(@PathVariable Long id) { + boolean result = contactService.deleteContact(id); + return Result.success(result); + } + + /** + * 设置主要联系人 + */ + @PutMapping("/{customerId}/contact/{contactId}/primary") + public Result setPrimary( + @PathVariable Long customerId, + @PathVariable Long contactId) { + boolean result = contactService.setPrimaryContact(customerId, contactId); + return Result.success(result); + } +} diff --git a/fund-cust/src/main/java/com/fundplatform/cust/data/entity/CustomerContact.java b/fund-cust/src/main/java/com/fundplatform/cust/data/entity/CustomerContact.java new file mode 100644 index 0000000..7aea94d --- /dev/null +++ b/fund-cust/src/main/java/com/fundplatform/cust/data/entity/CustomerContact.java @@ -0,0 +1,117 @@ +package com.fundplatform.cust.data.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.fundplatform.common.core.BaseEntity; + +import java.time.LocalDateTime; + +/** + * 联系人实体 + */ +@TableName("customer_contact") +public class CustomerContact extends BaseEntity { + + /** + * 客户ID + */ + private Long customerId; + + /** + * 联系人姓名 + */ + private String contactName; + + /** + * 职位 + */ + private String position; + + /** + * 手机号 + */ + private String phone; + + /** + * 邮箱 + */ + private String email; + + /** + * 是否主要联系人(0-否 1-是) + */ + private Integer isPrimary; + + /** + * 状态(0-禁用 1-启用) + */ + private Integer status; + + /** + * 备注 + */ + private String remark; + + public Long getCustomerId() { + return customerId; + } + + public void setCustomerId(Long customerId) { + this.customerId = customerId; + } + + public String getContactName() { + return contactName; + } + + public void setContactName(String contactName) { + this.contactName = contactName; + } + + public String getPosition() { + return position; + } + + public void setPosition(String position) { + this.position = position; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public Integer getIsPrimary() { + return isPrimary; + } + + public void setIsPrimary(Integer isPrimary) { + this.isPrimary = isPrimary; + } + + public Integer getStatus() { + return status; + } + + public void setStatus(Integer status) { + this.status = status; + } + + public String getRemark() { + return remark; + } + + public void setRemark(String remark) { + this.remark = remark; + } +} diff --git a/fund-cust/src/main/java/com/fundplatform/cust/data/mapper/CustomerContactMapper.java b/fund-cust/src/main/java/com/fundplatform/cust/data/mapper/CustomerContactMapper.java new file mode 100644 index 0000000..783708c --- /dev/null +++ b/fund-cust/src/main/java/com/fundplatform/cust/data/mapper/CustomerContactMapper.java @@ -0,0 +1,12 @@ +package com.fundplatform.cust.data.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.fundplatform.cust.data.entity.CustomerContact; +import org.apache.ibatis.annotations.Mapper; + +/** + * 联系人Mapper + */ +@Mapper +public interface CustomerContactMapper extends BaseMapper { +} diff --git a/fund-cust/src/main/java/com/fundplatform/cust/data/service/CustomerContactDataService.java b/fund-cust/src/main/java/com/fundplatform/cust/data/service/CustomerContactDataService.java new file mode 100644 index 0000000..1c3fb6a --- /dev/null +++ b/fund-cust/src/main/java/com/fundplatform/cust/data/service/CustomerContactDataService.java @@ -0,0 +1,10 @@ +package com.fundplatform.cust.data.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.fundplatform.cust.data.entity.CustomerContact; + +/** + * 联系人数据服务 + */ +public interface CustomerContactDataService extends IService { +} diff --git a/fund-cust/src/main/java/com/fundplatform/cust/data/service/impl/CustomerContactDataServiceImpl.java b/fund-cust/src/main/java/com/fundplatform/cust/data/service/impl/CustomerContactDataServiceImpl.java new file mode 100644 index 0000000..d55b78e --- /dev/null +++ b/fund-cust/src/main/java/com/fundplatform/cust/data/service/impl/CustomerContactDataServiceImpl.java @@ -0,0 +1,14 @@ +package com.fundplatform.cust.data.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.fundplatform.cust.data.entity.CustomerContact; +import com.fundplatform.cust.data.mapper.CustomerContactMapper; +import com.fundplatform.cust.data.service.CustomerContactDataService; +import org.springframework.stereotype.Service; + +/** + * 联系人数据服务实现 + */ +@Service +public class CustomerContactDataServiceImpl extends ServiceImpl implements CustomerContactDataService { +} diff --git a/fund-cust/src/main/java/com/fundplatform/cust/dto/ContactDTO.java b/fund-cust/src/main/java/com/fundplatform/cust/dto/ContactDTO.java new file mode 100644 index 0000000..8147f6a --- /dev/null +++ b/fund-cust/src/main/java/com/fundplatform/cust/dto/ContactDTO.java @@ -0,0 +1,126 @@ +package com.fundplatform.cust.dto; + +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; + +/** + * 联系人DTO + */ +public class ContactDTO { + + private Long id; + + /** + * 客户ID + */ + @NotNull(message = "客户ID不能为空") + private Long customerId; + + /** + * 联系人姓名 + */ + @NotBlank(message = "联系人姓名不能为空") + private String contactName; + + /** + * 职位 + */ + private String position; + + /** + * 手机号 + */ + private String phone; + + /** + * 邮箱 + */ + private String email; + + /** + * 是否主要联系人 + */ + private Integer isPrimary; + + /** + * 状态 + */ + private Integer status; + + /** + * 备注 + */ + private String remark; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public Long getCustomerId() { + return customerId; + } + + public void setCustomerId(Long customerId) { + this.customerId = customerId; + } + + public String getContactName() { + return contactName; + } + + public void setContactName(String contactName) { + this.contactName = contactName; + } + + public String getPosition() { + return position; + } + + public void setPosition(String position) { + this.position = position; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public Integer getIsPrimary() { + return isPrimary; + } + + public void setIsPrimary(Integer isPrimary) { + this.isPrimary = isPrimary; + } + + public Integer getStatus() { + return status; + } + + public void setStatus(Integer status) { + this.status = status; + } + + public String getRemark() { + return remark; + } + + public void setRemark(String remark) { + this.remark = remark; + } +} diff --git a/fund-cust/src/main/java/com/fundplatform/cust/service/ContactService.java b/fund-cust/src/main/java/com/fundplatform/cust/service/ContactService.java new file mode 100644 index 0000000..025f000 --- /dev/null +++ b/fund-cust/src/main/java/com/fundplatform/cust/service/ContactService.java @@ -0,0 +1,41 @@ +package com.fundplatform.cust.service; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.fundplatform.cust.dto.ContactDTO; +import com.fundplatform.cust.vo.ContactVO; + +/** + * 联系人服务接口 + */ +public interface ContactService { + + /** + * 创建联系人 + */ + Long createContact(ContactDTO dto); + + /** + * 更新联系人 + */ + boolean updateContact(Long id, ContactDTO dto); + + /** + * 根据ID查询联系人 + */ + ContactVO getContactById(Long id); + + /** + * 分页查询联系人 + */ + Page pageContacts(int pageNum, int pageSize, Long customerId); + + /** + * 删除联系人 + */ + boolean deleteContact(Long id); + + /** + * 设置主要联系人 + */ + boolean setPrimaryContact(Long customerId, Long contactId); +} diff --git a/fund-cust/src/main/java/com/fundplatform/cust/service/impl/ContactServiceImpl.java b/fund-cust/src/main/java/com/fundplatform/cust/service/impl/ContactServiceImpl.java new file mode 100644 index 0000000..ed97bfc --- /dev/null +++ b/fund-cust/src/main/java/com/fundplatform/cust/service/impl/ContactServiceImpl.java @@ -0,0 +1,148 @@ +package com.fundplatform.cust.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.fundplatform.cust.data.entity.CustomerContact; +import com.fundplatform.cust.data.service.CustomerContactDataService; +import com.fundplatform.cust.dto.ContactDTO; +import com.fundplatform.cust.service.ContactService; +import com.fundplatform.cust.vo.ContactVO; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.time.LocalDateTime; +import java.util.List; + +/** + * 联系人服务实现 + */ +@Service +public class ContactServiceImpl implements ContactService { + + private static final Logger log = LoggerFactory.getLogger(ContactServiceImpl.class); + + private final CustomerContactDataService contactDataService; + + public ContactServiceImpl(CustomerContactDataService contactDataService) { + this.contactDataService = contactDataService; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public Long createContact(ContactDTO dto) { + CustomerContact contact = new CustomerContact(); + contact.setCustomerId(dto.getCustomerId()); + contact.setContactName(dto.getContactName()); + contact.setPosition(dto.getPosition()); + contact.setPhone(dto.getPhone()); + contact.setEmail(dto.getEmail()); + contact.setIsPrimary(dto.getIsPrimary() != null ? dto.getIsPrimary() : 0); + contact.setStatus(dto.getStatus() != null ? dto.getStatus() : 1); + contact.setRemark(dto.getRemark()); + contact.setDeleted(0); + contact.setCreatedTime(LocalDateTime.now()); + + contactDataService.save(contact); + log.info("创建联系人成功: contactId={}, customerId={}", contact.getId(), contact.getCustomerId()); + return contact.getId(); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public boolean updateContact(Long id, ContactDTO dto) { + CustomerContact contact = contactDataService.getById(id); + if (contact == null || contact.getDeleted() == 1) { + throw new RuntimeException("联系人不存在"); + } + + contact.setContactName(dto.getContactName()); + contact.setPosition(dto.getPosition()); + contact.setPhone(dto.getPhone()); + contact.setEmail(dto.getEmail()); + contact.setIsPrimary(dto.getIsPrimary()); + contact.setStatus(dto.getStatus()); + contact.setRemark(dto.getRemark()); + contact.setUpdatedTime(LocalDateTime.now()); + + boolean result = contactDataService.updateById(contact); + log.info("更新联系人: contactId={}", id); + return result; + } + + @Override + public ContactVO getContactById(Long id) { + CustomerContact contact = contactDataService.getById(id); + if (contact == null || contact.getDeleted() == 1) { + throw new RuntimeException("联系人不存在"); + } + return convertToVO(contact); + } + + @Override + public Page pageContacts(int pageNum, int pageSize, Long customerId) { + Page page = new Page<>(pageNum, pageSize); + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.eq(CustomerContact::getDeleted, 0); + if (customerId != null) { + wrapper.eq(CustomerContact::getCustomerId, customerId); + } + wrapper.orderByDesc(CustomerContact::getIsPrimary); + wrapper.orderByDesc(CustomerContact::getCreatedTime); + + Page contactPage = contactDataService.page(page, wrapper); + Page voPage = new Page<>(contactPage.getCurrent(), contactPage.getSize(), contactPage.getTotal()); + voPage.setRecords(contactPage.getRecords().stream().map(this::convertToVO).toList()); + return voPage; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public boolean deleteContact(Long id) { + LambdaUpdateWrapper wrapper = new LambdaUpdateWrapper<>(); + wrapper.eq(CustomerContact::getId, id); + wrapper.set(CustomerContact::getDeleted, 1); + wrapper.set(CustomerContact::getUpdatedTime, LocalDateTime.now()); + boolean result = contactDataService.update(wrapper); + log.info("删除联系人: contactId={}", id); + return result; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public boolean setPrimaryContact(Long customerId, Long contactId) { + // 先清除该客户的所有主要联系人标记 + LambdaUpdateWrapper clearWrapper = new LambdaUpdateWrapper<>(); + clearWrapper.eq(CustomerContact::getCustomerId, customerId); + clearWrapper.set(CustomerContact::getIsPrimary, 0); + contactDataService.update(clearWrapper); + + // 设置新的主要联系人 + LambdaUpdateWrapper setWrapper = new LambdaUpdateWrapper<>(); + setWrapper.eq(CustomerContact::getId, contactId); + setWrapper.set(CustomerContact::getIsPrimary, 1); + setWrapper.set(CustomerContact::getUpdatedTime, LocalDateTime.now()); + boolean result = contactDataService.update(setWrapper); + + log.info("设置主要联系人: customerId={}, contactId={}", customerId, contactId); + return result; + } + + private ContactVO convertToVO(CustomerContact contact) { + ContactVO vo = new ContactVO(); + vo.setId(contact.getId()); + vo.setCustomerId(contact.getCustomerId()); + vo.setContactName(contact.getContactName()); + vo.setPosition(contact.getPosition()); + vo.setPhone(contact.getPhone()); + vo.setEmail(contact.getEmail()); + vo.setIsPrimary(contact.getIsPrimary()); + vo.setStatus(contact.getStatus()); + vo.setRemark(contact.getRemark()); + vo.setCreatedTime(contact.getCreatedTime()); + vo.setUpdatedTime(contact.getUpdatedTime()); + return vo; + } +} diff --git a/fund-cust/src/main/java/com/fundplatform/cust/vo/ContactVO.java b/fund-cust/src/main/java/com/fundplatform/cust/vo/ContactVO.java new file mode 100644 index 0000000..ca8aa18 --- /dev/null +++ b/fund-cust/src/main/java/com/fundplatform/cust/vo/ContactVO.java @@ -0,0 +1,162 @@ +package com.fundplatform.cust.vo; + +import java.time.LocalDateTime; + +/** + * 联系人VO + */ +public class ContactVO { + + private Long id; + + /** + * 客户ID + */ + private Long customerId; + + /** + * 客户名称 + */ + private String customerName; + + /** + * 联系人姓名 + */ + private String contactName; + + /** + * 职位 + */ + private String position; + + /** + * 手机号 + */ + private String phone; + + /** + * 邮箱 + */ + private String email; + + /** + * 是否主要联系人 + */ + private Integer isPrimary; + + /** + * 状态 + */ + private Integer status; + + /** + * 备注 + */ + private String remark; + + /** + * 创建时间 + */ + private LocalDateTime createdTime; + + /** + * 更新时间 + */ + private LocalDateTime updatedTime; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public Long getCustomerId() { + return customerId; + } + + public void setCustomerId(Long customerId) { + this.customerId = customerId; + } + + public String getCustomerName() { + return customerName; + } + + public void setCustomerName(String customerName) { + this.customerName = customerName; + } + + public String getContactName() { + return contactName; + } + + public void setContactName(String contactName) { + this.contactName = contactName; + } + + public String getPosition() { + return position; + } + + public void setPosition(String position) { + this.position = position; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public Integer getIsPrimary() { + return isPrimary; + } + + public void setIsPrimary(Integer isPrimary) { + this.isPrimary = isPrimary; + } + + public Integer getStatus() { + return status; + } + + public void setStatus(Integer status) { + this.status = status; + } + + public String getRemark() { + return remark; + } + + public void setRemark(String remark) { + this.remark = remark; + } + + public LocalDateTime getCreatedTime() { + return createdTime; + } + + public void setCreatedTime(LocalDateTime createdTime) { + this.createdTime = createdTime; + } + + public LocalDateTime getUpdatedTime() { + return updatedTime; + } + + public void setUpdatedTime(LocalDateTime updatedTime) { + this.updatedTime = updatedTime; + } +} diff --git a/fund-exp/src/main/java/com/fundplatform/exp/controller/ExpenseTypeController.java b/fund-exp/src/main/java/com/fundplatform/exp/controller/ExpenseTypeController.java index dbde24b..7bc94dd 100644 --- a/fund-exp/src/main/java/com/fundplatform/exp/controller/ExpenseTypeController.java +++ b/fund-exp/src/main/java/com/fundplatform/exp/controller/ExpenseTypeController.java @@ -35,8 +35,9 @@ public class ExpenseTypeController { /** * 更新支出类型 */ - @PutMapping - public Result update(@Valid @RequestBody ExpenseTypeDTO dto) { + @PutMapping("/{id}") + public Result update(@PathVariable Long id, @Valid @RequestBody ExpenseTypeDTO dto) { + dto.setId(id); return Result.success(typeService.updateType(dto)); } diff --git a/fund-exp/src/main/java/com/fundplatform/exp/controller/FundExpenseController.java b/fund-exp/src/main/java/com/fundplatform/exp/controller/FundExpenseController.java index e6f618b..81608ab 100644 --- a/fund-exp/src/main/java/com/fundplatform/exp/controller/FundExpenseController.java +++ b/fund-exp/src/main/java/com/fundplatform/exp/controller/FundExpenseController.java @@ -38,8 +38,9 @@ public class FundExpenseController { /** * 更新支出申请(仅待审批状态可修改) */ - @PutMapping - public Result update(@Valid @RequestBody FundExpenseDTO dto) { + @PutMapping("/{id}") + public Result update(@PathVariable Long id, @Valid @RequestBody FundExpenseDTO dto) { + dto.setId(id); return Result.success(expenseService.updateExpense(dto)); } diff --git a/fund-receipt/src/main/java/com/fundplatform/receipt/controller/ReceivableController.java b/fund-receipt/src/main/java/com/fundplatform/receipt/controller/ReceivableController.java index 18529d2..8776662 100644 --- a/fund-receipt/src/main/java/com/fundplatform/receipt/controller/ReceivableController.java +++ b/fund-receipt/src/main/java/com/fundplatform/receipt/controller/ReceivableController.java @@ -4,11 +4,13 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.fundplatform.common.core.Result; import com.fundplatform.receipt.dto.ReceivableDTO; import com.fundplatform.receipt.service.ReceivableService; +import com.fundplatform.receipt.vo.FundReceiptVO; import com.fundplatform.receipt.vo.ReceivableVO; import jakarta.validation.Valid; import org.springframework.web.bind.annotation.*; import java.math.BigDecimal; +import java.util.List; /** * 应收款管理Controller @@ -40,8 +42,9 @@ public class ReceivableController { /** * 更新应收款(仅待确认状态可修改) */ - @PutMapping - public Result update(@Valid @RequestBody ReceivableDTO dto) { + @PutMapping("/{id}") + public Result update(@PathVariable Long id, @Valid @RequestBody ReceivableDTO dto) { + dto.setId(id); return Result.success(receivableService.updateReceivable(dto)); } @@ -93,6 +96,14 @@ public class ReceivableController { return Result.success(receivableService.recordReceipt(id, amount)); } + /** + * 获取应收款的收款记录列表 + */ + @GetMapping("/{id}/receipts") + public Result> getReceipts(@PathVariable Long id) { + return Result.success(receivableService.getReceiptsByReceivableId(id)); + } + /** * 更新逾期状态 */ diff --git a/fund-receipt/src/main/java/com/fundplatform/receipt/data/entity/FundReceipt.java b/fund-receipt/src/main/java/com/fundplatform/receipt/data/entity/FundReceipt.java index 4366fb0..6650b06 100644 --- a/fund-receipt/src/main/java/com/fundplatform/receipt/data/entity/FundReceipt.java +++ b/fund-receipt/src/main/java/com/fundplatform/receipt/data/entity/FundReceipt.java @@ -48,6 +48,9 @@ public class FundReceipt extends BaseEntity { /** 关联客户ID */ private Long customerId; + /** 关联应收款ID */ + private Long receivableId; + /** 收款状态(0-待确认 1-已确认 2-已核销) */ private Integer receiptStatus; @@ -96,6 +99,8 @@ public class FundReceipt extends BaseEntity { public void setProjectId(Long projectId) { this.projectId = projectId; } public Long getCustomerId() { return customerId; } public void setCustomerId(Long customerId) { this.customerId = customerId; } + public Long getReceivableId() { return receivableId; } + public void setReceivableId(Long receivableId) { this.receivableId = receivableId; } public Integer getReceiptStatus() { return receiptStatus; } public void setReceiptStatus(Integer receiptStatus) { this.receiptStatus = receiptStatus; } public LocalDateTime getConfirmTime() { return confirmTime; } diff --git a/fund-receipt/src/main/java/com/fundplatform/receipt/service/FundReceiptService.java b/fund-receipt/src/main/java/com/fundplatform/receipt/service/FundReceiptService.java index fa3ec46..18dcd76 100644 --- a/fund-receipt/src/main/java/com/fundplatform/receipt/service/FundReceiptService.java +++ b/fund-receipt/src/main/java/com/fundplatform/receipt/service/FundReceiptService.java @@ -4,6 +4,8 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.fundplatform.receipt.dto.FundReceiptDTO; import com.fundplatform.receipt.vo.FundReceiptVO; +import java.util.List; + public interface FundReceiptService { Long createReceipt(FundReceiptDTO dto); @@ -14,6 +16,11 @@ public interface FundReceiptService { Page pageReceipts(int pageNum, int pageSize, String title, Integer receiptType, Integer receiptStatus); + /** + * 根据应收款ID查询收款记录 + */ + List getReceiptsByReceivableId(Long receivableId); + boolean deleteReceipt(Long id); boolean confirm(Long id); diff --git a/fund-receipt/src/main/java/com/fundplatform/receipt/service/ReceivableService.java b/fund-receipt/src/main/java/com/fundplatform/receipt/service/ReceivableService.java index 4f82b26..20ca2c2 100644 --- a/fund-receipt/src/main/java/com/fundplatform/receipt/service/ReceivableService.java +++ b/fund-receipt/src/main/java/com/fundplatform/receipt/service/ReceivableService.java @@ -2,9 +2,11 @@ package com.fundplatform.receipt.service; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.fundplatform.receipt.dto.ReceivableDTO; +import com.fundplatform.receipt.vo.FundReceiptVO; import com.fundplatform.receipt.vo.ReceivableVO; import java.math.BigDecimal; +import java.util.List; /** * 应收款服务接口 @@ -46,6 +48,11 @@ public interface ReceivableService { */ boolean recordReceipt(Long id, BigDecimal amount); + /** + * 获取应收款的收款记录 + */ + List getReceiptsByReceivableId(Long receivableId); + /** * 更新逾期状态 */ diff --git a/fund-receipt/src/main/java/com/fundplatform/receipt/service/impl/FundReceiptServiceImpl.java b/fund-receipt/src/main/java/com/fundplatform/receipt/service/impl/FundReceiptServiceImpl.java index 91c8d43..431169d 100644 --- a/fund-receipt/src/main/java/com/fundplatform/receipt/service/impl/FundReceiptServiceImpl.java +++ b/fund-receipt/src/main/java/com/fundplatform/receipt/service/impl/FundReceiptServiceImpl.java @@ -17,6 +17,7 @@ import org.springframework.util.StringUtils; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; +import java.util.List; import java.util.concurrent.atomic.AtomicInteger; @Service @@ -101,6 +102,15 @@ public class FundReceiptServiceImpl implements FundReceiptService { return voPage; } + @Override + public List getReceiptsByReceivableId(Long receivableId) { + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.eq(FundReceipt::getDeleted, 0); + wrapper.eq(FundReceipt::getReceivableId, receivableId); + wrapper.orderByDesc(FundReceipt::getCreatedTime); + return receiptDataService.list(wrapper).stream().map(this::convertToVO).toList(); + } + @Override @Transactional(rollbackFor = Exception.class) public boolean deleteReceipt(Long id) { @@ -151,6 +161,7 @@ public class FundReceiptServiceImpl implements FundReceiptService { vo.setPurpose(r.getPurpose()); vo.setProjectId(r.getProjectId()); vo.setCustomerId(r.getCustomerId()); + vo.setReceivableId(r.getReceivableId()); vo.setReceiptStatus(r.getReceiptStatus()); vo.setReceiptStatusName(getReceiptStatusName(r.getReceiptStatus())); vo.setConfirmTime(r.getConfirmTime()); diff --git a/fund-receipt/src/main/java/com/fundplatform/receipt/service/impl/ReceivableServiceImpl.java b/fund-receipt/src/main/java/com/fundplatform/receipt/service/impl/ReceivableServiceImpl.java index ac03f79..e1c8700 100644 --- a/fund-receipt/src/main/java/com/fundplatform/receipt/service/impl/ReceivableServiceImpl.java +++ b/fund-receipt/src/main/java/com/fundplatform/receipt/service/impl/ReceivableServiceImpl.java @@ -8,7 +8,9 @@ import com.fundplatform.common.context.UserContextHolder; import com.fundplatform.receipt.data.entity.Receivable; import com.fundplatform.receipt.data.service.ReceivableDataService; import com.fundplatform.receipt.dto.ReceivableDTO; +import com.fundplatform.receipt.service.FundReceiptService; import com.fundplatform.receipt.service.ReceivableService; +import com.fundplatform.receipt.vo.FundReceiptVO; import com.fundplatform.receipt.vo.ReceivableVO; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -19,6 +21,7 @@ import java.math.BigDecimal; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; +import java.util.List; import java.util.concurrent.atomic.AtomicInteger; @Service @@ -42,9 +45,11 @@ public class ReceivableServiceImpl implements ReceivableService { private static final int CONFIRM_CONFIRMED = 1; private final ReceivableDataService receivableDataService; + private final FundReceiptService receiptService; - public ReceivableServiceImpl(ReceivableDataService receivableDataService) { + public ReceivableServiceImpl(ReceivableDataService receivableDataService, FundReceiptService receiptService) { this.receivableDataService = receivableDataService; + this.receiptService = receiptService; } @Override @@ -229,6 +234,11 @@ public class ReceivableServiceImpl implements ReceivableService { return result; } + @Override + public List getReceiptsByReceivableId(Long receivableId) { + return receiptService.getReceiptsByReceivableId(receivableId); + } + @Override @Transactional(rollbackFor = Exception.class) public void updateOverdueStatus() { diff --git a/fund-receipt/src/main/java/com/fundplatform/receipt/vo/FundReceiptVO.java b/fund-receipt/src/main/java/com/fundplatform/receipt/vo/FundReceiptVO.java index fb5346d..b610222 100644 --- a/fund-receipt/src/main/java/com/fundplatform/receipt/vo/FundReceiptVO.java +++ b/fund-receipt/src/main/java/com/fundplatform/receipt/vo/FundReceiptVO.java @@ -19,6 +19,7 @@ public class FundReceiptVO { private String purpose; private Long projectId; private Long customerId; + private Long receivableId; private Integer receiptStatus; private String receiptStatusName; private LocalDateTime confirmTime; @@ -60,6 +61,8 @@ public class FundReceiptVO { public void setProjectId(Long projectId) { this.projectId = projectId; } public Long getCustomerId() { return customerId; } public void setCustomerId(Long customerId) { this.customerId = customerId; } + public Long getReceivableId() { return receivableId; } + public void setReceivableId(Long receivableId) { this.receivableId = receivableId; } public Integer getReceiptStatus() { return receiptStatus; } public void setReceiptStatus(Integer receiptStatus) { this.receiptStatus = receiptStatus; } public String getReceiptStatusName() { return receiptStatusName; } diff --git a/fund-sys/src/main/java/com/fundplatform/sys/controller/AuthController.java b/fund-sys/src/main/java/com/fundplatform/sys/controller/AuthController.java index 90a234e..70a1878 100644 --- a/fund-sys/src/main/java/com/fundplatform/sys/controller/AuthController.java +++ b/fund-sys/src/main/java/com/fundplatform/sys/controller/AuthController.java @@ -35,6 +35,24 @@ public class AuthController { return Result.success(vo); } + /** + * 用户登出 + */ + @PostMapping("/logout") + public Result logout(@RequestHeader(value = "X-User-Id", required = false) Long userId) { + authService.logout(userId); + return Result.success(); + } + + /** + * 刷新Token + */ + @PostMapping("/refresh") + public Result refreshToken(@RequestHeader("X-User-Id") Long userId) { + LoginVO vo = authService.refreshToken(userId); + return Result.success(vo); + } + /** * 获取当前用户信息 */ diff --git a/fund-sys/src/main/java/com/fundplatform/sys/controller/RoleController.java b/fund-sys/src/main/java/com/fundplatform/sys/controller/RoleController.java index 5c009d8..5fb4f03 100644 --- a/fund-sys/src/main/java/com/fundplatform/sys/controller/RoleController.java +++ b/fund-sys/src/main/java/com/fundplatform/sys/controller/RoleController.java @@ -69,7 +69,19 @@ public class RoleController { return Result.success(result); } - @PostMapping("/{id}/menus") + /** + * 获取角色菜单ID列表 + */ + @GetMapping("/{id}/menus") + public Result> getRoleMenus(@PathVariable Long id) { + List menuIds = roleService.getRoleMenus(id); + return Result.success(menuIds); + } + + /** + * 分配菜单给角色 + */ + @PutMapping("/{id}/menus") public Result assignMenus(@PathVariable Long id, @RequestBody List menuIds) { boolean result = roleService.assignMenus(id, menuIds); return Result.success(result); diff --git a/fund-sys/src/main/java/com/fundplatform/sys/service/AuthService.java b/fund-sys/src/main/java/com/fundplatform/sys/service/AuthService.java index f0f05b5..9ef970c 100644 --- a/fund-sys/src/main/java/com/fundplatform/sys/service/AuthService.java +++ b/fund-sys/src/main/java/com/fundplatform/sys/service/AuthService.java @@ -14,6 +14,16 @@ public interface AuthService { */ LoginVO login(LoginRequestDTO request); + /** + * 用户登出 + */ + void logout(Long userId); + + /** + * 刷新Token + */ + LoginVO refreshToken(Long userId); + /** * 获取当前用户信息 */ diff --git a/fund-sys/src/main/java/com/fundplatform/sys/service/RoleService.java b/fund-sys/src/main/java/com/fundplatform/sys/service/RoleService.java index 1a2de7d..0a8af3d 100644 --- a/fund-sys/src/main/java/com/fundplatform/sys/service/RoleService.java +++ b/fund-sys/src/main/java/com/fundplatform/sys/service/RoleService.java @@ -46,6 +46,11 @@ public interface RoleService { */ boolean updateStatus(Long id, Integer status); + /** + * 获取角色菜单ID列表 + */ + List getRoleMenus(Long roleId); + /** * 分配菜单权限 */ diff --git a/fund-sys/src/main/java/com/fundplatform/sys/service/impl/AuthServiceImpl.java b/fund-sys/src/main/java/com/fundplatform/sys/service/impl/AuthServiceImpl.java index 9f4787a..0ea2de5 100644 --- a/fund-sys/src/main/java/com/fundplatform/sys/service/impl/AuthServiceImpl.java +++ b/fund-sys/src/main/java/com/fundplatform/sys/service/impl/AuthServiceImpl.java @@ -58,6 +58,30 @@ public class AuthServiceImpl implements AuthService { return new LoginVO(user.getId(), user.getUsername(), token, user.getTenantId()); } + @Override + public void logout(Long userId) { + // TODO: 可以在此处清除用户的Token缓存或记录登出日志 + // 目前JWT是无状态的,登出只需前端清除Token即可 + } + + @Override + public LoginVO refreshToken(Long userId) { + SysUser user = userDataService.getById(userId); + if (user == null) { + throw new RuntimeException("用户不存在"); + } + + // 检查用户状态 + if (user.getStatus() != 1) { + throw new RuntimeException("用户已被禁用"); + } + + // 生成新Token + String token = JwtUtil.generateToken(user.getId(), user.getUsername(), user.getTenantId()); + + return new LoginVO(user.getId(), user.getUsername(), token, user.getTenantId()); + } + @Override public UserVO getUserInfo(Long userId) { SysUser user = userDataService.getById(userId); diff --git a/fund-sys/src/main/java/com/fundplatform/sys/service/impl/RoleServiceImpl.java b/fund-sys/src/main/java/com/fundplatform/sys/service/impl/RoleServiceImpl.java index e69ba69..4bc6c3d 100644 --- a/fund-sys/src/main/java/com/fundplatform/sys/service/impl/RoleServiceImpl.java +++ b/fund-sys/src/main/java/com/fundplatform/sys/service/impl/RoleServiceImpl.java @@ -144,6 +144,14 @@ public class RoleServiceImpl implements RoleService { return result; } + @Override + public List getRoleMenus(Long roleId) { + // TODO: 从sys_role_menu表查询角色关联的菜单ID + // 目前返回空列表 + log.info("获取角色菜单: roleId={}", roleId); + return List.of(); + } + @Override @Transactional(rollbackFor = Exception.class) public boolean assignMenus(Long roleId, List menuIds) {