From 33860a93e73b8b01645e6613919ea369b3e4f9db Mon Sep 17 00:00:00 2001
From: “wangming” <“wangming@antissoft.com”>
Date: Tue, 9 Dec 2025 22:52:16 +0800
Subject: [PATCH] feat: 新增合同管理系统功能
---
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqContract/ContractExpenseStatisticsInput.cs | 41 +++++++++++++++++++++++++++++++++++++++++
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqContract/ContractExpenseStatisticsOutput.cs | 108 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqContract/LqContractCrInput.cs | 108 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqContract/LqContractInfoOutput.cs | 132 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqContract/LqContractListOutput.cs | 126 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqContract/LqContractListQueryInput.cs | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqContract/LqContractRentDetailListOutput.cs | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqContract/LqContractRentDetailMarkPaidInput.cs | 42 ++++++++++++++++++++++++++++++++++++++++++
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqContract/LqContractUpInput.cs | 116 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqInventoryUsage/LqInventoryUsageBatchCreateInput.cs | 23 +++++++++++++++++++++++
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqInventoryUsage/LqInventoryUsageBatchInfoOutput.cs | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqInventoryUsage/StoreReceiveStatisticsInput.cs | 34 ++++++++++++++++++++++++++++++++++
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqInventoryUsageApplication/LqInventoryUsageApplicationApproveInput.cs | 18 ++++++++++++++++++
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqInventoryUsageApplication/LqInventoryUsageApplicationCrInput.cs | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqInventoryUsageApplication/LqInventoryUsageApplicationInfoOutput.cs | 305 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqInventoryUsageApplication/LqInventoryUsageApplicationListOutput.cs | 133 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqInventoryUsageApplication/LqInventoryUsageApplicationListQueryInput.cs | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqInventoryUsageApplication/LqInventoryUsageApplicationReceiveInput.cs | 18 ++++++++++++++++++
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqInventoryUsageApplication/LqInventoryUsageApplicationUpInput.cs | 23 +++++++++++++++++++++++
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqReimbursementApplicationInfoOutput.cs | 2 +-
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqTechTeacherSalary/TechTeacherSalaryInput.cs | 2 ++
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqTechTeacherSalary/TechTeacherSalaryOutput.cs | 2 ++
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Entity/lq_contract/LqContractEntity.cs | 140 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Entity/lq_contract_rent_detail/LqContractRentDetailEntity.cs | 98 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Entity/lq_inventory_usage/LqInventoryUsageEntity.cs | 12 ++++++++++++
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Entity/lq_inventory_usage_application/LqInventoryUsageApplicationEntity.cs | 130 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Entity/lq_inventory_usage_application_node/LqInventoryUsageApplicationNodeEntity.cs | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Entity/lq_inventory_usage_approval_record/LqInventoryUsageApprovalRecordEntity.cs | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
netcore/src/Modularity/Extend/NCC.Extend.Interfaces/LqInventoryUsageApplication/ILqInventoryUsageApplicationService.cs | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
netcore/src/Modularity/Extend/NCC.Extend.Interfaces/LqMdMajorProjectTeacherAssignment/ILqMdMajorProjectTeacherAssignmentService.cs | 5 +++--
netcore/src/Modularity/Extend/NCC.Extend/LqContractService.cs | 1039 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
netcore/src/Modularity/Extend/NCC.Extend/LqInventoryUsageService.cs | 583 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------
netcore/src/Modularity/Extend/NCC.Extend/LqMdMajorProjectTeacherAssignmentService.cs | 2 +-
netcore/src/Modularity/Extend/NCC.Extend/LqReimbursementApplicationService.cs | 8 ++++++++
sql/创建合同管理表结构.sql | 116 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
sql/创建库存使用申请审批流程表.sql | 102 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
sql/库存管理审批功能相关表结构.sql | 202 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
sql/库存管理审批功能表结构.sql | 214 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
合同管理系统-前端调用说明.md | 792 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
合同管理系统-逻辑梳理.md | 230 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
库存使用审批流程-前端调用说明.md | 442 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
41 files changed, 5911 insertions(+), 12 deletions(-)
create mode 100644 netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqContract/ContractExpenseStatisticsInput.cs
create mode 100644 netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqContract/ContractExpenseStatisticsOutput.cs
create mode 100644 netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqContract/LqContractCrInput.cs
create mode 100644 netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqContract/LqContractInfoOutput.cs
create mode 100644 netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqContract/LqContractListOutput.cs
create mode 100644 netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqContract/LqContractListQueryInput.cs
create mode 100644 netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqContract/LqContractRentDetailListOutput.cs
create mode 100644 netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqContract/LqContractRentDetailMarkPaidInput.cs
create mode 100644 netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqContract/LqContractUpInput.cs
create mode 100644 netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqInventoryUsage/StoreReceiveStatisticsInput.cs
create mode 100644 netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqInventoryUsageApplication/LqInventoryUsageApplicationApproveInput.cs
create mode 100644 netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqInventoryUsageApplication/LqInventoryUsageApplicationCrInput.cs
create mode 100644 netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqInventoryUsageApplication/LqInventoryUsageApplicationInfoOutput.cs
create mode 100644 netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqInventoryUsageApplication/LqInventoryUsageApplicationListOutput.cs
create mode 100644 netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqInventoryUsageApplication/LqInventoryUsageApplicationListQueryInput.cs
create mode 100644 netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqInventoryUsageApplication/LqInventoryUsageApplicationReceiveInput.cs
create mode 100644 netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqInventoryUsageApplication/LqInventoryUsageApplicationUpInput.cs
create mode 100644 netcore/src/Modularity/Extend/NCC.Extend.Entitys/Entity/lq_contract/LqContractEntity.cs
create mode 100644 netcore/src/Modularity/Extend/NCC.Extend.Entitys/Entity/lq_contract_rent_detail/LqContractRentDetailEntity.cs
create mode 100644 netcore/src/Modularity/Extend/NCC.Extend.Entitys/Entity/lq_inventory_usage_application/LqInventoryUsageApplicationEntity.cs
create mode 100644 netcore/src/Modularity/Extend/NCC.Extend.Entitys/Entity/lq_inventory_usage_application_node/LqInventoryUsageApplicationNodeEntity.cs
create mode 100644 netcore/src/Modularity/Extend/NCC.Extend.Entitys/Entity/lq_inventory_usage_approval_record/LqInventoryUsageApprovalRecordEntity.cs
create mode 100644 netcore/src/Modularity/Extend/NCC.Extend.Interfaces/LqInventoryUsageApplication/ILqInventoryUsageApplicationService.cs
create mode 100644 netcore/src/Modularity/Extend/NCC.Extend/LqContractService.cs
create mode 100644 sql/创建合同管理表结构.sql
create mode 100644 sql/创建库存使用申请审批流程表.sql
create mode 100644 sql/库存管理审批功能相关表结构.sql
create mode 100644 sql/库存管理审批功能表结构.sql
create mode 100644 合同管理系统-前端调用说明.md
create mode 100644 合同管理系统-逻辑梳理.md
create mode 100644 库存使用审批流程-前端调用说明.md
diff --git a/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqContract/ContractExpenseStatisticsInput.cs b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqContract/ContractExpenseStatisticsInput.cs
new file mode 100644
index 0000000..6a99c1a
--- /dev/null
+++ b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqContract/ContractExpenseStatisticsInput.cs
@@ -0,0 +1,41 @@
+using System;
+using System.ComponentModel.DataAnnotations;
+
+namespace NCC.Extend.Entitys.Dto.LqContract
+{
+ ///
+ /// 合同费用统计输入
+ ///
+ public class ContractExpenseStatisticsInput
+ {
+ ///
+ /// 门店ID(必填)
+ ///
+ [Required(ErrorMessage = "门店ID不能为空")]
+ [Display(Name = "门店ID")]
+ public string StoreId { get; set; }
+
+ ///
+ /// 统计年份(必填)
+ ///
+ [Required(ErrorMessage = "年份不能为空")]
+ [Range(2020, 2100, ErrorMessage = "年份必须在2020-2100之间")]
+ [Display(Name = "年份")]
+ public int Year { get; set; }
+
+ ///
+ /// 统计月份(必填,1-12)
+ ///
+ [Required(ErrorMessage = "月份不能为空")]
+ [Range(1, 12, ErrorMessage = "月份必须在1-12之间")]
+ [Display(Name = "月份")]
+ public int Month { get; set; }
+
+ ///
+ /// 分类列表(可选,不传则统计所有分类)
+ ///
+ [Display(Name = "分类列表")]
+ public string[] Categories { get; set; }
+ }
+}
+
diff --git a/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqContract/ContractExpenseStatisticsOutput.cs b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqContract/ContractExpenseStatisticsOutput.cs
new file mode 100644
index 0000000..9d88c4c
--- /dev/null
+++ b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqContract/ContractExpenseStatisticsOutput.cs
@@ -0,0 +1,108 @@
+using System.Collections.Generic;
+
+namespace NCC.Extend.Entitys.Dto.LqContract
+{
+ ///
+ /// 合同费用统计输出
+ ///
+ public class ContractExpenseStatisticsOutput
+ {
+ ///
+ /// 门店ID
+ ///
+ public string storeId { get; set; }
+
+ ///
+ /// 门店名称
+ ///
+ public string storeName { get; set; }
+
+ ///
+ /// 统计年份
+ ///
+ public int year { get; set; }
+
+ ///
+ /// 统计月份
+ ///
+ public int month { get; set; }
+
+ ///
+ /// 总费用(所有分类的费用总和)
+ ///
+ public decimal totalAmount { get; set; }
+
+ ///
+ /// 按分类统计的费用明细
+ ///
+ public List categoryDetails { get; set; }
+ }
+
+ ///
+ /// 分类费用明细
+ ///
+ public class CategoryExpenseDetail
+ {
+ ///
+ /// 分类名称
+ ///
+ public string category { get; set; }
+
+ ///
+ /// 该分类的费用总额
+ ///
+ public decimal amount { get; set; }
+
+ ///
+ /// 该分类的明细数量
+ ///
+ public int detailCount { get; set; }
+
+ ///
+ /// 明细列表
+ ///
+ public List details { get; set; }
+ }
+
+ ///
+ /// 费用明细项
+ ///
+ public class ExpenseDetailItem
+ {
+ ///
+ /// 明细ID
+ ///
+ public string detailId { get; set; }
+
+ ///
+ /// 合同ID
+ ///
+ public string contractId { get; set; }
+
+ ///
+ /// 合同标题
+ ///
+ public string contractTitle { get; set; }
+
+ ///
+ /// 分类
+ ///
+ public string category { get; set; }
+
+ ///
+ /// 应缴金额
+ ///
+ public decimal dueAmount { get; set; }
+
+ ///
+ /// 是否已缴(0-未缴,1-已缴)
+ ///
+ public int isPaid { get; set; }
+
+ ///
+ /// 实际缴费金额(如果已缴费)
+ ///
+ public decimal? actualPaymentAmount { get; set; }
+ }
+}
+
diff --git a/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqContract/LqContractCrInput.cs b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqContract/LqContractCrInput.cs
new file mode 100644
index 0000000..03c550f
--- /dev/null
+++ b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqContract/LqContractCrInput.cs
@@ -0,0 +1,108 @@
+using System;
+using System.ComponentModel.DataAnnotations;
+
+namespace NCC.Extend.Entitys.Dto.LqContract
+{
+ ///
+ /// 合同创建输入
+ ///
+ public class LqContractCrInput
+ {
+ ///
+ /// 门店ID(关联lq_mdxx.F_Id)
+ ///
+ [Required(ErrorMessage = "门店ID不能为空")]
+ [StringLength(50, ErrorMessage = "门店ID长度不能超过50个字符")]
+ [Display(Name = "门店ID")]
+ public string StoreId { get; set; }
+
+ ///
+ /// 标题
+ ///
+ [Required(ErrorMessage = "标题不能为空")]
+ [StringLength(200, ErrorMessage = "标题长度不能超过200个字符")]
+ [Display(Name = "标题")]
+ public string Title { get; set; }
+
+ ///
+ /// 分类(string类型,自己填写)
+ ///
+ [StringLength(100, ErrorMessage = "分类长度不能超过100个字符")]
+ [Display(Name = "分类")]
+ public string Category { get; set; }
+
+ ///
+ /// 户名
+ ///
+ [StringLength(200, ErrorMessage = "户名长度不能超过200个字符")]
+ [Display(Name = "户名")]
+ public string TenantName { get; set; }
+
+ ///
+ /// 合同起始日期
+ ///
+ [Required(ErrorMessage = "合同起始日期不能为空")]
+ [Display(Name = "合同起始日期")]
+ public DateTime ContractStartDate { get; set; }
+
+ ///
+ /// 合同结束日期
+ ///
+ [Required(ErrorMessage = "合同结束日期不能为空")]
+ [Display(Name = "合同结束日期")]
+ public DateTime ContractEndDate { get; set; }
+
+ ///
+ /// 提前多少天提醒
+ ///
+ [Range(0, 365, ErrorMessage = "提前提醒天数必须在0-365之间")]
+ [Display(Name = "提前提醒天数")]
+ public int ReminderDays { get; set; } = 0;
+
+ ///
+ /// 押金
+ ///
+ [Range(0, double.MaxValue, ErrorMessage = "押金不能小于0")]
+ [Display(Name = "押金")]
+ public decimal Deposit { get; set; } = 0;
+
+ ///
+ /// 月租
+ ///
+ [Required(ErrorMessage = "月租不能为空")]
+ [Range(0, double.MaxValue, ErrorMessage = "月租不能小于0")]
+ [Display(Name = "月租")]
+ public decimal MonthlyRent { get; set; }
+
+ ///
+ /// 缴租金额(每次交租的金额,通常=月租×交租周期)
+ ///
+ [Required(ErrorMessage = "缴租金额不能为空")]
+ [Range(0, double.MaxValue, ErrorMessage = "缴租金额不能小于0")]
+ [Display(Name = "缴租金额")]
+ public decimal PaymentAmount { get; set; }
+
+ ///
+ /// 交租周期(数字,表示几个月,如1、3、6等)
+ ///
+ [Required(ErrorMessage = "交租周期不能为空")]
+ [Range(1, 12, ErrorMessage = "交租周期必须在1-12个月之间")]
+ [Display(Name = "交租周期")]
+ public int PaymentCycle { get; set; }
+
+ ///
+ /// 备注
+ ///
+ [StringLength(1000, ErrorMessage = "备注长度不能超过1000个字符")]
+ [Display(Name = "备注")]
+ public string Remarks { get; set; }
+
+ ///
+ /// 附件(存储附件路径或JSON)
+ ///
+ [StringLength(500, ErrorMessage = "附件长度不能超过500个字符")]
+ [Display(Name = "附件")]
+ public string Attachment { get; set; }
+ }
+}
+
diff --git a/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqContract/LqContractInfoOutput.cs b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqContract/LqContractInfoOutput.cs
new file mode 100644
index 0000000..c142fe9
--- /dev/null
+++ b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqContract/LqContractInfoOutput.cs
@@ -0,0 +1,132 @@
+using System;
+using System.Collections.Generic;
+
+namespace NCC.Extend.Entitys.Dto.LqContract
+{
+ ///
+ /// 合同详情输出
+ ///
+ public class LqContractInfoOutput
+ {
+ ///
+ /// 合同ID
+ ///
+ public string id { get; set; }
+
+ ///
+ /// 门店ID
+ ///
+ public string storeId { get; set; }
+
+ ///
+ /// 店名
+ ///
+ public string storeName { get; set; }
+
+ ///
+ /// 标题
+ ///
+ public string title { get; set; }
+
+ ///
+ /// 分类
+ ///
+ public string category { get; set; }
+
+ ///
+ /// 户名
+ ///
+ public string tenantName { get; set; }
+
+ ///
+ /// 合同起始日期
+ ///
+ public DateTime contractStartDate { get; set; }
+
+ ///
+ /// 合同结束日期
+ ///
+ public DateTime contractEndDate { get; set; }
+
+ ///
+ /// 提前多少天提醒
+ ///
+ public int reminderDays { get; set; }
+
+ ///
+ /// 押金
+ ///
+ public decimal deposit { get; set; }
+
+ ///
+ /// 下次应交时间
+ ///
+ public DateTime? nextPaymentDate { get; set; }
+
+ ///
+ /// 月租
+ ///
+ public decimal monthlyRent { get; set; }
+
+ ///
+ /// 缴租金额
+ ///
+ public decimal paymentAmount { get; set; }
+
+ ///
+ /// 交租周期
+ ///
+ public int paymentCycle { get; set; }
+
+ ///
+ /// 备注
+ ///
+ public string remarks { get; set; }
+
+ ///
+ /// 附件
+ ///
+ public string attachment { get; set; }
+
+ ///
+ /// 创建人ID
+ ///
+ public string createUser { get; set; }
+
+ ///
+ /// 创建人姓名
+ ///
+ public string createUserName { get; set; }
+
+ ///
+ /// 创建时间
+ ///
+ public DateTime createTime { get; set; }
+
+ ///
+ /// 更新人ID
+ ///
+ public string updateUser { get; set; }
+
+ ///
+ /// 更新人姓名
+ ///
+ public string updateUserName { get; set; }
+
+ ///
+ /// 更新时间
+ ///
+ public DateTime? updateTime { get; set; }
+
+ ///
+ /// 是否有效
+ ///
+ public int isEffective { get; set; }
+
+ ///
+ /// 月租明细列表
+ ///
+ public List rentDetails { get; set; }
+ }
+}
+
diff --git a/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqContract/LqContractListOutput.cs b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqContract/LqContractListOutput.cs
new file mode 100644
index 0000000..f078e58
--- /dev/null
+++ b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqContract/LqContractListOutput.cs
@@ -0,0 +1,126 @@
+using System;
+
+namespace NCC.Extend.Entitys.Dto.LqContract
+{
+ ///
+ /// 合同列表输出
+ ///
+ public class LqContractListOutput
+ {
+ ///
+ /// 合同ID
+ ///
+ public string id { get; set; }
+
+ ///
+ /// 门店ID
+ ///
+ public string storeId { get; set; }
+
+ ///
+ /// 店名
+ ///
+ public string storeName { get; set; }
+
+ ///
+ /// 标题
+ ///
+ public string title { get; set; }
+
+ ///
+ /// 分类
+ ///
+ public string category { get; set; }
+
+ ///
+ /// 户名
+ ///
+ public string tenantName { get; set; }
+
+ ///
+ /// 合同起始日期
+ ///
+ public DateTime contractStartDate { get; set; }
+
+ ///
+ /// 合同结束日期
+ ///
+ public DateTime contractEndDate { get; set; }
+
+ ///
+ /// 提前多少天提醒
+ ///
+ public int reminderDays { get; set; }
+
+ ///
+ /// 押金
+ ///
+ public decimal deposit { get; set; }
+
+ ///
+ /// 下次应交时间
+ ///
+ public DateTime? nextPaymentDate { get; set; }
+
+ ///
+ /// 月租
+ ///
+ public decimal monthlyRent { get; set; }
+
+ ///
+ /// 缴租金额
+ ///
+ public decimal paymentAmount { get; set; }
+
+ ///
+ /// 交租周期
+ ///
+ public int paymentCycle { get; set; }
+
+ ///
+ /// 备注
+ ///
+ public string remarks { get; set; }
+
+ ///
+ /// 附件
+ ///
+ public string attachment { get; set; }
+
+ ///
+ /// 创建人ID
+ ///
+ public string createUser { get; set; }
+
+ ///
+ /// 创建人姓名
+ ///
+ public string createUserName { get; set; }
+
+ ///
+ /// 创建时间
+ ///
+ public DateTime createTime { get; set; }
+
+ ///
+ /// 更新人ID
+ ///
+ public string updateUser { get; set; }
+
+ ///
+ /// 更新人姓名
+ ///
+ public string updateUserName { get; set; }
+
+ ///
+ /// 更新时间
+ ///
+ public DateTime? updateTime { get; set; }
+
+ ///
+ /// 是否有效
+ ///
+ public int isEffective { get; set; }
+ }
+}
+
diff --git a/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqContract/LqContractListQueryInput.cs b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqContract/LqContractListQueryInput.cs
new file mode 100644
index 0000000..a559736
--- /dev/null
+++ b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqContract/LqContractListQueryInput.cs
@@ -0,0 +1,67 @@
+using NCC.Common.Filter;
+using System;
+using System.ComponentModel.DataAnnotations;
+
+namespace NCC.Extend.Entitys.Dto.LqContract
+{
+ ///
+ /// 合同列表查询输入
+ ///
+ public class LqContractListQueryInput : PageInputBase
+ {
+ ///
+ /// 门店ID
+ ///
+ [Display(Name = "门店ID", Description = "根据门店ID筛选")]
+ public string StoreId { get; set; }
+
+ ///
+ /// 门店名称(模糊查询)
+ ///
+ [Display(Name = "门店名称", Description = "根据门店名称筛选")]
+ public string StoreName { get; set; }
+
+ ///
+ /// 分类
+ ///
+ [Display(Name = "分类", Description = "根据分类筛选")]
+ public string Category { get; set; }
+
+ ///
+ /// 标题(模糊查询)
+ ///
+ [Display(Name = "标题", Description = "根据标题筛选")]
+ public string Title { get; set; }
+
+ ///
+ /// 合同起始日期(开始)
+ ///
+ [Display(Name = "合同起始日期(开始)", Description = "根据合同起始日期范围筛选")]
+ public DateTime? ContractStartDateBegin { get; set; }
+
+ ///
+ /// 合同起始日期(结束)
+ ///
+ [Display(Name = "合同起始日期(结束)", Description = "根据合同起始日期范围筛选")]
+ public DateTime? ContractStartDateEnd { get; set; }
+
+ ///
+ /// 合同结束日期(开始)
+ ///
+ [Display(Name = "合同结束日期(开始)", Description = "根据合同结束日期范围筛选")]
+ public DateTime? ContractEndDateBegin { get; set; }
+
+ ///
+ /// 合同结束日期(结束)
+ ///
+ [Display(Name = "合同结束日期(结束)", Description = "根据合同结束日期范围筛选")]
+ public DateTime? ContractEndDateEnd { get; set; }
+
+ ///
+ /// 是否有效
+ ///
+ [Display(Name = "是否有效", Description = "根据是否有效筛选")]
+ public int? IsEffective { get; set; }
+ }
+}
+
diff --git a/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqContract/LqContractRentDetailListOutput.cs b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqContract/LqContractRentDetailListOutput.cs
new file mode 100644
index 0000000..aec9644
--- /dev/null
+++ b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqContract/LqContractRentDetailListOutput.cs
@@ -0,0 +1,91 @@
+using System;
+
+namespace NCC.Extend.Entitys.Dto.LqContract
+{
+ ///
+ /// 月租明细列表输出
+ ///
+ public class LqContractRentDetailListOutput
+ {
+ ///
+ /// 明细ID
+ ///
+ public string id { get; set; }
+
+ ///
+ /// 合同ID
+ ///
+ public string contractId { get; set; }
+
+ ///
+ /// 应缴月份(表示哪个月份,格式:YYYY-MM-01)
+ ///
+ public DateTime paymentMonth { get; set; }
+
+ ///
+ /// 应缴日期(具体应缴日期)
+ ///
+ public DateTime dueDate { get; set; }
+
+ ///
+ /// 应缴金额
+ ///
+ public decimal dueAmount { get; set; }
+
+ ///
+ /// 是否已缴(0-未缴,1-已缴)
+ ///
+ public int isPaid { get; set; }
+
+ ///
+ /// 实际缴费时间
+ ///
+ public DateTime? actualPaymentDate { get; set; }
+
+ ///
+ /// 实际缴费金额
+ ///
+ public decimal? actualPaymentAmount { get; set; }
+
+ ///
+ /// 备注
+ ///
+ public string remarks { get; set; }
+
+ ///
+ /// 创建人ID
+ ///
+ public string createUser { get; set; }
+
+ ///
+ /// 创建人姓名
+ ///
+ public string createUserName { get; set; }
+
+ ///
+ /// 创建时间
+ ///
+ public DateTime createTime { get; set; }
+
+ ///
+ /// 更新人ID
+ ///
+ public string updateUser { get; set; }
+
+ ///
+ /// 更新人姓名
+ ///
+ public string updateUserName { get; set; }
+
+ ///
+ /// 更新时间
+ ///
+ public DateTime? updateTime { get; set; }
+
+ ///
+ /// 是否有效
+ ///
+ public int isEffective { get; set; }
+ }
+}
+
diff --git a/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqContract/LqContractRentDetailMarkPaidInput.cs b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqContract/LqContractRentDetailMarkPaidInput.cs
new file mode 100644
index 0000000..bf78c82
--- /dev/null
+++ b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqContract/LqContractRentDetailMarkPaidInput.cs
@@ -0,0 +1,42 @@
+using System;
+using System.ComponentModel.DataAnnotations;
+
+namespace NCC.Extend.Entitys.Dto.LqContract
+{
+ ///
+ /// 月租明细标记已缴费输入
+ ///
+ public class LqContractRentDetailMarkPaidInput
+ {
+ ///
+ /// 明细ID
+ ///
+ [Required(ErrorMessage = "明细ID不能为空")]
+ [StringLength(50, ErrorMessage = "明细ID长度不能超过50个字符")]
+ [Display(Name = "明细ID")]
+ public string Id { get; set; }
+
+ ///
+ /// 实际缴费时间
+ ///
+ [Required(ErrorMessage = "实际缴费时间不能为空")]
+ [Display(Name = "实际缴费时间")]
+ public DateTime ActualPaymentDate { get; set; }
+
+ ///
+ /// 实际缴费金额
+ ///
+ [Required(ErrorMessage = "实际缴费金额不能为空")]
+ [Range(0, double.MaxValue, ErrorMessage = "实际缴费金额不能小于0")]
+ [Display(Name = "实际缴费金额")]
+ public decimal ActualPaymentAmount { get; set; }
+
+ ///
+ /// 备注
+ ///
+ [StringLength(500, ErrorMessage = "备注长度不能超过500个字符")]
+ [Display(Name = "备注")]
+ public string Remarks { get; set; }
+ }
+}
+
diff --git a/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqContract/LqContractUpInput.cs b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqContract/LqContractUpInput.cs
new file mode 100644
index 0000000..41d07f5
--- /dev/null
+++ b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqContract/LqContractUpInput.cs
@@ -0,0 +1,116 @@
+using System;
+using System.ComponentModel.DataAnnotations;
+
+namespace NCC.Extend.Entitys.Dto.LqContract
+{
+ ///
+ /// 合同更新输入
+ ///
+ public class LqContractUpInput
+ {
+ ///
+ /// 合同ID
+ ///
+ [Required(ErrorMessage = "合同ID不能为空")]
+ [StringLength(50, ErrorMessage = "合同ID长度不能超过50个字符")]
+ [Display(Name = "合同ID")]
+ public string Id { get; set; }
+
+ ///
+ /// 门店ID(关联lq_mdxx.F_Id)
+ ///
+ [Required(ErrorMessage = "门店ID不能为空")]
+ [StringLength(50, ErrorMessage = "门店ID长度不能超过50个字符")]
+ [Display(Name = "门店ID")]
+ public string StoreId { get; set; }
+
+ ///
+ /// 标题
+ ///
+ [Required(ErrorMessage = "标题不能为空")]
+ [StringLength(200, ErrorMessage = "标题长度不能超过200个字符")]
+ [Display(Name = "标题")]
+ public string Title { get; set; }
+
+ ///
+ /// 分类(string类型,自己填写)
+ ///
+ [StringLength(100, ErrorMessage = "分类长度不能超过100个字符")]
+ [Display(Name = "分类")]
+ public string Category { get; set; }
+
+ ///
+ /// 户名
+ ///
+ [StringLength(200, ErrorMessage = "户名长度不能超过200个字符")]
+ [Display(Name = "户名")]
+ public string TenantName { get; set; }
+
+ ///
+ /// 合同起始日期
+ ///
+ [Required(ErrorMessage = "合同起始日期不能为空")]
+ [Display(Name = "合同起始日期")]
+ public DateTime ContractStartDate { get; set; }
+
+ ///
+ /// 合同结束日期
+ ///
+ [Required(ErrorMessage = "合同结束日期不能为空")]
+ [Display(Name = "合同结束日期")]
+ public DateTime ContractEndDate { get; set; }
+
+ ///
+ /// 提前多少天提醒
+ ///
+ [Range(0, 365, ErrorMessage = "提前提醒天数必须在0-365之间")]
+ [Display(Name = "提前提醒天数")]
+ public int ReminderDays { get; set; } = 0;
+
+ ///
+ /// 押金
+ ///
+ [Range(0, double.MaxValue, ErrorMessage = "押金不能小于0")]
+ [Display(Name = "押金")]
+ public decimal Deposit { get; set; } = 0;
+
+ ///
+ /// 月租
+ ///
+ [Required(ErrorMessage = "月租不能为空")]
+ [Range(0, double.MaxValue, ErrorMessage = "月租不能小于0")]
+ [Display(Name = "月租")]
+ public decimal MonthlyRent { get; set; }
+
+ ///
+ /// 缴租金额(每次交租的金额,通常=月租×交租周期)
+ ///
+ [Required(ErrorMessage = "缴租金额不能为空")]
+ [Range(0, double.MaxValue, ErrorMessage = "缴租金额不能小于0")]
+ [Display(Name = "缴租金额")]
+ public decimal PaymentAmount { get; set; }
+
+ ///
+ /// 交租周期(数字,表示几个月,如1、3、6等)
+ ///
+ [Required(ErrorMessage = "交租周期不能为空")]
+ [Range(1, 12, ErrorMessage = "交租周期必须在1-12个月之间")]
+ [Display(Name = "交租周期")]
+ public int PaymentCycle { get; set; }
+
+ ///
+ /// 备注
+ ///
+ [StringLength(1000, ErrorMessage = "备注长度不能超过1000个字符")]
+ [Display(Name = "备注")]
+ public string Remarks { get; set; }
+
+ ///
+ /// 附件(存储附件路径或JSON)
+ ///
+ [StringLength(500, ErrorMessage = "附件长度不能超过500个字符")]
+ [Display(Name = "附件")]
+ public string Attachment { get; set; }
+ }
+}
+
diff --git a/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqInventoryUsage/LqInventoryUsageBatchCreateInput.cs b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqInventoryUsage/LqInventoryUsageBatchCreateInput.cs
index 7c1b5b6..7891445 100644
--- a/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqInventoryUsage/LqInventoryUsageBatchCreateInput.cs
+++ b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqInventoryUsage/LqInventoryUsageBatchCreateInput.cs
@@ -23,6 +23,29 @@ namespace NCC.Extend.Entitys.Dto.LqInventoryUsage
[StringLength(50, ErrorMessage = "批次ID长度不能超过50个字符")]
[Display(Name = "使用批次ID")]
public string BatchId { get; set; }
+
+ ///
+ /// 审批人ID(财务老师或库管,必填,创建申请记录并提交审批)
+ ///
+ [Required(ErrorMessage = "审批人ID不能为空")]
+ [StringLength(50, ErrorMessage = "审批人ID长度不能超过50个字符")]
+ [Display(Name = "审批人ID")]
+ public string ApproverId { get; set; }
+
+ ///
+ /// 申请门店ID(必填)
+ ///
+ [Required(ErrorMessage = "申请门店ID不能为空")]
+ [StringLength(50, ErrorMessage = "申请门店ID长度不能超过50个字符")]
+ [Display(Name = "申请门店ID")]
+ public string ApplicationStoreId { get; set; }
+
+ ///
+ /// 备注(可选)
+ ///
+ [StringLength(500, ErrorMessage = "备注长度不能超过500个字符")]
+ [Display(Name = "备注")]
+ public string Remarks { get; set; }
}
///
diff --git a/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqInventoryUsage/LqInventoryUsageBatchInfoOutput.cs b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqInventoryUsage/LqInventoryUsageBatchInfoOutput.cs
index b60804e..2a7b101 100644
--- a/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqInventoryUsage/LqInventoryUsageBatchInfoOutput.cs
+++ b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqInventoryUsage/LqInventoryUsageBatchInfoOutput.cs
@@ -57,6 +57,67 @@ namespace NCC.Extend.Entitys.Dto.LqInventoryUsage
/// 使用记录列表
///
public List UsageRecords { get; set; }
+
+ ///
+ /// 申请记录信息(如果有)
+ ///
+ public ApplicationInfo ApplicationInfo { get; set; }
+ }
+
+ ///
+ /// 申请记录信息
+ ///
+ public class ApplicationInfo
+ {
+ ///
+ /// 申请ID
+ ///
+ public string Id { get; set; }
+
+ ///
+ /// 申请人ID
+ ///
+ public string ApplicationUserId { get; set; }
+
+ ///
+ /// 申请人姓名
+ ///
+ public string ApplicationUserName { get; set; }
+
+ ///
+ /// 申请门店ID
+ ///
+ public string ApplicationStoreId { get; set; }
+
+ ///
+ /// 申请时间
+ ///
+ public DateTime ApplicationTime { get; set; }
+
+ ///
+ /// 审批状态
+ ///
+ public string ApprovalStatus { get; set; }
+
+ ///
+ /// 是否已领取
+ ///
+ public int IsReceived { get; set; }
+
+ ///
+ /// 领取时间
+ ///
+ public DateTime? ReceiveTime { get; set; }
+
+ ///
+ /// 领取人ID
+ ///
+ public string ReceiveUser { get; set; }
+
+ ///
+ /// 备注
+ ///
+ public string Remarks { get; set; }
}
}
diff --git a/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqInventoryUsage/StoreReceiveStatisticsInput.cs b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqInventoryUsage/StoreReceiveStatisticsInput.cs
new file mode 100644
index 0000000..dc363eb
--- /dev/null
+++ b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqInventoryUsage/StoreReceiveStatisticsInput.cs
@@ -0,0 +1,34 @@
+using System.ComponentModel.DataAnnotations;
+
+namespace NCC.Extend.Entitys.Dto.LqInventoryUsage
+{
+ ///
+ /// 门店领取统计查询输入
+ ///
+ public class StoreReceiveStatisticsInput
+ {
+ ///
+ /// 统计年份
+ ///
+ [Required(ErrorMessage = "统计年份不能为空")]
+ [Range(2020, 2100, ErrorMessage = "年份必须在2020-2100之间")]
+ [Display(Name = "统计年份")]
+ public int Year { get; set; }
+
+ ///
+ /// 统计月份(1-12)
+ ///
+ [Required(ErrorMessage = "统计月份不能为空")]
+ [Range(1, 12, ErrorMessage = "月份必须在1-12之间")]
+ [Display(Name = "统计月份")]
+ public int Month { get; set; }
+
+ ///
+ /// 门店ID(可选,用于筛选特定门店)
+ ///
+ [StringLength(50, ErrorMessage = "门店ID长度不能超过50个字符")]
+ [Display(Name = "门店ID")]
+ public string StoreId { get; set; }
+ }
+}
+
diff --git a/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqInventoryUsageApplication/LqInventoryUsageApplicationApproveInput.cs b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqInventoryUsageApplication/LqInventoryUsageApplicationApproveInput.cs
new file mode 100644
index 0000000..2b49778
--- /dev/null
+++ b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqInventoryUsageApplication/LqInventoryUsageApplicationApproveInput.cs
@@ -0,0 +1,18 @@
+namespace NCC.Extend.Entitys.Dto.LqInventoryUsageApplication
+{
+ ///
+ /// 库存使用申请审批输入
+ ///
+ public class LqInventoryUsageApplicationApproveInput
+ {
+ ///
+ /// 审批结果(通过/不通过/退回)
+ ///
+ public string result { get; set; }
+
+ ///
+ /// 审批意见
+ ///
+ public string opinion { get; set; }
+ }
+}
diff --git a/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqInventoryUsageApplication/LqInventoryUsageApplicationCrInput.cs b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqInventoryUsageApplication/LqInventoryUsageApplicationCrInput.cs
new file mode 100644
index 0000000..c1307e1
--- /dev/null
+++ b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqInventoryUsageApplication/LqInventoryUsageApplicationCrInput.cs
@@ -0,0 +1,61 @@
+using System.Collections.Generic;
+
+namespace NCC.Extend.Entitys.Dto.LqInventoryUsageApplication
+{
+ ///
+ /// 库存使用申请创建输入
+ ///
+ public class LqInventoryUsageApplicationCrInput
+ {
+ ///
+ /// 使用批次ID(关联lq_inventory_usage.F_UsageBatchId)
+ ///
+ public string usageBatchId { get; set; }
+
+ ///
+ /// 申请门店ID
+ ///
+ public string applicationStoreId { get; set; }
+
+ ///
+ /// 备注
+ ///
+ public string remarks { get; set; }
+
+ ///
+ /// 审批节点配置(单节点,固定为1个节点)
+ ///
+ public ApprovalNodeConfig node { get; set; }
+ }
+
+ ///
+ /// 审批节点配置
+ ///
+ public class ApprovalNodeConfig
+ {
+ ///
+ /// 节点序号(固定为1)
+ ///
+ public int nodeOrder { get; set; } = 1;
+
+ ///
+ /// 节点名称(如:财务审批、库管审批)
+ ///
+ public string nodeName { get; set; }
+
+ ///
+ /// 审批类型(会签/或签,单节点通常使用"或签")
+ ///
+ public string approvalType { get; set; } = "或签";
+
+ ///
+ /// 审批人ID列表
+ ///
+ public List approverIds { get; set; }
+
+ ///
+ /// 审批人姓名列表
+ ///
+ public List approverNames { get; set; }
+ }
+}
diff --git a/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqInventoryUsageApplication/LqInventoryUsageApplicationInfoOutput.cs b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqInventoryUsageApplication/LqInventoryUsageApplicationInfoOutput.cs
new file mode 100644
index 0000000..bfb9679
--- /dev/null
+++ b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqInventoryUsageApplication/LqInventoryUsageApplicationInfoOutput.cs
@@ -0,0 +1,305 @@
+using System;
+using System.Collections.Generic;
+
+namespace NCC.Extend.Entitys.Dto.LqInventoryUsageApplication
+{
+ ///
+ /// 库存使用申请详情输出
+ ///
+ public class LqInventoryUsageApplicationInfoOutput
+ {
+ ///
+ /// 申请编号
+ ///
+ public string id { get; set; }
+
+ ///
+ /// 使用批次ID
+ ///
+ public string usageBatchId { get; set; }
+
+ ///
+ /// 申请人ID
+ ///
+ public string applicationUserId { get; set; }
+
+ ///
+ /// 申请人姓名
+ ///
+ public string applicationUserName { get; set; }
+
+ ///
+ /// 申请门店ID
+ ///
+ public string applicationStoreId { get; set; }
+
+ ///
+ /// 申请门店名称
+ ///
+ public string applicationStoreName { get; set; }
+
+ ///
+ /// 申请时间
+ ///
+ public DateTime applicationTime { get; set; }
+
+ ///
+ /// 节点数量(固定为1)
+ ///
+ public int nodeCount { get; set; }
+
+ ///
+ /// 当前审批节点(0-待审批,1-审批中,2-已完成)
+ ///
+ public int currentNodeOrder { get; set; }
+
+ ///
+ /// 当前节点ID
+ ///
+ public string currentNodeId { get; set; }
+
+ ///
+ /// 审批状态(待审批/审批中/已通过/未通过/已退回)
+ ///
+ public string approvalStatus { get; set; }
+
+ ///
+ /// 是否已领取(1-已领取,0-未领取)
+ ///
+ public int isReceived { get; set; }
+
+ ///
+ /// 领取时间
+ ///
+ public DateTime? receiveTime { get; set; }
+
+ ///
+ /// 领取人ID
+ ///
+ public string receiveUser { get; set; }
+
+ ///
+ /// 领取人姓名
+ ///
+ public string receiveUserName { get; set; }
+
+ ///
+ /// 备注
+ ///
+ public string remarks { get; set; }
+
+ ///
+ /// 创建时间
+ ///
+ public DateTime createTime { get; set; }
+
+ ///
+ /// 创建人ID
+ ///
+ public string createUser { get; set; }
+
+ ///
+ /// 创建人姓名
+ ///
+ public string createUserName { get; set; }
+
+ ///
+ /// 更新时间
+ ///
+ public DateTime? updateTime { get; set; }
+
+ ///
+ /// 更新人ID
+ ///
+ public string updateUser { get; set; }
+
+ ///
+ /// 更新人姓名
+ ///
+ public string updateUserName { get; set; }
+
+ ///
+ /// 是否有效(1-有效,0-无效)
+ ///
+ public int isEffective { get; set; }
+
+ ///
+ /// 审批节点信息
+ ///
+ public ApprovalNodeInfo nodeInfo { get; set; }
+
+ ///
+ /// 审批记录列表
+ ///
+ public List approvalRecords { get; set; }
+
+ ///
+ /// 使用记录列表(该批次的所有使用记录)
+ ///
+ public List usageRecords { get; set; }
+ }
+
+ ///
+ /// 审批节点信息
+ ///
+ public class ApprovalNodeInfo
+ {
+ ///
+ /// 节点ID
+ ///
+ public string nodeId { get; set; }
+
+ ///
+ /// 节点序号
+ ///
+ public int nodeOrder { get; set; }
+
+ ///
+ /// 节点名称
+ ///
+ public string nodeName { get; set; }
+
+ ///
+ /// 审批类型(会签/或签)
+ ///
+ public string approvalType { get; set; }
+
+ ///
+ /// 审批人列表
+ ///
+ public List approvers { get; set; }
+ }
+
+ ///
+ /// 审批人信息
+ ///
+ public class ApproverInfo
+ {
+ ///
+ /// 审批人ID
+ ///
+ public string userId { get; set; }
+
+ ///
+ /// 审批人姓名
+ ///
+ public string userName { get; set; }
+ }
+
+ ///
+ /// 审批记录信息
+ ///
+ public class ApprovalRecordInfo
+ {
+ ///
+ /// 审批记录ID
+ ///
+ public string id { get; set; }
+
+ ///
+ /// 节点ID
+ ///
+ public string nodeId { get; set; }
+
+ ///
+ /// 节点序号
+ ///
+ public int nodeOrder { get; set; }
+
+ ///
+ /// 审批人ID
+ ///
+ public string approverId { get; set; }
+
+ ///
+ /// 审批人姓名
+ ///
+ public string approverName { get; set; }
+
+ ///
+ /// 审批结果(待审批/已通过/未通过/已退回)
+ ///
+ public string approvalResult { get; set; }
+
+ ///
+ /// 审批意见
+ ///
+ public string approvalOpinion { get; set; }
+
+ ///
+ /// 审批时间
+ ///
+ public DateTime? approvalTime { get; set; }
+
+ ///
+ /// 是否当前节点(1-是,0-否)
+ ///
+ public int isCurrentNode { get; set; }
+ }
+
+ ///
+ /// 使用记录信息
+ ///
+ public class UsageRecordInfo
+ {
+ ///
+ /// 使用记录ID
+ ///
+ public string id { get; set; }
+
+ ///
+ /// 产品ID
+ ///
+ public string productId { get; set; }
+
+ ///
+ /// 产品名称
+ ///
+ public string productName { get; set; }
+
+ ///
+ /// 产品类别
+ ///
+ public string productCategory { get; set; }
+
+ ///
+ /// 产品价格
+ ///
+ public decimal productPrice { get; set; }
+
+ ///
+ /// 门店ID
+ ///
+ public string storeId { get; set; }
+
+ ///
+ /// 门店名称
+ ///
+ public string storeName { get; set; }
+
+ ///
+ /// 使用时间
+ ///
+ public DateTime usageTime { get; set; }
+
+ ///
+ /// 使用数量
+ ///
+ public int usageQuantity { get; set; }
+
+ ///
+ /// 单价
+ ///
+ public decimal unitPrice { get; set; }
+
+ ///
+ /// 合计金额
+ ///
+ public decimal totalAmount { get; set; }
+
+ ///
+ /// 关联消耗ID
+ ///
+ public string relatedConsumeId { get; set; }
+ }
+}
diff --git a/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqInventoryUsageApplication/LqInventoryUsageApplicationListOutput.cs b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqInventoryUsageApplication/LqInventoryUsageApplicationListOutput.cs
new file mode 100644
index 0000000..7c8beef
--- /dev/null
+++ b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqInventoryUsageApplication/LqInventoryUsageApplicationListOutput.cs
@@ -0,0 +1,133 @@
+using System;
+using System.Collections.Generic;
+
+namespace NCC.Extend.Entitys.Dto.LqInventoryUsageApplication
+{
+ ///
+ /// 库存使用申请列表输出
+ ///
+ public class LqInventoryUsageApplicationListOutput
+ {
+ ///
+ /// 申请编号
+ ///
+ public string id { get; set; }
+
+ ///
+ /// 使用批次ID
+ ///
+ public string usageBatchId { get; set; }
+
+ ///
+ /// 申请人ID
+ ///
+ public string applicationUserId { get; set; }
+
+ ///
+ /// 申请人姓名
+ ///
+ public string applicationUserName { get; set; }
+
+ ///
+ /// 申请门店ID
+ ///
+ public string applicationStoreId { get; set; }
+
+ ///
+ /// 申请门店名称
+ ///
+ public string applicationStoreName { get; set; }
+
+ ///
+ /// 申请时间
+ ///
+ public DateTime applicationTime { get; set; }
+
+ ///
+ /// 审批状态(待审批/审批中/已通过/未通过/已退回)
+ ///
+ public string approvalStatus { get; set; }
+
+ ///
+ /// 是否已领取(1-已领取,0-未领取)
+ ///
+ public int isReceived { get; set; }
+
+ ///
+ /// 领取时间
+ ///
+ public DateTime? receiveTime { get; set; }
+
+ ///
+ /// 领取人ID
+ ///
+ public string receiveUser { get; set; }
+
+ ///
+ /// 领取人姓名
+ ///
+ public string receiveUserName { get; set; }
+
+ ///
+ /// 备注
+ ///
+ public string remarks { get; set; }
+
+ ///
+ /// 创建时间
+ ///
+ public DateTime createTime { get; set; }
+
+ ///
+ /// 当前审批人信息列表
+ ///
+ public List currentApprovers { get; set; }
+
+ ///
+ /// 使用记录统计信息(批次总数量、总金额等)
+ ///
+ public BatchUsageInfo batchUsageInfo { get; set; }
+ }
+
+ ///
+ /// 当前审批人信息
+ ///
+ public class CurrentApproverInfo
+ {
+ ///
+ /// 审批人ID
+ ///
+ public string approverId { get; set; }
+
+ ///
+ /// 审批人姓名
+ ///
+ public string approverName { get; set; }
+
+ ///
+ /// 审批结果(待审批/已通过/未通过/已退回)
+ ///
+ public string approvalResult { get; set; }
+ }
+
+ ///
+ /// 批次使用统计信息
+ ///
+ public class BatchUsageInfo
+ {
+ ///
+ /// 使用记录总数
+ ///
+ public int totalCount { get; set; }
+
+ ///
+ /// 总使用数量
+ ///
+ public int totalQuantity { get; set; }
+
+ ///
+ /// 总金额
+ ///
+ public decimal totalAmount { get; set; }
+ }
+}
diff --git a/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqInventoryUsageApplication/LqInventoryUsageApplicationListQueryInput.cs b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqInventoryUsageApplication/LqInventoryUsageApplicationListQueryInput.cs
new file mode 100644
index 0000000..482e3d1
--- /dev/null
+++ b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqInventoryUsageApplication/LqInventoryUsageApplicationListQueryInput.cs
@@ -0,0 +1,83 @@
+namespace NCC.Extend.Entitys.Dto.LqInventoryUsageApplication
+{
+ ///
+ /// 库存使用申请列表查询输入
+ ///
+ public class LqInventoryUsageApplicationListQueryInput
+ {
+ ///
+ /// 当前页码
+ ///
+ public int currentPage { get; set; } = 1;
+
+ ///
+ /// 每页数量
+ ///
+ public int pageSize { get; set; } = 20;
+
+ ///
+ /// 排序字段
+ ///
+ public string sidx { get; set; }
+
+ ///
+ /// 排序方式(asc/desc)
+ ///
+ public string sort { get; set; }
+
+ ///
+ /// 关键字搜索
+ ///
+ public string keyword { get; set; }
+
+ ///
+ /// 申请编号
+ ///
+ public string id { get; set; }
+
+ ///
+ /// 使用批次ID
+ ///
+ public string usageBatchId { get; set; }
+
+ ///
+ /// 申请人ID
+ ///
+ public string applicationUserId { get; set; }
+
+ ///
+ /// 申请门店ID
+ ///
+ public string applicationStoreId { get; set; }
+
+ ///
+ /// 审批状态(待审批/审批中/已通过/未通过/已退回)
+ ///
+ public string approvalStatus { get; set; }
+
+ ///
+ /// 是否已领取(1-已领取,0-未领取)
+ ///
+ public int? isReceived { get; set; }
+
+ ///
+ /// 申请时间开始
+ ///
+ public System.DateTime? applicationTimeStart { get; set; }
+
+ ///
+ /// 申请时间结束
+ ///
+ public System.DateTime? applicationTimeEnd { get; set; }
+
+ ///
+ /// 是否有效(1-有效,0-无效)
+ ///
+ public int? isEffective { get; set; }
+
+ ///
+ /// 查询JSON(用于复杂查询条件)
+ ///
+ public string queryJson { get; set; }
+ }
+}
diff --git a/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqInventoryUsageApplication/LqInventoryUsageApplicationReceiveInput.cs b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqInventoryUsageApplication/LqInventoryUsageApplicationReceiveInput.cs
new file mode 100644
index 0000000..df2c06d
--- /dev/null
+++ b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqInventoryUsageApplication/LqInventoryUsageApplicationReceiveInput.cs
@@ -0,0 +1,18 @@
+namespace NCC.Extend.Entitys.Dto.LqInventoryUsageApplication
+{
+ ///
+ /// 库存使用申请领取输入
+ ///
+ public class LqInventoryUsageApplicationReceiveInput
+ {
+ ///
+ /// 是否已领取(1-已领取,0-未领取)
+ ///
+ public int isReceived { get; set; }
+
+ ///
+ /// 备注
+ ///
+ public string remarks { get; set; }
+ }
+}
diff --git a/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqInventoryUsageApplication/LqInventoryUsageApplicationUpInput.cs b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqInventoryUsageApplication/LqInventoryUsageApplicationUpInput.cs
new file mode 100644
index 0000000..5044e15
--- /dev/null
+++ b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqInventoryUsageApplication/LqInventoryUsageApplicationUpInput.cs
@@ -0,0 +1,23 @@
+namespace NCC.Extend.Entitys.Dto.LqInventoryUsageApplication
+{
+ ///
+ /// 库存使用申请更新输入
+ ///
+ public class LqInventoryUsageApplicationUpInput
+ {
+ ///
+ /// 申请编号
+ ///
+ public string id { get; set; }
+
+ ///
+ /// 是否已领取(1-已领取,0-未领取)
+ ///
+ public int? isReceived { get; set; }
+
+ ///
+ /// 备注
+ ///
+ public string remarks { get; set; }
+ }
+}
diff --git a/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqReimbursementApplicationInfoOutput.cs b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqReimbursementApplicationInfoOutput.cs
index cbcda0d..df440ab 100644
--- a/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqReimbursementApplicationInfoOutput.cs
+++ b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqReimbursementApplicationInfoOutput.cs
@@ -27,7 +27,7 @@ namespace NCC.Extend.Entitys.Dto.LqReimbursementApplication
/// 申请门店
///
public string applicationStoreId { get; set; }
-
+
///
/// 申请门店名称
///
diff --git a/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqTechTeacherSalary/TechTeacherSalaryInput.cs b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqTechTeacherSalary/TechTeacherSalaryInput.cs
index 24e8abe..33395db 100644
--- a/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqTechTeacherSalary/TechTeacherSalaryInput.cs
+++ b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqTechTeacherSalary/TechTeacherSalaryInput.cs
@@ -30,3 +30,5 @@ namespace NCC.Extend.Entitys.Dto.LqTechTeacherSalary
}
}
+
+
diff --git a/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqTechTeacherSalary/TechTeacherSalaryOutput.cs b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqTechTeacherSalary/TechTeacherSalaryOutput.cs
index 3e254cd..f3e0765 100644
--- a/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqTechTeacherSalary/TechTeacherSalaryOutput.cs
+++ b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqTechTeacherSalary/TechTeacherSalaryOutput.cs
@@ -319,3 +319,5 @@ namespace NCC.Extend.Entitys.Dto.LqTechTeacherSalary
}
}
+
+
diff --git a/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Entity/lq_contract/LqContractEntity.cs b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Entity/lq_contract/LqContractEntity.cs
new file mode 100644
index 0000000..53d274f
--- /dev/null
+++ b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Entity/lq_contract/LqContractEntity.cs
@@ -0,0 +1,140 @@
+using System;
+using NCC.Common.Const;
+using SqlSugar;
+
+namespace NCC.Extend.Entitys.lq_contract
+{
+ ///
+ /// 合同表
+ ///
+ [SugarTable("lq_contract")]
+ [Tenant(ClaimConst.TENANT_ID)]
+ public class LqContractEntity
+ {
+ ///
+ /// 主键ID
+ ///
+ [SugarColumn(ColumnName = "F_Id", IsPrimaryKey = true)]
+ public string Id { get; set; }
+
+ ///
+ /// 门店ID(关联lq_mdxx.F_Id)
+ ///
+ [SugarColumn(ColumnName = "F_StoreId")]
+ public string StoreId { get; set; }
+
+ ///
+ /// 店名(冗余字段,便于查询)
+ ///
+ [SugarColumn(ColumnName = "F_StoreName")]
+ public string StoreName { get; set; }
+
+ ///
+ /// 标题
+ ///
+ [SugarColumn(ColumnName = "F_Title")]
+ public string Title { get; set; }
+
+ ///
+ /// 分类(string类型,自己填写)
+ ///
+ [SugarColumn(ColumnName = "F_Category")]
+ public string Category { get; set; }
+
+ ///
+ /// 户名
+ ///
+ [SugarColumn(ColumnName = "F_TenantName")]
+ public string TenantName { get; set; }
+
+ ///
+ /// 合同起始日期
+ ///
+ [SugarColumn(ColumnName = "F_ContractStartDate")]
+ public DateTime ContractStartDate { get; set; }
+
+ ///
+ /// 合同结束日期
+ ///
+ [SugarColumn(ColumnName = "F_ContractEndDate")]
+ public DateTime ContractEndDate { get; set; }
+
+ ///
+ /// 提前多少天提醒
+ ///
+ [SugarColumn(ColumnName = "F_ReminderDays")]
+ public int ReminderDays { get; set; } = 0;
+
+ ///
+ /// 押金
+ ///
+ [SugarColumn(ColumnName = "F_Deposit", DecimalDigits = 2)]
+ public decimal Deposit { get; set; } = 0;
+
+ ///
+ /// 下次应交时间
+ ///
+ [SugarColumn(ColumnName = "F_NextPaymentDate")]
+ public DateTime? NextPaymentDate { get; set; }
+
+ ///
+ /// 月租
+ ///
+ [SugarColumn(ColumnName = "F_MonthlyRent", DecimalDigits = 2)]
+ public decimal MonthlyRent { get; set; }
+
+ ///
+ /// 缴租金额(每次交租的金额,通常=月租×交租周期)
+ ///
+ [SugarColumn(ColumnName = "F_PaymentAmount", DecimalDigits = 2)]
+ public decimal PaymentAmount { get; set; }
+
+ ///
+ /// 交租周期(数字,表示几个月,如1、3、6等)
+ ///
+ [SugarColumn(ColumnName = "F_PaymentCycle")]
+ public int PaymentCycle { get; set; }
+
+ ///
+ /// 备注
+ ///
+ [SugarColumn(ColumnName = "F_Remarks")]
+ public string Remarks { get; set; }
+
+ ///
+ /// 附件(存储附件路径或JSON)
+ ///
+ [SugarColumn(ColumnName = "F_Attachment")]
+ public string Attachment { get; set; }
+
+ ///
+ /// 创建人ID
+ ///
+ [SugarColumn(ColumnName = "F_CreateUser")]
+ public string CreateUser { get; set; }
+
+ ///
+ /// 创建时间
+ ///
+ [SugarColumn(ColumnName = "F_CreateTime")]
+ public DateTime CreateTime { get; set; }
+
+ ///
+ /// 更新人ID
+ ///
+ [SugarColumn(ColumnName = "F_UpdateUser")]
+ public string UpdateUser { get; set; }
+
+ ///
+ /// 更新时间
+ ///
+ [SugarColumn(ColumnName = "F_UpdateTime")]
+ public DateTime? UpdateTime { get; set; }
+
+ ///
+ /// 是否有效(1-有效,0-无效)
+ ///
+ [SugarColumn(ColumnName = "F_IsEffective")]
+ public int IsEffective { get; set; } = 1;
+ }
+}
diff --git a/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Entity/lq_contract_rent_detail/LqContractRentDetailEntity.cs b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Entity/lq_contract_rent_detail/LqContractRentDetailEntity.cs
new file mode 100644
index 0000000..9ac6f4f
--- /dev/null
+++ b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Entity/lq_contract_rent_detail/LqContractRentDetailEntity.cs
@@ -0,0 +1,98 @@
+using System;
+using NCC.Common.Const;
+using SqlSugar;
+
+namespace NCC.Extend.Entitys.lq_contract_rent_detail
+{
+ ///
+ /// 月租明细表
+ ///
+ [SugarTable("lq_contract_rent_detail")]
+ [Tenant(ClaimConst.TENANT_ID)]
+ public class LqContractRentDetailEntity
+ {
+ ///
+ /// 主键ID
+ ///
+ [SugarColumn(ColumnName = "F_Id", IsPrimaryKey = true)]
+ public string Id { get; set; }
+
+ ///
+ /// 合同ID(关联lq_contract.F_Id)
+ ///
+ [SugarColumn(ColumnName = "F_ContractId")]
+ public string ContractId { get; set; }
+
+ ///
+ /// 应缴月份(表示哪个月份,格式:YYYY-MM-01)
+ ///
+ [SugarColumn(ColumnName = "F_PaymentMonth")]
+ public DateTime PaymentMonth { get; set; }
+
+ ///
+ /// 应缴日期(具体应缴日期)
+ ///
+ [SugarColumn(ColumnName = "F_DueDate")]
+ public DateTime DueDate { get; set; }
+
+ ///
+ /// 应缴金额
+ ///
+ [SugarColumn(ColumnName = "F_DueAmount", DecimalDigits = 2)]
+ public decimal DueAmount { get; set; }
+
+ ///
+ /// 是否已缴(0-未缴,1-已缴)
+ ///
+ [SugarColumn(ColumnName = "F_IsPaid")]
+ public int IsPaid { get; set; } = 0;
+
+ ///
+ /// 实际缴费时间
+ ///
+ [SugarColumn(ColumnName = "F_ActualPaymentDate")]
+ public DateTime? ActualPaymentDate { get; set; }
+
+ ///
+ /// 实际缴费金额
+ ///
+ [SugarColumn(ColumnName = "F_ActualPaymentAmount", DecimalDigits = 2)]
+ public decimal? ActualPaymentAmount { get; set; }
+
+ ///
+ /// 备注
+ ///
+ [SugarColumn(ColumnName = "F_Remarks")]
+ public string Remarks { get; set; }
+
+ ///
+ /// 创建人ID
+ ///
+ [SugarColumn(ColumnName = "F_CreateUser")]
+ public string CreateUser { get; set; }
+
+ ///
+ /// 创建时间
+ ///
+ [SugarColumn(ColumnName = "F_CreateTime")]
+ public DateTime CreateTime { get; set; }
+
+ ///
+ /// 更新人ID
+ ///
+ [SugarColumn(ColumnName = "F_UpdateUser")]
+ public string UpdateUser { get; set; }
+
+ ///
+ /// 更新时间
+ ///
+ [SugarColumn(ColumnName = "F_UpdateTime")]
+ public DateTime? UpdateTime { get; set; }
+
+ ///
+ /// 是否有效(1-有效,0-无效)
+ ///
+ [SugarColumn(ColumnName = "F_IsEffective")]
+ public int IsEffective { get; set; } = 1;
+ }
+}
diff --git a/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Entity/lq_inventory_usage/LqInventoryUsageEntity.cs b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Entity/lq_inventory_usage/LqInventoryUsageEntity.cs
index 66babf8..d4e6622 100644
--- a/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Entity/lq_inventory_usage/LqInventoryUsageEntity.cs
+++ b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Entity/lq_inventory_usage/LqInventoryUsageEntity.cs
@@ -42,6 +42,18 @@ namespace NCC.Extend.Entitys.lq_inventory_usage
public int UsageQuantity { get; set; }
///
+ /// 单价(从产品表F_Price获取)
+ ///
+ [SugarColumn(ColumnName = "F_UnitPrice")]
+ public decimal UnitPrice { get; set; }
+
+ ///
+ /// 合计金额(单价×数量)
+ ///
+ [SugarColumn(ColumnName = "F_TotalAmount")]
+ public decimal TotalAmount { get; set; }
+
+ ///
/// 关联消耗ID
///
[SugarColumn(ColumnName = "F_RelatedConsumeId")]
diff --git a/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Entity/lq_inventory_usage_application/LqInventoryUsageApplicationEntity.cs b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Entity/lq_inventory_usage_application/LqInventoryUsageApplicationEntity.cs
new file mode 100644
index 0000000..b4fa096
--- /dev/null
+++ b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Entity/lq_inventory_usage_application/LqInventoryUsageApplicationEntity.cs
@@ -0,0 +1,130 @@
+using NCC.Common.Const;
+using SqlSugar;
+using System;
+
+namespace NCC.Extend.Entitys.lq_inventory_usage_application
+{
+ ///
+ /// 库存使用申请表
+ ///
+ [SugarTable("lq_inventory_usage_application")]
+ [Tenant(ClaimConst.TENANT_ID)]
+ public class LqInventoryUsageApplicationEntity
+ {
+ ///
+ /// 申请编号
+ ///
+ [SugarColumn(ColumnName = "F_Id", IsPrimaryKey = true)]
+ public string Id { get; set; }
+
+ ///
+ /// 使用批次ID(关联lq_inventory_usage.F_UsageBatchId)
+ ///
+ [SugarColumn(ColumnName = "F_UsageBatchId")]
+ public string UsageBatchId { get; set; }
+
+ ///
+ /// 申请人ID
+ ///
+ [SugarColumn(ColumnName = "F_ApplicationUserId")]
+ public string ApplicationUserId { get; set; }
+
+ ///
+ /// 申请人姓名
+ ///
+ [SugarColumn(ColumnName = "F_ApplicationUserName")]
+ public string ApplicationUserName { get; set; }
+
+ ///
+ /// 申请门店ID
+ ///
+ [SugarColumn(ColumnName = "F_ApplicationStoreId")]
+ public string ApplicationStoreId { get; set; }
+
+ ///
+ /// 申请时间
+ ///
+ [SugarColumn(ColumnName = "F_ApplicationTime")]
+ public DateTime ApplicationTime { get; set; }
+
+ ///
+ /// 节点数量(固定为1)
+ ///
+ [SugarColumn(ColumnName = "F_NodeCount")]
+ public int NodeCount { get; set; } = 1;
+
+ ///
+ /// 当前审批节点(0-待审批,1-审批中,2-已完成)
+ ///
+ [SugarColumn(ColumnName = "F_CurrentNodeOrder")]
+ public int CurrentNodeOrder { get; set; } = 0;
+
+ ///
+ /// 当前节点ID
+ ///
+ [SugarColumn(ColumnName = "F_CurrentNodeId")]
+ public string CurrentNodeId { get; set; }
+
+ ///
+ /// 审批状态(待审批/审批中/已通过/未通过/已退回)
+ ///
+ [SugarColumn(ColumnName = "F_ApprovalStatus")]
+ public string ApprovalStatus { get; set; } = "待审批";
+
+ ///
+ /// 是否已领取(1-已领取,0-未领取)
+ ///
+ [SugarColumn(ColumnName = "F_IsReceived")]
+ public int IsReceived { get; set; } = 0;
+
+ ///
+ /// 领取时间
+ ///
+ [SugarColumn(ColumnName = "F_ReceiveTime")]
+ public DateTime? ReceiveTime { get; set; }
+
+ ///
+ /// 领取人ID
+ ///
+ [SugarColumn(ColumnName = "F_ReceiveUser")]
+ public string ReceiveUser { get; set; }
+
+ ///
+ /// 备注
+ ///
+ [SugarColumn(ColumnName = "F_Remarks")]
+ public string Remarks { get; set; }
+
+ ///
+ /// 创建时间
+ ///
+ [SugarColumn(ColumnName = "F_CreateTime")]
+ public DateTime CreateTime { get; set; }
+
+ ///
+ /// 创建人ID
+ ///
+ [SugarColumn(ColumnName = "F_CreateUser")]
+ public string CreateUser { get; set; }
+
+ ///
+ /// 更新时间
+ ///
+ [SugarColumn(ColumnName = "F_UpdateTime")]
+ public DateTime? UpdateTime { get; set; }
+
+ ///
+ /// 更新人ID
+ ///
+ [SugarColumn(ColumnName = "F_UpdateUser")]
+ public string UpdateUser { get; set; }
+
+ ///
+ /// 是否有效(1-有效,0-无效)
+ ///
+ [SugarColumn(ColumnName = "F_IsEffective")]
+ public int IsEffective { get; set; } = 1;
+ }
+}
+
+
diff --git a/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Entity/lq_inventory_usage_application_node/LqInventoryUsageApplicationNodeEntity.cs b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Entity/lq_inventory_usage_application_node/LqInventoryUsageApplicationNodeEntity.cs
new file mode 100644
index 0000000..2de8618
--- /dev/null
+++ b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Entity/lq_inventory_usage_application_node/LqInventoryUsageApplicationNodeEntity.cs
@@ -0,0 +1,58 @@
+using NCC.Common.Const;
+using SqlSugar;
+using System;
+
+namespace NCC.Extend.Entitys.lq_inventory_usage_application_node
+{
+ ///
+ /// 库存使用申请节点表(每个申请的节点配置,固定为1个节点)
+ ///
+ [SugarTable("lq_inventory_usage_application_node")]
+ [Tenant(ClaimConst.TENANT_ID)]
+ public class LqInventoryUsageApplicationNodeEntity
+ {
+ ///
+ /// 节点编号
+ ///
+ [SugarColumn(ColumnName = "F_Id", IsPrimaryKey = true)]
+ public string Id { get; set; }
+
+ ///
+ /// 申请ID
+ ///
+ [SugarColumn(ColumnName = "F_ApplicationId")]
+ public string ApplicationId { get; set; }
+
+ ///
+ /// 节点顺序(固定为1)
+ ///
+ [SugarColumn(ColumnName = "F_NodeOrder")]
+ public int NodeOrder { get; set; } = 1;
+
+ ///
+ /// 节点名称
+ ///
+ [SugarColumn(ColumnName = "F_NodeName")]
+ public string NodeName { get; set; } = "审批";
+
+ ///
+ /// 审批类型(会签/或签)
+ ///
+ [SugarColumn(ColumnName = "F_ApprovalType")]
+ public string ApprovalType { get; set; } = "会签";
+
+ ///
+ /// 是否必审(1-必审,0-可选)
+ ///
+ [SugarColumn(ColumnName = "F_IsRequired")]
+ public int IsRequired { get; set; } = 1;
+
+ ///
+ /// 创建时间
+ ///
+ [SugarColumn(ColumnName = "F_CreateTime")]
+ public DateTime CreateTime { get; set; }
+ }
+}
+
+
diff --git a/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Entity/lq_inventory_usage_approval_record/LqInventoryUsageApprovalRecordEntity.cs b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Entity/lq_inventory_usage_approval_record/LqInventoryUsageApprovalRecordEntity.cs
new file mode 100644
index 0000000..5826882
--- /dev/null
+++ b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Entity/lq_inventory_usage_approval_record/LqInventoryUsageApprovalRecordEntity.cs
@@ -0,0 +1,76 @@
+using NCC.Common.Const;
+using SqlSugar;
+using System;
+
+namespace NCC.Extend.Entitys.lq_inventory_usage_approval_record
+{
+ ///
+ /// 库存使用申请审批记录表
+ ///
+ [SugarTable("lq_inventory_usage_approval_record")]
+ [Tenant(ClaimConst.TENANT_ID)]
+ public class LqInventoryUsageApprovalRecordEntity
+ {
+ ///
+ /// 记录编号
+ ///
+ [SugarColumn(ColumnName = "F_Id", IsPrimaryKey = true)]
+ public string Id { get; set; }
+
+ ///
+ /// 申请ID
+ ///
+ [SugarColumn(ColumnName = "F_ApplicationId")]
+ public string ApplicationId { get; set; }
+
+ ///
+ /// 节点编号
+ ///
+ [SugarColumn(ColumnName = "F_NodeId")]
+ public string NodeId { get; set; }
+
+ ///
+ /// 节点顺序(固定为1)
+ ///
+ [SugarColumn(ColumnName = "F_NodeOrder")]
+ public int NodeOrder { get; set; } = 1;
+
+ ///
+ /// 审批人ID
+ ///
+ [SugarColumn(ColumnName = "F_ApproverId")]
+ public string ApproverId { get; set; }
+
+ ///
+ /// 审批人姓名
+ ///
+ [SugarColumn(ColumnName = "F_ApproverName")]
+ public string ApproverName { get; set; }
+
+ ///
+ /// 审批结果(通过/不通过/退回)
+ ///
+ [SugarColumn(ColumnName = "F_ApprovalResult")]
+ public string ApprovalResult { get; set; }
+
+ ///
+ /// 审批意见
+ ///
+ [SugarColumn(ColumnName = "F_ApprovalOpinion")]
+ public string ApprovalOpinion { get; set; }
+
+ ///
+ /// 审批时间
+ ///
+ [SugarColumn(ColumnName = "F_ApprovalTime")]
+ public DateTime ApprovalTime { get; set; }
+
+ ///
+ /// 是否当前节点(1-是,0-否)
+ ///
+ [SugarColumn(ColumnName = "F_IsCurrentNode")]
+ public int IsCurrentNode { get; set; } = 0;
+ }
+}
+
+
diff --git a/netcore/src/Modularity/Extend/NCC.Extend.Interfaces/LqInventoryUsageApplication/ILqInventoryUsageApplicationService.cs b/netcore/src/Modularity/Extend/NCC.Extend.Interfaces/LqInventoryUsageApplication/ILqInventoryUsageApplicationService.cs
new file mode 100644
index 0000000..a744977
--- /dev/null
+++ b/netcore/src/Modularity/Extend/NCC.Extend.Interfaces/LqInventoryUsageApplication/ILqInventoryUsageApplicationService.cs
@@ -0,0 +1,78 @@
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using NCC.Extend.Entitys.Dto.LqInventoryUsageApplication;
+
+namespace NCC.Extend.Interfaces.LqInventoryUsageApplication
+{
+ ///
+ /// 库存使用申请服务接口
+ ///
+ public interface ILqInventoryUsageApplicationService
+ {
+ ///
+ /// 获取库存使用申请列表
+ ///
+ /// 查询参数
+ /// 分页列表
+ Task GetList(LqInventoryUsageApplicationListQueryInput input);
+
+ ///
+ /// 获取库存使用申请详情
+ ///
+ /// 申请编号
+ /// 申请详情
+ Task GetInfo(string id);
+
+ ///
+ /// 创建库存使用申请
+ ///
+ /// 创建参数
+ /// 创建的申请ID
+ Task Create(LqInventoryUsageApplicationCrInput input);
+
+ ///
+ /// 更新库存使用申请
+ ///
+ /// 申请编号
+ /// 更新参数
+ ///
+ Task Update(string id, LqInventoryUsageApplicationUpInput input);
+
+ ///
+ /// 提交审批
+ ///
+ /// 申请编号
+ ///
+ Task SubmitApproval(string id);
+
+ ///
+ /// 审批操作(通过/不通过/退回)
+ ///
+ /// 申请编号
+ /// 审批参数
+ ///
+ Task Approve(string id, LqInventoryUsageApplicationApproveInput input);
+
+ ///
+ /// 领取操作
+ ///
+ /// 申请编号
+ /// 领取参数
+ ///
+ Task Receive(string id, LqInventoryUsageApplicationReceiveInput input);
+
+ ///
+ /// 查询待审批列表
+ ///
+ /// 查询参数
+ /// 分页列表
+ Task PendingApproval(LqInventoryUsageApplicationListQueryInput input);
+
+ ///
+ /// 查询审批历史
+ ///
+ /// 申请编号
+ /// 审批历史记录列表
+ Task ApprovalHistory(string id);
+ }
+}
diff --git a/netcore/src/Modularity/Extend/NCC.Extend.Interfaces/LqMdMajorProjectTeacherAssignment/ILqMdMajorProjectTeacherAssignmentService.cs b/netcore/src/Modularity/Extend/NCC.Extend.Interfaces/LqMdMajorProjectTeacherAssignment/ILqMdMajorProjectTeacherAssignmentService.cs
index 03d3bf7..c42e95d 100644
--- a/netcore/src/Modularity/Extend/NCC.Extend.Interfaces/LqMdMajorProjectTeacherAssignment/ILqMdMajorProjectTeacherAssignmentService.cs
+++ b/netcore/src/Modularity/Extend/NCC.Extend.Interfaces/LqMdMajorProjectTeacherAssignment/ILqMdMajorProjectTeacherAssignmentService.cs
@@ -12,8 +12,9 @@ namespace NCC.Extend.Interfaces.LqMdMajorProjectTeacherAssignment
///
/// 复制上月设置
///
- /// 目标月份(YYYYMM格式),如果为空则复制到当前月份
+ /// 目标年份(YYYY格式),如果为空则复制到当前年份
+ /// 目标月份(MM格式),如果为空则复制到当前月份
///
- Task CopyLastMonthData(string targetMonth = null);
+ Task CopyLastMonthData(string targetYear = null, string targetMonth = null);
}
}
diff --git a/netcore/src/Modularity/Extend/NCC.Extend/LqContractService.cs b/netcore/src/Modularity/Extend/NCC.Extend/LqContractService.cs
new file mode 100644
index 0000000..9a85e27
--- /dev/null
+++ b/netcore/src/Modularity/Extend/NCC.Extend/LqContractService.cs
@@ -0,0 +1,1039 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Logging;
+using NCC.Common.Core.Manager;
+using NCC.Common.Filter;
+using NCC.Dependency;
+using NCC.DynamicApiController;
+using NCC.Extend.Entitys.Dto.LqContract;
+using NCC.Extend.Entitys.Enum;
+using NCC.Extend.Entitys.lq_contract;
+using NCC.Extend.Entitys.lq_contract_rent_detail;
+using NCC.Extend.Entitys.lq_mdxx;
+using NCC.FriendlyException;
+using NCC.System.Entitys.Permission;
+using SqlSugar;
+using Yitter.IdGenerator;
+
+namespace NCC.Extend
+{
+ ///
+ /// 合同管理服务
+ ///
+ [ApiDescriptionSettings(Tag = "绿纤合同管理", Name = "LqContract", Order = 250)]
+ [Route("api/Extend/LqContract")]
+ public class LqContractService : IDynamicApiController, ITransient
+ {
+ private readonly IUserManager _userManager;
+ private readonly ILogger _logger;
+ private readonly ISqlSugarClient _db;
+
+ ///
+ /// 构造函数
+ ///
+ /// 用户管理器
+ /// 日志记录器
+ /// 数据库客户端
+ public LqContractService(IUserManager userManager, ILogger logger, ISqlSugarClient db)
+ {
+ _userManager = userManager;
+ _logger = logger;
+ _db = db;
+ }
+
+ #region 创建合同
+
+ ///
+ /// 创建合同
+ ///
+ ///
+ /// 创建新合同,系统会自动根据合同信息生成月租明细
+ ///
+ /// 示例请求:
+ /// ```json
+ /// {
+ /// "storeId": "门店ID",
+ /// "title": "门店租赁合同",
+ /// "category": "租赁合同",
+ /// "tenantName": "张三",
+ /// "contractStartDate": "2025-01-01T00:00:00",
+ /// "contractEndDate": "2025-12-31T23:59:59",
+ /// "reminderDays": 7,
+ /// "deposit": 5000.00,
+ /// "monthlyRent": 1000.00,
+ /// "paymentAmount": 3000.00,
+ /// "paymentCycle": 3,
+ /// "remarks": "季度交租",
+ /// "attachment": ""
+ /// }
+ /// ```
+ ///
+ /// 业务流程:
+ /// 1. 验证合同信息
+ /// 2. 查询门店信息(获取店名)
+ /// 3. 创建合同记录
+ /// 4. 自动生成月租明细(根据合同起始日期、结束日期、交租周期、缴租金额)
+ /// 5. 计算下次应交时间
+ ///
+ /// 创建输入
+ /// 创建结果
+ /// 创建成功
+ /// 请求参数错误
+ /// 服务器错误
+ [HttpPost("Create")]
+ public async Task CreateAsync([FromBody] LqContractCrInput input)
+ {
+ try
+ {
+ // 验证合同日期
+ if (input.ContractStartDate >= input.ContractEndDate)
+ {
+ throw NCCException.Oh("合同起始日期必须小于合同结束日期");
+ }
+
+ // 验证交租周期
+ if (input.PaymentCycle <= 0 || input.PaymentCycle > 12)
+ {
+ throw NCCException.Oh("交租周期必须在1-12个月之间");
+ }
+
+ // 查询门店信息
+ var store = await _db.Queryable()
+ .Where(x => x.Id == input.StoreId)
+ .Select(x => new { x.Dm })
+ .FirstAsync();
+
+ if (store == null)
+ {
+ throw NCCException.Oh("门店不存在");
+ }
+
+ _db.Ado.BeginTran();
+
+ try
+ {
+ // 创建合同
+ var contractEntity = new LqContractEntity
+ {
+ Id = YitIdHelper.NextId().ToString(),
+ StoreId = input.StoreId,
+ StoreName = store.Dm ?? "",
+ Title = input.Title,
+ Category = input.Category,
+ TenantName = input.TenantName,
+ ContractStartDate = input.ContractStartDate,
+ ContractEndDate = input.ContractEndDate,
+ ReminderDays = input.ReminderDays,
+ Deposit = input.Deposit,
+ MonthlyRent = input.MonthlyRent,
+ PaymentAmount = input.PaymentAmount,
+ PaymentCycle = input.PaymentCycle,
+ Remarks = input.Remarks,
+ Attachment = input.Attachment,
+ CreateUser = _userManager.UserId,
+ CreateTime = DateTime.Now,
+ IsEffective = StatusEnum.有效.GetHashCode()
+ };
+
+ var insertCount = await _db.Insertable(contractEntity).ExecuteCommandAsync();
+ if (insertCount <= 0)
+ {
+ throw NCCException.Oh("创建合同失败");
+ }
+
+ // 自动生成月租明细
+ await GenerateRentDetailsAsync(contractEntity.Id, contractEntity.ContractStartDate, contractEntity.ContractEndDate, contractEntity.PaymentCycle, contractEntity.PaymentAmount);
+
+ // 计算下次应交时间
+ await CalculateNextPaymentDate(contractEntity.Id);
+
+ _db.Ado.CommitTran();
+ }
+ catch
+ {
+ _db.Ado.RollbackTran();
+ throw;
+ }
+ }
+ catch (Exception ex)
+ {
+ _db.Ado.RollbackTran();
+ _logger.LogError(ex, "创建合同失败");
+ throw NCCException.Oh($"创建失败:{ex.Message}");
+ }
+ }
+
+ #endregion
+
+ #region 更新合同
+
+ ///
+ /// 更新合同
+ ///
+ ///
+ /// 更新合同信息。如果修改了合同起始日期、结束日期、交租周期或缴租金额,系统会重新生成月租明细。
+ ///
+ /// 示例请求:
+ /// ```json
+ /// {
+ /// "id": "合同ID",
+ /// "storeId": "门店ID",
+ /// "title": "门店租赁合同",
+ /// "category": "租赁合同",
+ /// "tenantName": "张三",
+ /// "contractStartDate": "2025-01-01T00:00:00",
+ /// "contractEndDate": "2025-12-31T23:59:59",
+ /// "reminderDays": 7,
+ /// "deposit": 5000.00,
+ /// "monthlyRent": 1000.00,
+ /// "paymentAmount": 3000.00,
+ /// "paymentCycle": 3,
+ /// "remarks": "季度交租",
+ /// "attachment": ""
+ /// }
+ /// ```
+ ///
+ /// 更新输入
+ /// 更新结果
+ /// 更新成功
+ /// 请求参数错误或合同不存在
+ /// 服务器错误
+ [HttpPut("Update")]
+ public async Task UpdateAsync([FromBody] LqContractUpInput input)
+ {
+ try
+ {
+ // 查询合同
+ var contract = await _db.Queryable()
+ .Where(x => x.Id == input.Id && x.IsEffective == StatusEnum.有效.GetHashCode())
+ .FirstAsync();
+
+ if (contract == null)
+ {
+ throw NCCException.Oh("合同不存在或已失效");
+ }
+
+ // 验证合同日期
+ if (input.ContractStartDate >= input.ContractEndDate)
+ {
+ throw NCCException.Oh("合同起始日期必须小于合同结束日期");
+ }
+
+ // 验证交租周期
+ if (input.PaymentCycle <= 0 || input.PaymentCycle > 12)
+ {
+ throw NCCException.Oh("交租周期必须在1-12个月之间");
+ }
+
+ // 查询门店信息
+ var store = await _db.Queryable()
+ .Where(x => x.Id == input.StoreId)
+ .Select(x => new { x.Dm })
+ .FirstAsync();
+
+ if (store == null)
+ {
+ throw NCCException.Oh("门店不存在");
+ }
+
+ _db.Ado.BeginTran();
+
+ try
+ {
+ // 判断是否需要重新生成明细
+ bool needRegenerateDetails = contract.ContractStartDate != input.ContractStartDate ||
+ contract.ContractEndDate != input.ContractEndDate ||
+ contract.PaymentCycle != input.PaymentCycle ||
+ contract.PaymentAmount != input.PaymentAmount;
+
+ // 更新合同信息
+ contract.StoreId = input.StoreId;
+ contract.StoreName = store.Dm ?? "";
+ contract.Title = input.Title;
+ contract.Category = input.Category;
+ contract.TenantName = input.TenantName;
+ contract.ContractStartDate = input.ContractStartDate;
+ contract.ContractEndDate = input.ContractEndDate;
+ contract.ReminderDays = input.ReminderDays;
+ contract.Deposit = input.Deposit;
+ contract.MonthlyRent = input.MonthlyRent;
+ contract.PaymentAmount = input.PaymentAmount;
+ contract.PaymentCycle = input.PaymentCycle;
+ contract.Remarks = input.Remarks;
+ contract.Attachment = input.Attachment;
+ contract.UpdateUser = _userManager.UserId;
+ contract.UpdateTime = DateTime.Now;
+
+ var updateCount = await _db.Updateable(contract).ExecuteCommandAsync();
+ if (updateCount <= 0)
+ {
+ throw NCCException.Oh("更新合同失败");
+ }
+
+ // 如果需要重新生成明细,先删除旧明细,再生成新明细
+ if (needRegenerateDetails)
+ {
+ // 删除旧的明细(逻辑删除)
+ await _db.Updateable()
+ .SetColumns(x => new LqContractRentDetailEntity
+ {
+ IsEffective = StatusEnum.无效.GetHashCode(),
+ UpdateUser = _userManager.UserId,
+ UpdateTime = DateTime.Now
+ })
+ .Where(x => x.ContractId == contract.Id && x.IsEffective == StatusEnum.有效.GetHashCode())
+ .ExecuteCommandAsync();
+
+ // 生成新的明细
+ await GenerateRentDetailsAsync(contract.Id, contract.ContractStartDate, contract.ContractEndDate, contract.PaymentCycle, contract.PaymentAmount);
+ }
+
+ // 重新计算下次应交时间
+ await CalculateNextPaymentDate(contract.Id);
+
+ _db.Ado.CommitTran();
+ }
+ catch
+ {
+ _db.Ado.RollbackTran();
+ throw;
+ }
+ }
+ catch (Exception ex)
+ {
+ _db.Ado.RollbackTran();
+ _logger.LogError(ex, "更新合同失败");
+ throw NCCException.Oh($"更新失败:{ex.Message}");
+ }
+ }
+
+ #endregion
+
+ #region 删除合同
+
+ ///
+ /// 删除合同
+ ///
+ ///
+ /// 删除合同,同时会级联删除该合同的所有月租明细(逻辑删除)
+ ///
+ /// 示例请求:
+ /// ```
+ /// DELETE /api/Extend/LqContract/{id}
+ /// ```
+ ///
+ /// 合同ID
+ /// 删除结果
+ /// 删除成功
+ /// 合同不存在
+ /// 服务器错误
+ [HttpDelete("{id}")]
+ public async Task DeleteAsync([FromRoute] string id)
+ {
+ try
+ {
+ if (string.IsNullOrWhiteSpace(id))
+ {
+ throw NCCException.Oh("合同ID不能为空");
+ }
+
+ // 查询合同
+ var contract = await _db.Queryable()
+ .Where(x => x.Id == id && x.IsEffective == StatusEnum.有效.GetHashCode())
+ .FirstAsync();
+
+ if (contract == null)
+ {
+ throw NCCException.Oh("合同不存在或已失效");
+ }
+
+ _db.Ado.BeginTran();
+
+ try
+ {
+ // 删除该合同的所有月租明细(逻辑删除)
+ await _db.Updateable()
+ .SetColumns(x => new LqContractRentDetailEntity
+ {
+ IsEffective = StatusEnum.无效.GetHashCode(),
+ UpdateUser = _userManager.UserId,
+ UpdateTime = DateTime.Now
+ })
+ .Where(x => x.ContractId == id && x.IsEffective == StatusEnum.有效.GetHashCode())
+ .ExecuteCommandAsync();
+
+ // 删除合同(逻辑删除)
+ contract.IsEffective = StatusEnum.无效.GetHashCode();
+ contract.UpdateUser = _userManager.UserId;
+ contract.UpdateTime = DateTime.Now;
+
+ var updateCount = await _db.Updateable(contract).ExecuteCommandAsync();
+ if (updateCount <= 0)
+ {
+ throw NCCException.Oh("删除合同失败");
+ }
+
+ _db.Ado.CommitTran();
+ }
+ catch
+ {
+ _db.Ado.RollbackTran();
+ throw;
+ }
+ }
+ catch (Exception ex)
+ {
+ _db.Ado.RollbackTran();
+ _logger.LogError(ex, "删除合同失败");
+ throw NCCException.Oh($"删除失败:{ex.Message}");
+ }
+ }
+
+ #endregion
+
+ #region 获取合同列表
+
+ ///
+ /// 获取合同列表
+ ///
+ ///
+ /// 分页查询合同列表,支持多条件筛选
+ ///
+ /// 示例请求:
+ /// ```
+ /// GET /api/Extend/LqContract/GetList?currentPage=1&pageSize=10&storeId=门店ID&title=合同标题
+ /// ```
+ ///
+ /// 查询输入
+ /// 合同列表
+ /// 查询成功
+ /// 服务器错误
+ [HttpGet("GetList")]
+ public async Task GetListAsync([FromQuery] LqContractListQueryInput input)
+ {
+ try
+ {
+ var sidx = string.IsNullOrEmpty(input.sidx) ? "createTime" : input.sidx;
+ var sort = string.IsNullOrEmpty(input.sort) ? "desc" : input.sort;
+
+ var data = await _db.Queryable()
+ .WhereIF(!string.IsNullOrWhiteSpace(input.StoreId), x => x.StoreId == input.StoreId)
+ .WhereIF(!string.IsNullOrWhiteSpace(input.StoreName), x => x.StoreName != null && x.StoreName.Contains(input.StoreName))
+ .WhereIF(!string.IsNullOrWhiteSpace(input.Category), x => x.Category == input.Category)
+ .WhereIF(!string.IsNullOrWhiteSpace(input.Title), x => x.Title != null && x.Title.Contains(input.Title))
+ .WhereIF(input.ContractStartDateBegin.HasValue, x => x.ContractStartDate >= input.ContractStartDateBegin.Value)
+ .WhereIF(input.ContractStartDateEnd.HasValue, x => x.ContractStartDate <= input.ContractStartDateEnd.Value)
+ .WhereIF(input.ContractEndDateBegin.HasValue, x => x.ContractEndDate >= input.ContractEndDateBegin.Value)
+ .WhereIF(input.ContractEndDateEnd.HasValue, x => x.ContractEndDate <= input.ContractEndDateEnd.Value)
+ .WhereIF(input.IsEffective.HasValue, x => x.IsEffective == input.IsEffective.Value)
+ .Where(x => x.IsEffective == StatusEnum.有效.GetHashCode())
+ .Select(x => new LqContractListOutput
+ {
+ id = x.Id,
+ storeId = x.StoreId,
+ storeName = x.StoreName,
+ title = x.Title,
+ category = x.Category,
+ tenantName = x.TenantName,
+ contractStartDate = x.ContractStartDate,
+ contractEndDate = x.ContractEndDate,
+ reminderDays = x.ReminderDays,
+ deposit = x.Deposit,
+ nextPaymentDate = x.NextPaymentDate,
+ monthlyRent = x.MonthlyRent,
+ paymentAmount = x.PaymentAmount,
+ paymentCycle = x.PaymentCycle,
+ remarks = x.Remarks,
+ attachment = x.Attachment,
+ createUser = x.CreateUser,
+ createUserName = "",
+ createTime = x.CreateTime,
+ updateUser = x.UpdateUser,
+ updateUserName = "",
+ updateTime = x.UpdateTime,
+ isEffective = x.IsEffective
+ })
+ .MergeTable()
+ .OrderBy(sidx + " " + sort)
+ .ToPagedListAsync(input.currentPage, input.pageSize);
+
+ // 补充用户信息
+ var userIds = data.list.SelectMany(x => new[] { x.createUser, x.updateUser })
+ .Where(x => !string.IsNullOrEmpty(x))
+ .Distinct()
+ .ToList();
+
+ if (userIds.Any())
+ {
+ var userList = await _db.Queryable()
+ .Where(x => userIds.Contains(x.Id))
+ .Select(x => new { x.Id, x.RealName })
+ .ToListAsync();
+ var userDict = userList.ToDictionary(k => k.Id, v => v.RealName);
+
+ foreach (var item in data.list)
+ {
+ if (!string.IsNullOrEmpty(item.createUser) && userDict.ContainsKey(item.createUser))
+ item.createUserName = userDict[item.createUser];
+ if (!string.IsNullOrEmpty(item.updateUser) && userDict.ContainsKey(item.updateUser))
+ item.updateUserName = userDict[item.updateUser];
+ }
+ }
+
+ return PageResult.SqlSugarPageResult(data);
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError(ex, "获取合同列表失败");
+ throw NCCException.Oh($"获取合同列表失败:{ex.Message}");
+ }
+ }
+
+ #endregion
+
+ #region 获取合同详情
+
+ ///
+ /// 获取合同详情
+ ///
+ ///
+ /// 根据合同ID获取合同详细信息,包括月租明细列表
+ ///
+ /// 示例请求:
+ /// ```
+ /// GET /api/Extend/LqContract/GetInfo?id=合同ID
+ /// ```
+ ///
+ /// 合同ID
+ /// 合同详情
+ /// 查询成功
+ /// 合同ID不能为空
+ /// 合同不存在
+ /// 服务器错误
+ [HttpGet("GetInfo")]
+ public async Task GetInfoAsync([FromQuery] string id)
+ {
+ try
+ {
+ if (string.IsNullOrWhiteSpace(id))
+ {
+ throw NCCException.Oh("合同ID不能为空");
+ }
+
+ // 查询合同
+ var contract = await _db.Queryable()
+ .Where(x => x.Id == id && x.IsEffective == StatusEnum.有效.GetHashCode())
+ .FirstAsync();
+
+ if (contract == null)
+ {
+ throw NCCException.Oh("合同不存在或已失效");
+ }
+
+ // 查询月租明细
+ var rentDetails = await _db.Queryable()
+ .Where(x => x.ContractId == id && x.IsEffective == StatusEnum.有效.GetHashCode())
+ .OrderBy(x => x.PaymentMonth)
+ .Select(x => new LqContractRentDetailListOutput
+ {
+ id = x.Id,
+ contractId = x.ContractId,
+ paymentMonth = x.PaymentMonth,
+ dueDate = x.DueDate,
+ dueAmount = x.DueAmount,
+ isPaid = x.IsPaid,
+ actualPaymentDate = x.ActualPaymentDate,
+ actualPaymentAmount = x.ActualPaymentAmount,
+ remarks = x.Remarks,
+ createUser = x.CreateUser,
+ createUserName = "",
+ createTime = x.CreateTime,
+ updateUser = x.UpdateUser,
+ updateUserName = "",
+ updateTime = x.UpdateTime,
+ isEffective = x.IsEffective
+ })
+ .ToListAsync();
+
+ // 补充用户信息
+ var userIds = new List { contract.CreateUser, contract.UpdateUser };
+ userIds.AddRange(rentDetails.SelectMany(x => new[] { x.createUser, x.updateUser }).Where(x => !string.IsNullOrEmpty(x)));
+
+ string createUserName = "";
+ string updateUserName = "";
+
+ if (userIds.Any())
+ {
+ var userList = await _db.Queryable()
+ .Where(x => userIds.Distinct().Contains(x.Id))
+ .Select(x => new { x.Id, x.RealName })
+ .ToListAsync();
+ var userDict = userList.ToDictionary(k => k.Id, v => v.RealName);
+
+ if (!string.IsNullOrEmpty(contract.CreateUser) && userDict.ContainsKey(contract.CreateUser))
+ createUserName = userDict[contract.CreateUser];
+ if (!string.IsNullOrEmpty(contract.UpdateUser) && userDict.ContainsKey(contract.UpdateUser))
+ updateUserName = userDict[contract.UpdateUser];
+
+ foreach (var detail in rentDetails)
+ {
+ if (!string.IsNullOrEmpty(detail.createUser) && userDict.ContainsKey(detail.createUser))
+ detail.createUserName = userDict[detail.createUser];
+ if (!string.IsNullOrEmpty(detail.updateUser) && userDict.ContainsKey(detail.updateUser))
+ detail.updateUserName = userDict[detail.updateUser];
+ }
+ }
+
+ return new LqContractInfoOutput
+ {
+ id = contract.Id,
+ storeId = contract.StoreId,
+ storeName = contract.StoreName,
+ title = contract.Title,
+ category = contract.Category,
+ tenantName = contract.TenantName,
+ contractStartDate = contract.ContractStartDate,
+ contractEndDate = contract.ContractEndDate,
+ reminderDays = contract.ReminderDays,
+ deposit = contract.Deposit,
+ nextPaymentDate = contract.NextPaymentDate,
+ monthlyRent = contract.MonthlyRent,
+ paymentAmount = contract.PaymentAmount,
+ paymentCycle = contract.PaymentCycle,
+ remarks = contract.Remarks,
+ attachment = contract.Attachment,
+ createUser = contract.CreateUser,
+ createUserName = createUserName,
+ createTime = contract.CreateTime,
+ updateUser = contract.UpdateUser,
+ updateUserName = updateUserName,
+ updateTime = contract.UpdateTime,
+ isEffective = contract.IsEffective,
+ rentDetails = rentDetails
+ };
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError(ex, "获取合同详情失败");
+ throw NCCException.Oh($"获取合同详情失败:{ex.Message}");
+ }
+ }
+
+ #endregion
+
+ #region 获取月租明细列表
+
+ ///
+ /// 获取月租明细列表
+ ///
+ ///
+ /// 根据合同ID获取该合同的所有月租明细
+ ///
+ /// 示例请求:
+ /// ```
+ /// GET /api/Extend/LqContract/GetRentDetails?contractId=合同ID
+ /// ```
+ ///
+ /// 合同ID
+ /// 月租明细列表
+ /// 查询成功
+ /// 合同ID不能为空
+ /// 服务器错误
+ [HttpGet("GetRentDetails")]
+ public async Task GetRentDetailsAsync([FromQuery] string contractId)
+ {
+ try
+ {
+ if (string.IsNullOrWhiteSpace(contractId))
+ {
+ throw NCCException.Oh("合同ID不能为空");
+ }
+
+ var rentDetails = await _db.Queryable()
+ .Where(x => x.ContractId == contractId && x.IsEffective == StatusEnum.有效.GetHashCode())
+ .OrderBy(x => x.PaymentMonth)
+ .Select(x => new LqContractRentDetailListOutput
+ {
+ id = x.Id,
+ contractId = x.ContractId,
+ paymentMonth = x.PaymentMonth,
+ dueDate = x.DueDate,
+ dueAmount = x.DueAmount,
+ isPaid = x.IsPaid,
+ actualPaymentDate = x.ActualPaymentDate,
+ actualPaymentAmount = x.ActualPaymentAmount,
+ remarks = x.Remarks,
+ createUser = x.CreateUser,
+ createUserName = "",
+ createTime = x.CreateTime,
+ updateUser = x.UpdateUser,
+ updateUserName = "",
+ updateTime = x.UpdateTime,
+ isEffective = x.IsEffective
+ })
+ .ToListAsync();
+
+ // 补充用户信息
+ var userIds = rentDetails.SelectMany(x => new[] { x.createUser, x.updateUser })
+ .Where(x => !string.IsNullOrEmpty(x))
+ .Distinct()
+ .ToList();
+
+ if (userIds.Any())
+ {
+ var userList = await _db.Queryable()
+ .Where(x => userIds.Contains(x.Id))
+ .Select(x => new { x.Id, x.RealName })
+ .ToListAsync();
+ var userDict = userList.ToDictionary(k => k.Id, v => v.RealName);
+
+ foreach (var detail in rentDetails)
+ {
+ if (!string.IsNullOrEmpty(detail.createUser) && userDict.ContainsKey(detail.createUser))
+ detail.createUserName = userDict[detail.createUser];
+ if (!string.IsNullOrEmpty(detail.updateUser) && userDict.ContainsKey(detail.updateUser))
+ detail.updateUserName = userDict[detail.updateUser];
+ }
+ }
+
+ return rentDetails;
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError(ex, "获取月租明细列表失败");
+ throw NCCException.Oh($"获取月租明细列表失败:{ex.Message}");
+ }
+ }
+
+ #endregion
+
+ #region 标记明细已缴费
+
+ ///
+ /// 标记月租明细已缴费
+ ///
+ ///
+ /// 标记某条月租明细已缴费,记录实际缴费时间和金额
+ ///
+ /// 示例请求:
+ /// ```json
+ /// {
+ /// "id": "明细ID",
+ /// "actualPaymentDate": "2025-01-15T00:00:00",
+ /// "actualPaymentAmount": 3000.00,
+ /// "remarks": "已缴费"
+ /// }
+ /// ```
+ ///
+ /// 标记已缴费输入
+ /// 标记结果
+ /// 标记成功
+ /// 明细不存在或已缴费
+ /// 服务器错误
+ [HttpPut("MarkRentDetailPaid")]
+ public async Task MarkRentDetailPaidAsync([FromBody] LqContractRentDetailMarkPaidInput input)
+ {
+ try
+ {
+ // 查询明细
+ var detail = await _db.Queryable()
+ .Where(x => x.Id == input.Id && x.IsEffective == StatusEnum.有效.GetHashCode())
+ .FirstAsync();
+
+ if (detail == null)
+ {
+ throw NCCException.Oh("月租明细不存在或已失效");
+ }
+
+ if (detail.IsPaid == 1)
+ {
+ throw NCCException.Oh("该明细已标记为已缴费");
+ }
+
+ _db.Ado.BeginTran();
+
+ try
+ {
+ // 更新明细
+ detail.IsPaid = 1;
+ detail.ActualPaymentDate = input.ActualPaymentDate;
+ detail.ActualPaymentAmount = input.ActualPaymentAmount;
+ detail.Remarks = input.Remarks;
+ detail.UpdateUser = _userManager.UserId;
+ detail.UpdateTime = DateTime.Now;
+
+ var updateCount = await _db.Updateable(detail).ExecuteCommandAsync();
+ if (updateCount <= 0)
+ {
+ throw NCCException.Oh("标记已缴费失败");
+ }
+
+ // 重新计算下次应交时间
+ await CalculateNextPaymentDate(detail.ContractId);
+
+ _db.Ado.CommitTran();
+ }
+ catch
+ {
+ _db.Ado.RollbackTran();
+ throw;
+ }
+ }
+ catch (Exception ex)
+ {
+ _db.Ado.RollbackTran();
+ _logger.LogError(ex, "标记明细已缴费失败");
+ throw NCCException.Oh($"标记失败:{ex.Message}");
+ }
+ }
+
+ #endregion
+
+ #region 私有方法
+
+ ///
+ /// 自动生成月租明细
+ ///
+ /// 合同ID
+ /// 合同起始日期
+ /// 合同结束日期
+ /// 交租周期(月)
+ /// 缴租金额
+ private async Task GenerateRentDetailsAsync(string contractId, DateTime contractStartDate, DateTime contractEndDate, int paymentCycle, decimal paymentAmount)
+ {
+ var details = new List();
+ var currentDate = contractStartDate.Date;
+
+ // 从合同起始日期开始,每隔交租周期生成一条明细
+ while (currentDate <= contractEndDate)
+ {
+ // 应缴月份:当前日期的月份第一天(格式:YYYY-MM-01)
+ var paymentMonth = new DateTime(currentDate.Year, currentDate.Month, 1);
+ // 应缴日期:应缴月份的第一天(根据业务规则,应缴日期为应缴月份的第一天)
+ var dueDate = paymentMonth;
+
+ var detail = new LqContractRentDetailEntity
+ {
+ Id = YitIdHelper.NextId().ToString(),
+ ContractId = contractId,
+ PaymentMonth = paymentMonth,
+ DueDate = dueDate,
+ DueAmount = paymentAmount,
+ IsPaid = 0,
+ CreateUser = _userManager.UserId,
+ CreateTime = DateTime.Now,
+ IsEffective = StatusEnum.有效.GetHashCode()
+ };
+
+ details.Add(detail);
+
+ // 计算下一个交租日期(加上交租周期)
+ currentDate = currentDate.AddMonths(paymentCycle);
+ }
+
+ // 批量插入
+ if (details.Any())
+ {
+ await _db.Insertable(details).ExecuteCommandAsync();
+ }
+ }
+
+ ///
+ /// 计算下次应交时间(匿名方法)
+ ///
+ /// 合同ID
+ private async Task CalculateNextPaymentDate(string contractId)
+ {
+ // 查询合同信息
+ var contract = await _db.Queryable()
+ .Where(x => x.Id == contractId && x.IsEffective == StatusEnum.有效.GetHashCode())
+ .FirstAsync();
+
+ if (contract == null)
+ {
+ return;
+ }
+
+ // 查询该合同未缴费的明细,按应缴日期升序排列
+ var unpaidDetail = await _db.Queryable()
+ .Where(x => x.ContractId == contractId && x.IsEffective == StatusEnum.有效.GetHashCode() && x.IsPaid == 0)
+ .OrderBy(x => x.DueDate)
+ .FirstAsync();
+
+ if (unpaidDetail != null)
+ {
+ // 计算:下次应交时间 = 最早应缴日期 - 提前提醒天数
+ var nextPaymentDate = unpaidDetail.DueDate.AddDays(-contract.ReminderDays);
+
+ // 更新合同的下次应交时间
+ contract.NextPaymentDate = nextPaymentDate;
+ contract.UpdateUser = _userManager.UserId;
+ contract.UpdateTime = DateTime.Now;
+
+ await _db.Updateable(contract).ExecuteCommandAsync();
+ }
+ else
+ {
+ // 如果没有未缴费的明细,清空下次应交时间
+ contract.NextPaymentDate = null;
+ contract.UpdateUser = _userManager.UserId;
+ contract.UpdateTime = DateTime.Now;
+
+ await _db.Updateable(contract).ExecuteCommandAsync();
+ }
+ }
+
+ #endregion
+
+ #region 统计门店合同费用
+
+ ///
+ /// 统计门店合同费用
+ ///
+ ///
+ /// 根据门店ID和月份统计该门店的合同费用,支持按分类统计(租门店、员工宿舍、车辆、场所等)
+ ///
+ /// 示例请求:
+ /// ```json
+ /// {
+ /// "storeId": "1649328471923847168",
+ /// "year": 2025,
+ /// "month": 1,
+ /// "categories": ["租门店", "员工宿舍", "车辆", "场所"]
+ /// }
+ /// ```
+ ///
+ /// 参数说明:
+ /// - storeId: 门店ID(必填)
+ /// - year: 统计年份(必填)
+ /// - month: 统计月份(必填,1-12)
+ /// - categories: 分类列表(可选,不传则统计所有分类)
+ ///
+ /// 返回数据说明:
+ /// - storeId: 门店ID
+ /// - storeName: 门店名称
+ /// - year: 统计年份
+ /// - month: 统计月份
+ /// - totalAmount: 总费用(所有分类的费用总和)
+ /// - categoryDetails: 按分类统计的费用明细
+ /// - category: 分类名称
+ /// - amount: 该分类的费用总额
+ /// - detailCount: 该分类的明细数量
+ /// - details: 明细列表
+ ///
+ /// 统计输入
+ /// 费用统计结果
+ /// 统计成功
+ /// 请求参数错误
+ /// 服务器错误
+ [HttpPost("GetExpenseStatistics")]
+ public async Task GetExpenseStatisticsAsync([FromBody] ContractExpenseStatisticsInput input)
+ {
+ try
+ {
+ // 验证月份
+ if (input.Month < 1 || input.Month > 12)
+ {
+ throw NCCException.Oh("月份必须在1-12之间");
+ }
+
+ // 构建统计月份的开始和结束时间
+ var statisticsMonth = new DateTime(input.Year, input.Month, 1);
+ var monthStart = statisticsMonth;
+ var monthEnd = statisticsMonth.AddMonths(1).AddDays(-1);
+
+ // 查询门店信息
+ var store = await _db.Queryable()
+ .Where(x => x.Id == input.StoreId)
+ .Select(x => new { x.Dm })
+ .FirstAsync();
+
+ if (store == null)
+ {
+ throw NCCException.Oh("门店不存在");
+ }
+
+ // 查询该门店在指定月份的月租明细
+ var details = await _db.Queryable(
+ (detail, contract) => new JoinQueryInfos(
+ JoinType.Inner, detail.ContractId == contract.Id))
+ .Where((detail, contract) =>
+ contract.StoreId == input.StoreId &&
+ contract.IsEffective == StatusEnum.有效.GetHashCode() &&
+ detail.IsEffective == StatusEnum.有效.GetHashCode() &&
+ detail.PaymentMonth >= monthStart &&
+ detail.PaymentMonth <= monthEnd)
+ .WhereIF(input.Categories != null && input.Categories.Length > 0,
+ (detail, contract) => contract.Category != null && input.Categories.Contains(contract.Category))
+ .Select((detail, contract) => new
+ {
+ DetailId = detail.Id,
+ ContractId = contract.Id,
+ ContractTitle = contract.Title,
+ Category = contract.Category ?? "未分类",
+ DueAmount = detail.DueAmount,
+ IsPaid = detail.IsPaid,
+ ActualPaymentAmount = detail.ActualPaymentAmount
+ })
+ .ToListAsync();
+
+ // 按分类分组统计
+ var categoryGroups = details.GroupBy(x => x.Category).ToList();
+
+ var categoryDetails = new List();
+ decimal totalAmount = 0;
+
+ foreach (var group in categoryGroups)
+ {
+ var categoryName = group.Key;
+ var categoryItems = group.ToList();
+ var categoryAmount = categoryItems.Sum(x => x.DueAmount);
+ totalAmount += categoryAmount;
+
+ var expenseDetails = categoryItems.Select(x => new ExpenseDetailItem
+ {
+ detailId = x.DetailId,
+ contractId = x.ContractId,
+ contractTitle = x.ContractTitle,
+ category = x.Category,
+ dueAmount = x.DueAmount,
+ isPaid = x.IsPaid,
+ actualPaymentAmount = x.ActualPaymentAmount
+ }).ToList();
+
+ categoryDetails.Add(new CategoryExpenseDetail
+ {
+ category = categoryName,
+ amount = categoryAmount,
+ detailCount = categoryItems.Count,
+ details = expenseDetails
+ });
+ }
+
+ // 按分类名称排序
+ categoryDetails = categoryDetails.OrderBy(x => x.category).ToList();
+
+ return new ContractExpenseStatisticsOutput
+ {
+ storeId = input.StoreId,
+ storeName = store.Dm ?? "",
+ year = input.Year,
+ month = input.Month,
+ totalAmount = totalAmount,
+ categoryDetails = categoryDetails
+ };
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError(ex, "统计门店合同费用失败");
+ throw NCCException.Oh($"统计失败:{ex.Message}");
+ }
+ }
+
+ #endregion
+ }
+}
+
diff --git a/netcore/src/Modularity/Extend/NCC.Extend/LqInventoryUsageService.cs b/netcore/src/Modularity/Extend/NCC.Extend/LqInventoryUsageService.cs
index f9fca08..8d1b187 100644
--- a/netcore/src/Modularity/Extend/NCC.Extend/LqInventoryUsageService.cs
+++ b/netcore/src/Modularity/Extend/NCC.Extend/LqInventoryUsageService.cs
@@ -14,6 +14,8 @@ using NCC.Extend.Entitys.Enum;
using NCC.Extend.Entitys.lq_inventory;
using NCC.Extend.Entitys.lq_product;
using NCC.Extend.Entitys.lq_inventory_usage;
+using NCC.Extend.Entitys.lq_inventory_usage_application;
+using NCC.Extend.Entitys.lq_inventory_usage_approval_record;
using NCC.Extend.Entitys.lq_mdxx;
using NCC.Extend.Interfaces.LqInventoryUsage;
using NCC.FriendlyException;
@@ -89,6 +91,10 @@ namespace NCC.Extend
_db.Ado.BeginTran();
+ // 自动计算单价和合计金额
+ var unitPrice = product.Price;
+ var totalAmount = unitPrice * input.UsageQuantity;
+
// 创建使用记录
var usageEntity = new LqInventoryUsageEntity
{
@@ -97,6 +103,8 @@ namespace NCC.Extend
StoreId = input.StoreId,
UsageTime = input.UsageTime,
UsageQuantity = input.UsageQuantity,
+ UnitPrice = unitPrice,
+ TotalAmount = totalAmount,
RelatedConsumeId = input.RelatedConsumeId,
CreateUser = _userManager.UserId,
CreateTime = DateTime.Now,
@@ -120,15 +128,19 @@ namespace NCC.Extend
#region 批量添加库存使用记录
///
- /// 批量添加库存使用记录
+ /// 批量添加库存使用记录(带审批流程)
///
///
- /// 一次性添加多条库存使用记录,同一批次的所有记录使用相同的批次ID
+ /// 一次性添加多条库存使用记录,同一批次的所有记录使用相同的批次ID。创建使用记录后会自动创建申请记录并提交审批。
+ /// 系统会自动计算单价(从产品表获取)和合计金额(单价×数量)。
///
/// 示例请求:
/// ```json
/// {
/// "batchId": "可选,不传则自动生成",
+ /// "approverId": "审批人ID(财务老师或库管,必填)",
+ /// "applicationStoreId": "申请门店ID(必填)",
+ /// "remarks": "备注(可选)",
/// "usageItems": [
/// {
/// "productId": "产品ID",
@@ -143,12 +155,21 @@ namespace NCC.Extend
///
/// 参数说明:
/// - batchId: 批次ID,可选。如果不传,系统会自动生成一个唯一的批次ID
+ /// - approverId: 审批人ID(财务老师或库管),必填。创建申请记录后会自动提交审批
+ /// - applicationStoreId: 申请门店ID,必填
+ /// - remarks: 备注,可选
/// - usageItems: 使用记录列表,至少需要一条记录
/// - productId: 产品ID(必填)
/// - storeId: 门店ID(必填)
/// - usageTime: 使用时间(必填)
/// - usageQuantity: 使用数量(必填,必须大于0)
/// - relatedConsumeId: 关联消耗ID(可选)
+ ///
+ /// 业务流程:
+ /// 1. 验证库存是否充足
+ /// 2. 创建使用记录(自动计算单价和合计金额)
+ /// 3. 创建申请记录(状态:审批中)
+ /// 4. 返回批次ID和创建结果
///
/// 批量创建输入
/// 批量创建结果,包含批次ID和成功/失败信息
@@ -183,12 +204,13 @@ namespace NCC.Extend
var usageList = await _db.Queryable().Where(x => productIds.Contains(x.ProductId) && x.IsEffective == StatusEnum.有效.GetHashCode()).GroupBy(x => x.ProductId).Select(x => new { ProductId = x.ProductId, TotalUsage = SqlFunc.AggregateSum(x.UsageQuantity) }).ToListAsync();
var usageMap = usageList.ToDictionary(x => x.ProductId, x => Convert.ToInt32(x.TotalUsage));
- // 批量查询所有产品的名称
+ // 批量查询所有产品的名称和价格
var productDict = await _db.Queryable()
.Where(x => productIds.Contains(x.Id))
- .Select(x => new { x.Id, x.ProductName })
+ .Select(x => new { x.Id, x.ProductName, x.Price })
.ToListAsync();
var productNameMap = productDict.ToDictionary(x => x.Id, x => x.ProductName ?? "未知产品");
+ var productPriceMap = productDict.ToDictionary(x => x.Id, x => x.Price);
// 检查每个产品的库存
foreach (var productGroup in productGroups)
@@ -213,12 +235,16 @@ namespace NCC.Extend
try
{
- // 创建使用记录
+ // 创建使用记录(自动计算单价和合计金额)
var entitiesToInsert = new List();
for (int i = 0; i < input.UsageItems.Count; i++)
{
var item = input.UsageItems[i];
+ // 从产品价格字典获取单价
+ var unitPrice = productPriceMap.GetValueOrDefault(item.ProductId, 0);
+ var totalAmount = unitPrice * item.UsageQuantity;
+
var usageEntity = new LqInventoryUsageEntity
{
Id = YitIdHelper.NextId().ToString(),
@@ -226,6 +252,8 @@ namespace NCC.Extend
StoreId = item.StoreId,
UsageTime = item.UsageTime,
UsageQuantity = item.UsageQuantity,
+ UnitPrice = unitPrice,
+ TotalAmount = totalAmount,
RelatedConsumeId = item.RelatedConsumeId,
UsageBatchId = batchId,
CreateUser = _userManager.UserId,
@@ -247,6 +275,64 @@ namespace NCC.Extend
}
}
+ // 创建申请记录并提交审批(审批人ID为必填)
+ if (string.IsNullOrWhiteSpace(input.ApproverId))
+ {
+ throw NCCException.Oh("审批人ID不能为空");
+ }
+ if (string.IsNullOrWhiteSpace(input.ApplicationStoreId))
+ {
+ throw NCCException.Oh("申请门店ID不能为空");
+ }
+
+ {
+ // 获取申请人信息
+ var applicantUser = await _db.Queryable()
+ .Where(x => x.Id == _userManager.UserId)
+ .Select(x => new { x.Id, x.RealName })
+ .FirstAsync();
+
+ // 获取审批人信息
+ var approverUser = await _db.Queryable()
+ .Where(x => x.Id == input.ApproverId)
+ .Select(x => new { x.Id, x.RealName })
+ .FirstAsync();
+
+ if (approverUser == null)
+ {
+ throw NCCException.Oh("审批人不存在");
+ }
+
+ // 生成节点ID(使用批次ID作为节点ID,因为只有一个节点)
+ var nodeId = YitIdHelper.NextId().ToString();
+
+ // 创建申请记录
+ var applicationEntity = new LqInventoryUsageApplicationEntity
+ {
+ Id = YitIdHelper.NextId().ToString(),
+ UsageBatchId = batchId,
+ ApplicationUserId = applicantUser?.Id ?? _userManager.UserId,
+ ApplicationUserName = applicantUser?.RealName ?? "",
+ ApplicationStoreId = input.ApplicationStoreId,
+ ApplicationTime = DateTime.Now,
+ NodeCount = 1,
+ CurrentNodeOrder = 1, // 审批中
+ CurrentNodeId = nodeId,
+ ApprovalStatus = "审批中",
+ IsReceived = 0,
+ Remarks = input.Remarks,
+ CreateUser = _userManager.UserId,
+ CreateTime = DateTime.Now,
+ IsEffective = StatusEnum.有效.GetHashCode()
+ };
+
+ var applicationInsertCount = await _db.Insertable(applicationEntity).ExecuteCommandAsync();
+ if (applicationInsertCount <= 0)
+ {
+ throw NCCException.Oh("创建申请记录失败");
+ }
+ }
+
_db.Ado.CommitTran();
return new LqInventoryUsageBatchCreateOutput
@@ -420,17 +506,23 @@ namespace NCC.Extend
/// 根据批次号获取批次信息
///
///
- /// 根据批次ID查询该批次的所有使用记录信息,包括批次基本信息和详细的使用记录列表
+ /// 根据批次ID查询该批次的所有使用记录信息,包括批次基本信息和详细的使用记录列表。
+ /// 兼容旧数据:如果该批次没有申请记录(旧数据),ApplicationInfo字段为null。
///
/// 返回数据结构:
/// - 批次基本信息:批次ID、创建时间、创建人、统计信息等
/// - 使用记录列表:该批次的所有使用记录详情
+ /// - 申请记录信息(ApplicationInfo):如果存在申请记录,包含审批状态、是否已领取等信息;如果不存在(旧数据),则为null
///
/// 参数说明:
/// - batchId: 批次ID(必填)
+ ///
+ /// 兼容性说明:
+ /// - 新数据:包含完整的申请记录信息
+ /// - 旧数据:ApplicationInfo为null,但不影响使用记录的查询和显示
///
/// 批次ID
- /// 批次信息,包含该批次的所有使用记录
+ /// 批次信息,包含该批次的所有使用记录和申请记录(如果有)
/// 查询成功,返回批次信息和使用记录列表
/// 批次ID不能为空
/// 批次不存在
@@ -512,6 +604,29 @@ namespace NCC.Extend
var effectiveRecords = usageRecords.Where(x => x.isEffective == StatusEnum.有效.GetHashCode()).ToList();
var ineffectiveRecords = usageRecords.Where(x => x.isEffective == StatusEnum.无效.GetHashCode()).ToList();
+ // 查询申请记录(如果有)
+ var application = await _db.Queryable()
+ .Where(x => x.UsageBatchId == batchId && x.IsEffective == StatusEnum.有效.GetHashCode())
+ .FirstAsync();
+
+ ApplicationInfo applicationInfo = null;
+ if (application != null)
+ {
+ applicationInfo = new ApplicationInfo
+ {
+ Id = application.Id,
+ ApplicationUserId = application.ApplicationUserId,
+ ApplicationUserName = application.ApplicationUserName,
+ ApplicationStoreId = application.ApplicationStoreId,
+ ApplicationTime = application.ApplicationTime,
+ ApprovalStatus = application.ApprovalStatus,
+ IsReceived = application.IsReceived,
+ ReceiveTime = application.ReceiveTime,
+ ReceiveUser = application.ReceiveUser,
+ Remarks = application.Remarks
+ };
+ }
+
var batchInfo = new LqInventoryUsageBatchInfoOutput
{
BatchId = batchId,
@@ -523,7 +638,8 @@ namespace NCC.Extend
IneffectiveCount = ineffectiveRecords.Count,
TotalUsageQuantity = effectiveRecords.Sum(x => x.usageQuantity),
TotalUsageAmount = effectiveRecords.Sum(x => x.usageTotalValue),
- UsageRecords = usageRecords
+ UsageRecords = usageRecords,
+ ApplicationInfo = applicationInfo
};
return batchInfo;
@@ -768,6 +884,457 @@ namespace NCC.Extend
}
#endregion
+ #region 审批相关功能
+
+ ///
+ /// 审批库存使用申请(通过/不通过)
+ ///
+ ///
+ /// 审批库存使用申请,支持通过和不通过两种结果
+ ///
+ /// 示例请求:
+ /// ```
+ /// POST /api/Extend/LqInventoryUsage/Approve/{applicationId}?result=通过&opinion=审批意见
+ /// ```
+ ///
+ /// 参数说明:
+ /// - applicationId: 申请ID(必填)
+ /// - result: 审批结果(必填,值:通过/不通过)
+ /// - opinion: 审批意见(可选)
+ ///
+ /// 申请ID
+ /// 审批结果(通过/不通过)
+ /// 审批意见
+ /// 审批结果
+ /// 审批成功
+ /// 申请不存在或状态不正确
+ /// 服务器错误
+ [HttpPost("Approve/{applicationId}")]
+ public async Task ApproveApplicationAsync([FromRoute] string applicationId, [FromQuery] string result, [FromQuery] string opinion = "")
+ {
+ try
+ {
+ if (string.IsNullOrWhiteSpace(applicationId))
+ {
+ throw NCCException.Oh("申请ID不能为空");
+ }
+
+ if (string.IsNullOrWhiteSpace(result) || (result != "通过" && result != "不通过"))
+ {
+ throw NCCException.Oh("审批结果必须为'通过'或'不通过'");
+ }
+
+ // 获取申请记录
+ var application = await _db.Queryable()
+ .Where(x => x.Id == applicationId && x.IsEffective == StatusEnum.有效.GetHashCode())
+ .FirstAsync();
+
+ if (application == null)
+ {
+ throw NCCException.Oh("申请记录不存在或已失效");
+ }
+
+ // 验证申请状态
+ if (application.ApprovalStatus != "审批中")
+ {
+ throw NCCException.Oh($"申请当前状态为{application.ApprovalStatus},无法进行审批操作");
+ }
+
+ // 获取当前用户信息
+ var userInfo = await _userManager.GetUserInfo();
+ var approverUser = await _db.Queryable()
+ .Where(x => x.Id == userInfo.userId)
+ .Select(x => new { x.Id, x.RealName })
+ .FirstAsync();
+
+ _db.Ado.BeginTran();
+
+ try
+ {
+ // 创建审批记录
+ var approvalRecord = new LqInventoryUsageApprovalRecordEntity
+ {
+ Id = YitIdHelper.NextId().ToString(),
+ ApplicationId = applicationId,
+ NodeId = application.CurrentNodeId,
+ NodeOrder = 1,
+ ApproverId = approverUser.Id,
+ ApproverName = approverUser.RealName ?? "",
+ ApprovalResult = result,
+ ApprovalOpinion = opinion,
+ ApprovalTime = DateTime.Now,
+ IsCurrentNode = 1
+ };
+
+ await _db.Insertable(approvalRecord).ExecuteCommandAsync();
+
+ // 更新申请状态
+ if (result == "通过")
+ {
+ application.ApprovalStatus = "已通过";
+ application.CurrentNodeOrder = 2; // 已完成
+ }
+ else
+ {
+ application.ApprovalStatus = "未通过";
+ application.CurrentNodeOrder = 0; // 回到待审批状态
+ }
+
+ application.UpdateUser = userInfo.userId;
+ application.UpdateTime = DateTime.Now;
+
+ await _db.Updateable(application).ExecuteCommandAsync();
+
+ _db.Ado.CommitTran();
+ }
+ catch
+ {
+ _db.Ado.RollbackTran();
+ throw;
+ }
+ }
+ catch (Exception ex)
+ {
+ _db.Ado.RollbackTran();
+ _logger.LogError(ex, "审批申请失败");
+ throw NCCException.Oh($"审批失败:{ex.Message}");
+ }
+ }
+
+ ///
+ /// 标记申请已领取
+ ///
+ ///
+ /// 审批通过后,可以标记申请已领取
+ ///
+ /// 示例请求:
+ /// ```
+ /// PUT /api/Extend/LqInventoryUsage/MarkReceived/{applicationId}
+ /// ```
+ ///
+ /// 参数说明:
+ /// - applicationId: 申请ID(必填)
+ ///
+ /// 申请ID
+ /// 标记结果
+ /// 标记成功
+ /// 申请不存在或状态不正确
+ /// 服务器错误
+ [HttpPut("MarkReceived/{applicationId}")]
+ public async Task MarkReceivedAsync([FromRoute] string applicationId)
+ {
+ try
+ {
+ if (string.IsNullOrWhiteSpace(applicationId))
+ {
+ throw NCCException.Oh("申请ID不能为空");
+ }
+
+ // 获取申请记录
+ var application = await _db.Queryable()
+ .Where(x => x.Id == applicationId && x.IsEffective == StatusEnum.有效.GetHashCode())
+ .FirstAsync();
+
+ if (application == null)
+ {
+ throw NCCException.Oh("申请记录不存在或已失效");
+ }
+
+ // 验证申请状态(只有已通过的申请才能标记已领取)
+ if (application.ApprovalStatus != "已通过")
+ {
+ throw NCCException.Oh($"申请当前状态为{application.ApprovalStatus},只有已通过的申请才能标记已领取");
+ }
+
+ // 获取当前用户信息
+ var userInfo = await _userManager.GetUserInfo();
+
+ // 更新申请记录
+ application.IsReceived = 1;
+ application.ReceiveTime = DateTime.Now;
+ application.ReceiveUser = userInfo.userId;
+ application.UpdateUser = userInfo.userId;
+ application.UpdateTime = DateTime.Now;
+
+ var isOk = await _db.Updateable(application).ExecuteCommandAsync();
+ if (!(isOk > 0)) throw NCCException.Oh(ErrorCode.COM1003);
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError(ex, "标记已领取失败");
+ throw NCCException.Oh($"标记失败:{ex.Message}");
+ }
+ }
+
+ ///
+ /// 根据使用批次ID查询申请记录
+ ///
+ ///
+ /// 根据使用批次ID查询对应的申请记录信息。兼容旧数据:如果该批次没有申请记录(旧数据),会返回success=false,data=null。
+ ///
+ /// 示例请求:
+ /// ```
+ /// GET /api/Extend/LqInventoryUsage/GetApplicationByBatchId?batchId=批次ID
+ /// ```
+ ///
+ /// 参数说明:
+ /// - batchId: 使用批次ID(必填)
+ ///
+ /// 返回说明:
+ /// - 如果存在申请记录:返回完整的申请信息,包括审批状态、是否已领取、审批记录等
+ /// - 如果不存在申请记录(旧数据):返回success=false,message="该批次没有对应的申请记录",data=null
+ ///
+ /// 使用批次ID
+ /// 申请记录信息
+ /// 查询成功(可能没有申请记录,需要检查success字段)
+ /// 批次ID不能为空
+ /// 服务器错误
+ [HttpGet("GetApplicationByBatchId")]
+ public async Task GetApplicationByBatchIdAsync([FromQuery] string batchId)
+ {
+ try
+ {
+ if (string.IsNullOrWhiteSpace(batchId))
+ {
+ throw NCCException.Oh("批次ID不能为空");
+ }
+
+ // 查询申请记录
+ var application = await _db.Queryable()
+ .Where(x => x.UsageBatchId == batchId && x.IsEffective == StatusEnum.有效.GetHashCode())
+ .FirstAsync();
+
+ if (application == null)
+ {
+ return new
+ {
+ success = false,
+ message = "该批次没有对应的申请记录",
+ data = (object)null
+ };
+ }
+
+ // 查询审批记录
+ var approvalRecords = await _db.Queryable()
+ .Where(x => x.ApplicationId == application.Id)
+ .OrderBy(x => x.ApprovalTime)
+ .ToListAsync();
+
+ // 补充审批人姓名(如果审批记录中没有)
+ var approverIds = approvalRecords.Where(x => !string.IsNullOrEmpty(x.ApproverId))
+ .Select(x => x.ApproverId)
+ .Distinct()
+ .ToList();
+
+ var approverDict = new Dictionary();
+ if (approverIds.Any())
+ {
+ var approvers = await _db.Queryable()
+ .Where(x => approverIds.Contains(x.Id))
+ .Select(x => new { x.Id, x.RealName })
+ .ToListAsync();
+ approverDict = approvers.ToDictionary(k => k.Id, v => v.RealName ?? "");
+ }
+
+ return new
+ {
+ success = true,
+ data = new
+ {
+ id = application.Id,
+ usageBatchId = application.UsageBatchId,
+ applicationUserId = application.ApplicationUserId,
+ applicationUserName = application.ApplicationUserName,
+ applicationStoreId = application.ApplicationStoreId,
+ applicationTime = application.ApplicationTime,
+ approvalStatus = application.ApprovalStatus,
+ isReceived = application.IsReceived,
+ receiveTime = application.ReceiveTime,
+ receiveUser = application.ReceiveUser,
+ remarks = application.Remarks,
+ approvalRecords = approvalRecords.Select(x => new
+ {
+ id = x.Id,
+ approverId = x.ApproverId,
+ approverName = string.IsNullOrEmpty(x.ApproverName) && approverDict.ContainsKey(x.ApproverId)
+ ? approverDict[x.ApproverId]
+ : x.ApproverName,
+ approvalResult = x.ApprovalResult,
+ approvalOpinion = x.ApprovalOpinion,
+ approvalTime = x.ApprovalTime
+ }).ToList()
+ }
+ };
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError(ex, "查询申请记录失败");
+ throw NCCException.Oh($"查询失败:{ex.Message}");
+ }
+ }
+
+ #endregion
+
+ #region 门店领取统计
+
+ ///
+ /// 门店领取统计(按月份统计每个门店的领取总金额)
+ ///
+ ///
+ /// 统计指定月份每个门店已领取的库存使用申请的总金额。只统计审批通过且已领取的申请。
+ ///
+ /// 示例请求:
+ /// ```json
+ /// POST /api/Extend/LqInventoryUsage/GetStoreReceiveStatistics
+ /// {
+ /// "year": 2025,
+ /// "month": 11,
+ /// "storeId": "门店ID(可选)"
+ /// }
+ /// ```
+ ///
+ /// 参数说明:
+ /// - year: 统计年份(必填,范围:2020-2100)
+ /// - month: 统计月份(必填,范围:1-12)
+ /// - storeId: 门店ID(可选,不传则统计所有门店)
+ ///
+ /// 返回说明:
+ /// - 按门店分组统计
+ /// - 每个门店包含:门店ID、门店名称、申请数量、领取总金额
+ /// - 按总金额降序排列
+ ///
+ /// 统计查询输入
+ /// 门店领取统计列表
+ /// 查询成功
+ /// 输入参数错误
+ /// 服务器错误
+ [HttpPost("GetStoreReceiveStatistics")]
+ public async Task GetStoreReceiveStatisticsAsync([FromBody] StoreReceiveStatisticsInput input)
+ {
+ try
+ {
+ if (input == null)
+ {
+ throw NCCException.Oh("输入参数不能为空");
+ }
+
+ // 计算月份的开始和结束时间
+ var startDate = new DateTime(input.Year, input.Month, 1);
+ var endDate = startDate.AddMonths(1).AddDays(-1).Date.AddHours(23).AddMinutes(59).AddSeconds(59);
+
+ // 查询已领取的申请记录(审批通过且已领取)
+ var applicationQuery = _db.Queryable()
+ .Where(x => x.IsEffective == StatusEnum.有效.GetHashCode())
+ .Where(x => x.ApprovalStatus == "已通过")
+ .Where(x => x.IsReceived == 1)
+ .Where(x => x.ReceiveTime >= startDate && x.ReceiveTime <= endDate);
+
+ if (!string.IsNullOrWhiteSpace(input.StoreId))
+ {
+ applicationQuery = applicationQuery.Where(x => x.ApplicationStoreId == input.StoreId);
+ }
+
+ var applications = await applicationQuery.ToListAsync();
+
+ if (!applications.Any())
+ {
+ return new
+ {
+ success = true,
+ data = new List