ソースを参照

Merge branch 'master' of http://git.ycjcjy.com/estateagents/pc-channel

zhoulisen 5 年 前
コミット
30257c0cd2

+ 11
- 0
config/routes.js ファイルの表示

@@ -138,6 +138,17 @@ export default [
138 138
                 hideInMenu: true,
139 139
                 component: './eContract/company/edit',
140 140
               },
141
+              {
142
+                path: '/eContract/seal/list',
143
+                name: '印章管理',
144
+                component: './eContract/seal/list',
145
+              },
146
+              {
147
+                path: '/eContract/seal/detail',
148
+                name: '印章管理',
149
+                hideInMenu: true,
150
+                component: './eContract/seal/detail',
151
+              },
141 152
               {
142 153
                 path: '/eContract/relatedOrganization',
143 154
                 name: '关联组织',

+ 102
- 0
src/pages/eContract/seal/components/AddSeal.jsx ファイルの表示

@@ -0,0 +1,102 @@
1
+import React, { PureComponent, useState, useEffect } from 'react'
2
+import { Modal, Row, Col, Table, Pagination, Button, Form, Input,message, Icon, notification } from 'antd'
3
+import ImageUpload from './ImageUpload';
4
+import apis from '../../../../services/apis';
5
+import router from 'umi/router';
6
+import request from '../../../../utils/request';
7
+
8
+const AddSeal = props => {
9
+  const companyId = props.companyId
10
+  function close(e){
11
+    props.onCancel(e)
12
+  }
13
+
14
+  function handleSubmit (e) {
15
+    e.preventDefault();
16
+    props.form.validateFields((err, values) => {
17
+      if (!err){
18
+        request({ ...apis.seal.addSeal, data: { ...values, companyId: companyId },}).then((data) => {
19
+          message.info("保存成功")
20
+          props.onSuccess({visable:false, companyId: companyId});
21
+        }).catch((err) => {
22
+          message.info(err.msg || err.message)
23
+        })
24
+      }
25
+    });
26
+  }
27
+
28
+  function openNotificationWithIcon(type, message) {
29
+    notification[type]({
30
+      message,
31
+      description:
32
+        '',
33
+    });
34
+  }
35
+
36
+  function checkImageWH(file, width, height) {
37
+    let self = this;
38
+    return new Promise(function (resolve, reject) {
39
+        let filereader = new FileReader();
40
+        filereader.onload = e => {
41
+            let src = e.target.result;
42
+            const image = new Image();
43
+            image.onload = function () {
44
+                if (width && this.width != width && height && this.height != height) {
45
+                    message.error('图片尺寸不符合要求')
46
+                    reject();
47
+                } else {
48
+                    resolve();
49
+                }
50
+            };
51
+            image.onerror = reject;
52
+            image.src = src;
53
+        };
54
+        filereader.readAsDataURL(file);
55
+    });
56
+}
57
+
58
+  const handleBeforeUpload = (file) => {
59
+    //限制图片 格式、分辨率
60
+    const isPNG = file.type === 'image/png';
61
+    if (! isPNG){
62
+        message.error('请上传PNG格式图片')
63
+    }
64
+    return (isPNG ) && checkImageWH(file, 166, 166);
65
+  }  
66
+
67
+  const { getFieldDecorator } = props.form
68
+
69
+  return (
70
+    <Modal footer={null} title="新增印章" visible={props.visible} onCancel={() => close({visable:false})} width={800}>
71
+      <Form labelCol={{ span: 7 }} wrapperCol={{ span: 12 }} onSubmit={handleSubmit}>
72
+        <Form.Item label="印章名称">
73
+            {getFieldDecorator('sealName',{
74
+            rules: [
75
+                {
76
+                required: true,
77
+                message: '请填写印章名称',
78
+                },
79
+            ],
80
+            })(<Input maxLength={10}/>)}
81
+        </Form.Item>
82
+        <Form.Item label="印章图" help="166*166 像素,PNG格式透明底 ">
83
+            {getFieldDecorator('sealImg', {
84
+              rules: [{ required: true, message: '请选择印章图' }],
85
+            })(
86
+              <ImageUpload beforeUpload={handleBeforeUpload} />,
87
+            )}
88
+          </Form.Item>
89
+        <Form.Item style={{ width: '400px', margin: 'auto', display: 'flex', justifyContent: 'space-between' }}>
90
+            <Button type="primary" htmlType="submit">确定</Button>
91
+            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
92
+            <Button onClick={() => close({visable:false})}>取消</Button>
93
+         </Form.Item>
94
+      </Form>
95
+    </Modal>
96
+  );
97
+}
98
+
99
+const WrappedBase = Form.create({ name: 'AddSeal' })(AddSeal);
100
+
101
+export default WrappedBase
102
+

+ 33
- 0
src/pages/eContract/seal/components/AuthRes.jsx ファイルの表示

@@ -0,0 +1,33 @@
1
+import React, { PureComponent, useState, useEffect } from 'react'
2
+import { Modal, Row, Col, Table, Pagination, Button, Form, Input,message } from 'antd'
3
+
4
+import request from '../../../../utils/request';
5
+import apis from '../../../../services/apis';
6
+
7
+const AuthRes = props => {
8
+  const authRes = props.authInfo
9
+
10
+  return (
11
+    <Modal footer={null} title="授权信息" visible={props.visable} onCancel={props.onCancel} width={800}>
12
+      <Form labelCol={{ span: 7 }} wrapperCol={{ span: 12 }}>
13
+        <Form.Item label="授权状态">
14
+          <span>{authRes.status === 1 ? '已授权':'未授权'}</span>
15
+        </Form.Item>
16
+        <Form.Item label="授权类型">
17
+          <span>{authRes.authType === 'onLine' ? '接口线上授权': authRes.authType === 'offLine' ? '线下管理员授权' : ''}</span>
18
+        </Form.Item>
19
+        <Form.Item label="授权流水号">
20
+        <span>{authRes.transactionId}</span>
21
+        </Form.Item>
22
+        <Form.Item label="授权合同编号">
23
+        <span>{authRes.contractId}</span>
24
+        </Form.Item>
25
+      </Form>
26
+    </Modal>
27
+  );
28
+}
29
+
30
+const WrappedBase = Form.create({ name: 'AuthRes' })(AuthRes);
31
+
32
+export default WrappedBase
33
+

+ 127
- 0
src/pages/eContract/seal/components/Authorize.jsx ファイルの表示

@@ -0,0 +1,127 @@
1
+import React, { useState, useEffect } from 'react';
2
+import { Input, Menu, Dropdown, Button, Icon, message, Table, Divider, Tag, Select, Form, Alert, Tabs, Row, Col, Radio, tab } from 'antd';
3
+import { FormattedMessage } from 'umi-plugin-react/locale';
4
+import XForm, { FieldTypes } from '../../../../components/XForm';
5
+import router from 'umi/router';
6
+import apis from '../../../../services/apis';
7
+import request from '../../../../utils/request';
8
+import Wangedit from '../../../../components/Wangedit/Wangedit'
9
+import AuthRes from './AuthRes';
10
+import moment from 'moment';
11
+
12
+const { TabPane } = Tabs;
13
+
14
+const header = props => {
15
+    const companyId = props.companyId
16
+  
17
+    const [ data, setData ] = useState({})
18
+    const [ authData, setAuthData ] = useState({})
19
+    const [ authRes, setAuthRes ] = useState({visable: false, data: ''})
20
+
21
+    if(companyId){
22
+      useEffect(() => {
23
+        getCompanyData(companyId);
24
+        auth(companyId);
25
+      },[])
26
+    
27
+      // 查询列表
28
+    const getCompanyData = (companyId) => {
29
+      request({ ...apis.company.companyById, urlData: { id: companyId } }).then((data) => {
30
+        setData(data)
31
+      }).catch((err) => {
32
+        message.error(err.msg || err.message)
33
+      })
34
+     }
35
+    }
36
+
37
+    const auth = (companyId) => {
38
+      request({ ...apis.company.getAuthStatus, urlData: { id: companyId } }).then((data) => {
39
+        setAuthData(data)
40
+      }).catch((err) => {
41
+        message.error(err.msg || err.message)
42
+      })
43
+    }
44
+
45
+    const openFddUrl = (data) => {
46
+      window.open(data)
47
+    }
48
+  
49
+    function back(){
50
+      router.go(-1)
51
+    }
52
+
53
+    function applyAuth(){
54
+      request({ ...apis.company.autoAuthSeal, urlData: { id: companyId } }).then((data) => {
55
+        console.log(data, 'datatatata')
56
+        openFddUrl(data)
57
+        
58
+      }).catch((err) => {
59
+        message.error(err.msg || err.message)
60
+      })
61
+    }
62
+
63
+    function queryAuth(e){
64
+      console.log(e, 'eeadssa')
65
+      setAuthRes({visable:e.visable, data: authData})
66
+    }
67
+
68
+    function closeAuth(e){
69
+      console.log(e, '1111111')
70
+      setAuthRes({visable:e.visable, data: ''})
71
+    }
72
+    return (
73
+      <>
74
+        <Form labelCol={{ span: 7 }} wrapperCol={{ span: 12 }}>
75
+        <Form.Item label="企业名称">
76
+          <span>{data.companyName}</span>
77
+        </Form.Item>
78
+        <Form.Item label="流水号/交易号">
79
+          <span>{data.authorizeTransactionId}</span>
80
+        </Form.Item>
81
+        <Form.Item label="授权签署地址">
82
+        <span>{data.authorizeAddress}</span>
83
+        </Form.Item>
84
+        <Form.Item label="合同编号">
85
+        <span>{data.contractId}</span>
86
+        </Form.Item>
87
+        <Form.Item label="签章结果">
88
+        <span>{data.authorizeStatus === '3000' ? '签章成功':'签章失败'}</span>
89
+        </Form.Item>
90
+        <Form.Item label="签章结果描述">
91
+        <span>{data.authorizeDescription}</span>
92
+        </Form.Item>
93
+        <Form.Item label="下载地址">
94
+        <span>{data.authorizeDownloadUrl}</span>
95
+        </Form.Item>
96
+        <Form.Item label="查看地址">
97
+        <span>{data.authorizeViewUrl}</span>
98
+        </Form.Item>
99
+        {data.authorizeStatus === '3000' &&
100
+        <Form.Item label="授权状态">
101
+        <span>{data.authorizeStatus === '3000'? '已授权':'未授权'}</span>
102
+        </Form.Item>}
103
+        {data.authorizeStatus === '3000' &&
104
+        <Form.Item label="授权类型">
105
+        <span>{data.authorizeType === 'onLine' ? '接口线上授权':'线下管理员授权'}</span>
106
+        </Form.Item>}
107
+        {data.authorizeStatus === '3000' &&
108
+        <Form.Item label="授权流水号">
109
+        <span>{data.authorizeTransactionId}</span>
110
+        </Form.Item>}
111
+        {data.authorizeStatus === '3000' &&
112
+        <Form.Item label="授权合同编号">
113
+        <span>{data.contractId}</span>
114
+        </Form.Item>}
115
+      </Form>
116
+      <div style={{marginTop:'20px', marginBottom:'20px',textAlign:'center'}}>
117
+        {data.authorizeStatus != '3000' && <Button style={{margin:'20px 10px'}} onClick={() => applyAuth()} >申请授权</Button>}
118
+        <Button style={{margin:'20px 10px'}} onClick={(e) => queryAuth({visable:true})}>查看授权</Button>
119
+        <Button style={{margin:'20px 10px'}} onClick={() => back()} >返回</Button>
120
+      </div>
121
+      <AuthRes visable={authRes.visable} authInfo={authRes.data} onCancel={() => closeAuth({visable:false, data:''})}></AuthRes>
122
+      </>
123
+    )
124
+  }
125
+  
126
+  const WrappedNormalLoginForm = Form.create({ name: 'header' })(header);
127
+  export default WrappedNormalLoginForm

+ 84
- 0
src/pages/eContract/seal/components/FileUpload.jsx ファイルの表示

@@ -0,0 +1,84 @@
1
+import React, { useState, useEffect } from 'react'
2
+import { Upload, Button, Icon } from 'antd';
3
+import { uploaderProps } from '../../../../utils/upload';
4
+
5
+/**
6
+ * value 数据的接收格式 [{ url: xxxxx.mp4 }]
7
+ * size  参数限制可以上传多少个文件
8
+ * @param { value, size } props
9
+ */
10
+function fileUpload(props) {
11
+
12
+  const { value } = props
13
+  // console.log('fileUploadProps: ', props)
14
+  // eslint-disable-next-line react-hooks/rules-of-hooks
15
+  const [defaultFileList, setDefaultFileList] = useState([])
16
+
17
+  // eslint-disable-next-line react-hooks/rules-of-hooks
18
+  useEffect(() => {
19
+    setDefaultValue()
20
+  }, [props.value]);
21
+
22
+
23
+  function getFileList() {
24
+    console.log('fileUpload: ', value)
25
+    // value 数据的接收格式 [{ url: xxxxx.mp4 }, { url: xxxxx.jpg }]
26
+    return (value || []).filter(f => f !== undefined).map((img, inx) => ({ uid: inx, url: img, name: img.substring(img.lastIndexOf('/') + 1, img.length), status: 'done' }))
27
+  }
28
+
29
+  function setDefaultValue() {
30
+    if (!value) {
31
+      return;
32
+    }
33
+
34
+    setDefaultFileList(getFileList())
35
+  }
36
+
37
+  function onFileChange({ file, fileList }) {
38
+    console.log(file, fileList)
39
+    setDefaultFileList(fileList)
40
+    if (file.status === 'uploading') {
41
+      return
42
+    }
43
+
44
+    if (file.status === 'done' || file.status === 'removed') {
45
+
46
+      // 因为这个控件本身返回的数据格式 [{ ..., response: '服务器返回的数据' }]
47
+      // 但是 我这里自己用的时候 传入的数据是 [ 'xxxx.mp4', 'xxxx.jpg' ], 然后通过 getFileList() 转换成了 [{ url: 'xxx.mp4' }] 这样的格式
48
+
49
+      // 原因是因为 控件返回的数据 和 fileList 展示已经上传的数据 的格式字段不一样
50
+
51
+      const resFileList = fileList.filter(f => f.response !== undefined).map(i => i.response)
52
+      const tempFileList = fileList.filter(f => f.url !== undefined).map(i => i.url)
53
+      const resultList = tempFileList.concat(resFileList || [])
54
+      props.onChange(resultList)
55
+    }
56
+  }
57
+
58
+  return (
59
+    <>
60
+      <Upload
61
+        { ...uploaderProps }
62
+        {...props}
63
+        onChange={onFileChange}
64
+        fileList={defaultFileList}
65
+      >
66
+        {
67
+          props.size ?
68
+          (props.size > defaultFileList.length
69
+          && (
70
+            <Button>
71
+                <Icon type="upload" /> {props.label}
72
+              </Button>
73
+          )) : (
74
+            <Button>
75
+              <Icon type="upload" /> {props.label}
76
+            </Button>
77
+          )
78
+        }
79
+      </Upload>
80
+    </>
81
+  )
82
+}
83
+
84
+export default fileUpload

+ 62
- 0
src/pages/eContract/seal/components/ImageUpload.jsx ファイルの表示

@@ -0,0 +1,62 @@
1
+import React from 'react';
2
+import { Upload, Icon, message } from 'antd';
3
+import './style.less';
4
+import { uploaderProps } from '../../../../utils/upload';
5
+
6
+
7
+
8
+class ImageUpload extends React.Component {
9
+  state = {
10
+    loading: false,
11
+    imageUrl: undefined,
12
+  };
13
+
14
+  handleChange = info => {
15
+    if (info.file.status === "uploading") {
16
+      this.setState({ loading: true });
17
+      return;
18
+    }
19
+    
20
+    if (info.file.status === 'removed') {
21
+      this.props.onChange();
22
+    }
23
+
24
+  };
25
+
26
+  handleUploadSucess = (url) => {
27
+    this.setState({ loading: false });
28
+    if (typeof this.props.onChange === 'function') {
29
+      this.props.onChange(url);
30
+    }
31
+  }
32
+
33
+  render() {
34
+    const uploadButton = (
35
+      <div>
36
+        <Icon style={{ fontSize: '2em', color: '#aaa' }} type={this.state.loading ? "loading" : "plus"} />
37
+      </div>
38
+    );
39
+
40
+    const value = this.props.value;
41
+    return (
42
+      <Upload
43
+        listType="picture-card"
44
+        className="avatar-uploader"
45
+        showUploadList={false}
46
+        beforeUpload={this.props.beforeUpload}
47
+        onChange={this.handleChange}
48
+        {...uploaderProps}
49
+        disabled={this.props.disabled}
50
+        onSuccess={this.handleUploadSucess}
51
+      >
52
+        {(this.state.imageUrl || value) ? (
53
+          <img src={this.state.imageUrl || value} alt="avatar" style={{ width: "100%" }} />
54
+        ) : (
55
+            uploadButton
56
+          )}
57
+      </Upload>
58
+    );
59
+  }
60
+}
61
+
62
+export default ImageUpload;

+ 162
- 0
src/pages/eContract/seal/components/SealList.jsx ファイルの表示

@@ -0,0 +1,162 @@
1
+import React, { useState, useEffect } from 'react';
2
+import { Input, Menu, Dropdown, Button, Icon, message, Table, Divider, Tag, Select, Form, Alert, Tabs, Row, Col, Radio, tab, Avatar, Modal } from 'antd';
3
+import { FormattedMessage } from 'umi-plugin-react/locale';
4
+import XForm, { FieldTypes } from '../../../../components/XForm';
5
+import router from 'umi/router';
6
+import apis from '../../../../services/apis';
7
+import request from '../../../../utils/request';
8
+import Wangedit from '../../../../components/Wangedit/Wangedit'
9
+import moment from 'moment';
10
+import AddSeal from './AddSeal';
11
+import UpdateSeal from './UpdateSeal';
12
+
13
+const { TabPane } = Tabs;
14
+
15
+const header = props => {
16
+    const companyId = props.companyId;
17
+  
18
+    const [ data, setData ] = useState({})
19
+    const [sealData, setSealData] = useState({})
20
+    const [sealInfo, setSealInfo] = useState({visable: false, companyId: ''})
21
+    const [updateSeal, setUpdateSeal] = useState({visable: false, companyId: '', sealId: ''})
22
+
23
+    useEffect(() => {
24
+      getCompanyData({companyId: companyId});
25
+    },[])
26
+  
27
+    // 查询列表
28
+    function getCompanyData(params) {
29
+      request({ ...apis.seal.listByCompanyId, params: { ...params } }).then((data) => {
30
+        setData(data)
31
+      }).catch((err) => {
32
+        message.error(err.msg || err.message)
33
+      })
34
+    }  
35
+
36
+    const openFddUrl = () => {
37
+      window.open(data.certifiedAddress)
38
+    }
39
+  
40
+    // 提交事件
41
+    const handleSubmit = e => {
42
+      e.preventDefault();
43
+      props.form.validateFields((err, values) => {
44
+        if (!err) {
45
+          getCompanyData({ pageNumber: 1, pageSize: 10, ...values, companyId: companyId })
46
+        }
47
+      });
48
+    }
49
+
50
+     // 重置搜索
51
+     function handleReset () {
52
+      props.form.resetFields();
53
+    }
54
+
55
+    function addSealInfo(){
56
+      setSealInfo({visable: true, companyId: companyId})
57
+    }
58
+
59
+    function updateSealInfo(e){
60
+      setUpdateSeal(e);
61
+    }
62
+
63
+    function getList(e) {
64
+      setSealInfo(e)
65
+      getCompanyData(e)
66
+    }
67
+
68
+    function updateOnSuccess(e) {
69
+      setUpdateSeal(e);
70
+      getCompanyData(e)
71
+    }
72
+
73
+    const delSealInfo = (row) => {
74
+      Modal.confirm({
75
+          title: '删除后无法再使用这些章继续签章,不会影响已签署的合同',
76
+          okText: '确定',
77
+          cancelText: '取消',
78
+          onOk() {
79
+              request({ ...apis.seal.delSealById, urlData:{id: row.sealId} }).then((data) => {
80
+                  message.info('操作成功!')
81
+                  getCompanyData({ pageNum: 1, pageSize: 10, companyId: companyId })
82
+              }).catch((err) => {
83
+                  console.log(err)
84
+                  message.info(err.msg || err.message)
85
+              })
86
+          },
87
+        });
88
+  }
89
+
90
+
91
+
92
+    const columns = [
93
+      {
94
+        title: '印章编号',
95
+        dataIndex: 'sealId',
96
+        key: 'sealId',
97
+        align: 'center',
98
+      },
99
+      {
100
+        title: '印章名称',
101
+        dataIndex: 'sealName',
102
+        key: 'sealName',
103
+        align: 'center',
104
+      },
105
+      {
106
+        title: '印章图',
107
+        dataIndex: 'sealImg',
108
+        key: 'sealImg',
109
+        align: 'center',
110
+        render: (_, record) => <Avatar shape="square" style={{color: 'blue',cursor: 'pointer'}} src={record.sealImg} size={64} icon="user" />,
111
+      },
112
+      {
113
+        title: '印章上传时间',
114
+        dataIndex: 'createDate',
115
+        key: 'createDate',
116
+        align: 'center',
117
+        render: (x, row) => <><span>{row.createDate != null ? `${moment(row.createDate).format('YYYY-MM-DD HH:mm:ss')}` : ''}</span></>,
118
+      },
119
+      {
120
+        title: '操作',
121
+        dataIndex: '',
122
+        key: '',
123
+        align: 'center',
124
+        render: (text, record) => (
125
+            <>
126
+            <a style={{ color: '#66B3FF' }} onClick={() => updateSealInfo({visable:true, companyId: record.companyId, sealId: record.sealId})} ><span>修改</span></a>
127
+            <a style={{ color: '#66B3FF', marginLeft:'20px' }} onClick={() => delSealInfo(record)} ><span>删除</span></a>
128
+            </>
129
+        ),
130
+      },
131
+    ]
132
+
133
+    const { getFieldDecorator } = props.form
134
+    return (
135
+      <>
136
+      <Form layout="inline" onSubmit={e => handleSubmit(e)}>
137
+        <Form.Item>
138
+          {getFieldDecorator('sealName')(
139
+            <Input placeholder="印章名称"/>,
140
+          )}
141
+        </Form.Item>
142
+        <Form.Item>
143
+          <Button type="primary" htmlType="submit" >
144
+            搜索
145
+          </Button>
146
+          <Button style={{ marginLeft: 8 }} onClick={handleReset}>
147
+            重置
148
+            </Button>
149
+        </Form.Item>
150
+      </Form>
151
+        <div style={{marginTop:'20px', marginBottom:'20px'}}>
152
+          <Button type="danger" onClick={() => addSealInfo({visable:true})} >新增</Button>
153
+        </div>
154
+        <AddSeal visible={sealInfo.visable} companyId={sealInfo.companyId} onCancel={e => setSealInfo(e)} onSuccess={e => getList(e)}/>  
155
+        <UpdateSeal visible={updateSeal.visable} sealId={updateSeal.sealId} companyId={updateSeal.companyId} onCancel={e => setUpdateSeal(e)} onSuccess={e => updateOnSuccess(e)}/>  
156
+      <Table dataSource={data.records} columns={columns} pagination={false} rowKey="carouseFigureList"/>
157
+      </>
158
+    )
159
+  }
160
+  
161
+  const WrappedNormalLoginForm = Form.create({ name: 'header' })(header);
162
+  export default WrappedNormalLoginForm

+ 117
- 0
src/pages/eContract/seal/components/UpdateSeal.jsx ファイルの表示

@@ -0,0 +1,117 @@
1
+import React, { PureComponent, useState, useEffect } from 'react'
2
+import { Modal, Row, Col, Table, Pagination, Button, Form, Input,message, Icon, notification } from 'antd'
3
+import ImageUpload from './ImageUpload';
4
+import apis from '../../../../services/apis';
5
+import request from '../../../../utils/request';
6
+
7
+const UpdateSeal = props => {
8
+  const sealId = props.sealId
9
+  const companyId = props.companyId
10
+  const [sealData, setSealData] = useState({})
11
+
12
+  useEffect(() => {
13
+    getSealData();
14
+  },[sealId])
15
+
16
+  // 查询列表
17
+  function getSealData() {
18
+    request({ ...apis.seal.taSealById, urlData: { id: sealId } }).then((data) => {
19
+      setSealData(data)
20
+    }).catch((err) => {
21
+      message.error(err.msg || err.message)
22
+    })
23
+  }  
24
+
25
+  function close(e){
26
+    props.onSuccess(e)
27
+  }
28
+
29
+  function handleSubmit (e) {
30
+    e.preventDefault();
31
+    props.form.validateFields((err, values) => {
32
+      if (!err){
33
+        request({ ...apis.seal.updateSealById, urlData:{id: sealId}, data: { ...values, id: sealId, companyId: companyId },}).then((data) => {
34
+          message.info("保存成功")
35
+          close({visable:false, sealId:'', companyId: companyId})
36
+        }).catch((err) => {
37
+          message.info(err.msg || err.message)
38
+        })
39
+      }
40
+    });
41
+  }
42
+
43
+  function openNotificationWithIcon(type, message) {
44
+    notification[type]({
45
+      message,
46
+      description:
47
+        '',
48
+    });
49
+  }
50
+
51
+  function checkImageWH(file, width, height) {
52
+    let self = this;
53
+    return new Promise(function (resolve, reject) {
54
+        let filereader = new FileReader();
55
+        filereader.onload = e => {
56
+            let src = e.target.result;
57
+            const image = new Image();
58
+            image.onload = function () {
59
+                if (width && this.width != width && height && this.height != height) {
60
+                    message.error('图片尺寸不符合要求')
61
+                    reject();
62
+                } else {
63
+                    resolve();
64
+                }
65
+            };
66
+            image.onerror = reject;
67
+            image.src = src;
68
+        };
69
+        filereader.readAsDataURL(file);
70
+    });
71
+}
72
+
73
+  const handleBeforeUpload = (file) => {
74
+    //限制图片 格式、分辨率
75
+    const isPNG = file.type === 'image/png';
76
+    if (! isPNG){
77
+        message.error('请上传PNG格式图片')
78
+    }
79
+    return (isPNG ) && checkImageWH(file, 166, 166);
80
+  }  
81
+
82
+  const { getFieldDecorator } = props.form
83
+
84
+  return (
85
+    <Modal footer={null} title="修改印章" visible={props.visible} onCancel={() => close({visable:false, sealId:''})} width={800}>
86
+      <Form labelCol={{ span: 7 }} wrapperCol={{ span: 12 }} onSubmit={handleSubmit}>
87
+        <Form.Item label="印章名称">
88
+            {getFieldDecorator('sealName',{initialValue:sealData.sealName,
89
+            rules: [
90
+                {
91
+                required: true,
92
+                message: '请填写印章名称',
93
+                },
94
+            ],
95
+            })(<Input maxLength={10}/>)}
96
+        </Form.Item>
97
+        <Form.Item label="印章图" help="166*166 像素,PNG格式透明底 ">
98
+            {getFieldDecorator('sealImg', {initialValue:sealData.sealImg,
99
+              rules: [{ required: true, message: '请选择印章图' }],
100
+            })(
101
+              <ImageUpload beforeUpload={handleBeforeUpload} />,
102
+            )}
103
+          </Form.Item>
104
+        <Form.Item style={{ width: '400px', margin: 'auto', display: 'flex', justifyContent: 'space-between' }}>
105
+            <Button type="primary" htmlType="submit">确定</Button>
106
+            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
107
+            <Button onClick={() => close({visable:false, sealId:''})}>取消</Button>
108
+         </Form.Item>
109
+      </Form>
110
+    </Modal>
111
+  );
112
+}
113
+
114
+const WrappedBase = Form.create({ name: 'UpdateSeal' })(UpdateSeal);
115
+
116
+export default WrappedBase
117
+

+ 20
- 0
src/pages/eContract/seal/components/style.less ファイルの表示

@@ -0,0 +1,20 @@
1
+:global {
2
+  .avatar-uploader {
3
+    & > .ant-upload {
4
+      width: 128px;
5
+      height: 128px;
6
+    }
7
+  }
8
+}
9
+
10
+
11
+/* you can make up upload button and sample style by using stylesheets */
12
+.ant-upload-select-picture-card i {
13
+  font-size: 32px;
14
+  color: #999;
15
+}
16
+
17
+.ant-upload-select-picture-card .ant-upload-text {
18
+  margin-top: 8px;
19
+  color: #666;
20
+}

+ 63
- 0
src/pages/eContract/seal/detail.jsx ファイルの表示

@@ -0,0 +1,63 @@
1
+import React, { useState, useEffect } from 'react';
2
+import { Form, Icon, Input, Button, DatePicker, Select, Card, Row, Col, Pagination, Alert, Radio, Tag, Tooltip, Tabs, notification } from 'antd';
3
+import moment from 'moment';
4
+import request from '../../../utils/request';
5
+import apis from '../../../services/apis';
6
+import { router } from 'umi';
7
+
8
+import SealList from './components/SealList'
9
+import Authorize from './components/Authorize'
10
+
11
+
12
+
13
+const { Option } = Select
14
+const { TabPane } = Tabs;
15
+
16
+const formItemLayout = {
17
+  labelCol: {
18
+    xs: { span: 24 },
19
+    sm: { span: 2 },
20
+  },
21
+  wrapperCol: {
22
+    xs: { span: 24 },
23
+    sm: { span: 16 },
24
+  },
25
+};
26
+
27
+function openNotificationWithIcon(type, message) {
28
+  notification[type]({
29
+    message,
30
+    description:
31
+      '',
32
+  });
33
+}
34
+
35
+function EditHouse(props) {
36
+  const [tab, setTab] = useState('sealList')
37
+  const companyId = props.location.query.id;
38
+  function tabsCallback(e) {
39
+    setTab(e)
40
+  }
41
+
42
+  // building 回调
43
+  function buildingOnSuccess(e) {
44
+    setBuildingData(e)
45
+  }
46
+
47
+  return (
48
+    <>
49
+      <Tabs type="card" value={ tab } buttonStyle="solid" onChange={e => tabsCallback(e)}>
50
+        <TabPane tab="印章列表" key="sealList" ></TabPane>
51
+        <TabPane tab="自动签章授权" key="authorize" ></TabPane>
52
+      </Tabs>
53
+      <div style={{ marginTop: '20px' }}>
54
+        { (tab === 'sealList' && <SealList companyId={companyId}/>)}
55
+        { (tab === 'authorize' && <Authorize companyId={companyId}/>)}
56
+      </div>
57
+    </>
58
+  )
59
+}
60
+
61
+const WrappedEditHouseForm = Form.create({ name: 'editHouse' })(EditHouse);
62
+
63
+export default WrappedEditHouseForm

+ 223
- 0
src/pages/eContract/seal/list.jsx ファイルの表示

@@ -0,0 +1,223 @@
1
+import React, { useState, useEffect } from 'react';
2
+import { PageHeaderWrapper } from '@ant-design/pro-layout';
3
+import { Form, Pagination, Card, Button, Icon, Tooltip, message,   notification, Modal, Table, Select, Input, DatePicker } from 'antd';
4
+import router from 'umi/router';
5
+import moment from 'moment';
6
+import className from 'classnames';
7
+import Cell from '../../../components/Cell';
8
+import styles from './style.less';
9
+import { fetch, apis } from '../../../utils/request';
10
+import request from '../../../utils/request';
11
+import AuthButton from '@/components/AuthButton';
12
+
13
+const { MonthPicker, RangePicker, WeekPicker } = DatePicker;
14
+
15
+function header(props) {
16
+  // 获取初始化数据
17
+  const [ data, setData ] = useState({})
18
+  const [demandIdList, setDemandIdList] = useState([])
19
+
20
+  useEffect(() => {
21
+    getList({ pageNum: 1, pageSize: 10 });
22
+  },[])
23
+
24
+  // 查询列表
25
+  const getList = (params) => {
26
+    request({ ...apis.company.list, params: { ...params } }).then((data) => {
27
+        console.log(data)
28
+        setData(data)
29
+    })
30
+  }
31
+
32
+  
33
+  // 提交事件
34
+  const handleSubmit = (e, props) => {
35
+    e.preventDefault();
36
+    props.form.validateFields((err, values) => {
37
+      if (!err) {
38
+        getList({ pageNum: 1, pageSize: 10, ...values })
39
+      }
40
+    });
41
+  }
42
+
43
+  const changePageNum = (pageNumber) => {
44
+    let values  = props.form.getFieldsValue()
45
+    getList({ pageNum: pageNumber, pageSize: 10, ...values })
46
+  }
47
+
48
+  const rowSelection = {
49
+    onChange: (selectedRowKeys, selectedRows) => {
50
+      console.log('selectedRowKeys:', selectedRowKeys, 'selectedRows: ', selectedRows);
51
+      setDemandIdList(selectedRows)
52
+    },
53
+  };
54
+
55
+
56
+  // 跳转到编辑资讯
57
+  const toEditSeal = (id) => () => {
58
+    router.push({
59
+      pathname: '/eContract/seal/detail',
60
+      query: {
61
+        id
62
+      },
63
+    });
64
+  }
65
+
66
+  
67
+  // 跳转到编辑资讯
68
+  const toAddCompany = () => {
69
+    router.push({
70
+      pathname: '/eContract/company/add',
71
+    });
72
+  }
73
+
74
+  
75
+  const changeStatus = () => {
76
+    if(demandIdList.length < 1){
77
+      message.error('请先选择要删除的数据!')
78
+      return
79
+    }
80
+    const title = '确认将所选的' + demandIdList.length + '条数据删除?可删除条件:需求单状态 为 作废。'
81
+    Modal.confirm({
82
+      title: title,
83
+      okText: '确认',
84
+      cancelText: '取消',
85
+      onOk() {
86
+        request({ ...apis.sample.put, data: { ids: demandIdList.map(x => x.demandId) } }).then((data) => {
87
+          const resultMessage = '操作成功,其中'+data.successNum+'条成功删除,'+data.failNum+'条非作废状态未删除。'
88
+          message.info(resultMessage)
89
+          getList({ pageNum: 1, pageSize: 10 });
90
+        }).catch((err) => {
91
+          console.log(err)
92
+          message.info(err.msg || err.message)
93
+        })
94
+      }
95
+    });
96
+  }
97
+  /**
98
+   *
99
+   *
100
+   * @param {*} props
101
+   * @returns
102
+   */
103
+  const columns = [
104
+    {
105
+      title: '企业名称',
106
+      dataIndex: 'companyName',
107
+      key: 'companyName',
108
+      align: 'center',
109
+    },
110
+    {
111
+      title: '企业编号',
112
+      dataIndex: 'companyCode',
113
+      key: 'companyCode',
114
+      align: 'center',
115
+    },
116
+    {
117
+      title: '实名认证状态',
118
+      dataIndex: 'certifiedStatus',
119
+      key: 'certifiedStatus',
120
+      align: 'center',
121
+      render: (x, row) => {
122
+        if(row.certifiedStatus === 'certification'){return '审核通过'}
123
+      },
124
+    },
125
+    {
126
+      title: '印章数',
127
+      dataIndex: 'sealNum',
128
+      key: 'sealNum',
129
+      align: 'center',
130
+    },
131
+    {
132
+      title: '自动签章授权状态',
133
+      dataIndex: 'authorizeStatus',
134
+      key: 'authorizeStatus',
135
+      align: 'center',
136
+      render: (x, row) => {
137
+        if(row.authorizeStatus === 'certification'){return '审核通过'}
138
+      },
139
+    },
140
+    {
141
+      title: '操作',
142
+      dataIndex: 'handle',
143
+      key: 'handle',
144
+      align: 'center',
145
+      render: (x, row) => (
146
+        <span style={{ color: '#FF925C', cursor: 'pointer' }} onClick={toEditSeal(row.companyId)}>
147
+          查看详情<Icon type="form" className={styles.edit} />
148
+        </span>
149
+      ),
150
+    },
151
+  ];
152
+  function handleReset() {
153
+    props.form.resetFields();
154
+    getList({ pageNum: 1, pageSize: 10 })
155
+  }
156
+
157
+  const { getFieldDecorator } = props.form
158
+  return (
159
+
160
+    <>
161
+    <Form layout="inline" onSubmit={e => handleSubmit(e, props)}>
162
+        <Form.Item>
163
+          {getFieldDecorator('companyName')(
164
+            <Input
165
+              prefix={<Icon type="text" style={{ color: 'rgba(0,0,0,.25)' }} />}
166
+              placeholder="企业名称"
167
+            />,
168
+          )}
169
+        </Form.Item>
170
+        <Form.Item>
171
+          {getFieldDecorator('companyCode')(
172
+            <Input
173
+              prefix={<Icon type="text" style={{ color: 'rgba(0,0,0,.25)' }} />}
174
+              placeholder="企业编号"
175
+            />,
176
+          )}
177
+        </Form.Item>
178
+        <Form.Item>
179
+          {getFieldDecorator('certifiedStatus')(
180
+            <Select style={{ width: '180px' }} placeholder="实名认证状态">
181
+              <Select.Option value="1">未认证</Select.Option>
182
+              <Select.Option value="2">管理员资料已提交</Select.Option>
183
+              <Select.Option value="3">企业基本资料(没有申请表)已提交</Select.Option>
184
+              <Select.Option value="4">已提交待审核</Select.Option>
185
+              <Select.Option value="5">审核通过</Select.Option>
186
+              <Select.Option value="6">审核不通过</Select.Option>
187
+              <Select.Option value="7">人工初审通过</Select.Option>
188
+            </Select>,
189
+          )}
190
+        </Form.Item>
191
+        <Form.Item>
192
+          {getFieldDecorator('authorizeStatus')(
193
+            <Select style={{ width: '180px' }} placeholder="自动签章授权状态">
194
+              <Select.Option value="1">未认证</Select.Option>
195
+              <Select.Option value="2">管理员资料已提交</Select.Option>
196
+              <Select.Option value="3">企业基本资料(没有申请表)已提交</Select.Option>
197
+              <Select.Option value="4">已提交待审核</Select.Option>
198
+              <Select.Option value="5">审核通过</Select.Option>
199
+              <Select.Option value="6">审核不通过</Select.Option>
200
+              <Select.Option value="7">人工初审通过</Select.Option>
201
+            </Select>,
202
+          )}
203
+        </Form.Item>
204
+        <Form.Item>
205
+          <Button type="primary" htmlType="submit" className={styles.searchBtn}>
206
+            搜索
207
+          </Button>
208
+          <Button style={{ marginLeft: 8 }} onClick={handleReset}>
209
+              重置
210
+          </Button>
211
+        </Form.Item>
212
+      </Form>
213
+      
214
+      <Table rowSelection={rowSelection} rowKey="newsType" dataSource={data.records} columns={columns} pagination={false} />
215
+      <div style={{ display: 'flex', justifyContent: 'flex-end', marginTop: '30px' }}>
216
+        <Pagination showQuickJumper defaultCurrent={1} total={data.total} onChange={changePageNum} current={data.current}/>
217
+      </div>
218
+    </>
219
+  )
220
+}
221
+const WrappedHeader = Form.create({ name: 'header' })(header);
222
+
223
+export default WrappedHeader

+ 22
- 0
src/pages/eContract/seal/style.less ファイルの表示

@@ -0,0 +1,22 @@
1
+.flex-box {
2
+  display: flex;
3
+  flex-wrap: wrap;
4
+
5
+  .flex-item {
6
+    flex: none;
7
+  }
8
+
9
+  .flex-auto {
10
+    flex: auto;
11
+  }
12
+}
13
+
14
+.member {
15
+  margin-bottom: 36px;
16
+  margin-right: 24px;
17
+}
18
+
19
+.square {
20
+  height: 0;
21
+  padding-bottom : 80%;
22
+}

+ 42
- 2
src/services/apis.js ファイルの表示

@@ -260,6 +260,47 @@ const apis = {
260 260
       method: 'PUT',
261 261
       action: 'channel',
262 262
     },
263
+    companyById: {
264
+      url: `${prefix}/taCompany/:id`,
265
+      method: 'GET',
266
+      action: 'channel',
267
+    },
268
+    autoAuthSeal: {
269
+      url: `${prefix}/company/autoAuthCompany/:id`,
270
+      method: 'PUT',
271
+      action: 'channel',
272
+    },
273
+    getAuthStatus: {
274
+      url: `${prefix}/company/getAuthStatus/:id`,
275
+      method: 'GET',
276
+      action: 'channel',
277
+    }
278
+  },
279
+
280
+  seal: {
281
+    listByCompanyId: {
282
+      url: `${prefix}/taCompanySeal`,
283
+      method: 'GET',
284
+      action: 'channel',
285
+    },
286
+    addSeal: {
287
+      url: `${prefix}/taCompanySeal`,
288
+      method: 'POST',
289
+      action: 'channel',
290
+    },
291
+    taSealById: {
292
+      url: `${prefix}/taCompanySeal/:id`,
293
+      method: 'GET',
294
+      action: 'channel',
295
+    },
296
+    updateSealById: {
297
+      url: `${prefix}/taCompanySeal/:id`,
298
+      method: 'PUT',
299
+      action: 'channel',
300
+    },
301
+    delSealById: {
302
+      url: `${prefix}/delCompanySeal/:id`,
303
+      method: 'PUT',
263 304
     refresh: {
264 305
       url: `${prefix}/company/fdd/:id`,
265 306
       method: 'GET',
@@ -271,8 +312,7 @@ const apis = {
271 312
       action: 'channel',
272 313
     }
273 314
   }
274
-
275
-  
315
+  }  
276 316
 }
277 317
 
278 318
 export default apis;