PageSourceSearch

https://www.shfe.com.cn/images/common_utils.js

js shfe.com.cn collected 2026-10-02 07:02:08 UTC 23,274 bytes, 771 lines download raw bytes

1/*
2 * @Description:
3 * @Author: [email protected]
4 * @Date: 2023-08-23 15:13:01
5 */
6
7//  重写 toFixed方法
8Number.prototype.toFixed = function (d) {
9  var s1 = this + '';
10  if (!d) {
11    d = 0;
12  }
13  if (s1.indexOf('.') == -1) {
14    s1 += '.';
15  }
16  s1 += new Array(d + 1).join('0');
17  if (new RegExp('^(-|\\+)?(\\d+(\\.\\d{0,' + (d + 1) + '})?)\\d*$').test(s1)) {
18    var s = '0' + RegExp.$2,
19      pm = RegExp.$1,
20      a = RegExp.$3.length,
21      b = true;
22    if (a == d + 2) {
23      a = s.match(/\d/g);
24      if (parseInt(a[a.length - 1]) > 4) {
25        for (var i = a.length - 2; i >= 0; i--) {
26          a[i] = parseInt(a[i]) + 1;
27          if (a[i] == 10) {
28            a[i] = 0;
29            b = i != 1;
30          } else {
31            break;
32          }
33        }
34      }
35      s = a.join('').replace(new RegExp('(\\d+)(\\d{' + d + '})\\d$'), '$1.$2');
36    }
37    if (b) {
38      s = s.substr(1);
39    }
40    return (pm + s).replace(/\.$/, '');
41  }
42  return this + '';
43};
44
45
46// 针对公共的产品配置,缓存的日期与现在日期比较,如果相差大于一天,更新缓存
47let expose_pro_data = JSON.parse(sessionStorage.getItem('pro_config'));
48let past_date = JSON.parse(sessionStorage.getItem('config_date')); //上一次缓存记录的时间
49var nowTime = moment().format('YYYYMMDD');
50if (!expose_pro_data) {
51  requestProduct_config();
52  expose_pro_data = JSON.parse(sessionStorage.getItem('pro_config'));
53} else {
54  if (nowTime - past_date >= 1) {
55    requestProduct_config();
56    expose_pro_data = JSON.parse(sessionStorage.getItem('pro_config'));
57  }
58}
59
60// 针对公共的web_config.dat文件进行缓存,缓存的日期与现在日期比较,如果相差大于一天,更新缓存
61let expose_web_data = JSON.parse(sessionStorage.getItem('web_config_json'));
62if (!expose_web_data) {
63  requestWeb_config();
64  expose_web_data = JSON.parse(sessionStorage.getItem('web_config_json'));
65} else {
66  if (nowTime - past_date >= 1) {
67    requestWeb_config();
68    expose_web_data = JSON.parse(sessionStorage.getItem('web_config_json'));
69  }
70}
71
72
73
74let report_config_json = JSON.parse(sessionStorage.getItem('report_config_cn'));
75let report_config_json_en = JSON.parse(sessionStorage.getItem('report_config_en'));
76window.language_type = enumObj.language.cn;
77if ((language_type === enumObj.language.en && !report_config_json_en) || (language_type === enumObj.language.cn && !report_config_json)) {
78  handleConfigStorage(window.language_type);
79}
80
81// 处理报表备注缓存,切换中英文
82function handleConfigStorage(language) {
83  if (language === enumObj.language.en) {
84    // 英文
85    if (!report_config_json_en) {
86      queryReportMemo(language);
87    } else {
88      if (nowTime - past_date >= 1) {
89        queryReportMemo(language);
90      }
91    }
92  } else {
93    // 中文
94    if (!report_config_json) {
95      queryReportMemo(language);
96    } else {
97      if (nowTime - past_date >= 1) {
98        queryReportMemo(language);
99      }
100    }
101  }
102}
103
104/**
105 * 备注请求
106 * @param {*} language  语言对应的值 例如:cn、en, 默认cn
107 */
108function queryReportMemo(language) {
109  $.ajax({
110    url: api_shfe_report_config(language),
111    dataType: 'json',
112    async: false,
113    success: function (json) {
114      if (language === enumObj.language.en) {
115        // 英文
116        sessionStorage.setItem('report_config_en', JSON.stringify(json));
117        sessionStorage.setItem('config_date', moment().format('YYYYMMDD'));
118        report_config_json_en = JSON.parse(sessionStorage.getItem('report_config_en'));
119      } else {
120        // 中文
121        sessionStorage.setItem('report_config_cn', JSON.stringify(json));
122        sessionStorage.setItem('config_date', moment().format('YYYYMMDD'));
123        report_config_json = JSON.parse(sessionStorage.getItem('report_config_cn'));
124      }
125
126    },
127    error: function () {}
128  });
129}
130
131
132
133/**
134 *
135 * @param {} json 产品配置文件读取
136 * @returns
137 */
138function requestProduct_config() {
139  $.ajax({
140    url: api_shfe_product_config(),
141    dataType: 'json',
142    async: false,
143    success: function (json) {
144      const pro_json = JSON.parse(JSON.stringify(json));
145      // 添加productid_class字段: 例:productid:ag_f
146      Object.keys(json).forEach(item => {
147        pro_json[item].productid = item;
148      });
149      sessionStorage.setItem('pro_config', JSON.stringify(pro_json));
150      sessionStorage.setItem('config_date', moment().format('YYYYMMDD'));
151    },
152    error: function () {}
153  });
154}
155
156requestWeb_config();
157
158/**
159 *
160 * @param {} json web_config配置文件读取
161 * @returns
162 */
163function requestWeb_config() {
164  $.ajax({
165    url: api_shfe_web_config(),
166    dataType: 'json',
167    async: false,
168    success: function (json) {
169      const web_config_json = JSON.parse(JSON.stringify(json));
170      // 将单位做处理
171      let weightunit_cn = json.weightunit_cn.split(',').map(item => {
172        return item.split('|')[1];
173      })
174      let weightunit_en = json.weightunit_en.split(',').map(item => {
175        return item.split('|')[1];
176      })
177      let weightunits_en = json.weightunits_en.split(',').map(item => {
178        return item.split('|')[1];
179      })
180      let currency_cn = json.currency_cn.split(',').map(item => {
181        return item.split('|')[1];
182      })
183      let currency_en = json.currency_en.split(',').map(item => {
184        return item.split('|')[1];
185      })
186      web_config_json.weightunit_cn = weightunit_cn;
187      web_config_json.weightunit_en = weightunit_en;
188      web_config_json.weightunits_en = weightunits_en;
189      web_config_json.currency_cn = currency_cn;
190      web_config_json.currency_en = currency_en;
191      sessionStorage.setItem('web_config_json', JSON.stringify(web_config_json));
192    },
193    error: function () {}
194  });
195}
196
197
198/**
199 * @description 获取具体的web_config对应的值
200 * @param {*} key 属性值 例:weightunit_cn
201 */
202
203function getWebConfigPropValue(key) {
204  let value = expose_web_data[key] ? expose_web_data[key] : '';
205  return value ? value : '';
206}
207
208
209
210
211/**
212 * @description 获取品种属性
213 * @param {*} productid 产品id, 例:cu_f
214 * @param {*} propkey 产品对应的属性 例:decimal_number
215 */
216function getProductProp(productid, propkey) {
217  let value = expose_pro_data[productid] ? expose_pro_data[productid][propkey] : '';
218  return value ? value : '';
219}
220
221/**
222 * @description 通过品种组代码获取productid
223 * @param {*} productgroupid 品种组代码, 例:cu
224 * @param {*} productclass // 用于区分期货/期权  1 ==> 期货  2 ==> 期权
225 * @return 例: cu_f
226 */
227function getProductByGroup(productgroupid, productclass) {
228  let str = productgroupid.trim();
229  if( str.includes('_') ) {
230    return str
231  } else {
232    str = str + (productclass === enumObj.productclass._f ? enumObj.productclass_f : enumObj.productclass_o);
233    return str;
234  }
235}
236
237
238
239/**
240 * @description 通过合约代码获取productid
241 * @param {*} instrumentid: 合约代码 例:cu1203、cu1203C45000
242 */
243function getProductGroupIDByInstr(instrumentid) {
244  let reg = /[0-9]/;
245  if( reg.test(instrumentid)) {
246    return  instrumentid.substring(0, instrumentid.match(/[0-9]/).index);
247  } else {
248    return instrumentid;
249  }
250}
251
252
253
254/**
255 * @description 获取table的备注
256 * @param {*} reportid 报告分类 例如:shfe_kx
257 * @param {*} propkey  对应的属性 例如:report_1_note_total
258 * @param {*} querydate 查询日期 例如:20230628
259 * @param {*} language 语言 例如:cn、en
260 */
261function getReportMemo(reportid, propkey, querydate, language) {
262  let today_data = [];
263  if (language === enumObj.language.en) {
264    if (!(report_config_json_en[reportid] && report_config_json_en[reportid][propkey])) {
265      return {}
266    }
267    report_config_json_en[reportid][propkey].forEach(item => {
268      if ( item && (querydate >= item.begineffectivedate || !item.begineffectivedate) &&
269        (querydate < item.endeffectivedate || !item.endeffectivedate)) {
270        today_data.push(item);
271      }
272    });
273  } else {
274    if (!(report_config_json[reportid] && report_config_json[reportid][propkey])) {
275      return {}
276    }
277    report_config_json[reportid][propkey].forEach(item => {
278      if ( item && (querydate >= item.begineffectivedate || !item.begineffectivedate) &&
279        (querydate < item.endeffectivedate || !item.endeffectivedate)) {
280        today_data.push(item);
281      }
282    });
283  }
284
285  return today_data.length ? today_data[today_data.length - 1] : {};
286}
287
288
289
290/**
291 * @description 获取报表备注的单双边对应的值
292 * @param {*} reportid 报告分类 例如:shfe_kx
293 * @param {*} propkey  对应的属性 例如:'singlenote'
294 */
295
296function getReportSingleDoubleMemo(reportid, propkey) {
297  let obj_report_info = {};
298  if(  report_config_json[reportid][propkey] ) {
299    for(let index= 0; index < report_config_json[reportid][propkey].length; index++ ) {
300      if(  report_config_json[reportid][propkey][index] ) {
301        obj_report_info =  report_config_json[reportid][propkey][index] 
302        break;
303      }
304    }
305  }
306  return obj_report_info;
307}
308
309
310/**
311 * @description 获取品种列表,用于查询
312 * @param {*} exchangegroupid // 用于区分上期、能源 例如 'shfe', 'ine'
313 * @param {*} productclass // 用于区分期货/期权  1 ==> 期货  2 ==> 期权
314 */
315
316function getProductList(exchangegroupid, productclass) {
317  let pro_list_query = {
318    name: [],
319    list: []
320  }; // 记录希望的得到结果
321  let json_data = JSON.parse(JSON.stringify(expose_pro_data));
322
323  if (exchangegroupid === 'ine') {
324    // 针对上期和能源区分做的筛选
325    Object.keys(expose_pro_data).forEach(item => {
326      if (expose_pro_data[item].exchangegroupid !== exchangegroupid) {
327        delete json_data[item];
328      }
329    });
330  }
331  let pro_cate_name = []; // 记录金属等大类品种名字
332  let pro_cate = []; // 记录具体的品种
333  Object.values(json_data).forEach(item => {
334    if (item.productclass == productclass) {
335      pro_cate.push(item);
336      pro_cate_name.push({
337        name: item.product_type_cn,
338        sort_type: item.product_type_sort_cn
339      });
340    }
341  });
342  const uniqueCateList = pro_cate_name.filter((item, index) =>
343    pro_cate_name.findIndex(i => i.name === item.name) === index);
344  setArraySort(uniqueCateList, 'sort_type'); // 针对大类进行排序
345  pro_list_query.name = uniqueCateList;
346
347  //  针对品种进行分组
348  uniqueCateList.forEach((item, index) => {
349    pro_list_query.list.push([]);
350    pro_cate.forEach(m => {
351      if (m.product_type_cn === item.name) {
352        pro_list_query.list[index].push(m);
353      }
354    });
355  });
356  // 针对品种进行排序
357  pro_list_query.list.forEach((_, index) => {
358    setArraySort(pro_list_query.list[index], 'product_sort');
359  });
360  return pro_list_query;
361}
362
363
364/**
365 * @description 获取期权品种列表默认第一项
366 * @param {*} productclass // 用于区分期货/期权  1 ==> 期货  2 ==> 期权
367 */
368function pro_default_first() {
369  let select_doc = getProductList(enumObj.originalType.shfe, '2');
370  let select_arr1 = select_doc.list[0][0].productid; // 小类 :铜
371  return select_arr1;
372}
373
374
375
376
377/**
378 * 获取网站配置信息
379 */
380function getSysConfig(exchangegroupid, propkey) {}
381
382/**
383 * @description 获取到具体某个产品需要保留的精度, 并添加对应的精度字段
384 * @param {*} list 数据 -- 可能是数组,可能是单个对象
385 * @param {*} precision_type   代表的精度字段
386 *    可为单个元素,也可为数组
387 *    如果是单个元素,统一增加字段:precision
388 *    如果是数组,增加多个字段, 字段对应的key为precision_type中的每个元素
389 *    例:decimal_number, discountrate_decimal_number,
390 *    [ decimal_number, discountrate_decimal_number ]等
391 */
392function pro_precision(list, precision_type) {
393  // 数组的情况
394  if (Array.isArray(list)) {
395    list.map(a => {
396      var str = a.PRODUCTID.trim();
397      if (expose_pro_data[str]) {
398        if (Array.isArray(precision_type)) {
399          precision_type.map(item => {
400            if (item) {
401              a[item] = expose_pro_data[str][item];
402            }
403          })
404        } else {
405          a.precision = expose_pro_data[str][precision_type];
406        }
407      }
408    });
409    return list;
410  } else {
411    // 单条数据的情况
412    var str = list.PRODUCTID && list.PRODUCTID.trim();
413    if (expose_pro_data[str]) {
414      if (Array.isArray(precision_type)) {
415        precision_type.map(item => {
416          if (item) {
417            list[item] = expose_pro_data[str][item];
418          }
419        })
420      } else {
421        list.precision = expose_pro_data[str][precision_type];
422      }
423    }
424    return list;
425  }
426}
427
428/**
429 * @description 针对数据进行精度处理
430 * @param {*} value 传进来的需要处理的值
431 * @param {*} num 保留几位小数
432 */
433function handleDataPrecision(value, num) {
434  let val = '';
435  if (value === '' || value === undefined || value === null ) {
436    return val
437  } else {
438    val = Number(value);
439  }
440
441  if (num === '' || num === undefined || num === null ) {
442    num = 0
443  }
444
445  const number = Number(num);
446  if (val && val.toString().includes('.')) {
447    return val ? val.toFixed(number) : (val === 0 ? val.toFixed(number) : '');
448  } else {
449    return val.toFixed(number);
450  }
451}
452
453// 根据对象中的某个字段进行排序 setArraySort()  compare()
454function setArraySort(c, type_text) {
455  c.sort(compare(type_text));
456  return c;
457}
458// 根据对象中的某个字段进行排序 setArraySort()  compare()
459function compare(property) {
460  return function (a, b) {
461    return a[property] - b[property];
462  };
463}
464
465/**
466 * @description 将数组中的各个对象根据指定字段去重
467 * @param {*} list 需要去重的对象数组
468 * @param {*} item 根据数组里面每一个对象指定字段进行去重
469 * @returns
470 */
471function listParamsRepeat(list, item) {
472  if (list) {
473    list.forEach(obj => {
474      obj[item] = obj[item] ? obj[item].trim() : '';
475    });
476    let list_pro_only = noRepeat(list, item);
477    return list_pro_only;
478  } else {
479    return [];
480  }
481}
482
483// 根据数组中的某个字段,针对数组进行去重操作
484function noRepeat(arr, attr) {
485  const res = new Map();
486  return arr.filter((item) => {
487    var attrItem = item[attr];
488    return !res.has(attrItem) && res.set(attrItem, 1);
489  });
490}
491
492
493
494
495// 整个页面打印 / 局部打印
496function printTable(id) {
497  if (id) {
498    // 获取打印DOM
499    let el = document.getElementById(id);
500    // 当前页面样式
501    let headDom = document.getElementsByTagName("head")[0];
502    // 创建iframe
503    let iframe = document.createElement("iframe");
504    // 设置iframe样式
505    iframe.setAttribute("id", id);
506    iframe.setAttribute("src", 'javascript:');
507    iframe.setAttribute(
508      "style",
509      "position:absolute;width:0px;height:0px;left:-500px;top:-500px;"
510    );
511    // 在页面插入iframe
512    document.body.appendChild(iframe);
513    // 获取iframe内的html
514    let doc = iframe.contentWindow.document;
515
516    // 经需要打印的DOM插入iframe
517    let printMain = document.createElement("div");
518    printMain.setAttribute("id", id);
519    printMain.innerHTML = el.innerHTML;
520    doc.body.appendChild(printMain);
521    // 设置iframe内的header,添加样式文件
522    setTimeout(() => {
523      doc.getElementsByTagName("head")[0].innerHTML = headDom.innerHTML;
524      const table = doc.querySelectorAll('.el-table__header,.el-table__body');
525      const table1 = doc.querySelectorAll('.el-table');
526      const table2 = doc.querySelectorAll('.el-table__body-wrapper');
527      for (let i = 0; i < table2.length; i++) {
528        const tableItem = table2[i];
529        tableItem.style.maxHeight = 'unset';
530      }
531      for (let i = 0; i < table1.length; i++) {
532        const tableItem = table1[i];
533        tableItem.style.maxHeight = 'unset';
534      }
535      setTimeout(() => {
536        //el-table 打印不全的问题
537        for (let i = 0; i < table.length; i++) {
538          const tableItem = table[i];
539          tableItem.style.width = '100%';
540          const child = tableItem.childNodes;
541          for (let j = 0; j < child.length; j++) {
542            const element = child[j];
543            if (element.localName == 'colgroup') {
544              element.innerHTML = '';
545            }
546          }
547        }
548        setTimeout(function () {
549          iframe.contentWindow.focus();
550          iframe.contentWindow.print();
551          // 关闭iframe
552          doc.close();
553          document.body.removeChild(iframe);
554        }, 1000);
555      }, 1000)
556    }, 0)
557  } else {
558    let allDomObj1 = $('html');
559    // 获取页面上的table
560    let tableList1 = allDomObj1.find(".el-table");
561    if( tableList1.length > 0 ) {
562      let tableList = $('#js_index').find(".el-table");
563      for (let k4 = 0; k4 < tableList.length; k4++) {
564        var table =  tableList.eq(k4);
565        let header = table.find('.el-table__header tr').clone();
566        table.find('.el-table__header').remove();
567        let body = table.find('.el-table__body');
568        let tbody = body.find('tbody');
569        tbody.prepend(header);
570      }
571      window.print(); //打印方法
572      // Print('#js_index', {
573      //   noPrint: '.noPrint'
574      // });
575    } else {
576      window.print(); //打印方法
577    }
578  }
579}
580
581
582function toPrint() {
583  Print('#out_content', {
584    noPrint: '.noPrint'
585  });
586}
587
588// 导出excell和txt
589function exportExcel(name, type, id) {
590  let domId = '#export-table'
591  if (id) {
592    domId = `#${ id }`;
593  }
594
595
596  let dimIdStr = domId + ' .el-table'
597  let dimIdStr_fixed = domId + '  .el-table .el-table__fixed'
598
599  /* 从表生成工作簿对象 */
600  var wb = ''
601
602
603
604  var hope_el_table_list = $(dimIdStr).filter( function() {
605    return $('.el-table__fixed', this).length >0;
606  })
607
608
609  let fix_dom =  $(dimIdStr_fixed);
610
611  if( fix_dom && fix_dom.length > 0 ) {
612    hope_el_table_list.each( function(index, ele) {
613      fix_dom[index].remove();
614    })
615
616    wb = XLSX.utils.table_to_book(document.querySelector(domId));
617
618    hope_el_table_list.each( function(index, ele) {
619      ele.append( fix_dom[index] )
620    })
621  } else {
622    wb = XLSX.utils.table_to_book(document.querySelector(domId), { raw: true });
623  }
624
625  /* 获取二进制字符串作为输出 */
626  var wbout;
627  if(type === 'txt'){
628    let wbout1 = XLSX.write(wb, { bookType: type, bookSST: true, type: "binary" });
629    if( wbout1.includes('"')) {
630      wbout = wbout1.replace(/"/g, '')
631    } else {
632      wbout = wbout1;
633    }
634  }else{
635    var wbout = XLSX.write(wb, { bookType: type, bookSST: true, type: "array" });
636  }
637
638  try {
639    window.saveAs(
640      //Blob 对象表示一个不可变、原始数据的类文件对象。
641      //Blob 表示的不一定是JavaScript原生格式的数据。
642      //File 接口基于Blob,继承了 blob 的功能并将其扩展使其支持用户系统上的文件。
643      //返回一个新创建的 Blob 对象,其内容由参数中给定的数组串联组成。
644      new Blob([wbout], {
645        type: type == 'txt' ? 'text/plain;charset=utf-8' : "application/octet-stream"
646      }),
647      //设置导出文件名称
648      name + "." + type
649    );
650  } catch (e) {
651    if (typeof console !== "undefined") console.log(e, wbout);
652  }
653  return wbout;
654}
655
656
657
658// 解决el-table打印对不齐的情况
659function loadTable() {
660  let html_dom = $('html');
661  console.log();
662  let allDomObj = html_dom.clone();
663  // 获取页面上的table
664  let tableList = allDomObj.find(".el-table");
665  for (let i = 0; i < tableList.length; i++) {
666    var table = tableList.eq(i);
667    let header = table.find('.el-table__header tr').clone();
668    table.find('.el-table__header').remove();
669    let body = table.find('.el-table__body');
670    let tbody = body.find('tbody');
671    // header.find('tr,td,th,div,style,span').removeAttr('class').removeAttr('style');
672    // tbody.find('tr,td,th,div,style,span').removeAttr('class').removeAttr('style');
673    // tbody.find('span').each(function(e){
674    //   let $this = $(e);
675    //   $this.closest('td').html($this.html());
676    // });
677    // tbody.find('div').each(function(e){
678    //   let $this = $(e);
679    //   $this.closest('td').html($this.html());
680    // });
681    // body.width(1700).attr('border', 0);
682    tbody.prepend(header);
683  }
684  tableList.find('colgroup,.hidden-columns,.el-table__header-wrapper,.el-table__column-resize-proxy,.gutter,.el-scrollbar__thumb,.el-scrollbar__bar,.el-table__border-left-patch').remove();
685  
686  let iframe = $("<iframe></iframe>");
687  iframe.css( {
688    'position':'absolute',
689    'width':'0px',
690    'height':'0px',
691    'left':'-500px',
692    'top':'-500px',
693  } )
694  // 设置iframe样式
695  // iframe.setAttribute("id", id)
696
697  iframe.attr('srcdoc', allDomObj[0].outerHTML)
698
699  // 在页面插入iframe
700  $('body').append( iframe[0] )
701  // document.body.appendChild(iframe);
702
703  // 获取iframe内的html
704  let doc = iframe[0].contentWindow.document;
705  // iframe.srcdoc = allDomObj.outerHTML;
706  setTimeout(function () {
707    iframe[0].contentWindow.focus();
708    iframe[0].contentWindow.print();
709    // 关闭iframe
710    doc.close();
711    $('body').remove( iframe[0] )
712    // document.body.removeChild(iframe);
713  }, 1000);
714}
715
716
717
718//  计算两个日期之间的所有日期
719function enumerateDaysBetweenDates(startDate, endDate) { // 假定你已经保证了startDate 小于endDate,且二者不相等
720  let daysList = [];
721  let SDate = moment(startDate);
722  let EDate = moment(endDate);
723  let xt;
724  daysList.push(SDate.format("YYYYMMDD"));
725  while (SDate.add(1, "days").isBefore(EDate)) { // 注意这里add方法处理后SDate对象已经改变。
726    daysList.push(SDate.format("YYYYMMDD"));
727  }
728  daysList.push(EDate.format("YYYYMMDD"));
729  return daysList;
730}
731
732// 针对浏览器url携带的参数进行解析
733function pro_analysisUrl() {
734  //console.log(window.location.href);
735
736  var url = window.location.href.includes("?")
737    ? window.location.href.split("?")[1]
738    : ""; //截取?后面的内容
739
740  if (url == "") {
741    return '';
742  }
743
744  var paramsArr = url.split("&"); //第一次分割
745
746  var paramsObj = {};
747
748  for (var i = 0; i < paramsArr.length; i++) {
749    var combina = paramsArr[i].split("="); //第二次分割
750
751    paramsObj[combina[0]] = combina[1];
752  }
753
754  if (paramsObj.query_options) {
755    return paramsObj.query_options;
756  } else {
757    return ''
758  }
759}
760/**
761 * @description 通过套利合约代码获取productid
762 * @param {*} spreadInstrumentID: 套利合约代码 例:cu1203-luu1203 返回[cu,luu]
763 */
764function getProductGroupIDBySpreadInstr(sid) {
765  let reg = /[a-zA-Z]+/g;
766 let  arrproducts=sid.match(reg)
767  return arrproducts
768}
769
770
771

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.