Merge branch 'main' into commuters
This commit is contained in:
commit
9087d605e2
@ -37,14 +37,11 @@ $api.interceptors.response.use(
|
|||||||
},
|
},
|
||||||
function (error) {
|
function (error) {
|
||||||
const toastStore = useToastStore();
|
const toastStore = useToastStore();
|
||||||
const currentPage = error.config.headers['X-Page-Route'];
|
|
||||||
// 오류 응답 처리
|
// 오류 응답 처리
|
||||||
if (error.response) {
|
if (error.response) {
|
||||||
switch (error.response.status) {
|
switch (error.response.status) {
|
||||||
case 401:
|
case 401:
|
||||||
if (currentPage === '/login') {
|
if (!error.config.headers.isLogin) {
|
||||||
toastStore.onToast('아이디 혹은 비밀번호가 틀렸습니다.', 'e');
|
|
||||||
} else {
|
|
||||||
toastStore.onToast('인증이 필요합니다.', 'e');
|
toastStore.onToast('인증이 필요합니다.', 'e');
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|||||||
@ -1,18 +1,18 @@
|
|||||||
/*
|
/*
|
||||||
작성자 : 공현지
|
작성자 : 공현지
|
||||||
작성일 : 2025-01-17
|
작성일 : 2025-01-17
|
||||||
수정자 :
|
수정자 :
|
||||||
수정일 :
|
수정일 :
|
||||||
설명 : 공통 스크립트
|
설명 : 공통 스크립트
|
||||||
*/
|
*/
|
||||||
import Quill from 'quill';
|
import Quill from 'quill';
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*템플릿 사용법 : $common.변수
|
*템플릿 사용법 : $common.변수
|
||||||
*setup() 사용법 :
|
*setup() 사용법 :
|
||||||
const { appContext } = getCurrentInstance();
|
const { appContext } = getCurrentInstance();
|
||||||
const $common = appContext.config.globalProperties.$common;
|
const $common = appContext.config.globalProperties.$common;
|
||||||
$common.변수
|
$common.변수
|
||||||
*/
|
*/
|
||||||
const common = {
|
const common = {
|
||||||
// JSON 문자열로 Delta 타입을 변환
|
// JSON 문자열로 Delta 타입을 변환
|
||||||
@ -40,39 +40,39 @@ const common = {
|
|||||||
return null; // Delta 객체가 아니거나 ops가 없을 경우 null 반환
|
return null; // Delta 객체가 아니거나 ops가 없을 경우 null 반환
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
// /**
|
||||||
* Date 타입 문자열 포멧팅
|
// * Date 타입 문자열 포멧팅
|
||||||
*
|
// *
|
||||||
* @param {string} dateStr
|
// * @param {string} dateStr
|
||||||
* @return
|
// * @return
|
||||||
* 1. Date type 인 경우 예시 '25-02-24 12:02'
|
// * 1. Date type 인 경우 예시 '25-02-24 12:02'
|
||||||
* 2. Date type 이 아닌 경우 입력값 리턴
|
// * 2. Date type 이 아닌 경우 입력값 리턴
|
||||||
*
|
// *
|
||||||
*/
|
// */
|
||||||
dateFormatter(dateStr) {
|
// dateFormatter(dateStr) {
|
||||||
const date = new Date(dateStr);
|
// const date = new Date(dateStr);
|
||||||
const dateCheck = date.getTime();
|
// const dateCheck = date.getTime();
|
||||||
|
|
||||||
if (isNaN(dateCheck)) {
|
// if (isNaN(dateCheck)) {
|
||||||
return dateStr;
|
// return dateStr;
|
||||||
} else {
|
// } else {
|
||||||
const { year, month, day, hours, minutes } = this.formatDateTime(date);
|
// const { year, month, day, hours, minutes } = this.formatDateTime(date);
|
||||||
return `${year}-${month}-${day} ${hours}:${minutes}`;
|
// return `${year}-${month}-${day} ${hours}:${minutes}`;
|
||||||
}
|
// }
|
||||||
},
|
// },
|
||||||
|
|
||||||
formatDateTime(date) {
|
// formatDateTime(date) {
|
||||||
const zeroFormat = num => (num < 10 ? `0${num}` : num);
|
// const zeroFormat = num => (num < 10 ? `0${num}` : num);
|
||||||
|
|
||||||
return {
|
// return {
|
||||||
year: date.getFullYear(),
|
// year: date.getFullYear(),
|
||||||
month: zeroFormat(date.getMonth() + 1),
|
// month: zeroFormat(date.getMonth() + 1),
|
||||||
day: zeroFormat(date.getDate()),
|
// day: zeroFormat(date.getDate()),
|
||||||
hours: zeroFormat(date.getHours()),
|
// hours: zeroFormat(date.getHours()),
|
||||||
minutes: zeroFormat(date.getMinutes()),
|
// minutes: zeroFormat(date.getMinutes()),
|
||||||
seconds: zeroFormat(date.getSeconds()),
|
// seconds: zeroFormat(date.getSeconds()),
|
||||||
};
|
// };
|
||||||
},
|
// },
|
||||||
};
|
};
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
|||||||
@ -124,7 +124,7 @@ const toggleComment = () => {
|
|||||||
|
|
||||||
// 부모 컴포넌트에 대댓글 추가 요청
|
// 부모 컴포넌트에 대댓글 추가 요청
|
||||||
const submitComment = (newComment) => {
|
const submitComment = (newComment) => {
|
||||||
emit('submitComment', { parentId: props.comment.commentId, ...newComment });
|
emit('submitComment', { parentId: props.comment.commentId, ...newComment, LOCBRDTYP: newComment.LOCBRDTYP });
|
||||||
isComment.value = false;
|
isComment.value = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -76,26 +76,26 @@ const props = defineProps({
|
|||||||
default: false
|
default: false
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const comment = ref('');
|
const comment = ref('');
|
||||||
const password = ref('');
|
const password = ref('');
|
||||||
const isCheck = ref(props.unknown);
|
const isCheck = ref(false);
|
||||||
|
|
||||||
const emit = defineEmits(['submitComment']);
|
const emit = defineEmits(['submitComment']);
|
||||||
|
|
||||||
watch(() => props.unknown, (newVal) => {
|
|
||||||
isCheck.value = newVal;
|
|
||||||
});
|
|
||||||
|
|
||||||
function handleCommentSubmit() {
|
function handleCommentSubmit() {
|
||||||
|
if (props.unknown && isCheck.value && !password.value) {
|
||||||
|
alert('익명 댓글을 작성하려면 비밀번호를 입력해야 합니다.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const LOCBRDTYP = isCheck.value ? '300102' : null;
|
||||||
emit('submitComment', {
|
emit('submitComment', {
|
||||||
comment: comment.value,
|
comment: comment.value,
|
||||||
password: isCheck.value ? password.value : '',
|
password: isCheck.value ? password.value : '',
|
||||||
|
LOCBRDTYP,
|
||||||
|
isCheck: isCheck.value
|
||||||
});
|
});
|
||||||
|
|
||||||
comment.value = '';
|
comment.value = '';
|
||||||
password.value = '';
|
password.value = '';
|
||||||
|
isCheck.value = false; // 초기화
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -62,11 +62,8 @@ const props = defineProps({
|
|||||||
},
|
},
|
||||||
profileName: {
|
profileName: {
|
||||||
type: String,
|
type: String,
|
||||||
<<<<<<< HEAD
|
|
||||||
default: '익명',
|
default: '익명',
|
||||||
=======
|
|
||||||
default: '',
|
default: '',
|
||||||
>>>>>>> board-comment
|
|
||||||
},
|
},
|
||||||
unknown: {
|
unknown: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
|
|||||||
@ -4,10 +4,6 @@
|
|||||||
</button>
|
</button>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script setup>
|
||||||
export default {
|
|
||||||
name: 'WriteButton',
|
|
||||||
methods: {
|
|
||||||
},
|
|
||||||
};
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -1,55 +1,71 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="card mb-6">
|
<div class="card mb-6">
|
||||||
<div class="card-body">
|
<div class="card-body" v-if="!data.localVote.LOCVOTDEL" >
|
||||||
<h5 class="card-title mb-1"><div class="list-group-item list-group-item-action d-flex align-items-center cursor-pointer">
|
<h5 class="card-title mb-1"><div class="list-group-item list-group-item-action d-flex align-items-center cursor-pointer">
|
||||||
<img
|
<img
|
||||||
class="rounded-circle user-avatar border border-3 w-px-40"
|
class="rounded-circle user-avatar border border-3 w-px-40"
|
||||||
:src="`${baseUrl}upload/img/profile/${data.localVote.MEMBERPRF}`"
|
:src="`${baseUrl}upload/img/profile/${data.localVote.MEMBERPRF}`"
|
||||||
:style="`border-color: ${data.localVote.usercolor} !important;`"
|
:style="`border-color: ${data.localVote.usercolor} !important;`"
|
||||||
alt="user"
|
alt="user"
|
||||||
/>
|
/>
|
||||||
<div class="w-100">
|
<div class="w-100">
|
||||||
<div class="d-flex justify-content-between">
|
<div class="d-flex justify-content-between">
|
||||||
<div class="user-info">
|
<div class="user-info">
|
||||||
<h6 class="mb-1">{{ data.localVote.MEMBERNAM }}</h6>
|
<h6 class="mb-1">{{ data.localVote.MEMBERNAM }}</h6>
|
||||||
|
</div>
|
||||||
|
<div class="add-btn d-flex align-items-center">
|
||||||
|
<!-- 투표완료시 -->
|
||||||
|
<i v-if="data.yesVotetotal == '1'" class="bx bxs-check-circle link-success"></i>
|
||||||
|
<!-- 투표작성자만 수정/삭제/종료 가능 -->
|
||||||
|
<div v-if="userStore.user.id === data.localVote.LOCVOTREG">
|
||||||
|
<button
|
||||||
|
v-if="!data.localVote.LOCVOTDDT"
|
||||||
|
type="button"
|
||||||
|
class="bx btn btn-danger"
|
||||||
|
@click="endBtn(data.localVote.LOCVOTSEQ)"
|
||||||
|
>종료</button>
|
||||||
|
<EditBtn v-if="!data.localVote.LOCVOTDDT" @click="updateVote(data.localVote.LOCVOTSEQ)"/>
|
||||||
|
<DeleteBtn @click="voteDelete(data.localVote.LOCVOTSEQ)" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="add-btn">
|
|
||||||
<!-- 투표완료시 -->
|
|
||||||
<i class="bx bxs-check-circle link-success"></i>
|
|
||||||
<!-- 투표작성자만 수정/삭제/종료 가능 -->
|
|
||||||
<button
|
|
||||||
v-if="userStore.user.id === data.localVote.LOCVOTREG"
|
|
||||||
type="button" class="bx btn btn-danger">종료</button>
|
|
||||||
<EditBtn />
|
|
||||||
<DeleteBtn />
|
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
</h5>
|
||||||
|
<h5>{{ data.localVote.LOCVOTTTL }}</h5>
|
||||||
|
<div class="mb-1">{{ data.localVote.formatted_LOCVOTRDT }} ~ {{ data.localVote.formatted_LOCVOTEDT }}</div>
|
||||||
|
<!-- 투표완료시-->
|
||||||
|
<button v-if="data.yesVotetotal > 0 && !data.localVote.LOCVOTDDT" class="btn btn-primary btn-sm" >재투표</button>
|
||||||
|
<!-- 투표안했을시-->
|
||||||
|
<div v-if="data.localVote.LOCVOTDDT && data.voteResult.length == 0">
|
||||||
|
<small class="text-primary text-uppercase">투표 결과없음 (😂아무도 투표하지 않았습니다)</small>
|
||||||
|
</div>
|
||||||
|
<div v-else>
|
||||||
|
<vote-card-check
|
||||||
|
v-if="data.yesVotetotal == 0"
|
||||||
|
@addContents="addContents"
|
||||||
|
@checkedNames="checkedNames"
|
||||||
|
:data="data.voteDetails"
|
||||||
|
:voteInfo="data.localVote"
|
||||||
|
:total="data.voteDetails.length "/>
|
||||||
|
<!-- 투표완/미완 인원 -->
|
||||||
|
<vote-user-list v-if="!data.localVote.LOCVOTDDT"
|
||||||
|
:data="data.voteMembers"/>
|
||||||
|
<!-- 투표 결과 -->
|
||||||
|
<div v-if="data.localVote.LOCVOTDDT" class="mt-3">
|
||||||
|
<vote-result-list :data="data.voteResult" @randomList="randomList" :randomResultNum="data.localVote.LOCVOTRES"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</h5>
|
<div v-else class="card-body">
|
||||||
<h5>{{ data.localVote.LOCVOTTTL }}</h5>
|
<h5>{{ data.localVote.LOCVOTTTL }}</h5>
|
||||||
<div class="mb-1">{{ data.localVote.formatted_LOCVOTRDT }} ~ {{ data.localVote.formatted_LOCVOTEDT }}</div>
|
삭제된 투표입니다.
|
||||||
<!-- 투표완료시-->
|
|
||||||
<button v-if="data.yesVotetotal > 0" class="btn btn-primary btn-sm" >재투표</button>
|
|
||||||
<!-- 투표안했을시-->
|
|
||||||
<vote-card-check
|
|
||||||
v-if="data.yesVotetotal == 0"
|
|
||||||
@addContents="addContents"
|
|
||||||
@checkedNames="checkedNames"
|
|
||||||
:data="data.voteDetails"
|
|
||||||
:voteInfo="data.localVote"
|
|
||||||
:total="data.voteDetails.length "/>
|
|
||||||
<!-- 투표완/미완 인원 -->
|
|
||||||
<vote-user-list
|
|
||||||
:data="data.voteMembers"/>
|
|
||||||
<!-- 투표 결과 -->
|
|
||||||
<vote-result-list />
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref } from 'vue'
|
import { computed, onMounted, ref } from 'vue'
|
||||||
import EditBtn from '@c/button/EditBtn.vue';
|
import EditBtn from '@c/button/EditBtn.vue';
|
||||||
import DeleteBtn from '@c/button/DeleteBtn.vue';
|
import DeleteBtn from '@c/button/DeleteBtn.vue';
|
||||||
import voteUserList from '@c/voteboard/voteUserList.vue';
|
import voteUserList from '@c/voteboard/voteUserList.vue';
|
||||||
@ -63,19 +79,51 @@ const props = defineProps({
|
|||||||
type: Object,
|
type: Object,
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
|
randomresult: {
|
||||||
|
type: Boolean,
|
||||||
|
required: false,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
const baseUrl = $api.defaults.baseURL.replace(/api\/$/, '');
|
const baseUrl = $api.defaults.baseURL.replace(/api\/$/, '');
|
||||||
|
|
||||||
const userStore = useUserInfoStore();
|
const userStore = useUserInfoStore();
|
||||||
const emit = defineEmits(['addContents','checkedNames']);
|
const currentDate = new Date();
|
||||||
|
const voteEndDate = new Date(props.data.localVote.formatted_LOCVOTEDT.replace(' ', 'T'));
|
||||||
|
voteEndDate.setDate(voteEndDate.getDate() + 1);
|
||||||
|
// 종료 여부 계산
|
||||||
|
const isVoteEnded = computed(() => {
|
||||||
|
return currentDate > voteEndDate;
|
||||||
|
});
|
||||||
|
|
||||||
|
const emit = defineEmits(['addContents','checkedNames','endVoteId','voteEnded','randomList','voteDelete','updateVote']);
|
||||||
|
onMounted(() => {
|
||||||
|
if (isVoteEnded.value && !props.data.localVote.LOCVOTDDT) {
|
||||||
|
emit('voteEnded', { id: props.data.localVote.LOCVOTSEQ });
|
||||||
|
}
|
||||||
|
});
|
||||||
const addContents = (itemList, voteId) =>{
|
const addContents = (itemList, voteId) =>{
|
||||||
emit('addContents',itemList,voteId)
|
emit('addContents',itemList,voteId)
|
||||||
}
|
}
|
||||||
const checkedNames = (numList) =>{
|
const checkedNames = (numList) =>{
|
||||||
emit('checkedNames',numList);
|
emit('checkedNames',numList);
|
||||||
}
|
}
|
||||||
|
const endBtn = (voteid) =>{
|
||||||
|
voteEndDate.setTime(currentDate.getTime()); // 현재 날짜로 설정
|
||||||
|
emit('endVoteId',voteid);
|
||||||
|
}
|
||||||
|
const voteDelete = (voteid) =>{
|
||||||
|
emit('voteDelete',voteid);
|
||||||
|
}
|
||||||
|
const randomList = (random) =>{
|
||||||
|
emit('randomList',random,props.data.localVote.LOCVOTSEQ);
|
||||||
|
}
|
||||||
|
const updateVote = (voteid) =>{
|
||||||
|
emit('updateVote',voteid);
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
.disabled-class {
|
||||||
|
pointer-events: none; /* 클릭 방지 */
|
||||||
|
opacity: 0.5; /* 흐리게 표시 */
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -3,9 +3,15 @@
|
|||||||
<card
|
<card
|
||||||
@addContents="addContents"
|
@addContents="addContents"
|
||||||
@checkedNames="checkedNames"
|
@checkedNames="checkedNames"
|
||||||
|
@endVoteId="endVoteId"
|
||||||
|
@voteEnded="voteEnded"
|
||||||
|
@voteDelete="voteDelete"
|
||||||
|
@randomList="randomList"
|
||||||
|
@updateVote="updateVote"
|
||||||
v-for="(item, index) in data"
|
v-for="(item, index) in data"
|
||||||
:key="index"
|
:key="index"
|
||||||
:data="item" />
|
:data="item"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -16,14 +22,30 @@ const props = defineProps({
|
|||||||
type: Array,
|
type: Array,
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
|
|
||||||
});
|
});
|
||||||
const emit = defineEmits(['addContents','checkedNames']);
|
const emit = defineEmits(['addContents','checkedNames','endVoteId','voteEnded','voteDelete']);
|
||||||
const addContents = (itemList ,voteId) =>{
|
const addContents = (itemList ,voteId) =>{
|
||||||
emit('addContents',itemList ,voteId);
|
emit('addContents',itemList ,voteId);
|
||||||
}
|
}
|
||||||
const checkedNames = (numList) =>{
|
const checkedNames = (numList) =>{
|
||||||
emit('checkedNames',numList);
|
emit('checkedNames',numList);
|
||||||
}
|
}
|
||||||
|
const endVoteId = (VoteId) =>{
|
||||||
|
emit('endVoteId',VoteId);
|
||||||
|
}
|
||||||
|
const voteEnded = (id) =>{
|
||||||
|
emit('voteEnded',id);
|
||||||
|
}
|
||||||
|
const voteDelete = (id) =>{
|
||||||
|
emit('voteDelete',id);
|
||||||
|
}
|
||||||
|
const updateVote = (id) =>{
|
||||||
|
emit('updateVote',id);
|
||||||
|
}
|
||||||
|
const randomList = (randomList , id) =>{
|
||||||
|
emit('randomList',randomList,id);
|
||||||
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@ -2,14 +2,15 @@
|
|||||||
<div>
|
<div>
|
||||||
<ul class="timeline mb-0">
|
<ul class="timeline mb-0">
|
||||||
<li class="timeline-item ps-6 ">
|
<li class="timeline-item ps-6 ">
|
||||||
<span class="timeline-indicator-advanced timeline-indicator-success border-0 shadow-none">
|
<span class="timeline-indicator-advanced timeline-indicator-primary border-0 shadow-none">
|
||||||
<i class="icon-base bx bx-check-circle"></i>
|
<i class="icon-base bx bx-check-circle"></i>
|
||||||
</span>
|
</span>
|
||||||
<div class="timeline-event ps-1">
|
<div class="timeline-event ps-1">
|
||||||
<div class="timeline-header">
|
<div class="timeline-header">
|
||||||
<small class="text-success text-uppercase">투표결과</small>
|
<small class="text-primary text-uppercase">투표결과</small>
|
||||||
</div>
|
</div>
|
||||||
<h6 class="my-50">돼지고기 </h6>
|
<h6 v-if="data" class="my-50">{{ data[0].LOCVOTCON }}</h6>
|
||||||
|
<h6 v-if="randomResultNum" class="my-50">{{randomResultNum }}</h6>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
@ -17,6 +18,16 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
|
const props = defineProps({
|
||||||
|
data: {
|
||||||
|
type: Object,
|
||||||
|
required: false,
|
||||||
|
},
|
||||||
|
randomResultNum: {
|
||||||
|
type: String,
|
||||||
|
required: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@ -2,9 +2,10 @@
|
|||||||
<div class="card mb-6 border border-2 border-primary rounded primary-shadow">
|
<div class="card mb-6 border border-2 border-primary rounded primary-shadow">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<!-- 1위가 여러개일때 -->
|
<!-- 1위가 여러개일때 -->
|
||||||
<vote-result-random />
|
<vote-result-random v-if="topVoters.length > 1" :data="topVoters" :randomResultNum="randomResultNum"
|
||||||
|
@randomList="randomList"/>
|
||||||
<!-- 1위가 하나일때-->
|
<!-- 1위가 하나일때-->
|
||||||
<vote-result-card />
|
<vote-result-card v-if="topVoters.length == 1" :data="topVoters"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -12,6 +13,28 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import voteResultRandom from '@c/voteboard/voteResultRandom.vue';
|
import voteResultRandom from '@c/voteboard/voteResultRandom.vue';
|
||||||
import voteResultCard from '@c/voteboard/voteResultCard.vue';
|
import voteResultCard from '@c/voteboard/voteResultCard.vue';
|
||||||
|
import { computed } from 'vue';
|
||||||
|
const emit = defineEmits(['randomList']);
|
||||||
|
const props = defineProps({
|
||||||
|
data: {
|
||||||
|
type: Array,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
randomResultNum: {
|
||||||
|
type: String,
|
||||||
|
required: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
// 가장 많은 투표를 받은 항목들 (1위)
|
||||||
|
const topVoters = computed(() => {
|
||||||
|
// 가장 높은 VOTE_COUNT 찾기
|
||||||
|
const maxVoteCount = Math.max(...props.data.map(item => item.VOTE_COUNT));
|
||||||
|
// VOTE_COUNT가 가장 높은 항목들 필터링
|
||||||
|
return props.data.filter(item => item.VOTE_COUNT === maxVoteCount);
|
||||||
|
});
|
||||||
|
const randomList = (random) =>{
|
||||||
|
emit('randomList',random);
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
|||||||
@ -1,14 +1,55 @@
|
|||||||
<template>
|
<template>
|
||||||
|
<div v-if="!isRandom && !randomResultNum">
|
||||||
<h6><i class="icon-base bx bx-error icon-lg link-warning"></i> 1위가 중복 되었습니다</h6>
|
<h6><i class="icon-base bx bx-error icon-lg link-warning"></i> 1위가 중복 되었습니다</h6>
|
||||||
<!-- 중복된 1위 리스트 -->
|
<!-- 중복된 1위 리스트 -->
|
||||||
<vote-result-random-list />
|
<vote-result-random-list
|
||||||
|
v-for="(item,index) in data"
|
||||||
|
:key="index"
|
||||||
|
:data="item"
|
||||||
|
:randomResultNum="randomResultNum"/>
|
||||||
|
</div>
|
||||||
|
<div v-if="isRandom === false && randomResultNum">
|
||||||
|
<vote-result-card :randomResultNum="randomResultNum"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button v-if="isRandom" class="btn btn-primary" type="button" disabled="">
|
||||||
|
<span class="spinner-grow me-1" role="status" aria-hidden="true"></span>
|
||||||
|
랜덤뽑기중..
|
||||||
|
</button>
|
||||||
<div class="d-grid w-100 mt-6">
|
<div class="d-grid w-100 mt-6">
|
||||||
<button class="btn btn-primary" data-bs-target="#upgradePlanModal" data-bs-toggle="modal">랜덤 1위 뽑기</button>
|
<button v-if="!isRandom && !randomResultNum" @click="randomList" class="btn btn-primary">랜덤 1위 뽑기</button>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import voteResultRandomList from "@c/voteboard/voteResultRandomList.vue"
|
import voteResultRandomList from "@c/voteboard/voteResultRandomList.vue"
|
||||||
|
import voteResultCard from '@c/voteboard/voteResultCard.vue';
|
||||||
|
import { ref, watch } from "vue";
|
||||||
|
const emit = defineEmits(['randomList']);
|
||||||
|
const props = defineProps({
|
||||||
|
data: {
|
||||||
|
type: Array,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
randomResultNum: {
|
||||||
|
type: String,
|
||||||
|
required: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const isRandom = ref(false);
|
||||||
|
const randomList = () =>{
|
||||||
|
isRandom.value = true;
|
||||||
|
emit('randomList', props.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(() => props.randomResultNum, (newVal) => {
|
||||||
|
if (newVal) {
|
||||||
|
setTimeout(() => {
|
||||||
|
isRandom.value = false;
|
||||||
|
}, 2000);
|
||||||
|
}
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
<ul class="list-unstyled g-2 my-6 ">
|
<ul class="list-unstyled g-2 my-6 ">
|
||||||
<li class="mb-1 d-flex align-items-center ">
|
<li class="mb-1 d-flex align-items-center ">
|
||||||
<div class="d-flex align-items-center lh-1 me-4 mb-4 mb-sm-0">
|
<div class="d-flex align-items-center lh-1 me-4 mb-4 mb-sm-0">
|
||||||
<span class="badge badge-dot text-bg-warning me-1"></span> 돼지고기
|
<span class="badge badge-dot text-bg-warning me-1"></span> {{ data.LOCVOTCON }}
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
@ -11,7 +11,12 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
|
const props = defineProps({
|
||||||
|
data: {
|
||||||
|
type: Object,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
// voteCommon.js
|
// voteCommon.js
|
||||||
import { ref } from "vue";
|
import { ref } from "vue";
|
||||||
|
|
||||||
export function voteCommon(isVOte= false) {
|
export function voteCommon(isVote= false) {
|
||||||
const itemList = ref(isVOte ? [] : [{ content: "", url: "" }, { content: "", url: "" }]);
|
const itemList = ref(isVote ? [] : [{ content: "", url: "" }, { content: "", url: "" }]);
|
||||||
|
|
||||||
const addItem = () => {
|
const addItem = () => {
|
||||||
if (itemList.value.length < 10) {
|
if (itemList.value.length < 10) {
|
||||||
@ -11,9 +11,9 @@ export function voteCommon(isVOte= false) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const removeItem = (index) => {
|
const removeItem = (index) => {
|
||||||
if (!isVOte && index >= 2) {
|
if (!isVote && index >= 2) {
|
||||||
itemList.value.splice(index, 1);
|
itemList.value.splice(index, 1);
|
||||||
} else if (isVOte && itemList.value.length > 0) {
|
} else if (isVote && itemList.value.length > 0) {
|
||||||
itemList.value.splice(index, 1);
|
itemList.value.splice(index, 1);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
15
src/stores/voteDetail.js
Normal file
15
src/stores/voteDetail.js
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import { defineStore } from "pinia";
|
||||||
|
|
||||||
|
export const useVoteStore = defineStore("vote", {
|
||||||
|
state: () => ({
|
||||||
|
selectedVote: {}
|
||||||
|
}),
|
||||||
|
actions: {
|
||||||
|
setVoteData(data) {
|
||||||
|
this.selectedVote = data;
|
||||||
|
},
|
||||||
|
clearVoteData() {
|
||||||
|
this.selectedVote = {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
@ -76,9 +76,9 @@
|
|||||||
@updateReaction="handleUpdateReaction"
|
@updateReaction="handleUpdateReaction"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<p>현재 로그인한 사용자 ID: {{ currentUserId }}</p>
|
<!-- <p>현재 로그인한 사용자 ID: {{ currentUserId }}</p>
|
||||||
<p>게시글 작성자: {{ authorId }}</p>
|
<p>게시글 작성자: {{ authorId }}</p>
|
||||||
<p>isAuthor 값: {{ isAuthor }}</p>
|
<p>isAuthor 값: {{ isAuthor }}</p> -->
|
||||||
<!-- <p>use이미지:{{userStore.user.img}}</p> -->
|
<!-- <p>use이미지:{{userStore.user.img}}</p> -->
|
||||||
<!-- <img :src="`http://localhost:10325/upload/img/profile/${userStore.user.profile}`" alt="Profile Image" class="w-px-40 h-auto rounded-circle"/> -->
|
<!-- <img :src="`http://localhost:10325/upload/img/profile/${userStore.user.profile}`" alt="Profile Image" class="w-px-40 h-auto rounded-circle"/> -->
|
||||||
|
|
||||||
@ -94,6 +94,7 @@
|
|||||||
<BoardCommentArea
|
<BoardCommentArea
|
||||||
:profileName="profileName"
|
:profileName="profileName"
|
||||||
:unknown="unknown"
|
:unknown="unknown"
|
||||||
|
:commentAlert="commentAlert"
|
||||||
:passwordAlert="passwordAlert"
|
:passwordAlert="passwordAlert"
|
||||||
@submitComment="handleCommentSubmit"
|
@submitComment="handleCommentSubmit"
|
||||||
/>
|
/>
|
||||||
@ -139,6 +140,7 @@ import { ref, onMounted, computed } from 'vue';
|
|||||||
import { useRoute, useRouter } from 'vue-router';
|
import { useRoute, useRouter } from 'vue-router';
|
||||||
import { useUserInfoStore } from '@/stores/useUserInfoStore';
|
import { useUserInfoStore } from '@/stores/useUserInfoStore';
|
||||||
import axios from '@api';
|
import axios from '@api';
|
||||||
|
import { formattedDate } from '@/common/formattedDate.js';
|
||||||
|
|
||||||
// 게시물 데이터 상태
|
// 게시물 데이터 상태
|
||||||
const profileName = ref('');
|
const profileName = ref('');
|
||||||
@ -158,22 +160,19 @@ const route = useRoute();
|
|||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const userStore = useUserInfoStore();
|
const userStore = useUserInfoStore();
|
||||||
const currentBoardId = ref(Number(route.params.id));
|
const currentBoardId = ref(Number(route.params.id));
|
||||||
<<<<<<< HEAD
|
|
||||||
const unknown = computed(() => profileName.value === '익명');
|
const unknown = computed(() => profileName.value === '익명');
|
||||||
const currentUserId = ref('김자바'); // 현재 로그인한 사용자 id
|
|
||||||
const authorId = ref(null); // 작성자 id
|
|
||||||
=======
|
|
||||||
// const unknown = computed(() => profileName.value === '익명');
|
|
||||||
const currentUserId = computed(() => userStore.user.id); // 현재 로그인한 사용자 id
|
const currentUserId = computed(() => userStore.user.id); // 현재 로그인한 사용자 id
|
||||||
const authorId = ref(''); // 작성자 id
|
const authorId = ref(''); // 작성자 id
|
||||||
>>>>>>> board-comment
|
|
||||||
|
|
||||||
const isAuthor = computed(() => currentUserId.value === authorId.value);
|
const isAuthor = computed(() => currentUserId.value === authorId.value);
|
||||||
// const isCommentAuthor =
|
|
||||||
const commentsWithAuthStatus = computed(() => {
|
const commentsWithAuthStatus = computed(() => {
|
||||||
const updatedComments = comments.value.map(comment => ({
|
const updatedComments = comments.value.map(comment => ({
|
||||||
...comment,
|
...comment,
|
||||||
isCommentAuthor: comment.authorId === currentUserId.value
|
isCommentAuthor: comment.authorId === currentUserId.value,
|
||||||
|
children: comment.children.map(reply => ({
|
||||||
|
...reply,
|
||||||
|
isCommentAuthor: reply.authorId === currentUserId.value
|
||||||
|
}))
|
||||||
}));
|
}));
|
||||||
// console.log("✅ commentsWithAuthStatus 업데이트됨:", updatedComments);
|
// console.log("✅ commentsWithAuthStatus 업데이트됨:", updatedComments);
|
||||||
return updatedComments;
|
return updatedComments;
|
||||||
@ -188,6 +187,7 @@ const isCommentPassword = ref(false);
|
|||||||
const lastClickedButton = ref("");
|
const lastClickedButton = ref("");
|
||||||
const lastCommentClickedButton = ref("");
|
const lastCommentClickedButton = ref("");
|
||||||
const isEditTextarea = ref(false);
|
const isEditTextarea = ref(false);
|
||||||
|
const commentAlert = ref('')
|
||||||
|
|
||||||
const pagination = ref({
|
const pagination = ref({
|
||||||
currentPage: 1,
|
currentPage: 1,
|
||||||
@ -211,29 +211,21 @@ const fetchBoardDetails = async () => {
|
|||||||
const response = await axios.get(`board/${currentBoardId.value}`);
|
const response = await axios.get(`board/${currentBoardId.value}`);
|
||||||
const data = response.data.data;
|
const data = response.data.data;
|
||||||
|
|
||||||
console.log(data)
|
// console.log(data)
|
||||||
|
|
||||||
// API 응답 데이터 반영
|
// API 응답 데이터 반영
|
||||||
// const boardDetail = data.boardDetail || {};
|
// const boardDetail = data.boardDetail || {};
|
||||||
|
|
||||||
<<<<<<< HEAD
|
|
||||||
profileName.value = data.author || '익명';
|
profileName.value = data.author || '익명';
|
||||||
|
|
||||||
// 익명확인하고 싶을때
|
|
||||||
// profileName.value = 'null;
|
|
||||||
|
|
||||||
// 게시글의 작성자 여부를 확인 : 현재 로그인한 사용자가 이 게시글의 작성자인지 여부
|
|
||||||
authorId.value = data.author;
|
|
||||||
|
|
||||||
=======
|
|
||||||
profileName.value = data.author;
|
|
||||||
|
|
||||||
// 익명확인하고 싶을때
|
// 익명확인하고 싶을때
|
||||||
// profileName.value = '익명';
|
// profileName.value = '익명';
|
||||||
|
|
||||||
|
console.log("📌 게시글 작성자:", profileName.value); // 작성자 이름 출력
|
||||||
|
console.log("🔍 익명 여부 (unknown.value):", unknown.value); // 익명 여부 확인
|
||||||
|
|
||||||
|
|
||||||
authorId.value = data.authorId; //게시글 작성자 id
|
authorId.value = data.authorId; //게시글 작성자 id
|
||||||
>>>>>>> board-comment
|
|
||||||
boardTitle.value = data.title || '제목 없음';
|
boardTitle.value = data.title || '제목 없음';
|
||||||
boardContent.value = data.content || '';
|
boardContent.value = data.content || '';
|
||||||
date.value = data.date || '';
|
date.value = data.date || '';
|
||||||
@ -309,20 +301,14 @@ const fetchComments = async (page = 1) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
<<<<<<< HEAD
|
// console.log(response.data.data)
|
||||||
=======
|
|
||||||
console.log(response.data.data)
|
|
||||||
|
|
||||||
>>>>>>> board-comment
|
|
||||||
const commentsList = response.data.data.list.map(comment => ({
|
const commentsList = response.data.data.list.map(comment => ({
|
||||||
commentId: comment.LOCCMTSEQ, // 댓글 ID
|
commentId: comment.LOCCMTSEQ, // 댓글 ID
|
||||||
boardId: comment.LOCBRDSEQ,
|
boardId: comment.LOCBRDSEQ,
|
||||||
parentId: comment.LOCCMTPNT, // 부모 ID
|
parentId: comment.LOCCMTPNT, // 부모 ID
|
||||||
author: comment.author || '익명',
|
author: comment.author || '익명',
|
||||||
<<<<<<< HEAD
|
|
||||||
=======
|
|
||||||
authorId: comment.authorId,
|
authorId: comment.authorId,
|
||||||
>>>>>>> board-comment
|
|
||||||
content: comment.LOCCMTRPY,
|
content: comment.LOCCMTRPY,
|
||||||
likeCount: comment.likeCount || 0,
|
likeCount: comment.likeCount || 0,
|
||||||
dislikeCount: comment.dislikeCount || 0,
|
dislikeCount: comment.dislikeCount || 0,
|
||||||
@ -340,10 +326,12 @@ const fetchComments = async (page = 1) => {
|
|||||||
params: { LOCCMTPNT: comment.commentId }
|
params: { LOCCMTPNT: comment.commentId }
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log(`대댓글 데이터 (${comment.commentId}의 대댓글):`, replyResponse.data);
|
// console.log(`대댓글 데이터 (${comment.commentId}의 대댓글):`, replyResponse.data);
|
||||||
|
|
||||||
if (replyResponse.data.data) {
|
if (replyResponse.data.data) {
|
||||||
comment.children = replyResponse.data.data.map(reply => ({
|
comment.children = replyResponse.data.data.map(reply => ({
|
||||||
|
author: reply.author || '익명',
|
||||||
|
authorId: reply.authorId,
|
||||||
commentId: reply.LOCCMTSEQ,
|
commentId: reply.LOCCMTSEQ,
|
||||||
boardId: reply.LOCBRDSEQ,
|
boardId: reply.LOCBRDSEQ,
|
||||||
parentId: reply.LOCCMTPNT, // 부모 댓글 ID
|
parentId: reply.LOCCMTPNT, // 부모 댓글 ID
|
||||||
@ -386,29 +374,19 @@ const fetchComments = async (page = 1) => {
|
|||||||
console.log('댓글 목록 불러오기 오류:', error);
|
console.log('댓글 목록 불러오기 오류:', error);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
// const isSubmitting = ref(false);
|
|
||||||
|
|
||||||
// 댓글 작성
|
// 댓글 작성
|
||||||
const handleCommentSubmit = async ({ comment, password }) => {
|
const handleCommentSubmit = async (data) => {
|
||||||
console.log('댓글')
|
const { comment, password } = data;
|
||||||
//비밀번호 입력 안했을시
|
const LOCBRDTYP = data.LOCBRDTYP || null; // undefined 방지
|
||||||
// if (!password) {
|
|
||||||
// passwordAlert.value = "비밀번호를 입력해야 합니다.";
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// console.log('비밀번호 눌렀음')
|
|
||||||
|
|
||||||
// 중복 실행 방지
|
|
||||||
// if (isSubmitting.value) return;
|
|
||||||
// isSubmitting.value = true;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await axios.post(`board/${currentBoardId.value}/comment`, {
|
const response = await axios.post(`board/${currentBoardId.value}/comment`, {
|
||||||
LOCBRDSEQ: currentBoardId.value,
|
LOCBRDSEQ: currentBoardId.value,
|
||||||
LOCCMTRPY: comment,
|
LOCCMTRPY: comment,
|
||||||
LOCCMTPWD: password,
|
LOCCMTPWD: password,
|
||||||
LOCCMTPNT: 1
|
LOCCMTPNT: 1,
|
||||||
|
LOCBRDTYP // 익명 여부 전달
|
||||||
});
|
});
|
||||||
|
|
||||||
if (response.status === 200) {
|
if (response.status === 200) {
|
||||||
@ -426,48 +404,41 @@ const handleCommentSubmit = async ({ comment, password }) => {
|
|||||||
// 대댓글 추가 (부모 `BoardCommentList`로부터 이벤트 받아서 처리)
|
// 대댓글 추가 (부모 `BoardCommentList`로부터 이벤트 받아서 처리)
|
||||||
const handleCommentReply = async (reply) => {
|
const handleCommentReply = async (reply) => {
|
||||||
try {
|
try {
|
||||||
// console.log('대댓글 작성 요청 데이터:', {
|
// 익명 여부 체크 (체크박스가 체크되었을 경우 LOCBRDTYP을 300102로 설정)
|
||||||
// LOCBRDSEQ: currentBoardId.value,
|
|
||||||
// LOCCMTRPY: reply.comment,
|
|
||||||
// LOCCMTPWD: reply.password || null,
|
|
||||||
// LOCCMTPNT: reply.parentId
|
|
||||||
// });
|
|
||||||
|
|
||||||
const response = await axios.post(`board/${currentBoardId.value}/comment`, {
|
const requestBody = {
|
||||||
LOCBRDSEQ: currentBoardId.value,
|
LOCBRDSEQ: currentBoardId.value,
|
||||||
LOCCMTRPY: reply.comment,
|
LOCCMTRPY: reply.comment,
|
||||||
LOCCMTPWD: reply.password || null,
|
LOCCMTPWD: reply.password || null,
|
||||||
LOCCMTPNT: reply.parentId
|
LOCCMTPNT: reply.parentId,
|
||||||
});
|
LOCBRDTYP: reply.isCheck ? "300102" : null
|
||||||
|
};
|
||||||
// 응답 데이터를 자세히 로그로 확인
|
console.log(requestBody)
|
||||||
// console.log('대댓글 작성 응답:', {
|
const response = await axios.post(`board/${currentBoardId.value}/comment`, requestBody);
|
||||||
// status: response.status,
|
|
||||||
// data: response.data,
|
|
||||||
// headers: response.headers
|
|
||||||
// });
|
|
||||||
|
|
||||||
if (response.status === 200) {
|
if (response.status === 200) {
|
||||||
if (response.data.code === 200) { // 서버 응답 코드도 확인
|
if (response.data.code === 200) {
|
||||||
console.log('대댓글 작성 성공:', response.data);
|
console.log('✅ 대댓글 작성 성공:', response.data);
|
||||||
await fetchComments(); // 댓글 목록 새로고침
|
await fetchComments();
|
||||||
} else {
|
} else {
|
||||||
console.log('대댓글 작성 실패 - 서버 응답:', response.data);
|
console.log('❌ 대댓글 작성 실패 - 서버 응답:', response.data);
|
||||||
alert('대댓글 작성에 실패했습니다.');
|
alert('대댓글 작성에 실패했습니다.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('대댓글 작성 중 오류 발생:', error);
|
console.error('🚨 대댓글 작성 중 오류 발생:', error);
|
||||||
if (error.response) {
|
if (error.response) {
|
||||||
console.error('서버 응답 에러:', error.response.data);
|
console.error('📌 서버 응답 에러:', error.response.data);
|
||||||
}
|
}
|
||||||
alert('대댓글 작성 중 오류가 발생했습니다.');
|
alert('❌ 대댓글 작성 중 오류가 발생했습니다.');
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
// 게시글 수정 버튼 클릭
|
// 게시글 수정 버튼 클릭
|
||||||
const editClick = (unknown) => {
|
const editClick = (unknown) => {
|
||||||
if (unknown) {
|
const isUnknown = unknown?.unknown ?? false;
|
||||||
|
|
||||||
|
if (isUnknown) {
|
||||||
togglePassword("edit");
|
togglePassword("edit");
|
||||||
} else {
|
} else {
|
||||||
router.push({ name: "BoardEdit", params: { id: currentBoardId.value } });
|
router.push({ name: "BoardEdit", params: { id: currentBoardId.value } });
|
||||||
@ -483,47 +454,50 @@ const deleteClick = (unknown) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const findCommentById = (commentId, commentsList) => {
|
||||||
|
for (const comment of commentsList) {
|
||||||
|
if (comment.commentId === commentId) {
|
||||||
|
return comment; // 부모 댓글일 경우
|
||||||
|
}
|
||||||
|
if (comment.children && comment.children.length) {
|
||||||
|
const found = findCommentById(commentId, comment.children);
|
||||||
|
if (found) return found; // 대댓글일 경우
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
// 댓글 수정 버튼 클릭
|
// 댓글 수정 버튼 클릭
|
||||||
const editComment = (comment) => {
|
const editComment = (comment) => {
|
||||||
const targetComment = comments.value.find(c => c.commentId === comment.commentId);
|
console.log('대댓글 수정 버튼 클릭')
|
||||||
|
|
||||||
|
// 부모 또는 대댓글을 찾아서 가져오기
|
||||||
|
const targetComment = findCommentById(comment.commentId, comments.value);
|
||||||
|
|
||||||
if (!targetComment) {
|
if (!targetComment) {
|
||||||
|
console.log("대댓글을 찾을 수 없음:", comment.commentId);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 수정 text창 열림, 닫힘 유무
|
// 수정 text창 열림, 닫힘 유무 토글
|
||||||
if (targetComment.isEditTextarea) {
|
targetComment.isEditTextarea = !targetComment.isEditTextarea;
|
||||||
targetComment.isEditTextarea = false;
|
|
||||||
} else {
|
|
||||||
targetComment.isEditTextarea = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 익명일때
|
// 익명일 경우 비밀번호 입력창 활성화
|
||||||
if (unknown.value) {
|
if (unknown.value) {
|
||||||
toggleCommentPassword(comment, "edit");
|
toggleCommentPassword(comment, "edit");
|
||||||
} else {
|
|
||||||
comment.isEditTextarea = true;
|
|
||||||
}
|
}
|
||||||
<<<<<<< HEAD
|
|
||||||
|
|
||||||
// comments.value.forEach(c => {
|
|
||||||
// c.isEditTextarea = false;
|
|
||||||
// c.isCommentPassword = false;
|
|
||||||
// });
|
|
||||||
|
|
||||||
// if (comment.unknown) {
|
|
||||||
// comment.isCommentPassword = true;
|
|
||||||
// } else {
|
|
||||||
// comment.isEditTextarea = true;
|
|
||||||
// }
|
|
||||||
=======
|
|
||||||
>>>>>>> board-comment
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 댓글 삭제 버튼 클릭
|
// 댓글 삭제 버튼 클릭
|
||||||
const deleteComment = async (comment) => {
|
const deleteComment = async (comment) => {
|
||||||
|
console.log('🗑 댓글 삭제 시도:', comment);
|
||||||
|
|
||||||
// 익명 사용자인 경우
|
// 익명 사용자인 경우
|
||||||
if (unknown.value) {
|
const isMyComment = comment.authorId === currentUserId.value;
|
||||||
|
|
||||||
|
if (unknown.value && !isMyComment) {
|
||||||
|
console.log('🛑 익명 사용자의 댓글 삭제 시도 (비밀번호 필요)');
|
||||||
|
|
||||||
if (comment.isEditTextarea) {
|
if (comment.isEditTextarea) {
|
||||||
// 현재 수정 중이라면 수정 모드를 끄고, 삭제 비밀번호 입력창을 띄움
|
// 현재 수정 중이라면 수정 모드를 끄고, 삭제 비밀번호 입력창을 띄움
|
||||||
comment.isEditTextarea = false;
|
comment.isEditTextarea = false;
|
||||||
@ -533,8 +507,8 @@ const deleteComment = async (comment) => {
|
|||||||
toggleCommentPassword(comment, "delete");
|
toggleCommentPassword(comment, "delete");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// 로그인 사용자인 경우 (바로 삭제)
|
console.log('✅ 로그인 사용자 댓글 삭제 진행');
|
||||||
deleteReplyComment(comment)
|
deleteReplyComment(comment);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -626,11 +600,8 @@ const submitCommentPassword = async (comment, password) => {
|
|||||||
|
|
||||||
if (lastCommentClickedButton.value === "edit") {
|
if (lastCommentClickedButton.value === "edit") {
|
||||||
comment.isEditTextarea = true;
|
comment.isEditTextarea = true;
|
||||||
<<<<<<< HEAD
|
|
||||||
=======
|
|
||||||
passwordCommentAlert.value = "";
|
passwordCommentAlert.value = "";
|
||||||
|
|
||||||
>>>>>>> board-comment
|
|
||||||
// handleSubmitEdit(comment, comment.content);
|
// handleSubmitEdit(comment, comment.content);
|
||||||
} else if (lastCommentClickedButton.value === "delete") {
|
} else if (lastCommentClickedButton.value === "delete") {
|
||||||
passwordCommentAlert.value = "";
|
passwordCommentAlert.value = "";
|
||||||
@ -704,19 +675,20 @@ const handleSubmitEdit = async (comment, editedContent) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// 수정 성공 시 업데이트
|
// 수정 성공 시 업데이트
|
||||||
<<<<<<< HEAD
|
|
||||||
comment.content = editedContent;
|
|
||||||
comment.isEditTextarea = false;
|
|
||||||
=======
|
|
||||||
// comment.content = editedContent;
|
// comment.content = editedContent;
|
||||||
// comment.isEditTextarea = false;
|
// comment.isEditTextarea = false; f
|
||||||
if (response.status === 200) {
|
if (response.status === 200) {
|
||||||
// 댓글 목록 새로고침
|
|
||||||
await fetchComments();
|
const targetComment = findCommentById(comment.commentId, comments.value);
|
||||||
|
if (targetComment) {
|
||||||
|
targetComment.content = editedContent; // 댓글 내용 업데이트
|
||||||
|
targetComment.isEditTextarea = false; // 수정 모드 닫기
|
||||||
|
} else {
|
||||||
|
console.warn("❌ 수정할 댓글을 찾을 수 없음");
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
console.log("❌ 댓글 수정 실패:", response.data);
|
console.log("❌ 댓글 수정 실패:", response.data);
|
||||||
}
|
}
|
||||||
>>>>>>> board-comment
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("댓글 수정 중 오류 발생:", error);
|
console.error("댓글 수정 중 오류 발생:", error);
|
||||||
}
|
}
|
||||||
@ -724,13 +696,10 @@ const handleSubmitEdit = async (comment, editedContent) => {
|
|||||||
|
|
||||||
// 댓글 수정 취소 (대댓글 포함)
|
// 댓글 수정 취소 (대댓글 포함)
|
||||||
const handleCancelEdit = (comment) => {
|
const handleCancelEdit = (comment) => {
|
||||||
console.log("BoardView.vue - 댓글 수정 취소:", comment);
|
const targetComment = findCommentById(comment.commentId, comments.value);
|
||||||
|
|
||||||
// 원본 comments 배열에서 동일한 comment 찾기
|
|
||||||
const targetComment = comments.value.find(c => c.commentId === comment.commentId);
|
|
||||||
|
|
||||||
if (targetComment) {
|
if (targetComment) {
|
||||||
console.log("✅ 원본 데이터 찾음, 수정 취소 처리 가능");
|
console.log("✅ 원본 데이터 찾음, 수정 취소 처리 가능:", targetComment);
|
||||||
targetComment.isEditTextarea = false;
|
targetComment.isEditTextarea = false;
|
||||||
} else {
|
} else {
|
||||||
console.error("❌ 원본 데이터 찾을 수 없음, 수정 취소 실패");
|
console.error("❌ 원본 데이터 찾을 수 없음, 수정 취소 실패");
|
||||||
@ -745,15 +714,26 @@ const handlePageChange = (page) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 댓글 삭제 (대댓글 포함)
|
||||||
const handleCommentDeleted = (deletedCommentId) => {
|
const handleCommentDeleted = (deletedCommentId) => {
|
||||||
comments.value = comments.value.filter(comment => comment.commentId !== deletedCommentId);
|
// 댓글 삭제
|
||||||
};
|
const parentIndex = comments.value.findIndex(comment => comment.commentId === deletedCommentId);
|
||||||
|
|
||||||
// 날짜
|
if (parentIndex !== -1) {
|
||||||
const formattedDate = (dateString) => {
|
comments.value.splice(parentIndex, 1);
|
||||||
if (!dateString) return "날짜 없음";
|
return;
|
||||||
const dateObj = new Date(dateString);
|
}
|
||||||
return `${dateObj.getFullYear()}-${String(dateObj.getMonth() + 1).padStart(2, '0')}-${String(dateObj.getDate()).padStart(2, '0')} ${String(dateObj.getHours()).padStart(2, '0')}:${String(dateObj.getMinutes()).padStart(2, '0')}`;
|
|
||||||
|
// 2대댓글 삭제
|
||||||
|
for (let parent of comments.value) {
|
||||||
|
const childIndex = parent.children.findIndex(child => child.commentId === deletedCommentId);
|
||||||
|
if (childIndex !== -1) {
|
||||||
|
parent.children.splice(childIndex, 1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.error("❌ 삭제할 댓글을 찾을 수 없음:", deletedCommentId);
|
||||||
};
|
};
|
||||||
|
|
||||||
const formattedBoardDate = computed(() => formattedDate(date.value));
|
const formattedBoardDate = computed(() => formattedDate(date.value));
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
<template>
|
<template>
|
||||||
<RouterView />
|
<RouterView />
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name : 'voteboard',
|
name : 'voteboard',
|
||||||
inheritAttrs : false,
|
inheritAttrs : false,
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@ -3,39 +3,46 @@
|
|||||||
<div class="row g-3">
|
<div class="row g-3">
|
||||||
<div class="mt-8">
|
<div class="mt-8">
|
||||||
<!-- 투표 작성 -->
|
<!-- 투표 작성 -->
|
||||||
<router-link to="/voteboard/write"><WriteBtn /></router-link>
|
<WriteBtn @click="voteWrite" />
|
||||||
<!-- 내가한 투표 보기 -->
|
|
||||||
<div class="d-flex align-items-center">
|
|
||||||
<div class="form-check me-3">
|
|
||||||
<input class="form-check-input" type="checkbox" value="" id="deliveryAdd" checked="">
|
|
||||||
<label class="form-check-label" for="deliveryAdd">내가 한 투표</label>
|
|
||||||
</div>
|
|
||||||
<!-- 투표마감/투표중 셀렉트 -->
|
<!-- 투표마감/투표중 셀렉트 -->
|
||||||
<FormSelect class="col-3" name="cate" :isLabel="false" title="투표상태" :data="categoryList" @update:data="category = $event" />
|
<FormSelect class="col-3" name="cate" :isLabel="false" title="투표상태" :data="categoryList" @update:data="category = $event" @change="selectHandler"/>
|
||||||
|
<!-- 내가한 투표 보기 -->
|
||||||
|
<div class="p-4">
|
||||||
|
<div class="form-check">
|
||||||
|
<input class="form-check-input" type="checkbox" value="" id="defaultCheck1" v-model="ischeked" @change="changeCheck">
|
||||||
|
<label class="form-check-label" for="defaultCheck1"> 내가 한 투표 </label>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 투표리스트 -->
|
<!-- 투표리스트 -->
|
||||||
|
<div v-if="!voteListCardData" class="mt66"> ❌❌등록된 투표가 없습니다.❌❌</div>
|
||||||
<vote-list
|
<vote-list
|
||||||
:data="voteListCardData"
|
:data="voteListCardData"
|
||||||
@addContents="addContents"
|
@addContents="addContents"
|
||||||
@checkedNames="checkedNames"/>
|
@checkedNames="checkedNames"
|
||||||
|
@endVoteId="endVoteId"
|
||||||
|
@voteEnded="voteEnded"
|
||||||
|
@voteDelete="voteDelete"
|
||||||
|
@updateVote="updateVote"
|
||||||
|
@randomList="randomList"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- 페이지네이션 -->
|
||||||
|
<div class="row g-3">
|
||||||
|
<div class="mt-8">
|
||||||
|
<Pagination
|
||||||
|
v-if="PageData.pages"
|
||||||
|
v-bind="PageData"
|
||||||
|
@update:currentPage="handlePageChange"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- 페이지네이션 -->
|
|
||||||
<div class="row g-3">
|
|
||||||
<div class="mt-8">
|
|
||||||
<Pagination
|
|
||||||
v-if="PageData.pages"
|
|
||||||
v-bind="PageData"
|
|
||||||
@update:currentPage="handlePageChange"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup>
|
<script setup>
|
||||||
import { getCurrentInstance, onMounted, ref } from 'vue';
|
import { getCurrentInstance, onMounted, ref } from 'vue';
|
||||||
import Pagination from '@c/pagination/Pagination.vue';
|
import Pagination from '@c/pagination/Pagination.vue';
|
||||||
import router from '@/router';
|
|
||||||
import FormSelect from '@c/input/FormSelect.vue';
|
import FormSelect from '@c/input/FormSelect.vue';
|
||||||
import { useToastStore } from '@s/toastStore';
|
import { useToastStore } from '@s/toastStore';
|
||||||
import QEditor from '@c/editor/QEditor.vue';
|
import QEditor from '@c/editor/QEditor.vue';
|
||||||
@ -43,30 +50,58 @@ import $api from '@api';
|
|||||||
import Quill from 'quill';
|
import Quill from 'quill';
|
||||||
import WriteBtn from '@c/button/WriteBtn.vue';
|
import WriteBtn from '@c/button/WriteBtn.vue';
|
||||||
import voteList from '@c/voteboard/voteCardList.vue';
|
import voteList from '@c/voteboard/voteCardList.vue';
|
||||||
|
import { useVoteStore } from '@s/voteDetail';
|
||||||
|
import { useRouter } from 'vue-router';
|
||||||
|
|
||||||
const toastStore = useToastStore();
|
const toastStore = useToastStore();
|
||||||
const category = ref('0');
|
const category = ref('0');
|
||||||
const categoryList = ['전체','투표마감', '투표중'];
|
const categoryList = ['전체','투표마감','투표중'];
|
||||||
const PageData = ref([]);
|
const PageData = ref([]);
|
||||||
const voteListCardData = ref([]);
|
const voteListCardData = ref([]);
|
||||||
const titleAlert = ref(false);
|
const titleAlert = ref(false);
|
||||||
const addContent = ref('');
|
const addContent = ref('');
|
||||||
const currentPage = ref(1);
|
const currentPage = ref(1);
|
||||||
|
const voteset = ref(0);
|
||||||
|
const ischeked = ref(false);
|
||||||
|
const selectedVote = ref({}); // 선택된 투표 데이터
|
||||||
|
const router = useRouter();
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
getvoteList();
|
getvoteList();
|
||||||
});
|
});
|
||||||
|
const voteStore = useVoteStore();
|
||||||
|
//글작성
|
||||||
|
const voteWrite = () => {
|
||||||
|
voteStore.setVoteData(selectedVote.value);
|
||||||
|
console.log("Pinia 상태 업데이트됨:", voteStore.selectedVote);
|
||||||
|
router.push('/voteboard/write');
|
||||||
|
};
|
||||||
|
|
||||||
|
const changeCheck = () =>{
|
||||||
|
getvoteList();
|
||||||
|
}
|
||||||
//투표목록
|
//투표목록
|
||||||
const getvoteList = async () => {
|
const getvoteList = async () => {
|
||||||
console.log('pagee',currentPage.value)
|
const response = await $api.get('vote/getVoteList',{
|
||||||
const response = await $api.get('vote/getVoteList',{
|
params:
|
||||||
params: { page: currentPage.value }
|
{
|
||||||
});
|
page: currentPage.value
|
||||||
if (response.data.status === "OK") {
|
,voteset:voteset.value
|
||||||
PageData.value = response.data.data;
|
,myVote:ischeked.value ? '1':'0'
|
||||||
voteListCardData.value = response.data.data.list;
|
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
|
if (response.data.status === "OK") {
|
||||||
|
PageData.value = response.data.data;
|
||||||
|
voteListCardData.value = response.data.data.list;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const selectHandler = () =>{
|
||||||
|
voteset.value = category.value;
|
||||||
|
getvoteList();
|
||||||
|
}
|
||||||
|
|
||||||
//투표항목추가
|
//투표항목추가
|
||||||
const addContents = (itemList, voteId) =>{
|
const addContents = (itemList, voteId) => {
|
||||||
$api.post('vote/insertWord',{
|
$api.post('vote/insertWord',{
|
||||||
itemList :itemList
|
itemList :itemList
|
||||||
,voteId :voteId
|
,voteId :voteId
|
||||||
@ -78,7 +113,7 @@ const addContents = (itemList, voteId) =>{
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
//투표하기
|
//투표하기
|
||||||
const checkedNames = (numList) =>{
|
const checkedNames = (numList) => {
|
||||||
$api.post('vote/insertCheckedNums',{
|
$api.post('vote/insertCheckedNums',{
|
||||||
checkedList :numList
|
checkedList :numList
|
||||||
,votenum : numList[0].LOCVOTSEQ
|
,votenum : numList[0].LOCVOTSEQ
|
||||||
@ -89,7 +124,50 @@ const checkedNames = (numList) =>{
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
//투표종료
|
||||||
|
const endVoteId = (endVoteId) => {
|
||||||
|
$api.patch('vote/updateEndData',{
|
||||||
|
endVoteId :endVoteId
|
||||||
|
}).then((res)=>{
|
||||||
|
if(res.data.status === 'OK'){
|
||||||
|
toastStore.onToast('투표가 종료되었습니다.', 's');
|
||||||
|
getvoteList();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
//기한 지난 투표 종료
|
||||||
|
const voteEnded = async (id) =>{
|
||||||
|
await endVoteId(id.id);
|
||||||
|
}
|
||||||
|
//투표 삭제
|
||||||
|
const voteDelete =(id) =>{
|
||||||
|
$api.patch('vote/updateDeleteData',{
|
||||||
|
deleteVoteId :id
|
||||||
|
}).then((res)=>{
|
||||||
|
if(res.data.status === 'OK'){
|
||||||
|
toastStore.onToast('투표가 삭제되었습니다.', 's');
|
||||||
|
getvoteList();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
//랜덤 1위 뽑기
|
||||||
|
const randomList = (data,id) =>{
|
||||||
|
$api.post('vote/randomList',{
|
||||||
|
randomList :data
|
||||||
|
,voteid:id
|
||||||
|
}).then((res)=>{
|
||||||
|
if(res.data.status === 'OK'){
|
||||||
|
toastStore.onToast('랜덤뽑기 진행되었습니다.', 's');
|
||||||
|
getvoteList();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
//수정
|
||||||
|
const updateVote = (id) =>{
|
||||||
|
const voteData = voteListCardData.value.find((item) => item.localVote.LOCVOTSEQ === id);
|
||||||
|
selectedVote.value = voteData;
|
||||||
|
voteWrite();
|
||||||
|
}
|
||||||
// 페이지 변경
|
// 페이지 변경
|
||||||
const handlePageChange = async (page) => {
|
const handlePageChange = async (page) => {
|
||||||
currentPage.value=page;
|
currentPage.value=page;
|
||||||
|
|||||||
@ -5,66 +5,66 @@
|
|||||||
<div class="user-list-container">
|
<div class="user-list-container">
|
||||||
<ul class="timeline mb-1">
|
<ul class="timeline mb-1">
|
||||||
<li class="timeline-item timeline-item-transparent">
|
<li class="timeline-item timeline-item-transparent">
|
||||||
<span class="timeline-point timeline-point-info"></span>
|
<span class="timeline-point timeline-point-info"></span>
|
||||||
<div class="timeline-event">
|
<div class="timeline-event">
|
||||||
<div class="timeline-header mb-2">
|
<div class="timeline-header mb-2">
|
||||||
<h6 class="mb-0">투표 인원</h6>
|
<h6 class="mb-0">투표 인원</h6>
|
||||||
</div>
|
</div>
|
||||||
<UserList @userListInfo="userSet" @user-list-update="handleUserListUpdate" class="mb-3" />
|
<UserList @userListInfo="userSet" @user-list-update="handleUserListUpdate" class="mb-3" />
|
||||||
<div v-if="UserListAlert" class="red">2명이상 선택해주세요 </div>
|
<div v-if="UserListAlert" class="red">2명이상 선택해주세요 </div>
|
||||||
<form-input
|
<form-input
|
||||||
title="제목"
|
title="제목"
|
||||||
name="title"
|
name="title"
|
||||||
:is-essential="true"
|
:is-essential="true"
|
||||||
:is-alert="titleAlert"
|
:is-alert="titleAlert"
|
||||||
v-model="title"
|
:v-model="title"
|
||||||
/>
|
|
||||||
<form-input
|
|
||||||
title="종료날짜"
|
|
||||||
name="endDate"
|
|
||||||
type="date"
|
|
||||||
:is-essential="true"
|
|
||||||
:is-alert="endDateAlert"
|
|
||||||
v-model="endDate"
|
|
||||||
/>
|
|
||||||
<!-- 항목 입력 반복 -->
|
|
||||||
<div v-for="(item, index) in itemList" :key="index" class="d-flex align-items-center mb-2 position-relative">
|
|
||||||
<form-input
|
|
||||||
class="flex-grow-1 me-2"
|
|
||||||
:title="'항목 ' + (index + 1)"
|
|
||||||
:name="'content' + index"
|
|
||||||
:is-essential="index < 2"
|
|
||||||
:is-alert="contentAlerts[index]"
|
|
||||||
v-model="item.content"
|
|
||||||
/>
|
|
||||||
<link-input v-model="item.url" />
|
|
||||||
<delete-btn @click="removeItem(index)" :disabled="index < 2" class="ms-2" />
|
|
||||||
</div>
|
|
||||||
<plus-btn @click="addItem" :disabled="itemList.length >= 10" class="mb-3" />
|
|
||||||
<div>
|
|
||||||
<label class="list-group-item">
|
|
||||||
<input
|
|
||||||
class="form-check-input me-1"
|
|
||||||
type="checkbox"
|
|
||||||
id="addvoteitem"
|
|
||||||
v-model="addvoteitem"
|
|
||||||
/>
|
|
||||||
항목 추가여부
|
|
||||||
</label>
|
|
||||||
<label class="list-group-item">
|
|
||||||
<input
|
|
||||||
class="form-check-input me-1"
|
|
||||||
type="checkbox"
|
|
||||||
id="addvotemulti"
|
|
||||||
v-model="addvotemulti"
|
|
||||||
/>
|
/>
|
||||||
다중투표 허용여부
|
<form-input
|
||||||
</label>
|
title="종료날짜"
|
||||||
|
name="endDate"
|
||||||
|
type="date"
|
||||||
|
:is-essential="true"
|
||||||
|
:is-alert="endDateAlert"
|
||||||
|
v-model="endDate"
|
||||||
|
:min="today"
|
||||||
|
/>
|
||||||
|
<!-- 항목 입력 반복 -->
|
||||||
|
<div v-for="(item, index) in itemList" :key="index" class="d-flex align-items-center mb-2 position-relative">
|
||||||
|
<form-input
|
||||||
|
class="flex-grow-1 me-2"
|
||||||
|
:title="'항목 ' + (index + 1)"
|
||||||
|
:name="'content' + index"
|
||||||
|
:is-essential="index < 2"
|
||||||
|
:is-alert="contentAlerts[index]"
|
||||||
|
v-model="item.content"
|
||||||
|
/>
|
||||||
|
<link-input v-model="item.url" />
|
||||||
|
<delete-btn @click="removeItem(index)" :disabled="index < 2" class="ms-2" />
|
||||||
|
</div>
|
||||||
|
<plus-btn @click="addItem" :disabled="itemList.length >= 10" class="mb-3" />
|
||||||
|
<div>
|
||||||
|
<label class="list-group-item">
|
||||||
|
<input
|
||||||
|
class="form-check-input me-1"
|
||||||
|
type="checkbox"
|
||||||
|
id="addvoteitem"
|
||||||
|
v-model="addvoteitem"
|
||||||
|
/>
|
||||||
|
항목 추가여부
|
||||||
|
</label>
|
||||||
|
<label class="list-group-item">
|
||||||
|
<input
|
||||||
|
class="form-check-input me-1"
|
||||||
|
type="checkbox"
|
||||||
|
id="addvotemulti"
|
||||||
|
v-model="addvotemulti"
|
||||||
|
/>
|
||||||
|
다중투표 허용여부
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<div class="mb-4 d-flex justify-content-end">
|
<div class="mb-4 d-flex justify-content-end">
|
||||||
<button type="button" class="btn btn-info" @click="goList">
|
<button type="button" class="btn btn-info" @click="goList">
|
||||||
<i class="bx bx-left-arrow-alt"></i>
|
<i class="bx bx-left-arrow-alt"></i>
|
||||||
@ -80,7 +80,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, toRaw } from "vue";
|
import { onMounted, ref, toRaw } from "vue";
|
||||||
import UserList from "@c/user/UserList.vue";
|
import UserList from "@c/user/UserList.vue";
|
||||||
import formInput from "@c/input/FormInput.vue";
|
import formInput from "@c/input/FormInput.vue";
|
||||||
import { useToastStore } from "@s/toastStore";
|
import { useToastStore } from "@s/toastStore";
|
||||||
@ -90,7 +90,12 @@ import $api from "@api";
|
|||||||
import router from "@/router";
|
import router from "@/router";
|
||||||
import LinkInput from "@/components/voteboard/voteLinkInput.vue";
|
import LinkInput from "@/components/voteboard/voteLinkInput.vue";
|
||||||
import { voteCommon } from '@s/voteCommon';
|
import { voteCommon } from '@s/voteCommon';
|
||||||
|
import { useUserStore } from '@s/userList';
|
||||||
|
import { useRoute } from "vue-router";
|
||||||
|
import { useVoteStore } from "@s/voteDetail";
|
||||||
|
|
||||||
|
const userStore = useUserStore();
|
||||||
|
const today = new Date().toISOString().substring(0, 10);
|
||||||
const toastStore = useToastStore();
|
const toastStore = useToastStore();
|
||||||
const activeUserList = ref([]);
|
const activeUserList = ref([]);
|
||||||
const disabledUsers = ref([]);
|
const disabledUsers = ref([]);
|
||||||
@ -101,7 +106,6 @@ const UserListAlert = ref(false);
|
|||||||
const title = ref("");
|
const title = ref("");
|
||||||
const endDate = ref("");
|
const endDate = ref("");
|
||||||
const { itemList, addItem, removeItem } = voteCommon();
|
const { itemList, addItem, removeItem } = voteCommon();
|
||||||
|
|
||||||
const userListTotal = ref(0);
|
const userListTotal = ref(0);
|
||||||
const addvoteitem = ref(false);
|
const addvoteitem = ref(false);
|
||||||
const addvotemulti= ref(false);
|
const addvotemulti= ref(false);
|
||||||
@ -111,6 +115,13 @@ const userSet = ({ userList, userTotal }) => {
|
|||||||
userListTotal.value = userTotal;
|
userListTotal.value = userTotal;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const voteStore = useVoteStore();
|
||||||
|
|
||||||
|
onMounted(()=>{
|
||||||
|
console.log('상세데이터',voteStore.selectedVote);
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
const handleUserListUpdate = ({ activeUsers, disabledUsers: updatedDisabledUsers }) => {
|
const handleUserListUpdate = ({ activeUsers, disabledUsers: updatedDisabledUsers }) => {
|
||||||
activeUserList.value = activeUsers;
|
activeUserList.value = activeUsers;
|
||||||
disabledUsers.value = updatedDisabledUsers;
|
disabledUsers.value = updatedDisabledUsers;
|
||||||
@ -119,56 +130,51 @@ const handleUserListUpdate = ({ activeUsers, disabledUsers: updatedDisabledUsers
|
|||||||
|
|
||||||
const saveValid = () => {
|
const saveValid = () => {
|
||||||
let valid = true;
|
let valid = true;
|
||||||
|
if (disabledUsers.value.length === 0) {
|
||||||
|
activeUserList.value = [...userStore.userList];
|
||||||
|
}
|
||||||
if (title.value === '') {
|
if (title.value === '') {
|
||||||
titleAlert.value = true;
|
titleAlert.value = true;
|
||||||
valid = false;
|
valid = false;
|
||||||
} else {
|
} else {
|
||||||
titleAlert.value = false;
|
titleAlert.value = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (endDate.value === '') {
|
if (endDate.value === '') {
|
||||||
endDateAlert.value = true;
|
endDateAlert.value = true;
|
||||||
valid = false;
|
valid = false;
|
||||||
} else {
|
} else {
|
||||||
endDateAlert.value = false;
|
endDateAlert.value = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (itemList.value[0].content === '') {
|
if (itemList.value[0].content === '') {
|
||||||
contentAlerts.value[0] = true;
|
contentAlerts.value[0] = true;
|
||||||
valid = false;
|
valid = false;
|
||||||
} else {
|
} else {
|
||||||
contentAlerts.value[0] = false;
|
contentAlerts.value[0] = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (itemList.value[1].content === '') {
|
if (itemList.value[1].content === '') {
|
||||||
contentAlerts.value[1] = true;
|
contentAlerts.value[1] = true;
|
||||||
valid = false;
|
valid = false;
|
||||||
} else {
|
} else {
|
||||||
contentAlerts.value[1] = false;
|
contentAlerts.value[1] = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (activeUserList.value.length < 2) {
|
if (activeUserList.value.length < 2) {
|
||||||
UserListAlert.value = true;
|
UserListAlert.value = true;
|
||||||
valid = false;
|
valid = false;
|
||||||
} else {
|
} else {
|
||||||
UserListAlert.value = false;
|
UserListAlert.value = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (valid) {
|
if (valid) {
|
||||||
saveVote();
|
saveVote();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const saveVote = () => {
|
const saveVote = () => {
|
||||||
console.log('activeUserList',activeUserList.value)
|
|
||||||
const unwrappedUserList = toRaw(activeUserList.value);
|
const unwrappedUserList = toRaw(activeUserList.value);
|
||||||
const listId = unwrappedUserList.map(item => ({
|
const listId = unwrappedUserList.map(item => ({
|
||||||
id: item.MEMBERSEQ,
|
id: item.MEMBERSEQ,
|
||||||
}));
|
}));
|
||||||
$api.post('vote/insertWord',{
|
$api.post('vote/insertWord',{
|
||||||
addvoteIs :addvoteitem ? '1' :'0'
|
addvoteIs :addvoteitem.value === false ? '0' :'1'
|
||||||
,votemMltiIs :addvotemulti ? '1' :'0'
|
,votemMltiIs: addvotemulti.value === false ? '0' : '1'
|
||||||
,title :title.value
|
,title :title.value
|
||||||
,endDate :endDate.value
|
,endDate :endDate.value
|
||||||
,itemList :itemList.value
|
,itemList :itemList.value
|
||||||
@ -180,11 +186,9 @@ const saveVote = () => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
const goList = () => {
|
const goList = () => {
|
||||||
router.push('/voteboard');
|
router.push('/voteboard');
|
||||||
};
|
};
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user