@bit-sun/business-component 4.0.13-alpha.2 → 4.0.13-alpha.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bit-sun/business-component",
3
- "version": "4.0.13-alpha.2",
3
+ "version": "4.0.13-alpha.21",
4
4
  "scripts": {
5
5
  "start": "dumi dev",
6
6
  "docs:build": "dumi build",
@@ -53,6 +53,7 @@
53
53
  "querystring": "^0.2.1",
54
54
  "react": "^16.12.0",
55
55
  "react-beautiful-dnd": "10.0.0",
56
+ "react-dom": "^16.12.0",
56
57
  "react-resizable": "^3.0.4",
57
58
  "react-sortable-hoc": "^2.0.0",
58
59
  "serialize-javascript": "^6.0.0",
@@ -370,7 +370,7 @@ export default (props: any) => {
370
370
  }
371
371
  });
372
372
  }
373
- handleBssulaColumnsSpecialParams(d);
373
+ // handleBssulaColumnsSpecialParams(d);
374
374
  });
375
375
  setCommonRenderFn(props.columns);
376
376
  const authButton = localStorage.getItem(getMenuAuthDataKey())
@@ -405,7 +405,7 @@ export default (props: any) => {
405
405
 
406
406
  showColumns.forEach((item, index) => {
407
407
  item.width = item.width || getItemDefaultWidth(item);
408
- handleBssulaColumnsSpecialParams(item);
408
+ // handleBssulaColumnsSpecialParams(item);
409
409
  item.onHeaderCell = (column) => ({
410
410
  ...item,
411
411
  width:
@@ -429,7 +429,7 @@ export default (props: any) => {
429
429
 
430
430
  showExportColumns.forEach((item, index) => {
431
431
  item.width = item.width || getItemDefaultWidth(item);
432
- handleBssulaColumnsSpecialParams(item);
432
+ // handleBssulaColumnsSpecialParams(item);
433
433
  item.onHeaderCell = (column) => ({
434
434
  ...item,
435
435
  width:
@@ -715,9 +715,9 @@ export default (props: any) => {
715
715
  ...newColumns[index],
716
716
  width: size.width,
717
717
  };
718
- newColumns.forEach((d: any) => {
719
- handleBssulaColumnsSpecialParams(d);
720
- });
718
+ // newColumns.forEach((d: any) => {
719
+ // handleBssulaColumnsSpecialParams(d);
720
+ // });
721
721
  return [...newColumns];
722
722
  });
723
723
  };
@@ -711,7 +711,7 @@ class SortableTable extends React.Component {
711
711
  <div className={'sort_table_wrapper'}>
712
712
  {visible && (
713
713
  <Modal
714
- title="筛选条件设置"
714
+ title="展示列设置"
715
715
  wrapClassName={'sort_table_wrapper'}
716
716
  width={810}
717
717
  visible={visible}
@@ -748,7 +748,7 @@ class SortableTable extends React.Component {
748
748
  <div className={'sort_table'}>
749
749
  <div className={'sort_table_column_wrapper'}>
750
750
  <span className={'sort_table_column_count'}>
751
- <span>勾选你想使用的筛选条件</span>
751
+ <span>勾选你想展示的表格列</span>
752
752
  </span>
753
753
  <div className={'sort_table_column'}>
754
754
  <Input
@@ -882,7 +882,7 @@ class SortableTable extends React.Component {
882
882
  </div>
883
883
  <div className={'sort_table_content_wrapper'}>
884
884
  <span className={'sort_table_content_count'}>
885
- <span>已选择的搜索条件排序</span>
885
+ <span>已选择的展示列排序</span>
886
886
  </span>
887
887
  <div className={'sort_table_content'}>
888
888
  <span style={{ paddingLeft: '10px' }}>
@@ -1,5 +1,6 @@
1
1
  // @ts-nocheck
2
2
  import React, { useState } from 'react';
3
+ import * as ReactDOMServer from 'react-dom/server';
3
4
  import {
4
5
  Tooltip,
5
6
  Badge,
@@ -30,7 +31,6 @@ import { getMenuAuthDataKey } from '@/utils/LocalstorageUtils';
30
31
  import noImg from '../../../assets/list-no-img.svg';
31
32
  import qs from 'qs';
32
33
  import { shouldUseAuth } from '@/utils';
33
- import * as ReactDOMServer from 'react-dom/server';
34
34
 
35
35
 
36
36
  export const handleStatusBadge = (text: any, color: any) => {
@@ -723,6 +723,7 @@ export const authFn = (code?: any) => {
723
723
  export const renderToString = (
724
724
  render: ReactElement<any, string | JSXElementConstructor<any>> | string,
725
725
  ) => {
726
+ // return render;
726
727
  return typeof render === 'string'
727
728
  ? render
728
729
  : ReactDOMServer.renderToString(render);
@@ -34,16 +34,18 @@ const CommodityEntry = (props: any) => {
34
34
 
35
35
  const handleOk = () => {
36
36
  // 方法获取当前组件内部的数据,然后进行自身的业务操作
37
- const resultData = dataValidationRef.current?.getValidateData();
37
+ let resultData = props?.notValid ? dataValidationRef.current?.getData() : dataValidationRef.current?.getValidateData();
38
38
 
39
- if (!resultData.successData.length) {
40
- message.error("无校验通过数据,请校验数据");
41
- return;
42
- }
43
-
44
- if (resultData.failData.length) {
45
- message.error(`有${resultData.failData.length}条校验失败数据`);
46
- return;
39
+ if(!(!!props?.notValid)) {
40
+ if (!resultData.successData.length) {
41
+ message.error("无校验通过数据,请校验数据");
42
+ return;
43
+ }
44
+
45
+ if (resultData.failData.length) {
46
+ message.error(`有${resultData.failData.length}条校验失败数据`);
47
+ return;
48
+ }
47
49
  }
48
50
 
49
51
  callbackHandleOk(resultData, () => {
@@ -100,7 +100,9 @@ export const getMainCrumbNameMap = (menuData) => {
100
100
  };
101
101
  });
102
102
  };
103
- flattenMenuData(menuData, {});
103
+ const newList = (window.top||window)?.applicationList?.filter?.((app: any) => app.code === menuData?.[0]?.belongAppCode) || [];
104
+ const appChannelParent = newList.length > 0 ? { nameMap: [newList[0].name]} : {};
105
+ flattenMenuData(menuData,appChannelParent);
104
106
  return routerMap;
105
107
  }
106
108
 
@@ -1,5 +1,5 @@
1
1
  .bs_home_page_head_wrapper{
2
- height: 32px;
2
+ // 如果设置高度 需要考虑列表页引用有传提示参数alertProps情况,写死固定高度会导致提示遮挡筛选条件
3
3
  position: sticky;
4
4
  background: #fff;
5
5
  width: 100%;
@@ -0,0 +1,88 @@
1
+ // @ts-nocheck
2
+
3
+ import React, { useState, useEffect } from 'react';
4
+ import { Input, Select } from 'antd';
5
+ import { request } from 'bssula';
6
+
7
+ const ItemPropertySelector = ({
8
+ onChange,
9
+ value,
10
+ propertyCode,
11
+ name,
12
+ ...restProps
13
+ }: any) => {
14
+
15
+ const [source, setSource] = useState([]);
16
+
17
+ useEffect(() => {
18
+ // FIXME: 目前只能通过固定属性编码先获取属性id,再通过属性id去查属性值 @林军
19
+ if (propertyCode) {
20
+ request({
21
+ url: `/items/item/propertyValue/getPropertyValueNoPagerByCode?qp-propertyCode-eq=${propertyCode}&pageSize=5000`,
22
+ method: 'GET',
23
+ converter: ({ data }: any) => {
24
+ const source = (data?.items || []).map(item => ({
25
+ text: item.value,
26
+ value: item.value
27
+ }))
28
+ setSource(source);
29
+ }
30
+ })
31
+ return;
32
+ request({
33
+ url: `/items/item/property?qp-propertyCode-eq=${propertyCode}`,
34
+ metod: 'GET',
35
+ converter: ({ data }: any) => {
36
+ let propInfo = data?.items?.[0] || {};
37
+ if (propInfo?.dictIs) {
38
+ request({
39
+ url: `/items/bscDict/detailAndFilter/${propInfo?.dictCode}`,
40
+ method: 'GET',
41
+ converter: ({ data }: any) => {
42
+ const source = (data?.dictItemResVoList || []).map(item => ({
43
+ text: item.dictItemName,
44
+ value: item.dictItemName
45
+ }))
46
+ setSource(source);
47
+ }
48
+ })
49
+ return;
50
+ }
51
+
52
+ if (propInfo?.id) {
53
+ request({
54
+ url: `/items/item/propertyValue?qp-propertyId-eq=${propInfo?.id}`,
55
+ method: 'GET',
56
+ converter: ({ data }: any) => {
57
+ const source = (data?.items || []).map(item => ({
58
+ text: item.value,
59
+ value: item.value
60
+ }))
61
+ setSource(source);
62
+ }
63
+ })
64
+ }
65
+ }
66
+ })
67
+ }
68
+ }, [propertyCode]);
69
+
70
+
71
+ return (
72
+ <Select
73
+ {...restProps}
74
+ value={value}
75
+ allowClear
76
+ style={{width: '100%'}}
77
+ onChange={(v: any) => {
78
+ onChange(v);
79
+ }}
80
+ >
81
+ {source.map((res) => {
82
+ return <Select.Option value={res.value}>{res.text}</Select.Option>;
83
+ })}
84
+ </Select>
85
+ );
86
+ };
87
+
88
+ export default ItemPropertySelector;
@@ -342,6 +342,7 @@ export function commonFun (type?: string, prefixUrl: any, parentProps?:any) {
342
342
  specialBracket: true,
343
343
  otherParams: {
344
344
  'ownOrgSign': getCurrentTargetBgId(),
345
+ 'ctl-count': true
345
346
  }, // 默认参数
346
347
  },
347
348
  }
@@ -360,6 +361,10 @@ export function commonFun (type?: string, prefixUrl: any, parentProps?:any) {
360
361
  mappingValueField: 'itemCode',
361
362
  sourceName: 'qp-itemCode-in',
362
363
  specialBracket: true,
364
+ otherParams: {
365
+ 'ownOrgSign': getCurrentTargetBgId(),
366
+ 'ctl-count': true
367
+ }, // 默认参数
363
368
  },
364
369
  }
365
370
  } },
@@ -489,6 +494,142 @@ export function commonFun (type?: string, prefixUrl: any, parentProps?:any) {
489
494
 
490
495
  // 商品选择器spu
491
496
  if(type === 'spuCommodity') {
497
+ selectProps = {
498
+ placeholder: '输入商品(SPU)编码或名称',
499
+ renderTableColumns: [
500
+ {
501
+ title: '商品编码(SPU)',
502
+ dataIndex: 'itemCode',
503
+ },
504
+ {
505
+ title: '商品名称(SPU)',
506
+ dataIndex: 'name',
507
+ },
508
+ ],
509
+ ...selectConfigProps,
510
+ }
511
+ requestConfig = {
512
+ url: `${prefixUrl.selectPrefix}/item`,
513
+ filter: 'qp-itemCode,name-orGroup,like', // 过滤参数
514
+ mappingTextField: 'name',
515
+ mappingValueField: 'itemCode',
516
+ otherParams: {
517
+ 'qp-approveStatus-eq': 1, // 审核状态(0.待审批;1.审批通过;2.驳回;3.审批未通过)
518
+ sorter: 'desc-id',
519
+ ...(requestConfigProp?.addOtherParams || {}),
520
+ }, // 默认参数
521
+ sourceName: 'itemCode',
522
+ ...requestConfigProp,
523
+ }
524
+ tableSearchForm = [
525
+ { name: 'qp-name-like', label: '商品名称(SPU)' },
526
+ { name: 'qp-itemCode-like', label: '商品编码(SPU)' },
527
+ { name: 'qp-brandId-in', type: 'select', label: '品牌', field: {
528
+ type: 'select',
529
+ props: {
530
+ mode: 'multiple',
531
+ notFoundContent: '暂无数据',
532
+ allowClear: true,
533
+ showSearch: true,
534
+ showArrow: true,
535
+ maxTagCount: 1,
536
+ optionFilterProp: 'children',
537
+ filterOption: (input: string, option: { props: { children: string } }) =>
538
+ option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0,
539
+ },
540
+ } },
541
+ { name: 'qp-categoryId-in', type: 'treeSelect', label: '类目', field: {
542
+ type: 'treeSelect',
543
+ props: {
544
+ treeData: [],
545
+ treeCheckable: true,
546
+ showSearch: true,
547
+ allowClear: true,
548
+ showArrow: true,
549
+ treeNodeFilterProp: 'title',
550
+ treeDefaultExpandAll: true,
551
+ maxTagCount: 1,
552
+ placeholder: '请选择',
553
+ style: {
554
+ width: '100%',
555
+ },
556
+ dropdownStyle: { maxHeight: 400, maxWidth: 100, overflow: 'auto' }
557
+ },
558
+ } },
559
+ { name: 'qp-classId-in', type: 'select', label: '品类', field: {
560
+ type: 'select',
561
+ props: {
562
+ mode: 'multiple',
563
+ notFoundContent: '暂无数据',
564
+ allowClear: true,
565
+ showSearch: true,
566
+ showArrow: true,
567
+ maxTagCount: 1,
568
+ optionFilterProp: 'children',
569
+ filterOption: (input: string, option: { props: { children: string } }) =>
570
+ option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0,
571
+ },
572
+ } },
573
+ ]
574
+ Promise.all([
575
+ loadSelectSource(`${prefixUrl.formSelectFix}/brand/queryBrandList`, {
576
+ pageSize: 5000,
577
+ currentPage: 1,
578
+ 'ctl-withAuth': true
579
+ }),
580
+ loadSelectSource(`${prefixUrl.formSelectFix}/category/queryCategoryTree`, {
581
+ pageSize: 5000,
582
+ currentPage: 1,
583
+ }),
584
+ loadSelectSource(`${prefixUrl.formSelectFix}/class/withProperty`, {
585
+ pageSize: 5000,
586
+ currentPage: 1,
587
+ }),
588
+ ]).then((x: any)=>{
589
+ formatSource(x,0, 2, tableSearchForm,['id','name']);
590
+ formatTreeDataSource(x,1, 3, tableSearchForm);
591
+ formatSource(x,2, 4, tableSearchForm,['id','name']);
592
+ })
593
+ modalTableProps = {
594
+ modalTableTitle: '选择商品(SPU) ',
595
+ tableSearchForm,
596
+ tableColumns: [
597
+ {
598
+ title: '序号',
599
+ dataIndex: 'keyIndex',
600
+ defaultSort: 0,
601
+ },
602
+ {
603
+ title: '商品编码(SPU)',
604
+ dataIndex: 'itemCode',
605
+ defaultSort: 1,
606
+ },
607
+ {
608
+ title: '商品名称(SPU) ',
609
+ dataIndex: 'name',
610
+ defaultSort: 2,
611
+ },
612
+ {
613
+ title: '品牌',
614
+ dataIndex: 'brandName',
615
+ defaultSort: 3,
616
+ },
617
+ {
618
+ title: '类目',
619
+ dataIndex: 'categoryText',
620
+ defaultSort: 4,
621
+ },
622
+ {
623
+ title: '品类',
624
+ dataIndex: 'className',
625
+ },
626
+ ],
627
+ ...modalTableBusProps
628
+ }
629
+ }
630
+
631
+ // 新库存商品选择器spu
632
+ if(type === 'spuCommodityWithProperty') {
492
633
  selectProps = {
493
634
  placeholder: '输入spu编码或名称',
494
635
  renderTableColumns: [
@@ -504,12 +645,13 @@ export function commonFun (type?: string, prefixUrl: any, parentProps?:any) {
504
645
  ...selectConfigProps,
505
646
  }
506
647
  requestConfig = {
507
- url: `${prefixUrl.selectPrefix}/item`,
648
+ url: `/stock/item/doItemPageAll`,
649
+ method: 'POST',
508
650
  filter: 'qp-itemCode,name-orGroup,like', // 过滤参数
509
651
  mappingTextField: 'name',
510
652
  mappingValueField: 'itemCode',
511
653
  otherParams: {
512
- 'qp-approveStatus-eq': 1, // 审核状态(0.待审批;1.审批通过;2.驳回;3.审批未通过)
654
+ // 'qp-approveStatus-eq': 1, // 审核状态(0.待审批;1.审批通过;2.驳回;3.审批未通过)
513
655
  sorter: 'desc-id',
514
656
  ...(requestConfigProp?.addOtherParams || {}),
515
657
  }, // 默认参数
@@ -565,6 +707,61 @@ export function commonFun (type?: string, prefixUrl: any, parentProps?:any) {
565
707
  option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0,
566
708
  },
567
709
  } },
710
+ {
711
+ name: 'qp-year-in',
712
+ label: '年份',
713
+ field: {
714
+ type: 'itemPropertySelector',
715
+ props: {
716
+ propertyCode: 'SX0000114',
717
+ mode: 'multiple',
718
+ }
719
+ }
720
+ },
721
+ {
722
+ name: 'qp-season-in',
723
+ label: '季节',
724
+ field: {
725
+ type: 'itemPropertySelector',
726
+ props: {
727
+ propertyCode: 'SX0000070',
728
+ mode: 'multiple',
729
+ }
730
+ }
731
+ },
732
+ {
733
+ name: 'qp-zzdlbm-in',
734
+ label: '大类',
735
+ field: {
736
+ type: 'itemPropertySelector',
737
+ props: {
738
+ propertyCode: 'SX0000071',
739
+ mode: 'multiple',
740
+ }
741
+ }
742
+ },
743
+ {
744
+ name: 'qp-zzzlbm-in',
745
+ label: '中类',
746
+ field: {
747
+ type: 'itemPropertySelector',
748
+ props: {
749
+ propertyCode: 'SX0000072',
750
+ mode: 'multiple',
751
+ }
752
+ }
753
+ },
754
+ {
755
+ name: 'qp-zzxlbm-in',
756
+ label: '小类',
757
+ field: {
758
+ type: 'itemPropertySelector',
759
+ props: {
760
+ propertyCode: 'SX0000110',
761
+ mode: 'multiple',
762
+ }
763
+ }
764
+ },
568
765
  ]
569
766
  Promise.all([
570
767
  loadSelectSource(`${prefixUrl.formSelectFix}/brand/queryBrandList`, {
@@ -619,6 +816,7 @@ export function commonFun (type?: string, prefixUrl: any, parentProps?:any) {
619
816
  dataIndex: 'className',
620
817
  },
621
818
  ],
819
+ noEmptySearchField: true,
622
820
  ...modalTableBusProps
623
821
  }
624
822
  }
@@ -54,7 +54,7 @@ export default () => {
54
54
  setValue(value)
55
55
  },
56
56
  selectBusinessType: 'supplier',
57
- disabled: true,
57
+ // disabled: true,
58
58
  };
59
59
 
60
60
  const props2 = {
@@ -297,7 +297,7 @@ import {BusinessSearchSelect} from '../../../index.ts';
297
297
  const { TabPane } = Tabs;
298
298
  export default () => {
299
299
  const selectProps = {
300
- // mode: 'multiple',
300
+ mode: 'multiple',
301
301
  // maxTagCount: 1,
302
302
  // disabled: true
303
303
  }
@@ -317,7 +317,7 @@ export default () => {
317
317
  },
318
318
  // prefixUrl: { selectPrefix: '/bop/api', formSelectFix: '/bop/api' },
319
319
  selectProps,
320
- selectBusinessType: 'spuCommodity',
320
+ selectBusinessType: 'spuCommodityWithProperty',
321
321
  };
322
322
 
323
323
  const onTabChange = (key) => {
@@ -79,7 +79,7 @@ const handleDefaultPrefixUrl = (type: string) => {
79
79
  case 'supplier2': case 'customer2': case 'shopFile2': case 'platCompany': case 'market-channel':
80
80
  result = '/channel-manage';
81
81
  break;
82
- case 'skuCommodity': case 'skuPropertyValue': case 'spuCommodity': case 'skcCommodity': case 'brand':
82
+ case 'skuCommodity': case 'skuPropertyValue': case 'spuCommodity': case 'skcCommodity': case 'brand': case 'spuCommodityWithProperty':
83
83
  result = '/items';
84
84
  break;
85
85
  case 'physicalWarehouse': case 'realWarehouse': case 'virtualWarehouse': case 'channelWarehouse': case 'ownerWarehouse':
@@ -940,7 +940,7 @@ const AddSelect = (props: any) => {
940
940
  </div>
941
941
  {isModalVisible && (
942
942
  <Modal
943
- width='1200px'
943
+ width={`calc(100% - 320px)`}
944
944
  style={{ top: 20 }}
945
945
  bodyStyle={{ padding: '0px' }}
946
946
  visible={isModalVisible}
@@ -9,7 +9,7 @@ title: 批量搜索查询组件
9
9
  order: 2
10
10
  ---
11
11
 
12
- ## QueryMutipleInput
12
+ ## QueryMutipleSearchSelect
13
13
 
14
14
  Demo:
15
15
 
@@ -20,8 +20,7 @@ import { QueryMutipleSearchSelect } from '../../../index';
20
20
  export default () => {
21
21
  const requestConfig = {
22
22
  url: '/items/item/listNoPage/Simple',
23
- filter: 'qp-name-like', // qp-itemCode-like
24
- // filter: 'qp-skuCode,name-orGroup,like',
23
+ filter: 'qp-itemCode,name-orGroup,like',
25
24
  mappingTextField: 'name',
26
25
  mappingValueField: 'itemCode',
27
26
  sourceName: 'qp-itemCode-in'
@@ -91,6 +91,7 @@ const QueryMutipleSearchSelect = ({ onValueChange, requestConfig={}, selectProps
91
91
  const getData = (params: any = {}, callback?: any) => {
92
92
  if (!requestConfig) return;
93
93
  if (!url) return;
94
+ if(!searchValue?.length) return; // 空值默认不查询
94
95
 
95
96
  setFetching(true)
96
97
 
@@ -167,7 +168,7 @@ const QueryMutipleSearchSelect = ({ onValueChange, requestConfig={}, selectProps
167
168
  <Spin size="small" className='searchSelectSpin' />
168
169
  ) : (
169
170
  <div style={{ textAlign: 'center' }}>
170
- <div>{searchValue?'无匹配结果,请更换其他内容再试':`请录入内容模糊查询`}</div>
171
+ <div>{searchValue?'无匹配结果,请更换其他内容再试': (selectProps?.notFoundText||`请录入编码/名称模糊查询`)}</div>
171
172
  </div>
172
173
  )
173
174
  }
@@ -73,11 +73,6 @@
73
73
  &_dropdown_table {
74
74
  // padding: 4px 10px 6px;
75
75
 
76
- // 下拉table 复选框为单选时候隐藏
77
- .ant-table-cell .ant-table-selection-column .ant-radio,table tr td.ant-table-selection-column .ant-radio-wrapper {
78
- display: none;
79
- }
80
-
81
76
  // 下拉table 表头表体样式
82
77
  .ant-table.ant-table-bordered > .ant-table-container > .ant-table-header > table {
83
78
  font-family: MiSans-Regular;
@@ -103,7 +98,18 @@
103
98
  .ant-table.ant-table-bordered > .ant-table-container {
104
99
  .ant-table-body > table > tbody > tr > td.ant-table-selection-column,
105
100
  .ant-table-header > table > thead > tr > th.ant-table-selection-column {
106
- display: none;
101
+ visibility: hidden; // 不使用 display: none; 是因为此设置不占位,会导致表格scroll.x: 'max-content' 计算不准确
102
+ padding: 0;
103
+ margin: 0;
104
+ width: 0;
105
+ height: 0;
106
+ min-width: 0;
107
+ min-height: 0;
108
+ border: none;
109
+
110
+ .ant-radio-wrapper {
111
+ display: none;
112
+ }
107
113
  }
108
114
  }
109
115
  }
@@ -243,6 +249,10 @@
243
249
  &_wrapLeft1, &_wrapLeft2, &_wrapRight{
244
250
  background: #fff;
245
251
  width: calc(50% - 5px);
252
+ // 解决全选按钮位置偏左问题
253
+ .ant-table.ant-table-bordered > .ant-table-container > .ant-table-header > table .ant-table-thead .ant-table-selection .ant-checkbox-wrapper {
254
+ justify-content: center;
255
+ }
246
256
  }
247
257
  &_wrapLeft1 {
248
258
  width: 100%;