<script lang="ts" setup>
|
import type { ScrollActionType } from '@jnpf/ui';
|
|
import { onMounted, reactive, ref, toRefs } from 'vue';
|
|
import { useGlobSetting, useMessage } from '@jnpf/hooks';
|
import { createImgPreview, ScrollContainer } from '@jnpf/ui';
|
import { formatToDateTime } from '@jnpf/utils';
|
|
import { delComment, getCommentList } from '#/api/workFlow/template';
|
import emojiJson from '#/layouts/header/chat/emoji.json';
|
import { getAuthMediaUrl } from '#/utils/jnpf';
|
|
import CommentInput from './CommentInput.vue';
|
|
interface State {
|
list: any[];
|
loading: boolean;
|
listQuery: any;
|
}
|
|
const props = defineProps({
|
taskId: { type: [String, Number], default: '' },
|
});
|
|
const { createMessage } = useMessage();
|
const globSetting = useGlobSetting();
|
const apiUrl = ref(globSetting.apiURL);
|
const infiniteBody = ref<Nullable<ScrollActionType>>(null);
|
const state = reactive<State>({
|
list: [],
|
loading: false,
|
listQuery: {
|
currentPage: 1,
|
pageSize: 100000,
|
sort: 'desc',
|
sidx: '',
|
},
|
});
|
const { list, loading } = toRefs(state);
|
|
function handleReply(item, index) {
|
item.commentActive = true;
|
for (let i = 0; i < state.list.length; i++) {
|
if (i != index) state.list[i].commentActive = false;
|
}
|
}
|
function handleDel(id) {
|
delComment(id).then((res) => {
|
createMessage.success(res.msg);
|
init();
|
});
|
}
|
function handlePreview(list, index) {
|
const imageList = list.map((o) => getAuthMediaUrl(o.url));
|
createImgPreview({ imageList, index });
|
}
|
function replaceEmoji(str) {
|
if (!str) return '';
|
// 替换表情符号为图片
|
const replacedStr = str.replaceAll(/\[([^(\]|[)]*)\]/g, (item) => {
|
let obj = '';
|
for (const row of emojiJson) {
|
if (row.alt == item) {
|
obj = `<img src="/resource/emoji/${row.url}" class="comment-text-emoji" />`;
|
break;
|
}
|
}
|
return obj || str;
|
});
|
str = replacedStr;
|
return str;
|
}
|
function init() {
|
if (!props.taskId) return;
|
state.loading = true;
|
const query = { ...state.listQuery, taskId: props.taskId };
|
getCommentList(query)
|
.then((res) => {
|
const list = res.data.list.map((o) => ({
|
...o,
|
text: replaceEmoji(o.text),
|
replyText: replaceEmoji(o.replyText),
|
fileList: o.file ? JSON.parse(o.file) : [],
|
imageList: o.image ? JSON.parse(o.image) : [],
|
creatorTime: formatToDateTime(o.creatorTime),
|
}));
|
state.list = list;
|
state.loading = false;
|
})
|
.catch(() => {
|
state.loading = false;
|
});
|
}
|
|
onMounted(() => {
|
init();
|
});
|
</script>
|
<template>
|
<div class="form-extra-comment">
|
<ScrollContainer v-loading="loading" ref="infiniteBody" class="form-extra-comment-main">
|
<div class="form-extra-comment-list">
|
<div v-for="(item, i) in list" :key="i" class="form-extra-comment-item">
|
<div class="form-extra-comment-item-main">
|
<a-avatar :size="24" :src="apiUrl + item.creatorUserHeadIcon" class="comment-avatar" />
|
<div class="comment-content">
|
<div class="comment-head">
|
<p class="username">
|
{{ item.creatorUser }}
|
<span v-if="item.replyUser">
|
<span class="replay-separate">回复</span>
|
{{ item.replyUser }}
|
<a-tooltip>
|
<template #title>
|
<div v-html="item.replyText"></div>
|
</template>
|
<i class="icon-ym icon-ym-chat"></i>
|
</a-tooltip>
|
</span>
|
</p>
|
</div>
|
<p class="comment-text" v-html="item.isDel == 2 ? '该评论已被删除' : item.text"></p>
|
<div class="comment-other" v-if="item.isDel != 2 && (item.imageList?.length || item.fileList?.length)">
|
<div class="comment-img-list" v-if="item.imageList?.length">
|
<img
|
:src="getAuthMediaUrl(cItem.url)"
|
class="comment-img-item"
|
v-for="(cItem, ci) in item.imageList"
|
:key="ci"
|
@click="handlePreview(item.imageList, ci)" />
|
</div>
|
<div class="comment-file-List" v-if="item.fileList?.length">
|
<jnpf-upload-file v-model:value="item.fileList" detailed disabled :show-all-download="false" />
|
</div>
|
</div>
|
<div class="comment-actions">
|
<span class="time">{{ item.creatorTime }}</span>
|
<div v-if="item.isDel != 2">
|
<a-popconfirm title="确定删除该评论?" @confirm="handleDel(item.id)" v-if="item.isDel == 1">
|
<a-button type="link" color="error">删除</a-button>
|
</a-popconfirm>
|
<a-button type="link" class="ml-[10px]" @click="handleReply(item, i)">回复</a-button>
|
</div>
|
</div>
|
</div>
|
</div>
|
<CommentInput inner :task-id="taskId" :reply-id="item.id" v-if="item.commentActive" @hide-comment-input="item.commentActive = false" @reload="init" />
|
</div>
|
</div>
|
<jnpf-empty v-if="!list.length" />
|
</ScrollContainer>
|
<div class="form-extra-comment-list-footer">
|
<CommentInput :task-id="taskId" @reload="init" />
|
</div>
|
</div>
|
</template>
|