zhuangyunsheng 1 год назад
Родитель
Сommit
84b3cf4142

+ 71 - 0
src/components/ReplyCard/detail.vue

@@ -0,0 +1,71 @@
+<template>
+    <div class="reply-item-dialog">
+        <el-dialog v-model="visible" :title="`${childrenCount}条回复`" width="680" @closed="$emit('closed')">
+            <reply-tree ref="replyTree" @updateCount="childrenCount = $event" @closeDialog="visible = false"></reply-tree>
+        </el-dialog>
+    </div>
+</template>
+
+<script>
+import replyTree from "@/components/ReplyCard/tree/index.vue";
+
+export default {
+    emits: ["closed"],
+    components: {
+        replyTree
+    },
+    
+    data() {
+        return {
+            visible: false,
+
+            childrenCount: 0
+        }
+    },
+
+    methods: {
+        open() {
+            this.visible = true;
+            return this;
+        },
+
+        setData(data) {
+            nextTick(() => this.$refs.replyTree.setData(data));
+        }
+    }
+}
+</script>
+
+<style lang="scss" scoped>
+.reply-item-dialog :deep(.el-dialog) .el-dialog__body {
+  padding: 0 16px 10px;
+
+  .no-b-l {
+    border-left: none;
+  }
+
+  .el-card {
+    border: none;
+    border-radius: 0;
+
+    .el-card__body {
+      margin-left: 10px;
+      padding: 0;
+
+      .no-p-b {
+        padding-bottom: 0;
+      }
+    }
+  }
+
+  .el-divider {
+    margin-top: 40px;
+    border-color: var(--el-border-color-light);
+
+    .el-divider__text {
+      padding: 0 60px;
+      color: var(--el-text-color-disabled);
+    }
+  }
+}
+</style>

+ 9 - 6
src/components/ReplyCard/dialog.vue

@@ -1,5 +1,5 @@
 <template>
-    <el-dialog v-model="visible" :title="`回复@${form.replyName}`" width="680" @closed="$emit('closed')">
+    <el-dialog v-model="visible" :title="`回复@${form.replyName}`" width="600" align-center @closed="$emit('closed')">
         <el-input v-model="form.messageContent" type="textarea" autosize clearable show-word-limit maxlength="140" placeholder="发布你的回复"></el-input>
 
         <template #footer>
@@ -41,19 +41,22 @@ export default {
         },
 
         setData(data) {
-            if (data.parentId == 0) {
-                this.form.parentId = data.id;
-            } else {
+            this.form.parentId = data.id;
+            this.form.replyName = data.createName;
+
+            if (data.parentId != 0) {
                 this.form.parentId = data.parentId;
                 this.form.replyId = data.createId;
-                this.form.replyName = data.createName;
             }
         },
 
         // 表单提交方法
         submit() {
+            const data = Object.assign({}, this.form);
+            if (!data.replyId) data["replyName"] = null;
+
             this.isSaving = true;
-            API.add(this.form).then(res => {
+            API.add(data).then(res => {
                 this.isSaving = false;
                 if (res.code === 200) {
                     ElMessage.success("操作成功");

+ 12 - 3
src/components/ReplyCard/index.vue

@@ -49,7 +49,7 @@
                             </div>
                         </el-form-item>
                     </div>
-                    <el-button v-if="item.childrenCount > replyChildrenCount" class="text-reverse" type="primary" link>共{{ item.childrenCount }}条回复
+                    <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>
@@ -68,17 +68,20 @@
     </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>
 </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";
 
 export default {
     components: {
-        replyDetail
+        replyDetail,
+        replyChildDetail
     },
     props: {
         refId: { type: String, default: "" },
@@ -107,7 +110,8 @@ export default {
             messageContent: null,
 
             dialog: {
-                detail: false
+                detail: false,
+                child: false
             }
         }
     },
@@ -195,6 +199,11 @@ export default {
                     } else ElMessage.error(res.msg);
                 });
             }).catch(() => ElMessage.success("已取消"));
+        },
+
+        reply_children(data) {
+            this.dialog.child = true;
+            nextTick(() => this.$refs.replyChildDetail.open().setData(data));
         }
     }
 }

+ 89 - 0
src/components/ReplyCard/tree/index.vue

@@ -0,0 +1,89 @@
+<template>
+    <reply-item :replyItem="replyData" @success="reloadChildren" @closeDialog="$emit('closeDialog')"></reply-item>
+
+    <el-card v-loading="loading" shadow="never">
+        <template v-for="(item, index) in replyData.children" v-bind:key="index">
+            <reply-item :class="index == replyData.childrenCount - 1 && 'no-p-b'" :replyItem="item" @success="reloadChildren"></reply-item>
+        </template>
+        <el-divider>没有更多内容了</el-divider>
+    </el-card>
+</template>
+
+<script>
+import API from "@/api/policy/message";
+import replyItem from "@/components/ReplyCard/tree/item.vue";
+
+export default {
+    emits: ["updateCount", "closeDialog"],
+    components: {
+        replyItem
+    },
+    
+    data() {
+        return {
+            loading: false,
+            replyData: {
+                id: null,
+                parentId: 0,
+                refId: null,
+                refType: null,
+                createId: null,
+                createName: null,
+                createTime: null,
+                messageContent: null,
+                childrenCount: 0,
+                children: []
+            }
+        }
+    },
+
+    methods: {
+        setData(data) {
+            for (const key in this.replyData) {
+                if (key == "children") this.replyData[key] = [];
+                else this.replyData[key] = data[key];
+            }
+
+            if (data.parentId == 0) this.reloadChildren();
+        },
+
+        reloadChildren() {
+            this.loading = true;
+            API.get({ page: 1, size: 999, parentId: this.replyData.id, refId: this.replyData.refId, refType: this.replyData.refType }).then(res => {
+                this.loading = false;
+                if (res.code === 200) {
+                    this.replyData["childrenCount"] = res.data.total;
+                    this.replyData["children"] = res.data.records;
+                    this.$emit("updateCount", res.data.total);
+                } else ElMessage.error(res.msg);
+            }).catch(() => this.loading = false);
+        }
+    }
+}
+</script>
+
+<style lang="scss" scoped>
+.el-card {
+  border: none;
+  border-radius: 0;
+
+  .el-card__body {
+    margin-left: 10px;
+    padding: 0;
+
+    .no-p-b {
+      padding-bottom: 0;
+    }
+  }
+}
+
+.el-divider {
+  margin-top: 40px;
+  border-color: var(--el-border-color-light);
+
+  .el-divider__text {
+    padding: 0 60px;
+    color: var(--el-text-color-disabled);
+  }
+}
+</style>

+ 156 - 0
src/components/ReplyCard/tree/item.vue

@@ -0,0 +1,156 @@
+<template>
+    <el-form :class="['reply-item', replyItem.parentId == 0 && 'no-b-l']">
+        <div class="reply-item__content">
+            <el-form-item>
+                <template #label>{{ replyItem.createName }}<span>:</span>
+                    <template v-if="replyItem.replyId"><span>回复@</span>{{ replyItem.replyName }}<span>:</span></template>
+                </template>
+                {{ replyItem.messageContent }}
+            </el-form-item>
+            <el-form-item class="reply-date-item" :label="formatDate(replyItem.createTime)"></el-form-item>
+        </div>
+
+        <div class="reply-item__button-group">
+            <el-tooltip content="删除" :show-after="delay" placement="top">
+                <el-button v-if="replyItem.createId == loginUser" icon="delete" circle @click="reply_del"></el-button>
+            </el-tooltip>
+            <el-tooltip content="留言" :show-after="delay" placement="top">
+                <el-button circle @click="reply_add">
+                    <template #icon><tjm-icon-mdi-comment-text-outline /></template>
+                </el-button>
+            </el-tooltip>
+        </div>
+    </el-form>
+
+    <reply-detail v-if="dialog" ref="replyDetail" :refId="replyItem.refId" :refType="replyItem.refType" @success="$emit('success')" @closed="dialog = false"></reply-detail>
+</template>
+
+<script>
+import moment from "moment";
+import API from "@/api/policy/message";
+import { useUserStore } from "@/store/user";
+
+import replyDetail from "@/components/ReplyCard/dialog.vue";
+
+export default {
+    components: {
+        replyDetail
+    },
+    props: {
+        replyItem: { type: Object, default: () => {} }
+    },
+
+    data() {
+        return {
+            loginUser: useUserStore().userInfo.id,
+            delay: 800,
+
+            dialog: false
+        }
+    },
+
+    methods: {
+        formatDate(value) {
+            return value && moment(value).format("YY-MM-DD HH:mm") || "";
+        },
+
+        reply_add() {
+            this.dialog = true;
+            nextTick(() => this.$refs.replyDetail.open().setData(this.replyItem));
+        },
+
+        reply_del() {
+            ElMessageBox.confirm("是否确认删除?", "删除警告", {
+                type: "warning",
+                confirmButtonText: "确定",
+                cancelButtonText: "取消"
+            }).then(() => {
+                API.del({ ids: this.replyItem.id }).then(res => {
+                    if (res.code == 200) {
+                        ElMessage.success("操作成功");
+                        if (this.replyItem.parentId == 0) this.$emit("closeDialog");
+                        else this.$emit("success");
+                    } else ElMessage.error(res.msg);
+                });
+            }).catch(() => ElMessage.success("已取消"));
+        }
+    }
+}
+</script>
+
+<style lang="scss" scoped>
+.text-reverse {
+  display: flex;
+  flex-direction: row-reverse;
+
+  :deep([class*='el-icon'] + span) {
+    margin-left: 0;
+    margin-right: 6px;
+    font-size: 13px;
+  }
+}
+
+.reply-item {
+  display: flex;
+  align-items: center;
+  padding-left: 10px;
+  padding-bottom: 10px;
+  border-left: 1px solid var(--el-border-color-light);
+
+  .reply-item__content {
+    flex: 1;
+
+    .el-form-item {
+      margin-bottom: 0;
+
+      :deep(.el-form-item__label) {
+        height: fit-content;
+        padding-right: 6px;
+        line-height: 22px;
+        font-size: 13px;
+        color: var(--el-color-primary);
+
+        span {
+          color: var(--el-text-color-regular);
+        }
+      }
+
+      :deep(.el-form-item__content) {
+        height: fit-content;
+        line-height: 22px;
+        font-size: 13px;
+        color: var(--el-text-color-regular);
+      }
+    }
+
+    .reply-date-item :deep(.el-form-item__label) {
+      color: var(--el-text-color-placeholder);
+    }
+  }
+
+  .reply-item__button-group {
+    display: none;
+    margin-left: 10px;
+
+    .el-button {
+      width: 20px;
+      height: 20px;
+      padding: 0;
+      background-color: transparent;
+      border: none;
+
+      &:hover {
+        background-color: var(--el-color-primary-light-8);
+      }
+    }
+  }
+
+  &:hover .reply-item__button-group {
+    display: inline-flex;
+  }
+}
+
+.no-b-l {
+  border-left: none;
+}
+</style>

+ 4 - 4
src/components/Tooltip/index.vue

@@ -1,7 +1,7 @@
 <template>
-  <el-tooltip :content="content" :placement="placement" :disabled="!showTooltip">
-    <span class="yh-tooltip-content overflow-ellipsis" @mouseenter.stop.prevent="onMouseenter" @mouseleave.stop.prevent="showTooltip = false">{{ content }}</span>
-  </el-tooltip>
+    <el-tooltip :content="content" :placement="placement" :disabled="!showTooltip">
+        <span class="yh-tooltip-content overflow-ellipsis" @mouseenter.stop.prevent="onMouseenter" @mouseleave.stop.prevent="showTooltip = false">{{ content }}</span>
+    </el-tooltip>
 </template>
 
 <script>
@@ -20,7 +20,7 @@
 
 		methods: {
 			onMouseenter({ currentTarget }) {
-				this.showTooltip = currentTarget.scrollWidth >= currentTarget.parentElement.offsetWidth - this.spacing
+				this.showTooltip = currentTarget.scrollWidth >= currentTarget.parentElement.offsetWidth - this.spacing;
 			}
 		}
 	}