/* NAME: DESCRIPTION: ; PARAMETER: [ { name : 'step', title : '过滤Step', type : 'LineEdit', property : {tool_tip : '过滤Step'}, }, { name : 'auto_save', title : '自动保存', type : 'RadioBox', property : { item_list:[ {name:'yes',text:'YES'}, {name:'no',text:'NO'}, ], tool_tip:'是否自动保存料号开关' } } ] VERSION_HISTORY: V1.00 2020-09-25 Scott Sun 1.新版本 HELP: <html><body bgcolor="#DDECFE"> <font size="3" color="#003DB2"><p>功能简介</p></font> <p> sec drc 分析 </p> <br> <font size="3" color="#003DB2"><p>参数配置</p></font> <p> step信息 </p> <br> <font size="3" color="#003DB2"><p>注意事项</p></font> <p> 无 </p> <br> </body></html> */ // 引入模块 包 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 GEN = $.gen; var GUI = $.gui || {}; 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); } if (mode === "aimdfm") { var database = require("topsin.database"); database.addConnection($.conf.database_conf, "DFM"); var QDfm = database.query("DFM"); $.QDfm = QDfm; if ($.conf.product_type == "aimdfm") { QDfm.updateRow({ table: "pdm_aimdfm_task", data: { current_process_title: $.process_title }, where: { id: $.task_id } }); } } var Status = 'ok'; var resultData = []; var par = PAR; var default_par = { step: "drc", auto_save: "No", units: "mm" } for(var key in default_par){ if (!par.hasOwnProperty(key) || par[key] == ""){ par[key] = default_par[key] }} var job = Job; var Omatrix; 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"}) } } var stepList = GEN.getStepList({job:job}) stepList = stepList.filter(function(v){ var reg = new RegExp(par.step,"ig") return reg.test(v) }) if(stepList.length == 0){throw "未找到step"} // 上传matrix信息 var matrix = UPLOAD_LAYER_MATRIX({job:job}) // 分析matrix 获得分析后的matrix信息 var board_thickness = IKM.get_jobinfo({jobid:JobId,jobinfo:"board_thickness"}) || 0; board_thickness *= 1000 ; 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(); var check_list = 'pcb_analysis_jt01'; var signal = "", signals = []; var pg_layer = "", pg_layers = []; var drill = []; var sm_layers = [] , ss_layer = "", ss_layers = []; // var ($signal,@signal,@pg_layer,$pg_layer,@drill,@sm_layer,@ss_layer,$ss_layer); var matrix = GEN.getMatrix({job:job}); for (var layer in matrix) { var layerInfo = matrix[layer]; if(layerInfo.context == "board") { if(layerInfo.layer_type == 'signal' && /(cil)|(col)/.test(layer)){ var lyr_paras = {}; if(layerInfo.side == 'top'){ lyr_paras.layer1 = layer; lyr_paras.drills = 'yes'; lyr_paras.thickness = board_thickness/2; }else if(layerInfo.side == 'bottom'){ lyr_paras.layer2 = layer; lyr_paras.drills = 'yes'; lyr_paras.thickness = board_thickness/2; }else{ lyr_paras.layer1 = layer; lyr_paras.drills = 'no'; lyr_paras.thickness = 0; } var copperArea = GEN.copperArea(lyr_paras); copperArea.area = Number(copperArea.area).toFixed(3) - 0; copperArea.percent = parseInt(copperArea.percent) IKM.save_layerinfo({jobid:JobId, jobcategory:'org', tlname:layerInfo.tl_name, layerinfohash:{copper_area_pcs:copperArea.area, copper_area_ratio_pcs:copperArea.percent} }); signals.push(layer) layer += ';'; signal += layer; }else if(layerInfo.layer_type == 'power_ground' && /(cil)/.test(layer)){ var lyr_paras = { layer1 : layer, drills : 'no', thickness : 0 }; var copperArea = GEN.copperArea(lyr_paras); copperArea.area = Number(copperArea.area).toFixed(3) - 0; copperArea.percent = parseInt(copperArea.percent) IKM.save_layerinfo({jobid:JobId, jobcategory:'org', tlname:layerInfo.tl_name, layerinfohash:{copper_area_pcs:copperArea.area, copper_area_ratio_pcs:copperArea.percent} }); pg_layers.push(layer) layer += ';'; pg_layer += layer; } else if(layerInfo.layer_type == 'drill'){ drill.push(layer) } else if (layerInfo.layer_type == 'silk_screen' && /lpp/.test(layer)) { var lyr_paras = { layer1 : layer, drills : 'no', thickness : 0 }; var copperArea = GEN.copperArea(lyr_paras); copperArea.area = Number(copperArea.area).toFixed(3) - 0; copperArea.percent = parseInt(copperArea.percent) var target_attrname = layerInfo.side == 'top' ? 'ss_area_pcs_top' : 'ss_area_pcs_bot'; var jobinfohash = {}; jobinfohash[target_attrname] = copperArea.area; IKM.save_jobinfo({ jobid:JobId, jobcategory:'work', jobinfohash:jobinfohash }); ss_layers.push(layer) layer += ';'; ss_layer += layer; }else if(layerInfo.layer_type == 'solder_mask' && /smf/.test(layer)){ sm_layers.push(layer) } } } var tmp_layer = 'tl+copper+tmp++'; GEN.createLayer({job:job,layer:'tl+copper+tmp++',context:'misc',type:'signal',delete_exists:'yes'}); GEN.affectedLayer({affected:'yes',layer:tmp_layer,clear_before:'yes'}); var profile_limits = GEN.getProfileLimits({job:job,step:step,units:par.units}); if(profile_limits.xsize == 0){ GEN.affectedLayer( {mode:'all',affected:'no'} ); GEN.deleteLayer({job:job,layer:tmp_layer,step:step}); throw 'Cancel'; }else{ GEN.srFill({layer:tmp_layer}); var lyr_paras = {}; lyr_paras.layer1 = tmp_layer; lyr_paras.drills = 'no'; lyr_paras.thickness = 0; var copperArea = GEN.copperArea(lyr_paras); copperArea.area = Number(copperArea.area).toFixed(3) - 0; copperArea.percent = parseInt(copperArea.percent) GEN.affectedLayer( {mode:'all',affected:'no'} ); GEN.deleteLayer({job:job,layer:tmp_layer,step:step}); IKM.save_layerinfo({jobid:JobId, jobcategory:'org', tlname:step, layerinfohash:{board_area_pcs:copperArea.area, board_area_ratio_pcs:copperArea.percent} }); } if(GEN.isChklistExists({job:job,step:step,chklist:check_list})){ GEN.COM('chklist_delete',{chklist:check_list}); } GEN.COM("chklist_from_lib,chklist=" + check_list); GEN.COM("chklist_open,chklist=" + check_list); GEN.COM("chklist_show,chklist=" + check_list); GEN.chklistSelectAct({job:job,step:step,chklist:check_list,nact:1,select:'yes',clear_before:'yes'}); if(pg_layers.length > 0){ GEN.COM('chklist_select_act',{chklist:check_list,nact:2,select:'yes'});//运行PG层分析 } if(sm_layers.length > 0){ GEN.COM('chklist_select_act',{chklist:check_list,nact:3,select:'yes'}); } if(ss_layers.length > 0){ GEN.COM('chklist_select_act',{chklist:check_list,nact:4,select:'yes'}); } GEN.COM('chklist_select_act',{chklist:check_list,nact:5,select:'yes'}); GEN.chklistCupd({chklist:check_list,nact:1,params:{pp_layer:signal,pp_d2c:500,pp_tests:'Spacing\;Drill\;Size\;Rout\;SMD'}}); if(ss_layers.length > 0){ GEN.chklistCupd({chklist:check_list,nact:4,params:{pp_layers:ss_layer}}); } if(pg_layers.length > 0){ GEN.chklistCupd({chklist:check_list,nact:2,params:{pp_layers:pg_layer,pp_tests:'Drill\;Rout'}}); } GEN.chklistCupd({chklist:check_list,nact:5,params:{pp_tests:'Hole Separation\;NPTH to Rout'}}); GEN.chklistRun({chklist:check_list,nact:'s'}); // 分析取得结果插入数据库 var dirll_info = {},signal_info={},sm_info={}; for (var i in drill) { var drl = drill[i]; var drill_meas = GEN.getCheckMeas({job:job,step:step,chklist:check_list,nact:5,units:par.units,layer:drl}); var same_net = drill_meas.filter(function(v){return /same/.test(v)}) var diff_net = drill_meas.filter(function(v){return /diff/.test(v)}) var drill_to_outline = drill_meas.filter(function(v){return /drill_to_outline/.test(v)}) var np_to_rout = drill_meas.filter(function(v){return /npth2rout/.test(v)}) dirll_info[drl] = {}; if(same_net.length > 0){ var tmp = same_net[0].split(/\s+/); dirll_info[drl]["same_min"] = (tmp[2]/1000).toFixed(3); }else{ dirll_info[drl]["same_min"] = '/'; } if(diff_net.length > 0){ var tmp = diff_net[0].split(/\s+/); dirll_info[drl]["diff_min"] = (tmp[2]/1000).toFixed(3); }else{ dirll_info[drl]["diff_min"] = '/'; } if(drill_to_outline.length > 0){ var tmp = drill_to_outline[0].split(/\s+/); dirll_info[drl]["drill_to_outline"] = (tmp[2]/1000).toFixed(3); }else{ dirll_info[drl]["drill_to_outline"] = '/'; } if(np_to_rout.length > 0){ var tmp = np_to_rout[0].split(/\s+/); dirll_info[drl]["np_to_rout"] = (tmp[2]/1000).toFixed(3); }else{ dirll_info[drl]["np_to_rout"] = '/'; } IKM.save_layerinfo({jobid:JobId, jobcategory:'org', tlname:matrix[drl].tl_name, layerinfohash:{h2h_min_same_layer:dirll_info[drl].same_min, h2h_min_different_layer:dirll_info[drl].diff_min, drill_to_rout:dirll_info[drl].drill_to_outline, npth_to_rout:dirll_info[drl].np_to_rout } }); } signals.forEach(function(layer){ var signal_meas = GEN.getCheckMeas({job:job,step:step,chklist:check_list,nact:1,units:par.units,layer:layer}); var line_to_line = signal_meas.filter(function(v){return /l2l/.test(v)}) var line_to_pad = signal_meas.filter(function(v){return /p2line/.test(v)}) // 线到pad var pad_to_pad = signal_meas.filter(function(v){return /pth2pth|via2via/.test(v)}) // pad到pad var hole_to_copper = signal_meas.filter(function(v){return /(via2l)|(via2c)|(pth2c)|(pth2l)/.test(v)}) // hole到copper var min_ring = signal_meas.filter(function(v){return /(via_ar)|(pth_ar)/.test(v)}) // 最小ring var min_line = signal_meas.filter(function(v){return /(line)|(arc)/.test(v)}) // 最小线宽 var smd_pitch = signal_meas.filter(function(v){return /smd_pitch/.test(v)}) // SMD_pith var bga_pitch = signal_meas.filter(function(v){return /bga_pitch/.test(v)}) // BGA_pith var rout_copper = signal_meas.filter(function(v){return /r2c/.test(v)}) // rout to copper if(!signal_info[layer]){signal_info[layer] = {}} if(line_to_line.length > 0){ var tmp = line_to_line[0].split(/\s+/) signal_info[layer].line_to_line = (tmp[2]/1000).toFixed(3); }else{ signal_info[layer].line_to_line = '/'; } if(line_to_pad.length > 0){ var tmp = line_to_pad[0].split(/\s+/) signal_info[layer].line_to_pad = (tmp[2]/1000).toFixed(3); }else{ signal_info[layer].line_to_pad = '/'; } if(pad_to_pad.length > 0){ var tmp = pad_to_pad[0].split(/\s+/) signal_info[layer].pad_to_pad = (tmp[2]/1000).toFixed(3); }else{ signal_info[layer].pad_to_pad = '/'; } if(hole_to_copper.length > 0){ var tmp = hole_to_copper[0].split(/\s+/) signal_info[layer].hole_to_copper = (tmp[2]/1000).toFixed(3); }else{ signal_info[layer].hole_to_copper = '/'; } if(min_ring.length > 0){ var tmp = min_ring[0].split(/\s+/) signal_info[layer].min_ring = (tmp[2]/1000).toFixed(3); }else{ signal_info[layer].min_ring = '/'; } if(min_line.length > 0){ var tmp = min_line[0].split(/\s+/) signal_info[layer].min_line = (tmp[2]/1000).toFixed(3); }else{ signal_info[layer].min_line = '/'; } if(smd_pitch.length > 0){ var tmp = smd_pitch[0].split(/\s+/) signal_info[layer].smd_pitch = (tmp[2]/1000).toFixed(3); }else{ signal_info[layer].smd_pitch = '/'; } if(bga_pitch.length > 0){ var tmp = bga_pitch[0].split(/\s+/) signal_info[layer].bga_pitch = (tmp[2]/1000).toFixed(3); }else{ signal_info[layer].bga_pitch = '/'; } if(rout_copper.length > 0){ var tmp = rout_copper[0].split(/\s+/) signal_info[layer].rout_copper = (tmp[2]/1000).toFixed(3); }else{ signal_info[layer].rout_copper = '/'; } IKM.save_layerinfo({jobid:JobId, jobcategory:'org', tlname:matrix[layer].tl_name, layerinfohash:{l2l_min:signal_info[layer].line_to_line, l2p_min:signal_info[layer].line_to_pad, p2p_min:signal_info[layer].pad_to_pad, h2c_min:signal_info[layer].hole_to_copper, annular_ring_min:signal_info[layer].min_ring, org_line_width_min:signal_info[layer].min_line, rout_to_copper:signal_info[layer].rout_copper, smd_pitch:signal_info[layer].smd_pitch, bga_pitch:signal_info[layer].bga_pitch, } }); }) pg_layers.forEach(function(layer){ var pg_meas = GEN.getCheckMeas({job:job,step:step,chklist:check_list,nact:2,units:par.units,layer:layer}); var hole_to_copper = pg_meas.filter(function(v){return /(via2l)|(via2c)|(pth2c)|(pth2l)/.test(v)}) // hole到copper var min_ring = pg_meas.filter(function(v){return /(via2t)|(pth2t)/.test(v)}) // 最小ring var rout_copper = pg_meas.filter(function(v){return /r2c/.test(v)}) // rout to copper if(!signal_info[layer]){signal_info[layer] = {}} if(hole_to_copper.length > 0){ var tmp = hole_to_copper[0].split(/\s+/) signal_info[layer].hole_to_copper = (tmp[2]/1000).toFixed(3); }else{ signal_info[layer].hole_to_copper = '/'; } if(min_ring.length > 0){ var tmp = min_ring[0].split(/\s+/) signal_info[layer].min_ring = (tmp[2]/1000).toFixed(3); }else{ signal_info[layer].min_ring = '/'; } if(rout_copper.length > 0){ var tmp = rout_copper[0].split(/\s+/) signal_info[layer].rout_copper = (tmp[2]/1000).toFixed(3); }else{ signal_info[layer].rout_copper = '/'; } IKM.save_layerinfo({jobid:JobId, jobcategory:'org', tlname:matrix[layer].tl_name, layerinfohash:{ h2c_min:signal_info[layer].hole_to_copper, annular_ring_min:signal_info[layer].min_ring, rout_to_copper:signal_info[layer].rout_copper, }} ); }) sm_layers.forEach(function(layer){ var sm_meas = GEN.getCheckMeas({job:job,step:step,chklist:check_list,nact:3,units:par.units,layer:layer}); var pad_ring = sm_meas.filter(function(v){return /ar_pad/.test(v)}) // ring var pad_cover = sm_meas.filter(function(v){return /coverage/.test(v)}) // cover var pad_bridge = sm_meas.filter(function(v){return /pad2pad_bridge/.test(v)}) // bridge if(!signal_info[layer]){signal_info[layer] = {}} if(pad_ring.length > 0){ var tmp = pad_ring[0].split(/\s+/) signal_info[layer].pad_ring = (tmp[2]/1000).toFixed(3); }else{ signal_info[layer].pad_ring = '/'; } if(pad_cover.length > 0){ var tmp = pad_cover[0].split(/\s+/) signal_info[layer].pad_cover = (tmp[2]/1000).toFixed(3); }else{ signal_info[layer].pad_cover = '/'; } if(pad_bridge.length > 0){ var tmp = pad_bridge[0].split(/\s+/) signal_info[layer].pad_bridge = (tmp[2]/1000).toFixed(3); }else{ signal_info[layer].pad_bridge = '/'; } IKM.save_layerinfo({jobid:JobId, jobcategory:'org', tlname:matrix[layer].tl_name, layerinfohash:{ sm_bridge:signal_info[layer].pad_bridge, sm_cover:signal_info[layer].pad_cover, sm_annular_ring:signal_info[layer].pad_ring, }} ); }) ss_layers.forEach(function(layer){ var ss_meas = GEN.getCheckMeas({job:job,step:step,chklist:check_list,nact:4,units:par.units,layer:layer}); var ss_line = ss_meas.filter(function(v){return /ss_line/.test(v)}) if(!signal_info[layer]){signal_info[layer] = {}} if(ss_line.length > 0){ var tmp = ss_line[0].split(/\s+/) signal_info[layer].ss_min_line = (tmp[2]/1000).toFixed(3); }else{ signal_info[layer].ss_min_line = '/'; } IKM.save_layerinfo({jobid:JobId, jobcategory:'org', tlname:matrix[layer].tl_name, layerinfohash:{ ss_min_line:signal_info[layer].ss_min_line, }} ); }) var result = save_drill_info({job:job,step:step,step_type:'pcs',jobcategory:'mi'}); if (result){ throw result; } saveMeans({job:job,step:step,chklist:check_list}) GEN.clearLayers(); GEN.affectedLayer( {mode:'all',affected:'no'} ); GEN.closeStep() }) // 保存 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 (mode === "aimdfm") { $.QDfm.updateRow({table: "pdm_aimdfm_task",data: {progress: 33.33},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" } } catch (e) { 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 UPLOAD_LAYER_MATRIX(props){ var job = props.job props.jobcategory = props.jobcategory || "work" var matrix = ANALYSIS_STACKUP({job:job, jobcategory:props.jobcategory}); Omatrix = matrix var layers = Object.keys(matrix).sort(function(a,b){return matrix[a]["row"] - matrix[b]["row"]}) var tableName = "pdm_job_" + props.jobcategory + "_layer"; console.log("===========>matrix upload"); var oLayers = db.query("",function(q){ return q.selectMapMap({ table:tableName, field: ["odb_name", "release_status"], where:{job_id:JobId}, uniquefield: "odb_name" }) }); db.query("",function(q){ return q.deleteRow({ table:tableName, where:{job_id:JobId}, }) }); var fieldLst = ["name", "odb_context", "odb_type", "odb_polarity", "odb_side", "drl_start", "drl_end", "row_num", "type", "drl_start_num", "drl_end_num", "drl_from_num", "drl_to_num", "drl_connect_to", "odb_name", "side", "stackup_num", "customer_field", "input_file_name", "odb_row_num" ]; layers.forEach(function(layer){ var layerInfo = matrix[layer]; var tmpData = { "job_id": JobId, "name": layerInfo["name"] }; tmpData["release_status"] = (oLayers&&oLayers.hasOwnProperty(layerInfo["odb_name"])) ? oLayers[layerInfo["odb_name"]]["release_status"] : null; for (n = 0; n < fieldLst.length; n++) { tmpData[fieldLst[n]] = layerInfo[fieldLst[n]]; } db.query("",function(q){ return q.insertRow({ table:tableName, data: tmpData }) }); }) return matrix } function ANALYSIS_STACKUP(props){ var job = props.job if(!props.hasOwnProperty("jobcategory")){ props.jobcategory = 'work' } var matrix = GEN.getMatrix({job:job}) var layer_count = GEN.getLayerCount({job:job}) // ! IKM.save_job_info({jobid:JobId,jobcategory:props.jobcategory,jobinfohash:{TL_layer_count:layer_count}}) _.values(matrix).sort(function(a,b){return a.row-b.row}).forEach(function(layer){ layer.odb_name = layer.name; layer.name = layer.tl_name; layer.odb_context = layer.context; layer.odb_type = layer.layer_type; layer.odb_polarity = layer.polarity; layer.odb_side = layer.side; layer.row_num = layer.tl_num; layer.type = layer.tl_type; layer.side = layer.enum_tl_side; layer.input_file_name = layer.file_name; layer.odb_row_num = layer.row; if (layer.odb_name == 'ftdrill'){ layer.name = 'drill'; layer.drl_start_num = 1; layer.drl_end_num = layer_count; layer.drl_from_num = 1; layer.drl_to_num = layer_count; layer.type = 'main_drill'; } else if (/^ftdrill(\d+)-(\d+)/.test(layer.odb_name)){ // /^d(\d+)\-(\d+)$/ var tmp = /^ftdrill(\d+)-(\d+)/.exec(layer.odb_name) var drl_star = tmp[1]; var drl_end = tmp[2]; layer.drl_start_num = drl_star; layer.drl_end_num = drl_end; layer.drl_from_num = drl_star; layer.drl_to_num = drl_end; if(drl_end - drl_star == 1){ layer.name = 'laser' + drl_star + '-' + drl_end; layer.type = 'laser_drill'; // 镭射 } else if( drl_star == 1 || drl_end == layer_count ){ layer.name = 'drill' + drl_star + '-' + drl_end; layer.type = 'blind_drill'; // 埋孔 } else{ layer.name = 'drill' + drl_star + '-' + drl_end; layer.type = 'bury_drill'; // 盲孔 } } else if (/\-a$/.test(layer.odb_name)){ layer.side = 'top'; if(!layer.name){ layer.name = '__'+layer.odb_name+'__' } if(!layer.type){ layer.type = 'other' } } else if (/\-b$/.test(layer.odb_name)){ layer.side = 'bottom'; if(!layer.name){ layer.name = '__'+layer.odb_name+'__' } if(!layer.type){ layer.type = 'other' } } else{ if(!layer.name){ layer.name = '__'+layer.odb_name+'__' } if(!layer.type){ layer.type = 'other' } } }) return matrix; } function save_drill_info(props){ var job = props.job var step = props.step var matrix_ = GEN.getMatrix({job:job}); var drill = []; // 获取工作层 for (var key in matrix_) { if(matrix_[key].context == "board" && matrix_[key].tl_type=="drill") { drill.push(key) } } var matrix = ANALYSIS_STACKUP({job:job}); var orgDrills = []; var miDrills = []; drill.forEach(function(drl) { if(drl) { var tool = GEN.getTool({job:job,step:step,layer:drl,units:PAR.unit}); Object.keys(tool).sort(function(a,b){return tool[a].num - tool[b].num}).forEach(function(num){ var toolInfo = tool[num] var orgDrillInfo = { job_id : JobId, step_name : step, step_type : props.step_type, std_layer_name : matrix[drl].name, odb_layer_name : drl, row_num : num, drill_size : toolInfo.finish_size / 1000, finish_size : toolInfo.finish_size / 1000, drill_type : toolInfo.type2 != 'standard' ? toolInfo.type2 : toolInfo.type, drill_shape : toolInfo.shape, count : toolInfo.count, slot_length : toolInfo.slot_len, drill_size_lower_tol : toolInfo.min_tol, drill_size_upper_tol : toolInfo.max_tol } var miDrillInfo = { job_id : JobId, step_name : step, step_type : props.step_type, std_layer_name : matrix[drl].name, odb_layer_name : drl, row_num : num, drill_size : toolInfo.drill_size / 1000, finish_size : toolInfo.finish_size / 1000, drill_type : toolInfo.type2 != 'standard' ? toolInfo.type2 : toolInfo.type, drill_shape : toolInfo.shape, count : toolInfo.count, slot_length : toolInfo.slot_len, drill_size_lower_tol : toolInfo.min_tol, drill_size_upper_tol : toolInfo.max_tol }; orgDrills.push(orgDrillInfo); miDrills.push(miDrillInfo); }) } }) var func = 'function(ARGV)\ {\ var jobId = ARGV["job_id"];\ var data = ARGV["data"];\ var midata = ARGV["midata"];\ var stepName = ARGV["step_name"];\ var tableName = "pdm_job_" + ARGV["jobcategory"] + "_drill";\ //GUI.msgbox({text: TDataParse.variant2JsonStr(tableName)});\ //GUI.msgbox({detail: _.toString(ARGV["data"])});\ var db = new TSqlQueryV2(T_SQLCNT_POOL.getSqlDatabase());\ db.begin();\ try{\ var miData = [];\ var orgUidList = [];\ _.each(data, function(h){\ h.uid = TDataParse.getUuid();\ orgUidList.push(h.uid);\ });\ var i = 0;\ _.each(midata, function(n){\ n.uid = TDataParse.getUuid();\ var miMap = _.pick(n, ["job_id","std_layer_name","odb_layer_name","step_name","step_type","drill_size","finish_size","drill_type","drill_shape","drill_size_lower_tol","drill_size_upper_tol","slot_length"])\ miMap.uid = TDataParse.getUuid();\ if (n.step_type == "pcs") miMap.pcs_count = n.count;\ if (n.step_type == "array") miMap.array_count = n.count;\ miMap.calc_drill_size = n.drill_size;\ miMap.org_size = n.finish_size;\ miMap.org_slot_length = n.org_slot_length;\ miMap.org_size_upper_tol = n.drill_size_upper_tol;\ miMap.org_size_lower_tol = n.drill_size_lower_tol;\ miMap.org_uids = [orgUidList[i]];\ miData.push(miMap);\ i++;\ });\ db.deleteRow({table: "pdm_job_org_drill", where: {job_id: jobId}});\ db.batchInsert("pdm_job_org_drill", ["uid","job_id","step_name","step_type","std_layer_name","odb_layer_name","row_num","drill_size",\ "drill_type","drill_shape","count","slot_length","drill_size_lower_tol","drill_size_upper_tol"], data);\ if (ARGV["jobcategory"] == "mi") {\ db.deleteRow({table: "pdm_job_mi_drill", where: {job_id: jobId, step_name: stepName}});\ db.batchInsert("pdm_job_mi_drill", db.getFieldList("pdm_job_mi_drill"), miData);\ }\ if (db.lastError().isValid()) throw db.lastError();\ db.commit();\ return new TDataResponse();\ }\ catch (err)\ {\ GUI.msgbox({text: "Error", detail: _.toString(err.text())});\ db.rollback();\ return new TDataResponse(err, "");\ }\ }'; var ret = IKM.command( func,{job_id :JobId, data:orgDrills,midata:miDrills,jobcategory:props.jobcategory,step_name:step}, 1); // --work属性 if (ret.errText) { return { jobcategory:props.jobcategory, errText : ret.errText, errCode : ret.errCode, }; } } function mkPath(path, list) { if (list.length) { var newPath = path + '/' + list.shift() if (!fs.dirExists(newPath)) {fs.mkdir(newPath)} return mkPath(newPath, list) } else { return path } } function saveMeans(props){ var job = props.job var custstep = props.step var chklist = props.chklist var nact = props.nact var jobpath = GEN.getJobPath({job: job}) var filter = props.filter var afterPath = mkPath(jobpath, ["user", "opencam", "steps"]) var steps; if (custstep) { steps = [custstep] } else { steps = GEN.getStepList({job: job}) } if(!steps || steps.length==0){ return } steps.forEach(function (step) { var chkPath = mkPath(afterPath, [step, "chk"]) var chks if (chklist) {chks = [chklist]}else { chks = GEN.getChecklist({job: job,step: step}) } if(chks && chks.length){ chks.forEach(function (item, i) { var afterChkPath = mkPath(chkPath, [item]) var hdr = "{\n\ \"title\": \"" + item + "\",\n\ \"sequence\": " + (i + 1) + "\n\ }" fs.writeFile(afterChkPath + "/hdr", _.toString(hdr)) var nacts = [] if (nact) { nacts = [nact] } else { var nactCount = GEN.getChklistActCount({job:job,step:step,chklist:item}) for (var i = 0; i < nactCount; i++) { nacts.push(i+1) } } if(nacts.length > 0){ var actionPath = mkPath(afterChkPath, ["actions"]) nacts.forEach(function(index){ var titleFile = GEN.INFO({ entity_type: "check", entity_path: job + "/" + step + "/" + item, data_type: "TITLE", options: "action=" + index, parse:'no' }) var title = fs.readFile(titleFile) title = title.split("=")[1].trim() title = title.substring(1, title.length-1) var nackPath = mkPath(actionPath, [index+"-"+title]) fs.writeFile(nackPath + "/hdr", "{\n\ \"title\": \"" + (index + "-" + title) + "\",\n\ \"sequence\": " + index + ",\n\ \"dfm_name\": \"" + title + "\"\n\ }") var displayFile = GEN.INFO({ entity_type: 'check', entity_path: job + "/" + step + "/" + item, data_type: 'MEAS_DISP_ID', options: "action=" + index, parse:'no' }); fs.writeFile(nackPath + "/disp", fs.readFile(displayFile)) var measFile = GEN.INFO({entity_type:'check', entity_path:job+'/'+step+'/'+item, data_type:'MEAS', options:"index+action="+index, parse:'no'}); var means if(filter){ // 处理过滤 var fileArray = [] var file = fs.openFile(measFile,'r'); while(!file.atEnd()) { fileArray.push(file.readLine()) } if(Array.isArray(filter)){ var nowFilter = filter.filter(function(item2){ for (var key in item2) { var value = item2[key] if (!Array.isArray(value)){ item2[key] = [value] } } return item2.step.indexOf(step)>=0 && item2.chk.indexOf(item)>=0 && item2.nact.indexOf(index)>=0 }) if (nowFilter.length > 0){ var nowfilter = nowFilter.map(function(v){return v.filter}).reduce(function(a,b){ b.forEach(function(v2){ if (a.indexOf(v2)<0){ a.push(v2) } }) return a },[]) fileArray = fileArray.filter(function(line){ var flag = false nowfilter.forEach(function(f){ var reg = new RegExp(f, "ig") if (reg.test(line)){ flag = true } }) return flag }) } } else if (typeof filter == "object") { if (filter[step] && filter[step][item] && filter[step][item][String(index)]) { var nowFilter = filter[step][item][String(index)] if (!Array.isArray(nowFilter)){nowFilter = [nowFilter]} fileArray = fileArray.filter(function(line){ var flag = false nowFilter.forEach(function(f){ var reg = new RegExp(f, "ig") if (reg.test(line)){ flag = true } }) return flag }) } } means = fileArray.join("\n") } else { means = fs.readFile(measFile) } fs.writeFile(nackPath + "/meas", means) }) } }) } }) }