Commit 1eaa49b3 authored by Scott Sun's avatar Scott Sun

scott

parent 5458dacb
......@@ -134,7 +134,8 @@ var resultData = [];
var ALL = {}
var Omatrix = {};
try {
script_info({ result_severity: "analysis start" })
script_info({ progress: 65 })
console.log("=============================================>anaysis_start");
var par = PAR;
var vc_src_01005_pad_result = par.vc_src_01005_pad_result
......@@ -158,6 +159,8 @@ try {
if(step_list.indexOf(pcs_step)<0){
pcs_step = step_list[0]
}
script_info({ result_severity: "analysis update_matrix_info" })
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){
......@@ -209,6 +212,8 @@ try {
})
GEN.clearLayers()
script_info({ result_severity: "analysis drill_stack" })
script_info({ progress: 70 })
// * new 钻孔叠构
var cam_drill_structure = []
var stack_drills = _.values(matrix).filter(function(item){
......@@ -357,6 +362,8 @@ try {
}
}
GEN.closeStep()
script_info({ result_severity: "analysis panel_info" })
script_info({ progress: 70 })
// * profile 和 拼版
var pandle_step = step_list.map(function(v){
var type = "unknow";
......@@ -429,6 +436,7 @@ try {
}
ALL.gold_fingers = gold_fingers
GEN.closeStep()
script_info({ result_severity: "analysis some_job_info" })
var config = {
jobInfo: {
layer_count: ["signal","power_ground"], // Board属性的signal或者power_ground层
......@@ -508,7 +516,8 @@ try {
console.log("===================================> 5 save drill info")
script_info({ result_severity: "analysis drill_info" })
script_info({ progress: 75 })
// * 获取pcs_step 和 array_step的钻孔信息
var drill_tool_info = {};
var drillLayers = analysis_obj.matrixInfo.mDrills;
......@@ -630,7 +639,8 @@ try {
})
console.log("=============================> 6 set smd bga")
script_info({ result_severity: "analysis smd&bga" })
script_info({ progress: 80 })
var allStep = GEN.getStepList({job:job})
allStep.forEach(function(step){
GEN.openStep({job:job,name:step})
......@@ -780,6 +790,8 @@ try {
// jobpath = "/home/local_db/server_db/jobs/"+job
// }
mkPath(jobpath,["user","opcam","steps"])
script_info({ result_severity: "analysis signal" })
script_info({ progress: 85 })
stepList.forEach(function(step){
GEN.openStep({ job: job, name: step })
// 曝光
......@@ -791,6 +803,13 @@ try {
})
var layer_gold_type = /top/ig.test(item.signalL) ? "top" : "bot"
if(tmp_gold_info[layer_gold_type]){
var tmp_area_layer = "gold_area_tmp"
if(GEN.isLayerExists({job:job, layer:tmp_area_layer})){
GEN.deleteLayer({job:job, layer:[tmp_area_layer]})
}
GEN.copyLayer({source_job:job,source_step:step,source_layer:tmp_gold_info[layer_gold_type],dest_layer:tmp_area_layer,mode:'replace',invert:'no'});
GEN.COM("clip_area_strt")
GEN.COM("clip_area_end,layers_mode=layer_name,layer="+tmp_area_layer+",area=profile,area_type=rectangle,inout=outside,contour_cut=yes,margin=0,feat_types=line\;pad\;surface\;arc\;text")
var tmp_info = GEN.copperArea({layer1:tmp_gold_info[layer_gold_type],resolution_value:1})
// var tmp_info = GEN.exposedArea({layer1:item.signalL,mask1:tmp_gold_info[layer_gold_type]})
var tmp_data = {}
......@@ -854,7 +873,7 @@ try {
return {layer:v,symbol:symbol,start:tmp_matrix[v]["drl_start"],end:tmp_matrix[v]["drl_end"]}
})
var drillRes = analysisDrill(drillToSignals,step) // 钻孔分析结果
fs.writeFile("/home/toplinker/samba/scott_test/tmp",_.toString(drillRes))
// fs.writeFile("/home/toplinker/samba/scott_test/tmp",_.toString(drillRes))
console.log("===============drillRes:" + _.toString(drillRes));
drillRes.forEach(function(item){
save_layerinfo({
......@@ -892,6 +911,7 @@ try {
if(par.erf){
tmpitem.erf = par.erf
}
script_info({ result_severity: "analysis run_signal_chk" })
createChklistAndRun({ // 创建checklist并运行
layers: signalLayers,
items: [tmpitem]
......@@ -935,6 +955,8 @@ try {
IKM.msg("export")
script_info({ result_severity: "analysis export" })
script_info({ progress: 95 })
// 导出
if(par.export_path != "" && par.export_mode != "" && par.export_submode != "" ){
if(fs.exists(par.export_path)){
......@@ -955,7 +977,8 @@ try {
$.QDfm.updateRow({
table: "pdm_aimdfm_task",
data: {
progress: 33.33
result_severity:"analysis ok",
progress: 100
},
where: { id: $.task_id }
});
......@@ -1515,7 +1538,6 @@ function analysis(props){
GEN.createLayer({job:that.job,layer:tmp,conext:'misc',type:'document'})
GEN.COM("profile_to_rout,layer="+tmp+",width=1")
var feautres = GEN.getFeatures({job:that.job,step:step,layer:tmp,units:"mm"})
fs.writeFile("/home/samba/tmp/tmp.js", _.toString(feautres))
// 根据feautres 算出周长
var milling = Object.keys(feautres).reduce(function(a,b){
var value = feautres[b]
......@@ -2421,3 +2443,12 @@ function arcLength(x1,y1,x2,y2,x3,y3){
var length = +Math.sqrt(Math.pow(x2-x1,2) + Math.pow(y2-y1,2)) / sin0 * tmp
return length
}
function script_info(props){ // result_severity progress
if (mode === "aimdfm") {
$.QDfm.updateRow({
table: "pdm_aimdfm_task",
data: props,
where: { id: $.task_id }
});
}
}
\ No newline at end of file
......@@ -68,6 +68,8 @@ if (mode === "aimdfm") {
var Status = 'ok';
var resultData = [];
try {
script_info({ result_severity: "format start" })
script_info({ progress: 35 })
var par = PAR;
if(!par.hasOwnProperty("config_path") || par.config_path==""){
console.log("==============cfg");
......@@ -213,6 +215,8 @@ try {
var format_cfg = config.data_format // 拿到数据标准化配置
// 排序和设属性
script_info({ result_severity: "format sort" })
script_info({ progress: 40 })
var ret = sortLayer({job:job, rule:format_cfg, matrix:tl_name_matrix})
if(ret.err){throw err}
var after_sort_matrix = ret.sortNames
......@@ -222,6 +226,8 @@ try {
if(err){throw err}
// 改名
script_info({ result_severity: "format rename" })
script_info({ progress: 50 })
err = reName({job:job, matrix:after_sort_matrix, cfg:format_cfg})
if(err){throw err}
......@@ -251,6 +257,8 @@ try {
}
})
script_info({ result_severity: "format create profile" })
script_info({ progress: 55 })
var all_layer = Object.keys(tmp_matrix)
// 没有outline层
if(all_layer.indexOf("outline") >= 0) { profileRule.unshift("outline")}
......@@ -290,7 +298,8 @@ try {
$.QDfm.updateRow({
table: "pdm_aimdfm_task",
data: {
progress: 33.33
result_severity: "format ok",
progress: 60
},
where: { id: $.task_id }
});
......@@ -697,3 +706,13 @@ function selCopyLayer(props){ // 拷贝选择的到辅助层
}
GEN.selCopyOther({dest:'layer_name',target_layer:layer})
}
function script_info(props){ // result_severity progress
if (mode === "aimdfm") {
$.QDfm.updateRow({
table: "pdm_aimdfm_task",
data: props,
where: { id: $.task_id }
});
}
}
\ No newline at end of file
......@@ -52,6 +52,7 @@ console.log("=============================================>input_start");
var $ = require('topcam.scriptfunc').argv();
var fs = require('fs');
var _ = require('lodash');
var zip = require('topsin.zip');
var mode = $.ikm ? "topcam" : "aimdfm";
var IKM = $.ikm;
if (IKM==undefined ) { IKM = require('topcam.ikm6')($) }
......@@ -76,7 +77,8 @@ if (mode === "aimdfm") {
QDfm.updateRow({
table: "pdm_aimdfm_task",
data: {
current_process_title: $.process_title
current_process_title: $.process_title,
progress: 0
},
where: { id: $.task_id }
});
......@@ -86,6 +88,7 @@ var Status = 'ok';
var resultData = [];
var import_info = []
try {
script_info({ result_severity: "import start" })
var par = PAR;
// var db_path = db.query("",function(q){
// return q.selectValue({
......@@ -162,11 +165,21 @@ try {
}
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解压
jobFiles.forEach(function(item){
if(item.suffix === "zip"){
zip.unzip(item.path);
}
})
// 分析料号文件 得到料号导入信息 导入类型
var jobInfo = analyJobFiles({jobFiles:jobFiles.filter(function(v){return v.isFile}),custCfg:custCfg,config:config,job:job })
if(jobInfo.data.length == 0){throw "file error"}
var importOk = false; // 是否成功导入
script_info({ progress: 10 })
if(/odb/ig.test(jobInfo.type)){ // odb导入
......@@ -266,8 +279,10 @@ try {
importOk = true
}
if(!importOk){throw "import error"}
if(!importOk){
script_info({ result_severity: "import error" })
throw "import error"}
script_info({ progress: 20 })
// 导入结束
var matrix = GEN.getMatrix({job:job});
comp = Object.keys(matrix).filter(function(v){ // 如果有comp层 删除
......@@ -302,24 +317,23 @@ try {
})
}
// name type date user
resultData.push({type: "info",title:"导入资料列表",detail: [{ desc:
import_info.map(function(item){
var import_html = "<table border=1 align='center' cellpadding=5 cellspacing=0 style=\"text-align: center;\"><tr><th>导入状态/Import Status</th><th>文件/File</th><th>类型/Type</th><th>导入时间/Import Time</th><th>操作用户/User</th></tr>"
import_info.forEach(function(item){
var name = item.name
var type = item.type
var date = item.date
var user = item.user
return "导入资料:"+name+", 类型:"+type+", 导入时间:"+date+", 操作用户:"+user
}).join("\n")
}] })
import_html += "<tr><td>Readin</td><td>"+name+"</td><td>"+type+"</td><td>"+date+"</td><td>"+user+"</td></tr>"
})
import_html += "</table>"
// name type date user
resultData.push({type: "info",title:"导入资料列表",detail: [{ desc: import_html }] })
script_info({ result_severity: "import ok" })
if (mode === "aimdfm") {
$.QDfm.updateRow({
table: "pdm_aimdfm_task",
data: {
progress: 33.33
progress: 30
},
where: { id: $.task_id }
});
......@@ -477,3 +491,14 @@ function reNameStep(job) {
}
})
}
function script_info(props){ // result_severity progress
if (mode === "aimdfm") {
$.QDfm.updateRow({
table: "pdm_aimdfm_task",
data: props,
where: { id: $.task_id }
});
}
}
\ No newline at end of file
......@@ -572,7 +572,7 @@
{"orig_name" : ["mask_top\\.art","psm\\.art","sm_top"], "tl_name" : "sm_top" },
{"orig_name" : ["mask_bot\\.art","ssm\\.art","sm_bot"], "tl_name" : "sm_botm" },
{"orig_name" : ["^top$","^top.art$"], "tl_name" : "top" },
{"orig_name" : ["^0?(\\d+)_.*\\.art$","^l(\\d+)\\.art$","^0(\\d+).*ccp_ms","^s(\\d+)\\.art","lay(\\d+)\\.art","layer_(\\d+)"], "tl_name" : "l_($1)"},
{"orig_name" : ["^l(\\d+)_.*\\.art$","^0?(\\d+)_.*\\.art$","^l(\\d+)\\.art$","^0(\\d+).*ccp_ms","^s(\\d+)\\.art","lay(\\d+)\\.art","layer_(\\d+)"], "tl_name" : "l_($1)"},
{"orig_name" : ["^bottom$","^bottom\\.art$"], "tl_name" : "bottom" },
{"orig_name" : ["-(\\d+)-(\\d+)\\.drl$","(\\d+)-(\\d+)-laser\\.drl$","d(\\d+)-(\\d+)"], "tl_name" : "d_($1)-($2)"},
{"orig_name" : ["\\.rou$","^rout$"], "tl_name" : "rout" },
......
/*
NAME:
DESCRIPTION: ;
PARAMETER:
[
{
name : 'step_filter',
title : 'step 过滤',
type : 'LineEdit',
property : {tool_tip : 'step 过滤,默认是unit'},
},
{
name : 'auto_save',
title : '自动保存',
type : 'RadioBox',
property : {
item_list:[
{name:'yes',text:'YES'},
{name:'no',text:'NO'},
],
tool_tip:'是否自动保存料号开关'
}
}
]
VERSION_HISTORY:
V1.00 2020-04-28 Carver
1.新版本
HELP:
<html><body bgcolor="#DDECFE">
<font size="3" color="#003DB2"><p>功能简介</p></font>
<p> 删除重孔 </p>
<br>
<font size="3" color="#003DB2"><p>参数配置</p></font>
<p> </p>
<br>
<font size="3" color="#003DB2"><p>注意事项</p></font>
<p> 无 </p>
<br>
</body></html>
*/
//////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////
console.log("=============================>JTG_DRL_delete_duplicate_hole_aim");
// 引入模块 包
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 drl_name = 'drl'
try {
var par = PAR;
var default_par = {
step_filter: 'unit',
units: 'mm',
}
for(var key in default_par){ // 设置默认属性
if (!par.hasOwnProperty(key) || par[key] == ""){
par[key] = default_par[key]
}
}
if(_.isEmpty(Job)){throw "参数Job不存在"}
var 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" }
GEN.checkInout({job:job,mode:"out"});
}
var step = "unit"
var font_layer = "gto_font"
// IKM.msg(GEN.getFeatures({job:job, step:"unit", layer:"1",options:"feat_index"}))
// GEN.selLayerFeat({layer:"1", index:"1",operation:"select"})
// 字符优化
// 1. 拷贝到辅助层 _1 _2 changesymbol r0.1 _1辅助层转铜皮
var tmp1 = font_layer + "_1";
var tmp2 = font_layer + "_2";
var tmp3 = font_layer + "_3";
var tmp4 = font_layer + "_4";
var tmp5 = font_layer + "_5";
var bk = font_layer + "_bk";
[tmp1,tmp2,tmp3,tmp4,tmp5,bk].forEach(function(v){
if(GEN.isLayerExists({job:job, layer:v})){GEN.deleteLayer({job:job,layer:[v]})}
})
GEN.copyLayer({source_job:job,source_step:step,source_layer:font_layer,dest_layer:tmp1, mode:"replace"})
GEN.copyLayer({source_job:job,source_step:step,source_layer:font_layer,dest_layer:bk, mode:"replace"})
GEN.affectedLayer({affected:'no',mode:'all'})
GEN.selClearFeature()
GEN.workLayer({name:tmp1,display_number:2,clear_before:'yes'})
GEN.selChangeSym({symbol:"r0.1"})
GEN.copyLayer({source_job:job,source_step:step,source_layer:tmp1,dest_layer:tmp2, mode:"replace"})
GEN.COM("sel_contourize,accuracy=0,break_to_islands=yes,clean_hole_size=0,clean_hole_mode=x_and_y")
GEN.affectedLayer({affected:'no',mode:'all'})
GEN.clearLayers()
// 2.
var features = GEN.getFeatures({job:job,step:step,layer:tmp1,options:"feat_index"})
var indexes = []
features.forEach(function(item){
GEN.workLayer({name:tmp1,display_number:2,clear_before:'yes'})
var index = item.index;
// 选中index 将它复制到tmp3 获取信息
GEN.selLayerFeat({layer:tmp1, index:index,operation:"select"})
if(GEN.getSelectCount() > 0){
item.limit = GEN.getLayerLimits({job:job,step:step,layer:tmp1,units:'mm', options:"select"})
}
})
function surfaceAnalysis(props){
props.limit.xmin = props.limit.xmin - 0;
props.limit.ymin = props.limit.ymin - 0;
props.limit.xmax = props.limit.xmax - 0;
props.limit.ymax = props.limit.ymax - 0;
props.limit.xsize = props.limit.xsize - 0;
props.limit.ysize = props.limit.ysize - 0;
props.xc = props.limit.xsize / 2 + props.limit.xmin
props.yc = props.limit.ysize / 2 + props.limit.ymin
}
var xs = {};
var ys = {};
features.forEach(function(item){
surfaceAnalysis(item)
indexes.push({
index:item.index,
xmin : item.limit.xmin,
ymin : item.limit.ymin,
xmax : item.limit.xmax,
ymax : item.limit.ymax,
xc:item.xc,
yc:item.yc
})
if(!ys[turnFix(item.yc)]){ys[turnFix(item.yc)] = []}
ys[turnFix(item.yc)].push(item)
if(!xs[turnFix(item.xc)]){xs[turnFix(item.xc)] = []}
xs[turnFix(item.xc)].push(item)
})
var limitinfo = []
indexes = sameDirection(ys, "xc", limitinfo, indexes)
indexes = sameDirection(xs, "yc", limitinfo, indexes)
if(GEN.isLayerExists({job:job,layer:"_ok"})){GEN.deleteLayer({job:job,layer:["_ok"]})}
if(GEN.isLayerExists({job:job,layer:"_fail"})){GEN.deleteLayer({job:job,layer:["_fail"]})}
GEN.createLayer({job:job,layer:'_ok',conext:'misc',type:'document'})
GEN.createLayer({job:job,layer:'_fail',conext:'misc',type:'document'})
limitinfo.forEach(function(item){
GEN.workLayer({name:bk,display_number:2,clear_before:'yes'})
GEN.COM("filter_area_strt")
GEN.COM("filter_area_xy,x="+item.xmin+",y=" + item.ymin)
GEN.COM("filter_area_xy,x="+item.xmax+",y=" + item.ymax)
GEN.COM("filter_area_end,layer=,filter_name=popup,operation=select,area_type=rectangle,inside_area=yes,intersect_area=yes")
if(GEN.getSelectCount() > 0 ) {
GEN.selMoveOther({target_layer:'transform_temp',invert:'no',dx:0,dy:0,size:0})
GEN.workLayer({name:"transform_temp",display_number:2,clear_before:'yes'})
GEN.selTransform({mode:'anchor',oper:'scale',
x_anchor: item.xmin + Math.abs(item.xmax - item.xmin) / 2,
y_anchor: item.ymin + Math.abs(item.ymax - item.ymin) / 2,
x_scale:1.2,y_scale:1.2})
// 与成功层touch 有碰移动到失败层 没碰移动到成功层
GEN.selRefFeat({layers:"_ok",use:"filter",mode:"touch"})
if(GEN.getSelectCount() > 0) {
GEN.selClearFeature()
GEN.selMoveOther({target_layer:'_fail',invert:'no',dx:0,dy:0,size:0})
} else {
GEN.selMoveOther({target_layer:'_ok',invert:'no',dx:0,dy:0,size:0})
}
}
})
indexes.forEach(function(item){
var xc = item.xc;
var yc = item.yc;
GEN.workLayer({name:bk,display_number:2,clear_before:'yes'})
GEN.COM("filter_area_strt")
GEN.COM("filter_area_xy,x="+item.xmin+",y=" + item.ymin)
GEN.COM("filter_area_xy,x="+item.xmax+",y=" + item.ymax)
GEN.COM("filter_area_end,layer=,filter_name=popup,operation=select,area_type=rectangle,inside_area=yes,intersect_area=yes")
if(GEN.getSelectCount() > 0 ) {
GEN.selMoveOther({target_layer:'transform_temp',invert:'no',dx:0,dy:0,size:0})
GEN.workLayer({name:"transform_temp",display_number:2,clear_before:'yes'})
GEN.selTransform({mode:'anchor',oper:'scale',x_anchor: xc,y_anchor: yc,
x_scale:1.2,y_scale:1.2})
// 与成功层touch 有碰移动到失败层 没碰移动到成功层
GEN.selRefFeat({layers:"_ok",use:"filter",mode:"touch"})
if(GEN.getSelectCount() > 0) {
GEN.selClearFeature()
GEN.selMoveOther({target_layer:'_fail',invert:'no',dx:0,dy:0,size:0})
} else {
GEN.selMoveOther({target_layer:'_ok',invert:'no',dx:0,dy:0,size:0})
}
}
})
// 保存
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 sameDirection(xory, type, res, indexes) {
for (var key in xory) {
var current = -1;
var data = xory[key];
data.sort(function(a,b){return a[type] - b[type]})
data.forEach(function(item, i){
if (i > current){
var ret = [item];
current = searchFont(item, data, i, ret,type)
if(ret.length > 1) {
ret.forEach(function(item) {
indexes = indexes.filter(function(item2){
return item2.index != item.index
})
})
res.push(ret.reduce(function(a,b){
if(Number(b.limit.xmin) < Number(a.xmin)){
a.xmin = b.limit.xmin
}
if(Number(b.limit.ymin) < Number(a.ymin)){
a.ymin = b.limit.ymin
}
if(Number(b.limit.xmax) > Number(a.xmax)){
a.xmax = b.limit.xmax
}
if(Number(b.limit.ymax) > Number(a.ymax)){
a.ymax = b.limit.ymax
}
return a
},{
xmin: item.limit.xmin,
ymin: item.limit.ymin,
xmax: item.limit.xmax,
ymax: item.limit.ymax
}))
}
}
})
}
return indexes
}
function searchFont(l ,arr, i, ret, type){
if(arr[i+1]){
var len = Math.abs(l[type] - arr[i+1][type])
if(len <= 1.5){
ret.push(arr[i+1])
return searchFont(arr[i+1], arr, i+1, ret, type)
} else {return i}
}
return i+1
}
function turnFix(data) {
return parseFloat(data).toFixed(2)
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment