Message.vue 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. <template>
  2. <div
  3. title="消息"
  4. @click="showMessageLayer"
  5. style="height: 18px"
  6. :class="unreadCount > 0 ? 'twinkle' : ''"
  7. >
  8. <el-badge
  9. :hidden="unreadCount <= 0"
  10. :value="unreadCount"
  11. :max="99"
  12. type="danger"
  13. >
  14. <el-icon>
  15. <Message />
  16. </el-icon>
  17. </el-badge>
  18. </div>
  19. <MessageDialog v-model="messageLayerVisible" />
  20. <el-dialog
  21. title="重要系统通知"
  22. v-model="systemMessages.show"
  23. :append-to-body="true"
  24. :destroy-on-close="true"
  25. center
  26. :close-on-click-modal="false"
  27. :close-on-press-escape="false"
  28. :show-close="false"
  29. >
  30. <div class="system-message-time">
  31. {{ systemMessages.list[systemMessages.current].sendDatetime }}
  32. </div>
  33. <pre class="system-message-content">{{
  34. systemMessages.list[systemMessages.current].content
  35. }}</pre>
  36. <div class="system-message-footer">
  37. <el-button
  38. type="primary"
  39. icon="ArrowLeft"
  40. :disabled="systemMessages.current === 0"
  41. circle
  42. title="上一条"
  43. @click="messageIndexIncrease(-1)"
  44. ></el-button>
  45. <span class="system-message-count"
  46. >{{ systemMessages.current + 1 }} /
  47. {{ systemMessages.list.length }}</span
  48. >
  49. <el-button
  50. type="primary"
  51. icon="Arrow-right"
  52. :disabled="systemMessages.current === systemMessages.list.length - 1"
  53. circle
  54. title="下一条"
  55. @click="messageIndexIncrease(1)"
  56. ></el-button>
  57. </div>
  58. <div style="width: 100%; text-align: right; margin-top: -30px">
  59. <el-button
  60. icon="Close"
  61. type="danger"
  62. :disabled="systemMessages.current !== systemMessages.list.length - 1"
  63. @click="systemMessages.show = false"
  64. >关闭
  65. </el-button>
  66. </div>
  67. </el-dialog>
  68. </template>
  69. <script setup>
  70. import { computed, onMounted, ref, reactive } from "vue";
  71. import { onPageRefresh } from "@/api/messages";
  72. import { useSystemStore } from "@/pinia/system-store";
  73. import MessageDialog from "@/layout/function-list/message/MessageDialog.vue";
  74. const systemStore = useSystemStore();
  75. const unreadCount = computed(() => {
  76. return systemStore.unreadMessageCount;
  77. });
  78. const systemMessages = reactive({
  79. show: false,
  80. list: [],
  81. current: 0,
  82. });
  83. const messageIndexIncrease = val => {
  84. systemMessages.current += val;
  85. if (val === 1) {
  86. if (
  87. pushedMessageIds.value.indexOf(
  88. systemMessages.list[systemMessages.current].id
  89. ) === -1
  90. ) {
  91. systemStore.pushSystemMessage(
  92. systemMessages.list[systemMessages.current].id
  93. );
  94. }
  95. }
  96. };
  97. const pushedMessageIds = ref([]);
  98. const messageLayerVisible = ref(false);
  99. const showMessageLayer = () => {
  100. messageLayerVisible.value = true;
  101. };
  102. onMounted(() => {
  103. pushedMessageIds.value = systemStore.systemMessages;
  104. onPageRefresh(systemStore.getSystemMessages).then(res => {
  105. systemStore.setUnreadMessageCount(res.unreadCount);
  106. if (res.systemMessage.length > 0) {
  107. systemMessages.list = res.systemMessage;
  108. systemMessages.current = 0;
  109. systemMessages.show = true;
  110. if (pushedMessageIds.value.indexOf(systemMessages.list[0].id) === -1) {
  111. pushedMessageIds.value.push(systemMessages.list[0].id);
  112. systemStore.pushSystemMessage(systemMessages.list[0].id);
  113. }
  114. }
  115. });
  116. });
  117. </script>
  118. <style lang="scss" scoped>
  119. @keyframes fade {
  120. from {
  121. opacity: 1;
  122. }
  123. 50% {
  124. opacity: 0;
  125. }
  126. to {
  127. opacity: 1;
  128. }
  129. }
  130. @-webkit-keyframes fade {
  131. from {
  132. opacity: 1;
  133. }
  134. 50% {
  135. opacity: 0;
  136. }
  137. to {
  138. opacity: 1;
  139. }
  140. }
  141. .twinkle {
  142. animation: fade 600ms infinite;
  143. -webkit-animation: fade 600ms infinite;
  144. }
  145. i {
  146. font-size: 18px !important;
  147. cursor: pointer;
  148. font-size: 18px;
  149. &:focus {
  150. outline: none;
  151. }
  152. }
  153. .message-layer {
  154. display: flex;
  155. position: absolute;
  156. top: 60px;
  157. right: 100px;
  158. width: 560px;
  159. height: 460px;
  160. border: 1px solid gray;
  161. box-shadow: 2px 3px 10px 1px gray;
  162. background: white;
  163. z-index: 1000;
  164. .sender {
  165. width: 160px;
  166. border-right: 1px solid lightgray;
  167. > div {
  168. height: 32px;
  169. line-height: 32px;
  170. padding: 0 8px;
  171. margin: 8px;
  172. border: 1px solid lightgray;
  173. &:hover {
  174. cursor: pointer;
  175. background: #409eff;
  176. color: white;
  177. font-weight: bold;
  178. }
  179. }
  180. }
  181. .content {
  182. width: 400px;
  183. padding: 8px;
  184. > p {
  185. margin-top: 8px;
  186. font-size: 15px;
  187. font-weight: bold;
  188. text-overflow: ellipsis;
  189. white-space: nowrap;
  190. overflow: hidden;
  191. }
  192. > div {
  193. margin-bottom: 16px;
  194. border-radius: 4px;
  195. border: 2px solid rgb(53, 131, 221);
  196. }
  197. }
  198. }
  199. .sender-info {
  200. width: 106px;
  201. text-overflow: ellipsis;
  202. white-space: nowrap;
  203. overflow: hidden;
  204. }
  205. .message-body {
  206. margin: 8px;
  207. border: 1px dashed;
  208. border-radius: 4px;
  209. }
  210. .content-title-box {
  211. display: flex;
  212. height: 26px;
  213. line-height: 26px;
  214. padding: 0 4px;
  215. font-weight: bold;
  216. border-bottom: 1px dashed lightgray;
  217. }
  218. .content-title {
  219. width: 260px;
  220. padding-right: 10px;
  221. text-overflow: ellipsis;
  222. white-space: nowrap;
  223. overflow: hidden;
  224. }
  225. .content-time {
  226. font-size: 12px;
  227. width: 130px;
  228. }
  229. .content-box {
  230. padding: 4px;
  231. margin-bottom: 12px;
  232. background: rgb(248, 247, 247);
  233. }
  234. .system-message-time {
  235. font-size: 13px;
  236. color: gray;
  237. }
  238. .system-message-content {
  239. margin-top: 16px;
  240. font-size: 16px;
  241. font-weight: bold;
  242. color: #303133;
  243. white-space: pre-wrap;
  244. }
  245. .system-message-footer {
  246. margin-top: 20px;
  247. width: 100%;
  248. text-align: center;
  249. > span {
  250. font-size: 12px;
  251. color: gray;
  252. margin: 0 8px;
  253. }
  254. }
  255. </style>