From a1d7e81859f554f3a53680cc35f0f49bf1f77098 Mon Sep 17 00:00:00 2001
From: wwf <1971391498@qq.com>
Date: 星期四, 14 五月 2026 14:37:02 +0800
Subject: [PATCH] 导入项目

---
 src/views/mp/components/wx-msg/main.vue |  192 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 192 insertions(+), 0 deletions(-)

diff --git a/src/views/mp/components/wx-msg/main.vue b/src/views/mp/components/wx-msg/main.vue
new file mode 100644
index 0000000..5223113
--- /dev/null
+++ b/src/views/mp/components/wx-msg/main.vue
@@ -0,0 +1,192 @@
+<!--
+  - Copyright (C) 2018-2019
+  - All rights reserved, Designed By www.joolun.com
+  鑺嬮亾婧愮爜锛�
+  鈶� 绉婚櫎鏆傛椂鐢ㄤ笉鍒扮殑 websocket
+  鈶� 浠g爜浼樺寲锛岃ˉ鍏呮敞閲婏紝鎻愬崌闃呰鎬�
+-->
+<template>
+  <ContentWrap>
+    <div class="msg-div" ref="msgDivRef">
+      <!-- 鍔犺浇鏇村 -->
+      <div v-loading="loading"></div>
+      <div v-if="!loading">
+        <div class="el-table__empty-block" v-if="hasMore" @click="loadMore"
+          ><span class="el-table__empty-text">鐐瑰嚮鍔犺浇鏇村</span></div
+        >
+        <div class="el-table__empty-block" v-if="!hasMore"
+          ><span class="el-table__empty-text">娌℃湁鏇村浜�</span></div
+        >
+      </div>
+
+      <!-- 娑堟伅鍒楄〃 -->
+      <MsgList :list="list" :account-id="accountId" :user="user" />
+    </div>
+
+    <div class="msg-send" v-loading="sendLoading">
+      <WxReplySelect ref="replySelectRef" v-model="reply" />
+      <el-button type="success" class="send-but" @click="sendMsg">鍙戦��(S)</el-button>
+    </div>
+  </ContentWrap>
+</template>
+
+<script lang="ts" setup>
+import WxReplySelect, { Reply, ReplyType } from '@/views/mp/components/wx-reply'
+import MsgList from './components/MsgList.vue'
+import { getMessagePage, sendMessage } from '@/api/mp/message'
+import { getUser } from '@/api/mp/user'
+import profile from '@/assets/imgs/profile.jpg'
+import { User } from './types'
+
+defineOptions({ name: 'WxMsg' })
+
+const message = useMessage() // 娑堟伅寮圭獥
+
+const props = defineProps({
+  userId: {
+    type: Number,
+    required: true
+  }
+})
+
+const accountId = ref(-1) // 鍏紬鍙稩D锛岄渶瑕侀�氳繃userId鍒濆鍖�
+const loading = ref(false) // 娑堟伅鍒楄〃鏄惁姝e湪鍔犺浇涓�
+const hasMore = ref(true) // 鏄惁鍙互鍔犺浇鏇村
+const list = ref<any[]>([]) // 娑堟伅鍒楄〃
+const queryParams = reactive({
+  pageNo: 1, // 褰撳墠椤垫暟
+  pageSize: 14, // 姣忛〉鏄剧ず澶氬皯鏉�
+  accountId: accountId
+})
+
+// 鐢变簬寰俊涓嶅啀鎻愪緵鏄电О锛岀洿鎺ヤ娇鐢ㄢ�滅敤鎴封�濆睍绀�
+const user: User = reactive({
+  nickname: '鐢ㄦ埛',
+  avatar: profile,
+  accountId: accountId // 鍏紬鍙疯处鍙风紪鍙�
+})
+
+// ========= 娑堟伅鍙戦�� =========
+const sendLoading = ref(false) // 鍙戦�佹秷鎭槸鍚﹀姞杞戒腑
+// 寰俊鍙戦�佹秷鎭�
+const reply = ref<Reply>({
+  type: ReplyType.Text,
+  accountId: -1,
+  articles: []
+})
+
+const replySelectRef = ref<InstanceType<typeof WxReplySelect> | null>(null) // WxReplySelect缁勪欢ref锛岀敤浜庢秷鎭彂閫佹垚鍔熷悗娓呴櫎鍐呭
+const msgDivRef = ref<HTMLDivElement | null>(null) // 娑堟伅鏄剧ず绐楀彛ref锛岀敤浜庢粴鍔ㄥ埌搴曢儴
+
+/** 瀹屾垚鍔犺浇 */
+onMounted(async () => {
+  const data = await getUser(props.userId)
+  user.nickname = data.nickname?.length > 0 ? data.nickname : user.nickname
+  user.avatar = data.headImageUrl?.length > 0 ? data.headImageUrl : user.avatar
+  accountId.value = data.accountId
+  reply.value.accountId = data.accountId
+
+  refreshChange()
+})
+
+// 鎵ц鍙戦��
+const sendMsg = async () => {
+  if (!unref(reply)) {
+    return
+  }
+  // 鍏紬鍙烽檺鍒讹細瀹㈡湇娑堟伅锛屽叕浼楀彿鍙厑璁稿彂閫佷竴鏉�
+  if (
+    reply.value.type === ReplyType.News &&
+    reply.value.articles &&
+    reply.value.articles.length > 1
+  ) {
+    reply.value.articles = [reply.value.articles[0]]
+    message.success('鍥炬枃娑堟伅鏉℃暟闄愬埗鍦� 1 鏉′互鍐咃紝宸查粯璁ゅ彂閫佺涓�鏉�')
+  }
+
+  const data = await sendMessage({ userId: props.userId, ...reply.value })
+  sendLoading.value = false
+
+  list.value = [...list.value, ...[data]]
+  await scrollToBottom()
+
+  // 鍙戦�佸悗娓呯┖鏁版嵁
+  replySelectRef.value?.clear()
+}
+
+const loadMore = () => {
+  queryParams.pageNo++
+  getPage(queryParams, null)
+}
+
+const getPage = async (page: any, params: any = null) => {
+  loading.value = true
+  const dataTemp = await getMessagePage(
+    Object.assign(
+      {
+        pageNo: page.pageNo,
+        pageSize: page.pageSize,
+        userId: props.userId,
+        accountId: page.accountId
+      },
+      params
+    )
+  )
+
+  const scrollHeight = msgDivRef.value?.scrollHeight ?? 0
+  // 澶勭悊鏁版嵁
+  const data = dataTemp.list.reverse()
+  list.value = [...data, ...list.value]
+  loading.value = false
+  if (data.length < queryParams.pageSize || data.length === 0) {
+    hasMore.value = false
+  }
+  queryParams.pageNo = page.pageNo
+  queryParams.pageSize = page.pageSize
+  // 婊氬姩鍒板師鏉ョ殑浣嶇疆
+  if (queryParams.pageNo === 1) {
+    // 瀹氫綅鍒版秷鎭簳閮�
+    await scrollToBottom()
+  } else if (data.length !== 0) {
+    // 瀹氫綅婊氬姩鏉�
+    await nextTick()
+    if (scrollHeight !== 0) {
+      if (msgDivRef.value) {
+        msgDivRef.value.scrollTop = msgDivRef.value.scrollHeight - scrollHeight - 100
+      }
+    }
+  }
+}
+
+const refreshChange = () => {
+  getPage(queryParams)
+}
+
+/** 瀹氫綅鍒版秷鎭簳閮� */
+const scrollToBottom = async () => {
+  await nextTick()
+  if (msgDivRef.value) {
+    msgDivRef.value.scrollTop = msgDivRef.value.scrollHeight
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.msg-div {
+  height: 50vh;
+  margin-right: 10px;
+  margin-left: 10px;
+  overflow: auto;
+  background-color: #eaeaea;
+}
+
+.msg-send {
+  padding: 10px;
+}
+
+.send-but {
+  float: right;
+  margin-top: 8px;
+  margin-bottom: 8px;
+}
+</style>

--
Gitblit v1.8.0