潘超林 4 days ago
parent
commit
752def3a9a

+ 199 - 29
TUIKit/components/TUIChat/message-list/index.vue

@@ -30,7 +30,11 @@
         :scroll-into-view="`tui-${historyFirstMessageID}`"
         @scroll="handelScrollListScroll"
       >
-        <p v-if="!isCompleted" class="message-more" @click="getHistoryMessageList">
+        <p
+          v-if="!isCompleted"
+          class="message-more"
+          @click="getHistoryMessageList"
+        >
           {{ TUITranslateService.t("TUIChat.查看更多") }}
         </p>
         <li
@@ -45,7 +49,10 @@
           />
           <div class="message-item" @click="toggleID = ''">
             <MessageTip
-              v-if="item.type === TYPES.MSG_GRP_TIP || isCreateGroupCustomMessage(item)"
+              v-if="
+                item.type === TYPES.MSG_GRP_TIP ||
+                isCreateGroupCustomMessage(item)
+              "
               :content="item.getMessageContent()"
             />
 
@@ -91,7 +98,10 @@
                   :content="item.getMessageContent()"
                   :messageItem="item"
                 >
-                  <MessageVideo :content="item.getMessageContent()" :messageItem="item" />
+                  <MessageVideo
+                    :content="item.getMessageContent()"
+                    :messageItem="item"
+                  />
                 </ProgressMessage>
                 <MessageAudio
                   v-else-if="item.type === TYPES.MSG_AUDIO"
@@ -121,6 +131,7 @@
                 />
 
                 <MessageCustom
+                  @handleDraw="handleDraw"
                   class="MessageCustom"
                   v-else-if="item.payload.data"
                   :content="item.getMessageContent()"
@@ -151,7 +162,9 @@
               }"
               :messageItem="item"
               :isMultipleSelectMode="isMultipleSelectMode"
-              @toggleMultipleSelectMode="() => emits('toggleMultipleSelectMode')"
+              @toggleMultipleSelectMode="
+                () => emits('toggleMultipleSelectMode')
+              "
             />
           </div>
         </li>
@@ -194,6 +207,20 @@
         />
       </Drawer>
     </div>
+
+    <div class="mask" v-if="showMask">
+      <div class="back">
+        <div class="header">恭喜您获得现金红包</div>
+        <div class="main">
+          <span class="price">{{ redEnvelopeAmount }}</span>
+          <span class="unit">元</span>
+        </div>
+        <div class="footer">
+          <span class="text">红包可在【个人中心-我的钱包】中查看</span>
+          <button class="btn" @click="take">开心收下</button>
+        </div>
+      </div>
+    </div>
   </div>
 </template>
 
@@ -264,7 +291,7 @@ interface IProps {
   isNotInGroup: boolean;
   isMultipleSelectMode: boolean;
 }
-
+const showMask = ref(false);
 const emits = defineEmits<IEmits>();
 const props = withDefaults(defineProps<IProps>(), {
   isGroup: false,
@@ -296,17 +323,13 @@ const historyFirstMessageID = ref<string>("");
 const isShowSimpleMessageList = ref<boolean>(false);
 const simpleMessageListRenderMessageID = ref<string>();
 const audioPlayedMapping = ref<Record<string, boolean>>({});
-
 // audio control
 const broadcastNewAudioSrc = ref<string>("");
-
 const readStatusMessage = ref<IMessageModel>();
 const isShowReadUserStatusPanel = ref<boolean>(false);
-
 // Resend Message Dialog
 const reSendDialogShow = ref(false);
 const resendMessageData = ref();
-
 const scrollToBottom = () => {
   scrollTop.value += 300;
   // Solve the issue where swiping to the bottom for the first time after packaging Uniapp into an app has a delay,
@@ -320,7 +343,8 @@ const scrollToBottom = () => {
 const onCurrentConversationIDUpdated = (conversationID: string) => {
   currentConversationID.value = conversationID;
   if (isEnabledMessageReadReceiptGlobal()) {
-    const { groupProfile } = TUIStore.getConversationModel(conversationID) || {};
+    const { groupProfile } =
+      TUIStore.getConversationModel(conversationID) || {};
     groupType = groupProfile?.type;
   }
 
@@ -330,10 +354,41 @@ const onCurrentConversationIDUpdated = (conversationID: string) => {
   }
 };
 
+const redEnvelopeAmount = ref("");
+const redInfo = ref();
+const handleDraw = (record) => {
+  redInfo.value = record;
+  redEnvelopeAmount.value = record.info.redEnvelopeAmount;
+  if(!record.isOk){
+    Toast({
+      message: TUITranslateService.t(record.message),
+      type: TOAST_TYPE.ERROR,
+    });
+  }else{
+    showMask.value = true;
+  }
+
+};
+const take = () => {
+  if (redInfo.value.isOk) {
+    Toast({
+      message: TUITranslateService.t("红包可在【个人中心-我的钱包】中查看!"),
+      type: TOAST_TYPE.SUCCESS,
+    });
+  } else {
+    Toast({
+      message: TUITranslateService.t("红包领取失败,请联系客服反馈!"),
+      type: TOAST_TYPE.ERROR,
+    });
+  }
+
+  showMask.value = false;
+};
+
 onMounted(() => {
   // Retrieve the information about whether the audio has been played from localStorage
-  audioPlayedMapping.value = chatStorage.getChatStorage("audioPlayedMapping") || {};
-
+  audioPlayedMapping.value =
+    chatStorage.getChatStorage("audioPlayedMapping") || {};
   TUIStore.watch(StoreName.CHAT, {
     messageList: onMessageListUpdated,
     messageSource: onMessageSourceUpdated,
@@ -459,7 +514,10 @@ async function onMessageListUpdated(list: IMessageModel[]) {
 
 async function scrollToLatestMessage() {
   try {
-    const { scrollHeight } = await getScrollInfo("#messageScrollList", "messageList");
+    const { scrollHeight } = await getScrollInfo(
+      "#messageScrollList",
+      "messageList"
+    );
     if (scrollHeight) {
       scrollTop.value === scrollHeight
         ? (scrollTop.value = scrollHeight + 1)
@@ -478,7 +536,11 @@ async function onMessageSourceUpdated(message: IMessageModel) {
 }
 
 function scrollAndBlinkMessage(message: IMessageModel) {
-  if (messageList.value?.some((messageListItem) => messageListItem?.ID === message?.ID)) {
+  if (
+    messageList.value?.some(
+      (messageListItem) => messageListItem?.ID === message?.ID
+    )
+  ) {
     nextTick(async () => {
       await scrollToTargetMessage(message);
       await blinkMessage(message?.ID);
@@ -574,16 +636,24 @@ const handleImagePreview = (index: number) => {
     return;
   }
   const imageMessageIndex: number[] = [];
-  const imageMessageList: IMessageModel[] = messageList.value.filter((item, index) => {
-    if (!item.isRevoked && !item.hasRiskContent && item.type === TYPES.value.MSG_IMAGE) {
-      imageMessageIndex.push(index);
-      return true;
+  const imageMessageList: IMessageModel[] = messageList.value.filter(
+    (item, index) => {
+      if (
+        !item.isRevoked &&
+        !item.hasRiskContent &&
+        item.type === TYPES.value.MSG_IMAGE
+      ) {
+        imageMessageIndex.push(index);
+        return true;
+      }
+      return false;
     }
-    return false;
-  });
+  );
   uni.previewImage({
     current: imageMessageIndex.indexOf(index),
-    urls: imageMessageList.map((message) => message.payload.imageInfoArray?.[2].url),
+    urls: imageMessageList.map(
+      (message) => message.payload.imageInfoArray?.[2].url
+    ),
     // #ifdef APP-PLUS
     indicator: "number",
     // #endif
@@ -602,7 +672,10 @@ function blinkMessage(messageID: string): Promise<void> {
     if (index < 0) {
       blinkMessageIDList.value.push(messageID);
       const timer = setTimeout(() => {
-        blinkMessageIDList.value.splice(blinkMessageIDList.value.indexOf(messageID), 1);
+        blinkMessageIDList.value.splice(
+          blinkMessageIDList.value.indexOf(messageID),
+          1
+        );
         clearTimeout(timer);
         resolve();
       }, 3000);
@@ -670,7 +743,8 @@ function setReadReceiptPanelVisible(visible: boolean, message?: IMessageModel) {
 async function scrollToTargetMessage(message: IMessageModel) {
   const targetMessageID = message.ID;
   const isTargetMessageInScreen =
-    messageList.value && messageList.value.some((msg) => msg.ID === targetMessageID);
+    messageList.value &&
+    messageList.value.some((msg) => msg.ID === targetMessageID);
   if (targetMessageID && isTargetMessageInScreen) {
     const timer = setTimeout(async () => {
       try {
@@ -682,9 +756,15 @@ async function scrollToTargetMessage(message: IMessageModel) {
           "#tui-" + targetMessageID,
           "messageList"
         );
-        const { scrollTop } = await getScrollInfo("#messageScrollList", "messageList");
+        const { scrollTop } = await getScrollInfo(
+          "#messageScrollList",
+          "messageList"
+        );
         const finalScrollTop =
-          originalMessageRect.top + scrollTop - scrollViewRect.top - (selfAddValue++ % 2);
+          originalMessageRect.top +
+          scrollTop -
+          scrollViewRect.top -
+          (selfAddValue++ % 2);
         scrollTo(finalScrollTop);
         clearTimeout(timer);
       } catch (error) {
@@ -725,12 +805,14 @@ function changeSelectMessageIDList({
   // TODO need to delete this
   if (type === "clearAll") {
     multipleSelectedMessageIDList.value = [];
-  } else if (type === "add" && !multipleSelectedMessageIDList.value.includes(messageID)) {
+  } else if (
+    type === "add" &&
+    !multipleSelectedMessageIDList.value.includes(messageID)
+  ) {
     multipleSelectedMessageIDList.value.push(messageID);
   } else if (type === "remove") {
-    multipleSelectedMessageIDList.value = multipleSelectedMessageIDList.value.filter(
-      (id) => id !== messageID
-    );
+    multipleSelectedMessageIDList.value =
+      multipleSelectedMessageIDList.value.filter((id) => id !== messageID);
   }
 }
 
@@ -764,3 +846,91 @@ defineExpose({
 });
 </script>
 <style lang="scss" scoped src="./style/index.scss"></style>
+<style lang="scss" scoped>
+.mask {
+  width: 100vw;
+  height: 100vh;
+  position: absolute;
+  background: #00000080;
+  left: 0px;
+  top: 0px;
+  right: 0px;
+  z-index: 9999;
+  display: flex;
+  flex-direction: row;
+  justify-content: center;
+  align-items: center;
+}
+.back {
+  position: relative;
+  bottom: 100px;
+  height: 400px;
+  width: 300px;
+  // background: linear-gradient(225deg, #f74d30 0%, #ff7633 100%);
+  background: url("@/static/img/lqhbBack.png") no-repeat;
+  background-size: 100% 100%;
+  padding: 150px 20px 0px 20px !important;
+  display: block !important;
+  box-shadow: 0rpx 4rpx 12rpx 0rpx rgba(226, 226, 226, 0.23);
+  border-radius: 0px 20px 20px 20px;
+  .header {
+    font-weight: bold;
+    font-size: 36rpx;
+    color: #000000;
+    text-align: left;
+    font-style: normal;
+    text-align: center;
+  }
+  .main {
+    text-align: center;
+    height: 100px;
+    display: flex;
+    align-items: center;
+    flex-direction: row;
+    justify-content: center;
+
+    .price {
+      font-weight: 800;
+      font-size: 88rpx;
+      color: #ff2f2f;
+      text-align: left;
+      font-style: normal;
+    }
+    .unit {
+      font-weight: 800;
+      font-size: 19px;
+      color: #ff2f2f;
+      text-align: left;
+      font-style: normal;
+      position: relative;
+      bottom: -7px;
+    }
+  }
+  .footer {
+    text-align: center;
+
+    .text {
+      font-weight: 500;
+      font-size: 28rpx;
+      color: #ff2f2f;
+      text-align: center;
+      font-style: normal;
+    }
+    .btn {
+      margin-top: 20px;
+      width: 506rpx;
+      height: 100rpx;
+      background: linear-gradient(90deg, #ff3737 0%, #ff7b1d 100%);
+      border-radius: 56rpx;
+      display: flex;
+      flex-direction: row;
+      justify-content: center;
+      align-items: center;
+      font-weight: 500;
+      font-size: 40rpx;
+      color: #ffffff;
+      font-style: normal;
+    }
+  }
+}
+</style>

+ 28 - 5
TUIKit/components/TUIChat/message-list/message-elements/message-bubble.vue

@@ -195,7 +195,7 @@ function messageClass(message) {
     message._message &&
     message._message.payload &&
     message._message.payload.data
-      ? JSON.parse(message._message.payload.data).redEnvelopeExpireTime
+      ? JSON.parse(message._message.payload.data).expireTime
       : "";
 
   let expireTime = moment(msgtime).format("YYYY-MM-DD");
@@ -207,17 +207,20 @@ function messageClass(message) {
     expired = false;
   }
 
+  console.log('11111111',message.flow);
+  
+
   // 判断消息流向是 "out"
   if (message.flow === "out") {
     // 判断 businessId 是否为红包消息相关
     if (businessId === "red_envelope_message") {
       if (expired) {
-        return "contentCustom-in-lq";
+        return "contentCustom-out-lq";
       } else {
-        return "contentCustom-in";
+        return "contentCustom-out";
       }
     } else if (businessId === "red_envelope_message_gq") {
-      return "contentCustom-in-lq";
+      return "contentCustom-out-lq";
     } else {
       return "content-out";
     }
@@ -340,6 +343,16 @@ function openReadUserPanel() {
 </script>
 
 <style lang="scss" scoped>
+.contentCustom-out{
+  height: 100px;
+  // background: linear-gradient(225deg, #f74d30 0%, #ff7633 100%);
+  background: url("../../../../../static/img/fshb.png") no-repeat;
+  background-size: 100% 100%;
+  padding: 16px 20px !important;
+  display: block !important;
+  box-shadow: 0rpx 4rpx 12rpx 0rpx rgba(226, 226, 226, 0.23);
+  border-radius: 20px 0px 20px 20px;
+}
 .contentCustom-in {
   height: 100px;
   // background: linear-gradient(225deg, #f74d30 0%, #ff7633 100%);
@@ -350,7 +363,6 @@ function openReadUserPanel() {
   box-shadow: 0rpx 4rpx 12rpx 0rpx rgba(226, 226, 226, 0.23);
   border-radius: 0px 20px 20px 20px;
 }
-
 .contentCustom-in-lq {
   opacity: 0.5;
   height: 100px;
@@ -362,6 +374,17 @@ function openReadUserPanel() {
   box-shadow: 0rpx 4rpx 12rpx 0rpx rgba(226, 226, 226, 0.23);
   border-radius: 0px 20px 20px 20px;
 }
+.contentCustom-out-lq {
+  opacity: 0.5;
+  height: 100px;
+  // background: linear-gradient(225deg, #f74d30 0%, #ff7633 100%);
+  background: url("../../../../../static/img/fshb.png") no-repeat;
+  background-size: 100% 100%;
+  padding: 16px 20px !important;
+  display: block !important;
+  box-shadow: 0rpx 4rpx 12rpx 0rpx rgba(226, 226, 226, 0.23);
+  border-radius: 20px 0px 20px 20px;
+}
 :not(not) {
   display: flex;
   flex-direction: column;

+ 19 - 30
TUIKit/components/TUIChat/message-list/message-elements/message-custom.vue

@@ -3,16 +3,10 @@
     <template v-if="isCustom.businessID === 'red_envelope_message'">
       <div class="evaluate" @click="lqhb(isCustom)">
         <div class="evaluatered">
-          {{ titleImpl(isCustom.redEnvelopeExpireTime) }}
+          {{ titleImpl(isCustom.expireTime) }}
         </div>
         <div class="time">
-          {{ timeImpl(isCustom.redEnvelopeExpireTime) }}
-          <!-- {{
-            isCustom.redEnvelopeExpireTime
-              ? $moment(isCustom.redEnvelopeExpireTime).format("YYYY-MM-DD") +
-                "过期"
-              : ""
-          }} -->
+          {{ timeImpl(isCustom.expireTime) }}
         </div>
       </div>
     </template>
@@ -61,28 +55,22 @@ import {
 import { isUrl, JSONToObject } from "../../../../utils/index";
 import { CHAT_MSG_CUSTOM_TYPE } from "../../../../constant";
 import { ICustomMessagePayload } from "../../../../interface";
-import Icon from "../../../common/Icon.vue";
 import * as mesApi from "@/api/message/index";
 import moment from "moment";
-import TUIChatConfig from "../../config";
-const featureConfig = TUIChatConfig.getFeatureConfig();
 interface Props {
   messageItem: IMessageModel;
   content: any;
 }
-
 const props = withDefaults(defineProps<Props>(), {
   messageItem: undefined,
   content: undefined,
 });
-
 const custom = ref();
 const message = ref<IMessageModel>();
 const extension = ref();
 const isCustom = ref<ICustomMessagePayload>({
   businessID: "",
 });
-
 watchEffect(() => {
   custom.value = props.content;
   message.value = props.messageItem;
@@ -94,9 +82,7 @@ watchEffect(() => {
     extension.value = JSONToObject(payload.extension);
   }
 });
-const openLink = (url: any) => {
-  window.open(url);
-};
+
 function titleImpl(time) {
   if (time) {
     let expireTime = moment(time).format("YYYY-MM-DD");
@@ -126,19 +112,20 @@ function timeImpl(time) {
     return "";
   }
 }
+
+const emits = defineEmits(["draw"]);
+
 const lqhb = async (record) => {
-  console.log("lqhb 函数开始执行");
-  console.log("record.recordId:", record.recordId);
   // 检查过期时间
-  const expireTime = record.redEnvelopeExpireTime
-    ? moment(record.redEnvelopeExpireTime).format("YYYY-MM-DD")
+  const expireTime = record.expireTime
+    ? moment(record.expireTime).format("YYYY-MM-DD")
     : null;
   const now = moment();
   const isOk = expireTime && !now.isAfter(expireTime);
   if (isOk) {
     try {
       console.log("开始请求接口");
-      let res = await mesApi.default.receiveLq(record.recordId);
+      let res = await mesApi.default.receiveLq(record.receiveId);
       console.log("接口响应:", res);
       if (res.code == 200) {
         if (res.data) {
@@ -149,16 +136,18 @@ const lqhb = async (record) => {
           if (!message.value) return;
           const messageModel = TUIStore.getMessageModel(message.value.ID);
           messageModel.modifyMessage(props.messageItem.payload.data);
-          Toast({
-            message: TUITranslateService.t("红包领取成功,请在钱包余额查看!"),
-            type: TOAST_TYPE.SUCCESS,
-          });
+          emits("handleDraw", { info: record, isOk: true });
+          // Toast({
+          //   message: TUITranslateService.t("红包领取成功,请在钱包余额查看!"),
+          //   type: TOAST_TYPE.SUCCESS,
+          // });
         }
       } else {
-        Toast({
-          message: TUITranslateService.t("红包领取失败,请联系客服反馈!"),
-          type: TOAST_TYPE.ERROR,
-        });
+        emits("handleDraw", { info: record, isOk: false ,message:res.msg});
+        // Toast({
+        //   message: TUITranslateService.t("红包领取失败,请联系客服反馈!"),
+        //   type: TOAST_TYPE.ERROR,
+        // });
       }
     } catch (error) {
       console.error("接口请求出错:", error);

BIN
static/img/fshb.png


BIN
static/img/lqhbBack.png