diff --git a/PROJECT_RULES.md b/PROJECT_RULES.md index 908782f..7e26d21 100644 --- a/PROJECT_RULES.md +++ b/PROJECT_RULES.md @@ -143,6 +143,44 @@ Id = Guid.NewGuid().ToString() - 必须包含所有可能的HTTP状态码响应说明 - 复杂接口必须提供完整的请求示例 +### 接口测试规范 +- **必须测试**: 所有新开发的接口或修改的接口都必须进行测试 +- **测试要求**: + - 使用实际数据测试接口功能 + - 验证接口返回数据的正确性 + - 测试边界情况和异常情况 + - 验证接口性能和响应时间 + - 确保接口符合业务逻辑要求 +- **测试方式**: 可以使用 curl、Postman、Swagger 等工具进行接口测试 +- **测试通过**: 只有测试通过的接口才能提交代码 +- **测试token获取**: + - **接口地址**: `/api/oauth/Login` + - **请求方式**: POST + - **Content-Type**: `application/x-www-form-urlencoded` + - **请求参数**: + - `account`: `admin` + - `password`: `e10adc3949ba59abbe56e057f20f883e` + - **curl示例**: + ```bash + curl -X POST "http://localhost:2011/api/oauth/Login" \ + -H "Content-Type: application/x-www-form-urlencoded" \ + -d "account=admin&password=e10adc3949ba59abbe56e057f20f883e" + ``` + - **返回格式**: + ```json + { + "code": 200, + "msg": "操作成功", + "data": { + "theme": "functional", + "token": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", + "user": null + } + } + ``` + - **token使用**: 返回的token已包含"Bearer "前缀,可直接在请求头中使用:`Authorization: {data.token}` + + ## 📊 数据一致性规范 ### 统计与列表数据 diff --git a/netcore/src/Modularity/Extend/NCC.Extend.Entitys.Dto/LqTechTeacherSalary/TechTeacherStatisticsOutput.cs b/netcore/src/Modularity/Extend/NCC.Extend.Entitys.Dto/LqTechTeacherSalary/TechTeacherStatisticsOutput.cs deleted file mode 100644 index c50954a..0000000 --- a/netcore/src/Modularity/Extend/NCC.Extend.Entitys.Dto/LqTechTeacherSalary/TechTeacherStatisticsOutput.cs +++ /dev/null @@ -1,51 +0,0 @@ -using System; - -namespace NCC.Extend.Entitys.Dto.LqTechTeacherSalary -{ - /// - /// 科技部老师统计数据输出 - /// - public class TechTeacherStatisticsOutput - { - /// - /// 员工ID - /// - public string EmployeeId { get; set; } - - /// - /// 员工姓名 - /// - public string EmployeeName { get; set; } - - /// - /// 开单业绩 - /// - public decimal OrderAchievement { get; set; } - - /// - /// 消耗业绩 - /// - public decimal ConsumeAchievement { get; set; } - - /// - /// 退卡业绩 - /// - public decimal RefundAchievement { get; set; } - - /// - /// 人头(按月份+客户去重统计) - /// - public int PersonCount { get; set; } - - /// - /// 人次(按日期+客户去重统计) - /// - public decimal PersonTimes { get; set; } - - /// - /// 手工费 - /// - public decimal LaborCost { get; set; } - } -} - diff --git a/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqShareStatisticsHq/ShareStatisticsHqGenerateInput.cs b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqShareStatisticsHq/ShareStatisticsHqGenerateInput.cs new file mode 100644 index 0000000..0d93d4c --- /dev/null +++ b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqShareStatisticsHq/ShareStatisticsHqGenerateInput.cs @@ -0,0 +1,13 @@ +namespace NCC.Extend.Entitys.Dto.LqShareStatisticsHq +{ + /// + /// 总部股份统计生成输入 + /// + public class ShareStatisticsHqGenerateInput + { + /// + /// 统计月份(YYYYMM) + /// + public string StatisticsMonth { get; set; } + } +} diff --git a/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqShareStatisticsHq/ShareStatisticsHqOutput.cs b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqShareStatisticsHq/ShareStatisticsHqOutput.cs new file mode 100644 index 0000000..9a41bbd --- /dev/null +++ b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqShareStatisticsHq/ShareStatisticsHqOutput.cs @@ -0,0 +1,70 @@ +using System; + +namespace NCC.Extend.Entitys.Dto.LqShareStatisticsHq +{ + /// + /// 总部股份统计输出 + /// + public class ShareStatisticsHqOutput + { + /// + /// 主键ID + /// + public string Id { get; set; } + + /// + /// 统计月份 + /// + public string StatisticsMonth { get; set; } + + /// + /// 收入-全部 + /// + public decimal IncomeGeneral { get; set; } + + /// + /// 收入-科技部 + /// + public decimal IncomeTechDept { get; set; } + + /// + /// 成本-报销 + /// + public decimal CostReimbursement { get; set; } + + /// + /// 成本-人工 + /// + public decimal CostLabor { get; set; } + + /// + /// 成本-教育部房租 + /// + public decimal CostEducationRent { get; set; } + + /// + /// 成本-仓库房租 + /// + public decimal CostWarehouseRent { get; set; } + + /// + /// 成本-总部房租 + /// + public decimal CostHQRent { get; set; } + + /// + /// 运营利润 + /// + public decimal OperationalProfit { get; set; } + + /// + /// 创建时间 + /// + public DateTime CreateTime { get; set; } + + /// + /// 更新时间 + /// + public DateTime? UpdateTime { get; set; } + } +} diff --git a/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqShareStatisticsHq/ShareStatisticsHqQueryInput.cs b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqShareStatisticsHq/ShareStatisticsHqQueryInput.cs new file mode 100644 index 0000000..c099f26 --- /dev/null +++ b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqShareStatisticsHq/ShareStatisticsHqQueryInput.cs @@ -0,0 +1,13 @@ +namespace NCC.Extend.Entitys.Dto.LqShareStatisticsHq +{ + /// + /// 总部股份统计查询输入 + /// + public class ShareStatisticsHqQueryInput + { + /// + /// 统计月份(YYYYMM) + /// + public string StatisticsMonth { get; set; } + } +} diff --git a/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqShareStatisticsStore/ShareStatisticsStoreGenerateInput.cs b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqShareStatisticsStore/ShareStatisticsStoreGenerateInput.cs new file mode 100644 index 0000000..abb1f72 --- /dev/null +++ b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqShareStatisticsStore/ShareStatisticsStoreGenerateInput.cs @@ -0,0 +1,20 @@ +using System; + +namespace NCC.Extend.Entitys.Dto.LqShareStatisticsStore +{ + /// + /// 门店股份统计生成输入 + /// + public class ShareStatisticsStoreGenerateInput + { + /// + /// 统计月份(YYYYMM) + /// + public string StatisticsMonth { get; set; } + + /// + /// 门店ID(可选,为空则生成所有门店) + /// + public string StoreId { get; set; } + } +} diff --git a/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqShareStatisticsStore/ShareStatisticsStoreOutput.cs b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqShareStatisticsStore/ShareStatisticsStoreOutput.cs new file mode 100644 index 0000000..dbbeacb --- /dev/null +++ b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqShareStatisticsStore/ShareStatisticsStoreOutput.cs @@ -0,0 +1,268 @@ +using System; + +namespace NCC.Extend.Entitys.Dto.LqShareStatisticsStore +{ + /// + /// 门店股份统计输出 + /// + public class ShareStatisticsStoreOutput + { + /// + /// 主键ID + /// + public string Id { get; set; } + + /// + /// 门店ID + /// + public string StoreId { get; set; } + + /// + /// 门店名称 + /// + public string StoreName { get; set; } + + /// + /// 统计月份(YYYYMM) + /// + public string StatisticsMonth { get; set; } + + // 收入部分 + /// + /// 主营收入(消耗业绩-对应退款) + /// + public decimal MainIncome { get; set; } + + /// + /// 其他收入(退款差额>0) + /// + public decimal OtherIncome { get; set; } + + /// + /// 预收款(开单实付) + /// + public decimal AdvanceReceipt { get; set; } + + /// + /// 实际退款(实退业绩) + /// + public decimal Refund { get; set; } + + /// + /// 应收(合作医院) + /// + public decimal Receivables { get; set; } + + /// + /// 银行存款(开单实付-应收) + /// + public decimal BankDeposit { get; set; } + + // 成本部分 + /// + /// 主营成本-产品(仓库领取) + /// + public decimal CostProduct { get; set; } + + /// + /// 主营成本-福田(福田仓库领取) + /// + public decimal CostFutian { get; set; } + + /// + /// 主营成本-毛巾(清洗送出) + /// + public decimal CostTowel { get; set; } + + /// + /// 主营成本-科技部(科美业绩30%) + /// + public decimal CostTechDept { get; set; } + + /// + /// 主营成本-管理费(总业绩9%) + /// + public decimal CostManagementFee { get; set; } + + /// + /// 主营成本-合作(保留) + /// + public decimal CostCooperation { get; set; } + + /// + /// 主营成本-大项目(保留) + /// + public decimal CostMajorProject { get; set; } + + /// + /// 其他成本(退款差额<0) + /// + public decimal CostOther { get; set; } + + // 人工工资部分 + /// + /// 人工工资-健康师底薪 + /// + public decimal SalaryBaseHealthCoach { get; set; } + + /// + /// 人工工资-店助底薪 + /// + public decimal SalaryBaseAssistant { get; set; } + + /// + /// 人工工资-店助主任底薪 + /// + public decimal SalaryBaseDirector { get; set; } + + /// + /// 人工工资-店长底薪 + /// + public decimal SalaryBaseStoreManager { get; set; } + + /// + /// 人工工资-总经理/经理底薪 + /// + public decimal SalaryBaseGeneralManager { get; set; } + + /// + /// 人工工资-健康师提成 + /// + public decimal SalaryCommissionHealthCoach { get; set; } + + /// + /// 人工工资-店助提成 + /// + public decimal SalaryCommissionAssistant { get; set; } + + /// + /// 人工工资-店助主任提成 + /// + public decimal SalaryCommissionDirector { get; set; } + + /// + /// 人工工资-店长提成 + /// + public decimal SalaryCommissionStoreManager { get; set; } + + /// + /// 人工工资-总经理/经理提成 + /// + public decimal SalaryCommissionGeneralManager { get; set; } + + /// + /// 人工工资-手工 + /// + public decimal SalaryManual { get; set; } + + /// + /// 人工工资-出勤(保留) + /// + public decimal SalaryAttendance { get; set; } + + /// + /// 人工工资-岗位-手机保管费 + /// + public decimal SalaryPhoneCustody { get; set; } + + /// + /// 人工工资-岗位-人头 + /// + public decimal SalaryHeadcountReward { get; set; } + + /// + /// 人工工资-门店T区 + /// + public decimal SalaryTZone { get; set; } + + // 费用与其他 + /// + /// 社保(保留) + /// + public decimal SocialSecurity { get; set; } + + /// + /// 门店房租 + /// + public decimal StoreRent { get; set; } + + /// + /// 宿舍房租(保留) + /// + public decimal DormRent { get; set; } + + /// + /// 当期费用(报销) + /// + public decimal CurrentPeriodExpense { get; set; } + + /// + /// 当前费用-秦董(保留) + /// + public decimal CurrentPeriodExpenseQin { get; set; } + + /// + /// 财务费用(保留) + /// + public decimal FinancialFee { get; set; } + + // 奖励 + /// + /// 奖励-医美(保留) + /// + public decimal RewardMedicalBeauty { get; set; } + + /// + /// 奖励-其他(保留) + /// + public decimal RewardOther { get; set; } + + /// + /// 奖励-大单奖(保留) + /// + public decimal RewardLargeOrder { get; set; } + + /// + /// 奖励-首单奖(保留) + /// + public decimal RewardFirstOrder { get; set; } + + /// + /// 奖励(保留) + /// + public decimal RewardGeneral { get; set; } + + // 其他保留字段 + /// + /// 其他1(保留) + /// + public decimal Other1 { get; set; } + + /// + /// 其他2(保留) + /// + public decimal Other2 { get; set; } + + // 利润结果 + /// + /// 利润(预收-实退-主营成本-人工工资[分项汇总]-房租-费用-奖励-其他) + /// + public decimal Profit { get; set; } + + /// + /// 财务利润(主营-其他收入-主营成本-人工工资[分项汇总]-房租-费用-奖励-其他) + /// + public decimal FinancialProfit { get; set; } + + // 基础字段 + /// + /// 创建时间 + /// + public DateTime? CreateTime { get; set; } + + /// + /// 更新时间 + /// + public DateTime? UpdateTime { get; set; } + } +} diff --git a/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqShareStatisticsStore/ShareStatisticsStoreQueryInput.cs b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqShareStatisticsStore/ShareStatisticsStoreQueryInput.cs new file mode 100644 index 0000000..9ad52ee --- /dev/null +++ b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqShareStatisticsStore/ShareStatisticsStoreQueryInput.cs @@ -0,0 +1,25 @@ +using System; + +namespace NCC.Extend.Entitys.Dto.LqShareStatisticsStore +{ + /// + /// 门店股份统计查询输入 + /// + public class ShareStatisticsStoreQueryInput + { + /// + /// 统计月份(YYYYMM) + /// + public string StatisticsMonth { get; set; } + + /// + /// 门店ID(可选) + /// + public string StoreId { get; set; } + + /// + /// 门店名称(可选,模糊查询) + /// + public string StoreName { get; set; } + } +} diff --git a/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqShareStatisticsTechDept/ShareStatisticsTechDeptGenerateInput.cs b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqShareStatisticsTechDept/ShareStatisticsTechDeptGenerateInput.cs new file mode 100644 index 0000000..e0b29ed --- /dev/null +++ b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqShareStatisticsTechDept/ShareStatisticsTechDeptGenerateInput.cs @@ -0,0 +1,18 @@ +namespace NCC.Extend.Entitys.Dto.LqShareStatisticsTechDept +{ + /// + /// 科技部股份统计生成输入 + /// + public class ShareStatisticsTechDeptGenerateInput + { + /// + /// 统计月份(YYYYMM) + /// + public string StatisticsMonth { get; set; } + + /// + /// 部门名称(科技一部/科技二部,为空则生成两个部门) + /// + public string DepartmentName { get; set; } + } +} diff --git a/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqShareStatisticsTechDept/ShareStatisticsTechDeptOutput.cs b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqShareStatisticsTechDept/ShareStatisticsTechDeptOutput.cs new file mode 100644 index 0000000..6674655 --- /dev/null +++ b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqShareStatisticsTechDept/ShareStatisticsTechDeptOutput.cs @@ -0,0 +1,105 @@ +using System; + +namespace NCC.Extend.Entitys.Dto.LqShareStatisticsTechDept +{ + /// + /// 科技部股份统计输出 + /// + public class ShareStatisticsTechDeptOutput + { + /// + /// 主键ID + /// + public string Id { get; set; } + + /// + /// 部门名称 + /// + public string DepartmentName { get; set; } + + /// + /// 统计月份 + /// + public string StatisticsMonth { get; set; } + + /// + /// 收入 + /// + public decimal Income { get; set; } + + /// + /// 成本-报销 + /// + public decimal CostReimbursement { get; set; } + + /// + /// 成本-人工-老师底薪 + /// + public decimal CostTeacherBase { get; set; } + + /// + /// 成本-人工-手工费 + /// + public decimal CostTeacherManual { get; set; } + + /// + /// 成本-人工-开单提成 + /// + public decimal CostTeacherBillingComm { get; set; } + + /// + /// 成本-人工-消耗提成 + /// + public decimal CostTeacherConsumeComm { get; set; } + + /// + /// 成本-人工-专家提成 + /// + public decimal CostTeacherExpertComm { get; set; } + + /// + /// 成本-人工-加班 + /// + public decimal CostTeacherOvertime { get; set; } + + /// + /// 成本-人工-总经理底薪 + /// + public decimal CostGMBase { get; set; } + + /// + /// 成本-人工-总经理提成 + /// + public decimal CostGMComm { get; set; } + + /// + /// 奖励-科技部 + /// + public decimal RewardTechDept { get; set; } + + /// + /// 成本-其他1 + /// + public decimal CostOther1 { get; set; } + + /// + /// 成本-其他2 + /// + public decimal CostOther2 { get; set; } + + /// + /// 利润 + /// + public decimal Profit { get; set; } + + /// + /// 创建时间 + /// + public DateTime CreateTime { get; set; } + + /// + /// 更新时间 + /// + public DateTime? UpdateTime { get; set; } + } +} diff --git a/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqShareStatisticsTechDept/ShareStatisticsTechDeptQueryInput.cs b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqShareStatisticsTechDept/ShareStatisticsTechDeptQueryInput.cs new file mode 100644 index 0000000..573e7be --- /dev/null +++ b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqShareStatisticsTechDept/ShareStatisticsTechDeptQueryInput.cs @@ -0,0 +1,18 @@ +namespace NCC.Extend.Entitys.Dto.LqShareStatisticsTechDept +{ + /// + /// 科技部股份统计查询输入 + /// + public class ShareStatisticsTechDeptQueryInput + { + /// + /// 统计月份(YYYYMM) + /// + public string StatisticsMonth { get; set; } + + /// + /// 部门名称 + /// + public string DepartmentName { get; set; } + } +} diff --git a/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Entity/lq_share_statistics_hq/LqShareStatisticsHqEntity.cs b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Entity/lq_share_statistics_hq/LqShareStatisticsHqEntity.cs new file mode 100644 index 0000000..b7c81e4 --- /dev/null +++ b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Entity/lq_share_statistics_hq/LqShareStatisticsHqEntity.cs @@ -0,0 +1,104 @@ +using System; +using NCC.Common.Const; +using SqlSugar; + +namespace NCC.Extend.Entitys.lq_share_statistics_hq +{ + /// + /// 总部股份统计表 + /// + [SugarTable("lq_share_statistics_hq")] + [Tenant(ClaimConst.TENANT_ID)] + public class LqShareStatisticsHqEntity + { + /// + /// 主键ID + /// + [SugarColumn(ColumnName = "F_Id", IsPrimaryKey = true)] + public string Id { get; set; } + + /// + /// 统计月份(YYYYMM) + /// + [SugarColumn(ColumnName = "F_StatisticsMonth")] + public string StatisticsMonth { get; set; } + + /// + /// 收入-全部(开单业绩9%) + /// + [SugarColumn(ColumnName = "F_IncomeGeneral")] + public decimal IncomeGeneral { get; set; } + + /// + /// 收入-科技部(科美30%的9%) + /// + [SugarColumn(ColumnName = "F_IncomeTechDept")] + public decimal IncomeTechDept { get; set; } + + /// + /// 成本-报销(总部费用) + /// + [SugarColumn(ColumnName = "F_CostReimbursement")] + public decimal CostReimbursement { get; set; } + + /// + /// 成本-人工(保留) + /// + [SugarColumn(ColumnName = "F_CostLabor")] + public decimal CostLabor { get; set; } + + /// + /// 成本-教育部房租 + /// + [SugarColumn(ColumnName = "F_CostEducationRent")] + public decimal CostEducationRent { get; set; } + + /// + /// 成本-仓库房租 + /// + [SugarColumn(ColumnName = "F_CostWarehouseRent")] + public decimal CostWarehouseRent { get; set; } + + /// + /// 成本-总部房租 + /// + [SugarColumn(ColumnName = "F_CostHQRent")] + public decimal CostHQRent { get; set; } + + /// + /// 总部运营利润 + /// + [SugarColumn(ColumnName = "F_OperationalProfit")] + public decimal OperationalProfit { get; set; } + + /// + /// 创建时间 + /// + [SugarColumn(ColumnName = "F_CreateTime")] + public DateTime CreateTime { get; set; } + + /// + /// 更新时间 + /// + [SugarColumn(ColumnName = "F_UpdateTime")] + public DateTime? UpdateTime { get; set; } + + /// + /// 创建人 + /// + [SugarColumn(ColumnName = "F_CreateUser")] + public string CreateUser { get; set; } + + /// + /// 更新人 + /// + [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_share_statistics_store/LqShareStatisticsStoreEntity.cs b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Entity/lq_share_statistics_store/LqShareStatisticsStoreEntity.cs new file mode 100644 index 0000000..29eb161 --- /dev/null +++ b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Entity/lq_share_statistics_store/LqShareStatisticsStoreEntity.cs @@ -0,0 +1,340 @@ +using System; +using NCC.Common.Const; +using SqlSugar; + +namespace NCC.Extend.Entitys.lq_share_statistics_store +{ + /// + /// 门店股份统计表 + /// + [SugarTable("lq_share_statistics_store")] + [Tenant(ClaimConst.TENANT_ID)] + public class LqShareStatisticsStoreEntity + { + /// + /// 主键ID + /// + [SugarColumn(ColumnName = "F_Id", IsPrimaryKey = true)] + public string Id { get; set; } + + /// + /// 门店ID + /// + [SugarColumn(ColumnName = "F_StoreId")] + public string StoreId { get; set; } + + /// + /// 门店名称 + /// + [SugarColumn(ColumnName = "F_StoreName")] + public string StoreName { get; set; } + + /// + /// 统计月份(YYYYMM) + /// + [SugarColumn(ColumnName = "F_StatisticsMonth")] + public string StatisticsMonth { get; set; } + + // 收入部分 + /// + /// 主营收入(消耗业绩-对应退款) + /// + [SugarColumn(ColumnName = "F_MainIncome")] + public decimal MainIncome { get; set; } + + /// + /// 其他收入(退款差额>0) + /// + [SugarColumn(ColumnName = "F_OtherIncome")] + public decimal OtherIncome { get; set; } + + /// + /// 预收款(开单实付) + /// + [SugarColumn(ColumnName = "F_AdvanceReceipt")] + public decimal AdvanceReceipt { get; set; } + + /// + /// 实际退款(实退业绩) + /// + [SugarColumn(ColumnName = "F_Refund")] + public decimal Refund { get; set; } + + /// + /// 应收(合作医院) + /// + [SugarColumn(ColumnName = "F_Receivables")] + public decimal Receivables { get; set; } + + /// + /// 银行存款(开单实付-应收) + /// + [SugarColumn(ColumnName = "F_BankDeposit")] + public decimal BankDeposit { get; set; } + + // 成本部分 + /// + /// 主营成本-产品(仓库领取) + /// + [SugarColumn(ColumnName = "F_CostProduct")] + public decimal CostProduct { get; set; } + + /// + /// 主营成本-福田(福田仓库领取) + /// + [SugarColumn(ColumnName = "F_CostFutian")] + public decimal CostFutian { get; set; } + + /// + /// 主营成本-毛巾(清洗送出) + /// + [SugarColumn(ColumnName = "F_CostTowel")] + public decimal CostTowel { get; set; } + + /// + /// 主营成本-科技部(科美业绩30%) + /// + [SugarColumn(ColumnName = "F_CostTechDept")] + public decimal CostTechDept { get; set; } + + /// + /// 主营成本-管理费(总业绩9%) + /// + [SugarColumn(ColumnName = "F_CostManagementFee")] + public decimal CostManagementFee { get; set; } + + /// + /// 主营成本-合作(保留) + /// + [SugarColumn(ColumnName = "F_CostCooperation")] + public decimal CostCooperation { get; set; } + + /// + /// 主营成本-大项目(保留) + /// + [SugarColumn(ColumnName = "F_CostMajorProject")] + public decimal CostMajorProject { get; set; } + + /// + /// 其他成本(退款差额<0) + /// + [SugarColumn(ColumnName = "F_CostOther")] + public decimal CostOther { get; set; } + + // 人工工资部分 + /// + /// 人工工资-健康师底薪 + /// + [SugarColumn(ColumnName = "F_SalaryBaseHealthCoach")] + public decimal SalaryBaseHealthCoach { get; set; } + + /// + /// 人工工资-店助底薪 + /// + [SugarColumn(ColumnName = "F_SalaryBaseAssistant")] + public decimal SalaryBaseAssistant { get; set; } + + /// + /// 人工工资-店助主任底薪 + /// + [SugarColumn(ColumnName = "F_SalaryBaseDirector")] + public decimal SalaryBaseDirector { get; set; } + + /// + /// 人工工资-店长底薪 + /// + [SugarColumn(ColumnName = "F_SalaryBaseStoreManager")] + public decimal SalaryBaseStoreManager { get; set; } + + /// + /// 人工工资-总经理/经理底薪 + /// + [SugarColumn(ColumnName = "F_SalaryBaseGeneralManager")] + public decimal SalaryBaseGeneralManager { get; set; } + + /// + /// 人工工资-健康师提成 + /// + [SugarColumn(ColumnName = "F_SalaryCommissionHealthCoach")] + public decimal SalaryCommissionHealthCoach { get; set; } + + /// + /// 人工工资-店助提成 + /// + [SugarColumn(ColumnName = "F_SalaryCommissionAssistant")] + public decimal SalaryCommissionAssistant { get; set; } + + /// + /// 人工工资-店助主任提成 + /// + [SugarColumn(ColumnName = "F_SalaryCommissionDirector")] + public decimal SalaryCommissionDirector { get; set; } + + /// + /// 人工工资-店长提成 + /// + [SugarColumn(ColumnName = "F_SalaryCommissionStoreManager")] + public decimal SalaryCommissionStoreManager { get; set; } + + /// + /// 人工工资-总经理/经理提成 + /// + [SugarColumn(ColumnName = "F_SalaryCommissionGeneralManager")] + public decimal SalaryCommissionGeneralManager { get; set; } + + /// + /// 人工工资-手工 + /// + [SugarColumn(ColumnName = "F_SalaryManual")] + public decimal SalaryManual { get; set; } + + /// + /// 人工工资-出勤(保留) + /// + [SugarColumn(ColumnName = "F_SalaryAttendance")] + public decimal SalaryAttendance { get; set; } + + /// + /// 人工工资-岗位-手机保管费 + /// + [SugarColumn(ColumnName = "F_SalaryPhoneCustody")] + public decimal SalaryPhoneCustody { get; set; } + + /// + /// 人工工资-岗位-人头 + /// + [SugarColumn(ColumnName = "F_SalaryHeadcountReward")] + public decimal SalaryHeadcountReward { get; set; } + + /// + /// 人工工资-门店T区 + /// + [SugarColumn(ColumnName = "F_SalaryTZone")] + public decimal SalaryTZone { get; set; } + + // 费用与其他 + /// + /// 社保(保留) + /// + [SugarColumn(ColumnName = "F_SocialSecurity")] + public decimal SocialSecurity { get; set; } + + /// + /// 门店房租 + /// + [SugarColumn(ColumnName = "F_StoreRent")] + public decimal StoreRent { get; set; } + + /// + /// 宿舍房租(保留) + /// + [SugarColumn(ColumnName = "F_DormRent")] + public decimal DormRent { get; set; } + + /// + /// 当期费用(报销) + /// + [SugarColumn(ColumnName = "F_CurrentPeriodExpense")] + public decimal CurrentPeriodExpense { get; set; } + + /// + /// 当前费用-秦董(保留) + /// + [SugarColumn(ColumnName = "F_CurrentPeriodExpenseQin")] + public decimal CurrentPeriodExpenseQin { get; set; } + + /// + /// 财务费用(保留) + /// + [SugarColumn(ColumnName = "F_FinancialFee")] + public decimal FinancialFee { get; set; } + + // 奖励 + /// + /// 奖励-医美(保留) + /// + [SugarColumn(ColumnName = "F_RewardMedicalBeauty")] + public decimal RewardMedicalBeauty { get; set; } + + /// + /// 奖励-其他(保留) + /// + [SugarColumn(ColumnName = "F_RewardOther")] + public decimal RewardOther { get; set; } + + /// + /// 奖励-大单奖(保留) + /// + [SugarColumn(ColumnName = "F_RewardLargeOrder")] + public decimal RewardLargeOrder { get; set; } + + /// + /// 奖励-首单奖(保留) + /// + [SugarColumn(ColumnName = "F_RewardFirstOrder")] + public decimal RewardFirstOrder { get; set; } + + /// + /// 奖励(保留) + /// + [SugarColumn(ColumnName = "F_RewardGeneral")] + public decimal RewardGeneral { get; set; } + + // 其他保留字段 + /// + /// 其他1(保留) + /// + [SugarColumn(ColumnName = "F_Other1")] + public decimal Other1 { get; set; } + + /// + /// 其他2(保留) + /// + [SugarColumn(ColumnName = "F_Other2")] + public decimal Other2 { get; set; } + + // 利润结果 + /// + /// 利润(预收-实退-主营成本-人工工资[分项汇总]-房租-费用-奖励-其他) + /// + [SugarColumn(ColumnName = "F_Profit")] + public decimal Profit { get; set; } + + /// + /// 财务利润(主营-其他收入-主营成本-人工工资[分项汇总]-房租-费用-奖励-其他) + /// + [SugarColumn(ColumnName = "F_FinancialProfit")] + public decimal FinancialProfit { get; set; } + + // 基础字段 + /// + /// 创建时间 + /// + [SugarColumn(ColumnName = "F_CreateTime")] + public DateTime? CreateTime { get; set; } + + /// + /// 更新时间 + /// + [SugarColumn(ColumnName = "F_UpdateTime")] + public DateTime? UpdateTime { get; set; } + + /// + /// 创建人 + /// + [SugarColumn(ColumnName = "F_CreateUser")] + public string CreateUser { get; set; } + + /// + /// 更新人 + /// + [SugarColumn(ColumnName = "F_UpdateUser")] + public string UpdateUser { get; set; } + + /// + /// 是否有效(1:有效 0:无效) + /// + [SugarColumn(ColumnName = "F_IsEffective")] + public int IsEffective { get; set; } + } +} diff --git a/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Entity/lq_share_statistics_tech_dept/LqShareStatisticsTechDeptEntity.cs b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Entity/lq_share_statistics_tech_dept/LqShareStatisticsTechDeptEntity.cs new file mode 100644 index 0000000..96821f3 --- /dev/null +++ b/netcore/src/Modularity/Extend/NCC.Extend.Entitys/Entity/lq_share_statistics_tech_dept/LqShareStatisticsTechDeptEntity.cs @@ -0,0 +1,146 @@ +using System; +using NCC.Common.Const; +using SqlSugar; + +namespace NCC.Extend.Entitys.lq_share_statistics_tech_dept +{ + /// + /// 科技部股份统计表 + /// + [SugarTable("lq_share_statistics_tech_dept")] + [Tenant(ClaimConst.TENANT_ID)] + public class LqShareStatisticsTechDeptEntity + { + /// + /// 主键ID + /// + [SugarColumn(ColumnName = "F_Id", IsPrimaryKey = true)] + public string Id { get; set; } + + /// + /// 部门名称(科技一部/二部) + /// + [SugarColumn(ColumnName = "F_DepartmentName")] + public string DepartmentName { get; set; } + + /// + /// 统计月份(YYYYMM) + /// + [SugarColumn(ColumnName = "F_StatisticsMonth")] + public string StatisticsMonth { get; set; } + + /// + /// 收入(门店科美开单30%) + /// + [SugarColumn(ColumnName = "F_Income")] + public decimal Income { get; set; } + + /// + /// 成本-报销 + /// + [SugarColumn(ColumnName = "F_CostReimbursement")] + public decimal CostReimbursement { get; set; } + + /// + /// 成本-人工-科技部老师底薪 + /// + [SugarColumn(ColumnName = "F_CostTeacherBase")] + public decimal CostTeacherBase { get; set; } + + /// + /// 成本-人工-科技部手工费 + /// + [SugarColumn(ColumnName = "F_CostTeacherManual")] + public decimal CostTeacherManual { get; set; } + + /// + /// 成本-人工-科技部开单提成 + /// + [SugarColumn(ColumnName = "F_CostTeacherBillingComm")] + public decimal CostTeacherBillingComm { get; set; } + + /// + /// 成本-人工-科技部消耗提成 + /// + [SugarColumn(ColumnName = "F_CostTeacherConsumeComm")] + public decimal CostTeacherConsumeComm { get; set; } + + /// + /// 成本-人工-科技部专家提成(保留) + /// + [SugarColumn(ColumnName = "F_CostTeacherExpertComm")] + public decimal CostTeacherExpertComm { get; set; } + + /// + /// 成本-人工-科技部加班(保留) + /// + [SugarColumn(ColumnName = "F_CostTeacherOvertime")] + public decimal CostTeacherOvertime { get; set; } + + /// + /// 成本-人工-科技部总经理底薪 + /// + [SugarColumn(ColumnName = "F_CostGMBase")] + public decimal CostGMBase { get; set; } + + /// + /// 成本-人工-科技部总经理提成 + /// + [SugarColumn(ColumnName = "F_CostGMComm")] + public decimal CostGMComm { get; set; } + + /// + /// 奖励-科技部(保留) + /// + [SugarColumn(ColumnName = "F_RewardTechDept")] + public decimal RewardTechDept { get; set; } + + /// + /// 成本-其他1(保留) + /// + [SugarColumn(ColumnName = "F_CostOther1")] + public decimal CostOther1 { get; set; } + + /// + /// 成本-其他2(保留) + /// + [SugarColumn(ColumnName = "F_CostOther2")] + public decimal CostOther2 { get; set; } + + /// + /// 科技部利润 + /// + [SugarColumn(ColumnName = "F_Profit")] + public decimal Profit { get; set; } + + /// + /// 创建时间 + /// + [SugarColumn(ColumnName = "F_CreateTime")] + public DateTime CreateTime { get; set; } + + /// + /// 更新时间 + /// + [SugarColumn(ColumnName = "F_UpdateTime")] + public DateTime? UpdateTime { get; set; } + + /// + /// 创建人 + /// + [SugarColumn(ColumnName = "F_CreateUser")] + public string CreateUser { get; set; } + + /// + /// 更新人 + /// + [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/LqKdKdjlbService.cs b/netcore/src/Modularity/Extend/NCC.Extend/LqKdKdjlbService.cs index 66eec98..241d593 100644 --- a/netcore/src/Modularity/Extend/NCC.Extend/LqKdKdjlbService.cs +++ b/netcore/src/Modularity/Extend/NCC.Extend/LqKdKdjlbService.cs @@ -2294,6 +2294,7 @@ namespace NCC.Extend.LqKdKdjlb Sfyj = input.Sfyj, DeductAmount = input.DeductAmount, Qk = input.Qk, + Bz = input.Remark, UpdateTime = DateTime.Now }).Where(w => w.Id == input.BillingId).ExecuteCommandAsync(); diff --git a/netcore/src/Modularity/Extend/NCC.Extend/LqShareStatisticsHqService.cs b/netcore/src/Modularity/Extend/NCC.Extend/LqShareStatisticsHqService.cs new file mode 100644 index 0000000..1addbd2 --- /dev/null +++ b/netcore/src/Modularity/Extend/NCC.Extend/LqShareStatisticsHqService.cs @@ -0,0 +1,191 @@ +using Microsoft.AspNetCore.Mvc; +using NCC.Common.Filter; +using NCC.Dependency; +using NCC.DynamicApiController; +using NCC.Extend.Entitys.Dto.LqShareStatisticsHq; +using NCC.Extend.Entitys.lq_share_statistics_hq; +using NCC.Extend.Entitys.lq_kd_kdjlb; +using NCC.Extend.Entitys.lq_hytk_hytk; +using NCC.Extend.Entitys.lq_kd_pxmx; +using NCC.Extend.Entitys.lq_contract_rent_detail; +using SqlSugar; +using System; +using System.Linq; +using System.Threading.Tasks; +using Yitter.IdGenerator; + +namespace NCC.Extend +{ + /// + /// 总部股份统计服务 + /// + [ApiDescriptionSettings(Tag = "总部股份统计服务", Name = "LqShareStatisticsHq", Order = 402)] + [Route("api/Extend/[controller]")] + public class LqShareStatisticsHqService : IDynamicApiController, ITransient + { + private readonly ISqlSugarClient _db; + + public LqShareStatisticsHqService(ISqlSugarClient db) + { + _db = db; + } + + /// + /// 生成总部股份统计数据 + /// + /// 生成参数 + /// 生成结果 + [HttpPost("generate")] + public async Task GenerateStatistics([FromBody] ShareStatisticsHqGenerateInput input) + { + if (string.IsNullOrEmpty(input.StatisticsMonth) || input.StatisticsMonth.Length != 6) + { + return new { code = 500, msg = "统计月份格式错误,应为 YYYYMM" }; + } + + var year = int.Parse(input.StatisticsMonth.Substring(0, 4)); + var month = int.Parse(input.StatisticsMonth.Substring(4, 2)); + var startDate = new DateTime(year, month, 1); + var endDate = startDate.AddMonths(1).AddDays(-1); + + // 检查是否已存在 + var existing = await _db.Queryable() + .FirstAsync(x => x.StatisticsMonth == input.StatisticsMonth); + + var entity = existing ?? new LqShareStatisticsHqEntity + { + Id = YitIdHelper.NextId().ToString(), + StatisticsMonth = input.StatisticsMonth, + IsEffective = 1, + CreateTime = DateTime.Now, + CreateUser = "System" + }; + + // 计算各项数据 + await CalculateIncome(entity, startDate, endDate); + await CalculateCost(entity, startDate, endDate, input.StatisticsMonth); + CalculateProfit(entity); + + entity.UpdateTime = DateTime.Now; + entity.UpdateUser = "System"; + + if (existing == null) + { + await _db.Insertable(entity).ExecuteCommandAsync(); + return new { code = 200, msg = "生成成功", data = new { generated = true } }; + } + else + { + await _db.Updateable(entity).ExecuteCommandAsync(); + return new { code = 200, msg = "更新成功", data = new { updated = true } }; + } + } + + /// + /// 查询总部股份统计列表 + /// + /// 查询参数 + /// 统计列表 + [HttpGet("list")] + public async Task GetList([FromQuery] ShareStatisticsHqQueryInput input) + { + var query = _db.Queryable() + .Where(x => x.IsEffective == 1); + + if (!string.IsNullOrEmpty(input.StatisticsMonth)) + { + query = query.Where(x => x.StatisticsMonth == input.StatisticsMonth); + } + + var list = await query.OrderBy(x => x.StatisticsMonth, OrderByType.Desc) + .Select(x => new ShareStatisticsHqOutput + { + Id = x.Id, + StatisticsMonth = x.StatisticsMonth, + IncomeGeneral = x.IncomeGeneral, + IncomeTechDept = x.IncomeTechDept, + CostReimbursement = x.CostReimbursement, + CostLabor = x.CostLabor, + CostEducationRent = x.CostEducationRent, + CostWarehouseRent = x.CostWarehouseRent, + CostHQRent = x.CostHQRent, + OperationalProfit = x.OperationalProfit, + CreateTime = x.CreateTime, + UpdateTime = x.UpdateTime + }) + .ToListAsync(); + + return new { code = 200, msg = "查询成功", data = list }; + } + + #region 私有计算方法 + + /// + /// 计算收入部分 + /// + private async Task CalculateIncome(LqShareStatisticsHqEntity entity, DateTime startDate, DateTime endDate) + { + // 1. 收入-全部 = (所有门店的总开单实付业绩 - 所有门店的总实退金额) * 9% + var totalBilling = await _db.Queryable() + .Where(x => x.Kdrq >= startDate && x.Kdrq <= endDate && x.IsEffective == 1) + .SumAsync(x => x.Sfyj); + + var totalRefund = await _db.Queryable() + .Where(x => x.Tksj >= startDate && x.Tksj <= endDate && x.IsEffective == 1) + .SumAsync(x => x.Tkje ?? 0); + + entity.IncomeGeneral = (totalBilling - totalRefund) * 0.09m; + + // 2. 收入-科技部 = (总科美业绩 - 总科美退款) * 0.3 * 0.09 + var kemeiPerformance = await _db.Queryable() + .Where(x => x.Yjsj >= startDate && x.Yjsj <= endDate && x.IsEffective == 1) + .Where(x => x.ItemCategory == "科美") + .SumAsync(x => x.TotalPrice); + + // TODO: 需要确认科美退款的统计方式 + entity.IncomeTechDept = kemeiPerformance * 0.3m * 0.09m; + } + + /// + /// 计算成本部分 + /// + private async Task CalculateCost(LqShareStatisticsHqEntity entity, DateTime startDate, DateTime endDate, string statisticsMonth) + { + // 1. 成本-报销 (TODO: 需要确认总部报销的判定方式) + entity.CostReimbursement = 0; + + // 2. 成本-人工 (保留) + entity.CostLabor = 0; + + // 3. 成本-教育部房租 + // TODO: 需要确认如何识别教育部合同 + entity.CostEducationRent = 0; + + // 4. 成本-仓库房租 + // TODO: 需要确认如何识别仓库合同 + entity.CostWarehouseRent = 0; + + // 5. 成本-总部房租 + // TODO: 需要确认如何识别总部合同 + entity.CostHQRent = 0; + } + + /// + /// 计算利润 + /// + private void CalculateProfit(LqShareStatisticsHqEntity entity) + { + // 总部运营利润 = 收入(门店9%) + 收入(科技部9%) - 成本(报销) - 成本(人工) - 成本(房租) + var totalIncome = entity.IncomeGeneral + entity.IncomeTechDept; + var totalCost = entity.CostReimbursement + + entity.CostLabor + + entity.CostEducationRent + + entity.CostWarehouseRent + + entity.CostHQRent; + + entity.OperationalProfit = totalIncome - totalCost; + } + + #endregion + } +} diff --git a/netcore/src/Modularity/Extend/NCC.Extend/LqShareStatisticsStoreService.cs b/netcore/src/Modularity/Extend/NCC.Extend/LqShareStatisticsStoreService.cs new file mode 100644 index 0000000..36e7b68 --- /dev/null +++ b/netcore/src/Modularity/Extend/NCC.Extend/LqShareStatisticsStoreService.cs @@ -0,0 +1,500 @@ +using Microsoft.AspNetCore.Mvc; +using NCC.Common.Filter; +using NCC.Dependency; +using NCC.DynamicApiController; +using NCC.Extend.Entitys.Dto.LqShareStatisticsStore; +using NCC.Extend.Entitys.lq_share_statistics_store; +using NCC.Extend.Entitys.lq_xh_jksyj; +using NCC.Extend.Entitys.lq_kd_kdjlb; +using NCC.Extend.Entitys.lq_hytk_hytk; +using NCC.Extend.Entitys.lq_hytk_jksyj; +using NCC.Extend.Entitys.lq_inventory_usage; +using NCC.Extend.Entitys.lq_laundry_flow; +using NCC.Extend.Entitys.lq_salary_statistics; +using NCC.Extend.Entitys.lq_assistant_salary_statistics; +using NCC.Extend.Entitys.lq_director_salary_statistics; +using NCC.Extend.Entitys.lq_store_manager_salary_statistics; +using NCC.Extend.Entitys.lq_business_unit_manager_salary_statistics; +using NCC.Extend.Entitys.lq_contract_rent_detail; +using NCC.Extend.Entitys.lq_mdxx; +using NCC.Extend.Entitys.lq_kd_pxmx; +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Yitter.IdGenerator; + +namespace NCC.Extend +{ + /// + /// 门店股份统计服务 + /// + [ApiDescriptionSettings(Tag = "门店股份统计服务", Name = "LqShareStatisticsStore", Order = 400)] + [Route("api/Extend/[controller]")] + public class LqShareStatisticsStoreService : IDynamicApiController, ITransient + { + private readonly ISqlSugarClient _db; + + public LqShareStatisticsStoreService(ISqlSugarClient db) + { + _db = db; + } + + /// + /// 生成门店股份统计数据 + /// + /// 生成参数 + /// 生成结果 + [HttpPost("generate")] + public async Task GenerateStatistics([FromBody] ShareStatisticsStoreGenerateInput input) + { + if (string.IsNullOrEmpty(input.StatisticsMonth) || input.StatisticsMonth.Length != 6) + { + return new { code = 500, msg = "统计月份格式错误,应为 YYYYMM" }; + } + + var year = int.Parse(input.StatisticsMonth.Substring(0, 4)); + var month = int.Parse(input.StatisticsMonth.Substring(4, 2)); + var startDate = new DateTime(year, month, 1); + var endDate = startDate.AddMonths(1).AddDays(-1); + + // 获取门店列表 + var storeQuery = _db.Queryable(); + if (!string.IsNullOrEmpty(input.StoreId)) + { + storeQuery = storeQuery.Where(x => x.Id == input.StoreId); + } + var stores = await storeQuery.ToListAsync(); + + if (stores.Count == 0) + { + return new { code = 500, msg = "未找到有效门店" }; + } + + var generatedCount = 0; + var updatedCount = 0; + + foreach (var store in stores) + { + try + { + // 检查是否已存在 + var existing = await _db.Queryable() + .FirstAsync(x => x.StoreId == store.Id && x.StatisticsMonth == input.StatisticsMonth); + + var entity = existing ?? new LqShareStatisticsStoreEntity + { + Id = YitIdHelper.NextId().ToString(), + StoreId = store.Id, + StoreName = store.Dm, + StatisticsMonth = input.StatisticsMonth, + IsEffective = 1, + CreateTime = DateTime.Now, + CreateUser = "System" + }; + + // 计算各项数据 + await CalculateIncome(entity, startDate, endDate); + await CalculateCost(entity, startDate, endDate); + await CalculateSalary(entity, input.StatisticsMonth); + await CalculateExpense(entity, startDate, endDate, input.StatisticsMonth); + CalculateProfit(entity); + + entity.UpdateTime = DateTime.Now; + entity.UpdateUser = "System"; + + if (existing == null) + { + await _db.Insertable(entity).ExecuteCommandAsync(); + generatedCount++; + } + else + { + await _db.Updateable(entity).ExecuteCommandAsync(); + updatedCount++; + } + } + catch (Exception ex) + { + return new { code = 500, msg = $"处理门店 {store.Dm} 时出错: {ex.Message}, StackTrace: {ex.StackTrace}" }; + } + } + + return new + { + code = 200, + msg = "生成成功", + data = new + { + generatedCount, + updatedCount, + totalCount = stores.Count + } + }; + } + + /// + /// 查询门店股份统计列表 + /// + /// 查询参数 + /// 统计列表 + [HttpGet("list")] + public async Task GetList([FromQuery] ShareStatisticsStoreQueryInput input) + { + var query = _db.Queryable() + .Where(x => x.IsEffective == 1); + + if (!string.IsNullOrEmpty(input.StatisticsMonth)) + { + query = query.Where(x => x.StatisticsMonth == input.StatisticsMonth); + } + + if (!string.IsNullOrEmpty(input.StoreId)) + { + query = query.Where(x => x.StoreId == input.StoreId); + } + + if (!string.IsNullOrEmpty(input.StoreName)) + { + query = query.Where(x => x.StoreName.Contains(input.StoreName)); + } + + var list = await query.OrderBy(x => x.StatisticsMonth, OrderByType.Desc) + .OrderBy(x => x.StoreName) + .Select(x => new ShareStatisticsStoreOutput + { + Id = x.Id, + StoreId = x.StoreId, + StoreName = x.StoreName, + StatisticsMonth = x.StatisticsMonth, + MainIncome = x.MainIncome, + OtherIncome = x.OtherIncome, + AdvanceReceipt = x.AdvanceReceipt, + Refund = x.Refund, + Receivables = x.Receivables, + BankDeposit = x.BankDeposit, + CostProduct = x.CostProduct, + CostFutian = x.CostFutian, + CostTowel = x.CostTowel, + CostTechDept = x.CostTechDept, + CostManagementFee = x.CostManagementFee, + CostCooperation = x.CostCooperation, + CostMajorProject = x.CostMajorProject, + CostOther = x.CostOther, + SalaryBaseHealthCoach = x.SalaryBaseHealthCoach, + SalaryBaseAssistant = x.SalaryBaseAssistant, + SalaryBaseDirector = x.SalaryBaseDirector, + SalaryBaseStoreManager = x.SalaryBaseStoreManager, + SalaryBaseGeneralManager = x.SalaryBaseGeneralManager, + SalaryCommissionHealthCoach = x.SalaryCommissionHealthCoach, + SalaryCommissionAssistant = x.SalaryCommissionAssistant, + SalaryCommissionDirector = x.SalaryCommissionDirector, + SalaryCommissionStoreManager = x.SalaryCommissionStoreManager, + SalaryCommissionGeneralManager = x.SalaryCommissionGeneralManager, + SalaryManual = x.SalaryManual, + SalaryAttendance = x.SalaryAttendance, + SalaryPhoneCustody = x.SalaryPhoneCustody, + SalaryHeadcountReward = x.SalaryHeadcountReward, + SalaryTZone = x.SalaryTZone, + SocialSecurity = x.SocialSecurity, + StoreRent = x.StoreRent, + DormRent = x.DormRent, + CurrentPeriodExpense = x.CurrentPeriodExpense, + CurrentPeriodExpenseQin = x.CurrentPeriodExpenseQin, + FinancialFee = x.FinancialFee, + RewardMedicalBeauty = x.RewardMedicalBeauty, + RewardOther = x.RewardOther, + RewardLargeOrder = x.RewardLargeOrder, + RewardFirstOrder = x.RewardFirstOrder, + RewardGeneral = x.RewardGeneral, + Other1 = x.Other1, + Other2 = x.Other2, + Profit = x.Profit, + FinancialProfit = x.FinancialProfit, + CreateTime = x.CreateTime, + UpdateTime = x.UpdateTime + }) + .ToListAsync(); + + return new { code = 200, msg = "查询成功", data = list }; + } + + #region 私有计算方法 + + /// + /// 计算收入部分 + /// + private async Task CalculateIncome(LqShareStatisticsStoreEntity entity, DateTime startDate, DateTime endDate) + { + // 1. 主营收入 = 消耗业绩 - 消耗退款 + var consumePerformance = await _db.Queryable() + .Where(x => x.StoreId == entity.StoreId && x.Yjsj >= startDate && x.Yjsj <= endDate && x.IsEffective == 1) + .SumAsync(x => x.Jksyj); + + var consumeRefund = await _db.Queryable() + .Where(x => x.StoreId == entity.StoreId && x.Tksj >= startDate && x.Tksj <= endDate && x.IsEffective == 1) + .SumAsync(x => x.Jksyj); + + entity.MainIncome = (consumePerformance ?? 0) - (consumeRefund ?? 0); + + // 2. 预收款 = 开单实付 + entity.AdvanceReceipt = await _db.Queryable() + .Where(x => x.Djmd == entity.StoreId && x.Kdrq >= startDate && x.Kdrq <= endDate && x.IsEffective == 1) + .SumAsync(x => x.Sfyj); + + // 3. 实际退款 = 退卡实退金额 + entity.Refund = await _db.Queryable() + .Where(x => x.Md == entity.StoreId && x.Tksj >= startDate && x.Tksj <= endDate && x.IsEffective == 1) + .SumAsync(x => x.Tkje ?? 0); + + // 4. 应收 = 合作医院开单金额 + entity.Receivables = await _db.Queryable() + .Where(x => x.Djmd == entity.StoreId && x.Kdrq >= startDate && x.Kdrq <= endDate + && x.IsEffective == 1 && !string.IsNullOrEmpty(x.Fkyy)) + .SumAsync(x => x.Sfyj); + + // 5. 银行存款 = 开单实付 - 应收 + entity.BankDeposit = entity.AdvanceReceipt - entity.Receivables; + + // 6. 其他收入 = 退款差额 > 0 的部分 + var refundDiff = entity.Refund - (consumeRefund ?? 0); + entity.OtherIncome = refundDiff > 0 ? refundDiff : 0; + } + + /// + /// 计算成本部分 + /// + private async Task CalculateCost(LqShareStatisticsStoreEntity entity, DateTime startDate, DateTime endDate) + { + // 1. 产品成本 = 仓库领用金额 + entity.CostProduct = await _db.Queryable() + .Where(x => x.StoreId == entity.StoreId && x.UsageTime >= startDate && x.UsageTime <= endDate && x.IsEffective == 1) + .SumAsync(x => x.TotalAmount); + + // 2. 福田成本 = 福田仓库领用 (需要确认福田仓库ID) + // TODO: 需要确认福田仓库的识别方式 + entity.CostFutian = 0; + + // 3. 毛巾成本 = 洗毛巾费用 + entity.CostTowel = await _db.Queryable() + .Where(x => x.StoreId == entity.StoreId + && x.SendTime >= startDate && x.SendTime <= endDate + && x.IsEffective == 1) + .SumAsync(x => x.TotalPrice); + + // 4. 科技部成本 = 科美业绩 * 30% + var kemeiPerformance = await _db.Queryable() + .Where(x => x.Glkdbh.StartsWith(entity.StoreId) && x.Yjsj >= startDate && x.Yjsj <= endDate && x.IsEffective == 1) + .Where(x => x.ItemCategory == "科美") + .SumAsync(x => x.TotalPrice); + + entity.CostTechDept = kemeiPerformance * 0.3m; + + // 5. 管理费 = 总业绩 * 9% + var totalPerformance = await _db.Queryable() + .Where(x => x.Djmd == entity.StoreId && x.Kdrq >= startDate && x.Kdrq <= endDate && x.IsEffective == 1) + .SumAsync(x => x.Sfyj); + + entity.CostManagementFee = totalPerformance * 0.09m; + + // 6. 其他成本 = 退款差额 < 0 的部分 + var consumeRefund = await _db.Queryable() + .Where(x => x.StoreId == entity.StoreId && x.Tksj >= startDate && x.Tksj <= endDate && x.IsEffective == 1) + .SumAsync(x => x.Jksyj ?? 0); + + var refundDiff = entity.Refund - consumeRefund; + entity.CostOther = refundDiff < 0 ? Math.Abs(refundDiff) : 0; + + // 保留字段暂时为0 + entity.CostCooperation = 0; + entity.CostMajorProject = 0; + } + + /// + /// 计算人工工资部分 + /// + private async Task CalculateSalary(LqShareStatisticsStoreEntity entity, string statisticsMonth) + { + // 1. 健康师底薪和提成 + var healthCoachSalary = await _db.Queryable() + .Where(x => x.StoreId == entity.StoreId && x.StatisticsMonth == statisticsMonth) + .Select(x => new + { + BaseSalary = SqlFunc.AggregateSum(x.HealthCoachBaseSalary), + Commission = SqlFunc.AggregateSum(x.TotalCommission), + Manual = SqlFunc.AggregateSum(x.HandworkFee), + TZone = SqlFunc.AggregateSum(x.StoreTZoneCommission) + }) + .FirstAsync(); + + entity.SalaryBaseHealthCoach = healthCoachSalary?.BaseSalary ?? 0; + entity.SalaryCommissionHealthCoach = healthCoachSalary?.Commission ?? 0; + entity.SalaryManual = healthCoachSalary?.Manual ?? 0; + entity.SalaryTZone = healthCoachSalary?.TZone ?? 0; + + // 2. 店助底薪和提成 + var assistantSalary = await _db.Queryable() + .Where(x => x.StoreId == entity.StoreId && x.StatisticsMonth == statisticsMonth + && x.Position == "店助") + .Select(x => new + { + BaseSalary = SqlFunc.AggregateSum(x.BaseSalary), + Commission = SqlFunc.AggregateSum(x.CommissionAmount), + PhoneCustody = SqlFunc.AggregateSum(x.PhoneManagementFee), + HeadcountReward = SqlFunc.AggregateSum(x.Stage1Reward + x.Stage2Reward) + }) + .FirstAsync(); + + entity.SalaryBaseAssistant = assistantSalary?.BaseSalary ?? 0; + entity.SalaryCommissionAssistant = assistantSalary?.Commission ?? 0; + entity.SalaryPhoneCustody = assistantSalary?.PhoneCustody ?? 0; + entity.SalaryHeadcountReward = assistantSalary?.HeadcountReward ?? 0; + + // 3. 店助主任底薪和提成 + var directorSalary = await _db.Queryable() + .Where(x => x.StoreId == entity.StoreId && x.StatisticsMonth == statisticsMonth) + .Select(x => new + { + BaseSalary = SqlFunc.AggregateSum(x.ActualBaseSalary), + Commission = SqlFunc.AggregateSum(x.TotalCommissionAmount) + }) + .FirstAsync(); + + entity.SalaryBaseDirector = directorSalary?.BaseSalary ?? 0; + entity.SalaryCommissionDirector = directorSalary?.Commission ?? 0; + + // 4. 店长底薪和提成 + var storeManagerSalary = await _db.Queryable() + .Where(x => x.StoreId == entity.StoreId && x.StatisticsMonth == statisticsMonth) + .Select(x => new + { + BaseSalary = SqlFunc.AggregateSum(x.ActualBaseSalary), + Commission = SqlFunc.AggregateSum(x.CommissionAmount) + }) + .FirstAsync(); + + entity.SalaryBaseStoreManager = storeManagerSalary?.BaseSalary ?? 0; + entity.SalaryCommissionStoreManager = storeManagerSalary?.Commission ?? 0; + + // 5. 总经理/经理底薪和提成 + // 底薪按门店数平均分摊,提成需要从 F_StorePerformanceDetail JSON 中提取该门店的提成 + var gmSalary = await _db.Queryable() + .Where(x => x.StatisticsMonth == statisticsMonth) + .Where(x => x.StorePerformanceDetail.Contains(entity.StoreId)) + .ToListAsync(); + + decimal gmBaseSalary = 0; + decimal gmCommission = 0; + + foreach (var gm in gmSalary) + { + // 底薪平均分摊 + if (!string.IsNullOrEmpty(gm.StorePerformanceDetail)) + { + try + { + var storeDetails = Newtonsoft.Json.JsonConvert.DeserializeObject>>(gm.StorePerformanceDetail); + var storeCount = storeDetails?.Count ?? 1; + gmBaseSalary += gm.BaseSalary / storeCount; + + // 提取该门店的提成 + var storeDetail = storeDetails?.FirstOrDefault(s => s.ContainsKey("StoreId") && s["StoreId"].ToString() == entity.StoreId); + if (storeDetail != null && storeDetail.ContainsKey("Commission")) + { + gmCommission += Convert.ToDecimal(storeDetail["Commission"]); + } + } + catch + { + // JSON 解析失败,使用默认分摊 + gmBaseSalary += gm.BaseSalary; + } + } + } + + entity.SalaryBaseGeneralManager = gmBaseSalary; + entity.SalaryCommissionGeneralManager = gmCommission; + + // 保留字段 + entity.SalaryAttendance = 0; + } + + /// + /// 计算费用部分 + /// + private async Task CalculateExpense(LqShareStatisticsStoreEntity entity, DateTime startDate, DateTime endDate, string statisticsMonth) + { + // 1. 门店房租 - 需要通过合同关联门店 + // 从合同表关联租金明细 + // 解析统计月份 + var year = int.Parse(statisticsMonth.Substring(0, 4)); + var month = int.Parse(statisticsMonth.Substring(4, 2)); + + var rentDetail = await _db.Queryable((rd, c) => new JoinQueryInfos( + JoinType.Inner, rd.ContractId == c.Id)) + .Where((rd, c) => c.StoreId == entity.StoreId + && rd.PaymentMonth.Year == year + && rd.PaymentMonth.Month == month + && rd.IsEffective == 1) + .Select((rd, c) => rd.DueAmount) + .ToListAsync(); + + entity.StoreRent = rentDetail.Sum(); + + // 2. 当期费用 = 报销 + // TODO: 需要根据报销分类来筛选门店相关费用 + entity.CurrentPeriodExpense = 0; + + // 保留字段 + entity.SocialSecurity = 0; + entity.DormRent = 0; + entity.CurrentPeriodExpenseQin = 0; + entity.FinancialFee = 0; + entity.RewardMedicalBeauty = 0; + entity.RewardOther = 0; + entity.RewardLargeOrder = 0; + entity.RewardFirstOrder = 0; + entity.RewardGeneral = 0; + entity.Other1 = 0; + entity.Other2 = 0; + } + + /// + /// 计算利润 + /// + private void CalculateProfit(LqShareStatisticsStoreEntity entity) + { + // 人工工资汇总 + var totalSalary = entity.SalaryBaseHealthCoach + entity.SalaryBaseAssistant + entity.SalaryBaseDirector + + entity.SalaryBaseStoreManager + entity.SalaryBaseGeneralManager + + entity.SalaryCommissionHealthCoach + entity.SalaryCommissionAssistant + entity.SalaryCommissionDirector + + entity.SalaryCommissionStoreManager + entity.SalaryCommissionGeneralManager + + entity.SalaryManual + entity.SalaryAttendance + entity.SalaryPhoneCustody + + entity.SalaryHeadcountReward + entity.SalaryTZone; + + // 主营成本汇总 + var totalCost = entity.CostProduct + entity.CostFutian + entity.CostTowel + entity.CostTechDept + + entity.CostManagementFee + entity.CostCooperation + entity.CostMajorProject + entity.CostOther; + + // 费用汇总 + var totalExpense = entity.SocialSecurity + entity.StoreRent + entity.DormRent + entity.CurrentPeriodExpense + + entity.CurrentPeriodExpenseQin + entity.FinancialFee; + + // 奖励汇总 + var totalReward = entity.RewardMedicalBeauty + entity.RewardOther + entity.RewardLargeOrder + + entity.RewardFirstOrder + entity.RewardGeneral; + + // 其他汇总 + var totalOther = entity.Other1 + entity.Other2; + + // 利润 = 预收 - 实退 - 主营成本 - 人工工资 - 房租 - 费用 - 奖励 - 其他 + entity.Profit = entity.AdvanceReceipt - entity.Refund - totalCost - totalSalary - totalExpense - totalReward - totalOther; + + // 财务利润 = 主营收入 + 其他收入 - 主营成本 - 人工工资 - 房租 - 费用 - 奖励 - 其他 + entity.FinancialProfit = entity.MainIncome + entity.OtherIncome - totalCost - totalSalary - totalExpense - totalReward - totalOther; + } + + #endregion + } +} diff --git a/netcore/src/Modularity/Extend/NCC.Extend/LqShareStatisticsTechDeptService.cs b/netcore/src/Modularity/Extend/NCC.Extend/LqShareStatisticsTechDeptService.cs new file mode 100644 index 0000000..974123a --- /dev/null +++ b/netcore/src/Modularity/Extend/NCC.Extend/LqShareStatisticsTechDeptService.cs @@ -0,0 +1,262 @@ +using Microsoft.AspNetCore.Mvc; +using NCC.Common.Filter; +using NCC.Dependency; +using NCC.DynamicApiController; +using NCC.Extend.Entitys.Dto.LqShareStatisticsTechDept; +using NCC.Extend.Entitys.lq_share_statistics_tech_dept; +using NCC.Extend.Entitys.lq_mdxx; +using NCC.Extend.Entitys.lq_kd_pxmx; +using NCC.Extend.Entitys.lq_kd_kdjlb; +using NCC.Extend.Entitys.lq_hytk_jksyj; +using NCC.Extend.Entitys.lq_xh_jksyj; +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Yitter.IdGenerator; + +namespace NCC.Extend +{ + /// + /// 科技部股份统计服务 + /// + [ApiDescriptionSettings(Tag = "科技部股份统计服务", Name = "LqShareStatisticsTechDept", Order = 401)] + [Route("api/Extend/[controller]")] + public class LqShareStatisticsTechDeptService : IDynamicApiController, ITransient + { + private readonly ISqlSugarClient _db; + + public LqShareStatisticsTechDeptService(ISqlSugarClient db) + { + _db = db; + } + + /// + /// 生成科技部股份统计数据 + /// + /// 生成参数 + /// 生成结果 + [HttpPost("generate")] + public async Task GenerateStatistics([FromBody] ShareStatisticsTechDeptGenerateInput input) + { + if (string.IsNullOrEmpty(input.StatisticsMonth) || input.StatisticsMonth.Length != 6) + { + return new { code = 500, msg = "统计月份格式错误,应为 YYYYMM" }; + } + + var year = int.Parse(input.StatisticsMonth.Substring(0, 4)); + var month = int.Parse(input.StatisticsMonth.Substring(4, 2)); + var startDate = new DateTime(year, month, 1); + var endDate = startDate.AddMonths(1).AddDays(-1); + + // 确定要生成的部门列表 + var departments = new List(); + if (!string.IsNullOrEmpty(input.DepartmentName)) + { + departments.Add(input.DepartmentName); + } + else + { + departments.Add("科技一部"); + departments.Add("科技二部"); + } + + var generatedCount = 0; + var updatedCount = 0; + + foreach (var deptName in departments) + { + // 检查是否已存在 + var existing = await _db.Queryable() + .FirstAsync(x => x.DepartmentName == deptName && x.StatisticsMonth == input.StatisticsMonth); + + var entity = existing ?? new LqShareStatisticsTechDeptEntity + { + Id = YitIdHelper.NextId().ToString(), + DepartmentName = deptName, + StatisticsMonth = input.StatisticsMonth, + IsEffective = 1, + CreateTime = DateTime.Now, + CreateUser = "System" + }; + + // 计算各项数据 + await CalculateIncome(entity, deptName, startDate, endDate); + await CalculateCost(entity, deptName, startDate, endDate, input.StatisticsMonth); + CalculateProfit(entity); + + entity.UpdateTime = DateTime.Now; + entity.UpdateUser = "System"; + + if (existing == null) + { + await _db.Insertable(entity).ExecuteCommandAsync(); + generatedCount++; + } + else + { + await _db.Updateable(entity).ExecuteCommandAsync(); + updatedCount++; + } + } + + return new + { + code = 200, + msg = "生成成功", + data = new + { + generatedCount, + updatedCount, + totalCount = departments.Count + } + }; + } + + /// + /// 查询科技部股份统计列表 + /// + /// 查询参数 + /// 统计列表 + [HttpGet("list")] + public async Task GetList([FromQuery] ShareStatisticsTechDeptQueryInput input) + { + var query = _db.Queryable() + .Where(x => x.IsEffective == 1); + + if (!string.IsNullOrEmpty(input.StatisticsMonth)) + { + query = query.Where(x => x.StatisticsMonth == input.StatisticsMonth); + } + + if (!string.IsNullOrEmpty(input.DepartmentName)) + { + query = query.Where(x => x.DepartmentName == input.DepartmentName); + } + + var list = await query.OrderBy(x => x.StatisticsMonth, OrderByType.Desc) + .OrderBy(x => x.DepartmentName) + .Select(x => new ShareStatisticsTechDeptOutput + { + Id = x.Id, + DepartmentName = x.DepartmentName, + StatisticsMonth = x.StatisticsMonth, + Income = x.Income, + CostReimbursement = x.CostReimbursement, + CostTeacherBase = x.CostTeacherBase, + CostTeacherManual = x.CostTeacherManual, + CostTeacherBillingComm = x.CostTeacherBillingComm, + CostTeacherConsumeComm = x.CostTeacherConsumeComm, + CostTeacherExpertComm = x.CostTeacherExpertComm, + CostTeacherOvertime = x.CostTeacherOvertime, + CostGMBase = x.CostGMBase, + CostGMComm = x.CostGMComm, + RewardTechDept = x.RewardTechDept, + CostOther1 = x.CostOther1, + CostOther2 = x.CostOther2, + Profit = x.Profit, + CreateTime = x.CreateTime, + UpdateTime = x.UpdateTime + }) + .ToListAsync(); + + return new { code = 200, msg = "查询成功", data = list }; + } + + #region 私有计算方法 + + /// + /// 计算收入部分 + /// + private async Task CalculateIncome(LqShareStatisticsTechDeptEntity entity, string deptName, DateTime startDate, DateTime endDate) + { + // 1. 找到该科技部管辖的所有门店 + var stores = await _db.Queryable() + .Where(x => x.Kjb == deptName) + .Select(x => x.Id) + .ToListAsync(); + + if (stores.Count == 0) + { + entity.Income = 0; + return; + } + + // 2. 统计这些门店的科美项目开单实付业绩 + // 需要关联 lq_kd_kdjlb 来获取门店信息 + var kemeiIncome = await _db.Queryable((px, kd) => new JoinQueryInfos( + JoinType.Inner, px.Glkdbh == kd.Id)) + .Where((px, kd) => stores.Contains(kd.Djmd) && px.Yjsj >= startDate && px.Yjsj <= endDate && px.IsEffective == 1) + .Where((px, kd) => px.ItemCategory == "科美") + .SumAsync((px, kd) => px.TotalPrice); + + // 3. 减去对应的科美项目实退金额 + var kemeiRefund = await _db.Queryable() + .Where(x => stores.Contains(x.StoreId) && x.Tksj >= startDate && x.Tksj <= endDate && x.IsEffective == 1) + .Where(x => x.ItemCategory == "科美") + .SumAsync(x => x.Jksyj ?? 0); + + // 4. 结果 * 30% + entity.Income = (kemeiIncome - kemeiRefund) * 0.3m; + } + + /// + /// 计算成本部分 + /// + private async Task CalculateCost(LqShareStatisticsTechDeptEntity entity, string deptName, DateTime startDate, DateTime endDate, string statisticsMonth) + { + // 1. 成本-报销 (TODO: 需要确认报销分类的具体判定方式) + entity.CostReimbursement = 0; + + // 2. 成本-人工-科技部老师底薪 (TODO: 需要确认科技部老师工资表名和字段) + entity.CostTeacherBase = 0; + + // 3. 成本-人工-科技部手工费 + // 从消耗表中统计科技部老师的手工费 + // TODO: 需要确认如何识别科技部老师 + entity.CostTeacherManual = 0; + + // 4. 成本-人工-科技部开单提成 (TODO: 需要确认字段名) + entity.CostTeacherBillingComm = 0; + + // 5. 成本-人工-科技部消耗提成 (TODO: 需要确认字段名) + entity.CostTeacherConsumeComm = 0; + + // 6. 成本-人工-科技部总经理 (TODO: 需要确认科技部总经理工资表) + entity.CostGMBase = 0; + entity.CostGMComm = 0; + + // 保留字段 + entity.CostTeacherExpertComm = 0; + entity.CostTeacherOvertime = 0; + entity.RewardTechDept = 0; + entity.CostOther1 = 0; + entity.CostOther2 = 0; + } + + /// + /// 计算利润 + /// + private void CalculateProfit(LqShareStatisticsTechDeptEntity entity) + { + // 科技部利润 = 收入 - 成本报销 - 成本人工 - 其他 + var totalCost = entity.CostReimbursement + + entity.CostTeacherBase + + entity.CostTeacherManual + + entity.CostTeacherBillingComm + + entity.CostTeacherConsumeComm + + entity.CostTeacherExpertComm + + entity.CostTeacherOvertime + + entity.CostGMBase + + entity.CostGMComm + + entity.RewardTechDept + + entity.CostOther1 + + entity.CostOther2; + + entity.Profit = entity.Income - totalCost; + } + + #endregion + } +} diff --git a/sql/排查生美业绩统计差异-简化版.sql b/sql/排查生美业绩统计差异-简化版.sql index dbfd09e..d98ed59 100644 --- a/sql/排查生美业绩统计差异-简化版.sql +++ b/sql/排查生美业绩统计差异-简化版.sql @@ -116,3 +116,6 @@ ORDER BY 生美业绩 DESC; + + + diff --git a/sql/排查生美业绩统计差异详细.sql b/sql/排查生美业绩统计差异详细.sql index 4051a8d..4a4dde9 100644 --- a/sql/排查生美业绩统计差异详细.sql +++ b/sql/排查生美业绩统计差异详细.sql @@ -168,3 +168,6 @@ HAVING COUNT(*) > 1; + + + diff --git a/sql/检查生美业绩统计差异.sql b/sql/检查生美业绩统计差异.sql index 029e1dd..e14f4e0 100644 --- a/sql/检查生美业绩统计差异.sql +++ b/sql/检查生美业绩统计差异.sql @@ -138,3 +138,6 @@ ORDER BY 生美业绩 DESC; + + + diff --git a/test_tianwang_api.py b/test_tianwang_api.py index 270dada..7dcc326 100644 --- a/test_tianwang_api.py +++ b/test_tianwang_api.py @@ -71,3 +71,6 @@ total2 = sum([d.get('BillingPerformance', 0) for d in depts2]) print(f"\n教育一部+教育二部合计 BillingPerformance: {total2}") + + +