Commit 87aea27c659bff3aa3421d390ca5f3bf701563a3

Authored by “wangming”
1 parent 9e55866f

更新多个.DS_Store文件,删除不再使用的门店统计相关输入和输出类,优化项目结构和文件管理,确保代码整洁和功能完整性。

Showing 27 changed files with 1303 additions and 278 deletions
.DS_Store
No preview for this file type
创建事业部业绩统计流水表视图.sql renamed to [已用]创建事业部业绩统计流水表视图.sql
1 1 -- 创建事业部业绩统计流水表视图
2   --- 统计各个事业部的目标业绩、完成业绩、完成率
  2 +-- 统计各个事业部的目标业绩、完成业绩、完成率(基于开卡记录)
3 3  
4 4 DROP VIEW IF EXISTS `v_department_performance_flow`;
5 5  
6 6 CREATE VIEW `v_department_performance_flow` AS
7 7 SELECT
  8 + kd.F_Id AS order_id, -- 开单ID
8 9 o.F_Id AS department_id, -- 部门ID
9 10 o.F_FullName AS department_name, -- 部门名称
10 11 o.F_ParentId AS parent_id, -- 上级部门ID
11 12 parent.F_FullName AS parent_name, -- 上级部门名称
12 13 o.F_Category AS department_category, -- 部门分类
13   - kd.F_Id AS order_id, -- 开单ID
14   - kd.kdrq AS order_date, -- 开单时间
15   - kd.djmd AS store_id, -- 开单门店ID
  14 + kd.djmd AS store_id, -- 门店ID
16 15 m.mdbm AS store_code, -- 门店编号
17 16 m.dm AS store_name, -- 门店名称
  17 + kd.kdrq AS order_date, -- 开单时间
18 18 m.xsyj AS target_amount, -- 目标业绩(门店生命线)
19 19 kd.zdyj AS completed_amount, -- 完成业绩(整单业绩)
20 20 kd.sfyj AS actual_amount, -- 实付业绩
... ... @@ -55,4 +55,4 @@ WHERE (o.F_DeleteMark IS NULL OR o.F_DeleteMark != 1)
55 55 AND kd.kdrq IS NOT NULL; -- 只包含有开单日期的记录
56 56  
57 57 -- 添加视图注释
58   -ALTER VIEW `v_department_performance_flow` COMMENT = '事业部业绩统计流水表视图 - 统计各事业部目标业绩、完成业绩、完成率等详细信息';
  58 +--ALTER VIEW `v_department_performance_flow` COMMENT = '事业部业绩统计流水表视图 - 统计各事业部目标业绩、完成业绩、完成率等详细信息';
... ...
[已用]创建其他部门业绩统计流水表视图.sql 0 → 100644
  1 +-- 创建其他部门业绩统计流水表视图
  2 +-- 统计教育部、科技部、大项目部的开卡流水记录
  3 +
  4 +DROP VIEW IF EXISTS `v_other_department_performance_flow`;
  5 +
  6 +CREATE VIEW `v_other_department_performance_flow` AS
  7 +SELECT
  8 + kd.F_Id AS order_id, -- 开单ID
  9 + o.F_Id AS department_id, -- 部门ID
  10 + o.F_FullName AS department_name, -- 部门名称
  11 + o.F_ParentId AS parent_id, -- 上级部门ID
  12 + parent.F_FullName AS parent_name, -- 上级部门名称
  13 + o.F_Category AS department_category, -- 部门分类
  14 + kd.djmd AS store_id, -- 门店ID
  15 + m.mdbm AS store_code, -- 门店编号
  16 + m.dm AS store_name, -- 门店名称
  17 + kd.kdrq AS order_date, -- 开单时间
  18 + m.xsyj AS target_amount, -- 目标业绩(门店生命线)
  19 + kd.zdyj AS completed_amount, -- 完成业绩(整单业绩)
  20 + kd.sfyj AS actual_amount, -- 实付业绩
  21 + kd.qk AS debt_amount, -- 欠款
  22 + kd.jsj AS golden_triangle, -- 金三角
  23 + kd.kdhy AS member_id, -- 开单会员ID
  24 + kd.kdhyc AS member_name, -- 开单会员名称
  25 + kd.kdhysjh AS member_phone, -- 开单会员手机号
  26 + kd.gjlx AS customer_type, -- 顾客类型
  27 + kd.hgjg AS partner_institution, -- 合作机构
  28 + kd.fkfs AS payment_method, -- 付款方式
  29 + kd.khly AS customer_source, -- 客户来源
  30 + kd.tjr AS referrer, -- 推荐人
  31 + kd.sfskdd AS is_first_order, -- 是否首开订单
  32 + kd.jj AS description, -- 简介
  33 + kd.bz AS remarks, -- 备注
  34 + kd.F_CreateUser AS create_user, -- 开单用户
  35 + kd.F_FIleUrl AS file_url, -- 方案其他
  36 + -- 计算完成率
  37 + CASE
  38 + WHEN m.xsyj > 0 THEN ROUND((kd.zdyj / m.xsyj) * 100, 2)
  39 + ELSE 0
  40 + END AS completion_rate, -- 完成率(%)
  41 + -- 时间维度字段
  42 + YEAR(kd.kdrq) AS order_year, -- 开单年份
  43 + MONTH(kd.kdrq) AS order_month, -- 开单月份
  44 + QUARTER(kd.kdrq) AS order_quarter, -- 开单季度
  45 + DATE(kd.kdrq) AS order_date_only, -- 开单日期(不含时间)
  46 + -- 使用开单日期作为创建时间
  47 + kd.kdrq AS create_time, -- 创建时间(使用开单日期)
  48 + kd.kdrq AS modify_time -- 修改时间(使用开单日期)
  49 +FROM base_organize o
  50 +LEFT JOIN base_organize parent ON o.F_ParentId = parent.F_Id
  51 +LEFT JOIN lq_mdxx m ON (m.jyb = o.F_Id OR m.kjb = o.F_Id OR m.dxmb = o.F_Id)
  52 +LEFT JOIN lq_kd_kdjlb kd ON kd.djmd = m.F_Id
  53 +WHERE (o.F_DeleteMark IS NULL OR o.F_DeleteMark != 1)
  54 + AND o.F_Category = 'department' -- 只统计部门类型
  55 + AND (o.F_FullName IN ('教育部', '科技部', '大项目部') OR parent.F_FullName IN ('教育部', '科技部', '大项目部')) -- 统计这三个大部门及其子部门
  56 + AND kd.kdrq IS NOT NULL; -- 只包含有开单日期的记录
  57 +
  58 +-- 添加视图注释
  59 +--ALTER VIEW `v_other_department_performance_flow` COMMENT = '其他部门业绩统计流水表视图 - 统计教育部、科技部、大项目部的开卡流水记录';
... ...
[已用]创建经理门店基础信息视图.sql 0 → 100644
  1 +-- 创建经理门店基础信息视图(精简版)
  2 +-- 只包含必要的基础数据,不包含生命线设置
  3 +
  4 +DROP VIEW IF EXISTS v_manager_store_basic;
  5 +
  6 +CREATE VIEW v_manager_store_basic AS
  7 +SELECT
  8 + u.F_Id AS manager_user_id, -- 使用正确的用户ID字段
  9 + u.F_RealName AS manager_name,
  10 + u.F_GW AS manager_position,
  11 + u.F_OrganizeId AS manager_organize_id,
  12 + org.F_Id AS business_unit_id,
  13 + org.F_FullName AS business_unit_name,
  14 + org.F_ParentId AS parent_organize_id,
  15 + parent_org.F_FullName AS parent_organize_name,
  16 + md.F_Id AS store_id,
  17 + md.mdbm AS store_code,
  18 + md.dm AS store_name,
  19 + md.syb AS store_business_unit_id
  20 +FROM BASE_USER u
  21 +INNER JOIN BASE_ORGANIZE org ON u.F_OrganizeId = org.F_Id
  22 +INNER JOIN BASE_ORGANIZE parent_org ON org.F_ParentId = parent_org.F_Id
  23 +INNER JOIN lq_mdxx md ON md.syb = org.F_Id
  24 +WHERE u.F_EnabledMark = 1
  25 + AND u.F_DeleteMark IS NULL
  26 + AND org.F_EnabledMark = 1
  27 + AND org.F_DeleteMark IS NULL
  28 + AND parent_org.F_EnabledMark = 1
  29 + AND parent_org.F_DeleteMark IS NULL
  30 + AND (u.F_GW LIKE '%经理%' OR u.F_GW LIKE '%总经理%')
  31 + AND parent_org.F_FullName = '事业部';
0 32 \ No newline at end of file
... ...
netcore/netcore/.DS_Store
No preview for this file type
netcore/src/Application/.DS_Store
No preview for this file type
netcore/src/Application/NCC.API/.DS_Store
No preview for this file type
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqMdxx/StoreStatisticsInput.cs deleted
1   -using System;
2   -using System.ComponentModel.DataAnnotations;
3   -
4   -namespace NCC.Extend.Entitys.Dto.LqMdxx
5   -{
6   - /// <summary>
7   - /// 门店统计查询输入参数
8   - /// </summary>
9   - public class StoreStatisticsInput
10   - {
11   - /// <summary>
12   - /// 查询日期
13   - /// </summary>
14   - /// <remarks>
15   - /// 传入日期格式:2025-9-14
16   - /// 系统会自动计算本月1号到传入日期的时间范围
17   - /// 例如传入2025-9-14,则查询范围为2025-9-1到2025-9-14
18   - /// </remarks>
19   - /// <example>2025-9-14</example>
20   - [Required(ErrorMessage = "查询日期不能为空")]
21   - public DateTime QueryDate { get; set; }
22   - }
23   -}
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqMdxx/StoreStatisticsOutput.cs deleted
1   -using System;
2   -using System.Collections.Generic;
3   -
4   -namespace NCC.Extend.Entitys.Dto.LqMdxx
5   -{
6   - /// <summary>
7   - /// 门店统计结果输出
8   - /// </summary>
9   - public class StoreStatisticsOutput
10   - {
11   - /// <summary>
12   - /// 查询开始日期
13   - /// </summary>
14   - /// <example>2025-09-01</example>
15   - public DateTime StartDate { get; set; }
16   -
17   - /// <summary>
18   - /// 查询结束日期
19   - /// </summary>
20   - /// <example>2025-09-14</example>
21   - public DateTime EndDate { get; set; }
22   -
23   - /// <summary>
24   - /// 门店统计列表
25   - /// </summary>
26   - public List<StoreStatisticsInfo> StoreList { get; set; } = new List<StoreStatisticsInfo>();
27   -
28   - /// <summary>
29   - /// 汇总统计
30   - /// </summary>
31   - public StoreSummaryInfo Summary { get; set; } = new StoreSummaryInfo();
32   - }
33   -
34   - /// <summary>
35   - /// 门店统计信息
36   - /// </summary>
37   - public class StoreStatisticsInfo
38   - {
39   - /// <summary>
40   - /// 门店ID
41   - /// </summary>
42   - /// <example>123456789</example>
43   - public string StoreId { get; set; }
44   -
45   - /// <summary>
46   - /// 门店编码
47   - /// </summary>
48   - /// <example>MD001</example>
49   - public string StoreCode { get; set; }
50   -
51   - /// <summary>
52   - /// 门店名称
53   - /// </summary>
54   - /// <example>北京朝阳店</example>
55   - public string StoreName { get; set; }
56   -
57   - /// <summary>
58   - /// 员工数量
59   - /// </summary>
60   - /// <remarks>该门店的员工总数</remarks>
61   - /// <example>15</example>
62   - public int EmployeeCount { get; set; }
63   -
64   - /// <summary>
65   - /// 项目数量
66   - /// </summary>
67   - /// <remarks>统计期间该门店耗卡的项目总数</remarks>
68   - /// <example>128</example>
69   - public decimal ProjectCount { get; set; }
70   -
71   - /// <summary>
72   - /// 消耗业绩
73   - /// </summary>
74   - /// <remarks>统计期间该门店耗卡的金额总计</remarks>
75   - /// <example>25680.50</example>
76   - public decimal ConsumeAmount { get; set; }
77   -
78   - /// <summary>
79   - /// 城市
80   - /// </summary>
81   - /// <example>北京</example>
82   - public string City { get; set; }
83   -
84   - /// <summary>
85   - /// 事业部
86   - /// </summary>
87   - /// <example>华北事业部</example>
88   - public string BusinessUnit { get; set; }
89   - }
90   -
91   - /// <summary>
92   - /// 汇总统计信息
93   - /// </summary>
94   - public class StoreSummaryInfo
95   - {
96   - /// <summary>
97   - /// 门店总数
98   - /// </summary>
99   - /// <example>25</example>
100   - public int TotalStoreCount { get; set; }
101   -
102   - /// <summary>
103   - /// 员工总数
104   - /// </summary>
105   - /// <example>365</example>
106   - public int TotalEmployeeCount { get; set; }
107   -
108   - /// <summary>
109   - /// 项目总数
110   - /// </summary>
111   - /// <example>2580</example>
112   - public decimal TotalProjectCount { get; set; }
113   -
114   - /// <summary>
115   - /// 消耗业绩总计
116   - /// </summary>
117   - /// <example>568920.80</example>
118   - public decimal TotalConsumeAmount { get; set; }
119   - }
120   -}
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqStatistics/BusinessUnitStatisticsInfo.cs 0 → 100644
  1 +using System.ComponentModel.DataAnnotations;
  2 +
  3 +namespace NCC.Extend.Entitys.Dto.LqStatistics
  4 +{
  5 + /// <summary>
  6 + /// 事业部业绩统计信息
  7 + /// </summary>
  8 + public class BusinessUnitStatisticsInfo
  9 + {
  10 + /// <summary>
  11 + /// 部门ID
  12 + /// </summary>
  13 + [Display(Name = "部门ID")]
  14 + public string DepartmentId { get; set; }
  15 +
  16 + /// <summary>
  17 + /// 部门名称
  18 + /// </summary>
  19 + [Display(Name = "部门名称")]
  20 + public string DepartmentName { get; set; }
  21 +
  22 + /// <summary>
  23 + /// 父部门ID
  24 + /// </summary>
  25 + [Display(Name = "父部门ID")]
  26 + public string ParentId { get; set; }
  27 +
  28 + /// <summary>
  29 + /// 父部门名称
  30 + /// </summary>
  31 + [Display(Name = "父部门名称")]
  32 + public string ParentName { get; set; }
  33 +
  34 + /// <summary>
  35 + /// 目标业绩总和
  36 + /// </summary>
  37 + [Display(Name = "目标业绩总和")]
  38 + public decimal TotalTargetAmount { get; set; }
  39 +
  40 + /// <summary>
  41 + /// 完成业绩总和
  42 + /// </summary>
  43 + [Display(Name = "完成业绩总和")]
  44 + public decimal TotalActualAmount { get; set; }
  45 +
  46 + /// <summary>
  47 + /// 开单总数量
  48 + /// </summary>
  49 + [Display(Name = "开单总数量")]
  50 + public int TotalOrderCount { get; set; }
  51 +
  52 + /// <summary>
  53 + /// 完成率(%)
  54 + /// </summary>
  55 + [Display(Name = "完成率")]
  56 + public decimal CompletionRate { get; set; }
  57 + }
  58 +}
... ...
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqStatistics/BusinessUnitStatisticsInput.cs 0 → 100644
  1 +using System;
  2 +using System.ComponentModel.DataAnnotations;
  3 +
  4 +namespace NCC.Extend.Entitys.Dto.LqStatistics
  5 +{
  6 + /// <summary>
  7 + /// 事业部业绩统计查询输入模型
  8 + /// </summary>
  9 + public class BusinessUnitStatisticsInput
  10 + {
  11 + /// <summary>
  12 + /// 开始日期
  13 + /// </summary>
  14 + [Required(ErrorMessage = "开始日期不能为空")]
  15 + [Display(Name = "开始日期")]
  16 + public DateTime StartDate { get; set; }
  17 +
  18 + /// <summary>
  19 + /// 结束日期
  20 + /// </summary>
  21 + [Required(ErrorMessage = "结束日期不能为空")]
  22 + [Display(Name = "结束日期")]
  23 + public DateTime EndDate { get; set; }
  24 +
  25 + /// <summary>
  26 + /// 事业部ID(可选,不传则查询所有事业部)
  27 + /// </summary>
  28 + [Display(Name = "事业部ID")]
  29 + public string BusinessUnitId { get; set; }
  30 + }
  31 +}
... ...
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqStatistics/BusinessUnitStatisticsOutput.cs 0 → 100644
  1 +using System.Collections.Generic;
  2 +
  3 +namespace NCC.Extend.Entitys.Dto.LqStatistics
  4 +{
  5 + /// <summary>
  6 + /// 事业部业绩统计输出
  7 + /// </summary>
  8 + public class BusinessUnitStatisticsOutput
  9 + {
  10 + /// <summary>
  11 + /// 事业部业绩统计列表
  12 + /// </summary>
  13 + public List<BusinessUnitStatisticsInfo> BusinessUnitList { get; set; } = new List<BusinessUnitStatisticsInfo>();
  14 +
  15 + /// <summary>
  16 + /// 总记录数
  17 + /// </summary>
  18 + public int TotalCount { get; set; }
  19 + }
  20 +}
... ...
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqStatistics/ManagerStatisticsInfo.cs 0 → 100644
  1 +using System.ComponentModel.DataAnnotations;
  2 +
  3 +namespace NCC.Extend.Entitys.Dto.LqStatistics
  4 +{
  5 + /// <summary>
  6 + /// 经理业绩统计信息
  7 + /// </summary>
  8 + public class ManagerStatisticsInfo
  9 + {
  10 + /// <summary>
  11 + /// 经理姓名
  12 + /// </summary>
  13 + [Display(Name = "经理姓名")]
  14 + public string ManagerName { get; set; }
  15 +
  16 + /// <summary>
  17 + /// 经理用户ID
  18 + /// </summary>
  19 + [Display(Name = "经理用户ID")]
  20 + public string ManagerUserId { get; set; }
  21 +
  22 + /// <summary>
  23 + /// 事业部名称
  24 + /// </summary>
  25 + [Display(Name = "事业部名称")]
  26 + public string BusinessUnitName { get; set; }
  27 +
  28 + /// <summary>
  29 + /// 事业部ID
  30 + /// </summary>
  31 + [Display(Name = "事业部ID")]
  32 + public string BusinessUnitId { get; set; }
  33 +
  34 + /// <summary>
  35 + /// 门店名称
  36 + /// </summary>
  37 + [Display(Name = "门店名称")]
  38 + public string StoreName { get; set; }
  39 +
  40 + /// <summary>
  41 + /// 门店ID
  42 + /// </summary>
  43 + [Display(Name = "门店ID")]
  44 + public string StoreId { get; set; }
  45 +
  46 + /// <summary>
  47 + /// 目标业绩(生命线1)
  48 + /// </summary>
  49 + [Display(Name = "目标业绩")]
  50 + public decimal TargetPerformance { get; set; }
  51 +
  52 + /// <summary>
  53 + /// 完成业绩
  54 + /// </summary>
  55 + [Display(Name = "完成业绩")]
  56 + public decimal ActualPerformance { get; set; }
  57 +
  58 + /// <summary>
  59 + /// 完成率(%)
  60 + /// </summary>
  61 + [Display(Name = "完成率")]
  62 + public decimal CompletionRate { get; set; }
  63 +
  64 + /// <summary>
  65 + /// 开单数量
  66 + /// </summary>
  67 + [Display(Name = "开单数量")]
  68 + public int OrderCount { get; set; }
  69 + }
  70 +}
... ...
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqStatistics/ManagerStatisticsInput.cs 0 → 100644
  1 +using System;
  2 +using System.ComponentModel.DataAnnotations;
  3 +
  4 +namespace NCC.Extend.Entitys.Dto.LqStatistics
  5 +{
  6 + /// <summary>
  7 + /// 经理业绩统计输入模型
  8 + /// </summary>
  9 + public class ManagerStatisticsInput
  10 + {
  11 + /// <summary>
  12 + /// 查询日期
  13 + /// </summary>
  14 + [Required(ErrorMessage = "查询日期不能为空")]
  15 + [Display(Name = "查询日期")]
  16 + public DateTime QueryDate { get; set; }
  17 +
  18 + /// <summary>
  19 + /// 开始日期
  20 + /// </summary>
  21 + [Required(ErrorMessage = "开始日期不能为空")]
  22 + [Display(Name = "开始日期")]
  23 + public DateTime StartDate { get; set; }
  24 +
  25 + /// <summary>
  26 + /// 结束日期
  27 + /// </summary>
  28 + [Required(ErrorMessage = "结束日期不能为空")]
  29 + [Display(Name = "结束日期")]
  30 + public DateTime EndDate { get; set; }
  31 +
  32 + /// <summary>
  33 + /// 事业部ID(可选,不传则查询所有事业部)
  34 + /// </summary>
  35 + [Display(Name = "事业部ID")]
  36 + public string BusinessUnitId { get; set; }
  37 + }
  38 +}
... ...
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqStatistics/ManagerStatisticsOutput.cs 0 → 100644
  1 +using System.Collections.Generic;
  2 +
  3 +namespace NCC.Extend.Entitys.Dto.LqStatistics
  4 +{
  5 + /// <summary>
  6 + /// 经理业绩统计输出
  7 + /// </summary>
  8 + public class ManagerStatisticsOutput
  9 + {
  10 + /// <summary>
  11 + /// 经理统计列表
  12 + /// </summary>
  13 + public List<ManagerStatisticsInfo> ManagerList { get; set; } = new List<ManagerStatisticsInfo>();
  14 +
  15 + /// <summary>
  16 + /// 总记录数
  17 + /// </summary>
  18 + public int TotalCount { get; set; }
  19 + }
  20 +}
... ...
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqStatistics/ManagerSummaryStatisticsInfo.cs 0 → 100644
  1 +using System.ComponentModel.DataAnnotations;
  2 +
  3 +namespace NCC.Extend.Entitys.Dto.LqStatistics
  4 +{
  5 + /// <summary>
  6 + /// 经理业绩汇总统计信息
  7 + /// </summary>
  8 + public class ManagerSummaryStatisticsInfo
  9 + {
  10 + /// <summary>
  11 + /// 经理姓名
  12 + /// </summary>
  13 + [Display(Name = "经理姓名")]
  14 + public string ManagerName { get; set; }
  15 +
  16 + /// <summary>
  17 + /// 经理用户ID
  18 + /// </summary>
  19 + [Display(Name = "经理用户ID")]
  20 + public string ManagerUserId { get; set; }
  21 +
  22 + /// <summary>
  23 + /// 事业部名称
  24 + /// </summary>
  25 + [Display(Name = "事业部名称")]
  26 + public string BusinessUnitName { get; set; }
  27 +
  28 + /// <summary>
  29 + /// 事业部ID
  30 + /// </summary>
  31 + [Display(Name = "事业部ID")]
  32 + public string BusinessUnitId { get; set; }
  33 +
  34 + /// <summary>
  35 + /// 管理门店数量
  36 + /// </summary>
  37 + [Display(Name = "管理门店数量")]
  38 + public int StoreCount { get; set; }
  39 +
  40 + /// <summary>
  41 + /// 目标业绩总和
  42 + /// </summary>
  43 + [Display(Name = "目标业绩总和")]
  44 + public decimal TotalTargetPerformance { get; set; }
  45 +
  46 + /// <summary>
  47 + /// 完成业绩总和
  48 + /// </summary>
  49 + [Display(Name = "完成业绩总和")]
  50 + public decimal TotalActualPerformance { get; set; }
  51 +
  52 + /// <summary>
  53 + /// 完成率(%)
  54 + /// </summary>
  55 + [Display(Name = "完成率")]
  56 + public decimal CompletionRate { get; set; }
  57 +
  58 + /// <summary>
  59 + /// 开单总数量
  60 + /// </summary>
  61 + [Display(Name = "开单总数量")]
  62 + public int TotalOrderCount { get; set; }
  63 + }
  64 +}
... ...
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqStatistics/ManagerSummaryStatisticsOutput.cs 0 → 100644
  1 +using System.Collections.Generic;
  2 +
  3 +namespace NCC.Extend.Entitys.Dto.LqStatistics
  4 +{
  5 + /// <summary>
  6 + /// 经理业绩汇总统计输出
  7 + /// </summary>
  8 + public class ManagerSummaryStatisticsOutput
  9 + {
  10 + /// <summary>
  11 + /// 经理业绩汇总统计列表
  12 + /// </summary>
  13 + public List<ManagerSummaryStatisticsInfo> ManagerSummaryList { get; set; } = new List<ManagerSummaryStatisticsInfo>();
  14 +
  15 + /// <summary>
  16 + /// 总记录数
  17 + /// </summary>
  18 + public int TotalCount { get; set; }
  19 + }
  20 +}
... ...
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqStatistics/OtherDepartmentStatisticsInfo.cs 0 → 100644
  1 +using System.ComponentModel.DataAnnotations;
  2 +
  3 +namespace NCC.Extend.Entitys.Dto.LqStatistics
  4 +{
  5 + /// <summary>
  6 + /// 其他部门业绩统计信息
  7 + /// </summary>
  8 + public class OtherDepartmentStatisticsInfo
  9 + {
  10 + /// <summary>
  11 + /// 部门ID
  12 + /// </summary>
  13 + [Display(Name = "部门ID")]
  14 + public string DepartmentId { get; set; }
  15 +
  16 + /// <summary>
  17 + /// 部门名称
  18 + /// </summary>
  19 + [Display(Name = "部门名称")]
  20 + public string DepartmentName { get; set; }
  21 +
  22 + /// <summary>
  23 + /// 父部门ID
  24 + /// </summary>
  25 + [Display(Name = "父部门ID")]
  26 + public string ParentId { get; set; }
  27 +
  28 + /// <summary>
  29 + /// 父部门名称
  30 + /// </summary>
  31 + [Display(Name = "父部门名称")]
  32 + public string ParentName { get; set; }
  33 +
  34 + /// <summary>
  35 + /// 目标业绩总和
  36 + /// </summary>
  37 + [Display(Name = "目标业绩总和")]
  38 + public decimal TotalTargetAmount { get; set; }
  39 +
  40 + /// <summary>
  41 + /// 完成业绩总和
  42 + /// </summary>
  43 + [Display(Name = "完成业绩总和")]
  44 + public decimal TotalActualAmount { get; set; }
  45 +
  46 + /// <summary>
  47 + /// 开单总数量
  48 + /// </summary>
  49 + [Display(Name = "开单总数量")]
  50 + public int TotalOrderCount { get; set; }
  51 +
  52 + /// <summary>
  53 + /// 完成率(%)
  54 + /// </summary>
  55 + [Display(Name = "完成率")]
  56 + public decimal CompletionRate { get; set; }
  57 + }
  58 +}
... ...
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqStatistics/OtherDepartmentStatisticsInput.cs 0 → 100644
  1 +using System;
  2 +using System.ComponentModel.DataAnnotations;
  3 +
  4 +namespace NCC.Extend.Entitys.Dto.LqStatistics
  5 +{
  6 + /// <summary>
  7 + /// 其他部门业绩统计查询输入模型
  8 + /// </summary>
  9 + public class OtherDepartmentStatisticsInput
  10 + {
  11 + /// <summary>
  12 + /// 开始日期
  13 + /// </summary>
  14 + [Required(ErrorMessage = "开始日期不能为空")]
  15 + [Display(Name = "开始日期")]
  16 + public DateTime StartDate { get; set; }
  17 +
  18 + /// <summary>
  19 + /// 结束日期
  20 + /// </summary>
  21 + [Required(ErrorMessage = "结束日期不能为空")]
  22 + [Display(Name = "结束日期")]
  23 + public DateTime EndDate { get; set; }
  24 +
  25 + /// <summary>
  26 + /// 部门ID(可选,不传则查询所有部门)
  27 + /// </summary>
  28 + [Display(Name = "部门ID")]
  29 + public string DepartmentId { get; set; }
  30 + }
  31 +}
... ...
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqStatistics/OtherDepartmentStatisticsOutput.cs 0 → 100644
  1 +using System.Collections.Generic;
  2 +
  3 +namespace NCC.Extend.Entitys.Dto.LqStatistics
  4 +{
  5 + /// <summary>
  6 + /// 其他部门业绩统计输出
  7 + /// </summary>
  8 + public class OtherDepartmentStatisticsOutput
  9 + {
  10 + /// <summary>
  11 + /// 部门统计列表
  12 + /// </summary>
  13 + public List<OtherDepartmentStatisticsInfo> DepartmentList { get; set; } = new List<OtherDepartmentStatisticsInfo>();
  14 +
  15 + /// <summary>
  16 + /// 总记录数
  17 + /// </summary>
  18 + public int TotalCount { get; set; }
  19 + }
  20 +}
... ...
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqStatistics/StorePerformanceOutput.cs
... ... @@ -8,6 +8,12 @@ namespace NCC.Extend.Entitys.Dto.LqStatistics
8 8 public class StorePerformanceOutput
9 9 {
10 10 /// <summary>
  11 + /// 门店ID
  12 + /// </summary>
  13 + [Display(Name = "门店ID")]
  14 + public string StoreId { get; set; }
  15 +
  16 + /// <summary>
11 17 /// 门店编码
12 18 /// </summary>
13 19 [Display(Name = "门店编码")]
... ... @@ -20,6 +26,18 @@ namespace NCC.Extend.Entitys.Dto.LqStatistics
20 26 public string StoreName { get; set; }
21 27  
22 28 /// <summary>
  29 + /// 事业部ID
  30 + /// </summary>
  31 + [Display(Name = "事业部ID")]
  32 + public string BusinessUnitId { get; set; }
  33 +
  34 + /// <summary>
  35 + /// 事业部名称
  36 + /// </summary>
  37 + [Display(Name = "事业部名称")]
  38 + public string BusinessUnitName { get; set; }
  39 +
  40 + /// <summary>
23 41 /// 目标业绩(生命线)
24 42 /// </summary>
25 43 [Display(Name = "目标业绩")]
... ...
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqStatistics/StoreStatisticsInfo.cs 0 → 100644
  1 +using System.ComponentModel.DataAnnotations;
  2 +
  3 +namespace NCC.Extend.Entitys.Dto.LqStatistics
  4 +{
  5 + /// <summary>
  6 + /// 门店统计信息
  7 + /// </summary>
  8 + public class StoreStatisticsInfo
  9 + {
  10 + /// <summary>
  11 + /// 门店ID
  12 + /// </summary>
  13 + [Display(Name = "门店ID")]
  14 + public string StoreId { get; set; }
  15 +
  16 + /// <summary>
  17 + /// 门店名称
  18 + /// </summary>
  19 + [Display(Name = "门店名称")]
  20 + public string StoreName { get; set; }
  21 +
  22 + /// <summary>
  23 + /// 门店编码
  24 + /// </summary>
  25 + [Display(Name = "门店编码")]
  26 + public string StoreCode { get; set; }
  27 +
  28 + /// <summary>
  29 + /// 事业部ID
  30 + /// </summary>
  31 + [Display(Name = "事业部ID")]
  32 + public string BusinessUnitId { get; set; }
  33 +
  34 + /// <summary>
  35 + /// 事业部名称
  36 + /// </summary>
  37 + [Display(Name = "事业部名称")]
  38 + public string BusinessUnitName { get; set; }
  39 +
  40 + /// <summary>
  41 + /// 目标业绩
  42 + /// </summary>
  43 + [Display(Name = "目标业绩")]
  44 + public decimal TargetPerformance { get; set; }
  45 +
  46 + /// <summary>
  47 + /// 完成业绩
  48 + /// </summary>
  49 + [Display(Name = "完成业绩")]
  50 + public decimal ActualPerformance { get; set; }
  51 +
  52 + /// <summary>
  53 + /// 开单数量
  54 + /// </summary>
  55 + [Display(Name = "开单数量")]
  56 + public int OrderCount { get; set; }
  57 +
  58 + /// <summary>
  59 + /// 完成率(%)
  60 + /// </summary>
  61 + [Display(Name = "完成率")]
  62 + public decimal CompletionRate { get; set; }
  63 + }
  64 +}
... ...
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqStatistics/StoreStatisticsInput.cs 0 → 100644
  1 +using System;
  2 +using System.ComponentModel.DataAnnotations;
  3 +
  4 +namespace NCC.Extend.Entitys.Dto.LqStatistics
  5 +{
  6 + /// <summary>
  7 + /// 门店统计输入模型
  8 + /// </summary>
  9 + public class StoreStatisticsInput
  10 + {
  11 + /// <summary>
  12 + /// 开始日期
  13 + /// </summary>
  14 + [Required(ErrorMessage = "开始日期不能为空")]
  15 + [Display(Name = "开始日期")]
  16 + public DateTime StartDate { get; set; }
  17 +
  18 + /// <summary>
  19 + /// 结束日期
  20 + /// </summary>
  21 + [Required(ErrorMessage = "结束日期不能为空")]
  22 + [Display(Name = "结束日期")]
  23 + public DateTime EndDate { get; set; }
  24 +
  25 + /// <summary>
  26 + /// 门店ID(可选,不传则查询所有门店)
  27 + /// </summary>
  28 + [Display(Name = "门店ID")]
  29 + public string StoreId { get; set; }
  30 + }
  31 +}
... ...
netcore/src/Modularity/Extend/NCC.Extend.Entitys/Dto/LqStatistics/StoreStatisticsOutput.cs 0 → 100644
  1 +using System.Collections.Generic;
  2 +
  3 +namespace NCC.Extend.Entitys.Dto.LqStatistics
  4 +{
  5 + /// <summary>
  6 + /// 门店统计输出
  7 + /// </summary>
  8 + public class StoreStatisticsOutput
  9 + {
  10 + /// <summary>
  11 + /// 门店统计列表
  12 + /// </summary>
  13 + public List<StoreStatisticsInfo> StoreList { get; set; } = new List<StoreStatisticsInfo>();
  14 +
  15 + /// <summary>
  16 + /// 总记录数
  17 + /// </summary>
  18 + public int TotalCount { get; set; }
  19 + }
  20 +}
... ...
netcore/src/Modularity/Extend/NCC.Extend.Interfaces/LqStatistics/ILqStatisticsService.cs
1 1 using System.Collections.Generic;
2 2 using System.Threading.Tasks;
3   -using NCC.Extend.Entitys.Dto.LqStatistics;
4 3 using NCC.Extend.Entitys.Dto.LqMdxx;
  4 +using NCC.Extend.Entitys.Dto.LqStatistics;
5 5  
6 6 namespace NCC.Extend.Interfaces.LqStatistics
7 7 {
... ... @@ -22,5 +22,33 @@ namespace NCC.Extend.Interfaces.LqStatistics
22 22 /// <param name="input">查询参数</param>
23 23 /// <returns>门店统计结果</returns>
24 24 Task<StoreStatisticsOutput> GetStoreStatistics(StoreStatisticsInput input);
  25 +
  26 + /// <summary>
  27 + /// 获取事业部业绩统计
  28 + /// </summary>
  29 + /// <param name="input">查询参数</param>
  30 + /// <returns>事业部业绩统计结果</returns>
  31 + Task<BusinessUnitStatisticsOutput> GetBusinessUnitStatistics(BusinessUnitStatisticsInput input);
  32 +
  33 + /// <summary>
  34 + /// 获取其他部门业绩统计
  35 + /// </summary>
  36 + /// <param name="input">查询参数</param>
  37 + /// <returns>其他部门业绩统计结果</returns>
  38 + Task<OtherDepartmentStatisticsOutput> GetOtherDepartmentStatistics(OtherDepartmentStatisticsInput input);
  39 +
  40 + /// <summary>
  41 + /// 获取经理业绩统计
  42 + /// </summary>
  43 + /// <param name="input">查询参数</param>
  44 + /// <returns>经理业绩统计结果</returns>
  45 + Task<ManagerStatisticsOutput> GetManagerStatistics(ManagerStatisticsInput input);
  46 +
  47 + /// <summary>
  48 + /// 获取经理业绩汇总统计
  49 + /// </summary>
  50 + /// <param name="input">查询参数</param>
  51 + /// <returns>经理业绩汇总统计结果</returns>
  52 + Task<ManagerSummaryStatisticsOutput> GetManagerSummaryStatistics(ManagerStatisticsInput input);
25 53 }
26 54 }
... ...
netcore/src/Modularity/Extend/NCC.Extend/LqStatisticsService.cs
  1 +using System;
  2 +using System.Collections.Generic;
  3 +using System.Linq;
  4 +using System.Threading.Tasks;
  5 +using Microsoft.AspNetCore.Mvc;
  6 +using Microsoft.Extensions.Logging;
1 7 using NCC.Common.Core.Manager;
2 8 using NCC.Common.Enum;
3 9 using NCC.Common.Extension;
4 10 using NCC.Common.Filter;
5 11 using NCC.Dependency;
6 12 using NCC.DynamicApiController;
7   -using NCC.FriendlyException;
8   -using NCC.Extend.Interfaces.LqStatistics;
  13 +using NCC.Extend.Entitys.Dto.LqMdxx;
9 14 using NCC.Extend.Entitys.Dto.LqStatistics;
10   -using Microsoft.AspNetCore.Mvc;
11   -using SqlSugar;
12   -using System;
13   -using System.Collections.Generic;
14   -using System.Linq;
15   -using System.Threading.Tasks;
16 15 using NCC.Extend.Entitys.lq_mdxx;
17   -using NCC.Extend.Entitys.Dto.LqMdxx;
  16 +using NCC.Extend.Entitys.lq_yjmxb;
  17 +using NCC.Extend.Interfaces.LqStatistics;
  18 +using NCC.FriendlyException;
18 19 using NCC.System.Entitys.Permission;
19   -using Microsoft.Extensions.Logging;
  20 +using SqlSugar;
20 21  
21 22 namespace NCC.Extend.LqStatistics
22 23 {
... ... @@ -35,10 +36,7 @@ namespace NCC.Extend.LqStatistics
35 36 /// <summary>
36 37 /// 初始化一个<see cref="LqStatisticsService"/>类型的新实例
37 38 /// </summary>
38   - public LqStatisticsService(
39   - ISqlSugarRepository<LqMdxxEntity> lqMdxxRepository,
40   - IUserManager userManager,
41   - ILogger<LqStatisticsService> logger)
  39 + public LqStatisticsService(ISqlSugarRepository<LqMdxxEntity> lqMdxxRepository, IUserManager userManager, ILogger<LqStatisticsService> logger)
42 40 {
43 41 _lqMdxxRepository = lqMdxxRepository;
44 42 _db = _lqMdxxRepository.Context;
... ... @@ -46,173 +44,575 @@ namespace NCC.Extend.LqStatistics
46 44 _logger = logger;
47 45 }
48 46  
49   - #region 获取门店业绩统计列表
  47 + #region 获取门店业绩统计列表
50 48 /// <summary>
51 49 /// 获取门店业绩统计列表
52 50 /// </summary>
53   - /// <remarks>
54   - /// 查询所有门店的目标业绩、完成业绩、完成率等关键指标
55   - ///
56   - /// 返回数据包含:
57   - /// - 门店编码和店名
58   - /// - 目标业绩(生命线)
59   - /// - 完成业绩(实付业绩)
60   - /// - 完成率(百分比)
61   - /// - 开单数量
62   - ///
63   - /// 数据来源:v_store_performance_simple 视图
64   - /// </remarks>
65 51 /// <returns>门店业绩统计列表</returns>
66   - /// <response code="200">成功返回门店业绩统计列表</response>
67   - /// <response code="500">服务器内部错误</response>
68 52 [HttpGet]
69 53 public async Task<List<StorePerformanceOutput>> GetStorePerformanceList()
70 54 {
71 55 try
72 56 {
73   - var result = await _db.Ado.SqlQueryAsync<StorePerformanceOutput>(
74   - "SELECT " +
75   - "store_code AS StoreCode, " +
76   - "store_name AS StoreName, " +
77   - "target_performance AS TargetPerformance, " +
78   - "actual_performance AS ActualPerformance, " +
79   - "completion_rate AS CompletionRate, " +
80   - "order_count AS OrderCount " +
81   - "FROM v_store_performance_simple " +
82   - "ORDER BY actual_performance DESC");
83   -
84   - return result ?? new List<StorePerformanceOutput>();
  57 + _logger.LogInformation("开始查询门店业绩统计列表");
  58 +
  59 + var storeList = await _lqMdxxRepository
  60 + .AsQueryable()
  61 + .Where(x => x.Status == 1)
  62 + .Select(x => new StorePerformanceOutput
  63 + {
  64 + StoreId = x.Id,
  65 + StoreName = x.Dm,
  66 + StoreCode = x.Mdbm,
  67 + BusinessUnitId = x.Syb,
  68 + BusinessUnitName = x.Syb,
  69 + TargetPerformance = x.Xsyj ?? 0,
  70 + ActualPerformance = 0,
  71 + CompletionRate = 0,
  72 + })
  73 + .ToListAsync();
  74 +
  75 + _logger.LogInformation("门店业绩统计列表查询完成,返回{Count}条记录", storeList.Count);
  76 +
  77 + return storeList;
85 78 }
86 79 catch (Exception ex)
87 80 {
88   - throw NCCException.Oh(ErrorCode.COM1005, ex.Message);
  81 + _logger.LogError(ex, "查询门店业绩统计列表时发生错误");
  82 + throw NCCException.Oh("查询门店业绩统计列表失败", ex);
89 83 }
90 84 }
91 85 #endregion
92 86  
93   - #region 门店统计信息
  87 + #region 获取门店统计信息
94 88 /// <summary>
95 89 /// 获取门店统计信息
96 90 /// </summary>
  91 + /// <param name="input">查询参数</param>
  92 + /// <returns>门店统计结果</returns>
  93 + [HttpPost("StoreStatistics")]
  94 + public async Task<StoreStatisticsOutput> GetStoreStatistics(StoreStatisticsInput input)
  95 + {
  96 + try
  97 + {
  98 + _logger.LogInformation("开始查询门店统计信息,查询日期:{StartDate} - {EndDate},门店ID:{StoreId}", input.StartDate, input.EndDate, input.StoreId);
  99 +
  100 + // 构建查询参数
  101 + var parameters = new Dictionary<string, object> { { "@startDate", input.StartDate.ToString("yyyy-MM-dd 00:00:00") }, { "@endDate", input.EndDate.ToString("yyyy-MM-dd 23:59:59") } };
  102 +
  103 + // 构建WHERE条件
  104 + var whereClause = "WHERE (order_date >= @startDate AND order_date <= @endDate OR order_date IS NULL)";
  105 +
  106 + if (!string.IsNullOrEmpty(input.StoreId))
  107 + {
  108 + whereClause += " AND store_id = @storeId";
  109 + parameters.Add("@storeId", input.StoreId);
  110 + }
  111 +
  112 + // 构建SQL查询
  113 + var sql =
  114 + $@"
  115 + SELECT
  116 + store_id AS StoreId,
  117 + store_name AS StoreName,
  118 + store_code AS StoreCode,
  119 + business_unit_id AS BusinessUnitId,
  120 + business_unit_name AS BusinessUnitName,
  121 + target_performance AS TargetPerformance,
  122 + SUM(COALESCE(actual_amount, 0)) AS ActualPerformance,
  123 + COUNT(order_id) AS OrderCount,
  124 + CASE
  125 + WHEN target_performance > 0
  126 + THEN ROUND((SUM(COALESCE(actual_amount, 0)) / target_performance) * 100, 2)
  127 + ELSE 0
  128 + END AS CompletionRate
  129 + FROM v_store_daily_consume_stats
  130 + {whereClause}
  131 + GROUP BY
  132 + store_id,
  133 + store_name,
  134 + store_code,
  135 + business_unit_id,
  136 + business_unit_name,
  137 + target_performance
  138 + ORDER BY ActualPerformance DESC";
  139 +
  140 + _logger.LogInformation("执行SQL查询:{Sql}", sql);
  141 + _logger.LogInformation("查询参数:{Parameters}", string.Join(", ", parameters.Select(p => $"{p.Key}={p.Value}")));
  142 +
  143 + var results = await _db.Ado.SqlQueryAsync<dynamic>(sql, parameters);
  144 +
  145 + _logger.LogInformation("查询到门店统计数据数量:{Count}", results.Count);
  146 +
  147 + // 转换为输出格式
  148 + var storeList = results
  149 + .Select(r => new StoreStatisticsInfo
  150 + {
  151 + StoreId = r.StoreId?.ToString() ?? "",
  152 + StoreName = r.StoreName?.ToString() ?? "",
  153 + StoreCode = r.StoreCode?.ToString() ?? "",
  154 + BusinessUnitId = r.BusinessUnitId?.ToString() ?? "",
  155 + BusinessUnitName = r.BusinessUnitName?.ToString() ?? "",
  156 + TargetPerformance = Convert.ToDecimal(r.TargetPerformance ?? 0),
  157 + ActualPerformance = Convert.ToDecimal(r.ActualPerformance ?? 0),
  158 + OrderCount = Convert.ToInt32(r.OrderCount ?? 0),
  159 + CompletionRate = Convert.ToDecimal(r.CompletionRate ?? 0),
  160 + })
  161 + .ToList();
  162 +
  163 + _logger.LogInformation("门店统计信息查询完成,返回{Count}条记录", storeList.Count);
  164 +
  165 + return new StoreStatisticsOutput { StoreList = storeList, TotalCount = storeList.Count };
  166 + }
  167 + catch (Exception ex)
  168 + {
  169 + _logger.LogError(ex, "查询门店统计信息时发生错误,查询日期:{StartDate} - {EndDate},门店ID:{StoreId}", input.StartDate, input.EndDate, input.StoreId);
  170 + throw NCCException.Oh("查询门店统计信息失败", ex);
  171 + }
  172 + }
  173 + #endregion
  174 +
  175 + #region 获取事业部业绩统计
  176 + /// <summary>
  177 + /// 获取事业部业绩统计
  178 + /// </summary>
  179 + /// <param name="input">查询参数</param>
  180 + /// <returns>事业部业绩统计结果</returns>
  181 + [HttpPost("BusinessUnitStatistics")]
  182 + public async Task<BusinessUnitStatisticsOutput> GetBusinessUnitStatistics(BusinessUnitStatisticsInput input)
  183 + {
  184 + try
  185 + {
  186 + _logger.LogInformation("开始查询事业部业绩统计,查询日期:{StartDate} - {EndDate},事业部ID:{BusinessUnitId}", input.StartDate, input.EndDate, input.BusinessUnitId);
  187 +
  188 + // 构建查询参数
  189 + var parameters = new Dictionary<string, object> { { "@startDate", input.StartDate.ToString("yyyy-MM-dd 00:00:00") }, { "@endDate", input.EndDate.ToString("yyyy-MM-dd 23:59:59") } };
  190 +
  191 + // 构建WHERE条件
  192 + var whereClause = "WHERE (order_date >= @startDate AND order_date <= @endDate OR order_date IS NULL)";
  193 +
  194 + if (!string.IsNullOrEmpty(input.BusinessUnitId))
  195 + {
  196 + whereClause += " AND department_id = @businessUnitId";
  197 + parameters.Add("@businessUnitId", input.BusinessUnitId);
  198 + }
  199 +
  200 + // 构建SQL查询
  201 + var sql =
  202 + $@"
  203 + SELECT
  204 + department_id AS DepartmentId,
  205 + department_name AS DepartmentName,
  206 + parent_id AS ParentId,
  207 + parent_name AS ParentName,
  208 + SUM(COALESCE(target_amount, 0)) AS TotalTargetAmount,
  209 + SUM(COALESCE(actual_amount, 0)) AS TotalActualAmount,
  210 + COUNT(order_id) AS TotalOrderCount,
  211 + CASE
  212 + WHEN SUM(COALESCE(target_amount, 0)) > 0
  213 + THEN ROUND((SUM(COALESCE(actual_amount, 0)) / SUM(COALESCE(target_amount, 0))) * 100, 2)
  214 + ELSE 0
  215 + END AS CompletionRate
  216 + FROM v_department_performance_flow
  217 + {whereClause}
  218 + GROUP BY
  219 + department_id,
  220 + department_name,
  221 + parent_id,
  222 + parent_name
  223 + ORDER BY TotalActualAmount DESC";
  224 +
  225 + _logger.LogInformation("执行SQL查询:{Sql}", sql);
  226 + _logger.LogInformation("查询参数:{Parameters}", string.Join(", ", parameters.Select(p => $"{p.Key}={p.Value}")));
  227 +
  228 + var results = await _db.Ado.SqlQueryAsync<dynamic>(sql, parameters);
  229 +
  230 + _logger.LogInformation("查询到事业部业绩数据数量:{Count}", results.Count);
  231 +
  232 + // 转换为输出格式
  233 + var businessUnitList = results
  234 + .Select(r => new BusinessUnitStatisticsInfo
  235 + {
  236 + DepartmentId = r.DepartmentId?.ToString() ?? "",
  237 + DepartmentName = r.DepartmentName?.ToString() ?? "",
  238 + ParentId = r.ParentId?.ToString() ?? "",
  239 + ParentName = r.ParentName?.ToString() ?? "",
  240 + TotalTargetAmount = Convert.ToDecimal(r.TotalTargetAmount ?? 0),
  241 + TotalActualAmount = Convert.ToDecimal(r.TotalActualAmount ?? 0),
  242 + TotalOrderCount = Convert.ToInt32(r.TotalOrderCount ?? 0),
  243 + CompletionRate = Convert.ToDecimal(r.CompletionRate ?? 0),
  244 + })
  245 + .ToList();
  246 +
  247 + _logger.LogInformation("事业部业绩统计查询完成,返回{Count}条记录", businessUnitList.Count);
  248 +
  249 + return new BusinessUnitStatisticsOutput { BusinessUnitList = businessUnitList, TotalCount = businessUnitList.Count };
  250 + }
  251 + catch (Exception ex)
  252 + {
  253 + _logger.LogError(ex, "查询事业部业绩统计时发生错误,查询日期:{StartDate} - {EndDate},事业部ID:{BusinessUnitId}", input.StartDate, input.EndDate, input.BusinessUnitId);
  254 + throw NCCException.Oh("查询事业部业绩统计失败", ex);
  255 + }
  256 + }
  257 + #endregion
  258 +
  259 + #region 获取其他部门业绩统计
  260 + /// <summary>
  261 + /// 获取其他部门业绩统计
  262 + /// </summary>
  263 + /// <param name="input">查询参数</param>
  264 + /// <returns>其他部门业绩统计结果</returns>
  265 + [HttpPost("OtherDepartmentStatistics")]
  266 + public async Task<OtherDepartmentStatisticsOutput> GetOtherDepartmentStatistics(OtherDepartmentStatisticsInput input)
  267 + {
  268 + try
  269 + {
  270 + _logger.LogInformation("开始查询其他部门业绩统计,查询日期:{StartDate} - {EndDate},部门ID:{DepartmentId}", input.StartDate, input.EndDate, input.DepartmentId);
  271 +
  272 + // 构建查询参数
  273 + var parameters = new Dictionary<string, object> { { "@startDate", input.StartDate.ToString("yyyy-MM-dd 00:00:00") }, { "@endDate", input.EndDate.ToString("yyyy-MM-dd 23:59:59") } };
  274 +
  275 + // 构建WHERE条件
  276 + var whereClause = "WHERE (order_date >= @startDate AND order_date <= @endDate OR order_date IS NULL)";
  277 +
  278 + if (!string.IsNullOrEmpty(input.DepartmentId))
  279 + {
  280 + whereClause += " AND department_id = @departmentId";
  281 + parameters.Add("@departmentId", input.DepartmentId);
  282 + }
  283 +
  284 + // 构建SQL查询
  285 + var sql =
  286 + $@"
  287 + SELECT
  288 + department_id AS DepartmentId,
  289 + department_name AS DepartmentName,
  290 + parent_id AS ParentId,
  291 + parent_name AS ParentName,
  292 + SUM(COALESCE(target_amount, 0)) AS TotalTargetAmount,
  293 + SUM(COALESCE(actual_amount, 0)) AS TotalActualAmount,
  294 + COUNT(order_id) AS TotalOrderCount,
  295 + CASE
  296 + WHEN SUM(COALESCE(target_amount, 0)) > 0
  297 + THEN ROUND((SUM(COALESCE(actual_amount, 0)) / SUM(COALESCE(target_amount, 0))) * 100, 2)
  298 + ELSE 0
  299 + END AS CompletionRate
  300 + FROM v_other_department_performance_flow
  301 + {whereClause}
  302 + GROUP BY
  303 + department_id,
  304 + department_name,
  305 + parent_id,
  306 + parent_name
  307 + ORDER BY TotalActualAmount DESC";
  308 +
  309 + _logger.LogInformation("执行SQL查询:{Sql}", sql);
  310 + _logger.LogInformation("查询参数:{Parameters}", string.Join(", ", parameters.Select(p => $"{p.Key}={p.Value}")));
  311 +
  312 + var results = await _db.Ado.SqlQueryAsync<dynamic>(sql, parameters);
  313 +
  314 + _logger.LogInformation("查询到其他部门业绩数据数量:{Count}", results.Count);
  315 +
  316 + // 转换为输出格式
  317 + var departmentList = results
  318 + .Select(r => new OtherDepartmentStatisticsInfo
  319 + {
  320 + DepartmentId = r.DepartmentId?.ToString() ?? "",
  321 + DepartmentName = r.DepartmentName?.ToString() ?? "",
  322 + ParentId = r.ParentId?.ToString() ?? "",
  323 + ParentName = r.ParentName?.ToString() ?? "",
  324 + TotalTargetAmount = Convert.ToDecimal(r.TotalTargetAmount ?? 0),
  325 + TotalActualAmount = Convert.ToDecimal(r.TotalActualAmount ?? 0),
  326 + TotalOrderCount = Convert.ToInt32(r.TotalOrderCount ?? 0),
  327 + CompletionRate = Convert.ToDecimal(r.CompletionRate ?? 0),
  328 + })
  329 + .ToList();
  330 +
  331 + _logger.LogInformation("其他部门业绩统计查询完成,返回{Count}条记录", departmentList.Count);
  332 +
  333 + return new OtherDepartmentStatisticsOutput { DepartmentList = departmentList, TotalCount = departmentList.Count };
  334 + }
  335 + catch (Exception ex)
  336 + {
  337 + _logger.LogError(ex, "查询其他部门业绩统计时发生错误,查询日期:{StartDate} - {EndDate},部门ID:{DepartmentId}", input.StartDate, input.EndDate, input.DepartmentId);
  338 + throw NCCException.Oh("查询其他部门业绩统计失败", ex);
  339 + }
  340 + }
  341 + #endregion
  342 +
  343 + #region 获取经理业绩统计
  344 + /// <summary>
  345 + /// 获取经理业绩统计
  346 + /// </summary>
  347 + /// <param name="input">查询参数</param>
  348 + /// <returns>经理业绩统计结果</returns>
  349 + [HttpPost("ManagerStatistics")]
  350 + public async Task<ManagerStatisticsOutput> GetManagerStatistics(ManagerStatisticsInput input)
  351 + {
  352 + try
  353 + {
  354 + _logger.LogInformation("开始查询经理业绩统计,查询日期:{StartDate} - {EndDate},事业部ID:{BusinessUnitId}", input.StartDate, input.EndDate, input.BusinessUnitId);
  355 +
  356 + // 构建查询参数
  357 + var parameters = new Dictionary<string, object> { { "@startDate", input.StartDate.ToString("yyyy-MM-dd 00:00:00") }, { "@endDate", input.EndDate.ToString("yyyy-MM-dd 23:59:59") } };
  358 +
  359 + // 构建WHERE条件
  360 + var whereClause = "WHERE (flow.order_date >= @startDate AND flow.order_date <= @endDate OR flow.order_date IS NULL)";
  361 +
  362 + if (!string.IsNullOrEmpty(input.BusinessUnitId))
  363 + {
  364 + whereClause += " AND basic.business_unit_id = @businessUnitId";
  365 + parameters.Add("@businessUnitId", input.BusinessUnitId);
  366 + }
  367 +
  368 + // 构建SQL查询 - 按经理和门店统计
  369 + var sql =
  370 + $@"
  371 + SELECT
  372 + basic.manager_user_id AS ManagerUserId,
  373 + basic.manager_name AS ManagerName,
  374 + basic.business_unit_id AS BusinessUnitId,
  375 + basic.business_unit_name AS BusinessUnitName,
  376 + basic.store_id AS StoreId,
  377 + basic.store_name AS StoreName,
  378 + COALESCE(smx.smx1, 0) AS TargetPerformance,
  379 + SUM(COALESCE(flow.actual_amount, 0)) AS ActualPerformance,
  380 + COUNT(flow.order_id) AS OrderCount,
  381 + CASE
  382 + WHEN COALESCE(smx.smx1, 0) > 0
  383 + THEN ROUND((SUM(COALESCE(flow.actual_amount, 0)) / COALESCE(smx.smx1, 0)) * 100, 2)
  384 + ELSE 0
  385 + END AS CompletionRate
  386 + FROM v_manager_store_basic basic
  387 + LEFT JOIN lq_zjl_mdsmxsz smx ON basic.store_id = smx.md_id AND basic.manager_user_id = smx.zjl_userid
  388 + LEFT JOIN v_department_performance_flow flow ON basic.store_id = flow.store_id
  389 + {whereClause}
  390 + GROUP BY
  391 + basic.manager_user_id,
  392 + basic.manager_name,
  393 + basic.business_unit_id,
  394 + basic.business_unit_name,
  395 + basic.store_id,
  396 + basic.store_name,
  397 + smx.smx1
  398 + ORDER BY ActualPerformance DESC";
  399 +
  400 + _logger.LogInformation("执行SQL查询:{Sql}", sql);
  401 + _logger.LogInformation("查询参数:{Parameters}", string.Join(", ", parameters.Select(p => $"{p.Key}={p.Value}")));
  402 +
  403 + var results = await _db.Ado.SqlQueryAsync<dynamic>(sql, parameters);
  404 +
  405 + _logger.LogInformation("查询到经理业绩数据数量:{Count}", results.Count);
  406 +
  407 + // 转换为输出格式
  408 + var managerList = results
  409 + .Select(r => new ManagerStatisticsInfo
  410 + {
  411 + ManagerName = r.ManagerName?.ToString() ?? "",
  412 + ManagerUserId = r.ManagerUserId?.ToString() ?? "",
  413 + BusinessUnitName = r.BusinessUnitName?.ToString() ?? "",
  414 + BusinessUnitId = r.BusinessUnitId?.ToString() ?? "",
  415 + StoreName = r.StoreName?.ToString() ?? "",
  416 + StoreId = r.StoreId?.ToString() ?? "",
  417 + TargetPerformance = Convert.ToDecimal(r.TargetPerformance ?? 0),
  418 + ActualPerformance = Convert.ToDecimal(r.ActualPerformance ?? 0),
  419 + OrderCount = Convert.ToInt32(r.OrderCount ?? 0),
  420 + CompletionRate = Convert.ToDecimal(r.CompletionRate ?? 0),
  421 + })
  422 + .ToList();
  423 +
  424 + _logger.LogInformation("经理业绩统计查询完成,返回{Count}条记录", managerList.Count);
  425 +
  426 + return new ManagerStatisticsOutput { ManagerList = managerList, TotalCount = managerList.Count };
  427 + }
  428 + catch (Exception ex)
  429 + {
  430 + _logger.LogError(ex, "查询经理业绩统计时发生错误,查询日期:{StartDate} - {EndDate},事业部ID:{BusinessUnitId}", input.StartDate, input.EndDate, input.BusinessUnitId);
  431 + throw NCCException.Oh("查询经理业绩统计失败", ex);
  432 + }
  433 + }
  434 + #endregion
  435 +
  436 + #region 获取经理业绩汇总统计
  437 + /// <summary>
  438 + /// 获取经理业绩汇总统计
  439 + /// </summary>
97 440 /// <remarks>
98   - /// 统计各个门店在员工数量、项目数(耗卡里面的项目数量)和消耗业绩(耗卡里面的金额)
99   - /// 可以传入日期,然后去统计本月一号到传入的日期
100   - ///
  441 + /// 统计每个经理的目标业绩总和、完成业绩总和、完成率等汇总信息
  442 + ///
101 443 /// 示例请求:
102 444 /// ```json
103 445 /// {
104   - /// "queryDate": "2025-09-14"
  446 + /// "startDate": "2025-01-01T00:00:00",
  447 + /// "endDate": "2025-01-31T23:59:59",
  448 + /// "businessUnitId": "事业部ID(可选)"
105 449 /// }
106 450 /// ```
107   - ///
  451 + ///
108 452 /// 参数说明:
109   - /// - queryDate: 查询日期,系统会自动计算本月1号到该日期的统计范围
  453 + /// - startDate: 开始日期,格式:yyyy-MM-ddTHH:mm:ss
  454 + /// - endDate: 结束日期,格式:yyyy-MM-ddTHH:mm:ss
  455 + /// - businessUnitId: 事业部ID,可选参数,不传则查询所有事业部
  456 + ///
  457 + /// 返回数据说明:
  458 + /// - ManagerName: 经理姓名
  459 + /// - ManagerUserId: 经理用户ID
  460 + /// - BusinessUnitName: 事业部名称
  461 + /// - BusinessUnitId: 事业部ID
  462 + /// - StoreCount: 管理门店数量
  463 + /// - TotalTargetPerformance: 目标业绩总和
  464 + /// - TotalActualPerformance: 完成业绩总和
  465 + /// - CompletionRate: 完成率(%)
  466 + /// - TotalOrderCount: 开单总数量
110 467 /// </remarks>
111 468 /// <param name="input">查询参数</param>
112   - /// <returns>门店统计结果</returns>
113   - /// <response code="200">查询成功</response>
114   - /// <response code="400">参数错误</response>
  469 + /// <returns>经理业绩汇总统计结果</returns>
  470 + /// <response code="200">成功返回经理业绩汇总统计数据</response>
  471 + /// <response code="400">请求参数错误</response>
115 472 /// <response code="500">服务器内部错误</response>
116   - [HttpPost("StoreStatistics")]
117   - public async Task<StoreStatisticsOutput> GetStoreStatistics([FromBody] StoreStatisticsInput input)
  473 + [HttpPost("ManagerSummaryStatistics")]
  474 + public async Task<ManagerSummaryStatisticsOutput> GetManagerSummaryStatistics(ManagerStatisticsInput input)
118 475 {
119 476 try
120 477 {
121   - _logger.LogInformation("开始查询门店统计信息,查询日期:{QueryDate}", input.QueryDate);
122   -
123   - // 计算查询时间范围:本月1号到传入日期
124   - var startDate = new DateTime(input.QueryDate.Year, input.QueryDate.Month, 1);
125   - var endDate = input.QueryDate.Date.AddDays(1).AddSeconds(-1); // 包含当天结束时间
  478 + _logger.LogInformation("开始查询经理业绩汇总统计,查询日期:{StartDate} - {EndDate},事业部ID:{BusinessUnitId}", input.StartDate, input.EndDate, input.BusinessUnitId);
126 479  
127   - _logger.LogInformation("统计时间范围:{StartDate} 到 {EndDate}", startDate, endDate);
  480 + // 构建查询参数
  481 + var parameters = new Dictionary<string, object> { { "@startDate", input.StartDate.ToString("yyyy-MM-dd 00:00:00") }, { "@endDate", input.EndDate.ToString("yyyy-MM-dd 23:59:59") } };
128 482  
129   - // 1. 查询门店基础信息
130   - var storeList = await _db.Queryable<LqMdxxEntity>()
131   - .Select(it => new StoreStatisticsInfo
132   - {
133   - StoreId = it.Id,
134   - StoreCode = it.Mdbm,
135   - StoreName = it.Dm,
136   - City = it.Cs,
137   - BusinessUnit = it.Syb,
138   - EmployeeCount = 0,
139   - ProjectCount = 0,
140   - ConsumeAmount = 0
141   - })
142   - .ToListAsync();
  483 + // 构建WHERE条件
  484 + var whereClause = "WHERE (flow.order_date >= @startDate AND flow.order_date <= @endDate OR flow.order_date IS NULL)";
143 485  
144   - _logger.LogInformation("查询到门店数量:{Count}", storeList.Count);
  486 + if (!string.IsNullOrEmpty(input.BusinessUnitId))
  487 + {
  488 + whereClause += " AND basic.business_unit_id = @businessUnitId";
  489 + parameters.Add("@businessUnitId", input.BusinessUnitId);
  490 + }
145 491  
146   - // 2. 查询员工数量(按门店统计)
147   - var employeeCounts = await _db.Queryable<UserEntity>()
148   - .Where(u => !string.IsNullOrEmpty(u.Mdid) && u.DeleteMark != 1)
149   - .GroupBy(u => u.Mdid)
150   - .Select(g => new { StoreId = g.Mdid, Count = SqlFunc.AggregateCount(g.Id) })
151   - .ToListAsync();
  492 + // 构建SQL查询 - 按经理汇总统计
  493 + var sql =
  494 + $@"
  495 + SELECT
  496 + basic.manager_user_id AS ManagerUserId,
  497 + basic.manager_name AS ManagerName,
  498 + basic.business_unit_id AS BusinessUnitId,
  499 + basic.business_unit_name AS BusinessUnitName,
  500 + COUNT(DISTINCT basic.store_id) AS StoreCount,
  501 + SUM(COALESCE(smx.smx1, 0)) AS TotalTargetPerformance,
  502 + SUM(COALESCE(flow.actual_amount, 0)) AS TotalActualPerformance,
  503 + COUNT(flow.order_id) AS TotalOrderCount,
  504 + CASE
  505 + WHEN SUM(COALESCE(smx.smx1, 0)) > 0
  506 + THEN ROUND((SUM(COALESCE(flow.actual_amount, 0)) / SUM(COALESCE(smx.smx1, 0))) * 100, 2)
  507 + ELSE 0
  508 + END AS CompletionRate
  509 + FROM v_manager_store_basic basic
  510 + LEFT JOIN lq_zjl_mdsmxsz smx ON basic.store_id = smx.md_id AND basic.manager_user_id = smx.zjl_userid
  511 + LEFT JOIN v_department_performance_flow flow ON basic.store_id = flow.store_id
  512 + {whereClause}
  513 + GROUP BY
  514 + basic.manager_user_id,
  515 + basic.manager_name,
  516 + basic.business_unit_id,
  517 + basic.business_unit_name
  518 + ORDER BY TotalActualPerformance DESC";
152 519  
153   - _logger.LogInformation("查询到员工统计数量:{Count}", employeeCounts.Count);
  520 + _logger.LogInformation("执行SQL查询:{Sql}", sql);
  521 + _logger.LogInformation("查询参数:{Parameters}", string.Join(", ", parameters.Select(p => $"{p.Key}={p.Value}")));
154 522  
155   - // 3. 从视图查询项目数和消耗业绩
156   - var consumeStats = await _db.SqlQueryable<dynamic>(@"
157   - SELECT
158   - store_id,
159   - SUM(total_project_count) as total_project_count,
160   - SUM(total_consume_amount) as total_consume_amount
161   - FROM v_store_daily_consume_stats
162   - WHERE consume_date >= @startDate AND consume_date <= @endDate
163   - GROUP BY store_id")
164   - .AddParameters(new { startDate = startDate.ToString("yyyy-MM-dd"), endDate = input.QueryDate.ToString("yyyy-MM-dd") })
165   - .ToListAsync();
  523 + var results = await _db.Ado.SqlQueryAsync<dynamic>(sql, parameters);
166 524  
167   - _logger.LogInformation("查询到消耗统计数量:{Count}", consumeStats.Count);
  525 + _logger.LogInformation("查询到经理业绩汇总数据数量:{Count}", results.Count);
168 526  
169   - // 4. 合并统计数据
170   - foreach (var store in storeList)
171   - {
172   - // 匹配员工数量
173   - var employeeCount = employeeCounts.FirstOrDefault(e => e.StoreId == store.StoreId);
174   - if (employeeCount != null)
  527 + // 转换为输出格式
  528 + var managerSummaryList = results
  529 + .Select(r => new ManagerSummaryStatisticsInfo
175 530 {
176   - store.EmployeeCount = employeeCount.Count;
177   - }
  531 + ManagerName = r.ManagerName?.ToString() ?? "",
  532 + ManagerUserId = r.ManagerUserId?.ToString() ?? "",
  533 + BusinessUnitName = r.BusinessUnitName?.ToString() ?? "",
  534 + BusinessUnitId = r.BusinessUnitId?.ToString() ?? "",
  535 + StoreCount = Convert.ToInt32(r.StoreCount ?? 0),
  536 + TotalTargetPerformance = Convert.ToDecimal(r.TotalTargetPerformance ?? 0),
  537 + TotalActualPerformance = Convert.ToDecimal(r.TotalActualPerformance ?? 0),
  538 + TotalOrderCount = Convert.ToInt32(r.TotalOrderCount ?? 0),
  539 + CompletionRate = Convert.ToDecimal(r.CompletionRate ?? 0),
  540 + })
  541 + .ToList();
  542 +
  543 + _logger.LogInformation("经理业绩汇总统计查询完成,返回{Count}条记录", managerSummaryList.Count);
  544 +
  545 + return new ManagerSummaryStatisticsOutput { ManagerSummaryList = managerSummaryList, TotalCount = managerSummaryList.Count };
  546 + }
  547 + catch (Exception ex)
  548 + {
  549 + _logger.LogError(ex, "查询经理业绩汇总统计时发生错误,查询日期:{StartDate} - {EndDate},事业部ID:{BusinessUnitId}", input.StartDate, input.EndDate, input.BusinessUnitId);
  550 + throw NCCException.Oh("查询经理业绩汇总统计失败", ex);
  551 + }
  552 + }
  553 + #endregion
178 554  
179   - // 匹配项目数和消耗业绩
180   - var consumeStat = consumeStats.FirstOrDefault(c => c.store_id?.ToString() == store.StoreId);
181   - if (consumeStat != null)
  555 + #region 私有方法
  556 + /// <summary>
  557 + /// 递归获取子部门列表
  558 + /// </summary>
  559 + /// <param name="parentId">父部门ID</param>
  560 + /// <returns>子部门列表</returns>
  561 + private async Task<List<DepartmentInfo>> GetSubDepartmentsRecursively(string parentId)
  562 + {
  563 + var subDepartments = new List<DepartmentInfo>();
  564 +
  565 + try
  566 + {
  567 + // 查询直接子部门
  568 + var directChildren = await _db.Queryable<OrganizeEntity>()
  569 + .Where(x => x.ParentId == parentId && x.EnabledMark == 1 && x.DeleteMark == null)
  570 + .Select(x => new DepartmentInfo
182 571 {
183   - store.ProjectCount = Convert.ToDecimal(consumeStat.total_project_count ?? 0);
184   - store.ConsumeAmount = Convert.ToDecimal(consumeStat.total_consume_amount ?? 0);
185   - }
186   - }
  572 + DepartmentId = x.Id,
  573 + DepartmentName = x.FullName,
  574 + ParentId = x.ParentId,
  575 + })
  576 + .ToListAsync();
187 577  
188   - // 5. 计算汇总统计
189   - var summary = new StoreSummaryInfo
190   - {
191   - TotalStoreCount = storeList.Count,
192   - TotalEmployeeCount = storeList.Sum(s => s.EmployeeCount),
193   - TotalProjectCount = storeList.Sum(s => s.ProjectCount),
194   - TotalConsumeAmount = storeList.Sum(s => s.ConsumeAmount)
195   - };
  578 + subDepartments.AddRange(directChildren);
196 579  
197   - var result = new StoreStatisticsOutput
  580 + // 递归查询每个子部门的子部门
  581 + foreach (var child in directChildren)
198 582 {
199   - StartDate = startDate,
200   - EndDate = input.QueryDate,
201   - StoreList = storeList.OrderByDescending(s => s.ConsumeAmount).ToList(),
202   - Summary = summary
203   - };
204   -
205   - _logger.LogInformation("门店统计查询完成,门店数:{StoreCount},总员工数:{EmployeeCount},总项目数:{ProjectCount},总消耗业绩:{ConsumeAmount}",
206   - summary.TotalStoreCount, summary.TotalEmployeeCount, summary.TotalProjectCount, summary.TotalConsumeAmount);
  583 + var grandChildren = await GetSubDepartmentsRecursively(child.DepartmentId);
  584 + subDepartments.AddRange(grandChildren);
  585 + }
207 586  
208   - return result;
  587 + return subDepartments;
209 588 }
210 589 catch (Exception ex)
211 590 {
212   - _logger.LogError(ex, "查询门店统计信息时发生错误,查询日期:{QueryDate}", input.QueryDate);
213   - throw NCCException.Oh(ErrorCode.COM1000, "查询门店统计信息失败");
  591 + _logger.LogError(ex, "递归获取子部门列表时发生错误,父部门ID:{ParentId}", parentId);
  592 + return subDepartments;
214 593 }
215 594 }
216 595 #endregion
217 596 }
  597 +
  598 + /// <summary>
  599 + /// 部门信息
  600 + /// </summary>
  601 + public class DepartmentInfo
  602 + {
  603 + /// <summary>
  604 + /// 部门ID
  605 + /// </summary>
  606 + public string DepartmentId { get; set; }
  607 +
  608 + /// <summary>
  609 + /// 部门名称
  610 + /// </summary>
  611 + public string DepartmentName { get; set; }
  612 +
  613 + /// <summary>
  614 + /// 父部门ID
  615 + /// </summary>
  616 + public string ParentId { get; set; }
  617 + }
218 618 }
... ...
创建经理门店业绩统计视图.sql 0 → 100644
  1 +-- 创建经理门店业绩统计视图
  2 +-- 融合经理信息、管理门店、生命线设置、业绩流水数据
  3 +
  4 +DROP VIEW IF EXISTS `v_manager_store_performance`;
  5 +
  6 +CREATE VIEW `v_manager_store_performance` AS
  7 +SELECT
  8 + -- 经理基础信息
  9 + u.F_Id AS manager_user_id, -- 经理用户ID
  10 + u.F_REALNAME AS manager_name, -- 经理姓名
  11 + u.F_GW AS manager_position, -- 经理岗位
  12 + u.F_ORGANIZEID AS manager_organize_id, -- 经理组织ID
  13 +
  14 + -- 事业部信息
  15 + o.F_Id AS business_unit_id, -- 事业部ID
  16 + o.F_FullName AS business_unit_name, -- 事业部名称
  17 + o.F_ParentId AS parent_organize_id, -- 上级组织ID
  18 + parent.F_FullName AS parent_organize_name, -- 上级组织名称
  19 +
  20 + -- 门店信息
  21 + md.F_Id AS store_id, -- 门店ID
  22 + md.mdbm AS store_code, -- 门店编号
  23 + md.dm AS store_name, -- 门店名称
  24 + md.syb AS store_business_unit_id, -- 门店所属事业部ID
  25 +
  26 + -- 生命线设置信息
  27 + COALESCE(zjl.smx1, 0) AS target_performance, -- 目标业绩(生命线1)
  28 + zjl.tcbl1 AS commission_rate1, -- 生命线1提成比例
  29 + zjl.smx2 AS target_performance2, -- 目标业绩2(生命线2)
  30 + zjl.tcbl2 AS commission_rate2, -- 生命线2提成比例
  31 + zjl.smx3 AS target_performance3, -- 目标业绩3(生命线3)
  32 + zjl.tcbl3 AS commission_rate3, -- 生命线3提成比例
  33 +
  34 + -- 业绩流水信息(从现有视图获取)
  35 + flow.order_id, -- 开单ID
  36 + flow.order_date, -- 开单时间
  37 + flow.completed_amount, -- 完成业绩(整单业绩)
  38 + flow.actual_amount, -- 实付业绩
  39 + flow.debt_amount, -- 欠款
  40 + flow.completion_rate, -- 完成率
  41 + flow.golden_triangle, -- 金三角
  42 + flow.member_id, -- 开单会员ID
  43 + flow.member_name, -- 开单会员名称
  44 + flow.member_phone, -- 开单会员手机号
  45 + flow.customer_type, -- 顾客类型
  46 + flow.payment_method, -- 付款方式
  47 + flow.customer_source, -- 客户来源
  48 +
  49 + -- 时间维度
  50 + flow.order_year, -- 开单年份
  51 + flow.order_month, -- 开单月份
  52 + flow.order_quarter, -- 开单季度
  53 + flow.order_date_only, -- 开单日期(不含时间)
  54 +
  55 + -- 统计标识
  56 + CASE
  57 + WHEN flow.order_id IS NOT NULL THEN 1
  58 + ELSE 0
  59 + END AS has_performance, -- 是否有业绩记录
  60 +
  61 + -- 创建时间
  62 + COALESCE(flow.create_time, NOW()) AS create_time,
  63 + COALESCE(flow.modify_time, NOW()) AS modify_time
  64 +
  65 +FROM base_user u
  66 +-- 关联组织信息
  67 +LEFT JOIN base_organize o ON u.F_ORGANIZEID = o.F_Id
  68 +LEFT JOIN base_organize parent ON o.F_ParentId = parent.F_Id
  69 +-- 关联门店信息(通过事业部关联)
  70 +LEFT JOIN lq_mdxx md ON md.syb = o.F_Id
  71 +-- 关联生命线设置
  72 +LEFT JOIN lq_zjl_mdsmxsz zjl ON zjl.zjl_userid = u.F_Id
  73 + AND zjl.md_id = md.F_Id
  74 + AND zjl.deletemark = 0
  75 +-- 关联业绩流水(从现有视图)
  76 +LEFT JOIN v_department_performance_flow flow ON flow.store_id = md.F_Id
  77 + AND flow.department_id = o.F_Id
  78 +
  79 +WHERE u.F_DELETEMARK IS NULL -- 用户未删除
  80 + AND u.F_GW IS NOT NULL -- 有岗位信息
  81 + AND (u.F_GW LIKE '%经理%' OR u.F_GW LIKE '%总经理%' OR u.F_GW LIKE '%主管%') -- 经理岗位
  82 + AND o.F_Category = 'department' -- 部门类型
  83 + AND (o.F_DeleteMark IS NULL OR o.F_DeleteMark != 1) -- 组织未删除
  84 + AND md.F_Id IS NOT NULL; -- 有门店信息
  85 +
  86 +-- 添加视图注释
  87 +--ALTER VIEW `v_manager_store_performance` COMMENT = '经理门店业绩统计视图 - 融合经理信息、管理门店、生命线设置、业绩流水数据';
... ...