fix(编辑器+执行器): 去重条件上残留的文本比对设置会误报警告;并补上"两处身份不一致"的检测
用户报的现象:内层条件判断已经选了「去重」、身份元素也填了,但保存时**一直提示
"选了文本比对但没填比对的值"**(他看不到、也清不掉那两行)。
根因(我写的):从"元素类"切到「去重 / 屏幕状态」时,面板里"文本比对"那块是**隐藏**的,
但 params 里旧的 `cmp_op`/`cmp_value` 还留着;而校验没排除这两类不用文本比对的类型,
于是每次保存都拿那个残留去报警 —— 用户看不到源头的两行,自然无从下手。
- `static/admin/editor.js` 的 `validate`:
· 「去重 / 屏幕状态」不再报文本比对的警告(设计上就用不到);
· 这两类也不报"选择器为空"(去重用的是 `ident_value`,不是 `selector_value`);
· **顺手补一个真问题的检测**:去重的两处身份**空值也纳入比对** —— 一边填了、
另一边留空(= 用设备当身份)是最常见的不一致,只收非空值时恰好检测不到。
报错文案把"留空"写成「(留空 → 用设备当身份)」,用户一眼知道差在哪。
- `tasks/generic/task.py`:被忽略的文本比对只在**真的配了值**时才打 WARNING
(切换类型留下的空残留不必每轮刷日志)。
验证:把用户**生产任务的真实 JSON** 喂给新的 `validate()`:
假警告消失,只剩下一条真警告 ——「检查侧=账号元素 / 记账侧=留空(用设备)」身份不一致。
This commit is contained in:
+17
-12
@@ -922,25 +922,28 @@ var _stepEditor={
|
||||
warnings.push(name+' "'+label+'": 录制手势还没有轨迹,执行时会被跳过。');
|
||||
}
|
||||
}else if(s.type==='if_el'){
|
||||
if(!s.params.selector_value){
|
||||
// 「去重」「屏幕状态」这两类条件**不用文本比对**(面板里那块是隐藏的)。
|
||||
// 所以:① 留着旧 cmp_op/cmp_value 不该报警告(用户看不到、也清不掉,
|
||||
// 只会每次保存都被打扰);② 也别报"会被忽略"——那是设计如此。
|
||||
var cmpUsed=(s.params.selector_type!=='screen'&&s.params.selector_type!=='dedup');
|
||||
if(s.params.selector_type!=='dedup'&&!s.params.selector_value){
|
||||
warnings.push(name+' "'+label+'": 条件判断的选择器为空,会直接走"未找到"分支。');
|
||||
}
|
||||
if(s.params.cmp_op&&!String(s.params.cmp_value||'').trim()){
|
||||
if(cmpUsed&&s.params.cmp_op&&!String(s.params.cmp_value||'').trim()){
|
||||
warnings.push(name+' "'+label+'": 选了"文本比对('+s.params.cmp_op+')"但没填比对的值,'
|
||||
+'执行时永远不命中(相当于每次都走"未找到时"分支)。');
|
||||
}
|
||||
if(s.params.cmp_op&&s.params.selector_type==='screen'){
|
||||
warnings.push(name+' "'+label+'": 屏幕状态没有文本可比,文本比对的设置会被忽略。');
|
||||
}
|
||||
if(s.params.selector_type==='dedup'){
|
||||
hasDedupCheck=true;
|
||||
var iv=(s.params.ident_value||'').trim();
|
||||
if(iv)dedupIdents.push({where:name,type:s.params.ident_type||'text',value:iv});
|
||||
// 空值也收进来:一边填了、另一边没填 = 两处身份不一致(去重会对不上),
|
||||
// 必须报出来 —— 只收非空的话,这种最常见的不一致反而检测不到
|
||||
dedupIdents.push({where:name,type:s.params.ident_type||'text',
|
||||
value:(s.params.ident_value||'').trim()});
|
||||
}
|
||||
}else if(s.type==='mark_done'){
|
||||
hasMarkDone=true;
|
||||
var mv=(s.params.selector_value||'').trim();
|
||||
if(mv)dedupIdents.push({where:name,type:s.params.selector_type||'text',value:mv});
|
||||
dedupIdents.push({where:name,type:s.params.selector_type||'text',
|
||||
value:(s.params.selector_value||'').trim()});
|
||||
}
|
||||
_childArrs(s).forEach(function(a){
|
||||
if(a.length)check(a,name+' 子步骤');
|
||||
@@ -959,11 +962,13 @@ var _stepEditor={
|
||||
}
|
||||
if(dedupIdents.length>1){
|
||||
var first=dedupIdents[0];
|
||||
var showId=function(x){ return x.value?('「'+x.value+'」'):'(留空 → 用设备当身份)'; };
|
||||
dedupIdents.slice(1).forEach(function(d){
|
||||
if(d.value!==first.value||d.type!==first.type){
|
||||
warnings.push('去重的身份元素不一致:'+first.where+'用的是「'+first.value
|
||||
+'」,而'+d.where+'用的是「'+d.value+'」——两边不一致会算出不同的 key,'
|
||||
+'去重会静默失效。请改成同一个元素。');
|
||||
warnings.push('去重两处的身份不一致:'+first.where+' 是 '+showId(first)
|
||||
+',而 '+d.where+' 是 '+showId(d)
|
||||
+' —— 身份不一致会算出两个不同的 key,去重会失效'
|
||||
+'(检查查不到记账 / 或者反过来,结果就是重复或漏做)。请把两处填成同一个身份元素。');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -772,7 +772,9 @@ class GenericStepsWorker(BaseWorker):
|
||||
detail = (f"采集到 '{got}' {cmp_op} {n_val} 个候选值 → "
|
||||
f"{'符合' if hit else '不符合'}{extra}")
|
||||
found = hit
|
||||
elif cmp_op and sel_type in ("screen", "dedup"):
|
||||
elif cmp_op and str(cmp_val or "").strip() and sel_type in ("screen", "dedup"):
|
||||
# 只在**真的配了比对的值**时才提醒:从元素类切到「去重/屏幕状态」时
|
||||
# 界面上那块是隐藏的,旧值会留在 params 里,那种残留每轮都刷警告没意义
|
||||
_log.warning(f"[{self.serial}] {sel_type} 没有文本可比,已忽略文本比对设置")
|
||||
|
||||
if dynamic:
|
||||
|
||||
Reference in New Issue
Block a user