This commit is contained in:
nevermoregb 2025-03-28 18:50:43 +09:00
commit 9c28054001
4 changed files with 67 additions and 26 deletions

View File

@ -56,27 +56,54 @@
<template #body> <template #body>
<div v-if="selectedDateCommuters.length > 0"> <div v-if="selectedDateCommuters.length > 0">
<div v-for="(commuter, index) in selectedDateCommuters" :key="index"> <div v-for="(commuter, index) in selectedDateCommuters" :key="index">
<div class="d-flex align-items-center my-2"> <div class="row my-2 d-flex align-items-center">
<div class="col-4">
<img :src="`${baseUrl}upload/img/profile/${commuter.profile}`" <img :src="`${baseUrl}upload/img/profile/${commuter.profile}`"
class="rounded-circle me-2 w-px-50 h-px-50" class="rounded-circle me-2 w-px-50 h-px-50"
@error="$event.target.src = '/img/icons/icon.png'"> @error="$event.target.src = '/img/icons/icon.png'">
<span class="fw-bold">{{ commuter.memberName }}</span> <span class="fw-bold">{{ commuter.memberName }}</span>
</div>
<div class="ms-auto text-start fw-bold d-flex flex-column align-items-end"> <div class="col-8">
<div class="d-flex gap-1 align-items-center"> <div class="d-flex gap-1 align-items-center">
출근 : 출근 :
<div class="text-white rounded px-2" :style="`background: ${commuter.projctcolor} !important;`"> <MapPopover
:address="commuter.projectAddress"
v-if="commuter.projectAddress"
>
<template #trigger>
<div
class="text-white rounded px-2 cursor-pointer"
:style="`background: ${commuter.projctcolor} !important;`"
>
{{ commuter.PROJCTNAM }} {{ commuter.PROJCTNAM }}
</div> </div>
</template>
</MapPopover>
<span class="ms-auto">
({{ commuter.COMMUTCMT }}) ({{ commuter.COMMUTCMT }})
</span>
</div> </div>
<div v-if="commuter.PROJCTLVE" class="d-flex gap-1 mt-1"> <div v-if="commuter.PROJCTLVE" class="d-flex gap-1 mt-1">
퇴근 : 퇴근 :
<div class="text-white rounded px-2" :style="`background: ${commuter.leaveProjectColor} !important;`"> <MapPopover
:address="commuter.leaveProjectAddress"
v-if="commuter.leaveProjectAddress"
>
<template #trigger>
<div
class="text-white rounded px-2 cursor-pointer"
:style="`background: ${commuter.leaveProjectColor} !important;`"
>
{{ commuter.leaveProjectName }} {{ commuter.leaveProjectName }}
</div> </div>
</template>
</MapPopover>
<span class="ms-auto">
({{ commuter.COMMUTLVE || "00:00:00" }}) ({{ commuter.COMMUTLVE || "00:00:00" }})
</span>
</div> </div>
</div> </div>
</div> </div>
@ -105,6 +132,7 @@ import { useProjectStore } from '@/stores/useProjectStore';
import CommuterBtn from '@c/commuters/CommuterBtn.vue'; import CommuterBtn from '@c/commuters/CommuterBtn.vue';
import CommuterProjectList from '@c/commuters/CommuterProjectList.vue'; import CommuterProjectList from '@c/commuters/CommuterProjectList.vue';
import BackBtn from '@c/button/BackBtn.vue'; import BackBtn from '@c/button/BackBtn.vue';
import MapPopover from '@c/map/MapPopover.vue';
import { useDatePicker } from '@/stores/useDatePicker'; import { useDatePicker } from '@/stores/useDatePicker';
const datePickerStore = useDatePicker(); const datePickerStore = useDatePicker();

View File

@ -165,11 +165,10 @@
</template> </template>
<script setup> <script setup>
import { defineProps, onMounted, ref, computed, watch, nextTick } from 'vue'; import { defineProps, onMounted, ref, computed, watch } from 'vue';
import UserList from '@c/user/UserList.vue'; import UserList from '@c/user/UserList.vue';
import CenterModal from '@c/modal/CenterModal.vue'; import CenterModal from '@c/modal/CenterModal.vue';
import $api from '@api'; import $api from '@api';
import { KakaoMap, KakaoMapMarker } from 'vue3-kakao-maps';
import BackBtn from '@c/button/BackBtn.vue'; import BackBtn from '@c/button/BackBtn.vue';
import BackButton from '@c/button/BackBtn.vue'; import BackButton from '@c/button/BackBtn.vue';
import SaveButton from '@c/button/SaveBtn.vue'; import SaveButton from '@c/button/SaveBtn.vue';

View File

@ -56,7 +56,7 @@
<div class="col-md-12"> <div class="col-md-12">
<QEditor <QEditor
v-if="contentLoaded" v-if="contentLoaded"
@update:data="content = $event" @update:data="handleEditorDataUpdate"
@update:imageUrls="imageUrls = $event" @update:imageUrls="imageUrls = $event"
@update:uploadedImgList="handleUpdateEditorImg" @update:uploadedImgList="handleUpdateEditorImg"
@update:deleteImgIndexList="handleDeleteEditorImg" @update:deleteImgIndexList="handleDeleteEditorImg"
@ -90,6 +90,7 @@
import { useToastStore } from '@s/toastStore'; import { useToastStore } from '@s/toastStore';
import { useBoardAccessStore } from '@s/useBoardAccessStore'; import { useBoardAccessStore } from '@s/useBoardAccessStore';
import axios from '@api'; import axios from '@api';
import Quill from 'quill';
// //
const $common = inject('common'); const $common = inject('common');
@ -123,8 +124,22 @@
const editorDeleteImgList = ref([]); const editorDeleteImgList = ref([]);
const originalTitle = ref(''); const originalTitle = ref('');
const originalPlainText = ref(''); const originalContent = ref({});
const originalFiles = ref([]); const originalFiles = ref([]);
const contentInitialized = ref(false);
//
const isFirstContentUpdate = ref(true);
//
const handleEditorDataUpdate = data => {
content.value = data;
if (isFirstContentUpdate.value) {
originalContent.value = structuredClone(data);
isFirstContentUpdate.value = false;
contentInitialized.value = true;
}
};
function extractPlainText(delta) { function extractPlainText(delta) {
if (!delta || !Array.isArray(delta.ops)) return ''; if (!delta || !Array.isArray(delta.ops)) return '';
@ -136,11 +151,9 @@
} }
const isChanged = computed(() => { const isChanged = computed(() => {
if (!contentInitialized.value) return false;
const isTitleChanged = title.value !== originalTitle.value; const isTitleChanged = title.value !== originalTitle.value;
const currentPlainText = extractPlainText(content.value); const isContentChanged = isDeltaChanged(content.value, originalContent.value);
const isContentChanged = currentPlainText !== originalPlainText.value;
const currentAttachedFiles = attachFiles.value.filter(f => f.id);
const isFilesChanged = const isFilesChanged =
attachFiles.value.some(f => !f.id) || // id attachFiles.value.some(f => !f.id) || // id
delFileIdx.value.length > 0 || // delFileIdx.value.length > 0 || //
@ -194,6 +207,8 @@
title.value = boardData.title || '제목 없음'; title.value = boardData.title || '제목 없음';
content.value = boardData.content || '내용 없음'; content.value = boardData.content || '내용 없음';
originalTitle.value = title.value; originalTitle.value = title.value;
originalContent.value = structuredClone(boardData.content);
contentInitialized.value = true;
contentLoaded.value = true; contentLoaded.value = true;
}; };

View File

@ -78,10 +78,9 @@
style="line-height: 1.6" style="line-height: 1.6"
v-html="$common.contentToHtml(boardContent)" v-html="$common.contentToHtml(boardContent)"
></div> ></div>
<div v-if="!unknown" class="my-12 py-12 pt-12"></div>
<!-- 좋아요 버튼 --> <!-- 좋아요 버튼 -->
<div class="row justify-content-center my-10"> <div v-if="unknown || authorId" class="row justify-content-center my-10">
<BoardRecommendBtn <BoardRecommendBtn
:bigBtn="true" :bigBtn="true"
:boardId="currentBoardId" :boardId="currentBoardId"
@ -93,7 +92,7 @@
@updateReaction="handleUpdateReaction" @updateReaction="handleUpdateReaction"
/> />
</div> </div>
<div> <div v-if="unknown || authorId" >
<!-- 댓글 입력 영역 --> <!-- 댓글 입력 영역 -->
<BoardCommentArea <BoardCommentArea
:profileName="profileName" :profileName="profileName"
@ -107,7 +106,7 @@
</div> </div>
<!-- 댓글 목록 --> <!-- 댓글 목록 -->
<div class="card-footer"> <div v-if="unknown || authorId" class="card-footer">
<BoardCommentList <BoardCommentList
:unknown="unknown" :unknown="unknown"
:comments="commentsWithAuthStatus" :comments="commentsWithAuthStatus"