浏览代码

更新添加详情

lex-xin 9 月之前
父节点
当前提交
73f21d0dfd

+ 14 - 2
src/TUIKit/TUIComponents/container/TUIChat/components/message-custom.vue

@@ -92,7 +92,8 @@ import { isUrl, JSONToObject } from '../utils/utils';
 import constant from '../../constant';
 import { useStore } from 'vuex';
 import { eventGlobal } from "@/helpers";
-
+import TUIMessage from "../../../components/messageTUI/index";
+import { imGroupNoticeDetail } from "../../../../api";
 export default defineComponent({
   props: {
     data: {
@@ -172,7 +173,18 @@ export default defineComponent({
 
     const handleNotice = async () => {
       console.log(data.isCustom, 'data.isCustom')
-      eventGlobal.emit('handleNotice', data.isCustom?.msgId)
+      if(!data.isCustom?.msgId) return
+      try {
+        await imGroupNoticeDetail(data.isCustom?.msgId)
+        eventGlobal.emit('handleNotice', data.isCustom?.msgId)
+      } catch(e) {
+        //
+        TUIMessage({
+          message: e.message,
+          isH5: false,
+          type: "error",
+        });
+      }
     }
     return {
       ...toRefs(data),

+ 4 - 0
src/TUIKit/TUIComponents/container/TUIChat/manage-components/manage-member.vue

@@ -10,6 +10,7 @@
         </aside>
         <i v-if="item.role !== 'Owner' && isShowDel" class="icon icon-del" @click="submit(item)"></i>
       </li>
+      
       <li class="list-item" v-if="list.length < total" @click="getMore">
         {{ $t(`TUIChat.manage.查看更多`) }}
       </li>
@@ -108,6 +109,9 @@ export default ManageMember;
 .member {
   flex: 1;
   background: #ffffff;
+    overflow-y: auto;
+    overflow-x: hidden;
+    height: 100%;
   .list {
     display: flex;
     flex-direction: column;

+ 576 - 0
src/TUIKit/TUIComponents/container/TUIChat/manage-components/manage-notification-detail.vue

@@ -0,0 +1,576 @@
+<template>
+  <main :class="['notification', isEdit ? 'overflowHidden' : '']">
+    <div class="section" v-if="groupDetail?.id">
+      <div class="section-item">
+        <div class="userInfo">
+          <img class="img" :src="groupDetail.avatar" />
+
+          <div class="username">
+            <div class="users">
+              <span class="name">{{ groupDetail.username }}</span>
+              <span class="tag">{{ formatJobType(groupDetail.clientType) }}</span>
+            </div>
+            <div class="userTime">
+              <span class="time">{{ groupDetail.createTime }}</span>
+              <span class="tag" v-if="groupDetail.topFlag">置顶</span>
+            </div>
+          </div>
+
+          <n-popover
+            v-if="isAuth"
+            trigger="click"
+            ref="popoverRef"
+            :to="false"
+            placement="bottom-end"
+            width="160px"
+            :show-arrow="false"
+            class="popoverContainer"
+          >
+            <template #trigger>
+              <i class="iconMorePoint iconMore"></i>
+            </template>
+            <div class="p-list">
+              <div class="p-item" @click="onOperation(groupDetail, 'edit')">
+                编辑公告
+              </div>
+              <div class="p-item" @click="onOperation(groupDetail, 'top')">
+                设为置顶
+              </div>
+              <div
+                class="p-item p-red"
+                @click="onOperation(groupDetail, 'delete')"
+              >
+                删除公告
+              </div>
+            </div>
+          </n-popover>
+        </div>
+
+        <div class="section-content">
+          <h2>{{ groupDetail.title }}</h2>
+          <div class="content">
+            {{ groupDetail.content }}
+          </div>
+        </div>
+      </div>
+    </div>
+
+    <n-tooltip
+      trigger="hover"
+      :show-arrow="false"
+      class="toolsNotifi"
+      v-if="groupDetail.length > 0 && !isEdit"
+    >
+      <template #trigger>
+        <div class="iconNotifiAdd" @click="onOperation({}, 'add')"></div>
+      </template>
+      发布公告
+    </n-tooltip>
+
+    <div class="edit-notification" v-if="isEdit">
+      <div class="input-section">
+        <div class="input-title">
+          <i class="iconNotifit1"></i>
+          <span>公告标题</span>
+        </div>
+        <div class="input-content">
+          <n-input
+            v-model:value="title"
+            style="
+              --n-caret-color: #198cfe;
+              --n-border-hover: 1px solid #198cfe;
+              --n-border-focus: 1px solid #198cfe;
+              --n-loading-color: #198cfe;
+              --n-box-shadow-focus: 0 0 0 2px rgba(25 140 254, 0.2);
+            "
+            type="textarea"
+            placeholder="请输入公告标题"
+            show-count
+            :maxlength="50"
+          />
+        </div>
+      </div>
+
+      <div class="input-section">
+        <div class="input-title">
+          <i class="iconNotifit2"></i>
+          <span>公告内容</span>
+        </div>
+        <div class="input-content notice-content">
+          <n-input
+            v-model:value="input"
+            style="
+              --n-caret-color: #198cfe;
+              --n-border-hover: 1px solid #198cfe;
+              --n-border-focus: 1px solid #198cfe;
+              --n-loading-color: #198cfe;
+              --n-box-shadow-focus: 0 0 0 2px rgba(25 140 254, 0.2);
+            "
+            type="textarea"
+            placeholder="请输入公告内容"
+            :rows="10"
+            show-count
+            :maxlength="200"
+          />
+        </div>
+      </div>
+      <div class="input-section">
+        <div class="input-title input-slider">
+          <span>设置为置顶</span>
+
+          <Slider :open="topFlag" @change="onTopFlag" />
+        </div>
+      </div>
+      <div
+        :class="['submitBtn', !title || !input ? 'disabled' : '']"
+        @click="onSubmit"
+      >
+        发布
+      </div>
+    </div>
+  </main>
+</template>
+
+<script lang="ts">
+import {
+  defineComponent,
+  watchEffect,
+  reactive,
+  toRefs,
+  onMounted,
+  ref,
+} from "vue";
+import {
+  imGroupNoticeDetail,
+  imGroupNoticeSave,
+  imGroupNoticeUpdate,
+  imGroupNoticeRemove,
+} from "../../../../api";
+import Slider from "../../../components/sliderTUI/index.vue";
+const ManageNotification = defineComponent({
+  components: {
+    Slider,
+  },
+  props: {
+    data: {
+      type: Object,
+      default: () => ({}),
+    },
+    isAuth: {
+      type: Boolean,
+      default: false,
+    },
+    noticeId: {
+      type: String,
+      default: ""
+    }
+  },
+  setup(props: any, ctx: any) {
+    const data: any = reactive({
+      groupProfile: {},
+      id: "",
+      title: "",
+      input: "",
+      topFlag: true, // 是否置顶
+      loading: false,
+      groupDetail: {},
+      isEdit: false,
+    });
+    const popoverRef: any = ref();
+    const getNotification = async () => {
+      data.loading = true;
+      try {
+        // 获取群公告
+        let res = await imGroupNoticeDetail(data.id);
+        data.groupDetail = res.data || {};
+      } catch (e: any) {
+        //
+      }
+      data.loading = false;
+    };
+
+    const onMore = () => {
+      data.page = data.page + 1;
+      getNotification();
+    };
+
+    watchEffect(() => {
+      data.groupProfile = props.data;
+      data.id = props.noticeId
+      console.log(props)
+      // 不使用默认的数据,从我们自己的数据库中选择
+      // data.input = data.groupProfile.notification;
+      getNotification();
+    });
+
+    const formatJobType = (jobType: string) => {
+      const template = {
+        TEACHER: "音乐老师",
+        ADMIN: "管理员",
+        HEADMASTER: "校长",
+      } as any;
+      return template[jobType];
+    };
+
+
+    const onOperation = async (item: any, type: string) => {
+      try {
+        if (type === "edit") {
+          ctx.emit("changeStatus", "editDetail");
+          data.isEdit = true;
+          data.title = item.title;
+          data.input = item.content;
+          data.topFlag = item.topFlag;
+          data.id = item.id;
+        } else if (type === "top") {
+          await imGroupNoticeUpdate({
+            groupId: data.groupProfile.groupID,
+            topFlag: true,
+            id: item.id,
+          });
+          getNotification();
+        } else if (type === "delete") {
+          await imGroupNoticeRemove({
+            id: item.id,
+          });
+          ctx.emit("changeStatus", "deleteDetail");
+        } else if (type === "add") {
+          data.isEdit = true;
+          data.title = "";
+          data.input = "";
+          data.topFlag = true;
+          data.id = "";
+          ctx.emit("changeStatus", "addDetail");
+        }
+      } catch (e) {
+        //
+      }
+      popoverRef.value?.setShow(false);
+    };
+
+    const onSubmit = async () => {
+      if (!data.title || !data.input) {
+        return;
+      }
+      try {
+        //
+        if (data.id) {
+          await imGroupNoticeUpdate({
+            groupId: data.groupProfile.groupID,
+            topFlag: data.topFlag,
+            title: data.title,
+            content: data.input,
+            id: data.id,
+          });
+        } else {
+          await imGroupNoticeSave({
+            groupId: data.groupProfile.groupID,
+            title: data.title,
+            content: data.input,
+            topFlag: data.topFlag,
+          });
+        }
+
+        data.isEdit = false;
+        ctx.emit("changeStatus", "submitDetail");
+        data.page = 1;
+        data.groupDetail = [];
+        getNotification();
+      } catch {
+        //
+      }
+    };
+
+    const onTopFlag = (val: any) => {
+      console.log(val, 'onTopFlag')
+      data.topFlag = val
+    }
+
+    const onCloseEdit = () => {
+      data.isEdit = false;
+    };
+
+    ctx.expose({
+      onCloseEdit,
+    });
+
+    return {
+      ...toRefs(data),
+      popoverRef,
+      formatJobType,
+      onMore,
+      onTopFlag,
+      // updateProfile,
+      onOperation,
+      onSubmit,
+    };
+  },
+});
+export default ManageNotification;
+</script>
+
+<style lang="scss" scoped>
+@import url("../../../styles/common.scss");
+@import url("../../../styles/icon.scss");
+.notification {
+  position: relative;
+  flex: 1;
+  background: #ffffff;
+    overflow-y: auto;
+    overflow-x: hidden;
+    height: 100%;
+  // padding: 20px;
+  display: flex;
+  flex-direction: column;
+  background: #f8f9fc;
+
+  &.overflowHidden {
+    overflow: hidden;
+  }
+}
+
+.list-item {
+  padding: 13px;
+  align-items: center;
+  font-size: 14px;
+  overflow: hidden;
+  text-align: center;
+  cursor: pointer;
+}
+
+.section-item {
+  background: #fff;
+  padding: 20px;
+  margin-bottom: 8px;
+  .userInfo {
+    position: relative;
+    display: flex;
+    align-items: center;
+    border-bottom: 1px solid #f2f2f2;
+    padding-bottom: 16px;
+    margin-bottom: 16px;
+
+    .img {
+      width: 45px;
+      height: 45px;
+      border-radius: 6px;
+      margin-right: 10px;
+    }
+
+    .iconMore {
+      width: 23px;
+      height: 17px;
+      position: absolute;
+      right: 0;
+      top: 5px;
+      cursor: pointer;
+    }
+  }
+  .users {
+    display: flex;
+    align-items: center;
+    .name {
+      font-weight: 600;
+      font-size: 16px;
+      color: #333333;
+      line-height: 22px;
+    }
+    .tag {
+      margin-left: 5px;
+      font-weight: 400;
+      font-size: 12px;
+      line-height: 17px;
+      color: #2089ff;
+      background: #e8f4ff;
+      border-radius: 3px;
+      border: 1px solid rgba(25, 140, 254, 0.5);
+      padding: 0 4px;
+    }
+  }
+  .userTime {
+    .time {
+      font-size: 13px;
+      color: #777777;
+      line-height: 18px;
+    }
+    .tag {
+      font-size: 12px;
+      color: #f44541;
+      line-height: 17px;
+      border-radius: 10px;
+      border: 1px solid #f44541;
+      padding: 0 8px;
+      border-radius: 20px;
+      margin-left: 6px;
+    }
+  }
+
+  .section-content {
+    h2 {
+      font-weight: 600;
+      font-size: 16px;
+      color: #333333;
+      line-height: 24px;
+      word-wrap: break-word;
+      word-break: break-all;
+    }
+    .content {
+      font-size: 16px;
+      color: #777777;
+      line-height: 24px;
+      word-wrap: break-word;
+      word-break: break-all;
+    }
+  }
+}
+
+.iconNotifiAdd {
+  position: fixed;
+  bottom: 24px;
+  right: 16px;
+  width: 58px;
+  height: 58px;
+}
+
+.theEmpty {
+  width: 100%;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  flex-direction: column;
+  flex: 1;
+  background: #fff;
+  padding-bottom: 40px;
+
+  .emptyImg {
+    width: 210px;
+    height: 210px;
+  }
+
+  p {
+    font-size: 16px;
+    color: #aaaaaa;
+    line-height: 22px;
+  }
+}
+
+.notificationBtn {
+  margin-top: 10px;
+}
+
+.edit-notification {
+  position: fixed;
+  width: 360px;
+  height: calc(100% - 109Px);
+  top: 109Px;
+  right: 0;
+  z-index: 9;
+  background: #fff;
+  padding: 0 20px;
+  overflow-x: hidden;
+  overflow-y: auto;
+
+  .input-section {
+    padding-top: 20px;
+  }
+
+  .input-title {
+    display: flex;
+    align-items: center;
+    font-size: 16px;
+    color: #333333;
+    line-height: 22px;
+    padding-bottom: 10px;
+    .iconNotifit1,
+    .iconNotifit2 {
+      width: 22px;
+      height: 22px;
+      margin-right: 6px;
+      flex-shrink: 0;
+    }
+    span {
+      line-height: 1;
+      padding-bottom: 4px;
+    }
+  }
+
+  .input-slider {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    span {
+      padding-bottom: 0;
+    }
+
+    .slider-box {
+      cursor: pointer;
+    }
+  }
+
+  .n-input {
+    border-radius: 6px !important;
+    .n-input-wrapper {
+      padding-bottom: 18px !important;
+    }
+  }
+}
+
+.submitBtn {
+  margin-top: 30px;
+  margin-bottom: 20px;
+  background: #198cfe;
+  border-radius: 8px;
+  font-weight: 600;
+  font-size: 18px;
+  color: #ffffff;
+  line-height: 47px;
+  text-align: center;
+  cursor: pointer;
+
+  &.disabled {
+    opacity: 0.7;
+    cursor: not-allowed;
+  }
+}
+</style>
+<style lang="scss">
+.notice-content {
+  .n-input .n-input-wrapper {
+    padding-bottom: 18px !important;
+  }
+}
+
+.popoverContainer {
+  background: #ffffff;
+  box-shadow: 0px 2px 17px 0px rgba(0, 0, 0, 0.08) !important;
+  border-radius: 12px !important;
+  padding: 8px !important;
+  margin-top: 8px !important;
+
+  .p-item {
+    margin-bottom: 8px;
+    font-size: 16px;
+    color: #131415;
+    border-radius: 8px;
+    padding: 12px 0;
+    text-align: center;
+    cursor: pointer;
+    &:hover {
+      background: #f3f3f5;
+    }
+    &:last-child {
+      margin-bottom: 0;
+    }
+    &.p-red {
+      color: #f44541;
+    }
+  }
+}
+.toolsNotifi .n-popover__content {
+  color: #fff !important;
+}
+
+.notificationBtn .n-button__content {
+  color: #ffffff;
+}
+</style>

+ 20 - 9
src/TUIKit/TUIComponents/container/TUIChat/manage-components/manage-notification.vue

@@ -1,5 +1,5 @@
 <template>
-  <main class="notification">
+  <main :class="['notification', isEdit ? 'overflowHidden' : '']">
     <div class="section">
       <div class="section-item" v-for="(item, index) in groupList" :key="index">
         <div class="userInfo">
@@ -135,9 +135,7 @@
 
           <Slider :open="topFlag" @change="onTopFlag" />
         </div>
-        <!-- :open="conversation.groupProfile.muteAllMembers"  @change="setAllMuteTime" -->
       </div>
-
       <div
         :class="['submitBtn', !title || !input ? 'disabled' : '']"
         @click="onSubmit"
@@ -375,10 +373,18 @@ export default ManageNotification;
 .notification {
   position: relative;
   flex: 1;
+  background: #ffffff;
+    overflow-y: auto;
+    overflow-x: hidden;
+    height: 100%;
   // padding: 20px;
   display: flex;
   flex-direction: column;
   background: #f8f9fc;
+
+  &.overflowHidden {
+    overflow: hidden;
+  }
 }
 
 .list-item {
@@ -463,18 +469,21 @@ export default ManageNotification;
       font-size: 16px;
       color: #333333;
       line-height: 24px;
+      word-wrap: break-word;
+      word-break: break-all;
     }
     .content {
       font-size: 16px;
       color: #777777;
       line-height: 24px;
+      word-wrap: break-word;
       word-break: break-all;
     }
   }
 }
 
 .iconNotifiAdd {
-  position: absolute;
+  position: fixed;
   bottom: 24px;
   right: 16px;
   width: 58px;
@@ -508,15 +517,16 @@ export default ManageNotification;
 }
 
 .edit-notification {
-  position: absolute;
-  top: 0;
-  left: 0;
+  position: fixed;
+  width: 360px;
+  height: calc(100% - 109Px);
+  top: 109Px;
   right: 0;
-  bottom: 0;
   z-index: 9;
   background: #fff;
-
   padding: 0 20px;
+  overflow-x: hidden;
+  overflow-y: auto;
 
   .input-section {
     padding-top: 20px;
@@ -565,6 +575,7 @@ export default ManageNotification;
 
 .submitBtn {
   margin-top: 30px;
+  margin-bottom: 20px;
   background: #198cfe;
   border-radius: 8px;
   font-weight: 600;

+ 26 - 4
src/TUIKit/TUIComponents/container/TUIChat/manage-components/manage.vue

@@ -116,6 +116,7 @@
       <!-- :isShowDel="conversation.groupProfile.selfInfo.role === 'Owner'" -->
       <MemeberProfile v-else-if="currentTab === 'profile'" :userInfo="currentMember" />
       <ManageNotification ref="manageNotificationRef" v-else-if="currentTab === 'notification' || currentTab === 'notificationAdd' || currentTab === 'notificationUpdate'" :isAuth="isAuth" :data="conversation.groupProfile" @update="updateProfile" @changeStatus="onNotificationChangeStatus" />
+      <ManageNotificationDetail ref="manageNotificationDetailRef" v-else-if="currentTab === 'notificationDetail' || currentTab === 'notificationAddDetail' || currentTab === 'notificationUpdateDetail'" :noticeId="noticeId" :isAuth="isAuth" :data="conversation.groupProfile" @changeStatus="onNotificationChangeStatus" />
       <main class="admin" v-else-if="currentTab === 'admin'">
         <div class="admin-list" v-if="isAdmin">
           <label>{{ $t(`TUIChat.manage.群管理员`) }}</label>
@@ -192,6 +193,7 @@ import Transfer from "../../../components/transferTUI/index.vue";
 import Slider from "../../../components/sliderTUI/index.vue";
 import ManageName from "./manage-name.vue";
 import ManageNotification from "./manage-notification.vue";
+import ManageNotificationDetail from "./manage-notification-detail.vue";
 import ManageMember from "./manage-member.vue";
 import MemeberProfile from "./member-profile.vue";
 import DialogTUI from "../../../components/dialogTUi/index.vue";
@@ -208,6 +210,7 @@ const manage = defineComponent({
     Slider,
     ManageName,
     ManageNotification,
+    ManageNotificationDetail,
     ManageMember,
     MemeberProfile,
     DialogTUI,
@@ -248,6 +251,7 @@ const manage = defineComponent({
       editLableName: "",
       mask: false,
       currentTab: "",
+      noticeId: "", // 查看公告详情时
       transferType: "",
       isSearch: false,
       isRadio: false,
@@ -284,6 +288,7 @@ const manage = defineComponent({
 
     const dialog: any = ref();
     const manageNotificationRef: any = ref()
+    const manageNotificationDetailRef: any = ref()
 
     watchEffect(() => {
       data.conversation = props.conversation;
@@ -300,11 +305,16 @@ const manage = defineComponent({
           name = "群公告";
           break;
         case "notificationAdd":
+          case "notificationAddDetail":
           name = '添加群公告';
           break;
         case "notificationUpdate":
+        case "notificationUpdateDetail":
           name = '修改群公告';
           break;
+        case "notificationDetail":
+          name = "公告详情";
+          break;
          case "member":
           name = "群成员";
           break;
@@ -570,14 +580,20 @@ const manage = defineComponent({
 
     /** 群公告修改 */
     const onNotificationChangeStatus = (type: string) => {
-      console.log(type, 'type')
-      console.log(manageNotificationRef.value)
       if(type === "add") {
         data.currentTab = 'notificationAdd'
       } else if(type === "edit") {
         data.currentTab = 'notificationUpdate'
       } else if(type === "submit") {
         data.currentTab = 'notification'
+      } else if(type === "addDetail") {
+        data.currentTab = 'notificationAddDetail'
+      } else if(type === "editDetail") {
+        data.currentTab = 'notificationUpdateDetail'
+      } else if(type === "submitDetail") {
+        data.currentTab = 'notificationDetail'
+      } else if(type === "deleteDetail") {
+        data.currentTab = ""
       }
     }
 
@@ -601,6 +617,11 @@ const manage = defineComponent({
         data.currentTab = 'notification'
         return
       }
+      if(data.currentTab === "notificationAddDetail" || data.currentTab === "notificationUpdateDetail") {
+        manageNotificationDetailRef.value?.onCloseEdit()
+        data.currentTab = 'notificationDetail'
+        return
+      }
 
       if(tabName === 'onlyMute') {
         getUserList()
@@ -899,9 +920,9 @@ const manage = defineComponent({
 
     onMounted(() => {
       eventGlobal.on('handleNotice', (id: any) => {
-        console.log('22222')
-        data.currentTab = "notification"
         data.show = !data.show;
+        data.noticeId = id
+        data.currentTab = "notificationDetail"
         if (data.show) {
           getMember();
         }
@@ -948,6 +969,7 @@ const manage = defineComponent({
       showUserNum,
       dialog,
       manageNotificationRef,
+      manageNotificationDetailRef,
       handleGroupIDCopy,
       handleMemberProfileShow,
     };

+ 8 - 0
src/TUIKit/api.ts

@@ -99,11 +99,19 @@ export const imGroupNoticeUpdate = (params?: object) => {
 /**
  * 即时通讯 - 详情
  */
+export const imGroupNoticeDetail = (id?: any) => {
+  return request.get(api + "/imGroupNotice/detail/" + id);
+};
+
+
 let imGroupDetailUrl = api + "/imGroup/detail/";
 if (platform == "daya") {
   // https://test.dayaedu.com/api-teacher/imGroup/getDetail/1664236980537458690
   imGroupDetailUrl = api + "/imGroup/getDetail/";
 }
+/**
+ * 即时通讯 - 详情
+ */
 export const imGroupDetail = (params?: any) => {
   return request.get(imGroupDetailUrl + params.id);
 };