移除executor模块资金管理相关代码

This commit is contained in:
gaoqr
2025-09-03 10:12:04 +08:00
parent 772fbea1c6
commit c1ad7a5613
44 changed files with 2 additions and 2646 deletions
@@ -1,29 +0,0 @@
package com.cf.imes.module.executor.api.funds;
import com.cf.imes.framework.common.pojo.CommonResult;
import com.cf.imes.module.executor.enums.ApiConstants;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import java.math.BigDecimal;
/**
* @author 资金管理feign接口
*/
@FeignClient(name = ApiConstants.NAME) // TODO 晨丰:fallbackFactory =
@Tag(name = "RPC 服务 - 资金管理")
public interface ExecutorFundsApi {
String PREFIX = ApiConstants.PREFIX + "/funds";
@GetMapping(PREFIX +"/getInvoiceAmount")
@Operation(summary = "查询待审核的发票金额")
CommonResult<BigDecimal> getToExamineAmount();
}
@@ -1,36 +0,0 @@
package com.cf.imes.module.executor.api.funds;
import com.cf.imes.framework.common.pojo.CommonResult;
import com.cf.imes.module.executor.dal.mysql.funds.invoice.InvoiceRecordsMapper;
import com.cf.imes.module.executor.enums.amount.InvoiceStatusEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RestController;
import jakarta.annotation.Resource;
import java.math.BigDecimal;
@RestController // 提供 RESTful API 接口,给 Feign 调用
@Validated
@Slf4j
public class ExecutorFundsApiImpl implements ExecutorFundsApi{
@Resource
private InvoiceRecordsMapper invoiceRecordsMapper;
@Override
public CommonResult<BigDecimal> getToExamineAmount() {
BigDecimal examineAmount = invoiceRecordsMapper.selectToExamineAmount(InvoiceStatusEnum.PENDINGINVOICING.getStatus());
return CommonResult.success(examineAmount);
}
}
@@ -1,73 +0,0 @@
package com.cf.imes.module.executor.controller.admin.funds.balancedetails;
import com.cf.imes.framework.common.pojo.CommonResult;
import com.cf.imes.framework.common.pojo.PageParam;
import com.cf.imes.framework.common.pojo.PageResult;
import com.cf.imes.framework.common.util.object.BeanUtils;
import com.cf.imes.framework.excel.core.util.ExcelUtils;
import com.cf.imes.framework.operatelog.core.annotations.OperateLog;
import com.cf.imes.module.executor.controller.admin.funds.balancedetails.vo.BalanceDetailsRespVO;
import com.cf.imes.module.executor.controller.admin.funds.balancedetails.vo.BalanceDetailsPageReqVO;
import com.cf.imes.module.executor.service.funds.balancedetails.BalanceDetailsService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.Valid;
import java.io.IOException;
import java.util.List;
import static com.cf.imes.framework.common.pojo.CommonResult.success;
import static com.cf.imes.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
/**
* @author 组织余额明细
*/
@Tag(name = "管理后台 - 组织余额明细")
@RestController
@RequestMapping("/executor/balance")
@Validated
public class BalanceDetailsController {
@Resource
private BalanceDetailsService balanceDetailsService;
@GetMapping("")
@Operation(summary = "获取组织余额明细")
public CommonResult<PageResult<BalanceDetailsRespVO>> getBalanceDetailsPage(@Valid BalanceDetailsPageReqVO pageReqVO) {
return success(balanceDetailsService.getBalanceDetailsPage(pageReqVO));
}
@GetMapping("/export")
@Operation(summary = "组织余额明细导出")
@OperateLog(type = EXPORT)
public void balanceDetailsExport(@Valid BalanceDetailsPageReqVO pageReqVO,
HttpServletResponse response) throws IOException {
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
List<BalanceDetailsRespVO> list = balanceDetailsService.getBalanceDetailsPage(pageReqVO).getList();
// 导出 Excel
ExcelUtils.write(response, "余额明细表.xls", "数据", BalanceDetailsRespVO.class,
BeanUtils.toBean(list, BalanceDetailsRespVO.class));
}
}
@@ -1,48 +0,0 @@
package com.cf.imes.module.executor.controller.admin.funds.balancedetails.vo;
import com.cf.imes.framework.common.pojo.PageParam;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDate;
import static com.cf.imes.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY;
@Schema(description = "管理后台 - 组织余额明细分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@Builder
public class BalanceDetailsPageReqVO extends PageParam {
@Schema(description = "流水号")
private Long id;
@Schema(description = "组织名称")
private String organName;
@Schema(description = "交易类型")
private Integer tradeType;
@Schema(description = "收支类型")
private Integer incomeExpenseType;
@Schema(description = "创建时间", example = "[2022-07-01 ,2022-07-01]")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY)
private LocalDate[] createTime;
@Schema(description = "组织ID")
private Long organId;
}
@@ -1,83 +0,0 @@
package com.cf.imes.module.executor.controller.admin.funds.balancedetails.vo;
import com.alibaba.excel.annotation.ExcelProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDateTime;
@Data
public class BalanceDetailsRespVO {
@Schema(description = "流水号")
@ExcelProperty("流水号")
private Long businessNo;
@Schema(description = "交易类型,0充值 1软件购买")
@ExcelProperty("交易类型")
private Integer tradeType;
@Schema(description = "收支类型,0收入 1支出")
private Integer incomeExpenseType;
@Schema(description = "入账现金")
@ExcelProperty("入账现金")
private BigDecimal entryAmount;
@Schema(description = "入账赠送金")
@ExcelProperty("入账赠送金")
private BigDecimal entryGiftAmount;
@Schema(description = "支出现金")
@ExcelProperty("支出现金")
private BigDecimal expensesAmount;
@Schema(description = "支出赠送金")
@ExcelProperty("支出赠送金")
private BigDecimal expensesGiftAmount;
@Schema(description = "可用金额")
@ExcelProperty("可用金额")
private BigDecimal availableAmount;
@Schema(description = "现金金额")
@ExcelProperty("现金金额")
private BigDecimal amount;
@Schema(description = "赠送金额")
@ExcelProperty("赠送金额")
private BigDecimal giftAmount;
@Schema(description = "交易时间")
@ExcelProperty("交易时间")
private LocalDateTime createTime;
@Schema(description = "操作人")
@ExcelProperty("操作人")
private LocalDateTime creator;
@Schema(description = "支出/入账现金金额")
private BigDecimal cashAmountChange;
@Schema(description = "支出/入账赠送金金额")
private BigDecimal bonusAmountChange;
}
@@ -1,69 +0,0 @@
package com.cf.imes.module.executor.controller.admin.funds.bill;
import com.cf.imes.framework.common.pojo.CommonResult;
import com.cf.imes.framework.common.pojo.PageParam;
import com.cf.imes.framework.common.pojo.PageResult;
import com.cf.imes.framework.excel.core.util.ExcelUtils;
import com.cf.imes.framework.operatelog.core.annotations.OperateLog;
import com.cf.imes.module.executor.controller.admin.funds.balancedetails.vo.BalanceDetailsPageReqVO;
import com.cf.imes.module.executor.controller.admin.funds.bill.vo.BillDetailsRespVO;
import com.cf.imes.module.executor.service.funds.bill.BillService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.Valid;
import java.io.IOException;
import java.util.List;
import static com.cf.imes.framework.common.pojo.CommonResult.success;
import static com.cf.imes.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
/**
* @author 账单/总额明细
*/
@Tag(name = "管理后台 - 账单/总额明细")
@RestController
@RequestMapping("/executor/bill")
@Validated
public class BillController {
@Resource
private BillService billService;
@GetMapping("")
@Operation(summary = "获取组织账单明细")
public CommonResult<PageResult<BillDetailsRespVO>> getBillDetailsPage(@Valid BalanceDetailsPageReqVO pageReqVO) {
return success(billService.getBillDetailsPage(pageReqVO));
}
@GetMapping("/export")
@Operation(summary = "组织账单明细下载")
@OperateLog(type = EXPORT)
public void billDetailsExport(@Valid BalanceDetailsPageReqVO pageReqVO,
HttpServletResponse response) throws IOException {
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
List<BillDetailsRespVO> list = billService.getBillDetailsPage(pageReqVO).getList();
// 导出 Excel
ExcelUtils.write(response, "余额明细表.xls", "数据", BillDetailsRespVO.class,list);
}
}
@@ -1,77 +0,0 @@
package com.cf.imes.module.executor.controller.admin.funds.bill.vo;
import com.alibaba.excel.annotation.ExcelProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDateTime;
@Data
public class BillDetailsRespVO {
@Schema(description = "流水号")
@ExcelProperty("流水号")
private Long businessNo;
@Schema(description = "交易类型-枚举类-")
private Integer tradeType;
@Schema(description = "收支类型-枚举类")
private Integer incomeExpenseType;
@Schema(description = "充值金额")
@ExcelProperty("充值金额")
private BigDecimal rechargeAmount;
@Schema(description = "产品金额")
@ExcelProperty("产品金额")
private BigDecimal productAmount;
@Schema(description = "支出现金")
@ExcelProperty("支出现金")
private BigDecimal cashExpenditure;
@Schema(description = "支出账户余额")
@ExcelProperty("支出账户余额")
private BigDecimal expenditureAccountBalance;
@Schema(description = "实际支出总费用")
@ExcelProperty("实际支出总费用")
private BigDecimal actualTotalExpenditure;
@Schema(description = "交易时间")
@ExcelProperty("交易时间")
private LocalDateTime createTime;
@Schema(description = "操作人")
@ExcelProperty("操作人")
private LocalDateTime creator;
@Schema(description = "支出/入账现金金额")
private BigDecimal cashAmountChange;
@Schema(description = "支出/入账赠送金金额")
private BigDecimal bonusAmountChange;
@Schema(description = "可用余额")
private BigDecimal availableAmount;
}
@@ -1,140 +0,0 @@
package com.cf.imes.module.executor.controller.admin.funds.invoice;
import com.cf.imes.framework.common.pojo.CommonResult;
import com.cf.imes.framework.common.pojo.PageResult;
import com.cf.imes.framework.operatelog.core.annotations.OperateLog;
import com.cf.imes.module.executor.controller.admin.funds.invoice.vo.*;
import com.cf.imes.module.executor.service.funds.invoice.InvoiceService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.Valid;
import static com.cf.imes.framework.common.pojo.CommonResult.success;
import static com.cf.imes.framework.operatelog.core.enums.OperateTypeEnum.IMPORT;
/**
* @author 发票管理
*/
@Tag(name = "管理后台 - 发票管理")
@RestController
@RequestMapping("/executor/invoice")
@Validated
public class InvoiceController {
@Resource
private InvoiceService invoiceService;
@GetMapping("/{organId}")
@Operation(summary = "获取组织的开票金额信息")
@Parameter(name = "organId", description = "组织ID", required = true, example = "1")
public CommonResult<InvoiceAmountRespVO> getInvoiceAmount(@PathVariable("organId") Long organId) {
return success(invoiceService.getInvoiceAmount(organId));
}
@GetMapping("/details")
@Operation(summary = "获取组织可开票数据明细")
public CommonResult<PageResult<InvoiceDetailsRespVO>> getInvoiceDetails(@Valid InvoiceDetailsPageReqVO pageReqVO) {
return success(invoiceService.getInvoiceDetails(pageReqVO));
}
@GetMapping("/records")
@Operation(summary = "获取组织的开票记录")
public CommonResult<PageResult<InvoiceRecordsRespVO>> getInvoiceRecords(@Valid InvoiceDetailsPageReqVO pageReqVO) {
return success(invoiceService.getInvoiceRecords(pageReqVO));
}
@GetMapping("/invoice")
@Parameter(name = "invoiceId", description = "发票ID", required = true)
@Operation(summary = "获取发票对应的购买记录和抬头信息")
public CommonResult<InvoiceDetailsRespVO> getInvoiceIncome(@Valid @RequestParam("invoiceId") Long invoiceId) {
return success(invoiceService.getInvoiceIncome(invoiceId));
}
@PostMapping("")
@Operation(summary = "组织新增开票记录")
public CommonResult<Boolean> insetInvoiceRecords(@Valid @RequestBody InvoiceRecordsReqVO reqVO) {
invoiceService.insetInvoiceRecords(reqVO);
return success(Boolean.TRUE);
}
@PutMapping("")
@Operation(summary = "同意/拒绝开票")
public CommonResult<Boolean> invoicing(@Valid @RequestBody InvoiceInvoicingReqVO reqVO) {
invoiceService.invoicing(reqVO);
return success(Boolean.TRUE);
}
@PostMapping("/upload")
@Operation(summary = "发票上传")
@Parameter(name = "invoiceId", description = "发票ID", required = true)
@OperateLog(type = IMPORT)
public CommonResult<Boolean> uploadInvoice(@RequestParam("file") MultipartFile file,@RequestParam("invoiceId") Long invoiceId) {
invoiceService.uploadInvoice(file,invoiceId);
return success(Boolean.TRUE);
}
@GetMapping("/download")
@Operation(summary = "发票文件下载")
@Parameter(name = "invoiceId", description = "发票ID", required = true)
public void downloadInvoice(@RequestParam("invoiceId") Long invoiceId, HttpServletResponse response) {
invoiceService.downloadInvoice(invoiceId,response);
}
}
@@ -1,23 +0,0 @@
package com.cf.imes.module.executor.controller.admin.funds.invoice.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.math.BigDecimal;
@Data
public class InvoiceAmountRespVO {
@Schema(description = "可开票")
private BigDecimal invocable;
@Schema(description = "开票中")
private BigDecimal inTheInvoice;
@Schema(description = "已开票")
private BigDecimal invoiced;
}
@@ -1,61 +0,0 @@
package com.cf.imes.module.executor.controller.admin.funds.invoice.vo;
import com.cf.imes.framework.common.pojo.PageParam;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.springframework.format.annotation.DateTimeFormat;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import static com.cf.imes.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "管理后台 - 组织可开票的数据明细 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@Builder
public class InvoiceDetailsPageReqVO extends PageParam {
@Schema(description = "组织ID")
private Long organId;
@Schema(description = "发票号")
private String invoiceNo;
@Schema(description = "发票状态,1待开票 2已开票 3开票失败")
private Integer status;
@Schema(description = "申请人")
private String creator;
@Schema(description = "开票人")
private String invoicePerson;
@Schema(description = "发票金额")
private BigDecimal[] invoiceAmount;
@Schema(description = "开票时间", example = "[2022-07-01 01:01:01 ,2022-07-01 01:01:01]")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] invoiceTime;
@Schema(description = "交易时间", example = "[2022-07-01 01:01:01 ,2022-07-01 01:01:01]")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
@Schema(description = "交易金额")
private BigDecimal[] amount;
}
@@ -1,28 +0,0 @@
package com.cf.imes.module.executor.controller.admin.funds.invoice.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class InvoiceDetailsRespVO {
@Schema(description = "发票对应的购买记录")
private List<InvoicePurchaseRecord> invoicePurchaseRecords;
@Schema(description = "发票抬头信息")
private InvoiceTitleInfo invoiceTitleInfo;
}
@@ -1,17 +0,0 @@
package com.cf.imes.module.executor.controller.admin.funds.invoice.vo;
import lombok.Data;
import lombok.Getter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
@Getter
@Data
public class InvoiceFilePath {
@Value("${invoice.filepath:}")
private String filePath;
}
@@ -1,31 +0,0 @@
package com.cf.imes.module.executor.controller.admin.funds.invoice.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
public class InvoiceInvoicingReqVO {
@Schema(description = "发票抬头ID")
private Long id;
@Schema(description = "是否开票")
private Boolean isInvoicing;
@Schema(description = "发票号")
private String invoiceNo;
@Schema(description = "发票附件")
private String invoiceAttachmentPath;
@Schema(description = "备注")
private String remark;
}
@@ -1,38 +0,0 @@
package com.cf.imes.module.executor.controller.admin.funds.invoice.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDateTime;
@Data
public class InvoicePurchaseRecord {
@Schema(description = "流水号")
private Long businessNo;
@Schema(description = "购买记录ID")
private Long purchaseRecordId;
@Schema(description = "产品名称")
private String productName;
@Schema(description = "交易类型")
private Integer tradeType;
@Schema(description = "可开票金额")
private BigDecimal rechargeAmount;
@Schema(description = "交易时间")
private LocalDateTime createTime;
}
@@ -1,27 +0,0 @@
package com.cf.imes.module.executor.controller.admin.funds.invoice.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.math.BigDecimal;
import java.util.List;
@Data
public class InvoiceRecordsReqVO {
@Schema(description = "购买记录ID")
private List<Long> purchaseRecordId;
@Schema(description = "发票金额")
private BigDecimal invoiceAmount;
@Schema(description = "发票抬头ID")
private Long invoiceTitleId;
}
@@ -1,66 +0,0 @@
package com.cf.imes.module.executor.controller.admin.funds.invoice.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDateTime;
@Data
public class InvoiceRecordsRespVO {
@Schema(description = "发票ID")
private Long id;
@Schema(description = "组织ID")
private Long organId;
@Schema(description = "组织名称")
private String organName;
@Schema(description = "发票申请人ID")
private Long userId;
@Schema(description = "发票申请人名称")
private String creator;
@Schema(description = "发票号")
private String invoiceNo;
@Schema(description = "发票金额")
private BigDecimal invoiceAmount;
@Schema(description = "发票状态,1待开票 2已开票 3开票失败")
private Integer status;
@Schema(description = "发票附件保存路径")
private String invoiceAttachmentPath;
@Schema(description = "开票人")
private String invoicePerson;
@Schema(description = "开票人用户ID")
private Long invoicePersonId;
@Schema(description = "开票时间")
private LocalDateTime invoiceTime;
@Schema(description = "备注")
private String remark;
}
@@ -1,55 +0,0 @@
package com.cf.imes.module.executor.controller.admin.funds.invoice.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
public class InvoiceTitleInfo {
@Schema(description = "发票抬头ID")
private Long id;
@Schema(description = "组织ID")
private Long organId;
@Schema(description = "发票抬头")
private String invoiceTitle;
@Schema(description = "开具类型,0企业 1个人")
private Integer issueType;
@Schema(description = "发票类型,0增值税普通发票 1增值税专用发票")
private Integer invoiceType;
@Schema(description = "纳税人识别号")
private String taxpayerId;
@Schema(description = "开户银行名称")
private String bankName;
@Schema(description = "开户银行账号")
private String bankAccount;
@Schema(description = "注册场所地址")
private String registeredAddress;
@Schema(description = "注册固定电话")
private String fixedPhone;
@Schema(description = "邮箱")
private String email;
}
@@ -1,69 +0,0 @@
package com.cf.imes.module.executor.controller.admin.funds.purchase;
import com.cf.imes.framework.common.pojo.CommonResult;
import com.cf.imes.framework.common.pojo.PageParam;
import com.cf.imes.framework.common.pojo.PageResult;
import com.cf.imes.framework.excel.core.util.ExcelUtils;
import com.cf.imes.framework.operatelog.core.annotations.OperateLog;
import com.cf.imes.module.executor.controller.admin.funds.purchase.vo.PurchaseRecordPageReqVO;
import com.cf.imes.module.executor.controller.admin.funds.purchase.vo.PurchaseRecordRespVO;
import com.cf.imes.module.executor.service.funds.purchase.PurchaseService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.Valid;
import java.io.IOException;
import java.util.List;
import static com.cf.imes.framework.common.pojo.CommonResult.success;
import static com.cf.imes.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
/**
* @author 软件购买
*/
@Tag(name = "管理后台 - 软件购买")
@RestController
@RequestMapping("/executor/purchase")
@Validated
public class PurchaseController {
@Resource
private PurchaseService purchaseService;
@GetMapping("")
@Operation(summary = "获取软件的购买记录")
public CommonResult<PageResult<PurchaseRecordRespVO>> getPurchaseRecord(@Valid PurchaseRecordPageReqVO pageReqVO) {
return success(purchaseService.getPurchaseRecord(pageReqVO));
}
@GetMapping("/export")
@Operation(summary = "导出软件购买记录")
@OperateLog(type = EXPORT)
public void billDetailsExport(@Valid PurchaseRecordPageReqVO pageReqVO,
HttpServletResponse response) throws IOException {
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
List<PurchaseRecordRespVO> list = purchaseService.getPurchaseRecord(pageReqVO).getList();
// 导出 Excel
ExcelUtils.write(response, "软件购买记录表.xls", "数据", PurchaseRecordRespVO.class, list);
}
}
@@ -1,45 +0,0 @@
package com.cf.imes.module.executor.controller.admin.funds.purchase.vo;
import com.cf.imes.framework.common.pojo.PageParam;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import static com.cf.imes.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "管理后台 - 组织购买记录明细 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@Builder
public class PurchaseRecordPageReqVO extends PageParam {
@Schema(description = "组织ID")
private Long organId;
@Schema(description = "产品名称")
private String productName;
@Schema(description = "购买月数")
private Integer purchaseMonths;
@Schema(description = "购买时间", example = "[2022-07-01 01:01:01 ,2022-07-01 01:01:01]")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
@Schema(description = "操作人")
private String creator;
}
@@ -1,87 +0,0 @@
package com.cf.imes.module.executor.controller.admin.funds.purchase.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDateTime;
@Data
public class PurchaseRecordRespVO {
@Schema(description = "购买记录ID")
private Long id;
@Schema(description = "组织ID")
private Long organId;
@Schema(description = "产品ID")
private Long productId;
@Schema(description = "产品明细ID")
private Long productDetailsId;
@Schema(description = "产品名称")
private String productName;
@Schema(description = "购买月数")
private Integer purchaseMonths;
@Schema(description = "赠送月数")
private Integer giftMonths;
@Schema(description = "支付方式")
private Integer paymentMethod;
@Schema(description = "订单总额")
private BigDecimal totalAmount;
@Schema(description = "现金余额支出")
private BigDecimal accountBalanceSpent;
@Schema(description = "支付宝支出")
private BigDecimal alipaySpent;
@Schema(description = "微信支出")
private BigDecimal wechatSpent;
@Schema(description = "赠送金")
private BigDecimal giftMoneySpent;
@Schema(description = "货币类型")
private Integer currency;
@Schema(description = "货币单位")
private String currencyUnit;
@Schema(description = "是否开票")
private Integer isInvocing;
@Schema(description = "购买时间")
private LocalDateTime createTime;
@Schema(description = "操作人")
private String creator;
}
@@ -1,120 +0,0 @@
package com.cf.imes.module.executor.dal.dataobject.funds.balancedetails;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.cf.imes.framework.mybatis.core.dataobject.BaseDO;
import lombok.*;
import java.math.BigDecimal;
/**
* @author 收支明细表
*/
@TableName("income_expense_details")
@KeySequence("income_expense_details_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class IncomeExpenseDetailsDO extends BaseDO {
/**
* 主键
*/
@TableId
private Long id;
/**
* 流水号
*/
private String businessNo;
/**
* 组织ID
*/
private Long organId;
/**
* 充值-赠送金规则表
*/
private Long giftMoneyId;
/**
* 购买-购买记录id
*/
private Long purchaseId;
/**
* 用户ID
*/
private Long userId;
/**
* 交易类型
*/
private Integer tradeType;
/**
* 收支类型
*/
private Integer incomeExpenseType;
/**
* 支出/入账现金金额
*/
private BigDecimal cashAmountChange;
/**
* 支出/入账赠送金金额
*/
private BigDecimal bonusAmountChange;
/**
* 可用余额
*/
private BigDecimal availableAmount;
/**
* 现金金额
*/
private BigDecimal amount;
/**
* 赠送金额
*/
private BigDecimal giftAmount;
/**
* 货币类型
*/
private Integer currency;
/**
* 货币单位
*/
private String currencyUnit;
}
@@ -1,117 +0,0 @@
package com.cf.imes.module.executor.dal.dataobject.funds.invoice;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.cf.imes.framework.mybatis.core.dataobject.BaseDO;
import lombok.*;
import java.math.BigDecimal;
import java.time.LocalDateTime;
/**
* @author 开票记录表
*/
@TableName("invoice_records")
@KeySequence("invoice_records_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class InvoiceRecordsDO extends BaseDO {
/**
* 主键
*/
@TableId
private Long id;
/**
* 组织ID
*/
private Long organId;
/**
* 组织/发票抬头名称
*/
private String organName;
/**
* 用户ID-发票申请人ID
*/
private Long userId;
/**
* 发票号
*/
private String invoiceNo;
/**
* 购买记录单号
*/
private String purchaseIds;
/**
* 发票金额
*/
private BigDecimal invoiceAmount;
/**
* 发票状态,1待开票 2已开票 3开票失败
*/
private Integer status;
/**
* 发票附件保存路径
*/
private String invoiceAttachmentPath;
/**
* 开票人
*/
private String invoicePerson;
/**
* 开票人用户ID
*/
private Long invoicePersonId;
/**
* 开票时间
*/
private LocalDateTime invoiceTime;
/**
* 抬头ID
*/
private Long invoiceTitleId;
/**
* 抬头
*/
private String invoiceTitleInfo;
/**
* 备注
*/
private String remark;
}
@@ -1,153 +0,0 @@
package com.cf.imes.module.executor.dal.dataobject.funds.purchase;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.cf.imes.framework.mybatis.core.dataobject.BaseDO;
import lombok.*;
import java.math.BigDecimal;
import java.time.LocalDateTime;
/**
* @author 购买记录表
*/
@TableName("purchase_record")
@KeySequence("purchase_record_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class PurchaseRecordDO extends BaseDO {
/**
* 主键
*/
@TableId
private Long id;
/**
* 组织ID
*/
private Long organId;
/**
* 用户ID-发票申请人ID
*/
private Long userId;
/**
* 用户姓名
*/
private Long userName;
/**
* 产品ID
*/
private Long productId;
/**
* 产品明细ID
*/
private Long productDetailsId;
/**
* 产品名称
*/
private String productName;
/**
* 购买月数
*/
private Integer purchaseMonths;
/**
* 赠送月数
*/
private Integer giftMonths;
/**
* 产品开始时间
*/
private LocalDateTime startTime;
/**
* 产品结束时间
*/
private LocalDateTime endTime;
/**
* 支付方式
*/
private Integer paymentMethod;
/**
* 订单总额
*/
private BigDecimal totalAmount;
/**
* 现金余额支出
*/
private BigDecimal accountBalanceSpent;
/**
* 支付宝支出
*/
private BigDecimal alipaySpent;
/**
* 微信支出
*/
private BigDecimal wechatSpent;
/**
* 赠送金
*/
private BigDecimal giftMoneySpent;
/**
* 货币类型
*/
private Integer currency;
/**
* 货币单位
*/
private String currencyUnit;
/**
* 是否开票
*/
private Integer isInvocing;
}
@@ -1,39 +0,0 @@
package com.cf.imes.module.executor.dal.mysql.funds.balancedetails;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.cf.imes.framework.common.pojo.PageResult;
import com.cf.imes.framework.mybatis.core.mapper.BaseMapperX;
import com.cf.imes.framework.mybatis.core.query.LambdaQueryWrapperX;
import com.cf.imes.module.executor.controller.admin.funds.balancedetails.vo.BalanceDetailsPageReqVO;
import com.cf.imes.module.executor.controller.admin.funds.invoice.vo.InvoiceDetailsRespVO;
import com.cf.imes.module.executor.dal.dataobject.funds.balancedetails.IncomeExpenseDetailsDO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@Mapper
public interface IncomeExpenseDetailsMapper extends BaseMapperX<IncomeExpenseDetailsDO> {
default PageResult<IncomeExpenseDetailsDO> selectDetailsPage(BalanceDetailsPageReqVO pageReqVO,List<Long> organIds) {
return selectPage(pageReqVO, new LambdaQueryWrapperX<IncomeExpenseDetailsDO>()
.eqIfPresent(IncomeExpenseDetailsDO::getOrganId, pageReqVO.getOrganId())
.inIfPresent(IncomeExpenseDetailsDO::getOrganId,organIds)
.eq(IncomeExpenseDetailsDO::getDeleted, false)
.likeIfPresent(IncomeExpenseDetailsDO::getId,pageReqVO.getId() == null ? "" : String.valueOf(pageReqVO.getId()))
.eqIfPresent(IncomeExpenseDetailsDO::getTradeType,pageReqVO.getTradeType())
.eqIfPresent(IncomeExpenseDetailsDO::getIncomeExpenseType,pageReqVO.getIncomeExpenseType())
.betweenIfPresent(IncomeExpenseDetailsDO::getCreateTime,pageReqVO.getCreateTime()));
}
IPage<InvoiceDetailsRespVO> selectOrganInvoicable(@Param("page") IPage page, @Param(Constants.WRAPPER) Wrapper<IncomeExpenseDetailsDO> wrapper);
}
@@ -1,37 +0,0 @@
package com.cf.imes.module.executor.dal.mysql.funds.invoice;
import com.cf.imes.framework.common.pojo.PageResult;
import com.cf.imes.framework.mybatis.core.mapper.BaseMapperX;
import com.cf.imes.framework.mybatis.core.query.LambdaQueryWrapperX;
import com.cf.imes.module.executor.controller.admin.funds.invoice.vo.InvoiceDetailsPageReqVO;
import com.cf.imes.module.executor.dal.dataobject.funds.invoice.InvoiceRecordsDO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.math.BigDecimal;
@Mapper
public interface InvoiceRecordsMapper extends BaseMapperX<InvoiceRecordsDO> {
default PageResult<InvoiceRecordsDO> selectInvoiceRecordsPage(InvoiceDetailsPageReqVO pageReqVO) {
return selectPage(pageReqVO, new LambdaQueryWrapperX<InvoiceRecordsDO>()
.eq(InvoiceRecordsDO::getDeleted,false)
.eqIfPresent(InvoiceRecordsDO::getOrganId,pageReqVO.getOrganId())
.likeIfPresent(InvoiceRecordsDO::getInvoiceNo,pageReqVO.getInvoiceNo())
.eqIfPresent(InvoiceRecordsDO::getStatus,pageReqVO.getStatus())
.likeIfPresent(InvoiceRecordsDO::getCreator,pageReqVO.getCreator())
.likeIfPresent(InvoiceRecordsDO::getInvoicePerson,pageReqVO.getInvoicePerson())
.betweenIfPresent(InvoiceRecordsDO::getInvoiceAmount,pageReqVO.getInvoiceAmount())
.betweenIfPresent(InvoiceRecordsDO::getCreateTime,pageReqVO.getCreateTime())
.betweenIfPresent(InvoiceRecordsDO::getInvoiceTime,pageReqVO.getInvoiceTime()));
}
BigDecimal selectToExamineAmount(@Param("status") Integer status);
}
@@ -1,37 +0,0 @@
package com.cf.imes.module.executor.dal.mysql.funds.purchase;
import com.cf.imes.framework.common.pojo.PageResult;
import com.cf.imes.framework.mybatis.core.mapper.BaseMapperX;
import com.cf.imes.framework.mybatis.core.query.LambdaQueryWrapperX;
import com.cf.imes.module.executor.controller.admin.funds.invoice.vo.InvoiceAmountRespVO;
import com.cf.imes.module.executor.controller.admin.funds.invoice.vo.InvoicePurchaseRecord;
import com.cf.imes.module.executor.controller.admin.funds.purchase.vo.PurchaseRecordPageReqVO;
import com.cf.imes.module.executor.dal.dataobject.funds.purchase.PurchaseRecordDO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@Mapper
public interface PurchaseRecordMapper extends BaseMapperX<PurchaseRecordDO> {
InvoiceAmountRespVO selectOrganInvoice(@Param("organId") Long organId);
default PageResult<PurchaseRecordDO> selectPage(PurchaseRecordPageReqVO pageReqVO) {
return selectPage(pageReqVO, new LambdaQueryWrapperX<PurchaseRecordDO>()
.eq(PurchaseRecordDO::getDeleted,false)
.eqIfPresent(PurchaseRecordDO::getOrganId,pageReqVO.getOrganId())
.likeIfPresent(PurchaseRecordDO::getProductName,pageReqVO.getProductName())
.eqIfPresent(PurchaseRecordDO::getPurchaseMonths,pageReqVO.getPurchaseMonths())
.betweenIfPresent(PurchaseRecordDO::getCreateTime,pageReqVO.getCreateTime())
.likeIfPresent(PurchaseRecordDO::getCreator,pageReqVO.getCreator()));
}
List<InvoicePurchaseRecord> selectPurchaseRecord(@Param("purchaseIdList") List<Long> purchaseIdList, @Param("organId") Long organId);
}
@@ -5,7 +5,6 @@ import com.cf.imes.module.system.api.application.ApplicationApi;
import com.cf.imes.module.system.api.customplateno.CustomPlateNoSeqApi;
import com.cf.imes.module.system.api.dataSource.DataSourceApi;
import com.cf.imes.module.system.api.dict.DictDataApi;
import com.cf.imes.module.system.api.funds.SystemFundsApi;
import com.cf.imes.module.system.api.machine.MachineApi;
import com.cf.imes.module.system.api.organ.OrganApi;
import com.cf.imes.module.system.api.permission.PermissionApi;
@@ -23,6 +22,6 @@ import org.springframework.context.annotation.Configuration;
@Configuration(proxyBeanMethods = false)
@EnableFeignClients(clients = {AdminUserApi.class, MachineApi.class, DictDataApi.class,
FileApi.class, ProcessGroupApi.class, FileApi.class, DataSourceApi.class, ApplicationApi.class,
ProcessApi.class, OrganApi.class, SystemConfigApi.class, CustomPlateNoSeqApi.class, PermissionApi.class, SettingApi.class, SystemFundsApi.class})
ProcessApi.class, OrganApi.class, SystemConfigApi.class, CustomPlateNoSeqApi.class, PermissionApi.class, SettingApi.class})
public class RpcConfiguration {
}
@@ -1,17 +0,0 @@
package com.cf.imes.module.executor.service.funds.balancedetails;
import com.cf.imes.framework.common.pojo.PageResult;
import com.cf.imes.module.executor.controller.admin.funds.balancedetails.vo.BalanceDetailsPageReqVO;
import com.cf.imes.module.executor.controller.admin.funds.balancedetails.vo.BalanceDetailsRespVO;
/**
* @author 组织余额明细接口
*/
public interface BalanceDetailsService {
PageResult<BalanceDetailsRespVO> getBalanceDetailsPage(BalanceDetailsPageReqVO pageReqVO);
}
@@ -1,57 +0,0 @@
package com.cf.imes.module.executor.service.funds.balancedetails;
import cn.hutool.core.collection.CollUtil;
import com.cf.imes.framework.common.pojo.PageResult;
import com.cf.imes.framework.common.util.object.BeanUtils;
import com.cf.imes.module.executor.controller.admin.funds.balancedetails.vo.BalanceDetailsPageReqVO;
import com.cf.imes.module.executor.controller.admin.funds.balancedetails.vo.BalanceDetailsRespVO;
import com.cf.imes.module.executor.dal.dataobject.funds.balancedetails.IncomeExpenseDetailsDO;
import com.cf.imes.module.executor.dal.mysql.funds.balancedetails.IncomeExpenseDetailsMapper;
import com.cf.imes.module.executor.enums.amount.IncomeExpenseTypeEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import jakarta.annotation.Resource;
/**
* @author 组织余额明细接口 实现类
*/
@Slf4j
@Service
public class BalanceDetailsServiceImpl implements BalanceDetailsService{
@Resource
private IncomeExpenseDetailsMapper incomeExpenseDetailsMapper;
@Override
public PageResult<BalanceDetailsRespVO> getBalanceDetailsPage(BalanceDetailsPageReqVO pageReqVO) {
PageResult<IncomeExpenseDetailsDO> pageResult = incomeExpenseDetailsMapper.selectDetailsPage(pageReqVO,null);
if(CollUtil.isNotEmpty(pageResult.getList())){
return new PageResult<>();
}
PageResult<BalanceDetailsRespVO> result = BeanUtils.toBean(pageResult, BalanceDetailsRespVO.class);
result.getList().forEach(f->{
if(f.getIncomeExpenseType().equals(IncomeExpenseTypeEnum.INCOME.getType())){
f.setEntryAmount(f.getCashAmountChange());
f.setEntryGiftAmount(f.getBonusAmountChange());
}else {
f.setExpensesAmount(f.getCashAmountChange());
f.setExpensesGiftAmount(f.getBonusAmountChange());
}
});
return result;
}
}
@@ -1,17 +0,0 @@
package com.cf.imes.module.executor.service.funds.bill;
import com.cf.imes.framework.common.pojo.PageResult;
import com.cf.imes.module.executor.controller.admin.funds.balancedetails.vo.BalanceDetailsPageReqVO;
import com.cf.imes.module.executor.controller.admin.funds.bill.vo.BillDetailsRespVO;
/**
* @author 账单/总额明细 接口
*/
public interface BillService {
PageResult<BillDetailsRespVO> getBillDetailsPage(BalanceDetailsPageReqVO pageReqVO);
}
@@ -1,70 +0,0 @@
package com.cf.imes.module.executor.service.funds.bill;
import cn.hutool.core.collection.CollUtil;
import com.cf.imes.framework.common.pojo.PageResult;
import com.cf.imes.framework.common.util.object.BeanUtils;
import com.cf.imes.module.executor.controller.admin.funds.balancedetails.vo.BalanceDetailsPageReqVO;
import com.cf.imes.module.executor.controller.admin.funds.bill.vo.BillDetailsRespVO;
import com.cf.imes.module.executor.dal.dataobject.funds.balancedetails.IncomeExpenseDetailsDO;
import com.cf.imes.module.executor.dal.mysql.funds.balancedetails.IncomeExpenseDetailsMapper;
import com.cf.imes.module.executor.enums.amount.IncomeExpenseTypeEnum;
import com.cf.imes.module.executor.enums.amount.TradeTypeEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import jakarta.annotation.Resource;
/**
* @author 账单/总额明细接口 实现类
*/
@Slf4j
@Service
public class BillServiceImpl implements BillService{
@Resource
private IncomeExpenseDetailsMapper incomeExpenseDetailsMapper;
@Override
public PageResult<BillDetailsRespVO> getBillDetailsPage(BalanceDetailsPageReqVO pageReqVO) {
PageResult<IncomeExpenseDetailsDO> pageResult = incomeExpenseDetailsMapper.selectDetailsPage(pageReqVO,null);
if(CollUtil.isNotEmpty(pageResult.getList())){
return new PageResult<>();
}
PageResult<BillDetailsRespVO> result = BeanUtils.toBean(pageResult, BillDetailsRespVO.class);
result.getList().forEach(f->{
// 收支类型
f.setIncomeExpenseType(IncomeExpenseTypeEnum.EXPENSES.getType());
// 支出账户余额
f.setExpenditureAccountBalance(f.getAvailableAmount());
if(f.getTradeType().equals(TradeTypeEnum.INCOME.getType())){
// 充值金额
f.setRechargeAmount(f.getCashAmountChange());
// 支出现金
f.setCashExpenditure(f.getCashAmountChange());
// 实际支出总费用
f.setActualTotalExpenditure(f.getCashAmountChange());
}else if(f.getTradeType().equals(TradeTypeEnum.EXPENSES.getType())){
// 产品金额
f.setProductAmount(f.getCashAmountChange().add(f.getBonusAmountChange()));
// 支出现金
f.setCashExpenditure(f.getCashAmountChange());
// 实际支出总费用
f.setActualTotalExpenditure(f.getCashAmountChange().add(f.getBonusAmountChange()));
}
});
return result;
}
}
@@ -1,37 +0,0 @@
package com.cf.imes.module.executor.service.funds.invoice;
import com.cf.imes.framework.common.pojo.PageResult;
import com.cf.imes.module.executor.controller.admin.funds.invoice.vo.*;
import org.springframework.web.multipart.MultipartFile;
import jakarta.servlet.http.HttpServletResponse;
/**
* @author 发票管理接口
*/
public interface InvoiceService {
InvoiceAmountRespVO getInvoiceAmount(Long organId);
PageResult<InvoiceDetailsRespVO> getInvoiceDetails(InvoiceDetailsPageReqVO pageReqVO);
PageResult<InvoiceRecordsRespVO> getInvoiceRecords(InvoiceDetailsPageReqVO pageReqVO);
void insetInvoiceRecords(InvoiceRecordsReqVO reqVO);
InvoiceDetailsRespVO getInvoiceIncome(Long invoiceId);
void invoicing(InvoiceInvoicingReqVO reqVO);
void uploadInvoice(MultipartFile file, Long invoiceId);
void downloadInvoice(Long invoiceId, HttpServletResponse response);
}
@@ -1,412 +0,0 @@
package com.cf.imes.module.executor.service.funds.invoice;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.http.Header;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.PageDTO;
import com.cf.imes.framework.common.exception.ServiceException;
import com.cf.imes.framework.common.pojo.PageResult;
import com.cf.imes.framework.common.util.Assert.AssertUtils;
import com.cf.imes.framework.common.util.date.LocalDateTimeUtils;
import com.cf.imes.framework.common.util.json.JsonUtils;
import com.cf.imes.framework.common.util.object.BeanUtils;
import com.cf.imes.framework.mybatis.core.query.QueryWrapperX;
import com.cf.imes.framework.security.core.LoginUser;
import com.cf.imes.framework.security.core.util.SecurityFrameworkUtils;
import com.cf.imes.module.executor.controller.admin.funds.invoice.vo.*;
import com.cf.imes.module.executor.dal.dataobject.funds.balancedetails.IncomeExpenseDetailsDO;
import com.cf.imes.module.executor.dal.dataobject.funds.invoice.InvoiceRecordsDO;
import com.cf.imes.module.executor.dal.dataobject.funds.purchase.PurchaseRecordDO;
import com.cf.imes.module.executor.dal.mysql.funds.balancedetails.IncomeExpenseDetailsMapper;
import com.cf.imes.module.executor.dal.mysql.funds.invoice.InvoiceRecordsMapper;
import com.cf.imes.module.executor.dal.mysql.funds.purchase.PurchaseRecordMapper;
import com.cf.imes.module.executor.enums.amount.InvoiceStatusEnum;
import com.cf.imes.module.executor.enums.amount.TradeTypeEnum;
import com.cf.imes.module.system.api.funds.SystemFundsApi;
import com.cf.imes.module.system.api.funds.dto.InvoiceTitleInfoDTO;
import com.cf.imes.module.system.api.organ.OrganApi;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse;
import java.io.*;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Stream;
import static com.cf.imes.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.cf.imes.framework.common.util.json.JsonUtils.*;
import static com.cf.imes.framework.security.core.util.SecurityFrameworkUtils.getUserOrganId;
import static com.cf.imes.module.system.enums.ErrorCodeConstants.*;
/**
* @author 发票管理接口 实现类
*/
@Slf4j
@Service
public class InvoiceServiceImpl implements InvoiceService{
@Resource
private PurchaseRecordMapper purchaseRecordMapper;
@Resource
private IncomeExpenseDetailsMapper incomeExpenseDetailsMapper;
@Resource
private InvoiceRecordsMapper invoiceRecordsMapper;
@Resource
private SystemFundsApi systemFundsApi;
@Resource
private OrganApi organApi;
@Resource
private InvoiceFilePath invoiceFilePath;
private static final String UTF8_CHARSET = CharsetUtil.UTF_8;
private static final String ATTACHMENT_PREFIX = "attachment; filename=";
@Override
public InvoiceAmountRespVO getInvoiceAmount(Long organId) {
InvoiceAmountRespVO invoiceAmountRespVO = purchaseRecordMapper.selectOrganInvoice(organId);
BigDecimal invoiceableAmount = systemFundsApi.getOrganAmount(organId).getCheckedData().getInvoiceableAmount();
return invoiceAmountRespVO.setInvocable(invoiceableAmount);
}
@Override
public PageResult<InvoiceDetailsRespVO> getInvoiceDetails(InvoiceDetailsPageReqVO pageReqVO) {
PageDTO<InvoiceDetailsRespVO> page = new PageDTO<>(pageReqVO.getPageNo(), pageReqVO.getPageSize());
List<Integer> invoiceStatus = new ArrayList<>();
invoiceStatus.add(InvoiceStatusEnum.INVOICABLE.getStatus());
invoiceStatus.add(InvoiceStatusEnum.INVOICINGFAILED.getStatus());
QueryWrapperX<IncomeExpenseDetailsDO> queryWrapperX = new QueryWrapperX<>();
pageReqVO.setCreateTime(LocalDateTimeUtils.generateTimeSection(pageReqVO.getCreateTime()));
queryWrapperX
.eq("ied.organId",getUserOrganId())
.eq("ied.deleted",false)
.eq("ied.trade_type", TradeTypeEnum.EXPENSES.getType())
.in("pr.is_invocing", invoiceStatus)
.betweenIfPresent("ied.create_time",pageReqVO.getCreateTime())
.betweenIfPresent("ied.cash_amount_change",pageReqVO.getAmount());
IPage<InvoiceDetailsRespVO> respVOIPage = incomeExpenseDetailsMapper.selectOrganInvoicable(page, queryWrapperX);
List<InvoiceDetailsRespVO> records = respVOIPage.getRecords();
if (CollUtil.isEmpty(records)) {
return new PageResult<>();
}
return new PageResult<>(records, respVOIPage.getTotal());
}
@Override
public PageResult<InvoiceRecordsRespVO> getInvoiceRecords(InvoiceDetailsPageReqVO pageReqVO) {
pageReqVO.setCreateTime(LocalDateTimeUtils.generateTimeSection(pageReqVO.getCreateTime()));
pageReqVO.setInvoiceTime(LocalDateTimeUtils.generateTimeSection(pageReqVO.getInvoiceTime()));
PageResult<InvoiceRecordsDO> pageResult = invoiceRecordsMapper.selectInvoiceRecordsPage(pageReqVO);
List<InvoiceRecordsDO> resultList = pageResult.getList();
if(CollUtil.isEmpty(resultList)){
return new PageResult<>();
}
List<InvoiceRecordsRespVO> recordsRespVOS = BeanUtils.toBean(resultList, InvoiceRecordsRespVO.class);
return new PageResult<>(recordsRespVOS, pageResult.getTotal());
}
@Override
public void insetInvoiceRecords(InvoiceRecordsReqVO reqVO) {
LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
assert loginUser != null;
String organName = organApi.getOrganDetails(loginUser.getOrganId()).getCheckedData().getName();
InvoiceTitleInfoDTO titleInfoDTO = systemFundsApi.getInvoiceTitle(reqVO.getInvoiceTitleId()).getCheckedData();
invoiceRecordsMapper.insert(InvoiceRecordsDO.builder()
.userId(loginUser.getId())
.organName(organName)
.purchaseIds(JsonUtils.toJsonString(reqVO.getPurchaseRecordId()))
.invoiceAmount(reqVO.getInvoiceAmount())
.invoiceTitleId(reqVO.getInvoiceTitleId())
.invoiceTitleInfo(zipString(toJsonString(titleInfoDTO)))
.status(InvoiceStatusEnum.PENDINGINVOICING.getStatus())
.build());
// 更新购买记录表的发票状态
purchaseRecordMapper.update(new LambdaUpdateWrapper<PurchaseRecordDO>()
.eq(PurchaseRecordDO::getOrganId, loginUser.getOrganId())
.eq(PurchaseRecordDO::getDeleted,false)
.in(PurchaseRecordDO::getId,reqVO.getPurchaseRecordId())
.set(PurchaseRecordDO::getIsInvocing, InvoiceStatusEnum.PENDINGINVOICING.getStatus()));
// 减少组织余额的可开票的金额
systemFundsApi.reduceOrganAmount(loginUser.getOrganId(),reqVO.getInvoiceAmount());
}
@Override
public InvoiceDetailsRespVO getInvoiceIncome(Long invoiceId) {
InvoiceRecordsDO invoiceRecordsDO = invoiceRecordsMapper.selectById(invoiceId);
AssertUtils.notEmpty(invoiceRecordsDO,INVOICE_NO_EXIST);
String purchaseIds = Optional.ofNullable(invoiceRecordsDO.getPurchaseIds()).orElse("[]");
List<Long> purchaseIdList = JSON.parseArray(purchaseIds).toJavaList(Long.class).stream().distinct().toList();
List<InvoicePurchaseRecord> invoicePurchaseRecords = purchaseRecordMapper.selectPurchaseRecord(purchaseIdList, getUserOrganId());
InvoiceTitleInfo invoiceTitleInfo = parseObject(unzipString(invoiceRecordsDO.getInvoiceTitleInfo()), InvoiceTitleInfo.class);
return InvoiceDetailsRespVO.builder()
.invoicePurchaseRecords(invoicePurchaseRecords)
.invoiceTitleInfo(invoiceTitleInfo)
.build();
}
@Override
public void invoicing(InvoiceInvoicingReqVO reqVO) {
InvoiceRecordsDO invoiceRecordsDO = validateInvoiceExists(reqVO.getId());
if(invoiceRecordsDO.getStatus().equals(InvoiceStatusEnum.INVOICINGFAILED.getStatus())){
throw exception(THIS_INVOICE_IS_FAIL);
}
// if(invoiceRecordsDO.getStatus().equals(InvoiceStatusEnum.INVOICINGSUCCESSFUL.getStatus())){
// throw exception(THIS_INVOICE_IS_SUCCESS);
// }
String purchaseIds = Optional.ofNullable(invoiceRecordsDO.getPurchaseIds()).orElse("[]");
List<Long> purchaseIdList = JSON.parseArray(purchaseIds).toJavaList(Long.class).stream().distinct().toList();
List<PurchaseRecordDO> purchaseRecordDOS = validatePurchaseRecordExists(purchaseIdList);
if(Boolean.TRUE.equals(reqVO.getIsInvoicing())){
invoiceRecordsDO.setStatus(InvoiceStatusEnum.INVOICINGSUCCESSFUL.getStatus());
invoiceRecordsDO.setRemark(reqVO.getRemark());
purchaseRecordDOS.forEach(f->f.setIsInvocing(InvoiceStatusEnum.INVOICINGSUCCESSFUL.getStatus()));
}else {
// 增加组织余额可开票的金额
systemFundsApi.addOrganAmount(invoiceRecordsDO.getOrganId(),invoiceRecordsDO.getInvoiceAmount());
invoiceRecordsDO.setStatus(InvoiceStatusEnum.INVOICINGFAILED.getStatus());
String remark = Optional.ofNullable(reqVO.getRemark()).orElseThrow(() -> new ServiceException(INVOICING_REJECT_REASON));
invoiceRecordsDO.setRemark(remark);
purchaseRecordDOS.forEach(f->f.setIsInvocing(InvoiceStatusEnum.INVOICABLE.getStatus()));
}
invoiceRecordsDO.setInvoiceAttachmentPath(reqVO.getInvoiceAttachmentPath());
invoiceRecordsDO.setInvoiceNo(reqVO.getInvoiceNo());
invoiceRecordsMapper.updateById(invoiceRecordsDO);
purchaseRecordMapper.updateBatch(purchaseRecordDOS);
}
@Override
public void uploadInvoice(MultipartFile file, Long invoiceId) {
AssertUtils.notEmpty(file,INVOICE_FILE_IS_NULL);
// 生成存储目录
Path invoiceDir = Paths.get(invoiceFilePath.getFilePath(),String.valueOf(invoiceId));
if (!Files.exists(invoiceDir)) {
try {
Files.createDirectories(invoiceDir);
} catch (IOException e) {
log.error("发票附件目录创建失败" + e.getMessage());
throw exception(INVOICE_FILE_UPLOAD_FAILED);
}
}
// 删除旧文件(确保目录中只有一个文件)
try (Stream<Path> files = Files.list(invoiceDir)) {
files.forEach(existingFile -> {
try {
Files.delete(existingFile);
} catch (IOException e) {
log.error("发票附件旧文件删除失败:" + e.getMessage());
}
});
} catch (IOException e) {
log.error("发票附件旧文件删除失败: " + e.getMessage());
throw exception(INVOICE_FILE_UPLOAD_FAILED);
}
// 保存新文件
String fileName = Objects.requireNonNull(file.getOriginalFilename());
Path filePath = invoiceDir.resolve(fileName);
try (InputStream inputStream = file.getInputStream()) {
Files.copy(inputStream, filePath, StandardCopyOption.REPLACE_EXISTING);
} catch (IOException e) {
log.error("发票附件上传失败: " + e.getMessage());
throw exception(INVOICE_FILE_UPLOAD_FAILED);
}
}
@Override
public void downloadInvoice(Long invoiceId, HttpServletResponse response) {
Path invoiceDir = Paths.get(invoiceFilePath.getFilePath(), String.valueOf(invoiceId));
if (!Files.exists(invoiceDir)) {
throw exception(INVOICE_FILE_IS_NULL_NOT_DOWNLOAD);
}
// 获取目录中的文件
File[] files = invoiceDir.toFile().listFiles();
if (files == null || files.length == 0) {
throw exception(INVOICE_FILE_IS_NULL_NOT_DOWNLOAD);
}
// 取第一个文件
File file = files[0];
try (InputStream inputStream = new FileInputStream(file);
OutputStream outputStream = response.getOutputStream()) {
response.setCharacterEncoding(UTF8_CHARSET);
response.setContentType("application/octet-stream; charset=UTF-8");
response.setHeader(Header.CONTENT_DISPOSITION.getValue(), ATTACHMENT_PREFIX + URLEncoder.encode(file.getName(), UTF8_CHARSET));
response.setContentLengthLong(file.length());
byte[] buffer = new byte[8192];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
outputStream.flush();
} catch (IOException e) {
log.error("发票附件下载异常:"+ e.getMessage());
throw exception(INVOICE_FILE_DATA_ERROR);
}
}
private InvoiceRecordsDO validateInvoiceExists(Long invoiceId) {
InvoiceRecordsDO invoiceRecordsDO = invoiceRecordsMapper.selectById(invoiceId);
if (ObjectUtil.isNull(invoiceRecordsDO)) {
throw exception(INVOICE_NO_EXIST);
}
return invoiceRecordsDO;
}
private List<PurchaseRecordDO> validatePurchaseRecordExists(List<Long> purchaseId) {
List<PurchaseRecordDO> purchaseRecordDOS = purchaseRecordMapper.selectBatchIds(purchaseId);
if (ObjectUtil.isNull(purchaseRecordDOS)) {
throw exception(PURCHASE_RECORD_NO_EXIST);
}
return purchaseRecordDOS;
}
}
@@ -1,16 +0,0 @@
package com.cf.imes.module.executor.service.funds.purchase;
import com.cf.imes.framework.common.pojo.PageResult;
import com.cf.imes.module.executor.controller.admin.funds.purchase.vo.PurchaseRecordPageReqVO;
import com.cf.imes.module.executor.controller.admin.funds.purchase.vo.PurchaseRecordRespVO;
/**
* @author 软件购买接口
*/
public interface PurchaseService {
PageResult<PurchaseRecordRespVO> getPurchaseRecord(PurchaseRecordPageReqVO pageReqVO);
}
@@ -1,53 +0,0 @@
package com.cf.imes.module.executor.service.funds.purchase;
import cn.hutool.core.collection.CollUtil;
import com.cf.imes.framework.common.pojo.PageResult;
import com.cf.imes.framework.common.util.date.LocalDateTimeUtils;
import com.cf.imes.framework.common.util.object.BeanUtils;
import com.cf.imes.module.executor.controller.admin.funds.purchase.vo.PurchaseRecordPageReqVO;
import com.cf.imes.module.executor.controller.admin.funds.purchase.vo.PurchaseRecordRespVO;
import com.cf.imes.module.executor.dal.dataobject.funds.purchase.PurchaseRecordDO;
import com.cf.imes.module.executor.dal.mysql.funds.purchase.PurchaseRecordMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import jakarta.annotation.Resource;
import java.util.List;
/**
* @author 软件购买接口 实现类
*/
@Slf4j
@Service
public class PurchaseServiceImpl implements PurchaseService{
@Resource
private PurchaseRecordMapper purchaseRecordMapper;
@Override
public PageResult<PurchaseRecordRespVO> getPurchaseRecord(PurchaseRecordPageReqVO pageReqVO) {
pageReqVO.setCreateTime(LocalDateTimeUtils.generateTimeSection(pageReqVO.getCreateTime()));
PageResult<PurchaseRecordDO> pageResult = purchaseRecordMapper.selectPage(pageReqVO);
List<PurchaseRecordDO> resultList = pageResult.getList();
if(CollUtil.isEmpty(resultList)){
return new PageResult<>();
}
List<PurchaseRecordRespVO> respVOS = BeanUtils.toBean(resultList, PurchaseRecordRespVO.class);
return new PageResult<>(respVOS, pageResult.getTotal());
}
}
@@ -1,22 +0,0 @@
<?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.cf.imes.module.executor.dal.mysql.funds.balancedetails.IncomeExpenseDetailsMapper">
<select id="selectOrganInvoicable"
resultType="com.cf.imes.module.executor.controller.admin.funds.invoice.vo.InvoiceDetailsRespVO">
select distinct ied.business_no as businessNo,
ied.trade_type as tradeType,
ied.create_time as createTime,
ied.cash_amount_change as rechargeAmount,
pr.id as purchaseRecordId
from income_expense_details ied
left join purchase_record pr on ied.organId = pr.organId and ied.purchase_id = pr.id
${ew.customSqlSegment}
</select>
</mapper>
@@ -1,17 +0,0 @@
<?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.cf.imes.module.executor.dal.mysql.funds.invoice.InvoiceRecordsMapper">
<select id="selectToExamineAmount" resultType="java.math.BigDecimal">
select sum(invoice_amount)
from invoice_records
where deleted = false
and status = #{status}
</select>
</mapper>
@@ -1,51 +0,0 @@
<?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.cf.imes.module.executor.dal.mysql.funds.purchase.PurchaseRecordMapper">
<select id="selectOrganInvoice"
resultType="com.cf.imes.module.executor.controller.admin.funds.invoice.vo.InvoiceAmountRespVO">
select
sum(case when is_invocing = 1 then account_balance_spent + alipay_spent + wechat_spent end ) as inTheInvoice,
sum(case when is_invocing = 2 then account_balance_spent + alipay_spent + wechat_spent end ) as invoiced
from purchase_record
where organ_id = #{organId}
and deleted = false
</select>
<select id="selectPurchaseRecord"
resultType="com.cf.imes.module.executor.controller.admin.funds.invoice.vo.InvoicePurchaseRecord">
select distinct pr.id as purchaseRecordId,
pr.create_time as createTime,
pr.product_name as productName,
ied.cash_amount_change as rechargeAmount,
ied.trade_type as tradeType,
ied.business_no as businessNo
from purchase_record pr
join income_expense_details ied on pr.organId = ied.organId and ied.purchase_id = pr.id
where pr.organId = #{organId}
and pr.deleted = false
and pr.id in
<foreach item="purchaseIdList" collection="purchaseIdList" open="(" separator="," close=")">
#{purchaseIdList}
</foreach>
</select>
</mapper>