fix: bug修复

This commit is contained in:
kaizheng(郑凯) 2025-04-07 16:55:52 +08:00
parent 3a945a5259
commit 6bf48e1458
13 changed files with 347 additions and 303 deletions

12
package-lock.json generated
View File

@ -31,6 +31,7 @@
"vue-router": "^4.0.3", "vue-router": "^4.0.3",
"vue-waterfall-plugin-next": "^2.4.3", "vue-waterfall-plugin-next": "^2.4.3",
"vue3-hash-calendar": "^1.1.3", "vue3-hash-calendar": "^1.1.3",
"vue3-marquee": "^4.2.2",
"vuex": "^4.0.0" "vuex": "^4.0.0"
}, },
"devDependencies": { "devDependencies": {
@ -15428,6 +15429,17 @@
"vue": "^3.0.0" "vue": "^3.0.0"
} }
}, },
"node_modules/vue3-marquee": {
"version": "4.2.2",
"resolved": "https://registry.npmmirror.com/vue3-marquee/-/vue3-marquee-4.2.2.tgz",
"integrity": "sha512-FeFvGUVInKfFilXFcnl8sDRBJBZCZSNLlQDquJErB9db6W2xICRVqbRV/jtdzsEP0rftarLQhx9MeEAU0+TPuQ==",
"engines": {
"node": ">=12"
},
"peerDependencies": {
"vue": "^3.2"
}
},
"node_modules/vuex": { "node_modules/vuex": {
"version": "4.1.0", "version": "4.1.0",
"resolved": "https://registry.npmmirror.com/vuex/-/vuex-4.1.0.tgz", "resolved": "https://registry.npmmirror.com/vuex/-/vuex-4.1.0.tgz",

View File

@ -32,6 +32,7 @@
"vue-router": "^4.0.3", "vue-router": "^4.0.3",
"vue-waterfall-plugin-next": "^2.4.3", "vue-waterfall-plugin-next": "^2.4.3",
"vue3-hash-calendar": "^1.1.3", "vue3-hash-calendar": "^1.1.3",
"vue3-marquee": "^4.2.2",
"vuex": "^4.0.0" "vuex": "^4.0.0"
}, },
"devDependencies": { "devDependencies": {

View File

@ -1,28 +1,32 @@
window.config = { window.config = {
loginUrl: "https://web.ceniu.sztg.com/#/login", loginUrl: "https://web.ceniu.sztg.com/#/login",
VConsole: true, VConsole: false,
userIdList: [], userIdList: [],
shareEnv: "production", shareEnv: "production",
getCarProductLink: ({ getCarProductLink: ({
token, token,
refreshToken, refreshToken,
// departmentId = 36, // departmentId = 36,
// eId = 0, staffNo = "",
activityId, activityId,
}) => { }) => {
// let url = "" let url = ""
// if (activityId.includes("?")) { if (staffNo) {
// url = `${activityId}&departmentId=${departmentId}&eId=${eId}` if (activityId.includes("?")) {
// } else { url = `${activityId}&eId=${staffNo}`
// url = `${activityId}?eId=${eId}` } else {
// } url = `${activityId}?eId=${staffNo}`
}
} else {
url = activityId
}
// console.log("url", url) // console.log("url", url)
// debugger // debugger
return `https://web.ceniu.sztg.com/setTokenAndRedirect.html?token=${encodeURIComponent( return `https://web.ceniu.sztg.com/setTokenAndRedirect.html?token=${encodeURIComponent(
token token
)}&refreshToken=${encodeURIComponent( )}&refreshToken=${encodeURIComponent(
refreshToken refreshToken
)}&redirect=${encodeURIComponent(activityId)}` )}&redirect=${encodeURIComponent(url)}`
}, // 购物车产品地址 }, // 购物车产品地址
mobileRegister: mobileRegister:
"https://web.ceniu.sztg.com/#/login?pageType=mobileRegister&redirect=", // 用户注册地址 "https://web.ceniu.sztg.com/#/login?pageType=mobileRegister&redirect=", // 用户注册地址

View File

@ -1,47 +1,49 @@
import "amfe-flexible"; import "amfe-flexible"
import { createApp } from "vue"; import { createApp } from "vue"
import VConsole from "vconsole"; // import VConsole from "vconsole"
import App from "./App.vue"; import App from "./App.vue"
import router from "./router"; import router from "./router"
import store from "./store"; import store from "./store"
import "./assets/css/reset.css"; import "./assets/css/reset.css"
import "vant/es/dialog/style"; import "vant/es/dialog/style"
import "vant/es/toast/style"; import "vant/es/toast/style"
import "vant/es/image-preview/style"; import "vant/es/image-preview/style"
import VueHashCalendar from "vue3-hash-calendar"; import VueHashCalendar from "vue3-hash-calendar"
import "vue3-hash-calendar/es/index.css"; import "vue3-hash-calendar/es/index.css"
import { liveStatusObj } from "@/config/constant"; import { liveStatusObj } from "@/config/constant"
import shieldConfig from "@/config/index"; import shieldConfig from "@/config/index"
import { getProductType, dateFormat, getPrice } from "@/utils/filters"; import { getProductType, dateFormat, getPrice } from "@/utils/filters"
import SvgIcon from "@/components/SvgIcon"; import SvgIcon from "@/components/SvgIcon"
import Vue3Marquee from "vue3-marquee"
// import { terminalType } from "@/utils/index"; // import { terminalType } from "@/utils/index";
// import loadScript from "@/utils/loadScript"; // import loadScript from "@/utils/loadScript";
if (window.config.VConsole) { // if (window.config.VConsole) {
new VConsole(); // new VConsole();
} // }
const app = createApp(App); const app = createApp(App)
// 自定义指令 // 自定义指令
import * as directive from "@/directive"; import * as directive from "@/directive"
Object.keys(directive).forEach((key) => { Object.keys(directive).forEach((key) => {
app.directive(key, directive[key]); app.directive(key, directive[key])
}); })
const init = () => { const init = () => {
app.use(store); app.use(store)
app.use(router); app.use(router)
app.use(VueHashCalendar); app.use(VueHashCalendar)
app.config.globalProperties.$liveStatusObj = liveStatusObj; app.use(Vue3Marquee)
app.config.globalProperties.$shieldConfig = shieldConfig; app.config.globalProperties.$liveStatusObj = liveStatusObj
app.config.globalProperties.$shieldConfig = shieldConfig
app.config.globalProperties.$filters = { app.config.globalProperties.$filters = {
getProductType, getProductType,
dateFormat, dateFormat,
getPrice, getPrice,
}; }
app.component("svg-icon", SvgIcon); app.component("svg-icon", SvgIcon)
app.mount("#app"); app.mount("#app")
}; }
init(); init()

View File

@ -15,8 +15,7 @@
[$liveStatusObj.NotStart, $liveStatusObj.PausePlay].includes( [$liveStatusObj.NotStart, $liveStatusObj.PausePlay].includes(
liveStatus liveStatus
) )
" ">
>
<img class="over-icon" src="@/assets/images/no-play.png" alt="" /> <img class="over-icon" src="@/assets/images/no-play.png" alt="" />
<p v-if="liveStatus === $liveStatusObj.NotStart"> <p v-if="liveStatus === $liveStatusObj.NotStart">
即将开播敬请期待 即将开播敬请期待
@ -30,16 +29,14 @@
v-else-if=" v-else-if="
liveStatus === $liveStatusObj.FinishPlay && liveStatus === $liveStatusObj.FinishPlay &&
(!detail.libraryList || !detail.libraryList.length) (!detail.libraryList || !detail.libraryList.length)
" ">
>
<img class="over-icon" src="@/assets/images/shutdown.png" alt="" /> <img class="over-icon" src="@/assets/images/shutdown.png" alt="" />
直播已结束稍后将提供回放视频 直播已结束稍后将提供回放视频
</div> </div>
</div> </div>
<div <div
class="down-time-wrap" class="down-time-wrap"
v-if="detail.liveStatus === $liveStatusObj.NotStart" v-if="detail.liveStatus === $liveStatusObj.NotStart">
>
<div class="time"> <div class="time">
<img src="../../assets/images/time.png" alt="" /> <img src="../../assets/images/time.png" alt="" />
<span>{{ `距离${detail.playType == 1 ? "直" : "录"}播开始` }}</span> <span>{{ `距离${detail.playType == 1 ? "直" : "录"}播开始` }}</span>
@ -49,8 +46,7 @@
</div> </div>
<button <button
:class="[props.detail.isSubscribe !== 1 ? 'active' : '']" :class="[props.detail.isSubscribe !== 1 ? 'active' : '']"
v-preReClick="setSubLiveVideo" v-preReClick="setSubLiveVideo">
>
{{ props.detail.isSubscribe === 1 ? "已预约" : "立即预约" }} {{ props.detail.isSubscribe === 1 ? "已预约" : "立即预约" }}
</button> </button>
</div> </div>
@ -58,7 +54,15 @@
<img src="../../assets/images/normal_player.png" /> <img src="../../assets/images/normal_player.png" />
</div> </div>
</div> </div>
<Vue3Marquee :duration="10" pauseOnHover>
<p>
北京首证投资顾问有限公司 投资顾问{{ detail.advisorBasic.name
}}<i v-if="detail.advisorBasic.license"
>{{ detail.advisorBasic.license }}</i
>
观点仅供参考不作为投资决依据股市有风險投资需逢慎
</p>
</Vue3Marquee>
<van-tabs v-model:active="active" line-width="0.4rem"> <van-tabs v-model:active="active" line-width="0.4rem">
<van-tab title="互动" :name="0"> <van-tab title="互动" :name="0">
<TgInteract <TgInteract
@ -69,8 +73,7 @@
:isSpeak="isSpeak" :isSpeak="isSpeak"
@sendMsg="sendMsg" @sendMsg="sendMsg"
@closeActivity="closeActivity" @closeActivity="closeActivity"
@closeCarPush="closeCarPush" @closeCarPush="closeCarPush" />
/>
</van-tab> </van-tab>
<van-tab title="甄选服务" :name="1"> <van-tab title="甄选服务" :name="1">
<ShopCar :tgId="detail.advisorBasic?.id" :detail="detail" /> <ShopCar :tgId="detail.advisorBasic?.id" :detail="detail" />
@ -85,13 +88,11 @@
<DiscountCoupon <DiscountCoupon
ref="discountCouponRef" ref="discountCouponRef"
:item="couponDetail" :item="couponDetail"
:liveId="detail.id" :liveId="detail.id" />
/>
<QuestionnaireTip <QuestionnaireTip
ref="questionnaireTipRef" ref="questionnaireTipRef"
:questionTitle="questionTitle" :questionTitle="questionTitle"
:questionId="questionId" :questionId="questionId" />
/>
<Share ref="shareRef" :detail="detail" /> <Share ref="shareRef" :detail="detail" />
<img <img
@ -99,8 +100,7 @@
v-if="detail.openQw === 1 && route.query.saleUserId" v-if="detail.openQw === 1 && route.query.saleUserId"
class="getQRCode" class="getQRCode"
src="@/assets/images/getQRCode.png" src="@/assets/images/getQRCode.png"
alt="" alt="" />
/>
<van-overlay :show="openQwShow"> <van-overlay :show="openQwShow">
<div class="qw-wrap"> <div class="qw-wrap">
<div class="qw-content"> <div class="qw-content">
@ -113,61 +113,61 @@
</template> </template>
<script setup> <script setup>
import { ref, defineProps, watch } from "vue"; import { ref, defineProps, watch } from "vue"
import { useRoute } from "vue-router"; import { useRoute } from "vue-router"
import Nav from "@/components/NavBar.vue"; import Nav from "@/components/NavBar.vue"
import DiscountCoupon from "./components/DiscountCoupon.vue"; import DiscountCoupon from "./components/DiscountCoupon.vue"
import QuestionnaireTip from "./components/QuestionnaireTip.vue"; import QuestionnaireTip from "./components/QuestionnaireTip.vue"
import Share from "@/components/Share"; import Share from "@/components/Share"
import TgInteract from "./hComponents/TgInteract.vue"; import TgInteract from "./hComponents/TgInteract.vue"
import ShopCar from "./hComponents/ShopCar.vue"; import ShopCar from "./hComponents/ShopCar.vue"
import Information from "./hComponents/Information.vue"; import Information from "./hComponents/Information.vue"
import emitter from "@/utils/emitter"; import emitter from "@/utils/emitter"
import useGetLiveStatusObj from "@/hooks/useGetLiveStatusObj"; import useGetLiveStatusObj from "@/hooks/useGetLiveStatusObj"
import useShieldConfig from "@/hooks/useShieldConfig"; import useShieldConfig from "@/hooks/useShieldConfig"
import useWebSocketMsg from "@/hooks/useWebsocketMsg"; import useWebSocketMsg from "@/hooks/useWebsocketMsg"
import { queryWeiXinCode } from "@/api/video"; import { queryWeiXinCode } from "@/api/video"
import { nextTick } from "vue"; import { nextTick } from "vue"
import useCountDown from "@/hooks/useCountDown"; import useCountDown from "@/hooks/useCountDown"
import { subLiveVideo } from "@/api/video"; import { subLiveVideo } from "@/api/video"
const $shieldConfig = useShieldConfig(); const $shieldConfig = useShieldConfig()
const $liveStatusObj = useGetLiveStatusObj(); const $liveStatusObj = useGetLiveStatusObj()
const route = useRoute(); const route = useRoute()
const props = defineProps({ const props = defineProps({
detail: { detail: {
type: Object, type: Object,
default: () => ({}), default: () => ({}),
}, },
}); })
const active = ref(0); const active = ref(0)
const showLiveTip = ref( const showLiveTip = ref(
window.config.userIdList.includes(props.detail.advisorBasic?.userId) window.config.userIdList.includes(props.detail.advisorBasic?.userId)
); )
const tgInteractRef = ref(); const tgInteractRef = ref()
watch( watch(
() => active.value, () => active.value,
(value) => { (value) => {
if (value === 1) { if (value === 1) {
emitter.emit("updateCar"); emitter.emit("updateCar")
} else if (value === 0) { } else if (value === 0) {
nextTick(() => { nextTick(() => {
tgInteractRef.value && tgInteractRef.value.bsRefresh(); tgInteractRef.value && tgInteractRef.value.bsRefresh()
}); })
} }
} }
); )
const shareRef = ref(); const shareRef = ref()
const shareFn = () => { const shareFn = () => {
shareRef.value.showPopup = true; shareRef.value.showPopup = true
sendMsg(5); sendMsg(5)
}; }
const videoStyle = ref({ const videoStyle = ref({
background: `url(${props.detail.imgUrl}) left center no-repeat`, background: `url(${props.detail.imgUrl}) left center no-repeat`,
backgroundSize: "cover", backgroundSize: "cover",
}); })
const { const {
liveStatus, liveStatus,
@ -186,39 +186,39 @@ const {
} = useWebSocketMsg({ } = useWebSocketMsg({
detail: props.detail, detail: props.detail,
videoClass: ".videoRef", videoClass: ".videoRef",
}); })
const openQwShow = ref(false); const openQwShow = ref(false)
const qwImg = ref(); const qwImg = ref()
const getWeiXinCode = async () => { const getWeiXinCode = async () => {
if (!qwImg.value) { if (!qwImg.value) {
let ret = await queryWeiXinCode({ id: route.query.saleUserId }); let ret = await queryWeiXinCode({ id: route.query.saleUserId })
if (ret.code === 0) { if (ret.code === 0) {
qwImg.value = ret.data; qwImg.value = ret.data
} }
} }
openQwShow.value = true; openQwShow.value = true
}; }
// //
const { formTimeArr, startDownTime } = useCountDown(); const { formTimeArr, startDownTime } = useCountDown()
startDownTime(props.detail.startTime); startDownTime(props.detail.startTime)
const setSubLiveVideo = async () => { const setSubLiveVideo = async () => {
if (props.detail.isSubscribe === 1) return; if (props.detail.isSubscribe === 1) return
let ret = await subLiveVideo({ let ret = await subLiveVideo({
id: props.detail.id, id: props.detail.id,
option: props.detail.isSubscribe === 1 ? 2 : 1, option: props.detail.isSubscribe === 1 ? 2 : 1,
saleUserId: route.query.saleUserId, saleUserId: route.query.saleUserId,
}); })
if (ret.code === 0) { if (ret.code === 0) {
emitter.emit("updateVideoDetail", { emitter.emit("updateVideoDetail", {
isSubscribe: props.detail.isSubscribe === 1 ? 2 : 1, isSubscribe: props.detail.isSubscribe === 1 ? 2 : 1,
subscribeUserCount: ret.data.count, subscribeUserCount: ret.data.count,
}); })
} }
}; }
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
.right-icon { .right-icon {
@ -295,7 +295,7 @@ const setSubLiveVideo = async () => {
// height: calc(100% - 514px); // height: calc(100% - 514px);
height: calc(100% - 422px); height: calc(100% - 422px);
::v-deep .van-tabs__content { ::v-deep .van-tabs__content {
height: calc(100% - 90px); height: calc(100% - 130px);
.van-tab__panel { .van-tab__panel {
height: 100%; height: 100%;
} }
@ -432,4 +432,10 @@ const setSubLiveVideo = async () => {
height: calc(100% - 540px); height: calc(100% - 540px);
} }
} }
::v-deep .vue3-marquee {
background-color: rgba(0, 0, 0, 0.8);
color: #fff;
font-size: 24px;
line-height: 40px;
}
</style> </style>

View File

@ -21,8 +21,7 @@
store.state.userInfo.userId === item.replyBasic.userId)) store.state.userInfo.userId === item.replyBasic.userId))
)" )"
:class="[`li${index}`]" :class="[`li${index}`]"
:key="index" :key="index">
>
<div v-if="item.type === 1 && item.replyBasic"> <div v-if="item.type === 1 && item.replyBasic">
<div class="reply-content"> <div class="reply-content">
<div class="reply"> <div class="reply">
@ -59,8 +58,7 @@
:item="item.productBasic" :item="item.productBasic"
:liveProductId="detail.id" :liveProductId="detail.id"
:tgId="detail.advisorBasic?.id" :tgId="detail.advisorBasic?.id"
:isShopCar="true" :isShopCar="true" />
/>
</div> </div>
<div v-else-if="item.type === 3"> <div v-else-if="item.type === 3">
<p> <p>
@ -83,8 +81,7 @@
v-if=" v-if="
item.phone !== store.state.userInfo.userId && item.phone !== store.state.userInfo.userId &&
detail.isSubAdvisor !== 1 detail.isSubAdvisor !== 1
" ">
>
我也关注 我也关注
</button> </button>
</div> </div>
@ -101,15 +98,13 @@
<button <button
class="share" class="share"
@click="sendMsg(5)" @click="sendMsg(5)"
v-if="item.phone !== store.state.userInfo.userId" v-if="item.phone !== store.state.userInfo.userId">
>
我也要分享 我也要分享
</button> </button>
</div> </div>
<div <div
v-else-if="[6, 7, 9, 10].includes(item.type)" v-else-if="[6, 7, 9, 10].includes(item.type)"
style="color: #f46946" style="color: #f46946">
>
<p>{{ item.content }}</p> <p>{{ item.content }}</p>
</div> </div>
<div v-else-if="item.type === 8" style="color: #f46946"> <div v-else-if="item.type === 8" style="color: #f46946">
@ -137,12 +132,11 @@
:item="informMsgList[informMsgList.length - 1].productBasic" :item="informMsgList[informMsgList.length - 1].productBasic"
:liveProductId="detail.id" :liveProductId="detail.id"
:tgId="detail.advisorBasic?.id" :tgId="detail.advisorBasic?.id"
:isShopCar="true" :detail="detail"
> :isShopCar="true">
<img <img
@click.stop="productFloatShow = false" @click.stop="productFloatShow = false"
src="@/assets/images/chat/close.png" src="@/assets/images/chat/close.png" />
/>
</ProductItem> </ProductItem>
</div> </div>
</div> </div>
@ -150,21 +144,21 @@
</template> </template>
<script setup> <script setup>
import { ref, defineEmits, defineProps, onBeforeUnmount, computed } from "vue"; import { ref, defineEmits, defineProps, onBeforeUnmount, computed } from "vue"
import { useStore } from "vuex"; import { useStore } from "vuex"
import { showToast } from "vant"; import { showToast } from "vant"
import { sendFollowMessage, queryQuestionCheck } from "@/api/video"; import { sendFollowMessage, queryQuestionCheck } from "@/api/video"
import QuestionnairePopup from "../components/QuestionnairePopup.vue"; import QuestionnairePopup from "../components/QuestionnairePopup.vue"
import useChatData from "@/hooks/useChatData"; import useChatData from "@/hooks/useChatData"
import useGetLiveStatusObj from "@/hooks/useGetLiveStatusObj"; import useGetLiveStatusObj from "@/hooks/useGetLiveStatusObj"
import ProductItem from "./ProductItem.vue"; import ProductItem from "./ProductItem.vue"
import { attentionTg } from "@/api/index"; import { attentionTg } from "@/api/index"
import emitter from "@/utils/emitter"; import emitter from "@/utils/emitter"
import { nextTick } from "vue"; import { nextTick } from "vue"
import { queryLiveHisMsg } from "@/api/video"; import { queryLiveHisMsg } from "@/api/video"
const store = useStore(); const store = useStore()
const $liveStatusObj = useGetLiveStatusObj(); const $liveStatusObj = useGetLiveStatusObj()
const props = defineProps({ const props = defineProps({
className: { className: {
@ -180,19 +174,19 @@ const props = defineProps({
type: Array, type: Array,
default: () => [], default: () => [],
}, },
}); })
const productFloatShow = ref(false); const productFloatShow = ref(false)
const { hisMsgList, msgListRef, hasNext, bs } = useChatData( const { hisMsgList, msgListRef, hasNext, bs } = useChatData(
Object.assign({}, props.detail, { className: ".interact-scroll" }) Object.assign({}, props.detail, { className: ".interact-scroll" })
); )
const msgList = computed(() => { const msgList = computed(() => {
return hisMsgList.value.concat(props.informMsgList); return hisMsgList.value.concat(props.informMsgList)
}); })
let intervalTime = null; let intervalTime = null
const replenishMsg = async () => { const replenishMsg = async () => {
let ret = await queryLiveHisMsg({ let ret = await queryLiveHisMsg({
@ -200,32 +194,32 @@ const replenishMsg = async () => {
lastId: "", lastId: "",
size: 20, size: 20,
status: 1, status: 1,
}); })
if (ret.code === 0) { if (ret.code === 0) {
// let idsArr = msgList.value.map((item) => item.id); // let idsArr = msgList.value.map((item) => item.id);
let list = ret.data.list.reverse(); let list = ret.data.list.reverse()
emitter.emit("informMsgListPush", list); emitter.emit("informMsgListPush", list)
// list.forEach((item) => { // list.forEach((item) => {
// if (!idsArr.includes(item.id)) { // if (!idsArr.includes(item.id)) {
// emitter.emit("informMsgListPush", item); // emitter.emit("informMsgListPush", item);
// } // }
// }); // });
} }
}; }
let getNewMsg = (once) => { let getNewMsg = (once) => {
if (once) { if (once) {
replenishMsg(); replenishMsg()
} else { } else {
clearInterval(intervalTime); clearInterval(intervalTime)
intervalTime = setInterval(replenishMsg, 1000 * 30); intervalTime = setInterval(replenishMsg, 1000 * 30)
} }
}; }
emitter.on("getNewMsg", getNewMsg); emitter.on("getNewMsg", getNewMsg)
emitter.on("cancelGetNewMsg", () => { emitter.on("cancelGetNewMsg", () => {
clearInterval(intervalTime); clearInterval(intervalTime)
}); })
async function subAdvisor() { async function subAdvisor() {
let ret = await attentionTg({ let ret = await attentionTg({
@ -233,11 +227,11 @@ async function subAdvisor() {
channel: 2, channel: 2,
option: props.detail.isSubAdvisor === 1 ? 2 : 1, option: props.detail.isSubAdvisor === 1 ? 2 : 1,
videoId: props.detail.id, videoId: props.detail.id,
}); })
if (ret.code === 0) { if (ret.code === 0) {
emitter.emit("updateVideoDetail", { emitter.emit("updateVideoDetail", {
isSubAdvisor: props.detail.isSubAdvisor === 1 ? 2 : 1, isSubAdvisor: props.detail.isSubAdvisor === 1 ? 2 : 1,
}); })
props.detail.isSubAdvisor === 1 && props.detail.isSubAdvisor === 1 &&
[ [
$liveStatusObj.InLive, $liveStatusObj.InLive,
@ -247,61 +241,61 @@ async function subAdvisor() {
sendFollowMessage({ sendFollowMessage({
id: props.detail.id, id: props.detail.id,
option: props.detail.isSubAdvisor === 1 ? 2 : 1, option: props.detail.isSubAdvisor === 1 ? 2 : 1,
}); })
} }
} }
const questionnairePopupRef = ref(); const questionnairePopupRef = ref()
const questionId = ref(); const questionId = ref()
const goAnswer = async (item) => { const goAnswer = async (item) => {
// if (props.detail.liveStatus === $liveStatusObj.FinishPlay) { // if (props.detail.liveStatus === $liveStatusObj.FinishPlay) {
// return showToast(""); // return showToast("");
// } // }
let ret = await queryQuestionCheck({ questionId: item.questionId }); let ret = await queryQuestionCheck({ questionId: item.questionId })
if (ret.code === 0) { if (ret.code === 0) {
if (ret.data.result) { if (ret.data.result) {
questionId.value = item.questionId; questionId.value = item.questionId
questionnairePopupRef.value.showPopup = true; questionnairePopupRef.value.showPopup = true
} else if (ret.data.type === 1) { } else if (ret.data.type === 1) {
return showToast("您已完成问卷任务,无须重复填写!"); return showToast("您已完成问卷任务,无须重复填写!")
} else if (ret.data.type === 2) { } else if (ret.data.type === 2) {
return showToast("问卷已删除!"); return showToast("问卷已删除!")
} }
} }
}; }
const emit = defineEmits(["sendMsg"]); const emit = defineEmits(["sendMsg"])
const sendMsg = (type, params) => { const sendMsg = (type, params) => {
emit("sendMsg", type, params); emit("sendMsg", type, params)
}; }
emitter.on("uploadMsg", ({ key, item }) => { emitter.on("uploadMsg", ({ key, item }) => {
for (let i = 0; i < hisMsgList.value.length; i++) { for (let i = 0; i < hisMsgList.value.length; i++) {
if (key === "status" && hisMsgList.value[i].id === Number(item.data)) { if (key === "status" && hisMsgList.value[i].id === Number(item.data)) {
hisMsgList.value.splice(i, 1); hisMsgList.value.splice(i, 1)
} else if ( } else if (
key === "isOpen" && key === "isOpen" &&
hisMsgList.value[i].id === Number(item.messageId) hisMsgList.value[i].id === Number(item.messageId)
) { ) {
hisMsgList.value[i].isOpen = item.isOpen; hisMsgList.value[i].isOpen = item.isOpen
} else if ( } else if (
key === "isOpen" && key === "isOpen" &&
hisMsgList.value[i].replyBasic && hisMsgList.value[i].replyBasic &&
hisMsgList.value[i].replyBasic.id === Number(item.messageId) hisMsgList.value[i].replyBasic.id === Number(item.messageId)
) { ) {
hisMsgList.value[i].replyBasic.isOpen = item.isOpen; hisMsgList.value[i].replyBasic.isOpen = item.isOpen
} }
} }
nextTick(() => { nextTick(() => {
bs && bs.refresh(); bs && bs.refresh()
}); })
}); })
onBeforeUnmount(() => { onBeforeUnmount(() => {
emitter.off("uploadMsg"); emitter.off("uploadMsg")
emitter.off("getNewMsg"); emitter.off("getNewMsg")
emitter.off("cancelGetNewMsg"); emitter.off("cancelGetNewMsg")
}); })
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
.interact-scroll { .interact-scroll {

View File

@ -41,6 +41,11 @@ const props = defineProps({
type: Number, type: Number,
default: 3, default: 3,
}, },
detail: {
//
type: Object,
default: () => {},
},
}) })
const route = useRoute() const route = useRoute()
const store = useStore() const store = useStore()
@ -65,6 +70,8 @@ const toDetail = async () => {
token: store.state.userInfo.token, token: store.state.userInfo.token,
refreshToken: store.state.userInfo.refreshToken, refreshToken: store.state.userInfo.refreshToken,
activityId: props.item.url, activityId: props.item.url,
staffNo:
props.detail.saleUserStaffNo || props.detail.advisorBasic.staffNo,
}) })
} else { } else {
if (props.liveProductId) { if (props.liveProductId) {

View File

@ -4,8 +4,7 @@
round round
closeable closeable
position="bottom" position="bottom"
:style="{ height: '60%' }" :style="{ height: '60%' }">
>
<div class="header"> <div class="header">
<span @click="showOwnDiscount">我的卡券</span> <span @click="showOwnDiscount">我的卡券</span>
<h3>甄选服务</h3> <h3>甄选服务</h3>
@ -40,15 +39,15 @@
productType: item.productType, productType: item.productType,
url: item.url, url: item.url,
}" }"
:isShopCar="true" :detail="detail"
/> :isShopCar="true" />
<ServerItem <ServerItem
v-else v-else
:item="item" :item="item"
:liveProductId="route.query.id" :liveProductId="route.query.id"
:tgId="tgId" :tgId="tgId"
:isShopCar="true" :detail="detail"
/> :isShopCar="true" />
</div> </div>
<Empty text="暂无甄选服务~" v-if="!cartVOList || !cartVOList.length" /> <Empty text="暂无甄选服务~" v-if="!cartVOList || !cartVOList.length" />
@ -66,63 +65,68 @@ import {
onBeforeUnmount, onBeforeUnmount,
onMounted, onMounted,
nextTick, nextTick,
} from "vue"; } from "vue"
import { useRoute } from "vue-router"; import { useRoute } from "vue-router"
import ServerItem from "@/components/ServerItem.vue"; import ServerItem from "@/components/ServerItem.vue"
import Empty from "@/components/Empty.vue"; import Empty from "@/components/Empty.vue"
import { queryCartList } from "@/api/video"; import { queryCartList } from "@/api/video"
import emitter from "@/utils/emitter"; import emitter from "@/utils/emitter"
import ProductItem from "./ProductItem.vue"; import ProductItem from "./ProductItem.vue"
import OwnDiscount from "./OwnDiscount.vue"; import OwnDiscount from "./OwnDiscount.vue"
import useDisableScroll from "@/hooks/useDisableScroll"; import useDisableScroll from "@/hooks/useDisableScroll"
const { addScrollEvent } = useDisableScroll(); const { addScrollEvent } = useDisableScroll()
defineProps({ defineProps({
tgId: { tgId: {
type: String, type: String,
default: "", default: "",
}, },
}); detail: {
//
type: Object,
default: () => {},
},
})
onMounted(() => {}); onMounted(() => {})
onBeforeUnmount(() => { onBeforeUnmount(() => {
emitter.off("updateCar"); emitter.off("updateCar")
}); })
const route = useRoute(); const route = useRoute()
const cartVOList = ref([]); const cartVOList = ref([])
const getCartList = async () => { const getCartList = async () => {
let ret = await queryCartList({ let ret = await queryCartList({
id: route.query.id, id: route.query.id,
}); })
if (ret.code === 0) { if (ret.code === 0) {
cartVOList.value = ret.data; cartVOList.value = ret.data
nextTick(() => { nextTick(() => {
addScrollEvent(".list-wrap"); addScrollEvent(".list-wrap")
}); })
} }
}; }
const showPopup = ref(false); const showPopup = ref(false)
watch(showPopup, (val) => { watch(showPopup, (val) => {
if (val) { if (val) {
getCartList(); getCartList()
} }
}); })
const ownDiscountRef = ref(); const ownDiscountRef = ref()
const showOwnDiscount = () => { const showOwnDiscount = () => {
ownDiscountRef.value.showPopup = true; ownDiscountRef.value.showPopup = true
}; }
defineExpose({ defineExpose({
showPopup, showPopup,
}); })
emitter.on("updateCar", () => { emitter.on("updateCar", () => {
if (showPopup.value) getCartList(); if (showPopup.value) getCartList()
}); })
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
.popup-main { .popup-main {

View File

@ -5,8 +5,7 @@
className="hp" className="hp"
@sendMsg="sendMsg" @sendMsg="sendMsg"
:informMsgList="informMsgList" :informMsgList="informMsgList"
:detail="detail" :detail="detail" />
/>
<div class="recommend-img" v-show="showRecommend" @click="toActivityPage"> <div class="recommend-img" v-show="showRecommend" @click="toActivityPage">
<img :src="activityObj.imgUrl" alt="" srcset="" /> <img :src="activityObj.imgUrl" alt="" srcset="" />
<i @click.stop="closeActivity"></i> <i @click.stop="closeActivity"></i>
@ -29,27 +28,23 @@
:disabled=" :disabled="
isSpeak || [$liveStatusObj.FinishPlay].includes(detail.liveStatus) isSpeak || [$liveStatusObj.FinishPlay].includes(detail.liveStatus)
" "
@keyup.enter="sendMsg(1, { text })" @keyup.enter="sendMsg(1, { text })" />
/>
<button <button
class="send" class="send"
:disabled="!text || sendTextLoading" :disabled="!text || sendTextLoading"
@click="sendMsg(1, { text })" @click="sendMsg(1, { text })">
>
发送 发送
</button> </button>
<button class="share" @click="sendMsg(5)"></button> <button class="share" @click="sendMsg(5)"></button>
<button <button
class="clear" class="clear"
v-if="detail.liveStatus === $liveStatusObj.InLive" v-if="detail.liveStatus === $liveStatusObj.InLive"
@click.stop="clearScreenFn" @click.stop="clearScreenFn"></button>
></button>
<button class="shop" @click.stop="openProductList"></button> <button class="shop" @click.stop="openProductList"></button>
<button <button
v-if="detail.liveStatus !== $liveStatusObj.NotStart" v-if="detail.liveStatus !== $liveStatusObj.NotStart"
:class="['star', detail.isFavor === 1 ? 'active' : '']" :class="['star', detail.isFavor === 1 ? 'active' : '']"
@click.stop="sendMsg(4)" @click.stop="sendMsg(4)">
>
<span v-if="detail.favorUserCount">{{ <span v-if="detail.favorUserCount">{{
bigNumberTransform(detail.favorUserCount) bigNumberTransform(detail.favorUserCount)
}}</span> }}</span>
@ -57,27 +52,30 @@
</div> </div>
</div> </div>
<Share ref="shareRef" :detail="detail" /> <Share ref="shareRef" :detail="detail" />
<ProductList ref="productListRef" :tgId="detail.advisorBasic?.id" /> <ProductList
ref="productListRef"
:tgId="detail.advisorBasic?.id"
:detail="detail" />
</template> </template>
<script setup> <script setup>
import { ref, defineProps, watch, defineEmits } from "vue"; import { ref, defineProps, watch, defineEmits } from "vue"
import { useStore } from "vuex"; import { useStore } from "vuex"
import { showToast } from "vant"; import { showToast } from "vant"
import BScroll from "@better-scroll/core"; import BScroll from "@better-scroll/core"
import PullDown from "@better-scroll/pull-down"; import PullDown from "@better-scroll/pull-down"
import Share from "@/components/Share.vue"; import Share from "@/components/Share.vue"
import ProductList from "./ProductList.vue"; import ProductList from "./ProductList.vue"
import { likeVideo } from "@/api/video"; import { likeVideo } from "@/api/video"
import emitter from "@/utils/emitter"; import emitter from "@/utils/emitter"
import useGetLiveStatusObj from "@/hooks/useGetLiveStatusObj"; import useGetLiveStatusObj from "@/hooks/useGetLiveStatusObj"
import ChatFrame from "./ChatFrame.vue"; import ChatFrame from "./ChatFrame.vue"
import { userLogin } from "@/utils/login"; import { userLogin } from "@/utils/login"
const $liveStatusObj = useGetLiveStatusObj(); const $liveStatusObj = useGetLiveStatusObj()
BScroll.use(PullDown); BScroll.use(PullDown)
const store = useStore(); const store = useStore()
const props = defineProps({ const props = defineProps({
detail: { detail: {
// //
@ -99,141 +97,141 @@ const props = defineProps({
type: Boolean, type: Boolean,
default: false, default: false,
}, },
}); })
const showRecommend = ref(false); // const showRecommend = ref(false) //
watch( watch(
() => props.activityObj, () => props.activityObj,
() => { () => {
if (props.activityObj && Object.keys(props.activityObj).length) { if (props.activityObj && Object.keys(props.activityObj).length) {
showRecommend.value = true; showRecommend.value = true
} }
} }
); )
function toActivityPage() { function toActivityPage() {
location.href = props.activityObj.url; location.href = props.activityObj.url
} }
const text = ref(); const text = ref()
const shareRef = ref(); const shareRef = ref()
const sendTextLoading = ref(false); const sendTextLoading = ref(false)
const emit = defineEmits(["sendMsg", "clearScreenFn", "closeActivity"]); const emit = defineEmits(["sendMsg", "clearScreenFn", "closeActivity"])
const sendMsg = (type, params = {}) => { const sendMsg = (type, params = {}) => {
if (![1, 4].includes(type)) { if (![1, 4].includes(type)) {
// //
emit("sendMsg", type, params); emit("sendMsg", type, params)
} }
switch (type) { switch (type) {
case 1: case 1:
if (text.value) { if (text.value) {
sendTextLoading.value = true; sendTextLoading.value = true
emit("sendMsg", type, { emit("sendMsg", type, {
...params, ...params,
callBack: () => { callBack: () => {
sendTextLoading.value = false; sendTextLoading.value = false
text.value = ""; text.value = ""
}, },
errorBack: () => { errorBack: () => {
sendTextLoading.value = false; sendTextLoading.value = false
}, },
}); })
} else { } else {
showToast("请输入互动内容!"); showToast("请输入互动内容!")
} }
break; break
case 4: case 4:
dblclickLive(); dblclickLive()
break; break
case 5: case 5:
shareRef.value.showPopup = true; shareRef.value.showPopup = true
break; break
default: default:
break; break
}
};
function inputMsg() {
if (!store.state.token) {
userLogin();
} }
} }
const productListRef = ref(); function inputMsg() {
if (!store.state.token) {
userLogin()
}
}
const productListRef = ref()
const openProductList = () => { const openProductList = () => {
// //
productListRef.value.showPopup = true; productListRef.value.showPopup = true
}; }
// //
const clearScreenFn = () => { const clearScreenFn = () => {
emit("clearScreenFn"); emit("clearScreenFn")
}; }
// //
const closeActivity = () => { const closeActivity = () => {
showRecommend.value = false; showRecommend.value = false
emit("closeActivity"); emit("closeActivity")
}; }
let liveIndex = 0; let liveIndex = 0
const liveIcon = [ const liveIcon = [
require("@/assets/images/liveIcon/icon1.png"), require("@/assets/images/liveIcon/icon1.png"),
require("@/assets/images/liveIcon/icon2.png"), require("@/assets/images/liveIcon/icon2.png"),
require("@/assets/images/liveIcon/icon3.png"), require("@/assets/images/liveIcon/icon3.png"),
require("@/assets/images/liveIcon/icon4.png"), require("@/assets/images/liveIcon/icon4.png"),
]; ]
const sendLikeVideo = async (liveNum) => { const sendLikeVideo = async (liveNum) => {
const ret = await likeVideo({ const ret = await likeVideo({
id: props.detail.id, id: props.detail.id,
option: 1, option: 1,
num: liveNum, num: liveNum,
}); })
if (ret.code === 0) { if (ret.code === 0) {
emitter.emit("updateVideoDetail", { emitter.emit("updateVideoDetail", {
isFavor: 1, isFavor: 1,
favorUserCount: ret.data.count, favorUserCount: ret.data.count,
}); })
} }
}; }
let sendLiveTime = null; let sendLiveTime = null
const dblclickLive = () => { const dblclickLive = () => {
const img = document.createElement("img"); const img = document.createElement("img")
img.setAttribute("src", liveIcon[liveIndex % 4]); img.setAttribute("src", liveIcon[liveIndex % 4])
img.setAttribute("class", "live-icon"); img.setAttribute("class", "live-icon")
document.querySelector(".star").appendChild(img); document.querySelector(".star").appendChild(img)
liveIndex++; liveIndex++
((img) => { ;((img) => {
setTimeout(() => { setTimeout(() => {
let star = document.querySelector(".star"); let star = document.querySelector(".star")
star && star.removeChild(img); star && star.removeChild(img)
}, 2000); }, 2000)
})(img); })(img)
clearTimeout(sendLiveTime); clearTimeout(sendLiveTime)
sendLiveTime = setTimeout(() => { sendLiveTime = setTimeout(() => {
sendLikeVideo(liveIndex); sendLikeVideo(liveIndex)
liveIndex = 0; liveIndex = 0
}, 1000); }, 1000)
}; }
function bigNumberTransform(value) { function bigNumberTransform(value) {
let param = {}; let param = {}
let k = 10000, let k = 10000,
sizes = ["", "万", "亿", "万亿"], sizes = ["", "万", "亿", "万亿"],
i; i
if (value < k) { if (value < k) {
param.value = value; param.value = value
param.unit = ""; param.unit = ""
} else { } else {
i = Math.floor(Math.log(value) / Math.log(k)); i = Math.floor(Math.log(value) / Math.log(k))
param.value = value / Math.pow(k, i); param.value = value / Math.pow(k, i)
param.unit = `${sizes[i]}+`; param.unit = `${sizes[i]}+`
} }
let number = param.value + param.unit; let number = param.value + param.unit
return number; return number
} }
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">

View File

@ -43,6 +43,11 @@ const props = defineProps({
type: Number, type: Number,
default: 3, default: 3,
}, },
detail: {
//
type: Object,
default: () => {},
},
}) })
const route = useRoute() const route = useRoute()
const store = useStore() const store = useStore()
@ -67,6 +72,8 @@ const toDetail = async () => {
token: store.state.userInfo.token, token: store.state.userInfo.token,
refreshToken: store.state.userInfo.refreshToken, refreshToken: store.state.userInfo.refreshToken,
activityId: props.item.url, activityId: props.item.url,
staffNo:
props.detail.saleUserStaffNo || props.detail.advisorBasic.staffNo,
}) })
} else { } else {
if (props.liveProductId) { if (props.liveProductId) {

View File

@ -169,6 +169,7 @@
:item="item.productBasic" :item="item.productBasic"
:liveProductId="detail.id" :liveProductId="detail.id"
:tgId="detail.advisorBasic?.id" :tgId="detail.advisorBasic?.id"
:detail="detail"
:isShopCar="true" /> :isShopCar="true" />
</div> </div>
<div v-else-if="item.type === 4"> <div v-else-if="item.type === 4">

View File

@ -13,6 +13,7 @@
url: item.url, url: item.url,
coverImgUrl: item.coverImgUrl, coverImgUrl: item.coverImgUrl,
}" }"
:detail="detail"
:isShopCar="true" /> :isShopCar="true" />
<ServerItem <ServerItem
v-else v-else
@ -44,6 +45,11 @@ defineProps({
type: String, type: String,
default: "", default: "",
}, },
detail: {
//
type: Object,
default: () => ({}),
},
}) })
onMounted(() => { onMounted(() => {

View File

@ -232,6 +232,8 @@ async function toActivityPage(type) {
token: store.state.userInfo.token, token: store.state.userInfo.token,
refreshToken: store.state.userInfo.refreshToken, refreshToken: store.state.userInfo.refreshToken,
activityId: props.carPushObj.url, activityId: props.carPushObj.url,
staffNo:
props.detail.saleUserStaffNo || props.detail.advisorBasic.staffNo,
}) })
} }
} }