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-waterfall-plugin-next": "^2.4.3",
"vue3-hash-calendar": "^1.1.3",
"vue3-marquee": "^4.2.2",
"vuex": "^4.0.0"
},
"devDependencies": {
@ -15428,6 +15429,17 @@
"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": {
"version": "4.1.0",
"resolved": "https://registry.npmmirror.com/vuex/-/vuex-4.1.0.tgz",

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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