|
|
@@ -1,5 +1,5 @@
|
|
|
<template>
|
|
|
- <el-card shadow="never" :class="total > 0 && 'reply-card'">
|
|
|
+ <el-card :class="['reply-card', total > 0 && 'header-has-border']" shadow="never">
|
|
|
<template #header>
|
|
|
<el-button type="primary" link @click="showInput = !showInput">留言
|
|
|
<template #icon><el-icon size="16"><tjm-icon-mdi-comment-text-outline /></el-icon></template>
|
|
|
@@ -11,77 +11,36 @@
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
- <el-form v-loading="loading">
|
|
|
- <template v-for="(item, index) in replyData" :key="item.id">
|
|
|
- <div class="reply-item">
|
|
|
- <el-form-item :label="`${item.createName}:`">{{ item.messageContent }}</el-form-item>
|
|
|
- <el-form-item class="reply-date-item" :label="formatDate(item.createTime)">
|
|
|
- <div class="handle-button-group">
|
|
|
- <el-tooltip content="删除" placement="top">
|
|
|
- <el-button v-if="item.createId == loginUser" icon="delete" circle @click="reply_del(item)"></el-button>
|
|
|
- </el-tooltip>
|
|
|
- <el-tooltip content="留言" placement="top">
|
|
|
- <el-button circle @click="reply_add(item)">
|
|
|
- <template #icon><tjm-icon-mdi-comment-text-outline /></template>
|
|
|
- </el-button>
|
|
|
- </el-tooltip>
|
|
|
- </div>
|
|
|
- </el-form-item>
|
|
|
- </div>
|
|
|
- <div class="reply-item__children">
|
|
|
- <div class="reply-item" v-for="child in replyChildren[index]" :key="child.id">
|
|
|
- <el-form-item>
|
|
|
- <template #label>{{ child.createName }}:
|
|
|
- <template v-if="child.replyId"><span>回复@</span>{{ child.replyName }}:</template>
|
|
|
- </template>
|
|
|
- {{ child.messageContent }}
|
|
|
- </el-form-item>
|
|
|
- <el-form-item class="reply-date-item" :label="formatDate(child.createTime)">
|
|
|
- <div class="handle-button-group">
|
|
|
- <el-tooltip content="删除" placement="top">
|
|
|
- <el-button v-if="child.createId == loginUser" icon="delete" circle @click="reply_del(child)"></el-button>
|
|
|
- </el-tooltip>
|
|
|
- <el-tooltip content="留言" placement="top">
|
|
|
- <el-button circle @click="reply_add(child)">
|
|
|
- <template #icon><tjm-icon-mdi-comment-text-outline /></template>
|
|
|
- </el-button>
|
|
|
- </el-tooltip>
|
|
|
- </div>
|
|
|
- </el-form-item>
|
|
|
- </div>
|
|
|
- <el-button v-if="item.childrenCount > replyChildrenCount" class="text-reverse" type="primary" link @click="reply_children(item)">共{{ item.childrenCount }}条回复
|
|
|
- <template #icon><el-icon size="22"><tjm-icon-mdi-menu-down /></el-icon></template>
|
|
|
- </el-button>
|
|
|
- </div>
|
|
|
- </template>
|
|
|
- </el-form>
|
|
|
-
|
|
|
- <template v-if="total > replyCount">
|
|
|
- <el-divider></el-divider>
|
|
|
- <el-button class="text-reverse" type="primary" link>查看全部{{ allTotal }}条留言
|
|
|
- <template #icon><arrow-right /></template>
|
|
|
- </el-button>
|
|
|
- </template>
|
|
|
- <template v-else>
|
|
|
- <el-divider v-if="total">已加载全部留言</el-divider>
|
|
|
+ <template v-for="(item, index) in replyData" v-bind:key="index">
|
|
|
+ <reply-tree :currentReply="item" :pageSize="replyChildrenCount" @closeDialog="reloadTree">
|
|
|
+ <!-- 回复详情 -->
|
|
|
+ <el-button class="text-reverse" type="primary" link @click="reply_detail(item)">共{{ item.childrenCount }}条回复
|
|
|
+ <template #icon><el-icon size="22"><tjm-icon-mdi-menu-down /></el-icon></template>
|
|
|
+ </el-button>
|
|
|
+ </reply-tree>
|
|
|
</template>
|
|
|
+
|
|
|
+ <div class="reply-card__footer">
|
|
|
+ <template v-if="total > replyCount">
|
|
|
+ <el-divider></el-divider>
|
|
|
+ <el-button class="text-reverse" type="primary" icon="arrow-right" link>查看全部11条留言</el-button>
|
|
|
+ </template>
|
|
|
+ <template v-else><el-divider v-if="total">已加载全部留言</el-divider></template>
|
|
|
+ </div>
|
|
|
</el-card>
|
|
|
|
|
|
- <reply-detail v-if="dialog.detail" ref="replyDetail" :refId="refId" :refType="refType" @success="reloadChildrenTree" @closed="dialog.detail = false"></reply-detail>
|
|
|
- <reply-child-detail v-if="dialog.child" ref="replyChildDetail" @closed="reloadTree(), dialog.child = false"></reply-child-detail>
|
|
|
+ <reply-detail v-if="dialog" ref="replyDetail" @closed="reloadTree(), dialog = false"></reply-detail>
|
|
|
</template>
|
|
|
|
|
|
<script>
|
|
|
-import moment from "moment";
|
|
|
import API from "@/api/policy/message";
|
|
|
-import replyDetail from "./dialog.vue";
|
|
|
-import replyChildDetail from "./detail.vue";
|
|
|
-import { useUserStore } from "@/store/user";
|
|
|
+import replyTree from "@/components/ReplyCard/tree/index.vue";
|
|
|
+import replyDetail from "@/components/ReplyCard/detail.vue";
|
|
|
|
|
|
export default {
|
|
|
components: {
|
|
|
- replyDetail,
|
|
|
- replyChildDetail
|
|
|
+ replyTree,
|
|
|
+ replyDetail
|
|
|
},
|
|
|
props: {
|
|
|
refId: { type: String, default: "" },
|
|
|
@@ -93,7 +52,6 @@ export default {
|
|
|
data() {
|
|
|
return {
|
|
|
loading: false,
|
|
|
- loginUser: useUserStore().userInfo.id,
|
|
|
params: {
|
|
|
page: 1,
|
|
|
size: this.replyCount,
|
|
|
@@ -103,22 +61,12 @@ export default {
|
|
|
},
|
|
|
total: 0,
|
|
|
replyData: [],
|
|
|
- replyChildren: [],
|
|
|
|
|
|
showInput: false,
|
|
|
isSaving: false,
|
|
|
messageContent: null,
|
|
|
|
|
|
- dialog: {
|
|
|
- detail: false,
|
|
|
- child: false
|
|
|
- }
|
|
|
- }
|
|
|
- },
|
|
|
-
|
|
|
- computed: {
|
|
|
- allTotal() {
|
|
|
- return this.total + (this.replyChildren.length && this.replyChildren.map(c => c.length).reduce((p, v) => p + v) || 0);
|
|
|
+ dialog: false
|
|
|
}
|
|
|
},
|
|
|
|
|
|
@@ -127,10 +75,6 @@ export default {
|
|
|
},
|
|
|
|
|
|
methods: {
|
|
|
- formatDate(value) {
|
|
|
- return value && moment(value).format("YY-MM-DD HH:mm") || "";
|
|
|
- },
|
|
|
-
|
|
|
reloadTree() {
|
|
|
this.loading = true;
|
|
|
API.get(this.params).then(res => {
|
|
|
@@ -138,28 +82,10 @@ export default {
|
|
|
if (res.code === 200) {
|
|
|
this.replyData = res.data.records;
|
|
|
this.total = res.data.total;
|
|
|
- this.reloadChildrenTree();
|
|
|
} else ElMessage.error(res.msg);
|
|
|
}).catch(() => this.loading = false);
|
|
|
},
|
|
|
|
|
|
- reloadChildrenTree(parentId) {
|
|
|
- let promiseArray = [];
|
|
|
- if (parentId) {
|
|
|
- const reply_i = this.replyData.findIndex(c => c.id == parentId);
|
|
|
- this.replyData[reply_i].childrenCount++;
|
|
|
-
|
|
|
- promiseArray = this.replyData.map(_ => []);
|
|
|
- promiseArray[reply_i] = API.get({ ...this.params, size: this.replyChildrenCount, parentId });
|
|
|
- } else this.replyData.forEach(item => promiseArray.push(API.get({ ...this.params, size: this.replyChildrenCount, parentId: item.id })));
|
|
|
-
|
|
|
- Promise.all(promiseArray).then(res => {
|
|
|
- this.replyChildren = res.map(r => r.code == 200 && r.data.records || []);
|
|
|
- }).catch(() => {
|
|
|
- this.replyChildren = [];
|
|
|
- });
|
|
|
- },
|
|
|
-
|
|
|
submit() {
|
|
|
if (this.refId && this.refType) {
|
|
|
const data = {
|
|
|
@@ -181,29 +107,9 @@ export default {
|
|
|
}
|
|
|
},
|
|
|
|
|
|
- reply_add(data) {
|
|
|
- this.dialog.detail = true;
|
|
|
- nextTick(() => this.$refs.replyDetail.open().setData(data));
|
|
|
- },
|
|
|
-
|
|
|
- reply_del(data) {
|
|
|
- ElMessageBox.confirm("是否确认删除?", "删除警告", {
|
|
|
- type: "warning",
|
|
|
- confirmButtonText: "确定",
|
|
|
- cancelButtonText: "取消"
|
|
|
- }).then(() => {
|
|
|
- API.del({ ids: data.id }).then(res => {
|
|
|
- if (res.code == 200) {
|
|
|
- ElMessage.success("操作成功");
|
|
|
- this.reloadTree();
|
|
|
- } else ElMessage.error(res.msg);
|
|
|
- });
|
|
|
- }).catch(() => ElMessage.success("已取消"));
|
|
|
- },
|
|
|
-
|
|
|
- reply_children(data) {
|
|
|
- this.dialog.child = true;
|
|
|
- nextTick(() => this.$refs.replyChildDetail.open().setData(data));
|
|
|
+ reply_detail(data) {
|
|
|
+ this.dialog = true;
|
|
|
+ nextTick(() => this.$refs.replyDetail.open(data));
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@@ -216,21 +122,21 @@ export default {
|
|
|
|
|
|
:deep([class*='el-icon'] + span) {
|
|
|
margin-left: 0;
|
|
|
- margin-right: 6px;
|
|
|
font-size: 13px;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-.el-card {
|
|
|
+.reply-card {
|
|
|
+ --el-card-border-color: var(--el-border-color-lighter);
|
|
|
margin-bottom: 25px;
|
|
|
border-top: none;
|
|
|
- border-radius: 0 0 var(--el-card-border-radius) var(--el-card-border-radius);
|
|
|
+ border-radius: 0;
|
|
|
|
|
|
:deep(.el-card__header) {
|
|
|
display: flex;
|
|
|
flex-direction: column;
|
|
|
align-items: center;
|
|
|
- border-bottom: 0;
|
|
|
+ border-bottom: none;
|
|
|
padding: calc(var(--el-card-padding) / 2) var(--el-card-padding);
|
|
|
|
|
|
.reply-form {
|
|
|
@@ -247,108 +153,62 @@ export default {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- :deep(.el-card__body) {
|
|
|
+ > :deep(.el-card__body) {
|
|
|
padding: 0;
|
|
|
|
|
|
- .el-divider {
|
|
|
- margin: calc(var(--el-card-padding) / 2) 0;
|
|
|
- border-color: var(--el-border-color-light);
|
|
|
-
|
|
|
- .el-divider__text {
|
|
|
- color: var(--el-text-color-disabled);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
+ .el-card {
|
|
|
+ border: none;
|
|
|
+ border-radius: 0;
|
|
|
|
|
|
-.reply-card :deep(.el-card__body) {
|
|
|
- display: flex;
|
|
|
- flex-direction: column;
|
|
|
- padding: calc(var(--el-card-padding) / 2) var(--el-card-padding);
|
|
|
- padding-top: 0;
|
|
|
+ .el-card__body {
|
|
|
+ margin-left: 10px;
|
|
|
+ padding: 0;
|
|
|
|
|
|
- .el-form {
|
|
|
- flex-basis: 100%;
|
|
|
- padding: calc(var(--el-card-padding) / 2) 10% 0;
|
|
|
- border-top: 1px solid var(--el-card-border-color);
|
|
|
-
|
|
|
- .el-form-item {
|
|
|
- align-items: baseline;
|
|
|
- margin-bottom: 0;
|
|
|
- padding: 0 6px;
|
|
|
- border-radius: 4px 4px 0 0;
|
|
|
-
|
|
|
- .el-form-item__label {
|
|
|
- height: fit-content;
|
|
|
- line-height: 22px;
|
|
|
- font-size: 13px;
|
|
|
- color: var(--el-color-primary);
|
|
|
- }
|
|
|
-
|
|
|
- .el-form-item__content {
|
|
|
- height: fit-content;
|
|
|
- line-height: 22px;
|
|
|
- font-size: 13px;
|
|
|
- color: var(--el-text-color-regular);
|
|
|
+ .text-reverse {
|
|
|
+ margin-bottom: 10px;
|
|
|
+ padding: calc(9px / 2) 0 calc(9px / 2) 9px;
|
|
|
+ border: none;
|
|
|
+ border-left: 1px solid var(--el-border-color-lighter);
|
|
|
+ border-radius: 0;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- .reply-date-item {
|
|
|
- margin-bottom: 6px;
|
|
|
- align-items: center;
|
|
|
- border-radius: 0 0 4px 4px;
|
|
|
-
|
|
|
- .el-form-item__label {
|
|
|
- color: var(--el-text-color-placeholder);
|
|
|
- }
|
|
|
-
|
|
|
- .el-form-item__content {
|
|
|
- justify-content: flex-end;
|
|
|
-
|
|
|
- .handle-button-group {
|
|
|
- display: none;
|
|
|
+ .reply-card__footer {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ justify-content: center;
|
|
|
+ height: fit-content;
|
|
|
|
|
|
- .el-button {
|
|
|
- width: 20px;
|
|
|
- height: 20px;
|
|
|
- padding: 0;
|
|
|
- background-color: transparent;
|
|
|
- border: none;
|
|
|
+ .el-divider {
|
|
|
+ margin: 10px 0;
|
|
|
+ border-color: var(--el-card-border-color);
|
|
|
|
|
|
- &:hover {
|
|
|
- background-color: var(--el-color-primary-light-8);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
+ :deep(.el-divider__text) {
|
|
|
+ padding: 0 60px;
|
|
|
+ color: var(--el-text-color-disabled);
|
|
|
}
|
|
|
}
|
|
|
+ }
|
|
|
+}
|
|
|
|
|
|
- .reply-item:hover .el-form-item {
|
|
|
- background: var(--el-color-primary-light-9);
|
|
|
+.header-has-border.reply-card > :deep {
|
|
|
+ .el-card__header {
|
|
|
+ position: relative;
|
|
|
|
|
|
- .el-form-item__content .handle-button-group {
|
|
|
- display: inline-flex;
|
|
|
- }
|
|
|
+ &::after {
|
|
|
+ content: '';
|
|
|
+ position: absolute;
|
|
|
+ bottom: 0;
|
|
|
+ width: 80%;
|
|
|
+ height: 1px;
|
|
|
+ background: var(--el-card-border-color);
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- .reply-item__children {
|
|
|
- margin-bottom: 6px;
|
|
|
- margin-left: 6px;
|
|
|
- padding-left: 1px;
|
|
|
- border-left: 1px solid var(--el-card-border-color);
|
|
|
-
|
|
|
- .el-form-item__label span {
|
|
|
- color: var(--el-text-color-regular);
|
|
|
- }
|
|
|
-
|
|
|
- .reply-item:last-child .reply-date-item {
|
|
|
- margin-bottom: 0;
|
|
|
- }
|
|
|
-
|
|
|
- .text-reverse {
|
|
|
- margin-left: 3px;
|
|
|
- }
|
|
|
- }
|
|
|
+ .el-card__body {
|
|
|
+ padding: calc(var(--el-card-padding) / 2) 10%;
|
|
|
}
|
|
|
}
|
|
|
</style>
|