ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [고객 관리 시스템] 2탄
    React 2020. 6. 13. 23:29

    www.youtube.com/watch?v=zug4VBcZOrI&list=PLRx0vPvlEmdD1pSqKZiTihy5rplxecNpz&index=8

    유튜브 나동빈님의 강의를 듣고 시작한 프로젝트입니다.

     

    이번 시간에는 Database에 데이터를 전송하고, 삭제 하는 기능을 추가하는 시간입니다.

     

    실제 Database를 생성 할 것입니다.

     

    아래의 명령어로 customer라는 table을 생성합니다.

    create table customer

     

    이제 사용 될 테이블을 생성합니다.

    CREATE TABLE CUSTOMER (
           id           INT(64),      
           image        VARCHAR(1024),
           name			VARCHAR(64),
           birth	    VARCHAR(64),
           gender       VARCHAR(64),
           job          VARCHAR2(10),
           createdDate  DATETIME,
           isDeleted    INT,
           PRIMARY KEY id
    );
    

     

    아래 INSERT를 이용하여 값을 넣어줍니다.

    INSERT INTO CUSTOMER VALUES ()

     

    select문을 이용하여 Table에 값이 정상적으로 들어갔는지 확인해봅니다.

    select * from customer;

     

     

     

    1. CustomerAdd

    import React from 'react';
    import { post } from 'axios';
    import Dialog from '@material-ui/core/Dialog';
    import DialogActions from '@material-ui/core/DialogActions';
    import DialogTitle from '@material-ui/core/DialogTitle';
    import DialogContent from '@material-ui/core/DialogContent';
    import TextField from '@material-ui/core/TextField';
    import Button from '@material-ui/core/Button';
    
    import {withStyles} from '@material-ui/core/styles';
    
    const styles = theme => ({
        hidden : {
            display :'none'
        }
    })
    
    class CustomerAdd extends React.Component{
        constructor(props) {
            super(props);
            this.state = {
                file : null,
                userName : '',
                birth : '',
                gender : '',
                job : '',
                fileName  : '',
                open : false //dialog open 상태
            };
            this.handleFormSubmit = this.handleFormSubmit.bind(this);
            this.addCustomer = this.addCustomer.bind(this);
            this.handleFileChange = this.handleFileChange.bind(this);
            this.handleValueChange = this.handleValueChange.bind(this);
            this.handleClickOpen = this.handleClickOpen.bind(this);
            this.handleClickClose = this.handleClickClose.bind(this);
        }
    
        handleClickOpen() {
            this.setState({
                open : true
            });
        }
    
        handleClickClose() {
            this.setState({
                file : null,
                userName : '',
                birth : '',
                gender : '',
                job : '',
                fileName  : '',
                open : false
            });
        }
    
    	//모든 값이 설정되고 OK버튼을 누를 시 발생하는 Submit이벤트
        handleFormSubmit(e) {
            e.preventDefault();
            this.addCustomer()
                .then(function(response) {
                    console.log(response.data);
                    //addCustomer가 성공적으로 발생 시 updateCustomer발생
                    this.props.updateCustomer();
                }.bind(this));
                
            this.setState({
                file : null,
                userName : '',
                birth : '',
                gender : '',
                job : '',
                fileName  : '',
                open : false
            });
            //window.location.reload();
        }
    	
        addCustomer(e) {
        	//form형태로 현재 설정된 state값들을 만들어 post로 전달한다.
            const url = '/api/customers';
            const formData = new FormData();
            formData.append('image', this.state.file);
            formData.append('fileName', this.state.fileName);
            formData.append('userName', this.state.userName);
            formData.append('birth', this.state.birth);
            formData.append('gender', this.state.gender);
            formData.append('job', this.state.job);
            //전송할 데이터에 파일이 있을경우
            const config = {
                headers : {
                    'context-type' : 'multipart/form-data'
                }
            }
            return post(url, formData, config);
        }
    
    	//file선택이 될 경우 file, fileName을 설정
        handleFileChange(e) {
            e.preventDefault();
            this.setState({
                file : e.target.files[0],
                fileName : e.target.value
            });
        }
    
    	//직업, 생일, 성별, 직업의 onChange 발생 시 setState를 통하여 값을 넣어줌.
        handleValueChange(e){
            let nextState = {};
            nextState[e.target.name] = e.target.value;
            this.setState(nextState);
        }
    
        render() {
            const {classes} = this.props;
            return(
                <div>
                    <Button variant="contained" color='primary' onClick={this.handleClickOpen.bind(this)}>
                        고객 추가하기
                    </Button>
                    <Dialog open={this.state.open} onClose={this.handleClickClose}>
                        <DialogTitle>고객 추가</DialogTitle>
                        <DialogContent>
                            <input className={classes.hidden} accept="image/*" id="raised-button-file" type='file' file={this.state.file} value={this.state.fileName} onChange={this.handleFileChange}></input>
                            <label htmlFor="raised-button-file">
                                <Button variant="contained" color="primary" component="span" name="file">
                                    {this.state.fileName === "" ? "프로필 이미지 선택" : this.state.fileName}
                                </Button>
                            </label>
                            <br/>  
                            <TextField label="이름" type='text' name='userName' value={this.state.userName} onChange={this.handleValueChange}></TextField><br/>
                            <TextField label="생년월일" type='text' name='birth' value={this.state.birth} onChange={this.handleValueChange}></TextField><br/>
                            <TextField label="성별" type='text' name='gender' value={this.state.gender} onChange={this.handleValueChange}></TextField><br/>
                            <TextField label="직업" type='text' name='job' value={this.state.job} onChange={this.handleValueChange}></TextField><br/>
                        </DialogContent>
                        <DialogActions>
                            <Button variant="contained" color="primary" onClick={this.handleFormSubmit}>
                                추가
                            </Button>
                            <Button variant="outlined" color="primary" onClick={this.handleClickClose}>
                                닫기
                            </Button>
                        </DialogActions>
                    </Dialog>
                </div>
            )
        }
    }
    
    export default withStyles(styles)(CustomerAdd);

     

    2. Server.js

    const fs = require('fs');
    const express = require("express");
    const bodyParse = require("body-parser");
    const app = express();
    const port = process.env.PORT || 5000;
    
    app.use(bodyParse.json());
    app.use(bodyParse.urlencoded({extended : true}));
    
    const data = fs.readFileSync('./database.json');
    
    //npm install --save mysql
    //database 연동을 위한 라이브러리
    const conf = JSON.parse(data);
    const mysql = require('mysql');
    
    const connection = mysql.createConnection({
      host : conf.host,
      user : conf.user,
      password : conf.password,
      port : conf.port,
      database : conf.database
    });
    
    connection.connect();
    
    //파일 처리를 위한 multer 라이브러리
    //npm install --save multer
    const multer = require('multer');
    const upload = multer({dest : './upload'});
    
    
    //database에서 customers table을 가져온다.
    app.get('/api/customers', (req, res) => {
      connection.query(
        // isDeleted가 0인 것만 가져옴
        "SELECT * FROM CUSTOMER WHERE isDeleted = 0",
        (err, rows, fields) => {
          res.send(rows);
        }
      );
    });
    
    app.use('/image', express.static('./upload')); //사용자는 image 폴더로 확인하고 실제 매핑은 ./upload
    
    //table에 새롭게 추가되는 사용자 정보를 추가한다.
    app.post('/api/customers', upload.single('image'), function(req, res) {
      let sql = "INSERT INTO CUSTOMER VALUES (null, ?, ?, ?, ?, ?, now(), 0)";
      let image = '/image/' + req.file.filename;
      let name = req.body.userName;
      let birth = req.body.birth;
      let gender = req.body.gender;
      let job = req.body.job;
      let params = [image, name, birth, gender, job];
      
      connection.query(sql, params, function(err, rows, fields) {
        res.send(rows);
      });
    });
    
    //table에서 사용자를 삭제한다. 실제 databases에서 삭제되지는 않지만, isDelete값으로 구분한다.
    app.delete('/api/customer/:id', function(req, res) {
      let sql = "UPDATE CUSTOMER SET isDeleted = 1 WHERE id = ?";
      let params = [req.params.id];
      connection.query(sql, params, function(err, rows, fields) {
        res.send(rows);
      });
    });
    
    app.listen(port, () => console.log(`Listening on port ${port}`));
    

     

     

     

    3. CustomerDelete

    import React from 'react';
    import Button from '@material-ui/core/Button';
    import Dialog from '@material-ui/core/Dialog';
    import DialogActions from '@material-ui/core/DialogActions';
    import DialogTitle from '@material-ui/core/DialogTitle';
    import DialogContent from '@material-ui/core/DialogContent';
    import TextField from '@material-ui/core/TextField';
    import { Typography } from '@material-ui/core';
    
    class CustomerDelete extends React.Component{
    
        constructor(props) {
            super(props);
            this.state = {
                open : false
            };
        }
        deleteCutomer(id) {
            const url = '/api/customer/' + id;
            fetch(url, {
                method : "DELETE"
            });
            this.props.updateCustomer();
        }
    
        handleDeleteClose() {
            this.setState({
                open : false
            });
        }
        handleDeleteOpen() {
            this.setState({
                open : true
            });
        }
        render() {
    
            return(
                <div>
                <Button variant="contained" color="secondary" onClick={this.handleDeleteOpen.bind(this)}>삭제</Button>
                <Dialog open={this.state.open} onClose={this.handleDeleteClose.bind(this)}>
                    <DialogTitle>삭제</DialogTitle>
                    <DialogContent>
                        <Typography gutterBottom>
                        정말 삭제하시겠습니까?
                        </Typography>
                    </DialogContent>
                    <DialogActions>
                        <Button variant="contained" color="primary" onClick={this.deleteCutomer.bind(this, this.props.id)}>
                                네
                        </Button>
                        <Button variant="outlined" color="primary" onClick={this.handleDeleteClose.bind(this)}>
                                아니오
                        </Button>
                    </DialogActions>
                </Dialog>
                </div>
            )
        }
    }
    
    export default CustomerDelete;

     

    'React' 카테고리의 다른 글

    [고객관리시스템] 1탄  (0) 2020.06.10
    [React] 시작하기  (0) 2020.06.07

    댓글

Designed by Tistory.