246 lines
8.4 KiB
Vue
246 lines
8.4 KiB
Vue
<template>
|
|
<div class="col-md-6 col-lg-4 col-xl-4 order-0 mb-6">
|
|
<div class="card h-100">
|
|
<div class="card-header d-flex justify-content-between">
|
|
<div class="card-title mb-0">
|
|
<h5 class="mb-1 me-2">투표진행</h5>
|
|
</div>
|
|
</div>
|
|
<div class="card-body" v-if="voteListData.length > 0">
|
|
<ul class="p-0 m-0">
|
|
<li class="d-flex mb-1" v-for="item in voteListData" :key="item.LOCVOTSEQ">
|
|
<div class="d-flex w-100 flex-wrap align-items-center justify-content-between gap-2">
|
|
<div class="me-2 mb-3">
|
|
<div class="text-muted small">{{ item.localVote.formatted_LOCVOTRDT }}</div>
|
|
<div class="d-flex flex-wrap align-items-center">
|
|
<div class="avatar flex-shrink-0 me-1">
|
|
<img
|
|
style="cursor: auto;"
|
|
class="rounded-circle user-avatar"
|
|
:src="getProfileImage(item.localVote.MEMBERPRF)"
|
|
alt="최초 작성자"
|
|
:style="{ borderColor: item.localVote.usercolor }"
|
|
@error="setDefaultImage"
|
|
/>
|
|
</div>
|
|
<!-- <div class="timeline-event ps-1" style="cursor: pointer;" @click="goVoteList()" > -->
|
|
<div class="timeline-event ps-1" style="cursor: pointer;" @click.stop="openModal(item.localVote.LOCVOTSEQ)" >
|
|
<div class="timeline-header ">
|
|
<small ><strong>{{ truncateTitle(item.localVote.LOCVOTTTL) }}</strong></small>
|
|
</div>
|
|
|
|
<small class="d-flex align-items-center lh-1 me-4 mb-4 mb-sm-0"
|
|
:style="{ color: getDaysAgo(item.localVote.formatted_LOCVOTEDT) == '금일 종료' ? 'red' : '' }">
|
|
⏰{{getDaysAgo(item.localVote.formatted_LOCVOTEDT)}} ({{item.localVote.total_voted}}/{{ item.localVote.total_votable }})
|
|
</small>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
<div class="card-body" v-else>
|
|
진행중인 투표가 없습니다.
|
|
</div>
|
|
<!-- 모달 푸터: 더보기 버튼 오른쪽 정렬 -->
|
|
<div class="modal-foote d-flex">
|
|
<router-link
|
|
to="/voteboard"
|
|
class="btn btn-primary mr-1 pe-1 ps-1 ms-auto my-auto h-50"
|
|
>
|
|
more
|
|
</router-link>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<!--투표 모달 -->
|
|
<CenterModal :display="isModalOpen" @close="closeModal">
|
|
<template #title> 투표 하기 </template>
|
|
<template #body>
|
|
<div>
|
|
<vote-list
|
|
:key="voteListKey"
|
|
:data="selectVoteDate"
|
|
@checkedNames="checkedNames"
|
|
@addContents="addContents"
|
|
@endVoteId="endVoteId"
|
|
@voteDelete="voteDelete"
|
|
/>
|
|
</div>
|
|
</template>
|
|
<template #footer>
|
|
<BackButton @click="closeModal" />
|
|
</template>
|
|
</CenterModal>
|
|
</template>
|
|
|
|
<script setup>
|
|
import router from '@/router';
|
|
import $api from '@api';
|
|
import { onMounted, ref } from 'vue';
|
|
import CenterModal from '@c/modal/CenterModal.vue';
|
|
import BackButton from '@c/button/BackBtn.vue';
|
|
import voteList from '@c/voteboard/voteCardList.vue';
|
|
import { useToastStore } from '@s/toastStore';
|
|
|
|
const toastStore = useToastStore();
|
|
const currentPage = ref(1);
|
|
const voteset = ref(0);
|
|
const voteListData= ref([]);
|
|
const voteListKey = ref(0); //초기화
|
|
// 로그 모달 상태
|
|
const isModalOpen = ref(false);
|
|
const selectVoteDate = ref([]);
|
|
// 로그 모달 열기
|
|
const openModal = async (id) => {
|
|
isModalOpen.value = true;
|
|
if(id){
|
|
const selectData = voteListData.value.filter((item) => item.localVote.LOCVOTSEQ === id);
|
|
selectVoteDate.value = selectData;
|
|
}
|
|
};
|
|
// 로그 모달 닫기
|
|
const closeModal = () => {
|
|
isModalOpen.value = false;
|
|
voteListKey.value++;
|
|
};
|
|
// 프로필 이미지
|
|
const baseUrl = $api.defaults.baseURL.replace(/api\/$/, '');
|
|
const defaultProfile = "/img/icons/icon.png";
|
|
const getProfileImage = (profilePath) => {
|
|
return profilePath && profilePath.trim() ? `${baseUrl}upload/img/profile/${profilePath}` : defaultProfile;
|
|
};
|
|
const setDefaultImage = (event) => {
|
|
event.target.src = defaultProfile;
|
|
};
|
|
|
|
onMounted(() => {
|
|
getvoteList();
|
|
});
|
|
|
|
//투표목록
|
|
const getvoteList = () => {
|
|
$api.get('vote/getVoteList',{
|
|
params:
|
|
{
|
|
page: 1
|
|
,voteset:'2' //투표중
|
|
,myVote:'2' //내가 안한 투표
|
|
}
|
|
}).then(res => {
|
|
voteListData.value = res.data.data.list;
|
|
voteListData.value = res.data.data.list.slice(0, 6);
|
|
})
|
|
};
|
|
|
|
//투표하기
|
|
const checkedNames = (numList) => {
|
|
$api.post('vote/insertCheckedNums',{
|
|
checkedList :numList
|
|
,votenum : numList[0].LOCVOTSEQ
|
|
}).then((res)=>{
|
|
if(res.data.status === 'OK'){
|
|
toastStore.onToast('투표가 완료되었습니다.', 's');
|
|
isModalOpen.value = false;
|
|
getvoteList();
|
|
voteListKey.value++;
|
|
}
|
|
})
|
|
}
|
|
//투표항목추가
|
|
const addContents = (itemList, voteId) => {
|
|
$api.post('vote/insertWord',{
|
|
itemList :itemList
|
|
,voteId :voteId
|
|
}).then((res)=>{
|
|
if(res.data.status === 'OK'){
|
|
toastStore.onToast('항목이 등록되었습니다.', 's');
|
|
getvoteList();
|
|
const updatedVote = selectVoteDate.value.find(vote => vote.localVote.LOCVOTSEQ === voteId);
|
|
if (updatedVote) {
|
|
if (!updatedVote.voteDetails) {
|
|
updatedVote.voteDetails = [];
|
|
}
|
|
const maxSeq = updatedVote.voteDetails.reduce((max, item) => {
|
|
return item.VOTDETSEQ > max ? item.VOTDETSEQ : max;
|
|
}, 0);
|
|
// 새 항목을 voteDetails에 추가
|
|
itemList.forEach(item => {
|
|
updatedVote.voteDetails.push({
|
|
VOTDETSEQ: maxSeq + 1,
|
|
LOCVOTSEQ: voteId,
|
|
LOCVOTCON: item.content,
|
|
LOCVOTLIK: item.url,
|
|
VOTE_COUNT: 0,
|
|
yesvote: 0
|
|
});
|
|
});
|
|
}
|
|
}
|
|
})
|
|
}
|
|
//투표종료
|
|
const endVoteId = (endVoteId) => {
|
|
$api.patch('vote/updateEndData',{
|
|
endVoteId :endVoteId
|
|
}).then((res)=>{
|
|
if(res.data.status === 'OK'){
|
|
getvoteList();
|
|
isModalOpen.value = false;
|
|
}
|
|
})
|
|
}
|
|
//투표 삭제
|
|
const voteDelete =(id) =>{
|
|
$api.patch('vote/updateDeleteData',{
|
|
deleteVoteId :id
|
|
}).then((res)=>{
|
|
if(res.data.status === 'OK'){
|
|
toastStore.onToast('투표가 삭제되었습니다.', 's');
|
|
getvoteList();
|
|
isModalOpen.value = false;
|
|
}
|
|
})
|
|
}
|
|
// 제목이 14글자 넘어가면 ... 처리하는 함수
|
|
const truncateTitle = title => {
|
|
return title.length > 10 ? title.slice(0, 10) + '...' : title;
|
|
};
|
|
|
|
//투표이동
|
|
const goVoteList = () =>{
|
|
router.push({
|
|
path: '/voteboard',
|
|
query: {
|
|
voteset: '2' //투표중
|
|
,myVote:'2' //내가 안한 투표
|
|
,id:id
|
|
}
|
|
});
|
|
}
|
|
//종료 ㅇㅇ 일 전
|
|
const getDaysAgo = (dateString) => {
|
|
const inputDate = new Date(dateString); // 문자열을 Date 객체로 변환
|
|
const today = new Date(); // 현재 날짜 가져오기
|
|
|
|
const input = new Date(inputDate.getFullYear(), inputDate.getMonth(), inputDate.getDate());
|
|
const now = new Date(today.getFullYear(), today.getMonth(), today.getDate());
|
|
|
|
const timeDiff = now - input;
|
|
const dayDiff = Math.floor(timeDiff / (1000 * 60 * 60 * 24));
|
|
// 오늘 날짜인 경우 "오늘" 반환
|
|
if (dayDiff === 0) return "금일 종료";
|
|
|
|
return `종료 ${Math.abs(dayDiff)}일 전`;
|
|
};
|
|
</script>
|
|
|
|
<style scoped>
|
|
.user-avatar {
|
|
border: 3px solid;
|
|
padding: 0.1px;
|
|
}
|
|
</style>
|