|
@@ -0,0 +1,235 @@
|
|
|
+import React, { useState } from 'react'
|
|
|
+import styled from 'styled-components'
|
|
|
+import arrowImgUrl from '../style/img/arrow.png'
|
|
|
+import syncImgUrl from '../style/img/sync.png'
|
|
|
+import warningImgUrl from '../style/img/warning.png'
|
|
|
+import deleteImgUrl from '../style/img/delete.png'
|
|
|
+
|
|
|
+const StepThreeDiv = styled.div`
|
|
|
+ .title {
|
|
|
+ font-weight: 600;
|
|
|
+ border-left: 3px solid #1881da;
|
|
|
+ padding-left: 12px;
|
|
|
+ }
|
|
|
+ .tip {
|
|
|
+ font-size: 12px;
|
|
|
+ font-weight: 400;
|
|
|
+ color: #bbbbbb;
|
|
|
+ line-height: 17px;
|
|
|
+ padding-left: 52px;
|
|
|
+ margin: 30px 0 30px;
|
|
|
+ }
|
|
|
+ .table__wrapper {
|
|
|
+ padding-left: 52px;
|
|
|
+ display: flex;
|
|
|
+ }
|
|
|
+ .table__source {
|
|
|
+ border-radius: 2px;
|
|
|
+ border: 1px solid #c8d3e9;
|
|
|
+ width: 400px;
|
|
|
+ }
|
|
|
+ .table__title {
|
|
|
+ border-bottom: 1px solid #c8d3e9;
|
|
|
+ height: 50px;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: space-between;
|
|
|
+ padding: 0 20px;
|
|
|
+ }
|
|
|
+ .table__content {
|
|
|
+ height: 500px;
|
|
|
+ display: felx;
|
|
|
+ justify-content: space-between;
|
|
|
+ padding: 10px 20px;
|
|
|
+ overflow-y: scroll;
|
|
|
+ }
|
|
|
+ .field__wrapper {
|
|
|
+ background: #ebeff3;
|
|
|
+ padding: 8px 10px;
|
|
|
+ width: 140px;
|
|
|
+ font-size: 12px;
|
|
|
+ font-weight: 400;
|
|
|
+ line-height: 17px;
|
|
|
+ }
|
|
|
+ .field__sync {
|
|
|
+ background: #eef5fe;
|
|
|
+ }
|
|
|
+ .arrow {
|
|
|
+ padding: 0 20px;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ }
|
|
|
+ .sync__img {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ height: 33px;
|
|
|
+ margin-bottom: 1em;
|
|
|
+ }
|
|
|
+ .mapping__content {
|
|
|
+ height: 500px;
|
|
|
+ padding: 10px 20px;
|
|
|
+ overflow-y: scroll;
|
|
|
+ }
|
|
|
+ .mapping__item {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
+ margin-bottom: 1em;
|
|
|
+ }
|
|
|
+`
|
|
|
+
|
|
|
+const datasourceFields = [
|
|
|
+ {
|
|
|
+ key: '1',
|
|
|
+ value: '字段',
|
|
|
+ type: 'string',
|
|
|
+ },
|
|
|
+ {
|
|
|
+ key: '2',
|
|
|
+ value: '字段2',
|
|
|
+ type: 'boolean',
|
|
|
+ },
|
|
|
+ {
|
|
|
+ key: '3',
|
|
|
+ value: '字段3',
|
|
|
+ type: 'boolean',
|
|
|
+ },
|
|
|
+]
|
|
|
+
|
|
|
+const syncFields = [
|
|
|
+ {
|
|
|
+ key: '1',
|
|
|
+ value: '字段',
|
|
|
+ type: 'boolean',
|
|
|
+ },
|
|
|
+ {
|
|
|
+ key: '2',
|
|
|
+ value: '字段2',
|
|
|
+ type: 'boolean',
|
|
|
+ },
|
|
|
+ {
|
|
|
+ key: '3',
|
|
|
+ value: '字段3',
|
|
|
+ type: 'boolean',
|
|
|
+ },
|
|
|
+]
|
|
|
+
|
|
|
+const StepThree = () => {
|
|
|
+ // 映射管理
|
|
|
+ const [syncMappings, setSyncMappings] = useState([])
|
|
|
+
|
|
|
+ const syncFieldData = index => {
|
|
|
+ setSyncMappings([
|
|
|
+ ...syncMappings,
|
|
|
+ {
|
|
|
+ datasourceField: datasourceFields[index].value,
|
|
|
+ syncField: syncFields[index].value,
|
|
|
+ },
|
|
|
+ ])
|
|
|
+ }
|
|
|
+ const deleteMapping = mapping => {
|
|
|
+ setSyncMappings(syncMappings.filter(item => item !== mapping))
|
|
|
+ }
|
|
|
+ return (
|
|
|
+ <StepThreeDiv>
|
|
|
+ <p className="title">配置转换规则</p>
|
|
|
+ <p className="tip">拖拽提取源数据表中的字段,与加载源数据表</p>
|
|
|
+ <div className="table__wrapper">
|
|
|
+ <div className="table__source">
|
|
|
+ <div className="table__title">
|
|
|
+ <span>提取源:{'表1'}</span>
|
|
|
+ <span>加载源:{'表2'}</span>
|
|
|
+ </div>
|
|
|
+ <div className="table__content">
|
|
|
+ <div>
|
|
|
+ {datasourceFields.map(item => {
|
|
|
+ return (
|
|
|
+ <p className="field__wrapper field__sync" key={item.key}>
|
|
|
+ {item.value}
|
|
|
+ </p>
|
|
|
+ )
|
|
|
+ })}
|
|
|
+ </div>
|
|
|
+ <div>
|
|
|
+ {datasourceFields.map((item, index) => {
|
|
|
+ const sameType =
|
|
|
+ datasourceFields[index].type === syncFields[index].type
|
|
|
+ return (
|
|
|
+ <div className="sync__img" key={item.key}>
|
|
|
+ <img
|
|
|
+ src={sameType ? syncImgUrl : warningImgUrl}
|
|
|
+ alt=""
|
|
|
+ onClick={() => {
|
|
|
+ if (sameType) syncFieldData(index)
|
|
|
+ }}
|
|
|
+ style={{
|
|
|
+ width: '20px',
|
|
|
+ height: '20px',
|
|
|
+ cursor: sameType ? 'pointer' : 'no-drop',
|
|
|
+ }}
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ )
|
|
|
+ })}
|
|
|
+ </div>
|
|
|
+ <div>
|
|
|
+ {syncFields.map(item => {
|
|
|
+ return (
|
|
|
+ <p className="field__wrapper" key={item.key}>
|
|
|
+ {item.value}
|
|
|
+ </p>
|
|
|
+ )
|
|
|
+ })}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div className="arrow">
|
|
|
+ <img
|
|
|
+ src={arrowImgUrl}
|
|
|
+ alt=""
|
|
|
+ style={{ width: '20px', height: '20px' }}
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ <div className="table__source">
|
|
|
+ <div className="table__title">
|
|
|
+ <span>映射管理</span>
|
|
|
+ <span
|
|
|
+ onClick={() => {
|
|
|
+ setSyncMappings([])
|
|
|
+ }}
|
|
|
+ style={{
|
|
|
+ color: '#7D7D7D',
|
|
|
+ cursor: 'pointer',
|
|
|
+ }}>
|
|
|
+ 清空
|
|
|
+ </span>
|
|
|
+ </div>
|
|
|
+ <div className="mapping__content">
|
|
|
+ {syncMappings.map((item, index) => {
|
|
|
+ return (
|
|
|
+ <div className="mapping__item" key={index}>
|
|
|
+ <span style={{ width: '30px' }}>{index + 1}</span>
|
|
|
+ <span className="field__wrapper">{item.datasourceField}</span>
|
|
|
+ <img
|
|
|
+ src={syncImgUrl}
|
|
|
+ alt=""
|
|
|
+ style={{ width: '20px', height: '20px' }}
|
|
|
+ />
|
|
|
+ <span className="field__wrapper">{item.syncField}</span>
|
|
|
+ <img
|
|
|
+ src={deleteImgUrl}
|
|
|
+ alt=""
|
|
|
+ onClick={() => deleteMapping(item)}
|
|
|
+ style={{ width: '15px', height: '15px', cursor: 'pointer' }}
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ )
|
|
|
+ })}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </StepThreeDiv>
|
|
|
+ )
|
|
|
+}
|
|
|
+
|
|
|
+export default StepThree
|