Commit f891e7d46c6a111df56fed4579183d9001edf706

Authored by “wangming”
1 parent 28ad29c0

1

历史开单记录接口文档.md 0 → 100644
  1 +# 历史开单记录接口文档
  2 +
  3 +## 说明
  4 +历史开单记录接口用于查询从老系统迁移过来的开单记录数据。
  5 +
  6 +## 接口列表
  7 +
  8 +### 1. 获取历史开单记录列表
  9 +
  10 +**接口地址**: `GET /api/Extend/LqOrderRecords`
  11 +
  12 +**请求参数** (Query参数):
  13 +
  14 +| 参数名 | 类型 | 必填 | 说明 |
  15 +|--------|------|------|------|
  16 +| currentPage | int | 是 | 当前页码,从1开始 |
  17 +| pageSize | int | 是 | 每页数量 |
  18 +| memberNo | string | 否 | 会员编号(模糊匹配) |
  19 +| memberPhone | string | 否 | 会员手机号(模糊匹配) |
  20 +| sidx | string | 否 | 排序字段,默认 "id" |
  21 +| sort | string | 否 | 排序方式,默认 "desc"(asc/desc) |
  22 +
  23 +**请求示例**:
  24 +```javascript
  25 +// 基础查询
  26 +GET /api/Extend/LqOrderRecords?currentPage=1&pageSize=10
  27 +
  28 +// 通过会员编号筛选
  29 +GET /api/Extend/LqOrderRecords?currentPage=1&pageSize=10&memberNo=GK2022120408026
  30 +
  31 +// 通过会员手机号筛选
  32 +GET /api/Extend/LqOrderRecords?currentPage=1&pageSize=10&memberPhone=13699443779
  33 +
  34 +// 组合筛选
  35 +GET /api/Extend/LqOrderRecords?currentPage=1&pageSize=10&memberNo=GK&memberPhone=136
  36 +```
  37 +
  38 +**响应示例**:
  39 +```json
  40 +{
  41 + "code": 200,
  42 + "msg": "操作成功",
  43 + "data": {
  44 + "pagination": {
  45 + "pageIndex": 1,
  46 + "pageSize": 10,
  47 + "total": 100
  48 + },
  49 + "list": [
  50 + {
  51 + "id": 1,
  52 + "orderNo": "KD20231201001",
  53 + "imageName": "image1.jpg",
  54 + "memberNo": "GK2022120408026",
  55 + "memberPhone": "13699443779",
  56 + "memberName": "张三",
  57 + "remarks": "备注信息",
  58 + "createdAt": "2023-12-01T10:00:00",
  59 + "updatedAt": "2023-12-01T10:00:00"
  60 + }
  61 + ]
  62 + }
  63 +}
  64 +```
  65 +
  66 +**响应字段说明**:
  67 +
  68 +| 字段名 | 类型 | 说明 |
  69 +|--------|------|------|
  70 +| id | int | 主键ID |
  71 +| orderNo | string | 开单号 |
  72 +| imageName | string | 图片名称 |
  73 +| memberNo | string | 会员编号 |
  74 +| memberPhone | string | 会员手机号 |
  75 +| memberName | string | 会员名称 |
  76 +| remarks | string | 备注 |
  77 +| createdAt | string | 创建时间(ISO 8601格式) |
  78 +| updatedAt | string | 更新时间(ISO 8601格式) |
  79 +
  80 +---
  81 +
  82 +### 2. 获取历史开单记录详情
  83 +
  84 +**接口地址**: `GET /api/Extend/LqOrderRecords/{id}`
  85 +
  86 +**路径参数**:
  87 +
  88 +| 参数名 | 类型 | 必填 | 说明 |
  89 +|--------|------|------|------|
  90 +| id | int | 是 | 主键ID |
  91 +
  92 +**请求示例**:
  93 +```javascript
  94 +GET /api/Extend/LqOrderRecords/1
  95 +```
  96 +
  97 +**响应示例**:
  98 +```json
  99 +{
  100 + "code": 200,
  101 + "msg": "操作成功",
  102 + "data": {
  103 + "id": 1,
  104 + "orderNo": "KD20231201001",
  105 + "imageName": "image1.jpg",
  106 + "memberNo": "GK2022120408026",
  107 + "memberPhone": "13699443779",
  108 + "memberName": "张三",
  109 + "remarks": "备注信息",
  110 + "createdAt": "2023-12-01T10:00:00",
  111 + "updatedAt": "2023-12-01T10:00:00"
  112 + }
  113 +}
  114 +```
  115 +
  116 +**错误响应** (记录不存在):
  117 +```json
  118 +{
  119 + "code": 500,
  120 + "msg": "未找到该历史开单记录",
  121 + "data": null
  122 +}
  123 +```
  124 +
  125 +---
  126 +
  127 +## 前端调用示例
  128 +
  129 +### Vue/axios 示例
  130 +
  131 +```javascript
  132 +import axios from 'axios'
  133 +
  134 +// 获取列表
  135 +async function getOrderRecordsList(params) {
  136 + try {
  137 + const response = await axios.get('/api/Extend/LqOrderRecords', {
  138 + params: {
  139 + currentPage: params.currentPage || 1,
  140 + pageSize: params.pageSize || 10,
  141 + memberNo: params.memberNo || '',
  142 + memberPhone: params.memberPhone || '',
  143 + sidx: params.sidx || 'id',
  144 + sort: params.sort || 'desc'
  145 + }
  146 + })
  147 + return response.data
  148 + } catch (error) {
  149 + console.error('获取历史开单记录列表失败:', error)
  150 + throw error
  151 + }
  152 +}
  153 +
  154 +// 获取详情
  155 +async function getOrderRecordInfo(id) {
  156 + try {
  157 + const response = await axios.get(`/api/Extend/LqOrderRecords/${id}`)
  158 + return response.data
  159 + } catch (error) {
  160 + console.error('获取历史开单记录详情失败:', error)
  161 + throw error
  162 + }
  163 +}
  164 +
  165 +// 使用示例
  166 +// 1. 查询所有记录
  167 +getOrderRecordsList({ currentPage: 1, pageSize: 10 })
  168 +
  169 +// 2. 通过会员编号筛选
  170 +getOrderRecordsList({
  171 + currentPage: 1,
  172 + pageSize: 10,
  173 + memberNo: 'GK2022120408026'
  174 +})
  175 +
  176 +// 3. 通过会员手机号筛选
  177 +getOrderRecordsList({
  178 + currentPage: 1,
  179 + pageSize: 10,
  180 + memberPhone: '13699443779'
  181 +})
  182 +
  183 +// 4. 获取详情
  184 +getOrderRecordInfo(1)
  185 +```
  186 +
  187 +---
  188 +
  189 +## 注意事项
  190 +
  191 +1. **数据来源**: 这些数据是从老系统迁移过来的历史数据,只读不写
  192 +2. **筛选条件**: `memberNo` 和 `memberPhone` 支持模糊匹配(Contains查询)
  193 +3. **分页**: 必须提供 `currentPage` 和 `pageSize` 参数
  194 +4. **排序**: 默认按 `id` 降序排列,可通过 `sidx` 和 `sort` 参数自定义
  195 +5. **认证**: 所有接口都需要在请求头中携带认证Token
  196 + ```
  197 + Authorization: Bearer {token}
  198 + ```
  199 +
  200 +---
  201 +
  202 +## 接口状态
  203 +
  204 +✅ **已实现并通过测试**
  205 +- 代码已编译通过
  206 +- 接口测试通过,功能正常
  207 +- 测试结果:
  208 + - ✅ 列表查询:成功(共31495条记录)
  209 + - ✅ 会员编号筛选:成功(筛选出30642条记录)
  210 + - ✅ 会员手机号筛选:成功(筛选出2756条记录)
  211 + - ✅ 详情查询:成功
  212 + - ✅ 错误处理:正确返回错误提示
  213 +
... ...
客户GK2020082101082医美会员分析.md 0 → 100644
  1 +# 客户 GK2020082101082 医美会员分析报告
  2 +
  3 +## 客户基本信息
  4 +- **客户编号**: GK2020082101082
  5 +- **客户名称**: 韦明霞
  6 +- **手机号**: 15928992865
  7 +- **当前状态**: `F_IsMedicalMember = 0`(不是医美会员)
  8 +- **医美会员时间**: 2025-11-29(但标记为0,可能是历史记录)
  9 +
  10 +---
  11 +
  12 +## 医美会员计算规则
  13 +
  14 +### 计算逻辑
  15 +根据代码 `LqKhxxService.cs` 中的 `UpdateMemberTypeFlags` 方法:
  16 +
  17 +1. **数据来源**: 查询该会员的所有有效开单品项明细
  18 + - 表:`lq_kd_pxmx`(开单品项明细)
  19 + - 关联:`lq_kd_kdjlb`(开单记录表)
  20 +
  21 +2. **筛选条件**:
  22 + - `pxmx.F_IsEffective = 1`(品项明细有效)
  23 + - `kd.F_IsEffective = 1`(开单记录有效)
  24 + - `pxmx.F_ActualPrice > 0`(实际价格大于0)
  25 + - `pxmx.px != '61'`(排除女神卡)
  26 +
  27 +3. **计算方式**:
  28 + ```csharp
  29 + var medicalAmount = billingItems
  30 + .Where(x => x.ItemCategory == "医美")
  31 + .Sum(x => x.ActualPrice);
  32 +
  33 + if (medicalAmount > MemberInfoUpdateConfig.MedicalMemberAmountThreshold)
  34 + {
  35 + member.IsMedicalMember = 1; // 是医美会员
  36 + }
  37 + else
  38 + {
  39 + member.IsMedicalMember = 0; // 不是医美会员
  40 + }
  41 + ```
  42 +
  43 +4. **阈值配置**:
  44 + - 医美会员判断金额阈值:**3000元**
  45 + - 配置位置:`MemberInfoUpdateConfig.MedicalMemberAmountThreshold = 3000m`
  46 +
  47 +---
  48 +
  49 +## 该客户的医美品项明细
  50 +
  51 +### 医美品项统计(已确认完整)
  52 +- **医美品项总数**: 8个(已确认,无遗漏)
  53 +- **医美品项总金额**: **1459.34元**
  54 +- **医美会员阈值**: 3000元
  55 +- **判断结果**: ❌ **不是医美会员**(1459.34 < 3000)
  56 +
  57 +### 完整品项分类统计
  58 +- **总有效品项数**: 48个
  59 +- **医美品项**: 8个,总金额 1459.34元
  60 +- **生美品项**: 17个,总金额 124490.47元
  61 +- **科美品项**: 23个,总金额 621450.17元
  62 +
  63 +### 医美品项分布
  64 +- **开单记录数**: 1个(2025-11-29)
  65 +- **该开单包含**: 11个品项(其中8个医美,3个其他分类)
  66 +
  67 +### 医美品项明细列表
  68 +
  69 +| 品项ID | 品项名称 | 品项分类 | 实际价格 | 开单日期 |
  70 +|--------|---------|---------|---------|---------|
  71 +| 757744121354913029 | 直播-肝胆排毒 | 医美 | 199.00 | 2025-11-29 |
  72 +| 757740784001746181 | 直播-除皱秒杀 | 医美 | 199.00 | 2025-11-29 |
  73 +| 757743414367225093 | 直播-私密排毒 | 医美 | 199.00 | 2025-11-29 |
  74 +| 757744676965975301 | 直播-脂间艺术定金 | 医美 | 199.00 | 2025-11-29 |
  75 +| 757740991623988485 | 直播-小V脸秒杀 | 医美 | 199.00 | 2025-11-29 |
  76 +| 757742347281761541 | 直播-面部提升 | 医美 | 199.00 | 2025-11-29 |
  77 +| 757743777686226181 | 直播-仪器收紧(私密) | 医美 | 199.00 | 2025-11-29 |
  78 +| 763566455714219269 | 直播-气血针 | 医美 | 66.34 | 2025-11-29 |
  79 +
  80 +**金额计算**:
  81 +- 7个 × 199.00 = 1393.00元
  82 +- 1个 × 66.34 = 66.34元
  83 +- **总计**: 1459.34元
  84 +
  85 +---
  86 +
  87 +## 问题分析
  88 +
  89 +### 为什么不是医美会员?
  90 +
  91 +1. **金额不足**:
  92 + - 该客户的医美品项总金额为 **1459.34元**
  93 + - 医美会员阈值要求 **3000元**
  94 + - 差额:3000 - 1459.34 = **1540.66元**
  95 +
  96 +2. **品项特点**:
  97 + - 所有医美品项都是"直播"相关的低价品项
  98 + - 单价较低(199元、66.34元)
  99 + - 虽然数量有8个,但总金额未达到阈值
  100 +
  101 +3. **F_MedicalMemberTime 字段说明**:
  102 + - 该字段有值(2025-11-29),但 `F_IsMedicalMember = 0`
  103 + - 可能原因:
  104 + - 之前计算时设置了时间,但后来金额不满足条件,标记被重置为0
  105 + - 或者该时间字段是首次购买医美品项的时间,而非成为医美会员的时间
  106 +
  107 +---
  108 +
  109 +## 如何成为医美会员?
  110 +
  111 +### 条件
  112 +客户需要满足以下条件才能成为医美会员:
  113 +
  114 +1. **累计医美品项金额 > 3000元**
  115 + - 当前金额:1459.34元
  116 + - 还需金额:**1540.66元**
  117 +
  118 +2. **品项要求**:
  119 + - 品项分类必须是"医美"
  120 + - 开单记录和品项明细都必须有效(F_IsEffective = 1)
  121 + - 实际价格必须大于0
  122 + - 排除女神卡(px != '61')
  123 +
  124 +### 计算逻辑位置
  125 +- **代码文件**: `netcore/src/Modularity/Extend/NCC.Extend/LqKhxxService.cs`
  126 +- **方法**: `UpdateMemberTypeFlags`
  127 +- **行数**: 1968-1989行
  128 +
  129 +### 配置位置
  130 +- **代码文件**: `netcore/src/Modularity/Extend/NCC.Extend.Entitys/Config/MemberInfoUpdateConfig.cs`
  131 +- **属性**: `MedicalMemberAmountThreshold`
  132 +- **当前值**: 3000元
  133 +
  134 +---
  135 +
  136 +## 其他会员类型统计(参考)
  137 +
  138 +该客户的其他品项统计:
  139 +- **生美品项**: 多个,总金额远超过500元(生美会员阈值)
  140 +- **科美品项**: 多个,有单品项金额超过3800元(科技部会员阈值)
  141 +
  142 +---
  143 +
  144 +## 总结
  145 +
  146 +客户 **GK2020082101082(韦明霞)** 不是医美会员的原因是:
  147 +- ✅ 有医美品项(8个,已确认完整)
  148 +- ❌ 但医美品项总金额(1459.34元)未达到阈值(3000元)
  149 +- 📊 差额:还需1540.66元才能成为医美会员
  150 +- 📅 所有医美品项都在2025-11-29这一个开单记录中
  151 +
  152 +**计算逻辑确认**:
  153 +- ✅ 查询逻辑正确:已查询所有有效开单品项明细
  154 +- ✅ 筛选条件正确:有效记录、价格>0、排除女神卡
  155 +- ✅ 金额计算正确:8个医美品项累计1459.34元
  156 +- ✅ 阈值判断正确:1459.34 < 3000,所以不是医美会员
  157 +
  158 +**建议**: 如果该客户需要成为医美会员,需要再购买至少1540.66元的医美品项。
  159 +
... ...
开单升单逻辑Bug排查报告.md 0 → 100644
  1 +# 开单升单逻辑Bug排查报告
  2 +
  3 +## 排查目的
  4 +确认 `UpdateForNoDelete` 方法中是否存在升单字段赋值错误,因为这是生产环境,需要谨慎验证。
  5 +
  6 +---
  7 +
  8 +## 代码对比分析
  9 +
  10 +### 1. Create方法(新增开单)- 第856-884行
  11 +
  12 +**逻辑正确** ✅
  13 +
  14 +```csharp
  15 +//判断升医美:当前开单包含医美品项 + 之前有医美类型的开单记录 + 实付业绩>=1000
  16 +if (hasMedicalItemInCurrentBilling && hasPreviousMedicalBilling && MedicalItemInCurrentBillingAmount >= 1000)
  17 +{
  18 + entity.UpgradeMedicalBeauty = "是"; // ✅ 正确
  19 +}
  20 +
  21 +//判断升科美:当前开单包含科美品项 + 之前有科美类型的开单记录
  22 +if (hasTechItemInCurrentBilling && hasPreviousTechBilling)
  23 +{
  24 + entity.UpgradeTechBeauty = "是"; // ✅ 正确
  25 +}
  26 +
  27 +//判断升生美:当前开单包含生美品项 + 之前有生美类型的开单记录
  28 +if (hasLifeItemInCurrentBilling && hasPreviousLifeBilling)
  29 +{
  30 + entity.UpgradeLifeBeauty = "是"; // ✅ 正确
  31 +}
  32 +```
  33 +
  34 +---
  35 +
  36 +### 2. UpdateForNoDelete方法(更新开单)- 第1192-1220行
  37 +
  38 +**逻辑存在Bug** ❌
  39 +
  40 +```csharp
  41 +// 第1192行:判断升医美的条件
  42 +var isMedicalProject = hasMedicalItemInCurrentBilling && await _db.Queryable<LqKdPxmxEntity>()
  43 + .Where(x => x.MemberId == entity.Kdhy
  44 + && x.IsEffective == StatusEnum.有效.GetHashCode()
  45 + && x.ItemCategory == "医美" // 判断医美
  46 + && x.ActualPrice > 0
  47 + && x.Px != "61"
  48 + && x.Glkdbh != id)
  49 + .AnyAsync();
  50 +
  51 +// 第1193-1200行:判断升医美,但赋值错误
  52 +if (isMedicalProject && MedicalItemInCurrentBillingAmount >= 1000)
  53 +{
  54 + entity.UpgradeLifeBeauty = "是"; // ❌ BUG:应该是 UpgradeMedicalBeauty
  55 +}
  56 +else
  57 +{
  58 + entity.UpgradeLifeBeauty = "否"; // ❌ BUG:应该是 UpgradeMedicalBeauty
  59 +}
  60 +
  61 +// 第1202行:判断升科美的条件
  62 +var isTechProject = hasTechItemInCurrentBilling && await _db.Queryable<LqKdPxmxEntity>()
  63 + .Where(x => x.MemberId == entity.Kdhy
  64 + && x.IsEffective == StatusEnum.有效.GetHashCode()
  65 + && x.ItemCategory == "科美" // 判断科美
  66 + && x.ActualPrice > 0
  67 + && x.Px != "61"
  68 + && x.Glkdbh != id)
  69 + .AnyAsync();
  70 +
  71 +// 第1203-1210行:判断升科美,赋值正确
  72 +if (isTechProject)
  73 +{
  74 + entity.UpgradeTechBeauty = "是"; // ✅ 正确
  75 +}
  76 +
  77 +// 第1212行:判断升生美的条件
  78 +var isLifeProject = hasLifeItemInCurrentBilling && await _db.Queryable<LqKdPxmxEntity>()
  79 + .Where(x => x.MemberId == entity.Kdhy
  80 + && x.IsEffective == StatusEnum.有效.GetHashCode()
  81 + && x.ItemCategory == "生美" // 判断生美
  82 + && x.ActualPrice > 0
  83 + && x.Px != "61"
  84 + && x.Glkdbh != id)
  85 + .AnyAsync();
  86 +
  87 +// 第1213-1220行:判断升生美,但赋值错误
  88 +if (isLifeProject)
  89 +{
  90 + entity.UpgradeMedicalBeauty = "是"; // ❌ BUG:应该是 UpgradeLifeBeauty
  91 +}
  92 +else
  93 +{
  94 + entity.UpgradeMedicalBeauty = "否"; // ❌ BUG:应该是 UpgradeLifeBeauty
  95 +}
  96 +```
  97 +
  98 +---
  99 +
  100 +### 3. 批量处理方法(BatchProcessHistoricalUpgradeTypes)- 第4342-4348行
  101 +
  102 +**逻辑正确** ✅
  103 +
  104 +```csharp
  105 +// 判断升医美
  106 +billing.UpgradeMedicalBeauty = (hasMedicalItem && hasPreviousMedical && medicalItemAmount >= 1000) ? "是" : "否";
  107 +
  108 +// 判断升科美
  109 +billing.UpgradeTechBeauty = (hasTechItem && hasPreviousTech) ? "是" : "否";
  110 +
  111 +// 判断升生美
  112 +billing.UpgradeLifeBeauty = (hasLifeItem && hasPreviousLife) ? "是" : "否";
  113 +```
  114 +
  115 +---
  116 +
  117 +## Bug确认
  118 +
  119 +### Bug 1:升医美判断错误赋值
  120 +- **位置**:第1193-1200行
  121 +- **问题**:判断升医美的条件,但赋值给了 `UpgradeLifeBeauty`(升生美字段)
  122 +- **正确应该是**:赋值给 `UpgradeMedicalBeauty`
  123 +
  124 +### Bug 2:升生美判断错误赋值
  125 +- **位置**:第1213-1220行
  126 +- **问题**:判断升生美的条件,但赋值给了 `UpgradeMedicalBeauty`(升医美字段)
  127 +- **正确应该是**:赋值给 `UpgradeLifeBeauty`
  128 +
  129 +---
  130 +
  131 +## 影响分析
  132 +
  133 +### 受影响的操作
  134 +- **UpdateForNoDelete方法**:当通过此方法更新开单记录时,升单标记会被错误赋值
  135 +
  136 +### 不受影响的操作
  137 +- **Create方法**:新增开单时,升单标记是正确的
  138 +- **批量处理方法**:批量处理历史数据时,升单标记是正确的
  139 +
  140 +### 实际影响
  141 +1. **如果开单记录只通过Create方法创建,从未通过Update方法更新**:
  142 + - ✅ 升单标记是正确的
  143 +
  144 +2. **如果开单记录通过Update方法更新过**:
  145 + - ❌ 升医美的标记会被错误地写入 `UpgradeLifeBeauty` 字段
  146 + - ❌ 升生美的标记会被错误地写入 `UpgradeMedicalBeauty` 字段
  147 + - ✅ 升科美的标记是正确的
  148 +
  149 +3. **数据混乱情况**:
  150 + - 如果一个开单同时满足升医美和升生美的条件,通过Update方法更新后:
  151 + - `UpgradeLifeBeauty` 会被设置为"是"(但实际应该是升医美)
  152 + - `UpgradeMedicalBeauty` 会被设置为"是"(但实际应该是升生美)
  153 + - 数据完全错位
  154 +
  155 +---
  156 +
  157 +## 验证建议
  158 +
  159 +### 1. 检查Update方法使用频率
  160 +- 查询最近几个月通过 `UpdateForNoDelete` 方法更新的开单记录数量
  161 +- 确认是否有大量数据受到影响
  162 +
  163 +### 2. 抽样验证数据
  164 +- 随机抽取一些通过Update方法更新的开单记录
  165 +- 检查其升单标记是否与品项明细匹配
  166 +- 如果发现不匹配,说明Bug确实存在
  167 +
  168 +### 3. 对比Create和Update的数据
  169 +- 对比同一时间段通过Create和Update方法处理的升单标记
  170 +- 如果Update方法处理的数据有明显异常,说明Bug存在
  171 +
  172 +---
  173 +
  174 +## 修复方案
  175 +
  176 +### 修复代码位置
  177 +- **文件**:`netcore/src/Modularity/Extend/NCC.Extend/LqKdKdjlbService.cs`
  178 +- **方法**:`UpdateForNoDelete`
  179 +- **行数**:第1195行和第1215行
  180 +
  181 +### 修复内容
  182 +
  183 +**第1195行**:
  184 +```csharp
  185 +// 修复前
  186 +entity.UpgradeLifeBeauty = "是";
  187 +
  188 +// 修复后
  189 +entity.UpgradeMedicalBeauty = "是";
  190 +```
  191 +
  192 +**第1199行**:
  193 +```csharp
  194 +// 修复前
  195 +entity.UpgradeLifeBeauty = "否";
  196 +
  197 +// 修复后
  198 +entity.UpgradeMedicalBeauty = "否";
  199 +```
  200 +
  201 +**第1215行**:
  202 +```csharp
  203 +// 修复前
  204 +entity.UpgradeMedicalBeauty = "是";
  205 +
  206 +// 修复后
  207 +entity.UpgradeLifeBeauty = "是";
  208 +```
  209 +
  210 +**第1219行**:
  211 +```csharp
  212 +// 修复前
  213 +entity.UpgradeMedicalBeauty = "否";
  214 +
  215 +// 修复后
  216 +entity.UpgradeLifeBeauty = "否";
  217 +```
  218 +
  219 +---
  220 +
  221 +## 结论
  222 +
  223 +**Bug确实存在**,但需要确认:
  224 +1. `UpdateForNoDelete` 方法在生产环境中的使用频率
  225 +2. 是否有历史数据受到影响
  226 +3. 是否需要修复历史数据
  227 +
  228 +**建议**:
  229 +1. 先修复代码Bug
  230 +2. 评估是否需要修复历史数据(如果Update方法使用频率不高,可能影响范围有限)
  231 +3. 如果影响范围大,考虑使用批量处理方法重新计算受影响的开单记录的升单标记
  232 +
... ...
开单升单逻辑说明.md 0 → 100644
  1 +# 开单升单逻辑说明文档
  2 +
  3 +## 概述
  4 +升单是指已经开过会员再次消费的情况。系统会根据当前开单的品项类型和会员历史开单记录,自动判断是否为升单,并标记升单类型。
  5 +
  6 +## 升单类型字段
  7 +- `F_UpgradeLifeBeauty`:升生美(再次开单时,包含生美品项的订单)
  8 +- `F_UpgradeTechBeauty`:升科美(再次开单时,包含科美品项的订单)
  9 +- `F_UpgradeMedicalBeauty`:升医美(再次开单时,包含医美品项的订单)
  10 +
  11 +---
  12 +
  13 +## 升单判断逻辑
  14 +
  15 +### 1. 升医美(UpgradeMedicalBeauty)
  16 +
  17 +**判断条件**(需同时满足):
  18 +1. ✅ **当前开单包含医美品项**
  19 + - 检查当前开单的品项明细中,是否有品项分类(`lq_xmzl.qt2`)为"医美"的记录
  20 +
  21 +2. ✅ **之前有医美类型的开单记录**
  22 + - 查询该会员(`kdhy`)在**当前开单之前**的所有有效开单品项明细
  23 + - 筛选条件:
  24 + - `F_IsEffective = 1`(品项明细有效)
  25 + - `ItemCategory = "医美"`(品项分类为医美)
  26 + - `ActualPrice > 0`(实际价格大于0)
  27 + - `Px != "61"`(排除女神卡)
  28 +
  29 +3. ✅ **当前开单的医美品项实付业绩 >= 1000元**
  30 + - 计算当前开单中所有医美品项的 `actualPrice` 总和
  31 + - 必须 >= 1000元
  32 +
  33 +**代码位置**:`LqKdKdjlbService.cs` 第856-864行
  34 +
  35 +**代码逻辑**:
  36 +```csharp
  37 +//判断升医美:当前开单包含医美品项 + 之前有医美类型的开单记录 + 实付业绩>=1000
  38 +if (hasMedicalItemInCurrentBilling && hasPreviousMedicalBilling && MedicalItemInCurrentBillingAmount >= 1000)
  39 +{
  40 + entity.UpgradeMedicalBeauty = "是";
  41 +}
  42 +else
  43 +{
  44 + entity.UpgradeMedicalBeauty = "否";
  45 +}
  46 +```
  47 +
  48 +---
  49 +
  50 +### 2. 升科美(UpgradeTechBeauty)
  51 +
  52 +**判断条件**(需同时满足):
  53 +1. ✅ **当前开单包含科美品项**
  54 + - 检查当前开单的品项明细中,是否有品项分类为"科美"的记录
  55 +
  56 +2. ✅ **之前有科美类型的开单记录**
  57 + - 查询该会员在当前开单之前的所有有效开单品项明细
  58 + - 筛选条件:
  59 + - `F_IsEffective = 1`
  60 + - `ItemCategory = "科美"`
  61 + - `ActualPrice > 0`
  62 + - `Px != "61"`(排除女神卡)
  63 +
  64 +**代码位置**:`LqKdKdjlbService.cs` 第866-874行
  65 +
  66 +**代码逻辑**:
  67 +```csharp
  68 +//判断升科美:当前开单包含科美品项 + 之前有科美类型的开单记录
  69 +if (hasTechItemInCurrentBilling && hasPreviousTechBilling)
  70 +{
  71 + entity.UpgradeTechBeauty = "是";
  72 +}
  73 +else
  74 +{
  75 + entity.UpgradeTechBeauty = "否";
  76 +}
  77 +```
  78 +
  79 +---
  80 +
  81 +### 3. 升生美(UpgradeLifeBeauty)
  82 +
  83 +**判断条件**(需同时满足):
  84 +1. ✅ **当前开单包含生美品项**
  85 + - 检查当前开单的品项明细中,是否有品项分类为"生美"的记录
  86 +
  87 +2. ✅ **之前有生美类型的开单记录**
  88 + - 查询该会员在当前开单之前的所有有效开单品项明细
  89 + - 筛选条件:
  90 + - `F_IsEffective = 1`
  91 + - `ItemCategory = "生美"`
  92 + - `ActualPrice > 0`
  93 + - `Px != "61"`(排除女神卡)
  94 +
  95 +**代码位置**:`LqKdKdjlbService.cs` 第876-884行
  96 +
  97 +**代码逻辑**:
  98 +```csharp
  99 +//判断升生美:当前开单包含生美品项 + 之前有生美类型的开单记录
  100 +if (hasLifeItemInCurrentBilling && hasPreviousLifeBilling)
  101 +{
  102 + entity.UpgradeLifeBeauty = "是";
  103 +}
  104 +else
  105 +{
  106 + entity.UpgradeLifeBeauty = "否";
  107 +}
  108 +```
  109 +
  110 +---
  111 +
  112 +## 关键代码位置
  113 +
  114 +### 新增开单(Create方法)
  115 +- **文件**:`netcore/src/Modularity/Extend/NCC.Extend/LqKdKdjlbService.cs`
  116 +- **方法**:`Create`(第799-884行)
  117 +- **逻辑**:在创建新开单时,自动判断并设置升单类型字段
  118 +
  119 +### 更新开单(Update方法)
  120 +- **文件**:`netcore/src/Modularity/Extend/NCC.Extend/LqKdKdjlbService.cs`
  121 +- **方法**:`Update`(第1190-1220行)
  122 +- **⚠️ 注意**:Update方法中的升单判断逻辑**存在Bug**(见下方说明)
  123 +
  124 +### 批量处理历史数据
  125 +- **文件**:`netcore/src/Modularity/Extend/NCC.Extend/LqKdKdjlbService.cs`
  126 +- **方法**:`BatchProcessHistoricalUpgradeTypes`(第4220-4398行)
  127 +- **逻辑**:批量更新历史开单记录的升单类型字段
  128 +
  129 +---
  130 +
  131 +## ⚠️ 发现的Bug
  132 +
  133 +### Update方法中的字段赋值错误
  134 +
  135 +**位置**:`LqKdKdjlbService.cs` 第1192-1220行
  136 +
  137 +**问题**:
  138 +1. **第1195行**:判断升医美,但赋值给了 `UpgradeLifeBeauty`(应该是 `UpgradeMedicalBeauty`)
  139 +2. **第1215行**:判断升生美,但赋值给了 `UpgradeMedicalBeauty`(应该是 `UpgradeLifeBeauty`)
  140 +
  141 +**错误代码**:
  142 +```csharp
  143 +// 第1192-1200行:判断升医美,但赋值错误
  144 +var isMedicalProject = hasMedicalItemInCurrentBilling && await _db.Queryable<LqKdPxmxEntity>()...
  145 +if (isMedicalProject && MedicalItemInCurrentBillingAmount >= 1000)
  146 +{
  147 + entity.UpgradeLifeBeauty = "是"; // ❌ 错误:应该是 UpgradeMedicalBeauty
  148 +}
  149 +
  150 +// 第1212-1220行:判断升生美,但赋值错误
  151 +var isLifeProject = hasLifeItemInCurrentBilling && await _db.Queryable<LqKdPxmxEntity>()...
  152 +if (isLifeProject)
  153 +{
  154 + entity.UpgradeMedicalBeauty = "是"; // ❌ 错误:应该是 UpgradeLifeBeauty
  155 +}
  156 +```
  157 +
  158 +**正确代码应该是**:
  159 +```csharp
  160 +// 升医美
  161 +if (isMedicalProject && MedicalItemInCurrentBillingAmount >= 1000)
  162 +{
  163 + entity.UpgradeMedicalBeauty = "是"; // ✅ 正确
  164 +}
  165 +
  166 +// 升生美
  167 +if (isLifeProject)
  168 +{
  169 + entity.UpgradeLifeBeauty = "是"; // ✅ 正确
  170 +}
  171 +```
  172 +
  173 +---
  174 +
  175 +## 数据来源说明
  176 +
  177 +### 品项分类获取
  178 +- **表**:`lq_xmzl`(项目资料表)
  179 +- **字段**:`qt2`(品项分类:生美/科美/医美)
  180 +- **关联**:通过 `lq_kd_pxmx.px = lq_xmzl.F_Id` 关联
  181 +
  182 +### 历史开单记录查询
  183 +- **表**:`lq_kd_pxmx`(开单品项明细表)
  184 +- **筛选条件**:
  185 + - `MemberId = 当前会员ID`
  186 + - `F_IsEffective = 1`(有效)
  187 + - `ItemCategory = 对应类型`(生美/科美/医美)
  188 + - `ActualPrice > 0`(实际价格大于0)
  189 + - `Px != "61"`(排除女神卡)
  190 + - `Glkdbh != 当前开单ID`(排除当前开单本身,仅查询历史记录)
  191 +
  192 +---
  193 +
  194 +## 升单判断流程图
  195 +
  196 +### 升医美流程
  197 +```
  198 +开始
  199 + ↓
  200 +当前开单是否包含医美品项?
  201 + ↓ 是
  202 +之前是否有医美类型的开单记录?
  203 + ↓ 是
  204 +当前开单医美品项实付业绩 >= 1000元?
  205 + ↓ 是
  206 +标记为:升医美 = "是"
  207 + ↓
  208 +结束
  209 +```
  210 +
  211 +### 升科美流程
  212 +```
  213 +开始
  214 + ↓
  215 +当前开单是否包含科美品项?
  216 + ↓ 是
  217 +之前是否有科美类型的开单记录?
  218 + ↓ 是
  219 +标记为:升科美 = "是"
  220 + ↓
  221 +结束
  222 +```
  223 +
  224 +### 升生美流程
  225 +```
  226 +开始
  227 + ↓
  228 +当前开单是否包含生美品项?
  229 + ↓ 是
  230 +之前是否有生美类型的开单记录?
  231 + ↓ 是
  232 +标记为:升生美 = "是"
  233 + ↓
  234 +结束
  235 +```
  236 +
  237 +---
  238 +
  239 +## 注意事项
  240 +
  241 +1. **升单判断是独立的**:一个开单可以同时标记为升医美、升科美、升生美(如果同时满足条件)
  242 +
  243 +2. **时间顺序很重要**:判断"之前是否有开单记录"时,是基于开单日期(`kdrq`)来判断的,必须是当前开单日期之前的记录
  244 +
  245 +3. **排除女神卡**:所有升单判断都排除品项ID为"61"的女神卡
  246 +
  247 +4. **有效记录**:只统计有效的开单记录和品项明细(`F_IsEffective = 1`)
  248 +
  249 +5. **医美升单特殊要求**:升医美除了需要满足前两个条件外,还需要当前开单的医美品项实付业绩 >= 1000元
  250 +
  251 +---
  252 +
  253 +## 修复建议
  254 +
  255 +建议修复 `Update` 方法中的字段赋值错误,确保:
  256 +- 升医美 → 赋值给 `UpgradeMedicalBeauty`
  257 +- 升科美 → 赋值给 `UpgradeTechBeauty`
  258 +- 升生美 → 赋值给 `UpgradeLifeBeauty`
  259 +
... ...
集团驾驶舱标题修改记录.md 0 → 100644
  1 +# 集团驾驶舱标题修改记录
  2 +
  3 +## 修改时间
  4 +2025-12-28
  5 +
  6 +## 修改状态
  7 +✅ **已完成** - 所有标题已成功修改
  8 +
  9 +## 原始标题记录
  10 +
  11 +### 一、主页面标题
  12 +- **文件**: `antis-ncc-admin/src/views/statisticsList/form9.vue`
  13 +- **位置**: 第6行
  14 +- **原始**: `集团驾驶舱` + `本月经营动态监测`
  15 +
  16 +### 二、核心 KPI 指标(6个)
  17 +- **文件**: `antis-ncc-admin/src/views/statisticsList/form9.vue`
  18 +- **位置**: 第620-625行(kpiList数组)
  19 +1. `本月成交总额`
  20 +2. `本月消耗金额`
  21 +3. `完成业绩(净额)`
  22 +4. `开单目标达成`
  23 +5. `本月拓客人数`
  24 +6. `退卡总计`
  25 +
  26 +### 三、卡片模块标题(11个)
  27 +- **文件**: `antis-ncc-admin/src/views/statisticsList/form9.vue`
  28 +1. 第63行: `会员核心指标`
  29 +2. 第249行: `会员类型分布`
  30 +3. 第259行: `会员分类统计`
  31 +4. 第297行: `营收与服务产出趋势分析`
  32 +5. 第311行: `拓客全链路转化漏斗`
  33 +6. 第327行: `门店业绩琅琊榜`
  34 +7. 第342行: `核心员效贡献矩阵`
  35 +8. 第370行: `金三角战队协同榜`
  36 +9. 第387行: `会员到店频次分布`
  37 +10. 第394行: `消耗品项 TOP 10`
  38 +11. 第409行: `开单品项 TOP 10`
  39 +
  40 +### 四、KPI 穿透弹窗标题(6个)
  41 +- **文件**: `antis-ncc-admin/src/views/statisticsList/form9.vue`
  42 +- **位置**: 第715-722行(titleMap对象)
  43 +1. `成交数据深度分析`
  44 +2. `消耗数据深度分析`
  45 +3. `净业绩完成度分析`
  46 +4. `开单目标达成度分析`
  47 +5. `拓客数据深度分析`
  48 +6. `退卡数据深度分析`
  49 +
  50 +### 五、年度经营统计分析页面
  51 +- **文件**: `antis-ncc-admin/src/views/extend/annualSummary/dashboard/index.vue`
  52 +
  53 +#### 主标题
  54 +- 第6行: `年度经营统计分析`
  55 +
  56 +#### 子页面标签(9个)
  57 +- 第32行: `月度趋势分析`
  58 +- 第35行: `全年门店业绩表`
  59 +- 第38行: `全年门店消耗表`
  60 +- 第41行: `年度门店人头表`
  61 +- 第44行: `年度门店人次表`
  62 +- 第47行: `年度门店项目数表`
  63 +- 第50行: `门店五项指标统计`
  64 +- 第53行: `事业部五项指标统计`
  65 +- 第56行: `事业部内部汇总`
  66 +
  67 +#### 子页面图表标题(10个)
  68 +- 第70行: `业绩走势对比`
  69 +- 第79行: `消耗走势对比`
  70 +- 第90行: `客头数走势`
  71 +- 第99行: `客次数走势`
  72 +- 第108行: `项目数走势`
  73 +- 第118行: `月度趋势数据列表`
  74 +- 第140行: `业绩走势图`
  75 +- 第148行: `业绩数据列表`
  76 +- 第171行: `消耗走势图`
  77 +- 第179行: `消耗数据列表`
  78 +
  79 +### 六、KPI 穿透子页面内部标题
  80 +
  81 +#### 成交分析页面
  82 +- **文件**: `antis-ncc-admin/src/components/kpi-drill/billing-analysis.vue`
  83 +- 第9行: `每日开单金额 & 人数`
  84 +- 第18行: `本月成交明细`
  85 +
  86 +#### 消耗分析页面
  87 +- **文件**: `antis-ncc-admin/src/components/kpi-drill/consume-analysis.vue`
  88 +- 第9行: `每日消耗金额 & 人数`
  89 +- 第18行: `本月消耗明细`
  90 +
  91 +#### 退卡分析页面
  92 +- **文件**: `antis-ncc-admin/src/components/kpi-drill/refund-analysis.vue`
  93 +- 第9行: `各门店退卡金额分布(不包含转卡)`
  94 +- 第21行: `退卡明细`
  95 +
  96 +---
  97 +
  98 +## 新标题方案
  99 +
  100 +### 一、主页面标题
  101 +- 新: `战略决策指挥中心` + `实时经营态势感知`
  102 +
  103 +### 二、核心 KPI 指标(6个)
  104 +1. `营收核心指标`
  105 +2. `服务产出价值`
  106 +3. `净收益达成`
  107 +4. `目标完成度`
  108 +5. `新客增长量`
  109 +6. `风险管控指标`
  110 +
  111 +### 三、卡片模块标题(11个)
  112 +1. `会员资产全景`
  113 +2. `会员结构洞察`
  114 +3. `会员价值分层`
  115 +4. `经营效能趋势`
  116 +5. `客户获取转化链`
  117 +6. `门店卓越榜`
  118 +7. `团队效能矩阵`
  119 +8. `协同作战榜`
  120 +9. `客户活跃度分析`
  121 +10. `热门服务品项`
  122 +11. `热销产品品项`
  123 +
  124 +### 四、KPI 穿透弹窗标题(6个)
  125 +1. `营收洞察报告`
  126 +2. `服务价值分析`
  127 +3. `净收益达成分析`
  128 +4. `目标达成诊断`
  129 +5. `客户增长分析`
  130 +6. `风险预警分析`
  131 +
  132 +### 五、年度经营统计分析页面
  133 +
  134 +#### 主标题
  135 +- 新: `年度经营全景报告`
  136 +
  137 +#### 子页面标签(9个)
  138 +1. `月度经营趋势`
  139 +2. `年度业绩总览`
  140 +3. `年度消耗总览`
  141 +4. `年度客流量总览`
  142 +5. `年度到店频次总览`
  143 +6. `年度项目量总览`
  144 +7. `门店综合指标`
  145 +8. `事业部综合指标`
  146 +9. `事业部经营汇总`
  147 +
  148 +#### 子页面图表标题(10个)
  149 +1. `业绩趋势对比`
  150 +2. `消耗趋势对比`
  151 +3. `客流量趋势`
  152 +4. `到店频次趋势`
  153 +5. `项目量趋势`
  154 +6. `月度趋势明细`
  155 +7. `业绩趋势图`
  156 +8. `业绩明细表`
  157 +9. `消耗趋势图`
  158 +10. `消耗明细表`
  159 +
  160 +### 六、KPI 穿透子页面内部标题
  161 +
  162 +#### 成交分析页面
  163 +- `日度成交趋势`
  164 +- `成交明细清单`
  165 +
  166 +#### 消耗分析页面
  167 +- `日度消耗趋势`
  168 +- `消耗明细清单`
  169 +
  170 +#### 退卡分析页面
  171 +- `门店退卡分布`
  172 +- `退卡明细清单`
  173 +
  174 +---
  175 +
  176 +## 修改完成确认
  177 +
  178 +### 修改的文件列表
  179 +1. ✅ `antis-ncc-admin/src/views/statisticsList/form9.vue` - 集团驾驶舱主页面
  180 +2. ✅ `antis-ncc-admin/src/views/extend/annualSummary/dashboard/index.vue` - 年度经营统计分析页面
  181 +3. ✅ `antis-ncc-admin/src/components/kpi-drill/billing-analysis.vue` - 成交分析子页面
  182 +4. ✅ `antis-ncc-admin/src/components/kpi-drill/consume-analysis.vue` - 消耗分析子页面
  183 +5. ✅ `antis-ncc-admin/src/components/kpi-drill/refund-analysis.vue` - 退卡分析子页面
  184 +
  185 +### 修改统计
  186 +- **总修改项**: 42个标题
  187 +- **修改文件数**: 5个文件
  188 +- **语法检查**: ✅ 通过
  189 +
  190 +### 注意事项
  191 +- 所有原始标题已完整记录,如需回滚可参考本文件
  192 +- 修改后的标题保持了原有的功能逻辑不变
  193 +- 所有修改已通过语法检查,无错误
  194 +
... ...