142 lines
4.1 KiB
Go
142 lines
4.1 KiB
Go
package service
|
|
|
|
import "sort"
|
|
|
|
// DetectionRecommendInput 多检测方式推荐输入
|
|
type DetectionRecommendInput struct {
|
|
HasLamp bool
|
|
HasSers bool
|
|
HasQPCR bool
|
|
HasHyperspectral bool
|
|
Urgency string // routine/urgent
|
|
OperatorLevel string // novice/expert
|
|
CostPreference string // balanced/low_cost/fastest
|
|
}
|
|
|
|
// DetectionRecommendation 推荐结果
|
|
type DetectionRecommendation struct {
|
|
Method string `json:"method"`
|
|
Name string `json:"name"`
|
|
Reason string `json:"reason"`
|
|
Time string `json:"time"`
|
|
Cost string `json:"cost"`
|
|
Difficulty string `json:"difficulty"`
|
|
}
|
|
|
|
type methodScore struct {
|
|
info DetectionRecommendation
|
|
time int
|
|
cost int
|
|
diff int
|
|
}
|
|
|
|
// RecommendMethod 按设备条件/紧急程度/操作者水平/成本偏好推荐检测方式
|
|
// 规则取自规格书 3.3.2 与 11.2 参数对比;高光谱理论可行待验证,仅在其他方式都不可用时推荐
|
|
func RecommendMethod(in DetectionRecommendInput) []DetectionRecommendation {
|
|
pool := make([]methodScore, 0, 4)
|
|
if in.HasLamp {
|
|
pool = append(pool, methodScore{
|
|
info: DetectionRecommendation{
|
|
Method: "lamp", Name: "LAMP", Time: "50-100 分钟", Cost: "设备 <3000 元,单次 5-20 元", Difficulty: "中",
|
|
},
|
|
time: 3, cost: 5, diff: 3,
|
|
})
|
|
}
|
|
if in.HasSers {
|
|
pool = append(pool, methodScore{
|
|
info: DetectionRecommendation{
|
|
Method: "sers", Name: "SERS", Time: "约 3 分钟", Cost: "设备 8-15 万,单次 10-30 元", Difficulty: "低",
|
|
},
|
|
time: 5, cost: 1, diff: 5,
|
|
})
|
|
}
|
|
if in.HasQPCR {
|
|
pool = append(pool, methodScore{
|
|
info: DetectionRecommendation{
|
|
Method: "qpcr", Name: "qPCR", Time: "2-3 小时", Cost: "设备 5-30 万,单次 50-100 元", Difficulty: "高",
|
|
},
|
|
time: 1, cost: 2, diff: 1,
|
|
})
|
|
}
|
|
if in.HasHyperspectral {
|
|
pool = append(pool, methodScore{
|
|
info: DetectionRecommendation{
|
|
Method: "hyperspectral", Name: "高光谱", Time: "秒级~分钟级", Cost: "设备数万-十几万,单次 0 元", Difficulty: "低(待验证)",
|
|
},
|
|
time: 5, cost: 2, diff: 5,
|
|
})
|
|
}
|
|
if len(pool) == 0 {
|
|
return nil
|
|
}
|
|
|
|
// 高光谱理论可行待验证:仅当它是唯一可用方式时推荐,否则剔除
|
|
if len(pool) > 1 {
|
|
filtered := pool[:0]
|
|
for _, m := range pool {
|
|
if m.info.Method != "hyperspectral" {
|
|
filtered = append(filtered, m)
|
|
}
|
|
}
|
|
pool = filtered
|
|
}
|
|
|
|
// 权重
|
|
wt, wc, wd := 0.3, 0.4, 0.3
|
|
if in.Urgency == "urgent" {
|
|
wt, wc, wd = 0.6, 0.2, 0.2
|
|
}
|
|
if in.OperatorLevel == "novice" {
|
|
wt, wc, wd = 0.2, 0.2, 0.6
|
|
}
|
|
if in.CostPreference == "low_cost" {
|
|
wt, wc, wd = 0.2, 0.6, 0.2
|
|
} else if in.CostPreference == "fastest" {
|
|
wt, wc, wd = 0.6, 0.2, 0.2
|
|
}
|
|
|
|
scores := make([]float64, len(pool))
|
|
for i, m := range pool {
|
|
scores[i] = wt*float64(m.time) + wc*float64(m.cost) + wd*float64(m.diff)
|
|
}
|
|
order := make([]int, len(pool))
|
|
for i := range order {
|
|
order[i] = i
|
|
}
|
|
sort.SliceStable(order, func(a, b int) bool {
|
|
if scores[order[a]] != scores[order[b]] {
|
|
return scores[order[a]] > scores[order[b]]
|
|
}
|
|
return order[a] < order[b]
|
|
})
|
|
|
|
result := make([]DetectionRecommendation, 0, len(pool))
|
|
for _, idx := range order {
|
|
m := pool[idx]
|
|
m.info.Reason = reasonFor(m.info.Method, in)
|
|
result = append(result, m.info)
|
|
}
|
|
return result
|
|
}
|
|
|
|
func reasonFor(method string, in DetectionRecommendInput) string {
|
|
switch method {
|
|
case "sers":
|
|
return "出结果最快(约 3 分钟)、操作难度低,适合紧急或新手场景;设备投入较高"
|
|
case "lamp":
|
|
if in.CostPreference == "low_cost" {
|
|
return "设备投入最低(<3000 元)、基层最务实,性价比高"
|
|
}
|
|
if in.Urgency == "urgent" {
|
|
return "在无 SERS 时最快的可选方案(50-100 分钟),设备投入低"
|
|
}
|
|
return "设备投入低、基层最务实,是目前蚕业领域最常用的分子检测方案"
|
|
case "qpcr":
|
|
return "金标准准确率最高,适合争议仲裁;设备投入大、操作门槛高、耗时 2-3 小时"
|
|
case "hyperspectral":
|
|
return "非接触秒级检测,但蚕病领域理论可行待验证,建议先做可行性实验"
|
|
default:
|
|
return ""
|
|
}
|
|
}
|