yuanchao 3 月之前
父节点
当前提交
4b3639432a
共有 34 个文件被更改,包括 548 次插入196 次删除
  1. 4 2
      .env.development
  2. 2 0
      index.html
  3. 1 1
      package.json
  4. 34 23
      src/common/chat/components/Conversation/convert.js
  5. 9 0
      src/common/chat/components/Conversation/index.vue
  6. 4 0
      src/common/chat/index.scss
  7. 72 23
      src/common/chat/index.vue
  8. 4 0
      src/common/register/index.scss
  9. 6 1
      src/components/prod-item/index.vue
  10. 211 0
      src/components/write-logistics-info/components/select-logistics/index.vue
  11. 2 31
      src/components/write-logistics-info/index.scss
  12. 11 33
      src/components/write-logistics-info/index.vue
  13. 10 2
      src/lang/en.js
  14. 10 2
      src/lang/zh.js
  15. 1 1
      src/layout/mian-content.vue
  16. 16 0
      src/stores/web-config.js
  17. 1 0
      src/utils/http.js
  18. 1 1
      src/utils/index.js
  19. 40 3
      src/views/detail/index.vue
  20. 15 2
      src/views/index/index.vue
  21. 14 2
      src/views/invoice-detail/index.vue
  22. 6 12
      src/views/list/index.vue
  23. 5 0
      src/views/member-center/buy-member/index.vue
  24. 1 1
      src/views/member-center/integral-mall/index.vue
  25. 7 36
      src/views/order-detail/index.vue
  26. 8 3
      src/views/payment/index.vue
  27. 1 1
      src/views/return-detail/components/refund-progress/index.vue
  28. 2 2
      src/views/return-detail/index.vue
  29. 4 1
      src/views/select-decorate/index.vue
  30. 3 2
      src/views/shop-prod-list/index.vue
  31. 4 1
      src/views/user-center/return-proof/index.vue
  32. 3 0
      src/views/user-center/uc-coupons/index.scss
  33. 32 8
      src/views/user-center/uc-coupons/index.vue
  34. 4 2
      src/views/user-center/uc-order/index.vue

+ 4 - 2
.env.development

@@ -5,7 +5,8 @@
 VITE_APP_ENV = 'development'
 
 # 统一接口域名
-VITE_APP_BASE_API = 'https://b2b2c-api.mall4j.com'
+#VITE_APP_BASE_API = 'https://b2b2c-api.mall4j.com'
+VITE_APP_BASE_API = 'http://180.76.117.109:8112'
 
 # 客服websocket接口请求地址,https对应wss,http对应ws
 VITE_APP_WS_IM_API = 'wss://b2b2c-im.mall4j.com'
@@ -17,4 +18,5 @@ VITE_APP_H5_DOMAIN = 'https://h5.mall4j.com'
 VITE_APP_MERCHANT_PLATFORM_URL = 'https://b2b2c-multishop.mall4j.com'
 
 # 图片域名
-VITE_APP_RESOURCES_URL = 'https://img.mall4j.com/'
+#VITE_APP_RESOURCES_URL = 'https://img.mall4j.com/'
+VITE_APP_RESOURCES_URL = 'http://180.76.117.109:9000/mall4j/'

+ 2 - 0
index.html

@@ -1,9 +1,11 @@
 <!DOCTYPE html>
 <html translate="no">
   <head>
+    <title></title>
     <meta charset="UTF-8" />
     <meta name="viewport" content="width=device-width, initial-scale=1.0" />
     <meta name="renderer" content="webkit">
+    <meta name="keywords" content="">
     <meta name="description" content="mall4pc-bbc,电商,购物,商城">
     <meta name="google" content="notranslate">
   </head>

+ 1 - 1
package.json

@@ -33,7 +33,7 @@
     "vue-cookies": "1.8.3",
     "vue-i18n": "9.7.0",
     "vue-router": "4.2.5",
-    "wukongimjssdk": "1.2.10"
+    "wukongimjssdk": "1.3.1"
   },
   "devDependencies": {
     "@element-plus/icons-vue": "2.1.0",

+ 34 - 23
src/common/chat/components/Conversation/convert.js

@@ -1,4 +1,4 @@
-import { Conversation, Setting, WKSDK, Message, StreamItem, Channel, ChannelTypePerson, ChannelTypeGroup, MessageStatus, SyncOptions, MessageExtra, MessageContent } from 'wukongimjssdk'
+import { Conversation, MessageContentType, Setting, WKSDK, Message, Stream, Channel, ChannelTypePerson, ChannelTypeGroup, MessageStatus, SyncOptions, MessageExtra, MessageContent } from 'wukongimjssdk'
 
 import BigNumber from 'bignumber.js'
 import { Buffer } from 'buffer'
@@ -33,17 +33,30 @@ export class Convert {
     message.fromUID = msgMap.fromUid
     message.timestamp = msgMap.timestamp
     message.status = MessageStatus.Normal
-    const decodedBuffer = Buffer.from(msgMap.payload, 'base64')
-    const contentObj = JSON.parse(decodedBuffer.toString('utf8'))
+
     let contentType = 0
-    if (contentObj) {
-      contentType = contentObj.type
-    }
-    const messageContent = WKSDK.shared().getMessageContent(contentType)
-    if (contentObj) {
-      messageContent.decode(this.stringToUint8Array(JSON.stringify(contentObj)))
+    try {
+      let contentObj = null
+      const payload = msgMap.payload
+      if (payload && payload !== '') {
+        const decodedBuffer = Buffer.from(payload, 'base64')
+        contentObj = JSON.parse(decodedBuffer.toString('utf8'))
+        if (contentObj) {
+          contentType = contentObj.type
+        }
+      }
+
+      const messageContent = WKSDK.shared().getMessageContent(contentType)
+      if (contentObj) {
+        messageContent.decode(this.stringToUint8Array(JSON.stringify(contentObj)))
+      }
+      message.content = messageContent
+    } catch (e) {
+      console.log(e)
+      // 如果报错,直接设置为unknown
+      const messageContent = WKSDK.shared().getMessageContent(MessageContentType.unknown)
+      message.content = messageContent
     }
-    message.content = messageContent
 
     message.isDeleted = msgMap.is_deleted === 1
 
@@ -51,20 +64,18 @@ export class Convert {
     if (streamMaps && streamMaps.length > 0) {
       const streams = []
       for (const streamMap of streamMaps) {
-        const streamItem = new StreamItem()
-        streamItem.clientMsgNo = streamMap.clientMsgNo
-        streamItem.streamSeq = streamMap.stream_seq
-        if (streamMap.blob && streamMap.blob.length > 0) {
-          const blob = Buffer.from(streamMap.blob, 'base64')
-          const blobObj = JSON.parse(blob.toString('utf8'))
-          const blobType = blobObj.type
-          const blobContent = WKSDK.shared().getMessageContent(contentType)
-          if (blobObj) {
-            blobContent.decode(this.stringToUint8Array(JSON.stringify(blobObj)))
+        const streamItem = new Stream()
+        streamItem.streamNo = streamMap.clientMsgNo
+        streamItem.streamId = streamMap.stream_idstr
+        if (streamMap.payload && streamMap.payload.length > 0) {
+          const payload = Buffer.from(streamMap.payload, 'base64')
+          const payloadObj = JSON.parse(payload.toString('utf8'))
+          const payloadType = payloadObj.type
+          const payloadContent = WKSDK.shared().getMessageContent(payloadType)
+          if (payloadObj) {
+            payloadContent.decode(this.stringToUint8Array(JSON.stringify(payloadObj)))
           }
-          streamItem.clientMsgNo = streamMap.clientMsgNo
-          streamItem.streamSeq = streamMap.stream_seq
-          streamItem.content = blobContent
+          streamItem.content = payloadContent
         }
         streams.push(streamItem)
       }

+ 9 - 0
src/common/chat/components/Conversation/index.vue

@@ -162,6 +162,15 @@ const conversationListener = async (conversation, action) => {
   }
   if (action === ConversationAction.add) {
     conversationWraps.value = [new ConversationWrap(conversation), ...(conversationWraps.value || [])]
+    const arr = conversation.channel.channelID.split('_')
+    const shopId = arr[arr.length - 1]
+    http.post('/p/wuKongIm/getShopChannelInfo?shopId=' + shopId).then(({ data }) => {
+      if (data) {
+        conversationWraps.value[0].conversation.pic = data.pic
+        conversationWraps.value[0].conversation.shopName = data.shopName
+        conversationWraps.value[0].conversation.shopId = data.imChannel.shopId
+      }
+    })
   } else if (action === ConversationAction.update) {
     const index = conversationWraps.value?.findIndex(item => item.channel.channelID === conversation.channel.channelID && item.channel.channelType === conversation.channel.channelType)
     if (isJSON(conversation.lastMessage?.content.text)) {

+ 4 - 0
src/common/chat/index.scss

@@ -1203,6 +1203,10 @@
     display: flex;
     align-items: center;
     white-space: nowrap;
+    .fail {
+      color: #e43130;
+      white-space: nowrap;
+    }
   }
 }
 .bubble.right {

+ 72 - 23
src/common/chat/index.vue

@@ -72,17 +72,24 @@
                     >
                       <div style="display: flex; justify-content: flex-end;max-width: 70%;">
                         <div class="bubble right">
-                          <div class="read-status">
-                            <div
-                              v-if="maxReadSeq>=m.messageSeq"
+                          <div
+                            v-show="!sendStatusObj[m.clientSeq]"
+                            class="read-status"
+                          >
+                            <!-- 已读/未读/发送失败文本 -->
+                            <span
+                              v-if="sendFailSeqs.includes(m.clientSeq)"
+                              class="fail"
                             >
-                              {{ $t('chat.read') }}
-                            </div>
-                            <div
+                              {{ $t('chat.sendFail') }}
+                            </span>
+                            <span
                               v-else
+                              class="unread"
                             >
-                              {{ $t('chat.unRead') }}
-                            </div>
+                              {{ maxReadSeq >= m.messageSeq ? $t('chat.read') : $t('chat.unRead') }}
+                            </span>
+                            <!-- end已读/未读/发送失败文本 -->
                           </div>
                           <div
                             v-if="m.content.text?.msgType===1"
@@ -618,7 +625,7 @@ const fileRef = ref(null)
 let selectFileObj = null // 上传图片对象
 // 发送图片
 const toolEvent = async () => {
-  WKSDK.shared().chatManager.removeMessageStatusListener(messageStatusListener)
+  sendAutoReplyInfo = null
   if (fileRef.value.files[0]) {
     selectFileObj = await compressImage(fileRef.value.files[0])
   }
@@ -661,6 +668,9 @@ const toolEvent = async () => {
  * 链接点击去往商品详情
  */
 const toProdDetail = (prodInfo, type, orderType) => {
+  sendAutoReplyInfo = null
+  WKSDK.shared().chatManager.removeMessageListener(messageListener)
+  WKSDK.shared().disconnect()
   // type 1 点击订单跳转 type
   let routeUrl = null
   if (Cookie.get('bbcToken')) {
@@ -756,6 +766,7 @@ let messageListener
 let sendStatus = false
 const channelInfolineStatus = ref(false)
 const loginOtherSide = ref(false)
+let connectSuccess = false
 const getWukong = () => {
   http.post('/p/wuKongIm/registerOrLogin').then(({ data }) => {
     // 认证信息
@@ -770,6 +781,7 @@ const getWukong = () => {
 
     // 监听连接状态
     connectStatusListener = (status) => {
+      connectSuccess = status === ConnectStatus.Connected
       if (status === ConnectStatus.Connected) {
         title.value = $t('chat.ConnectionSuccessful')
         loginOtherSide.value = false
@@ -780,8 +792,39 @@ const getWukong = () => {
       }
     }
     WKSDK.shared().connectManager.addConnectStatusListener(connectStatusListener)
+    // 监听消息发送状态
+    listenMsgSendStatus()
   })
 }
+
+const sendFailSeqs = ref([])
+const sendStatusObj = ref({}) // clientSeq为key,value为加载状态
+const listenMsgSendStatus = () => {
+  sendFailSeqs.value = [] // 清空发送失败的seqs
+  sendStatusObj.value = {} // 清空发送状态对象
+  sendAutoReplyInfo = null // 清空自动回复信息
+  WKSDK.shared().chatManager.removeMessageStatusListener(messageStatusListener)
+  messageStatusListener = (ack) => {
+    if (ack.reasonCode === 1) {
+      // 发送自动回复
+      if (sendAutoReplyInfo) {
+        http.request({
+          url: '/p/wuKongIm/sendAutoReplyContent',
+          method: 'POST',
+          data: sendAutoReplyInfo
+        })
+        sendAutoReplyInfo = null
+      }
+    } else {
+      // eslint-disable-next-line no-console
+      console.log('消息发送失败=>>', ack)
+      sendFailSeqs.value.push(ack.clientSeq)
+    }
+    sendStatusObj.value[ack.clientSeq] = false
+  }
+  WKSDK.shared().chatManager.addMessageStatusListener(messageStatusListener)
+}
+
 const isJSON = (str) => {
   if (typeof str == 'string') {
     try {
@@ -819,7 +862,7 @@ const textMsg = ref(null) // 用户输入内容
 // eslint-disable-next-line no-unused-vars
 const sendText = async (type, prod, orderInfo) => {
   if (!to.value.channelID) return
-  WKSDK.shared().chatManager.removeMessageStatusListener(messageStatusListener)
+  sendAutoReplyInfo = null
   // type 1 = 发送消息  type 2 = 发送商品链接  type 3 = 右侧我的订单发送  type 4 = 发送订单号
   if (type === 1) {
     if (!textMsg.value || (textMsg.value && textMsg.value.match(/^\s+$/))) {
@@ -928,6 +971,8 @@ const onSelectChannel = (channel, shopName, id, maxSeq, status) => {
   } else {
     titleName.value = shopName
   }
+  sendFailSeqs.value = []
+  sendStatusObj.value = {} // 清空发送状态对象
   messages.value = []
   pullLast() // 拉取最新消息
 
@@ -1083,6 +1128,13 @@ const pullLast = async () => {
     } else {
       msg.timeStr = util.tsToDate(new Date().getTime(), 'M月D日 h:m')
     }
+    if (msg.clientSeq) {
+      if (!connectSuccess) {
+        sendFailSeqs.value.push(msg.clientSeq)
+      } else if (sendStatusObj.value[msg.clientSeq] !== false) {
+        sendStatusObj.value[msg.clientSeq] = true
+      }
+    }
     messages.value.push(msg)
     scrollBottom()
   }
@@ -1113,12 +1165,14 @@ WKSDK.shared().config.provider.syncMessagesCallback = async (channel, opts) => {
   if (messageList) {
     messageList.forEach((msg) => {
       const message = Convert.toMessage(msg)
-      message.content.text = JSON.parse(message.content.text)
-      message.timeStr = util.tsToDate(
-        message.timestamp * 1000,
-        'M月D日 h:m'
-      )
-      resultMessages.push(message)
+      if (isJSON(message.content.text)) {
+        message.content.text = JSON.parse(message.content.text)
+        message.timeStr = util.tsToDate(
+          message.timestamp * 1000,
+          'M月D日 h:m'
+        )
+        resultMessages.push(message)
+      }
     })
     resultMessages.length > 0 && resultMessages.reduce((prev, cur) => {
       // 将时间更换为某某月某某日 要是是当天即去掉月日
@@ -1279,18 +1333,13 @@ const handleScroll = (e) => {
   }
 }
 let messageStatusListener
+let sendAutoReplyInfo = null
 const sendIssues = async (content, issues, channelId) => {
-  WKSDK.shared().chatManager.removeMessageStatusListener(messageStatusListener)
   const setting = Setting.fromUint8(0)
   const msgObj = JSON.stringify({ msg: issues, msgType: 1 })
   const sendContent = new MessageText(msgObj)
+  sendAutoReplyInfo = { channelId, content: JSON.stringify({ msg: content, msgType: -1 }) }
   WKSDK.shared().chatManager.send(sendContent, to.value, setting)
-  messageStatusListener = (ack) => {
-    if (ack.reasonCode === 1) {
-      http.post('/p/wuKongIm/sendAutoReplyContent', { channelId, content: JSON.stringify({ msg: content, msgType: -1 }) })
-    }
-  }
-  WKSDK.shared().chatManager.addMessageStatusListener(messageStatusListener)
 }
 // 判断是否当天的信息
 const isTimestampToday = (timestamp) => {

+ 4 - 0
src/common/register/index.scss

@@ -1,5 +1,9 @@
 /* 注册 */
 .page-register {
+  .el-checkbox{
+    --el-checkbox-checked-bg-color: #146ef7;
+    --el-checkbox-checked-input-border-color: #146ef7;
+  }
   .r-header {
     background: #fff;
     box-shadow: 0 3px 5px rgba(0, 0, 0, 0.05);

+ 6 - 1
src/components/prod-item/index.vue

@@ -94,7 +94,7 @@
             </span>
           </div>
           <div
-            v-if="[1, 2].includes(item.prodType) && item.activityOriginalPrice > item.activityPrice"
+            v-if="showOriginalPrice && [1, 2].includes(item.prodType) && item.activityOriginalPrice > item.activityPrice"
             class="old-price"
           >
             ¥{{ toPrice(item.activityOriginalPrice) }}
@@ -135,6 +135,11 @@ const props = defineProps({
   pageType: {
     type: Number,
     default: 0
+  },
+  // 是否展示原价
+  showOriginalPrice: {
+    type: Boolean,
+    default: true
   }
 })
 const emit = defineEmits(['tapProd', 'updatePicIndext', 'handClick'])

+ 211 - 0
src/components/write-logistics-info/components/select-logistics/index.vue

@@ -0,0 +1,211 @@
+<template>
+  <div class="select-box">
+    <el-select
+      v-model="selDvy"
+      v-loadmore="loadmore"
+      :style="selStyle"
+      :teleported="false"
+      value-key="dvyId"
+      :filterable="filterable"
+      :remote="filterable"
+      :remote-method="remoteMethod"
+      :placeholder="placeTips"
+      :disabled="disabled"
+      remote-show-suffix
+      @change="onChange"
+      @focus="onFocus"
+      @blur="onBlur"
+    >
+      <el-option
+        v-for="item in devList"
+        :key="item.dvyId"
+        :label="item.dvyName"
+        :value="item"
+      />
+    </el-select>
+  </div>
+</template>
+
+<script setup>
+const emit = defineEmits(['update:modelValue', 'change'])
+
+const vLoadmore = {
+  mounted (el, binding) {
+    // 获取element-ui定义好的scroll盒子
+    const SELECTWRAP_DOM = el.querySelector('.el-select-dropdown .el-select-dropdown__wrap')
+    SELECTWRAP_DOM?.addEventListener('scroll', debounce(() => {
+      if (!isFocus) {
+        return
+      }
+      const condition = SELECTWRAP_DOM.scrollHeight - SELECTWRAP_DOM.scrollTop - 30 <= SELECTWRAP_DOM.clientHeight
+      if (condition) {
+        binding.value()
+      }
+    }))
+  }
+}
+
+const props = defineProps({
+  modelValue: {
+    type: [String, Number],
+    default: ''
+  },
+  selStyle: {
+    type: Object,
+    default: () => {}
+  },
+  placeTips: {
+    type: String,
+    default: $t('applyReturn.select')
+  },
+  disabled: {
+    type: Boolean,
+    default: false
+  },
+  filterable: {
+    type: Boolean,
+    default: false
+  }
+})
+
+// 防抖函数
+function debounce (fn, delay = 50) {
+  let timer = null
+  return function () {
+    if (timer) {
+      clearTimeout(timer)
+    }
+    timer = setTimeout(fn, delay)
+  }
+}
+
+const selDvy = ref({}) // 当前选择的值
+const size = 20
+let current = 1
+const dvyName = ref('')
+let pages = 0
+const devList = ref([])
+let isSearch = false
+watch(() => props.modelValue, (val) => {
+  Object.assign(selDvy.value, { dvyId: val })
+  selDvy.value = {
+    ...selDvy.value,
+    dvyId: val
+  }
+}, {
+  immediate: true
+})
+
+onMounted(() => {
+  getDeliveryList()
+})
+
+let isFocus = false
+const onBlur = () => {
+  if (devList.value.length) {
+    devList.value = []
+  }
+  isFocus = false
+}
+
+const onChange = (val) => {
+  isFocus = false
+  emit('update:modelValue', val.dvyId)
+  emit('change', val)
+}
+const onFocus = () => {
+  isFocus = true
+  if (devList.value.length === 0) {
+    remoteMethod()
+  }
+}
+
+const remoteMethod = (name) => {
+  if (!isFocus || name === dvyName.value) return
+  isSearch = true
+  current = 1
+  dvyName.value = name || ''
+  getDeliveryList()
+}
+// 获取物流列表
+const getDeliveryList = () => {
+  http({
+    url: '/p/delivery/page',
+    method: 'get',
+    params: {
+      size,
+      current,
+      dvyName: dvyName.value
+    }
+  }).then(({ data }) => {
+    current = data.current
+    pages = data.pages
+    if (data.current === 1) {
+      devList.value = data.records
+      if (selDvy.value.dvyId && !isSearch) {
+        checkCurSel(devList.value, selDvy.value.dvyId)
+      }
+    } else {
+      const fList = data.records.filter(r => r.dvyId !== selDvy.value.dvyId)
+      devList.value.push(...fList)
+    }
+  })
+}
+// 获取当前id的物流
+const getDeliveryById = (dvyId) => {
+  http({
+    url: '/p/delivery/page',
+    method: 'get',
+    params: {
+      dvyId
+    }
+  }).then(({ data }) => {
+    devList.value.unshift(...data.records)
+  })
+}
+// 分页加载
+const loadmore = () => {
+  if (current < pages) {
+    current++
+    getDeliveryList()
+  }
+}
+// 筛查出当前所选的对象
+const checkCurSel = (curList, curId) => {
+  for (const item of curList) {
+    if (item.dvyId === curId) {
+      return
+    }
+  }
+  getDeliveryById(curId)
+}
+
+</script>
+<style scoped lang="scss">
+.select-box{
+  :deep(.el-select) {
+    width: 322px;
+    height: 40px;
+    .el-input__wrapper {
+      box-shadow: 0 0 0 1px #EEE !important;
+      width: 322px;
+      height: 40px;
+      border-radius: 0;
+      border: 0;
+      &:hover {
+        box-shadow: 0 0 0 1px #EEE !important;
+      }
+    }
+    .el-input__wrapper.is-focus {
+      box-shadow: 0 0 0 1px #EEE !important;
+    }
+    .el-scrollbar {
+      overscroll-behavior: contain;
+      .el-select-dropdown__item.selected{
+        color: #e1251b;
+      }
+    }
+  }
+}
+
+</style>

+ 2 - 31
src/components/write-logistics-info/index.scss

@@ -6,23 +6,6 @@
     max-width: 100%;
   }
   .logistics-msg {
-    &:deep(.area) {
-      width: 322px;
-      height: 40px;
-      .el-input__wrapper {
-        box-shadow: 0 0 0 1px #EEE !important;
-        width: 322px;
-        height: 40px;
-        border-radius: 0;
-        border: 0;
-        &:hover {
-          box-shadow: 0 0 0 1px #EEE !important;
-        }
-      }
-      .el-input__wrapper.is-focus {
-        box-shadow: 0 0 0 1px #EEE !important;
-      }
-    }
 
     &:deep(.el-upload--picture-card) {
       width: 70px;
@@ -87,11 +70,7 @@
       }
     }
   }
-  .area {
-    .el-scrollbar {
-      width: 97px;
-    }
-  }
+
   .error-item {
     height: 50px;
   }
@@ -119,15 +98,7 @@
   .el-select-dropdown {
     z-index: 20005 !important;
   }
-  .el-select {
-    .area {
-      .el-select {
-        .el-input {
-          overflow: hidden;
-        }
-      }
-    }
-  }
+
   .fix-transform-blur {
     z-index: 1998;
     position: fixed;

+ 11 - 33
src/components/write-logistics-info/index.vue

@@ -39,23 +39,11 @@
               <div class="label">
                 {{ $t('applyReturn.logisticsCompany') }}:
               </div>
-              <div class="select-box">
-                <!-- 物流公司 -->
-                <el-select
-                  v-model="dvyName"
-                  :placeholder="$t('applyReturn.select')"
-                  class="area"
-                  @change="selectCompany"
-                >
-                  <el-option
-                    v-for="company in deliveryList"
-                    :key="company.dvyId"
-                    style="width: 322px"
-                    :label="company.dvyName"
-                    :value="company"
-                  />
-                </el-select>
-              </div>
+              <!-- 物流公司 -->
+              <selectLogistics
+                :model-value="dvyId"
+                @change="selectCompany"
+              />
               <div class="error-text-wrap">
                 <div
                   v-if="isLogisticCompanyTip"
@@ -159,6 +147,7 @@
 
 <script setup>
 import { ElMessage } from 'element-plus'
+import selectLogistics from './components/select-logistics/index.vue'
 
 const props = defineProps({
   refundSn: {
@@ -186,17 +175,16 @@ const emit = defineEmits(['toggleAddrPop'])
 const router = useRouter()
 
 const dvyName = ref('') // 快递公司名字
-let dvyId = 0 // 物流公司id
+const dvyId = ref(0) // 物流公司id
 const LogisticsNumber = ref('') // 物流单号
 const remarks = ref('') // 备注
 const imgs = ref('')
 const fileList = ref([]) // 已上传的凭证图片列表(用于回显)
 onMounted(() => {
-  loadDeliveryData()
   // 根据物流单号判断回填信息
   if (props.refundDelivery.deyNu) {
     dvyName.value = props.refundDelivery.deyName
-    dvyId = props.refundDelivery.deyId
+    dvyId.value = props.refundDelivery.deyId
     LogisticsNumber.value = props.refundDelivery.deyNu
     remarks.value = props.refundDelivery.senderRemarks
     imgs.value = props.refundDelivery.imgs
@@ -219,22 +207,12 @@ const imgPreview = (url) => {
   dialogVisible.value = true
 }
 
-const deliveryList = ref([]) // 物流公司
-/**
- * 加载物流公司
- */
-const loadDeliveryData = () => {
-  http.get('/p/delivery/list').then(({ data }) => {
-    deliveryList.value = data
-  })
-}
-
 /**
  * 选择物流公司
  */
 const selectCompany = (val) => {
   dvyName.value = val.dvyName
-  dvyId = val.dvyId
+  dvyId.value = val.dvyId
 }
 
 const isLogisticCompanyTip = ref(false)
@@ -263,12 +241,12 @@ const writeLogisticsMsg = () => {
   }
 
   // 校验 物流公司名称不能为空
-  if (!dvyName.value || !dvyId) {
+  if (!dvyName.value || !dvyId.value) {
     isLogisticCompanyTip.value = true
     return
   }
   const orderRefundExpressParam = {
-    expressId: dvyId,
+    expressId: dvyId.value,
     expressName: dvyName.value,
     expressNo: LogisticsNumber.value,
     imgs: imgs.value,

+ 10 - 2
src/lang/en.js

@@ -356,7 +356,8 @@ const en = {
     eventLimit: 'Event limit',
     piece: 'piece',
     play: 'play',
-    scanCode: 'Non-express delivery of goods need to scan the code of the cell phone to place an order'
+    scanCode: 'Non-express delivery of goods need to scan the code of the cell phone to place an order',
+    stationProdTip: 'Please check the store products on the mobile app.'
   },
   package: {
     selectPackage: 'Choose a package',
@@ -420,7 +421,11 @@ const en = {
     someItemsAvailableInSelectedStores: 'Some products available',
     deletedCouponsWillNotBeRestored: 'Deleted coupons will not be restored, please consider carefully',
     universal: 'Universal(Excluding special products)',
-    specifiedProductsAvailable: 'Specified products available'
+    specifiedProductsAvailable: 'Specified products available',
+    notYetStarted: 'not yet started',
+    started: 'started',
+    startUsing: 'start using'
+
   },
   shopIndex: {
     selfOperatedStores: 'Self-operated stores',
@@ -750,6 +755,7 @@ const en = {
     logisticsCompany: 'Logistics company',
     shipmentNumber: 'Shipment number',
     refundReason20: 'Merchant has agreed, waiting for refund',
+    sellerAgree: 'The merchant has agreed, please return the goods according to the given address',
     refundAddress: 'Refund address',
     buyerRequestRefund: 'Buyer request for refund',
     refundDescription: 'Refund description',
@@ -1055,6 +1061,7 @@ const en = {
     weChatSweepPayment: 'WeChat sweep payment',
     completedPayment: 'Completed payment',
     CessationRecruitment: 'This membership level is closed for recruitment',
+    cannotBuyLower: 'Users cannot purchase lower level members during the membership period',
     cancel: 'Cancel',
     purchaseSuccess: 'Purchase Success',
     purchaseFailure: 'Purchase Failure',
@@ -1251,6 +1258,7 @@ const en = {
     noMore: 'No more',
     read: 'Read',
     unRead: 'Un read',
+    sendFail: 'Fail',
     noRecord: 'No record',
     chatRecordTips1: 'The above is',
     chatRecordTips2: 'customer service chat record',

+ 10 - 2
src/lang/zh.js

@@ -355,7 +355,8 @@ const zh = {
     eventLimit: '活动限购',
     piece: '件',
     play: '播放',
-    scanCode: '非快递配送商品需手机扫码下单'
+    scanCode: '非快递配送商品需手机扫码下单',
+    stationProdTip: '门店商品请到移动端查看'
   },
   package: {
     selectPackage: '选择套餐',
@@ -459,7 +460,11 @@ const zh = {
     someItemsAvailableInSelectedStores: '部分商品可用',
     deletedCouponsWillNotBeRestored: '已删除的优惠券将不可恢复,请您谨慎考虑',
     universal: '全场通用(特殊商品除外)',
-    specifiedProductsAvailable: '指定商品可用'
+    specifiedProductsAvailable: '指定商品可用',
+    notYetStarted: '未开始',
+    started: '已开始',
+    startUsing: '开始使用'
+
   },
   userCenter: {
     deleteTheSelected: '确认要删除选中的商品记录吗?',
@@ -740,6 +745,7 @@ const zh = {
     logisticsCompany: '物流公司',
     shipmentNumber: '物流单号',
     refundReason20: '卖家已同意,等待退款',
+    sellerAgree: '商家已同意,请按照给出地址寄回商品',
     refundAddress: '退款地址',
     buyerRequestRefund: '买家申请退款',
     refundDescription: '退款描述',
@@ -1045,6 +1051,7 @@ const zh = {
     weChatSweepPayment: '微信扫一扫支付',
     completedPayment: '已完成支付',
     CessationRecruitment: '该会员等级已停止招募',
+    cannotBuyLower: '付费会员期间无法购买低等级会员',
     cancel: '取 消',
     purchaseSuccess: '购买成功',
     purchaseFailure: '购买失败',
@@ -1242,6 +1249,7 @@ const zh = {
     onLine: '(在线)',
     offLine: '(离线)',
     unRead: '未读',
+    sendFail: '发送失败',
     noRecord: '暂无记录',
     chatRecordTips1: '以上是',
     chatRecordTips2: '客服聊天记录',

+ 1 - 1
src/layout/mian-content.vue

@@ -1,6 +1,6 @@
 <template>
   <div class="layout-main-content">
-    <router-view :key="$route.fullPath" />
+    <router-view />
   </div>
 </template>
 

+ 16 - 0
src/stores/web-config.js

@@ -3,6 +3,7 @@ import logo from '@/assets/images/website-config/logo.png'
 import loginBG from '@/assets/images/website-config/login-bg.jpg'
 import code from '@/assets/images/website-config/code.jpg'
 import logoText from '@/assets/images/website-config/logo-text.png'
+import Cookie from 'vue-cookies'
 
 const defaultConfig = {
   // 登录logo
@@ -75,6 +76,7 @@ export const useWebConfigStore = defineStore('webConfig', {
     // 更新配置
     setWebConfig (data) {
       this.pcConfig = this.formatConfigInfo(data)
+      this.updateMetaTags(data)
     },
     // 格式化配置信息
     formatConfigInfo (config) {
@@ -99,6 +101,20 @@ export const useWebConfigStore = defineStore('webConfig', {
       data.pcLogoImgText = config.pcLogoImgText || defaultConfig.pcLogoImgText
       data.pcWelcome = config.pcWelcome || defaultConfig.pcWelcome
       return Object.assign(config, data)
+    },
+    updateMetaTags  (data) {
+      const lang = +Cookie.get('bbcLangKey')
+      if (!data.webConfigLangList) return
+      // data.configLangList
+      const langConfig = data.webConfigLangList.find(item => item.lang === lang) || data.webConfigLangList[0]
+      if (langConfig?.pcKeyWords) {
+        const metaKeywords = document.querySelector("meta[name='keywords']")
+        metaKeywords.setAttribute('content', langConfig.pcKeyWords)
+      }
+      if (langConfig?.pcDescriptive) {
+        const metaDescription = document.querySelector("meta[name='description']")
+        metaDescription.setAttribute('content', langConfig.pcDescriptive)
+      }
     }
   }
 })

+ 1 - 0
src/utils/http.js

@@ -18,6 +18,7 @@ http.interceptors.request.use(
   config => {
     // 语言类型
     config.headers.locale = cookie.get('bbcLanguage') || 'zh_CN'
+    config.headers.timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone || 'Asia/Shanghai'
     if (config.url === '/p/user/recentBrowse') {
       config.headers['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8'
     } else {

+ 1 - 1
src/utils/index.js

@@ -31,7 +31,7 @@ export const formatHtml = (content) => {
   content = content.replace(/class=/gi, 'sss=')
   content = content.replace(/<img/gi, '<img style="max-width:100% !important;margin:0;display:inline-block !important; vertical-align:middle;" ')
   content = content.replace(/style="/gi, 'style="max-width:100% !important;table-layout:fixed;word-wrap:break-word;word-break:break-word;')
-  content = content.replace(/<table/gi, '<table style="table-layout:fixed;word-wrap:break-word;word-break:break-word;" ')
+  content = content.replace(/<table/gi, '<table style="width:100%;table-layout:fixed;word-wrap:break-word;word-break:break-word;" ')
   content = content.replace(/<td/gi, '<td cellspacing="0" cellpadding="0" style="border-width:1px; border-style:solid; border-color:#666; margin: 0px; padding: 0px;"')
   content = content.replace(/<video/gi, '<video style="width:100% !important;height:auto !important;margin:0;display:flex;" ')
   return content

+ 40 - 3
src/views/detail/index.vue

@@ -854,7 +854,7 @@
                     type="number"
                     class="number"
                     oninput="value=value.replace(/[^\d]/g,'')"
-                    @blur="resetProdNum"
+                    @blur="judgeInput"
                   >
                   <span
                     :class="['increase', prohibit2 ? 'limit' : '']"
@@ -1812,8 +1812,6 @@ onMounted(async () => {
   }
   // 积分推荐商品列表
   recommendGoods()
-  // 设置网页标题
-  document.title = $t('prodDetail.productDetails')
 })
 const recommendGoods = () => {
   http.get('/search/page', {
@@ -1892,6 +1890,39 @@ const formatDate = (val) => {
     return util.tsToDate(val.replace(/-/g, '/'), 'Y-M-D')
   }
 }
+const updateMetaTags = (prodInfo) => {
+  const prodName = prodInfo?.prodName
+  const keyWords = prodInfo?.keyWords
+  const brief = prodInfo?.brief
+  // 设置页面标题
+  if (prodName) {
+    document.title = prodName
+  } else {
+    document.title = $t('product.productDetails')
+  }
+
+  // 更新 keywords meta 标签
+  if (keyWords) {
+    let metaKeywords = document.querySelector("meta[name='keywords']")
+    if (!metaKeywords) {
+      metaKeywords = document.createElement('meta')
+      metaKeywords.setAttribute('name', 'keywords')
+      document.head.appendChild(metaKeywords)
+    }
+    metaKeywords.setAttribute('content', keyWords)
+  }
+
+  // 更新 description meta 标签
+  if (brief) {
+    let metaDescription = document.querySelector("meta[name='description']")
+    if (!metaDescription) {
+      metaDescription = document.createElement('meta')
+      metaDescription.setAttribute('name', 'description')
+      document.head.appendChild(metaDescription)
+    }
+    metaDescription.setAttribute('content', brief)
+  }
+}
 
 const productActivity = computed(() => {
   return prodInfo.value.productActivity || {}
@@ -1937,6 +1968,7 @@ const getProdInfo = (addrId) => {
         }
         data.deliveryModeVO = data.deliveryModeVO || JSON.parse(data.deliveryMode)
         prodInfo.value = data
+        updateMetaTags(data)
         totalStocks.value = data.totalStocks
         isDelivery.value = data.isDelivery
         prodInfo.value.preSellTime = formatDate(prodInfo.value.preSellTime)
@@ -2819,7 +2851,11 @@ const toChooseItem = (skuLineItem, key) => {
     skuList = countdownFlag.value && prodInfo.value.productActivity.seckill ? prodInfo.value.productActivity.seckill.seckillSkuList : prodInfo.value.skuList
   }
   parseSelectedObjToVals(skuList)
+  resetProdNum()
+}
 
+// 重置商品数量
+const resetProdNum = () => {
   const objKey = countdownFlag.value && prodInfo.value.productActivity.seckill ? 'seckillStocks' : 'stocks'
   if (defaultSku.value[objKey]) {
     // 有库存
@@ -3236,6 +3272,7 @@ const onSelectDelivery = async (id) => {
     groupBuyInfo(addrId)
   }
   isShowDeliveryPop.value = false
+  resetProdNum()
 }
 
 const onClosePop = () => {

+ 15 - 2
src/views/index/index.vue

@@ -239,6 +239,7 @@
           <prod-item
             :pale-list="checkHotSalesProd && hotSalesList.records[0].products"
             :list-type="0"
+            :show-original-price="false"
             @update-pic-indext="updatePicIndextH"
           />
         </div>
@@ -404,10 +405,22 @@ const handlePageConfig = async (homeData) => {
   // 设置网页标题文本和图标
   if ((decorateHeader.value.length > 0 || decoratePageIndex.value.length > 0) && route.path === '/') {
     document.title = decorateTitle
-  } else {
-    document.title = webConfigData.value.pcTitleContent || ''
   }
 }
+// 监听 webConfigData.value.pcTitleContent 的变化
+watch(() => webConfigData.value.pcTitleContent, (newVal) => {
+  if (!newVal) return
+  // 只有在没有装修数据时才设置默认标题
+  if (
+    route.path === '/' &&
+      !decorateHeader.value.length &&
+      !decoratePageIndex.value.length
+  ) {
+    document.title = webConfigData.value.pcTitleContent
+  }
+},
+{ immediate: true, deep: true }
+)
 // 获取秒杀商品
 const getSnapUpList = () => {
   http.get('/search/page', {

+ 14 - 2
src/views/invoice-detail/index.vue

@@ -156,7 +156,7 @@
                   v-if="filePath"
                   target="_blank"
                   rel="noopener noreferrer"
-                  :href="checkFileUrl(filePath)"
+                  @click="downloadFile(checkFileUrl(filePath))"
                 >
                   <div
                     class="item-con download"
@@ -435,10 +435,12 @@ const getInvoiceDetail = () => {
     getInvoiceFile()
   })
 }
+let fileName = ''
 const getInvoiceFile = () => {
   if (invoiceInfo.value.fileId) {
     http.get('/p/file/get_file_by_id?fileId=' + invoiceInfo.value.fileId).then(({ data }) => {
       filePath.value = data.filePath
+      fileName = data.fileName
     })
   }
 }
@@ -519,7 +521,17 @@ const parsePrice = (value) => {
   // 截取小数点后两位,并以小数点为切割点将val转化为数组
   return val.toFixed(2).split('.')
 }
-
+const downloadFile = async (filePath) => {
+  const response = await fetch(filePath)
+  const blob = await response.blob()
+  const url = window.URL.createObjectURL(new Blob([blob]))
+  const link = document.createElement('a')
+  link.href = url
+  link.setAttribute('download', fileName + '.pdf') // 设置下载文件名
+  document.body.appendChild(link)
+  link.click()
+  link.remove()
+}
 </script>
 
 <style lang="scss" scoped>

+ 6 - 12
src/views/list/index.vue

@@ -191,7 +191,7 @@
       <div
         class="goods-list"
       >
-        <div style="paddingTop:20px">
+        <div style="padding-top:20px">
           <div
             v-if="st == 4 && couponInfo.couponType === 1"
             class="coupon-condition"
@@ -306,7 +306,7 @@ const getDataList = (queryPar = {}) => {
     param = Object.assign({
       keyword: query.pn || '',
       categoryId: Number(query.thCid) || '',
-      sort: 21, // 这里的sort并不是排序 是 状态
+      sort: 27, // 这里的sort并不是排序 是 状态
       orderBy: Number(query.ob) || 0, // 这里的orderby 才是状态
       current: Number(query.c) || 1, // 这里是页码
       isAllProdType: true,
@@ -397,12 +397,14 @@ watch(() => categoryId.value, () => {
 })
 
 watch(() => route.query, () => {
-  if (Number(route.query.st) === 1) {
+  st.value = Number(route.query.st)
+  if (st.value === 1) {
     document.title = $t('commonHead.newProducts')
   }
-  if (Number(route.query.st) === 0) {
+  if (st.value === 0) {
     document.title = $t('commonHead.productList')
   }
+  getDataList(route.query)
 }, { deep: true })
 
 /**
@@ -554,17 +556,9 @@ const updatePicIndext = (index, newValue) => {
 const couponInfo = ref({})
 // 获取一张优惠券信息
 const getCouponInfo = () => {
-  // const params = {
-  //   url: '/coupon/couponById?couponId=' + tagid,
-  //   method: 'GET'
-  // }
-  // http.request(params).then(({ data: res }) => {
-  //   couponInfo.value = res
-  // })
   http.get('/coupon/couponById?couponId=' + couponId)
     .then(({ data }) => {
       couponInfo.value = data
-      console.log('🚀 ~ .then ~ couponInfo.value:', couponInfo.value)
     })
 }
 const goListIndex = () => {

+ 5 - 0
src/views/member-center/buy-member/index.vue

@@ -325,6 +325,11 @@ const buyNow = (item, index) => {
   if (item.recruitStatus === 0) {
     return ElMessage.error($t('memberCenter.CessationRecruitment'))
   }
+  // 已有付费会员时购买低级付费会员
+  const { levelType, level } = memberInfo.value.userLevel
+  if (levelType === 1 && level > item.level) {
+    return ElMessage.error($t('memberCenter.cannotBuyLower'))
+  }
   if (memberInfo.value.growth >= item.needGrowth) {
     if (!checkPayWay(paySwitchInfo.value)) return
     isShowPop.value = true

+ 1 - 1
src/views/member-center/integral-mall/index.vue

@@ -169,7 +169,7 @@ const getScroeList = () => {
       current: current.value,
       size: 20,
       prodType: 3,
-      sort: 2,
+      sort: 16,
       stationId: 0 // 过滤掉门店发布的商品
     }
   }).then(({ data }) => {

+ 7 - 36
src/views/order-detail/index.vue

@@ -50,7 +50,7 @@
             v-if="orderInfo.status === 1 && betweenTime.signs === 1"
             class="description"
           >
-            {{ $t('orderDetails.remainingTime') }} {{ betweenTime.min + ':' + betweenTime.sec }}
+            {{ $t('orderDetails.remainingTime') }} {{ betweenTime.hou + ':' + betweenTime.min + ':' + betweenTime.sec }}
           </div>
           <div
             v-if="orderInfo.cancelTime === null"
@@ -638,7 +638,7 @@
                       <a
                         href="javascript:void(0);"
                         class="img"
-                        @click="toDetail(prod)"
+                        @click="toProdDetail(prod)"
                       >
                         <ImgShow :src="prod.pic" />
                       </a>
@@ -646,7 +646,7 @@
                         <a
                           href="javascript:void(0);"
                           class="name"
-                          @click="toDetail(prod)"
+                          @click="toProdDetail(prod)"
                         >{{ prod.prodName }}</a>
                         <span class="sku">{{ prod.skuName }}</span>
                         <span
@@ -758,7 +758,7 @@
                         v-if="(orderInfo.status > 4 || orderInfo.cancelTime !==null) && orderInfo.status !== 7 && !orderInfo.stationId"
                         href="javascript:void(0)"
                         :class="['action-btn']"
-                        @click="toProdDetail(prod.prodId,prod.useScore)"
+                        @click="toProdDetail(prod)"
                       >{{ $t('orderDetails.repurchase') }}</a>
                     </div>
                   </td>
@@ -1124,11 +1124,7 @@ const countdown = () => {
 /**
  * 跳转详情页
  */
-const toDetail = (prod) => {
-  if (orderInfo.value.orderType === 2 && !orderInfo.value.seckillId) {
-    ElMessage.warning($t('spike.currentSecondsAreOver'))
-    return
-  }
+const toProdDetail = (prod) => {
   let newPage
   if (orderInfo.value.orderType === 3) {
     newPage = router.resolve({ path: '/detail', query: { prodId: prod.prodId, scoreFee: prod.useScore } })
@@ -1143,6 +1139,8 @@ const toDetail = (prod) => {
     // 门店商品不可跳转
     if (!data.stationId) {
       window.open(newPage.href, '_blank', 'noopener,noreferrer')
+    } else {
+      ElMessage.warning($t('prodDetail.stationProdTip'))
     }
   })
 }
@@ -1334,33 +1332,6 @@ const toShopPage = (shopId) => {
 const userCenter = () => {
   router.push({ path: '/user-center' })
 }
-/**
-* 跳转到商品详情页
-*/
-const toProdDetails = (prodId) => {
-  const newPage = router.resolve({ path: '/detail', query: { prodId } })
-  http.get('/prod/prodInfo', {
-    params: {
-      prodId
-    }
-  }).then(() => {
-    window.open(newPage.href, '_blank', 'noopener,noreferrer')
-  })
-}
-const toProdDetail = (prodId, scoreFee) => {
-  if (orderInfo.value.orderType === 3) {
-    http.get('/prod/prodInfo', {
-      params: {
-        prodId
-      }
-    }).then(() => {
-      const newPage = router.resolve({ path: '/detail', query: { prodId, scoreFee } })
-      window.open(newPage.href, '_blank', 'noopener,noreferrer')
-    })
-  } else {
-    toProdDetails(prodId)
-  }
-}
 
 /**
  * 是否最后一个商品在执行单个商品退款事件

+ 8 - 3
src/views/payment/index.vue

@@ -66,14 +66,14 @@
                 class="time"
               >
                 请在
-                <span class="warning">{{ min }} : {{ sec }}</span>内付款,否则交易会被取消。
+                <span class="warning">{{ hour }} : {{ min }} : {{ sec }}</span>内付款,否则交易会被取消。
               </div>
               <div
                 v-if="isOverTime && $t('language') !== 'zh_CN'"
                 class="time"
               >
                 please pay within
-                <span class="warning">{{ min }} : {{ sec }}</span>,otherwise the transaction will be cancelled。
+                <span class="warning">{{ hour }} : {{ min }} : {{ sec }}</span>,otherwise the transaction will be cancelled。
               </div>
               <div
                 v-if="!isOverTime"
@@ -299,6 +299,7 @@ const getBalanceInfo = () => {
 }
 
 // 倒计时
+const hour = ref('00') // 时
 const min = ref('00') // 分
 const sec = ref('00') // 秒
 const isCanPay = ref(true) // 是否能支付
@@ -317,6 +318,9 @@ const countTime = () => {
 
   // 定义变量 d,h,m,s保存倒计时的时间
   if (leftTime >= 0) {
+    // 小时
+    const h = Math.floor(leftTime / 1000 / 60 / 60 % 24)
+    hour.value = h < 10 ? '0' + h : h
     // 分
     const m = Math.floor(leftTime / 1000 / 60 % 60)
     min.value = m < 10 ? '0' + m : m
@@ -324,13 +328,14 @@ const countTime = () => {
     const s = Math.floor(leftTime / 1000 % 60)
     sec.value = s < 10 ? '0' + s : s
   } else {
+    hour.value = '00'
     min.value = '00'
     sec.value = '00'
     isOverTime.value = false
     isCanPay.value = false
   }
   // 等于0的时候不调用
-  if (Number(min.value) === 0 && Number(sec.value) === 0) {
+  if (Number(hour.value) === 0 && Number(min.value) === 0 && Number(sec.value) === 0) {
     return
   }
   // 递归每秒调用countTime方法,显示动态时间效果,

+ 1 - 1
src/views/return-detail/components/refund-progress/index.vue

@@ -272,7 +272,7 @@
           {{ refundDetail.shopName }}
         </div>
         <div class="text">
-          <p>{{ $t('applyReturn.refundReason20') }}</p>
+          <p>{{ $t('applyReturn.sellerAgree') }}</p>
           <p>{{ $t('applyReturn.refundAddress') }}:{{ refundDetail.refundDelivery.receiverName }}&nbsp;&nbsp;{{ refundDetail.refundDelivery.receiverMobile }}&nbsp;&nbsp;{{ refundDetail.refundDelivery.receiverAddr }}</p>
         </div>
       </div>

+ 2 - 2
src/views/return-detail/index.vue

@@ -321,7 +321,7 @@
               >
                 <!-- (买家申请 || 卖家接受 || 商家拒绝) || isCancel可撤销 -->
                 <a
-                  v-if="(refundDetail.returnMoneySts === 1 || refundDetail.returnMoneySts === 2 || refundDetail.returnMoneySts === 7) && refundDetail.isCancel"
+                  v-if="((refundDetail.returnMoneySts === 1 || refundDetail.returnMoneySts === 2 || refundDetail.returnMoneySts === 7) && refundDetail.isCancel) || (refundDetail.returnMoneySts === 2 && refundDetail.applyType === 2)"
                   href="JavaScript:void(0)"
                   class="action-a"
                   @click="cancelApply"
@@ -638,7 +638,7 @@ const onCancelPlayApply = () => {
 const onApplyPlayIntervene = (proofType) => {
   router.push({
     path: '/user-center/return-proof',
-    query: { proofType, refundId: refundDetail.value.refundId, refundSn: refundDetail.value.refundSn }
+    query: { proofType, refundId: refundDetail.value.refundId, refundSn: refundDetail.value.refundSn, orderNumber: refundDetail.value.orderNumber }
   })
 }
 

+ 4 - 1
src/views/select-decorate/index.vue

@@ -39,6 +39,7 @@
 <script setup>
 import commonHeaders from '@/components/decorate-component/common-header/index.vue' // 平台头部
 import qs from 'qs'
+import Cookie from 'vue-cookies'
 
 const decorateHeader = ref([]) // 商家头部
 const setTopHeader = computed(() => { // 判断当前显示商家导航还是平台导航
@@ -375,7 +376,9 @@ const selectAllInterface = () => {
   // 如果是商家装修页,此时需要获取分类
   if (setTopHeader.value === 'shops') {
     getCategoryMessage()
-    getUserCollection()
+    if (Cookie.get('bbcToken')) {
+      getUserCollection()
+    }
     getShopInfo()
   }
 }

+ 3 - 2
src/views/shop-prod-list/index.vue

@@ -265,9 +265,10 @@ watch(() => route.query, (newVal, oldVal) => {
   // 路由变话页面刷新
   if (newVal.sid === oldVal.sid) {
     langStore.handleShopRouter(newVal)
-    return
   }
-  location.reload()
+  if (route.path === '/shop-prod-list') {
+    getPageData(newVal)
+  }
 })
 
 const backPath = computed(() => {

+ 4 - 1
src/views/user-center/return-proof/index.vue

@@ -54,8 +54,10 @@ const photoFiles = ref('')
 const proofType = ref(1)
 let refundId = ''
 let refundSn = ''
+let orderNumber = ''
 onMounted(() => {
   proofType.value = +route.query.proofType
+  orderNumber = +route.query.orderNumber
   refundId = route.query.refundId
   refundSn = route.query.refundSn
   document.title = proofType.value === 1 ? $t('applyReturn.ApplyForCustomerServiceIntervention') : $t('applyReturn.SupplementaryVouchers')
@@ -93,7 +95,8 @@ const onSubmit = () => {
       refundId,
       sysType: 0,
       voucherDesc: buyerDesc.value,
-      imgUrls: photoFiles.value
+      imgUrls: photoFiles.value,
+      orderNumber
     }
   }).then(() => {
     ElMessage({

+ 3 - 0
src/views/user-center/uc-coupons/index.scss

@@ -104,6 +104,9 @@
           .time {
             margin-right: auto;
           }
+          .content-time {
+            display: flex;
+          }
         }
       }
       .coupon-info {

+ 32 - 8
src/views/user-center/uc-coupons/index.vue

@@ -91,11 +91,27 @@
               <span class="limit">{{ $t('coupons.availableOver').replace('x', item.cashCondition) }}</span>
             </div>
             <div class="coupon-time">
-              <div class="tit">
-                {{ $t('coupons.validUntil') }}:
+              <div
+                v-if="!isCouponAvailable(item)"
+                class="content-time"
+              >
+                <div class="tit">
+                  {{ $t('coupons.notYetStarted') }}:
+                </div>
+                <div class="time">
+                  {{ item.startTime + $t('coupons.startUsing') }}
+                </div>
               </div>
-              <div class="time">
-                {{ item.startTime }} - {{ item.endTime }}
+              <div
+                v-else
+                class="content-time"
+              >
+                <div class="tit">
+                  {{ $t('coupons.started') }}:
+                </div>
+                <div class="time">
+                  {{ $t('memberCenter.validUntil') + item.endTime }}
+                </div>
               </div>
             </div>
           </div>
@@ -284,7 +300,11 @@ onMounted(() => {
   getCouponList(1)
   getCouponCount()
 })
-
+const isCouponAvailable = (coupon) => {
+  const now = new Date().getTime()
+  const start = new Date(coupon.startTime).getTime()
+  return now >= start
+}
 const isEmpty = ref(false)
 const status = ref(1)
 const current = ref(route.query.current || 1) // 当前页数
@@ -304,7 +324,7 @@ const getCouponList = (statusPar) => {
       status: status.value,
       current: current.value,
       size: 12,
-      stationId: 0
+      type: 1
     }
   }).then(({ data }) => {
     dataList.value = data.records
@@ -317,7 +337,7 @@ const getCouponList = (statusPar) => {
           status: status.value,
           current: current.value,
           size: 12,
-          stationId: 0
+          type: 1
         }
       }).then(({ data }) => {
         dataList.value = data.records
@@ -335,7 +355,11 @@ const unUseCount = ref(0)
  * 获取各分类数量
  */
 const getCouponCount = () => {
-  http.get('/p/myCoupon/getMyCouponsStatusCount?stationId=0').then(({ data }) => {
+  http.get('/p/myCoupon/getMyCouponsStatusCount', {
+    params: {
+      type: 1
+    }
+  }).then(({ data }) => {
     expiredCount.value = data.expiredCount
     unUseCount.value = data.unUseCount
     useCount.value = data.useCount

+ 4 - 2
src/views/user-center/uc-order/index.vue

@@ -705,6 +705,8 @@ const toProdDetail = (orderType, prodId, seckillId, scoreFee) => {
     // 门店商品不可跳转
     if (!data.stationId) {
       window.open(newPage.href, '_blank', 'noopener,noreferrer')
+    } else {
+      ElMessage.warning($t('prodDetail.stationProdTip'))
     }
   })
 }
@@ -820,10 +822,10 @@ const getOrderList = () => {
     current: current.value,
     size: size.value,
     status: status.value,
-    orderName: '',
+    orderName: orderName.value || '',
     orderTimeStatus: orderTimeStatus.value || '',
     orderType: orderType.value >= 0 ? orderType.value : '',
-    orderNumber: '',
+    orderNumber: orderNumber.value || '',
     orderMold: orderMold.value,
     showDelivery: true
   }