node 2022/02/10

무간·2022년 2월 10일

파일명 routes/seller.js

// 2. 물품전체 조회(판매자 토큰에 해당하는 것만)
// localhost:3000/seller/selectlist
router.get('/selectlist', checkToken, async function(req, res, next) {
    try{
        const email = req.body.uid;
        const dbconn     = await db.connect(dburl);
        const collection = dbconn.db(dbname).collection('item1');     

        const result     = await collection.find(
            { seller : email },
            { projection : { filename:0, filedata:0, filesize:0, filetype:0 } }
        ).sort({ _id : 1 }).toArray();

        // result => [ { result[0] }, { result[1] }, { result[2] }]
        // 변수에 없는키를 넣어야 추가됨. 있는 키는 변경
        for(let i=0; i<result.length; i++){
            result[i]['imageUrl'] = `/seller/image?code=${result[i]._id}&ts=${new Date().getTime()}`;
        }

        console.log(result);
       
        return res.send({status : 200, result:result});
       
        
    }
    catch(e){
        console.error(e);
        res.send({status : -1, message:e});        
    }  
});

============================================

파일명 src/component/seller/Menu1Insert.vue

<template>
    <div>
        <h3>파일명 src/component/seller/Menu1Insert.vue</h3>

        <hr />

        <button @click="handleAdd">항목추가</button>
        <button @click="handleSub">항목삭제</button>
        <hr />

        {{ state.items }}
        <table border="1">
            <tr v-for="(tmp, idx) in state.cnt" :key="tmp">
                <td><input type="file" @change="handleImage($event,idx)"/></td>
                <td><input type="text" v-model="state.items[idx].name" placeholder="물품명" /></td>
                <td><input type="text" v-model="state.items[idx].price" placeholder="가격" /></td>
                <td><input type="text" v-model="state.items[idx].quantity" placeholder="수량" /></td>
                <td><input type="text" v-model="state.items[idx].content" placeholder="설명" /></td>
            </tr>
        </table>
        <hr />
        <button @click="handleInsertAction">일괄추가</button>

    </div>
</template>

<script>
import { reactive } from 'vue';
import axios from 'axios';
import { useRouter } from 'vue-router';

export default {
    setup () {
        const router = useRouter();
        const state = reactive({
            cnt      : 2,
            token    : sessionStorage.getItem("TOKEN"),
            items    : [
                {
                    image    :'',
                    name     :'사과',
                    price    : 1000,
                    quantity : 100,
                    content  : '맛있는 사과',
                },
                {
                    image    :'',
                    name     :'오렌지',
                    price    : 2000,
                    quantity : 200,
                    content  : '맛있는 오렌지',
                },
            ],            
        });

        const handleAdd = () => {
            state.cnt++; // 1씩 증가
            // state.items의 마지막에 { }것을 추가
            state.items.push({ // push는 추가
                image    :'',
                name     :'오렌지',
                price    : 2000,
                quantity : 200,
                content  : '맛있는 오렌지',
            });
        }        

        const handleSub = () => {            
            if( state.cnt >= 3 ) { // 1개를 뺐을때 2이상이면
                state.cnt--;         // 실제적으로 숫자를 뺌
                // pop => state.items의 마지막에 {}것을 제거
                state.items.pop();   // 추가했던 항목의 마지막을 제거함 pop은 제거
            }
        }

        // 파일을 첨부하거나 또는 취소하거나
        const handleImage = (e, idx) =>{
            console.log(e);     // 첨부한 파일 정보
            console.log(idx);   // 위치

            if(e.target.files[0]){
                state.items[idx].image = e.target.files[0];
            }
            else{
                state.items[idx].image ='';
            }

        }

        const handleInsertAction = async() =>{
            const url = `/seller/insert`;
            const headers = { "Content-Type" : "multipart/form-data", "token" : state.token };
            const body = new FormData();
            //state.items => [{},{},{},{}]
            for(let i=0; i<state.items.length; i++){
                body.append("image", state.items[i].image);
                body.append("title", state.items[i].name);
                body.append("price", state.items[i].price);
                body.append("quantity", state.items[i].quantity);
                body.append("content", state.items[i].content);
            }

            const response = await axios.post(url, body, { headers });
            console.log(response);
            if(response.data.status === 200){
                alert('추가가 완료 되었습니다.');
                router.push({name:"Seller"});
            }
            else{
                alert('추가하지 않은 항목을 확인하세요');
            }


        }

        return {state, handleAdd, handleSub, handleInsertAction, handleImage}
    }
}
</script>

<style lang="scss" scoped>

</style>

============================================

파일명 src/components/seller/Menu1.vue

<template>
    <div style="border:1px solid #cccccc;padding:20px;">
        <h3>물품관리</h3>

        <button @click="handlePage">일괄추가</button>
        <button @click="handleDelete">일괄삭제</button>
        <button @click="handleUpdate">일괄수정</button>

        <hr />

            <!-- <el-table :data="state.items" style="width: 100%">
                <el-table-column label="체크"  width="50"><input type="checkbox" /></el-table-column>
                <el-table-column prop="_id" label="물품코드" width="80" />

                <el-table-column  label="이미지">
                    <template #default="scope">
                        <div>                    
                            <img :src="scope.row.imageUrl" style="width:50px; heigh:50px"/>
                        </div>
                    </template></el-table-column>

                <el-table-column prop="name" label="이름" />
                <el-table-column prop="price" label="가격" />
                <el-table-column prop="quantity" label="수량" />
                <el-table-column prop="content" label="내용" />
                <el-table-column prop="regdate" label="등록일자" width="200" />
                <el-table-column label="버튼" >
                    <el-button size="small" type="primary">수정</el-button><br/>
                    <el-button size="small" type="info" @click="handleDeleteAction(item._id)">삭제</el-button>                   
                </el-table-column>
            </el-table> -->
            


        <hr />
        {{state.items}}
        {{state.chk}}

        <table border="1">            

            <thead>
                <tr>
                    <th>체크</th>
                    <th>물품코드</th>
                    <th>이미지</th>
                    <th>이름</th>
                    <th>가격</th>
                    <th>수량</th>
                    <th>내용</th>
                    <th>등록일자</th>
                    <th>버튼</th>
                </tr>                
            </thead>

            
            <tbody>
                <tr v-for="(item, idx) in state.items" :key="item">

                    <td><input type="checkbox" :value="item._id" v-model="state.chk" /></td>

                    <td><button @click="handleDetailPage(item._id)">{{item._id}}</button></td>
                    <td>
                        <img :src="item.imageUrl" style="width:50px; heigh:50px" /><br/>
                        <input type="file" @change="handleImage($event, idx)" />
                    </td>
                    <td><input type="text" v-model="item.name"     style="width:50px"  /></td>
                    <td><input type="text" v-model="item.price"    style="width:50px"  /></td>
                    <td><input type="text" v-model="item.quantity" style="width:50px"  /></td>
                    <td><input type="text" v-model="item.content"  style="width:150px" /></td>                    
                    <td>{{item.regdate}}</td>
                    <td>
                        <button @click="handleUpdateAction(idx)" >수정</button><br/>
                        <button @click="handleDeleteAction([item._id])" >삭제</button>
                    </td>
                </tr>
            </tbody>

        </table>

        

    </div>
</template>

<script>
import { reactive, onMounted } from 'vue';
import { useRouter } from 'vue-router';
import axios from 'axios';

export default {
    setup () {
        const router = useRouter();

        const state = reactive({
            token : sessionStorage.getItem("TOKEN"),      
            chk : []      
        });   

        const handleDetailPage = (code) => {
            router.push({name:'Menu1Detail',query:{code:code}});

        }
        
        const handleUpdate = async() => {
            let arr = [];
            // 전체 개수 (1,2,3,4,5,6,7,8)
            for(let i=0; i<state.items.length; i++){
                // 체크한 개수(2,4,6)
                for(let j=0; j<state.chk.length; j++){

                    // 전체 내용에서 체크한 번호가 일치하면
                    if(state.items[i]._id === state.chk[j]){
                        //console.log(state.items[i]._id, state.chk[j]);
                        // arr변수에 일치하는 것만 저장
                        arr.push(state.items[i]);
                    }

                }
            }
            // arr는 사용자가 체크한 항목만 복사된 변수
            console.log(arr);

            const url =`/seller/update`;
            const headers ={ "Content-Type" : "multipart/form-data", "token" : state.token };
            // {code : [1050], title:['a']}
            const body = new FormData();

            for(let i=0; i<arr.length; i++){
                body.append('image', arr[i].image ); // 배열X
                body.append('code',  arr[i]._id );
                body.append('title', arr[i].name );
                body.append('price', arr[i].price );
                body.append('quantity', arr[i].quantity );
                body.append('content', arr[i].content );
            }

            const response = await axios.put(url, body, { headers });
            console.log(response);            
            if(response.data.status === 200 ){
                alert('수정되었습니다.')
                await handleLoadData();
                state.chk=[];
            }

        }

        const handleUpdateAction = async(idx) => {
            const url =`/seller/update`;
            const headers ={ "Content-Type" : "multipart/form-data", "token" : state.token };
            // {code : [1050], title:['a']}
            const body = new FormData();
            body.append('image', state.items[idx].image ); // 배열X
            body.append('code',  state.items[idx]._id );
            body.append('title', state.items[idx].name );
            body.append('price', state.items[idx].price );
            body.append('quantity', state.items[idx].quantity );
            body.append('content', state.items[idx].content );
            // steat.items => [ { 수정}, { 수정}, { 수정} ]
            // state.items[idx];

            const response = await axios.put(url, body, { headers });
            console.log(response);            
            if(response.data.status === 200 ){
                alert('수정되었습니다.')
                await handleLoadData();
                
            }

        }

        const handleImage = (e, idx) => {
            if(e.target.files[0]){
                state.items[idx].image = e.target.files[0];
            }
            else{
                state.items[idx].image ='';
            }

        }        

        const handleDelete = async() => {                        
            await handleDeleteAction(state.chk);                
        }


        const handleDeleteAction = async(code) => {
            if(confirm('삭제할까요?')){
                const url =`/seller/delete`;
                const headers = {"Content-Type":"application/json", "token":state.token };
                const body = {code:code};
                const response = await axios.delete(url,{headers:headers, data:body});
                console.log(response.data);
                if(response.data.status === 200 ){
                    await handleLoadData();
                    state.chk=[];
                }
            }
        }

        

        const handlePage = () => {
            router.push({name:"Menu1Insert"});

        }

        const handleLoadData = async() => {

            const url =`/seller/selectlist`;
            const headers = { "Content-Type":"application/json", "token":state.token };
            const response = await axios.get(url,{headers});
            console.log(response.data);            

            if(response.data.status === 200 ){
                state.items = response.data.result;
            }

        }

        //생명주기
        onMounted( async()=>{
            await handleLoadData();
            
           
        });
        
        

        return {state, handlePage, handleDeleteAction, handleUpdateAction, handleImage, handleDelete, handleUpdate, handleDetailPage }
    }
}
</script>

<style lang="scss" scoped>

</style>

============================================

파일명 src/component/seller/Menu1Detail.vue

<template>
    <div v-if="state.items">
        <h3>파일명 src/component/seller/Menu1Detail.vue</h3>

        <table border="1">
            <thead>
                <tr>                    
                    <th>물품코드</th>
                    <th>이미지</th>
                    <th>이름</th>
                    <th>가격</th>
                    <th>수량</th>
                    <th>내용</th>
                    <th>등록일자</th>                    
                    <th>서브이미지</th>                    
                </tr>                
            </thead>   
                    
            <tbody>
                <tr>
                    <td>{{state.items._id}}</td>
                    <td><img :src="state.items.imageUrl" style="width:50px; heigh:50px" /></td>
                    <td>{{state.items.name}}</td>
                    <td>{{state.items.price}}</td>
                    <td>{{state.items.quantity}}</td>
                    <td>{{state.items.content}}</td>
                    <td>{{state.items.regdate}}</td>
                    <td>
                        <div v-for="tmp in state.items.subImage" :key="tmp" style="display:inline-block">
                            <img :src="tmp.imageUrl" style="width:50px; heigh:50px" />
                        </div>
                    </td>
                    
                </tr>
            </tbody>
        </table>

        <table border="1">
            <thead>
                <tr>
                    <th>물품코드</th>
                    <td>{{state.items._id}}</td>
                </tr>
                <tr>
                    <th>이미지</th>
                    <td>
                        <img :src="state.items.imageUrl" style="width:50px; heigh:50px" />
                    </td>
                </tr>
                <tr>
                    <th>이름</th>
                    <td>{{state.items.name}}</td>
                </tr>
                <tr>
                    <th>가격</th>
                    <td>{{state.items.price}}</td>
                </tr>
                <tr>
                    <th>수량</th>
                    <td>{{state.items.quantity}}</td>
                </tr>
                <tr>
                    <th>내용</th>
                    <td>{{state.items.content}}</td>
                </tr>
                <tr>
                    <th>등록일자</th>
                    <td>{{state.items.regdate}}</td>
                </tr>
                <tr>
                    <th>서브이미지</th>
                    <td>
                        <div v-for="tmp in state.items.subImage" :key="tmp" style="display:inline-block">
                            <img :src="tmp.imageUrl" style="width:50px; heigh:50px" />
                        </div>
                    </td>
                </tr>
            </thead>
            


        </table>

        


    </div>
</template>

<script>
import { onMounted, reactive } from 'vue';
import { useRoute } from 'vue-router';
import axios from 'axios'

export default {
    setup () {
        const route = useRoute(); // 이동 하기
        const state = reactive({
            code  : route.query.code,
            token : sessionStorage.getItem("TOKEN"),

        })

        // 생명주기 onMounted에서 
        //  /seller/selectone?code=111 을 호출해서 화면에 표시하시오.

         const handleLoadData = async() => {

            const url = `/seller/selectone?code=${state.code}`;
            const headers = { "Content-Type":"application/json", "token":state.token };
            const response = await axios.get(url,{headers});
            console.log(response.data);            

            if(response.data.status === 200 ){
                state.items = response.data.result;
            }

        }

        //생명주기
        onMounted( async()=>{
            await handleLoadData();           
        });

        

        return {state}
    }
}
</script>

<style lang="scss" scoped>

</style>
profile
당신을 한 줄로 소개해보세요

0개의 댓글