373 lines
16 KiB
Vue
373 lines
16 KiB
Vue
<template>
|
|
<!-- Comments-->
|
|
<section aria-labelledby="notes-title">
|
|
<div
|
|
class="border border-gray-300 shadow sm:rounded-lg sm:overflow-hidden"
|
|
>
|
|
<div class="divide-y divide-gray-200">
|
|
<div class="px-4 py-5 sm:px-6">
|
|
<h2
|
|
id="notes-title"
|
|
class="text-lg font-medium text-gray-900"
|
|
>
|
|
{{ title }}
|
|
</h2>
|
|
</div>
|
|
<div class="px-4 py-6 sm:px-6">
|
|
<ul role="list" class="space-y-8">
|
|
<li
|
|
v-for="commentItem in listData"
|
|
:key="commentItem.serial"
|
|
>
|
|
<div class="flex space-x-3">
|
|
<div class="flex-shrink-0 items-center">
|
|
<BaseAvater1
|
|
:image-size="2"
|
|
:image-url="commentItem.profile_url"
|
|
/>
|
|
</div>
|
|
|
|
<div>
|
|
<div class="text-sm">
|
|
<a
|
|
:href="
|
|
'/user/profile/' +
|
|
commentItem.pid
|
|
"
|
|
class="font-medium text-gray-900"
|
|
>{{ commentItem.nick }}</a
|
|
>
|
|
</div>
|
|
<div
|
|
class="mt-1 text-sm text-gray-700 break-all"
|
|
>
|
|
<p>{{ commentItem.comment }}</p>
|
|
</div>
|
|
<div class="mt-2 text-sm space-x-2">
|
|
<span
|
|
class="text-gray-500 font-medium"
|
|
>{{
|
|
$dayjs(
|
|
commentItem.created
|
|
).fromNow()
|
|
}}</span
|
|
>
|
|
{{ ' ' }}
|
|
<span
|
|
v-if="!readOnlyFlag"
|
|
class="text-gray-500 font-medium"
|
|
>·</span
|
|
>
|
|
{{ ' ' }}
|
|
|
|
<span
|
|
v-if="commentItem.like_count != 0"
|
|
class="text-gray-500 font-medium"
|
|
>{{
|
|
'좋아요 ' +
|
|
_utils.formatNumberInBytesStyle(
|
|
commentItem.like_count,
|
|
0
|
|
) +
|
|
'개'
|
|
}}</span
|
|
>
|
|
<span
|
|
v-if="
|
|
commentItem.dislike_count != 0
|
|
"
|
|
class="text-gray-500 font-medium"
|
|
>{{
|
|
'싫어요 ' +
|
|
_utils.formatNumberInBytesStyle(
|
|
commentItem.dislike_count,
|
|
0
|
|
) +
|
|
'개'
|
|
}}</span
|
|
>
|
|
<span
|
|
v-if="commentItem.report_count != 0"
|
|
class="text-gray-500 font-medium"
|
|
>{{
|
|
'신고 ' +
|
|
_utils.formatNumberInBytesStyle(
|
|
commentItem.report_count,
|
|
0
|
|
) +
|
|
'개'
|
|
}}</span
|
|
>
|
|
|
|
<button
|
|
v-if="
|
|
commentItem.myFlag == true &&
|
|
!readOnlyFlag
|
|
"
|
|
type="button"
|
|
class="text-gray-900 font-medium"
|
|
@click="
|
|
doAction(
|
|
'delete',
|
|
commentItem.cid
|
|
)
|
|
"
|
|
>
|
|
삭제
|
|
</button>
|
|
<button
|
|
v-if="!readOnlyFlag"
|
|
type="button"
|
|
class="text-gray-900 font-medium"
|
|
@click="
|
|
doAction(
|
|
'like',
|
|
commentItem.cid
|
|
)
|
|
"
|
|
>
|
|
좋아요
|
|
</button>
|
|
<button
|
|
v-if="!readOnlyFlag"
|
|
type="button"
|
|
class="text-gray-900 font-medium"
|
|
@click="
|
|
doAction(
|
|
'dislike',
|
|
commentItem.cid
|
|
)
|
|
"
|
|
>
|
|
싫어요
|
|
</button>
|
|
|
|
<button
|
|
v-if="!readOnlyFlag"
|
|
type="button"
|
|
class="text-gray-900 font-medium"
|
|
@click="
|
|
doAction(
|
|
'report',
|
|
commentItem.cid
|
|
)
|
|
"
|
|
>
|
|
신고
|
|
</button>
|
|
|
|
<button
|
|
v-if="!readOnlyFlag"
|
|
type="button"
|
|
class="text-gray-900 font-medium"
|
|
@click="
|
|
doAction(
|
|
'cancel',
|
|
commentItem.cid
|
|
)
|
|
"
|
|
>
|
|
신고 취소
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</li>
|
|
<li v-if="listData.length == 0">
|
|
<div>등록된 댓글이 없습니다.</div>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
<BasePagination1
|
|
class="mb-5 px-4 sm:px-6"
|
|
:total-page-count="totalPageCount"
|
|
:current-page-number="currentPageNumber"
|
|
:page-size="pageSize"
|
|
:records-total="recordsTotal"
|
|
:page-move="pageMove"
|
|
/>
|
|
</div>
|
|
<div v-if="!readOnlyFlag" class="bg-gray-50 px-4 py-6 sm:px-6">
|
|
<div class="flex space-x-3">
|
|
<div class="flex-shrink-0">
|
|
<BaseUserProfileImage :image-size="2" />
|
|
</div>
|
|
<div class="min-w-0 flex-1">
|
|
<form>
|
|
<div>
|
|
<label for="comment" class="sr-only">{{
|
|
title
|
|
}}</label>
|
|
<textarea
|
|
id="comment"
|
|
v-model="comment"
|
|
style="resize: none"
|
|
name="comment"
|
|
rows="3"
|
|
class="shadow-sm block w-full focus:ring-blue-500 focus:border-blue-500 sm:text-sm border border-gray-300 rounded-md"
|
|
placeholder="댓글 내용을 입력하세요."
|
|
/>
|
|
</div>
|
|
<div class="mt-3 flex items-center justify-between">
|
|
<a
|
|
href="#"
|
|
class="group inline-flex items-start text-sm space-x-2 text-gray-500 hover:text-gray-900"
|
|
>
|
|
<QuestionMarkCircleIcon
|
|
class="flex-shrink-0 h-5 w-5 text-gray-400 group-hover:text-gray-500"
|
|
aria-hidden="true"
|
|
/>
|
|
<span>
|
|
모욕적인 표현이 포함된 댓글은 등록이
|
|
거부될 수 있습니다.
|
|
</span>
|
|
</a>
|
|
<button
|
|
type="button"
|
|
class="inline-flex items-center justify-center px-4 py-2 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500"
|
|
@click="addComment()"
|
|
>
|
|
댓글 등록
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { QuestionMarkCircleIcon } from '@heroicons/vue/24/solid';
|
|
|
|
const comment = ref('');
|
|
|
|
const props = defineProps({
|
|
tid: { type: String, required: true },
|
|
title: { type: String, default: '댓글' },
|
|
readOnlyFlag: { type: Boolean, required: true },
|
|
});
|
|
|
|
// console.log('huk props = ', props);
|
|
|
|
const title = ref(props.title);
|
|
|
|
console.log('title = ', title.value);
|
|
|
|
const listData = ref([]);
|
|
|
|
const readOnlyFlag = ref(props.readOnlyFlag);
|
|
|
|
const totalPageCount = ref(1);
|
|
const currentPageNumber = ref(Number.MAX_SAFE_INTEGER);
|
|
const pageSize = ref(3);
|
|
const recordsTotal = ref(0);
|
|
|
|
function pageMove(targetPageIdex) {
|
|
// console.log('on pageMove(), targetPageIdex=', targetPageIdex);
|
|
currentPageNumber.value = targetPageIdex;
|
|
refresh();
|
|
}
|
|
|
|
async function addComment() {
|
|
if (comment.value.trim() != '') {
|
|
const responseJson = await _crossCtl.doComm('insert', 'comment', {
|
|
hero: props.tid,
|
|
comment: comment.value,
|
|
for: 'board',
|
|
});
|
|
|
|
if (responseJson['responseCode'] != 200) {
|
|
alert(responseJson['responseMessage']);
|
|
} else {
|
|
console.log('responseJson=', responseJson);
|
|
comment.value = '';
|
|
refresh();
|
|
}
|
|
}
|
|
}
|
|
|
|
async function refresh() {
|
|
if (props.tid != '') {
|
|
const responseJson = await _crossCtl.doComm('list', 'comment:active', {
|
|
hero: props.tid,
|
|
start: (currentPageNumber.value - 1) * pageSize.value,
|
|
length: pageSize.value,
|
|
});
|
|
|
|
if (responseJson['responseCode'] != 200) {
|
|
alert(responseJson['responseMessage']);
|
|
} else {
|
|
console.log('responseJson=', responseJson);
|
|
currentPageNumber.value = responseJson['currentPageNumber'];
|
|
totalPageCount.value = responseJson['totalPageCount'];
|
|
pageSize.value = parseInt(responseJson['pageSize']);
|
|
recordsTotal.value = responseJson['recordsTotal'];
|
|
|
|
listData.value = responseJson['data'];
|
|
}
|
|
}
|
|
}
|
|
|
|
if (props.tid != '' && _crossCtl.isAuthenticated) {
|
|
const responseJson = await _crossCtl.doComm('list', 'like', {
|
|
hero: props.tid,
|
|
start: 0,
|
|
length: -1,
|
|
});
|
|
|
|
if (responseJson['responseCode'] != 200) {
|
|
alert(responseJson['responseMessage']);
|
|
} else {
|
|
console.log('like responseJson=', responseJson);
|
|
refresh();
|
|
}
|
|
}
|
|
|
|
async function doAction(tag, target) {
|
|
console.log('in doAction(), tag =', tag, ', target =', target);
|
|
let tmpResponseJson = null;
|
|
switch (tag) {
|
|
case 'like':
|
|
case 'dislike':
|
|
tmpResponseJson = await _crossCtl.doComm('update', 'like', {
|
|
domain: props.tid,
|
|
hero: target,
|
|
for: 'comment',
|
|
tag: tag,
|
|
});
|
|
refresh();
|
|
break;
|
|
case 'report':
|
|
tmpResponseJson = await _crossCtl.doComm('update', 'report', {
|
|
domain: props.tid,
|
|
hero: target,
|
|
for: 'comment',
|
|
tag: tag,
|
|
});
|
|
refresh();
|
|
break;
|
|
case 'cancel':
|
|
tmpResponseJson = await _crossCtl.doComm('update', 'report', {
|
|
domain: props.tid,
|
|
hero: target,
|
|
for: 'comment',
|
|
tag: tag,
|
|
});
|
|
refresh();
|
|
|
|
break;
|
|
case 'delete':
|
|
tmpResponseJson = await _crossCtl.doComm('delete', 'comment', {
|
|
hero: target,
|
|
tid: props.tid,
|
|
from: 'board',
|
|
});
|
|
refresh();
|
|
|
|
break;
|
|
}
|
|
}
|
|
</script>
|