From b7f23e926b96dfa4bdf3762883718c56d641407e Mon Sep 17 00:00:00 2001
From: "scott.sun" <scott.sun@topibd.com>
Date: Fri, 12 Mar 2021 17:02:49 +0800
Subject: [PATCH] scott

---
 "GUI\346\265\213\350\257\225/gui.js"          |   2 +-
 "GUI\346\265\213\350\257\225/x.js"            |  35 ++--
 ats/topcam/ATS_AIM_customer_data_analysis.js  |  91 +++++----
 ats/topcam/ATS_AIM_data_format.js             | 123 +++++++++---
 ats/topcam/ATS_AIM_data_input.js              | 118 ++++++++---
 ats/topcam/config_ats.js                      |   5 +-
 ats/topcam/input_jsc.jsc                      | Bin 0 -> 23008 bytes
 .../ZDA_PNL_run_map.pl"                       |   0
 .../ZDA_PNL_run_overlay.pl"                   |   0
 template.js                                   | 189 ++++++++++++++----
 "\351\234\200\346\261\202/1.js"               |   1 +
 11 files changed, 405 insertions(+), 159 deletions(-)
 create mode 100644 ats/topcam/input_jsc.jsc
 rename "public_script/\346\235\277\346\241\206/TL_PNL_run_map.pl" => "public_script/\346\235\277\346\241\206/ZDA_PNL_run_map.pl" (100%)
 rename "public_script/\346\235\277\346\241\206/TL_PNL_run_overlay.pl" => "public_script/\346\235\277\346\241\206/ZDA_PNL_run_overlay.pl" (100%)

diff --git "a/GUI\346\265\213\350\257\225/gui.js" "b/GUI\346\265\213\350\257\225/gui.js"
index d4a64d4..4f77955 100644
--- "a/GUI\346\265\213\350\257\225/gui.js"
+++ "b/GUI\346\265\213\350\257\225/gui.js"
@@ -304,7 +304,7 @@ try {
         },
         defaultlayer: ["layer1"]
     });
-
+  
     GUI.msg(r) // {layers:['layer2'],step:null,job:'job2',layertype:'null'}
 
 
diff --git "a/GUI\346\265\213\350\257\225/x.js" "b/GUI\346\265\213\350\257\225/x.js"
index 39c7839..d10721c 100644
--- "a/GUI\346\265\213\350\257\225/x.js"
+++ "b/GUI\346\265\213\350\257\225/x.js"
@@ -7,19 +7,29 @@ function gen() {
         console.log("pause");
     }
 }
-
+var str = "-------\nxxxx xxxx\naslkdankdassadddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd"
 gui.setLang("zhtw"); // zhcn, zhtw, en
 
-var r = gui.msgBox({
-    title: "info",
-    icon: "info",
-    text: "are you ok?",
-    buttons: ["Ok", "Cancel"],
+// var r = gui.msgBox({
+//     title: "info",
+//     icon: "info",
+//     text: str,
+//     buttons: ["Ok", "Cancel"],
+//     gen: new gen()
+// });
+// console.log(r);
+
+// r = gui.confirm(str, "");
+
+x = gui.debug({
+    title: " 检查",
+    text: str,
+    defaultsize: [800, 600],
+    size: [800, 600],
     gen: new gen()
 });
-console.log(r);
 
-r = gui.confirm("are you ok?", "");
+/*
 console.log(r);
 var selected = gui.selectFromTreeview({
     title: "test",
@@ -416,12 +426,7 @@ r = gui.selectJobLayer({
 
 console.log(r);
 
-x = gui.debug({
-    title: "debug",
-    text: "ciao",
-    size: [400, 300],
-    gen: new gen()
-});
+
 
 var DB = require('topsin.database');
 DB.addConnection({
@@ -445,3 +450,5 @@ x = gui.showSendMail({
 console.log(x);
 
 
+
+*/
\ No newline at end of file
diff --git a/ats/topcam/ATS_AIM_customer_data_analysis.js b/ats/topcam/ATS_AIM_customer_data_analysis.js
index 6a59c8c..ba02e9f 100644
--- a/ats/topcam/ATS_AIM_customer_data_analysis.js
+++ b/ats/topcam/ATS_AIM_customer_data_analysis.js
@@ -217,9 +217,8 @@ try {
     // 检查料号是否能够check out
 	if(GEN.checkInout({job:job,mode:"test"}) != 0 && mode == "aimdfm"){ throw "the job check" }
     GEN.checkInout({job:job,mode:"out"});
-    script_info({ msg: "Data Analysis" ,result_severity:"info"})
+    script_info({ msg: "Data Analysis" ,result_severity:"info",progress: 65})
 	global._ERRORMAG = "Failed to Data Analysis"; 
-	script_info({ progress: 65 })
     var pcs_step = par.pcs_step == "" ? "cad" : par.pcs_step;
     var array_step = par.array_step == "" ? "stp" : par.array_step;
     var step_list = GEN.getStepList({job:job})
@@ -229,12 +228,13 @@ try {
     if(step_list.indexOf(pcs_step)<0){
         pcs_step = step_list[0]
     }
-
     script_info({ msg: "Upload matrix",result_severity:"info" })
 	global._ERRORMAG = "Error-Upload matrix"; 
-	script_info({ progress: 65 })
     var matrix = UPLOAD_LAYER_MATRIX({job:job})  // 分析matrix 获得分析后的matrix信息
     GEN.openStep({job:job, name:pcs_step})
+    
+    
+
     _.values(matrix).forEach(function(v){
         if(v.context == "board" && v.layer_type == "drill"){
             if(v.type == "laser_drill"){
@@ -259,6 +259,15 @@ try {
                     GEN.COM("cur_atr_set,attribute=.drill,option=plated")
                     GEN.COM("sel_change_atr,mode=add")
                 }
+
+                GEN.selectByFilter({include_syms:include_syms.join("\\;")})
+                GEN.selReverse();
+                if(GEN.getSelectCount() > 0){
+                    GEN.COM("cur_atr_reset")
+                    GEN.COM("cur_atr_set,attribute=.drill,option=via")
+                    GEN.COM("sel_change_atr,mode=add")
+                }
+
                 GEN.clearLayers()
                 GEN.selClearFeature()
             } else if(v.type == "main_drill" || v.type == "blind_drill" || v.type == "bury_drill") {
@@ -295,11 +304,10 @@ try {
         }
     })
     GEN.clearLayers()
-
-    script_info({ msg: "Drill Stackup analysis" })
+   
+    script_info({ msg: "Drill Stackup analysis" ,progress: 70,result_severity:"info"})
 	global._ERRORMAG = "Error-Drill Stackup analysis"; 
 
-    script_info({ progress: 70 })
     // * new 钻孔叠构
     var cam_drill_structure = []
     var stack_drills = _.values(matrix).filter(function(item){
@@ -422,10 +430,9 @@ try {
     var analysis_obj = analysis({job:job,jobId:JobId,pcs_step:pcs_step,array_step:array_step,matrix:matrix})
     // 创建profile
     var tmp_matrix = GEN.getMatrix({job:job})
-    script_info({ msg: "Profile analysis" })
+    script_info({ msg: "Profile analysis",progress: 70 ,result_severity:"info"})
 	global._ERRORMAG = "Error-Profile analysis"; 
 
-	script_info({ progress: 70 })
     // * profile 和 拼版
     var pandle_step = step_list.map(function(v){
         var type = "unknow";
@@ -470,7 +477,7 @@ try {
         var repeat = GEN.getSR1({job:job,step:v,units:"mm"})
         var step_repeat = {}
         repeat.forEach(function(item, i){
-    step_repeat[String(i)] = {
+            step_repeat[String(i)] = {
                 x:item.xa,
                 y:item.ya,
                 dx: item.dx,dy: item.dy,
@@ -486,7 +493,12 @@ try {
         panel_info.step_repeat = step_repeat
         save_panel_info({info:panel_info, table:"pdm_job_panelizer_step"})
         GEN.closeStep()
-    return {name:v, type:type}})
+        return {name:v, type:type}
+    })
+
+
+
+
 
     // glod_finger
     var gold_fingers = Object.keys(tmp_matrix).filter(function(v){return /^enig_top$|^enig_bot$/ig.test(v)})
@@ -506,7 +518,7 @@ try {
     }
     ALL.gold_fingers = gold_fingers
     GEN.closeStep()
-    script_info({ msg: "PN analysis" })
+    script_info({ msg: "PN analysis",result_severity:"info"})
 	global._ERRORMAG = "Error-PN analysis"; 
 
   
@@ -549,6 +561,7 @@ try {
     }
     console.log("===============================> 2analysis_obj")
     
+ 
    
     // 分析料号info
     var jobInfo = {}
@@ -594,11 +607,11 @@ try {
     })
     console.log("=================================> 5 save drill info")
 
+ 
 
-    script_info({ msg: "Drill layer analysis" })
+    script_info({ msg: "Drill layer analysis",result_severity:"info",progress: 75 })
 	global._ERRORMAG = "Error-Drill layer analysis"; 
 
-	script_info({ progress: 75 })
     // * 获取pcs_step 和 array_step的钻孔信息
     var drill_tool_info = {};
     var drillLayers = analysis_obj.matrixInfo.mDrills;
@@ -618,14 +631,15 @@ try {
         var step = item.name;
         if(GEN.isStepExists({job:job, step:step})){
             GEN.openStep({job:job, name:step})
-
-
-
             drillLayers.forEach(function(layer){
                 var layer = layer.name;
                 if(!GEN.isLayerEmpty({job:job,step:step,layer:layer})){
                     var mv_layer = moveSlotDrls({job:job, step:step, layer:layer})
-                    GEN.COM("tools_set,layer="+layer+",slots=by_length")
+
+                    if (!global._extra) {
+                        GEN.COM("tools_set,layer="+layer+",slots=by_length")
+                    }
+                    
                     GEN.COM("tools_merge_ex,layer="+layer+",mode=merge")
                     var tool = GEN.getTool({job:job,step:step,layer:layer,units:"mm"}); // {"1":{"count":"01156","num":"1","type":"plated","min_tol":"0","max_tol":"0","finish_size":"100.31","drill_size":"100.31","slot_len":"0","type2":"standard","shape":"hole","bit":0}}
                     if(!drill_tool_info[layer]){
@@ -736,12 +750,10 @@ try {
         })
 	})
     
-    
-    console.log("=============================> 6 set smd bga")
-    script_info({ msg: "SMD&BGA create" })
+    console.log("=============================> 6 set smd bga");
+    script_info({ msg: "SMD&BGA create" ,progress: 80,result_severity:"info" });
 	global._ERRORMAG = "Error-SMD&BGA create"; 
 
-    script_info({ progress: 80 });
     step_list.forEach(function(step){
         GEN.openStep({job:job,name:step})
         GEN.affectedLayer({affected:'no',mode:'all'})
@@ -809,7 +821,7 @@ try {
         GEN.closeStep()
     })
     console.log("============= ===============> 6 analysis smd")
-    script_info({ msg: "SMD&BGA analysis" })
+    script_info({ msg: "SMD&BGA analysis",result_severity:"info"  })
     global._ERRORMAG = "Error-SMD&BGA analysis";
     // smd
     var smdInfo;
@@ -841,9 +853,9 @@ try {
     console.log("================================> 9 copper_percent signal drill")
     // 分析layer info
     var stepList = [pcs_step];
-    var oChecklistName = "mychecklist"
-    var signalLayers = analysis_obj.matrixInfo.mSignals.map(function(v){return v.name})
-    var drillLayers = analysis_obj.matrixInfo.mDrills.map(function(v){return v.name})
+    var oChecklistName = "mychecklist";
+    var signalLayers = analysis_obj.matrixInfo.mSignals.map(function(v){return v.name});
+    var drillLayers = analysis_obj.matrixInfo.mDrills.map(function(v){return v.name});
 
     console.log("=============================> 13 save copperArea copper_distribution")
     var copper_distribution_steplist= [pcs_step, array_step];
@@ -892,7 +904,7 @@ try {
         min_pad2pad: ["p2p", "smd2smd", "smd2pad","via2via","bga2pad"],
         min_ar_laser:["laser_via_ar"],
         min_ar_via:["via_ar"],    
-        min_ar_pth:["pth_ar"],
+        min_ar_pth:["pth_ar","ar"],
         min_ar_npth:["npth_ar"]
     }
     save_job_info({
@@ -906,9 +918,8 @@ try {
     // } else {
     //     jobpath = "/home/local_db/server_db/jobs/"+job
     // }
-    script_info({ msg: "Signal layer analysis" })
+    script_info({ msg: "Signal layer analysis",result_severity:"info" ,progress: 85  })
 	global._ERRORMAG = "Error-Signal layer analysis"; 
-    script_info({ progress: 85 })
     stepList.forEach(function(step){
         GEN.openStep({ job: job, name: step })
         // 曝光
@@ -989,7 +1000,7 @@ try {
                         jobid: JobId,
                         layer: item.signalL,
                         layerinfohash: {
-                            org_min_pad_size: getMinSym(syms)
+                            org_min_pad_size: getMinSym(syms,1)
                         }
                     })
                     if(item.solderL) {
@@ -1002,7 +1013,7 @@ try {
                                 jobid: JobId,
                                 layer: item.signalL,
                                 layerinfohash: {
-                                    org_min_pad_sm_opening_size: getMinSym(syms2)
+                                    org_min_pad_sm_opening_size: getMinSym(syms2,1)
                                 }
                             })
                             GEN.deleteLayer({job:job, layer:item.signalL + "_sm"})
@@ -1053,8 +1064,12 @@ try {
         GEN.affectedLayer({affected:'no',mode:'all'})
         signalLayers.forEach(function(signal){
             GEN.workLayer({name:signal,display_number:2,clear_before:'yes'})
+
+            GEN.COM("filter_set,filter_name=popup,update_popup=no,feat_types=line")
+            
             GEN.selRefFeat({layers:'out_rout',use:'filter',mode:'touch'})
             if(GEN.getSelectCount() > 0) {GEN.selDelete()}
+            GEN.COM("filter_reset,filter_name=popup")
         })
 
         // 创建chklist并运行 如果chklist存在先删除
@@ -1113,7 +1128,7 @@ try {
         // signal层分析结果
         script_info({ msg: "Error-get ChkRes",result_severity:"ok" })
         var res = analysisChkAttr({layers:signalLayers, info:info, step:step, job:job, oChecklistName:"quotation_check",jobpath:jobpath})
-        
+        exportInfo(res);
         //  数据入库
         Object.keys(res).forEach(function(key){
             var val = res[key]
@@ -1187,8 +1202,7 @@ try {
 		})
 	});
     
-    script_info({ progress: 95 })
-    script_info({ msg: "analysis done" })
+    script_info({ msg: "analysis done" ,result_severity:"info"})
     
     //! means信息无法导出
     if(par.export_path != "" && par.export_mode != "" && par.export_submode != "" ){
@@ -2336,7 +2350,12 @@ function analysisChkAttr(par) {
                 return a
             }, "N/A")
             if(hash[v][key]=="N/A"){
-                hash[v][key] = 999
+                // min_ar_laser
+                if(/^min_ar/ig.test(key)){
+                    hash[v][key] = 150
+                } else {
+                    hash[v][key] = 999
+                }
             }
         })
     })
@@ -3057,7 +3076,7 @@ function getMinSym(sym) {
 		if(!info.size) {
 			var width = Number(info.width)
 			var height = Number(info.height)
-			info.size = width > height ? height : width;
+			info.size = width < height ? height : width;
 		}
 		if(info.size) {
 			if(!min_size){min_size = info.size}
diff --git a/ats/topcam/ATS_AIM_data_format.js b/ats/topcam/ATS_AIM_data_format.js
index f94515f..411ff87 100644
--- a/ats/topcam/ATS_AIM_data_format.js
+++ b/ats/topcam/ATS_AIM_data_format.js
@@ -102,9 +102,8 @@ try {
 	if(cam_workflow_info && cam_workflow_info != ""){  
 		throw cam_workflow_info
 	}
-	script_info({ msg: "Data formatting" ,result_severity:"info"})
+	script_info({ msg: "Data formatting" ,result_severity:"info",progress: 35 })
 	global._ERRORMAG = "Failed to data format";
-	script_info({ progress: 35 })
     var par = PAR;
 	if(!par.hasOwnProperty("config_path") || par.config_path==""){
 		console.log("=========== ===cfg");
@@ -261,20 +260,20 @@ try {
 
 	var format_cfg = config.data_format   // 拿到数据标准化配置
 	// 排序和设属性
-	script_info({ progress: 40 })
+	script_info({ progress: 40,msg: "Sort layer" ,result_severity:"info" })
 	var ret = sortLayer({job:job, rule:format_cfg, matrix:tl_name_matrix})
 	if(ret.err){throw err}
 	var after_sort_matrix = ret.sortNames
 	
 	// 改名
-	script_info({ msg: "Change the name" ,result_severity:"info"})
+	script_info({ msg: "Change the name" ,result_severity:"info", progress: 50 })
 	global._ERRORMAG = "Failed to change name"; 
-	script_info({ progress: 50 })
+	var tmp_step = GEN.getStepList({job:job})
+	GEN.openStep({job:job,name:tmp_step[0]})
+
 	err = reName({job:job, matrix:after_sort_matrix, cfg:format_cfg})
 	if(err){throw err}
 	// 处理 yu cca   ftdrillx-x-np
-	var tmp_step = GEN.getStepList({job:job})
-	GEN.openStep({job:job,name:tmp_step[0]})
 	var layers = Object.keys(GEN.getMatrix({job:job})) 
 	layers.forEach(function(layer) {
 		if(/^ftdrill(\d+)-(\d+)-np$/ig.test(layer)) {
@@ -379,6 +378,37 @@ try {
 		GEN.closeStep()
 	}
 
+	// 新增规则 通孔层小于 0.15mm的孔移到每一层镭射层
+	var pcs_step = GEN.getStepList({job:job})[0];
+	GEN.openStep({job:job, name:pcs_step})
+	if(GEN.isLayerExists({job:job, layer:"ftdrill"})){
+		GEN.workLayer({name:"ftdrill",display_number:2,clear_before:'yes'})
+		var syms_tmp = GEN.getLayerSymsHist({job:job,step:pcs_step,layer:'ftdrill'});
+		var laser_sym = [];
+		for (var key in syms_tmp) {
+			var syms_info = syms_tmp[key];
+			if(syms_info.size && syms_info.size <= 5.906){
+				laser_sym.push(key)
+			}
+		}
+		if(laser_sym.length){
+			_.values(matrix).forEach(function(v){
+				if(v.context == "board" && v.layer_type == "drill" && v.type == "laser_drill"){ 
+					GEN.selectByFilter({include_syms:laser_sym.join("\\;")})
+					if(GEN.getSelectCount() > 0) {
+						GEN.selCopyOther({dest:'layer_name',target_layer:v.name,invert:'no',dx:0,dy:0,size:0})
+					}
+				}
+			});
+			GEN.selectByFilter({include_syms:laser_sym.join("\\;")})
+			if(GEN.getSelectCount() > 0) {
+				GEN.selDelete()
+			}
+		}
+	}    
+	GEN.closeStep()
+
+
 	var job_attrs = db.query("",function(q){
 		return q.selectValue({
 			table:'pdm_job',
@@ -393,17 +423,28 @@ try {
 	GEN.saveJob({ job: job });
 	GEN.checkInout({job:job,mode:"in"})
 	GEN.closeJob({job:job});
-	GEN.COM("open_job,job="+job);	
+	GEN.COM("open_job,job="+job);
 	
-	script_info({ msg: "Creating Profile" ,result_severity:"info"})
+	script_info({ msg: "Creating Profile" ,result_severity:"info",progress: 55})
 	global._ERRORMAG = "Failed to create profile"; 
 
-	script_info({ progress: 55 })
 	var all_layer = Object.keys(GEN.getMatrix({job:job}));
 	// 没有outline层
 		// 判断有没有profile
-		var tmp_step = GEN.getStepList({job:job})[0]
+		var tmp_step = GEN.getStepList({job:job})[0];
 		GEN.openStep({job:job, name:tmp_step})
+
+
+
+
+
+
+
+
+
+
+
+
 		if(!hasProfle({job:job, step:tmp_step})){  // 如果没有profile
 			if(/^2171$/ig.test(par.customer)){
 				// 看看有没有 outline 层或者rout层
@@ -680,14 +721,20 @@ catch (e) {
 }
 
 function checkIn(){
-	GEN.COM("open_job,job="+Job+",open_win=no,disk_map=,job_map=")
-	GEN.AUX("set_group,group=99")
-	GEN.COM("close_job,job="+Job+"")
-	GEN.COM("disp_on")
-	GEN.COM("origin_on")
-	GEN.COM("disp_on")
-	GEN.COM("origin_on")
-	GEN.COM("checkin_closed_job,job="+Job);
+	db.query("",function(q){
+		return q.insertRow({
+			table:'pdm_aimdfm_task',
+			data:{
+				job_id:JobId,
+				flow_id:13,
+				task_title: Job + ":checkin",
+				status: 'waiting',
+				user_name: "Admin",
+				user_id: 1
+			}
+		})
+	});
+
 }
 
 function tlNameMatrix(props){  // 设置标准名
@@ -717,6 +764,7 @@ function tlNameMatrix(props){  // 设置标准名
 			if(/^comp_\+_/.test(key)){   
 				return _.assign(val,{tl_name:key})
 			}
+			IKM.save_layerinfo({ jobid: JobId, layer: key, layerinfohash: { layer_name_final: key }})
 			return val
 		}
 		for(var i=0;i<tlRule.length;i++){
@@ -872,7 +920,7 @@ function reName(props) { // 改名 par{job:要改名的料号, rule: {要改名
     var job = props.job
 	var matrix = props.matrix
 	var cfg = props.cfg
-
+	var step = GEN.getStepList({job:job})[0]
 	matrix = matrix.filter(function(v){
 		if(v.name == v.new_name){
 			IKM.save_layerinfo({ jobid: JobId, layer: v.name, layerinfohash: { layer_name_final: v.new_name }})
@@ -887,7 +935,10 @@ function reName(props) { // 改名 par{job:要改名的料号, rule: {要改名
 		if(new_name && new_name!="" && new_name != v.name && layers_tmp.indexOf(new_name) < 0){
 			IKM.save_layerinfo({ jobid: JobId, layer: v.name, layerinfohash: { layer_name_final: new_name }})
 			tmp.push(v.name + " ---- " +new_name)
-			GEN.renameLayer({job:job,layer:v.name,new_name:new_name})
+			GEN.copyLayer({source_job:job,source_step:step,source_layer:v.name,dest_layer:v.name+"_bk",mode:"replace"})
+			GEN.renameLayer({job:job,layer:v.name,new_name:new_name});
+
+
 			return false
 		} else {
 			return true
@@ -948,6 +999,9 @@ function reName(props) { // 改名 par{job:要改名的料号, rule: {要改名
 			var layers_tmp = Object.keys(GEN.getMatrix({job:job}));
 			if(v.orig_name !== v.new_name && layers_tmp.indexOf(v.new_name) < 0){
 				IKM.save_layerinfo({ jobid: JobId, layer: v.orig_name, layerinfohash: { layer_name_final: v.new_name }})
+	
+				GEN.copyLayer({source_job:job,source_step:step,source_layer:v.orig_name,dest_layer:v.orig_name+"_bk",mode:"replace"})
+
 				GEN.renameLayer({job:job,layer:v.orig_name,new_name:v.new_name})
 			}
 		});
@@ -957,18 +1011,20 @@ function reName(props) { // 改名 par{job:要改名的料号, rule: {要改名
 	var afterMatrix = GEN.getMatrix({job:job});
 	var signals = Object.keys(afterMatrix).filter(function(v){return afterMatrix[v].layer_type=="signal" && afterMatrix[v].context=="board"})
 	signals = signals.sort(function(a,b){return afterMatrix[a].row - afterMatrix[b].row})
-	var topSignal = signals[0]
-	var botSignal = signals[signals.length -1]
-	if(topSignal !== "top"){
-		if(!GEN.isLayerExists({job:job, layer:"top"})){
-			IKM.save_layerinfo({ jobid: JobId, layer: topSignal, layerinfohash: { layer_name_final: "top" }})
-			GEN.renameLayer({job:job,layer:topSignal,new_name:"top"})
+	if(signals.length > 0){
+		var topSignal = signals[0]
+		var botSignal = signals[signals.length -1]
+		if(topSignal !== "top"){
+			if(!GEN.isLayerExists({job:job, layer:"top"})){
+				IKM.save_layerinfo({ jobid: JobId, layer: topSignal, layerinfohash: { layer_name_final: "top" }})
+				GEN.renameLayer({job:job,layer:topSignal,new_name:"top"})
+			}
 		}
-	}
-	if(botSignal !== "bottom"){
-		if(!GEN.isLayerExists({job:job, layer:"bottom"})){
-			IKM.save_layerinfo({ jobid: JobId, layer: botSignal, layerinfohash: { layer_name_final: "bottom" }})
-			GEN.renameLayer({job:job,layer:botSignal,new_name:"bottom"})
+		if(botSignal !== "bottom"){
+			if(!GEN.isLayerExists({job:job, layer:"bottom"})){
+				IKM.save_layerinfo({ jobid: JobId, layer: botSignal, layerinfohash: { layer_name_final: "bottom" }})
+				GEN.renameLayer({job:job,layer:botSignal,new_name:"bottom"})
+			}
 		}
 	}
 }
@@ -1221,4 +1277,5 @@ function sendEmail(msg) {
 function hasProfle(props) {
 	var now_profile = GEN.getProfile({job:props.job, step:props.step})
 	return now_profile && now_profile.match(/\n/ig) && now_profile.match(/\n/ig).length != 1
-}
\ No newline at end of file
+}
+
diff --git a/ats/topcam/ATS_AIM_data_input.js b/ats/topcam/ATS_AIM_data_input.js
index 834f938..edcdaa6 100644
--- a/ats/topcam/ATS_AIM_data_input.js
+++ b/ats/topcam/ATS_AIM_data_input.js
@@ -190,15 +190,19 @@ try {
 	} else {
 		jobFiles = fs.listDir(jobFile[0].path)
 	}
+
 	// GEN.COM("config_edit,name=iol_gbr_polygon_break,value=1,mode=user")
 	// GEN.COM("config_edit,name=iol_fix_ill_polygon,value=yes,mode=user")
 	
 	// 将jobFile下的zip解压
 	script_info({ msg: "unzip the file", result_severity:"info" })
 	global._ERRORMAG = "Failed to unzip the file";
-	decompression(jobFile[0].path, []);
 
-	changePath2(jobFile[0].path)
+	var change_files = [];
+
+	decompression(jobFile[0].path, [],change_files);
+
+	changePath2(jobFile[0].path);
 
 	var job_attrs = db.query("",function(q){
 		return q.selectValue({
@@ -218,9 +222,8 @@ try {
 			where:{id : JobId}
 		})
 	});
-
 	
-	jobFiles = fs.listDir(jobFile[0].path)
+	jobFiles = fs.listDir(jobFile[0].path);
 	
 	// 分析料号文件 得到料号导入信息 导入类型
 	var jobInfo = analyJobFiles({jobFiles:jobFiles.filter(function(v){return v.isFile}),custCfg:custCfg,config:config,job:job })
@@ -230,8 +233,7 @@ try {
 		throw "file error"}
 	var importOk = false;  // 是否成功导入
 
-	script_info({ progress: 10 });
-	script_info({ result_severity: "ok" })
+	script_info({ progress: 10 ,result_severity:"ok", msg:""});
 
 	if(/odb/ig.test(jobInfo.type)){  // odb导入
 		script_info({ msg: "Import odb++", result_severity:"error" });
@@ -379,9 +381,27 @@ try {
 		}
 		importOk = true
 	}
+
+	// [{
+	// 	"ori_dirname": "/home/toplinker/samba/1352/13520028_128/TLK0802/1streceived20200422/zip_custom0",
+	// 	"dirname": "/home/toplinker/samba/1352/13520028_128/TLK0802/1streceived20200422/custom1615366305861",
+	// 	"newpath": "/home/toplinker/samba/1352/13520028_128/TLK0802/1streceived20200422/custom1615366305861.zip"
+	// }, {
+	// 	"ori_dirname": "/home/toplinker/samba/1352/13520028_128/TLK0802/1streceived20200422/custom1615366305861/sh1scmnrlmSMD_VB",
+	// 	"dirname": "/home/toplinker/samba/1352/13520028_128/TLK0802/1streceived20200422/custom1615366305861/custom1615366305954",
+	// 	"newpath": "/home/toplinker/samba/1352/13520028_128/TLK0802/1streceived20200422/custom1615366305861/custom1615366305954.zip"
+	// }]
+
+	change_files.reverse().forEach(function(item){
+		fs.unlink(item.newpath);
+		if(fs.exists(item.ori_dirname)){
+			fs.rename(item.ori_dirname,item.ori_dirname+"_bk");
+		}
+		fs.rename(item.dirname, item.ori_dirname);
+	})
 	if(!importOk){ throw "import error"}
-	script_info({ progress: 20 })
-	script_info({ result_severity: "ok" })
+
+	script_info({ progress: 20 ,result_severity:"ok", msg:""});
 
 	global._ERRORMAG = null;
 	reNameStep(job)
@@ -408,6 +428,7 @@ try {
 	GEN.openStep({job:job,name:steplist[0]})
 	// 额外操作
 	if (custCfg.extra) {
+		global._extra = true; 
 		custCfg.extra.forEach(function(item){
 			var props = {
 				type : jobInfo.type,
@@ -436,8 +457,7 @@ try {
 	import_html += "</table>"
     // name type date user
     resultData.push({type: "info",title:"导入资料列表",detail: [{ desc: import_html }] })
-	script_info({ msg: "Data Readin" })
-	script_info({ result_severity: "ok" })
+	script_info({ msg: "Data Readin" ,result_severity:"ok"})
 
 	if (mode === "aimdfm") {
 		$.QDfm.updateRow({
@@ -466,7 +486,7 @@ try {
 	}		
 }
 catch (e) {
-	script_info({ result_severity: "error" })
+	script_info({ result_severity: "error",msg:"" })
 	if(global._ERRORMAG){
 		script_info({ msg: global._ERRORMAG });
 		var job_attrs = db.query("",function(q){
@@ -607,8 +627,8 @@ function now(){
 function reNameStep(job) {
 	var stepList = GEN.getStepList({job:job})
 	if(!stepList){return}
-	var pcs = []
-	var arr = []
+	var pcs = [];
+	var arr = [];
 	stepList.forEach(function(v){
 		if(v){
 			if(v==="cad"){
@@ -644,23 +664,33 @@ function script_info(props){  // result_severity  progress
 	}
 }
 
-function decompression(path, zips) {
+function decompression(path, zips, change_files) {
 	var files = fs.listDir(path)
-	var count = 0;
 	var zipfiles = files.filter(function(item){
-		if (/zip/ig.test(item.suffix) || item.suffix == "rar" || item.suffix=="7z" || item.suffix == "ZIP") {
+		if (/zip/ig.test(item.suffix) || item.suffix == "rar" || item.suffix=="7z") {
 			inputState.push(item.suffix);
 			console.log("--->path:" + item.path)
 			if(zips.indexOf(item.path) < 0){
 				zips.push(item.path);
-				if(item.name.length >= 30 && !/�|\?/.test(item.name)) {
-					var mvname = "custom" + count + "." + item.suffix;
-					count++;
-					fs.rename(item.path, item.dir + "/" + mvname);  
-					item.path = item.dir + "/" + mvname
+				//if(item.name.length >= 30 && !/�|\?/.test(item.name)) {
+				if(/[^\da-zA-Z_]/.test(item.name)){
+					var tmp_code = new Date().getTime()
+					var ori_dirname = item.path.replace(/\.(zipx|zip|7z|rar)$/ig, "");
+					var mvname = "custom" + tmp_code + "." + item.suffix;
+					// fs.rename(item.path, item.dir + "/" + mvname); 
+					fs.copyFile(item.path,item.dir + "/" + mvname,true);
+					item.path = item.dir + "/" + mvname;
+
+					change_files.push({
+						ori_dirname: ori_dirname,
+						dirname: item.path.replace(/\.(zipx|zip|7z|rar)$/ig, ""),
+						newpath: item.path   // 后续删除
+					})
+
+					zips.push(item.path);
 				}
 				var dir_name = item.path.replace(/\.(zipx|zip|7z|rar)$/ig, "");
-				autoUn(item.path, dir_name);
+				autoUn(item.path, dir_name,item.dir);
 				return true
 			}
 		}
@@ -675,13 +705,13 @@ function decompression(path, zips) {
 		// }
 		return false
 	})
-	if(zipfiles.length) {decompression(path, zips)}
+	if(zipfiles.length) {decompression(path, zips, change_files)}
 }
 
 function changePath(path) {
     return path.replace(/[^/]+\//ig, function(v){
         if(v.length >= 10 && /\s/ig.test(v)) {
-            v = v.replace(" ", "\\ ")
+            v = v.replace(" ", "\\ ");
             return v.slice(0,6) + "~1/"
         } else {
             return v
@@ -689,12 +719,40 @@ function changePath(path) {
     })
 }
 
-function autoUn(path, dirname) {
+function autoUn(path, dirname, dir) {
+	// 解压密码逻辑 先获取 /home/toplinker/samba/unzip_pwd.txt
+	var pw = "/home/toplinker/samba/unzip_pwd.txt";
+	var pws = fs.readFile(pw);
+
+	var strs = pws.split("\n")
+	var ret = {};
+	strs.map(function(v) {
+		var tmp = v.split(/\s+/);
+		ret[tmp[0].trim()] = tmp[1].trim()
+	});
+	var pwd;
+	if(ret[Job]){
+		pwd = ret[Job]
+	}
+
+	if(fs.exists(dir + "/pw.txt")){
+		pwd = fs.readFile(dir + "/pw.txt");
+	}
+
     if(/\.rar$/.test(path)){
-		fs.mkdir(dirname)
-        process.exec('/opt/rar/unrar', ['x' , path, dirname, "-o+"])
+		fs.mkdir(dirname);
+		
+		if(pwd){
+			process.exec('/opt/rar/unrar', ['x' , path, dirname, "-o+","-p"+pwd])
+		} else {
+			process.exec('/opt/rar/unrar', ['x' , path, dirname, "-o+"])
+		}
     } else {
-        process.exec('/usr/local/lib/p7zip/7za', ['x' , path, "-o"+dirname, "-aoa"])
+		if(pwd){
+			process.exec('/usr/local/lib/p7zip/7za', ['x' , path, "-o"+dirname, "-aoa", "-p"+pwd])
+		} else {
+			process.exec('/usr/local/lib/p7zip/7za', ['x' , path, "-o"+dirname, "-aoa"])
+		}
     }
 }
 
@@ -721,9 +779,9 @@ function changePath2(filePath){
         newFileName = newFileName.replace(/\?/g,'');//去除文件名中?
 		var newPath = tmp[i].path.replace(/^(.*)\/[^\/]*$/,"$1");
         if(tmp[i].path != (newPath+'/'+newFileName)){
-			fs.rmdir(newPath+'/'+newFileName)
+			// fs.rmdir(newPath+'/'+newFileName)
+			// fs.rename(newPath+'/'+newFileName, newPath+'/'+newFileName+"_bk");
 			fs.rename(tmp[i].path,newPath+'/'+newFileName);
 		}
 	}
-	
 }
\ No newline at end of file
diff --git a/ats/topcam/config_ats.js b/ats/topcam/config_ats.js
index 150e02d..d7aa71b 100644
--- a/ats/topcam/config_ats.js
+++ b/ats/topcam/config_ats.js
@@ -639,11 +639,12 @@
 						var step = props.step;
 						fileInfo.forEach(function(item){
 							var layer = item.file.name.toLowerCase().split(" ").join("-")
+						
 							var path = item.file.path
 							var filectx = fs.readFile(path)
 							var tmp = filectx.match(/Holesize \d\. = [\d\.]+ Tolerance = [\S]+ [\S]+ [\S]+ Quantity = \d+\n/igm)
 							if(tmp && tmp.length) {
-								var units = "mm"
+								var units = "mm";
 								var res = tmp.map(function(v,i) {
 									var tmp2 = /Holesize \d\. = ([\d\.]+) Tolerance = ([\S]+) ([\S]+) ([\S]+) Quantity = \d+\n/igm.exec(v);
 									if(/MILS/ig.test(tmp2[4])){
@@ -682,7 +683,7 @@
 								})
 								GEN.COM("tools_set,layer="+layer+",thickness=0,user_params=,slots=by_length")
 							}
-						})
+						});
 						GEN.saveJob({ job: job });
 					}
 				}
diff --git a/ats/topcam/input_jsc.jsc b/ats/topcam/input_jsc.jsc
new file mode 100644
index 0000000000000000000000000000000000000000..274647efb98858373e34e54d92aa15e2b5b85cc8
GIT binary patch
literal 23008
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

literal 0
HcmV?d00001

diff --git "a/public_script/\346\235\277\346\241\206/TL_PNL_run_map.pl" "b/public_script/\346\235\277\346\241\206/ZDA_PNL_run_map.pl"
similarity index 100%
rename from "public_script/\346\235\277\346\241\206/TL_PNL_run_map.pl"
rename to "public_script/\346\235\277\346\241\206/ZDA_PNL_run_map.pl"
diff --git "a/public_script/\346\235\277\346\241\206/TL_PNL_run_overlay.pl" "b/public_script/\346\235\277\346\241\206/ZDA_PNL_run_overlay.pl"
similarity index 100%
rename from "public_script/\346\235\277\346\241\206/TL_PNL_run_overlay.pl"
rename to "public_script/\346\235\277\346\241\206/ZDA_PNL_run_overlay.pl"
diff --git a/template.js b/template.js
index 9783ac9..533a7ad 100644
--- a/template.js
+++ b/template.js
@@ -1,34 +1,34 @@
 /*
 NAME: 
-DESCRIPTION: ;
+DESCRIPTION: 描述;
 PARAMETER:
-    [
+	[
 		{
 			name : 'step',
 			title : 'step',
 			type : 'LineEdit',
-			property : {tool_tip : '目标step,默认是orig'},
+			property : {tool_tip : '目标step,默认是orig'}
 		},
 		{
-            name : 'auto_save',
+			name : 'auto_save',
 			title : '自动保存',
-            type : 'RadioBox',
-            property : {
+			type : 'RadioBox',
+			property : {
 				item_list:[
 					{name:'yes',text:'YES'},
 					{name:'no',text:'NO'},
 				],
 				tool_tip:'是否自动保存料号开关'
 			}
-        }
+		}
 	]
 	
  VERSION_HISTORY:
-	V1.00 2021-02-19 Scott Sun
-	    1.新版本
+	V1.00 2021-03-08 Scott Sun
+		1.新版本
 		
  HELP:
- 	<html><body bgcolor="#DDECFE">
+	  <html><body bgcolor="#DDECFE">
 		<font size="3" color="#003DB2"><p>功能简介</p></font>
 		<p> 标题 </ p>
 		<br>
@@ -40,22 +40,21 @@ PARAMETER:
 		<br>
 	</body></html>	
 */
-//////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////
-console.log("==============================>template");
-// 引入模块 包
+
+// 引入模块 包 外部参数
 var $ = require('topcam.scriptfunc').argv();
 var fs = require('fs');
 var _ = require('lodash');
 var mode = $.ikm ? "topcam" : "aimdfm";
-var IKM = $.ikm; 
-if (IKM==undefined ) { IKM = require('topcam.ikm6')($) }
+var IKM = $.ikm ? $.ikm : require('topcam.ikm6')($);
 var GEN = $.gen;
 var Job = $.job || $.job_name;
 var JobId = $.job_id;
-var db = $.db || IKM.db
-var PAR = {}
-if ($.par) { PAR = $.par } else if ($.hasOwnProperty('script_parameter')){ PAR = JSON.parse($.script_parameter); }
+var db = $.db || IKM.db;
+var gui_piug = require('topsin.gengui');
+var GUI = gui_piug.newGui(gui_piug.__dirname);
+var PAR = {};
+if ($.par) { PAR = $.par } else if ($.hasOwnProperty('script_parameter')) { PAR = JSON.parse($.script_parameter); }
 if (mode === "aimdfm") {
 	var database = require("topsin.database");
 	database.addConnection($.conf.database_conf, "DFM");
@@ -67,37 +66,141 @@ if (mode === "aimdfm") {
 }
 var Status = 'ok';
 var resultData = [];
-var par = PAR;
-var default_par = {
-    step: "orig",
+var par = PAR;  // 接收参数
+var default_par = { // 设置默认参数
+	step: "orig",
 	auto_save: "No",
-	units:"mm"
+	units: "mm"
+}
+for (var key in default_par) {
+	if (!par.hasOwnProperty(key) || par[key] == "") {
+		par[key] = default_par[key]
+	}
 }
-for(var key in default_par){ if (!par.hasOwnProperty(key) || par[key] == ""){ par[key] = default_par[key] }}
+
+// 定义变量
 var job = Job;
+
 try {
-	if(_.isEmpty(job)){throw "参数job不存在"} else { job = job.toLowerCase() }
-	if(!GEN.isJobExists({job:job})){throw "料号"+job+"不存在"}
-	if(!GEN.isJobOpen({job:job})){ GEN.openJob({job:job}) }
-    if(mode == "aimdfm"){ if(GEN.checkInout({job:job,mode:"test"}) != 0){ throw "the job check" } else { GEN.checkInout({job:job,mode:"out"}) } }
+	// 常规验证 准备工作
+
+	if (!GEN.isJobExists({ job: job })) { throw "料号" + job + "不存在" }
+	if (!GEN.isJobOpen({ job: job })) { GEN.openJob({ job: job }) }
+	if (mode == "aimdfm") {
+		if (GEN.checkInout({job: job,mode: "test"}) != 0) {
+			throw "the job check"
+		}
+		GEN.checkInout({job: job,mode: "out"});
+	}
+
+	// 主体
+
+	var stepList = GEN.getStepList({job:job})     // 工作step列表
+	stepList = stepList.filter(function(step){
+		var reg = new RegExp(par.step,"ig");
+		return reg.test(step);
+	})
+
+    var verification = function(size) {
+        return size <= 500
+    }
+
+    var drills = getLayer({layer_type:"drill",name:"drl"})
+
+	stepList.forEach(function(step) {
+        GEN.openStep({ job: job, name: step });
+        GEN.clearLayers(); //清除层显示
+        GEN.affectedLayer({ mode: 'all', affected: 'no' }); //设置影响层全部不影响
+        GEN.COM("sel_options,clear_mode=clear_after,display_mode=all_layers,area_inout=inside,area_select=select,select_mode=standard,area_touching_mode=exclude");
+        GEN.units({ type: par.units }); //单位初始化
+        GEN.zoomHome(); //窗口显示回到原始位置
+		GEN.selClearFeature()
+		drills.forEach(function(drl) {
+            GEN.workLayer({name:drl,display_number:2,clear_before:'yes'})
+            var sys = GEN.getLayerSymsHist({job:Job,step:'net',layer:drl,units:'mm'})
+            var includesys = [];
+            // r700":{"symbol":"r700","line":"0","pad":"400","arc":"0","size":"700"},
+            Object.keys(sys).forEach(function(key){
+                var symbolinfo = sys[key];
+                if(!symbolinfo.size && symbolinfo.width){
+                    symbolinfo.size = symbolinfo.width > symbolinfo.height ? symbolinfo.width : symbolinfo.height;
+                }
+                if(symbolinfo.size){
+                    symbolinfo.size = symbolinfo.size - 0;
+                    if(verification(symbolinfo.size)){
+                        includesys.push(symbolinfo.symbol)
+                    }
+                }
+            })
+            if(includesys.length){
+                GEN.selectByFilter({include_syms:includesys.join(";")})
+                if(GEN.getSelectCount()>0){
+                    GEN.COM("cur_atr_set,attribute=.drill,option=via")
+                    GEN.COM("sel_change_atr,mode=add")
+                }
+            }
+		})
+	})
 
-	console.log("=================test==============");
 
-	// 保存
-	if(/yes/ig.test(par.auto_save)){GEN.checkInout({job:job,mode:"out"}); GEN.saveJob({ job: job });GEN.checkInout({job:job,mode:"in"});GEN.closeJob({job:job});} else {GEN.checkInout({job:job,mode:"in"})}
+
+
+
+	
+	// 保存料号
+	if (/yes/ig.test(par.auto_save)) { 
+		GEN.checkInout({ job: job, mode: "out" }); 
+		GEN.saveJob({ job: job }); 
+	} 
+	GEN.checkInout({ job: job, mode: "in" });
+	
+	// 结尾返回 固定写法
+	var Return = "Done"
 	if (mode === "aimdfm") {
-		$.QDfm.updateRow({table: "pdm_aimdfm_task",data: {progress: 100},where: { id: $.task_id }});
-		if (GEN.hasError()) { Status = 'error';resultData.push({ type: "error", title: "GEN错误!", detail: [{ desc: _.join(GEN.STATUS, "\n") }] });
-			return {status: Status,result_data: resultData};
-		} else { resultData.push({ type: "info", title: "操作完成, 请注意检查!" }); return {status: Status,result_data: resultData}; }
-	}else { return "Done" }
+		$.QDfm.updateRow({ table: "pdm_aimdfm_task", data: { progress: 100 }, where: { id: $.task_id } });
+		var tmperr = { type: "info", title: "操作完成, 请注意检查!" }
+		if (GEN.hasError()) {
+			Status = 'error'; 
+			tmperr = { type: "error", title: "GEN错误!", detail: [{ desc: GEN.STATUS.join("\n") }] }
+		}
+		resultData.push(tmperr);
+		Return = { status: Status, result_data: resultData };
+	}
+	return Return
 } catch (e) {
+	if(GEN.STATUS.length > 0) {
+		IKM.msg(GEN.STATUS.join("\n")); 
+	}
+	IKM.msg(e); 
+	Status = 'error';
+	resultData.push({ type: "error", title: "脚本执行出错!", detail: [{ desc: _.toString(e) }] });
+	return (mode === "aimdfm") ? { status: Status, result_data: resultData } : "Error";
+}
 
-	GEN.COM("disp_on")
-	GEN.COM("origin_on")
-	GEN.COM("checkin_closed_job,job="+job);
 
-	IKM.msg(_.join(GEN.STATUS, "\n"));IKM.msg(e);Status = 'error';
-    resultData.push({type: "error", title: "脚本执行出错!", detail: [{desc: _.toString(e)}]});
-    return (mode === "aimdfm") ? {status: Status, result_data: resultData} : "Error";
-}
+
+function getLayer(props){ // 获取层
+    if (!props) {
+    	return
+    }
+    if (!props.context) {
+    	props.context = "board"
+    }
+    var matrix = GEN.getMatrix({job:job})
+    return Object.keys(matrix).reduce(function(a,b){
+        var info = matrix[b];
+        var ret = true;
+        for (var key in props) {
+        	if (!Array.isArray(props[key])) {
+        		props[key] = [props[key]]
+        	}
+        	if (info[key] && props[key].indexOf(info[key]) < 0) {
+        		ret = false
+        	}
+        }
+        if (ret) {
+        	a.push(props.res == "info" ? info : b)
+        }
+        return a
+    },[])
+}
\ No newline at end of file
diff --git "a/\351\234\200\346\261\202/1.js" "b/\351\234\200\346\261\202/1.js"
index 4f7d29c..142480b 100644
--- "a/\351\234\200\346\261\202/1.js"
+++ "b/\351\234\200\346\261\202/1.js"
@@ -31,6 +31,7 @@ try {
         if(!GEN.isChklistExists({job:JOB,step:step,chklist:config.check})){
             GEN.COM("chklist_from_lib,chklist=" + config.check); // 不存在要从lib copy一个
         }
+        
         GEN.chklistShow({chklist:config.check})
         _.forEach(config.nacts,function(nact){
             GEN.chklistRun({chklist:config.check,nact:nact})  // 运行checklist
-- 
2.21.0