|
@@ -12,22 +12,50 @@
|
|
|
chatMessage.senderId === loginUser.userId || chatMessage.proxySenderId === loginUser.userId ? 'my-message' : 'other-message']">
|
|
|
<!-- 自己的消息,头像在右,消息在左 -->
|
|
|
<template v-if="chatMessage.senderId === loginUser.userId || chatMessage.proxySenderId === loginUser.userId">
|
|
|
- <div class="message-content my-message-content" :style="{ backgroundColor: '#a9ea7a' }">
|
|
|
+ <div v-if="chatMessage.type === 1" class="message-content my-message-content" :style="{ backgroundColor: '#a9ea7a' }">
|
|
|
{{ chatMessage.message }}
|
|
|
</div>
|
|
|
+ <div v-if="chatMessage.type === 3" class="message-content my-message-content" :style="{ padding: 0 }">
|
|
|
+ <!-- 红包消息 -->
|
|
|
+ <div class="red-packet-message-card" @click="openRedPacket(chatMessage.messageExt.id)">
|
|
|
+ <img src="../static/images/redpacket.png" class="red-packet-icon">
|
|
|
+ <div class="red-packet-blessing">
|
|
|
+ {{chatMessage.messageExt.blessing ? chatMessage.messageExt.blessing : '恭喜发财, 大吉大利'}}
|
|
|
+ </div>
|
|
|
+ <div class="red-packet-name">
|
|
|
+ WebChat 红包
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
<div class="message-avatar my-avatar">
|
|
|
<img :src="loginUser.photo" alt="avatar" />
|
|
|
+ <div v-if="chatMessage.type === 3" class="chat-mess-triangle-right" style="border-left: 16px solid #e99f4f"></div>
|
|
|
+ <div v-if="chatMessage.type != 3" class="chat-mess-triangle-right" style="border-left: 16px solid #a9ea7a"></div>
|
|
|
</div>
|
|
|
</template>
|
|
|
<!-- 其他人的消息,头像在左,消息在右 -->
|
|
|
<template v-else>
|
|
|
<div class="message-avatar other-avatar">
|
|
|
<img :src="chatMessage.proxySender != null ? chatMessage.proxySender?.photo : selectChatUser.photo" alt="avatar" />
|
|
|
+ <div v-if="chatMessage.type === 3" class="chat-mess-triangle-left" style="border-right: 16px solid #e99f4f"></div>
|
|
|
+ <div v-if="chatMessage.type != 3" class="chat-mess-triangle-left" style="border-right: 16px solid #f5f5f5"></div>
|
|
|
</div>
|
|
|
<div class="proxy-user-name">{{ chatMessage.proxySender.userName }}</div>
|
|
|
- <div class="message-content other-message-content" :style="{ backgroundColor: '#f5f5f5' }">
|
|
|
+ <div v-if="chatMessage.type === 1" class="message-content other-message-content" :style="{ backgroundColor: '#f5f5f5' }">
|
|
|
{{ chatMessage.message }}
|
|
|
</div>
|
|
|
+ <div v-if="chatMessage.type === 3" class="message-content other-message-content" :style="{ padding: 0 }">
|
|
|
+ <!-- 红包消息 -->
|
|
|
+ <div class="red-packet-message-card" @click="openRedPacket(chatMessage.messageExt.id)">
|
|
|
+ <img src="../static/images/redpacket.png" class="red-packet-icon">
|
|
|
+ <div class="red-packet-blessing">
|
|
|
+ {{chatMessage.messageExt.blessing ? chatMessage.messageExt.blessing : '恭喜发财, 大吉大利'}}
|
|
|
+ </div>
|
|
|
+ <div class="red-packet-name">
|
|
|
+ WebChat 红包
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
</template>
|
|
|
<!-- 消息内容出发特效关键词 -->
|
|
|
<ChatEmojiAnimations
|
|
@@ -96,11 +124,97 @@
|
|
|
:openVideo="openVideo"
|
|
|
@close="handleVideoClose"/>
|
|
|
</a-modal>
|
|
|
+
|
|
|
+
|
|
|
+ <a-modal
|
|
|
+ v-model:visible="openRedPacketModalVisible"
|
|
|
+ :width="300"
|
|
|
+ :height="300"
|
|
|
+ :okButtonProps="{ style: { display: 'none' } }"
|
|
|
+ :cancelButtonProps="{ style: { display: 'none' } }"
|
|
|
+ class="openRedPacket"
|
|
|
+ >
|
|
|
+ <div class="open-red-packet-header" style="text-align: center;">
|
|
|
+ <div style="color: #666; font-size: 18px; line-height: 50px;">{{openRedPacketText}}</div>
|
|
|
+ <div style="font-size: 35px; color: #c1a36e;">{{openRedPacketAmount}}</div>
|
|
|
+ </div>
|
|
|
+ </a-modal>
|
|
|
+
|
|
|
+ <a-modal
|
|
|
+ v-model:visible="sendRedPacketModalVisible"
|
|
|
+ :width="400"
|
|
|
+ :height="450"
|
|
|
+ class="red-packet-modal"
|
|
|
+ :okButtonProps="{ style: { display: 'none' } }"
|
|
|
+ :cancelButtonProps="{ style: { display: 'none' } }"
|
|
|
+ >
|
|
|
+ <template #title>
|
|
|
+ <div class="modal-title" style="margin-bottom: 10px;">
|
|
|
+ 发红包
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ <!-- 隐藏的文件上传input -->
|
|
|
+ <input
|
|
|
+ type="file"
|
|
|
+ ref="redPacketFileInput"
|
|
|
+ accept="image/*"
|
|
|
+ style="display: none;"
|
|
|
+ @change="handleFileUpload"
|
|
|
+ />
|
|
|
+ <a-dropdown>
|
|
|
+ <a class="ant-dropdown-link" @click.prevent style="color: #ff5e4b; font-weight: 600;">
|
|
|
+ 选择红包类型
|
|
|
+ <RightOutlined />
|
|
|
+ </a>
|
|
|
+ <template #overlay>
|
|
|
+ <a-menu>
|
|
|
+ <a-menu-item>
|
|
|
+ <a href="javascript:;">拼手气红包</a>
|
|
|
+ </a-menu-item>
|
|
|
+ <a-menu-item>
|
|
|
+ <a href="javascript:;">固定红包</a>
|
|
|
+ </a-menu-item>
|
|
|
+ </a-menu>
|
|
|
+ </template>
|
|
|
+ </a-dropdown>
|
|
|
+ <a-input prefix="¥" suffix="RMB" class="red-packet-input" placeholder="红包金额 ¥0.00" v-model:value="sendTotalMoney"/>
|
|
|
+ <a-input suffix="个" class="red-packet-input" placeholder="红包个数" v-model:value="sendTotalCount"/>
|
|
|
+ <a-input suffix="😊" class="red-packet-input" placeholder="恭喜发财,大吉大利" v-model:value="sendBlessing"/>
|
|
|
+ <a-dropdown style="width: 100%">
|
|
|
+ <template #overlay>
|
|
|
+ <a-menu @click="uploadRedPacketCover">
|
|
|
+ <a-menu-item key="1">
|
|
|
+ <PictureOutlined />
|
|
|
+ 上传红包红面
|
|
|
+ </a-menu-item>
|
|
|
+ </a-menu>
|
|
|
+ </template>
|
|
|
+ <a-button class="red-packet-cover-button">
|
|
|
+ 红包封面 <RightOutlined />
|
|
|
+ <!-- 显示预览图 -->
|
|
|
+ <img
|
|
|
+ v-if="redPacketCover"
|
|
|
+ :src="redPacketCover"
|
|
|
+ class="cover-preview"
|
|
|
+ />
|
|
|
+ </a-button>
|
|
|
+ </a-dropdown>
|
|
|
+ <div class="red-packet-money">
|
|
|
+ ¥ {{sendTotalMoney}}
|
|
|
+ </div>
|
|
|
+ <a-button type="primary" class="send-red-packet-button" @click="sendRedPacket">塞钱进红包</a-button>
|
|
|
+
|
|
|
+ <div class="red-packet-tip">
|
|
|
+ 使用WebChat钱包余额直接发红包
|
|
|
+ </div>
|
|
|
+
|
|
|
+ </a-modal>
|
|
|
</template>
|
|
|
|
|
|
<script>
|
|
|
import axios from 'axios';
|
|
|
import { inject, defineComponent, ref, onMounted, onUnmounted, watch } from 'vue';
|
|
|
+ import { message } from 'ant-design-vue';
|
|
|
import Video2Group from './video2group.vue';
|
|
|
import ChatEmojiAnimations from './animation/emojiAnimations.vue';
|
|
|
export default defineComponent({
|
|
@@ -126,9 +240,23 @@
|
|
|
const groupDetailVisible = ref(false)
|
|
|
const groupVideoModalVisible = ref(false);
|
|
|
|
|
|
+ const openRedPacketModalVisible = ref(false)
|
|
|
+ const sendRedPacketModalVisible = ref(false)
|
|
|
+ const redPacketMoney = ref(0.00)
|
|
|
+ const redPacketCover = ref(null);
|
|
|
+ const redPacketFileInput = ref(null);
|
|
|
+ const uploadUrl = `/client-service/chat/file/upload`; // 上传API
|
|
|
+
|
|
|
const showChatEmojiAnimations = ref(false);
|
|
|
const emojis = ref([""]);
|
|
|
|
|
|
+ const redPacketType = ref(2);
|
|
|
+ const sendTotalMoney = ref(0.0);
|
|
|
+ const sendTotalCount = ref(1);
|
|
|
+ const sendBlessing = ref("恭喜发财,大吉大利");
|
|
|
+ const openRedPacketText = ref("恭喜你,获得");
|
|
|
+ const openRedPacketAmount = ref("¥ 0.00");
|
|
|
+
|
|
|
// 维护关键词,emoji特效
|
|
|
const messageKeywords = ["生日快乐", "比心", "爱你", "礼物", "红包", "💣", "炸弹", "💩", "屎"];
|
|
|
const messageKeywordsEmojis = ["🍰", "♥️", "😘", "🎁", "🧧", "💣", "💣", "💩", "💩"];
|
|
@@ -176,10 +304,12 @@
|
|
|
// 在此处理收到的消息
|
|
|
const socketMessage = JSON.parse(event.data);
|
|
|
if(socketMessage.senderId != selectChatUser.value.userId) {
|
|
|
- return;
|
|
|
+ if (messageType === 1) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
}
|
|
|
const messageType = socketMessage.type;
|
|
|
- if (messageType === 1) {
|
|
|
+ if (messageType === 1 || messageType === 3) {
|
|
|
// 处理对话
|
|
|
chatMessageArr.value.push(socketMessage);
|
|
|
// 关键词出发emoji飘落特效
|
|
@@ -293,6 +423,102 @@
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ // 点击上传菜单项
|
|
|
+ const uploadRedPacketCover = ({ key }) => {
|
|
|
+ if (key === '1') {
|
|
|
+ // 触发隐藏的input点击
|
|
|
+ redPacketFileInput.value.click();
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ // 处理文件选择
|
|
|
+ const handleFileUpload = async (e) => {
|
|
|
+ const file = e.target.files[0];
|
|
|
+ if (!file) return;
|
|
|
+ // 校验文件类型
|
|
|
+ if (!file.type.startsWith('image/')) {
|
|
|
+ message.error('请选择图片文件');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ // 校验文件大小(示例限制2MB)
|
|
|
+ if (file.size > 10 * 1024 * 1024) {
|
|
|
+ message.error('图片大小不能超过10MB');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ // 方式2:上传到服务器(示例使用axios)
|
|
|
+ try {
|
|
|
+ const formData = new FormData();
|
|
|
+ formData.append('file', file);
|
|
|
+ const response = await axios.post(uploadUrl, formData, {
|
|
|
+ headers: {
|
|
|
+ 'Content-Type': 'multipart/form-data',
|
|
|
+ 'origin-url': window.location.href,
|
|
|
+ 'upload-path': 'images/redPacket'
|
|
|
+ }
|
|
|
+ });
|
|
|
+ if (response.data.code === 40001) {
|
|
|
+ window.location.href = response.data.redirect_url;
|
|
|
+ }
|
|
|
+ // 预览红包封面图
|
|
|
+ redPacketCover.value = response.data.data.url;
|
|
|
+ } catch (error) {
|
|
|
+ message.error('上传失败');
|
|
|
+ console.error('Upload error:', error);
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ const sendRedPacket = async () => {
|
|
|
+ if (!sendTotalMoney.value || sendTotalMoney.value < 1 || sendTotalMoney.value > 200) {
|
|
|
+ message.error("红包金额控制在1 ~ 200元以内");
|
|
|
+ return ;
|
|
|
+ }
|
|
|
+ if (!sendTotalCount.value || sendTotalCount.value < 1) {
|
|
|
+ message.error("最少发出一个红包");
|
|
|
+ return ;
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ // 调用接口发送登录请求
|
|
|
+ const response = await axios.post(`/client-service/chat/red-packet/send`,
|
|
|
+ {
|
|
|
+ receiver: selectChatUser.value.userId,
|
|
|
+ totalMoney: sendTotalMoney.value,
|
|
|
+ blessing: sendBlessing.value,
|
|
|
+ type: 2,
|
|
|
+ count: sendTotalCount.value
|
|
|
+ });
|
|
|
+ if (response.data.code === 40001) {
|
|
|
+ window.location.href = response.data.redirect_url;
|
|
|
+ } else if (response.data.code != 200) {
|
|
|
+ message.error(response.data.msg);
|
|
|
+ } else {
|
|
|
+ sendRedPacketModalVisible.value = false;
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ // 处理错误,例如显示错误消息
|
|
|
+ console.log("====>" + error);
|
|
|
+ message.error("服务异常,稍后重试", error);
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ const openRedPacket = async (redPacketId) => {
|
|
|
+ const response = await axios.get(`/client-service/chat/red-packet/open/` + redPacketId, {
|
|
|
+ // 这里可以添加请求的配置,例如 headers 或 params
|
|
|
+ })
|
|
|
+ if (response.data.code === 40001) {
|
|
|
+ window.location.href = response.data.redirect_url;
|
|
|
+ return;
|
|
|
+ } else if (response.data.code === 200) {
|
|
|
+ openRedPacketText.value = "🎉 恭喜你,获得 ";
|
|
|
+ openRedPacketAmount.value = "¥ " + response.data.data;
|
|
|
+ openRedPacketModalVisible.value = true;
|
|
|
+ } else {
|
|
|
+ openRedPacketText.value = "😅 哎呀~";
|
|
|
+ openRedPacketAmount.value = response.data.msg;
|
|
|
+ openRedPacketModalVisible.value = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
const handleClick = (type) => {
|
|
|
switch (type) {
|
|
|
case 'emoji':
|
|
@@ -301,11 +527,10 @@
|
|
|
break;
|
|
|
case 'redPacket':
|
|
|
console.log('点击了红包按钮');
|
|
|
- // 在此添加红包按钮的逻辑,例如打开红包发送界面等
|
|
|
+ sendRedPacketModalVisible.value = true;
|
|
|
break;
|
|
|
case 'audioVideo':
|
|
|
console.log('点击了音视频按钮');
|
|
|
- // 在此添加音视频按钮的逻辑,例如打开音视频通话界面等
|
|
|
groupVideoModalVisible.value = true;
|
|
|
break;
|
|
|
case 'file':
|
|
@@ -325,6 +550,16 @@
|
|
|
|
|
|
|
|
|
return {
|
|
|
+ sendTotalCount,
|
|
|
+ openRedPacketModalVisible,
|
|
|
+ sendTotalMoney,
|
|
|
+ sendBlessing,
|
|
|
+ redPacketType,
|
|
|
+ uploadUrl,
|
|
|
+ redPacketCover,
|
|
|
+ redPacketFileInput,
|
|
|
+ sendRedPacketModalVisible,
|
|
|
+ redPacketMoney,
|
|
|
showChatEmojiAnimations,
|
|
|
emojis,
|
|
|
openVideo,
|
|
@@ -338,6 +573,10 @@
|
|
|
heartbeatInterval,
|
|
|
chatMessageArr,
|
|
|
groupDetailVisible,
|
|
|
+ openRedPacketText,
|
|
|
+ openRedPacketAmount,
|
|
|
+ openRedPacket,
|
|
|
+ sendRedPacket,
|
|
|
handleVideoModalVisibleChange,
|
|
|
handleClick,
|
|
|
handleSendMessage,
|
|
@@ -346,7 +585,9 @@
|
|
|
afterVisibleChange,
|
|
|
showDrawer,
|
|
|
loadChatMessages,
|
|
|
- handleVideoClose
|
|
|
+ handleVideoClose,
|
|
|
+ handleFileUpload,
|
|
|
+ uploadRedPacketCover
|
|
|
};
|
|
|
}
|
|
|
});
|
|
@@ -444,6 +685,7 @@
|
|
|
justify-content: flex-start;
|
|
|
}
|
|
|
.message-avatar {
|
|
|
+ position: relative;
|
|
|
margin-right: 10px;
|
|
|
}
|
|
|
.message-avatar img {
|
|
@@ -509,4 +751,101 @@
|
|
|
height: 100%;
|
|
|
z-index: 999;
|
|
|
}
|
|
|
+.red-packet-input, .red-packet-cover-button {
|
|
|
+ height: 50px;
|
|
|
+ margin-top: 15px;
|
|
|
+ background-color: white;
|
|
|
+}
|
|
|
+.red-packet-cover-button {
|
|
|
+ width: 100%;
|
|
|
+ text-align: left;
|
|
|
+}
|
|
|
+.send-red-packet-button {
|
|
|
+ background-color: #ff5e4b;
|
|
|
+ color: white;
|
|
|
+ width: 170px;
|
|
|
+ height: 45px;
|
|
|
+ margin-top: 30px;
|
|
|
+ margin-left: 100px;
|
|
|
+}
|
|
|
+.send-red-packet-button:hover {
|
|
|
+ background-color:rgb(252, 68, 48);
|
|
|
+}
|
|
|
+.red-packet-money {
|
|
|
+ position: relative;
|
|
|
+ width: 100%;
|
|
|
+ line-height: 50px;
|
|
|
+ font-size: 35px;
|
|
|
+ margin-top: 40px;
|
|
|
+ text-align: center;
|
|
|
+ font-weight: 700;
|
|
|
+}
|
|
|
+.red-packet-tip {
|
|
|
+ color: gray;
|
|
|
+ font-size: 12px;
|
|
|
+ margin-top: 100px;
|
|
|
+ text-align: center;
|
|
|
+}
|
|
|
+.cover-preview {
|
|
|
+ position: relative;
|
|
|
+ float: right;
|
|
|
+ height: 20px;
|
|
|
+}
|
|
|
+.red-packet-message-card {
|
|
|
+ position: relative;
|
|
|
+ width: 270px;
|
|
|
+ height: 85px;
|
|
|
+ color: white;
|
|
|
+ border-radius: 5px;
|
|
|
+ background-color: #e99f4f;
|
|
|
+}
|
|
|
+.red-packet-name {
|
|
|
+ position: absolute;
|
|
|
+ left: 0px;
|
|
|
+ bottom: 0px;
|
|
|
+ border-top: 1px solid #d48a3a;
|
|
|
+ width: 100%;
|
|
|
+ height: 20px;
|
|
|
+ line-height: 20px;
|
|
|
+ color: white;
|
|
|
+ text-align: left;
|
|
|
+ text-indent: 1em;
|
|
|
+ font-size: 9px;
|
|
|
+}
|
|
|
+.red-packet-icon {
|
|
|
+ position: absolute;
|
|
|
+ left: 20px;
|
|
|
+ top: 15px;
|
|
|
+ height: 40px;
|
|
|
+ border-radius: 3px;
|
|
|
+}
|
|
|
+.red-packet-blessing {
|
|
|
+ position: absolute;
|
|
|
+ left: 70px;
|
|
|
+ top: 15px;
|
|
|
+ width: 170px;
|
|
|
+ white-space: nowrap; /* 确保文本不会换行 */
|
|
|
+ overflow: hidden; /* 隐藏超出容器的文本 */
|
|
|
+ text-overflow: ellipsis; /* 当文本超出容器时显示省略号 */
|
|
|
+ }
|
|
|
+ .chat-mess-triangle-left {
|
|
|
+ position: absolute;
|
|
|
+ right: -20px;
|
|
|
+ top: 17px;
|
|
|
+ width: 0;
|
|
|
+ height: 0;
|
|
|
+ border-top: 8px solid transparent;
|
|
|
+ border-right: 16px solid #f5f5f5;
|
|
|
+ border-bottom: 8px solid transparent;
|
|
|
+}
|
|
|
+.chat-mess-triangle-right {
|
|
|
+ position: absolute;
|
|
|
+ left: -20px;
|
|
|
+ top: 10px;
|
|
|
+ width: 0;
|
|
|
+ height: 0;
|
|
|
+ border-top: 8px solid transparent;
|
|
|
+ border-left: 16px solid #a9ea7a;
|
|
|
+ border-bottom: 8px solid transparent;
|
|
|
+}
|
|
|
</style>
|