feat(demo-web): 图表编号、坐标轴与策略文档同步
- 合规/质量/营销多图:Top10 轴标签、单位、CMP/QLT/MKT 编号 - 审计与 AE 滞后:CMP-CV-101/701 整合视图;mock 数据补充 - QLT-AE-1004/1005、QLT-CNC-302 动态 Top N、MKT 柱状轴配置等 Made-with: Cursor
This commit is contained in:
parent
56dd8a9628
commit
0c80de9da9
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -30,13 +30,35 @@ export function buildAeMonthlyByOccurrence(context: AnalysisContext) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** CMP-AE-101 补充:为月度序列计算对应年度平均数 */
|
||||||
|
export function buildAeMonthlyWithYearAverage(context: AnalysisContext) {
|
||||||
|
const monthly = buildAeMonthlyByOccurrence(context)
|
||||||
|
const yearlyBucket = new Map<string, number[]>()
|
||||||
|
monthly.months.forEach((month, idx) => {
|
||||||
|
const year = month.slice(0, 4)
|
||||||
|
const values = yearlyBucket.get(year) ?? []
|
||||||
|
values.push(monthly.values[idx])
|
||||||
|
yearlyBucket.set(year, values)
|
||||||
|
})
|
||||||
|
const yearlyAvg = new Map<string, number>()
|
||||||
|
yearlyBucket.forEach((values, year) => {
|
||||||
|
const avg = values.reduce((sum, val) => sum + val, 0) / values.length
|
||||||
|
yearlyAvg.set(year, Number(avg.toFixed(2)))
|
||||||
|
})
|
||||||
|
return {
|
||||||
|
months: monthly.months,
|
||||||
|
values: monthly.values,
|
||||||
|
yearAvg: monthly.months.map((month) => yearlyAvg.get(month.slice(0, 4)) ?? 0),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** 产品事件 Top(全期,按发生日期归属可选扩展;此处为全量计数) */
|
/** 产品事件 Top(全期,按发生日期归属可选扩展;此处为全量计数) */
|
||||||
export function buildPsurTopProducts(context: AnalysisContext) {
|
export function buildPsurTopProducts(context: AnalysisContext, topN = 10) {
|
||||||
const counter = new Map<string, number>()
|
const counter = new Map<string, number>()
|
||||||
context.ae.forEach((record) => {
|
context.ae.forEach((record) => {
|
||||||
counter.set(record.productName, (counter.get(record.productName) ?? 0) + 1)
|
counter.set(record.productName, (counter.get(record.productName) ?? 0) + 1)
|
||||||
})
|
})
|
||||||
const sorted = [...counter.entries()].sort((a, b) => b[1] - a[1]).slice(0, 6)
|
const sorted = [...counter.entries()].sort((a, b) => b[1] - a[1]).slice(0, topN)
|
||||||
return {
|
return {
|
||||||
labels: sorted.map((item) => item[0]),
|
labels: sorted.map((item) => item[0]),
|
||||||
values: sorted.map((item) => item[1]),
|
values: sorted.map((item) => item[1]),
|
||||||
|
|
@ -75,6 +97,26 @@ export function buildGlobalMonthlyPpm(context: AnalysisContext) {
|
||||||
return { months, ppm }
|
return { months, ppm }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** CMP-AE-201 补充:月度涉及产品数与 AE 报告数(可设置截止月) */
|
||||||
|
export function buildMonthlyProductAndAeCounts(context: AnalysisContext, endMonth = '9999-12') {
|
||||||
|
const productSets = new Map<string, Set<string>>()
|
||||||
|
const aeCount = new Map<string, number>()
|
||||||
|
context.ae.forEach((record) => {
|
||||||
|
const month = monthKey(record.occurrenceDate)
|
||||||
|
if (month > endMonth) return
|
||||||
|
const products = productSets.get(month) ?? new Set<string>()
|
||||||
|
products.add(record.productName)
|
||||||
|
productSets.set(month, products)
|
||||||
|
aeCount.set(month, (aeCount.get(month) ?? 0) + 1)
|
||||||
|
})
|
||||||
|
const months = [...aeCount.keys()].sort()
|
||||||
|
return {
|
||||||
|
months,
|
||||||
|
productCounts: months.map((m) => productSets.get(m)?.size ?? 0),
|
||||||
|
aeCounts: months.map((m) => aeCount.get(m) ?? 0),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** CMP-AE-501:SAE 报告条数(按发生月) */
|
/** CMP-AE-501:SAE 报告条数(按发生月) */
|
||||||
export function buildSaeMonthlyByOccurrence(context: AnalysisContext) {
|
export function buildSaeMonthlyByOccurrence(context: AnalysisContext) {
|
||||||
const counter = new Map<string, number>()
|
const counter = new Map<string, number>()
|
||||||
|
|
@ -134,12 +176,19 @@ export function buildReportingTimelinessRate(context: AnalysisContext, threshold
|
||||||
return { rate: Number(((ok / denom) * 100).toFixed(1)), sample: denom }
|
return { rate: Number(((ok / denom) * 100).toFixed(1)), sample: denom }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** CMP-AE-301:器械故障 Top */
|
/** CMP-AE-301:器械故障 Top10(含每类涉及产品信息) */
|
||||||
export function buildTopDeviceFailures(context: AnalysisContext, topN = 10) {
|
export function buildTopDeviceFailures(context: AnalysisContext, topN = 10) {
|
||||||
const counter = new Map<string, number>()
|
const counter = new Map<string, number>()
|
||||||
|
const productsByFailure = new Map<string, Map<string, number>>()
|
||||||
context.ae.forEach((r) => {
|
context.ae.forEach((r) => {
|
||||||
const k = r.deviceFailure || '(空)'
|
const k = r.deviceFailure || '(空)'
|
||||||
counter.set(k, (counter.get(k) ?? 0) + 1)
|
counter.set(k, (counter.get(k) ?? 0) + 1)
|
||||||
|
const p = r.productName || '(空)'
|
||||||
|
if (!productsByFailure.has(k)) {
|
||||||
|
productsByFailure.set(k, new Map<string, number>())
|
||||||
|
}
|
||||||
|
const productCounter = productsByFailure.get(k)!
|
||||||
|
productCounter.set(p, (productCounter.get(p) ?? 0) + 1)
|
||||||
})
|
})
|
||||||
const sorted = [...counter.entries()].sort((a, b) => b[1] - a[1]).slice(0, topN)
|
const sorted = [...counter.entries()].sort((a, b) => b[1] - a[1]).slice(0, topN)
|
||||||
const total = context.ae.length || 1
|
const total = context.ae.length || 1
|
||||||
|
|
@ -147,6 +196,14 @@ export function buildTopDeviceFailures(context: AnalysisContext, topN = 10) {
|
||||||
labels: sorted.map((i) => i[0]),
|
labels: sorted.map((i) => i[0]),
|
||||||
values: sorted.map((i) => i[1]),
|
values: sorted.map((i) => i[1]),
|
||||||
pct: sorted.map((i) => Number(((i[1] / total) * 100).toFixed(1))),
|
pct: sorted.map((i) => Number(((i[1] / total) * 100).toFixed(1))),
|
||||||
|
topProducts: sorted.map(([failure]) => {
|
||||||
|
const productCounter = productsByFailure.get(failure)
|
||||||
|
if (!productCounter) return []
|
||||||
|
return [...productCounter.entries()]
|
||||||
|
.sort((a, b) => b[1] - a[1])
|
||||||
|
.slice(0, 3)
|
||||||
|
.map(([product, count]) => ({ product, count }))
|
||||||
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -251,6 +308,7 @@ export function buildComplianceMatching(context: AnalysisContext) {
|
||||||
let lagCompliantFromRegistration = 0
|
let lagCompliantFromRegistration = 0
|
||||||
let lagSample = 0
|
let lagSample = 0
|
||||||
let lagCompliantFromC3 = 0
|
let lagCompliantFromC3 = 0
|
||||||
|
const matchedLagDays: number[] = []
|
||||||
for (const c of flagged) {
|
for (const c of flagged) {
|
||||||
const candidates = context.ae.filter(
|
const candidates = context.ae.filter(
|
||||||
(a) =>
|
(a) =>
|
||||||
|
|
@ -268,6 +326,7 @@ export function buildComplianceMatching(context: AnalysisContext) {
|
||||||
lagSample += 1
|
lagSample += 1
|
||||||
const lagReg = daysBetween(best.reviewDate, best.registrationDate)
|
const lagReg = daysBetween(best.reviewDate, best.registrationDate)
|
||||||
if (lagReg >= 0 && lagReg <= 15) lagCompliantFromRegistration += 1
|
if (lagReg >= 0 && lagReg <= 15) lagCompliantFromRegistration += 1
|
||||||
|
if (lagReg >= 0) matchedLagDays.push(lagReg)
|
||||||
const lagC3 = daysBetween(best.reviewDate, c.registerDate)
|
const lagC3 = daysBetween(best.reviewDate, c.registerDate)
|
||||||
if (lagC3 >= 0 && lagC3 <= 15) lagCompliantFromC3 += 1
|
if (lagC3 >= 0 && lagC3 <= 15) lagCompliantFromC3 += 1
|
||||||
}
|
}
|
||||||
|
|
@ -282,6 +341,7 @@ export function buildComplianceMatching(context: AnalysisContext) {
|
||||||
lagSample > 0 ? Number(((lagCompliantFromRegistration / lagSample) * 100).toFixed(1)) : 0,
|
lagSample > 0 ? Number(((lagCompliantFromRegistration / lagSample) * 100).toFixed(1)) : 0,
|
||||||
timelinessFromC3Pct: lagSample > 0 ? Number(((lagCompliantFromC3 / lagSample) * 100).toFixed(1)) : 0,
|
timelinessFromC3Pct: lagSample > 0 ? Number(((lagCompliantFromC3 / lagSample) * 100).toFixed(1)) : 0,
|
||||||
lagSample,
|
lagSample,
|
||||||
|
matchedLagDays,
|
||||||
missedRows,
|
missedRows,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -393,7 +393,7 @@ export function buildComprehensiveInsightRows(context: AnalysisContext): Insight
|
||||||
dimension,
|
dimension,
|
||||||
pageTitle: def.title,
|
pageTitle: def.title,
|
||||||
chartId: chart.id,
|
chartId: chart.id,
|
||||||
chartTitle: chart.title,
|
chartTitle: typeof chart.title === 'function' ? chart.title(context) : chart.title,
|
||||||
bullets,
|
bullets,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,8 @@ export interface ChartExplain {
|
||||||
|
|
||||||
export interface ChartDefinition {
|
export interface ChartDefinition {
|
||||||
id: string
|
id: string
|
||||||
title: string
|
/** 静态文案,或根据上下文返回动态标题(如 Top N 与柱数一致) */
|
||||||
|
title: string | ((context: AnalysisContext) => string)
|
||||||
/** 一句话摘要,可放在卡片标题行右侧 */
|
/** 一句话摘要,可放在卡片标题行右侧 */
|
||||||
description?: string
|
description?: string
|
||||||
/** 取数范围与分析逻辑(与《质量方向分析》等指标文档对齐) */
|
/** 取数范围与分析逻辑(与《质量方向分析》等指标文档对齐) */
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,13 @@ function resolveOption(builder?: (ctx: AnalysisContext) => EChartsOption) {
|
||||||
return builder(context.value)
|
return builder(context.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function resolveChartTitle(chart: { title: string | ((ctx: AnalysisContext) => string) }) {
|
||||||
|
if (typeof chart.title === 'function') {
|
||||||
|
return context.value ? chart.title(context.value) : '…'
|
||||||
|
}
|
||||||
|
return chart.title
|
||||||
|
}
|
||||||
|
|
||||||
const pillarText: Record<string, string> = {
|
const pillarText: Record<string, string> = {
|
||||||
goal: '目标层',
|
goal: '目标层',
|
||||||
monitor: '监测层',
|
monitor: '监测层',
|
||||||
|
|
@ -58,7 +65,7 @@ const pillarText: Record<string, string> = {
|
||||||
<el-row :gutter="16">
|
<el-row :gutter="16">
|
||||||
<el-col v-for="chart in section.charts" :key="chart.id" :xs="24" :sm="24" :md="12">
|
<el-col v-for="chart in section.charts" :key="chart.id" :xs="24" :sm="24" :md="12">
|
||||||
<ChartCard
|
<ChartCard
|
||||||
:title="chart.title"
|
:title="resolveChartTitle(chart)"
|
||||||
:description="chart.description"
|
:description="chart.description"
|
||||||
:chart-explain="chart.chartExplain"
|
:chart-explain="chart.chartExplain"
|
||||||
:option="resolveOption(chart.optionBuilder)"
|
:option="resolveOption(chart.optionBuilder)"
|
||||||
|
|
|
||||||
|
|
@ -72,9 +72,9 @@
|
||||||
|
|
||||||
| 指标编码 | 指标名称 | 计算逻辑与方法 | 页面呈现用途 |
|
| 指标编码 | 指标名称 | 计算逻辑与方法 | 页面呈现用途 |
|
||||||
|----------|----------|----------------|--------------|
|
|----------|----------|----------------|--------------|
|
||||||
| **CMP-AE-101** | 不良事件报告数(按时间桶) | **分子**:时间过滤落在各时间桶内、符合纳入规则的 AE **报告条数**。**时间过滤字段**:**发生日期**。**分母**:无。**维度**:年/季/月。**过滤**:排除测试/重复标记(若有字段)。 | **趋势总览卡片/折线图**:回答「事件量是否异常上升」,作为 PSUR「总体趋势」章节的封面指标。 |
|
| **CMP-AE-101** | 不良事件报告数(按时间段) | **分子**:时间过滤落在各时间段内、符合纳入规则的 AE **报告条数**。**时间过滤字段**:**发生日期**。**分母**:无。**维度**:年/季/月。**过滤**:排除测试/重复标记(若有字段)。 | **趋势总览卡片/折线图**:回答「事件量是否异常上升」,作为 PSUR「总体趋势」章节封面指标;图中增加**年度平均数**并以每个年度不同颜色呈现,补充横纵坐标单位名称,图例数据名称统一为“**事件报告数**”。 |
|
||||||
| **CMP-AE-102** | 不良事件报告数(按注册证号 × 年) | 对 AE 按 `注册证编号` 与 **`发生日期` 所在公历年**(发生年)分组计数。 | **堆叠或分面折线**:识别「哪一个注册证贡献主要增量」,支撑注册证分级监管与再评价讨论。 |
|
| **CMP-AE-102** | 不良事件报告数(按注册证号 × 年) | 对 AE 按 `注册证编号` 与 **`发生日期` 所在公历年**(发生年)分组计数。 | **堆叠或分面折线**:识别「哪一个注册证贡献主要增量」,支撑注册证分级监管与再评价讨论。 |
|
||||||
| **CMP-AE-103** | 不良事件报告数(按主要产品/BU × 时间桶) | 通过产品主数据将 AE 产品映射到 **产品线/BU**,按 **发生日期** 落入的时间桶计数 **报告条数**。 | **管理驾驶舱分 BU 视图**:向事业部同步安全负荷,用于资源与对外沟通优先级。 |
|
| **CMP-AE-103** | 产品AE累计事件数Top 10 | 按 **产品名称** 聚合 AE **报告条数**,降序取 Top 10;可通过产品主数据映射到 **产品线/BU**。 | **柱状图**:图表名称为「产品AE累计事件数Top 10」,用于 PSUR 产品章节与管理驾驶舱分产品线视图,向事业部同步安全负荷。 |
|
||||||
|
|
||||||
**实现注意**:监管报送若需「报告期」切片展示,可另建**辅助看板**按 `审核日期`/`录入日期` 复算,但与本文 **CMP-AE-*** 主口径不一致时须在页面显著标注,避免与按发生日的安全信号混读。
|
**实现注意**:监管报送若需「报告期」切片展示,可另建**辅助看板**按 `审核日期`/`录入日期` 复算,但与本文 **CMP-AE-*** 主口径不一致时须在页面显著标注,避免与按发生日的安全信号混读。
|
||||||
|
|
||||||
|
|
@ -84,7 +84,7 @@
|
||||||
|
|
||||||
| 指标编码 | 指标名称 | 计算逻辑与方法 | 页面呈现用途 |
|
| 指标编码 | 指标名称 | 计算逻辑与方法 | 页面呈现用途 |
|
||||||
|----------|----------|----------------|--------------|
|
|----------|----------|----------------|--------------|
|
||||||
| **CMP-AE-201** | 产品级不良事件 PPM | **公式**:`PPM = (AE 报告数 / 同期入院量) × 1,000,000`。**分子**:按 **发生日期** 落入统计期的 AE **报告条数**。**分母**:同一统计期、与 AE 经 **产品对齐键** 匹配后的 **入院量** 汇总值(Qty 或 Amt 由模型固化,全司一致)。无分母或分母为 0 时:仅展示分子并灰显「率」或显示「N/A」。**维度**:产品/SKU/注册证。 | **PPM 趋势折线 + 脚注声明分母为入院量及字段**:支撑 PSUR「发生率」叙述。 |
|
| **CMP-AE-201** | 产品级不良事件 PPM | **公式**:`PPM = (AE 报告数 / 同期入院量) × 1,000,000`。**分子**:按 **发生日期** 落入统计期的 AE **报告条数**。**分母**:同一统计期、与 AE 经 **产品对齐键** 匹配后的 **入院量** 汇总值(Qty 或 Amt 由模型固化,全司一致)。无分母或分母为 0 时:仅展示分子并灰显「率」或显示「N/A」。**维度**:产品/SKU/注册证。**统计窗口**:截至 `2026-03`。 | **产品级不良事件 PPM 趋势图**:标题去除“演示”字样,补充横纵坐标单位,并同步呈现每月涉及产品数与对应不良事件数;图内副标题仅展示统计窗口,PPM 公式由卡片脚注统一说明(避免重复)。 |
|
||||||
| **CMP-AE-202** | BU/产品线分组 PPM | 在 CMP-AE-201 基础上,分子为 BU 内 AE **报告条数**之和,分母为 BU 内 **入院量**之和,再计算 PPM(禁止先算 SKU PPM 再简单平均)。 | **事业部对比条形图**:同一尺度下比较不同 BU 的安全负荷是否正常。 |
|
| **CMP-AE-202** | BU/产品线分组 PPM | 在 CMP-AE-201 基础上,分子为 BU 内 AE **报告条数**之和,分母为 BU 内 **入院量**之和,再计算 PPM(禁止先算 SKU PPM 再简单平均)。 | **事业部对比条形图**:同一尺度下比较不同 BU 的安全负荷是否正常。 |
|
||||||
| **CMP-AE-203** | PPM 的 SPC 控制图(规则可选 Western Electric/Nelson) | 以连续时间序列为子组(如按月):子组内 AE 数与入院量与 CMP-AE-201 一致;对 PPM 序列计算中心线、控制限及判异标注。分母波动大时优先 **U 图/P 图**(按子组入院量加权)。 | **预警型折线控件**:当点出界或连续同侧时高亮,服务「趋势预警」与管理层简报。 |
|
| **CMP-AE-203** | PPM 的 SPC 控制图(规则可选 Western Electric/Nelson) | 以连续时间序列为子组(如按月):子组内 AE 数与入院量与 CMP-AE-201 一致;对 PPM 序列计算中心线、控制限及判异标注。分母波动大时优先 **U 图/P 图**(按子组入院量加权)。 | **预警型折线控件**:当点出界或连续同侧时高亮,服务「趋势预警」与管理层简报。 |
|
||||||
|
|
||||||
|
|
@ -94,7 +94,8 @@
|
||||||
|
|
||||||
| 指标编码 | 指标名称 | 计算逻辑与方法 | 页面呈现用途 |
|
| 指标编码 | 指标名称 | 计算逻辑与方法 | 页面呈现用途 |
|
||||||
|----------|----------|----------------|--------------|
|
|----------|----------|----------------|--------------|
|
||||||
| **CMP-AE-301** | TOP10 器械故障表现占比 | 对 AE 的「器械故障表现」字段规范化编码后计数,取 Top10;**占比** = 该类型计数 / 当期有效 AE 总数 ×100%。 | **横向柱状图**:PSUR「常见原因/故障」小节,快速列出需工程评估的故障类型。 |
|
| **CMP-AE-301** | 器械故障Top10 | 对 AE 的「器械故障表现」字段规范化编码后按**累计事件数量**降序计数,取 Top10;累计数量的年份范围按**最早年份至今**进行整体累计;并按故障类型聚合该类型涉及的产品信息(可展示 TopN 产品)。 | **横向柱状图**:图表名称为「器械故障Top10」,按累计事件数量展示 Top 事件;在 tooltip/标签中展示该故障涉及产品,产品信息使用其他颜色高亮且不展示产品后缀数量。 |
|
||||||
|
|
||||||
| **CMP-AE-302** | 伤害表现频次表 | 对「伤害表现」字段计数;可按 **是否属于 SAE 严重标准**(见 §1.4)分层小计。 | **表格 + 导出**:与监管分类对齐,用于医学评审与说明书/IFU 风险提示更新。 |
|
| **CMP-AE-302** | 伤害表现频次表 | 对「伤害表现」字段计数;可按 **是否属于 SAE 严重标准**(见 §1.4)分层小计。 | **表格 + 导出**:与监管分类对齐,用于医学评审与说明书/IFU 风险提示更新。 |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
@ -115,7 +116,7 @@
|
||||||
|
|
||||||
| 指标编码 | 指标名称 | 计算逻辑与方法 | 页面呈现用途 |
|
| 指标编码 | 指标名称 | 计算逻辑与方法 | 页面呈现用途 |
|
||||||
|----------|----------|----------------|--------------|
|
|----------|----------|----------------|--------------|
|
||||||
| **CMP-AE-501** | SAE 报告数(年/季) | 筛选满足 **§1.4 SAE 严重标准** 的 AE,按 **发生日期** 落入的年/季时间桶对 **报告条数** 计数。 | **SAE 趋势折线**:PSUR/风险管理会「严重事件」专段。 |
|
| **CMP-AE-501** | SAE 报告数(按发生月) | 筛选满足 **§1.4 SAE 严重标准** 的 AE,按 **发生日期** 落入的月时间桶对 **报告条数** 计数。 | **SAE 趋势折线**:每个月的 SAE 数量在数据点上具体呈现(标签显示),用于严重事件专章趋势。 |
|
||||||
| **CMP-AE-502** | SAE 占全部 AE 比例 | `SAE 报告条数 / 当期全部 AE 报告条数 ×100%`;当期与桶边界均以 **发生日期** 为准。若 AE 表含非器械事件,先按业务规则限定器械范围再算。 | **占比卡片 + 趋势**:观察严重事件是否「量增」同时「占比增」。 |
|
| **CMP-AE-502** | SAE 占全部 AE 比例 | `SAE 报告条数 / 当期全部 AE 报告条数 ×100%`;当期与桶边界均以 **发生日期** 为准。若 AE 表含非器械事件,先按业务规则限定器械范围再算。 | **占比卡片 + 趋势**:观察严重事件是否「量增」同时「占比增」。 |
|
||||||
| **CMP-AE-503** | SAE 分布(产品/医院/地区) | 在 SAE 子集(定义同 §1.4)上按维度聚合计数;可选 **SAE 率** = SAE 数 / 同期入院量(对齐键同 CMP-AE-201)。 | **地图/条形图**:定位高风险聚集点,支持现场调查与沟通名单。 |
|
| **CMP-AE-503** | SAE 分布(产品/医院/地区) | 在 SAE 子集(定义同 §1.4)上按维度聚合计数;可选 **SAE 率** = SAE 数 / 同期入院量(对齐键同 CMP-AE-201)。 | **地图/条形图**:定位高风险聚集点,支持现场调查与沟通名单。 |
|
||||||
|
|
||||||
|
|
@ -125,7 +126,7 @@
|
||||||
|
|
||||||
| 指标编码 | 指标名称 | 计算逻辑与方法 | 页面呈现用途 |
|
| 指标编码 | 指标名称 | 计算逻辑与方法 | 页面呈现用途 |
|
||||||
|----------|----------|----------------|--------------|
|
|----------|----------|----------------|--------------|
|
||||||
| **CMP-AE-601** | 省级 AE 报告数 | 按 **发生日期** 落入统计期的 AE,经省份(或医院→省份映射)聚合计 **报告条数**。 | **中国地图着色**:展示地理聚集,辅助供应链与批次假设。 |
|
| **CMP-AE-601** | 省级 AE 报告数 | 按 **发生日期** 落入统计期的 AE,经省份(或医院→省份映射)聚合计 **报告条数**。 | **柱状图**:每个柱子下方显示对应省份名称,展示地理聚集,辅助供应链与批次假设。 |
|
||||||
| **CMP-AE-602** | 省级 AE 发生率(入院量分母) | `省 AE 报告条数 / 省入院量`;分子时间口径为 **发生日期**,分母为同期 **入院量** 按省汇总(字段 Qty/Amt 与产品对齐规则同 CMP-AE-201)。 | **地图 + 表格双视图**:区分「绝对量大」与「相对率高」,减少误判人口大省。 |
|
| **CMP-AE-602** | 省级 AE 发生率(入院量分母) | `省 AE 报告条数 / 省入院量`;分子时间口径为 **发生日期**,分母为同期 **入院量** 按省汇总(字段 Qty/Amt 与产品对齐规则同 CMP-AE-201)。 | **地图 + 表格双视图**:区分「绝对量大」与「相对率高」,减少误判人口大省。 |
|
||||||
| **CMP-AE-603** | 区域 TOP 事件类型 | 对每个省,在该省当期 AE(**发生日期**)中取事件名称或故障类型的 TopN。 | **下钻表格**:从省到事件类型的快速穿透,用于区域医学联络准备材料。 |
|
| **CMP-AE-603** | 区域 TOP 事件类型 | 对每个省,在该省当期 AE(**发生日期**)中取事件名称或故障类型的 TopN。 | **下钻表格**:从省到事件类型的快速穿透,用于区域医学联络准备材料。 |
|
||||||
|
|
||||||
|
|
@ -135,9 +136,7 @@
|
||||||
|
|
||||||
| 指标编码 | 指标名称 | 计算逻辑与方法 | 页面呈现用途 |
|
| 指标编码 | 指标名称 | 计算逻辑与方法 | 页面呈现用途 |
|
||||||
|----------|----------|----------------|--------------|
|
|----------|----------|----------------|--------------|
|
||||||
| **CMP-AE-701** | 单条 AE 上报滞后天数(获知→闭环) | **定义**:`Lag = T_end − 登记日期`。其中 **获知日** 已确认为 **`登记日期`**;`T_end` 为企业统一配置的**报告闭环终点日**(`审核日期` 或「首次提交监管/国家系统日期」二选一)。仅统计两日期均非空的 AE **报告条数**;若 `登记日期 > T_end` 则标为数据质量异常单。 | **直方图/箱线图**:展示从获知登记到闭环的滞后分布。 |
|
| **CMP-AE-701** | 上报合规率 | 整合原 CMP-AE-701~703。**定义**:`Lag = T_end − 登记日期`(获知日=登记日期;`T_end`=审核日期或首次提交监管日期,企业统一配置)。仅统计两日期均非空的 AE 报告;**合规率** = `Lag ≤ 15天` 的条数 / 可判定总条数 ×100%。超窗(`Lag > 15天`)案例以红色柱标记,支撑 CAPA 与整改闭环。 | **柱状图**:图表名称为「CMP-AE-701 上报合规率」,横坐标为滞后天数分段(天),纵坐标为 AE 条数(条);≤15天合规区间以绿色显示,>15天超窗区间以红色显示;副标题呈现可判定总条数、合规条数、合规率及超窗条数。 |
|
||||||
| **CMP-AE-702** | 法规时限合规率(15 天/45 天等) | 在 CMP-AE-701 可判定集合上,按事件分类(是否适用死亡/危及生命等**更短时限**,以企业规则表配置)分别比较 `Lag ≤ T`。**合规率** = 合规条数 / 可判定条数。 | **仪表盘阈值灯**:内控与审计应答「是否满足报告时限」。 |
|
|
||||||
| **CMP-AE-703** | 超窗案例清单 | 列出 `Lag > T` 的 AE **报告**及超窗天数、责任单元(若可解析)。 | **整改任务列表**:支持 CAPA 与流程 IT 改进闭环。 |
|
|
||||||
|
|
||||||
*注:「15/45 天」是否顺延节假日可作为**可配置策略**,须在报表脚注固定输出;**与投诉 C3 登记的跨表时效**见 **CMP-CV-104**。*
|
*注:「15/45 天」是否顺延节假日可作为**可配置策略**,须在报表脚注固定输出;**与投诉 C3 登记的跨表时效**见 **CMP-CV-104**。*
|
||||||
|
|
||||||
|
|
@ -184,10 +183,7 @@
|
||||||
|
|
||||||
| 指标编码 | 指标名称 | 计算逻辑与方法 | 页面呈现用途 |
|
| 指标编码 | 指标名称 | 计算逻辑与方法 | 页面呈现用途 |
|
||||||
|----------|----------|----------------|--------------|
|
|----------|----------|----------------|--------------|
|
||||||
| **CMP-CV-101** | 疑似漏报条数 | 基准集合中,**无任何**满足匹配规则的 AE 记录的投诉条数。 | **审计高亮列表**:逐条进入调查与补报流程。 |
|
| **CMP-CV-101** | 上报合规审计摘要 | 将 CMP-CV-101~104 四项指标整合为一张图表。**漏报率**(CMP-CV-102)= 疑似漏报条数 / 基准集合总条数 ×100%;**匹配率**(CMP-CV-103)= 匹配成功条数 / 基准集合总条数 ×100%;**时效合规率(登记口径)**(CMP-CV-104)= 匹配子集中 `Lag = T_end − 登记日期 ≤ 15天` 的占比;**时效合规率(C3口径)** = `Lag₂ = T_end − 投诉.C3登记日期 ≤ 15天` 的占比。副标题展示基准样本量、匹配条数及疑似漏报条数(绝对值)。 | **柱状图**:图表名称为「CMP-CV-101 上报合规审计摘要」,四个审计指标分柱展示百分比,副标题呈现绝对量(基准总条数、匹配条数、疑似漏报条数),用于内控季度汇报与外审抽样框架说明。 |
|
||||||
| **CMP-CV-102** | 漏报率 | `疑似漏报条数 / 基准集合总条数 ×100%`。 | **合规 KPI 卡片**:季度汇报内控与管理层。 |
|
|
||||||
| **CMP-CV-103** | 匹配成功条数 | 基准集合中存在 ≥1 条 AE 匹配的投诉数。 | **过程能力参考**:与漏报率互补,用于评估匹配规则是否过严。 |
|
|
||||||
| **CMP-CV-104** | 上报时效合规率(投诉-AE 配对子集) | 在匹配成功子集上:**优先**对 AE 使用 **CMP-AE-701/702**(`Lag = T_end − 登记日期`)计算合规率;若业务需展示「投诉通道起点」则并列计算 `Lag₂ = T_end − 投诉.C3登记日期` 的合规率并在 UI 标注双口径。 | **联接视图**:同时看「有没有报」与「报得是否及时」,并区分获知登记 vs 投诉登记起点。 |
|
|
||||||
|
|
||||||
**页面呈现用途(主题级)**:本分析模块整体用于回应《医疗器械不良事件监测和再评价管理办法》等法规中的**上报义务**内控证据,并可作为外审时的抽样框架说明。
|
**页面呈现用途(主题级)**:本分析模块整体用于回应《医疗器械不良事件监测和再评价管理办法》等法规中的**上报义务**内控证据,并可作为外审时的抽样框架说明。
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,7 @@
|
||||||
|
|
||||||
| 指标编码 | 指标名称 | 计算逻辑与方法 | 页面呈现用途 |
|
| 指标编码 | 指标名称 | 计算逻辑与方法 | 页面呈现用途 |
|
||||||
|----------|----------|----------------|--------------|
|
|----------|----------|----------------|--------------|
|
||||||
| **MKT-OP-101** | 操作不当投诉医院 TopN | 子集:`调查结论 = 操作不当`;按 **`医院名称`** 计数投诉条数,降序取 TopN。 | **条形图**:培训现场名单与院内教育优先级。 |
|
| **MKT-OP-101** | 操作不当投诉:医院Top 10 | 子集:`调查结论 = 操作不当`;按 **`医院名称`** 计数投诉条数,降序取 Top 10。 | **柱状图**:图表名称为「操作不当投诉:医院Top 10」,培训现场名单与院内教育优先级。 |
|
||||||
| **MKT-OP-102** | 操作不当投诉经销商分布(条数) | 同上子集;每条投诉经 **`医院名称` → 入院量众数 DealerName`** 归入经销商后计数。 | **条形图**:渠道侧辅导与考核对象排序。 |
|
| **MKT-OP-102** | 操作不当投诉经销商分布(条数) | 同上子集;每条投诉经 **`医院名称` → 入院量众数 DealerName`** 归入经销商后计数。 | **条形图**:渠道侧辅导与考核对象排序。 |
|
||||||
| **MKT-OP-103** | 经销商操作不当率(入院量分母) | 子集同上;**分子**=该经销商名下医院映射后的操作不当条数;**分母**=入院量表 **`DealerName`** 等于该经销商的 **CY Qty 汇总**;**率** = 分子/分母×1000(件/千件,与质量 QLT-SAL-901 量级一致便于对照)。 | **排序条形图**:识别「相对销量操作不当偏多」的经销商。 |
|
| **MKT-OP-103** | 经销商操作不当率(入院量分母) | 子集同上;**分子**=该经销商名下医院映射后的操作不当条数;**分母**=入院量表 **`DealerName`** 等于该经销商的 **CY Qty 汇总**;**率** = 分子/分母×1000(件/千件,与质量 QLT-SAL-901 量级一致便于对照)。 | **排序条形图**:识别「相对销量操作不当偏多」的经销商。 |
|
||||||
| **MKT-OP-104** | 产品操作不当占比 | 按 **`产品名称`**:`操作不当条数 / 该产品全部投诉条数 ×100%`;可设最小投诉量阈值再展示避免小样本。 | **条形图**:说明书/视频/数字化指导优先级。 |
|
| **MKT-OP-104** | 产品操作不当占比 | 按 **`产品名称`**:`操作不当条数 / 该产品全部投诉条数 ×100%`;可设最小投诉量阈值再展示避免小样本。 | **条形图**:说明书/视频/数字化指导优先级。 |
|
||||||
|
|
@ -61,7 +61,7 @@
|
||||||
|----------|----------|----------------|--------------|
|
|----------|----------|----------------|--------------|
|
||||||
| **MKT-RG-201** | 省级投诉率(入院量分母) | **分子**:投诉经医院→**省**映射后的条数(可全量投诉或限定时间窗)。**分母**:入院量表同一 **Province** 的 **CY Qty** 汇总。**率** = 分子/分母×1000。 | **省级排名条形图/地图**:区域资源与活动排期。 |
|
| **MKT-RG-201** | 省级投诉率(入院量分母) | **分子**:投诉经医院→**省**映射后的条数(可全量投诉或限定时间窗)。**分母**:入院量表同一 **Province** 的 **CY Qty** 汇总。**率** = 分子/分母×1000。 | **省级排名条形图/地图**:区域资源与活动排期。 |
|
||||||
| **MKT-RG-202** | 经销商投诉率(入院量分母) | **分子**:投诉经医院→**DealerName(众数)** 归类计数。**分母**:入院量表 **DealerName** 维度 **CY Qty** 汇总。**率** = 分子/分母×1000。 | **经销商排名**:辅导、仓储、配送假设的优先验证名单。 |
|
| **MKT-RG-202** | 经销商投诉率(入院量分母) | **分子**:投诉经医院→**DealerName(众数)** 归类计数。**分母**:入院量表 **DealerName** 维度 **CY Qty** 汇总。**率** = 分子/分母×1000。 | **经销商排名**:辅导、仓储、配送假设的优先验证名单。 |
|
||||||
| **MKT-RG-203**(可选) | 省级投诉条数(不分母) | 仅计数,用于与 MKT-RG-201 对照区分「绝对量大」与「相对率高」。 | **并列卡片或表**:避免人口大省误判。 |
|
| **MKT-RG-203** | 省级投诉条数Top 10(绝对量) | 按省计数投诉条数,降序取 Top 10,不做入院量标准化,用于与 MKT-RG-201 对照区分「绝对量大」与「相对率高」。 | **柱状图**:图表名称为「省级投诉条数Top 10(绝对量)」,避免人口大省误判。 |
|
||||||
|
|
||||||
**实现注意**:同一医院在多经销商、多 BU 行中共存时,**众数规则**可能随月份切片变化,须在数据字典中固定;与质量方向 **医院×产品** 对齐键若不一致,应在页面脚注声明。
|
**实现注意**:同一医院在多经销商、多 BU 行中共存时,**众数规则**可能随月份切片变化,须在数据字典中固定;与质量方向 **医院×产品** 对齐键若不一致,应在页面脚注声明。
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,7 @@
|
||||||
|
|
||||||
| 指标编码 | 指标名称 | 计算逻辑与方法 | 页面呈现用途 |
|
| 指标编码 | 指标名称 | 计算逻辑与方法 | 页面呈现用途 |
|
||||||
|----------|----------|----------------|--------------|
|
|----------|----------|----------------|--------------|
|
||||||
| **QLT-BTH-101** | 批号投诉条数排名 | 按 **`批号`**(投诉表)分组,在 **`C3登记日期`** 落入统计期的集合内对 **投诉条数** 计数,降序取 TopN。空批号可单列「未填批号」桶。 | **条形图 + 下钻清单**:快速锁定高频问题批,触发批次调查流程。 |
|
| **QLT-BTH-101** | 批号投诉条数Top 10 | 按 **`批号`**(投诉表)分组,在 **`C3登记日期`** 落入统计期的集合内对 **投诉条数** 计数,降序取 Top 10。空批号可单列「未填批号」桶。 | **柱状图**:图表名称为「批号投诉条数Top 10」,快速锁定高频问题批,触发批次调查流程。 |
|
||||||
| **QLT-BTH-102** | 单批重复投诉率 | 对每条非空批号:`该批投诉条数 / 该批涉及医院去重数` 或 `该批投诉条数 / 该批产品入院量(若可对齐)`;二选一全司固化。**简单版**:批内投诉条数 ≥2 记为「重复投诉批次」并列表。 | **批次风险标签**:区分「单次孤立」与「同批多点爆发」。 |
|
| **QLT-BTH-102** | 单批重复投诉率 | 对每条非空批号:`该批投诉条数 / 该批涉及医院去重数` 或 `该批投诉条数 / 该批产品入院量(若可对齐)`;二选一全司固化。**简单版**:批内投诉条数 ≥2 记为「重复投诉批次」并列表。 | **批次风险标签**:区分「单次孤立」与「同批多点爆发」。 |
|
||||||
| **QLT-BTH-103** | 问题批次故障结构 | 在 QLT-BTH-101 选中的批号子集上,对 **`故障类型`** 计数及占比。 | **堆叠条或饼图**:支撑根因假设(工艺 vs 运输 vs 原料)。 |
|
| **QLT-BTH-103** | 问题批次故障结构 | 在 QLT-BTH-101 选中的批号子集上,对 **`故障类型`** 计数及占比。 | **堆叠条或饼图**:支撑根因假设(工艺 vs 运输 vs 原料)。 |
|
||||||
| **QLT-BTH-104** | 投诉批号 × AE 产品批号双计数 | 同一统计期内:投诉侧按 **`批号`** 计数;AE 侧按 **`产品批号`** 计数。通过 **产品名称(及可选型号)** 弱关联后并列展示(不要求逐条匹配)。 | **对照表**:质量与 PV 共看「同一产品批是否双通道上升」。 |
|
| **QLT-BTH-104** | 投诉批号 × AE 产品批号双计数 | 同一统计期内:投诉侧按 **`批号`** 计数;AE 侧按 **`产品批号`** 计数。通过 **产品名称(及可选型号)** 弱关联后并列展示(不要求逐条匹配)。 | **对照表**:质量与 PV 共看「同一产品批是否双通道上升」。 |
|
||||||
|
|
@ -74,9 +74,9 @@
|
||||||
|
|
||||||
| 指标编码 | 指标名称 | 计算逻辑与方法 | 页面呈现用途 |
|
| 指标编码 | 指标名称 | 计算逻辑与方法 | 页面呈现用途 |
|
||||||
|----------|----------|----------------|--------------|
|
|----------|----------|----------------|--------------|
|
||||||
| **QLT-CNC-301** | 医院投诉集中度(HHI 或 TopN 占比) | 按 **`医院名称`** 计数投诉条数;可计算 **HHI** = Σ(份额²) 或 **Top5 医院占比**。时间过滤:**`C3登记日期`**。 | **地图/条形图**:识别「单点高压」医院,安排现场或培训。 |
|
| **QLT-CNC-301** | 医院投诉条数Top 10 | 按 **`医院名称`** 计数投诉条数,降序取 Top 10。时间过滤:**`C3登记日期`**。 | **柱状图**:图表名称为「医院投诉条数Top 10」,识别「单点高压」医院,安排现场或培训。 |
|
||||||
| **QLT-CNC-302** | 产品投诉集中度 | 按 **`产品名称`**(或映射到 **MaterialDesc**)计数;可叠加 **BU** 分层。 | **Pareto 条形图**:与 QLT-PRD 系列共用产品排序逻辑。 |
|
| **QLT-CNC-302** | 产品投诉条数Top N | 按 **`产品名称`**(或映射到 **MaterialDesc**)计数,降序取前 **N** 条(**N** 为统计期内不同产品数与展示上限中的较小值,演示默认上限 10);可叠加 **BU** 分层。 | **柱状图**:图表名称动态为「QLT-CNC-302 产品投诉条数Top **N**」,**N** 与图中实际柱数一致;与调查/赔付饼图联读以定位重点产品。 |
|
||||||
| **QLT-CNC-303** | 事件/故障类型集中度 | 按 **`故障类型`** 或从 **`投诉详情`** 抽取的事件标签(若后续有 NLP)计数;Top10 及累计占比达 80% 的截断线(Pareto)。 | **全局缺陷雷达**:与 §3.2 主题 E 的「产品×故障」互补(一维 vs 二维)。 |
|
| **QLT-CNC-303** | 故障类型Top 10 | 按 **`故障类型`** 计数,降序取 Top 10;可扩展累计占比达 80% 的截断线(Pareto)。 | **柱状图**:图表名称为「故障类型Top 10」,与 Pareto 组合图互补的一维缺陷雷达。 |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -87,7 +87,7 @@
|
||||||
| **QLT-PRD-401** | 组合键投诉条数 | 维度 = **`产品名称` × `故障类型`**,统计期内对 **投诉条数** 求和;按条数降序。 | **Pareto 图(横轴为组合)**:展示「80% 投诉由哪些组合贡献」。 |
|
| **QLT-PRD-401** | 组合键投诉条数 | 维度 = **`产品名称` × `故障类型`**,统计期内对 **投诉条数** 求和;按条数降序。 | **Pareto 图(横轴为组合)**:展示「80% 投诉由哪些组合贡献」。 |
|
||||||
| **QLT-PRD-402** | 各产品 Top3 故障类型及占比 | 在每个 **`产品名称`** 内,对 **`故障类型`** 取 Top3,占比 = 该类型条数 / 该产品总投诉条数。 | **产品卡片矩阵**:研发与工程按产品认领改进项。 |
|
| **QLT-PRD-402** | 各产品 Top3 故障类型及占比 | 在每个 **`产品名称`** 内,对 **`故障类型`** 取 Top3,占比 = 该类型条数 / 该产品总投诉条数。 | **产品卡片矩阵**:研发与工程按产品认领改进项。 |
|
||||||
| **QLT-PRD-403** | 高频故障聚焦清单 | 在全局或 BU 子集上,筛选 **`故障类型`** ∈ {渗漏, 断裂, 流速异常, …}(码表可配置)且条数超阈值的组合。 | **CAPA 输入池**:与主策略 §3.1 e 示例故障对齐。 |
|
| **QLT-PRD-403** | 高频故障聚焦清单 | 在全局或 BU 子集上,筛选 **`故障类型`** ∈ {渗漏, 断裂, 流速异常, …}(码表可配置)且条数超阈值的组合。 | **CAPA 输入池**:与主策略 §3.1 e 示例故障对齐。 |
|
||||||
|
QLT-PRD-401
|
||||||
---
|
---
|
||||||
|
|
||||||
### 3.3 主题 E:调查结论与质量改进项池
|
### 3.3 主题 E:调查结论与质量改进项池
|
||||||
|
|
@ -95,7 +95,7 @@
|
||||||
| 指标编码 | 指标名称 | 计算逻辑与方法 | 页面呈现用途 |
|
| 指标编码 | 指标名称 | 计算逻辑与方法 | 页面呈现用途 |
|
||||||
|----------|----------|----------------|--------------|
|
|----------|----------|----------------|--------------|
|
||||||
| **QLT-INV-501** | 调查结论分布 | 对 **`调查结论(处理结果)`** 计数及占比(产品缺陷成立 / 未复现 / 操作不当 / 运输损伤 / 资料不足等)。时间:**`C3登记日期`** 或 **`调查报告完成日期`**(二选一做「调查产出」视图时固定)。 | **堆叠柱(按时间)**:看结论结构是否恶化(如「产品缺陷成立」上升)。 |
|
| **QLT-INV-501** | 调查结论分布 | 对 **`调查结论(处理结果)`** 计数及占比(产品缺陷成立 / 未复现 / 操作不当 / 运输损伤 / 资料不足等)。时间:**`C3登记日期`** 或 **`调查报告完成日期`**(二选一做「调查产出」视图时固定)。 | **堆叠柱(按时间)**:看结论结构是否恶化(如「产品缺陷成立」上升)。 |
|
||||||
| **QLT-INV-502** | 「产品缺陷成立」× 产品 × 故障 | 子集:`调查结论` = **产品缺陷成立**;按 **产品 × 故障类型** 计数。 | **已确认质量问题池**:DFMEA/PFMEA 与设计变更的输入。 |
|
| **QLT-INV-502** | 产品缺陷成立:产品×故障Top 10 | 子集:`调查结论` = **产品缺陷成立**;按 **产品 × 故障类型** 计数,降序取 Top 10。 | **柱状图**:图表名称含 **QLT-INV-502**;横轴为 **产品×故障组合**(每个柱子下方完整展示组合名称,形如「产品 / 故障」);纵轴为 **投诉条数(条)**;用于已确认质量问题池,作为 DFMEA/PFMEA 与设计变更的输入。 |
|
||||||
| **QLT-INV-503** | 「操作不当」× 医院 / 产品 | 子集:`调查结论` = **操作不当**;按医院或产品聚合。 | **培训需求清单**:与营销 §4.1 可共用数据,页面受众不同。 |
|
| **QLT-INV-503** | 「操作不当」× 医院 / 产品 | 子集:`调查结论` = **操作不当**;按医院或产品聚合。 | **培训需求清单**:与营销 §4.1 可共用数据,页面受众不同。 |
|
||||||
| **QLT-INV-504** | 「运输损伤」× 经销商(若可关联) | 子集:`调查结论` = **运输损伤**;通过入院量 **`DealerName`** 与投诉医院映射后聚合。 | **物流薄弱环节看板**:与主策略 §3.3 n 一致方向。 |
|
| **QLT-INV-504** | 「运输损伤」× 经销商(若可关联) | 子集:`调查结论` = **运输损伤**;通过入院量 **`DealerName`** 与投诉医院映射后聚合。 | **物流薄弱环节看板**:与主策略 §3.3 n 一致方向。 |
|
||||||
| **QLT-INV-505** | 「资料不足」字段缺失模式 | 统计「资料不足」子集中 **`有样品返回`**、附件、关键文本为空等模式(字段可用时)。 | **流程 IT 改进**:减少反复补件。 |
|
| **QLT-INV-505** | 「资料不足」字段缺失模式 | 统计「资料不足」子集中 **`有样品返回`**、附件、关键文本为空等模式(字段可用时)。 | **流程 IT 改进**:减少反复补件。 |
|
||||||
|
|
@ -121,7 +121,7 @@
|
||||||
| **QLT-TRN-701** | 首次出现投诉的医院 | 对每个 **`医院名称`**,取 **最小 `C3登记日期`** 落在统计期内且该医院历史(全量或滚动三年)此前无投诉则标记「首诉医院」。 | **新风险点清单**:客户成功或质量拜访优先级。 |
|
| **QLT-TRN-701** | 首次出现投诉的医院 | 对每个 **`医院名称`**,取 **最小 `C3登记日期`** 落在统计期内且该医院历史(全量或滚动三年)此前无投诉则标记「首诉医院」。 | **新风险点清单**:客户成功或质量拜访优先级。 |
|
||||||
| **QLT-TRN-702** | 首次出现投诉的产品 | 同理对 **`产品名称`**(或物料)判定「首诉产品」。 | **新产品/新适应症暴露** 监测。 |
|
| **QLT-TRN-702** | 首次出现投诉的产品 | 同理对 **`产品名称`**(或物料)判定「首诉产品」。 | **新产品/新适应症暴露** 监测。 |
|
||||||
| **QLT-TRN-703** | 产品投诉量环比增长超 20% | 产品维度下对比 **等长两窗** 投诉条数,增速公式见 §1.4;输出超阈产品列表。 | **趋势预警表**:与主策略 §3.2 c 一致。 |
|
| **QLT-TRN-703** | 产品投诉量环比增长超 20% | 产品维度下对比 **等长两窗** 投诉条数,增速公式见 §1.4;输出超阈产品列表。 | **趋势预警表**:与主策略 §3.2 c 一致。 |
|
||||||
| **QLT-TRN-704** | 区域(省)投诉量环比增长超 20% | 投诉经医院映射 **`Province`**(入院量)后聚合;环比同 §1.4。 | **区域热力 + 列表**:供应链或渠道协同。 |
|
| **QLT-TRN-704** | 区域(省)投诉量环比增长超 20% | 投诉经医院映射 **`Province`**(入院量表 **医院→省** 众数)后聚合;按 **`C3登记日期`** 月份拆 **上半年(1–6月)** 与 **下半年(7–12月)** 分别计数 **投诉条数**;环比增速公式见 §1.4(前端演示图为各省上下半年对照,可与增速阈值列表联读)。 | **分组柱状图**:图表名称含 **QLT-TRN-704**;横轴为 **省份名称**,每个分组下方完整展示对应省名;横轴名称标注为省份维度,纵轴为 **投诉条数(条)**;用于区域波动监测与供应链/渠道协同。 |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -138,7 +138,7 @@
|
||||||
|
|
||||||
| 指标编码 | 指标名称 | 计算逻辑与方法 | 页面呈现用途 |
|
| 指标编码 | 指标名称 | 计算逻辑与方法 | 页面呈现用途 |
|
||||||
|----------|----------|----------------|--------------|
|
|----------|----------|----------------|--------------|
|
||||||
| **QLT-SAL-901** | 医院×产品投诉率 | **分子**:统计期内该 **医院+产品** 投诉条数(**`C3登记日期`**)。**分母**:同期入院量 **CY Qty**(或 Amt)在相同对齐键上汇总。无分母时灰显。 | **散点或四象限**:识别「低销量高投诉」异常点。 |
|
| **QLT-SAL-901** | 医院×产品 投诉率Top 10 | **分子**:统计期内该 **医院+产品** 投诉条数(**`C3登记日期`**)。**分母**:同期入院量 **CY Qty**(或 Amt)在相同对齐键上汇总。无分母时灰显。降序取 Top 10。 | **柱状图**:图表名称为「医院×产品 投诉率Top 10(每千件入院量)」,突出相对暴露下的高频组合。 |
|
||||||
| **QLT-SAL-902** | 新入院组合投诉率 vs 存量 | 新入院定义见 §1.4;分别计算新入院组合与存量的 **投诉率**(分子分母同 QLT-SAL-901)。 | **新市场磨合风险**:与主策略 §3.3 b 营销价值并列展示时脚注受众。 |
|
| **QLT-SAL-902** | 新入院组合投诉率 vs 存量 | 新入院定义见 §1.4;分别计算新入院组合与存量的 **投诉率**(分子分母同 QLT-SAL-901)。 | **新市场磨合风险**:与主策略 §3.3 b 营销价值并列展示时脚注受众。 |
|
||||||
| **QLT-SAL-903** | 新入院后首诉时间 | 对每个新入院组合,首条投诉的 **`C3登记日期`** 与入院首月的间隔分布。 | **入院后 30/60/90 天** 关怀与巡检依据。 |
|
| **QLT-SAL-903** | 新入院后首诉时间 | 对每个新入院组合,首条投诉的 **`C3登记日期`** 与入院首月的间隔分布。 | **入院后 30/60/90 天** 关怀与巡检依据。 |
|
||||||
|
|
||||||
|
|
@ -151,6 +151,8 @@
|
||||||
| **QLT-AE-1001** | 投诉合并为不良事件比例(升级率) | **`是否不良事件 = 是`** 的投诉条数 / 总投诉条数(时间窗内);可按 **BU** 分层。 | **升级文化/流程** 对比:各事业线是否愿报、敢报。 |
|
| **QLT-AE-1001** | 投诉合并为不良事件比例(升级率) | **`是否不良事件 = 是`** 的投诉条数 / 总投诉条数(时间窗内);可按 **BU** 分层。 | **升级文化/流程** 对比:各事业线是否愿报、敢报。 |
|
||||||
| **QLT-AE-1002** | 样品返回与调查结论关系 | 交叉 **`有样品返回`** / **`上报坏品数量`** 与 **`调查结论`**(卡方或简单占比表)。 | **证据链完整性**:与主策略 §3.4.1 g 一致。 |
|
| **QLT-AE-1002** | 样品返回与调查结论关系 | 交叉 **`有样品返回`** / **`上报坏品数量`** 与 **`调查结论`**(卡方或简单占比表)。 | **证据链完整性**:与主策略 §3.4.1 g 一致。 |
|
||||||
| **QLT-AE-1003** | 医院 AE 报告量 vs 入院量 | AE 按 **`单位名称`** 与 **发生日期**(合规口径)计数;入院量同院同期分母;散点。**注意**:与投诉率时间轴不同,页面须双脚注。 | **报告行为异常点**(非直接质量结论):识别需复核的报送模式。 |
|
| **QLT-AE-1003** | 医院 AE 报告量 vs 入院量 | AE 按 **`单位名称`** 与 **发生日期**(合规口径)计数;入院量同院同期分母;散点。**注意**:与投诉率时间轴不同,页面须双脚注。 | **报告行为异常点**(非直接质量结论):识别需复核的报送模式。 |
|
||||||
|
| **QLT-AE-1004** | 已升级投诉故障类型分布 | 子集 **`是否不良事件 = 是`**;按 **`故障类型`** 计数;时间过滤默认 **`C3登记日期`**。 | **柱状图**:编号 QLT-AE-1004;横轴故障类型、纵轴投诉条数(条);与主策略 §3.4.3「报告且投诉」叙事衔接。 |
|
||||||
|
| **QLT-AE-1005** | 已升级投诉登记月份趋势 | 同上子集;按 **`C3登记日期`** 公历年月桶对投诉条数求和。 | **折线图**:编号 QLT-AE-1005;横轴为登记月(可简写为 yy-MM),纵轴条数;与 AE 发生月趋势对照时须脚注双时间轴。 |
|
||||||
|
|
||||||
**漏报与上报时效**:严格合规 KPI 仍以 [合规方向分析.md](./合规方向分析.md) **§3.1**(`CMP-CV-101`~`104` 等)为准;质量方向分析视图可 **嵌入同一语义指标** 或链接跳转,避免重复定义。
|
**漏报与上报时效**:严格合规 KPI 仍以 [合规方向分析.md](./合规方向分析.md) **§3.1**(`CMP-CV-101`~`104` 等)为准;质量方向分析视图可 **嵌入同一语义指标** 或链接跳转,避免重复定义。
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue