|
@@ -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>
|