=head
 NAME: 
 DESCRIPTION: 
 PARAMETER:
	[
		{
			name : 'step_filter',
			title : '过滤Step',
			type : 'LineEdit',
			property : {tool_tip : '未设定则手动选择'},
		},
		{
			name : 'save_job',
			title : '保存料号',
			type : 'RadioBox',
			property : {
				size_policy:'Expanding,Fixed',
				item_list:[
					{name:'Yes',text:'Yes'},
					{name:'No',text:'No'},
				],
				tool_tip:'脚本结束后自动保存料号,未设定,默认为No'
			},
			pack : {row:1,column:1},
		}
	]
	
 VERSION_HISTORY:
	V1.00 2020-1-14 Super
		1.新版本.
	V1.1 2020-2-28 Super
		1.增加每层残铜
		2.增加每个step的满铜面积
	V1.2 2020-03-03 Super
		1.上传钻孔信息
	V1.3 2020-04-15 Kurri
		1.增加上传文字面积
	V1.4 2020-04-26 Super
		1.增加最小线宽
		2.PG层增加孔到铜
	V1.5 2020-05-11 Super
		1.钻孔上传的大小按mm存储
	V1.6 2020-07-03 Kurri
		1.钻孔上传原稿时先删除料号所有step的原稿钻孔(多pcs情况如何处理的逻辑待客户确认)
	V1.7 2020-07-03 Super
		1.analysis SM 
	V1.71 2020-08-11 Super Zhang
		1.add silck min line
 HELP:
	<html><body bgcolor="#DDECFE">
		<font size="3" color="#003DB2"><p>功能简介</p></font>
		  <p>  </p>
		  <br>
		<font size="3" color="#003DB2"><p>参数配置</p></font>
		<font color="#008000"><p> ● 无</p></font>
		<font size="3" color="#003DB2"><p>注意事项</p></font>
		  <p> ● 无 </p>
		  <br>
	</body></html>
=cut
use warnings;
use strict;
use utf8;
use Encode;
use Data::Dump qw/dump/;
doScript("TL_Public");
use_module('TL_GenMath');

my ($Job,$Step)= ($JOB,undef);
$Step = $PAR->{step_filter} ? $PAR->{step_filter} : '.*';
my @work_layers;
$PAR->{del_backup} = 'yes' unless $PAR->{del_backup};
$PAR->{save_job} = 'No' unless $PAR->{save_job};
$PAR->{units} = 'mm' unless $PAR->{units};
###############################################################################
try{
    show_loading("判断是否选择料号..",0,position=>'n');
	unless( $Job){
		$GUI->msgbox(-icon=>'error',-text=>"请先选择料号后再执行脚本!");
        return 'Cancel';
	}
	
	##
	update_loading("检查${Job}是否存在..",0,position=>'n');
	unless ( $GEN->isJobExists(job=>$Job) ){
        $GUI->msgbox(-icon=>'error',-text=>"料号${Job}不存在,请确认。");
        return 'Cancel';
    }
	
	##
	update_loading("正在打开料号 ${Job} ...",0,position=>'n');
	$GEN->openJob(job=>$Job);

	##
	update_loading("过滤工作step...",0,position=>'n');
	my $return = get_work_step();
	return 'Cancel' if $return eq 'Cancel';

	
	##
	update_loading("打开Step...",0,position=>'n');
	$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=>'mm' );
	$GEN->zoomHome();

	my $board_thickness = $IKM->get_jobinfo(-jobname=>$Job,-jobcategory=>'work',-jobinfo=>'board_thickness',-units=>$PAR->{units})||0;
	$board_thickness *= 1000 ;
	
	update_loading("正在上传matrix信息,请稍候..",0,position=>'n');
	$PAR->{public_script} = "SEC_Public";
	doScript("$PAR->{public_script}");
	my $ans = UPLOAD_LAYER_MATRIX(job=>$Job,jobcategory=>'org');
	if ($ans ){
		$GUI->msgbox(-icon=>'warning',-text=>dump($ans));
		return 'Error';
	}
	
	update_loading("资料分析中,请稍候..",0,position=>'n');
	my $check_list = 'pcb_analysis_jt01';
	my ($signal,@signal,@pg_layer,$pg_layer,@drill,@sm_layer,@ss_layer,$ss_layer);
	my %matrix = $GEN->getMatrix(job=>$Job,type=>'hash');
	foreach my $layer (sort {$matrix{$a}{row} <=> $matrix{$b}{row}}  keys %matrix) {
		if(defined($matrix{$layer}{context}) and $matrix{$layer}{context} eq 'board' ){
			if($matrix{$layer}{layer_type} eq 'signal' and $layer =~ /(cil)|(col)/){
				my %lyr_paras;
				if($matrix{$layer}{side} eq 'top'){
					$lyr_paras{layer1} = $layer;
					$lyr_paras{drills} = 'yes';
					$lyr_paras{thickness} = $board_thickness/2;
				}elsif($matrix{$layer}{side} eq '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;
				}
				my $copperArea = $GEN->copperArea(%lyr_paras);
				$copperArea->{area} = sprintf('%.3f',$copperArea->{area});
				$copperArea->{percent} = sprintf('%d',$copperArea->{percent});
				$IKM->save_layerinfo(-jobid=>$JOB_ID,
									 -jobcategory=>'org',
									 -tlname=>$matrix{$layer}{tl_name},
									 -layerinfohash=>{copper_area_pcs=>$copperArea->{area},
													  copper_area_ratio_pcs=>$copperArea->{percent}}
									);
				push @signal,$layer;
				$layer .= ';';
				$signal .= $layer; 
			}elsif($matrix{$layer}{layer_type} eq 'power_ground' and $layer =~ /(cil)/){
				my %lyr_paras = (
					layer1 => $layer,
					drills => 'no',
					thickness => 0
				);
				my $copperArea = $GEN->copperArea(%lyr_paras);
				$copperArea->{area} = sprintf('%.3f',$copperArea->{area});
				$copperArea->{percent} = sprintf('%d',$copperArea->{percent});
				$IKM->save_layerinfo(-jobid=>$JOB_ID,
									 -jobcategory=>'org',
									 -tlname=>$matrix{$layer}{tl_name},
									 -layerinfohash=>{copper_area_pcs=>$copperArea->{area},
													  copper_area_ratio_pcs=>$copperArea->{percent}}
									);
				push @pg_layer,$layer;
				$layer .= ';';
				$pg_layer .= $layer; 
			}elsif($matrix{$layer}{layer_type} eq 'drill'){
				push @drill,$layer;
			}
			elsif ($matrix{$layer}{layer_type} eq 'silk_screen' and $layer =~ /lpp/) {
				my %lyr_paras = (
					layer1 => $layer,
					drills => 'no',
					thickness => 0
				);
				my $copperArea = $GEN->copperArea(%lyr_paras);
				my $target_attrname = $matrix{$layer}{side} eq 'top' ? 'ss_area_pcs_top' : 'ss_area_pcs_bot';
				my $jobinfohash = {};
				$jobinfohash->{$target_attrname} = $copperArea->{area};
				$IKM->save_jobinfo(
					-jobid=>$JOB_ID,
					-jobcategory=>'work',
					-jobinfohash=>$jobinfohash
				);
				push @ss_layer,$layer;
				$layer .= ';';
				$ss_layer .= $layer;
			}elsif($matrix{$layer}{layer_type} eq 'solder_mask' and $layer =~ /smf/){
				push @sm_layer,$layer;
			}
		}
	}
	
	my $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');
	my $profile_limits = $GEN->getProfileLimits(job=>$Job,step=>$Step,units=>'mm');
	
	if($profile_limits->{xsize} == 0){
		$GEN->affectedLayer( mode=>'all',affected=>'no' );
		$GEN->deleteLayer(job=>$Job,layer=>$tmp_layer,step=>$Step);
		$GUI->msgbox(-icon=>'error',-text=>"请先创建${Step}的profile线!");
        return 'Cancel';
	}else{
		$GEN->srFill(layer=>$tmp_layer);
		my %lyr_paras;
		$lyr_paras{layer1} = $tmp_layer;
		$lyr_paras{drills} = 'no';
		$lyr_paras{thickness} = 0;
		my $copperArea = $GEN->copperArea(%lyr_paras);
		$copperArea->{area} = sprintf('%.3f',$copperArea->{area});
		$copperArea->{percent} = sprintf('%d',$copperArea->{percent});
		$GEN->affectedLayer( mode=>'all',affected=>'no' );
		$GEN->deleteLayer(job=>$Job,layer=>$tmp_layer,step=>$Step);
		$IKM->save_layerinfo(-jobid=>$JOB_ID,
						-jobcategory=>'org',
						-tlname=>$Step,
						-layerinfohash=>{board_area_pcs=>$copperArea->{area},
										board_area_ratio_pcs=>$copperArea->{percent}}
					);
	}
	# unless ($GEN->isChklistExists(job=>$Job,step=>$Step,chklist=>$check_list)) {
	# 	$GUI->msgbox(-icon=>'error',-text=>"系统中未发现pcb_analysis_jt01的checklist请和系统管理员联系!!!");
	# 	return 'Error';
    # }

	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_layer){
		$GEN->COM('chklist_select_act',chklist=>$check_list,nact=>2,select=>'yes');#运行PG层分析
	}
	if(@sm_layer){
		$GEN->COM('chklist_select_act',chklist=>$check_list,nact=>3,select=>'yes');
	}
	if(@ss_layer){
		$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_layer){
		$GEN->chklistCupd(chklist=>$check_list,nact=>4,params=>{pp_layers=>$ss_layer});
	}
	
	if(@pg_layer){
		$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');

	#分析取得结果插入数据库
	my($dirll_info,$signal_info,$sm_info);
	foreach my $drl (@drill){
		my @drill_meas  = $GEN->getCheckMeas(job=>$Job,step=>$Step,chklist=>$check_list,nact=>5,units=>'mm',layer=>$drl);
		my @same_net = grep($_ =~ /(same)/,@drill_meas);
		my @diff_net = grep($_ =~ /(diff)/,@drill_meas);
		
		my @drill_to_outline = grep($_ =~ /(drill_to_outline)/,@drill_meas);
		my @np_to_rout = grep($_ =~ /(npth2rout)/,@drill_meas);
		
		if(@same_net > 0){
			my @tmp = split(/\s+/,$same_net[0]);
			$dirll_info->{$drl}{same_min} = sprintf("%0.3f",$tmp[2]/1000);
		}else{
			$dirll_info->{$drl}{same_min} = '/';
		}

		if(@diff_net > 0){
			my @tmp = split(/\s+/,$diff_net[0]);
			$dirll_info->{$drl}{diff_min} = sprintf("%0.3f",$tmp[2]/1000);
		}else{
			$dirll_info->{$drl}{diff_min} = '/';
		}
		
		if(@drill_to_outline > 0){
			my @tmp = split(/\s+/,$drill_to_outline[0]);
			$dirll_info->{$drl}{drill_to_outline} = sprintf("%0.3f",$tmp[2]/1000);
		}else{
			$dirll_info->{$drl}{drill_to_outline} = '/';
		}
		if(@np_to_rout > 0){
			my @tmp = split(/\s+/,$np_to_rout[0]);
			$dirll_info->{$drl}{np_to_rout} = sprintf("%0.3f",$tmp[2]/1000);
		}else{
			$dirll_info->{$drl}{np_to_rout} = '/';
		}
		#$GUI->debug(-text=>dump($matrix{$drl}{tl_name},'--->>>',$dirll_info));
		$IKM->save_layerinfo(-jobid=>$JOB_ID,
							 -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},
							 				}
							 );
	}

	foreach my $layer (@signal){
		my @signal_meas = $GEN->getCheckMeas(job=>$Job,step=>$Step,chklist=>$check_list,nact=>1,units=>'mm',layer=>$layer);
		my @line_to_line = grep($_ =~ /(l2l)/,@signal_meas);#线到线
		my @line_to_pad = grep($_ =~ /(p2line)/,@signal_meas);#线到pad
		my @pad_to_pad = grep($_ =~ /(pth2pth)|(via2via)/,@signal_meas);#pad到pad
		my @hole_to_copper = grep($_ =~ /(via2l)|(via2c)|(pth2c)|(pth2l)/,@signal_meas);##hole到copper
		my @min_ring = grep($_ =~ /(via_ar)|(pth_ar)/,@signal_meas);;#最小ring
		my @min_line = grep($_ =~ /(line)|(arc)/,@signal_meas);#最小线宽
		
		my @smd_pitch = grep($_ =~ /(smd_pitch)/,@signal_meas);#SMD_pith
		my @bga_pitch = grep($_ =~ /(bga_pitch)/,@signal_meas);#BGA_pith
		my @rout_copper = grep($_ =~ /(r2c)/,@signal_meas);#rout to copper
		
		if(@line_to_line > 0){
			my @tmp = split(/\s+/,$line_to_line[0]);
			$signal_info->{$layer}{line_to_line} = sprintf("%0.3f",$tmp[2]/1000);
		}else{
			$signal_info->{$layer}{line_to_line} = '/';
		}

		if(@line_to_pad > 0){
			my @tmp = split(/\s+/,$line_to_pad[0]);
			$signal_info->{$layer}{line_to_pad} = sprintf("%0.3f",$tmp[2]/1000);
		}else{
			$signal_info->{$layer}{line_to_pad} = '/';
		}

		if(@pad_to_pad > 0){
			my @tmp = split(/\s+/,$pad_to_pad[0]);
			$signal_info->{$layer}{pad_to_pad} = sprintf("%0.3f",$tmp[2]/1000);
		}else{
			$signal_info->{$layer}{pad_to_pad} = '/';
		}

		if(@hole_to_copper > 0){
			my @tmp = split(/\s+/,$hole_to_copper[0]);
			$signal_info->{$layer}{hole_to_copper} = sprintf("%0.3f",$tmp[2]/1000);
		}else{
			$signal_info->{$layer}{hole_to_copper} = '/';
		}

		if(@min_ring > 0){
			my @tmp = split(/\s+/,$min_ring[0]);
			$signal_info->{$layer}{min_ring} = sprintf("%0.3f",$tmp[2]/1000);
		}else{
			$signal_info->{$layer}{min_ring} = '/';
		}

		if(@min_line > 0){
			my @tmp = split(/\s+/,$min_line[0]);
			$signal_info->{$layer}{min_line} = sprintf("%0.3f",$tmp[2]/1000);
		}else{
			$signal_info->{$layer}{min_line} = '/';
		}
		
		if(@smd_pitch > 0){
			my @tmp = split(/\s+/,$smd_pitch[0]);
			$signal_info->{$layer}{smd_pitch} = sprintf("%0.3f",$tmp[2]/1000);
		}else{
			$signal_info->{$layer}{smd_pitch} = '/';
		}
		if(@bga_pitch > 0){
			my @tmp = split(/\s+/,$bga_pitch[0]);
			$signal_info->{$layer}{bga_pitch} = sprintf("%0.3f",$tmp[2]/1000);
		}else{
			$signal_info->{$layer}{bga_pitch} = '/';
		}		
		if(@rout_copper > 0){
			my @tmp = split(/\s+/,$rout_copper[0]);
			$signal_info->{$layer}{rout_copper} = sprintf("%0.3f",$tmp[2]/1000);
		}else{
			$signal_info->{$layer}{rout_copper} = '/';
		}
		$IKM->save_layerinfo(-jobid=>$JOB_ID,
						-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},
									}
						);
	}

	foreach my $layer (@pg_layer){
		my @pg_meas = $GEN->getCheckMeas(job=>$Job,step=>$Step,chklist=>$check_list,nact=>2,units=>'mm',layer=>$layer);
		my @hole_to_copper = grep($_ =~ /(via2l)|(via2c)|(pth2c)|(pth2l)/,@pg_meas);##hole到copper
		my @min_ring = grep($_ =~ /(via2t)|(pth2t)/,@pg_meas);#最小ring
		
		my @rout_copper = grep($_ =~ /(r2c)/,@pg_meas);#rout to copper
		
		if(@hole_to_copper > 0){
			my @tmp = split(/\s+/,$hole_to_copper[0]);
			$signal_info->{$layer}{hole_to_copper} = sprintf("%0.3f",$tmp[2]/1000);
		}else{
			$signal_info->{$layer}{hole_to_copper} = '/';
		}
		if(@min_ring > 0){
			my @tmp = split(/\s+/,$min_ring[0]);
			$signal_info->{$layer}{min_ring} = sprintf("%0.3f",$tmp[2]/1000);
		}else{
			$signal_info->{$layer}{min_ring} = '/';
		}
		if(@rout_copper > 0){
			my @tmp = split(/\s+/,$rout_copper[0]);
			$signal_info->{$layer}{rout_copper} = sprintf("%0.3f",$tmp[2]/1000);
		}else{
			$signal_info->{$layer}{rout_copper} = '/';
		}
		$IKM->save_layerinfo(-jobid=>$JOB_ID,
				-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},
							}
				);
	}

	foreach my $layer (@sm_layer){
		my @sm_meas = $GEN->getCheckMeas(job=>$Job,step=>$Step,chklist=>$check_list,nact=>3,units=>'mm',layer=>$layer);
		my @pad_ring   = grep($_ =~ /(ar_pad)/,@sm_meas);#ring
		my @pad_cover  = grep($_ =~ /(coverage)/,@sm_meas);#cover
		my @pad_bridge = grep($_ =~ /(pad2pad_bridge)/,@sm_meas);#bridge
		if(@pad_ring > 0){
			my @tmp = split(/\s+/,$pad_ring[0]);
			$signal_info->{$layer}{pad_ring} = sprintf("%0.3f",$tmp[2]/1000);
		}else{
			$signal_info->{$layer}{pad_ring} = '/';
		}
		if(@pad_cover > 0){
			my @tmp = split(/\s+/,$pad_cover[0]);
			$signal_info->{$layer}{pad_cover} = sprintf("%0.3f",$tmp[2]/1000);
		}else{
			$signal_info->{$layer}{pad_cover} = '/';
		}
		if(@pad_bridge > 0){
			my @tmp = split(/\s+/,$pad_bridge[0]);
			$signal_info->{$layer}{pad_bridge} = sprintf("%0.3f",$tmp[2]/1000);
		}else{
			$signal_info->{$layer}{pad_bridge} = '/';
		}
		$IKM->save_layerinfo(-jobid=>$JOB_ID,
		-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},
					}
		);
	}
	
	foreach my $layer (@ss_layer){
		my @ss_meas = $GEN->getCheckMeas(job=>$Job,step=>$Step,chklist=>$check_list,nact=>4,units=>'mm',layer=>$layer);
		my @ss_line   = grep($_ =~ /(ss_line)/,@ss_meas);#min line wide
		
		if(@ss_line > 0){
			my @tmp = split(/\s+/,$ss_line[0]);
			$signal_info->{$layer}{ss_min_line} = sprintf("%0.3f",$tmp[2]/1000);
		}else{
			$signal_info->{$layer}{ss_min_line} = '/';
		}
		$IKM->save_layerinfo(-jobid=>$JOB_ID,
		-jobcategory=>'org',
		-tlname=>$matrix{$layer}{tl_name},
		-layerinfohash=>{
							ss_min_line=>$signal_info->{$layer}{ss_min_line},
					}
		);
	}

	update_loading("正在上传drill信息,请稍候..",0,position=>'n');
	my $result = save_drill_info(job=>$Job,step=>$Step,step_type=>'pcs',jobcategory=>'mi');
	if ($result ){
		$GUI->msgbox(-icon=>'warning',-text=>dump($result));
		return 'Error';
	}

	if ($GEN->{STATUS}){
		$GUI->msgbox(-icon=>'error',-text=>'请在pcb_analysis_jt01(checklist)中检查数值是否正确!!!');
	}

	##
	update_loading("程式运行结束...",0,position=>'n');
	$GEN->clearLayers();
	$GEN->affectedLayer( mode=>'all',affected=>'no' );
	hide_loading();
	
	
	##保存料号
	if( $PAR->{save_job} =~ /yes/i ){
		show_loading("$Job 正在保存料号,请稍候...",0,position=>'n');
		$GEN->checkInout(job=>$Job,mode=>'out');
		$GEN->saveJob(job=>$Job);
		hide_loading();
	}
	
	unless ($GEN->{STATUS}){
		return 'done';
	}
	else{
		$GUI->msgbox(-icon=>'error',-text=>join("\n",@{$GEN->{STATUS}}));
		return 'Error';
	}
}
catch Error::Simple with {
	my $error = encode("utf8",shift);
	$GUI->msgbox(-icon=>'error',-text=>$error);
	$GEN->COM("disp_on");
	return 'Error';
}
finally{
};
####################################################################
sub get_work_step {
	update_loading("选择工作step...",0,position=>'n');
    my @steps =  $GEN->getStepList(job=>$Job);
	if ( @steps == 0 ) {
		$GUI->msgbox(-icon=>'error',-text=>'在料号中没有Step存在,你将退出!');
		return 'Cancel';
	}
	elsif (@steps != 0){
		my @tmp_steps = grep(/$Step/,@steps);
		if ( @tmp_steps == 0 ) {
		   $GUI->msgbox(-icon=>'warning',-text=>'根据脚本参数过滤出来的step不存在,请检查资料或者脚本参数配置!');
		   return 'Cancel';
		}
		elsif (@tmp_steps == 1) {
			$Step = $tmp_steps[0];
		}
        else {
            $Step = $GUI->select_step(-title=>'请选择工作 Step',
                                      -steplist=>[@tmp_steps],
									  -default=>[$tmp_steps[0]],
									  -gen=>$GEN,
                                      -selectmode=>'single');
            return 'Cancel' unless ($Step);            
        }
	}
}

=head
	上传钻孔信息
=cut
sub save_drill_info{
	my %par = @_;
	my $Job = $par{job};
	
	my %matrix_ = $GEN->getMatrix(job=>$Job,type=>'hash');
	my @drill;
	# 获取工作层
	foreach my $layer (sort {$matrix_{$a}{row} <=> $matrix_{$b}{row}}  keys %matrix_) {
		next unless $matrix_{$layer}{context} eq 'board';
		if ($matrix_{$layer}{tl_type} eq 'drill') {
			push @drill,$layer;
		}
	}

	my $matrix = ANALYSIS_STACKUP(job=>$Job);

	my (@orgDrills,@miDrills);
	foreach my $drl (@drill) {
		next unless $drl;
		my %tool = $GEN->getTool(job=>$Job,step=>$par{step},layer=>$drl,units=>$PAR->{units});
		#$GUI->debug(dump(\%tool));
		foreach my $num ( sort {$tool{$a}{num} <=> $tool{$b}{num}} keys %tool ) {
			my $drill = $tool{$num};
			my $orgDrill = {
				job_id		=> $JOB_ID,
				step_name	=> $par{step},
				step_type	=> $par{step_type},
				std_layer_name	=> $matrix->{$drl}{name},
				odb_layer_name	=> $drl,
				row_num		=> $num,
				drill_size	=> $drill->{finish_size} / 1000,
				finish_size	=> $drill->{finish_size} / 1000,
				drill_type	=> $drill->{type2} ne 'standard' ? $drill->{type2} : $drill->{type},
				drill_shape	=> $drill->{shape},
				count		=> $drill->{count},
				slot_length	=> $drill->{slot_len},
				drill_size_lower_tol => $drill->{min_tol},
				drill_size_upper_tol => $drill->{max_tol}
			};
			my $miDrill = {
				job_id		=> $JOB_ID,
				step_name	=> $par{step},
				step_type	=> $par{step_type},
				std_layer_name	=> $matrix->{$drl}{name},
				odb_layer_name	=> $drl,
				row_num		=> $num,
				drill_size	=> $drill->{drill_size}  / 1000,
				finish_size	=> $drill->{finish_size} / 1000,
				drill_type	=> $drill->{type2} ne 'standard' ? $drill->{type2} : $drill->{type},
				drill_shape	=> $drill->{shape},
				count		=> $drill->{count},
				slot_length	=> $drill->{slot_len},
				drill_size_lower_tol => $drill->{min_tol},
				drill_size_upper_tol => $drill->{max_tol}
			};
			push @orgDrills, $orgDrill;
			push @miDrills, $miDrill;
		}
	}
	return undef unless @orgDrills;

	my $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, "");
		}
	}';
	my $json = new JSON;
	my $ret = $IKM->command( $func,{job_id =>$JOB_ID, data=>[@orgDrills],midata=>[@miDrills],jobcategory=>$par{jobcategory},step_name=>$par{step}}, 1);#--work属性
	if ($ret->{errText}) {
		return {
			jobcategory=>$par{jobcategory},
			errText => $ret->{errText},
			errCode => $ret->{errCode},
		};
	}
	return undef;
}

__END__