InitDataBase.jsx 16.8 KB
Newer Older
皮倩雯's avatar
皮倩雯 committed
1 2
/* eslint-disable spaced-comment */
/* eslint-disable eqeqeq */
3
import React, { useEffect, useRef, useState } from 'react';
张烨's avatar
张烨 committed
4 5 6 7 8 9 10 11 12
import {
  Card,
  Form,
  Input,
  Button,
  Select,
  Table,
  Space,
  notification,
13 14
  Modal,
  Row,
张烨's avatar
张烨 committed
15
  Col,
Maofei94's avatar
Maofei94 committed
16
  Popconfirm,
17
  Spin,
18 19
  Tabs,
  Radio,
张烨's avatar
张烨 committed
20
} from 'antd';
21
import PageContainer from '@/components/BasePageContainer';
22
import RadioBox from '@/components/RadioGroup';
23
import { connect } from 'react-redux';
Maofei94's avatar
Maofei94 committed
24 25
import {
  setTableSQLDirName,
26 27 28 29 30 31
  deleteConnNew,
  initDBv4new,
  getInitDBLogNew,
  getConnRecordNew,
  getDataBaseConfigNew,
  saveConnectionNew,
Maofei94's avatar
Maofei94 committed
32
  getDataBaseList,
33 34
  updateConnDescNew,
  deleteInitDBLogNew,
Maofei94's avatar
Maofei94 committed
35
  connectionTest,
36 37 38
  GetProductList, // 获取产品列表
  GetDbProduct, // 获取产品方案配置
  InitAddDataBase, // 数据库初始化
39
  InitEditDataBase, // 二次初始化
Maofei94's avatar
Maofei94 committed
40
} from '@/services/database/api';
皮倩雯's avatar
皮倩雯 committed
41
import CryptoJS from 'crypto-js';
张烨's avatar
张烨 committed
42
import styles from './InitDataBase.less';
皮倩雯's avatar
皮倩雯 committed
43
import InitModal from './initModal';
44

45
const { TabPane } = Tabs;
张烨's avatar
张烨 committed
46
const { Option } = Select;
赵吉's avatar
赵吉 committed
47
const formLables = {
张烨's avatar
张烨 committed
48 49 50 51 52
  ip: '服务器名或IP地址',
  userName: '数据库用户名称',
  password: '数据库用户密码',
  dbName: '数据库名称',
};
53
let time = null;
张烨's avatar
张烨 committed
54 55
const InitDataBase = props => {
  const [form] = Form.useForm();
张烨's avatar
张烨 committed
56
  const [tableLoading, setTableLoading] = useState(false); // 连接记录
张烨's avatar
张烨 committed
57 58 59 60 61
  const [dbForm, setDbForm] = useState({
    ip: '',
    dbName: '',
    password: '',
    userName: '',
皮倩雯's avatar
皮倩雯 committed
62
    providerType: '',
张烨's avatar
张烨 committed
63 64
    inUse: '',
  });
张烨's avatar
张烨 committed
65 66 67
  const [data, setData] = useState([]); // 数据库链接记录
  const [option, setOption] = useState([]); // 下拉列表数据
  const [desc, setDesc] = useState(''); // 修改描述
68 69 70 71 72
  const [modalVisible, setModalVisible] = useState({
    describeVisible: false, // 描述弹窗
    versionVisible: false, // 检查版本弹窗
    initVisible: false, // 初始化选择产品弹窗
  }); // 修改弹窗
皮倩雯's avatar
皮倩雯 committed
73

74
  const [cardLoading, setCardLoading] = useState(false); // 初始化card Loading
皮倩雯's avatar
皮倩雯 committed
75 76
  const [flag, setFlag] = useState(0);
  const [keepData, setKeepData] = useState({});
77
  const chooseDb = useRef({});
皮倩雯's avatar
皮倩雯 committed
78 79
  const key = CryptoJS.enc.Utf8.parse('1p2a3n4d5a6o7m8s9a10n1e2t3c4o5re'); //十六位十六进制数作为密钥
  const iv = CryptoJS.enc.Utf8.parse('1234567890000000');
皮倩雯's avatar
皮倩雯 committed
80
  const [pickItem, setPickItem] = useState();
81 82

  // 获取数据库配置信息
张烨's avatar
张烨 committed
83
  useEffect(() => {
84 85 86 87 88 89
    setCardLoading(true);
    // 数据库连接记录初始化
    getConnRecordData();
    getDataBaseConfigNew().then(resnew => {
      setCardLoading(false);
      let res = resnew.data;
90
      if (resnew.code === 0) {
91 92 93 94 95
        const { inUse } = res;

        let obj = {};
        Object.keys(dbForm).forEach(k => {
          obj[k] = res[k];
96
        });
97 98
        form.setFieldsValue({ ...obj });
        setDbForm(val => ({ ...val, ...obj }));
99 100
      }
    });
101 102
    return () => {
      if (time) {
103 104
        clearTimeout(time);
        time = null;
105
      }
106 107
    };
  }, []);
皮倩雯's avatar
皮倩雯 committed
108 109 110 111 112 113 114 115 116 117 118

  // 解密
  const Decrypt = word => {
    let encryptedHexStr = CryptoJS.enc.Hex.parse(word);
    let srcs = CryptoJS.enc.Base64.stringify(encryptedHexStr);
    let decrypt = CryptoJS.AES.decrypt(srcs, key, {
      iv,
      mode: CryptoJS.mode.CBC,
      padding: CryptoJS.pad.Pkcs7,
    });
    let decryptedStr = decrypt.toString(CryptoJS.enc.Utf8);
皮倩雯's avatar
皮倩雯 committed
119
    return decryptedStr?.toString();
皮倩雯's avatar
皮倩雯 committed
120 121 122 123 124 125 126 127 128 129 130 131 132
  };

  //加密
  const Encrypt = word => {
    let srcs = CryptoJS.enc.Utf8.parse(word);
    let encrypted = CryptoJS.AES.encrypt(srcs, key, {
      iv,
      mode: CryptoJS.mode.CBC,
      padding: CryptoJS.pad.Pkcs7,
    });
    return encrypted.ciphertext.toString().toUpperCase();
  };

133 134 135 136
  // 弹出模态框
  const handleShowModal = (key, value) => {
    setModalVisible({ ...modalVisible, [key]: value });
  };
137 138 139 140 141 142
  // 获取数据库连接记录
  const getConnRecordData = () => {
    setTableLoading(true);
    getConnRecordNew()
      .then(resnew => {
        setTableLoading(false);
143
        if (resnew.code === 0) {
144 145 146 147
          let res = resnew.data;
          let arr = res.map((item, index) => {
            item.key = index;
            return item;
张烨's avatar
张烨 committed
148
          });
149
          setData(arr);
张烨's avatar
张烨 committed
150
        }
151 152 153
      })
      .catch(err => {
        setTableLoading(false);
tianfen's avatar
tianfen committed
154
      });
Maofei94's avatar
Maofei94 committed
155
  };
皮倩雯's avatar
皮倩雯 committed
156

张烨's avatar
张烨 committed
157 158 159 160
  const onValuesChange = (value, b) => {
    form.setFieldsValue(value);
  };
  const onChange = value => {
161
    const { length } = value;
张烨's avatar
张烨 committed
162
    form.setFieldsValue({
163
      dbName: value[length - 1],
张烨's avatar
张烨 committed
164 165
    });
  };
张烨's avatar
张烨 committed
166
  // 保存连接
167
  const onFinish = values => {
168
    setCardLoading(true);
张烨's avatar
张烨 committed
169
    const obj = values;
皮倩雯's avatar
皮倩雯 committed
170 171 172 173
    let pwd = obj.password;
    if (obj.password.length < 32 || !isAlphanumeric(obj.password)) {
      pwd = Encrypt(obj.password);
    }
174
    saveConnectionNew({
张烨's avatar
张烨 committed
175 176 177
      ip: obj.ip,
      dbName: obj.dbName,
      userName: obj.userName,
178
      password: pwd,
皮倩雯's avatar
皮倩雯 committed
179
      providerType: obj.providerType,
180
      desc: chooseDb.current.desc,
181 182
    })
      .then(resnew => {
183
        setCardLoading(false);
184
        if (resnew.code === 0) {
皮倩雯's avatar
皮倩雯 committed
185 186 187 188 189
          setFlag(flag + 1);
          setKeepData({
            ip: obj.ip,
            dbName: obj.dbName,
            userName: obj.userName,
190
            password: pwd,
皮倩雯's avatar
皮倩雯 committed
191
          });
192 193
          // setUpData(upData + 1);
          getConnRecordData();
张烨's avatar
张烨 committed
194
          notification.success({
Maofei94's avatar
Maofei94 committed
195
            message: '提示',
张烨's avatar
张烨 committed
196 197 198 199 200 201
            duration: 3,
            description: '保存成功',
          });
        } else {
          notification.error({
            message: '提示',
Maofei94's avatar
Maofei94 committed
202
            duration: 15,
203
            description: resnew.msg,
张烨's avatar
张烨 committed
204 205
          });
        }
206 207 208
      })
      .catch(err => {
        setCardLoading(false);
皮倩雯's avatar
皮倩雯 committed
209 210 211 212 213
        notification.error({
          message: '提示',
          duration: 15,
          description: err,
        });
214
      });
215
  };
皮倩雯's avatar
皮倩雯 committed
216

217
  // 测试连接
张烨's avatar
张烨 committed
218
  const onCheck = e => {
219
    setCardLoading(true);
张烨's avatar
张烨 committed
220
    const obj = form.getFieldsValue();
皮倩雯's avatar
皮倩雯 committed
221 222 223 224
    let pwd = obj.password;
    if (obj.password.length < 32 || !isAlphanumeric(obj.password)) {
      pwd = Encrypt(obj.password);
    }
225 226 227 228
    connectionTest({
      ip: obj.ip,
      dbName: obj.dbName,
      userName: obj.userName,
皮倩雯's avatar
皮倩雯 committed
229
      providerType: obj.providerType,
230
      password: pwd,
张烨's avatar
张烨 committed
231 232
    })
      .then(res => {
233
        setCardLoading(false);
皮倩雯's avatar
皮倩雯 committed
234
        if (res.code == 0 && res.data == true) {
张烨's avatar
张烨 committed
235
          notification.success({
Maofei94's avatar
Maofei94 committed
236
            message: '提示',
张烨's avatar
张烨 committed
237 238 239 240 241 242
            duration: 3,
            description: '连接成功',
          });
        } else {
          notification.error({
            message: '提示',
Maofei94's avatar
Maofei94 committed
243
            duration: 15,
皮倩雯's avatar
皮倩雯 committed
244
            description: res.msg,
张烨's avatar
张烨 committed
245 246 247 248
          });
        }
      })
      .catch(err => {
249
        setCardLoading(false);
张烨's avatar
张烨 committed
250
        console.log(err);
251
      });
张烨's avatar
张烨 committed
252
  };
皮倩雯's avatar
皮倩雯 committed
253 254 255 256 257

  const isAlphanumeric = str => {
    return /^[A-Za-z0-9]+$/.test(str);
  };

Maofei94's avatar
Maofei94 committed
258
  // 获取数据库列表
张烨's avatar
张烨 committed
259 260
  const selectFocus = e => {
    let params = form.getFieldsValue();
皮倩雯's avatar
皮倩雯 committed
261 262 263 264
    let pwd = params.password;
    if (params.password.length < 32 || !isAlphanumeric(params.password)) {
      pwd = Encrypt(params.password);
    }
Maofei94's avatar
Maofei94 committed
265
    getDataBaseList({
张烨's avatar
张烨 committed
266
      userName: params.userName || '',
267
      password: pwd || '',
张烨's avatar
张烨 committed
268
      ip: params.ip || '',
皮倩雯's avatar
皮倩雯 committed
269
      providerType: params.providerType || '',
张烨's avatar
张烨 committed
270 271
    })
      .then(res => {
皮倩雯's avatar
皮倩雯 committed
272 273
        if (res.code == 0) {
          setOption(res.data.root);
张烨's avatar
张烨 committed
274 275
        } else {
          notification.error({
Maofei94's avatar
Maofei94 committed
276
            message: '提示',
Maofei94's avatar
Maofei94 committed
277
            duration: 15,
皮倩雯's avatar
皮倩雯 committed
278
            description: res.msg,
张烨's avatar
张烨 committed
279 280 281 282 283 284 285 286
          });
          setOption([]);
        }
      })
      .catch(err => {
        console.error(err);
      });
  };
张烨's avatar
张烨 committed
287
  // 点击表格回显到表单
张烨's avatar
张烨 committed
288 289
  const tableClick = item => {
    let obj = { ...dbForm };
张烨's avatar
张烨 committed
290
    Object.keys(obj).forEach(k => {
张烨's avatar
张烨 committed
291
      obj[k] = item[k];
张烨's avatar
张烨 committed
292
    });
293
    chooseDb.current = item;
294
    form.setFieldsValue({ ...obj });
张烨's avatar
张烨 committed
295
  };
皮倩雯's avatar
皮倩雯 committed
296

张烨's avatar
张烨 committed
297
  // 展示修改描述
Maofei94's avatar
Maofei94 committed
298 299
  const changeDesc = val => {
    setDesc(val);
300
    handleShowModal('describeVisible', true);
张烨's avatar
张烨 committed
301 302 303 304 305
  };
  const descChange = e => {
    const { value } = e.target;
    setDesc(value);
  };
皮倩雯's avatar
皮倩雯 committed
306

张烨's avatar
张烨 committed
307 308 309
  // 弹窗确认回调
  const modalOkCallback = () => {
    // 更新描述
310
    updateConnDescNew({
皮倩雯's avatar
皮倩雯 committed
311 312 313 314 315
      ip: pickItem.ip,
      dbName: pickItem.dbName,
      userName: pickItem.userName,
      password: pickItem.password,
      providerType: pickItem.providerType,
张烨's avatar
张烨 committed
316
      desc,
317
    })
318 319
      .then(res => {
        if (res.code === 0) {
皮倩雯's avatar
皮倩雯 committed
320
          handleShowModal('describeVisible', false);
321
          getConnRecordData();
Maofei94's avatar
Maofei94 committed
322 323 324
        } else {
          notification.error({
            message: '提示',
皮倩雯's avatar
皮倩雯 committed
325
            duration: 5,
326
            description: res.msg,
Maofei94's avatar
Maofei94 committed
327 328 329 330
          });
        }
      })
      .catch(err => {
皮倩雯's avatar
皮倩雯 committed
331
        handleShowModal('describeVisible', false);
Maofei94's avatar
Maofei94 committed
332 333
      });
  };
皮倩雯's avatar
皮倩雯 committed
334

张烨's avatar
张烨 committed
335 336 337 338 339
  const columns = [
    {
      title: '服务器名或IP地址',
      dataIndex: 'ip',
      key: 'ip',
Maofei94's avatar
Maofei94 committed
340 341
      width: 180,
      ellipsis: true,
皮倩雯's avatar
皮倩雯 committed
342
      align: 'center',
张烨's avatar
张烨 committed
343 344 345 346 347
    },
    {
      title: '数据库名称',
      dataIndex: 'dbName',
      key: 'dbName',
Maofei94's avatar
Maofei94 committed
348 349
      width: 180,
      ellipsis: true,
皮倩雯's avatar
皮倩雯 committed
350
      align: 'center',
张烨's avatar
张烨 committed
351 352 353 354 355
    },
    {
      title: '数据库用户名称',
      dataIndex: 'userName',
      key: 'userName',
Maofei94's avatar
Maofei94 committed
356 357
      width: 180,
      ellipsis: true,
皮倩雯's avatar
皮倩雯 committed
358
      align: 'center',
张烨's avatar
张烨 committed
359 360 361 362 363
    },
    {
      title: '保存时间',
      dataIndex: 'saveTime',
      key: 'saveTime',
Maofei94's avatar
Maofei94 committed
364 365
      width: 180,
      ellipsis: true,
皮倩雯's avatar
皮倩雯 committed
366 367 368 369 370 371 372 373 374
      align: 'center',
    },
    {
      title: '数据库类型',
      dataIndex: 'providerType',
      key: 'providerType',
      width: 180,
      ellipsis: true,
      align: 'center',
张烨's avatar
张烨 committed
375 376 377 378 379
    },
    {
      title: '描述',
      dataIndex: 'desc',
      key: 'desc',
Maofei94's avatar
Maofei94 committed
380
      ellipsis: true,
皮倩雯's avatar
皮倩雯 committed
381
      align: 'center',
张烨's avatar
张烨 committed
382 383
    },
    {
Maofei94's avatar
Maofei94 committed
384 385 386
      title: '操作',
      dataIndex: 'action',
      key: 'action',
Maofei94's avatar
Maofei94 committed
387 388
      width: 250,
      ellipsis: true,
皮倩雯's avatar
皮倩雯 committed
389
      align: 'center',
Maofei94's avatar
Maofei94 committed
390 391 392 393 394
      render: (text, record) => (
        <Space>
          <Button
            type="primary"
            size="small"
皮倩雯's avatar
皮倩雯 committed
395 396
            onClick={e => {
              e.stopPropagation();
Maofei94's avatar
Maofei94 committed
397
              changeDesc(record.desc);
皮倩雯's avatar
皮倩雯 committed
398
              setPickItem(record);
Maofei94's avatar
Maofei94 committed
399 400 401 402 403
            }}
          >
            修改描述
          </Button>
        </Space>
张烨's avatar
张烨 committed
404
      ),
张烨's avatar
张烨 committed
405 406
    },
  ];
皮倩雯's avatar
皮倩雯 committed
407

张烨's avatar
张烨 committed
408 409
  return (
    <>
410
      <PageContainer className={styles.InitDataBaseContainer}>
皮倩雯's avatar
皮倩雯 committed
411
        <Card className={styles.cardTop}>
412
          <Spin tip="loading..." spinning={cardLoading}>
413
            {/* <div className={styles.tableTitle}>数据库初始化</div> */}
414
            <Form
皮倩雯's avatar
皮倩雯 committed
415
              className={styles.cardBottom}
416 417 418 419 420 421
              layout="horizontal"
              labelAlign="left"
              labelCol={{ span: 3 }}
              form={form}
              onFinish={onFinish}
              onValuesChange={onValuesChange}
422
              autoComplete="off"
423
            >
皮倩雯's avatar
皮倩雯 committed
424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442
              <Form.Item
                label="数据库类型"
                name="providerType"
                rules={[
                  {
                    validator: (rule, value) => {
                      if (form.getFieldValue().providerType == '') {
                        return Promise.reject('ip必填');
                      }
                      return Promise.resolve();
                    },
                  },
                ]}
              >
                <Select placeholder="请选择数据库类型">
                  <Select.Option value="SqlServer">SqlServer</Select.Option>
                  <Select.Option value="Dm">Dm</Select.Option>
                </Select>
              </Form.Item>
皮倩雯's avatar
皮倩雯 committed
443 444 445 446 447 448 449 450 451 452 453 454 455 456
              <Form.Item
                label={`${formLables.ip}:`}
                name="ip"
                rules={[
                  {
                    validator: (rule, value) => {
                      if (form.getFieldValue().ip == '') {
                        return Promise.reject('ip必填');
                      }
                      return Promise.resolve();
                    },
                  },
                ]}
              >
457 458
                <Input placeholder="请输入服务器名或IP地址" />
              </Form.Item>
皮倩雯's avatar
皮倩雯 committed
459 460 461 462 463 464 465 466 467 468 469 470 471 472
              <Form.Item
                label={`${formLables.userName}:`}
                name="userName"
                rules={[
                  {
                    validator: (rule, value) => {
                      if (form.getFieldValue().userName == '') {
                        return Promise.reject('用户名称必填');
                      }
                      return Promise.resolve();
                    },
                  },
                ]}
              >
473
                <Input placeholder="请输入用户名称" autoComplete="off" />
474
              </Form.Item>
皮倩雯's avatar
皮倩雯 committed
475
              <Form.Item
476
                label="数据库用户密码"
皮倩雯's avatar
皮倩雯 committed
477 478 479 480 481 482 483 484 485 486 487 488 489
                name="password"
                rules={[
                  {
                    validator: (rule, value) => {
                      console.log(form.getFieldValue().password);
                      if (form.getFieldValue().password == '') {
                        return Promise.reject('用户密码必填');
                      }
                      return Promise.resolve();
                    },
                  },
                ]}
              >
490 491 492 493 494 495
                <Input
                  placeholder="请输入用户密码"
                  type="password"
                  autoComplete="new-password"
                  id="pwd"
                />
496
              </Form.Item>
皮倩雯's avatar
皮倩雯 committed
497
              <Form.Item
498
                label="数据库名称"
皮倩雯's avatar
皮倩雯 committed
499 500 501 502 503 504 505 506 507 508 509 510 511 512 513
                name="dbName"
                rules={[
                  {
                    validator: (rule, value) => {
                      if (
                        form.getFieldValue().dbName == '' ||
                        form.getFieldValue().dbName == undefined
                      ) {
                        return Promise.reject('数据库名称必填');
                      }
                      return Promise.resolve();
                    },
                  },
                ]}
              >
514 515 516 517 518 519 520 521 522 523 524 525 526 527 528
                <Select
                  showSearch
                  mode="tags"
                  placeholder="请选择数据库"
                  optionFilterProp="children"
                  onFocus={() => {
                    selectFocus();
                  }}
                  onChange={e => {
                    onChange(e);
                  }}
                  // eslint-disable-next-line no-shadow
                  filterOption={(input, option) => {
                    return (
                      option.children &&
529
                      option.children.toLowerCase().indexOf(input.toLowerCase()) >= 0
530 531 532 533 534 535 536 537 538 539 540 541
                    );
                  }}
                >
                  {option &&
                    option.length > 0 &&
                    option.map((item, index) => (
                      <Option value={item.value} key={item.value + index}>
                        {item.value}
                      </Option>
                    ))}
                </Select>
              </Form.Item>
Maofei94's avatar
Maofei94 committed
542
              <Form.Item wrapperCol={{ offset: 3 }}>
543 544 545 546
                <div className={styles.tCenter}>
                  <Space size="large" className={styles.btnBox}>
                    <Space>
                      <Button onClick={onCheck}>测试连接</Button>
547
                      <Button type="primary" htmlType="submit" loading={tableLoading}>
548 549 550
                        保存连接
                      </Button>
                    </Space>
Maofei94's avatar
Maofei94 committed
551
                  </Space>
552 553 554 555
                </div>
              </Form.Item>
            </Form>
          </Spin>
张烨's avatar
张烨 committed
556 557
        </Card>

皮倩雯's avatar
皮倩雯 committed
558
        <Card className={styles.cardBottom}>
559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577
          <div className={styles.recordBox}>
            <div className={styles.tableTitle}>近期保存的数据库连接</div>
            <Table
              style={{ marginTop: '20px', marginBottom: '20px' }}
              scroll={{ x: 'max-content', y: 'calc(100vh - 550px)' }}
              columns={columns}
              dataSource={data}
              pagination={false}
              bordered
              loading={tableLoading}
              size="small"
              onRow={record => ({
                onClick: () => {
                  tableClick(record);
                  setFlag(0);
                }, // 点击行
              })}
            />
          </div>
张烨's avatar
张烨 committed
578
        </Card>
579
        <Modal
张烨's avatar
张烨 committed
580
          title="修改链接描述"
581
          visible={modalVisible.describeVisible}
张烨's avatar
张烨 committed
582
          onOk={() => modalOkCallback()}
583
          onCancel={() => handleShowModal('describeVisible', false)}
584
          width="800px"
585
          bodyStyle={{
张烨's avatar
张烨 committed
586
            minHeight: '100px',
587
          }}
张烨's avatar
张烨 committed
588
          cancelText="取消"
Maofei94's avatar
Maofei94 committed
589
          okText="确认"
Maofei94's avatar
Maofei94 committed
590
          destroyOnClose
591
        >
张烨's avatar
张烨 committed
592
          <Row>
593
            <Col span={2} className={styles.decsBox}>
Maofei94's avatar
Maofei94 committed
594
              描述:
张烨's avatar
张烨 committed
595
            </Col>
Maofei94's avatar
Maofei94 committed
596

597
            <Col span={22}>
张烨's avatar
张烨 committed
598 599
              <Input
                placeholder="请输入描述"
Maofei94's avatar
Maofei94 committed
600 601
                allowClear
                defaultValue={desc}
张烨's avatar
张烨 committed
602 603 604 605 606
                onChange={value => {
                  descChange(value);
                }}
              />
            </Col>
607
          </Row>
608
        </Modal>
张烨's avatar
张烨 committed
609 610 611 612
      </PageContainer>
    </>
  );
};
613

张烨's avatar
张烨 committed
614
export default connect()(InitDataBase);