Commit f891e7d46c6a111df56fed4579183d9001edf706
1 parent
28ad29c0
1
Showing
5 changed files
with
1057 additions
and
0 deletions
历史开单记录接口文档.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 | + | ... | ... |