메인 -용어집 투표진행 추가가

This commit is contained in:
khj0414 2025-04-01 16:16:42 +09:00
parent 453f1d46f7
commit 61a3041a5e
4 changed files with 232 additions and 62 deletions

View File

@ -8,46 +8,118 @@
</div>
<div class="card-body">
<ul class="p-0 m-0">
<li class="d-flex align-items-center mb-5">
<li class="d-flex mb-1" v-for="item in voteList" :key="item.LOCVOTSEQ">
<div class="d-flex w-100 flex-wrap align-items-center justify-content-between gap-2">
<div class="me-2">
<div class="me-2 mb-3">
<small class="card-subtitle">{{ item.localVote.formatted_LOCVOTEDT }}</small>
<div class="d-flex flex-wrap align-items-center">
<div class="avatar avatar-sm me-2">
<img src="../../assets/img/avatars/1.png" alt="Avatar" class="rounded-circle"
@error="$event.target.src = '/img/icons/icon.png'">
<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>
<p class="mb-0 fw-medium">12 회식투표</p>
<div class="timeline-event ps-1" style="cursor: pointer;" @click="goVoteList()" >
<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"><span class="badge badge-dot text-bg-warning me-1">
</span> {{ getDaysAgo(item.localVote.formatted_LOCVOTEDT) }}</small>
</div>
<small>2025-01-02 11:20~2025-01-02 11:20</small>
</div>
<div class="d-flex w-100 flex-wrap align-items-center justify-content-between gap-2">
<div class="me-2">
<div class="d-flex flex-wrap align-items-center">
<div class="avatar avatar-sm me-2">
<img src="../../assets/img/avatars/1.png" alt="Avatar" class="rounded-circle"
@error="$event.target.src = '/img/icons/icon.png'">
</div>
<div>
<p class="mb-0 fw-medium">커피타임 장소 투표해요</p>
</div>
</div>
<small>2025-01-02 11:20~2025-01-02 11:20</small>
</div>
</div>
</div>
</li>
</ul>
</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>
</template>
<script setup>
import router from '@/router';
import $api from '@api';
import { onMounted, ref } from 'vue';
//
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;
};
const currentPage = ref(1);
const voteset = ref(0);
const voteList= ref([]);
onMounted(() => {
getvoteList();
});
//
const getvoteList = () => {
$api.get('vote/getVoteList',{
//
params:
{
page: 1
,voteset:'2' //
,myVote:'2' //
}
}).then(res => {
voteList.value = res.data.data.list;
voteList.value = res.data.data.list.slice(0, 5);
})
};
// 14 ...
const truncateTitle = title => {
return title.length > 14 ? title.slice(0, 14) + '...' : title;
};
//
const goVoteList = () =>{
router.push({
path: '/voteboard',
query: {
voteset: '2',
}
});
}
//
const getDaysAgo = (dateString) => {
const inputDate = new Date(dateString); // Date
const today = new Date(); //
// ( )
const timeDiff = today - inputDate;
const dayDiff = Math.floor(timeDiff / (1000 * 60 * 60 * 24))+1; //
// ""
if (dayDiff === 0) return "금일 종료";
return `종료 ${Math.abs(dayDiff)}일 전`;
};
</script>
<style scoped>
.user-avatar {
border: 3px solid;
padding: 0.1px;
}
</style>

View File

@ -7,39 +7,125 @@
</div>
</div>
<div class="card-body">
<ul class="p-0 m-0">
<li class="d-flex align-items-center mb-5">
<div class="avatar flex-shrink-0 me-3">
<span class="avatar-initial rounded bg-label-primary"><span class="avatar-initial rounded bg-label-primary"><span class="avatar-initial rounded bg-label-primary">it</span></span></span>
<ul class="p-0 m-0" v-for="item in wordList" :key="item.WRDDICSEQ">
<small class="card-subtitle">{{$common.dateFormatter(item.lastEditor.updatedAt)}}</small>
<li class="d-flex mb-1">
<div class="avatar flex-shrink-0 me-1" >
<img
style="cursor: auto;"
class="rounded-circle user-avatar"
:src="getProfileImage(item.lastEditor.profileImage)"
alt="최종 작성자"
:style="{ borderColor: item.lastEditor.color }"
@error="setDefaultImage"
/>
</div>
<div class="d-flex w-100 flex-wrap align-items-center justify-content-between gap-2">
<div class="me-2">
<h6 class="mb-0">css</h6>
<small>class 주는방법은 ...</small>
</div>
</div>
</li>
<li class="d-flex align-items-center mb-5">
<div class="avatar flex-shrink-0 me-3">
<span class="avatar-initial rounded bg-label-primary"><span class="avatar-initial rounded bg-label-primary"><span class="avatar-initial rounded bg-label-primary">it</span></span></span>
</div>
<div class="d-flex w-100 flex-wrap align-items-center justify-content-between gap-2">
<div class="me-2">
<h6 class="mb-0">css</h6>
<small>class 주는방법은 ...</small>
<div class="timeline-event ps-1" style="cursor: pointer;" @click="goWordList(item.WRDDICCAT,item.WRDDICTTL)">
<div class="timeline-header">
<small class="text-primary text-uppercase">{{ item.category }}</small>
</div>
<h6 class="my-50">{{truncateTitle(item.WRDDICTTL) }}</h6>
</div>
</li>
</ul>
</div>
<!-- 모달 푸터: 더보기 버튼 오른쪽 정렬 -->
<div class="modal-foote d-flex ">
<router-link
to="/wordDict"
class="btn btn-primary mr-1 pe-1 ps-1 ms-auto my-auto h-50"
>
more
</router-link>
</div>
</div>
</div>
</template>
<script setup>
import axios from '@api';
import { getCurrentInstance, onMounted, ref } from 'vue';
import { useRouter } from 'vue-router';
import commonApi from '@/common/commonApi';
const { appContext } = getCurrentInstance();
const $common = appContext.config.globalProperties.$common;
const router = useRouter();
onMounted(() => {
getwordList();
});
//
const baseUrl = axios.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;
};
const wordList = ref([]);
//
const getwordList = (searchKeyword='', indexKeyword='', category='') => {
axios.get('worddict/getWordList',{
params: {
searchKeyword : searchKeyword,
indexKeyword :indexKeyword,
category : category,
pageNum:5
}
})
.then(res => {
wordList.value = res.data.data.data;
});
};
// /
const getFirstCharacter = (char) => {
const CHOSUNG_LIST = [
'ㄱ', 'ㄲ', 'ㄴ', 'ㄷ', 'ㄸ', 'ㄹ', 'ㅁ', 'ㅂ', 'ㅃ', 'ㅅ',
'ㅆ', 'ㅇ', 'ㅈ', 'ㅉ', 'ㅊ', 'ㅋ', 'ㅌ', 'ㅍ', 'ㅎ'
];
if (!char || char.length === 0) return '';
const code = char.charCodeAt(0);
// (~)
if (code >= 0xAC00 && code <= 0xD7A3) {
const index = Math.floor((code - 0xAC00) / (21 * 28));
return CHOSUNG_LIST[index];
}
//
if (char.match(/[a-zA-Z]/)) {
return char.toLowerCase();
}
// (, )
return char;
};
//
const goWordList = (category, indexKeyword) => {
const firstChar = getFirstCharacter(indexKeyword[0]); //
router.push({
path: '/wordDict',
query: {
indexKeyword: firstChar,
category: category
}
});
};
// 14 ...
const truncateTitle = title => {
return title.length > 25 ? title.slice(0, 25) + '...' : title;
};
</script>
<style scoped>
.user-avatar {
border: 3px solid;
padding: 0.1px;
}
</style>

View File

@ -57,7 +57,7 @@ import $api from '@api';
import Quill from 'quill';
import WriteBtn from '@c/button/WriteBtn.vue';
import voteList from '@c/voteboard/voteCardList.vue';
import { useRouter } from 'vue-router';
import { useRoute, useRouter } from 'vue-router';
const toastStore = useToastStore();
const category = ref('0');
@ -71,8 +71,12 @@ const voteset = ref(0);
const ischeked = ref(false);
const selectedVote = ref({}); //
const router = useRouter();
const route = useRoute();
onMounted(async () => {
onMounted(() => {
const maincvoteset = route.query.voteset || '0';
voteset.value =maincvoteset;
category.value = maincvoteset;
getvoteList();
});
//

View File

@ -54,18 +54,21 @@
</template>
<script setup>
import { ref, computed, onMounted, getCurrentInstance, toRaw } from 'vue';
import axios from '@api';
import SearchBar from '@c/search/SearchBar.vue';
import WriteButton from '@c/button/WriteBtn.vue';
import CategoryBtn from '@/components/category/CategoryBtn.vue';
import DictCard from '@/components/wordDict/DictCard.vue';
import DictWrite from '@/components/wordDict/DictWrite.vue';
import DictAlphabetFilter from '@/components/wordDict/DictAlphabetFilter.vue';
import commonApi from '@/common/commonApi';
import { useToastStore } from '@s/toastStore';
import { useWriteVisibleStore } from '@s/writeVisible';
import LoadingSpinner from "@v/LoadingPage.vue";
import { ref, computed, onMounted, getCurrentInstance, toRaw } from 'vue';
import axios from '@api';
import SearchBar from '@c/search/SearchBar.vue';
import WriteButton from '@c/button/WriteBtn.vue';
import CategoryBtn from '@/components/category/CategoryBtn.vue';
import DictCard from '@/components/wordDict/DictCard.vue';
import DictWrite from '@/components/wordDict/DictWrite.vue';
import DictAlphabetFilter from '@/components/wordDict/DictAlphabetFilter.vue';
import commonApi from '@/common/commonApi';
import { useToastStore } from '@s/toastStore';
import { useWriteVisibleStore } from '@s/writeVisible';
import LoadingSpinner from "@v/LoadingPage.vue";
import { useRoute } from 'vue-router';
const route = useRoute();
//
const writeStore = useWriteVisibleStore();
@ -111,6 +114,11 @@
onMounted(() => {
getIndex();
writeStore.closeAll();
const mainindexKeyword = route.query.indexKeyword || '';
const maincategory = route.query.category || '';
selectedAlphabet.value = mainindexKeyword;
selectedCategory.value = maincategory;
getwordList('', selectedAlphabet.value, selectedCategory.value );
});
const refreshWordList = (category) => {