Your Name 3 gadus atpakaļ
vecāks
revīzija
1be8528882

+ 71
- 25
src/pages/Medical/Test/Batch/Step.jsx Parādīt failu

@@ -1,19 +1,35 @@
1 1
 import React, { useState, useRef } from 'react'
2
-import { Button, Checkbox, Select, Space, Carousel, Typography } from 'antd'
2
+import { Row, Col, Button, InputNumber, Select, Carousel, Typography } from 'antd'
3 3
 import { getRangeOfSheet, getAllCols } from './excel'
4 4
 import styles from './style.less'
5 5
 
6 6
 const { Title } = Typography;
7 7
 const { Option } = Select;
8 8
 
9
+const ColSelect = (props) => {
10
+  const { value, onChange, cols } = props
11
+
12
+  return (
13
+    <Select value={value} onChange={onChange} allowClear style={{minWidth: '90%'}}>
14
+      {
15
+        cols.map((col) => (<Option key={col} value={col}>{col}</Option>))
16
+      }
17
+    </Select>
18
+  )
19
+}
20
+
9 21
 export default (props) => {
10
-  const { workbook } = props
22
+  const { workbook, onChange } = props
11 23
 
12 24
   const sliderRef = useRef()
13 25
   const [sheetName, setSheetName] = useState()
14 26
   const sheetRef = useRef()
15 27
   const [allCols, setAllCols] = useState([])
16
-  const [columns, setColumns] = useState()
28
+  const [studentNoCol, setStudentCol] = useState()
29
+  const [testNoCol, setTestCol] = useState()
30
+  const [dataStartRow, setDataStartRow] = useState(2)
31
+
32
+  const maped = studentNoCol && testNoCol && studentNoCol !== testNoCol
17 33
 
18 34
   const handleSheetSelect = (nm) => {
19 35
     setSheetName(nm)
@@ -24,39 +40,69 @@ export default (props) => {
24 40
     setAllCols(cols)
25 41
   }
26 42
 
27
-  const handleColChange = (cols) => {
28
-    setColumns(cols)
29
-  }
30
-
31 43
   const next = () => {
32 44
     sliderRef.current.next()
33 45
   }
34 46
 
47
+  const handleSubmit = () => {
48
+    onChange({
49
+      sheet: sheetRef.current,
50
+      cols: { studentNoCol, testNoCol },
51
+      dataStartRow,
52
+    })
53
+    
54
+    const t = setTimeout(() => {
55
+      // 重置所有
56
+      sliderRef.current.goTo(0, true)
57
+      setSheetName()
58
+      sheetRef.current = null
59
+      setAllCols([])
60
+      setStudentCol()
61
+      setTestCol()
62
+      setDataStartRow(2)
63
+      clearTimeout(t)
64
+    })
65
+  }
66
+
35 67
   return (
36 68
     <div>
37
-      <Carousel ref={sliderRef}>
69
+      <Carousel ref={sliderRef} style={{width: '100%'}}>
70
+        {/* 第一步 */}
38 71
         <div className={styles['step-box']}>
39
-          <Space direction="vertical" size="large" style={{width: '100%'}}>
40
-            <Title level={4}>请选择 sheet</Title>
41
-            <Select value={sheetName} onChange={handleSheetSelect}  style={{minWidth: '200px'}}>
42
-              {
43
-                (workbook.SheetNames || []).map((nm) => (<Option key={nm} value={nm}>{nm}</Option>))
44
-              }
45
-            </Select>
72
+            <Title level={5}>请选择 sheet</Title>
73
+            <div className={styles['step-content']}>
74
+              <Select value={sheetName} onChange={handleSheetSelect}  style={{minWidth: '200px'}}>
75
+                {
76
+                  (workbook.SheetNames || []).map((nm) => (<Option key={nm} value={nm}>{nm}</Option>))
77
+                }
78
+              </Select>
79
+            </div>
46 80
             <Button disabled={!sheetName} type="primary" onClick={next}>下一步</Button>
47
-          </Space>
48 81
         </div>
49 82
         
83
+        {/* 第二步 */}
84
+        <div className={styles['step-box']}>
85
+          <Title level={5}>请设置 数据映射列</Title>
86
+          <div className={styles['step-content']}>
87
+            <Row style={{padding: '.3em 0'}}>
88
+              <Col span={12}>体检号:</Col>
89
+              <Col span={12}><ColSelect cols={allCols} value={testNoCol} onChange={setTestCol} /></Col>
90
+            </Row>
91
+            <Row style={{padding: '.3em 0'}}>
92
+              <Col span={12}>学号:</Col>
93
+              <Col span={12}><ColSelect cols={allCols} value={studentNoCol} onChange={setStudentCol} /></Col>
94
+            </Row>
95
+          </div>
96
+          <Button type="primary" disabled={!maped} onClick={next}>下一步</Button>
97
+        </div>
98
+        
99
+        {/* 第三步 */}
50 100
         <div className={styles['step-box']}>
51
-          <Space direction="vertical" size="large" style={{width: '100%'}}>
52
-            <Title level={4}>请选择 数据列</Title>
53
-            <Checkbox.Group style={{ width: '100%' }} value={columns} onChange={handleColChange}>
54
-              {
55
-                allCols.map((col) => (<div key={col}><Checkbox value={col}>{col}</Checkbox></div>))
56
-              }
57
-            </Checkbox.Group>
58
-            <Button type="primary" disabled={!columns || !columns.length} onClick={next}>下一步</Button>
59
-          </Space>
101
+          <Title level={5}>请设置 数据起始行</Title>
102
+          <div className={styles['step-content']}>
103
+            <InputNumber value={dataStartRow} onChange={setDataStartRow} step={1} min={1} max={1000} />
104
+          </div>
105
+          <Button type="primary" disabled={!dataStartRow} onClick={handleSubmit}>完成</Button>
60 106
         </div>
61 107
       </Carousel>
62 108
     </div>

+ 85
- 6
src/pages/Medical/Test/Batch/index.jsx Parādīt failu

@@ -1,7 +1,7 @@
1 1
 import React, { useRef, useState } from 'react';
2 2
 import { PageContainer } from '@ant-design/pro-layout';
3
-import { Alert, Button, Card, message, Space, Modal } from 'antd';
4
-import { UploadOutlined } from '@ant-design/icons';
3
+import { Alert, Button, Card, message, Space, Modal, Table } from 'antd';
4
+import { FileExcelOutlined, SaveOutlined, FileZipOutlined } from '@ant-design/icons';
5 5
 import School from '@/components/School';
6 6
 import Step from './Step'
7 7
 import { read } from './excel'
@@ -13,6 +13,30 @@ export default (props) => {
13 13
   const [reading, setReading] = useState(false)
14 14
 
15 15
   const workbookRef = useRef()
16
+  const [dataSource, setDataSource] = useState([])
17
+  const [zipFile, setZipFile] = useState()
18
+
19
+  const columns = [
20
+    {
21
+      key: 'index',
22
+      title: '序号',
23
+      width: 200,
24
+      align: 'center',
25
+      render: (t,r,i) => i + 1,
26
+    },
27
+    {
28
+      key: 'testNo',
29
+      dataIndex: 'testNo',
30
+      title: '体检号',
31
+      align: 'center',
32
+    },
33
+    {
34
+      key: 'studentNo',
35
+      dataIndex: 'studentNo',
36
+      title: '学号',
37
+      align: 'center',
38
+    },
39
+  ]
16 40
 
17 41
   const handleFile = () => {
18 42
     const input = document.createElement('input')
@@ -37,10 +61,46 @@ export default (props) => {
37 61
     input.click()
38 62
   }
39 63
 
64
+  const handleZipFile = () => {
65
+    const input = document.createElement('input')
66
+    input.type = 'file'
67
+    input.accept = 'application/zip'
68
+    input.onchange = (e) => {
69
+      const file = e.target.files[0]
70
+      if (!file) {
71
+        message.warning('请选择文件')
72
+      }
73
+      setZipFile(file)
74
+    }
75
+    input.click()
76
+
77
+  }
78
+
79
+  const handleSettingChange = (e) => {
80
+    setVisible(false)
81
+
82
+    const { dataStartRow, sheet, cols } = e
83
+
84
+    const [, end] = sheet['!ref'].split(':')
85
+    const maxRow = /\d+/.exec(end)[0] - 0
86
+    const arr = []
87
+    for (let i = dataStartRow; i <= maxRow; i += 1) {
88
+      const testNo = sheet[`${cols.testNoCol}${i}`]?.v
89
+      const studentNo = sheet[`${cols.studentNoCol}${i}`]?.v
90
+
91
+      arr.push({
92
+        testNo,
93
+        studentNo, 
94
+      })
95
+    }
96
+
97
+    setDataSource(arr)
98
+  }
99
+
40 100
   return (
41 101
     <PageContainer>
42 102
       <Space direction="vertical" size="large" style={{width: '100%'}}>
43
-        <Alert message="友情提示" description="导入文件数据不要超过 200 列, 6000 行" type="info" closable />
103
+        <Alert message="友情提示" description="导入文件数据不要超过 200 列, 6000 行。如果出现未知错误, 请退出重试几次" type="info" closable />
44 104
         <Card>
45 105
           <Space direction="horizontal" size="large">
46 106
             <School
@@ -57,20 +117,39 @@ export default (props) => {
57 117
               type="primary"
58 118
               loading={reading}
59 119
               disabled={!schoolId}
60
-              icon={<UploadOutlined />}
120
+              icon={<FileExcelOutlined />}
61 121
               onClick={handleFile}
62
-            >导入</Button>
122
+            >上传 Excel 文件</Button>
123
+
124
+            <Button
125
+              ghost
126
+              type="primary"
127
+              disabled={!dataSource ||!dataSource.length}
128
+              icon={<FileZipOutlined />}
129
+              onClick={handleZipFile}
130
+            >上传 ZIP 文件</Button>
131
+            
132
+            <Button
133
+              type="primary"
134
+              loading={reading}
135
+              disabled={!zipFile}
136
+              icon={<SaveOutlined />}
137
+              onClick={handleFile}
138
+            >保存入库</Button>
63 139
           </Space>
64 140
         </Card>
141
+
142
+        <Table columns={columns} dataSource={dataSource} rowKey="testNo" pagination={false} />
65 143
       </Space>
66 144
       <Modal
67 145
         title="设置数据内容"
68 146
         visible={visible}
69 147
         onCancel={() => setVisible(false)}
70 148
         footer={null}
149
+        width={480}
71 150
         maskClosable={false}
72 151
       >
73
-        <Step workbook={workbookRef.current} />
152
+        <Step workbook={workbookRef.current} onChange={handleSettingChange} />
74 153
       </Modal>
75 154
     </PageContainer>
76 155
   )

+ 9
- 2
src/pages/Medical/Test/Batch/style.less Parādīt failu

@@ -1,5 +1,12 @@
1 1
 
2 2
 .step-box {
3
-  width: 800px;
4
-  min-height: 600px;
3
+  width: 100%;
4
+
5
+  .step-content {
6
+    width: 100%;
7
+    height: 240px;
8
+    margin: 2em 0;
9
+    box-sizing: border-box;
10
+    overflow-y: auto;
11
+  }
5 12
 }